Break RA_DEBUG option into several levels to get better control over

debug output.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3724 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-09-14 23:05:33 +00:00
parent 521758fb79
commit 39c94e105f
12 changed files with 234 additions and 208 deletions

View File

@ -1,3 +1,9 @@
//===-- IGNode.cpp -------------------------------------------------------===//
//
// class IGNode for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/IGNode.h" #include "llvm/CodeGen/IGNode.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>

View File

@ -1,6 +1,12 @@
//===-- InterferenceGraph.cpp ---------------------------------------------===//
//
// Interference graph for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/InterferenceGraph.h" #include "llvm/CodeGen/InterferenceGraph.h"
#include "Support/STLExtras.h"
#include "llvm/CodeGen/RegAllocCommon.h" #include "llvm/CodeGen/RegAllocCommon.h"
#include "Support/STLExtras.h"
#include <algorithm> #include <algorithm>
using std::cerr; using std::cerr;
@ -14,7 +20,7 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
{ {
IG = NULL; IG = NULL;
Size = 0; Size = 0;
if( DEBUG_RA) { if( DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "Interference graph created!\n"; cerr << "Interference graph created!\n";
} }
} }
@ -76,17 +82,15 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
IGNode *const IGNode1 = LR1->getUserIGNode(); IGNode *const IGNode1 = LR1->getUserIGNode();
IGNode *const IGNode2 = LR2->getUserIGNode(); IGNode *const IGNode2 = LR2->getUserIGNode();
if( DEBUG_RA) { assertIGNode( IGNode1 );
assertIGNode( IGNode1 ); assertIGNode( IGNode2 );
assertIGNode( IGNode2 );
}
const unsigned int row = IGNode1->getIndex(); const unsigned int row = IGNode1->getIndex();
const unsigned int col = IGNode2->getIndex(); const unsigned int col = IGNode2->getIndex();
char *val; char *val;
if( DEBUG_RA > 1) if( DEBUG_RA >= RA_DEBUG_Interference > 1)
cerr << "setting intf for: [" << row << "][" << col << "]\n"; cerr << "setting intf for: [" << row << "][" << col << "]\n";
( row > col) ? val = &IG[row][col]: val = &IG[col][row]; ( row > col) ? val = &IG[row][col]: val = &IG[col][row];
@ -107,11 +111,8 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
const LiveRange *const LR2 ) const { const LiveRange *const LR2 ) const {
assert(LR1 != LR2); assert(LR1 != LR2);
assertIGNode( LR1->getUserIGNode() );
if( DEBUG_RA) { assertIGNode( LR2->getUserIGNode() );
assertIGNode( LR1->getUserIGNode() );
assertIGNode( LR2->getUserIGNode() );
}
const unsigned int row = LR1->getUserIGNode()->getIndex(); const unsigned int row = LR1->getUserIGNode()->getIndex();
const unsigned int col = LR2->getUserIGNode()->getIndex(); const unsigned int col = LR2->getUserIGNode()->getIndex();
@ -144,7 +145,7 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
assertIGNode( DestNode ); assertIGNode( DestNode );
assertIGNode( SrcNode ); assertIGNode( SrcNode );
if( DEBUG_RA > 1) { if( DEBUG_RA >= RA_DEBUG_Interference > 1) {
cerr << "Merging LRs: \""; printSet(*LR1); cerr << "Merging LRs: \""; printSet(*LR1);
cerr << "\" and \""; printSet(*LR2); cerr << "\" and \""; printSet(*LR2);
cerr << "\"\n"; cerr << "\"\n";

View File

@ -1,4 +1,11 @@
//===-- LiveRangeInfo.cpp -------------------------------------------------===//
//
// Live range construction for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/LiveRangeInfo.h" #include "llvm/CodeGen/LiveRangeInfo.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/CodeGen/RegClass.h" #include "llvm/CodeGen/RegClass.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h" #include "llvm/CodeGen/MachineCodeForBasicBlock.h"
@ -6,7 +13,6 @@
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "Support/SetOperations.h" #include "Support/SetOperations.h"
#include "llvm/CodeGen/RegAllocCommon.h"
using std::cerr; using std::cerr;
LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm, LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
@ -80,8 +86,8 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void LiveRangeInfo::constructLiveRanges() { void LiveRangeInfo::constructLiveRanges() {
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "Consturcting Live Ranges ...\n"; cerr << "Constructing Live Ranges ...\n";
// first find the live ranges for all incoming args of the function since // first find the live ranges for all incoming args of the function since
// those LRs start from the start of the function // those LRs start from the start of the function
@ -97,8 +103,8 @@ void LiveRangeInfo::constructLiveRanges() {
ArgRange->setRegClass(RegClassList[rcid]); ArgRange->setRegClass(RegClassList[rcid]);
if( DEBUG_RA > 1) if( DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " adding LiveRange for argument " << RAV(AI) << "\n"; cerr << " Adding LiveRange for argument " << RAV(AI) << "\n";
} }
// Now suggest hardware registers for these function args // Now suggest hardware registers for these function args
@ -133,7 +139,7 @@ void LiveRangeInfo::constructLiveRanges() {
// iterate over MI operands to find defs // iterate over MI operands to find defs
for (MachineInstr::val_op_iterator OpI = MInst->begin(), for (MachineInstr::val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI) { OpE = MInst->end(); OpI != OpE; ++OpI) {
if(DEBUG_RA) { if(DEBUG_RA >= RA_DEBUG_LiveRanges) {
MachineOperand::MachineOperandType OpTyp = MachineOperand::MachineOperandType OpTyp =
OpI.getMachineOperand().getOperandType(); OpI.getMachineOperand().getOperandType();
@ -161,7 +167,7 @@ void LiveRangeInfo::constructLiveRanges() {
DefRange->insert(Def); // add the instruction (def) to it DefRange->insert(Def); // add the instruction (def) to it
LiveRangeMap[ Def ] = DefRange; // update the map LiveRangeMap[ Def ] = DefRange; // update the map
if (DEBUG_RA > 1) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " creating a LR for def: " << RAV(Def) << "\n"; cerr << " creating a LR for def: " << RAV(Def) << "\n";
// set the register class of the new live range // set the register class of the new live range
@ -174,7 +180,7 @@ void LiveRangeInfo::constructLiveRanges() {
OpI.getMachineOperand().getVRegValue(), isCC ); OpI.getMachineOperand().getVRegValue(), isCC );
if (isCC && DEBUG_RA) if (isCC && DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\a**created a LR for a CC reg:" cerr << "\a**created a LR for a CC reg:"
<< RAV(OpI.getMachineOperand().getVRegValue()); << RAV(OpI.getMachineOperand().getVRegValue());
@ -185,9 +191,8 @@ void LiveRangeInfo::constructLiveRanges() {
// to the merged set // to the merged set
LiveRangeMap[Def] = DefRange; LiveRangeMap[Def] = DefRange;
if (DEBUG_RA > 1) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " added to an existing LR for def: " cerr << " Added to existing LR for def: " << RAV(Def) << "\n";
<< RAV(Def) << "\n";
} }
} // if isDef() } // if isDef()
@ -205,7 +210,7 @@ void LiveRangeInfo::constructLiveRanges() {
suggestRegs4CallRets(); suggestRegs4CallRets();
if( DEBUG_RA) if( DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "Initial Live Ranges constructed!\n"; cerr << "Initial Live Ranges constructed!\n";
} }
@ -260,8 +265,8 @@ void LiveRangeInfo::suggestRegs4CallRets()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void LiveRangeInfo::coalesceLRs() void LiveRangeInfo::coalesceLRs()
{ {
if(DEBUG_RA) if(DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\nCoalscing LRs ...\n"; cerr << "\nCoalescing LRs ...\n";
for(Function::const_iterator BBI = Meth->begin(), BBE = Meth->end(); for(Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
BBI != BBE; ++BBI) { BBI != BBE; ++BBI) {
@ -275,7 +280,7 @@ void LiveRangeInfo::coalesceLRs()
const MachineInstr * MInst = *MInstIterator; const MachineInstr * MInst = *MInstIterator;
if( DEBUG_RA > 1) { if( DEBUG_RA >= RA_DEBUG_LiveRanges) {
cerr << " *Iterating over machine instr "; cerr << " *Iterating over machine instr ";
MInst->dump(); MInst->dump();
cerr << "\n"; cerr << "\n";
@ -296,7 +301,7 @@ void LiveRangeInfo::coalesceLRs()
LiveRange *LROfUse = getLiveRangeForValue( *UseI ); LiveRange *LROfUse = getLiveRangeForValue( *UseI );
if (!LROfUse) { // if LR of use is not found if (!LROfUse) { // if LR of use is not found
//don't warn about labels //don't warn about labels
if (!isa<BasicBlock>(*UseI) && DEBUG_RA) if (!isa<BasicBlock>(*UseI) && DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n"; cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n";
continue; // ignore and continue continue; // ignore and continue
} }
@ -331,8 +336,8 @@ void LiveRangeInfo::coalesceLRs()
} // for all machine instructions } // for all machine instructions
} // for all BBs } // for all BBs
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\nCoalscing Done!\n"; cerr << "\nCoalescing Done!\n";
} }
@ -347,8 +352,9 @@ void LiveRangeInfo::printLiveRanges() {
cerr << "\nPrinting Live Ranges from Hash Map:\n"; cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end(); ++HMI) { for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) { if (HMI->first && HMI->second) {
cerr << " " << RAV(HMI->first) << "\t: "; cerr << " Value* " << RAV(HMI->first) << "\t: ";
printSet(*HMI->second); cerr << "\n"; cerr << "LR# " << HMI->second->getUserIGNode()->getIndex();
cerr << "\t:Values = "; printSet(*HMI->second); cerr << "\n";
} }
} }
} }

View File

@ -4,4 +4,6 @@ DIRS =
LIBRARYNAME = regalloc LIBRARYNAME = regalloc
BUILD_ARCHIVE = 1
include $(LEVEL)/Makefile.common include $(LEVEL)/Makefile.common

View File

@ -5,6 +5,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/CodeGen/RegisterAllocation.h" #include "llvm/CodeGen/RegisterAllocation.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/CodeGen/PhyRegAlloc.h" #include "llvm/CodeGen/PhyRegAlloc.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrAnnot.h" #include "llvm/CodeGen/MachineInstrAnnot.h"
@ -17,24 +18,25 @@
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "Support/CommandLine.h"
#include "Support/STLExtras.h" #include "Support/STLExtras.h"
#include <math.h> #include <math.h>
using std::cerr; using std::cerr;
using std::vector; using std::vector;
RegAllocDebugLevel_t DEBUG_RA; RegAllocDebugLevel_t DEBUG_RA;
static cl::opt<RegAllocDebugLevel_t, true> static cl::opt<RegAllocDebugLevel_t, true>
DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA), DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA),
cl::desc("enable register allocation debugging information"), cl::desc("enable register allocation debugging information"),
cl::values( cl::values(
clEnumValN(RA_DEBUG_None , "n", "disable debug output"), clEnumValN(RA_DEBUG_None , "n", "disable debug output"),
clEnumValN(RA_DEBUG_Normal , "y", "enable debug output"), clEnumValN(RA_DEBUG_Results, "y", "debug output for allocation results"),
clEnumValN(RA_DEBUG_Verbose, "v", "enable extra debug output"), clEnumValN(RA_DEBUG_Coloring, "c", "debug output for graph coloring step"),
clEnumValN(RA_DEBUG_Interference,"ig","debug output for interference graphs"),
clEnumValN(RA_DEBUG_LiveRanges , "lr","debug output for live ranges"),
clEnumValN(RA_DEBUG_Verbose, "v", "extra debug output"),
0)); 0));
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// RegisterAllocation pass front end... // RegisterAllocation pass front end...
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -104,7 +106,7 @@ PhyRegAlloc::~PhyRegAlloc() {
// and IGNodeList (one in each IG). The actual nodes will be pushed later. // and IGNodeList (one in each IG). The actual nodes will be pushed later.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::createIGNodeListsAndIGs() { void PhyRegAlloc::createIGNodeListsAndIGs() {
if (DEBUG_RA) cerr << "Creating LR lists ...\n"; if (DEBUG_RA >= RA_DEBUG_LiveRanges) cerr << "Creating LR lists ...\n";
// hash map iterator // hash map iterator
LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin(); LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin();
@ -116,18 +118,16 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
if (HMI->first) { if (HMI->first) {
LiveRange *L = HMI->second; // get the LiveRange LiveRange *L = HMI->second; // get the LiveRange
if (!L) { if (!L) {
if (DEBUG_RA) { if (DEBUG_RA)
cerr << "\n*?!?Warning: Null liver range found for: " cerr << "\n**** ?!?WARNING: NULL LIVE RANGE FOUND FOR: "
<< RAV(HMI->first) << "\n"; << RAV(HMI->first) << "****\n";
}
continue; continue;
} }
// if the Value * is not null, and LR
// is not yet written to the IGNodeList // if the Value * is not null, and LR is not yet written to the IGNodeList
if (!(L->getUserIGNode()) ) { if (!(L->getUserIGNode()) ) {
RegClass *const RC = // RegClass of first value in the LR RegClass *const RC = // RegClass of first value in the LR
RegClassList[ L->getRegClass()->getID() ]; RegClassList[ L->getRegClass()->getID() ];
RC->addLRToIG(L); // add this LR to an IG RC->addLRToIG(L); // add this LR to an IG
} }
} }
@ -137,19 +137,17 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[rc]->createInterferenceGraph(); RegClassList[rc]->createInterferenceGraph();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges) cerr << "LRLists Created!\n";
cerr << "LRLists Created!\n";
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// This method will add all interferences at for a given instruction. // 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 // 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 // class as that of live var. The live var passed to this function is the
// LVset AFTER the instruction // LVset AFTER the instruction
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::addInterference(const Value *Def, void PhyRegAlloc::addInterference(const Value *Def,
const ValueSet *LVSet, const ValueSet *LVSet,
bool isCallInst) { bool isCallInst) {
@ -173,26 +171,16 @@ void PhyRegAlloc::addInterference(const Value *Def,
cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> "; cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
// get the live range corresponding to live var // get the live range corresponding to live var
// //
LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt); LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt);
// LROfVar can be null if it is a const since a const // LROfVar can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above // doesn't have a dominating def - see Assumptions above
// //
if (LROfVar) { if (LROfVar)
if (LROfDef == LROfVar) // do not set interf for same LR if (LROfDef != LROfVar) // do not set interf for same LR
continue; if (RCOfDef == LROfVar->getRegClass()) // 2 reg classes are the same
RCOfDef->setInterference( LROfDef, LROfVar);
// if 2 reg classes are the same set interference
//
if (RCOfDef == LROfVar->getRegClass()) {
RCOfDef->setInterference( LROfDef, LROfVar);
} else if (DEBUG_RA >= RA_DEBUG_Verbose) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cerr << " warning: no live range for " << RAV(*LIt) << "\n";
}
}
} }
} }
@ -208,7 +196,7 @@ void PhyRegAlloc::addInterference(const Value *Def,
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
const ValueSet *LVSetAft) { const ValueSet *LVSetAft) {
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "\n For call inst: " << *MInst; cerr << "\n For call inst: " << *MInst;
ValueSet::const_iterator LIt = LVSetAft->begin(); ValueSet::const_iterator LIt = LVSetAft->begin();
@ -221,18 +209,17 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
// //
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt ); LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
if (LR && DEBUG_RA) {
cerr << "\n\tLR Aft Call: ";
printSet(*LR);
}
// LR can be null if it is a const since a const // LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above // doesn't have a dominating def - see Assumptions above
// //
if (LR ) { if (LR ) {
if (DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "\n\tLR after Call: ";
printSet(*LR);
}
LR->setCallInterference(); LR->setCallInterference();
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "\n ++Added call interf for LR: " ; cerr << "\n ++After adding call interference for LR: " ;
printSet(*LR); printSet(*LR);
} }
} }
@ -274,7 +261,8 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
void PhyRegAlloc::buildInterferenceGraphs() void PhyRegAlloc::buildInterferenceGraphs()
{ {
if (DEBUG_RA) cerr << "Creating interference graphs ...\n"; if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Creating interference graphs ...\n";
unsigned BBLoopDepthCost; unsigned BBLoopDepthCost;
for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end(); for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
@ -351,9 +339,8 @@ void PhyRegAlloc::buildInterferenceGraphs()
// //
addInterferencesForArgs(); addInterferencesForArgs();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Interference graphs calculted!\n"; cerr << "Interference graphs calculated!\n";
} }
@ -403,15 +390,16 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// This method will add interferences for incoming arguments to a function. // This method will add interferences for incoming arguments to a function.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::addInterferencesForArgs() { void PhyRegAlloc::addInterferencesForArgs() {
// get the InSet of root BB // get the InSet of root BB
const ValueSet &InSet = LVI->getInSetOfBB(&Meth->front()); const ValueSet &InSet = LVI->getInSetOfBB(&Meth->front());
for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI) { for (Function::const_aiterator AI=Meth->abegin(); AI != Meth->aend(); ++AI) {
// add interferences between args and LVars at start // add interferences between args and LVars at start
addInterference(AI, &InSet, false); addInterference(AI, &InSet, false);
if (DEBUG_RA >= RA_DEBUG_Verbose) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << " - %% adding interference for argument " << RAV(AI) << "\n"; cerr << " - %% adding interference for argument " << RAV(AI) << "\n";
} }
} }
@ -442,8 +430,8 @@ PrependInstructions(vector<MachineInstr *> &IBef,
for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt) for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt)
{ {
if (DEBUG_RA) { if (DEBUG_RA) {
if (OrigMI) cerr << "For MInst: " << *OrigMI; if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
cerr << msg << " PREPENDed instr: " << **AdIt << "\n"; cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n";
} }
MII = MIVec.insert(MII, *AdIt); MII = MIVec.insert(MII, *AdIt);
++MII; ++MII;
@ -464,8 +452,8 @@ AppendInstructions(std::vector<MachineInstr *> &IAft,
for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt )
{ {
if (DEBUG_RA) { if (DEBUG_RA) {
if (OrigMI) cerr << "For MInst: " << *OrigMI; if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
cerr << msg << " APPENDed instr: " << **AdIt << "\n"; cerr << msg << "APPENDed instr:\n " << **AdIt << "\n";
} }
++MII; // insert before the next instruction ++MII; // insert before the next instruction
MII = MIVec.insert(MII, *AdIt); MII = MIVec.insert(MII, *AdIt);
@ -674,9 +662,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft.begin(), MIAft.end()); AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft.begin(), MIAft.end());
if (DEBUG_RA) { if (DEBUG_RA) {
cerr << "\nFor Inst " << *MInst; cerr << "\nFor Inst:\n " << *MInst;
cerr << " - SPILLED LR: "; printSet(*LR); cerr << "SPILLED LR# " << LR->getUserIGNode()->getIndex();
cerr << "\n - Added Instructions:"; cerr << "; added Instructions:";
for_each(MIBef.begin(), MIBef.end(), std::mem_fun(&MachineInstr::dump)); for_each(MIBef.begin(), MIBef.end(), std::mem_fun(&MachineInstr::dump));
for_each(MIAft.begin(), MIAft.end(), std::mem_fun(&MachineInstr::dump)); for_each(MIAft.begin(), MIAft.end(), std::mem_fun(&MachineInstr::dump));
} }
@ -1015,8 +1003,6 @@ void PhyRegAlloc::printLabel(const Value *const Val) {
void PhyRegAlloc::markUnusableSugColors() void PhyRegAlloc::markUnusableSugColors()
{ {
if (DEBUG_RA ) cerr << "\nmarking unusable suggested colors ...\n";
// hash map iterator // hash map iterator
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin(); LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end(); LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
@ -1048,7 +1034,7 @@ void PhyRegAlloc::markUnusableSugColors()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::allocateStackSpace4SpilledLRs() { void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
if (DEBUG_RA) cerr << "\nsetting LR stack offsets ...\n"; if (DEBUG_RA) cerr << "\nSetting LR stack offsets for spills...\n";
LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin(); LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin();
LiveRangeMapType::const_iterator HMIEnd = LRI.getLiveRangeMap()->end(); LiveRangeMapType::const_iterator HMIEnd = LRI.getLiveRangeMap()->end();
@ -1056,8 +1042,13 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
for ( ; HMI != HMIEnd ; ++HMI) { for ( ; HMI != HMIEnd ; ++HMI) {
if (HMI->first && HMI->second) { if (HMI->first && HMI->second) {
LiveRange *L = HMI->second; // get the LiveRange LiveRange *L = HMI->second; // get the LiveRange
if (!L->hasColor()) // NOTE: ** allocating the size of long Type ** if (!L->hasColor()) { // NOTE: ** allocating the size of long Type **
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy)); int stackOffset = mcInfo.allocateSpilledValue(TM, Type::LongTy);
L->setSpillOffFromFP(stackOffset);
if (DEBUG_RA)
cerr << " LR# " << L->getUserIGNode()->getIndex()
<< ": stack-offset = " << stackOffset << "\n";
}
} }
} // for all LR's in hash map } // for all LR's in hash map
} }
@ -1077,7 +1068,7 @@ void PhyRegAlloc::allocateRegisters()
// //
LRI.constructLiveRanges(); // create LR info LRI.constructLiveRanges(); // create LR info
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
LRI.printLiveRanges(); LRI.printLiveRanges();
createIGNodeListsAndIGs(); // create IGNode list and IGs createIGNodeListsAndIGs(); // create IGNode list and IGs
@ -1085,7 +1076,7 @@ void PhyRegAlloc::allocateRegisters()
buildInterferenceGraphs(); // build IGs in all reg classes buildInterferenceGraphs(); // build IGs in all reg classes
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_LiveRanges) {
// print all LRs in all reg classes // print all LRs in all reg classes
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[rc]->printIGNodeList(); RegClassList[rc]->printIGNodeList();
@ -1099,7 +1090,7 @@ void PhyRegAlloc::allocateRegisters()
LRI.coalesceLRs(); // coalesce all live ranges LRI.coalesceLRs(); // coalesce all live ranges
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_LiveRanges) {
// print all LRs in all reg classes // print all LRs in all reg classes
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[ rc ]->printIGNodeList(); RegClassList[ rc ]->printIGNodeList();
@ -1139,8 +1130,8 @@ void PhyRegAlloc::allocateRegisters()
updateMachineCode(); updateMachineCode();
if (DEBUG_RA) { if (DEBUG_RA) {
cerr << "\n**** Machine Code After Register Allocation:\n\n";
MachineCodeForMethod::get(Meth).dump(); MachineCodeForMethod::get(Meth).dump();
printMachineCode(); // only for DEBUGGING
} }
} }

View File

@ -1,3 +1,9 @@
//===-- RegClass.cpp -----------------------------------------------------===//
//
// class RegClass for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/RegClass.h" #include "llvm/CodeGen/RegClass.h"
#include "llvm/CodeGen/RegAllocCommon.h" #include "llvm/CodeGen/RegAllocCommon.h"
using std::cerr; using std::cerr;
@ -11,7 +17,7 @@ RegClass::RegClass(const Function *M,
const ReservedColorListType *RCL) const ReservedColorListType *RCL)
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ), : Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
IG(this), IGNodeStack(), ReservedColorList(RCL) { IG(this), IGNodeStack(), ReservedColorList(RCL) {
if( DEBUG_RA) if( DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Created Reg Class: " << RegClassID << "\n"; cerr << "Created Reg Class: " << RegClassID << "\n";
IsColorUsedArr.resize(Mrc->getNumOfAllRegs()); IsColorUsedArr.resize(Mrc->getNumOfAllRegs());
@ -24,7 +30,8 @@ RegClass::RegClass(const Function *M,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void RegClass::colorAllRegs() void RegClass::colorAllRegs()
{ {
if(DEBUG_RA) cerr << "Coloring IG of reg class " << RegClassID << " ...\n"; if(DEBUG_RA >= RA_DEBUG_Coloring)
cerr << "Coloring IG of reg class " << RegClassID << " ...\n";
// pre-color IGNodes // pre-color IGNodes
pushAllIGNodes(); // push all IG Nodes pushAllIGNodes(); // push all IG Nodes
@ -57,7 +64,7 @@ void RegClass::pushAllIGNodes()
// push non-constrained IGNodes // push non-constrained IGNodes
bool PushedAll = pushUnconstrainedIGNodes(); bool PushedAll = pushUnconstrainedIGNodes();
if( DEBUG_RA) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Puhsed all-unconstrained IGNodes. "; cerr << " Puhsed all-unconstrained IGNodes. ";
if( PushedAll ) cerr << " No constrained nodes left."; if( PushedAll ) cerr << " No constrained nodes left.";
cerr << "\n"; cerr << "\n";
@ -88,7 +95,7 @@ void RegClass::pushAllIGNodes()
// //
NeedMoreSpills = !pushUnconstrainedIGNodes(); NeedMoreSpills = !pushUnconstrainedIGNodes();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Coloring)
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex(); cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
} while(NeedMoreSpills); // repeat until we have pushed all } while(NeedMoreSpills); // repeat until we have pushed all
@ -129,7 +136,7 @@ bool RegClass::pushUnconstrainedIGNodes()
IGNodeStack.push( IGNode ); // push IGNode on to the stack IGNodeStack.push( IGNode ); // push IGNode on to the stack
IGNode->pushOnStack(); // set OnStack and dec deg of neighs IGNode->pushOnStack(); // set OnStack and dec deg of neighs
if (DEBUG_RA > 1) { if (DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ; cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ;
cerr << " on to stack\n"; cerr << " on to stack\n";
} }
@ -230,7 +237,7 @@ void RegClass::colorIGNode(IGNode *const Node)
MRC->colorIGNode(Node, IsColorUsedArr); MRC->colorIGNode(Node, IsColorUsedArr);
} }
else { else {
if( DEBUG_RA ) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Node " << Node->getIndex(); cerr << " Node " << Node->getIndex();
cerr << " already colored with color " << Node->getColor() << "\n"; cerr << " already colored with color " << Node->getColor() << "\n";
} }
@ -238,7 +245,7 @@ void RegClass::colorIGNode(IGNode *const Node)
if( !Node->hasColor() ) { if( !Node->hasColor() ) {
if( DEBUG_RA ) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Node " << Node->getIndex(); cerr << " Node " << Node->getIndex();
cerr << " - could not find a color (needs spilling)\n"; cerr << " - could not find a color (needs spilling)\n";
} }

View File

@ -1,3 +1,9 @@
//===-- IGNode.cpp -------------------------------------------------------===//
//
// class IGNode for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/IGNode.h" #include "llvm/CodeGen/IGNode.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>

View File

@ -1,6 +1,12 @@
//===-- InterferenceGraph.cpp ---------------------------------------------===//
//
// Interference graph for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/InterferenceGraph.h" #include "llvm/CodeGen/InterferenceGraph.h"
#include "Support/STLExtras.h"
#include "llvm/CodeGen/RegAllocCommon.h" #include "llvm/CodeGen/RegAllocCommon.h"
#include "Support/STLExtras.h"
#include <algorithm> #include <algorithm>
using std::cerr; using std::cerr;
@ -14,7 +20,7 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
{ {
IG = NULL; IG = NULL;
Size = 0; Size = 0;
if( DEBUG_RA) { if( DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "Interference graph created!\n"; cerr << "Interference graph created!\n";
} }
} }
@ -76,17 +82,15 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
IGNode *const IGNode1 = LR1->getUserIGNode(); IGNode *const IGNode1 = LR1->getUserIGNode();
IGNode *const IGNode2 = LR2->getUserIGNode(); IGNode *const IGNode2 = LR2->getUserIGNode();
if( DEBUG_RA) { assertIGNode( IGNode1 );
assertIGNode( IGNode1 ); assertIGNode( IGNode2 );
assertIGNode( IGNode2 );
}
const unsigned int row = IGNode1->getIndex(); const unsigned int row = IGNode1->getIndex();
const unsigned int col = IGNode2->getIndex(); const unsigned int col = IGNode2->getIndex();
char *val; char *val;
if( DEBUG_RA > 1) if( DEBUG_RA >= RA_DEBUG_Interference > 1)
cerr << "setting intf for: [" << row << "][" << col << "]\n"; cerr << "setting intf for: [" << row << "][" << col << "]\n";
( row > col) ? val = &IG[row][col]: val = &IG[col][row]; ( row > col) ? val = &IG[row][col]: val = &IG[col][row];
@ -107,11 +111,8 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
const LiveRange *const LR2 ) const { const LiveRange *const LR2 ) const {
assert(LR1 != LR2); assert(LR1 != LR2);
assertIGNode( LR1->getUserIGNode() );
if( DEBUG_RA) { assertIGNode( LR2->getUserIGNode() );
assertIGNode( LR1->getUserIGNode() );
assertIGNode( LR2->getUserIGNode() );
}
const unsigned int row = LR1->getUserIGNode()->getIndex(); const unsigned int row = LR1->getUserIGNode()->getIndex();
const unsigned int col = LR2->getUserIGNode()->getIndex(); const unsigned int col = LR2->getUserIGNode()->getIndex();
@ -144,7 +145,7 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
assertIGNode( DestNode ); assertIGNode( DestNode );
assertIGNode( SrcNode ); assertIGNode( SrcNode );
if( DEBUG_RA > 1) { if( DEBUG_RA >= RA_DEBUG_Interference > 1) {
cerr << "Merging LRs: \""; printSet(*LR1); cerr << "Merging LRs: \""; printSet(*LR1);
cerr << "\" and \""; printSet(*LR2); cerr << "\" and \""; printSet(*LR2);
cerr << "\"\n"; cerr << "\"\n";

View File

@ -1,4 +1,11 @@
//===-- LiveRangeInfo.cpp -------------------------------------------------===//
//
// Live range construction for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/LiveRangeInfo.h" #include "llvm/CodeGen/LiveRangeInfo.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/CodeGen/RegClass.h" #include "llvm/CodeGen/RegClass.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h" #include "llvm/CodeGen/MachineCodeForBasicBlock.h"
@ -6,7 +13,6 @@
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "Support/SetOperations.h" #include "Support/SetOperations.h"
#include "llvm/CodeGen/RegAllocCommon.h"
using std::cerr; using std::cerr;
LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm, LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
@ -80,8 +86,8 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void LiveRangeInfo::constructLiveRanges() { void LiveRangeInfo::constructLiveRanges() {
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "Consturcting Live Ranges ...\n"; cerr << "Constructing Live Ranges ...\n";
// first find the live ranges for all incoming args of the function since // first find the live ranges for all incoming args of the function since
// those LRs start from the start of the function // those LRs start from the start of the function
@ -97,8 +103,8 @@ void LiveRangeInfo::constructLiveRanges() {
ArgRange->setRegClass(RegClassList[rcid]); ArgRange->setRegClass(RegClassList[rcid]);
if( DEBUG_RA > 1) if( DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " adding LiveRange for argument " << RAV(AI) << "\n"; cerr << " Adding LiveRange for argument " << RAV(AI) << "\n";
} }
// Now suggest hardware registers for these function args // Now suggest hardware registers for these function args
@ -133,7 +139,7 @@ void LiveRangeInfo::constructLiveRanges() {
// iterate over MI operands to find defs // iterate over MI operands to find defs
for (MachineInstr::val_op_iterator OpI = MInst->begin(), for (MachineInstr::val_op_iterator OpI = MInst->begin(),
OpE = MInst->end(); OpI != OpE; ++OpI) { OpE = MInst->end(); OpI != OpE; ++OpI) {
if(DEBUG_RA) { if(DEBUG_RA >= RA_DEBUG_LiveRanges) {
MachineOperand::MachineOperandType OpTyp = MachineOperand::MachineOperandType OpTyp =
OpI.getMachineOperand().getOperandType(); OpI.getMachineOperand().getOperandType();
@ -161,7 +167,7 @@ void LiveRangeInfo::constructLiveRanges() {
DefRange->insert(Def); // add the instruction (def) to it DefRange->insert(Def); // add the instruction (def) to it
LiveRangeMap[ Def ] = DefRange; // update the map LiveRangeMap[ Def ] = DefRange; // update the map
if (DEBUG_RA > 1) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " creating a LR for def: " << RAV(Def) << "\n"; cerr << " creating a LR for def: " << RAV(Def) << "\n";
// set the register class of the new live range // set the register class of the new live range
@ -174,7 +180,7 @@ void LiveRangeInfo::constructLiveRanges() {
OpI.getMachineOperand().getVRegValue(), isCC ); OpI.getMachineOperand().getVRegValue(), isCC );
if (isCC && DEBUG_RA) if (isCC && DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\a**created a LR for a CC reg:" cerr << "\a**created a LR for a CC reg:"
<< RAV(OpI.getMachineOperand().getVRegValue()); << RAV(OpI.getMachineOperand().getVRegValue());
@ -185,9 +191,8 @@ void LiveRangeInfo::constructLiveRanges() {
// to the merged set // to the merged set
LiveRangeMap[Def] = DefRange; LiveRangeMap[Def] = DefRange;
if (DEBUG_RA > 1) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " added to an existing LR for def: " cerr << " Added to existing LR for def: " << RAV(Def) << "\n";
<< RAV(Def) << "\n";
} }
} // if isDef() } // if isDef()
@ -205,7 +210,7 @@ void LiveRangeInfo::constructLiveRanges() {
suggestRegs4CallRets(); suggestRegs4CallRets();
if( DEBUG_RA) if( DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "Initial Live Ranges constructed!\n"; cerr << "Initial Live Ranges constructed!\n";
} }
@ -260,8 +265,8 @@ void LiveRangeInfo::suggestRegs4CallRets()
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void LiveRangeInfo::coalesceLRs() void LiveRangeInfo::coalesceLRs()
{ {
if(DEBUG_RA) if(DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\nCoalscing LRs ...\n"; cerr << "\nCoalescing LRs ...\n";
for(Function::const_iterator BBI = Meth->begin(), BBE = Meth->end(); for(Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
BBI != BBE; ++BBI) { BBI != BBE; ++BBI) {
@ -275,7 +280,7 @@ void LiveRangeInfo::coalesceLRs()
const MachineInstr * MInst = *MInstIterator; const MachineInstr * MInst = *MInstIterator;
if( DEBUG_RA > 1) { if( DEBUG_RA >= RA_DEBUG_LiveRanges) {
cerr << " *Iterating over machine instr "; cerr << " *Iterating over machine instr ";
MInst->dump(); MInst->dump();
cerr << "\n"; cerr << "\n";
@ -296,7 +301,7 @@ void LiveRangeInfo::coalesceLRs()
LiveRange *LROfUse = getLiveRangeForValue( *UseI ); LiveRange *LROfUse = getLiveRangeForValue( *UseI );
if (!LROfUse) { // if LR of use is not found if (!LROfUse) { // if LR of use is not found
//don't warn about labels //don't warn about labels
if (!isa<BasicBlock>(*UseI) && DEBUG_RA) if (!isa<BasicBlock>(*UseI) && DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n"; cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n";
continue; // ignore and continue continue; // ignore and continue
} }
@ -331,8 +336,8 @@ void LiveRangeInfo::coalesceLRs()
} // for all machine instructions } // for all machine instructions
} // for all BBs } // for all BBs
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
cerr << "\nCoalscing Done!\n"; cerr << "\nCoalescing Done!\n";
} }
@ -347,8 +352,9 @@ void LiveRangeInfo::printLiveRanges() {
cerr << "\nPrinting Live Ranges from Hash Map:\n"; cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end(); ++HMI) { for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) { if (HMI->first && HMI->second) {
cerr << " " << RAV(HMI->first) << "\t: "; cerr << " Value* " << RAV(HMI->first) << "\t: ";
printSet(*HMI->second); cerr << "\n"; cerr << "LR# " << HMI->second->getUserIGNode()->getIndex();
cerr << "\t:Values = "; printSet(*HMI->second); cerr << "\n";
} }
} }
} }

View File

@ -4,4 +4,6 @@ DIRS =
LIBRARYNAME = regalloc LIBRARYNAME = regalloc
BUILD_ARCHIVE = 1
include $(LEVEL)/Makefile.common include $(LEVEL)/Makefile.common

View File

@ -5,6 +5,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/CodeGen/RegisterAllocation.h" #include "llvm/CodeGen/RegisterAllocation.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/CodeGen/PhyRegAlloc.h" #include "llvm/CodeGen/PhyRegAlloc.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrAnnot.h" #include "llvm/CodeGen/MachineInstrAnnot.h"
@ -17,24 +18,25 @@
#include "llvm/Function.h" #include "llvm/Function.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "Support/CommandLine.h"
#include "Support/STLExtras.h" #include "Support/STLExtras.h"
#include <math.h> #include <math.h>
using std::cerr; using std::cerr;
using std::vector; using std::vector;
RegAllocDebugLevel_t DEBUG_RA; RegAllocDebugLevel_t DEBUG_RA;
static cl::opt<RegAllocDebugLevel_t, true> static cl::opt<RegAllocDebugLevel_t, true>
DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA), DRA_opt("dregalloc", cl::Hidden, cl::location(DEBUG_RA),
cl::desc("enable register allocation debugging information"), cl::desc("enable register allocation debugging information"),
cl::values( cl::values(
clEnumValN(RA_DEBUG_None , "n", "disable debug output"), clEnumValN(RA_DEBUG_None , "n", "disable debug output"),
clEnumValN(RA_DEBUG_Normal , "y", "enable debug output"), clEnumValN(RA_DEBUG_Results, "y", "debug output for allocation results"),
clEnumValN(RA_DEBUG_Verbose, "v", "enable extra debug output"), clEnumValN(RA_DEBUG_Coloring, "c", "debug output for graph coloring step"),
clEnumValN(RA_DEBUG_Interference,"ig","debug output for interference graphs"),
clEnumValN(RA_DEBUG_LiveRanges , "lr","debug output for live ranges"),
clEnumValN(RA_DEBUG_Verbose, "v", "extra debug output"),
0)); 0));
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// RegisterAllocation pass front end... // RegisterAllocation pass front end...
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -104,7 +106,7 @@ PhyRegAlloc::~PhyRegAlloc() {
// and IGNodeList (one in each IG). The actual nodes will be pushed later. // and IGNodeList (one in each IG). The actual nodes will be pushed later.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::createIGNodeListsAndIGs() { void PhyRegAlloc::createIGNodeListsAndIGs() {
if (DEBUG_RA) cerr << "Creating LR lists ...\n"; if (DEBUG_RA >= RA_DEBUG_LiveRanges) cerr << "Creating LR lists ...\n";
// hash map iterator // hash map iterator
LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin(); LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin();
@ -116,18 +118,16 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
if (HMI->first) { if (HMI->first) {
LiveRange *L = HMI->second; // get the LiveRange LiveRange *L = HMI->second; // get the LiveRange
if (!L) { if (!L) {
if (DEBUG_RA) { if (DEBUG_RA)
cerr << "\n*?!?Warning: Null liver range found for: " cerr << "\n**** ?!?WARNING: NULL LIVE RANGE FOUND FOR: "
<< RAV(HMI->first) << "\n"; << RAV(HMI->first) << "****\n";
}
continue; continue;
} }
// if the Value * is not null, and LR
// is not yet written to the IGNodeList // if the Value * is not null, and LR is not yet written to the IGNodeList
if (!(L->getUserIGNode()) ) { if (!(L->getUserIGNode()) ) {
RegClass *const RC = // RegClass of first value in the LR RegClass *const RC = // RegClass of first value in the LR
RegClassList[ L->getRegClass()->getID() ]; RegClassList[ L->getRegClass()->getID() ];
RC->addLRToIG(L); // add this LR to an IG RC->addLRToIG(L); // add this LR to an IG
} }
} }
@ -137,19 +137,17 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[rc]->createInterferenceGraph(); RegClassList[rc]->createInterferenceGraph();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges) cerr << "LRLists Created!\n";
cerr << "LRLists Created!\n";
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// This method will add all interferences at for a given instruction. // 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 // 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 // class as that of live var. The live var passed to this function is the
// LVset AFTER the instruction // LVset AFTER the instruction
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::addInterference(const Value *Def, void PhyRegAlloc::addInterference(const Value *Def,
const ValueSet *LVSet, const ValueSet *LVSet,
bool isCallInst) { bool isCallInst) {
@ -173,26 +171,16 @@ void PhyRegAlloc::addInterference(const Value *Def,
cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> "; cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
// get the live range corresponding to live var // get the live range corresponding to live var
// //
LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt); LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt);
// LROfVar can be null if it is a const since a const // LROfVar can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above // doesn't have a dominating def - see Assumptions above
// //
if (LROfVar) { if (LROfVar)
if (LROfDef == LROfVar) // do not set interf for same LR if (LROfDef != LROfVar) // do not set interf for same LR
continue; if (RCOfDef == LROfVar->getRegClass()) // 2 reg classes are the same
RCOfDef->setInterference( LROfDef, LROfVar);
// if 2 reg classes are the same set interference
//
if (RCOfDef == LROfVar->getRegClass()) {
RCOfDef->setInterference( LROfDef, LROfVar);
} else if (DEBUG_RA >= RA_DEBUG_Verbose) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cerr << " warning: no live range for " << RAV(*LIt) << "\n";
}
}
} }
} }
@ -208,7 +196,7 @@ void PhyRegAlloc::addInterference(const Value *Def,
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst, void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
const ValueSet *LVSetAft) { const ValueSet *LVSetAft) {
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "\n For call inst: " << *MInst; cerr << "\n For call inst: " << *MInst;
ValueSet::const_iterator LIt = LVSetAft->begin(); ValueSet::const_iterator LIt = LVSetAft->begin();
@ -221,18 +209,17 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
// //
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt ); LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
if (LR && DEBUG_RA) {
cerr << "\n\tLR Aft Call: ";
printSet(*LR);
}
// LR can be null if it is a const since a const // LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above // doesn't have a dominating def - see Assumptions above
// //
if (LR ) { if (LR ) {
if (DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "\n\tLR after Call: ";
printSet(*LR);
}
LR->setCallInterference(); LR->setCallInterference();
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_Interference) {
cerr << "\n ++Added call interf for LR: " ; cerr << "\n ++After adding call interference for LR: " ;
printSet(*LR); printSet(*LR);
} }
} }
@ -274,7 +261,8 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
void PhyRegAlloc::buildInterferenceGraphs() void PhyRegAlloc::buildInterferenceGraphs()
{ {
if (DEBUG_RA) cerr << "Creating interference graphs ...\n"; if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Creating interference graphs ...\n";
unsigned BBLoopDepthCost; unsigned BBLoopDepthCost;
for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end(); for (Function::const_iterator BBI = Meth->begin(), BBE = Meth->end();
@ -351,9 +339,8 @@ void PhyRegAlloc::buildInterferenceGraphs()
// //
addInterferencesForArgs(); addInterferencesForArgs();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Interference graphs calculted!\n"; cerr << "Interference graphs calculated!\n";
} }
@ -403,15 +390,16 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// This method will add interferences for incoming arguments to a function. // This method will add interferences for incoming arguments to a function.
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::addInterferencesForArgs() { void PhyRegAlloc::addInterferencesForArgs() {
// get the InSet of root BB // get the InSet of root BB
const ValueSet &InSet = LVI->getInSetOfBB(&Meth->front()); const ValueSet &InSet = LVI->getInSetOfBB(&Meth->front());
for (Function::const_aiterator AI = Meth->abegin(); AI != Meth->aend(); ++AI) { for (Function::const_aiterator AI=Meth->abegin(); AI != Meth->aend(); ++AI) {
// add interferences between args and LVars at start // add interferences between args and LVars at start
addInterference(AI, &InSet, false); addInterference(AI, &InSet, false);
if (DEBUG_RA >= RA_DEBUG_Verbose) if (DEBUG_RA >= RA_DEBUG_Interference)
cerr << " - %% adding interference for argument " << RAV(AI) << "\n"; cerr << " - %% adding interference for argument " << RAV(AI) << "\n";
} }
} }
@ -442,8 +430,8 @@ PrependInstructions(vector<MachineInstr *> &IBef,
for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt) for (AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt)
{ {
if (DEBUG_RA) { if (DEBUG_RA) {
if (OrigMI) cerr << "For MInst: " << *OrigMI; if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
cerr << msg << " PREPENDed instr: " << **AdIt << "\n"; cerr << msg << "PREPENDed instr:\n " << **AdIt << "\n";
} }
MII = MIVec.insert(MII, *AdIt); MII = MIVec.insert(MII, *AdIt);
++MII; ++MII;
@ -464,8 +452,8 @@ AppendInstructions(std::vector<MachineInstr *> &IAft,
for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt ) for ( AdIt = IAft.begin(); AdIt != IAft.end() ; ++AdIt )
{ {
if (DEBUG_RA) { if (DEBUG_RA) {
if (OrigMI) cerr << "For MInst: " << *OrigMI; if (OrigMI) cerr << "For MInst:\n " << *OrigMI;
cerr << msg << " APPENDed instr: " << **AdIt << "\n"; cerr << msg << "APPENDed instr:\n " << **AdIt << "\n";
} }
++MII; // insert before the next instruction ++MII; // insert before the next instruction
MII = MIVec.insert(MII, *AdIt); MII = MIVec.insert(MII, *AdIt);
@ -674,9 +662,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft.begin(), MIAft.end()); AI.InstrnsAfter.insert(AI.InstrnsAfter.begin(), MIAft.begin(), MIAft.end());
if (DEBUG_RA) { if (DEBUG_RA) {
cerr << "\nFor Inst " << *MInst; cerr << "\nFor Inst:\n " << *MInst;
cerr << " - SPILLED LR: "; printSet(*LR); cerr << "SPILLED LR# " << LR->getUserIGNode()->getIndex();
cerr << "\n - Added Instructions:"; cerr << "; added Instructions:";
for_each(MIBef.begin(), MIBef.end(), std::mem_fun(&MachineInstr::dump)); for_each(MIBef.begin(), MIBef.end(), std::mem_fun(&MachineInstr::dump));
for_each(MIAft.begin(), MIAft.end(), std::mem_fun(&MachineInstr::dump)); for_each(MIAft.begin(), MIAft.end(), std::mem_fun(&MachineInstr::dump));
} }
@ -1015,8 +1003,6 @@ void PhyRegAlloc::printLabel(const Value *const Val) {
void PhyRegAlloc::markUnusableSugColors() void PhyRegAlloc::markUnusableSugColors()
{ {
if (DEBUG_RA ) cerr << "\nmarking unusable suggested colors ...\n";
// hash map iterator // hash map iterator
LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin(); LiveRangeMapType::const_iterator HMI = (LRI.getLiveRangeMap())->begin();
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end(); LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
@ -1048,7 +1034,7 @@ void PhyRegAlloc::markUnusableSugColors()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void PhyRegAlloc::allocateStackSpace4SpilledLRs() { void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
if (DEBUG_RA) cerr << "\nsetting LR stack offsets ...\n"; if (DEBUG_RA) cerr << "\nSetting LR stack offsets for spills...\n";
LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin(); LiveRangeMapType::const_iterator HMI = LRI.getLiveRangeMap()->begin();
LiveRangeMapType::const_iterator HMIEnd = LRI.getLiveRangeMap()->end(); LiveRangeMapType::const_iterator HMIEnd = LRI.getLiveRangeMap()->end();
@ -1056,8 +1042,13 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
for ( ; HMI != HMIEnd ; ++HMI) { for ( ; HMI != HMIEnd ; ++HMI) {
if (HMI->first && HMI->second) { if (HMI->first && HMI->second) {
LiveRange *L = HMI->second; // get the LiveRange LiveRange *L = HMI->second; // get the LiveRange
if (!L->hasColor()) // NOTE: ** allocating the size of long Type ** if (!L->hasColor()) { // NOTE: ** allocating the size of long Type **
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy)); int stackOffset = mcInfo.allocateSpilledValue(TM, Type::LongTy);
L->setSpillOffFromFP(stackOffset);
if (DEBUG_RA)
cerr << " LR# " << L->getUserIGNode()->getIndex()
<< ": stack-offset = " << stackOffset << "\n";
}
} }
} // for all LR's in hash map } // for all LR's in hash map
} }
@ -1077,7 +1068,7 @@ void PhyRegAlloc::allocateRegisters()
// //
LRI.constructLiveRanges(); // create LR info LRI.constructLiveRanges(); // create LR info
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_LiveRanges)
LRI.printLiveRanges(); LRI.printLiveRanges();
createIGNodeListsAndIGs(); // create IGNode list and IGs createIGNodeListsAndIGs(); // create IGNode list and IGs
@ -1085,7 +1076,7 @@ void PhyRegAlloc::allocateRegisters()
buildInterferenceGraphs(); // build IGs in all reg classes buildInterferenceGraphs(); // build IGs in all reg classes
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_LiveRanges) {
// print all LRs in all reg classes // print all LRs in all reg classes
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[rc]->printIGNodeList(); RegClassList[rc]->printIGNodeList();
@ -1099,7 +1090,7 @@ void PhyRegAlloc::allocateRegisters()
LRI.coalesceLRs(); // coalesce all live ranges LRI.coalesceLRs(); // coalesce all live ranges
if (DEBUG_RA) { if (DEBUG_RA >= RA_DEBUG_LiveRanges) {
// print all LRs in all reg classes // print all LRs in all reg classes
for ( unsigned rc=0; rc < NumOfRegClasses ; rc++) for ( unsigned rc=0; rc < NumOfRegClasses ; rc++)
RegClassList[ rc ]->printIGNodeList(); RegClassList[ rc ]->printIGNodeList();
@ -1139,8 +1130,8 @@ void PhyRegAlloc::allocateRegisters()
updateMachineCode(); updateMachineCode();
if (DEBUG_RA) { if (DEBUG_RA) {
cerr << "\n**** Machine Code After Register Allocation:\n\n";
MachineCodeForMethod::get(Meth).dump(); MachineCodeForMethod::get(Meth).dump();
printMachineCode(); // only for DEBUGGING
} }
} }

View File

@ -1,3 +1,9 @@
//===-- RegClass.cpp -----------------------------------------------------===//
//
// class RegClass for coloring-based register allocation for LLVM.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/RegClass.h" #include "llvm/CodeGen/RegClass.h"
#include "llvm/CodeGen/RegAllocCommon.h" #include "llvm/CodeGen/RegAllocCommon.h"
using std::cerr; using std::cerr;
@ -11,7 +17,7 @@ RegClass::RegClass(const Function *M,
const ReservedColorListType *RCL) const ReservedColorListType *RCL)
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ), : Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
IG(this), IGNodeStack(), ReservedColorList(RCL) { IG(this), IGNodeStack(), ReservedColorList(RCL) {
if( DEBUG_RA) if( DEBUG_RA >= RA_DEBUG_Interference)
cerr << "Created Reg Class: " << RegClassID << "\n"; cerr << "Created Reg Class: " << RegClassID << "\n";
IsColorUsedArr.resize(Mrc->getNumOfAllRegs()); IsColorUsedArr.resize(Mrc->getNumOfAllRegs());
@ -24,7 +30,8 @@ RegClass::RegClass(const Function *M,
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void RegClass::colorAllRegs() void RegClass::colorAllRegs()
{ {
if(DEBUG_RA) cerr << "Coloring IG of reg class " << RegClassID << " ...\n"; if(DEBUG_RA >= RA_DEBUG_Coloring)
cerr << "Coloring IG of reg class " << RegClassID << " ...\n";
// pre-color IGNodes // pre-color IGNodes
pushAllIGNodes(); // push all IG Nodes pushAllIGNodes(); // push all IG Nodes
@ -57,7 +64,7 @@ void RegClass::pushAllIGNodes()
// push non-constrained IGNodes // push non-constrained IGNodes
bool PushedAll = pushUnconstrainedIGNodes(); bool PushedAll = pushUnconstrainedIGNodes();
if( DEBUG_RA) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Puhsed all-unconstrained IGNodes. "; cerr << " Puhsed all-unconstrained IGNodes. ";
if( PushedAll ) cerr << " No constrained nodes left."; if( PushedAll ) cerr << " No constrained nodes left.";
cerr << "\n"; cerr << "\n";
@ -88,7 +95,7 @@ void RegClass::pushAllIGNodes()
// //
NeedMoreSpills = !pushUnconstrainedIGNodes(); NeedMoreSpills = !pushUnconstrainedIGNodes();
if (DEBUG_RA) if (DEBUG_RA >= RA_DEBUG_Coloring)
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex(); cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
} while(NeedMoreSpills); // repeat until we have pushed all } while(NeedMoreSpills); // repeat until we have pushed all
@ -129,7 +136,7 @@ bool RegClass::pushUnconstrainedIGNodes()
IGNodeStack.push( IGNode ); // push IGNode on to the stack IGNodeStack.push( IGNode ); // push IGNode on to the stack
IGNode->pushOnStack(); // set OnStack and dec deg of neighs IGNode->pushOnStack(); // set OnStack and dec deg of neighs
if (DEBUG_RA > 1) { if (DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ; cerr << " pushed un-constrained IGNode " << IGNode->getIndex() ;
cerr << " on to stack\n"; cerr << " on to stack\n";
} }
@ -230,7 +237,7 @@ void RegClass::colorIGNode(IGNode *const Node)
MRC->colorIGNode(Node, IsColorUsedArr); MRC->colorIGNode(Node, IsColorUsedArr);
} }
else { else {
if( DEBUG_RA ) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Node " << Node->getIndex(); cerr << " Node " << Node->getIndex();
cerr << " already colored with color " << Node->getColor() << "\n"; cerr << " already colored with color " << Node->getColor() << "\n";
} }
@ -238,7 +245,7 @@ void RegClass::colorIGNode(IGNode *const Node)
if( !Node->hasColor() ) { if( !Node->hasColor() ) {
if( DEBUG_RA ) { if( DEBUG_RA >= RA_DEBUG_Coloring) {
cerr << " Node " << Node->getIndex(); cerr << " Node " << Node->getIndex();
cerr << " - could not find a color (needs spilling)\n"; cerr << " - could not find a color (needs spilling)\n";
} }