[llvm-commits] CVS: llvm/lib/Reoptimizer/Inst/InstManip.cpp InstManip.h Phases.cpp SparcInstManip.cpp SparcInstManip.h

Joel Stanley jstanley at cs.uiuc.edu
Wed Apr 30 12:26:01 PDT 2003


Changes in directory llvm/lib/Reoptimizer/Inst:

InstManip.cpp updated: 1.11 -> 1.12
InstManip.h updated: 1.12 -> 1.13
Phases.cpp updated: 1.17 -> 1.18
SparcInstManip.cpp updated: 1.2 -> 1.3
SparcInstManip.h updated: 1.2 -> 1.3

---
Log message:

Major refactoring completed -- the Phase classes only know about a generic InstManip
object.  When support for other platforms is added, we will have to control which concrete
instance of InstManip is used at construction of the Phase 2 instance.  Phase 2 passes its
InstManip instance along to subsequent phases, so that is the only point where the
concrete instance needs to be changed.  As of right now, a SparcInstManip instance is
created in a hard-coded manner, although only the InstManip interface is visible to the
Phase classes.

The spill region issue (wherein recursive invocations of the phase functions can occur) is
still outstanding, so InstManip still owns the variable-sized phase 3 spill region and
SparcInstManip owns the fixed-size phase 4 spill region.



---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/Inst/InstManip.cpp
diff -u llvm/lib/Reoptimizer/Inst/InstManip.cpp:1.11 llvm/lib/Reoptimizer/Inst/InstManip.cpp:1.12
--- llvm/lib/Reoptimizer/Inst/InstManip.cpp:1.11	Wed Apr 30 11:36:09 2003
+++ llvm/lib/Reoptimizer/Inst/InstManip.cpp	Wed Apr 30 12:31:47 2003
@@ -41,12 +41,16 @@
     ostr << "}";
 }
 
-InstManip::InstManip(TraceCache* tc, unsigned sharedSize, unsigned instWidth):
+InstManip::InstManip(TraceCache* tc,
+                     unsigned sharedSize,
+                     unsigned instWidth,
+                     unsigned nopInst):
     m_pTC(tc),
     m_pPhase3SpillRegion(0),
     m_pCurrSpill(0),
     m_sharedSize(sharedSize),
-    m_instWidth(instWidth)
+    m_instWidth(instWidth),
+    m_nopInst(nopInst)
 {
     assert(tc && "InstManip requires valid TraceCache instance");
 }


Index: llvm/lib/Reoptimizer/Inst/InstManip.h
diff -u llvm/lib/Reoptimizer/Inst/InstManip.h:1.12 llvm/lib/Reoptimizer/Inst/InstManip.h:1.13
--- llvm/lib/Reoptimizer/Inst/InstManip.h:1.12	Wed Apr 30 11:36:09 2003
+++ llvm/lib/Reoptimizer/Inst/InstManip.h	Wed Apr 30 12:31:47 2003
@@ -35,7 +35,11 @@
 class InstManip 
 {
   public:
-    InstManip(TraceCache* vm, unsigned sharedSize, unsigned instWidth);
+    InstManip(TraceCache* tc,
+              unsigned sharedSize,
+              unsigned instWidth,
+              unsigned nopInst);
+
     virtual ~InstManip();
 
     typedef std::pair<uint64_t, uint64_t> AddressRange;
@@ -62,6 +66,14 @@
     virtual unsigned getSlotSize(Phase2* p2) const = 0;
     virtual unsigned getSlotSize(Phase3* p3, InstCandidate& cand) const = 0;
 
+    // findCandidates - Build the vector of instruction candidates that occur in the
+    // region defined by the given addresses. This is necessarily a platform-dependent
+    // action.
+
+    virtual void     findCandidates(uint64_t start,
+                                    uint64_t end,
+                                    std::vector<InstCandidate>& candidates) = 0;
+
     // getStartAddr - return the desired starting position in the function body. This is
     // useful for skipping standard prologue code that occurs at the start of the function
     // body.
@@ -83,7 +95,8 @@
     inline void      printRange(uint64_t start, uint64_t end) const;
 
     unsigned         getSharedSize() const { return m_sharedSize; }
-    unsigned         getInstWidth() const { return m_instWidth; }
+    unsigned         getInstWidth() const  { return m_instWidth;  }
+    unsigned         getNOP() const        { return m_nopInst;    }
 
   protected:
     InstManip() {}
@@ -98,6 +111,7 @@
 
     unsigned               m_sharedSize;         // # of shared registers that must be spilled
     unsigned               m_instWidth;          // instruction width, in bytes
+    unsigned               m_nopInst;            // NOP instruction word
 };
 
 void InstManip::printRange(uint64_t start, uint64_t end) const


Index: llvm/lib/Reoptimizer/Inst/Phases.cpp
diff -u llvm/lib/Reoptimizer/Inst/Phases.cpp:1.17 llvm/lib/Reoptimizer/Inst/Phases.cpp:1.18
--- llvm/lib/Reoptimizer/Inst/Phases.cpp:1.17	Wed Apr 30 11:36:09 2003
+++ llvm/lib/Reoptimizer/Inst/Phases.cpp	Wed Apr 30 12:31:47 2003
@@ -10,24 +10,15 @@
 //      
 //       1. Read the neccessary ELF data associated with the executable image.
 //       
-//       2. For each function F (only in text segment preferably), write code to call phase 3.
+//       2. For each function F (in section labelled ".text"), write code to call phase 3.
 //
 //           2a. Replace the first (replacable) instruction in F with a branch to a new
 //           slot (annulling bit should specify *not* to execute the branch delay slot) in
 //           the dummy function.
 //
-// 	     2b. In the new slot, write the contents of the phase 3 slot:
-//                        +------------------------------------+
-//                        |   save registers (new stack frame) |
-//                        |     load parameter for phase 3     |
-//                        |           call to phase 3          |
-//                        |                nop                 |
-//                        |        branch back to orig code    |
-//                        |          restore registers         |
-//                        +------------------------------------+
-//               where the parameter to phase 3 is a pointer the heap-allocated Phase3Info
-//               instance.
-//
+// 	     2b. In the new slot, write the contents of the phase 3 slot (see appropriate
+// 	     InstManip instance for detailed information about slot contents).
+// 	     
 // PHASE 3:
 //
 //       - Deallocate the parameter structure whenever it is convenient to do so.
@@ -40,32 +31,23 @@
 //       3. For each load-volatile candidate,
 //         3a. Obtain a new slot in the dummy function.
 //         3b. Replace the load candidate with branch to slot.
-//         3c. In the new slot, write the contents of the phase 4 slot:
-//                  +---------------------------------------+
-//                  |    save registers (new stack frame)   |
-//                  |           save global registers       |
-//                  | copy load-src addr to param1 register |
-//                  | load p4 struct ptr to param2 register |
-//                  |             call to phase 4           |
-//                  |                  nop                  |
-//                  |        restore global registers       |
-//                  |          branch back to orig code     |
-//                  |           restore registers           |
-//                  +---------------------------------------+
+//         3c. In the new slot, write the contents of the phase 4 slot (see appropriate
+//         InstManip instance for detailed information about slot contents).
 //
-//       4. Deallocate the slot that originated this invocation.
+//       4. Deallocate the slot that originated this invocation of phase3().
 //
 // PHASE 4:
 //
 //      1. Examine the tag (i.e. load-src addr) passed by phase 3
 //        1a. If tag is in GBT, we have a valid candidate, so do step 2.
-//        1b. If tag is not in GBT, our candidate is invalid, so delete slot and return to
-//        original code.
+//        1b. If tag is not in GBT, our candidate is invalid, so restore original program state and
+//            go to step 3.
+//
+//      2. Change the branch to the phase 4 slot to branch to a (new) phase 5 slot. See
+//      appropriate InstManip instance for detailed information about phase 5 slot
+//      contents.
 //
-//      2. Set up the phase 5 slot that will actually call the instrumentation function:
-//                  +---------------------------------------+
-//                  |                  ...                  |
-//                  +---------------------------------------+
+//      3. Deallocate the slot that originated this invocation of phase4().
 //
 
 #include <stdlib.h>
@@ -79,7 +61,7 @@
 #include "llvm/Reoptimizer/MemoryManager.h"
 
 #include "ElfReader.h"
-//#include "InstManip.h"
+#include "InstManip.h"
 #include "SparcInstManip.h"
 #include "PhaseInfo.h"
 
@@ -108,23 +90,17 @@
 class Phase2 
 {
   public:
-    Phase2(TraceCache* pTraceCache, SparcInstManip* pIM);
+    Phase2(TraceCache* pTC, InstManip* pIM);
     void transform();
     void transformFunction(AddressRange& range);
 
   private:
     Phase2() {}
     
-    TraceCache*     m_pTraceCache;
-    SparcInstManip*      m_pInstManip;
-
-    //static uint64_t* sm_pSpillRegion; // Base pointer to the spill region for phase 3 invocations
-    //static uint64_t* sm_pCurrSpill;   // Pointer to current location in the spill region
+    TraceCache* m_pTC;
+    InstManip*  m_pIM;
 };
 
-//uint64_t* Phase2::sm_pSpillRegion = 0;
-//uint64_t* Phase2::sm_pCurrSpill = 0;
-
 // Phase3 is the class that is responsible for making the "phase 3" transformation; the
 // global function phase3() is responsible for constructing one Phase3 instance per
 // invocation and invoking transform on it.
@@ -143,8 +119,8 @@
     void            processCandidates(vector<InstCandidate>& candidates);
 
     Phase3Info* m_pPhase3Info;
-    TraceCache* m_pTraceCache;
-    SparcInstManip*  m_pInstManip;
+    TraceCache* m_pTC;
+    InstManip*  m_pIM;
 };
 
 // Phase4 is the class that is responsible for making the "phase 4" transformation; the
@@ -162,9 +138,9 @@
   private:
     Phase4() {}
 
-    Phase4Info* m_pPhase4Info;
-    TraceCache* m_pTraceCache;
-    SparcInstManip*  m_pInstManip;
+    Phase4Info* m_pPhase4Info; 
+    TraceCache* m_pTC;
+    InstManip*  m_pIM;
     uint64_t    m_tag;         // Entry to look for in the GBT
 };
 
@@ -173,14 +149,13 @@
 extern "C" void phase2() 
 {
     TraceCache* pTC = new TraceCache();
-    SparcInstManip* pIM = new SparcInstManip(pTC);
-    Phase2 ph(pTC, pIM);
+    Phase2 ph(pTC, new SparcInstManip(pTC));
     ph.transform();
 }
 
-Phase2::Phase2(TraceCache* tc, SparcInstManip* pInstManip):
-    m_pTraceCache(tc),
-    m_pInstManip(pInstManip)
+Phase2::Phase2(TraceCache* tc, InstManip* pIM):
+    m_pTC(tc),
+    m_pIM(pIM)
 {
 }
 
@@ -206,11 +181,8 @@
 
     cerr << "There are " << funcs.size() << " functions to process." << endl << endl;
 
-    m_pInstManip->makePhase3SpillRegion(funcs.size());
+    m_pIM->makePhase3SpillRegion(funcs.size());
     
-    //sm_pSpillRegion = new uint64_t[m_pInstManip->getSharedSize() * funcs.size()];
-    //sm_pCurrSpill = sm_pSpillRegion;
-
     for(vector<std::pair<std::string, AddressRange> >::iterator i = funcs.begin(),
             e = funcs.end(); i != e; ++i) {
         if(i->first == "fibs") {
@@ -256,106 +228,37 @@
     // from the TraceCache memory manager (i.e., a new slot in the dummy function). Hold
     // onto the replaced instruction for later restoration.
     
-    VirtualMem* vm = m_pTraceCache->getVM();
-    uint64_t repInstAddr = m_pInstManip->getStartAddr(range.first);
+    VirtualMem* vm = m_pTC->getVM();
+    uint64_t repInstAddr = m_pIM->getStartAddr(range.first);
     unsigned origInst = vm->readInstrFrmVm(repInstAddr);
 
-    assert(!m_pInstManip->isBranch(origInst) &&
+    assert(!m_pIM->isBranch(origInst) &&
            "Unhandled case: branch instruction first in function body");
 
-    unsigned slotSize = m_pInstManip->getSlotSize(this);
+    unsigned slotSize = m_pIM->getSlotSize(this);
 
     // Replace instruction at repInstAddr with a branch to start of a new slot.
-    uint64_t slotBase = replaceInstWithBrToSlot(repInstAddr, slotSize, m_pTraceCache, m_pInstManip);
+    uint64_t slotBase = replaceInstWithBrToSlot(repInstAddr, slotSize, m_pTC, m_pIM);
 
     // Build the Phase3Info structure and generate the phase 3 slot. 
 
     Phase3Info* p3info = new Phase3Info(range, origInst, repInstAddr,
-                                        slotBase, slotSize, m_pTraceCache, m_pInstManip);
-
-    vector<unsigned> snippet;
-    m_pInstManip->buildSlot(p3info, snippet);
-
-    // Dump snippet instructions:
-    cerr << "phase3 slot instructions:" << endl;
-    for(vector<unsigned>::iterator j = snippet.begin(), k = snippet.end(); j != k; ++j) {
-        m_pInstManip->printInst(*j);
-        cerr << endl;
-    }
-
-    // Copy the snippet code into the slot
-    copySnippetToSlot(snippet, slotBase, vm, m_pInstManip);
-    
-    // {{{ Old version of this function
-#if 0
-    // Obtain address of first replacable instruction in function and obtain a new slot from
-    // the TraceCache memory manager (i.e., a new slot in the dummy function).
-    
-    uint64_t repInstAddr = m_pInstManip->skipFunctionHdr(range.first);
-    uint64_t slotBase = m_pTraceCache->getMemMgr()->getMemory(getSlotSize());
-    assert(slotBase && "Unable to obtain memory from MemoryManger instance");
-
-    // Replace instruction at repInstAddr with a branch to start of slot.
-    VirtualMem* vm = m_pTraceCache->getVM();
-    unsigned origInst = vm->readInstrFrmVm(repInstAddr);
-    assert(!m_pInstManip->isBranch(origInst) &&
-           "Unhandled case: branch instruction first in function body");
-    vm->writeInstToVM(repInstAddr, m_pInstManip->getBranchAlways(slotBase, repInstAddr));
-
-    // Generate the phase 3 slot. See picture of phase 3 slot contents for more info.
-
-    Phase3Info* p3info = new Phase3Info(range, origInst, repInstAddr,
-                                        slotBase, getSlotSize(), m_pTraceCache, m_pInstManip);
+                                        slotBase, slotSize, m_pTC, m_pIM);
 
     vector<unsigned> snippet;
-    m_pInstManip->startCode(snippet);
-
-    uint64_t* pCurrSpill = m_pInstManip->getCurrentSpill();
-    
-    m_pInstManip->generateSave();
-    m_pInstManip->generateSpillShared((uint64_t) pCurrSpill);
-    m_pInstManip->generateLoad((uint64_t) p3info, InstManip::REG_0, InstManip::REG_1);
-    m_pInstManip->generateCall((uint64_t) &phase3, slotBase);
-    m_pInstManip->generateRestoreShared((uint64_t) pCurrSpill);
-    m_pInstManip->generateBranchAlways(repInstAddr, slotBase, m_pInstManip->getRestoreInst());
-
-    m_pInstManip->endCode();
+    m_pIM->buildSlot(p3info, snippet);
 
     // Dump snippet instructions:
     cerr << "phase3 slot instructions:" << endl;
     for(vector<unsigned>::iterator j = snippet.begin(), k = snippet.end(); j != k; ++j) {
-        m_pInstManip->printInst(*j);
+        m_pIM->printInst(*j);
         cerr << endl;
     }
 
-    // Bump the current spill pointer to the next "spill slot" in the spill region used
-    // before/after phase3() invocations.
-
-    m_pInstManip->advanceSpill();
-    //sm_pCurrSpill += m_pInstManip->getSharedSize();
-
     // Copy the snippet code into the slot
-    assert(snippet.size() == getSlotSize() && "Snippet size does not match slot size");
-    copySnippetToSlot(snippet, slotBase, vm, m_pInstManip);
-#endif
-    // }}}
+    copySnippetToSlot(snippet, slotBase, vm, m_pIM);
 }
 
-#if 0
-unsigned Phase2::getSlotSize() const
-{
-    // The following sum corresponds to the sizes consumed by the various regions of the
-    // phase 2 slot.  See picture of phase 2 contents for details.
-
-    return m_pInstManip->getGenSaveSize() +
-        m_pInstManip->getGenSpillSharedSize() +
-        m_pInstManip->getGenLoadSize() +
-        m_pInstManip->getGenCallSize() +
-        m_pInstManip->getGenRestoreSharedSize() +
-        m_pInstManip->getGenBranchAlwaysSize();
-}
-#endif
-
 //////////////// Phase3 implementation ////////////////
 
 void phase3(Phase3Info* p3info)
@@ -366,8 +269,8 @@
 
 Phase3::Phase3(Phase3Info* p3info):
     m_pPhase3Info(p3info),
-    m_pTraceCache(p3info->getTraceCache()),
-    m_pInstManip(p3info->getIM())
+    m_pTC(p3info->getTraceCache()),
+    m_pIM(p3info->getIM())
 {
     cerr << "================ Begin Phase 3 [" << std::hex
          << m_pPhase3Info->getStartAddr() << ", " << m_pPhase3Info->getEndAddr()
@@ -377,7 +280,7 @@
     // original code (thus effectively removing the branch to the slot created by phase 2
     // as well).
 
-    m_pTraceCache->getVM()->writeInstToVM(p3info->getReplaceAddr(), p3info->getOrigInst());
+    m_pTC->getVM()->writeInstToVM(p3info->getReplaceAddr(), p3info->getOrigInst());
 }
 
 Phase3::~Phase3() 
@@ -392,7 +295,7 @@
 
     uint64_t slotBase = m_pPhase3Info->getSlot();
     unsigned slotSize = m_pPhase3Info->getSlotSize();
-    m_pTraceCache->getMemMgr()->freeTraceMemory(slotBase, slotSize);
+    m_pTC->getMemMgr()->freeTraceMemory(slotBase, slotSize);
 
     // Deallocate the parameter structure
     delete m_pPhase3Info;
@@ -405,119 +308,41 @@
 
     for(vector<InstCandidate>::iterator i = candidates.begin(), e = candidates.end(); i != e; ++i) {
         cerr << "Transforming " << *i << endl;
-        unsigned slotSize = m_pInstManip->getSlotSize(this, *i);
+        unsigned slotSize = m_pIM->getSlotSize(this, *i);
 
         // Replace load candidate instruction with a branch to the start of a new slot.
         uint64_t slotBase = replaceInstWithBrToSlot(i->front().first, slotSize,
-                                                    m_pTraceCache, m_pInstManip);
+                                                    m_pTC, m_pIM);
 
         // Build the Phase4Info structure and generate the phase 4 slot.
 
-        Phase4Info* p4info = new Phase4Info(*i, slotBase, slotSize, m_pTraceCache, m_pInstManip);
+        Phase4Info* p4info = new Phase4Info(*i, slotBase, slotSize, m_pTC, m_pIM);
 
         vector<unsigned> snippet;
-        m_pInstManip->buildSlot(p4info, snippet);
+        m_pIM->buildSlot(p4info, snippet);
 
         // Dump snippet instructions:
         cerr << "phase4 slot instructions:" << endl;
         for(vector<unsigned>::iterator j = snippet.begin(), k = snippet.end(); j != k; ++j) {
-            m_pInstManip->printInst(*j);
+            m_pIM->printInst(*j);
             cerr << endl;
         }
 
         // Copy the snippet code into the slot
-        copySnippetToSlot(snippet, slotBase, m_pTraceCache->getVM(), m_pInstManip);
+        copySnippetToSlot(snippet, slotBase, m_pTC->getVM(), m_pIM);
 
         // just one candidate for now
         break;
     }
-
-    // {{{ Old version of this function
-
-#if 0
-    // For each load candidate, obtain a new slot and write the phase 3 slot region
-    // contents into it.  See diagram in comments at top of file for more info.
-
-    for(vector<InstCandidate>::iterator i = candidates.begin(), e = candidates.end(); i != e; ++i) {
-        cerr << "Transforming " << *i << endl;
-
-        // Replace load candidate instruction with a branch to the start of a new slot.
-        uint64_t slotBase = replaceInstWithBrToSlot(i->front().first, getSlotSize(*i),
-                                                    m_pTraceCache, *m_pInstManip);
-
-        // Generate the phase 4 slot. See picture of phase 4 slot contents for more info.
-
-        Phase4Info* p4info = new Phase4Info(*i, slotBase, getSlotSize(*i), m_pTraceCache, m_pInstManip);
-
-        uint64_t spillAddr = m_pInstManip->getPhase3SpillAddr();
-
-        vector<unsigned> snippet;
-        m_pInstManip->startCode(snippet);
-
-        // NB: We pass parameters to the phase4 function in REG_0 and REG_1 on the
-        // assumption that the input parameters will be looked for there. However, it is
-        // possible that the input parameters will be taken from the parameter array at
-        // fixed offsets from the stack pointer.  Hence, we store the parameters there as
-        // well.
-        
-        m_pInstManip->generateSave();
-        m_pInstManip->generateAddressCopy(i->front().second, InstManip::REG_0, true);      // REG_0 live to call
-        m_pInstManip->generateParamStore(InstManip::REG_0, SparcInstManip::PARAM_0);
-        m_pInstManip->generateSpillShared(spillAddr, InstManip::REG_1, InstManip::REG_2);
-        m_pInstManip->generateLoad((uint64_t) p4info, InstManip::REG_1, InstManip::REG_2); // REG_1 live to call
-        m_pInstManip->generateParamStore(InstManip::REG_1, SparcInstManip::PARAM_1);
-        m_pInstManip->generateCall((uint64_t) &phase4, slotBase);
-        m_pInstManip->generateRestoreShared(spillAddr);
-        m_pInstManip->generateBranchAlways(i->front().first, slotBase, m_pInstManip->getRestoreInst());
-
-        m_pInstManip->endCode();
-
-        // Dump snippet instructions:
-
-        cerr << "phase4 slot instructions:" << endl;
-        
-        for(vector<unsigned>::iterator j = snippet.begin(), k = snippet.end(); j != k; ++j) {
-            m_pInstManip->printInst(*j);
-            cerr << endl;
-        }
-
-        // Copy the snippet code into the slot
-        assert(snippet.size() == getSlotSize(*i) && "Snippet size does not match slot size");
-        copySnippetToSlot(snippet, slotBase, m_pTraceCache->getVM(), m_pInstManip);
-
-        // just one candidate for now
-        break;
-    }
-#endif
-
-    // }}}
 }
 
-#if 0
-unsigned Phase3::getSlotSize(InstCandidate& cand) const
-{
-    // The following sum corresponds to the sizes consumed by the various regions of the
-    // phase 3 slot.  See picture of phase 3 contents for details.
-
-    return m_pInstManip->getGenSaveSize() +
-        m_pInstManip->getGenAddressCopySize(cand.front().second) +
-        m_pInstManip->getGenParamStoreSize() +
-        m_pInstManip->getGenSpillSharedSize() +
-        m_pInstManip->getGenLoadSize() +
-        m_pInstManip->getGenParamStoreSize() +
-        m_pInstManip->getGenCallSize() +
-        m_pInstManip->getGenRestoreSharedSize() +
-        m_pInstManip->getGenBranchAlwaysSize();
-}
-#endif
-
 void Phase3::transform()
 {
     // 2. Analyze the function and determine the load-volatile candidates...
     vector<InstCandidate> candidates;
-    m_pInstManip->findCandidates(m_pPhase3Info->getStartAddr(),
-                               m_pPhase3Info->getEndAddr(),
-                               candidates);
+    m_pIM->findCandidates(m_pPhase3Info->getStartAddr(),
+                          m_pPhase3Info->getEndAddr(),
+                          candidates);
 
     // ...and process them
     processCandidates(candidates);
@@ -535,8 +360,8 @@
 
 Phase4::Phase4(uint64_t tag, Phase4Info* p4info):
     m_pPhase4Info(p4info),
-    m_pTraceCache(p4info->getTraceCache()),
-    m_pInstManip(p4info->getIM()),
+    m_pTC(p4info->getTraceCache()),
+    m_pIM(p4info->getIM()),
     m_tag(tag)
 {
     cerr << "phase4 ctor: tag is " << tag << endl;
@@ -555,7 +380,7 @@
 
     uint64_t slotBase = m_pPhase4Info->getSlot();
     unsigned slotSize = m_pPhase4Info->getSlotSize();
-    m_pTraceCache->getMemMgr()->freeTraceMemory(slotBase, slotSize);
+    m_pTC->getMemMgr()->freeTraceMemory(slotBase, slotSize);
 
     // Deallocate the parameter structure
     delete m_pPhase4Info;
@@ -603,16 +428,16 @@
         // it over the original code.
 
         uint64_t slotBase = replaceInstWithBrToSlot(cand.front().first, getSlotSize(),
-                                                    m_pTraceCache, m_instManip);
+                                                    m_pTC, m_instManip);
 #endif
 
         // Write NOPs over the original instructions that were associated with the elected
         // candidate, but leave the branch instruction intact.
 
-        VirtualMem* vm = m_pTraceCache->getVM();
+        VirtualMem* vm = m_pTC->getVM();
         for(vector<std::pair<uint64_t, unsigned> >::const_iterator i = cand.getInsts().begin() + 1,
                 e = cand.getInsts().end(); i != e; ++i)
-            vm->writeInstToVM(i->first, m_pInstManip->getNOP());
+            vm->writeInstToVM(i->first, m_pIM->getNOP());
 
         // Write the instructions to call the instrumentation function
 


Index: llvm/lib/Reoptimizer/Inst/SparcInstManip.cpp
diff -u llvm/lib/Reoptimizer/Inst/SparcInstManip.cpp:1.2 llvm/lib/Reoptimizer/Inst/SparcInstManip.cpp:1.3
--- llvm/lib/Reoptimizer/Inst/SparcInstManip.cpp:1.2	Wed Apr 30 11:36:09 2003
+++ llvm/lib/Reoptimizer/Inst/SparcInstManip.cpp	Wed Apr 30 12:31:47 2003
@@ -3,6 +3,37 @@
 //       date: Tue Apr 29 21:21:50 CDT 2003
 //     fileid: SparcInstManip.cpp
 //    purpose: Implements the SparcInstManip class as described in SparcInstManip.h
+//
+// SparcInstManip implements behavior that constructs the contents of "slots" -- regions
+// of memory allocated by a MemoryManager instance that will be branch to at runtime.  A
+// phase n slot is written by phase n-1, and is when executed, invokes the appropriate
+// function for phase n.
+//
+// Phase 3 slot:
+//                        +------------------------------------+
+//                        |   save registers (new stack frame) |
+//                        |      spill shared registers        |
+//                        |  load Phase3Info addr to param1    |
+//                        |           call to phase 3          |
+//                        |                nop                 |
+//                        |       restore shared registers     |
+//                        |        branch back to orig code    |
+//                        |          restore registers         |
+//                        +------------------------------------+
+//
+// Phase 4 slot:
+//                       +---------------------------------------+
+//                       |    save registers (new stack frame)   |
+//                       |         spill shared registers        |
+//                       |      copy load-src addr to param1     |
+//                       |      load Phase4Info addr to param2   |
+//                       |           call to phase 4             |
+//                       |                nop                    |
+//                       |      restore shared registers         |
+//                       |        branch back to orig code       |
+//                       |          restore registers            |
+//                       +---------------------------------------+
+// []
 
 #include <iostream>
 #include <iomanip>
@@ -16,7 +47,6 @@
 #include "SparcInstManip.h"
 #include "PhaseInfo.h"
 
-const unsigned SparcInstManip::NOP_INST = 0x01000000;
 const unsigned SparcInstManip::BRANCH_ALWAYS_BASE = 0x10480000;
 const unsigned SparcInstManip::BRANCH_ALWAYS_BASE_ANNUL = 0x30480000;
 const unsigned SparcInstManip::BIAS = 2047;
@@ -31,7 +61,7 @@
 void phase4(uint64_t tag, Phase4Info* p4info);
 
 SparcInstManip::SparcInstManip(TraceCache* tc):
-    InstManip(tc, SHARED_SIZE, INST_WIDTH),
+    InstManip(tc, SHARED_SIZE, INST_WIDTH, NOP_INST),
     m_pCurrSnippet(0)
 {
     assert(tc && "SparcInstManip requires valid TraceCache instance");
@@ -154,6 +184,17 @@
         getGenBranchAlwaysSize();
 }
 
+void SparcInstManip::findCandidates(uint64_t start,
+                                    uint64_t end,
+                                    vector<InstCandidate>& candidates) 
+{
+    for(uint64_t currAddr = start; currAddr <= end; currAddr += getInstWidth()) {
+        InstCandidate cand(this);
+        if(isCandidateLoad(currAddr, end, cand))
+            candidates.push_back(cand);
+    }
+}
+
 uint64_t SparcInstManip::getStartAddr(uint64_t addr) const
 {
     // For SparcV9, skip the save instruction, if present.
@@ -293,7 +334,7 @@
 
     // Add call instruction and nop (for call delay slot) to code snippet.
     snippet.push_back(getCallInst(dest, callInstAddr));
-    snippet.push_back(NOP_INST);
+    snippet.push_back(getNOP());
 
     assert(snippet.size() - initSize == getGenCallSize() &&
            "Unexpected number of instructions in code sequence for call");
@@ -401,17 +442,6 @@
 
     assert(snippet.size() - initSize == getGenBranchAlwaysSize() &&
            "Unexpected number of instruction in code sequence for branch-always");
-}
-
-void SparcInstManip::findCandidates(uint64_t start,
-                                    uint64_t end,
-                                    vector<InstCandidate>& candidates) 
-{
-    for(uint64_t currAddr = start; currAddr <= end; currAddr += getInstWidth()) {
-        InstCandidate cand(this);
-        if(isCandidateLoad(currAddr, end, cand))
-            candidates.push_back(cand);
-    }
 }
 
 static inline bool isLoadHalfWord(unsigned inst)


Index: llvm/lib/Reoptimizer/Inst/SparcInstManip.h
diff -u llvm/lib/Reoptimizer/Inst/SparcInstManip.h:1.2 llvm/lib/Reoptimizer/Inst/SparcInstManip.h:1.3
--- llvm/lib/Reoptimizer/Inst/SparcInstManip.h:1.2	Wed Apr 30 11:36:09 2003
+++ llvm/lib/Reoptimizer/Inst/SparcInstManip.h	Wed Apr 30 12:31:47 2003
@@ -17,7 +17,7 @@
 class SparcInstManip : public InstManip
 {
   public:
-    SparcInstManip(TraceCache* vm);
+    SparcInstManip(TraceCache* tc);
 
     // Offsets in stack frame for function parameters
     enum StackOffset {
@@ -35,6 +35,11 @@
 
     virtual unsigned getSlotSize(Phase2* p2) const;
     virtual unsigned getSlotSize(Phase3* p3, InstCandidate& cand) const;
+
+    virtual void     findCandidates(uint64_t start,
+                                    uint64_t end,
+                                    std::vector<InstCandidate>& candidates);
+
     virtual uint64_t getStartAddr(uint64_t funcStartAddr) const;
     inline unsigned  getBranchAlways(uint64_t dest, uint64_t pc, bool annulHigh = true) const;
     inline bool      isBranch(unsigned inst) const;
@@ -73,17 +78,12 @@
                                          LogicalRegister tmp1 = REG_0,
                                          LogicalRegister tmp2 = REG_1);
                      
-    void             findCandidates(uint64_t start,
-                                    uint64_t end,
-                                    std::vector<InstCandidate>& candidates);
-                     
     unsigned         getRestoreInst() const;
     inline unsigned  getCallInst(uint64_t dest, uint64_t pc) const;
 
     // These are functions so when SparcInstManip is superclassed, they'd become virtual, etc.
     // In the short term we could use class constants, but this is more clear.
     
-    unsigned         getNOP() const                   { return NOP_INST;                       }
     unsigned         getGenLoadSize() const           { return 6;                              }
     unsigned         getGenCallSize() const           { return 2;                              }
     unsigned         getGenBranchAlwaysSize() const   { return 2;                              }
@@ -127,8 +127,8 @@
     // Branch-always (annul bit low) instruction base (i.e., address not filled in yet)
     static const unsigned BRANCH_ALWAYS_BASE;
 
-    // NOP instruction
-    static const unsigned NOP_INST;
+    // NOP instruction for SparcV9
+    static const unsigned NOP_INST = 0x01000000;
 
     // Size (in number of 64-bit words) required for storing shared registers
     static const unsigned SHARED_SIZE = 7;





More information about the llvm-commits mailing list