mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-29 10:32:47 +00:00
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:
parent
5c488182da
commit
b4432f3d47
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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!");
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user