Skip to content

Commit 6641d9f

Browse files
committed
fixup! fixup! fixup! [BOLT][AArch64] Add support for compact code model
1 parent 4dc0221 commit 6641d9f

File tree

1 file changed

+40
-27
lines changed

1 file changed

+40
-27
lines changed

bolt/lib/Passes/LongJmp.cpp

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -683,11 +683,15 @@ void LongJmpPass::relaxLocalBranches(BinaryFunction &BF) {
683683
DenseMap<const BinaryBasicBlock *, BinaryBasicBlock *> FragmentTrampolines;
684684

685685
// Create a trampoline code after \p BB or at the end of the fragment if BB
686-
// is nullptr.
686+
// is nullptr. If /p UpdateOffsets is true, update FragmentSize and offsets
687+
// for basic blocks affected by the insertion of the trampoline.
687688
auto addTrampolineAfter = [&](BinaryBasicBlock *BB,
688689
BinaryBasicBlock *TargetBB, uint64_t Count,
689690
bool UpdateOffsets = true) {
690-
std::unique_ptr<BinaryBasicBlock> TrampolineBB = BF.createBasicBlock();
691+
FunctionTrampolines.emplace_back(BB ? BB : FF.back(),
692+
BF.createBasicBlock());
693+
BinaryBasicBlock *TrampolineBB = FunctionTrampolines.back().second.get();
694+
691695
MCInst Inst;
692696
{
693697
auto L = BC.scopeLock();
@@ -702,37 +706,46 @@ void LongJmpPass::relaxLocalBranches(BinaryFunction &BF) {
702706
TrampolineBB->setOutputEndAddress(TrampolineAddress + TrampolineSize);
703707
TrampolineBB->setFragmentNum(FF.getFragmentNum());
704708

705-
if (UpdateOffsets) {
706-
FragmentSize += TrampolineSize;
707-
for (BinaryBasicBlock *IBB : FF) {
708-
if (IBB->getOutputStartAddress() >= TrampolineAddress) {
709-
IBB->setOutputStartAddress(IBB->getOutputStartAddress() +
710-
TrampolineSize);
711-
IBB->setOutputEndAddress(IBB->getOutputEndAddress() +
709+
if (!FragmentTrampolines.lookup(TargetBB))
710+
FragmentTrampolines[TargetBB] = TrampolineBB;
711+
712+
if (!UpdateOffsets)
713+
return TrampolineBB;
714+
715+
FragmentSize += TrampolineSize;
716+
717+
// If the trampoline was added at the end of the fragment, offsets of
718+
// other fragments should stay intact.
719+
if (!BB)
720+
return TrampolineBB;
721+
722+
// Update offsets for blocks after BB.
723+
for (BinaryBasicBlock *IBB : FF) {
724+
if (IBB->getOutputStartAddress() >= TrampolineAddress) {
725+
IBB->setOutputStartAddress(IBB->getOutputStartAddress() +
712726
TrampolineSize);
713-
}
727+
IBB->setOutputEndAddress(IBB->getOutputEndAddress() + TrampolineSize);
714728
}
715-
for (auto &Pair : FunctionTrampolines) {
716-
BinaryBasicBlock *IBB = Pair.second.get();
717-
if (IBB->getFragmentNum() != TrampolineBB->getFragmentNum())
718-
continue;
719-
if (IBB == TrampolineBB.get())
720-
continue;
721-
if (IBB->getOutputStartAddress() >= TrampolineAddress) {
722-
IBB->setOutputStartAddress(IBB->getOutputStartAddress() +
723-
TrampolineSize);
724-
IBB->setOutputEndAddress(IBB->getOutputEndAddress() +
729+
}
730+
731+
// Update offsets for trampolines in this fragment that are placed after
732+
// the new trampoline. Note that trampoline blocks are not part of the
733+
// function/fragment layout until we add them right before the return
734+
// from relaxLocalBranches().
735+
for (auto &Pair : FunctionTrampolines) {
736+
BinaryBasicBlock *IBB = Pair.second.get();
737+
if (IBB->getFragmentNum() != TrampolineBB->getFragmentNum())
738+
continue;
739+
if (IBB == TrampolineBB)
740+
continue;
741+
if (IBB->getOutputStartAddress() >= TrampolineAddress) {
742+
IBB->setOutputStartAddress(IBB->getOutputStartAddress() +
725743
TrampolineSize);
726-
}
744+
IBB->setOutputEndAddress(IBB->getOutputEndAddress() + TrampolineSize);
727745
}
728746
}
729747

730-
if (!FragmentTrampolines.lookup(TargetBB))
731-
FragmentTrampolines[TargetBB] = TrampolineBB.get();
732-
FunctionTrampolines.emplace_back(BB ? BB : FF.back(),
733-
std::move(TrampolineBB));
734-
735-
return FunctionTrampolines.back().second.get();
748+
return TrampolineBB;
736749
};
737750

738751
// Pre-populate trampolines by splitting unconditional branches from the

0 commit comments

Comments
 (0)