Suck block address tracking out of targets into the JIT Emitter. This
authorChris Lattner <sabre@nondot.org>
Wed, 3 May 2006 17:10:41 +0000 (17:10 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 3 May 2006 17:10:41 +0000 (17:10 +0000)
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

include/llvm/CodeGen/MachineCodeEmitter.h
lib/CodeGen/ELFWriter.cpp
lib/ExecutionEngine/JIT/JITEmitter.cpp
lib/Target/Alpha/AlphaCodeEmitter.cpp
lib/Target/PowerPC/PPCCodeEmitter.cpp
lib/Target/X86/X86CodeEmitter.cpp

index 43b14ca38f9359ca368aad40e2060f5daab6dfe7..b1d2a9a77c7f2aee0ff8a0d1fcea310aac44fb9c 100644 (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
index 029cfe2b020f745feb5a4c481deabe6942f732f4..bf3c5882c402fcf1dcc9ec2c55fd47daba8262fb 100644 (file)
@@ -61,21 +61,24 @@ 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) {
+
+    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) {
       assert(0 && "JIT specific function called!");
index a8d9170d4517aa884532b123a30cf388cf18b379..4a6cd715a5800111cbee35d841ab6d9abd1bb575 100644 (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!");
   
index 8cadbd0562292f61d240e41bdccc4efbee3d1e5f..cd033204e32d1d1098477cfe2167fc98508fbfaa 100644 (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;
index 69bd8307852cd437132202fc5c70d1499221d5ac..9be0f1041c06043a50dd92eb16de36598ffd3bbd 100644 (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());
 
index 9e2c998e3f159a75cdd511fe0f5d5c4bfedefd29..4dd95598a6f5e6c07285de1fa09459492327fef7 100644 (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