-
Notifications
You must be signed in to change notification settings - Fork 12.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RISCV] Support the large code model. #70308
Conversation
@llvm/pr-subscribers-backend-risc-v Author: Jim Lin (tclin914) ChangesImplement large code model for GlobalAddressSDNode, BlockAddressSDNode and ExternalSymbolSDNode. See discussion on co-authored by: Kuan-Lin Chen <rufus@andestech.com> Patch is 95.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/70308.diff 10 Files Affected:
diff --git a/llvm/lib/Target/RISCV/CMakeLists.txt b/llvm/lib/Target/RISCV/CMakeLists.txt
index 4d5fa79389ea68b..b6ed0b86e39e9ba 100644
--- a/llvm/lib/Target/RISCV/CMakeLists.txt
+++ b/llvm/lib/Target/RISCV/CMakeLists.txt
@@ -29,6 +29,7 @@ add_public_tablegen_target(RISCVCommonTableGen)
add_llvm_target(RISCVCodeGen
RISCVAsmPrinter.cpp
RISCVCodeGenPrepare.cpp
+ RISCVConstantPoolValue.cpp
RISCVDeadRegisterDefinitions.cpp
RISCVMakeCompressible.cpp
RISCVExpandAtomicPseudoInsts.cpp
diff --git a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
index 0fd514fa87cd2f9..6308d1f574b4d03 100644
--- a/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
+++ b/llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp
@@ -16,6 +16,7 @@
#include "MCTargetDesc/RISCVMCExpr.h"
#include "MCTargetDesc/RISCVTargetStreamer.h"
#include "RISCV.h"
+#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVTargetMachine.h"
#include "TargetInfo/RISCVTargetInfo.h"
@@ -75,6 +76,8 @@ class RISCVAsmPrinter : public AsmPrinter {
void emitInstruction(const MachineInstr *MI) override;
+ void emitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) override;
+
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
const char *ExtraCode, raw_ostream &OS) override;
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
@@ -981,3 +984,35 @@ bool RISCVAsmPrinter::lowerToMCInst(const MachineInstr *MI, MCInst &OutMI) {
}
return false;
}
+
+static MCSymbolRefExpr::VariantKind
+getModifierVariantKind(RISCVCP::RISCVCPModifier Modifier) {
+ switch (Modifier) {
+ case RISCVCP::None:
+ return MCSymbolRefExpr::VK_None;
+ }
+ llvm_unreachable("Invalid RISCVCPModifier!");
+}
+
+void RISCVAsmPrinter::emitMachineConstantPoolValue(
+ MachineConstantPoolValue *MCPV) {
+ auto *RCPV = static_cast<RISCVConstantPoolValue *>(MCPV);
+ MCSymbol *MCSym;
+
+ if (RCPV->isGlobalValue()) {
+ auto GV = cast<RISCVConstantPoolConstant>(RCPV)->getGlobalValue();
+ MCSym = getSymbol(GV);
+ } else if (RCPV->isBlockAddress()) {
+ auto BA = cast<RISCVConstantPoolConstant>(RCPV)->getBlockAddress();
+ MCSym = GetBlockAddressSymbol(BA);
+ } else {
+ assert(RCPV->isExtSymbol() && "unrecognized constant pool value");
+ auto Sym = cast<RISCVConstantPoolSymbol>(RCPV)->getSymbol();
+ MCSym = GetExternalSymbolSymbol(Sym);
+ }
+
+ const MCExpr *Expr = MCSymbolRefExpr::create(
+ MCSym, getModifierVariantKind(RCPV->getModifier()), OutContext);
+ uint64_t Size = getDataLayout().getTypeAllocSize(RCPV->getType());
+ OutStreamer->emitValue(Expr, Size);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
new file mode 100644
index 000000000000000..398dfbd9bb65948
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp
@@ -0,0 +1,114 @@
+//===------- RISCVConstantPoolValue.cpp - RISC-V constantpool value -------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RISC-V specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#include "RISCVConstantPoolValue.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/Type.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+RISCVConstantPoolValue::RISCVConstantPoolValue(
+ LLVMContext &C, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier)
+ : MachineConstantPoolValue((Type *)Type::getInt64Ty(C)), Kind(Kind),
+ Modifier(Modifier) {}
+
+RISCVConstantPoolValue::RISCVConstantPoolValue(
+ Type *Ty, RISCVCP::RISCVCPKind Kind, RISCVCP::RISCVCPModifier Modifier)
+ : MachineConstantPoolValue(Ty), Kind(Kind), Modifier(Modifier) {}
+
+int RISCVConstantPoolValue::getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) {
+ llvm_unreachable("Shouldn't be calling this directly!");
+}
+
+StringRef RISCVConstantPoolValue::getModifierText() const {
+ switch (Modifier) {
+ case RISCVCP::None:
+ return "";
+ }
+ llvm_unreachable("Unknown modifier!");
+}
+
+void RISCVConstantPoolValue::print(raw_ostream &O) const {
+ if (hasModifier())
+ O << "@" << getModifierText();
+}
+
+RISCVConstantPoolConstant::RISCVConstantPoolConstant(Type *Ty,
+ const Constant *GV,
+ RISCVCP::RISCVCPKind Kind)
+ : RISCVConstantPoolValue(Ty, Kind, RISCVCP::None), CVal(GV) {}
+
+RISCVConstantPoolConstant *
+RISCVConstantPoolConstant::Create(const GlobalValue *GV,
+ RISCVCP::RISCVCPKind Kind) {
+ return new RISCVConstantPoolConstant(GV->getType(), GV, Kind);
+}
+
+RISCVConstantPoolConstant *
+RISCVConstantPoolConstant::Create(const Constant *C,
+ RISCVCP::RISCVCPKind Kind) {
+ return new RISCVConstantPoolConstant(C->getType(), C, Kind);
+}
+
+int RISCVConstantPoolConstant::getExistingMachineCPValue(
+ MachineConstantPool *CP, Align Alignment) {
+ return getExistingMachineCPValueImpl<RISCVConstantPoolConstant>(CP,
+ Alignment);
+}
+
+void RISCVConstantPoolConstant::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ ID.AddPointer(CVal);
+}
+
+void RISCVConstantPoolConstant::print(raw_ostream &O) const {
+ O << CVal->getName();
+ RISCVConstantPoolValue::print(O);
+}
+
+const GlobalValue *RISCVConstantPoolConstant::getGlobalValue() const {
+ return dyn_cast_or_null<GlobalValue>(CVal);
+}
+
+const BlockAddress *RISCVConstantPoolConstant::getBlockAddress() const {
+ return dyn_cast_or_null<BlockAddress>(CVal);
+}
+
+RISCVConstantPoolSymbol::RISCVConstantPoolSymbol(
+ LLVMContext &C, StringRef s, RISCVCP::RISCVCPModifier Modifier)
+ : RISCVConstantPoolValue(C, RISCVCP::ExtSymbol, Modifier), S(s) {}
+
+RISCVConstantPoolSymbol *
+RISCVConstantPoolSymbol::Create(LLVMContext &C, StringRef s,
+ RISCVCP::RISCVCPModifier Modifier) {
+ return new RISCVConstantPoolSymbol(C, s, Modifier);
+}
+
+int RISCVConstantPoolSymbol::getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) {
+ return getExistingMachineCPValueImpl<RISCVConstantPoolSymbol>(CP, Alignment);
+}
+
+void RISCVConstantPoolSymbol::addSelectionDAGCSEId(FoldingSetNodeID &ID) {
+ ID.AddString(S);
+}
+
+void RISCVConstantPoolSymbol::print(raw_ostream &O) const {
+ O << S;
+ RISCVConstantPoolValue::print(O);
+}
diff --git a/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
new file mode 100644
index 000000000000000..8edd95e9a065fd7
--- /dev/null
+++ b/llvm/lib/Target/RISCV/RISCVConstantPoolValue.h
@@ -0,0 +1,147 @@
+//===--- RISCVConstantPoolValue.h - RISC-V constantpool value ---*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the RISC-V specific constantpool value class.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
+#define LLVM_LIB_TARGET_RISCV_RISCVCONSTANTPOOLVALUE_H
+
+#include "llvm/CodeGen/MachineConstantPool.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace llvm {
+
+class LLVMContext;
+class GlobalValue;
+class BlockAddress;
+
+namespace RISCVCP {
+
+enum RISCVCPKind { ExtSymbol, GlobalValue, BlockAddress };
+
+enum RISCVCPModifier {
+ None,
+};
+} // end namespace RISCVCP
+
+/// A RISCV-specific constant pool value.
+class RISCVConstantPoolValue : public MachineConstantPoolValue {
+ RISCVCP::RISCVCPKind Kind;
+ RISCVCP::RISCVCPModifier Modifier;
+
+protected:
+ RISCVConstantPoolValue(LLVMContext &C, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier);
+
+ RISCVConstantPoolValue(Type *Ty, RISCVCP::RISCVCPKind Kind,
+ RISCVCP::RISCVCPModifier Modifier);
+
+ template <typename Derived>
+ int getExistingMachineCPValueImpl(MachineConstantPool *CP, Align Alignment) {
+ const std::vector<MachineConstantPoolEntry> &Constants = CP->getConstants();
+ for (unsigned i = 0, e = Constants.size(); i != e; ++i) {
+ if (Constants[i].isMachineConstantPoolEntry() &&
+ Constants[i].getAlign() >= Alignment) {
+ auto *CPV = static_cast<RISCVConstantPoolValue *>(
+ Constants[i].Val.MachineCPVal);
+ if (Derived *APC = dyn_cast<Derived>(CPV))
+ if (cast<Derived>(this)->equals(APC))
+ return i;
+ }
+ }
+
+ return -1;
+ }
+
+public:
+ ~RISCVConstantPoolValue() = default;
+
+ RISCVCP::RISCVCPModifier getModifier() const { return Modifier; }
+ StringRef getModifierText() const;
+ bool hasModifier() const { return Modifier != RISCVCP::None; }
+
+ bool isExtSymbol() const { return Kind == RISCVCP::ExtSymbol; }
+ bool isGlobalValue() const { return Kind == RISCVCP::GlobalValue; }
+ bool isBlockAddress() const { return Kind == RISCVCP::BlockAddress; }
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override {}
+
+ bool equals(const RISCVConstantPoolValue *A) const {
+ return this->Modifier == A->Modifier;
+ }
+
+ void print(raw_ostream &O) const override;
+};
+
+class RISCVConstantPoolConstant : public RISCVConstantPoolValue {
+ const Constant *CVal;
+
+ RISCVConstantPoolConstant(Type *Ty, const Constant *GV,
+ RISCVCP::RISCVCPKind Kind);
+
+public:
+ static RISCVConstantPoolConstant *Create(const GlobalValue *GV,
+ RISCVCP::RISCVCPKind Kind);
+ static RISCVConstantPoolConstant *Create(const Constant *C,
+ RISCVCP::RISCVCPKind Kind);
+
+ const GlobalValue *getGlobalValue() const;
+ const BlockAddress *getBlockAddress() const;
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
+
+ void print(raw_ostream &O) const override;
+
+ bool equals(const RISCVConstantPoolConstant *A) const {
+ return CVal == A->CVal && RISCVConstantPoolValue::equals(A);
+ }
+
+ static bool classof(const RISCVConstantPoolValue *RCPV) {
+ return RCPV->isGlobalValue() || RCPV->isBlockAddress();
+ }
+};
+
+class RISCVConstantPoolSymbol : public RISCVConstantPoolValue {
+ const std::string S;
+
+ RISCVConstantPoolSymbol(LLVMContext &C, StringRef s,
+ RISCVCP::RISCVCPModifier Modifier);
+
+public:
+ static RISCVConstantPoolSymbol *Create(LLVMContext &C, StringRef s,
+ RISCVCP ::RISCVCPModifier Modifier);
+
+ std::string getSymbol() const { return S; }
+
+ int getExistingMachineCPValue(MachineConstantPool *CP,
+ Align Alignment) override;
+
+ void addSelectionDAGCSEId(FoldingSetNodeID &ID) override;
+
+ void print(raw_ostream &O) const override;
+
+ bool equals(const RISCVConstantPoolSymbol *A) const {
+ return S == A->S && RISCVConstantPoolValue::equals(A);
+ }
+ static bool classof(const RISCVConstantPoolValue *RCPV) {
+ return RCPV->isExtSymbol();
+ }
+};
+
+} // end namespace llvm
+
+#endif
diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index beb371063f89b2d..e523995a909f599 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -14,6 +14,7 @@
#include "RISCVISelLowering.h"
#include "MCTargetDesc/RISCVMatInt.h"
#include "RISCV.h"
+#include "RISCVConstantPoolValue.h"
#include "RISCVMachineFunctionInfo.h"
#include "RISCVRegisterInfo.h"
#include "RISCVSubtarget.h"
@@ -6431,6 +6432,44 @@ static SDValue getTargetNode(JumpTableSDNode *N, const SDLoc &DL, EVT Ty,
return DAG.getTargetJumpTable(N->getIndex(), Ty, Flags);
}
+static SDValue getTargetNode(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty,
+ SelectionDAG &DAG, unsigned Flags) {
+ llvm_unreachable("Unexpected node type.");
+}
+
+template <class NodeTy>
+static SDValue getLargeAddr(NodeTy *N, SDLoc DL, EVT Ty, SelectionDAG &DAG) {
+ if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(N)) {
+ RISCVConstantPoolConstant *CPV =
+ RISCVConstantPoolConstant::Create(G->getGlobal(), RISCVCP::GlobalValue);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else if (BlockAddressSDNode *B = dyn_cast<BlockAddressSDNode>(N)) {
+ RISCVConstantPoolConstant *CPV = RISCVConstantPoolConstant::Create(
+ B->getBlockAddress(), RISCVCP::BlockAddress);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(N)) {
+ RISCVConstantPoolSymbol *CPV = RISCVConstantPoolSymbol::Create(
+ *DAG.getContext(), S->getSymbol(), RISCVCP::None);
+ SDValue CPAddr = DAG.getTargetConstantPool(CPV, Ty, Align(8));
+ SDValue LC = DAG.getNode(RISCVISD::LLA, DL, Ty, CPAddr);
+ return DAG.getLoad(
+ Ty, DL, DAG.getEntryNode(), LC,
+ MachinePointerInfo::getConstantPool(DAG.getMachineFunction()));
+ } else {
+ // Using pc-relative mode for other node type.
+ SDValue Addr = getTargetNode(N, DL, Ty, DAG, 0);
+ return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
+ }
+}
+
template <class NodeTy>
SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
bool IsLocal, bool IsExternWeak) const {
@@ -6499,6 +6538,9 @@ SDValue RISCVTargetLowering::getAddr(NodeTy *N, SelectionDAG &DAG,
// expands to (addi (auipc %pcrel_hi(sym)) %pcrel_lo(auipc)).
return DAG.getNode(RISCVISD::LLA, DL, Ty, Addr);
}
+ case CodeModel::Large: {
+ return getLargeAddr(N, DL, Ty, DAG);
+ }
}
}
@@ -17489,22 +17531,32 @@ SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI,
// If the callee is a GlobalAddress/ExternalSymbol node, turn it into a
// TargetGlobalAddress/TargetExternalSymbol node so that legalize won't
// split it and then direct call can be matched by PseudoCALL.
- if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
- const GlobalValue *GV = S->getGlobal();
+ if (getTargetMachine().getCodeModel() == CodeModel::Large) {
+ if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ } else if (ExternalSymbolSDNode *S =
+ dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ Callee = getLargeAddr(S, DL, getPointerTy(DAG.getDataLayout()), DAG);
+ }
+ } else {
+ if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
+ const GlobalValue *GV = S->getGlobal();
+ unsigned OpFlags = RISCVII::MO_CALL;
- unsigned OpFlags = RISCVII::MO_CALL;
- if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
- OpFlags = RISCVII::MO_PLT;
+ if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
+ OpFlags = RISCVII::MO_PLT;
- Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
- } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
- unsigned OpFlags = RISCVII::MO_CALL;
+ Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
+ } else if (ExternalSymbolSDNode *S =
+ dyn_cast<ExternalSymbolSDNode>(Callee)) {
+ unsigned OpFlags = RISCVII::MO_CALL;
- if (!getTargetMachine().shouldAssumeDSOLocal(*MF.getFunction().getParent(),
- nullptr))
- OpFlags = RISCVII::MO_PLT;
+ if (!getTargetMachine().shouldAssumeDSOLocal(
+ *MF.getFunction().getParent(), nullptr))
+ OpFlags = RISCVII::MO_PLT;
- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
+ Callee = DAG.getTargetExternalSymbol(S->getSymbol(), PtrVT, OpFlags);
+ }
}
// The first call operand is the chain and the second is the target address.
diff --git a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
index 7c9e57e6eef3ced..ea9ab37ae415ce6 100644
--- a/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
+++ b/llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp
@@ -114,7 +114,7 @@ bool RISCVELFTargetObjectFile::isConstantInSmallSection(
MCSection *RISCVELFTargetObjectFile::getSectionForConstant(
const DataLayout &DL, SectionKind Kind, const Constant *C,
Align &Alignment) const {
- if (isConstantInSmallSection(DL, C))
+ if (C && isConstantInSmallSection(DL, C))
return SmallDataSection;
// Otherwise, we work the same as ELF.
diff --git a/llvm/test/CodeGen/RISCV/calls.ll b/llvm/test/CodeGen/RISCV/calls.ll
index e3459875362d45d..509daaa2970cd20 100644
--- a/llvm/test/CodeGen/RISCV/calls.ll
+++ b/llvm/test/CodeGen/RISCV/calls.ll
@@ -3,6 +3,14 @@
; RUN: | FileCheck -check-prefix=RV32I %s
; RUN: llc -relocation-model=pic -mtriple=riscv32 -verify-machineinstrs < %s \
; RUN: | FileCheck -check-prefix=RV32I-PIC %s
+; RUN: llc -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I %s
+; RUN: llc -code-model=small -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-SMALL %s
+; RUN: llc -code-model=medium -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-MEDIUM %s
+; RUN: llc -code-model=large -mtriple=riscv64 -verify-machineinstrs < %s \
+; RUN: | FileCheck -check-prefix=RV64I-LARGE %s
declare i32 @external_function(i32)
@@ -24,6 +32,45 @@ define i32 @test_call_external(i32 %a) nounwind {
; RV32I-PIC-NEXT: lw ra, 12(sp) # 4-byte Folded Reload
; RV32I-PIC-NEXT: addi sp, sp, 16
; RV32I-PIC-NEXT: ret
+;
+; RV64I-LABEL: test_call_external:
+; RV64I: # %bb.0:
+; RV64I-NEXT: addi sp, sp, -16
+; RV64I-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-NEXT: call external_function@plt
+; RV64I-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-NEXT: addi sp, sp, 16
+; RV64I-NEXT: ret
+;
+; RV64I-SMALL-LABEL: test_call_external:
+; RV64I-SMALL: # %bb.0:
+; RV64I-SMALL-NEXT: addi sp, sp, -16
+; RV64I-SMALL-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-SMALL-NEXT: call external_function@plt
+; RV64I-SMALL-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-SMALL-NEXT: addi sp, sp, 16
+; RV64I-SMALL-NEXT: ret
+;
+; RV64I-MEDIUM-LABEL: test_call_external:
+; RV64I-MEDIUM: # %bb.0:
+; RV64I-MEDIUM-NEXT: addi sp, sp, -16
+; RV64I-MEDIUM-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-MEDIUM-NEXT: call external_function@plt
+; RV64I-MEDIUM-NEXT: ld ra, 8(sp) # 8-byte Folded Reload
+; RV64I-MEDIUM-NEXT: addi sp, sp, 16
+; RV64I-MEDIUM-NEXT: ret
+;
+; RV64I-LARGE-LABEL: test_call_external:
+; RV64I-LARGE: # %bb.0:
+; RV64I-LARGE-NEXT: addi sp, sp, -16
+; RV64I-LARGE-NEXT: sd ra, 8(sp) # 8-byte Folded Spill
+; RV64I-LARGE-NEXT: .Lp...
[truncated]
|
It seems to me that we're some way from agreement and consensus on the spec, so I understand this patch is here for a proof of concept to accompany that discussion and to elicit early feedback/review on the implementation approach (which is a great contribution - thanks!). But I wanted to explicitly note that I think we shouldn't look to review and merge this until there's clear agreement on the spec. |
✅ With the latest revision this PR passed the C/C++ code formatter. |
Kindly ping. spec seems almost being ready. |
I believe the spec contains a lot of unresolved discussions and I would not call it "almost being ready". On the GCC side, |
4e3f582
to
d776b59
Compare
Any progress on this? or still waiting for the spec? |
b74d194
to
88399e1
Compare
kindly ping. |
Can we have some evaluations about impacts on code size and performance when using large code model? |
Our internal evaluation shows that the impact on both code size and performance is about 2.2% compared to the medany. |
Implement large code model for GlobalAddressSDNode, BlockAddressSDNode and ExternalSymbolSDNode. See discussion on riscv-non-isa/riscv-elf-psabi-doc#388. co-authored by: Kuan-Lin Chen <rufus@andestech.com>
Since getLargeAddr is reused before, that getTargetNode must have `ExternalSymbolSDNode` version during template instantiation.
7c6894e
to
544286a
Compare
kindly ping. |
It's only been 3 days; courtesy is no sooner than a week for non-urgent patches https://llvm.org/docs/CodeReview.html#code-reviews-speed-and-reciprocity |
The last time I updated the code to address the review comments was one week ago. I replied with the evaluation results three days ago and simply rebased it to resolve the conflict two days ago. I will wait longer next time. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM other than those minor nits.
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/146/builds/1105 Here is the relevant piece of the build log for the reference
|
Implement large code model for GlobalAddressSDNode and ExternalSymbolSDNode. See discussion on riscv-non-isa/riscv-elf-psabi-doc#388. --------- Co-authored-by: Kuan-Lin Chen <rufus@andestech.com>
Implement large code model for GlobalAddressSDNode and ExternalSymbolSDNode. See discussion on riscv-non-isa/riscv-elf-psabi-doc#388. --------- Co-authored-by: Kuan-Lin Chen <rufus@andestech.com>
Implement large code model for GlobalAddressSDNode and ExternalSymbolSDNode.
See discussion on
riscv-non-isa/riscv-elf-psabi-doc#388.
co-authored by: Kuan-Lin Chen rufus@andestech.com