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

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


Changes in directory llvm/lib/Reoptimizer/BinInterface:

construct.cpp updated: 1.3 -> 1.4

---
Log message:

First version of working bininterface API/implementation

---
Diffs of the changes:

Index: llvm/lib/Reoptimizer/BinInterface/construct.cpp
diff -u llvm/lib/Reoptimizer/BinInterface/construct.cpp:1.3 llvm/lib/Reoptimizer/BinInterface/construct.cpp:1.4
--- llvm/lib/Reoptimizer/BinInterface/construct.cpp:1.3	Thu Apr 10 18:12:35 2003
+++ llvm/lib/Reoptimizer/BinInterface/construct.cpp	Sat May 31 17:07:40 2003
@@ -1,31 +1,149 @@
-//*****************************************************************************
+//===--------llvm/Reoptimizer/BinInterface/construct.cpp----------*- C++ -*--=//
 //                   SPARC Binary Manipulation Interface
 //
 //                              SSA Construction
-//
-// 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"        // the 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 <assert.h>
 #include <vector>
+
 using std::pair;            // use STL pair class
+using std::vector;
 
-#include <assert.h>
+//for every liveout, create a livein node
+//this makes sure a PHI node is created for every such node
+void BinInterface::process_liveouts(unsigned int s){
+  unsigned map[32];
+  
+  //detect liveouts
+  //At every branch, the defs so far are assumed as liveouts
+  for (unsigned int i = begin(SECTION_TRACE); i!=end(SECTION_TRACE); ){
+    //go until we find an internal branch
+    instruction *instr = itable[i];
+    unsigned flags = instr->flags;
+    if(flags & IF_BRINTERNAL){
+      assert(instr->next != end(SECTION_TRACE));
+  
+      //set maps to zero
+      for (int x = 0; x < 32; x++)
+	map[x] = 0; 
+    
+      //read from instr->next->next until end
+      for(unsigned int m = itable[instr->next]->next; m != end(SECTION_TRACE);){
+	instruction *instr2 = itable[m];
+	unsigned flags2 = instr2->flags;
+
+	if (flags2 & IF_W_RD)
+	  map[RD_FLD(instr2->instr, INSTR_RD)] = m;
+	
+	m = instr2->next;
+      }
+
+      //read from begin until one more instruction
+      unsigned int j = begin(SECTION_TRACE);
+      instruction *instr2 = itable[j];
+      unsigned flags2 = instr2->flags;
+      
+      if (flags2 & IF_W_RD)
+	map[RD_FLD(instr2->instr, INSTR_RD)] = j;
+      
+      do{
+	j = instr2->next;
+	instr2 = itable[j];
+	flags2 = instr2->flags;
+	
+	if (flags2 & IF_W_RD)
+	  map[RD_FLD(instr2->instr, INSTR_RD)] = j;
+      }
+      while(j != instr->next);
+      
+      unsigned brdest = instr->ibranch.dest;
+      for (int q=0;q<32;q++){
+	if(map[q]){
+	  itable[map[q]]->flags |= IF_LIVEOUT;
+	}
+      }
+    }
+    
+    i = instr->next;
+  }
+  
+  //push every liveout into live-in
+  //EVERY liveout must also be livein,
+  //because if the loop never executed,
+  //the livein must become liveout
+  for (unsigned int i = begin(s); i!=end(s); ){
+    // look at instruction
+    instruction * instr = itable[i];
+    unsigned   flags = instr->flags;
+    
+    if(flags & IF_W_RD){
+      unsigned char reg = RD_FLD(instr->instr, INSTR_RD);
+      for(vector<unsigned char>::iterator VI = liveOutRegs.begin(),
+	    VE = liveOutRegs.end(); VI != VE; ++VI)
+	if(reg == *VI){
+	  instr->flags |= IF_LIVEOUT;
+	  flags |= IF_LIVEOUT;
+	}
+    }
+    
+    if(flags & IF_LIVEOUT){
+      assert(flags & IF_W_RD && "Does not write!");
+      int rd = RD_FLD(instr->instr, INSTR_RD);
+      allocnodelivein(SECTION_PROLOG,rd); 
+    }
+    
+    // advance
+    i = instr->next; 
+  }
+}
+
+//create livein nodes!
+void BinInterface::process_marklivein(unsigned s, unsigned map[32]){
+  // iterate all instructions in this section
+  for (unsigned int i = begin(s); i!=end(s); ){
+    // look at instruction
+    instruction * instr = itable[i];
+    unsigned   flags = instr->flags;
+    
+    // what uses?
+    if (flags & IF_R_RS1 && !(flags & IF_RS1_RS2_DEFINED)){
+      int rs1 = RD_FLD(instr->instr, INSTR_RS1);
+      if (!map[rs1])
+	// oops. we just made a reference to an incoming value. Instantiate
+	map[rs1] = allocnodelivein(SECTION_PROLOG, rs1);
+    }
+    
+    if (flags & IF_R_RS2 && !(flags & IF_RS1_RS2_DEFINED)){
+      int rs2 = RD_FLD(instr->instr, INSTR_RS2);
+      if (!map[rs2])
+	map[rs2] = allocnodelivein(SECTION_PROLOG, rs2);
+    }
+    
+    if (flags & IF_R_RD){
+      int rd = RD_FLD(instr->instr, INSTR_RD);
+      map[rd] = allocnodelivein(SECTION_PROLOG, rd);
+    }
+
+    // does he write to a register?
+    if (flags & IF_W_RD){
+      int rd = RD_FLD(instr->instr, INSTR_RD);
+      map[rd] = i;
+    }
+    
+    // advance
+    i = instr->next;
+  }
+}
 
 //*****************************************************************************
 //  process_markgen(unsigned s, unsigned map[32], 
@@ -47,52 +165,48 @@
 //
 //*****************************************************************************
 
-void BinInterface::process_markgen (unsigned s, unsigned  map[32])
-{
-   // iterate all instructions in this section
-   for (int i = begin(s); i!=end(s); )
-   {
-      // look at instruction
-      instruction * instr = itable[i];
-      unsigned   flags = instr->flags;
-
-      // what uses?
-      if (flags & IF_R_RS1)
-      {
-         int rs1 = RD_FLD(instr->instr, INSTR_RS1);
-         if (!map[rs1])
-            // oops. we just made a reference to an incoming value. Instantiate
-            map[rs1] = allocnodelivein(sections[0],rs1);
-
-         instr->alu.genrs1 = map[rs1];
-      }
-
-      if (flags & IF_R_RS2)
-      {
-         int rs2 = RD_FLD(instr->instr, INSTR_RS2);
-         if (!map[rs2])
-            map[rs2] = allocnodelivein(sections[0],rs2);
-         instr->alu.genrs2 = map[rs2];
-      }
-
-      if (flags & IF_R_RD)
-      {
-         int rd = RD_FLD(instr->instr, INSTR_RD);
-         if (!map[rd])
-            map[rd] = allocnodelivein(sections[0], rd);
-         instr->alu.genrd  = map[rd];
-      }
-
-      // does he write to a register?
-      if (flags & IF_W_RD)
-         map[RD_FLD(instr->instr, INSTR_RD)] = i;
-      else if (flags & IF_PHI)
-         map[instr->instr] = instr->self; // use phi node for reg val
-
-      // advance
-      i = instr->next;
-
-   }
+void BinInterface::process_markgen (unsigned s, unsigned  map[32]){
+  // iterate all instructions in this section
+  for (unsigned int i = begin(s); i!=end(s); ){
+    // look at instruction
+    instruction * instr = itable[i];
+    unsigned   flags = instr->flags;
+    
+    // what uses?
+    if (flags & IF_R_RS1 && !(flags & IF_RS1_RS2_DEFINED)){
+      int rs1 = RD_FLD(instr->instr, INSTR_RS1);
+      assert(map[rs1]);
+      
+      instr->alu.genrs1 = map[rs1];
+    }
+    
+    if (flags & IF_R_RS2 && !(flags & IF_RS1_RS2_DEFINED)){
+      int rs2 = RD_FLD(instr->instr, INSTR_RS2);
+      assert(map[rs2]);
+      instr->alu.genrs2 = map[rs2];
+    }
+    
+    if (flags & IF_R_RD){
+      int rd = RD_FLD(instr->instr, INSTR_RD);
+      assert(map[rd]);
+      instr->alu.genrd  = map[rd];
+    }
+    
+    if(flags & IF_NODELIVEIN)
+      map[instr->livein.reg] = i; 
+    
+    // does he write to a register?
+    if (flags & IF_W_RD){
+      int rd = RD_FLD(instr->instr, INSTR_RD);
+      map[rd] = i;
+    }
+    
+    else if (flags & IF_PHI)
+      map[instr->instr] = instr->self; // use phi node for reg val
+    
+    // advance
+    i = instr->next;
+  }
 }
 
 //*****************************************************************************
@@ -103,51 +217,44 @@
 //  
 //*****************************************************************************
 
-void BinInterface::construct_merge(int s, int brdest, unsigned map[32], fvector<unsigned[32]> & regmaps)
-{
-    // Iterate across all registers
-    for (int q=0;q<32;q++)
-    if (!regmaps[brdest][q])         // section we branched to
-                                     // had no data on register q
-        regmaps[brdest][q] = map[q]; // inherit the value
-                                     // using the SSA contents at our
-                                     // point
-                                    
-    else if (regmaps[brdest][q]!=map[q])    // not the same?
-    {
-        // we need a phi node - or we need to append to one
-        instruction * d = itable[regmaps[brdest][q]];
-        if (d->flags & IF_PHI)
-        {
-            // nothing is in the register on our side
-            if (!map[q])
-                map[q] = allocnodelivein(s,q);     //must have been livein
+void BinInterface::construct_merge(int s, int brdest, unsigned map[32], 
+                                   vector<vector<unsigned int> > & regmaps){
+  // Iterate across all registers
+  for (int q=0;q<32;q++)
+    if (!regmaps[brdest][q]) // section we branched to, had not datae on reg q
+      regmaps[brdest][q] = map[q]; // inherit the value
+  
+    else if (regmaps[brdest][q]!=map[q]){    // not the same?
+      // we need a phi node - or we need to append to one
+      instruction * d = itable[regmaps[brdest][q]];
+      if (d->flags & IF_PHI){
+	// nothing is in the register on our side
+	if (!map[q])
+	  map[q] = allocnodelivein(s,q);     //must have been livein
         
-            d->phi.params->push_back(map[q]);     // append to a phi node
-        }
-        else // There wasn't already a PHI node
-        {
+	d->phi.params->push_back(map[q]);     // append to a phi node
+      }
+      else{ // There wasn't already a PHI node
             // create a phi node
-            instruction * phi = allocphi();
-
-            // Live in check
-            if (!regmaps[brdest][q])
-                regmaps[brdest][q] = allocnodelivein(s,q);
-
-            phi->phi.params->push_back(regmaps[brdest][q]);
-
-            // live in check
-            if (!map[q])
-                map[q] = allocnodelivein(s,q);
-
-            phi->phi.params->push_back(map[q]);
-
-            // link in the phi node and update both maps
-            insert_instr(sections[s], phi);
-            map[q]             = phi->self;
-            regmaps[brdest][q] = phi->self;
-            phi->instr         = q;         // the register it applies to
-        }
+	instruction * phi = allocphi();
+	
+	// Live in check
+	assert(regmaps[brdest][q]);
+	
+	phi->phi.params->push_back(regmaps[brdest][q]);
+	
+	// live in check
+	if (!map[q])
+	  map[q] = allocnodelivein(s,q);
+	
+	phi->phi.params->push_back(map[q]);
+	
+	// link in the phi node and update both maps
+	insert_instr(sections[s], phi);
+	map[q]             = phi->self;
+	regmaps[brdest][q] = phi->self;
+	phi->instr         = q;         // the register it applies to
+      }
     }
 }
 
@@ -163,35 +270,79 @@
 
 
 void BinInterface::process_section(unsigned s, unsigned  map[32],
-                                   fvector<unsigned[32]> & regmaps)
-{
-   // Inherit
-   for (int v=0;v<32;v++)
-      regmaps[s][v] = map[v];
-
-   // iterate all instructions in this section
-   for (int i = begin(s); i!=end(s); )
-   {
-      // look at instruction
-      instruction * instr = itable[i];
-      unsigned      flags = instr->flags;
-
-      // is the instruction a branch?
-      if (flags & IF_BRINTERNAL)
-      {
-
-         // follow the branch and MERGE the tables.
-         int brdest = instr->ibranch.dest;
-         construct_merge( s,  brdest, map, regmaps);
-
-      }
+                                   vector<vector<unsigned int> > & regmaps){
+  // Inherit
+  for (int v=0;v<32;v++)
+    regmaps[s][v] = map[v];
+  
+  // iterate all instructions in this section
+  for (unsigned int i = begin(s); i!=end(s); ){
+    // look at instruction
+    instruction * instr = itable[i];
+    unsigned      flags = instr->flags;
+    
+    // does he write to a register?
+    if (flags & IF_W_RD)
+      map[RD_FLD(instr->instr, INSTR_RD)] = i;
+    
+    if(flags & IF_NODELIVEIN)
+      map[instr->livein.reg] = i;
+    
+    i = instr->next;
+  }
+}
 
-      // does he write to a register?
-      if (flags & IF_W_RD)
-         map[RD_FLD(instr->instr, INSTR_RD)] = i;
 
+void BinInterface::create_exits_liveouts(vector<vector<unsigned int> > & regmaps){
+  // iterate all instructions in this section
+  unsigned  map[32];
+  for (int x = 0; x < 32; x++)
+    map[x] = 0; 
+  
+  for (unsigned int i = begin(SECTION_TRACE); i!=end(SECTION_TRACE); ){
+    // look at instruction
+    instruction * instr = itable[i];
+    unsigned      flags = instr->flags;
+    
+    
+    // is the instruction a branch?
+    if (flags & IF_BRINTERNAL){
+      // follow the branch and MERGE the tables.
+      unsigned int brdest = instr->ibranch.dest;
+      //process one more instruction
+      if(brdest == SECTION_TRACE){
+	i = instr->next;
+	continue;
+      }
+      
       i = instr->next;
-   }
+      instr = itable[i];
+      flags = instr->flags;
+      if(flags & IF_W_RD)
+	map[RD_FLD(instr->instr, INSTR_RD)] = i;
+      
+      else if(flags & IF_NODELIVEIN)
+	map[instr->livein.reg] = i;
+      
+      else if (flags & IF_PHI)
+	map[instr->instr] = instr->self; // use phi node for reg val
+      
+      for (int q=0;q<32;q++)
+	regmaps[brdest][q] = map[q];
+    }
+    
+    // does he write to a register?
+    if (flags & IF_W_RD)
+      map[RD_FLD(instr->instr, INSTR_RD)] = i;
+    
+    else if(flags & IF_NODELIVEIN)
+      map[instr->livein.reg] = i;
+    
+    else if (flags & IF_PHI)
+      map[instr->instr] = instr->self; // use phi node for reg val
+    
+    i = instr->next;
+  }
 }
 
 //*****************************************************************************
@@ -202,86 +353,89 @@
 //  
 //*****************************************************************************
 
-void BinInterface::reduce()
-{
-   fvector<unsigned[32]> regmaps(alloca);
-   regmaps.resize(sections.size());
-
-   unsigned map[32];   
-
-   // Initially all registers have unknown SSA values
-   for (int i = 0; i < 32; i++)
-      map[i] = 0;        
+void BinInterface::reduce(){
+  vector<vector<unsigned int> > regmaps;//(alloca);
+  regmaps.resize(sections.size());
+  for(int i = 0, e = sections.size(); i < e; i++)
+    regmaps[i].resize(32);
+  
+  unsigned map[32];   
+  
+  //mark all liveouts as livein
+  process_liveouts(SECTION_TRACE);
+  
+  // Initially all registers have unknown SSA values
+  for (int i = 0; i < 32; i++)
+    map[i] = 0;        
+  
+  //create livein nodes for trace section
+  process_marklivein(SECTION_TRACE, map);
+  
+  //set maps to zero
+  for (int i = 0; i < 32; i++)
+    map[i] = 0; 
+  
+  // Clear header maps
+  for (unsigned int s=0;s<sections.size();s++)
+    for (unsigned int p=0;p<32;p++)
+      regmaps[s][p] = 0;
+  
+  int scns = sections.size();
+  
+  // Calculate phi nodes and contents of registers
+  // at section start points
+  process_section(SECTION_PROLOG, map, regmaps);
+  process_section(SECTION_TRACE,  map, regmaps);
+  
+  
+  //merge TRACE with itself
+  construct_merge(SECTION_TRACE, SECTION_TRACE, map, regmaps);
+  
+  // clear the map
+  for (int v=0;v<32;v++)
+    map[v] = 0;
+  
+  create_exits_liveouts(regmaps);
+  
+  // Update gen fields for instructions (can't be done
+  // in last pass due to insertion of PHI's)
+  process_markgen(SECTION_PROLOG, map);
+  process_markgen(SECTION_TRACE , map);
+  
+  // For each epilog
+  for (unsigned int s=SECTION_TRACE+1;s<sections.size();s++){
+    unsigned int i;
+    // At this point regmaps[s][i] contains the SSA contents of register i
+    // Check if any of these values were marked SSA liveout. If they are
+    // add them to a register shuffle set.
+    
+    vector<shufflepair> * shuffles = new vector<shufflepair>();
+    
+    for (i=1;i<32; i++){
+      unsigned ssaid = regmaps[s][i];
       
-   // Clear header maps
-   for (int s=0;s<sections.size();s++)
-      for (int p=0;p<32;p++)
-         regmaps[s][p] = 0;
-
-   int scns = sections.size();
-
-   // Note we don't process epilogs since they are not
-   // allowed to have 'initial' code
-   
-   // Calculate phi nodes and contents of registers
-   // at section start points
-   process_section(SECTION_PROLOG, map, regmaps);
-   process_section(SECTION_TRACE,  map, regmaps);
-   
-   // there is am implicit transition from TRACE->first epilog
-   construct_merge(SECTION_TRACE, SECTION_TRACE+1, map, regmaps);
-
-
-
-   // clear the map
-   for (int v=0;v<32;v++)
-      map[v] = 0;
-
-   // Update gen fields for instructions (can't be done
-   // in last pass due to insertion of PHI's)
-   process_markgen(SECTION_PROLOG, map);
-   process_markgen(SECTION_TRACE , map);
-
-   // For each epilog
-   for (int s=SECTION_TRACE+1;s<sections.size();s++)
-   {
-      int i;
-      // At this point regmaps[s][i] contains the SSA contents of register i
-      // Check if any of these values were marked SSA liveout. If they are
-      // add them to a register shuffle set.
-      
-      fvector<shufflepair> * shuffles = new fvector<shufflepair>(alloca);
+      if (!ssaid)
+	continue;
       
-      shuffles->sizehint(16);
-
-      for (i=1;i<32; i++)
-      {
-         unsigned ssaid = regmaps[s][i];
-         
-         if (!ssaid)
-            continue;
-            
-         instruction * instr = itable[ssaid];
-         if (instr->flags & IF_PHI)
-         {
-            // if any of the PHI parameters are marked live out,
-            // the phi node itself becomes liveout.
-            unsigned flags = 0;
-            
-            for (int s = 0; s< instr->phi.params->size(); s++)
-               flags |= itable[(*instr->phi.params)[s]]->flags;
-               
-            if (flags & IF_LIVEOUT)
-               shuffles->push_back(shufflepair(i,ssaid));
-         }
-         if (itable[ssaid]->flags & IF_LIVEOUT)
-         {
-            // this one is liveout.  Let's do the insertion
-            shuffles->push_back(shufflepair(i,ssaid));
-         }
+      instruction * instr = itable[ssaid];
+      if (instr->flags & IF_PHI){
+	// if any of the PHI parameters are marked live out,
+	// the phi node itself becomes liveout.
+	unsigned flags = 0;
+	
+	for (unsigned int s = 0; s< instr->phi.params->size(); s++)
+	  flags |= itable[(*instr->phi.params)[s]]->flags;
+	
+	if (flags & IF_LIVEOUT)
+	  shuffles->push_back(shufflepair(i,ssaid));
+      }
+      else{
+	// this one is liveout.  Let's do the insertion
+	shuffles->push_back(shufflepair(i,ssaid));
       }
-      // place the shuffler node
-      allocnodeshuffles(s, shuffles);
-   }
+    }
+    // place the shuffler node
+    allocnodeshuffles(s, shuffles);
+  }
 }
 





More information about the llvm-commits mailing list