Corrected call interference bug

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@916 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Ruchira Sasanka 2001-10-19 17:21:03 +00:00
parent ffa6f9ca06
commit 958faf3f5a
4 changed files with 174 additions and 28 deletions

View File

@ -36,6 +36,11 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
if(L2->hasSuggestedColor())
L1->setSuggestedColor( L2->getSuggestedColor() );
if( L2->isCallInterference() )
L1->setCallInterference();
delete ( L2 ); // delete L2 as it is no longer needed
}

View File

@ -125,25 +125,84 @@ void PhyRegAlloc::addInterference(const Value *const Def,
}
//the live range of this var interferes with this call
if( isCallInst ) {
LROfVar->addCallInterference( (const Instruction *const) Def );
if( DEBUG_RA) {
cout << "\n ++Added Call Interf to set:";
LROfVar->printSet();
}
}
}
else if(DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cout << " warning: no live range for " ;
printValue( *LIt); cout << endl; }
}
}
}
}
//----------------------------------------------------------------------------
// For a call instruction, this method sets the CallInterference flag in
// the LR of each variable live int the Live Variable Set live after the
// call instruction (except the return value of the call instruction - since
// the return value does not interfere with that call itself).
//----------------------------------------------------------------------------
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
const LiveVarSet *const LVSetAft )
{
// Now find the LR of the return value of the call
// The last *implicit operand* is the return value of a call
// We do this because, we look at the LV set *after* the instruction
// to determine, which LRs must be saved across calls. The return value
// of the call is live in this set - but it does not interfere with call
// (i.e., we can allocate a volatile register to the return value)
LiveRange *RetValLR = NULL;
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
if( NumOfImpRefs > 0 ) {
if( MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1);
RetValLR = LRI.getLiveRangeForValue( RetVal );
assert( RetValLR && "No LR for RetValue of call");
}
}
if( DEBUG_RA)
cout << "\n For call inst: " << *MInst;
LiveVarSet::const_iterator LIt = LVSetAft->begin();
// for each live var in live variable set after machine inst
for( ; LIt != LVSetAft->end(); ++LIt) {
// get the live range corresponding to live var
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
if( LR && DEBUG_RA) {
cout << "\n\tLR Aft Call: ";
LR->printSet();
}
// LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
if( LR && (LR != RetValLR) ) {
LR->setCallInterference();
if( DEBUG_RA) {
cout << "\n ++Added call interf for LR: " ;
LR->printSet();
}
}
}
}
//----------------------------------------------------------------------------
// This method will walk thru code and create interferences in the IG of
// each RegClass.
@ -174,7 +233,16 @@ void PhyRegAlloc::buildInterferenceGraphs()
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
// if( isCallInst) cout << "\n%%% Found call Inst:\n";
if( isCallInst ) {
//cout << "\nFor call inst: " << *MInst;
// set the isCallInterference flag of each live range wich extends
// accross this call instruction. This information is used by graph
// coloring algo to avoid allocating volatile colors to live ranges
// that span across calls (since they have to be saved/restored)
setCallInterferences( MInst, LVSetAI);
}
// iterate over MI operands to find defs
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
@ -275,7 +343,7 @@ void PhyRegAlloc::addInterferencesForArgs()
void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
const BasicBlock *BB )
{
assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
// assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
int StackOff = -8; // ****TODO : Change
hash_set<unsigned> PushedRegSet;
@ -315,7 +383,7 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
// get the live range corresponding to live var
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
// LROfVar can be null if it is a const since a const
// LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
if( LR ) {
@ -354,7 +422,7 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
StackOff -= 8; // ****TODO: Correct ??????
if(DEBUG_RA) {
cout << "For callee save call inst:" << *MInst << endl;
cerr << "\nFor callee save call inst:" << *MInst;
cerr << "\n -inserted caller saving instrs:\n\t ";
cerr << *AdIBef << "\n\t" << *AdIAft ;
}

View File

@ -36,6 +36,11 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
if(L2->hasSuggestedColor())
L1->setSuggestedColor( L2->getSuggestedColor() );
if( L2->isCallInterference() )
L1->setCallInterference();
delete ( L2 ); // delete L2 as it is no longer needed
}

View File

@ -125,25 +125,84 @@ void PhyRegAlloc::addInterference(const Value *const Def,
}
//the live range of this var interferes with this call
if( isCallInst ) {
LROfVar->addCallInterference( (const Instruction *const) Def );
if( DEBUG_RA) {
cout << "\n ++Added Call Interf to set:";
LROfVar->printSet();
}
}
}
else if(DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cout << " warning: no live range for " ;
printValue( *LIt); cout << endl; }
}
}
}
}
//----------------------------------------------------------------------------
// For a call instruction, this method sets the CallInterference flag in
// the LR of each variable live int the Live Variable Set live after the
// call instruction (except the return value of the call instruction - since
// the return value does not interfere with that call itself).
//----------------------------------------------------------------------------
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
const LiveVarSet *const LVSetAft )
{
// Now find the LR of the return value of the call
// The last *implicit operand* is the return value of a call
// We do this because, we look at the LV set *after* the instruction
// to determine, which LRs must be saved across calls. The return value
// of the call is live in this set - but it does not interfere with call
// (i.e., we can allocate a volatile register to the return value)
LiveRange *RetValLR = NULL;
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
if( NumOfImpRefs > 0 ) {
if( MInst->implicitRefIsDefined(NumOfImpRefs-1) ) {
const Value *RetVal = MInst->getImplicitRef(NumOfImpRefs-1);
RetValLR = LRI.getLiveRangeForValue( RetVal );
assert( RetValLR && "No LR for RetValue of call");
}
}
if( DEBUG_RA)
cout << "\n For call inst: " << *MInst;
LiveVarSet::const_iterator LIt = LVSetAft->begin();
// for each live var in live variable set after machine inst
for( ; LIt != LVSetAft->end(); ++LIt) {
// get the live range corresponding to live var
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
if( LR && DEBUG_RA) {
cout << "\n\tLR Aft Call: ";
LR->printSet();
}
// LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
if( LR && (LR != RetValLR) ) {
LR->setCallInterference();
if( DEBUG_RA) {
cout << "\n ++Added call interf for LR: " ;
LR->printSet();
}
}
}
}
//----------------------------------------------------------------------------
// This method will walk thru code and create interferences in the IG of
// each RegClass.
@ -174,7 +233,16 @@ void PhyRegAlloc::buildInterferenceGraphs()
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
// if( isCallInst) cout << "\n%%% Found call Inst:\n";
if( isCallInst ) {
//cout << "\nFor call inst: " << *MInst;
// set the isCallInterference flag of each live range wich extends
// accross this call instruction. This information is used by graph
// coloring algo to avoid allocating volatile colors to live ranges
// that span across calls (since they have to be saved/restored)
setCallInterferences( MInst, LVSetAI);
}
// iterate over MI operands to find defs
for( MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done(); ++OpI) {
@ -275,7 +343,7 @@ void PhyRegAlloc::addInterferencesForArgs()
void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
const BasicBlock *BB )
{
assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
// assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
int StackOff = -8; // ****TODO : Change
hash_set<unsigned> PushedRegSet;
@ -315,7 +383,7 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
// get the live range corresponding to live var
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
// LROfVar can be null if it is a const since a const
// LR can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
if( LR ) {
@ -354,7 +422,7 @@ void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
StackOff -= 8; // ****TODO: Correct ??????
if(DEBUG_RA) {
cout << "For callee save call inst:" << *MInst << endl;
cerr << "\nFor callee save call inst:" << *MInst;
cerr << "\n -inserted caller saving instrs:\n\t ";
cerr << *AdIBef << "\n\t" << *AdIAft ;
}