[llvm-commits] CVS: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp SecondTrigger.cpp

Brian Gaeke gaeke at niobe.cs.uiuc.edu
Wed Aug 6 16:53:01 PDT 2003


Changes in directory llvm/lib/Reoptimizer/LightWtProfiling/Trigger:

FirstTrigger.cpp updated: 1.8 -> 1.9
SecondTrigger.cpp updated: 1.6 -> 1.7

---
Log message:

Move private includes to top of files.
Add many more meaningful comments.
Remove global map iterationCounter, which is incremented but never tested.
Instead of manually extracting return address from %i7, use GCC's
 __builtin_return_address(0).
Refactor scanning-for-branch functionality which is shared between
 FirstTrigger.cpp and SecondTrigger.cpp.

Also:

FirstTrigger.cpp: 
Include scheduler.h, SLI.h and Timer.h for access to functions from
 those files, instead of copying the extern decls here.
Change declaration of dummy function used for trace cache.
Remove seenOccur, which is never used.  Remove getFirstTrace, which is just
 a wrapper around doInstrumentation.
Switch to using `pcAddr' for the name of the return address, to correspond
 more closely to SecondTrigger.
 
SecondTrigger.cpp: 
Include Timer.h for access to functions from that file, instead of
 copying the extern decls here.
Add a bit of debugging output to triggerBB (not yet used).


---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp
diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.8 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.9
--- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp:1.8	Tue Aug  5 14:34:19 2003
+++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/FirstTrigger.cpp	Wed Aug  6 16:52:04 2003
@@ -8,6 +8,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "GetTimer.h"
+#include "RegSaveRestore.h"
+#include "scheduler.h"
+#include "SLI.h"
+#include "Timer.h"
 #include "llvm/Reoptimizer/VirtualMem.h"
 #include "llvm/Reoptimizer/InstrUtils.h"
 #include "llvm/Reoptimizer/TraceCache.h"
@@ -16,32 +21,26 @@
 #include <sys/time.h>
 #include <cstdlib>
 #include <algorithm>
-#include "GetTimer.h"
 #ifdef __sparc
 #include <libcpc.h>
 #endif
-#include "RegSaveRestore.h"
 
 using namespace std;
 
 extern long THRESHOLD_LEVEL_2;
 extern long LEVEL_TWO_EXITS; 
 
-// Function used as space for the trace cache:
-extern int dummyFunction2(int);
+// Function used as space for the second-level instrumentation trace cache.
+extern "C" void dummyFunction2 ();
+
+// From SecondTrigger.cpp:
+extern uint32_t scanForBranch (const uint64_t startAddr, uint64_t &foundAddr);
 
 // Global counters for diagnostics:
-int initialize_timer();
-extern uint64_t llvm_interval_counter;
 extern std::map<uint64_t, int> exitCounter;
-extern std::map<uint64_t, int> iterationCounter;
 extern std::map<uint64_t, uint64_t> firstTriggerAddr; //tracestart addr
 extern std::map<uint64_t, std::pair<long, long> > backOffCounters; 
 
-// Good, bad backoff
-void insert_address_at(uint64_t n, uint64_t m);
-void doInstrumentation(uint64_t addr1, uint64_t addr2, VirtualMem *vm);
-
 int reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1;
 int exit_count=0;
 
@@ -49,19 +48,15 @@
 TraceCache *tr2;
 VirtualMem *vm;
 
-void getFirstTrace(uint64_t addr1, uint64_t addr2, int depth, VirtualMem *vm, 
-		   TraceCache *tr){
-  //addr1: the "target" of backward branch
-  //addr2: the PC of branch instruction
-  //to read any instruction at address addr1 do the following
-  //     unsigned int instr =  vm->readInstrFrmVm(addr);
-  doInstrumentation(addr1, addr2, vm);
-}
-
+// Initialization method for the reoptimizer. A call to this function
+// from main() is inserted by the opt -instloops pass
+// (Transforms/Instrumentation/ProfilePaths/InstLoops.cpp).
+// reoptimizerInitialize is passed a pointer to reopt_threshold in t
+// (why?)
 extern "C" void reoptimizerInitialize(int *t){
   vm = new VirtualMem();
   tr = new TraceCache(30000, vm);
-  tr2 = new TraceCache(&dummyFunction2, 30000, vm);
+  tr2 = new TraceCache(dummyFunction2, 30000, vm);
  
   if(getenv("THRESHOLD_LEVEL_2")!=NULL)
     THRESHOLD_LEVEL_2 = atoi(getenv("THRESHOLD_LEVEL_2"));
@@ -75,6 +70,10 @@
   else
     reopt_threshold = DEFAULT_THRESHOLD_LEVEL_1;
 
+  // FIXME: This should not be necessary if we are already setting
+  // reopt_threshold above. Remove the junk from InstLoops.cpp that
+  // makes reopt_threshold visible to the called program, and remove
+  // this, later.
   *t=30;
 
   //initialize_timer();
@@ -102,45 +101,38 @@
   SAVE_FPRS_REG(fprs_reg);
   SAVE_CCR_REG(ccr_reg);
 
-  // Maps of counters we use:
+  // This is where we keep the counter for each first-level
+  // instrumented branch.
   static map<uint64_t, int> counterMap;
-  static map<uint64_t, int> seenOccur;
 
-  // FIXME: What is brAddr?
-  uint64_t brAddr;
-#ifdef __sparc
-  asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0));
-#else
-  assert(false && "Case not handled for this processor architecture!");
-#endif
+  // Get return address of this invocation (on SPARC, this is in %i7).
+  uint64_t pcAddr = (uint64_t) __builtin_return_address(0);
 
   // Increment the counter for this branch, and check it against
   // THRESHOLD_LEVEL_1. If it exceeds the threshold, we may have to
   // generate second-level instrumentation (SLI).
-  if(++counterMap[brAddr] > reopt_threshold){
-    counterMap.erase(brAddr);
-    //std::cerr<<"Originally Removed from addr: "<<(void *)brAddr<<"\n";
-
-    // Scan forward through memory starting from brAddr, looking for a branch
-    // instruction.
-    char offst = 8; 
-    unsigned int brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2);
-    while(!isBranchInstr(brInst)){
-      offst += 4;
-      brInst = vm->readInstrFrmVm(brAddr + offst, tr, tr2);
-    }
-    assert(isBranchInstr(brInst) && "Not a branch!");
-    uint64_t brTarget = getBranchTarget(brInst, brAddr+offst);
-    firstTriggerAddr[brTarget] = brAddr;
+  if(++counterMap[pcAddr] > reopt_threshold){
+    counterMap.erase(pcAddr);
+    //std::cerr<<"Originally Removed from addr: "<<(void *)pcAddr<<"\n";
+
+    // Scan forward through memory starting from pcAddr+8 looking for
+    // a branch instruction. The first one we find should be the
+    // backward branch that was instrumented.
+    uint64_t branchAddr;
+    uint32_t brInst = scanForBranch (pcAddr + 8, branchAddr);
+    
+    // Get the target of the (assumed backward) branch we found.
+    uint64_t brTarget = getBranchTarget (brInst, branchAddr);
+    firstTriggerAddr[brTarget] = pcAddr;
     
     // Check if trace cache already has optimized code. If it does,
     // we do not generate SLI.
-    if(!tr->hasTraceAddr(brTarget, brAddr+offst)) {
+    if(!tr->hasTraceAddr(brTarget, branchAddr)) {
       // No optimized code in trace cache; generate SLI now.
-      getFirstTrace(brTarget, brAddr+offst, 100, vm, tr);
+      doInstrumentation(brTarget, branchAddr, vm);
     } else {
 #ifdef GET_ALL_INFO
-      std::cerr<<"SLI-exists\t"<<(void *)brTarget<<"\t"<<(void *)(brTarget+offst)<<"\n";
+      std::cerr<<"SLI-exists\t"<<(void *)brTarget<<"\t"<<(void *)branchAddr<<"\n";
 #endif
       // Write a branch going to the top of the trace in tr.
       uint64_t traceAddrInTC = tr->getStartAddr(brTarget);
@@ -150,12 +142,17 @@
       doFlush(brTarget-16, brTarget+16);
       doFlush(traceAddrInTC-16, traceAddrInTC+16);
     }
-        
-    assert(isCallInstr(vm->readInstrFrmVm(brAddr, tr, tr2)) && "not call");
-    vm->writeInstToVM(brAddr, NOP);
-    doFlush(brAddr-8, brAddr+16);
+    
+    // Overwrite the call instruction that called llvm_first_trigger
+    // with a NOP, thus turning off first-level instrumentation for
+    // this branch.
+    assert(isCallInstr(vm->readInstrFrmVm(pcAddr, tr, tr2)) &&
+	   "Couldn't find call instruction that called llvm_first_trigger");
+    vm->writeInstToVM(pcAddr, NOP);
+    doFlush(pcAddr-8, pcAddr+16);
   }
- 
+
+  // FIXME: Why are these here?
   fprs_reg ^= 0;
   ccr_reg ^= 0;
 


Index: llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp
diff -u llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.6 llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.7
--- llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp:1.6	Tue Aug  5 15:00:18 2003
+++ llvm/lib/Reoptimizer/LightWtProfiling/Trigger/SecondTrigger.cpp	Wed Aug  6 16:52:05 2003
@@ -8,6 +8,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "GetTimer.h"
+#include "RegSaveRestore.h"
+#include "Timer.h"
 #include "llvm/Reoptimizer/Mapping/LLVMinfo.h"
 #include "llvm/Reoptimizer/VirtualMem.h"
 #include "llvm/Reoptimizer/InstrUtils.h"
@@ -16,12 +19,9 @@
 #include "llvm/iTerminators.h"
 #include "llvm/Support/CFG.h"
 #include "llvm/Module.h"
-#include "GetTimer.h"
-#include "RegSaveRestore.h"
 #include <sys/time.h>
 #include <sys/types.h>
 #include <cstdlib>
-
 #ifdef __sparc
 #include <libcpc.h>
 #endif
@@ -30,12 +30,13 @@
 using std::vector;
 using std::pair;
 
-extern "C" void llvm_time_end2();
-extern "C" void llvm_time_start();
-
 #define CALL 0x40000000
 
 long THRESHOLD_LEVEL_2;
+
+// If a trace selected as "hot" is exited more than a certain number
+// of times, then it will be rejected; this certain number is set to
+// 1/3 of the THRESHOLD_LEVEL_2 value.
 long LEVEL_TWO_EXITS; 
 
 extern TraceCache *tr;
@@ -48,22 +49,23 @@
 
 extern "C" void llvm_first_trigger(int *cnt);
 
-//global counters for diagonistcs
 void insert_address_at(uint64_t n, uint64_t m);
+
+// Forward declarations
 void generateTraces(uint64_t start, uint64_t end, 
 		    std::vector<uint64_t> &paths, 
 		    uint64_t firstLevelTraceStartAddr);
 void getReturnCode(vector<unsigned int> &traces, int &index, 
 		   uint64_t ret);
 
-extern uint64_t llvm_interval_counter;
 std::map<uint64_t, int> exitCounter;
-//std::map<uint64_t, int> iterationCounter;
 std::map<uint64_t, uint64_t> firstTriggerAddr; //tracestart addr
 std::map<uint64_t, pair<long, long> > backOffCounters;
 
 void triggerBB(vector<BasicBlock *> &vBB, VirtualMem *vm, TraceCache *tr, 
-	       TraceCache *tr2, uint64_t a);
+	       TraceCache *tr2, uint64_t a) {
+  std::cerr << "We made it to triggerBB\n";
+}
 
 extern "C" void llvm_time_start(){
 #ifdef __sparc
@@ -101,13 +103,15 @@
   SAVE_FPRS_REG(fprs_reg);
   SAVE_CCR_REG(ccr_reg);
 
-  uint64_t brAddr;
-#ifdef __sparc
-  asm("add %%i7, %1, %0":"=r"(brAddr):"i" (0));
-#endif
+  // Get return address of this invocation (on SPARC, this is in %i7).
+  uint64_t brAddr = (uint64_t) __builtin_return_address(0);
+
   uint64_t reverseAddr = tr->getOriginalAddress(tr->getAddrLessThan(brAddr));
+
+  // Increment the number of times we have exited the trace.
   int accumulate = exitCounter[reverseAddr]++;
-  
+
+  // If we've exited the trace more than LEVEL_TWO_EXITS times, then...
   if(accumulate > LEVEL_TWO_EXITS){
 
 #ifdef GET_ALL_INFO
@@ -121,7 +125,6 @@
     delete pathCounter[reverseAddr];
     pathCounter.erase(reverseAddr);
     totalCount[reverseAddr] = 0;
-    //    iterationCounter[reverseAddr] = 0;
     
     tr->patchTrace(tr->getAddrLessThan(brAddr));
     if(!backOffCounters[reverseAddr].second)
@@ -187,6 +190,23 @@
   }
 }
 
+/// Scan forward through memory starting from startAddr looking for a
+/// branch instruction. When one is found, foundAddr is set to its
+/// address, and the instruction word itself is returned.
+///
+uint32_t scanForBranch (const uint64_t startAddr, uint64_t &foundAddr)
+{
+  uint64_t addr = startAddr;
+  uint32_t instr = vm->readInstrFrmVm (addr, tr, tr2);
+  while (!isBranchInstr (instr)) {
+    addr += 4;
+    instr = vm->readInstrFrmVm (addr, tr, tr2);
+  }
+  foundAddr = addr;
+  assert (isBranchInstr (instr) && "scanForBranch: Found instr not a branch!");
+  return instr;
+}
+
 void countPath () {
   uint64_t branchHist;
   uint64_t i_reg_save[6];
@@ -197,6 +217,7 @@
   uint64_t fsr_reg;
   uint64_t g1_reg;
 
+  // Save registers on the stack in variables declared above.
   SAVE_I_REGS(i_reg_save);
   SAVE_G1_REG(branchHist);
   SAVE_G1_REG(g1_reg);
@@ -207,27 +228,19 @@
   SAVE_FPRS_REG(fprs_reg);
   SAVE_CCR_REG(ccr_reg);
  
-  uint64_t pcAddr, startAddr, endAddr;
-  
-  //get the PC address for call to trigger
-#ifdef __sparc
-  asm volatile("add %%i7, %1, %0":"=r"(pcAddr):"i" (0));
-#else
-  assert(false && "Case not handled for this processor architecture!");
-#endif
-
-  unsigned int offst = 4;
-  unsigned int branchInstr;
-  do{
-    offst += 4;
-    branchInstr = vm->readInstrFrmVm(pcAddr+offst, tr, tr2);
-  }while(!isBranchInstr(branchInstr));
-  
-  endAddr = pcAddr + offst+4; //until delay slot!
+  // Get return address -- that is, the PC where this call to countPath
+  // was made (on SPARC, this is in %i7).
+  uint64_t pcAddr = (uint64_t) __builtin_return_address(0);
+
+  // Scan forward through memory starting from pcAddr+8 looking for a
+  // branch instruction.
+  uint64_t branchAddr;
+  uint32_t branchInstr = scanForBranch (pcAddr + 8, branchAddr);
+  uint64_t endAddr = branchAddr + 4; // Address of branch delay slot.
 
-  startAddr = getBranchTarget(branchInstr, pcAddr+offst);
+  // Get the target of the branch we found.
+  uint64_t startAddr = getBranchTarget(branchInstr, branchAddr);
   uint64_t reverseAddr = tr->getOriginalAddress(startAddr);
-  //++iterationCounter[reverseAddr];
 
   pcAddr = reverseAddr;
 
@@ -254,7 +267,6 @@
       delete pathCounter[pcAddr];
       pathCounter.erase(pcAddr);
       totalCount[pcAddr] = 0;
-      //iterationCounter[reverseAddr] = 0;
       exitCounter[reverseAddr] = 0;
       
       tr->patchTrace(startAddr);
@@ -280,7 +292,6 @@
 	    
 	    int total = totalCount[pcAddr];
 
-	    //	    iterationCounter[reverseAddr] = 0;
 	    exitCounter[reverseAddr] = 0;
 	    if(!backOffCounters[reverseAddr].first)
 	      backOffCounters[reverseAddr].first = 1;
@@ -336,7 +347,6 @@
 	    delete pathCounter[pcAddr];
 	    pathCounter.erase(pcAddr);
 	    totalCount[pcAddr] = 0;
-	    //	    iterationCounter[reverseAddr] = 0;
 	    exitCounter[reverseAddr] = 0;
 
 	    tr->patchTrace(startAddr);





More information about the llvm-commits mailing list