class Pass;
class IntrinsicLowering;
+// Relocation model types.
+namespace Reloc {
+ enum Model {
+ Default,
+ Static,
+ PIC,
+ DynamicNoPIC
+ };
+}
+
//===----------------------------------------------------------------------===//
///
/// TargetMachine - Primary interface to the complete machine description for
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 {
/// 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
FunctionPass *createDarwinAsmPrinter(std::ostream &OS, TargetMachine &TM);
FunctionPass *createAIXAsmPrinter(std::ostream &OS, TargetMachine &TM);
-extern bool PPCGenerateStaticCode;
extern PPCTargetEnum PPCTarget;
} // end namespace llvm;
}
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() ||
} else {
O << "ha16(";
printOp(MI->getOperand(OpNo));
- if (PICEnabled)
+ if (TM.getRelocationModel() == Reloc::PIC)
O << "-\"L" << getFunctionNumber() << "$pb\")";
else
O << ')';
} else {
O << "lo16(";
printOp(MI->getOperand(OpNo));
- if (PICEnabled)
+ if (TM.getRelocationModel() == Reloc::PIC)
O << "-\"L" << getFunctionNumber() << "$pb\")";
else
O << ')';
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";
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);
}
// Output stubs for dynamically-linked functions
- if (PICEnabled) {
+ if (TM.getRelocationModel() == Reloc::PIC) {
for (std::set<std::string>::iterator i = FnStubs.begin(), e = FnStubs.end();
i != e; ++i) {
SwitchSection(".section __TEXT,__picsymbolstub1,symbol_stubs,"
}
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)
}
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;
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);
// Only lower ConstantPool on Darwin.
if (!getTargetMachine().getSubtarget<PPCSubtarget>().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);
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);
if (!getTargetMachine().getSubtarget<PPCSubtarget>().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);
using namespace llvm;
PPCTargetEnum llvm::PPCTarget = TargetDefault;
-bool llvm::PPCGenerateStaticCode = false;
namespace llvm {
cl::opt<PPCTargetEnum, true>
clEnumValN(TargetDarwin,"darwin",
" Enable Darwin codegen"),
clEnumValEnd),
- cl::location(PPCTarget), cl::init(TargetDefault));
-
- cl::opt<bool, true>
- PPCStaticCode("ppc-static",
- cl::desc("PowerPC: generate completely non-pic code"),
- cl::location(PPCGenerateStaticCode));
+ cl::location(PPCTarget), cl::init(TargetDefault));
}
#if defined(__APPLE__)
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
}
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());
//===----------------------------------------------------------------------===//
#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
#include "llvm/Type.h"
#include "llvm/CodeGen/IntrinsicLowering.h"
#include "llvm/Support/CommandLine.h"
bool NoFramePointerElim;
bool NoExcessFPPrecision;
bool UnsafeFPMath;
- bool PICEnabled;
+ Reloc::Model RelocationModel;
};
namespace {
cl::opt<bool, true> PrintCode("print-machineinstrs",
cl::desc("Enable optimizations that may decrease FP precision"),
cl::location(UnsafeFPMath),
cl::init(false));
- cl::opt<bool, true>
- EnablePIC("enable-pic",
- cl::desc("Enable generation of position independant code"),
- cl::location(PICEnabled),
- cl::init(false));
+ cl::opt<llvm::Reloc::Model, true>
+ 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));
};
//---------------------------------------------------------------------------
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;
+}
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
} else {
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
- if (PICEnabled)
+ if (TM.getRelocationModel() == Reloc::PIC)
O << "-\"L" << getFunctionNumber() << "$pb\"";
}
} else {
}
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;
}
} 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();
}
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);
}
void Emitter::emitBasicBlock(const MachineBasicBlock &MBB) {
- assert(!PICEnabled && "CodeEmitter does not support PIC!");
if (uint64_t Addr = MCE.getCurrentPCValue())
BasicBlockAddrs[&MBB] = Addr;
if (getTargetMachine().
getSubtarget<X86Subtarget>().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);
}
GlobalValue *GV = cast<GlobalAddressSDNode>(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);
// 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));
}
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 << '$';
} else {
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
- if (PICEnabled)
+ if (TM.getRelocationModel() == Reloc::PIC)
O << "-\"L" << getFunctionNumber() << "$pb\"";
}
} else {
}
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;
}
} 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()) {
FrameInfo(TargetFrameInfo::StackGrowsDown,
Subtarget.getStackAlignment(), -4),
JITInfo(*this) {
+ if (getRelocationModel() == Reloc::Default)
+ if (Subtarget.isTargetDarwin())
+ setRelocationModel(Reloc::DynamicNoPIC);
+ else
+ setRelocationModel(Reloc::PIC);
}
/// 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());