--- /dev/null
+#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 );
+}
--- /dev/null
+#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;
+
+ }
+}
+
+
--- /dev/null
+#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;
+ }
+ }
+}
+
+
--- /dev/null
+#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);
+}
+
+
+
+
--- /dev/null
+#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
--- /dev/null
+#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 );
+}
--- /dev/null
+#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;
+
+ }
+}
+
+
--- /dev/null
+#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;
+ }
+ }
+}
+
+
--- /dev/null
+#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);
+}
+
+
+
+
--- /dev/null
+#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