mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-04-16 05:41:45 +00:00
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:
parent
ffa6f9ca06
commit
958faf3f5a
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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 ;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user