aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Analysis/LiveVar/BBLiveVar.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/LiveVar/BBLiveVar.cpp')
-rw-r--r--lib/Analysis/LiveVar/BBLiveVar.cpp158
1 files changed, 158 insertions, 0 deletions
diff --git a/lib/Analysis/LiveVar/BBLiveVar.cpp b/lib/Analysis/LiveVar/BBLiveVar.cpp
new file mode 100644
index 0000000..aeb7f91
--- /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<<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;
+}