[PATCH] D66340: [RISCV] Support NonLazyBind

Maxim Davydov via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 18 07:49:29 PDT 2019


M_ximus updated this revision to Diff 220666.
M_ximus edited the summary of this revision.
M_ximus added a comment.

All mistakes in the patch were fixed.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66340/new/

https://reviews.llvm.org/D66340

Files:
  llvm/lib/Target/RISCV/RISCVISelLowering.cpp
  llvm/lib/Target/RISCV/RISCVSubtarget.cpp
  llvm/lib/Target/RISCV/RISCVSubtarget.h
  llvm/test/CodeGen/RISCV/no-plt.ll


Index: llvm/test/CodeGen/RISCV/no-plt.ll
===================================================================
--- /dev/null
+++ llvm/test/CodeGen/RISCV/no-plt.ll
@@ -0,0 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc -mtriple=riscv64 -relocation-model=pic < %s | FileCheck %s
+
+declare void @global() nonlazybind
+
+define void @no_plt_call() nounwind {
+; CHECK-LABEL: no_plt_call:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    addi sp, sp, -16
+; CHECK-NEXT:    sd ra, 8(sp)
+; CHECK-NEXT:  .LBB0_1: # Label of block must be emitted
+; CHECK-NEXT:    auipc a0, %got_pcrel_hi(global)
+; CHECK-NEXT:    ld a0, %pcrel_lo(.LBB0_1)(a0)
+; CHECK-NEXT:    jalr a0
+; CHECK-NEXT:    ld ra, 8(sp)
+; CHECK-NEXT:    addi sp, sp, 16
+; CHECK-NEXT:    ret
+  call void @global()
+  ret void
+}
Index: llvm/lib/Target/RISCV/RISCVSubtarget.h
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.h
+++ llvm/lib/Target/RISCV/RISCVSubtarget.h
@@ -67,6 +67,11 @@
   // definition of this function is auto-generated by tblgen.
   void ParseSubtargetFeatures(StringRef CPU, StringRef FS);
 
+  // Return how the function given by GV should be invoked:
+  // via the PLT, by taking its address from the GOT, or with a direct call.
+  unsigned char classifyGlobalFunctionReference(const GlobalValue *GV,
+  						const TargetMachine &TM) const;
+
   const RISCVFrameLowering *getFrameLowering() const override {
     return &FrameLowering;
   }
Index: llvm/lib/Target/RISCV/RISCVSubtarget.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVSubtarget.cpp
+++ llvm/lib/Target/RISCV/RISCVSubtarget.cpp
@@ -61,6 +61,17 @@
       *static_cast<const RISCVTargetMachine *>(&TM), *this, *RBI));
 }
 
+unsigned char RISCVSubtarget::classifyGlobalFunctionReference(
+    const GlobalValue *GV, const TargetMachine &TM) const {
+  auto *F = dyn_cast<Function>(GV);
+  if (!TM.shouldAssumeDSOLocal(*GV->getParent(), GV)) {
+    if (F && F->hasFnAttribute(Attribute::NonLazyBind))
+      return RISCVII::MO_GOT_HI;
+    return RISCVII::MO_PLT;
+  }
+  return RISCVII::MO_CALL;
+}
+
 const CallLowering *RISCVSubtarget::getCallLowering() const {
   return CallLoweringInfo.get();
 }
Index: llvm/lib/Target/RISCV/RISCVISelLowering.cpp
===================================================================
--- llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -2185,14 +2185,18 @@
   // 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.
+  // GlobalAddress/ExternalSymbol may become a normal node
+  // and indirectly called if using NonLazyBind.
   if (GlobalAddressSDNode *S = dyn_cast<GlobalAddressSDNode>(Callee)) {
     const GlobalValue *GV = S->getGlobal();
 
-    unsigned OpFlags = RISCVII::MO_CALL;
-    if (!getTargetMachine().shouldAssumeDSOLocal(*GV->getParent(), GV))
-      OpFlags = RISCVII::MO_PLT;
+    unsigned OpFlags =
+        Subtarget.classifyGlobalFunctionReference(GV, getTargetMachine());
 
-    Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
+    if (OpFlags == RISCVII::MO_GOT_HI)
+      Callee = getAddr(S, DAG, /*IsLocal=*/false);
+    else
+      Callee = DAG.getTargetGlobalAddress(GV, DL, PtrVT, 0, OpFlags);
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
     unsigned OpFlags = RISCVII::MO_CALL;
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D66340.220666.patch
Type: text/x-patch
Size: 3611 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190918/0d170613/attachment-0001.bin>


More information about the llvm-commits mailing list