mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
*** empty log message ***
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@580 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
94d86e9677
commit
8e6047920d
31
lib/CodeGen/RegAlloc/IGNode.cpp
Normal file
31
lib/CodeGen/RegAlloc/IGNode.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
|
||||
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
||||
ParentLR(PLR)
|
||||
{
|
||||
OnStack = false;
|
||||
CurDegree = -1 ;
|
||||
ParentLR->setUserIGNode( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void IGNode::pushOnStack() // sets on to stack and
|
||||
{ // reduce the degree of neighbors
|
||||
OnStack = true;
|
||||
unsigned int neighs = AdjList.size();
|
||||
|
||||
for(unsigned int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
||||
}
|
||||
|
||||
|
||||
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
||||
vector <IGNode *>::iterator It = AdjList.begin();
|
||||
|
||||
// find Node
|
||||
for( ; It != AdjList.end() && (*It != Node); It++ ) ;
|
||||
assert( It != AdjList.end() ); // the node must be there
|
||||
|
||||
AdjList.erase( It );
|
||||
}
|
226
lib/CodeGen/RegAlloc/InterferenceGraph.cpp
Normal file
226
lib/CodeGen/RegAlloc/InterferenceGraph.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||
|
||||
|
||||
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
||||
IGNodeList()
|
||||
{
|
||||
IG = NULL;
|
||||
Size = 0;
|
||||
if( DEBUG_RA) {
|
||||
cout << "Interference graph created!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
InterferenceGraph:: ~InterferenceGraph() { // destructor
|
||||
if( IG )
|
||||
delete []IG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void InterferenceGraph::createGraph()
|
||||
{
|
||||
Size = IGNodeList.size();
|
||||
IG = (char **) new char *[Size];
|
||||
for( unsigned int r=0; r < Size; ++r)
|
||||
IG[r] = new char[Size];
|
||||
|
||||
// init IG matrix
|
||||
for(unsigned int i=0; i < Size; i++)
|
||||
for( unsigned int j=0; j < Size ; j++)
|
||||
IG[i][j] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
||||
{
|
||||
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
||||
IGNodeList.push_back( Node );
|
||||
//Node->setRegClass( RegCl );
|
||||
}
|
||||
|
||||
|
||||
// update both the matrix and AdjLists of nodes.
|
||||
// If there is already an interference between LR1 and LR2, adj lists
|
||||
// are not updated. LR1 and LR2 must be distinct since if not, it suggests
|
||||
// that there is some wrong logic in some other method.
|
||||
|
||||
void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) {
|
||||
assert(LR1 != LR2);
|
||||
|
||||
IGNode *const IGNode1 = LR1->getUserIGNode();
|
||||
IGNode *const IGNode2 = LR2->getUserIGNode();
|
||||
|
||||
if( DEBUG_RA) {
|
||||
assertIGNode( IGNode1 );
|
||||
assertIGNode( IGNode2 );
|
||||
}
|
||||
|
||||
const unsigned int row = IGNode1->getIndex();
|
||||
const unsigned int col = IGNode2->getIndex();
|
||||
|
||||
char *val;
|
||||
|
||||
if( DEBUG_RA > 1)
|
||||
cout << "setting intf for: [" << row << "][" << col << "]" << endl;
|
||||
|
||||
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
|
||||
|
||||
if( ! (*val) ) { // if this interf is not previously set
|
||||
|
||||
*val = 1; // add edges between nodes
|
||||
IGNode1->addAdjIGNode( IGNode2 );
|
||||
IGNode2->addAdjIGNode( IGNode1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) const {
|
||||
|
||||
assert(LR1 != LR2);
|
||||
|
||||
if( DEBUG_RA) {
|
||||
assertIGNode( LR1->getUserIGNode() );
|
||||
assertIGNode( LR2->getUserIGNode() );
|
||||
}
|
||||
|
||||
const unsigned int row = LR1->getUserIGNode()->getIndex();
|
||||
const unsigned int col = LR2->getUserIGNode()->getIndex();
|
||||
|
||||
char ret;
|
||||
( row > col) ? (ret = IG[row][col]) : (ret = IG[col][row]) ;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
||||
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
||||
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
||||
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
||||
|
||||
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||
LiveRange *const LR2 ) {
|
||||
|
||||
assert( LR1 != LR2); // cannot merge the same live range
|
||||
|
||||
IGNode *const DestNode = LR1->getUserIGNode();
|
||||
IGNode *SrcNode = LR2->getUserIGNode();
|
||||
|
||||
assertIGNode( DestNode );
|
||||
assertIGNode( SrcNode );
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << "Merging LRs: \""; LR1->printSet();
|
||||
cout << "\" and \""; LR2->printSet();
|
||||
cout << "\"" << endl;
|
||||
}
|
||||
|
||||
unsigned SrcDegree = SrcNode->getNumOfNeighbors();
|
||||
const unsigned SrcInd = SrcNode->getIndex();
|
||||
|
||||
|
||||
// for all neighs of SrcNode
|
||||
for(unsigned i=0; i < SrcDegree; i++) {
|
||||
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
|
||||
|
||||
LiveRange *const LROfNeigh = NeighNode->getParentLR();
|
||||
|
||||
// delete edge between src and neigh - even neigh == dest
|
||||
NeighNode->delAdjIGNode(SrcNode);
|
||||
|
||||
// set the matrix posn to 0 betn src and neigh - even neigh == dest
|
||||
const unsigned NInd = NeighNode->getIndex();
|
||||
( SrcInd > NInd) ? (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ;
|
||||
|
||||
|
||||
if( LR1 != LROfNeigh) { // if the neigh != dest
|
||||
|
||||
// add edge betwn Dest and Neigh - if there is no current edge
|
||||
setInterference(LR1, LROfNeigh );
|
||||
}
|
||||
|
||||
//cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
|
||||
//cout << NeighNode->getNumOfNeighbors();
|
||||
//cout << " Dest: [" << DestNode->getIndex() << "] ";
|
||||
//cout << DestNode->getNumOfNeighbors() << endl;
|
||||
|
||||
}
|
||||
|
||||
IGNodeList[ SrcInd ] = NULL;
|
||||
|
||||
// SrcNode is no longer necessary - LR2 must be deleted by the caller
|
||||
delete( SrcNode );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// must be called after modifications to the graph are over but before
|
||||
// pushing IGNodes on to the stack for coloring.
|
||||
|
||||
void InterferenceGraph::setCurDegreeOfIGNodes()
|
||||
{
|
||||
unsigned Size = IGNodeList.size();
|
||||
|
||||
for( unsigned i=0; i < Size; i++) {
|
||||
IGNode *Node = IGNodeList[i];
|
||||
if( Node )
|
||||
Node->setCurDegree();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------- debugging (Printing) methods -----------------------
|
||||
|
||||
|
||||
void InterferenceGraph::printIG() const
|
||||
{
|
||||
|
||||
for(unsigned int i=0; i < Size; i++) {
|
||||
|
||||
const IGNode *const Node = IGNodeList[i];
|
||||
if( ! Node )
|
||||
continue; // skip empty rows
|
||||
|
||||
cout << " [" << i << "] ";
|
||||
|
||||
for( unsigned int j=0; j < Size; j++) {
|
||||
if( j >= i) break;
|
||||
if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterferenceGraph::printIGNodeList() const
|
||||
{
|
||||
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
||||
|
||||
for(unsigned i=0; i < IGNodeList.size() ; ++i) {
|
||||
|
||||
const IGNode *const Node = IGNodeList[i];
|
||||
|
||||
if( ! Node )
|
||||
continue;
|
||||
|
||||
cout << " [" << Node->getIndex() << "] ";
|
||||
(Node->getParentLR())->printSet();
|
||||
//int Deg = Node->getCurDegree();
|
||||
cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
283
lib/CodeGen/RegAlloc/LiveRangeInfo.cpp
Normal file
283
lib/CodeGen/RegAlloc/LiveRangeInfo.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||
|
||||
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
||||
const TargetMachine& tm,
|
||||
vector<RegClass *> &RCL)
|
||||
: Meth(M), LiveRangeMap(),
|
||||
TM(tm), RegClassList(RCL)
|
||||
{ }
|
||||
|
||||
|
||||
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
||||
// Note: the caller must make sure that L1 and L2 are distinct
|
||||
|
||||
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
||||
{
|
||||
assert( L1 != L2);
|
||||
L1->setUnion( L2 ); // add elements of L2 to L1
|
||||
ValueSet::iterator L2It;
|
||||
|
||||
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
||||
|
||||
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
||||
|
||||
L1->add( *L2It ); // add the var in L2 to L1
|
||||
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map to L1
|
||||
}
|
||||
delete ( L2 ); // delete L2 as it is no longer needed
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LiveRangeInfo::constructLiveRanges()
|
||||
{
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Consturcting Live Ranges ..." << endl;
|
||||
|
||||
// first find the live ranges for all incoming args of the method since
|
||||
// those LRs start from the start of the method
|
||||
|
||||
// get the argument list
|
||||
const Method::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
// get an iterator to arg list
|
||||
Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
|
||||
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
|
||||
LiveRange * ArgRange = new LiveRange(); // creates a new LR and
|
||||
const Value *const Val = (const Value *) *ArgIt;
|
||||
|
||||
assert( Val);
|
||||
|
||||
ArgRange->add( Val ); // add the arg (def) to it
|
||||
LiveRangeMap[ Val ] = ArgRange;
|
||||
|
||||
// create a temp machine op to find the register class of value
|
||||
//const MachineOperand Op(MachineOperand::MO_VirtualRegister);
|
||||
|
||||
unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( Val );
|
||||
ArgRange->setRegClass(RegClassList[ rcid ] );
|
||||
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " adding LiveRange for argument ";
|
||||
printValue( (const Value *) *ArgIt); cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now find all LRs for machine the instructions. A new LR will be created
|
||||
// only for defs in the machine instr since, we assume that all Values are
|
||||
// defined before they are used. However, there can be multiple defs for
|
||||
// the same Value in machine instructions.
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // go thru BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); MInstIterator++) {
|
||||
|
||||
const MachineInstr * MInst = *MInstIterator;
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); OpI++) {
|
||||
|
||||
// create a new LR iff this operand is a def
|
||||
if( OpI.isDef() ) {
|
||||
|
||||
const Value *const Def = *OpI;
|
||||
LiveRange *DefRange = LiveRangeMap[Def];
|
||||
|
||||
// see LR already there (because of multiple defs)
|
||||
|
||||
if( !DefRange) { // if it is not in LiveRangeMap
|
||||
|
||||
DefRange = new LiveRange(); // creates a new live range and
|
||||
DefRange->add( Def ); // add the instruction (def) to it
|
||||
LiveRangeMap[ Def ] = DefRange; // update the map
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " creating a LR for def: ";
|
||||
printValue(Def); cout << endl;
|
||||
}
|
||||
|
||||
// set the register class of the new live range
|
||||
//assert( RegClassList.size() );
|
||||
MachineOperand::MachineOperandType OpTy =
|
||||
OpI.getMachineOperand().getOperandType();
|
||||
|
||||
bool isCC = ( OpTy == MachineOperand::MO_CCRegister);
|
||||
unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue(
|
||||
OpI.getMachineOperand().getVRegValue(), isCC );
|
||||
|
||||
|
||||
if(isCC )
|
||||
cout << "\a" << "**created a LR for a CC reg**" << cout;
|
||||
|
||||
DefRange->setRegClass( RegClassList[ rcid ] );
|
||||
|
||||
}
|
||||
else {
|
||||
DefRange->add( Def ); // add the opearand to def range
|
||||
// update the map - Operand points
|
||||
// to the merged set
|
||||
LiveRangeMap[ Def ] = DefRange;
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " added to an existing LR for def: ";
|
||||
printValue( Def ); cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // if isDef()
|
||||
|
||||
} // for all opereands in machine instructions
|
||||
|
||||
} // for all machine instructions in the BB
|
||||
|
||||
} // for all BBs in method
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Initial Live Ranges constructed!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LiveRangeInfo::coalesceLRs()
|
||||
{
|
||||
|
||||
/* Algorithm:
|
||||
for each BB in method
|
||||
for each machine instruction (inst)
|
||||
for each definition (def) in inst
|
||||
for each operand (op) of inst that is a use
|
||||
if the def and op are of the same type
|
||||
if the def and op do not interfere //i.e., not simultaneously live
|
||||
if (degree(LR of def) + degree(LR of op)) <= # avail regs
|
||||
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
||||
|
||||
*/
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << endl << "Coalscing LRs ..." << endl;
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
const MachineInstr * MInst = *MInstIterator;
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " *Iterating over machine instr ";
|
||||
MInst->dump();
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for(MachineInstr::val_op_const_iterator DefI(MInst);!DefI.done();++DefI){
|
||||
|
||||
if( DefI.isDef() ) { // iff this operand is a def
|
||||
|
||||
LiveRange *const LROfDef = getLiveRangeForValue( *DefI );
|
||||
assert( LROfDef );
|
||||
RegClass *const RCOfDef = LROfDef->getRegClass();
|
||||
|
||||
MachineInstr::val_op_const_iterator UseI(MInst);
|
||||
for( ; !UseI.done(); ++UseI){ // for all uses
|
||||
|
||||
LiveRange *const LROfUse = getLiveRangeForValue( *UseI );
|
||||
|
||||
if( ! LROfUse ) { // if LR of use is not found
|
||||
|
||||
//don't warn about labels
|
||||
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
|
||||
cout<<" !! Warning: No LR for use "; printValue(*UseI);
|
||||
cout << endl;
|
||||
}
|
||||
continue; // ignore and continue
|
||||
}
|
||||
|
||||
if( LROfUse == LROfDef) // nothing to merge if they are same
|
||||
continue;
|
||||
|
||||
// RegClass *const RCOfUse = LROfUse->getRegClass();
|
||||
|
||||
//if( RCOfDef == RCOfUse ) { // if the reg classes are the same
|
||||
|
||||
|
||||
if( LROfUse->getTypeID() == LROfDef->getTypeID() ) {
|
||||
|
||||
if( ! RCOfDef->getInterference(LROfDef, LROfUse) ) {
|
||||
|
||||
unsigned CombinedDegree =
|
||||
LROfDef->getUserIGNode()->getNumOfNeighbors() +
|
||||
LROfUse->getUserIGNode()->getNumOfNeighbors();
|
||||
|
||||
if( CombinedDegree <= RCOfDef->getNumOfAvailRegs() ) {
|
||||
|
||||
RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
|
||||
unionAndUpdateLRs(LROfDef, LROfUse);
|
||||
|
||||
} // if combined degree is less than # of regs
|
||||
|
||||
} // if def and use do not interfere
|
||||
|
||||
} // if reg classes are the same
|
||||
|
||||
} // for all uses
|
||||
|
||||
} // if def
|
||||
|
||||
} // for all defs
|
||||
|
||||
} // for all machine instructions
|
||||
|
||||
} // for all BBs
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << endl << "Coalscing Done!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------- Debug code for printing ---------------*/
|
||||
|
||||
|
||||
void LiveRangeInfo::printLiveRanges()
|
||||
{
|
||||
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
|
||||
cout << endl << "Printing Live Ranges from Hash Map:" << endl;
|
||||
for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
|
||||
if( (*HMI).first ) {
|
||||
cout <<" "; printValue((*HMI).first); cout << "\t: ";
|
||||
((*HMI).second)->printSet(); cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
343
lib/CodeGen/RegAlloc/PhyRegAloc.cpp
Normal file
343
lib/CodeGen/RegAlloc/PhyRegAloc.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
#include "llvm/CodeGen/PhyRegAlloc.h"
|
||||
|
||||
|
||||
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()),
|
||||
CallInstrList(),
|
||||
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) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::createIGNodeListsAndIGs()
|
||||
{
|
||||
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 ) {
|
||||
|
||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||
|
||||
if( (*HMI).first ) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
//the live range of this var interferes with this call
|
||||
if( isCallInst )
|
||||
LROfVar->addCallInterference( (const Instruction *const) Def );
|
||||
|
||||
}
|
||||
else if(DEBUG_RA) {
|
||||
// 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; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::buildInterferenceGraphs()
|
||||
{
|
||||
|
||||
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
const MachineInstr *const MInst = *MInstIterator;
|
||||
|
||||
// get the LV set after the instruction
|
||||
const LiveVarSet *const LVSetAI =
|
||||
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
||||
|
||||
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
||||
|
||||
if( OpI.isDef() ) {
|
||||
// create a new LR iff this operand is a def
|
||||
addInterference(*OpI, LVSetAI, isCallInst );
|
||||
|
||||
} //if this is a def
|
||||
|
||||
} // for all operands
|
||||
|
||||
} // for all machine instructions in BB
|
||||
|
||||
|
||||
// go thru LLVM instructions in the basic block and record all CALL
|
||||
// instructions in the CallInstrList
|
||||
BasicBlock::const_iterator InstIt = (*BBI)->begin();
|
||||
|
||||
for( ; InstIt != (*BBI)->end() ; ++ InstIt) {
|
||||
|
||||
if( (*InstIt)->getOpcode() == Instruction::Call )
|
||||
CallInstrList.push_back( *InstIt );
|
||||
}
|
||||
|
||||
} // for all BBs in method
|
||||
|
||||
|
||||
// add interferences for method arguments. Since there are no explict
|
||||
// defs in method for args, we have to add them manually
|
||||
|
||||
addInterferencesForArgs(); // add interference for method args
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Interference graphs calculted!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::addInterferencesForArgs()
|
||||
{
|
||||
// get the InSet of root BB
|
||||
const LiveVarSet *const InSet = LVI->getInSetOfBB( Meth->front() );
|
||||
|
||||
// get the argument list
|
||||
const Method::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
|
||||
// get an iterator to arg list
|
||||
Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
|
||||
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
addInterference( *ArgIt, InSet, false ); // add interferences between
|
||||
// args and LVars at start
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " - %% adding interference for argument ";
|
||||
printValue( (const Value *) *ArgIt); cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::updateMachineCode()
|
||||
{
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
cout << endl << "BB "; printValue( *BBI); cout << ": ";
|
||||
|
||||
// get the iterator for machine instructions
|
||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
MachineInstr *const MInst = *MInstIterator;
|
||||
|
||||
cout << endl << "\t";
|
||||
cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
|
||||
|
||||
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
|
||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
Op.getOperandType() == MachineOperand::MO_CCRegister) {
|
||||
|
||||
const Value *const Val = Op.getVRegValue();
|
||||
|
||||
if( !Val ) {
|
||||
cout << "\t<** Value is NULL!!!**>";
|
||||
continue;
|
||||
}
|
||||
assert( Val && "Value is NULL");
|
||||
|
||||
const LiveRange *const LR = LRI.getLiveRangeForValue(Val);
|
||||
|
||||
if ( !LR ) {
|
||||
if( ! ( (Val->getType())->isLabelType() ||
|
||||
(Val->getValueType() == Value::ConstantVal) ) ) {
|
||||
cout << "\t" << "<*No LiveRange for: ";
|
||||
printValue( Val); cout << "*>";
|
||||
}
|
||||
|
||||
|
||||
//assert( LR && "No LR found for Value");
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned RCID = (LR->getRegClass())->getID();
|
||||
|
||||
//cout << "Setting reg for value: "; printValue( Val );
|
||||
//cout << endl;
|
||||
|
||||
//Op.setRegForValue( MRI.getUnifiedRegNum(RCID, LR->getColor()) );
|
||||
|
||||
int RegNum = MRI.getUnifiedRegNum(RCID, LR->getColor());
|
||||
|
||||
cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
|
||||
|
||||
}
|
||||
else
|
||||
cout << "\t" << Op; // use dump field
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::allocateRegisters()
|
||||
{
|
||||
constructLiveRanges(); // create LR info
|
||||
|
||||
if( DEBUG_RA)
|
||||
LRI.printLiveRanges();
|
||||
|
||||
createIGNodeListsAndIGs(); // create IGNode list and IGs
|
||||
|
||||
buildInterferenceGraphs(); // build IGs in all reg classes
|
||||
|
||||
|
||||
if( DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
}
|
||||
|
||||
LRI.coalesceLRs(); // coalesce all live ranges
|
||||
|
||||
if( DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
}
|
||||
|
||||
MRI.colorArgs(Meth, LRI); // color method args
|
||||
MRI.colorCallArgs(CallInstrList, LRI, AddedInstrMap); // color call args of call instrns
|
||||
|
||||
// color all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->colorAllRegs();
|
||||
|
||||
updateMachineCode();
|
||||
//PrintMachineInstructions(Meth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
202
lib/CodeGen/RegAlloc/RegClass.cpp
Normal file
202
lib/CodeGen/RegAlloc/RegClass.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include "llvm/CodeGen/RegClass.h"
|
||||
|
||||
|
||||
|
||||
RegClass::RegClass(const Method *const M,
|
||||
const MachineRegClassInfo *const Mrc,
|
||||
const ReservedColorListType *const RCL)
|
||||
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
||||
IG(this), IGNodeStack(), ReservedColorList(RCL)
|
||||
{
|
||||
if( DEBUG_RA)
|
||||
cout << "Created Reg Class: " << RegClassID << endl;
|
||||
|
||||
// This constructor inits IG. The actual matrix is created by a call to
|
||||
// createInterferenceGraph() above.
|
||||
|
||||
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RegClass::colorAllRegs()
|
||||
{
|
||||
if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
|
||||
|
||||
//preColorIGNodes(); // pre-color IGNodes
|
||||
pushAllIGNodes(); // push all IG Nodes
|
||||
|
||||
unsigned int StackSize = IGNodeStack.size();
|
||||
IGNode *CurIGNode;
|
||||
|
||||
// for all LRs on stack
|
||||
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
||||
|
||||
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
||||
IGNodeStack.pop();
|
||||
colorIGNode (CurIGNode); // color it
|
||||
}
|
||||
|
||||
|
||||
// InsertSpillCode; ********* TODO ********
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RegClass::pushAllIGNodes()
|
||||
{
|
||||
bool NeedMoreSpills;
|
||||
IGNode *IGNodeSpill, *IGNode;
|
||||
|
||||
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
||||
|
||||
// push non-constrained IGNodes
|
||||
bool PushedAll = pushUnconstrainedIGNodes();
|
||||
|
||||
if( DEBUG_RA) {
|
||||
cout << " Puhsed all-unconstrained IGNodes. ";
|
||||
if( PushedAll ) cout << " No constrained nodes left.";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if( PushedAll ) // if NO constrained nodes left
|
||||
return;
|
||||
|
||||
|
||||
// now, we have constrained nodes. So, push one of them (the one with min
|
||||
// spill cost) and try to push the others as unConstrained nodes.
|
||||
// Repeat this.
|
||||
|
||||
do{
|
||||
|
||||
//get IGNode with min spill cost
|
||||
IGNodeSpill = getIGNodeWithMinSpillCost();
|
||||
|
||||
// push IGNode on to stack
|
||||
IGNodeStack.push( IGNodeSpill );
|
||||
|
||||
// set OnStack flag and decrement degree of neighs
|
||||
IGNode->pushOnStack();
|
||||
|
||||
// now push NON-constrined ones, if any
|
||||
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
||||
|
||||
} while( NeedMoreSpills ); // repeat until we have pushed all
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool RegClass::pushUnconstrainedIGNodes()
|
||||
{
|
||||
// # of LRs for this reg class
|
||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||
bool pushedall = true;
|
||||
|
||||
// a pass over IGNodeList
|
||||
for( unsigned i =0; i < IGNodeListSize; i++) {
|
||||
|
||||
// get IGNode i from IGNodeList
|
||||
IGNode *IGNode = IG.getIGNodeList()[i];
|
||||
|
||||
if( ! IGNode ) // can be null due to merging
|
||||
continue;
|
||||
|
||||
// if the degree of IGNode is lower
|
||||
if( (unsigned) IGNode->getCurDegree() < MRC->getNumOfAvailRegs() ) {
|
||||
IGNodeStack.push( IGNode ); // push IGNode on to the stack
|
||||
IGNode->pushOnStack(); // set OnStack and dec deg of neighs
|
||||
|
||||
if (DEBUG_RA > 1) {
|
||||
cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
|
||||
cout << " on to stack" << endl;
|
||||
}
|
||||
}
|
||||
else pushedall = false; // we didn't push all live ranges
|
||||
|
||||
} // for
|
||||
|
||||
// returns true if we pushed all live ranges - else false
|
||||
return pushedall;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
||||
{
|
||||
IGNode *IGNode=NULL;
|
||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||
|
||||
// pass over IGNodeList
|
||||
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
||||
IGNode = IG.getIGNodeList()[i];
|
||||
|
||||
if( ! IGNode ) // can be null due to merging
|
||||
continue;
|
||||
|
||||
// return the first IGNode ########## Change this #######
|
||||
if( ! IGNode->isOnStack() ) return IGNode;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RegClass::colorIGNode(IGNode *const Node)
|
||||
{
|
||||
|
||||
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
||||
|
||||
|
||||
// init all elements to false;
|
||||
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
||||
IsColorUsedArr[ i ] = false;
|
||||
}
|
||||
|
||||
// init all reserved_regs to true - we can't use them
|
||||
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
||||
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
||||
}
|
||||
|
||||
MRC->colorIGNode(Node, IsColorUsedArr);
|
||||
}
|
||||
else {
|
||||
cout << " Node " << Node->getIndex();
|
||||
cout << " already colored with color " << Node->getColor() << endl;
|
||||
}
|
||||
|
||||
|
||||
if( !Node->hasColor() ) {
|
||||
cout << " Node " << Node->getIndex();
|
||||
cout << " - could not find a color (needs spilling)" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
if( DEBUG_RA) { // printing code
|
||||
/* cout << " Node " << Node->getIndex();
|
||||
if( Node->hasColor() ) {
|
||||
cout << " colored with color " << Node->getColor() << " [" ;
|
||||
cout << SparcFloatRegOrder::getRegName(Node->getColor());
|
||||
if( Node->getTypeID() == Type::DoubleTyID )
|
||||
cout << "+" << SparcFloatRegOrder::getRegName(Node->getColor()+1);
|
||||
cout << "]" << endl;
|
||||
}
|
||||
*/
|
||||
// MRC->printReg( Node->getParentLR());
|
||||
cout << " Node " << Node->getIndex();
|
||||
if( Node->hasColor() )
|
||||
cout << " colored with color " << Node->getColor() << endl;
|
||||
|
||||
#endif
|
31
lib/Target/SparcV9/RegAlloc/IGNode.cpp
Normal file
31
lib/Target/SparcV9/RegAlloc/IGNode.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
|
||||
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
||||
ParentLR(PLR)
|
||||
{
|
||||
OnStack = false;
|
||||
CurDegree = -1 ;
|
||||
ParentLR->setUserIGNode( this );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void IGNode::pushOnStack() // sets on to stack and
|
||||
{ // reduce the degree of neighbors
|
||||
OnStack = true;
|
||||
unsigned int neighs = AdjList.size();
|
||||
|
||||
for(unsigned int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
||||
}
|
||||
|
||||
|
||||
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
||||
vector <IGNode *>::iterator It = AdjList.begin();
|
||||
|
||||
// find Node
|
||||
for( ; It != AdjList.end() && (*It != Node); It++ ) ;
|
||||
assert( It != AdjList.end() ); // the node must be there
|
||||
|
||||
AdjList.erase( It );
|
||||
}
|
226
lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp
Normal file
226
lib/Target/SparcV9/RegAlloc/InterferenceGraph.cpp
Normal file
@ -0,0 +1,226 @@
|
||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||
|
||||
|
||||
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
||||
IGNodeList()
|
||||
{
|
||||
IG = NULL;
|
||||
Size = 0;
|
||||
if( DEBUG_RA) {
|
||||
cout << "Interference graph created!" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
InterferenceGraph:: ~InterferenceGraph() { // destructor
|
||||
if( IG )
|
||||
delete []IG;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void InterferenceGraph::createGraph()
|
||||
{
|
||||
Size = IGNodeList.size();
|
||||
IG = (char **) new char *[Size];
|
||||
for( unsigned int r=0; r < Size; ++r)
|
||||
IG[r] = new char[Size];
|
||||
|
||||
// init IG matrix
|
||||
for(unsigned int i=0; i < Size; i++)
|
||||
for( unsigned int j=0; j < Size ; j++)
|
||||
IG[i][j] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
||||
{
|
||||
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
||||
IGNodeList.push_back( Node );
|
||||
//Node->setRegClass( RegCl );
|
||||
}
|
||||
|
||||
|
||||
// update both the matrix and AdjLists of nodes.
|
||||
// If there is already an interference between LR1 and LR2, adj lists
|
||||
// are not updated. LR1 and LR2 must be distinct since if not, it suggests
|
||||
// that there is some wrong logic in some other method.
|
||||
|
||||
void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) {
|
||||
assert(LR1 != LR2);
|
||||
|
||||
IGNode *const IGNode1 = LR1->getUserIGNode();
|
||||
IGNode *const IGNode2 = LR2->getUserIGNode();
|
||||
|
||||
if( DEBUG_RA) {
|
||||
assertIGNode( IGNode1 );
|
||||
assertIGNode( IGNode2 );
|
||||
}
|
||||
|
||||
const unsigned int row = IGNode1->getIndex();
|
||||
const unsigned int col = IGNode2->getIndex();
|
||||
|
||||
char *val;
|
||||
|
||||
if( DEBUG_RA > 1)
|
||||
cout << "setting intf for: [" << row << "][" << col << "]" << endl;
|
||||
|
||||
( row > col) ? val = &IG[row][col]: val = &IG[col][row];
|
||||
|
||||
if( ! (*val) ) { // if this interf is not previously set
|
||||
|
||||
*val = 1; // add edges between nodes
|
||||
IGNode1->addAdjIGNode( IGNode2 );
|
||||
IGNode2->addAdjIGNode( IGNode1 );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) const {
|
||||
|
||||
assert(LR1 != LR2);
|
||||
|
||||
if( DEBUG_RA) {
|
||||
assertIGNode( LR1->getUserIGNode() );
|
||||
assertIGNode( LR2->getUserIGNode() );
|
||||
}
|
||||
|
||||
const unsigned int row = LR1->getUserIGNode()->getIndex();
|
||||
const unsigned int col = LR2->getUserIGNode()->getIndex();
|
||||
|
||||
char ret;
|
||||
( row > col) ? (ret = IG[row][col]) : (ret = IG[col][row]) ;
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
||||
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
||||
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
||||
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
||||
|
||||
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||
LiveRange *const LR2 ) {
|
||||
|
||||
assert( LR1 != LR2); // cannot merge the same live range
|
||||
|
||||
IGNode *const DestNode = LR1->getUserIGNode();
|
||||
IGNode *SrcNode = LR2->getUserIGNode();
|
||||
|
||||
assertIGNode( DestNode );
|
||||
assertIGNode( SrcNode );
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << "Merging LRs: \""; LR1->printSet();
|
||||
cout << "\" and \""; LR2->printSet();
|
||||
cout << "\"" << endl;
|
||||
}
|
||||
|
||||
unsigned SrcDegree = SrcNode->getNumOfNeighbors();
|
||||
const unsigned SrcInd = SrcNode->getIndex();
|
||||
|
||||
|
||||
// for all neighs of SrcNode
|
||||
for(unsigned i=0; i < SrcDegree; i++) {
|
||||
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
|
||||
|
||||
LiveRange *const LROfNeigh = NeighNode->getParentLR();
|
||||
|
||||
// delete edge between src and neigh - even neigh == dest
|
||||
NeighNode->delAdjIGNode(SrcNode);
|
||||
|
||||
// set the matrix posn to 0 betn src and neigh - even neigh == dest
|
||||
const unsigned NInd = NeighNode->getIndex();
|
||||
( SrcInd > NInd) ? (IG[SrcInd][NInd]=0) : (IG[NInd][SrcInd]=0) ;
|
||||
|
||||
|
||||
if( LR1 != LROfNeigh) { // if the neigh != dest
|
||||
|
||||
// add edge betwn Dest and Neigh - if there is no current edge
|
||||
setInterference(LR1, LROfNeigh );
|
||||
}
|
||||
|
||||
//cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
|
||||
//cout << NeighNode->getNumOfNeighbors();
|
||||
//cout << " Dest: [" << DestNode->getIndex() << "] ";
|
||||
//cout << DestNode->getNumOfNeighbors() << endl;
|
||||
|
||||
}
|
||||
|
||||
IGNodeList[ SrcInd ] = NULL;
|
||||
|
||||
// SrcNode is no longer necessary - LR2 must be deleted by the caller
|
||||
delete( SrcNode );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// must be called after modifications to the graph are over but before
|
||||
// pushing IGNodes on to the stack for coloring.
|
||||
|
||||
void InterferenceGraph::setCurDegreeOfIGNodes()
|
||||
{
|
||||
unsigned Size = IGNodeList.size();
|
||||
|
||||
for( unsigned i=0; i < Size; i++) {
|
||||
IGNode *Node = IGNodeList[i];
|
||||
if( Node )
|
||||
Node->setCurDegree();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//--------------------- debugging (Printing) methods -----------------------
|
||||
|
||||
|
||||
void InterferenceGraph::printIG() const
|
||||
{
|
||||
|
||||
for(unsigned int i=0; i < Size; i++) {
|
||||
|
||||
const IGNode *const Node = IGNodeList[i];
|
||||
if( ! Node )
|
||||
continue; // skip empty rows
|
||||
|
||||
cout << " [" << i << "] ";
|
||||
|
||||
for( unsigned int j=0; j < Size; j++) {
|
||||
if( j >= i) break;
|
||||
if( IG[i][j] ) cout << "(" << i << "," << j << ") ";
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InterferenceGraph::printIGNodeList() const
|
||||
{
|
||||
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
||||
|
||||
for(unsigned i=0; i < IGNodeList.size() ; ++i) {
|
||||
|
||||
const IGNode *const Node = IGNodeList[i];
|
||||
|
||||
if( ! Node )
|
||||
continue;
|
||||
|
||||
cout << " [" << Node->getIndex() << "] ";
|
||||
(Node->getParentLR())->printSet();
|
||||
//int Deg = Node->getCurDegree();
|
||||
cout << "\t <# of Neighs: " << Node->getNumOfNeighbors() << ">" << endl;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
283
lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
Normal file
283
lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
Normal file
@ -0,0 +1,283 @@
|
||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||
|
||||
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
||||
const TargetMachine& tm,
|
||||
vector<RegClass *> &RCL)
|
||||
: Meth(M), LiveRangeMap(),
|
||||
TM(tm), RegClassList(RCL)
|
||||
{ }
|
||||
|
||||
|
||||
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
||||
// Note: the caller must make sure that L1 and L2 are distinct
|
||||
|
||||
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
||||
{
|
||||
assert( L1 != L2);
|
||||
L1->setUnion( L2 ); // add elements of L2 to L1
|
||||
ValueSet::iterator L2It;
|
||||
|
||||
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
||||
|
||||
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
||||
|
||||
L1->add( *L2It ); // add the var in L2 to L1
|
||||
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map to L1
|
||||
}
|
||||
delete ( L2 ); // delete L2 as it is no longer needed
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void LiveRangeInfo::constructLiveRanges()
|
||||
{
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Consturcting Live Ranges ..." << endl;
|
||||
|
||||
// first find the live ranges for all incoming args of the method since
|
||||
// those LRs start from the start of the method
|
||||
|
||||
// get the argument list
|
||||
const Method::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
// get an iterator to arg list
|
||||
Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
|
||||
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
|
||||
LiveRange * ArgRange = new LiveRange(); // creates a new LR and
|
||||
const Value *const Val = (const Value *) *ArgIt;
|
||||
|
||||
assert( Val);
|
||||
|
||||
ArgRange->add( Val ); // add the arg (def) to it
|
||||
LiveRangeMap[ Val ] = ArgRange;
|
||||
|
||||
// create a temp machine op to find the register class of value
|
||||
//const MachineOperand Op(MachineOperand::MO_VirtualRegister);
|
||||
|
||||
unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( Val );
|
||||
ArgRange->setRegClass(RegClassList[ rcid ] );
|
||||
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " adding LiveRange for argument ";
|
||||
printValue( (const Value *) *ArgIt); cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now find all LRs for machine the instructions. A new LR will be created
|
||||
// only for defs in the machine instr since, we assume that all Values are
|
||||
// defined before they are used. However, there can be multiple defs for
|
||||
// the same Value in machine instructions.
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // go thru BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); MInstIterator++) {
|
||||
|
||||
const MachineInstr * MInst = *MInstIterator;
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); OpI++) {
|
||||
|
||||
// create a new LR iff this operand is a def
|
||||
if( OpI.isDef() ) {
|
||||
|
||||
const Value *const Def = *OpI;
|
||||
LiveRange *DefRange = LiveRangeMap[Def];
|
||||
|
||||
// see LR already there (because of multiple defs)
|
||||
|
||||
if( !DefRange) { // if it is not in LiveRangeMap
|
||||
|
||||
DefRange = new LiveRange(); // creates a new live range and
|
||||
DefRange->add( Def ); // add the instruction (def) to it
|
||||
LiveRangeMap[ Def ] = DefRange; // update the map
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " creating a LR for def: ";
|
||||
printValue(Def); cout << endl;
|
||||
}
|
||||
|
||||
// set the register class of the new live range
|
||||
//assert( RegClassList.size() );
|
||||
MachineOperand::MachineOperandType OpTy =
|
||||
OpI.getMachineOperand().getOperandType();
|
||||
|
||||
bool isCC = ( OpTy == MachineOperand::MO_CCRegister);
|
||||
unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue(
|
||||
OpI.getMachineOperand().getVRegValue(), isCC );
|
||||
|
||||
|
||||
if(isCC )
|
||||
cout << "\a" << "**created a LR for a CC reg**" << cout;
|
||||
|
||||
DefRange->setRegClass( RegClassList[ rcid ] );
|
||||
|
||||
}
|
||||
else {
|
||||
DefRange->add( Def ); // add the opearand to def range
|
||||
// update the map - Operand points
|
||||
// to the merged set
|
||||
LiveRangeMap[ Def ] = DefRange;
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " added to an existing LR for def: ";
|
||||
printValue( Def ); cout << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
} // if isDef()
|
||||
|
||||
} // for all opereands in machine instructions
|
||||
|
||||
} // for all machine instructions in the BB
|
||||
|
||||
} // for all BBs in method
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Initial Live Ranges constructed!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LiveRangeInfo::coalesceLRs()
|
||||
{
|
||||
|
||||
/* Algorithm:
|
||||
for each BB in method
|
||||
for each machine instruction (inst)
|
||||
for each definition (def) in inst
|
||||
for each operand (op) of inst that is a use
|
||||
if the def and op are of the same type
|
||||
if the def and op do not interfere //i.e., not simultaneously live
|
||||
if (degree(LR of def) + degree(LR of op)) <= # avail regs
|
||||
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
||||
|
||||
*/
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << endl << "Coalscing LRs ..." << endl;
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
const MachineInstr * MInst = *MInstIterator;
|
||||
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " *Iterating over machine instr ";
|
||||
MInst->dump();
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for(MachineInstr::val_op_const_iterator DefI(MInst);!DefI.done();++DefI){
|
||||
|
||||
if( DefI.isDef() ) { // iff this operand is a def
|
||||
|
||||
LiveRange *const LROfDef = getLiveRangeForValue( *DefI );
|
||||
assert( LROfDef );
|
||||
RegClass *const RCOfDef = LROfDef->getRegClass();
|
||||
|
||||
MachineInstr::val_op_const_iterator UseI(MInst);
|
||||
for( ; !UseI.done(); ++UseI){ // for all uses
|
||||
|
||||
LiveRange *const LROfUse = getLiveRangeForValue( *UseI );
|
||||
|
||||
if( ! LROfUse ) { // if LR of use is not found
|
||||
|
||||
//don't warn about labels
|
||||
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
|
||||
cout<<" !! Warning: No LR for use "; printValue(*UseI);
|
||||
cout << endl;
|
||||
}
|
||||
continue; // ignore and continue
|
||||
}
|
||||
|
||||
if( LROfUse == LROfDef) // nothing to merge if they are same
|
||||
continue;
|
||||
|
||||
// RegClass *const RCOfUse = LROfUse->getRegClass();
|
||||
|
||||
//if( RCOfDef == RCOfUse ) { // if the reg classes are the same
|
||||
|
||||
|
||||
if( LROfUse->getTypeID() == LROfDef->getTypeID() ) {
|
||||
|
||||
if( ! RCOfDef->getInterference(LROfDef, LROfUse) ) {
|
||||
|
||||
unsigned CombinedDegree =
|
||||
LROfDef->getUserIGNode()->getNumOfNeighbors() +
|
||||
LROfUse->getUserIGNode()->getNumOfNeighbors();
|
||||
|
||||
if( CombinedDegree <= RCOfDef->getNumOfAvailRegs() ) {
|
||||
|
||||
RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
|
||||
unionAndUpdateLRs(LROfDef, LROfUse);
|
||||
|
||||
} // if combined degree is less than # of regs
|
||||
|
||||
} // if def and use do not interfere
|
||||
|
||||
} // if reg classes are the same
|
||||
|
||||
} // for all uses
|
||||
|
||||
} // if def
|
||||
|
||||
} // for all defs
|
||||
|
||||
} // for all machine instructions
|
||||
|
||||
} // for all BBs
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << endl << "Coalscing Done!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------- Debug code for printing ---------------*/
|
||||
|
||||
|
||||
void LiveRangeInfo::printLiveRanges()
|
||||
{
|
||||
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
|
||||
cout << endl << "Printing Live Ranges from Hash Map:" << endl;
|
||||
for( ; HMI != LiveRangeMap.end() ; HMI ++ ) {
|
||||
if( (*HMI).first ) {
|
||||
cout <<" "; printValue((*HMI).first); cout << "\t: ";
|
||||
((*HMI).second)->printSet(); cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
343
lib/Target/SparcV9/RegAlloc/PhyRegAloc.cpp
Normal file
343
lib/Target/SparcV9/RegAlloc/PhyRegAloc.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
#include "llvm/CodeGen/PhyRegAlloc.h"
|
||||
|
||||
|
||||
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()),
|
||||
CallInstrList(),
|
||||
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) );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::createIGNodeListsAndIGs()
|
||||
{
|
||||
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 ) {
|
||||
|
||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||
|
||||
if( (*HMI).first ) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// 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);
|
||||
|
||||
}
|
||||
|
||||
//the live range of this var interferes with this call
|
||||
if( isCallInst )
|
||||
LROfVar->addCallInterference( (const Instruction *const) Def );
|
||||
|
||||
}
|
||||
else if(DEBUG_RA) {
|
||||
// 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; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::buildInterferenceGraphs()
|
||||
{
|
||||
|
||||
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
// get the iterator for machine instructions
|
||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::const_iterator
|
||||
MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
const MachineInstr *const MInst = *MInstIterator;
|
||||
|
||||
// get the LV set after the instruction
|
||||
const LiveVarSet *const LVSetAI =
|
||||
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
||||
|
||||
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
||||
|
||||
// iterate over MI operands to find defs
|
||||
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
||||
|
||||
if( OpI.isDef() ) {
|
||||
// create a new LR iff this operand is a def
|
||||
addInterference(*OpI, LVSetAI, isCallInst );
|
||||
|
||||
} //if this is a def
|
||||
|
||||
} // for all operands
|
||||
|
||||
} // for all machine instructions in BB
|
||||
|
||||
|
||||
// go thru LLVM instructions in the basic block and record all CALL
|
||||
// instructions in the CallInstrList
|
||||
BasicBlock::const_iterator InstIt = (*BBI)->begin();
|
||||
|
||||
for( ; InstIt != (*BBI)->end() ; ++ InstIt) {
|
||||
|
||||
if( (*InstIt)->getOpcode() == Instruction::Call )
|
||||
CallInstrList.push_back( *InstIt );
|
||||
}
|
||||
|
||||
} // for all BBs in method
|
||||
|
||||
|
||||
// add interferences for method arguments. Since there are no explict
|
||||
// defs in method for args, we have to add them manually
|
||||
|
||||
addInterferencesForArgs(); // add interference for method args
|
||||
|
||||
if( DEBUG_RA)
|
||||
cout << "Interference graphs calculted!" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::addInterferencesForArgs()
|
||||
{
|
||||
// get the InSet of root BB
|
||||
const LiveVarSet *const InSet = LVI->getInSetOfBB( Meth->front() );
|
||||
|
||||
// get the argument list
|
||||
const Method::ArgumentListType& ArgList = Meth->getArgumentList();
|
||||
|
||||
// get an iterator to arg list
|
||||
Method::ArgumentListType::const_iterator ArgIt = ArgList.begin();
|
||||
|
||||
|
||||
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
|
||||
addInterference( *ArgIt, InSet, false ); // add interferences between
|
||||
// args and LVars at start
|
||||
if( DEBUG_RA > 1) {
|
||||
cout << " - %% adding interference for argument ";
|
||||
printValue( (const Value *) *ArgIt); cout << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::updateMachineCode()
|
||||
{
|
||||
|
||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||
|
||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||
|
||||
cout << endl << "BB "; printValue( *BBI); cout << ": ";
|
||||
|
||||
// get the iterator for machine instructions
|
||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
||||
|
||||
// iterate over all the machine instructions in BB
|
||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||
|
||||
MachineInstr *const MInst = *MInstIterator;
|
||||
|
||||
cout << endl << "\t";
|
||||
cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
|
||||
|
||||
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
|
||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
|
||||
if( Op.getOperandType() == MachineOperand::MO_VirtualRegister ||
|
||||
Op.getOperandType() == MachineOperand::MO_CCRegister) {
|
||||
|
||||
const Value *const Val = Op.getVRegValue();
|
||||
|
||||
if( !Val ) {
|
||||
cout << "\t<** Value is NULL!!!**>";
|
||||
continue;
|
||||
}
|
||||
assert( Val && "Value is NULL");
|
||||
|
||||
const LiveRange *const LR = LRI.getLiveRangeForValue(Val);
|
||||
|
||||
if ( !LR ) {
|
||||
if( ! ( (Val->getType())->isLabelType() ||
|
||||
(Val->getValueType() == Value::ConstantVal) ) ) {
|
||||
cout << "\t" << "<*No LiveRange for: ";
|
||||
printValue( Val); cout << "*>";
|
||||
}
|
||||
|
||||
|
||||
//assert( LR && "No LR found for Value");
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned RCID = (LR->getRegClass())->getID();
|
||||
|
||||
//cout << "Setting reg for value: "; printValue( Val );
|
||||
//cout << endl;
|
||||
|
||||
//Op.setRegForValue( MRI.getUnifiedRegNum(RCID, LR->getColor()) );
|
||||
|
||||
int RegNum = MRI.getUnifiedRegNum(RCID, LR->getColor());
|
||||
|
||||
cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
|
||||
|
||||
}
|
||||
else
|
||||
cout << "\t" << Op; // use dump field
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void PhyRegAlloc::allocateRegisters()
|
||||
{
|
||||
constructLiveRanges(); // create LR info
|
||||
|
||||
if( DEBUG_RA)
|
||||
LRI.printLiveRanges();
|
||||
|
||||
createIGNodeListsAndIGs(); // create IGNode list and IGs
|
||||
|
||||
buildInterferenceGraphs(); // build IGs in all reg classes
|
||||
|
||||
|
||||
if( DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
}
|
||||
|
||||
LRI.coalesceLRs(); // coalesce all live ranges
|
||||
|
||||
if( DEBUG_RA) {
|
||||
// print all LRs in all reg classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIGNodeList();
|
||||
|
||||
// print IGs in all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->printIG();
|
||||
}
|
||||
|
||||
MRI.colorArgs(Meth, LRI); // color method args
|
||||
MRI.colorCallArgs(CallInstrList, LRI, AddedInstrMap); // color call args of call instrns
|
||||
|
||||
// color all register classes
|
||||
for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
|
||||
RegClassList[ rc ]->colorAllRegs();
|
||||
|
||||
updateMachineCode();
|
||||
//PrintMachineInstructions(Meth);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
202
lib/Target/SparcV9/RegAlloc/RegClass.cpp
Normal file
202
lib/Target/SparcV9/RegAlloc/RegClass.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
#include "llvm/CodeGen/RegClass.h"
|
||||
|
||||
|
||||
|
||||
RegClass::RegClass(const Method *const M,
|
||||
const MachineRegClassInfo *const Mrc,
|
||||
const ReservedColorListType *const RCL)
|
||||
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
||||
IG(this), IGNodeStack(), ReservedColorList(RCL)
|
||||
{
|
||||
if( DEBUG_RA)
|
||||
cout << "Created Reg Class: " << RegClassID << endl;
|
||||
|
||||
// This constructor inits IG. The actual matrix is created by a call to
|
||||
// createInterferenceGraph() above.
|
||||
|
||||
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RegClass::colorAllRegs()
|
||||
{
|
||||
if(DEBUG_RA) cout << "Coloring IGs ..." << endl;
|
||||
|
||||
//preColorIGNodes(); // pre-color IGNodes
|
||||
pushAllIGNodes(); // push all IG Nodes
|
||||
|
||||
unsigned int StackSize = IGNodeStack.size();
|
||||
IGNode *CurIGNode;
|
||||
|
||||
// for all LRs on stack
|
||||
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
||||
|
||||
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
||||
IGNodeStack.pop();
|
||||
colorIGNode (CurIGNode); // color it
|
||||
}
|
||||
|
||||
|
||||
// InsertSpillCode; ********* TODO ********
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RegClass::pushAllIGNodes()
|
||||
{
|
||||
bool NeedMoreSpills;
|
||||
IGNode *IGNodeSpill, *IGNode;
|
||||
|
||||
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
||||
|
||||
// push non-constrained IGNodes
|
||||
bool PushedAll = pushUnconstrainedIGNodes();
|
||||
|
||||
if( DEBUG_RA) {
|
||||
cout << " Puhsed all-unconstrained IGNodes. ";
|
||||
if( PushedAll ) cout << " No constrained nodes left.";
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
if( PushedAll ) // if NO constrained nodes left
|
||||
return;
|
||||
|
||||
|
||||
// now, we have constrained nodes. So, push one of them (the one with min
|
||||
// spill cost) and try to push the others as unConstrained nodes.
|
||||
// Repeat this.
|
||||
|
||||
do{
|
||||
|
||||
//get IGNode with min spill cost
|
||||
IGNodeSpill = getIGNodeWithMinSpillCost();
|
||||
|
||||
// push IGNode on to stack
|
||||
IGNodeStack.push( IGNodeSpill );
|
||||
|
||||
// set OnStack flag and decrement degree of neighs
|
||||
IGNode->pushOnStack();
|
||||
|
||||
// now push NON-constrined ones, if any
|
||||
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
||||
|
||||
} while( NeedMoreSpills ); // repeat until we have pushed all
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool RegClass::pushUnconstrainedIGNodes()
|
||||
{
|
||||
// # of LRs for this reg class
|
||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||
bool pushedall = true;
|
||||
|
||||
// a pass over IGNodeList
|
||||
for( unsigned i =0; i < IGNodeListSize; i++) {
|
||||
|
||||
// get IGNode i from IGNodeList
|
||||
IGNode *IGNode = IG.getIGNodeList()[i];
|
||||
|
||||
if( ! IGNode ) // can be null due to merging
|
||||
continue;
|
||||
|
||||
// if the degree of IGNode is lower
|
||||
if( (unsigned) IGNode->getCurDegree() < MRC->getNumOfAvailRegs() ) {
|
||||
IGNodeStack.push( IGNode ); // push IGNode on to the stack
|
||||
IGNode->pushOnStack(); // set OnStack and dec deg of neighs
|
||||
|
||||
if (DEBUG_RA > 1) {
|
||||
cout << " pushed un-constrained IGNode " << IGNode->getIndex() ;
|
||||
cout << " on to stack" << endl;
|
||||
}
|
||||
}
|
||||
else pushedall = false; // we didn't push all live ranges
|
||||
|
||||
} // for
|
||||
|
||||
// returns true if we pushed all live ranges - else false
|
||||
return pushedall;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
||||
{
|
||||
IGNode *IGNode=NULL;
|
||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||
|
||||
// pass over IGNodeList
|
||||
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
||||
IGNode = IG.getIGNodeList()[i];
|
||||
|
||||
if( ! IGNode ) // can be null due to merging
|
||||
continue;
|
||||
|
||||
// return the first IGNode ########## Change this #######
|
||||
if( ! IGNode->isOnStack() ) return IGNode;
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void RegClass::colorIGNode(IGNode *const Node)
|
||||
{
|
||||
|
||||
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
||||
|
||||
|
||||
// init all elements to false;
|
||||
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
||||
IsColorUsedArr[ i ] = false;
|
||||
}
|
||||
|
||||
// init all reserved_regs to true - we can't use them
|
||||
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
||||
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
||||
}
|
||||
|
||||
MRC->colorIGNode(Node, IsColorUsedArr);
|
||||
}
|
||||
else {
|
||||
cout << " Node " << Node->getIndex();
|
||||
cout << " already colored with color " << Node->getColor() << endl;
|
||||
}
|
||||
|
||||
|
||||
if( !Node->hasColor() ) {
|
||||
cout << " Node " << Node->getIndex();
|
||||
cout << " - could not find a color (needs spilling)" << endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
if( DEBUG_RA) { // printing code
|
||||
/* cout << " Node " << Node->getIndex();
|
||||
if( Node->hasColor() ) {
|
||||
cout << " colored with color " << Node->getColor() << " [" ;
|
||||
cout << SparcFloatRegOrder::getRegName(Node->getColor());
|
||||
if( Node->getTypeID() == Type::DoubleTyID )
|
||||
cout << "+" << SparcFloatRegOrder::getRegName(Node->getColor()+1);
|
||||
cout << "]" << endl;
|
||||
}
|
||||
*/
|
||||
// MRC->printReg( Node->getParentLR());
|
||||
cout << " Node " << Node->getIndex();
|
||||
if( Node->hasColor() )
|
||||
cout << " colored with color " << Node->getColor() << endl;
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user