Make isel determine where to emit PLT-relative calls instead of having
authorChris Lattner <sabre@nondot.org>
Thu, 9 Jul 2009 05:02:21 +0000 (05:02 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 9 Jul 2009 05:02:21 +0000 (05:02 +0000)
asmprinter do it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75104 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
lib/Target/X86/X86ISelLowering.cpp

index 6624a009a70e5b816faca8e3766bdeea54c3bc04..f8e6e8e314ddc74012c0e9c75bd1a93c6952342d 100644 (file)
@@ -282,10 +282,6 @@ bool X86ATTAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   return false;
 }
 
-static inline bool shouldPrintPLT(TargetMachine &TM, const X86Subtarget* ST) {
-  return ST->isTargetELF() && TM.getRelocationModel() == Reloc::PIC_;
-}
-
 /// print_pcrel_imm - This is used to print an immediate value that ends up
 /// being encoded as a pc-relative value.  These print slightly differently, for
 /// example, a $ is not emitted.
@@ -352,14 +348,11 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
         O << "__imp_";
       O << Name;
       
-      if (shouldPrintPLT(TM, Subtarget)) {
-        // Assemble call via PLT for externally visible symbols
-        if (!GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
-            !GV->hasLocalLinkage()) {
-          O << "@PLT";
-          assert(MO.getTargetFlags() == 0);
-        }
-      }
+      // Assemble call via PLT for externally visible symbols.
+      if (MO.getTargetFlags() == X86II::MO_PLT)
+        O << "@PLT";
+        
+      
       if (Subtarget->isTargetCygMing() && GV->isDeclaration())
         // Save function name for later type emission
         FnStubs.insert(Name);
@@ -400,10 +393,8 @@ void X86ATTAsmPrinter::print_pcrel_imm(const MachineInstr *MI, unsigned OpNo) {
       O << ']';
     }
     
-    if (shouldPrintPLT(TM, Subtarget)) {
+    if (MO.getTargetFlags() == X86II::MO_PLT)
       O << "@PLT";
-      assert(MO.getTargetFlags() == 0);
-    }
     
     if (needCloseParen)
       O << ')';
index d859423300117c26c769e6abdf81c3c998c64844..eba503d8f2abbc57b39b2764d81bd9551b89e4bb 100644 (file)
@@ -1901,11 +1901,33 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
     // We should use extra load for direct calls to dllimported functions in
     // non-JIT mode.
     if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
-                                        getTargetMachine(), true))
+                                        getTargetMachine(), true)) {
+      unsigned char OpFlags = 0;
+    
+      // On ELF targets, in both X86-64 and X86-32 mode, direct calls to
+      // external symbols most go through the PLT in PIC mode.  If the symbol
+      // has hidden or protected visibility, or if it is static or local, then
+      // we don't need to use the PLT - we can directly call it.
+      if (Subtarget->isTargetELF() &&
+          getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+          G->getGlobal()->hasDefaultVisibility() &&
+          !G->getGlobal()->hasLocalLinkage())
+        OpFlags = X86II::MO_PLT;
+
       Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy(),
-                                          G->getOffset());
+                                          G->getOffset(), OpFlags);
+    }
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
-    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
+    unsigned char OpFlags = 0;
+
+    // On ELF targets, in either X86-64 or X86-32 mode, direct calls to external
+    // symbols should go through the PLT.
+    if (Subtarget->isTargetELF() &&
+        getTargetMachine().getRelocationModel() == Reloc::PIC_)
+      OpFlags = X86II::MO_PLT;
+    
+    Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
+                                         OpFlags);
   } else if (IsTailCall) {
     unsigned Opc = Is64Bit ? X86::R11 : X86::EAX;