Skip to content

Commit 9e19f0a

Browse files
committed
[BOLT] Improve function splitting at OpNegateRAState handling
- Previous version used the Layout API which should not be used. - This version iterates on Fragments to have the same effect. - NegateRAState is added to the first *non-empty* BB of the cold fragment.
1 parent 0cec69a commit 9e19f0a

File tree

1 file changed

+24
-20
lines changed

1 file changed

+24
-20
lines changed

bolt/lib/Passes/InsertNegateRAStatePass.cpp

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,27 +43,32 @@ void InsertNegateRAState::runOnFunction(BinaryFunction &BF) {
4343

4444
fixUnknownStates(BF);
4545

46-
bool FirstIter = true;
47-
MCInst PrevInst;
48-
BinaryBasicBlock *PrevBB = nullptr;
49-
// We need to iterate on BBs in the Layout order
50-
// not in the order they are stored in the BF class.
51-
auto *Begin = BF.getLayout().block_begin();
52-
auto *End = BF.getLayout().block_end();
53-
for (auto *BB = Begin; BB != End; BB++) {
54-
55-
// Support for function splitting:
56-
// if two consecutive BBs with Signed state are going to end up in different
57-
// functions, we have to add a OpNegateRAState to the beginning of the newly
58-
// split function, so it starts with a Signed state.
59-
if (PrevBB != nullptr &&
60-
PrevBB->getFragmentNum() != (*BB)->getFragmentNum() &&
61-
BC.MIB->isRASigned(*((*BB)->begin()))) {
62-
BF.addCFIInstruction(*BB, (*BB)->begin(),
46+
// Support for function splitting:
47+
// if two consecutive BBs with Signed state are going to end up in different
48+
// functions (so are held by different FunctionFragments), we have to add a
49+
// OpNegateRAState to the beginning of the newly split function, so it starts
50+
// with a Signed state.
51+
for (FunctionFragment &FF : BF.getLayout().fragments()) {
52+
// Find the first BB in the FF which has Instructions.
53+
// BOLT can generate empty BBs at function splitting which are only used as
54+
// target labels. We should add the negate-ra-state CFI to the first
55+
// non-empty BB.
56+
auto FirstNonEmpty =
57+
std::find_if(FF.begin(), FF.end(), [](BinaryBasicBlock *BB) {
58+
// getFirstNonPseudo returns BB.end() if it does not find any
59+
// Instructions.
60+
return BB->getFirstNonPseudo() != BB->end();
61+
});
62+
if (BC.MIB->isRASigned(*((*FirstNonEmpty)->begin()))) {
63+
BF.addCFIInstruction(*FirstNonEmpty, (*FirstNonEmpty)->begin(),
6364
MCCFIInstruction::createNegateRAState(nullptr));
6465
}
66+
}
6567

66-
for (auto It = (*BB)->begin(); It != (*BB)->end(); ++It) {
68+
bool FirstIter = true;
69+
MCInst PrevInst;
70+
for (BinaryBasicBlock &BB : BF) {
71+
for (auto It = BB.begin(); It != BB.end(); ++It) {
6772

6873
MCInst &Inst = *It;
6974
if (BC.MIB->isCFI(Inst))
@@ -76,15 +81,14 @@ void InsertNegateRAState::runOnFunction(BinaryFunction &BF) {
7681
(BC.MIB->isRAUnsigned(PrevInst) && BC.MIB->isRASigned(Inst))) {
7782

7883
It = BF.addCFIInstruction(
79-
*BB, It, MCCFIInstruction::createNegateRAState(nullptr));
84+
&BB, It, MCCFIInstruction::createNegateRAState(nullptr));
8085
}
8186

8287
} else {
8388
FirstIter = false;
8489
}
8590
PrevInst = *It;
8691
}
87-
PrevBB = *BB;
8892
}
8993
}
9094

0 commit comments

Comments
 (0)