Skip to content

Commit 7f031d1

Browse files
authored
[BOLT] Fix address mapping for ICP code (#70136)
When we create new code for indirect code promotion optimization, we should mark it as originating from the indirect jump instruction for BOLT address translation (BAT) to map it to the original instruction.
1 parent b3857b2 commit 7f031d1

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,7 @@ void BinaryFunction::print(raw_ostream &OS, std::string Annotation) {
533533
if (BB->getCFIState() >= 0)
534534
OS << " CFI State : " << BB->getCFIState() << '\n';
535535
if (opts::EnableBAT) {
536-
OS << " Input offset: " << Twine::utohexstr(BB->getInputOffset())
536+
OS << " Input offset: 0x" << Twine::utohexstr(BB->getInputOffset())
537537
<< "\n";
538538
}
539539
if (!BB->pred_empty()) {

bolt/lib/Passes/IndirectCallPromotion.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,15 @@ IndirectCallPromotion::rewriteCall(
754754
const bool IsTailCallOrJT =
755755
(MIB->isTailCall(CallInst) || Function.getJumpTable(CallInst));
756756

757+
// If we are tracking the indirect call/jump address, propagate the address to
758+
// the ICP code.
759+
const std::optional<uint32_t> IndirectInstrOffset = MIB->getOffset(CallInst);
760+
if (IndirectInstrOffset) {
761+
for (auto &[Symbol, Instructions] : ICPcode)
762+
for (MCInst &Inst : Instructions)
763+
MIB->setOffset(Inst, *IndirectInstrOffset);
764+
}
765+
757766
// Move instructions from the tail of the original call block
758767
// to the merge block.
759768

@@ -767,10 +776,12 @@ IndirectCallPromotion::rewriteCall(
767776
TailInsts.push_back(*++TailInst);
768777

769778
InstructionListType MovedInst = IndCallBlock.splitInstructions(&CallInst);
770-
// Link new BBs to the original input offset of the BB where the indirect
771-
// call site is, so we can map samples recorded in new BBs back to the
772-
// original BB seen in the input binary (if using BAT)
773-
const uint32_t OrigOffset = IndCallBlock.getInputOffset();
779+
// Link new BBs to the original input offset of the indirect call site or its
780+
// containing BB, so we can map samples recorded in new BBs back to the
781+
// original BB seen in the input binary (if using BAT).
782+
const uint32_t OrigOffset = IndirectInstrOffset
783+
? *IndirectInstrOffset
784+
: IndCallBlock.getInputOffset();
774785

775786
IndCallBlock.eraseInstructions(MethodFetchInsns.begin(),
776787
MethodFetchInsns.end());

bolt/test/X86/jump-table-icp.test

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ CHECK: Successors: .Ltmp{{.*}} (mispreds: 189, count: 189), .LFT{{.*}} (mispre
3737
CHECK: .LFT{{.*}} (4 instructions, align : 1)
3838
CHECK-NEXT: Exec Count : 881
3939
CHECK: Predecessors: .LBB{{.*}}
40-
CHECK: Successors: .Ltmp{{.*}} (mispreds: 138, count: 155), .Ltmp{{.*}} (mispreds: 0, count: 726)
40+
CHECK: je {{.*}} # Offset: 28
41+
CHECK-NEXT: Successors: .Ltmp{{.*}} (mispreds: 138, count: 155), .Ltmp{{.*}} (mispreds: 0, count: 726)
4142

4243
CHECK: .Ltmp{{.*}} (1 instructions, align : 1)
4344
CHECK-NEXT: Exec Count : 726
4445
CHECK: Predecessors: .LFT{{.*}}
45-
CHECK: Successors: .L{{.*}} (mispreds: 126, count: 157), .L{{.*}} (mispreds: 140, count: 156), .L{{.*}} (mispreds: 134, count: 152), .L{{.*}} (mispreds: 137, count: 150), .L{{.*}} (mispreds: 129, count: 148), .L{{.*}} (mispreds: 0, count: 0)
46+
CHECK: jmpq {{.*}} # Offset: 28
47+
CHECK-NEXT: Successors: .L{{.*}} (mispreds: 126, count: 157), .L{{.*}} (mispreds: 140, count: 156), .L{{.*}} (mispreds: 134, count: 152), .L{{.*}} (mispreds: 137, count: 150), .L{{.*}} (mispreds: 129, count: 148), .L{{.*}} (mispreds: 0, count: 0)
4648

4749
CHECK: .Ltmp{{.*}} (5 instructions, align : 1)
4850
CHECK-NEXT: Exec Count : 167

0 commit comments

Comments
 (0)