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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@28082 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2006-05-03 17:10:41 +00:00
parent 5c488182da
commit b4432f3d47
6 changed files with 74 additions and 73 deletions

View File

@ -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<uint64_t> &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

View File

@ -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<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!
void startFunctionStub(unsigned StubSize) {

View File

@ -354,6 +354,11 @@ namespace {
/// Relocations - These are the relocations that the function needs, as
/// emitted.
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.
///
@ -381,8 +386,7 @@ public:
void emitConstantPool(MachineConstantPool *MCP);
void initJumpTableInfo(MachineJumpTableInfo *MJTI);
virtual void emitJumpTableInfo(MachineJumpTableInfo *MJTI,
std::vector<uint64_t> &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<uint64_t> &MBBM) {
void JITEmitter::emitJumpTableInfo(MachineJumpTableInfo *MJTI) {
const std::vector<MachineJumpTableEntry> &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<MachineJumpTableEntry> &JT = JumpTable->getJumpTables();
assert(Index < JT.size() && "Invalid jump table index!");

View File

@ -35,8 +35,7 @@ namespace {
class AlphaCodeEmitter : public MachineFunctionPass {
const AlphaInstrInfo *II;
MachineCodeEmitter &MCE;
std::vector<unsigned*> BasicBlockAddrs;
std::vector<std::pair<const MachineBasicBlock *, unsigned*> > BBRefs;
std::vector<std::pair<MachineBasicBlock *, unsigned*> > 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;

View File

@ -33,9 +33,7 @@ namespace {
// Tracks which instruction references which BasicBlock
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
///
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());

View File

@ -35,7 +35,6 @@ namespace {
class Emitter : public MachineFunctionPass {
const X86InstrInfo *II;
MachineCodeEmitter &MCE;
std::vector<uint64_t> BasicBlockAddrs;
std::vector<std::pair<MachineBasicBlock *, unsigned> > 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