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

Joel Stanley jstanley at cs.uiuc.edu
Sun May 18 22:01:00 PDT 2003


Changes in directory llvm/lib/Reoptimizer/Inst/lib:

SparcInstManip.cpp updated: 1.14 -> 1.15
SparcInstManip.h updated: 1.13 -> 1.14

---
Log message:

Fixed bug with address copy when the compiler-generated address arithmetic
relies on a value in a local register. The solution is a bit ugly, and a better
one is probably needed.


---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp
diff -u llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.14 llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.15
--- llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp:1.14	Sun May 18 20:35:31 2003
+++ llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.cpp	Sun May 18 22:00:38 2003
@@ -5,9 +5,10 @@
 //    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.
+// of memory allocated by a MemoryManager instance and/or off of the heap that will be
+// branched to at runtime.  A phase n slot is written by phase n-1, and is when executed,
+// invokes the appropriate function for phase n.  The notable exception is the last phase,
+// which will end up invoking the proper instrumentation function.
 //
 // Phase 3 slot:
 //                        +------------------------------------+
@@ -34,23 +35,27 @@
 //                       |          restore registers            |
 //                       +---------------------------------------+
 //
-// Phase 5 slot:
-//   NB: Slot does *not* save registers with the 'save' instruction, because
-//       it must perform the alloca within the stack frame of the code that
-//       invoked it.
-//           +------------------------------------------------------+
-//           | alloc spill area/reg save/inst param region on stack |
-//           |          manually-save clobbered registers           |
-//           |              spill shared registers                  |
-//           |              copy GBTElem ptr to param 1             |
-//           |            copy spill area addr to param 2           |
-//           |                   call phase 5                       |
-//           |                        nop                           |
-//           |                restore shared registers              |
-//           |          manually-restore clobbered registers        |
-//           |               branch back to orig code               |
-//           |                         nop                          |
-//           +------------------------------------------------------+
+// Phase 5 "jump slot":
+//           +---------------------------------------------------+
+//           | obtain new stack frame w/ spill region & RA space |
+//           |          load address of heap slot                |
+//           |                 jmpl to heap slot                 |
+//           |               branch back to orig code            |
+//           |                  restore registers                |
+//           +---------------------------------------------------+
+// 
+//
+// Phase 5 heap slot:
+//           +-------------------------------------------------+
+//           |         spill shared registers (to stack)       |
+//           |         copy GBTElem ptr to param 1             |
+//           |       copy spill area addr to param 2           |
+//           |              call phase 5                       |
+//           |                   nop                           |
+//           |           restore shared registers (from stack) |
+//           |          return to phase 5 jump slot            |
+//           |                    nop                          |
+//           +-------------------------------------------------+
 // []
 
 #include <iostream>
@@ -123,7 +128,7 @@
         m_outputToInputReg[i] = i;
 }
 
-static unsigned getSPSub(unsigned size)
+static unsigned getSPSub(int size)
 {
     return MK_ADD_R_I(R_O6, R_O6, -size);
 }
@@ -166,15 +171,31 @@
     uint64_t slotBase = p4info->getSlot();
     uint64_t spillAddr = (uint64_t) getPhase4SpillAddr();
     const InstCandidate& cand = p4info->getCandidate();
+
+    // It is possible that the arithmetic used in the load-volatile instruction candidate
+    // uses a local register. If this is the case, we must perform the arithmetic before
+    // actually issuing the save command, because we lose the contents of the local
+    // registers after the save completes.  Hence, we make room for one word on the stack
+    // so that we can save the result of the arithmetic.
     
     startCode(snippet);
 
+    unsigned stkSize = getAligned(STKFRM_MIN + WORD_WIDTH);
+    generateSPSub(stkSize);
+    generateStackStore(REG_0, STKFRM_MIN);
+    generateAddressCopy(cand.front().second, REG_0, false); // REG_0 live to call
     generateSave();
 
+    // REG_0, which was "live to call" at the address copy, is now the corresponding
+    // input register because the save instruction gave us a new window. Transfer the
+    // value in the corresponding input register into REG_0.
+
+    unsigned reg = m_logicalToActualReg[REG_0];
+    m_pCurrSnippet->push_back(MK_MOV_R_R(reg, m_outputToInputReg[reg]));
+    
     // NB: Pass the value found in the register used by the candidate-load instruction,
     // and the p4info ptr to the phase4 function call.
 
-    generateAddressCopy(cand.front().second, REG_0, true); // REG_0 live to call
     generateStackStore(REG_0, PARAM_0);
     generateSpillShared(spillAddr, REG_1, REG_2);
     generateLoad((uint64_t) p4info, REG_1, REG_2);         // REG_1 live to call
@@ -182,7 +203,9 @@
     generateCall((uint64_t) &phase4, slotBase);
 
     generateRestoreShared(spillAddr, REG_0, REG_1);
-    generateBranchAlways(cand.front().first, slotBase, getRestoreInst());
+    generateRestore();
+    generateStackLoad(REG_0, STKFRM_MIN);
+    generateBranchAlways(cand.front().first, slotBase, getSPSub(-stkSize));
 
     endCode();
 
@@ -208,13 +231,13 @@
 {
     unsigned sharedSize = WORD_WIDTH * getSharedSize();
 
-    // WORD_WIDTH * 3 belows occurs because we need two words for saving the values of the
-    // two scratch registers, and 1 word for saving the return address in the jump slot.
-    unsigned stkSize = getAligned(STKFRM_MIN + sharedSize + WORD_WIDTH * 3);
+    // WORD_WIDTH occurs below because we need a word for saving the return address (in
+    // the jump slot) for use in the heap slot.
+    unsigned stkSize = getAligned(STKFRM_MIN + sharedSize + WORD_WIDTH);
 
     DEBUG_MSG(2, "buildSlot(p5) stack offset is " << stkSize << endl);
 
-    unsigned retAddrStkOff = STKFRM_MIN + sharedSize + 2 * WORD_WIDTH;
+    unsigned retAddrStkOff = STKFRM_MIN + sharedSize;
     unsigned* heapSlot = buildPhase5HeapSlot(gbte, sharedSize, retAddrStkOff);
 
     DEBUG_MSG(2, "buildPhase5HeapSlot completed\n");
@@ -238,27 +261,17 @@
     //                            +--------------------------------+
     //                            | ret addr for use by heap slot  | } WORD_WIDTH
     //                            +--------------------------------+
-    //                            | save area for clobbered regs   | } WORD_WIDTH * 2
-    //                            +--------------------------------+
     //                            | spill region for shared regs   | } sharedSize
     //  sp + BIAS + STKFRM_MIN -> +--------------------------------+
     //
 
-    generateSPSub(stkSize);
-
-    // Save registers REG_{0,7} so we don't have to issue a 'save'
-    generateStackStore(REG_0, STKFRM_MIN + sharedSize);
-    generateStackStore(REG_7, STKFRM_MIN + sharedSize + WORD_WIDTH);
+    generateSave(stkSize);
 
     // Address of jmpl instruction will be in REG_7 at entry to heapSlot.
     // This means that REG_7 is live until its use in heapSlot.
     generateLdJmpl((uint64_t) heapSlot, REG_0, REG_7);
 
-    // Restore registers REG_{0,7} so we don't have to issue a 'restore'
-    generateStackLoad(REG_0, STKFRM_MIN + sharedSize);
-    generateStackLoad(REG_7, STKFRM_MIN + sharedSize + WORD_WIDTH);
-
-    generateBranchAlways(instAddr + getInstWidth(), slotBase, getSPSub(-stkSize));
+    generateBranchAlways(instAddr + getInstWidth(), slotBase, getRestoreInst());
 
     endCode();
     DEBUG_MSG(2, "buildSlot(p5) completed\n");
@@ -289,14 +302,19 @@
 
     (void) p3;
     
-    return GEN_SAVE_SIZE + 
+    return GEN_SPSUB_SIZE +
+        GEN_STKSTORE_SIZE +
         getGenAddressCopySize(cand.front().second) +
+        GEN_SAVE_SIZE +
+        GEN_MOV_SIZE +
         GEN_STKSTORE_SIZE +
         GEN_SPL_SIZE +
         GEN_LOAD_SIZE +
         GEN_STKSTORE_SIZE +
         GEN_CALL_SIZE +
         GEN_UNSPL_SIZE +
+        GEN_RESTORE_SIZE +
+        GEN_STKLOAD_SIZE +
         GEN_BRANCH_ALWAYS_SIZE;
 }
 
@@ -309,14 +327,8 @@
     (void) p4;
 
     return
-        GEN_SPSUB_SIZE +
-        GEN_STKSTORE_SIZE +
-        GEN_STKSTORE_SIZE +
-        GEN_STKSTORE_SIZE +
+        GEN_SAVE_SIZE +
         GEN_LDJMPL_SIZE +
-        GEN_STKLOAD_SIZE +
-        GEN_STKLOAD_SIZE +
-        GEN_STKLOAD_SIZE +
         GEN_BRANCH_ALWAYS_SIZE;
 }
 
@@ -493,9 +505,9 @@
            "Unexpected number of instructions in code sequence for SP offset");
 }
 
-// generateSPSub - Generate code to allocate 'size' bytes on the stack
+// generateSPSub - Generate code to decrement %sp by 'size' bytes.
 
-void SparcInstManip::generateSPSub(unsigned size)
+void SparcInstManip::generateSPSub(int size)
 {
     assert(m_pCurrSnippet && "Invalid snippet for code generation");
     assert(size % STACK_ALIGN == 0 && "SP size is not aligned");


Index: llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.h
diff -u llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.h:1.13 llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.h:1.14
--- llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.h:1.13	Sun May 18 20:35:31 2003
+++ llvm/lib/Reoptimizer/Inst/lib/SparcInstManip.h	Sun May 18 22:00:38 2003
@@ -70,7 +70,7 @@
                      
     void             generateCall(uint64_t dest, uint64_t slotBase);
     void             generateSPOffset(LogicalRegister reg, unsigned offset);
-    void             generateSPSub(unsigned size);
+    void             generateSPSub(int size);
 
     void             generateJmpl(LogicalRegister useForIndirect,
                                   LogicalRegister returnAddrDest,
@@ -175,6 +175,7 @@
     static const unsigned GEN_SPOFFSET_SIZE =      1;
     static const unsigned GEN_JMPL_SIZE =          2;
     static const unsigned GEN_LDJMPL_SIZE =        GEN_LOAD_SIZE + GEN_JMPL_SIZE;
+    static const unsigned GEN_MOV_SIZE =           1;
 };
 
 unsigned SparcInstManip::getBranchAlways(uint64_t dest, uint64_t pc, bool annul) const





More information about the llvm-commits mailing list