[llvm] [RISCV] Implement trampolines for rv64 (PR #96309)
Roger Ferrer Ibáñez via llvm-commits
llvm-commits at lists.llvm.org
Wed Oct 16 22:54:38 PDT 2024
https://github.com/rofirrim updated https://github.com/llvm/llvm-project/pull/96309
>From 94f41940733e8387d6e1528d60ff0479337e152a Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Thu, 20 Jun 2024 06:49:11 +0000
Subject: [PATCH 01/14] [RISCV] Implement trampolines for rv64
This is implementation is heavily based on what the X86 target does but
emitting the instructions that GCC emits for rv64.
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 126 ++++++++++++++++++++
llvm/lib/Target/RISCV/RISCVISelLowering.h | 3 +
llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 80 +++++++++++++
3 files changed, 209 insertions(+)
create mode 100644 llvm/test/CodeGen/RISCV/rv64-trampoline.ll
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 14249e34921ee1..d8078773722475 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -625,6 +625,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,
setOperationAction(ISD::READSTEADYCOUNTER, MVT::i64,
Subtarget.is64Bit() ? Legal : Custom);
+ if (Subtarget.is64Bit()) {
+ setOperationAction(ISD::INIT_TRAMPOLINE, MVT::Other, Custom);
+ setOperationAction(ISD::ADJUST_TRAMPOLINE, MVT::Other, Custom);
+ }
+
setOperationAction({ISD::TRAP, ISD::DEBUGTRAP}, MVT::Other, Legal);
setOperationAction(ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
if (Subtarget.is64Bit())
@@ -7400,6 +7405,10 @@ SDValue RISCVTargetLowering::LowerOperation(SDValue Op,
return emitFlushICache(DAG, Op.getOperand(0), Op.getOperand(1),
Op.getOperand(2), Flags, DL);
}
+ case ISD::INIT_TRAMPOLINE:
+ return lowerINIT_TRAMPOLINE(Op, DAG);
+ case ISD::ADJUST_TRAMPOLINE:
+ return lowerADJUST_TRAMPOLINE(Op, DAG);
}
}
@@ -7415,6 +7424,123 @@ SDValue RISCVTargetLowering::emitFlushICache(SelectionDAG &DAG, SDValue InChain,
return CallResult.second;
}
+SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
+ SelectionDAG &DAG) const {
+ if (!Subtarget.is64Bit())
+ llvm::report_fatal_error("Trampolines only implemented for RV64");
+
+ SDValue Root = Op.getOperand(0);
+ SDValue Trmp = Op.getOperand(1); // trampoline
+ SDLoc dl(Op);
+
+ const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
+
+ // We store in the trampoline buffer the following instructions and data.
+ // Offset:
+ // 0: auipc t2, 0
+ // 4: ld t0, 24(t2)
+ // 8: ld t2, 16(t2)
+ // 12: jalr t0
+ // 16: <StaticChainOffset>
+ // 24: <FunctionAddressOffset>
+ // 32:
+
+ // Constants shamelessly taken from GCC.
+ constexpr unsigned Opcode_AUIPC = 0x17;
+ constexpr unsigned Opcode_LD = 0x3003;
+ constexpr unsigned Opcode_JALR = 0x67;
+ constexpr unsigned ShiftField_RD = 7;
+ constexpr unsigned ShiftField_RS1 = 15;
+ constexpr unsigned ShiftField_IMM = 20;
+ constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function)
+ constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain)
+
+ constexpr unsigned StaticChainOffset = 16;
+ constexpr unsigned FunctionAddressOffset = 24;
+
+ SDValue OutChains[6];
+ SDValue Addr = Trmp;
+
+ // auipc t2, 0
+ // Loads the current PC into t2.
+ constexpr uint32_t AUIPC_X7_0 =
+ Opcode_AUIPC | (Reg_X7 << ShiftField_RD);
+ OutChains[0] =
+ DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
+
+ // ld t0, 24(t2)
+ // Loads the function address into t0. Note that we are using offsets
+ // pc-relative to the first instruction of the trampoline.
+ const uint32_t LD_X5_TargetFunctionOffset =
+ Opcode_LD | (Reg_X5 << ShiftField_RD) |
+ (Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM);
+ Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(4, dl, MVT::i64));
+ OutChains[1] = DAG.getTruncStore(
+ Root, dl,
+ DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr,
+ MachinePointerInfo(TrmpAddr, 4), MVT::i32);
+
+ // ld t2, 16(t2)
+ // Load the value of the static chain.
+ const uint32_t LD_X7_StaticChainOffset =
+ Opcode_LD | (Reg_X7 << ShiftField_RD) |
+ (Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM);
+ Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(8, dl, MVT::i64));
+ OutChains[2] = DAG.getTruncStore(
+ Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32);
+
+ // jalr t0
+ // Jump to the function.
+ const uint32_t JALR_X5 =
+ Opcode_JALR | (Reg_X5 << ShiftField_RS1);
+ Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(12, dl, MVT::i64));
+ OutChains[3] =
+ DAG.getTruncStore(Root, dl, DAG.getConstant(JALR_X5, dl, MVT::i64), Addr,
+ MachinePointerInfo(TrmpAddr, 12), MVT::i32);
+
+ // Now store the variable part of the trampoline.
+ SDValue FunctionAddress = Op.getOperand(2);
+ SDValue StaticChain = Op.getOperand(3);
+
+ // Store the given static chain in the trampoline buffer.
+ Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(StaticChainOffset, dl, MVT::i64));
+ OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr,
+ MachinePointerInfo(TrmpAddr, StaticChainOffset));
+
+ // Store the given function address in the trampoline buffer.
+ Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(FunctionAddressOffset, dl, MVT::i64));
+ OutChains[5] =
+ DAG.getStore(Root, dl, FunctionAddress, Addr,
+ MachinePointerInfo(TrmpAddr, FunctionAddressOffset));
+
+ SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
+
+ // Compute end of trampoline.
+ SDValue EndOfTrmp = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(32, dl, MVT::i64));
+
+ // Call clear cache on the trampoline buffer.
+ SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken,
+ Trmp, EndOfTrmp);
+
+ return Chain;
+}
+
+SDValue RISCVTargetLowering::lowerADJUST_TRAMPOLINE(SDValue Op,
+ SelectionDAG &DAG) const {
+ if (!Subtarget.is64Bit())
+ llvm::report_fatal_error("Trampolines only implemented for RV64");
+
+ return Op.getOperand(0);
+}
+
static SDValue getTargetNode(GlobalAddressSDNode *N, const SDLoc &DL, EVT Ty,
SelectionDAG &DAG, unsigned Flags) {
return DAG.getTargetGlobalAddress(N->getGlobal(), DL, Ty, 0, Flags);
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.h b/llvm/lib/Target/RISCV/RISCVISelLowering.h
index 3864d58a129e98..c3749447955330 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.h
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.h
@@ -992,6 +992,9 @@ class RISCVTargetLowering : public TargetLowering {
SDValue expandUnalignedRVVLoad(SDValue Op, SelectionDAG &DAG) const;
SDValue expandUnalignedRVVStore(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
+ SDValue lowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
+
bool isEligibleForTailCallOptimization(
CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
const SmallVector<CCValAssign, 16> &ArgLocs) const;
diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
new file mode 100644
index 00000000000000..4a7a50fc09bf89
--- /dev/null
+++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
@@ -0,0 +1,80 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64 %s
+; RUN: llc -mtriple=riscv64-unknown-linux-gnu -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64-LINUX %s
+
+declare void @llvm.init.trampoline(ptr, ptr, ptr)
+declare ptr @llvm.adjust.trampoline(ptr)
+declare i64 @f(ptr nest, i64)
+
+define i64 @test0(i64 %n, ptr %p) nounwind {
+; RV64-LABEL: test0:
+; RV64: # %bb.0:
+; RV64-NEXT: addi sp, sp, -64
+; RV64-NEXT: sd ra, 56(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd s0, 48(sp) # 8-byte Folded Spill
+; RV64-NEXT: sd s1, 40(sp) # 8-byte Folded Spill
+; RV64-NEXT: mv s0, a0
+; RV64-NEXT: lui a0, %hi(.LCPI0_0)
+; RV64-NEXT: ld a0, %lo(.LCPI0_0)(a0)
+; RV64-NEXT: lui a2, %hi(f)
+; RV64-NEXT: addi a2, a2, %lo(f)
+; RV64-NEXT: sd a2, 32(sp)
+; RV64-NEXT: sd a1, 24(sp)
+; RV64-NEXT: sd a0, 16(sp)
+; RV64-NEXT: lui a0, 6203
+; RV64-NEXT: addi a0, a0, 643
+; RV64-NEXT: slli a0, a0, 32
+; RV64-NEXT: addi a0, a0, 919
+; RV64-NEXT: sd a0, 8(sp)
+; RV64-NEXT: addi a1, sp, 40
+; RV64-NEXT: addi a0, sp, 8
+; RV64-NEXT: addi s1, sp, 8
+; RV64-NEXT: call __clear_cache
+; RV64-NEXT: mv a0, s0
+; RV64-NEXT: jalr s1
+; RV64-NEXT: ld ra, 56(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld s0, 48(sp) # 8-byte Folded Reload
+; RV64-NEXT: ld s1, 40(sp) # 8-byte Folded Reload
+; RV64-NEXT: addi sp, sp, 64
+; RV64-NEXT: ret
+;
+; RV64-LINUX-LABEL: test0:
+; RV64-LINUX: # %bb.0:
+; RV64-LINUX-NEXT: addi sp, sp, -64
+; RV64-LINUX-NEXT: sd ra, 56(sp) # 8-byte Folded Spill
+; RV64-LINUX-NEXT: sd s0, 48(sp) # 8-byte Folded Spill
+; RV64-LINUX-NEXT: sd s1, 40(sp) # 8-byte Folded Spill
+; RV64-LINUX-NEXT: mv s0, a0
+; RV64-LINUX-NEXT: lui a0, %hi(.LCPI0_0)
+; RV64-LINUX-NEXT: ld a0, %lo(.LCPI0_0)(a0)
+; RV64-LINUX-NEXT: lui a2, %hi(f)
+; RV64-LINUX-NEXT: addi a2, a2, %lo(f)
+; RV64-LINUX-NEXT: sd a2, 32(sp)
+; RV64-LINUX-NEXT: sd a1, 24(sp)
+; RV64-LINUX-NEXT: sd a0, 16(sp)
+; RV64-LINUX-NEXT: lui a0, 6203
+; RV64-LINUX-NEXT: addi a0, a0, 643
+; RV64-LINUX-NEXT: slli a0, a0, 32
+; RV64-LINUX-NEXT: addi a0, a0, 919
+; RV64-LINUX-NEXT: sd a0, 8(sp)
+; RV64-LINUX-NEXT: addi a1, sp, 40
+; RV64-LINUX-NEXT: addi a0, sp, 8
+; RV64-LINUX-NEXT: addi s1, sp, 8
+; RV64-LINUX-NEXT: li a2, 0
+; RV64-LINUX-NEXT: call __riscv_flush_icache
+; RV64-LINUX-NEXT: mv a0, s0
+; RV64-LINUX-NEXT: jalr s1
+; RV64-LINUX-NEXT: ld ra, 56(sp) # 8-byte Folded Reload
+; RV64-LINUX-NEXT: ld s0, 48(sp) # 8-byte Folded Reload
+; RV64-LINUX-NEXT: ld s1, 40(sp) # 8-byte Folded Reload
+; RV64-LINUX-NEXT: addi sp, sp, 64
+; RV64-LINUX-NEXT: ret
+ %alloca = alloca [32 x i8], align 8
+ call void @llvm.init.trampoline(ptr %alloca, ptr @f, ptr %p)
+ %tramp = call ptr @llvm.adjust.trampoline(ptr %alloca)
+ %ret = call i64 %tramp(i64 %n)
+ ret i64 %ret
+
+}
>From 3e3d9fc94ad5cb055c3384aec7edfea93309ca0f Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 07:27:15 +0000
Subject: [PATCH 02/14] Use MCCodeEmitter to encode instructions rather than
hardcoded constants
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 56 +++++++++++++--------
1 file changed, 36 insertions(+), 20 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index d8078773722475..2294412c6beab2 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -37,6 +37,8 @@
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicsRISCV.h"
#include "llvm/IR/PatternMatch.h"
+#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCInstBuilder.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
@@ -7429,6 +7431,14 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
if (!Subtarget.is64Bit())
llvm::report_fatal_error("Trampolines only implemented for RV64");
+ // Create an MCCodeEmitter to encode instructions.
+ TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering();
+ assert(TLO);
+ MCContext& MCCtx = TLO->getContext();
+
+ std::unique_ptr<MCCodeEmitter> CodeEmitter(
+ createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
+
SDValue Root = Op.getOperand(0);
SDValue Trmp = Op.getOperand(1); // trampoline
SDLoc dl(Op);
@@ -7445,26 +7455,30 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// 24: <FunctionAddressOffset>
// 32:
- // Constants shamelessly taken from GCC.
- constexpr unsigned Opcode_AUIPC = 0x17;
- constexpr unsigned Opcode_LD = 0x3003;
- constexpr unsigned Opcode_JALR = 0x67;
- constexpr unsigned ShiftField_RD = 7;
- constexpr unsigned ShiftField_RS1 = 15;
- constexpr unsigned ShiftField_IMM = 20;
- constexpr unsigned Reg_X5 = 0x5; // x5/t0 (holds the address to the function)
- constexpr unsigned Reg_X7 = 0x7; // x7/t2 (holds the static chain)
-
constexpr unsigned StaticChainOffset = 16;
constexpr unsigned FunctionAddressOffset = 24;
+ auto GetEncoding = [&](const MCInst &MC) {
+ SmallVector<char, 4> CB;
+ SmallVector<MCFixup> Fixups;
+ const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
+ assert(STI);
+ CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
+ assert(CB.size() == 4);
+ assert(Fixups.empty());
+ uint32_t Encoding = support::endian::read32le(CB.data());
+ return Encoding;
+ };
+
SDValue OutChains[6];
SDValue Addr = Trmp;
// auipc t2, 0
// Loads the current PC into t2.
- constexpr uint32_t AUIPC_X7_0 =
- Opcode_AUIPC | (Reg_X7 << ShiftField_RD);
+ MCInst AUIPC_X7_0_Inst =
+ MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0);
+
+ uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst);
OutChains[0] =
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
@@ -7472,9 +7486,10 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// ld t0, 24(t2)
// Loads the function address into t0. Note that we are using offsets
// pc-relative to the first instruction of the trampoline.
- const uint32_t LD_X5_TargetFunctionOffset =
- Opcode_LD | (Reg_X5 << ShiftField_RD) |
- (Reg_X7 << ShiftField_RS1) | (FunctionAddressOffset << ShiftField_IMM);
+ MCInst LD_X5_TargetFunctionOffset_Inst =
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24);
+ uint32_t LD_X5_TargetFunctionOffset =
+ GetEncoding(LD_X5_TargetFunctionOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(4, dl, MVT::i64));
OutChains[1] = DAG.getTruncStore(
@@ -7484,9 +7499,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// ld t2, 16(t2)
// Load the value of the static chain.
- const uint32_t LD_X7_StaticChainOffset =
- Opcode_LD | (Reg_X7 << ShiftField_RD) |
- (Reg_X7 << ShiftField_RS1) | (StaticChainOffset << ShiftField_IMM);
+ MCInst LD_X7_StaticChainOffset_Inst =
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16);
+ uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(8, dl, MVT::i64));
OutChains[2] = DAG.getTruncStore(
@@ -7495,8 +7510,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// jalr t0
// Jump to the function.
- const uint32_t JALR_X5 =
- Opcode_JALR | (Reg_X5 << ShiftField_RS1);
+ MCInst JALR_X5_Inst =
+ MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0);
+ uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(12, dl, MVT::i64));
OutChains[3] =
>From 5e3ce766892b563ed5014c388ef2280f372b6227 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 07:51:44 +0000
Subject: [PATCH 03/14] Remove stray blank line
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 2294412c6beab2..359a4bbc2538ae 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7477,7 +7477,6 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Loads the current PC into t2.
MCInst AUIPC_X7_0_Inst =
MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0);
-
uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst);
OutChains[0] =
DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
>From 82367f4616173758977aaa73d0138adb14de1b76 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 19 Jul 2024 13:50:52 +0000
Subject: [PATCH 04/14] clang-format
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 359a4bbc2538ae..163df9025386ee 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7434,7 +7434,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Create an MCCodeEmitter to encode instructions.
TargetLoweringObjectFile *TLO = getTargetMachine().getObjFileLowering();
assert(TLO);
- MCContext& MCCtx = TLO->getContext();
+ MCContext &MCCtx = TLO->getContext();
std::unique_ptr<MCCodeEmitter> CodeEmitter(
createRISCVMCCodeEmitter(*getTargetMachine().getMCInstrInfo(), MCCtx));
@@ -7492,8 +7492,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(4, dl, MVT::i64));
OutChains[1] = DAG.getTruncStore(
- Root, dl,
- DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr,
+ Root, dl, DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr,
MachinePointerInfo(TrmpAddr, 4), MVT::i32);
// ld t2, 16(t2)
@@ -7504,8 +7503,8 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(8, dl, MVT::i64));
OutChains[2] = DAG.getTruncStore(
- Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32);
+ Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), Addr,
+ MachinePointerInfo(TrmpAddr, 8), MVT::i32);
// jalr t0
// Jump to the function.
>From 3a76960fe47b3f24af4f48e3e85ee079d73f90d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Roger=20Ferrer=20Ib=C3=A1=C3=B1ez?= <rofirrim at gmail.com>
Date: Tue, 30 Jul 2024 14:46:51 +0200
Subject: [PATCH 05/14] Apply suggestions from code review
Co-authored-by: Pengcheng Wang <wangpengcheng.pp at bytedance.com>
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 163df9025386ee..5f94e47b45d491 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7486,7 +7486,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Loads the function address into t0. Note that we are using offsets
// pc-relative to the first instruction of the trampoline.
MCInst LD_X5_TargetFunctionOffset_Inst =
- MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(24);
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(FunctionAddressOffset);
uint32_t LD_X5_TargetFunctionOffset =
GetEncoding(LD_X5_TargetFunctionOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
@@ -7498,7 +7498,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// ld t2, 16(t2)
// Load the value of the static chain.
MCInst LD_X7_StaticChainOffset_Inst =
- MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(16);
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(StaticChainOffset);
uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(8, dl, MVT::i64));
>From b6f7492ad3e6c838f5d2f28f2387407c8690039b Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Tue, 30 Jul 2024 13:02:27 +0000
Subject: [PATCH 06/14] Avoid awkward variable names
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 49 ++++++++++++---------
1 file changed, 27 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 5f94e47b45d491..574c3a2afb7571 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7475,47 +7475,52 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// auipc t2, 0
// Loads the current PC into t2.
- MCInst AUIPC_X7_0_Inst =
- MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0);
- uint32_t AUIPC_X7_0 = GetEncoding(AUIPC_X7_0_Inst);
- OutChains[0] =
- DAG.getTruncStore(Root, dl, DAG.getConstant(AUIPC_X7_0, dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
+ OutChains[0] = DAG.getTruncStore(
+ Root, dl,
+ DAG.getConstant(
+ GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
+ dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
// ld t0, 24(t2)
// Loads the function address into t0. Note that we are using offsets
// pc-relative to the first instruction of the trampoline.
- MCInst LD_X5_TargetFunctionOffset_Inst =
- MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(FunctionAddressOffset);
- uint32_t LD_X5_TargetFunctionOffset =
- GetEncoding(LD_X5_TargetFunctionOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(4, dl, MVT::i64));
OutChains[1] = DAG.getTruncStore(
- Root, dl, DAG.getConstant(LD_X5_TargetFunctionOffset, dl, MVT::i64), Addr,
- MachinePointerInfo(TrmpAddr, 4), MVT::i32);
+ Root, dl,
+ DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD)
+ .addReg(RISCV::X5)
+ .addReg(RISCV::X7)
+ .addImm(FunctionAddressOffset)),
+ dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr, 4), MVT::i32);
// ld t2, 16(t2)
// Load the value of the static chain.
- MCInst LD_X7_StaticChainOffset_Inst =
- MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(StaticChainOffset);
- uint32_t LD_X7_StaticChainOffset = GetEncoding(LD_X7_StaticChainOffset_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(8, dl, MVT::i64));
OutChains[2] = DAG.getTruncStore(
- Root, dl, DAG.getConstant(LD_X7_StaticChainOffset, dl, MVT::i64), Addr,
- MachinePointerInfo(TrmpAddr, 8), MVT::i32);
+ Root, dl,
+ DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD)
+ .addReg(RISCV::X7)
+ .addReg(RISCV::X7)
+ .addImm(StaticChainOffset)),
+ dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32);
// jalr t0
// Jump to the function.
- MCInst JALR_X5_Inst =
- MCInstBuilder(RISCV::JALR).addReg(RISCV::X0).addReg(RISCV::X5).addImm(0);
- uint32_t JALR_X5 = GetEncoding(JALR_X5_Inst);
Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(12, dl, MVT::i64));
OutChains[3] =
- DAG.getTruncStore(Root, dl, DAG.getConstant(JALR_X5, dl, MVT::i64), Addr,
- MachinePointerInfo(TrmpAddr, 12), MVT::i32);
+ DAG.getTruncStore(Root, dl,
+ DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::JALR)
+ .addReg(RISCV::X0)
+ .addReg(RISCV::X5)
+ .addImm(0)),
+ dl, MVT::i64),
+ Addr, MachinePointerInfo(TrmpAddr, 12), MVT::i32);
// Now store the variable part of the trampoline.
SDValue FunctionAddress = Op.getOperand(2);
>From ca45c156c70b9716afde79ecba7d9816a5c05d1e Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 2 Aug 2024 06:19:50 +0000
Subject: [PATCH 07/14] Reduce the amount of repetition
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 84 ++++++++-------------
1 file changed, 33 insertions(+), 51 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 574c3a2afb7571..0dd853c3d3bd31 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7471,63 +7471,45 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
};
SDValue OutChains[6];
- SDValue Addr = Trmp;
-
- // auipc t2, 0
- // Loads the current PC into t2.
- OutChains[0] = DAG.getTruncStore(
- Root, dl,
- DAG.getConstant(
- GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
- dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr), MVT::i32);
-
- // ld t0, 24(t2)
- // Loads the function address into t0. Note that we are using offsets
- // pc-relative to the first instruction of the trampoline.
- Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(4, dl, MVT::i64));
- OutChains[1] = DAG.getTruncStore(
- Root, dl,
- DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD)
- .addReg(RISCV::X5)
- .addReg(RISCV::X7)
- .addImm(FunctionAddressOffset)),
- dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr, 4), MVT::i32);
-
- // ld t2, 16(t2)
- // Load the value of the static chain.
- Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(8, dl, MVT::i64));
- OutChains[2] = DAG.getTruncStore(
- Root, dl,
- DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::LD)
- .addReg(RISCV::X7)
- .addReg(RISCV::X7)
- .addImm(StaticChainOffset)),
- dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr, 8), MVT::i32);
-
- // jalr t0
- // Jump to the function.
- Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(12, dl, MVT::i64));
- OutChains[3] =
- DAG.getTruncStore(Root, dl,
- DAG.getConstant(GetEncoding(MCInstBuilder(RISCV::JALR)
- .addReg(RISCV::X0)
- .addReg(RISCV::X5)
- .addImm(0)),
- dl, MVT::i64),
- Addr, MachinePointerInfo(TrmpAddr, 12), MVT::i32);
+
+ uint32_t Encodings[] = {
+ // auipc t2, 0
+ // Loads the current PC into t2.
+ GetEncoding(MCInstBuilder(RISCV::AUIPC).addReg(RISCV::X7).addImm(0)),
+ // ld t0, 24(t2)
+ // Loads the function address into t0. Note that we are using offsets
+ // pc-relative to the first instruction of the trampoline.
+ GetEncoding(
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X5).addReg(RISCV::X7).addImm(
+ FunctionAddressOffset)),
+ // ld t2, 16(t2)
+ // Load the value of the static chain.
+ GetEncoding(
+ MCInstBuilder(RISCV::LD).addReg(RISCV::X7).addReg(RISCV::X7).addImm(
+ StaticChainOffset)),
+ // jalr t0
+ // Jump to the function.
+ GetEncoding(MCInstBuilder(RISCV::JALR)
+ .addReg(RISCV::X0)
+ .addReg(RISCV::X5)
+ .addImm(0))};
+
+ // Store encoded instructions.
+ for (auto [Idx, Encoding] : llvm::enumerate(Encodings)) {
+ SDValue Addr = Idx > 0 ? DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(Idx * 4, dl, MVT::i64))
+ : Trmp;
+ OutChains[Idx] = DAG.getTruncStore(
+ Root, dl, DAG.getConstant(Encoding, dl, MVT::i64), Addr,
+ MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32);
+ }
// Now store the variable part of the trampoline.
SDValue FunctionAddress = Op.getOperand(2);
SDValue StaticChain = Op.getOperand(3);
// Store the given static chain in the trampoline buffer.
- Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(StaticChainOffset, dl, MVT::i64));
OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr,
MachinePointerInfo(TrmpAddr, StaticChainOffset));
>From 215597bfcf0f91a793874858163a586ba83e844e Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Fri, 2 Aug 2024 10:20:26 +0000
Subject: [PATCH 08/14] clang-format
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 0dd853c3d3bd31..5b5f39e9139ea9 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7497,8 +7497,8 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Store encoded instructions.
for (auto [Idx, Encoding] : llvm::enumerate(Encodings)) {
SDValue Addr = Idx > 0 ? DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(Idx * 4, dl, MVT::i64))
- : Trmp;
+ DAG.getConstant(Idx * 4, dl, MVT::i64))
+ : Trmp;
OutChains[Idx] = DAG.getTruncStore(
Root, dl, DAG.getConstant(Encoding, dl, MVT::i64), Addr,
MachinePointerInfo(TrmpAddr, Idx * 4), MVT::i32);
@@ -7510,7 +7510,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Store the given static chain in the trampoline buffer.
SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(StaticChainOffset, dl, MVT::i64));
+ DAG.getConstant(StaticChainOffset, dl, MVT::i64));
OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr,
MachinePointerInfo(TrmpAddr, StaticChainOffset));
>From 9a0c0bbad33017ebd0f771d0b4a2d4ca681fd916 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:17:29 +0200
Subject: [PATCH 09/14] Remove assertions
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 5b5f39e9139ea9..c131d21d7d1691 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7464,8 +7464,6 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
assert(STI);
CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
- assert(CB.size() == 4);
- assert(Fixups.empty());
uint32_t Encoding = support::endian::read32le(CB.data());
return Encoding;
};
>From 63d0daa1c16dbb9f23ebdbcf469277ba9af7781c Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:19:56 +0200
Subject: [PATCH 10/14] Hoist initialisation
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index c131d21d7d1691..1b563b70d12129 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7458,11 +7458,11 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
constexpr unsigned StaticChainOffset = 16;
constexpr unsigned FunctionAddressOffset = 24;
+ const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
+ assert(STI);
auto GetEncoding = [&](const MCInst &MC) {
SmallVector<char, 4> CB;
SmallVector<MCFixup> Fixups;
- const MCSubtargetInfo *STI = getTargetMachine().getMCSubtargetInfo();
- assert(STI);
CodeEmitter->encodeInstruction(MC, CB, Fixups, *STI);
uint32_t Encoding = support::endian::read32le(CB.data());
return Encoding;
>From 6d65d1bc8cc53ad87e73795ddda758bed1a517ca Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:26:00 +0200
Subject: [PATCH 11/14] Only flush the part of the trampoline buffer containing
instructions
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 +++++----
llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 4 ++--
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1b563b70d12129..1f25c10d9a0186 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7521,11 +7521,12 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
- // Compute end of trampoline.
- SDValue EndOfTrmp = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(32, dl, MVT::i64));
+ // Compute end of instructions of trampoline.
+ SDValue EndOfTrmp =
+ DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(StaticChainOffset, dl, MVT::i64));
- // Call clear cache on the trampoline buffer.
+ // Call clear cache on the trampoline instructions.
SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken,
Trmp, EndOfTrmp);
diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
index 4a7a50fc09bf89..1ddc5fb159777f 100644
--- a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
+++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
@@ -28,7 +28,7 @@ define i64 @test0(i64 %n, ptr %p) nounwind {
; RV64-NEXT: slli a0, a0, 32
; RV64-NEXT: addi a0, a0, 919
; RV64-NEXT: sd a0, 8(sp)
-; RV64-NEXT: addi a1, sp, 40
+; RV64-NEXT: addi a1, sp, 24
; RV64-NEXT: addi a0, sp, 8
; RV64-NEXT: addi s1, sp, 8
; RV64-NEXT: call __clear_cache
@@ -59,7 +59,7 @@ define i64 @test0(i64 %n, ptr %p) nounwind {
; RV64-LINUX-NEXT: slli a0, a0, 32
; RV64-LINUX-NEXT: addi a0, a0, 919
; RV64-LINUX-NEXT: sd a0, 8(sp)
-; RV64-LINUX-NEXT: addi a1, sp, 40
+; RV64-LINUX-NEXT: addi a1, sp, 24
; RV64-LINUX-NEXT: addi a0, sp, 8
; RV64-LINUX-NEXT: addi s1, sp, 8
; RV64-LINUX-NEXT: li a2, 0
>From 3a73d1c6645f26e27712cd290397c56ec5ffb410 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:39:49 +0200
Subject: [PATCH 12/14] Reduce the amount of repetition
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 28 ++++++++++++---------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 1f25c10d9a0186..98063e28bca9cf 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7506,18 +7506,22 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
SDValue FunctionAddress = Op.getOperand(2);
SDValue StaticChain = Op.getOperand(3);
- // Store the given static chain in the trampoline buffer.
- SDValue Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(StaticChainOffset, dl, MVT::i64));
- OutChains[4] = DAG.getStore(Root, dl, StaticChain, Addr,
- MachinePointerInfo(TrmpAddr, StaticChainOffset));
-
- // Store the given function address in the trampoline buffer.
- Addr = DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(FunctionAddressOffset, dl, MVT::i64));
- OutChains[5] =
- DAG.getStore(Root, dl, FunctionAddress, Addr,
- MachinePointerInfo(TrmpAddr, FunctionAddressOffset));
+ // Store the given static chain and function pointer in the trampoline buffer.
+ struct OffsetValuePair {
+ unsigned Offset;
+ SDValue Value;
+ } OffsetValues[] = {
+ {StaticChainOffset, StaticChain},
+ {FunctionAddressOffset, FunctionAddress},
+ };
+ for (auto [Idx, OffsetValue] : llvm::enumerate(OffsetValues)) {
+ SDValue Addr =
+ DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
+ DAG.getConstant(OffsetValue.Offset, dl, MVT::i64));
+ OutChains[Idx + 4] =
+ DAG.getStore(Root, dl, OffsetValue.Value, Addr,
+ MachinePointerInfo(TrmpAddr, OffsetValue.Offset));
+ }
SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
>From 54248d56214bd7806ec0407c6408a0020a44e1b3 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <rofirrim at gmail.com>
Date: Tue, 6 Aug 2024 08:44:09 +0200
Subject: [PATCH 13/14] Remove some more repetition
---
llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 98063e28bca9cf..ad1244c4d5a66b 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -7508,8 +7508,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
// Store the given static chain and function pointer in the trampoline buffer.
struct OffsetValuePair {
- unsigned Offset;
- SDValue Value;
+ const unsigned Offset;
+ const SDValue Value;
+ SDValue Addr = SDValue(); // Used to cache the address.
} OffsetValues[] = {
{StaticChainOffset, StaticChain},
{FunctionAddressOffset, FunctionAddress},
@@ -7518,6 +7519,7 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
SDValue Addr =
DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
DAG.getConstant(OffsetValue.Offset, dl, MVT::i64));
+ OffsetValue.Addr = Addr;
OutChains[Idx + 4] =
DAG.getStore(Root, dl, OffsetValue.Value, Addr,
MachinePointerInfo(TrmpAddr, OffsetValue.Offset));
@@ -7525,10 +7527,9 @@ SDValue RISCVTargetLowering::lowerINIT_TRAMPOLINE(SDValue Op,
SDValue StoreToken = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, OutChains);
- // Compute end of instructions of trampoline.
- SDValue EndOfTrmp =
- DAG.getNode(ISD::ADD, dl, MVT::i64, Trmp,
- DAG.getConstant(StaticChainOffset, dl, MVT::i64));
+ // The end of instructions of trampoline is the same as the static chain
+ // address that we computed earlier.
+ SDValue EndOfTrmp = OffsetValues[0].Addr;
// Call clear cache on the trampoline instructions.
SDValue Chain = DAG.getNode(ISD::CLEAR_CACHE, dl, MVT::Other, StoreToken,
>From acb1e6b69765101c536d29c3fca55c35dfc9b971 Mon Sep 17 00:00:00 2001
From: Roger Ferrer Ibanez <roger.ferrer at bsc.es>
Date: Thu, 17 Oct 2024 05:48:28 +0000
Subject: [PATCH 14/14] Update test
Codegen used to coalesce the stores into a single sd. Now it emits
two sw.
---
llvm/test/CodeGen/RISCV/rv64-trampoline.ll | 44 +++++++++++-----------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
index 1ddc5fb159777f..ba184063265098 100644
--- a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
+++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll
@@ -16,18 +16,18 @@ define i64 @test0(i64 %n, ptr %p) nounwind {
; RV64-NEXT: sd s0, 48(sp) # 8-byte Folded Spill
; RV64-NEXT: sd s1, 40(sp) # 8-byte Folded Spill
; RV64-NEXT: mv s0, a0
-; RV64-NEXT: lui a0, %hi(.LCPI0_0)
-; RV64-NEXT: ld a0, %lo(.LCPI0_0)(a0)
-; RV64-NEXT: lui a2, %hi(f)
-; RV64-NEXT: addi a2, a2, %lo(f)
-; RV64-NEXT: sd a2, 32(sp)
+; RV64-NEXT: lui a0, %hi(f)
+; RV64-NEXT: addi a0, a0, %lo(f)
+; RV64-NEXT: sd a0, 32(sp)
+; RV64-NEXT: li a0, 919
+; RV64-NEXT: lui a2, %hi(.LCPI0_0)
+; RV64-NEXT: ld a2, %lo(.LCPI0_0)(a2)
+; RV64-NEXT: lui a3, 6203
+; RV64-NEXT: addi a3, a3, 643
+; RV64-NEXT: sw a0, 8(sp)
+; RV64-NEXT: sw a3, 12(sp)
+; RV64-NEXT: sd a2, 16(sp)
; RV64-NEXT: sd a1, 24(sp)
-; RV64-NEXT: sd a0, 16(sp)
-; RV64-NEXT: lui a0, 6203
-; RV64-NEXT: addi a0, a0, 643
-; RV64-NEXT: slli a0, a0, 32
-; RV64-NEXT: addi a0, a0, 919
-; RV64-NEXT: sd a0, 8(sp)
; RV64-NEXT: addi a1, sp, 24
; RV64-NEXT: addi a0, sp, 8
; RV64-NEXT: addi s1, sp, 8
@@ -47,18 +47,18 @@ define i64 @test0(i64 %n, ptr %p) nounwind {
; RV64-LINUX-NEXT: sd s0, 48(sp) # 8-byte Folded Spill
; RV64-LINUX-NEXT: sd s1, 40(sp) # 8-byte Folded Spill
; RV64-LINUX-NEXT: mv s0, a0
-; RV64-LINUX-NEXT: lui a0, %hi(.LCPI0_0)
-; RV64-LINUX-NEXT: ld a0, %lo(.LCPI0_0)(a0)
-; RV64-LINUX-NEXT: lui a2, %hi(f)
-; RV64-LINUX-NEXT: addi a2, a2, %lo(f)
-; RV64-LINUX-NEXT: sd a2, 32(sp)
+; RV64-LINUX-NEXT: lui a0, %hi(f)
+; RV64-LINUX-NEXT: addi a0, a0, %lo(f)
+; RV64-LINUX-NEXT: sd a0, 32(sp)
+; RV64-LINUX-NEXT: li a0, 919
+; RV64-LINUX-NEXT: lui a2, %hi(.LCPI0_0)
+; RV64-LINUX-NEXT: ld a2, %lo(.LCPI0_0)(a2)
+; RV64-LINUX-NEXT: lui a3, 6203
+; RV64-LINUX-NEXT: addi a3, a3, 643
+; RV64-LINUX-NEXT: sw a0, 8(sp)
+; RV64-LINUX-NEXT: sw a3, 12(sp)
+; RV64-LINUX-NEXT: sd a2, 16(sp)
; RV64-LINUX-NEXT: sd a1, 24(sp)
-; RV64-LINUX-NEXT: sd a0, 16(sp)
-; RV64-LINUX-NEXT: lui a0, 6203
-; RV64-LINUX-NEXT: addi a0, a0, 643
-; RV64-LINUX-NEXT: slli a0, a0, 32
-; RV64-LINUX-NEXT: addi a0, a0, 919
-; RV64-LINUX-NEXT: sd a0, 8(sp)
; RV64-LINUX-NEXT: addi a1, sp, 24
; RV64-LINUX-NEXT: addi a0, sp, 8
; RV64-LINUX-NEXT: addi s1, sp, 8
More information about the llvm-commits
mailing list