diff --git a/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp b/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp index 3b61e1e6b78..633b621d805 100644 --- a/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp +++ b/lib/CodeGen/RegAlloc/PhyRegAlloc.cpp @@ -22,7 +22,7 @@ PhyRegAlloc::PhyRegAlloc(const Method *const M, Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList), MRI( tm.getRegInfo() ), NumOfRegClasses(MRI.getNumOfRegClasses()), - AddedInstrMap(), StackOffsets() + AddedInstrMap(), StackOffsets(), PhiInstList() { // **TODO: use an actual reserved color list @@ -227,7 +227,7 @@ void PhyRegAlloc::buildInterferenceGraphs() // iterate over all the machine instructions in BB for( ; MInstIterator != MIVec.end(); ++MInstIterator) { - const MachineInstr *const MInst = *MInstIterator; + const MachineInstr * MInst = *MInstIterator; // get the LV set after the instruction const LiveVarSet *const LVSetAI = @@ -268,6 +268,12 @@ void PhyRegAlloc::buildInterferenceGraphs() addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst ); } + + // record phi instrns in PhiInstList + if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) ) + PhiInstList.push_back( MInst ); + + } // for all machine instructions in BB } // for all BBs in method @@ -1115,6 +1121,53 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() +void PhyRegAlloc::insertPhiEleminateInstrns() { + + vector< const MachineInstr *>:: const_iterator It = PhiInstList.begin(); + + for( ; It != PhiInstList.end(); ++It ) { + + const MachineInstr *PhiMI = *It; + + Value *Def = (PhiMI->getOperand(0)).getVRegValue(); + const LiveRange *LROfDef = LRI.getLiveRangeForValue( Def ); + + assert(LROfDef && "NO LR for a def of phi"); + + for(unsigned OpNum=1; OpNum < PhiMI->getNumOperands(); ++OpNum) { + + if( OpNum % 2) { // i.e., the + + Value *Use = (PhiMI->getOperand(OpNum)).getVRegValue(); + + const LiveRange *LROfUse = LRI.getLiveRangeForValue( Use ); + + if( LROfUse != LROfDef) { + + // the result of the phi received a live range different to + // that of this use, so copy it + + const BasicBlock *BB = + (BasicBlock *) (PhiMI->getOperand(OpNum+1)).getVRegValue(); + + MachineCodeForBasicBlock& MIVec = (BB)->getMachineInstrVec(); + + MachineInstr *AdI = MRI.cpValue2Value(Use, Def); + + MIVec.push_back( AdI ); + + cerr << "\n%%% Added a phi elimination instr: " << *AdI; + + } // if LRs are different + + } // if operand is an incoming Value (i.e., not a BB) + + } // for all phi operands + + } // for all phi instrns in PhiInstMap + +} + //---------------------------------------------------------------------------- @@ -1150,6 +1203,10 @@ void PhyRegAlloc::allocateRegisters() LRI.coalesceLRs(); // coalesce all live ranges + // coalscing could not get rid of all phi's, add phi elimination + // instructions + // insertPhiEleminateInstrns(); + if( DEBUG_RA) { // print all LRs in all reg classes for( unsigned int rc=0; rc < NumOfRegClasses ; rc++) diff --git a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp index 3b61e1e6b78..633b621d805 100644 --- a/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp +++ b/lib/Target/SparcV9/RegAlloc/PhyRegAlloc.cpp @@ -22,7 +22,7 @@ PhyRegAlloc::PhyRegAlloc(const Method *const M, Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList), MRI( tm.getRegInfo() ), NumOfRegClasses(MRI.getNumOfRegClasses()), - AddedInstrMap(), StackOffsets() + AddedInstrMap(), StackOffsets(), PhiInstList() { // **TODO: use an actual reserved color list @@ -227,7 +227,7 @@ void PhyRegAlloc::buildInterferenceGraphs() // iterate over all the machine instructions in BB for( ; MInstIterator != MIVec.end(); ++MInstIterator) { - const MachineInstr *const MInst = *MInstIterator; + const MachineInstr * MInst = *MInstIterator; // get the LV set after the instruction const LiveVarSet *const LVSetAI = @@ -268,6 +268,12 @@ void PhyRegAlloc::buildInterferenceGraphs() addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst ); } + + // record phi instrns in PhiInstList + if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) ) + PhiInstList.push_back( MInst ); + + } // for all machine instructions in BB } // for all BBs in method @@ -1115,6 +1121,53 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() +void PhyRegAlloc::insertPhiEleminateInstrns() { + + vector< const MachineInstr *>:: const_iterator It = PhiInstList.begin(); + + for( ; It != PhiInstList.end(); ++It ) { + + const MachineInstr *PhiMI = *It; + + Value *Def = (PhiMI->getOperand(0)).getVRegValue(); + const LiveRange *LROfDef = LRI.getLiveRangeForValue( Def ); + + assert(LROfDef && "NO LR for a def of phi"); + + for(unsigned OpNum=1; OpNum < PhiMI->getNumOperands(); ++OpNum) { + + if( OpNum % 2) { // i.e., the + + Value *Use = (PhiMI->getOperand(OpNum)).getVRegValue(); + + const LiveRange *LROfUse = LRI.getLiveRangeForValue( Use ); + + if( LROfUse != LROfDef) { + + // the result of the phi received a live range different to + // that of this use, so copy it + + const BasicBlock *BB = + (BasicBlock *) (PhiMI->getOperand(OpNum+1)).getVRegValue(); + + MachineCodeForBasicBlock& MIVec = (BB)->getMachineInstrVec(); + + MachineInstr *AdI = MRI.cpValue2Value(Use, Def); + + MIVec.push_back( AdI ); + + cerr << "\n%%% Added a phi elimination instr: " << *AdI; + + } // if LRs are different + + } // if operand is an incoming Value (i.e., not a BB) + + } // for all phi operands + + } // for all phi instrns in PhiInstMap + +} + //---------------------------------------------------------------------------- @@ -1150,6 +1203,10 @@ void PhyRegAlloc::allocateRegisters() LRI.coalesceLRs(); // coalesce all live ranges + // coalscing could not get rid of all phi's, add phi elimination + // instructions + // insertPhiEleminateInstrns(); + if( DEBUG_RA) { // print all LRs in all reg classes for( unsigned int rc=0; rc < NumOfRegClasses ; rc++) diff --git a/lib/Target/SparcV9/SparcV9Internals.h b/lib/Target/SparcV9/SparcV9Internals.h index 653a2018a77..72b234f72cb 100644 --- a/lib/Target/SparcV9/SparcV9Internals.h +++ b/lib/Target/SparcV9/SparcV9Internals.h @@ -401,6 +401,9 @@ class UltraSparcRegInfo : public MachineRegInfo MachineInstr * cpMem2RegMI(const unsigned SrcPtrReg, const int Offset, const unsigned DestReg, const int RegType) const; + MachineInstr* cpValue2Value(Value *Src, Value *Dest) const; + + inline bool isRegVolatile(const int RegClassID, const int Reg) const { return (MachineRegClassArr[RegClassID])->isRegVolatile(Reg); } diff --git a/lib/Target/SparcV9/SparcV9RegInfo.cpp b/lib/Target/SparcV9/SparcV9RegInfo.cpp index 11180f5995b..a34a5305ae7 100644 --- a/lib/Target/SparcV9/SparcV9RegInfo.cpp +++ b/lib/Target/SparcV9/SparcV9RegInfo.cpp @@ -979,7 +979,19 @@ MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg, } +MachineInstr* UltraSparcRegInfo::cpValue2Value(Value *Src, Value *Dest) const { + MachineInstr * MI = NULL; + + MI = new MachineInstr(ADD, 3); + MI->SetMachineOperand(0, MachineOperand:: MO_VirtualRegister, Src, false); + MI->SetMachineOperand(1, SparcIntRegOrder::g0, false); + MI->SetMachineOperand(2, MachineOperand:: MO_VirtualRegister, Dest, true); + + + return MI; + +}