diff --git a/include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h b/include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h new file mode 100644 index 00000000000..206fef8e3e8 --- /dev/null +++ b/include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h @@ -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 index 00000000000..a7f1ccd6fd5 --- /dev/null +++ b/include/llvm/Analysis/LiveVar/LiveVarMap.h @@ -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 + +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 BBToBBLiveVarMapType; + +typedef hash_map InstToLiveVarSetMapType; + + +#endif + + diff --git a/include/llvm/Analysis/LiveVar/LiveVarSet.h b/include/llvm/Analysis/LiveVar/LiveVarSet.h new file mode 100644 index 00000000000..37d0d21547a --- /dev/null +++ b/include/llvm/Analysis/LiveVar/LiveVarSet.h @@ -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 index 00000000000..02d3906178c --- /dev/null +++ b/include/llvm/Analysis/LiveVar/ValueSet.h @@ -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 + +#include +#include +#include +#include + +#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 +{ + + 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 index 00000000000..206fef8e3e8 --- /dev/null +++ b/include/llvm/CodeGen/FunctionLiveVarInfo.h @@ -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 index 00000000000..02d3906178c --- /dev/null +++ b/include/llvm/CodeGen/ValueSet.h @@ -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 + +#include +#include +#include +#include + +#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 +{ + + 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 index 00000000000..aeb7f9184c5 --- /dev/null +++ b/lib/Analysis/LiveVar/BBLiveVar.cpp @@ -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< 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 index 00000000000..7917cc21315 --- /dev/null +++ b/lib/Analysis/LiveVar/BBLiveVar.h @@ -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 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 index 00000000000..b4126b00293 --- /dev/null +++ b/lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp @@ -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 index 00000000000..c8938175494 --- /dev/null +++ b/lib/Analysis/LiveVar/LiveVarSet.cpp @@ -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 index 00000000000..81d49480802 --- /dev/null +++ b/lib/Analysis/LiveVar/Makefile @@ -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 index 00000000000..d86587cde4c --- /dev/null +++ b/lib/Analysis/LiveVar/ValueSet.cpp @@ -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 () { } + + // for performing two set unions +bool ValueSet::setUnion( const ValueSet *const set1) { + const_iterator set1it; + pair 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 ); +}