[llvm-commits] [llvm] r76006 - in /llvm/trunk: lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp lib/Target/SystemZ/SystemZISelLowering.cpp lib/Target/SystemZ/SystemZInstrInfo.h lib/Target/SystemZ/SystemZInstrInfo.td lib/Target/SystemZ/SystemZOperands.td lib/Target/SystemZ/SystemZSubtarget.cpp lib/Target/SystemZ/SystemZSubtarget.h lib/Target/SystemZ/SystemZTargetMachine.cpp test/CodeGen/SystemZ/10-FuncsPic.ll test/CodeGen/SystemZ/10-GlobalsPic.ll

Anton Korobeynikov asl at math.spbu.ru
Thu Jul 16 07:16:06 PDT 2009


Author: asl
Date: Thu Jul 16 09:16:05 2009
New Revision: 76006

URL: http://llvm.org/viewvc/llvm-project?rev=76006&view=rev
Log:
Implement 'large' PIC model

Added:
    llvm/trunk/test/CodeGen/SystemZ/10-FuncsPic.ll
    llvm/trunk/test/CodeGen/SystemZ/10-GlobalsPic.ll
Modified:
    llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h
    llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
    llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
    llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.cpp
    llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.h
    llvm/trunk/lib/Target/SystemZ/SystemZTargetMachine.cpp

Modified: llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/AsmPrinter/SystemZAsmPrinter.cpp Thu Jul 16 09:16:05 2009
@@ -50,6 +50,7 @@
 
     void printOperand(const MachineInstr *MI, int OpNum,
                       const char* Modifier = 0);
+    void printPCRelImmOperand(const MachineInstr *MI, int OpNum);
     void printRIAddrOperand(const MachineInstr *MI, int OpNum,
                             const char* Modifier = 0);
     void printRRIAddrOperand(const MachineInstr *MI, int OpNum,
@@ -186,6 +187,40 @@
   assert(0 && "Should not happen");
 }
 
+void SystemZAsmPrinter::printPCRelImmOperand(const MachineInstr *MI, int OpNum) {
+  const MachineOperand &MO = MI->getOperand(OpNum);
+  switch (MO.getType()) {
+  case MachineOperand::MO_GlobalAddress: {
+    const GlobalValue *GV = MO.getGlobal();
+    std::string Name = Mang->getValueName(GV);
+
+    O << Name;
+
+    // Assemble calls via PLT for externally visible symbols if PIC.
+    if (TM.getRelocationModel() == Reloc::PIC_ &&
+        !GV->hasHiddenVisibility() && !GV->hasProtectedVisibility() &&
+        !GV->hasLocalLinkage())
+      O << "@PLT";
+
+    printOffset(MO.getOffset());
+    return;
+  }
+  case MachineOperand::MO_ExternalSymbol: {
+    std::string Name(TAI->getGlobalPrefix());
+    Name += MO.getSymbolName();
+    O << Name;
+
+    if (TM.getRelocationModel() == Reloc::PIC_)
+      O << "@PLT";
+
+    return;
+  }
+  default:
+    assert(0 && "Not implemented yet!");
+  }
+}
+
+
 void SystemZAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
                                      const char* Modifier) {
   const MachineOperand &MO = MI->getOperand(OpNum);
@@ -219,23 +254,31 @@
     return;
   case MachineOperand::MO_GlobalAddress: {
     const GlobalValue *GV = MO.getGlobal();
-
     std::string Name = Mang->getValueName(GV);
-    assert(MO.getOffset() == 0 && "No offsets allowed!");
 
     O << Name;
-
-    return;
+    break;
   }
   case MachineOperand::MO_ExternalSymbol: {
     std::string Name(TAI->getGlobalPrefix());
     Name += MO.getSymbolName();
     O << Name;
-    return;
+    break;
   }
   default:
     assert(0 && "Not implemented yet!");
   }
+
+  switch (MO.getTargetFlags()) {
+  default:
+    assert(0 && "Unknown target flag on GV operand");
+  case SystemZII::MO_NO_FLAG:
+    break;
+  case SystemZII::MO_GOTENT:    O << "@GOTENT";    break;
+  case SystemZII::MO_PLT:       O << "@PLT";       break;
+  }
+
+  printOffset(MO.getOffset());
 }
 
 void SystemZAsmPrinter::printRIAddrOperand(const MachineInstr *MI, int OpNum,

Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Thu Jul 16 09:16:05 2009
@@ -545,10 +545,38 @@
                                                   SelectionDAG &DAG) {
   DebugLoc dl = Op.getDebugLoc();
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
-  SDValue GA = DAG.getTargetGlobalAddress(GV, getPointerTy());
+  int64_t Offset = cast<GlobalAddressSDNode>(Op)->getOffset();
 
-  // FIXME: Verify stuff for constant globals entries
-  return DAG.getNode(SystemZISD::PCRelativeWrapper, dl, getPointerTy(), GA);
+  bool IsPic = getTargetMachine().getRelocationModel() == Reloc::PIC_;
+  bool ExtraLoadRequired =
+    Subtarget.GVRequiresExtraLoad(GV, getTargetMachine(), false);
+
+  SDValue Result;
+  if (!IsPic && !ExtraLoadRequired) {
+    Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset);
+    Offset = 0;
+  } else {
+    unsigned char OpFlags = 0;
+    if (ExtraLoadRequired)
+      OpFlags = SystemZII::MO_GOTENT;
+
+    Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), 0, OpFlags);
+  }
+
+  Result = DAG.getNode(SystemZISD::PCRelativeWrapper, dl,
+                       getPointerTy(), Result);
+
+  if (ExtraLoadRequired)
+    Result = DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(), Result,
+                         PseudoSourceValue::getGOT(), 0);
+
+  // If there was a non-zero offset that we didn't fold, create an explicit
+  // addition for it.
+  if (Offset != 0)
+    Result = DAG.getNode(ISD::ADD, dl, getPointerTy(), Result,
+                         DAG.getConstant(Offset, getPointerTy()));
+
+  return Result;
 }
 
 

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.h Thu Jul 16 09:16:05 2009
@@ -23,6 +23,30 @@
 
 class SystemZTargetMachine;
 
+/// SystemZII - This namespace holds all of the target specific flags that
+/// instruction info tracks.
+///
+namespace SystemZII {
+  enum {
+    //===------------------------------------------------------------------===//
+    // SystemZ Specific MachineOperand flags.
+
+    MO_NO_FLAG = 0,
+
+    /// MO_GOTENT - On a symbol operand this indicates that the immediate is
+    /// the offset to the location of the symbol name from the base of the GOT.
+    ///
+    ///    SYMBOL_LABEL @GOTENT
+    MO_GOTENT = 1,
+
+    /// MO_PLT - On a symbol operand this indicates that the immediate is
+    /// offset to the PLT entry of symbol name from the current code location.
+    ///
+    ///    SYMBOL_LABEL @PLT
+    MO_PLT = 2
+  };
+}
+
 class SystemZInstrInfo : public TargetInstrInfoImpl {
   const SystemZRegisterInfo RI;
   SystemZTargetMachine &TM;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Thu Jul 16 09:16:05 2009
@@ -134,7 +134,7 @@
   // All calls clobber the non-callee saved registers. Uses for argument
   // registers are added manually.
   let Defs = [R0D, R1D, R2D, R3D, R4D, R5D, R14D] in {
-    def CALLi     : Pseudo<(outs), (ins i64imm:$dst, variable_ops),
+    def CALLi     : Pseudo<(outs), (ins imm_pcrel:$dst, variable_ops),
                            "brasl\t%r14, $dst", [(SystemZcall imm:$dst)]>;
     def CALLr     : Pseudo<(outs), (ins ADDR64:$dst, variable_ops),
                            "basr\t%r14, $dst", [(SystemZcall ADDR64:$dst)]>;

Modified: llvm/trunk/lib/Target/SystemZ/SystemZOperands.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZOperands.td?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZOperands.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZOperands.td Thu Jul 16 09:16:05 2009
@@ -244,6 +244,10 @@
   let PrintMethod = "printS32ImmOperand";
 }
 
+def imm_pcrel : Operand<i64> {
+  let PrintMethod = "printPCRelImmOperand";
+}
+
 //===----------------------------------------------------------------------===//
 // SystemZ Operand Definitions.
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.cpp?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.cpp Thu Jul 16 09:16:05 2009
@@ -14,6 +14,7 @@
 #include "SystemZSubtarget.h"
 #include "SystemZ.h"
 #include "SystemZGenSubtarget.inc"
+#include "llvm/GlobalValue.h"
 #include "llvm/Target/TargetMachine.h"
 
 using namespace llvm;
@@ -26,3 +27,21 @@
   // Parse features string.
   ParseSubtargetFeatures(FS, CPU);
 }
+
+/// True if accessing the GV requires an extra load.
+bool SystemZSubtarget::GVRequiresExtraLoad(const GlobalValue* GV,
+                                           const TargetMachine& TM,
+                                           bool isDirectCall) const {
+  if (TM.getRelocationModel() == Reloc::PIC_) {
+    // Extra load is needed for all externally visible.
+    if (isDirectCall)
+      return false;
+
+    if (GV->hasLocalLinkage() || GV->hasHiddenVisibility())
+      return false;
+
+    return true;
+  }
+
+  return false;
+}

Modified: llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.h?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZSubtarget.h Thu Jul 16 09:16:05 2009
@@ -21,6 +21,7 @@
 namespace llvm {
 class Module;
 class TargetMachine;
+class GlobalValue;
 
 class SystemZSubtarget : public TargetSubtarget {
   bool HasZ10Insts;
@@ -37,6 +38,9 @@
                                      const std::string &CPU);
 
   bool isZ10() const { return HasZ10Insts; }
+
+  bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine& TM,
+                           bool isDirectCall) const;
 };
 } // End llvm namespace
 

Modified: llvm/trunk/lib/Target/SystemZ/SystemZTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZTargetMachine.cpp?rev=76006&r1=76005&r2=76006&view=diff

==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZTargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZTargetMachine.cpp Thu Jul 16 09:16:05 2009
@@ -42,6 +42,9 @@
     DataLayout("E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"),
     InstrInfo(*this), TLInfo(*this),
     FrameInfo(TargetFrameInfo::StackGrowsDown, 8, -160) {
+
+  if (getRelocationModel() == Reloc::Default)
+    setRelocationModel(Reloc::Static);
 }
 
 bool SystemZTargetMachine::addInstSelector(PassManagerBase &PM,

Added: llvm/trunk/test/CodeGen/SystemZ/10-FuncsPic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/10-FuncsPic.ll?rev=76006&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/10-FuncsPic.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/10-FuncsPic.ll Thu Jul 16 09:16:05 2009
@@ -0,0 +1,27 @@
+; RUN: llvm-as < %s | llc -relocation-model=pic | grep GOTENT | count 3
+; RUN: llvm-as < %s | llc -relocation-model=pic | grep PLT | count 1
+
+target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
+target triple = "s390x-linux"
+ at ptr = external global void (...)*		; <void (...)**> [#uses=2]
+
+define void @foo1() nounwind {
+entry:
+	store void (...)* @func, void (...)** @ptr
+	ret void
+}
+
+declare void @func(...)
+
+define void @foo2() nounwind {
+entry:
+	tail call void (...)* @func() nounwind
+	ret void
+}
+
+define void @foo3() nounwind {
+entry:
+	%tmp = load void (...)** @ptr		; <void (...)*> [#uses=1]
+	tail call void (...)* %tmp() nounwind
+	ret void
+}

Added: llvm/trunk/test/CodeGen/SystemZ/10-GlobalsPic.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/10-GlobalsPic.ll?rev=76006&view=auto

==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/10-GlobalsPic.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/10-GlobalsPic.ll Thu Jul 16 09:16:05 2009
@@ -0,0 +1,29 @@
+; RUN: llvm-as < %s | llc -relocation-model=pic | grep GOTENT | count 6
+
+target datalayout = "E-p:64:64:64-i8:8:16-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128-a0:16:16"
+target triple = "s390x-linux"
+ at src = external global i32		; <i32*> [#uses=2]
+ at dst = external global i32		; <i32*> [#uses=2]
+ at ptr = external global i32*		; <i32**> [#uses=2]
+
+define void @foo1() nounwind {
+entry:
+	%tmp = load i32* @src		; <i32> [#uses=1]
+	store i32 %tmp, i32* @dst
+	ret void
+}
+
+define void @foo2() nounwind {
+entry:
+	store i32* @dst, i32** @ptr
+	ret void
+}
+
+define void @foo3() nounwind {
+entry:
+	%tmp = load i32* @src		; <i32> [#uses=1]
+	%tmp1 = load i32** @ptr		; <i32*> [#uses=1]
+	%arrayidx = getelementptr i32* %tmp1, i64 1		; <i32*> [#uses=1]
+	store i32 %tmp, i32* %arrayidx
+	ret void
+}





More information about the llvm-commits mailing list