diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index d13a4ed78df..5a58951a75a 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -34,6 +34,16 @@ class PassManager; class Pass; class IntrinsicLowering; +// Relocation model types. +namespace Reloc { + enum Model { + Default, + Static, + PIC, + DynamicNoPIC + }; +} + //===----------------------------------------------------------------------===// /// /// TargetMachine - Primary interface to the complete machine description for @@ -135,6 +145,13 @@ public: virtual const TargetSchedInfo *getSchedInfo() const { return 0; } virtual const SparcV9RegInfo *getRegInfo() const { return 0; } + /// getRelocationModel - Returns the code generation relocation model. The + /// choices are static, PIC, and dynamic-no-pic, and target default. + static Reloc::Model getRelocationModel(); + + /// setRelocationModel - Sets the code generation relocation model. + static void setRelocationModel(Reloc::Model Model); + /// CodeGenFileType - These enums are meant to be passed into /// addPassesToEmitFile to indicate what type of file to emit. enum CodeGenFileType { diff --git a/include/llvm/Target/TargetOptions.h b/include/llvm/Target/TargetOptions.h index 31fdeb8fed2..e208eba6418 100644 --- a/include/llvm/Target/TargetOptions.h +++ b/include/llvm/Target/TargetOptions.h @@ -40,12 +40,6 @@ namespace llvm { /// produce results that are "less precise" than IEEE allows. This includes /// use of X86 instructions like FSIN and FCOS instead of libcalls. extern bool UnsafeFPMath; - - /// PICEnabled - This flag is enabled when the -enable-pic flag is specified - /// on the command line. When this flag is on, the code generator produces - /// position independant code. - extern bool PICEnabled; - } // End llvm namespace #endif diff --git a/lib/Target/PowerPC/PPC.h b/lib/Target/PowerPC/PPC.h index 1146cdf327a..a12dfdfb112 100644 --- a/lib/Target/PowerPC/PPC.h +++ b/lib/Target/PowerPC/PPC.h @@ -31,7 +31,6 @@ FunctionPass *createPPCISelDag(TargetMachine &TM); FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM); FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM); -extern bool PPCGenerateStaticCode; extern PPCTargetEnum PPCTarget; } // end namespace llvm; diff --git a/lib/Target/PowerPC/PPCAsmPrinter.cpp b/lib/Target/PowerPC/PPCAsmPrinter.cpp index bc19f1659d9..714a36d1e7d 100644 --- a/lib/Target/PowerPC/PPCAsmPrinter.cpp +++ b/lib/Target/PowerPC/PPCAsmPrinter.cpp @@ -132,7 +132,7 @@ namespace { } void printCallOperand(const MachineInstr *MI, unsigned OpNo) { const MachineOperand &MO = MI->getOperand(OpNo); - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { if (MO.getType() == MachineOperand::MO_GlobalAddress) { GlobalValue *GV = MO.getGlobal(); if (((GV->isExternal() || GV->hasWeakLinkage() || @@ -167,7 +167,7 @@ namespace { } else { O << "ha16("; printOp(MI->getOperand(OpNo)); - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\")"; else O << ')'; @@ -179,7 +179,7 @@ namespace { } else { O << "lo16("; printOp(MI->getOperand(OpNo)); - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\")"; else O << ')'; @@ -362,7 +362,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { return; case MachineOperand::MO_ExternalSymbol: // Computing the address of an external symbol, not calling it. - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { std::string Name(GlobalPrefix); Name += MO.getSymbolName(); GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; @@ -377,7 +377,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) { int offset = MO.getOffset(); // External or weakly linked global variables need non-lazily-resolved stubs - if (!PPCGenerateStaticCode) { + if (TM.getRelocationModel() != Reloc::Static) { if (((GV->isExternal() || GV->hasWeakLinkage() || GV->hasLinkOnceLinkage()))) { GVStubs.insert(Name); @@ -585,7 +585,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) { } // Output stubs for dynamically-linked functions - if (PICEnabled) { + if (TM.getRelocationModel() == Reloc::PIC) { for (std::set::iterator i = FnStubs.begin(), e = FnStubs.end(); i != e; ++i) { SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs," diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 5103f272753..d315a2d62b8 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -86,6 +86,9 @@ bool PPCTargetMachine::addPassesToEmitMachineCode(FunctionPassManager &PM, } bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { + assert((MF.getTarget().getRelocationModel() != Reloc::Default || + MF.getTarget().getRelocationModel() != Reloc::Static) && + "JIT relocation model must be set to static or default!"); MCE.startFunction(MF); MCE.emitConstantPool(MF.getConstantPool()); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) @@ -118,7 +121,6 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { } void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - assert(!PICEnabled && "CodeEmitter does not support PIC!"); BBLocations[&MBB] = MCE.getCurrentPCValue(); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ MachineInstr &MI = *I; diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index 003d16c26b1..154fe177ba1 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -396,7 +396,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i32, CP->getAlignment()); SDOperand Zero = DAG.getConstant(0, MVT::i32); - if (PPCGenerateStaticCode) { + if (getTargetMachine().getRelocationModel() == Reloc::Static) { // Generate non-pic code that has direct accesses to the constant pool. // The address of the global is just (hi(&g)+lo(&g)). SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); @@ -407,7 +407,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // Only lower ConstantPool on Darwin. if (!getTargetMachine().getSubtarget().isDarwin()) break; SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, CPI, Zero); - if (PICEnabled) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". Hi = DAG.getNode(ISD::ADD, MVT::i32, DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); @@ -423,7 +423,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32, GSDN->getOffset()); SDOperand Zero = DAG.getConstant(0, MVT::i32); - if (PPCGenerateStaticCode) { + if (getTargetMachine().getRelocationModel() == Reloc::Static) { // Generate non-pic code that has direct accesses to globals. // The address of the global is just (hi(&g)+lo(&g)). SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); @@ -435,7 +435,7 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { if (!getTargetMachine().getSubtarget().isDarwin()) break; SDOperand Hi = DAG.getNode(PPCISD::Hi, MVT::i32, GA, Zero); - if (PICEnabled) { + if (getTargetMachine().getRelocationModel() == Reloc::PIC) { // With PIC, the first instruction is actually "GR+hi(&G)". Hi = DAG.getNode(ISD::ADD, MVT::i32, DAG.getNode(PPCISD::GlobalBaseReg, MVT::i32), Hi); diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp index c7a34280ea7..606dfc09799 100644 --- a/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/lib/Target/PowerPC/PPCSubtarget.cpp @@ -19,7 +19,6 @@ using namespace llvm; PPCTargetEnum llvm::PPCTarget = TargetDefault; -bool llvm::PPCGenerateStaticCode = false; namespace llvm { cl::opt @@ -29,12 +28,7 @@ namespace llvm { clEnumValN(TargetDarwin,"darwin", " Enable Darwin codegen"), clEnumValEnd), - cl::location(PPCTarget), cl::init(TargetDefault)); - - cl::opt - PPCStaticCode("ppc-static", - cl::desc("PowerPC: generate completely non-pic code"), - cl::location(PPCGenerateStaticCode)); + cl::location(PPCTarget), cl::init(TargetDefault)); } #if defined(__APPLE__) diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index a58926ff7e8..9b5701b65e9 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -67,6 +67,11 @@ PPCTargetMachine::PPCTargetMachine(const Module &M, IntrinsicLowering *IL, if (Subtarget.isAIX()) PPCTarget = TargetAIX; if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; } + if (getRelocationModel() == Reloc::Default) + if (Subtarget.isDarwin()) + setRelocationModel(Reloc::DynamicNoPIC); + else + setRelocationModel(Reloc::PIC); } /// addPassesToEmitFile - Add passes to the specified pass manager to implement @@ -129,8 +134,8 @@ bool PPCTargetMachine::addPassesToEmitFile(PassManager &PM, } void PPCJITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - // The JIT does not support or need PIC. - PICEnabled = false; + // The JIT should use static relocation model. + TM.setRelocationModel(Reloc::Static); // Run loop strength reduction before anything else. PM.add(createLoopStrengthReducePass()); diff --git a/lib/Target/TargetMachine.cpp b/lib/Target/TargetMachine.cpp index 82759e8280c..a2a4200b067 100644 --- a/lib/Target/TargetMachine.cpp +++ b/lib/Target/TargetMachine.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Type.h" #include "llvm/CodeGen/IntrinsicLowering.h" #include "llvm/Support/CommandLine.h" @@ -26,7 +27,7 @@ namespace llvm { bool NoFramePointerElim; bool NoExcessFPPrecision; bool UnsafeFPMath; - bool PICEnabled; + Reloc::Model RelocationModel; }; namespace { cl::opt PrintCode("print-machineinstrs", @@ -48,11 +49,22 @@ namespace { cl::desc("Enable optimizations that may decrease FP precision"), cl::location(UnsafeFPMath), cl::init(false)); - cl::opt - EnablePIC("enable-pic", - cl::desc("Enable generation of position independant code"), - cl::location(PICEnabled), - cl::init(false)); + cl::opt + DefRelocationModel( + "relocation-model", + cl::desc("Choose relocation model"), + cl::location(RelocationModel), + cl::init(Reloc::Default), + cl::values( + clEnumValN(Reloc::Default, "default", + "Target default relocation model"), + clEnumValN(Reloc::Static, "static", + "Non-relocatable code"), + clEnumValN(Reloc::PIC, "pic", + "Fully relocatable, position independent code"), + clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic", + "Relocatable external references, non-relocatable code"), + clEnumValEnd)); }; //--------------------------------------------------------------------------- @@ -87,3 +99,13 @@ TargetMachine::~TargetMachine() { delete IL; } +/// getRelocationModel - Returns the code generation relocation model. The +/// choices are static, PIC, and dynamic-no-pic, and target default. +Reloc::Model TargetMachine::getRelocationModel() { + return RelocationModel; +} + +/// setRelocationModel - Sets the code generation relocation model. +void TargetMachine::setRelocationModel(Reloc::Model Model) { + RelocationModel = Model; +} diff --git a/lib/Target/X86/X86ATTAsmPrinter.cpp b/lib/Target/X86/X86ATTAsmPrinter.cpp index 9b43873f290..f1774fd8946 100755 --- a/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -119,7 +119,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << '$'; // Darwin block shameless ripped from PPCAsmPrinter.cpp - if (forDarwin) { + if (forDarwin && TM.getRelocationModel() != Reloc::Static) { GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); // Link-once, External, or Weakly-linked global variables need @@ -133,7 +133,7 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { @@ -150,14 +150,14 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo, } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (isCallOp && forDarwin) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) { + std::string Name(GlobalPrefix); + Name += MO.getSymbolName(); FnStubs.insert(Name); O << "L" << Name << "$stub"; return; } - if (!isMemOp && !isCallOp) O << '$'; + if (!isCallOp) O << '$'; O << GlobalPrefix << MO.getSymbolName(); return; } @@ -198,7 +198,7 @@ void X86ATTAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ } else if (BaseReg.isConstantPoolIndex()) { O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" << BaseReg.getConstantPoolIndex(); - if (forDarwin && PICEnabled) + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; if (DispSpec.getImmedValue()) O << "+" << DispSpec.getImmedValue(); diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 0c0ed538ab2..772f1abc204 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -77,6 +77,9 @@ FunctionPass *llvm::createX86CodeEmitterPass(MachineCodeEmitter &MCE) { } bool Emitter::runOnMachineFunction(MachineFunction &MF) { + assert((MF.getTarget().getRelocationModel() != Reloc::Default || + MF.getTarget().getRelocationModel() != Reloc::Static) && + "JIT relocation model must be set to static or default!"); II = ((X86TargetMachine&)MF.getTarget()).getInstrInfo(); MCE.startFunction(MF); @@ -97,7 +100,6 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) { } void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) { - assert(!PICEnabled && "CodeEmitter does not support PIC!"); if (uint64_t Addr = MCE.getCurrentPCValue()) BasicBlockAddrs[&MBB] = Addr; diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 77fc52bc457..105e6cebcb6 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1836,7 +1836,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { if (getTargetMachine(). getSubtarget().isTargetDarwin()) { // With PIC, the address is actually $g + Offset. - if (PICEnabled) + if (getTargetMachine().getRelocationModel() == Reloc::PIC) Result = DAG.getNode(ISD::ADD, getPointerTy(), DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Result); } @@ -1851,7 +1851,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { GlobalValue *GV = cast(Op)->getGlobal(); SDOperand Addr = DAG.getTargetGlobalAddress(GV, getPointerTy()); // With PIC, the address is actually $g + Offset. - if (PICEnabled) + if (getTargetMachine().getRelocationModel() == Reloc::PIC) Addr = DAG.getNode(ISD::ADD, getPointerTy(), DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()), Addr); @@ -1859,8 +1859,9 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { // the value at address GV, not the value of GV itself. This means that // the GlobalAddress must be in the base or index register of the address, // not the GV offset field. - if (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isExternal() && !GV->hasNotBeenReadFromBytecode())) + if (getTargetMachine().getRelocationModel() != Reloc::Static && + (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))) Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), Addr, DAG.getSrcValue(NULL)); } diff --git a/lib/Target/X86/X86IntelAsmPrinter.cpp b/lib/Target/X86/X86IntelAsmPrinter.cpp index 90fe3ac6492..1a5aba16608 100755 --- a/lib/Target/X86/X86IntelAsmPrinter.cpp +++ b/lib/Target/X86/X86IntelAsmPrinter.cpp @@ -113,7 +113,7 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, bool isCallOp = Modifier && !strcmp(Modifier, "call"); bool isMemOp = Modifier && !strcmp(Modifier, "mem"); if (!isMemOp && !isCallOp) O << "OFFSET "; - if (forDarwin) { + if (forDarwin && TM.getRelocationModel() != Reloc::Static) { GlobalValue *GV = MO.getGlobal(); std::string Name = Mang->getValueName(GV); if (!isMemOp && !isCallOp) O << '$'; @@ -128,7 +128,7 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, } else { GVStubs.insert(Name); O << "L" << Name << "$non_lazy_ptr"; - if (PICEnabled) + if (TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; } } else { @@ -145,13 +145,14 @@ void X86IntelAsmPrinter::printOp(const MachineOperand &MO, } case MachineOperand::MO_ExternalSymbol: { bool isCallOp = Modifier && !strcmp(Modifier, "call"); - bool isMemOp = Modifier && !strcmp(Modifier, "mem"); - if (isCallOp && forDarwin) { - std::string Name(GlobalPrefix); Name += MO.getSymbolName(); + if (isCallOp && forDarwin && TM.getRelocationModel() != Reloc::Static) { + std::string Name(GlobalPrefix); + Name += MO.getSymbolName(); FnStubs.insert(Name); O << "L" << Name << "$stub"; return; } + if (!isCallOp) O << "OFFSET "; O << GlobalPrefix << MO.getSymbolName(); return; } @@ -177,7 +178,7 @@ void X86IntelAsmPrinter::printMemReference(const MachineInstr *MI, unsigned Op){ } else if (BaseReg.isConstantPoolIndex()) { O << "[" << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_" << BaseReg.getConstantPoolIndex(); - if (forDarwin && PICEnabled) + if (forDarwin && TM.getRelocationModel() == Reloc::PIC) O << "-\"L" << getFunctionNumber() << "$pb\""; if (IndexReg.getReg()) { diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index f24e1b026a9..8adce3115de 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -76,6 +76,11 @@ X86TargetMachine::X86TargetMachine(const Module &M, FrameInfo(TargetFrameInfo::StackGrowsDown, Subtarget.getStackAlignment(), -4), JITInfo(*this) { + if (getRelocationModel() == Reloc::Default) + if (Subtarget.isTargetDarwin()) + setRelocationModel(Reloc::DynamicNoPIC); + else + setRelocationModel(Reloc::PIC); } @@ -149,8 +154,8 @@ bool X86TargetMachine::addPassesToEmitFile(PassManager &PM, std::ostream &Out, /// not supported for this target. /// void X86JITInfo::addPassesToJITCompile(FunctionPassManager &PM) { - // The JIT does not support or need PIC. - PICEnabled = false; + // The JIT should use static relocation model. + TM.setRelocationModel(Reloc::Static); // FIXME: Implement efficient support for garbage collection intrinsics. PM.add(createLowerGCPass());