[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