[llvm-commits] [llvm] r45575 - in /llvm/trunk: include/llvm/CodeGen/MachineRelocation.h include/llvm/Target/TargetJITInfo.h lib/ExecutionEngine/JIT/JITEmitter.cpp lib/Target/X86/X86CodeEmitter.cpp lib/Target/X86/X86JITInfo.cpp lib/Target/X86/X86JITInfo.h
Evan Cheng
evan.cheng at apple.com
Fri Jan 4 02:46:53 PST 2008
Author: evancheng
Date: Fri Jan 4 04:46:51 2008
New Revision: 45575
URL: http://llvm.org/viewvc/llvm-project?rev=45575&view=rev
Log:
X86 PIC JIT support fixes: encoding bugs, add lazy pointer stubs support.
Modified:
llvm/trunk/include/llvm/CodeGen/MachineRelocation.h
llvm/trunk/include/llvm/Target/TargetJITInfo.h
llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
llvm/trunk/lib/Target/X86/X86JITInfo.cpp
llvm/trunk/lib/Target/X86/X86JITInfo.h
Modified: llvm/trunk/include/llvm/CodeGen/MachineRelocation.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineRelocation.h?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineRelocation.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineRelocation.h Fri Jan 4 04:46:51 2008
@@ -39,6 +39,7 @@
enum AddressType {
isResult, // Relocation has be transformed into its result pointer.
isGV, // The Target.GV field is valid.
+ isGVLazyPtr, // Relocation of a lazily resolved GV address.
isBB, // Relocation of BB address.
isExtSym, // The Target.ExtSym field is valid.
isConstPool, // Relocation of constant pool address.
@@ -55,7 +56,7 @@
union {
void *Result; // If this has been resolved to a resolved pointer
- GlobalValue *GV; // If this is a pointer to an LLVM global
+ GlobalValue *GV; // If this is a pointer to a GV or a GV lazy ptr
MachineBasicBlock *MBB; // If this is a pointer to a LLVM BB
const char *ExtSym; // If this is a pointer to a named symbol
unsigned Index; // Constant pool / jump table index
@@ -93,6 +94,25 @@
return Result;
}
+ /// MachineRelocation::getGVLazyPtr - Return a relocation entry for a
+ /// lazily resolved GlobalValue address.
+ static MachineRelocation getGVLazyPtr(intptr_t offset,
+ unsigned RelocationType,
+ GlobalValue *GV, intptr_t cst = 0,
+ bool NeedStub = 0,
+ bool GOTrelative = 0) {
+ assert((RelocationType & ~63) == 0 && "Relocation type too large!");
+ MachineRelocation Result;
+ Result.Offset = offset;
+ Result.ConstantVal = cst;
+ Result.TargetReloType = RelocationType;
+ Result.AddrType = isGVLazyPtr;
+ Result.NeedStub = NeedStub;
+ Result.GOTRelative = GOTrelative;
+ Result.Target.GV = GV;
+ return Result;
+ }
+
/// MachineRelocation::getBB - Return a relocation entry for a BB.
///
static MachineRelocation getBB(intptr_t offset,unsigned RelocationType,
@@ -193,6 +213,12 @@
return AddrType == isGV;
}
+ /// isGlobalValueVLazyPtr - Return true if this relocation is the address
+ /// of a lazily resolved GlobalValue.
+ bool isGlobalValueLazyPtr() const {
+ return AddrType == isGVLazyPtr;
+ }
+
/// isBasicBlock - Return true if this relocation is a basic block reference.
///
bool isBasicBlock() const {
@@ -234,7 +260,8 @@
/// getGlobalValue - If this is a global value reference, return the
/// referenced global.
GlobalValue *getGlobalValue() const {
- assert(isGlobalValue() && "This is not a global value reference!");
+ assert((isGlobalValue() || isGlobalValueLazyPtr()) &&
+ "This is not a global value reference!");
return Target.GV;
}
Modified: llvm/trunk/include/llvm/Target/TargetJITInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetJITInfo.h?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetJITInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetJITInfo.h Fri Jan 4 04:46:51 2008
@@ -40,6 +40,13 @@
///
virtual void replaceMachineCodeForFunction(void *Old, void *New) = 0;
+ /// emitGlobalValueLazyPtr - Use the specified MachineCodeEmitter object to
+ /// emit a lazy pointer which contains the address of the specified GV.
+ virtual void *emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE) {
+ assert(0 && "This target doesn't implement emitGlobalValueLazyPtr!");
+ return 0;
+ }
+
/// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
/// small native function that simply calls the function at the specified
/// address. Return the address of the resultant function.
Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Fri Jan 4 04:46:51 2008
@@ -52,6 +52,10 @@
/// corresponds to.
std::map<void*, Function*> StubToFunctionMap;
+ /// GlobalToLazyPtrMap - Keep track of the lazy pointer created for a
+ /// particular GlobalVariable so that we can reuse them if necessary.
+ std::map<GlobalValue*, void*> GlobalToLazyPtrMap;
+
public:
std::map<Function*, void*>& getFunctionToStubMap(const MutexGuard& locked) {
assert(locked.holds(TheJIT->lock));
@@ -62,6 +66,12 @@
assert(locked.holds(TheJIT->lock));
return StubToFunctionMap;
}
+
+ std::map<GlobalValue*, void*>&
+ getGlobalToLazyPtrMap(const MutexGuard& locked) {
+ assert(locked.holds(TheJIT->lock));
+ return GlobalToLazyPtrMap;
+ }
};
/// JITResolver - Keep track of, and resolve, call sites for functions that
@@ -103,6 +113,10 @@
/// specified address, created lazily on demand.
void *getExternalFunctionStub(void *FnAddr);
+ /// getGlobalValueLazyPtr - Return a lazy pointer containing the specified
+ /// GV address.
+ void *getGlobalValueLazyPtr(GlobalValue *V, void *GVAddress);
+
/// AddCallbackAtLocation - If the target is capable of rewriting an
/// instruction without the use of a stub, record the location of the use so
/// we know which function is being used at the location.
@@ -181,6 +195,25 @@
return Stub;
}
+/// getGlobalValueLazyPtr - Return a lazy pointer containing the specified
+/// GV address.
+void *JITResolver::getGlobalValueLazyPtr(GlobalValue *GV, void *GVAddress) {
+ MutexGuard locked(TheJIT->lock);
+
+ // If we already have a stub for this global variable, recycle it.
+ void *&LazyPtr = state.getGlobalToLazyPtrMap(locked)[GV];
+ if (LazyPtr) return LazyPtr;
+
+ // Otherwise, codegen a new lazy pointer.
+ LazyPtr = TheJIT->getJITInfo().emitGlobalValueLazyPtr(GVAddress,
+ *TheJIT->getCodeEmitter());
+
+ DOUT << "JIT: Stub emitted at [" << LazyPtr << "] for GV '"
+ << GV->getName() << "'\n";
+
+ return LazyPtr;
+}
+
/// getExternalFunctionStub - Return a stub for the function at the
/// specified address, created lazily on demand.
void *JITResolver::getExternalFunctionStub(void *FnAddr) {
@@ -361,6 +394,8 @@
}
private:
void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub);
+ void *getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
+ bool NoNeedStub);
};
}
@@ -396,6 +431,16 @@
return Resolver.getFunctionStub(F);
}
+void *JITEmitter::getPointerToGVLazyPtr(GlobalValue *V, void *Reference,
+ bool DoesntNeedStub) {
+ // Make sure GV is emitted first.
+ // FIXME: For now, if the GV is an external function we force the JIT to
+ // compile it so the lazy pointer will contain the fully resolved address.
+ void *GVAddress = getPointerToGlobal(V, Reference, true);
+ return Resolver.getGlobalValueLazyPtr(V, GVAddress);
+}
+
+
void JITEmitter::startFunction(MachineFunction &F) {
uintptr_t ActualSize;
BufferBegin = CurBufferPtr = MemMgr->startFunctionBody(F.getFunction(),
@@ -450,6 +495,10 @@
ResultPtr = getPointerToGlobal(MR.getGlobalValue(),
BufferBegin+MR.getMachineCodeOffset(),
MR.doesntNeedStub());
+ } else if (MR.isGlobalValueLazyPtr()) {
+ ResultPtr = getPointerToGVLazyPtr(MR.getGlobalValue(),
+ BufferBegin+MR.getMachineCodeOffset(),
+ MR.doesntNeedStub());
} else if (MR.isBasicBlock()) {
ResultPtr = (void*)getMachineBasicBlockAddress(MR.getBasicBlock());
} else if (MR.isConstantPoolIndex()) {
Modified: llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86CodeEmitter.cpp Fri Jan 4 04:46:51 2008
@@ -40,20 +40,17 @@
intptr_t PICBase;
bool Is64BitMode;
bool IsPIC;
- bool IsStatic;
public:
static char ID;
explicit Emitter(TargetMachine &tm, MachineCodeEmitter &mce)
: MachineFunctionPass((intptr_t)&ID), II(0), TD(0), TM(tm),
MCE(mce), PICBase(0), Is64BitMode(false),
- IsPIC(TM.getRelocationModel() == Reloc::PIC_),
- IsStatic(TM.getRelocationModel() == Reloc::Static) {}
+ IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
Emitter(TargetMachine &tm, MachineCodeEmitter &mce,
const X86InstrInfo &ii, const TargetData &td, bool is64)
: MachineFunctionPass((intptr_t)&ID), II(&ii), TD(&td), TM(tm),
MCE(mce), PICBase(0), Is64BitMode(is64),
- IsPIC(TM.getRelocationModel() == Reloc::PIC_),
- IsStatic(TM.getRelocationModel() == Reloc::Static) {}
+ IsPIC(TM.getRelocationModel() == Reloc::PIC_) {}
bool runOnMachineFunction(MachineFunction &MF);
@@ -67,7 +64,7 @@
void emitPCRelativeBlockAddress(MachineBasicBlock *MBB);
void emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
int Disp = 0, intptr_t PCAdj = 0,
- bool NeedStub = false);
+ bool NeedStub = false, bool IsLazy = false);
void emitExternalSymbolAddress(const char *ES, unsigned Reloc);
void emitConstPoolAddress(unsigned CPI, unsigned Reloc, int Disp = 0,
intptr_t PCAdj = 0);
@@ -88,6 +85,8 @@
unsigned getX86RegNum(unsigned RegNo);
bool isX86_64ExtendedReg(const MachineOperand &MO);
unsigned determineREX(const MachineInstr &MI);
+
+ bool gvNeedsLazyPtr(const GlobalValue *GV);
};
char Emitter::ID = 0;
}
@@ -103,10 +102,9 @@
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();
- TD = ((X86TargetMachine&)MF.getTarget()).getTargetData();
- Is64BitMode =
- ((X86TargetMachine&)MF.getTarget()).getSubtarget<X86Subtarget>().is64Bit();
+ II = ((X86TargetMachine&)TM).getInstrInfo();
+ TD = ((X86TargetMachine&)TM).getTargetData();
+ Is64BitMode = TM.getSubtarget<X86Subtarget>().is64Bit();
do {
MCE.startFunction(MF);
@@ -139,11 +137,19 @@
///
void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc,
int Disp /* = 0 */, intptr_t PCAdj /* = 0 */,
- bool NeedStub /* = false */) {
+ bool NeedStub /* = false */,
+ bool isLazy /* = false */) {
+ intptr_t RelocCST = 0;
if (Reloc == X86::reloc_picrel_word)
- PCAdj += PICBase;
- MCE.addRelocation(MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
- GV, PCAdj, NeedStub));
+ RelocCST = PICBase;
+ else if (Reloc == X86::reloc_pcrel_word)
+ RelocCST = PCAdj;
+ MachineRelocation MR = isLazy
+ ? MachineRelocation::getGVLazyPtr(MCE.getCurrentPCOffset(), Reloc,
+ GV, RelocCST, NeedStub)
+ : MachineRelocation::getGV(MCE.getCurrentPCOffset(), Reloc,
+ GV, RelocCST, NeedStub);
+ MCE.addRelocation(MR);
if (Reloc == X86::reloc_absolute_dword)
MCE.emitWordLE(0);
MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
@@ -153,9 +159,9 @@
/// be emitted to the current location in the function, and allow it to be PC
/// relative.
void Emitter::emitExternalSymbolAddress(const char *ES, unsigned Reloc) {
- intptr_t PCAdj = (Reloc == X86::reloc_picrel_word) ? PICBase : 0;
+ intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBase : 0;
MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(),
- Reloc, ES, PCAdj));
+ Reloc, ES, RelocCST));
if (Reloc == X86::reloc_absolute_dword)
MCE.emitWordLE(0);
MCE.emitWordLE(0);
@@ -167,10 +173,13 @@
void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc,
int Disp /* = 0 */,
intptr_t PCAdj /* = 0 */) {
+ intptr_t RelocCST = 0;
if (Reloc == X86::reloc_picrel_word)
- PCAdj += PICBase;
+ RelocCST = PICBase;
+ else if (Reloc == X86::reloc_pcrel_word)
+ RelocCST = PCAdj;
MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(),
- Reloc, CPI, PCAdj));
+ Reloc, CPI, RelocCST));
if (Reloc == X86::reloc_absolute_dword)
MCE.emitWordLE(0);
MCE.emitWordLE(Disp); // The relocated value will be added to the displacement
@@ -181,10 +190,13 @@
/// relative.
void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc,
intptr_t PCAdj /* = 0 */) {
+ intptr_t RelocCST = 0;
if (Reloc == X86::reloc_picrel_word)
- PCAdj += PICBase;
+ RelocCST = PICBase;
+ else if (Reloc == X86::reloc_pcrel_word)
+ RelocCST = PCAdj;
MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(),
- Reloc, JTI, PCAdj));
+ Reloc, JTI, RelocCST));
if (Reloc == X86::reloc_absolute_dword)
MCE.emitWordLE(0);
MCE.emitWordLE(0); // The relocated value will be added to the displacement
@@ -223,6 +235,11 @@
return Value == (signed char)Value;
}
+bool Emitter::gvNeedsLazyPtr(const GlobalValue *GV) {
+ return !Is64BitMode &&
+ TM.getSubtarget<X86Subtarget>().GVRequiresExtraLoad(GV, TM, false);
+}
+
void Emitter::emitDisplacementField(const MachineOperand *RelocOp,
int DispVal, intptr_t PCAdj) {
// If this is a simple integer displacement that doesn't require a relocation,
@@ -241,9 +258,10 @@
// 89 04 25 00 00 00 00 mov %eax,0x0 # Absolute
unsigned rt = Is64BitMode ? X86::reloc_pcrel_word
: (IsPIC ? X86::reloc_picrel_word : X86::reloc_absolute_word);
- bool NeedStub = !IsStatic || isa<Function>(RelocOp->getGlobal());
+ bool NeedStub = isa<Function>(RelocOp->getGlobal());
+ bool isLazy = gvNeedsLazyPtr(RelocOp->getGlobal());
emitGlobalAddress(RelocOp->getGlobal(), rt, RelocOp->getOffset(),
- PCAdj, NeedStub);
+ PCAdj, NeedStub, isLazy);
} else if (RelocOp->isConstantPoolIndex()) {
unsigned rt = Is64BitMode ? X86::reloc_pcrel_word : X86::reloc_picrel_word;
emitConstPoolAddress(RelocOp->getIndex(), rt,
@@ -601,8 +619,7 @@
if (MO.isMachineBasicBlock()) {
emitPCRelativeBlockAddress(MO.getMBB());
} else if (MO.isGlobalAddress()) {
- bool NeedStub = !IsStatic ||
- (Is64BitMode && TM.getCodeModel() == CodeModel::Large);
+ bool NeedStub = Is64BitMode && TM.getCodeModel() == CodeModel::Large;
emitGlobalAddress(MO.getGlobal(), X86::reloc_pcrel_word,
0, 0, NeedStub);
} else if (MO.isExternalSymbol()) {
@@ -634,8 +651,10 @@
if (Opcode == X86::MOV64ri)
rt = X86::reloc_absolute_dword; // FIXME: add X86II flag?
if (MO1.isGlobalAddress()) {
- bool NeedStub = !IsStatic || isa<Function>(MO1.getGlobal());
- emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0, NeedStub);
+ bool NeedStub = isa<Function>(MO1.getGlobal());
+ bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
+ emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
+ NeedStub, isLazy);
} else if (MO1.isExternalSymbol())
emitExternalSymbolAddress(MO1.getSymbolName(), rt);
else if (MO1.isConstantPoolIndex())
@@ -704,8 +723,10 @@
if (Opcode == X86::MOV64ri32)
rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
if (MO1.isGlobalAddress()) {
- bool NeedStub = !IsStatic || isa<Function>(MO1.getGlobal());
- emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0, NeedStub);
+ bool NeedStub = isa<Function>(MO1.getGlobal());
+ bool isLazy = gvNeedsLazyPtr(MO1.getGlobal());
+ emitGlobalAddress(MO1.getGlobal(), rt, MO1.getOffset(), 0,
+ NeedStub, isLazy);
} else if (MO1.isExternalSymbol())
emitExternalSymbolAddress(MO1.getSymbolName(), rt);
else if (MO1.isConstantPoolIndex())
@@ -739,8 +760,10 @@
if (Opcode == X86::MOV64mi32)
rt = X86::reloc_absolute_word; // FIXME: add X86II flag?
if (MO.isGlobalAddress()) {
- bool NeedStub = !IsStatic || isa<Function>(MO.getGlobal());
- emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0, NeedStub);
+ bool NeedStub = isa<Function>(MO.getGlobal());
+ bool isLazy = gvNeedsLazyPtr(MO.getGlobal());
+ emitGlobalAddress(MO.getGlobal(), rt, MO.getOffset(), 0,
+ NeedStub, isLazy);
} else if (MO.isExternalSymbol())
emitExternalSymbolAddress(MO.getSymbolName(), rt);
else if (MO.isConstantPoolIndex())
Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.cpp?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.cpp Fri Jan 4 04:46:51 2008
@@ -380,6 +380,18 @@
return X86CompilationCallback;
}
+void *X86JITInfo::emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE) {
+#ifdef __x86_64__
+ MCE.startFunctionStub(8, 8);
+ MCE.emitWordLE(((unsigned *)&GV)[0]);
+ MCE.emitWordLE(((unsigned *)&GV)[1]);
+#else
+ MCE.startFunctionStub(4, 4);
+ MCE.emitWordLE((unsigned)GV);
+#endif
+ return MCE.finishFunctionStub(0);
+}
+
void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) {
// Note, we cast to intptr_t here to silence a -pedantic warning that
// complains about casting a function pointer to a normal pointer.
Modified: llvm/trunk/lib/Target/X86/X86JITInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.h?rev=45575&r1=45574&r2=45575&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.h Fri Jan 4 04:46:51 2008
@@ -31,6 +31,10 @@
///
virtual void replaceMachineCodeForFunction(void *Old, void *New);
+ /// emitGlobalValueLazyPtr - Use the specified MachineCodeEmitter object to
+ /// emit a lazy pointer which contains the address of the specified GV.
+ virtual void *emitGlobalValueLazyPtr(void *GV, MachineCodeEmitter &MCE);
+
/// emitFunctionStub - Use the specified MachineCodeEmitter object to emit a
/// small native function that simply calls the function at the specified
/// address.
More information about the llvm-commits
mailing list