forked from OSchip/llvm-project
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:
parent
9954bc9c19
commit
1d8ee1fc80
|
@ -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
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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!");
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue