#include "llvm/CodeGen/PhyRegAlloc.h"
cl::Enum<RegAllocDebugLevel_t> DEBUG_RA("dregalloc", cl::NoFlags,
"enable register allocation debugging information",
clEnumValN(RA_DEBUG_None , "n", "disable debug output"),
clEnumValN(RA_DEBUG_Normal , "y", "enable debug output"),
clEnumValN(RA_DEBUG_Verbose, "v", "enable extra debug output"), 0);
//----------------------------------------------------------------------------
// Constructor: Init local composite objects and create register classes.
//----------------------------------------------------------------------------
PhyRegAlloc::PhyRegAlloc(const Method *const M,
const TargetMachine& tm,
MethodLiveVarInfo *const Lvi)
: RegClassList(),
Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList),
MRI( tm.getRegInfo() ),
NumOfRegClasses(MRI.getNumOfRegClasses()),
AddedInstrMap()
{
// **TODO: use an actual reserved color list
ReservedColorListType *RCL = new ReservedColorListType();
// create each RegisterClass and put in RegClassList
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), RCL) );
}
//----------------------------------------------------------------------------
// This method initally creates interference graphs (one in each reg class)
// and IGNodeList (one in each IG). The actual nodes will be pushed later.
//----------------------------------------------------------------------------
void PhyRegAlloc::createIGNodeListsAndIGs()
{
if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
// hash map iterator
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
// hash map end
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
for( ; HMI != HMIEnd ; ++HMI ) {
if( (*HMI).first ) {
LiveRange *L = (*HMI).second; // get the LiveRange
if( !L) {
if( DEBUG_RA) {
cout << "\n*?!?Warning: Null liver range found for: ";
printValue( (*HMI).first) ; cout << endl;
}
continue;
}
// if the Value * is not null, and LR
// is not yet written to the IGNodeList
if( !(L->getUserIGNode()) ) {
RegClass *const RC = // RegClass of first value in the LR
//RegClassList [MRI.getRegClassIDOfValue(*(L->begin()))];
RegClassList[ L->getRegClass()->getID() ];
RC-> addLRToIG( L ); // add this LR to an IG
}
}
}
// init RegClassList
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[ rc ]->createInterferenceGraph();
if( DEBUG_RA)
cout << "LRLists Created!" << endl;
}
//----------------------------------------------------------------------------
// This method will add all interferences at for a given instruction.
// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg
// class as that of live var. The live var passed to this function is the
// LVset AFTER the instruction
//----------------------------------------------------------------------------
void PhyRegAlloc::addInterference(const Value *const Def,
const LiveVarSet *const LVSet,
const bool isCallInst) {
LiveVarSet::const_iterator LIt = LVSet->begin();
// get the live range of instruction
const LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
assert( IGNodeOfDef );
RegClass *const RCOfDef = LROfDef->getRegClass();
// for each live var in live variable set
for( ; LIt != LVSet->end(); ++LIt) {
if( DEBUG_RA > 1) {
cout << "< Def="; printValue(Def);
cout << ", Lvar="; printValue( *LIt); cout << "> ";
}
// get the live range corresponding to live var
LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );
// LROfVar can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
if( LROfVar) {
if(LROfDef == LROfVar) // do not set interf for same LR
continue;
// if 2 reg classes are the same set interference
if( RCOfDef == LROfVar->getRegClass() ){
RCOfDef->setInterference( LROfDef, LROfVar);
}
else if(DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cout << " warning: no live range for " ;
printValue( *LIt); cout << endl