Skip to content
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

Merged
merged 20 commits into from
Sep 9, 2024
Merged

Conversation

tclin914
Copy link
Contributor

@tclin914 tclin914 commented Oct 26, 2023

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 [email protected]

@llvmbot
Copy link
Member

llvmbot commented Oct 26, 2023

@llvm/pr-subscribers-backend-risc-v

Author: Jim Lin (tclin914)

Changes

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 <[email protected]>


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:

  • (modified) llvm/lib/Target/RISCV/CMakeLists.txt (+1)
  • (modified) llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp (+35)
  • (added) llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp (+114)
  • (added) llvm/lib/Target/RISCV/RISCVConstantPoolValue.h (+147)
  • (modified) llvm/lib/Target/RISCV/RISCVISelLowering.cpp (+64-12)
  • (modified) llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp (+1-1)
  • (modified) llvm/test/CodeGen/RISCV/calls.ll (+524)
  • (modified) llvm/test/CodeGen/RISCV/codemodel-lowering.ll (+161)
  • (modified) llvm/test/CodeGen/RISCV/fold-addi-loadstore.ll (+198)
  • (modified) llvm/test/CodeGen/RISCV/inline-asm-mem-constraint.ll (+553)
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]

@asb
Copy link
Contributor

asb commented Oct 27, 2023

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.

Copy link

github-actions bot commented Dec 13, 2023

✅ With the latest revision this PR passed the C/C++ code formatter.

llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVAsmPrinter.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVConstantPoolValue.h Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVConstantPoolValue.h Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp Outdated Show resolved Hide resolved
@tclin914
Copy link
Contributor Author

Kindly ping. spec seems almost being ready.

@MaskRay
Copy link
Member

MaskRay commented Dec 21, 2023

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, RISC-V: Support -mcmodel=large. landed on Dec 20.

@amitch1999
Copy link

Any progress on this? or still waiting for the spec?

@tclin914 tclin914 force-pushed the codemodel-large-up branch from b74d194 to 88399e1 Compare August 19, 2024 03:15
@tclin914 tclin914 changed the title [RFC][RISCV] Support the large code model. [RISCV] Support the large code model. Aug 26, 2024
@tclin914
Copy link
Contributor Author

kindly ping.

llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVISelLowering.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVISelLowering.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVISelLowering.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVISelLowering.cpp Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVISelLowering.cpp Outdated Show resolved Hide resolved
@wangpc-pp
Copy link
Contributor

Can we have some evaluations about impacts on code size and performance when using large code model?

@tclin914
Copy link
Contributor Author

tclin914 commented Sep 2, 2024

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.

Kuan-Lin Chen and others added 2 commits September 3, 2024 09:33
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 <[email protected]>
@tclin914
Copy link
Contributor Author

tclin914 commented Sep 5, 2024

kindly ping.

@jrtc27
Copy link
Collaborator

jrtc27 commented Sep 5, 2024

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

@tclin914
Copy link
Contributor Author

tclin914 commented Sep 5, 2024

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.

Copy link
Collaborator

@topperc topperc left a 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/lib/Target/RISCV/RISCVConstantPoolValue.h Outdated Show resolved Hide resolved
llvm/lib/Target/RISCV/RISCVConstantPoolValue.cpp Outdated Show resolved Hide resolved
@tclin914 tclin914 merged commit fef84c5 into llvm:main Sep 9, 2024
8 checks passed
@tclin914 tclin914 deleted the codemodel-large-up branch September 9, 2024 01:30
@llvm-ci
Copy link
Collaborator

llvm-ci commented Sep 9, 2024

LLVM Buildbot has detected a new failure on builder lld-x86_64-win running on as-worker-93 while building llvm at step 7 "test-build-unified-tree-check-all".

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
Step 7 (test-build-unified-tree-check-all) failure: test (failure)
******************** TEST 'LLVM-Unit :: Support/./SupportTests.exe/43/86' FAILED ********************
Script(shard):
--
GTEST_OUTPUT=json:C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe-LLVM-Unit-10024-43-86.json GTEST_SHUFFLE=0 GTEST_TOTAL_SHARDS=86 GTEST_SHARD_INDEX=43 C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe
--

Script:
--
C:\a\lld-x86_64-win\build\unittests\Support\.\SupportTests.exe --gtest_filter=ProgramEnvTest.CreateProcessLongPath
--
C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(160): error: Expected equality of these values:
  0
  RC
    Which is: -2

C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp(163): error: fs::remove(Twine(LongPath)): did not return errc::success.
error number: 13
error message: permission denied



C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:160
Expected equality of these values:
  0
  RC
    Which is: -2

C:\a\lld-x86_64-win\llvm-project\llvm\unittests\Support\ProgramTest.cpp:163
fs::remove(Twine(LongPath)): did not return errc::success.
error number: 13
error message: permission denied




********************


dlav-sc pushed a commit to dlav-sc/llvm-project that referenced this pull request Sep 10, 2024
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 <[email protected]>
VitaNuo pushed a commit to VitaNuo/llvm-project that referenced this pull request Sep 12, 2024
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 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants