diff --git a/include/llvm/CodeGen/MachineCodeEmitter.h b/include/llvm/CodeGen/MachineCodeEmitter.h index 43b14ca38f9..b1d2a9a77c7 100644 --- a/include/llvm/CodeGen/MachineCodeEmitter.h +++ b/include/llvm/CodeGen/MachineCodeEmitter.h @@ -74,13 +74,6 @@ public: /// virtual bool finishFunction(MachineFunction &F) = 0; - /// emitJumpTableInfo - This callback is invoked to output the jump tables - /// for the function. In addition to a pointer to the MachineJumpTableInfo, - /// this function also takes a map of MBB IDs to addresses, so that the final - /// addresses of the MBBs can be written to the jump tables. - virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI, - std::vector &MBBM) = 0; - /// startFunctionStub - This callback is invoked when the JIT needs the /// address of a function that has not been code generated yet. The StubSize /// specifies the total size required by the stub. Stubs are not allowed to @@ -158,7 +151,11 @@ public: } return Result; } - + + /// StartMachineBasicBlock - This should be called by the target when a new + /// basic block is about to be emitted. This way the MCE knows where the + /// start of the block is, and can implement getMachineBasicBlockAddress. + virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) = 0; /// getCurrentPCValue - This returns the address that the next emitted byte /// will be output to. @@ -177,15 +174,24 @@ public: /// noted with this interface. virtual void addRelocation(const MachineRelocation &MR) = 0; + + /// FIXME: These should all be handled with relocations! + /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in /// the constant pool that was last emitted with the emitConstantPool method. /// - virtual uint64_t getConstantPoolEntryAddress(unsigned Index) = 0; + virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const = 0; /// getJumpTableEntryAddress - Return the address of the jump table with index /// 'Index' in the function that last called initJumpTableInfo. /// - virtual uint64_t getJumpTableEntryAddress(unsigned Index) = 0; + virtual intptr_t getJumpTableEntryAddress(unsigned Index) const = 0; + + /// getMachineBasicBlockAddress - Return the address of the specified + /// MachineBasicBlock, only usable after the label for the MBB has been + /// emitted. + /// + virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const= 0; }; } // End llvm namespace diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp index 029cfe2b020..bf3c5882c40 100644 --- a/lib/CodeGen/ELFWriter.cpp +++ b/lib/CodeGen/ELFWriter.cpp @@ -61,20 +61,23 @@ namespace llvm { void addRelocation(const MachineRelocation &MR) { assert(0 && "relo not handled yet!"); } - virtual uint64_t getConstantPoolEntryAddress(unsigned Index) { + + virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { + } + + virtual intptr_t getConstantPoolEntryAddress(unsigned Index) const { assert(0 && "CP not implementated yet!"); return 0; } - virtual uint64_t getJumpTableEntryAddress(unsigned Index) { + virtual intptr_t getJumpTableEntryAddress(unsigned Index) const { assert(0 && "JT not implementated yet!"); return 0; } - - virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI, - std::vector &MBBM) { - assert(0 && "JT not implementated yet!"); - } + virtual intptr_t getMachineBasicBlockAddress(MachineBasicBlock *MBB) const { + assert(0 && "JT not implementated yet!"); + return 0; + } /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE! void startFunctionStub(unsigned StubSize) { diff --git a/lib/ExecutionEngine/JIT/JITEmitter.cpp b/lib/ExecutionEngine/JIT/JITEmitter.cpp index a8d9170d451..4a6cd715a58 100644 --- a/lib/ExecutionEngine/JIT/JITEmitter.cpp +++ b/lib/ExecutionEngine/JIT/JITEmitter.cpp @@ -354,6 +354,11 @@ namespace { /// Relocations - These are the relocations that the function needs, as /// emitted. std::vector Relocations; + + /// MBBLocations - This vector is a mapping from MBB ID's to their address. + /// It is filled in by the StartMachineBasicBlock callback and queried by + /// the getMachineBasicBlockAddress callback. + std::vector MBBLocations; /// ConstantPool - The constant pool for the current function. /// @@ -381,8 +386,7 @@ public: void emitConstantPool(MachineConstantPool *MCP); void initJumpTableInfo(MachineJumpTableInfo *MJTI); - virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI, - std::vector &MBBM); + void emitJumpTableInfo(MachineJumpTableInfo *MJTI); virtual void startFunctionStub(unsigned StubSize); virtual void* finishFunctionStub(const Function *F); @@ -390,9 +394,22 @@ public: virtual void addRelocation(const MachineRelocation &MR) { Relocations.push_back(MR); } + + virtual void StartMachineBasicBlock(MachineBasicBlock *MBB) { + if (MBBLocations.size() <= (unsigned)MBB->getNumber()) + MBBLocations.resize((MBB->getNumber()+1)*2); + MBBLocations[MBB->getNumber()] = getCurrentPCValue(); + } + + 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!"); + return MBBLocations[MBB->getNumber()]; + } - virtual uint64_t getConstantPoolEntryAddress(unsigned Entry); - virtual uint64_t getJumpTableEntryAddress(unsigned Entry); private: void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); @@ -447,9 +464,13 @@ void JITEmitter::startFunction(MachineFunction &F) { // About to start emitting the machine code for the function. emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); + + MBBLocations.clear(); } bool JITEmitter::finishFunction(MachineFunction &F) { + emitJumpTableInfo(F.getJumpTableInfo()); + MemMgr.endFunctionBody(CurBufferPtr); NumBytes += getCurrentPCOffset(); @@ -549,8 +570,7 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) { JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment()); } -void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI, - std::vector &MBBM) { +void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) { const std::vector &JT = MJTI->getJumpTables(); if (JT.empty() || JumpTableBase == 0) return; @@ -566,7 +586,7 @@ void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI, // Store the address of the basic block for this jump table slot in the // memory we allocated for the jump table in 'initJumpTableInfo' for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) - *SlotPtr++ = (intptr_t)MBBM[MBBs[mi]->getNumber()]; + *SlotPtr++ = getMachineBasicBlockAddress(MBBs[mi]); } } @@ -591,7 +611,7 @@ void *JITEmitter::finishFunctionStub(const Function *F) { // in the constant pool that was last emitted with the 'emitConstantPool' // method. // -uint64_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) { +intptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const { assert(ConstantNum < ConstantPool->getConstants().size() && "Invalid ConstantPoolIndex!"); return (intptr_t)ConstantPoolBase + @@ -601,7 +621,7 @@ uint64_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) { // getJumpTableEntryAddress - Return the address of the JumpTable with index // 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' // -uint64_t JITEmitter::getJumpTableEntryAddress(unsigned Index) { +intptr_t JITEmitter::getJumpTableEntryAddress(unsigned Index) const { const std::vector &JT = JumpTable->getJumpTables(); assert(Index < JT.size() && "Invalid jump table index!"); diff --git a/lib/Target/Alpha/AlphaCodeEmitter.cpp b/lib/Target/Alpha/AlphaCodeEmitter.cpp index 8cadbd05622..cd033204e32 100644 --- a/lib/Target/Alpha/AlphaCodeEmitter.cpp +++ b/lib/Target/Alpha/AlphaCodeEmitter.cpp @@ -35,8 +35,7 @@ namespace { class AlphaCodeEmitter : public MachineFunctionPass { const AlphaInstrInfo *II; MachineCodeEmitter &MCE; - std::vector BasicBlockAddrs; - std::vector > BBRefs; + std::vector > BBRefs; /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// @@ -78,7 +77,6 @@ bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { do { BBRefs.clear(); - BasicBlockAddrs.clear(); MCE.startFunction(MF); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) @@ -87,7 +85,8 @@ bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { // Resolve all forward branches now... for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { - unsigned* Location = BasicBlockAddrs[BBRefs[i].first->getNumber()]; + unsigned* Location = + (unsigned*)MCE.getMachineBasicBlockAddress(BBRefs[i].first); unsigned* Ref = (unsigned*)BBRefs[i].second; intptr_t BranchTargetDisp = (((unsigned char*)Location - (unsigned char*)Ref) >> 2) - 1; @@ -97,17 +96,11 @@ bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) { *Ref |= (BranchTargetDisp & ((1 << 21)-1)); } BBRefs.clear(); - BasicBlockAddrs.clear(); - return false; } void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) - BasicBlockAddrs.resize((MBB.getNumber()+1)*2); - - BasicBlockAddrs[MBB.getNumber()] = (unsigned*)MCE.getCurrentPCValue(); - + MCE.StartMachineBasicBlock(&MBB); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) { MachineInstr &MI = *I; diff --git a/lib/Target/PowerPC/PPCCodeEmitter.cpp b/lib/Target/PowerPC/PPCCodeEmitter.cpp index 69bd8307852..9be0f1041c0 100644 --- a/lib/Target/PowerPC/PPCCodeEmitter.cpp +++ b/lib/Target/PowerPC/PPCCodeEmitter.cpp @@ -33,9 +33,7 @@ namespace { // Tracks which instruction references which BasicBlock std::vector > BBRefs; - // Tracks where each BasicBlock starts, indexes by BB number. - std::vector BasicBlockAddrs; - + /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); @@ -87,17 +85,15 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { "JIT relocation model must be set to static or default!"); do { BBRefs.clear(); - BasicBlockAddrs.clear(); MCE.startFunction(MF); for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) emitBasicBlock(*BB); - MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BasicBlockAddrs); } while (MCE.finishFunction(MF)); // Resolve branches to BasicBlocks for the entire function for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { - intptr_t Location = BasicBlockAddrs[BBRefs[i].first->getNumber()]; + intptr_t Location = MCE.getMachineBasicBlockAddress(BBRefs[i].first); unsigned *Ref = BBRefs[i].second; DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location << "\n"); @@ -115,15 +111,13 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) { } } BBRefs.clear(); - BasicBlockAddrs.clear(); return false; } void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { - if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) - BasicBlockAddrs.resize((MBB.getNumber()+1)*2); - BasicBlockAddrs[MBB.getNumber()] = MCE.getCurrentPCValue(); + MCE.StartMachineBasicBlock(&MBB); + for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ MachineInstr &MI = *I; unsigned Opcode = MI.getOpcode(); @@ -145,8 +139,8 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { - int rv = 0; // Return value; defaults to 0 for unhandled cases - // or things that get fixed up later by the JIT. + intptr_t rv = 0; // Return value; defaults to 0 for unhandled cases + // or things that get fixed up later by the JIT. if (MO.isRegister()) { rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg()); diff --git a/lib/Target/X86/X86CodeEmitter.cpp b/lib/Target/X86/X86CodeEmitter.cpp index 9e2c998e3f1..4dd95598a6f 100644 --- a/lib/Target/X86/X86CodeEmitter.cpp +++ b/lib/Target/X86/X86CodeEmitter.cpp @@ -35,7 +35,6 @@ namespace { class Emitter : public MachineFunctionPass { const X86InstrInfo *II; MachineCodeEmitter &MCE; - std::vector BasicBlockAddrs; std::vector > BBRefs; public: explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} @@ -83,30 +82,24 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) { do { BBRefs.clear(); - BasicBlockAddrs.clear(); MCE.startFunction(MF); for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) emitBasicBlock(*I); - MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BasicBlockAddrs); } while (MCE.finishFunction(MF)); // Resolve all forward branches now. for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { - unsigned Location = BasicBlockAddrs[BBRefs[i].first->getNumber()]; + unsigned Location = MCE.getMachineBasicBlockAddress(BBRefs[i].first); unsigned Ref = BBRefs[i].second; *((unsigned*)(intptr_t)Ref) = Location-Ref-4; } BBRefs.clear(); - BasicBlockAddrs.clear(); return false; } void Emitter::emitBasicBlock(MachineBasicBlock &MBB) { - if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) - BasicBlockAddrs.resize((MBB.getNumber()+1)*2); - BasicBlockAddrs[MBB.getNumber()] = MCE.getCurrentPCValue(); - + MCE.StartMachineBasicBlock(&MBB); for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end(); I != E; ++I) emitInstruction(*I); @@ -118,23 +111,15 @@ void Emitter::emitPCRelativeValue(unsigned Address) { MCE.emitWordLE(Address-MCE.getCurrentPCValue()-4); } -/// emitPCRelativeBlockAddress - This method emits the PC relative address of -/// the specified basic block, or if the basic block hasn't been emitted yet -/// (because this is a forward branch), it keeps track of the information -/// necessary to resolve this address later (and emits a dummy value). +/// emitPCRelativeBlockAddress - This method keeps track of the information +/// necessary to resolve the address of this block later and emits a dummy +/// value. /// void Emitter::emitPCRelativeBlockAddress(MachineBasicBlock *MBB) { - // If this is a backwards branch, we already know the address of the target, - // so just emit the value. - unsigned MBBNo = MBB->getNumber(); - if (MBBNo < BasicBlockAddrs.size() && BasicBlockAddrs[MBBNo]) { - emitPCRelativeValue(BasicBlockAddrs[MBBNo]); - } else { - // Otherwise, remember where this reference was and where it is to so we can - // deal with it later. - BBRefs.push_back(std::make_pair(MBB, MCE.getCurrentPCValue())); - MCE.emitWordLE(0); - } + // Remember where this reference was and where it is to so we can + // deal with it later. + BBRefs.push_back(std::make_pair(MBB, MCE.getCurrentPCValue())); + MCE.emitWordLE(0); } /// emitGlobalAddressForCall - Emit the specified address to the code stream