From 2a3e08b5961353fa3faeadf81f481ae9f5463427 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sat, 5 Jan 2008 02:26:58 +0000 Subject: [PATCH] X86 JIT PIC jumptable support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45616 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/MachineCodeEmitter.h | 1 + include/llvm/Target/TargetJITInfo.h | 7 +++++++ lib/ExecutionEngine/JIT/JITEmitter.cpp | 10 ++++++---- lib/Target/X86/X86CodeEmitter.cpp | 23 ++++++++++++++--------- lib/Target/X86/X86JITInfo.cpp | 6 ++++++ lib/Target/X86/X86JITInfo.h | 10 ++++++++++ 6 files changed, 44 insertions(+), 13 deletions(-) diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index ede40d13cfb..2c207f22f85 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -58,6 +58,7 @@ protected: /// all code emission requests will be ignored (this is the buffer overflow /// condition). unsigned char *CurBufferPtr; + public: virtual ~MachineCodeEmitter() {} diff --git a/include/llvm/Target/TargetJITInfo.h b/include/llvm/Target/TargetJITInfo.h index 3be6cb79ce9..1ad927b9b04 100644 --- a/include/llvm/Target/TargetJITInfo.h +++ b/include/llvm/Target/TargetJITInfo.h @@ -55,6 +55,13 @@ namespace llvm { return 0; } + /// getPICJumpTableEntry - Returns the value of the jumptable entry for the + /// specific basic block. + virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase) { + assert(0 && "This target doesn't implement getPICJumpTableEntry!"); + return 0; + } + /// LazyResolverFn - This typedef is used to represent the function that /// unresolved call points should invoke. This is a target specific /// function that knows how to walk the stack and find out which stub the diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index aa572a408f8..049b3bc4a36 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -341,7 +341,7 @@ namespace { /// JumpTableBase - A pointer to the first entry in the jump table. /// void *JumpTableBase; - + /// Resolver - This contains info about the currently resolved functions. JITResolver Resolver; public: @@ -380,7 +380,7 @@ namespace { virtual intptr_t getConstantPoolEntryAddress(unsigned Entry) const; virtual intptr_t getJumpTableEntryAddress(unsigned Entry) const; - + virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { assert(MBBLocations.size() > (unsigned)MBB->getNumber() && MBBLocations[MBB->getNumber()] && "MBB not emitted!"); @@ -616,8 +616,10 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { // Store the offset of the basic block for this jump table slot in the // memory we allocated for the jump table in 'initJumpTableInfo' intptr_t Base = (intptr_t)SlotPtr; - for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) - *SlotPtr++ = (intptr_t)getMachineBasicBlockAddress(MBBs[mi]) - Base; + for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) { + intptr_t MBBAddr = getMachineBasicBlockAddress(MBBs[mi]); + *SlotPtr++ = TheJIT->getJITInfo().getPICJumpTableEntry(MBBAddr, Base); + } } } else { assert(MJTI->getEntrySize() == sizeof(void*) && "Cross JIT'ing?"); diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index d531fd5f7b6..bc2c007a6bc 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -14,6 +14,7 @@ #define DEBUG_TYPE "x86-emitter" #include "X86InstrInfo.h" +#include "X86JITInfo.h" #include "X86Subtarget.h" #include "X86TargetMachine.h" #include "X86Relocations.h" @@ -37,19 +38,19 @@ namespace { const TargetData *TD; TargetMachine &TM; MachineCodeEmitter &MCE; - intptr_t PICBase; + intptr_t PICBaseOffset; bool Is64BitMode; bool IsPIC; 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), + MCE(mce), PICBaseOffset(0), Is64BitMode(false), 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), + MCE(mce), PICBaseOffset(0), Is64BitMode(is64), IsPIC(TM.getRelocationModel() == Reloc::PIC_) {} bool runOnMachineFunction(MachineFunction &MF); @@ -148,7 +149,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc, bool isLazy /* = false */) { intptr_t RelocCST = 0; if (Reloc == X86::reloc_picrel_word) - RelocCST = PICBase; + RelocCST = PICBaseOffset; else if (Reloc == X86::reloc_pcrel_word) RelocCST = PCAdj; MachineRelocation MR = isLazy @@ -166,7 +167,7 @@ void Emitter::emitGlobalAddress(GlobalValue *GV, unsigned Reloc, /// 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 RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBase : 0; + intptr_t RelocCST = (Reloc == X86::reloc_picrel_word) ? PICBaseOffset : 0; MCE.addRelocation(MachineRelocation::getExtSym(MCE.getCurrentPCOffset(), Reloc, ES, RelocCST)); if (Reloc == X86::reloc_absolute_dword) @@ -182,7 +183,7 @@ void Emitter::emitConstPoolAddress(unsigned CPI, unsigned Reloc, intptr_t PCAdj /* = 0 */) { intptr_t RelocCST = 0; if (Reloc == X86::reloc_picrel_word) - RelocCST = PICBase; + RelocCST = PICBaseOffset; else if (Reloc == X86::reloc_pcrel_word) RelocCST = PCAdj; MCE.addRelocation(MachineRelocation::getConstPool(MCE.getCurrentPCOffset(), @@ -199,7 +200,7 @@ void Emitter::emitJumpTableAddress(unsigned JTI, unsigned Reloc, intptr_t PCAdj /* = 0 */) { intptr_t RelocCST = 0; if (Reloc == X86::reloc_picrel_word) - RelocCST = PICBase; + RelocCST = PICBaseOffset; else if (Reloc == X86::reloc_pcrel_word) RelocCST = PCAdj; MCE.addRelocation(MachineRelocation::getJumpTable(MCE.getCurrentPCOffset(), @@ -615,13 +616,17 @@ void Emitter::emitInstruction(const MachineInstr &MI, case X86::FP_REG_KILL: break; #endif - case X86::MOVPC32r: + case X86::MOVPC32r: { // This emits the "call" portion of this pseudo instruction. MCE.emitByte(BaseOpcode); emitConstant(0, sizeOfImm(Desc)); - PICBase = MCE.getCurrentPCOffset(); + // Remember PIC base. + PICBaseOffset = MCE.getCurrentPCOffset(); + X86JITInfo *JTI = dynamic_cast(TM.getJITInfo()); + JTI->setPICBase(MCE.getCurrentPCValue()); break; } + } CurOp = NumOps; break; diff --git a/lib/Target/X86/X86JITInfo.cpp b/lib/Target/X86/X86JITInfo.cpp index d5d3cda2dc6..dd451176568 100644 --- a/lib/Target/X86/X86JITInfo.cpp +++ b/lib/Target/X86/X86JITInfo.cpp @@ -440,6 +440,12 @@ void *X86JITInfo::emitFunctionStub(void *Fn, MachineCodeEmitter &MCE) { return MCE.finishFunctionStub(0); } +/// getPICJumpTableEntry - Returns the value of the jumptable entry for the +/// specific basic block. +intptr_t X86JITInfo::getPICJumpTableEntry(intptr_t BB, intptr_t Entry) { + return BB - PICBase; +} + /// relocate - Before the JIT can run a block of code that has been emitted, /// it must rewrite the code to contain the actual addresses of any /// referenced global symbols. diff --git a/lib/Target/X86/X86JITInfo.h b/lib/Target/X86/X86JITInfo.h index f1639040c42..183e2f2bb81 100644 --- a/lib/Target/X86/X86JITInfo.h +++ b/lib/Target/X86/X86JITInfo.h @@ -21,6 +21,7 @@ namespace llvm { class X86JITInfo : public TargetJITInfo { X86TargetMachine &TM; + intptr_t PICBase; public: X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;} @@ -40,6 +41,10 @@ namespace llvm { /// address. virtual void *emitFunctionStub(void *Fn, MachineCodeEmitter &MCE); + /// getPICJumpTableEntry - Returns the value of the jumptable entry for the + /// specific basic block. + virtual intptr_t getPICJumpTableEntry(intptr_t BB, intptr_t JTBase); + /// getLazyResolverFunction - Expose the lazy resolver to the JIT. virtual LazyResolverFn getLazyResolverFunction(JITCompilerFn); @@ -48,6 +53,11 @@ namespace llvm { /// referenced global symbols. virtual void relocate(void *Function, MachineRelocation *MR, unsigned NumRelocs, unsigned char* GOTBase); + + /// setPICBase / getPICBase - Getter / setter of PICBase, used to compute + /// PIC jumptable entry. + void setPICBase(intptr_t Base) { PICBase = Base; } + intptr_t getPICBase() const { return PICBase; } }; }