[llvm-commits] CVS: llvm/lib/Reoptimizer/BinInterface/select.cpp

Anand Shukla ashukla at cs.uiuc.edu
Sat May 31 17:08:01 PDT 2003


Changes in directory llvm/lib/Reoptimizer/BinInterface:

select.cpp updated: 1.3 -> 1.4

---
Log message:

First version of working bininterface API/implementation

---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/BinInterface/select.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/select.cpp:1.3 llvm/lib/Reoptimizer/BinInterface/select.cpp:1.4
--- llvm/lib/Reoptimizer/BinInterface/select.cpp:1.3	Thu Apr 10 18:12:35 2003
+++ llvm/lib/Reoptimizer/BinInterface/select.cpp	Sat May 31 17:07:49 2003
@@ -1,33 +1,22 @@
-//*****************************************************************************
-//                   SPARC Binary Manipulation Interface
+//===--------llvm/Reoptimizer/BinInterface/select.cpp-------------*- C++ -*--=//
 //
 //                          Register Allocator
-//
-// Interface Definition
-//
-//
-// 2002 Cameron Buschardt
-//*****************************************************************************
-
-
+//===----------------------------------------------------------------------===//
 
+#include "llvm/Reoptimizer/BinInterface/analyze.h"  // SPARC analysis library 
+#include "llvm/Reoptimizer/BinInterface/sparcbin.h" // Prototype for this class
+#include "llvm/Reoptimizer/BinInterface/sparcpriv.h"// Private definitions
+#include "llvm/Reoptimizer/BinInterface/sparcdis.h" // sparc disassembler
+#include "llvm/Reoptimizer/BinInterface/bitmath.h"  // binary math routines
+#include "llvm/Reoptimizer/BinInterface/sparc9.h"   // SPARC9 opcode definitions
+#include "llvm/Reoptimizer/BinInterface/regmask.h"  // Register mask allocator
 #include <stdio.h>
 #include <stdlib.h>
-#include "salloc.h"         // Stack allocator class
-#include "fvector.h"        // fast vector (sits on stack allocator)
-#include "analyze.h"        // SPARC analysis library 
-#include "sparcbin.h"       // Prototype for this class
-#include "sparcpriv.h"      // Private definitions
-#include "regmask.h"        // Register mask allocator
-
-#include "llvm/Reoptimizer/BinInterface/sparcdis.h"       // prototype for sparc disassembler
-#include "llvm/Reoptimizer/BinInterface/bitmath.h"        // header of optimized binary math routines
-#include "llvm/Reoptimizer/BinInterface/sparc9.h"         // SPARC 9 opcode definitions
+#include <vector>
+#include <assert.h>
 
-#include <vector>           // Use STL pair class
 using std::pair;
 
-#include <assert.h>
 
 //*****************************************************************************
 // select(regalloc & regs)
@@ -41,111 +30,137 @@
 {
    regs.touched_regs = 0;    // mask containing all the touched registers
    regs.liveout_regs = 0;    // mask of JUST liveout registers
-   
+   regs.livein_regs = 0;
+
    unsigned  max_midx= 0;    // maximal stack index that we access
    
    // don't assign vreg of 0.
-   int       free_vreg = 1, s,k,i,p;          // first free
+   unsigned int free_vreg = 1, s,k,i,p;          // first free
 
    // This table stores the Virtual Registers that were
    // assigned to each SSA node
-   fvector<unsigned> & ssa_to_vreg   = regs.ssa_to_vreg;
+   vector<unsigned> & ssa_to_vreg   = regs.ssa_to_vreg;
    
    // This table has the live-range and register assignments
    // for a given virtual register
-   fvector<vreginfo> & vregs         = regs.vregs;
+   vector<vreginfo> & vregs         = regs.vregs;
 
    // Mark everyone as having no register assigned
-   ssa_to_vreg.inc(itable.size());
-   for (k = 0; k<ssa_to_vreg.size(); k++)
+   //ssa_to_vreg.inc(itable.size());
+   ssa_to_vreg.resize(itable.size());
+   for (unsigned k = 0; k<itable.size(); k++)
       ssa_to_vreg[k] = 0;
 
    // Condense PHI nodes and assign virtual registers
    // to PHI's ONLY
-   for (s=0;s<sections.size();s++)
-      for (i = begin(s); i!=end(s); i=next(i))
-      {
-         instruction * instr = itable[i];
-         unsigned   flags = instr->flags;
-
-         if (flags & IF_PHI)
-         {
-            for (int p=0; p< instr->phi.params->size(); p++)
-            {
-               int id = (*instr->phi.params)[p];
-               ssa_to_vreg[id] = free_vreg;
-            }
-            ssa_to_vreg[i] = free_vreg;
-            free_vreg++;
-         }
-      }
+   for (s=0;s<sections.size();s++){
+     for (i = begin(s); i!=end(s); i=next(i)){
+       instruction * instr = itable[i];
+       unsigned   flags = instr->flags;
+       
+       if (flags & IF_PHI){
+	 //printf("In PHI\n");
+	 for (unsigned int p=0; p< instr->phi.params->size(); p++){
+	   int id = (*instr->phi.params)[p];
+	   ssa_to_vreg[id] = free_vreg;
+	   printf("PHI Id=%d ssa=%d vreg=%d\n", i, id, ssa_to_vreg[id]);
+	 }
+	 ssa_to_vreg[i] = free_vreg;
+
+	 free_vreg++;
+       }
+     }
+   }
 
    // size the vreg structures and initialize
-   vregs.inc(itable.size());
-   for (p = 0 ; p < free_vreg; p++)
-      vregs[p].uses = vregs[p].lastuse = vregs[p].mreg = 0;
-
+   //   vregs.inc(free_vreg);
+   vregs.resize(itable.size());
+   for(int x = 0, e = itable.size(); x < e; x++)
+     vregs[x].uses = vregs[x].lastuse = 
+       vregs[x].mreg = 0;
+
+   for (s=0;s<sections.size();s++){
+     for (i = begin(s); i!=end(s); i=next(i)){
+       printf("SSA: %d vreg: %d\n", i, ssa_to_vreg[i]);
+     }
+   }
+   
    // Assign Vregs to non-phi parameters.  Calculate usage information
    // for ALL virtual registers.  Also calculate liveout reg set
-   for (s=0;s<sections.size();s++)
-      for (int i = begin(s); i!=end(s); i=next(i))
-      {
-         instruction * instr = itable[i];
-         unsigned   flags = instr->flags;
-
-         if (!ssa_to_vreg[i])    //not got a vreg yet?
-         {
-            // allocate one
-            ssa_to_vreg[i] = free_vreg;
-            vregs.inc(1);
-            
-            vregs[free_vreg].uses = 
-                vregs[free_vreg].lastuse = 
-                vregs[free_vreg].mreg = 0;
-                
-            free_vreg++;
-         }
-
-         if (flags & IF_REGSHUFFLE)
-         {
-            fvector<shufflepair> * v = instr->regshuffle.shuffles;
-            for (int z=0;z<v->size();z++)
-            {
-               int gen = (*v)[z].gen;
-               int vr = ssa_to_vreg[gen];
-               vregs[vr].uses++;
-               vregs[vr].lastuse = i;
-               regs.liveout_regs |= (1 << (*v)[z].reg);    //liveout reg
-            }
-            continue;
-         }
-
-         // note since PHI nodes have been collapsed
-         // through the vreg assignment. we don't need to process them! =p
-         // Livein nodes are also skipped
-         if (flags & (IF_ALUOP | IF_BR))
-         {
-            if (flags & IF_R_RS1)            // do we read from RS1?
-            {
-               int id = ssa_to_vreg[instr->alu.genrs1];
-               vregs[id].uses++;
-               vregs[id].lastuse = i;
-            }
-            if (flags & IF_R_RS2)             // do we read from RS2?
-            {
-               int id = ssa_to_vreg[instr->alu.genrs2];
-               vregs[id].uses++;
-               vregs[id].lastuse = i;
-            }
-            if (flags & IF_R_RD)              // do we read from RD?
-            {
-               int id = ssa_to_vreg[instr->alu.genrd];
-               vregs[id].uses++;
-               vregs[id].lastuse = i;
-            }
-         }
-      }
-
+   for (s=0;s<sections.size();s++){
+     for (unsigned int i = begin(s); i!=end(s); i=next(i)){
+       instruction * instr = itable[i];
+       unsigned   flags = instr->flags;
+       
+       if (!ssa_to_vreg[i]){    //not got a vreg yet?
+	 // allocate one
+	 assert(free_vreg < itable.size());
+	 ssa_to_vreg[i] = free_vreg;
+	 //vregs.inc(1);
+	 
+	 vregs[free_vreg].uses = 
+	   vregs[free_vreg].lastuse = 
+	   vregs[free_vreg].mreg = 0;
+	 
+	 printf("Assigned vreg to ssa=%d\n",i); 
+	 free_vreg++;
+       }
+       
+       if (flags & IF_REGSHUFFLE){
+	 //So this is a use, so mark the use for the associated 
+	 //ssa id
+	 vector<shufflepair> * v = instr->regshuffle.shuffles;
+	 for (unsigned int z=0; z<v->size(); z++){
+      	   int gen = (*v)[z].gen; //SSA id
+	   //check if ssa-id still exists
+	   if(itable[gen] == NULL)
+	     continue;
+	   int vr = ssa_to_vreg[gen];
+	   //assert vr exists
+	   //--Anand
+	   assert(vr && "There should be a vr!");
+	   vregs[vr].uses++;
+	   vregs[vr].lastuse = i;
+	   regs.liveout_regs |= (1 << (*v)[z].reg);    //liveout reg
+	 }
+	 continue;
+       }
+       
+       // note since PHI nodes have been collapsed
+       // through the vreg assignment. we don't need to process them! =p
+       // Livein nodes are also skipped
+       if (flags & (IF_ALUOP | IF_BR)){
+	 if (flags & IF_R_RS1){            // do we read from RS1?
+	   int id;
+	   if(flags & IF_BR){
+	     if(flags & IF_BRINTERNAL)
+	       id = ssa_to_vreg[instr->ibranch.genrs1];
+	     else
+	       id = ssa_to_vreg[instr->ebranch.genrs1];
+	   }
+	   else
+	     id = ssa_to_vreg[instr->alu.genrs1];
+	   
+	   vregs[id].uses++;
+	   vregs[id].lastuse = i;
+	 }
+	 
+	 if (flags & IF_R_RS2){             // do we read from RS2?
+	   int id = ssa_to_vreg[instr->alu.genrs2];
+	   vregs[id].uses++;
+	   vregs[id].lastuse = i;
+	 }
+	 
+	 if (flags & IF_R_RD){              // do we read from RD?
+	   int id = ssa_to_vreg[instr->alu.genrd];
+	   vregs[id].uses++;
+	   vregs[id].lastuse = i;
+	 }
+       
+       }
+       printf("i = %d vreg=%d free-reg=%d\n", i, ssa_to_vreg[i],free_vreg);
+     }
+   }
    // register allocation state
    
    //
@@ -153,10 +168,14 @@
    //   as well as the 32 generic spill slots (used for 
    //   shuffle instructions)
    //
-   regmask     freeregs(alloca,ROUNDUP32(itable.size())+32);    
    
+   //regmask freeregs(alloca,ROUNDUP32(itable.size())+32);    
+   regmask freeregs(ROUNDUP32(itable.size())+32);
+
    unsigned    hwregs[32];          // vreg index in that register
-   freeregs.set32(R_ALLOCREGS);     // mark candidate registers free
+   
+   //Do not allocate g0, o6(SP), i6(FP)
+   freeregs.set32(R_ALLOCREGS);// mark candidate registers free
 
    for (s = 0; s< 32; s++)
       hwregs[s] = 0;
@@ -172,140 +191,193 @@
       // Mark that register not free
       freeregs.grabreg(mreg);
       regs.touched_regs |= (1<<mreg);
+      regs.livein_regs |= (1<<mreg);
       hwregs[mreg] = ssa_to_vreg[livein[p]];
-   }
 
+      //mark last use as end of section trace --Anand
+      vregs[ssa_to_vreg[livein[p]]].lastuse = end(SECTION_TRACE);
+
+      printf("liveInId=%d vreg=%d hwreg=%d\n",livein[p], ssa_to_vreg[livein[p]], mreg);
+   }
+ 
+   //Allocate regs which have been "pinned" down
+   for(std::vector<unsigned int>::iterator VI = pinned.begin(), 
+	 VE = pinned.end();
+       VI != VE; ++VI){
+     unsigned int outReg =RD_FLD(itable[*VI]->instr, INSTR_RD);
+     vregs[ssa_to_vreg[*VI]].mreg = outReg;
+     
+     freeregs.grabreg(outReg);
+     regs.touched_regs |= (1<<outReg);
+     hwregs[outReg] = ssa_to_vreg[*VI];
+     printf("pinned down: id=%d mreg=%d\n", *VI, outReg);
+   }
+   
    // grab our spill registers
    regs.spillreg = freeregs.allocreg32();
-   for (int z=0;z<32;z++)
-   {
-      regs.memspills[z] = freeregs.allocmemreg();
-        
-      unsigned midx = VREG_GETMEM(regs.memspills[z]);
-      if (midx > max_midx)
-         max_midx = midx;
+   for (int z=0;z<32;z++){
+     regs.memspills[z] = freeregs.allocmemreg();
+     
+     unsigned midx = VREG_GETMEM(regs.memspills[z]);
+     if (midx > max_midx)
+       max_midx = midx;
    }
 
    // Iterate across instructions
-   for (s=0;s<sections.size();s++)
-      for (i = begin(s); i!=end(s); i=next(i))
-      {
-         // Find what registers this instruction depends on.
-         int rs1;        // this register will contain the rs1 value
-         int rs2;        // this register will contain the rs2 value
-         int rd;         // this register will contain the rd value
-
-         instruction * instr = itable[i];
-         unsigned   flags = instr->flags;
-
-
-         // make sure this is ACTUALLY an instruction and not a phi node
-         if (! (flags & (IF_ALUOP | IF_BR)))
-            continue;
-
-         unsigned ins = instr->instr;
-         // mask off and replace rs1
-         if (flags & IF_R_RS1)
-         {
-            int vid = ssa_to_vreg[instr->alu.genrs1];
-            if (vregs[vid].lastuse == i)
-            {
-               freeregs.freereg(vregs[vid].mreg);
-
-               if (VREG_ISREG(vregs[vid].mreg))
-                  hwregs[vregs[vid].mreg] = 0;
-            }
-         }
-
-         if (flags & IF_R_RS2)
-         {
-            int vid = ssa_to_vreg[instr->alu.genrs2];
-            if (vregs[vid].lastuse == i)
-            {
-               freeregs.freereg(vregs[vid].mreg);
-               if (VREG_ISREG(vregs[vid].mreg))
-                  hwregs[vregs[vid].mreg] = 0;
-            }
-         }
-
-         if (flags & IF_R_RD)
-         {
-            int vid = ssa_to_vreg[instr->alu.genrd];
-            if (vregs[vid].lastuse == i)
-            {
-               freeregs.freereg(vregs[vid].mreg);
-               if (VREG_ISREG(vregs[vid].mreg))
-                  hwregs[vregs[vid].mreg] = 0;
-            }
-         }
-
-         if (flags & IF_W_RD)
-         {
-            int id = ssa_to_vreg[i];
-            int dreg = freeregs.allocreg();
-
-
-            if (VREG_ISMEM(dreg))
-            {
-               unsigned midx = VREG_GETMEM(dreg);
-               
-               if (midx > max_midx)
-                  max_midx = midx;
-
-               // Select a live range to spill
-               unsigned min_cnt = 0xFFFFFFFF;
-               unsigned min_idx = 0;
-
-               for (int j = 0; j < 32; j++)
-               {
-                  if (!hwregs[j])
-                     continue;
-
-                  vreginfo & v = vregs[hwregs[j]];
-                  if (v.uses < min_cnt)
-                  {
-                     min_cnt = v.uses;
-                     min_idx = j;
-                  }
-               }
-
-               // mincnt/minidx now contain the smallest allocated
-
-               if (min_cnt < vregs[id].uses)
-               {
-                  // spill using this register
-                  int oid         = hwregs[min_idx];
-                  vregs[id].mreg  = min_idx;
-                  
-                  assert(min_idx < 32);
-                  hwregs[min_idx] = id;
-                  vregs[oid].mreg = dreg;
-               }
-               else
-               {
-                  // no spill
-                  vregs[id].mreg = dreg;
-               }
-            }
-            else
-            {
-               regs.touched_regs |= (1<<dreg);
-               assert(dreg < 32);
-               hwregs[dreg]   = id;
-               vregs[id].mreg = dreg;
-            }
-
-            vregs[id].mreg = dreg;
-         }
-      }
-
+   for (s=0;s<sections.size();s++){
+     for (i = begin(s); i!=end(s); i=next(i)){
+       // Find what registers this instruction depends on.
+       int rs1;        // this register will contain the rs1 value
+       int rs2;        // this register will contain the rs2 value
+       int rd;         // this register will contain the rd value
+       
+       instruction * instr = itable[i];
+       unsigned   flags = instr->flags;
+       
+       // make sure this is ACTUALLY an instruction and not a phi node
+       if (! (flags & (IF_ALUOP | IF_BR)))
+	 continue;
+       
+       unsigned ins = instr->instr;
+       // mask off and replace rs1
+       if (flags & IF_R_RS1){
+	 int vid;
+	 if(flags & IF_BR){
+	   if(flags & IF_BRINTERNAL)
+	     vid = ssa_to_vreg[instr->ibranch.genrs1];
+	   else
+	     vid = ssa_to_vreg[instr->ebranch.genrs1];
+	 }
+	 else
+	   vid = ssa_to_vreg[instr->alu.genrs1];
+	 
+	 //if this is last use, free up the machine reg
+	 if (vregs[vid].lastuse == i && vregs[vid].mreg != 0){
+	   freeregs.freereg(vregs[vid].mreg);
+	   
+	   if (VREG_ISREG(vregs[vid].mreg))
+	     hwregs[vregs[vid].mreg] = 0;
+	 }
+       }
+       
+       if (flags & IF_R_RS2){
+	 int vid = ssa_to_vreg[instr->alu.genrs2];
+	 if (vregs[vid].lastuse == i && vregs[vid].mreg != 0){
+	   freeregs.freereg(vregs[vid].mreg);
+	   if (VREG_ISREG(vregs[vid].mreg))
+	     hwregs[vregs[vid].mreg] = 0;
+	 }
+       }
+
+       if (flags & IF_R_RD){
+	 int vid = ssa_to_vreg[instr->alu.genrd];
+	 if (vregs[vid].lastuse == i && vregs[vid].mreg != 0){
+	   freeregs.freereg(vregs[vid].mreg);
+	   if (VREG_ISREG(vregs[vid].mreg))
+	     hwregs[vregs[vid].mreg] = 0;
+	 }
+       }
+       
+       if ((flags & IF_W_RD) || ((flags & IF_RS1_RS2_DEFINED) && 
+				 !(flags & IF_BR))){
+	 assert((!(flags & IF_RS1_RS2_DEFINED) || 
+		 (flags & IF_RS1_RS2_DEFINED) && !(flags & IF_LIVEOUT)) && 
+		"liveout for new instructions not implemented");
+	 
+	 bool skipIteration = false;
+	 //make sure this instruction is not in pinned
+	 for(std::vector<unsigned int>::iterator VI = pinned.begin(), 
+	       VE = pinned.end(); VI != VE; ++VI){
+	   if(*VI == i){
+	     skipIteration = true;
+	     break;
+	   }
+	 }
+	 
+	 if(vregs[ssa_to_vreg[i]].mreg)
+	   skipIteration = true;
+	 
+	 if(skipIteration){
+	   printf("Before skipping\n");
+	   sparc_print(instr->instr);
+	   printf("\nSSAid:%u vreg:%u mreg:%u\n", i, ssa_to_vreg[i], 
+		  vregs[ssa_to_vreg[i]].mreg);
+	   continue;
+	 }
+	     
+	 int id = ssa_to_vreg[i];
+	 int dreg = freeregs.allocreg();
+	 
+	 
+	 printf("instr----\n");
+	 sparc_print(instr->instr);
+	 printf("\nid = %d \t dreg = %d \t free= %x\n", i, dreg, 
+		freeregs.free32());
+	 
+	 if (VREG_ISMEM(dreg)){
+	   //printf("Here\n");
+	   //assert(0);
+	   unsigned midx = VREG_GETMEM(dreg);
+	   
+	   if (midx > max_midx)
+	     max_midx = midx;
+	   
+	   // Select a live range to spill
+	   unsigned min_cnt = 0xFFFFFFFF;
+	   unsigned min_idx = 0;
+	   
+	   //select register with minimal usage
+	   //Problem: it used global usage count
+	   //and not usage count from HERE ON
+	   for (int j = 0; j < 32; j++){
+	     if (!hwregs[j])
+	       continue;
+	     
+	     vreginfo & v = vregs[hwregs[j]];
+	     if (v.uses < min_cnt){
+	       min_cnt = v.uses;
+	       min_idx = j;
+	     }
+	   }
+	   
+	   // mincnt/minidx now contain the smallest allocated
+	   
+	   if (min_cnt < vregs[id].uses){
+	     // spill using this register
+	     int oid         = hwregs[min_idx];
+	     vregs[id].mreg  = min_idx;
+	     
+	     //printf("Min idx = %d\n", min_idx);
+	     
+	     assert(min_idx < 32);
+	     hwregs[min_idx] = id;
+	     vregs[oid].mreg = dreg;
+	   }
+	   else{
+	     // no spill
+	     vregs[id].mreg = dreg;
+	   }
+	 }
+	 else{
+	   regs.touched_regs |= (1<<dreg);
+	   assert(dreg < 32);
+	   hwregs[dreg]   = id;
+	   vregs[id].mreg = dreg;
+	 }
+	 
+	 vregs[id].mreg = dreg;
+       }
+     }
+   }
+   
    // print register assignment
-   /*for (int x=0;x<ssa_to_vreg.size();x++)
-   {
-       int id = ssa_to_vreg[x];
-       printf("l%d: -> v%d reg=%d\n", x,id, vregs[id].mreg);
-   }*/
-
+   for (s=0;s<sections.size();s++){
+     for (unsigned int i = begin(s); i!=end(s); i=next(i)){
+       printf("l%d: -> v%d reg=%d\n", i,ssa_to_vreg[i], 
+	      vregs[ssa_to_vreg[i]].mreg);
+     }
+   }
+   
    // calculate amount of stack space needed
    regs.stack_size = max_midx+8;
 }





More information about the llvm-commits mailing list