*** empty log message ***
authorRuchira Sasanka <sasanka@students.uiuc.edu>
Tue, 24 Jul 2001 17:14:13 +0000 (17:14 +0000)
committerRuchira Sasanka <sasanka@students.uiuc.edu>
Tue, 24 Jul 2001 17:14:13 +0000 (17:14 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@291 91177308-0d34-0410-b5e6-96231b3b80d8

18 files changed:
include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h [new file with mode: 0644]
include/llvm/Analysis/LiveVar/LiveVarMap.h [new file with mode: 0644]
include/llvm/Analysis/LiveVar/LiveVarSet.h [new file with mode: 0644]
include/llvm/Analysis/LiveVar/ValueSet.h [new file with mode: 0644]
include/llvm/CodeGen/FunctionLiveVarInfo.h [new file with mode: 0644]
include/llvm/CodeGen/ValueSet.h [new file with mode: 0644]
lib/Analysis/LiveVar/BBLiveVar.cpp [new file with mode: 0644]
lib/Analysis/LiveVar/BBLiveVar.h [new file with mode: 0644]
lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp [new file with mode: 0644]
lib/Analysis/LiveVar/LiveVarSet.cpp [new file with mode: 0644]
lib/Analysis/LiveVar/Makefile [new file with mode: 0644]
lib/Analysis/LiveVar/ValueSet.cpp [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/BBLiveVar.cpp [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/BBLiveVar.h [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/FunctionLiveVarInfo.cpp [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/LiveVarSet.cpp [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/Makefile [new file with mode: 0644]
lib/Target/SparcV9/LiveVar/ValueSet.cpp [new file with mode: 0644]

diff --git a/include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h b/include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h
new file mode 100644 (file)
index 0000000..206fef8
--- /dev/null
@@ -0,0 +1,129 @@
+/* Title:   MethodLiveVarInfo.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: 
+
+   This is the interface for live variable info of a method that is required by 
+   any other part of the compiler
+
+   It should be called like:
+
+       MethodLiveVarInfo MLVI( Mehtod *);  // initializes data structures
+       MLVI.analyze();                    // do the actural live variable anal
+
+ After the analysis, getInSetOfBB or getOutSetofBB can be called to get 
+ live var info of a BB
+
+ The live var set before an instruction can be constructed in several ways:
+
+ 1. Use the OutSet and applyTranferFuncForInst(const Instruction *const Inst) 
+    declared in LiveVarSet and  traverse the instructions of a basic block in 
+    reverse (using const_reverse_iterator in the BB class). 
+
+    This is the most efficient method if you need LV info for several (all) 
+    instructions in a BasicBlock. An example is given below:
+
+
+    LiveVarSet LVSet;  // this will be the set used to traverse through each BB
+
+                   // Initialize LVSet so that it is the same as OutSet of the BB
+    LVSet.setUnion( LVI->getOutSetOfBB( *BBI ) );  
+    BasicBlock::InstListType::const_reverse_iterator 
+      InstIterator = InstListInBB.rbegin();  // get the reverse it for inst in BB
+
+                            // iterate over all the instructions in BB in reverse
+    for( ; InstIterator != InstListInBB.rend(); InstIterator++) {  
+
+      //...... all  code here which uses LVSet ........
+
+      LVSet.applyTranferFuncForInst(*InstIterator);
+
+      // Now LVSet contains live vars ABOVE the current instrution
+    }
+
+    See buildInterferenceGraph() for the above example.
+
+
+ 2. Use the function getLiveVarSetBeforeInst(Instruction *) to get the LV Info 
+    just before an instruction.
+
+    This function caluclates the LV info for a BB only once and caches that 
+    info. If the cache does not contain the LV info of the instruction, it 
+    calculates the LV info for the whole BB and caches them.
+
+    Getting liveVar info this way uses more memory since, LV info should be 
+    cached.
+
+
+ **BUGS: Cannot be called on a method prototype because the BB front() 
+   iterator causes a seg fault in CFG.h (Chris will fix this)
+   So, currently, DO NOT call this for method prototypes. 
+
+*/
+
+
+#ifndef METH_LIVE_VAR_INFO_H
+#define METH_LIVE_VAR_INFO_H
+
+        // for printing out debug messages
+#define DEBUG_LV (1)
+
+#include "LiveVarSet.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
+#include "llvm/Method.h"
+#include "llvm/CFG.h"
+
+#include "LiveVarMap.h"
+#include "BBLiveVar.h"
+
+
+class MethodLiveVarInfo
+{
+ private:
+  const Method *Meth;   // Live var anal is done on this method 
+                        // set by constructor
+
+  BBToBBLiveVarMapType  BB2BBLVMap;  // A map betwn the BasicBlock and BBLiveVar
+
+  InstToLiveVarSetMapType Inst2LVSetMap; // Instruction to LiveVarSet Map 
+                                         //- for providing LV info for each inst
+
+  void constructBBs();          // constructs BBLiveVars and init Def and In sets
+  bool  doSingleBackwardPass(); // do one backward pass over the CFG
+
+  
+
+ public:
+  MethodLiveVarInfo(Method *const Meth);    // constructor 
+
+  ~MethodLiveVarInfo();                     // destructor
+
+  void analyze();             // performs a liver var analysis of a single method
+
+                                                           // gets OutSet of a BB
+  inline const LiveVarSet *getOutSetOfBB( const BasicBlock *const BB)  const {   
+    return (   (* (BB2BBLVMap.find(BB)) ).second  )->getOutSet();
+  }
+
+                                                            // gets InSet of a BB
+  inline const LiveVarSet *getInSetOfBB( const BasicBlock *const BB)  const { 
+    return (   (* (BB2BBLVMap.find(BB)) ).second  )->getInSet();
+  }
+                                   // gets the Live var set before an instruction
+  const LiveVarSet * 
+    MethodLiveVarInfo::getLiveVarSetBeforeInst(const Instruction *const Inst);
+
+};
+
+
+
+
+
+#endif
+
+
+
+
diff --git a/include/llvm/Analysis/LiveVar/LiveVarMap.h b/include/llvm/Analysis/LiveVar/LiveVarMap.h
new file mode 100644 (file)
index 0000000..a7f1ccd
--- /dev/null
@@ -0,0 +1,46 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: This file contains the class for a map between the BasicBlock class
+            and the BBLiveVar class, which is a wrapper class of BasicBlock
+           used for the live variable analysis. The reverse mapping can
+           be found in the BBLiveVar class (It has a pointer to the 
+           corresponding BasicBlock)
+*/
+
+
+#ifndef LIVE_VAR_MAP_H
+#define LIVE_VAR_MAP_H
+
+#include <hash_map>
+
+class BasicBlock;
+class BBLiveVar;
+
+
+struct hashFuncInst {        // sturcture containing the hash function for Inst
+  inline size_t operator () (const Instruction *val) const { 
+    return (size_t) val;  
+  }
+};
+
+
+struct hashFuncBB {          // sturcture containing the hash function for BB
+  inline size_t operator () (const BasicBlock *val) const { 
+    return (size_t) val; 
+  }
+};
+
+
+
+
+typedef hash_map<const BasicBlock *,  
+                BBLiveVar *, hashFuncBB > BBToBBLiveVarMapType;
+
+typedef hash_map<const Instruction *,  const LiveVarSet *, 
+                hashFuncInst> InstToLiveVarSetMapType;
+
+
+#endif
+
+
diff --git a/include/llvm/Analysis/LiveVar/LiveVarSet.h b/include/llvm/Analysis/LiveVar/LiveVarSet.h
new file mode 100644 (file)
index 0000000..37d0d21
--- /dev/null
@@ -0,0 +1,26 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: Contains the class definition of LiveVarSet which is used for
+            live variable analysis.
+*/
+
+#ifndef LIVE_VAR_SET_H
+#define LIVE_VAR_SET_H
+
+#include "ValueSet.h"
+#include "llvm/Instruction.h"
+#include "llvm/Type.h"
+
+class LiveVarSet : public ValueSet
+{
+
+ public:
+  void applyTranferFuncForInst(const Instruction *const Inst); 
+  
+};
+
+
+#endif
+
+
diff --git a/include/llvm/Analysis/LiveVar/ValueSet.h b/include/llvm/Analysis/LiveVar/ValueSet.h
new file mode 100644 (file)
index 0000000..02d3906
--- /dev/null
@@ -0,0 +1,62 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: Contains a mathematical set of Values. LiveVarSet is derived from
+            this. Contains both class and method definitions
+*/
+
+#ifndef VALUE_SET_H
+#define VALUE_SET_H
+
+#include <stdlib.h>
+
+#include <hash_set>
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include "llvm/Value.h"
+
+
+//------------------------ Support functions ---------------------------------
+
+struct hashFuncValue {                // sturcture containing the hash function. 
+  inline size_t operator () (const Value *const val) const 
+  { return (size_t) val;  }
+};
+
+
+
+//------------------- Class Definition for ValueSet ----------------------------
+
+void printValue( const Value *const v);  // func to print a Value 
+
+
+
+class ValueSet : public hash_set<const Value *,  hashFuncValue > 
+{
+ public:
+  ValueSet();   // constructor
+
+  inline void add(const Value *const  val) 
+    { assert( val ); insert(val);}           // for adding a live variable to set
+
+  inline void remove(const Value *const  val) 
+    { assert( val ); erase(val); }       // for removing a live variable from set
+
+  bool setUnion( const ValueSet *const set1);    // for performing two set unions
+  void setSubtract( const ValueSet *const set1); // for performing set difference
+
+                                                 // for performing set difference
+  void setDifference( const ValueSet *const set1, const ValueSet *const set2); 
+  void printSet() const;  // for printing a live variable set
+};
+
+
+
+
+
+
+#endif
diff --git a/include/llvm/CodeGen/FunctionLiveVarInfo.h b/include/llvm/CodeGen/FunctionLiveVarInfo.h
new file mode 100644 (file)
index 0000000..206fef8
--- /dev/null
@@ -0,0 +1,129 @@
+/* Title:   MethodLiveVarInfo.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: 
+
+   This is the interface for live variable info of a method that is required by 
+   any other part of the compiler
+
+   It should be called like:
+
+       MethodLiveVarInfo MLVI( Mehtod *);  // initializes data structures
+       MLVI.analyze();                    // do the actural live variable anal
+
+ After the analysis, getInSetOfBB or getOutSetofBB can be called to get 
+ live var info of a BB
+
+ The live var set before an instruction can be constructed in several ways:
+
+ 1. Use the OutSet and applyTranferFuncForInst(const Instruction *const Inst) 
+    declared in LiveVarSet and  traverse the instructions of a basic block in 
+    reverse (using const_reverse_iterator in the BB class). 
+
+    This is the most efficient method if you need LV info for several (all) 
+    instructions in a BasicBlock. An example is given below:
+
+
+    LiveVarSet LVSet;  // this will be the set used to traverse through each BB
+
+                   // Initialize LVSet so that it is the same as OutSet of the BB
+    LVSet.setUnion( LVI->getOutSetOfBB( *BBI ) );  
+    BasicBlock::InstListType::const_reverse_iterator 
+      InstIterator = InstListInBB.rbegin();  // get the reverse it for inst in BB
+
+                            // iterate over all the instructions in BB in reverse
+    for( ; InstIterator != InstListInBB.rend(); InstIterator++) {  
+
+      //...... all  code here which uses LVSet ........
+
+      LVSet.applyTranferFuncForInst(*InstIterator);
+
+      // Now LVSet contains live vars ABOVE the current instrution
+    }
+
+    See buildInterferenceGraph() for the above example.
+
+
+ 2. Use the function getLiveVarSetBeforeInst(Instruction *) to get the LV Info 
+    just before an instruction.
+
+    This function caluclates the LV info for a BB only once and caches that 
+    info. If the cache does not contain the LV info of the instruction, it 
+    calculates the LV info for the whole BB and caches them.
+
+    Getting liveVar info this way uses more memory since, LV info should be 
+    cached.
+
+
+ **BUGS: Cannot be called on a method prototype because the BB front() 
+   iterator causes a seg fault in CFG.h (Chris will fix this)
+   So, currently, DO NOT call this for method prototypes. 
+
+*/
+
+
+#ifndef METH_LIVE_VAR_INFO_H
+#define METH_LIVE_VAR_INFO_H
+
+        // for printing out debug messages
+#define DEBUG_LV (1)
+
+#include "LiveVarSet.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
+#include "llvm/Method.h"
+#include "llvm/CFG.h"
+
+#include "LiveVarMap.h"
+#include "BBLiveVar.h"
+
+
+class MethodLiveVarInfo
+{
+ private:
+  const Method *Meth;   // Live var anal is done on this method 
+                        // set by constructor
+
+  BBToBBLiveVarMapType  BB2BBLVMap;  // A map betwn the BasicBlock and BBLiveVar
+
+  InstToLiveVarSetMapType Inst2LVSetMap; // Instruction to LiveVarSet Map 
+                                         //- for providing LV info for each inst
+
+  void constructBBs();          // constructs BBLiveVars and init Def and In sets
+  bool  doSingleBackwardPass(); // do one backward pass over the CFG
+
+  
+
+ public:
+  MethodLiveVarInfo(Method *const Meth);    // constructor 
+
+  ~MethodLiveVarInfo();                     // destructor
+
+  void analyze();             // performs a liver var analysis of a single method
+
+                                                           // gets OutSet of a BB
+  inline const LiveVarSet *getOutSetOfBB( const BasicBlock *const BB)  const {   
+    return (   (* (BB2BBLVMap.find(BB)) ).second  )->getOutSet();
+  }
+
+                                                            // gets InSet of a BB
+  inline const LiveVarSet *getInSetOfBB( const BasicBlock *const BB)  const { 
+    return (   (* (BB2BBLVMap.find(BB)) ).second  )->getInSet();
+  }
+                                   // gets the Live var set before an instruction
+  const LiveVarSet * 
+    MethodLiveVarInfo::getLiveVarSetBeforeInst(const Instruction *const Inst);
+
+};
+
+
+
+
+
+#endif
+
+
+
+
diff --git a/include/llvm/CodeGen/ValueSet.h b/include/llvm/CodeGen/ValueSet.h
new file mode 100644 (file)
index 0000000..02d3906
--- /dev/null
@@ -0,0 +1,62 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: Contains a mathematical set of Values. LiveVarSet is derived from
+            this. Contains both class and method definitions
+*/
+
+#ifndef VALUE_SET_H
+#define VALUE_SET_H
+
+#include <stdlib.h>
+
+#include <hash_set>
+#include <algorithm>
+#include <fstream>
+#include <iostream>
+
+#include "llvm/Value.h"
+
+
+//------------------------ Support functions ---------------------------------
+
+struct hashFuncValue {                // sturcture containing the hash function. 
+  inline size_t operator () (const Value *const val) const 
+  { return (size_t) val;  }
+};
+
+
+
+//------------------- Class Definition for ValueSet ----------------------------
+
+void printValue( const Value *const v);  // func to print a Value 
+
+
+
+class ValueSet : public hash_set<const Value *,  hashFuncValue > 
+{
+ public:
+  ValueSet();   // constructor
+
+  inline void add(const Value *const  val) 
+    { assert( val ); insert(val);}           // for adding a live variable to set
+
+  inline void remove(const Value *const  val) 
+    { assert( val ); erase(val); }       // for removing a live variable from set
+
+  bool setUnion( const ValueSet *const set1);    // for performing two set unions
+  void setSubtract( const ValueSet *const set1); // for performing set difference
+
+                                                 // for performing set difference
+  void setDifference( const ValueSet *const set1, const ValueSet *const set2); 
+  void printSet() const;  // for printing a live variable set
+};
+
+
+
+
+
+
+#endif
diff --git a/lib/Analysis/LiveVar/BBLiveVar.cpp b/lib/Analysis/LiveVar/BBLiveVar.cpp
new file mode 100644 (file)
index 0000000..aeb7f91
--- /dev/null
@@ -0,0 +1,158 @@
+#include "llvm/Analysis/LiveVar/BBLiveVar.h"
+
+
+/********************* Implementation **************************************/
+
+BBLiveVar::BBLiveVar( const BasicBlock* baseBB, unsigned int RdfoId) 
+                      : DefSet(),  InSet(), OutSet(), PhiArgMap() {  
+    BaseBB = baseBB;   
+    InSetChanged = OutSetChanged = false;
+    POId = RdfoId;
+}
+
+
+
+void BBLiveVar::calcDefUseSets()  // caluculates def and use sets for each BB
+{
+                                                // instructions in basic block 
+  const BasicBlock::InstListType&  InstListInBB = BaseBB->getInstList();   
+
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstIterator = InstListInBB.rbegin();  // get the iterator for instructions
+
+                                     // iterate over all the instructions in BB
+  for( ; InstIterator != InstListInBB.rend(); InstIterator++) {  
+
+    const Instruction * Inst  = *InstIterator;     // Inst is the current instr
+    assert(Inst);
+
+    if( Inst->isDefinition() ) {  // add to Defs only if this instr is a def
+  
+      DefSet.add( Inst );   // nstruction is a def - so add to def set
+      InSet.remove( Inst);  // this definition kills any uses
+      InSetChanged = true; 
+      //cout << " adding inst to def "; printValue( Inst ); cout << endl;
+    }
+
+    Instruction::op_const_iterator 
+      OpI = Inst->op_begin();                // get iterator for operands
+
+    bool IsPhi=( Inst->getOpcode() == Instruction::PHINode );  // Is this a phi
+
+    for(int OpNum=0 ; OpI != Inst->op_end() ; OpI++) { // iterate over operands
+
+      if ( ((*OpI)->getType())->isLabelType() ) 
+       continue;                                      // don't process labels 
+
+      InSet.add( *OpI );      // An operand is a use - so add to use set
+      OutSet.remove( *OpI );  // remove if there is a definition below this use
+
+      if( IsPhi ) {           // for a phi node
+                              // put args into the PhiArgMap
+       PhiArgMap[ *OpI ] = ((PHINode *) Inst )->getIncomingBlock( OpNum++ ); 
+       assert( PhiArgMap[ *OpI ] );
+       //cout << " Phi operand "; printValue( *OpI ); 
+       //cout  << " came from BB "; printValue(PhiArgMap[*OpI]); cout<<endl;
+      }
+
+      InSetChanged = true; 
+      //cout << " adding operand to use "; printValue( *OpI ); cout << endl;
+    }
+    
+  }
+} 
+       
+
+
+bool BBLiveVar::applyTransferFunc() // calculates the InSet in terms of OutSet 
+{
+
+  // IMPORTANT: caller should check whether the OutSet changed 
+  //           (else no point in calling)
+
+  LiveVarSet OutMinusDef;                      // set to hold (Out[B] - Def[B])
+  OutMinusDef.setDifference( &OutSet, &DefSet);
+  InSetChanged = InSet.setUnion( &OutMinusDef );
+  OutSetChanged = false;    // no change to OutSet since transfer func applied
+
+  return InSetChanged;
+}
+
+
+
+                        // calculates Out set using In sets of the predecessors
+bool BBLiveVar::setPropagate( LiveVarSet *const OutSet, 
+                             const LiveVarSet *const InSet, 
+                             const BasicBlock *const PredBB) {
+
+  LiveVarSet::const_iterator InIt;
+  pair<LiveVarSet::iterator, bool> result;
+  bool changed = false;
+  const BasicBlock *PredBBOfPhiArg;
+
+                                               // for all all elements in InSet
+  for( InIt = InSet->begin() ; InIt != InSet->end(); InIt++) {  
+    PredBBOfPhiArg =  PhiArgMap[ *InIt ];
+
+                        // if this var is not a phi arg or it came from this BB
+    if( !PredBBOfPhiArg || PredBBOfPhiArg == PredBB) {  
+      result = OutSet->insert( *InIt );               // insert to this set
+      if( result.second == true) changed = true;
+    }
+  }
+
+  return changed;
+} 
+
+
+
+                                // propogates in set to OutSets of PREDECESSORs
+bool BBLiveVar::applyFlowFunc(BBToBBLiveVarMapType LVMap) 
+{
+
+  // IMPORTANT: caller should check whether inset changed 
+  //            (else no point in calling)
+
+  bool needAnotherIt= false;  // did this BB change any OutSets of pred.s 
+                              // whose POId is lower
+
+
+  cfg::pred_const_iterator PredBBI = cfg::pred_begin(BaseBB);
+
+  for( ; PredBBI != cfg::pred_end(BaseBB) ; PredBBI++) {
+    assert( *PredBBI );                 // assert that the predecessor is valid
+    BBLiveVar  *PredLVBB = LVMap[*PredBBI];
+
+                                                               // do set union
+    if(  setPropagate( &(PredLVBB->OutSet), &InSet, *PredBBI ) == true) {  
+      PredLVBB->OutSetChanged = true;
+
+      if( PredLVBB->getPOId() <= POId) // if the predec POId is lower than mine
+       needAnotherIt = true;   
+    }
+  } // for
+
+  return needAnotherIt;
+
+}
+
+
+
+
+
+/* ----------------- Methods For Debugging (Printing) ----------------- */
+
+void BBLiveVar::printAllSets() const
+{
+  cout << "Defs: ";   DefSet.printSet();  cout << endl;
+  cout << "In: ";   InSet.printSet();  cout << endl;
+  cout << "Out: ";   OutSet.printSet();  cout << endl;
+}
+
+void BBLiveVar::printInOutSets() const
+{
+  cout << "In: ";   InSet.printSet();  cout << endl;
+  cout << "Out: ";   OutSet.printSet();  cout << endl;
+}
diff --git a/lib/Analysis/LiveVar/BBLiveVar.h b/lib/Analysis/LiveVar/BBLiveVar.h
new file mode 100644 (file)
index 0000000..7917cc2
--- /dev/null
@@ -0,0 +1,69 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: This is a wrapper class for BasicBlock which is used by live 
+             variable anaysis
+*/
+
+#ifndef LIVE_VAR_BB_H
+#define LIVE_VAR_BB_H
+
+#include "LiveVarSet.h"
+#include "LiveVarMap.h"
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
+#include "llvm/CFG.h"
+#include "llvm/Type.h"
+#include "llvm/iOther.h"
+
+
+class BBLiveVar 
+{
+  const BasicBlock* BaseBB;     // pointer to BasicBlock
+  unsigned int POId;            // Post-Order ID
+
+  LiveVarSet DefSet;            // Def set for LV analysis
+  LiveVarSet InSet, OutSet;     // In & Out for LV analysis
+  bool InSetChanged, OutSetChanged;   // set if the InSet/OutSet is modified
+
+                                // map that contains phi args->BB they came
+  hash_map<const Value *, const BasicBlock *, hashFuncValue> PhiArgMap;  
+
+                     // method to propogate an InSet to OutSet of a predecessor
+  bool setPropagate( LiveVarSet *const OutSetOfPred, 
+                    const LiveVarSet *const InSetOfThisBB,
+                    const BasicBlock *const PredBB);
+
+ public:
+
+  BBLiveVar( const BasicBlock* baseBB, unsigned int POId);
+
+  inline bool isInSetChanged() const { return InSetChanged; }    
+  inline bool isOutSetChanged() const { return OutSetChanged; }
+
+  inline unsigned int getPOId() const { return POId; }
+
+  void calcDefUseSets() ;         // calculates the Def & Use sets for this BB
+  bool  applyTransferFunc();      // calcultes the In in terms of Out 
+
+                        // calculates Out set using In sets of the predecessors
+  bool applyFlowFunc(BBToBBLiveVarMapType LVMap);    
+
+  inline const LiveVarSet* getOutSet()  const { return &OutSet; }
+  inline const LiveVarSet*  getInSet() const { return &InSet; }
+
+  void printAllSets() const;    // for printing Def/In/Out sets
+  void printInOutSets() const;  // for printing In/Out sets
+
+  //TODO write a destructor to deallocate Def/In.Out sets and PhiArgMap
+
+};
+
+
+
+
+
+
+#endif
+
diff --git a/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp b/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp
new file mode 100644 (file)
index 0000000..b4126b0
--- /dev/null
@@ -0,0 +1,189 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: 
+
+   This is the interface for live variable info of a method that is required by 
+   any other part of the compiler.
+
+*/
+
+
+#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
+
+
+
+
+/************************** Constructor/Destructor ***************************/
+
+
+MethodLiveVarInfo::MethodLiveVarInfo(Method *const MethPtr) :  BB2BBLVMap()  
+{
+  Meth = MethPtr;  // init BB2BBLVMap and records Method for future use
+}
+
+
+
+MethodLiveVarInfo:: ~MethodLiveVarInfo()
+{
+  BBToBBLiveVarMapType::iterator HMI = BB2BBLVMap.begin();   // hash map iterator
+
+  for( ; HMI != BB2BBLVMap.end() ; HMI ++ ) {  
+    if( (*HMI).first )                    // delete all LiveVarSets in BB2BBLVMap
+      delete (*HMI).second;
+   }
+}
+
+
+// -------------------------- support functions -------------------------------
+
+
+
+                                // constructs BBLiveVars and init Def and In sets
+void MethodLiveVarInfo::constructBBs()   
+{
+  unsigned int POId = 0;   // Reverse Depth-first Order ID
+
+  cfg::po_const_iterator BBI = cfg::po_begin(Meth);
+
+  for(  ; BBI != cfg::po_end(Meth) ; ++BBI, ++POId) 
+  { 
+
+    if(DEBUG_LV) cout << "-- For BB " << (*BBI)->getName() << ":" << endl ;
+
+    const BasicBlock *BB = *BBI;      // get the current BB 
+    BBLiveVar * LVBB = new BBLiveVar( BB, POId );  // create a new BBLiveVar
+    
+    BB2BBLVMap[ BB ] = LVBB;  // insert the pair to Map
+    
+    LVBB->calcDefUseSets();  // calculates the def and in set
+
+    if(DEBUG_LV) LVBB->printAllSets();
+    //cout << "InSetChanged: " << LVBB->isInSetChanged() << endl; 
+  }
+
+}
+
+                                             // do one backward pass over the CFG
+bool MethodLiveVarInfo::doSingleBackwardPass()  
+{
+  bool ResultFlow, NeedAnotherIteration = false;
+
+  if(DEBUG_LV) cout << endl <<  "------- After Backward Pass --------" << endl;
+
+  cfg::po_const_iterator BBI = cfg::po_begin(Meth);
+
+  for( ; BBI != cfg::po_end(Meth) ; ++BBI) 
+  { 
+
+    BBLiveVar* LVBB = BB2BBLVMap[*BBI];
+    assert( LVBB );
+
+    if(DEBUG_LV) cout << "-- For BB " << (*BBI)->getName() << ":"  << endl;
+    // cout << " (POId=" << LVBB->getPOId() << ")" << endl ;
+
+    ResultFlow = false;
+
+    if( LVBB->isOutSetChanged() ) 
+      LVBB->applyTransferFunc();   // apply the Transfer Func to calc the InSet
+    if( LVBB->isInSetChanged() )  
+      ResultFlow = LVBB->applyFlowFunc( BB2BBLVMap ); // to calc Outsets of preds
+
+    if(DEBUG_LV) LVBB->printInOutSets();
+    //cout << "InChanged = " << LVBB->isInSetChanged() 
+    //cout << "   UpdatedBBwithLowerPOId = " << ResultFlow  << endl;
+
+    if( ResultFlow ) NeedAnotherIteration = true;
+
+  }
+
+  return NeedAnotherIteration; // true if we need to reiterate over the CFG
+}
+
+
+
+
+
+void MethodLiveVarInfo::analyze()          // performs live var anal for a method
+{
+  //cout << "In analyze . . ." << cout;
+
+  constructBBs();          // create and initialize all the BBLiveVars of the CFG
+
+  bool NeedAnotherIteration = false;
+  do {
+    NeedAnotherIteration = doSingleBackwardPass( );   // do one  pass over  CFG
+  } while (NeedAnotherIteration );      // repeat until we need more iterations
+}
+
+
+
+
+/* This function will give the LiveVar info for any instruction in a method. It 
+   should be called after a call to analyze().
+
+   This function calucluates live var info for all the instructions in a BB, 
+   when LVInfo for one inst is requested. Hence, this function is useful when 
+   live var info is required for many (or all) instructions in a basic block
+   Also, the arguments to this method does not require specific iterators
+*/
+
+
+const LiveVarSet * 
+MethodLiveVarInfo::getLiveVarSetBeforeInst(const Instruction *const Inst) 
+{
+                                   // get the BB corresponding to the instruction
+  const BasicBlock *const CurBB = Inst->getParent();  
+
+  const LiveVarSet *LVSet = Inst2LVSetMap[Inst];
+
+  if( LVSet  ) return LVSet;                     // if found, just return the set
+
+  const BasicBlock::InstListType&  InstListInBB = CurBB->getInstList();         
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstItEnd= InstListInBB.rend() - 1;    // InstItEnd is set to the first instr
+
+                                                  // LVSet of first instr = InSet
+  Inst2LVSetMap[*InstItEnd] = getInSetOfBB( CurBB );  
+
+                  // if the first instruction is requested, just return the InSet
+  if( Inst == *InstItEnd) return  Inst2LVSetMap[Inst];      
+
+                 // else calculate for all other instruction in the BB
+
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstIt= InstListInBB.rbegin();  // get the iterator for instructions in BB
+
+  LiveVarSet *CurSet = new LiveVarSet();
+  CurSet->setUnion( getOutSetOfBB( CurBB ));   // LVSet now contains the OutSet
+
+    // calculate LVSet for all instructions in the basic block (except the first)
+  for( ; InstIt != InstItEnd ;  InstIt++) {    
+
+    CurSet->applyTranferFuncForInst( *InstIt );  // apply the transfer Func
+    LiveVarSet *NewSet = new LiveVarSet();       // create a new set and
+    NewSet->setUnion( CurSet );                  // copy the set after T/F to it 
+    Inst2LVSetMap[*InstIt] = NewSet;             // record that in the map
+  }
+
+  return Inst2LVSetMap[Inst];
+}
+
+
+
+/*
+NOTES: delete all the LVBBs allocated by adding a destructor to the BB2BBLVMap???
+            use the dfo_iterator in the doSingleBackwardPass  
+*/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/Analysis/LiveVar/LiveVarSet.cpp b/lib/Analysis/LiveVar/LiveVarSet.cpp
new file mode 100644 (file)
index 0000000..c893817
--- /dev/null
@@ -0,0 +1,20 @@
+#include "llvm/Analysis/LiveVar/LiveVarSet.h"
+
+
+// This function applies an instruction to a live var set (accepts OutSet) and
+//  makes necessary changes to it (produces InSet)
+
+void LiveVarSet::applyTranferFuncForInst(const Instruction *const Inst) 
+{
+
+  if( Inst->isDefinition() ) {  // add to Defs iff this instr is a definition
+       remove(Inst);            // this definition kills any uses
+  }
+  Instruction::op_const_iterator OpI = Inst->op_begin();  // get operand iterat
+
+  for( ; OpI != Inst->op_end() ; OpI++) {              // iterate over operands
+    if ( ((*OpI)->getType())->isLabelType()) continue; // don't process labels 
+    add( *OpI );                     // An operand is a use - so add to use set
+  }
+
+}
diff --git a/lib/Analysis/LiveVar/Makefile b/lib/Analysis/LiveVar/Makefile
new file mode 100644 (file)
index 0000000..81d4948
--- /dev/null
@@ -0,0 +1,7 @@
+
+LEVEL = ../../..
+
+LIBRARYNAME = livevar
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Analysis/LiveVar/ValueSet.cpp b/lib/Analysis/LiveVar/ValueSet.cpp
new file mode 100644 (file)
index 0000000..d86587c
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include "llvm/Analysis/LiveVar/ValueSet.h"
+
+
+void printValue( const Value *const v)  // func to print a Value 
+{
+  if( (*v).hasName() ) cout << v << "(" << ((*v).getName()) << ") ";
+  //if( (*v).hasName() ) cout <<  ((*v).getName()) << " ";
+  else  cout << v  << " ";
+}
+
+
+//---------------- Method implementations --------------------------
+
+
+ValueSet:: ValueSet() : hash_set<const Value *,  hashFuncValue> () { }
+
+                                                 // for performing two set unions
+bool ValueSet::setUnion( const ValueSet *const set1) {   
+  const_iterator set1it;
+  pair<iterator, bool> result;
+  bool changed = false;
+
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++) {  
+                                                  // for all all elements in set1
+    result = insert( *set1it );                   // insert to this set
+      if( result.second == true) changed = true;
+  }
+
+  return changed;
+}
+
+
+                                              // for performing set difference
+void ValueSet::setDifference( const ValueSet *const set1, 
+                             const ValueSet *const set2) { 
+
+  const_iterator set1it, set2it;
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++) {  
+                                             // for all elements in set1
+    iterator set2it = set2->find( *set1it ); // find wether the elem is in set2
+    if( set2it == set2->end() )              // if the element is not in set2
+      insert( *set1it );                     // insert to this set
+  }
+}
+
+
+                                         // for performing set subtraction
+void ValueSet::setSubtract( const ValueSet *const set1) { 
+  const_iterator set1it;
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++)  
+                                        // for all elements in set1
+    erase( *set1it );                   // erase that element from this set
+}
+
+
+
+
+void ValueSet::printSet()  const {   // for printing a live variable set
+      const_iterator it;
+      for( it = begin() ; it != end(); it++) 
+       printValue( *it );
+}
diff --git a/lib/Target/SparcV9/LiveVar/BBLiveVar.cpp b/lib/Target/SparcV9/LiveVar/BBLiveVar.cpp
new file mode 100644 (file)
index 0000000..aeb7f91
--- /dev/null
@@ -0,0 +1,158 @@
+#include "llvm/Analysis/LiveVar/BBLiveVar.h"
+
+
+/********************* Implementation **************************************/
+
+BBLiveVar::BBLiveVar( const BasicBlock* baseBB, unsigned int RdfoId) 
+                      : DefSet(),  InSet(), OutSet(), PhiArgMap() {  
+    BaseBB = baseBB;   
+    InSetChanged = OutSetChanged = false;
+    POId = RdfoId;
+}
+
+
+
+void BBLiveVar::calcDefUseSets()  // caluculates def and use sets for each BB
+{
+                                                // instructions in basic block 
+  const BasicBlock::InstListType&  InstListInBB = BaseBB->getInstList();   
+
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstIterator = InstListInBB.rbegin();  // get the iterator for instructions
+
+                                     // iterate over all the instructions in BB
+  for( ; InstIterator != InstListInBB.rend(); InstIterator++) {  
+
+    const Instruction * Inst  = *InstIterator;     // Inst is the current instr
+    assert(Inst);
+
+    if( Inst->isDefinition() ) {  // add to Defs only if this instr is a def
+  
+      DefSet.add( Inst );   // nstruction is a def - so add to def set
+      InSet.remove( Inst);  // this definition kills any uses
+      InSetChanged = true; 
+      //cout << " adding inst to def "; printValue( Inst ); cout << endl;
+    }
+
+    Instruction::op_const_iterator 
+      OpI = Inst->op_begin();                // get iterator for operands
+
+    bool IsPhi=( Inst->getOpcode() == Instruction::PHINode );  // Is this a phi
+
+    for(int OpNum=0 ; OpI != Inst->op_end() ; OpI++) { // iterate over operands
+
+      if ( ((*OpI)->getType())->isLabelType() ) 
+       continue;                                      // don't process labels 
+
+      InSet.add( *OpI );      // An operand is a use - so add to use set
+      OutSet.remove( *OpI );  // remove if there is a definition below this use
+
+      if( IsPhi ) {           // for a phi node
+                              // put args into the PhiArgMap
+       PhiArgMap[ *OpI ] = ((PHINode *) Inst )->getIncomingBlock( OpNum++ ); 
+       assert( PhiArgMap[ *OpI ] );
+       //cout << " Phi operand "; printValue( *OpI ); 
+       //cout  << " came from BB "; printValue(PhiArgMap[*OpI]); cout<<endl;
+      }
+
+      InSetChanged = true; 
+      //cout << " adding operand to use "; printValue( *OpI ); cout << endl;
+    }
+    
+  }
+} 
+       
+
+
+bool BBLiveVar::applyTransferFunc() // calculates the InSet in terms of OutSet 
+{
+
+  // IMPORTANT: caller should check whether the OutSet changed 
+  //           (else no point in calling)
+
+  LiveVarSet OutMinusDef;                      // set to hold (Out[B] - Def[B])
+  OutMinusDef.setDifference( &OutSet, &DefSet);
+  InSetChanged = InSet.setUnion( &OutMinusDef );
+  OutSetChanged = false;    // no change to OutSet since transfer func applied
+
+  return InSetChanged;
+}
+
+
+
+                        // calculates Out set using In sets of the predecessors
+bool BBLiveVar::setPropagate( LiveVarSet *const OutSet, 
+                             const LiveVarSet *const InSet, 
+                             const BasicBlock *const PredBB) {
+
+  LiveVarSet::const_iterator InIt;
+  pair<LiveVarSet::iterator, bool> result;
+  bool changed = false;
+  const BasicBlock *PredBBOfPhiArg;
+
+                                               // for all all elements in InSet
+  for( InIt = InSet->begin() ; InIt != InSet->end(); InIt++) {  
+    PredBBOfPhiArg =  PhiArgMap[ *InIt ];
+
+                        // if this var is not a phi arg or it came from this BB
+    if( !PredBBOfPhiArg || PredBBOfPhiArg == PredBB) {  
+      result = OutSet->insert( *InIt );               // insert to this set
+      if( result.second == true) changed = true;
+    }
+  }
+
+  return changed;
+} 
+
+
+
+                                // propogates in set to OutSets of PREDECESSORs
+bool BBLiveVar::applyFlowFunc(BBToBBLiveVarMapType LVMap) 
+{
+
+  // IMPORTANT: caller should check whether inset changed 
+  //            (else no point in calling)
+
+  bool needAnotherIt= false;  // did this BB change any OutSets of pred.s 
+                              // whose POId is lower
+
+
+  cfg::pred_const_iterator PredBBI = cfg::pred_begin(BaseBB);
+
+  for( ; PredBBI != cfg::pred_end(BaseBB) ; PredBBI++) {
+    assert( *PredBBI );                 // assert that the predecessor is valid
+    BBLiveVar  *PredLVBB = LVMap[*PredBBI];
+
+                                                               // do set union
+    if(  setPropagate( &(PredLVBB->OutSet), &InSet, *PredBBI ) == true) {  
+      PredLVBB->OutSetChanged = true;
+
+      if( PredLVBB->getPOId() <= POId) // if the predec POId is lower than mine
+       needAnotherIt = true;   
+    }
+  } // for
+
+  return needAnotherIt;
+
+}
+
+
+
+
+
+/* ----------------- Methods For Debugging (Printing) ----------------- */
+
+void BBLiveVar::printAllSets() const
+{
+  cout << "Defs: ";   DefSet.printSet();  cout << endl;
+  cout << "In: ";   InSet.printSet();  cout << endl;
+  cout << "Out: ";   OutSet.printSet();  cout << endl;
+}
+
+void BBLiveVar::printInOutSets() const
+{
+  cout << "In: ";   InSet.printSet();  cout << endl;
+  cout << "Out: ";   OutSet.printSet();  cout << endl;
+}
diff --git a/lib/Target/SparcV9/LiveVar/BBLiveVar.h b/lib/Target/SparcV9/LiveVar/BBLiveVar.h
new file mode 100644 (file)
index 0000000..7917cc2
--- /dev/null
@@ -0,0 +1,69 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: This is a wrapper class for BasicBlock which is used by live 
+             variable anaysis
+*/
+
+#ifndef LIVE_VAR_BB_H
+#define LIVE_VAR_BB_H
+
+#include "LiveVarSet.h"
+#include "LiveVarMap.h"
+
+#include "llvm/BasicBlock.h"
+#include "llvm/Instruction.h"
+#include "llvm/CFG.h"
+#include "llvm/Type.h"
+#include "llvm/iOther.h"
+
+
+class BBLiveVar 
+{
+  const BasicBlock* BaseBB;     // pointer to BasicBlock
+  unsigned int POId;            // Post-Order ID
+
+  LiveVarSet DefSet;            // Def set for LV analysis
+  LiveVarSet InSet, OutSet;     // In & Out for LV analysis
+  bool InSetChanged, OutSetChanged;   // set if the InSet/OutSet is modified
+
+                                // map that contains phi args->BB they came
+  hash_map<const Value *, const BasicBlock *, hashFuncValue> PhiArgMap;  
+
+                     // method to propogate an InSet to OutSet of a predecessor
+  bool setPropagate( LiveVarSet *const OutSetOfPred, 
+                    const LiveVarSet *const InSetOfThisBB,
+                    const BasicBlock *const PredBB);
+
+ public:
+
+  BBLiveVar( const BasicBlock* baseBB, unsigned int POId);
+
+  inline bool isInSetChanged() const { return InSetChanged; }    
+  inline bool isOutSetChanged() const { return OutSetChanged; }
+
+  inline unsigned int getPOId() const { return POId; }
+
+  void calcDefUseSets() ;         // calculates the Def & Use sets for this BB
+  bool  applyTransferFunc();      // calcultes the In in terms of Out 
+
+                        // calculates Out set using In sets of the predecessors
+  bool applyFlowFunc(BBToBBLiveVarMapType LVMap);    
+
+  inline const LiveVarSet* getOutSet()  const { return &OutSet; }
+  inline const LiveVarSet*  getInSet() const { return &InSet; }
+
+  void printAllSets() const;    // for printing Def/In/Out sets
+  void printInOutSets() const;  // for printing In/Out sets
+
+  //TODO write a destructor to deallocate Def/In.Out sets and PhiArgMap
+
+};
+
+
+
+
+
+
+#endif
+
diff --git a/lib/Target/SparcV9/LiveVar/FunctionLiveVarInfo.cpp b/lib/Target/SparcV9/LiveVar/FunctionLiveVarInfo.cpp
new file mode 100644 (file)
index 0000000..b4126b0
--- /dev/null
@@ -0,0 +1,189 @@
+/* Title:   ValueSet.h
+   Author:  Ruchira Sasanka
+   Date:    Jun 30, 01
+   Purpose: 
+
+   This is the interface for live variable info of a method that is required by 
+   any other part of the compiler.
+
+*/
+
+
+#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
+
+
+
+
+/************************** Constructor/Destructor ***************************/
+
+
+MethodLiveVarInfo::MethodLiveVarInfo(Method *const MethPtr) :  BB2BBLVMap()  
+{
+  Meth = MethPtr;  // init BB2BBLVMap and records Method for future use
+}
+
+
+
+MethodLiveVarInfo:: ~MethodLiveVarInfo()
+{
+  BBToBBLiveVarMapType::iterator HMI = BB2BBLVMap.begin();   // hash map iterator
+
+  for( ; HMI != BB2BBLVMap.end() ; HMI ++ ) {  
+    if( (*HMI).first )                    // delete all LiveVarSets in BB2BBLVMap
+      delete (*HMI).second;
+   }
+}
+
+
+// -------------------------- support functions -------------------------------
+
+
+
+                                // constructs BBLiveVars and init Def and In sets
+void MethodLiveVarInfo::constructBBs()   
+{
+  unsigned int POId = 0;   // Reverse Depth-first Order ID
+
+  cfg::po_const_iterator BBI = cfg::po_begin(Meth);
+
+  for(  ; BBI != cfg::po_end(Meth) ; ++BBI, ++POId) 
+  { 
+
+    if(DEBUG_LV) cout << "-- For BB " << (*BBI)->getName() << ":" << endl ;
+
+    const BasicBlock *BB = *BBI;      // get the current BB 
+    BBLiveVar * LVBB = new BBLiveVar( BB, POId );  // create a new BBLiveVar
+    
+    BB2BBLVMap[ BB ] = LVBB;  // insert the pair to Map
+    
+    LVBB->calcDefUseSets();  // calculates the def and in set
+
+    if(DEBUG_LV) LVBB->printAllSets();
+    //cout << "InSetChanged: " << LVBB->isInSetChanged() << endl; 
+  }
+
+}
+
+                                             // do one backward pass over the CFG
+bool MethodLiveVarInfo::doSingleBackwardPass()  
+{
+  bool ResultFlow, NeedAnotherIteration = false;
+
+  if(DEBUG_LV) cout << endl <<  "------- After Backward Pass --------" << endl;
+
+  cfg::po_const_iterator BBI = cfg::po_begin(Meth);
+
+  for( ; BBI != cfg::po_end(Meth) ; ++BBI) 
+  { 
+
+    BBLiveVar* LVBB = BB2BBLVMap[*BBI];
+    assert( LVBB );
+
+    if(DEBUG_LV) cout << "-- For BB " << (*BBI)->getName() << ":"  << endl;
+    // cout << " (POId=" << LVBB->getPOId() << ")" << endl ;
+
+    ResultFlow = false;
+
+    if( LVBB->isOutSetChanged() ) 
+      LVBB->applyTransferFunc();   // apply the Transfer Func to calc the InSet
+    if( LVBB->isInSetChanged() )  
+      ResultFlow = LVBB->applyFlowFunc( BB2BBLVMap ); // to calc Outsets of preds
+
+    if(DEBUG_LV) LVBB->printInOutSets();
+    //cout << "InChanged = " << LVBB->isInSetChanged() 
+    //cout << "   UpdatedBBwithLowerPOId = " << ResultFlow  << endl;
+
+    if( ResultFlow ) NeedAnotherIteration = true;
+
+  }
+
+  return NeedAnotherIteration; // true if we need to reiterate over the CFG
+}
+
+
+
+
+
+void MethodLiveVarInfo::analyze()          // performs live var anal for a method
+{
+  //cout << "In analyze . . ." << cout;
+
+  constructBBs();          // create and initialize all the BBLiveVars of the CFG
+
+  bool NeedAnotherIteration = false;
+  do {
+    NeedAnotherIteration = doSingleBackwardPass( );   // do one  pass over  CFG
+  } while (NeedAnotherIteration );      // repeat until we need more iterations
+}
+
+
+
+
+/* This function will give the LiveVar info for any instruction in a method. It 
+   should be called after a call to analyze().
+
+   This function calucluates live var info for all the instructions in a BB, 
+   when LVInfo for one inst is requested. Hence, this function is useful when 
+   live var info is required for many (or all) instructions in a basic block
+   Also, the arguments to this method does not require specific iterators
+*/
+
+
+const LiveVarSet * 
+MethodLiveVarInfo::getLiveVarSetBeforeInst(const Instruction *const Inst) 
+{
+                                   // get the BB corresponding to the instruction
+  const BasicBlock *const CurBB = Inst->getParent();  
+
+  const LiveVarSet *LVSet = Inst2LVSetMap[Inst];
+
+  if( LVSet  ) return LVSet;                     // if found, just return the set
+
+  const BasicBlock::InstListType&  InstListInBB = CurBB->getInstList();         
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstItEnd= InstListInBB.rend() - 1;    // InstItEnd is set to the first instr
+
+                                                  // LVSet of first instr = InSet
+  Inst2LVSetMap[*InstItEnd] = getInSetOfBB( CurBB );  
+
+                  // if the first instruction is requested, just return the InSet
+  if( Inst == *InstItEnd) return  Inst2LVSetMap[Inst];      
+
+                 // else calculate for all other instruction in the BB
+
+  BasicBlock::InstListType::const_reverse_iterator 
+    InstIt= InstListInBB.rbegin();  // get the iterator for instructions in BB
+
+  LiveVarSet *CurSet = new LiveVarSet();
+  CurSet->setUnion( getOutSetOfBB( CurBB ));   // LVSet now contains the OutSet
+
+    // calculate LVSet for all instructions in the basic block (except the first)
+  for( ; InstIt != InstItEnd ;  InstIt++) {    
+
+    CurSet->applyTranferFuncForInst( *InstIt );  // apply the transfer Func
+    LiveVarSet *NewSet = new LiveVarSet();       // create a new set and
+    NewSet->setUnion( CurSet );                  // copy the set after T/F to it 
+    Inst2LVSetMap[*InstIt] = NewSet;             // record that in the map
+  }
+
+  return Inst2LVSetMap[Inst];
+}
+
+
+
+/*
+NOTES: delete all the LVBBs allocated by adding a destructor to the BB2BBLVMap???
+            use the dfo_iterator in the doSingleBackwardPass  
+*/
+
+
+
+
+
+
+
+
+
+
+
diff --git a/lib/Target/SparcV9/LiveVar/LiveVarSet.cpp b/lib/Target/SparcV9/LiveVar/LiveVarSet.cpp
new file mode 100644 (file)
index 0000000..c893817
--- /dev/null
@@ -0,0 +1,20 @@
+#include "llvm/Analysis/LiveVar/LiveVarSet.h"
+
+
+// This function applies an instruction to a live var set (accepts OutSet) and
+//  makes necessary changes to it (produces InSet)
+
+void LiveVarSet::applyTranferFuncForInst(const Instruction *const Inst) 
+{
+
+  if( Inst->isDefinition() ) {  // add to Defs iff this instr is a definition
+       remove(Inst);            // this definition kills any uses
+  }
+  Instruction::op_const_iterator OpI = Inst->op_begin();  // get operand iterat
+
+  for( ; OpI != Inst->op_end() ; OpI++) {              // iterate over operands
+    if ( ((*OpI)->getType())->isLabelType()) continue; // don't process labels 
+    add( *OpI );                     // An operand is a use - so add to use set
+  }
+
+}
diff --git a/lib/Target/SparcV9/LiveVar/Makefile b/lib/Target/SparcV9/LiveVar/Makefile
new file mode 100644 (file)
index 0000000..81d4948
--- /dev/null
@@ -0,0 +1,7 @@
+
+LEVEL = ../../..
+
+LIBRARYNAME = livevar
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Target/SparcV9/LiveVar/ValueSet.cpp b/lib/Target/SparcV9/LiveVar/ValueSet.cpp
new file mode 100644 (file)
index 0000000..d86587c
--- /dev/null
@@ -0,0 +1,63 @@
+
+#include "llvm/Analysis/LiveVar/ValueSet.h"
+
+
+void printValue( const Value *const v)  // func to print a Value 
+{
+  if( (*v).hasName() ) cout << v << "(" << ((*v).getName()) << ") ";
+  //if( (*v).hasName() ) cout <<  ((*v).getName()) << " ";
+  else  cout << v  << " ";
+}
+
+
+//---------------- Method implementations --------------------------
+
+
+ValueSet:: ValueSet() : hash_set<const Value *,  hashFuncValue> () { }
+
+                                                 // for performing two set unions
+bool ValueSet::setUnion( const ValueSet *const set1) {   
+  const_iterator set1it;
+  pair<iterator, bool> result;
+  bool changed = false;
+
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++) {  
+                                                  // for all all elements in set1
+    result = insert( *set1it );                   // insert to this set
+      if( result.second == true) changed = true;
+  }
+
+  return changed;
+}
+
+
+                                              // for performing set difference
+void ValueSet::setDifference( const ValueSet *const set1, 
+                             const ValueSet *const set2) { 
+
+  const_iterator set1it, set2it;
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++) {  
+                                             // for all elements in set1
+    iterator set2it = set2->find( *set1it ); // find wether the elem is in set2
+    if( set2it == set2->end() )              // if the element is not in set2
+      insert( *set1it );                     // insert to this set
+  }
+}
+
+
+                                         // for performing set subtraction
+void ValueSet::setSubtract( const ValueSet *const set1) { 
+  const_iterator set1it;
+  for( set1it = set1->begin() ; set1it != set1->end(); set1it++)  
+                                        // for all elements in set1
+    erase( *set1it );                   // erase that element from this set
+}
+
+
+
+
+void ValueSet::printSet()  const {   // for printing a live variable set
+      const_iterator it;
+      for( it = begin() ; it != end(); it++) 
+       printValue( *it );
+}