aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/SparcV9/RegAlloc
diff options
context:
space:
mode:
authorRuchira Sasanka <sasanka@students.uiuc.edu>2001-09-30 23:11:59 +0000
committerRuchira Sasanka <sasanka@students.uiuc.edu>2001-09-30 23:11:59 +0000
commita5ab9648a8e295a84817327d96ed4f83fa468d0c (patch)
treef14b9b5d20af42d8df6efb095ac410382a204479 /lib/Target/SparcV9/RegAlloc
parent6b12936ac3513ef6d60ea8ac7fccf89636d172be (diff)
downloadexternal_llvm-a5ab9648a8e295a84817327d96ed4f83fa468d0c.zip
external_llvm-a5ab9648a8e295a84817327d96ed4f83fa468d0c.tar.gz
external_llvm-a5ab9648a8e295a84817327d96ed4f83fa468d0c.tar.bz2
--added suggesting colors; call/ret arg handling
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@670 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/SparcV9/RegAlloc')
-rw-r--r--lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp111
-rw-r--r--lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp172
2 files changed, 235 insertions, 48 deletions
diff --git a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
index 658f3d2..4d3e925 100644
--- a/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
+++ b/lib/Target/SparcV9/RegAlloc/LiveRangeInfo.cpp
@@ -4,12 +4,15 @@ LiveRangeInfo::LiveRangeInfo(const Method *const M,
const TargetMachine& tm,
vector<RegClass *> &RCL)
: Meth(M), LiveRangeMap(),
- TM(tm), RegClassList(RCL)
+ TM(tm), RegClassList(RCL),
+ MRI( tm.getRegInfo()),
+ CallRetInstrList()
{ }
// 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
+// Note: the caller must make sure that L1 and L2 are distinct and both
+// LRs don't have suggested colors
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
{
@@ -24,6 +27,15 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
L1->add( *L2It ); // add the var in L2 to L1
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map to L1
}
+
+
+ // Now if LROfDef(L1) has a suggested color, it will remain.
+ // But, if LROfUse(L2) has a suggested color, the new range
+ // must have the same color.
+
+ if(L2->hasSuggestedColor())
+ L1->setSuggestedColor( L2->getSuggestedColor() );
+
delete ( L2 ); // delete L2 as it is no longer needed
}
@@ -58,7 +70,7 @@ void LiveRangeInfo::constructLiveRanges()
// create a temp machine op to find the register class of value
//const MachineOperand Op(MachineOperand::MO_VirtualRegister);
- unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue( Val );
+ unsigned rcid = MRI.getRegClassIDOfValue( Val );
ArgRange->setRegClass(RegClassList[ rcid ] );
@@ -68,16 +80,24 @@ void LiveRangeInfo::constructLiveRanges()
}
}
+ // Now suggest hardware registers for these method args
+ MRI.suggestRegs4MethodArgs(Meth, *this);
+
+
+
+ // Now find speical LLVM instructions (CALL, RET) and LRs in machine
+ // instructions.
- // 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
+ // 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.
+
// get the iterator for machine instructions
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
MachineCodeForBasicBlock::const_iterator
@@ -87,12 +107,20 @@ void LiveRangeInfo::constructLiveRanges()
for( ; MInstIterator != MIVec.end(); MInstIterator++) {
const MachineInstr * MInst = *MInstIterator;
+
+ // Now if the machine instruction has special operands that must be
+ // set with a "suggested color", do it here.
+
+
+ if( MRI.handleSpecialMInstr(MInst, *this, RegClassList) )
+ continue;
+
// iterate over MI operands to find defs
- for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); OpI++) {
+ for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
- // delete later from here ************
+ // delete later from here ************
MachineOperand::MachineOperandType OpTyp =
OpI.getMachineOperand().getOperandType();
@@ -104,11 +132,21 @@ void LiveRangeInfo::constructLiveRanges()
// ************* to here
-
// create a new LR iff this operand is a def
if( OpI.isDef() ) {
const Value *const Def = *OpI;
+
+
+ // Only instruction values are accepted for live ranges here
+
+ if( Def->getValueType() != Value::InstructionVal ) {
+ cout << "\n**%%Error: Def is not an instruction val. Def=";
+ printValue( Def ); cout << endl;
+ continue;
+ }
+
+
LiveRange *DefRange = LiveRangeMap[Def];
// see LR already there (because of multiple defs)
@@ -130,7 +168,7 @@ void LiveRangeInfo::constructLiveRanges()
OpI.getMachineOperand().getOperandType();
bool isCC = ( OpTy == MachineOperand::MO_CCRegister);
- unsigned rcid = (TM.getRegInfo()).getRegClassIDOfValue(
+ unsigned rcid = MRI.getRegClassIDOfValue(
OpI.getMachineOperand().getVRegValue(), isCC );
@@ -163,6 +201,42 @@ void LiveRangeInfo::constructLiveRanges()
} // for all machine instructions in the BB
+
+ } // for all BBs in method
+
+ // go thru LLVM instructions in the basic block and suggest colors
+ // for their args. Also record all CALL
+ // instructions and Return instructions in the CallRetInstrList
+ // This is done because since there are no reverse pointers in machine
+ // instructions to find the llvm instruction, when we encounter a call
+ // or a return whose args must be specailly colored (e.g., %o's for args)
+ // We have to makes sure that all LRs of call/ret args are added before
+ // doing this. But return value of call will not have a LR.
+
+ BBI = Meth->begin(); // random iterator for BBs
+
+ for( ; BBI != Meth->end(); ++BBI) { // go thru BBs in random order
+
+ BasicBlock::const_iterator InstIt = (*BBI)->begin();
+
+ for( ; InstIt != (*BBI)->end() ; ++InstIt) {
+
+ const Instruction *const CallRetI = *InstIt;
+ unsigned OpCode = (CallRetI)->getOpcode();
+
+ if( (OpCode == Instruction::Call) ) {
+ CallRetInstrList.push_back(CallRetI );
+ MRI.suggestRegs4CallArgs( (CallInst *) CallRetI, *this, RegClassList );
+ }
+
+ else if (OpCode == Instruction::Ret ) {
+ CallRetInstrList.push_back( CallRetI );
+ MRI.suggestReg4RetValue( (ReturnInst *) CallRetI, *this);
+ }
+
+
+ } // for each llvm instr in BB
+
} // for all BBs in method
if( DEBUG_RA)
@@ -183,7 +257,8 @@ void LiveRangeInfo::coalesceLRs()
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 both LRs do not have suggested colors
+ merge2IGNodes(def, op) // i.e., merge 2 LRs
*/
@@ -253,8 +328,14 @@ void LiveRangeInfo::coalesceLRs()
if( CombinedDegree <= RCOfDef->getNumOfAvailRegs() ) {
- RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
- unionAndUpdateLRs(LROfDef, LROfUse);
+ // if both LRs do not have suggested colors
+ if( ! (LROfDef->hasSuggestedColor() &&
+ LROfUse->hasSuggestedColor() ) ) {
+
+ RCOfDef->mergeIGNodesOfLRs(LROfDef, LROfUse);
+ unionAndUpdateLRs(LROfDef, LROfUse);
+ }
+
} // if combined degree is less than # of regs
@@ -289,7 +370,7 @@ 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 ) {
+ if( (*HMI).first && (*HMI).second ) {
cout <<" "; printValue((*HMI).first); cout << "\t: ";
((*HMI).second)->printSet(); cout << endl;
}
diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp
index 1cb1809..832e482 100644
--- a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp
+++ b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp
@@ -17,8 +17,6 @@ PhyRegAlloc::PhyRegAlloc(const Method *const M,
Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList),
MRI( tm.getRegInfo() ),
NumOfRegClasses(MRI.getNumOfRegClasses()),
- CallInstrList(),
- RetInstrList(),
AddedInstrMap()
{
@@ -47,10 +45,18 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
for( ; HMI != HMIEnd ; ++HMI ) {
+
+ if( (*HMI).first ) {
- LiveRange *L = (*HMI).second; // get the LiveRange
+ LiveRange *L = (*HMI).second; // get the LiveRange
- if( (*HMI).first ) {
+ if( !L) {
+ if( DEBUG_RA) {
+ cout << "\n*?!?Warning: Null liver range found for: ";
+ printValue( (*HMI).first) ; cout << endl;
+ }
+ continue;
+ }
// if the Value * is not null, and LR
// is not yet written to the IGNodeList
if( !(L->getUserIGNode()) ) {
@@ -155,7 +161,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
// 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
@@ -178,6 +184,8 @@ void PhyRegAlloc::buildInterferenceGraphs()
} // for all machine instructions in BB
+#if 0
+
// go thru LLVM instructions in the basic block and record all CALL
// instructions and Return instructions in the CallInstrList
// This is done because since there are no reverse pointers in machine
@@ -194,6 +202,9 @@ void PhyRegAlloc::buildInterferenceGraphs()
else if( OpCode == Instruction::Ret )
RetInstrList.push_back( *InstIt );
}
+
+#endif
+
} // for all BBs in method
@@ -257,7 +268,38 @@ void PhyRegAlloc::updateMachineCode()
// iterate over all the machine instructions in BB
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
- MachineInstr *const MInst = *MInstIterator;
+ MachineInstr *MInst = *MInstIterator;
+
+
+ // If there are instructions before to be added, add them now
+ // ***TODO: Add InstrnsAfter as well
+ if( AddedInstrMap[ MInst ] ) {
+
+ vector<MachineInstr *> &IBef =
+ (AddedInstrMap[MInst])->InstrnsBefore;
+
+ if( ! IBef.empty() ) {
+
+ vector<MachineInstr *>::iterator AdIt;
+
+ for( AdIt = IBef.begin(); AdIt != IBef.end() ; ++AdIt ) {
+
+ cout << "*ADDED instr opcode: ";
+ cout << TargetInstrDescriptors[(*AdIt)->getOpCode()].opCodeString;
+ cout << endl;
+
+ MInstIterator = MIVec.insert( MInstIterator, *AdIt );
+ ++MInstIterator;
+ }
+
+ }
+
+ // restart from the topmost instruction added
+ //MInst = *MInstIterator;
+
+ }
+
+
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
@@ -289,8 +331,9 @@ void PhyRegAlloc::updateMachineCode()
cout << TargetInstrDescriptors[MInst->getOpCode()].opCodeString;
}
- Op.setRegForValue( -1 ); // mark register as invalid
+ Op.setRegForValue( 1000 ); // mark register as invalid
+#if 0
if( ((Val->getType())->isLabelType()) ||
(Val->getValueType() == Value::ConstantVal) )
; // do nothing
@@ -308,14 +351,16 @@ void PhyRegAlloc::updateMachineCode()
Op.setRegForValue( MRI.getReturnAddressReg() );
}
-
- else
+
+ if (Val->getValueType() == Value::InstructionVal)
{
cout << "!Warning: No LiveRange for: ";
printValue( Val); cout << " Type: " << Val->getValueType();
cout << " RegVal=" << Op.getAllocatedRegNum() << endl;
}
+#endif
+
continue;
}
@@ -376,8 +421,6 @@ void PhyRegAlloc::printMachineCode()
Op.getOperandType() == MachineOperand::MO_CCRegister ||
Op.getOperandType() == MachineOperand::MO_PCRelativeDisp ) {
-
-
const Value *const Val = Op.getVRegValue () ;
// ****this code is temporary till NULL Values are fixed
if( ! Val ) {
@@ -386,8 +429,7 @@ void PhyRegAlloc::printMachineCode()
}
// if a label or a constant
- if( (Val->getValueType() == Value::BasicBlockVal) ||
- (Val->getValueType() == Value::ConstantVal) ) {
+ if( (Val->getValueType() == Value::BasicBlockVal) ) {
cout << "\t"; printLabel( Op.getVRegValue () );
}
@@ -395,7 +437,10 @@ void PhyRegAlloc::printMachineCode()
// else it must be a register value
const int RegNum = Op.getAllocatedRegNum();
+ //if( RegNum != 1000)
+
cout << "\t" << "%" << MRI.getUnifiedRegName( RegNum );
+ // else cout << "\t<*NoReg*>";
}
@@ -418,6 +463,67 @@ void PhyRegAlloc::printMachineCode()
}
+//----------------------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+
+void PhyRegAlloc::colorCallRetArgs()
+{
+
+ CallRetInstrListType &CallRetInstList = LRI.getCallRetInstrList();
+ CallRetInstrListType::const_iterator It = CallRetInstList.begin();
+
+ for( ; It != CallRetInstList.end(); ++It ) {
+
+ const Instruction *const CallRetI = *It;
+ unsigned OpCode = (CallRetI)->getOpcode();
+
+ const MachineInstr *CRMI = *((CallRetI->getMachineInstrVec()).begin());
+
+
+ assert( (TM.getInstrInfo().isReturn(CRMI->getOpCode()) ||
+ TM.getInstrInfo().isCall(CRMI->getOpCode()) )
+ && "First Machine Instruction is not a Call/Retrunr" );
+
+ // get the added instructions for this Call/Ret instruciton
+ AddedInstrns *AI = AddedInstrMap[ CRMI ];
+ if ( !AI ) {
+ AI = new AddedInstrns();
+ AddedInstrMap[ CRMI ] = AI;
+ }
+
+ if( (OpCode == Instruction::Call) )
+ MRI.colorCallArgs( (CallInst *) CallRetI, LRI, AI );
+
+
+ else if (OpCode == Instruction::Ret )
+ MRI.colorRetValue( (ReturnInst *) CallRetI, LRI, AI );
+
+
+ else assert( 0 && "Non Call/Ret instrn in CallRetInstrList\n" );
+
+ }
+
+}
+
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+void PhyRegAlloc::colorIncomingArgs()
+{
+ const BasicBlock *const FirstBB = Meth->front();
+ const MachineInstr *FirstMI = *((FirstBB->getMachineInstrVec()).begin());
+ assert( FirstMI && "No machine instruction in entry BB");
+
+ AddedInstrns *AI = AddedInstrMap[ FirstMI ];
+ if ( !AI ) {
+ AI = new AddedInstrns();
+ AddedInstrMap[ FirstMI ] = AI;
+ }
+
+ MRI.colorMethodArgs(Meth, LRI, AI );
+}
+
//----------------------------------------------------------------------------
// Used to generate a label for a basic block
@@ -437,56 +543,56 @@ void PhyRegAlloc::printLabel(const Value *const Val)
void PhyRegAlloc::allocateRegisters()
{
+
+ // make sure that we put all register classes into the RegClassList
+ // before we call constructLiveRanges (now done in the constructor of
+ // PhyRegAlloc class).
+
constructLiveRanges(); // create LR info
- if( DEBUG_RA)
+ if( DEBUG_RA )
LRI.printLiveRanges();
-
+
createIGNodeListsAndIGs(); // create IGNode list and IGs
buildInterferenceGraphs(); // build IGs in all reg classes
-
- if( DEBUG_RA) {
+
+ 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();
}
+ // color all register classes
+ for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
+ RegClassList[ rc ]->colorAllRegs();
- // the following three calls must be made in that order since
- // coloring or definitions must come before their uses
- MRI.colorArgs(Meth, LRI); // color method args
- // color call args of call instrns
- MRI.colorCallArgs(CallInstrList, LRI, AddedInstrMap);
- // color return args
- MRI.colorRetArg(CallInstrList, LRI, AddedInstrMap);
-
+ // color incoming args and call args
+ colorIncomingArgs();
+ colorCallRetArgs();
- // color all register classes
- for( unsigned int rc=0; rc < NumOfRegClasses ; rc++)
- RegClassList[ rc ]->colorAllRegs();
updateMachineCode();
if (DEBUG_RA) {
- PrintMachineInstructions(Meth);
+ // PrintMachineInstructions(Meth);
printMachineCode(); // only for DEBUGGING
}
}