Skip to content

Commit bab1c5d

Browse files
Bill Nellmemfrob
authored andcommitted
[BOLT] Refactor branch analysis code.
Summary: Move the indirect branch analysis code from BinaryFunction to MCInstrAnalysis/X86MCTargetDesc.cpp. In the process of doing this, I've added an MCRegInfo to MCInstrAnalysis which allowed me to remove a bunch of extra method parameters. I've also had to refactor how BinaryFunction held on to instructions/offsets so that it would be easy to pass a sequence of instructions to the analysis code (rather than a map keyed by offset). Note: I think there are a bunch of MCInstrAnalysis methods that have a BitVector output parameter that could be changed to a return value since the size of the vector is based on the number of registers, i.e. from MCRegisterInfo. I haven't done this in order to keep the diff a more manageable size. (cherry picked from FBD6213556)
1 parent f976ad6 commit bab1c5d

11 files changed

+118
-318
lines changed

bolt/BinaryFunction.cpp

Lines changed: 68 additions & 264 deletions
Large diffs are not rendered by default.

bolt/BinaryFunction.h

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,9 @@ class BinaryFunction {
461461

462462
/// Temporary holder of instructions before CFG is constructed.
463463
/// Map offset in the function to MCInst.
464-
using InstrMapType = std::map<uint32_t, MCInst>;
465-
InstrMapType Instructions;
464+
using InstrMapType = std::map<uint32_t, size_t>;
465+
InstrMapType InstructionOffsets;
466+
std::vector<MCInst> Instructions;
466467

467468
/// List of DWARF CFI instructions. Original CFI from the binary must be
468469
/// sorted w.r.t. offset that it appears. We rely on this to replay CFIs
@@ -736,30 +737,25 @@ class BinaryFunction {
736737
}
737738

738739
void addInstruction(uint64_t Offset, MCInst &&Instruction) {
739-
Instructions.emplace(Offset, std::forward<MCInst>(Instruction));
740+
assert(InstructionOffsets.size() == Instructions.size() &&
741+
"There must be one instruction at every offset.");
742+
Instructions.emplace_back(std::forward<MCInst>(Instruction));
743+
InstructionOffsets[Offset] = Instructions.size() - 1;
740744
}
741745

742746
/// Return instruction at a given offset in the function. Valid before
743747
/// CFG is constructed.
744748
MCInst *getInstructionAtOffset(uint64_t Offset) {
745749
assert(CurrentState == State::Disassembled &&
746750
"can only call function in Disassembled state");
747-
auto II = Instructions.find(Offset);
748-
return (II == Instructions.end()) ? nullptr : &II->second;
751+
auto II = InstructionOffsets.find(Offset);
752+
return (II == InstructionOffsets.end())
753+
? nullptr : &Instructions[II->second];
749754
}
750755

751-
/// Different types of indirect branches encountered during disassembly.
752-
enum class IndirectBranchType : char {
753-
UNKNOWN = 0, /// Unable to determine type.
754-
POSSIBLE_TAIL_CALL, /// Possibly a tail call.
755-
POSSIBLE_JUMP_TABLE, /// Possibly a switch/jump table.
756-
POSSIBLE_PIC_JUMP_TABLE, /// Possibly a jump table for PIC.
757-
POSSIBLE_GOTO /// Possibly a gcc's computed goto.
758-
};
759-
760-
/// Analyze indirect branch \p Instruction before it is added to
761-
/// Instructions list.
762-
IndirectBranchType analyzeIndirectBranch(MCInst &Instruction,
756+
/// Analyze and process indirect branch \p Instruction before it is
757+
/// added to Instructions list.
758+
IndirectBranchType processIndirectBranch(MCInst &Instruction,
763759
unsigned Size,
764760
uint64_t Offset);
765761

@@ -1439,22 +1435,23 @@ class BinaryFunction {
14391435
// harder for us to recover this information, since we can create empty BBs
14401436
// with NOPs and then reorder it away.
14411437
// We fix this by moving the CFI instruction just before any NOPs.
1442-
auto I = Instructions.lower_bound(Offset);
1438+
auto I = InstructionOffsets.lower_bound(Offset);
14431439
if (Offset == getSize()) {
1444-
assert(I == Instructions.end() && "unexpected iterator value");
1440+
assert(I == InstructionOffsets.end() && "unexpected iterator value");
14451441
// Sometimes compiler issues restore_state after all instructions
14461442
// in the function (even after nop).
14471443
--I;
14481444
Offset = I->first;
14491445
}
14501446
assert(I->first == Offset && "CFI pointing to unknown instruction");
1451-
if (I == Instructions.begin()) {
1447+
if (I == InstructionOffsets.begin()) {
14521448
CIEFrameInstructions.emplace_back(std::forward<MCCFIInstruction>(Inst));
14531449
return;
14541450
}
14551451

14561452
--I;
1457-
while (I != Instructions.begin() && BC.MIA->isNoop(I->second)) {
1453+
while (I != InstructionOffsets.begin() &&
1454+
BC.MIA->isNoop(Instructions[I->second])) {
14581455
Offset = I->first;
14591456
--I;
14601457
}

bolt/Exceptions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
219219
// Create a handler entry if necessary.
220220
MCSymbol *LPSymbol{nullptr};
221221
if (LandingPad) {
222-
if (Instructions.find(LandingPad) == Instructions.end()) {
222+
if (InstructionOffsets.find(LandingPad) == InstructionOffsets.end()) {
223223
if (opts::Verbosity >= 1) {
224224
errs() << "BOLT-WARNING: landing pad " << Twine::utohexstr(LandingPad)
225225
<< " not pointing to an instruction in function "
@@ -237,11 +237,11 @@ void BinaryFunction::parseLSDA(ArrayRef<uint8_t> LSDASectionData,
237237
}
238238

239239
// Mark all call instructions in the range.
240-
auto II = Instructions.find(Start);
241-
auto IE = Instructions.end();
240+
auto II = InstructionOffsets.find(Start);
241+
auto IE = InstructionOffsets.end();
242242
assert(II != IE && "exception range not pointing to an instruction");
243243
do {
244-
auto &Instruction = II->second;
244+
auto &Instruction = Instructions[II->second];
245245
if (BC.MIA->isCall(Instruction)) {
246246
assert(!BC.MIA->isInvoke(Instruction) &&
247247
"overlapping exception ranges detected");

bolt/Passes/FrameAnalysis.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,9 @@ class FrameAccessAnalysis {
106106
MCPhysReg Reg{0};
107107
int64_t StackOffset{0};
108108
bool IsIndexed{false};
109-
if (!BC.MIA->isStackAccess(*BC.MRI, Inst, FIE.IsLoad, FIE.IsStore,
110-
FIE.IsStoreFromReg, Reg, SrcImm, FIE.StackPtrReg,
111-
StackOffset, FIE.Size, FIE.IsSimple,
112-
IsIndexed)) {
109+
if (!BC.MIA->isStackAccess(Inst, FIE.IsLoad, FIE.IsStore, FIE.IsStoreFromReg,
110+
Reg, SrcImm, FIE.StackPtrReg, StackOffset, FIE.Size,
111+
FIE.IsSimple, IsIndexed)) {
113112
return true;
114113
}
115114

@@ -205,7 +204,7 @@ class FrameAccessAnalysis {
205204
return true;
206205
}
207206

208-
if (BC.MIA->escapesVariable(Inst, *BC.MRI, SPT.HasFramePointer)) {
207+
if (BC.MIA->escapesVariable(Inst, SPT.HasFramePointer)) {
209208
DEBUG(dbgs() << "Leaked stack address, giving up on this function.\n");
210209
DEBUG(dbgs() << "Blame insn: ");
211210
DEBUG(Inst.dump());

bolt/Passes/LivenessAnalysis.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class LivenessAnalysis
4444

4545
bool isAlive(ProgramPoint PP, MCPhysReg Reg) const {
4646
BitVector BV = (*this->getStateAt(PP));
47-
const BitVector &RegAliases = BC.MIA->getAliases(Reg, *BC.MRI);
47+
const BitVector &RegAliases = BC.MIA->getAliases(Reg);
4848
BV &= RegAliases;
4949
return BV.any();
5050
}
@@ -60,7 +60,7 @@ class LivenessAnalysis
6060
BitVector BV = *this->getStateAt(P);
6161
BV.flip();
6262
BitVector GPRegs(NumRegs, false);
63-
this->BC.MIA->getGPRegs(GPRegs, *this->BC.MRI);
63+
this->BC.MIA->getGPRegs(GPRegs);
6464
BV &= GPRegs;
6565
int Reg = BV.find_first();
6666
return Reg != -1 ? Reg : 0;
@@ -91,7 +91,7 @@ class LivenessAnalysis
9191
// Kill
9292
auto Written = BitVector(NumRegs, false);
9393
if (!IsCall) {
94-
this->BC.MIA->getWrittenRegs(Point, Written, *this->BC.MRI);
94+
this->BC.MIA->getWrittenRegs(Point, Written);
9595
} else {
9696
RA.getInstClobberList(Point, Written);
9797
// When clobber list is conservative, it is clobbering all/most registers,
@@ -100,7 +100,7 @@ class LivenessAnalysis
100100
// because we don't really know what's going on.
101101
if (RA.isConservative(Written)) {
102102
Written.reset();
103-
BC.MIA->getCalleeSavedRegs(Written, *this->BC.MRI);
103+
BC.MIA->getCalleeSavedRegs(Written);
104104
}
105105
}
106106
Written.flip();

bolt/Passes/ReachingDefOrUse.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ReachingDefOrUse
4545
if (Def) {
4646
RA.getInstClobberList(**I, BV);
4747
} else {
48-
this->BC.MIA->getTouchedRegs(**I, BV, *this->BC.MRI);
48+
this->BC.MIA->getTouchedRegs(**I, BV);
4949
}
5050
if (BV[Reg])
5151
return true;
@@ -101,7 +101,7 @@ class ReachingDefOrUse
101101
if (Def)
102102
RA.getInstClobberList(*Y, YClobbers);
103103
else
104-
this->BC.MIA->getTouchedRegs(*Y, YClobbers, *this->BC.MRI);
104+
this->BC.MIA->getTouchedRegs(*Y, YClobbers);
105105
// X kills Y if it clobbers Y completely -- this is a conservative approach.
106106
// In practice, we may produce use-def links that may not exist.
107107
XClobbers &= YClobbers;

bolt/Passes/RegAnalysis.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ void RegAnalysis::beConservative(BitVector &Result) const {
9393
Result.set();
9494
} else {
9595
BitVector BV(BC.MRI->getNumRegs(), false);
96-
BC.MIA->getCalleeSavedRegs(BV, *BC.MRI);
96+
BC.MIA->getCalleeSavedRegs(BV);
9797
BV.flip();
9898
Result |= BV;
9999
}
@@ -104,7 +104,7 @@ bool RegAnalysis::isConservative(BitVector &Vec) const {
104104
return Vec.all();
105105
} else {
106106
BitVector BV(BC.MRI->getNumRegs(), false);
107-
BC.MIA->getCalleeSavedRegs(BV, *BC.MRI);
107+
BC.MIA->getCalleeSavedRegs(BV);
108108
BV |= Vec;
109109
return BV.all();
110110
}
@@ -114,9 +114,9 @@ void RegAnalysis::getInstUsedRegsList(const MCInst &Inst, BitVector &RegSet,
114114
bool GetClobbers) const {
115115
if (!BC.MIA->isCall(Inst)) {
116116
if (GetClobbers)
117-
BC.MIA->getClobberedRegs(Inst, RegSet, *BC.MRI);
117+
BC.MIA->getClobberedRegs(Inst, RegSet);
118118
else
119-
BC.MIA->getUsedRegs(Inst, RegSet, *BC.MRI);
119+
BC.MIA->getUsedRegs(Inst, RegSet);
120120
return;
121121
}
122122

bolt/Passes/ShrinkWrapping.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -603,9 +603,9 @@ void StackLayoutModifier::performChanges() {
603603
bool IsStoreFromReg{false};
604604
uint8_t Size{0};
605605
bool Success{false};
606-
Success = BC.MIA->isStackAccess(*BC.MRI, Inst, IsLoad, IsStore,
607-
IsStoreFromReg, Reg, SrcImm, StackPtrReg,
608-
StackOffset, Size, IsSimple, IsIndexed);
606+
Success = BC.MIA->isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg,
607+
Reg, SrcImm, StackPtrReg, StackOffset,
608+
Size, IsSimple, IsIndexed);
609609
assert(Success && IsSimple && !IsIndexed && (!IsStore || IsStoreFromReg));
610610
if (StackPtrReg != BC.MIA->getFramePointer())
611611
Adjustment = -Adjustment;
@@ -642,13 +642,13 @@ void ShrinkWrapping::classifyCSRUses() {
642642
BitVector(DA.NumInstrs, false));
643643

644644
const BitVector &FPAliases =
645-
BC.MIA->getAliases(BC.MIA->getFramePointer(), *BC.MRI);
645+
BC.MIA->getAliases(BC.MIA->getFramePointer());
646646
for (auto &BB : BF) {
647647
for (auto &Inst : BB) {
648648
if (BC.MIA->isCFI(Inst))
649649
continue;
650650
auto BV = BitVector(BC.MRI->getNumRegs(), false);
651-
BC.MIA->getTouchedRegs(Inst, BV, *BC.MRI);
651+
BC.MIA->getTouchedRegs(Inst, BV);
652652
BV &= CSA.CalleeSaved;
653653
for (int I = BV.find_first(); I != -1; I = BV.find_next(I)) {
654654
if (I == 0)
@@ -668,7 +668,7 @@ void ShrinkWrapping::classifyCSRUses() {
668668
}
669669

670670
void ShrinkWrapping::pruneUnwantedCSRs() {
671-
BitVector ParamRegs = BC.MIA->getRegsUsedAsParams(*BC.MRI);
671+
BitVector ParamRegs = BC.MIA->getRegsUsedAsParams();
672672
for (unsigned I = 0, E = BC.MRI->getNumRegs(); I != E; ++I) {
673673
if (!CSA.CalleeSaved[I])
674674
continue;
@@ -1080,7 +1080,7 @@ bool ShrinkWrapping::doesInstUsesCSR(const MCInst &Inst, uint16_t CSR) {
10801080
CSA.getRestoredReg(Inst) == CSR)
10811081
return false;
10821082
BitVector BV = BitVector(BC.MRI->getNumRegs(), false);
1083-
BC.MIA->getTouchedRegs(Inst, BV, *BC.MRI);
1083+
BC.MIA->getTouchedRegs(Inst, BV);
10841084
return BV[CSR];
10851085
}
10861086

@@ -1389,9 +1389,9 @@ void ShrinkWrapping::insertUpdatedCFI(unsigned CSR, int SPValPush,
13891389
bool IsSimple{false};
13901390
bool IsStoreFromReg{false};
13911391
uint8_t Size{0};
1392-
if (!BC.MIA->isStackAccess(*BC.MRI, *InstIter, IsLoad, IsStore,
1393-
IsStoreFromReg, Reg, SrcImm, StackPtrReg,
1394-
StackOffset, Size, IsSimple, IsIndexed))
1392+
if (!BC.MIA->isStackAccess(*InstIter, IsLoad, IsStore, IsStoreFromReg,
1393+
Reg, SrcImm, StackPtrReg, StackOffset,
1394+
Size, IsSimple, IsIndexed))
13951395
continue;
13961396
if (Reg != CSR || !IsStore || !IsSimple)
13971397
continue;

bolt/Passes/StackPointerTracking.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class StackPointerTrackingBase
165165
}
166166

167167
if (!HasFramePointer) {
168-
if (MIA->escapesVariable(Point, *this->BC.MRI, false)) {
168+
if (MIA->escapesVariable(Point, false)) {
169169
HasFramePointer = true;
170170
}
171171
}

bolt/Passes/StokeInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ void StokeInfo::runOnFunctions(
165165
DefaultDefInMask.resize(NumRegs, false);
166166
DefaultLiveOutMask.resize(NumRegs, false);
167167

168-
BC.MIA->getDefaultDefIn(DefaultDefInMask, *BC.MRI);
169-
BC.MIA->getDefaultLiveOut(DefaultLiveOutMask, *BC.MRI);
168+
BC.MIA->getDefaultDefIn(DefaultDefInMask);
169+
BC.MIA->getDefaultLiveOut(DefaultLiveOutMask);
170170

171171
getRegNameFromBitVec(BC, DefaultDefInMask);
172172
getRegNameFromBitVec(BC, DefaultLiveOutMask);

0 commit comments

Comments
 (0)