Skip to content

Commit 8a87530

Browse files
author
Amirhossein Pashaeehir
committed
Store only the last row in the state
1 parent ccfeaa5 commit 8a87530

File tree

4 files changed

+44
-58
lines changed

4 files changed

+44
-58
lines changed

llvm/include/llvm/DWARFCFIChecker/DWARFCFIAnalysis.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ class DWARFCFIAnalysis {
7474

7575
private:
7676
void checkRegDiff(const MCInst &Inst, DWARFRegNum Reg,
77-
const dwarf::UnwindRow *PrevRow,
78-
const dwarf::UnwindRow *NextRow,
77+
const dwarf::UnwindRow &PrevRow,
78+
const dwarf::UnwindRow &NextRow,
7979
const SmallSet<DWARFRegNum, 4> &Reads,
8080
const SmallSet<DWARFRegNum, 4> &Writes);
8181

82-
void checkCFADiff(const MCInst &Inst, const dwarf::UnwindRow *PrevRow,
83-
const dwarf::UnwindRow *NextRow,
82+
void checkCFADiff(const MCInst &Inst, const dwarf::UnwindRow &PrevRow,
83+
const dwarf::UnwindRow &NextRow,
8484
const SmallSet<DWARFRegNum, 4> &Reads,
8585
const SmallSet<DWARFRegNum, 4> &Writes);
8686

llvm/include/llvm/DWARFCFIChecker/DWARFCFIState.h

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,24 @@ namespace llvm {
2323

2424
using DWARFRegNum = uint32_t;
2525

26-
/// This class is used to maintain a CFI state and history, referred to as an
27-
/// unwinding table, during CFI analysis. The table is private, meaning the only
28-
/// way to modify it is to append a new row by updating it with a CFI directive,
29-
/// and the only way to read from it is to read the last row (i.e., current CFI
30-
/// state) from the table. The fetched row is constant and should not be
31-
/// modified or deleted.
26+
/// This class is used to maintain a CFI state, referred to as an unwinding row,
27+
/// during CFI analysis. The only way to modify the state is by updating it with
28+
/// a CFI directive.
3229
class DWARFCFIState {
3330
public:
34-
DWARFCFIState(MCContext *Context) : Context(Context) {};
35-
~DWARFCFIState();
31+
DWARFCFIState(MCContext *Context) : Context(Context), IsInitiated(false) {};
3632

37-
std::optional<const dwarf::UnwindRow *> getCurrentUnwindRow() const;
33+
std::optional<dwarf::UnwindRow> getCurrentUnwindRow() const;
34+
/// This method updates the state by applying \p Directive to the current
35+
/// state. If the directive is not supported by the checker or any error
36+
/// happens while applying the CFI directive, a warning or error is reported
37+
/// to the user, and the directive is ignored, leaving the state unchanged.
3838
void update(const MCCFIInstruction &Directive);
3939

4040
private:
41+
dwarf::UnwindRow Row;
4142
MCContext *Context;
42-
std::vector<dwarf::UnwindRow *> Table;
43+
bool IsInitiated;
4344

4445
dwarf::CFIProgram convert(MCCFIInstruction Directive);
4546
};

llvm/lib/DWARFCFIChecker/DWARFCFIAnalysis.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ struct CFARegOffsetInfo {
4444
};
4545

4646
static std::optional<CFARegOffsetInfo>
47-
getCFARegOffsetInfo(const dwarf::UnwindRow *UnwindRow) {
48-
auto CFALocation = UnwindRow->getCFAValue();
47+
getCFARegOffsetInfo(const dwarf::UnwindRow &UnwindRow) {
48+
auto CFALocation = UnwindRow.getCFAValue();
4949
if (CFALocation.getLocation() !=
5050
dwarf::UnwindLocation::Location::RegPlusOffset) {
5151
return std::nullopt;
@@ -55,8 +55,8 @@ getCFARegOffsetInfo(const dwarf::UnwindRow *UnwindRow) {
5555
}
5656

5757
static SmallSet<DWARFRegNum, 4>
58-
getUnwindRuleRegSet(const dwarf::UnwindRow *UnwindRow, DWARFRegNum Reg) {
59-
auto MaybeLoc = UnwindRow->getRegisterLocations().getRegisterLocation(Reg);
58+
getUnwindRuleRegSet(const dwarf::UnwindRow &UnwindRow, DWARFRegNum Reg) {
59+
auto MaybeLoc = UnwindRow.getRegisterLocations().getRegisterLocation(Reg);
6060
assert(MaybeLoc && "The register should be included in the unwinding row");
6161
auto Loc = *MaybeLoc;
6262

@@ -131,7 +131,7 @@ void DWARFCFIAnalysis::update(const MCInst &Inst,
131131
auto MaybePrevRow = State.getCurrentUnwindRow();
132132
assert(MaybePrevRow && "The analysis should have initialized the "
133133
"history with at least one row by now");
134-
const dwarf::UnwindRow *PrevRow = MaybePrevRow.value();
134+
auto PrevRow = *MaybePrevRow;
135135

136136
for (auto &&Directive : Directives)
137137
State.update(Directive);
@@ -158,7 +158,7 @@ void DWARFCFIAnalysis::update(const MCInst &Inst,
158158

159159
auto MaybeNextRow = State.getCurrentUnwindRow();
160160
assert(MaybeNextRow && "Prev row existed, so should the current row.");
161-
const dwarf::UnwindRow *NextRow = *MaybeNextRow;
161+
auto NextRow = *MaybeNextRow;
162162

163163
checkCFADiff(Inst, PrevRow, NextRow, Reads, Writes);
164164

@@ -170,12 +170,12 @@ void DWARFCFIAnalysis::update(const MCInst &Inst,
170170
}
171171

172172
void DWARFCFIAnalysis::checkRegDiff(const MCInst &Inst, DWARFRegNum Reg,
173-
const dwarf::UnwindRow *PrevRow,
174-
const dwarf::UnwindRow *NextRow,
173+
const dwarf::UnwindRow &PrevRow,
174+
const dwarf::UnwindRow &NextRow,
175175
const SmallSet<DWARFRegNum, 4> &Reads,
176176
const SmallSet<DWARFRegNum, 4> &Writes) {
177-
auto MaybePrevLoc = PrevRow->getRegisterLocations().getRegisterLocation(Reg);
178-
auto MaybeNextLoc = NextRow->getRegisterLocations().getRegisterLocation(Reg);
177+
auto MaybePrevLoc = PrevRow.getRegisterLocations().getRegisterLocation(Reg);
178+
auto MaybeNextLoc = NextRow.getRegisterLocations().getRegisterLocation(Reg);
179179

180180
// All the tracked registers are added during initiation. So if a register is
181181
// not added, should stay the same during execution and vice versa.
@@ -256,8 +256,8 @@ void DWARFCFIAnalysis::checkRegDiff(const MCInst &Inst, DWARFRegNum Reg,
256256
}
257257

258258
void DWARFCFIAnalysis::checkCFADiff(const MCInst &Inst,
259-
const dwarf::UnwindRow *PrevRow,
260-
const dwarf::UnwindRow *NextRow,
259+
const dwarf::UnwindRow &PrevRow,
260+
const dwarf::UnwindRow &NextRow,
261261
const SmallSet<DWARFRegNum, 4> &Reads,
262262
const SmallSet<DWARFRegNum, 4> &Writes) {
263263

llvm/lib/DWARFCFIChecker/DWARFCFIState.cpp

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,38 +18,26 @@
1818

1919
using namespace llvm;
2020

21-
DWARFCFIState::~DWARFCFIState() {
22-
for (auto &&Row : Table)
23-
delete Row;
24-
}
25-
26-
std::optional<const dwarf::UnwindRow *>
27-
DWARFCFIState::getCurrentUnwindRow() const {
28-
if (!Table.size())
21+
std::optional<dwarf::UnwindRow> DWARFCFIState::getCurrentUnwindRow() const {
22+
if (!IsInitiated)
2923
return std::nullopt;
30-
31-
return *(--Table.end());
24+
return Row;
3225
}
3326

3427
void DWARFCFIState::update(const MCCFIInstruction &Directive) {
3528
auto CFIP = convert(Directive);
3629

37-
auto MaybeCurrentRow = getCurrentUnwindRow();
38-
39-
// This is a copy of the last row of the table (or a new empty row), its value
40-
// will be updated by `parseRows`.
41-
dwarf::UnwindRow *NewRow = nullptr;
42-
if (MaybeCurrentRow)
43-
NewRow = new dwarf::UnwindRow(*(MaybeCurrentRow.value()));
44-
else
45-
NewRow = new dwarf::UnwindRow();
30+
// This is a copy of the current row, its value will be updated by
31+
// `parseRows`.
32+
dwarf::UnwindRow NewRow = Row;
4633

4734
// `parseRows` updates the current row by applying the `CFIProgram` to it.
48-
// During this process, it may create multiple rows that should be placed in
49-
// the unwinding table, preceding the newly updated row and following the
50-
// previous rows. These middle rows are stored in `PrecedingRows`.
35+
// During this process, it may create multiple rows preceding the newly
36+
// updated row and following the previous rows. These middle rows are stored
37+
// in `PrecedingRows`. For now, there is no need to store these rows in the
38+
// state, so they are ignored in the end.
5139
dwarf::UnwindTable::RowContainer PrecedingRows;
52-
if (Error Err = parseRows(CFIP, *NewRow, nullptr).moveInto(PrecedingRows)) {
40+
if (Error Err = parseRows(CFIP, NewRow, nullptr).takeError()) {
5341
Context->reportError(
5442
Directive.getLoc(),
5543
formatv("could not parse this CFI directive due to: {0}",
@@ -59,9 +47,8 @@ void DWARFCFIState::update(const MCCFIInstruction &Directive) {
5947
return;
6048
}
6149

62-
for (auto &&PrecedingRow : PrecedingRows)
63-
Table.push_back(new dwarf::UnwindRow(PrecedingRow));
64-
Table.push_back(NewRow);
50+
Row = NewRow;
51+
IsInitiated = true;
6552
}
6653

6754
dwarf::CFIProgram DWARFCFIState::convert(MCCFIInstruction Directive) {
@@ -101,20 +88,18 @@ dwarf::CFIProgram DWARFCFIState::convert(MCCFIInstruction Directive) {
10188
break;
10289
case MCCFIInstruction::OpRelOffset:
10390
assert(
104-
MaybeCurrentRow &&
91+
IsInitiated &&
10592
"Cannot define relative offset to a non-existing CFA unwinding rule");
10693

10794
CFIP.addInstruction(dwarf::DW_CFA_offset, Directive.getRegister(),
108-
Directive.getOffset() -
109-
(*MaybeCurrentRow)->getCFAValue().getOffset());
95+
Directive.getOffset() - Row.getCFAValue().getOffset());
11096
break;
11197
case MCCFIInstruction::OpAdjustCfaOffset:
112-
assert(MaybeCurrentRow &&
98+
assert(IsInitiated &&
11399
"Cannot adjust CFA offset of a non-existing CFA unwinding rule");
114100

115101
CFIP.addInstruction(dwarf::DW_CFA_def_cfa_offset,
116-
Directive.getOffset() +
117-
(*MaybeCurrentRow)->getCFAValue().getOffset());
102+
Directive.getOffset() + Row.getCFAValue().getOffset());
118103
break;
119104
case MCCFIInstruction::OpEscape:
120105
// TODO: DWARFExpressions are not supported yet, ignoring expression here.

0 commit comments

Comments
 (0)