[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