Suck block address tracking out of targets into the JIT Emitter. This

simplifies the MachineCodeEmitter interface just a little bit and makes
BasicBlocks work like constant pools and jump tables.

llvm-svn: 28082
This commit is contained in:
Chris Lattner 2006-05-03 17:10:41 +00:00
parent 9954bc9c19
commit 1d8ee1fc80
6 changed files with 74 additions and 73 deletions

View File

@ -74,13 +74,6 @@ public:
/// ///
virtual bool finishFunction(MachineFunction &F) = 0; 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<uint64_t> &MBBM) = 0;
/// startFunctionStub - This callback is invoked when the JIT needs the /// startFunctionStub - This callback is invoked when the JIT needs the
/// address of a function that has not been code generated yet. The StubSize /// 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 /// specifies the total size required by the stub. Stubs are not allowed to
@ -158,7 +151,11 @@ public:
} }
return Result; 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 /// getCurrentPCValue - This returns the address that the next emitted byte
/// will be output to. /// will be output to.
@ -177,15 +174,24 @@ public:
/// noted with this interface. /// noted with this interface.
virtual void addRelocation(const MachineRelocation &MR) = 0; virtual void addRelocation(const MachineRelocation &MR) = 0;
/// FIXME: These should all be handled with relocations!
/// getConstantPoolEntryAddress - Return the address of the 'Index' entry in /// getConstantPoolEntryAddress - Return the address of the 'Index' entry in
/// the constant pool that was last emitted with the emitConstantPool method. /// 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 /// getJumpTableEntryAddress - Return the address of the jump table with index
/// 'Index' in the function that last called initJumpTableInfo. /// '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 } // End llvm namespace

View File

@ -61,20 +61,23 @@ namespace llvm {
void addRelocation(const MachineRelocation &MR) { void addRelocation(const MachineRelocation &MR) {
assert(0 && "relo not handled yet!"); 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!"); assert(0 && "CP not implementated yet!");
return 0; return 0;
} }
virtual uint64_t getJumpTableEntryAddress(unsigned Index) { virtual intptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(0 && "JT not implementated yet!"); assert(0 && "JT not implementated yet!");
return 0; return 0;
} }
virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI,
std::vector<uint64_t> &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! /// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
void startFunctionStub(unsigned StubSize) { void startFunctionStub(unsigned StubSize) {

View File

@ -354,6 +354,11 @@ namespace {
/// Relocations - These are the relocations that the function needs, as /// Relocations - These are the relocations that the function needs, as
/// emitted. /// emitted.
std::vector<MachineRelocation> Relocations; std::vector<MachineRelocation> 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<intptr_t> MBBLocations;
/// ConstantPool - The constant pool for the current function. /// ConstantPool - The constant pool for the current function.
/// ///
@ -381,8 +386,7 @@ public:
void emitConstantPool(MachineConstantPool *MCP); void emitConstantPool(MachineConstantPool *MCP);
void initJumpTableInfo(MachineJumpTableInfo *MJTI); void initJumpTableInfo(MachineJumpTableInfo *MJTI);
virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI, void emitJumpTableInfo(MachineJumpTableInfo *MJTI);
std::vector<uint64_t> &MBBM);
virtual void startFunctionStub(unsigned StubSize); virtual void startFunctionStub(unsigned StubSize);
virtual void* finishFunctionStub(const Function *F); virtual void* finishFunctionStub(const Function *F);
@ -390,9 +394,22 @@ public:
virtual void addRelocation(const MachineRelocation &MR) { virtual void addRelocation(const MachineRelocation &MR) {
Relocations.push_back(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: private:
void *getPointerToGlobal(GlobalValue *GV, void *Reference, bool NoNeedStub); 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. // About to start emitting the machine code for the function.
emitAlignment(std::max(F.getFunction()->getAlignment(), 8U)); emitAlignment(std::max(F.getFunction()->getAlignment(), 8U));
TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr); TheJIT->updateGlobalMapping(F.getFunction(), CurBufferPtr);
MBBLocations.clear();
} }
bool JITEmitter::finishFunction(MachineFunction &F) { bool JITEmitter::finishFunction(MachineFunction &F) {
emitJumpTableInfo(F.getJumpTableInfo());
MemMgr.endFunctionBody(CurBufferPtr); MemMgr.endFunctionBody(CurBufferPtr);
NumBytes += getCurrentPCOffset(); NumBytes += getCurrentPCOffset();
@ -549,8 +570,7 @@ void JITEmitter::initJumpTableInfo(MachineJumpTableInfo *MJTI) {
JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment()); JumpTableBase = allocateSpace(NumEntries * EntrySize, MJTI->getAlignment());
} }
void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI, void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
std::vector<uint64_t> &MBBM) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty() || JumpTableBase == 0) return; 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 // Store the address of the basic block for this jump table slot in the
// memory we allocated for the jump table in 'initJumpTableInfo' // memory we allocated for the jump table in 'initJumpTableInfo'
for (unsigned mi = 0, me = MBBs.size(); mi != me; ++mi) 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' // in the constant pool that was last emitted with the 'emitConstantPool'
// method. // method.
// //
uint64_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) { intptr_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) const {
assert(ConstantNum < ConstantPool->getConstants().size() && assert(ConstantNum < ConstantPool->getConstants().size() &&
"Invalid ConstantPoolIndex!"); "Invalid ConstantPoolIndex!");
return (intptr_t)ConstantPoolBase + return (intptr_t)ConstantPoolBase +
@ -601,7 +621,7 @@ uint64_t JITEmitter::getConstantPoolEntryAddress(unsigned ConstantNum) {
// getJumpTableEntryAddress - Return the address of the JumpTable with index // getJumpTableEntryAddress - Return the address of the JumpTable with index
// 'Index' in the jumpp table that was last initialized with 'initJumpTableInfo' // '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<MachineJumpTableEntry> &JT = JumpTable->getJumpTables(); const std::vector<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
assert(Index < JT.size() && "Invalid jump table index!"); assert(Index < JT.size() && "Invalid jump table index!");

View File

@ -35,8 +35,7 @@ namespace {
class AlphaCodeEmitter : public MachineFunctionPass { class AlphaCodeEmitter : public MachineFunctionPass {
const AlphaInstrInfo *II; const AlphaInstrInfo *II;
MachineCodeEmitter &MCE; MachineCodeEmitter &MCE;
std::vector<unsigned*> BasicBlockAddrs; std::vector<std::pair<MachineBasicBlock *, unsigned*> > BBRefs;
std::vector<std::pair<const MachineBasicBlock *, unsigned*> > BBRefs;
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
/// ///
@ -78,7 +77,6 @@ bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
do { do {
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
MCE.startFunction(MF); MCE.startFunction(MF);
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) 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... // Resolve all forward branches now...
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { 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; unsigned* Ref = (unsigned*)BBRefs[i].second;
intptr_t BranchTargetDisp = intptr_t BranchTargetDisp =
(((unsigned char*)Location - (unsigned char*)Ref) >> 2) - 1; (((unsigned char*)Location - (unsigned char*)Ref) >> 2) - 1;
@ -97,17 +96,11 @@ bool AlphaCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
*Ref |= (BranchTargetDisp & ((1 << 21)-1)); *Ref |= (BranchTargetDisp & ((1 << 21)-1));
} }
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
return false; return false;
} }
void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { void AlphaCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) MCE.StartMachineBasicBlock(&MBB);
BasicBlockAddrs.resize((MBB.getNumber()+1)*2);
BasicBlockAddrs[MBB.getNumber()] = (unsigned*)MCE.getCurrentPCValue();
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) { I != E; ++I) {
MachineInstr &MI = *I; MachineInstr &MI = *I;

View File

@ -33,9 +33,7 @@ namespace {
// Tracks which instruction references which BasicBlock // Tracks which instruction references which BasicBlock
std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs; std::vector<std::pair<MachineBasicBlock*, unsigned*> > BBRefs;
// Tracks where each BasicBlock starts, indexes by BB number.
std::vector<uint64_t> BasicBlockAddrs;
/// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr /// getMachineOpValue - evaluates the MachineOperand of a given MachineInstr
/// ///
int getMachineOpValue(MachineInstr &MI, MachineOperand &MO); 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!"); "JIT relocation model must be set to static or default!");
do { do {
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
MCE.startFunction(MF); MCE.startFunction(MF);
for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB) for (MachineFunction::iterator BB = MF.begin(), E = MF.end(); BB != E; ++BB)
emitBasicBlock(*BB); emitBasicBlock(*BB);
MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BasicBlockAddrs);
} while (MCE.finishFunction(MF)); } while (MCE.finishFunction(MF));
// Resolve branches to BasicBlocks for the entire function // Resolve branches to BasicBlocks for the entire function
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { 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; unsigned *Ref = BBRefs[i].second;
DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location DEBUG(std::cerr << "Fixup @ " << (void*)Ref << " to " << (void*)Location
<< "\n"); << "\n");
@ -115,15 +111,13 @@ bool PPCCodeEmitter::runOnMachineFunction(MachineFunction &MF) {
} }
} }
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
return false; return false;
} }
void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) { void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) MCE.StartMachineBasicBlock(&MBB);
BasicBlockAddrs.resize((MBB.getNumber()+1)*2);
BasicBlockAddrs[MBB.getNumber()] = MCE.getCurrentPCValue();
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){ for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
MachineInstr &MI = *I; MachineInstr &MI = *I;
unsigned Opcode = MI.getOpcode(); unsigned Opcode = MI.getOpcode();
@ -145,8 +139,8 @@ void PPCCodeEmitter::emitBasicBlock(MachineBasicBlock &MBB) {
int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) { int PPCCodeEmitter::getMachineOpValue(MachineInstr &MI, MachineOperand &MO) {
int rv = 0; // Return value; defaults to 0 for unhandled cases intptr_t rv = 0; // Return value; defaults to 0 for unhandled cases
// or things that get fixed up later by the JIT. // or things that get fixed up later by the JIT.
if (MO.isRegister()) { if (MO.isRegister()) {
rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg()); rv = PPCRegisterInfo::getRegisterNumbering(MO.getReg());

View File

@ -35,7 +35,6 @@ namespace {
class Emitter : public MachineFunctionPass { class Emitter : public MachineFunctionPass {
const X86InstrInfo *II; const X86InstrInfo *II;
MachineCodeEmitter &MCE; MachineCodeEmitter &MCE;
std::vector<uint64_t> BasicBlockAddrs;
std::vector<std::pair<MachineBasicBlock *, unsigned> > BBRefs; std::vector<std::pair<MachineBasicBlock *, unsigned> > BBRefs;
public: public:
explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {} explicit Emitter(MachineCodeEmitter &mce) : II(0), MCE(mce) {}
@ -83,30 +82,24 @@ bool Emitter::runOnMachineFunction(MachineFunction &MF) {
do { do {
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
MCE.startFunction(MF); MCE.startFunction(MF);
for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I)
emitBasicBlock(*I); emitBasicBlock(*I);
MCE.emitJumpTableInfo(MF.getJumpTableInfo(), BasicBlockAddrs);
} while (MCE.finishFunction(MF)); } while (MCE.finishFunction(MF));
// Resolve all forward branches now. // Resolve all forward branches now.
for (unsigned i = 0, e = BBRefs.size(); i != e; ++i) { 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 Ref = BBRefs[i].second;
*((unsigned*)(intptr_t)Ref) = Location-Ref-4; *((unsigned*)(intptr_t)Ref) = Location-Ref-4;
} }
BBRefs.clear(); BBRefs.clear();
BasicBlockAddrs.clear();
return false; return false;
} }
void Emitter::emitBasicBlock(MachineBasicBlock &MBB) { void Emitter::emitBasicBlock(MachineBasicBlock &MBB) {
if (BasicBlockAddrs.size() <= (unsigned)MBB.getNumber()) MCE.StartMachineBasicBlock(&MBB);
BasicBlockAddrs.resize((MBB.getNumber()+1)*2);
BasicBlockAddrs[MBB.getNumber()] = MCE.getCurrentPCValue();
for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end(); for (MachineBasicBlock::const_iterator I = MBB.begin(), E = MBB.end();
I != E; ++I) I != E; ++I)
emitInstruction(*I); emitInstruction(*I);
@ -118,23 +111,15 @@ void Emitter::emitPCRelativeValue(unsigned Address) {
MCE.emitWordLE(Address-MCE.getCurrentPCValue()-4); MCE.emitWordLE(Address-MCE.getCurrentPCValue()-4);
} }
/// emitPCRelativeBlockAddress - This method emits the PC relative address of /// emitPCRelativeBlockAddress - This method keeps track of the information
/// the specified basic block, or if the basic block hasn't been emitted yet /// necessary to resolve the address of this block later and emits a dummy
/// (because this is a forward branch), it keeps track of the information /// value.
/// necessary to resolve this address later (and emits a dummy value).
/// ///
void Emitter::emitPCRelativeBlockAddress(MachineBasicBlock *MBB) { void Emitter::emitPCRelativeBlockAddress(MachineBasicBlock *MBB) {
// If this is a backwards branch, we already know the address of the target, // Remember where this reference was and where it is to so we can
// so just emit the value. // deal with it later.
unsigned MBBNo = MBB->getNumber(); BBRefs.push_back(std::make_pair(MBB, MCE.getCurrentPCValue()));
if (MBBNo < BasicBlockAddrs.size() && BasicBlockAddrs[MBBNo]) { MCE.emitWordLE(0);
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);
}
} }
/// emitGlobalAddressForCall - Emit the specified address to the code stream /// emitGlobalAddressForCall - Emit the specified address to the code stream