mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-02 00:16:25 +00:00
*** empty log message ***
llvm-svn: 291
This commit is contained in:
parent
aafababdd2
commit
12710ee1b2
129
include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h
Normal file
129
include/llvm/Analysis/LiveVar/FunctionLiveVarInfo.h
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
|
46
include/llvm/Analysis/LiveVar/LiveVarMap.h
Normal file
46
include/llvm/Analysis/LiveVar/LiveVarMap.h
Normal file
@ -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
|
||||
|
||||
|
26
include/llvm/Analysis/LiveVar/LiveVarSet.h
Normal file
26
include/llvm/Analysis/LiveVar/LiveVarSet.h
Normal file
@ -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
|
||||
|
||||
|
62
include/llvm/Analysis/LiveVar/ValueSet.h
Normal file
62
include/llvm/Analysis/LiveVar/ValueSet.h
Normal file
@ -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
|
129
include/llvm/CodeGen/FunctionLiveVarInfo.h
Normal file
129
include/llvm/CodeGen/FunctionLiveVarInfo.h
Normal file
@ -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
|
||||
|
||||
|
||||
|
||||
|
62
include/llvm/CodeGen/ValueSet.h
Normal file
62
include/llvm/CodeGen/ValueSet.h
Normal file
@ -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
|
158
lib/Analysis/LiveVar/BBLiveVar.cpp
Normal file
158
lib/Analysis/LiveVar/BBLiveVar.cpp
Normal file
@ -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;
|
||||
}
|
69
lib/Analysis/LiveVar/BBLiveVar.h
Normal file
69
lib/Analysis/LiveVar/BBLiveVar.h
Normal file
@ -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
|
||||
|
189
lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp
Normal file
189
lib/Analysis/LiveVar/FunctionLiveVarInfo.cpp
Normal file
@ -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
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
20
lib/Analysis/LiveVar/LiveVarSet.cpp
Normal file
20
lib/Analysis/LiveVar/LiveVarSet.cpp
Normal file
@ -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
|
||||
}
|
||||
|
||||
}
|
7
lib/Analysis/LiveVar/Makefile
Normal file
7
lib/Analysis/LiveVar/Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
LEVEL = ../../..
|
||||
|
||||
LIBRARYNAME = livevar
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
63
lib/Analysis/LiveVar/ValueSet.cpp
Normal file
63
lib/Analysis/LiveVar/ValueSet.cpp
Normal file
@ -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 );
|
||||
}
|
Loading…
Reference in New Issue
Block a user