[llvm] [BOLT][AArch64]support `inline-small-functions` for AArch64 (PR #120187)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Dec 17 00:43:35 PST 2024
https://github.com/liusy58 updated https://github.com/llvm/llvm-project/pull/120187
>From efce59a824c41a35360462ea5ff4dc137d0026d5 Mon Sep 17 00:00:00 2001
From: liusy58 <liusy58 at linux.alibaba.com>
Date: Thu, 12 Dec 2024 19:33:36 +0800
Subject: [PATCH] [BOLT][AArch64] support inline-small-functions for AArch64
---
bolt/lib/Passes/Inliner.cpp | 4 +-
.../Target/AArch64/AArch64MCPlusBuilder.cpp | 28 ++++++++++
bolt/test/AArch64/inline-small-function-1.s | 47 ++++++++++++++++
bolt/test/AArch64/inline-small-function-2.s | 53 +++++++++++++++++++
4 files changed, 130 insertions(+), 2 deletions(-)
create mode 100644 bolt/test/AArch64/inline-small-function-1.s
create mode 100644 bolt/test/AArch64/inline-small-function-2.s
diff --git a/bolt/lib/Passes/Inliner.cpp b/bolt/lib/Passes/Inliner.cpp
index f004a8eeea185b..1793f4ff1f1480 100644
--- a/bolt/lib/Passes/Inliner.cpp
+++ b/bolt/lib/Passes/Inliner.cpp
@@ -310,13 +310,13 @@ Inliner::inlineCall(BinaryBasicBlock &CallerBB,
if (MIB.isPseudo(Inst))
continue;
- MIB.stripAnnotations(Inst, /*KeepTC=*/BC.isX86());
+ MIB.stripAnnotations(Inst, /*KeepTC=*/BC.isX86() || BC.isAArch64());
// Fix branch target. Strictly speaking, we don't have to do this as
// targets of direct branches will be fixed later and don't matter
// in the CFG state. However, disassembly may look misleading, and
// hence we do the fixing.
- if (MIB.isBranch(Inst)) {
+ if (MIB.isBranch(Inst) && !MIB.isTailCall(Inst)) {
assert(!MIB.isIndirectBranch(Inst) &&
"unexpected indirect branch in callee");
const BinaryBasicBlock *TargetBB =
diff --git a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
index 7e08e5c81d26ff..0722b8ae0cb2c9 100644
--- a/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
+++ b/bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
@@ -133,6 +133,34 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
public:
using MCPlusBuilder::MCPlusBuilder;
+ MCPhysReg getStackPointer() const override { return AArch64::SP; }
+
+ bool isPush(const MCInst &Inst) const override { return false; }
+
+ bool isPop(const MCInst &Inst) const override { return false; }
+
+ void createCall(MCInst &Inst, const MCSymbol *Target,
+ MCContext *Ctx) override {
+ createDirectCall(Inst, Target, Ctx, false);
+ }
+
+ bool convertTailCallToCall(MCInst &Inst) override {
+ int NewOpcode;
+ switch (Inst.getOpcode()) {
+ default:
+ return false;
+ case AArch64::B:
+ NewOpcode = AArch64::BL;
+ break;
+ case AArch64::BR:
+ NewOpcode = AArch64::BLR;
+ break;
+ }
+ Inst.setOpcode(NewOpcode);
+ removeAnnotation(Inst, MCPlus::MCAnnotation::kTailCall);
+ return true;
+ }
+
bool equals(const MCTargetExpr &A, const MCTargetExpr &B,
CompFuncTy Comp) const override {
const auto &AArch64ExprA = cast<AArch64MCExpr>(A);
diff --git a/bolt/test/AArch64/inline-small-function-1.s b/bolt/test/AArch64/inline-small-function-1.s
new file mode 100644
index 00000000000000..80d86962257fc2
--- /dev/null
+++ b/bolt/test/AArch64/inline-small-function-1.s
@@ -0,0 +1,47 @@
+## This test checks that inline is properly handled by BOLT on aarch64.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-linux-gnu %s -o %t.o
+# RUN: %clang --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --inline-small-functions --print-inline --print-only=_Z3barP1A -debug-only=bolt-inliner %t.exe -o %t.bolt | FileCheck %s
+
+# CHECK: BOLT-INFO: inlined 0 calls at 1 call sites in 2 iteration(s). Change in binary size: 4 bytes.
+# CHECK: Binary Function "_Z3barP1A" after inlining {
+# CHECK-NOT: bl _Z3fooP1A
+# CHECK: ldr x8, [x0]
+# CHECK-NEXT: ldr w0, [x8]
+
+ .text
+ .globl _Z3fooP1A
+ .type _Z3fooP1A, at function
+_Z3fooP1A:
+ ldr x8, [x0]
+ ldr w0, [x8]
+ ret
+.Lfunc_end0:
+ .size _Z3fooP1A, .Lfunc_end0-_Z3fooP1A
+
+ .globl _Z3barP1A
+ .type _Z3barP1A, at function
+_Z3barP1A:
+ stp x29, x30, [sp, #-16]!
+ mov x29, sp
+ bl _Z3fooP1A
+ mul w0, w0, w0
+ ldp x29, x30, [sp], #16
+ ret
+.Lfunc_end1:
+ .size _Z3barP1A, .Lfunc_end1-_Z3barP1A
+
+ .globl main
+ .p2align 2
+ .type main, at function
+main:
+ mov w0, wzr
+ ret
+.Lfunc_end2:
+ .size main, .Lfunc_end2-main
+
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
\ No newline at end of file
diff --git a/bolt/test/AArch64/inline-small-function-2.s b/bolt/test/AArch64/inline-small-function-2.s
new file mode 100644
index 00000000000000..22cd8f10927f77
--- /dev/null
+++ b/bolt/test/AArch64/inline-small-function-2.s
@@ -0,0 +1,53 @@
+## This test checks that inline is properly handled by BOLT on aarch64.
+
+# REQUIRES: system-linux
+
+# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-linux-gnu %s -o %t.o
+# RUN: %clang --target=aarch64-unknown-linux %t.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt --inline-small-functions --print-inline --print-only=test \
+# RUN: %t.exe -o %t.bolt | FileCheck %s
+
+#CHECK: BOLT-INFO: inlined 0 calls at 1 call sites in 2 iteration(s). Change in binary size: 4 bytes.
+#CHECK: Binary Function "test" after inlining {
+#CHECK-NOT: bl indirect
+#CHECK: add w0, w1, w0
+#CHECK-NEXT: blr x2
+
+ .text
+ .globl indirect
+ .type indirect, at function
+indirect:
+ add w0, w1, w0
+ br x2
+.Lfunc_end0:
+ .size indirect, .Lfunc_end0-indirect
+
+ .globl test
+ .type test, at function
+test:
+ stp x29, x30, [sp, #-32]!
+ stp x20, x19, [sp, #16]
+ mov x29, sp
+ mov w19, w1
+ mov w20, w0
+ bl indirect
+ add w8, w19, w20
+ cmp w0, #0
+ csinc w0, w8, wzr, eq
+ ldp x20, x19, [sp, #16]
+ ldp x29, x30, [sp], #32
+ ret
+.Lfunc_end1:
+ .size test, .Lfunc_end1-test
+
+ .globl main
+ .type main, at function
+main:
+ mov w0, wzr
+ ret
+.Lfunc_end2:
+ .size main, .Lfunc_end2-main
+
+ .section ".note.GNU-stack","", at progbits
+ .addrsig
+
\ No newline at end of file
More information about the llvm-commits
mailing list