Skip to content

Commit 35ba613

Browse files
committed
[BOLT][AArch64] Speedup computeInstructionSize (llvm#121106)
AArch64 instructions have a fixed size 4 bytes, no need to compute.
1 parent e83e0c3 commit 35ba613

File tree

6 files changed

+127
-0
lines changed

6 files changed

+127
-0
lines changed

bolt/include/bolt/Core/BinaryContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,6 +1363,12 @@ class BinaryContext {
13631363
if (std::optional<uint32_t> Size = MIB->getSize(Inst))
13641364
return *Size;
13651365

1366+
if (MIB->isPseudo(Inst))
1367+
return 0;
1368+
1369+
if (std::optional<uint32_t> Size = MIB->getInstructionSize(Inst))
1370+
return *Size;
1371+
13661372
if (!Emitter)
13671373
Emitter = this->MCE.get();
13681374
SmallString<256> Code;

bolt/include/bolt/Core/MCPlusBuilder.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,11 @@ class MCPlusBuilder {
610610

611611
virtual bool isLeave(const MCInst &Inst) const { return false; }
612612

613+
virtual bool hasUseOrDefofSPOrFP(const MCInst &Inst) const {
614+
llvm_unreachable("not implemented");
615+
return false;
616+
}
617+
613618
virtual bool isADRP(const MCInst &Inst) const {
614619
llvm_unreachable("not implemented");
615620
return false;
@@ -1204,6 +1209,11 @@ class MCPlusBuilder {
12041209
/// Get instruction size specified via annotation.
12051210
std::optional<uint32_t> getSize(const MCInst &Inst) const;
12061211

1212+
/// Get target-specific instruction size.
1213+
virtual std::optional<uint32_t> getInstructionSize(const MCInst &Inst) const {
1214+
return std::nullopt;
1215+
}
1216+
12071217
/// Set instruction size.
12081218
void setSize(MCInst &Inst, uint32_t Size) const;
12091219

bolt/lib/Core/BinaryFunction.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1961,6 +1961,59 @@ bool BinaryFunction::postProcessIndirectBranches(
19611961
bool IsEpilogue = llvm::any_of(BB, [&](const MCInst &Instr) {
19621962
return BC.MIB->isLeave(Instr) || BC.MIB->isPop(Instr);
19631963
});
1964+
if (BC.isAArch64()) {
1965+
// Any adr instruction of aarch64 will generate a new entry,
1966+
// Adr instruction cannt afford to do any optimizations
1967+
if (!IsEpilogue && !isMultiEntry()) {
1968+
BinaryBasicBlock::iterator LastDefCFAOffsetInstIter = BB.end();
1969+
// find the last OpDefCfaOffset 0 instruction.
1970+
for (BinaryBasicBlock::iterator Iter = BB.begin(); Iter != BB.end();
1971+
++Iter) {
1972+
if (&*Iter == &Instr) {
1973+
break;
1974+
}
1975+
if (BC.MIB->isCFI(*Iter)) {
1976+
const MCCFIInstruction *CFIInst =
1977+
BB.getParent()->getCFIFor(*Iter);
1978+
if ((CFIInst->getOperation() ==
1979+
MCCFIInstruction::OpDefCfaOffset) &&
1980+
(CFIInst->getOffset() == 0)) {
1981+
LastDefCFAOffsetInstIter = Iter;
1982+
break;
1983+
}
1984+
}
1985+
}
1986+
if (LastDefCFAOffsetInstIter != BB.end()) {
1987+
IsEpilogue = true;
1988+
// make sure there is no instruction manipulating sp between the two
1989+
// instructions
1990+
BinaryBasicBlock::iterator Iter = LastDefCFAOffsetInstIter;
1991+
while (&*Iter != &Instr) {
1992+
if (BC.MIB->hasUseOrDefofSPOrFP(*Iter)) {
1993+
IsEpilogue = false;
1994+
break;
1995+
}
1996+
++Iter;
1997+
}
1998+
}
1999+
}
2000+
2001+
if (!IsEpilogue) {
2002+
IsEpilogue = true;
2003+
BinaryFunction *Func = BB.getFunction();
2004+
for (const BinaryBasicBlock &BinaryBB : *Func) {
2005+
for (const MCInst &Inst : BinaryBB) {
2006+
if (BC.MIB->hasUseOrDefofSPOrFP(Inst)) {
2007+
IsEpilogue = false;
2008+
break;
2009+
}
2010+
}
2011+
if (!IsEpilogue) {
2012+
break;
2013+
}
2014+
}
2015+
}
2016+
}
19642017
if (IsEpilogue) {
19652018
BC.MIB->convertJmpToTailCall(Instr);
19662019
BB.removeAllSuccessors();

bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,21 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
17921792
}
17931793

17941794
uint16_t getMinFunctionAlignment() const override { return 4; }
1795+
1796+
std::optional<uint32_t>
1797+
getInstructionSize(const MCInst &Inst) const override {
1798+
return 4;
1799+
}
1800+
1801+
bool hasUseOrDefofSPOrFP(const MCInst &Inst) const override {
1802+
if (isPseudo(Inst) || isNoop(Inst) || isCFI(Inst)) {
1803+
return false;
1804+
}
1805+
return hasDefOfPhysReg(Inst, AArch64::SP) ||
1806+
hasUseOfPhysReg(Inst, AArch64::SP) ||
1807+
hasDefOfPhysReg(Inst, AArch64::FP) ||
1808+
hasUseOfPhysReg(Inst, AArch64::FP);
1809+
}
17951810
};
17961811

17971812
} // end anonymous namespace

bolt/lib/Target/X86/X86MCPlusBuilder.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,17 @@ class X86MCPlusBuilder : public MCPlusBuilder {
8989
public:
9090
using MCPlusBuilder::MCPlusBuilder;
9191

92+
virtual bool hasUseOrDefofSPOrFP(const MCInst &Inst) const override {
93+
bool IsLoad, IsStore, IsStoreFromReg, IsSimple, IsIndexed;
94+
MCPhysReg Reg;
95+
int32_t SrcImm;
96+
uint16_t StackPtrReg;
97+
int64_t StackOffset;
98+
uint8_t Size;
99+
return isStackAccess(Inst, IsLoad, IsStore, IsStoreFromReg, Reg, SrcImm,
100+
StackPtrReg, StackOffset, Size, IsSimple, IsIndexed);
101+
}
102+
92103
std::unique_ptr<MCSymbolizer>
93104
createTargetSymbolizer(BinaryFunction &Function,
94105
bool CreateNewSymbols) const override {
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## This test checks that inline is properly handled by BOLT on aarch64.
2+
3+
# REQUIRES: system-linux
4+
5+
# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o
6+
# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q
7+
# RUN: /mnt/nvme0n1/lsy/development_bolt/alibaba-llvm-project-build/bin/llvm-bolt --print-all --print-only=indirect \
8+
# RUN: %t.exe -o %t.bolt | FileCheck %s
9+
10+
#CHECK: Binary Function "indirect" after building cfg {
11+
#CHECK-NOT: # UNKNOWN CONTROL FLOW
12+
#CHECK: End of Function "indirect"
13+
.text
14+
.globl indirect
15+
.type indirect,@function
16+
indirect:
17+
cbz x0, .LBB0_2
18+
ldr x8, [x0]
19+
ldr x1, [x8]
20+
br x1
21+
.LBB0_2:
22+
mov w0, #3
23+
ret
24+
.size indirect, .-indirect
25+
26+
27+
.globl main
28+
.type main,@function
29+
main:
30+
mov w0, wzr
31+
ret
32+
.size main, .-main

0 commit comments

Comments
 (0)