forked from OSchip/llvm-project
Removed class RegStackOffsets and used class MachineCodeForMethod
directly to manage stack frame. llvm-svn: 1186
This commit is contained in:
parent
c53037205b
commit
d9f8598104
|
@ -1,7 +1,23 @@
|
|||
#include "llvm/CodeGen/PhyRegAlloc.h"
|
||||
// $Id$
|
||||
//***************************************************************************
|
||||
// File:
|
||||
// PhyRegAlloc.cpp
|
||||
//
|
||||
// Purpose:
|
||||
// Register allocation for LLVM.
|
||||
//
|
||||
// History:
|
||||
// 9/10/01 - Ruchira Sasanka - created.
|
||||
//**************************************************************************/
|
||||
|
||||
//***TODO: There are several places we add instructions. Validate the order
|
||||
// of adding these instructions.
|
||||
#include "llvm/CodeGen/PhyRegAlloc.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/MachineFrameInfo.h"
|
||||
|
||||
|
||||
// ***TODO: There are several places we add instructions. Validate the order
|
||||
// of adding these instructions.
|
||||
|
||||
|
||||
|
||||
|
@ -15,15 +31,18 @@ cl::Enum<RegAllocDebugLevel_t> DEBUG_RA("dregalloc", cl::NoFlags,
|
|||
//----------------------------------------------------------------------------
|
||||
// Constructor: Init local composite objects and create register classes.
|
||||
//----------------------------------------------------------------------------
|
||||
PhyRegAlloc::PhyRegAlloc(const Method *const M,
|
||||
PhyRegAlloc::PhyRegAlloc(Method *M,
|
||||
const TargetMachine& tm,
|
||||
MethodLiveVarInfo *const Lvi)
|
||||
: RegClassList(),
|
||||
Meth(M), TM(tm), LVI(Lvi), LRI(M, tm, RegClassList),
|
||||
TM(tm),
|
||||
Meth(M),
|
||||
mcInfo(MachineCodeForMethod::get(M)),
|
||||
LVI(Lvi), LRI(M, tm, RegClassList),
|
||||
MRI( tm.getRegInfo() ),
|
||||
NumOfRegClasses(MRI.getNumOfRegClasses()),
|
||||
AddedInstrMap(), StackOffsets() /*, PhiInstList()*/
|
||||
|
||||
AddedInstrMap()
|
||||
/*, PhiInstList()*/
|
||||
{
|
||||
// **TODO: use an actual reserved color list
|
||||
ReservedColorListType *RCL = new ReservedColorListType();
|
||||
|
@ -31,10 +50,6 @@ PhyRegAlloc::PhyRegAlloc(const Method *const M,
|
|||
// 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) );
|
||||
|
||||
// **TODO: Init to the correct value. Also reset this to the correct
|
||||
// value at the start of each instruction. Need a way to track max used
|
||||
int curOffset4TmpSpills =0 ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -318,125 +333,6 @@ void PhyRegAlloc::addInterferencesForArgs()
|
|||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This method inserts caller saving/restoring instructons before/after
|
||||
// a call machine instruction.
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void PhyRegAlloc::insertCallerSavingCode(const MachineInstr *MInst,
|
||||
const BasicBlock *BB )
|
||||
{
|
||||
// assert( (TM.getInstrInfo()).isCall( MInst->getOpCode() ) );
|
||||
|
||||
StackOffsets.resetTmpPos();
|
||||
|
||||
hash_set<unsigned> PushedRegSet;
|
||||
|
||||
// Now find the LR of the return value of the call
|
||||
// The last *implicit operand* is the return value of a call
|
||||
// Insert it to to he PushedRegSet since we must not save that register
|
||||
// and restore it after the 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 we must not save/restore it.
|
||||
|
||||
|
||||
const Value *RetVal = MRI.getCallInstRetVal( MInst );
|
||||
|
||||
if( RetVal ) {
|
||||
|
||||
LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
|
||||
assert( RetValLR && "No LR for RetValue of call");
|
||||
|
||||
PushedRegSet.insert(
|
||||
MRI.getUnifiedRegNum((RetValLR->getRegClass())->getID(),
|
||||
RetValLR->getColor() ) );
|
||||
}
|
||||
|
||||
|
||||
const LiveVarSet *LVSetAft = LVI->getLiveVarSetAfterMInst(MInst, BB);
|
||||
|
||||
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 );
|
||||
|
||||
// LR can be null if it is a const since a const
|
||||
// doesn't have a dominating def - see Assumptions above
|
||||
if( LR ) {
|
||||
|
||||
if( LR->hasColor() ) {
|
||||
|
||||
unsigned RCID = (LR->getRegClass())->getID();
|
||||
unsigned Color = LR->getColor();
|
||||
|
||||
if ( MRI.isRegVolatile(RCID, Color) ) {
|
||||
|
||||
// if the value is in both LV sets (i.e., live before and after
|
||||
// the call machine instruction)
|
||||
|
||||
unsigned Reg = MRI.getUnifiedRegNum(RCID, Color);
|
||||
|
||||
if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
|
||||
|
||||
// if we haven't already pushed that register
|
||||
|
||||
unsigned RegType = MRI.getRegType( LR );
|
||||
|
||||
// Now get two instructions - to push on stack and pop from stack
|
||||
// and add them to InstrnsBefore and InstrnsAfter of the
|
||||
// call instruction
|
||||
|
||||
int StackOff = StackOffsets.getNewTmpPosOffFromSP();
|
||||
|
||||
/**** TODO
|
||||
|
||||
if( RegType == SaveViaIntReg) {
|
||||
|
||||
int FreeIntReg = getFreedIntReg(......)
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
MachineInstr *AdIBef =
|
||||
MRI.cpReg2MemMI(Reg, MRI.getStackPointer(), StackOff, RegType );
|
||||
|
||||
MachineInstr *AdIAft =
|
||||
MRI.cpMem2RegMI(MRI.getStackPointer(), StackOff, Reg, RegType );
|
||||
|
||||
((AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
|
||||
((AddedInstrMap[MInst])->InstrnsAfter).push_back(AdIAft);
|
||||
|
||||
PushedRegSet.insert( Reg );
|
||||
|
||||
if(DEBUG_RA) {
|
||||
cerr << "\nFor callee save call inst:" << *MInst;
|
||||
cerr << "\n -inserted caller saving instrs:\n\t ";
|
||||
cerr << *AdIBef << "\n\t" << *AdIAft ;
|
||||
}
|
||||
} // if not already pushed
|
||||
|
||||
} // if LR has a volatile color
|
||||
|
||||
} // if LR has color
|
||||
|
||||
} // if there is a LR for Var
|
||||
|
||||
} // for each value in the LV set after instruction
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This method is called after register allocation is complete to set the
|
||||
// allocated reisters in the machine code. This code will add register numbers
|
||||
|
@ -490,8 +386,8 @@ void PhyRegAlloc::updateMachineCode()
|
|||
|
||||
// reset the stack offset for temporary variables since we may
|
||||
// need that to spill
|
||||
StackOffsets.resetTmpPos();
|
||||
|
||||
mcInfo.popAllTempValues(TM);
|
||||
|
||||
//for(MachineInstr::val_op_const_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||
|
||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||
|
@ -607,82 +503,6 @@ void PhyRegAlloc::updateMachineCode()
|
|||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// This method inserts spill code for AN operand whose LR was spilled.
|
||||
// This method may be called several times for a single machine instruction
|
||||
// if it contains many spilled operands. Each time it is called, it finds
|
||||
// a register which is not live at that instruction and also which is not
|
||||
// used by other spilled operands of the same instruction. Then it uses
|
||||
// this register temporarily to accomodate the spilled value.
|
||||
//----------------------------------------------------------------------------
|
||||
void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
||||
const MachineInstr *MInst,
|
||||
const BasisBlock *BB,
|
||||
const unsigned OpNum) {
|
||||
|
||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||
bool isDef = MInst->operandIsDefined(OpNum);
|
||||
unsigned RegType = MRI.getRegType( LR );
|
||||
int SpillOff = LR->getSpillOffFromFP();
|
||||
RegClass *RC = LR->getRegClass();
|
||||
const LiveVarSet *LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB);
|
||||
int TmpOff = StackOffsets.getNewTmpPosOffFromSP();
|
||||
MachineInstr *MIBef, *AdIMid, *MIAft;
|
||||
int TmpReg;
|
||||
|
||||
TmpReg = getUsableRegAtMI(RC, RegType, MInst,LVSetBef, MIBef, MIAft);
|
||||
TmpReg = getUnifiedRegNum( RC->getID(), TmpReg );
|
||||
|
||||
|
||||
if( !isDef ) {
|
||||
|
||||
// for a USE, we have to load the value of LR from stack to a TmpReg
|
||||
// and use the TmpReg as one operand of instruction
|
||||
|
||||
// actual loading instruction
|
||||
AdIMid = MRI.cpMem2RegMI(MRI.getFramePointer(), SpillOff, TmpReg, RegType);
|
||||
|
||||
if( MIBef )
|
||||
((AddedInstrMap[MInst])->InstrnsBefore).push_back(MIBef);
|
||||
|
||||
((AddedInstrMap[MInst])->InstrnsBefore).push_back(AdiMid);
|
||||
|
||||
if( MIAft)
|
||||
((AddedInstrMap[MInst])->InstrnsAfter).push_front(MIAft);
|
||||
|
||||
|
||||
}
|
||||
else { // if this is a Def
|
||||
|
||||
// for a DEF, we have to store the value produced by this instruction
|
||||
// on the stack position allocated for this LR
|
||||
|
||||
// actual storing instruction
|
||||
AdIMid = MRI.cpReg2MemMI(TmpReg, MRI.getFramePointer(), SpillOff, RegType);
|
||||
|
||||
if( MIBef )
|
||||
((AddedInstrMap[MInst])->InstrnsBefore).push_back(MIBef);
|
||||
|
||||
((AddedInstrMap[MInst])->InstrnsBefore).push_back(AdiMid);
|
||||
|
||||
if( MIAft)
|
||||
((AddedInstrMap[MInst])->InstrnsAfter).push_front(MIAft);
|
||||
|
||||
} // if !DEF
|
||||
|
||||
|
||||
Op.setRegForValue( TmpReg ); // set the opearnd
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// We can use the following method to get a temporary register to be used
|
||||
// BEFORE any given machine instruction. If there is a register available,
|
||||
|
@ -710,8 +530,9 @@ int PhyRegAlloc::getUsableRegAtMI(RegClass *RC,
|
|||
// we couldn't find an unused register. Generate code to free up a reg by
|
||||
// saving it on stack and restoring after the instruction
|
||||
|
||||
int TmpOff = StackOffsets.getNewTmpPosOffFromFP();
|
||||
|
||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
||||
int TmpOff = mcInfo.pushTempValue(TM, /*size*/ 8);
|
||||
|
||||
Reg = getRegNotUsedByThisInst(RC, MInst);
|
||||
MIBef = MRI.cpReg2MemMI(Reg, MRI.getFramePointer(), TmpOff, RegType );
|
||||
MIAft = MRI.cpMem2RegMI(MRI.getFramePointer(), TmpOff, Reg, RegType );
|
||||
|
@ -1011,8 +832,8 @@ void PhyRegAlloc::colorCallRetArgs()
|
|||
|
||||
// Tmp stack poistions are needed by some calls that have spilled args
|
||||
// So reset it before we call each such method
|
||||
StackOffsets.resetTmpPos();
|
||||
|
||||
mcInfo.popAllTempValues(TM);
|
||||
|
||||
if( (TM.getInstrInfo()).isCall( OpCode ) )
|
||||
MRI.colorCallArgs( CRMI, LRI, AI, *this );
|
||||
|
||||
|
@ -1112,17 +933,13 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs()
|
|||
LiveRangeMapType::const_iterator HMIEnd = (LRI.getLiveRangeMap())->end();
|
||||
|
||||
for( ; HMI != HMIEnd ; ++HMI ) {
|
||||
|
||||
if( (*HMI).first ) {
|
||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||
if(L)
|
||||
if( ! L->hasColor() )
|
||||
L->setSpillOffFromFP( StackOffsets.getNewSpillOffFromFP() );
|
||||
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM,L->getType()));
|
||||
}
|
||||
} // for all LR's in hash map
|
||||
|
||||
StackOffsets.setEndOfSpillRegion();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1195,7 +1012,7 @@ void PhyRegAlloc::allocateRegisters()
|
|||
|
||||
updateMachineCode();
|
||||
if (DEBUG_RA) {
|
||||
Meth->getMachineCode().dump();
|
||||
MachineCodeForMethod::get(Meth).dump();
|
||||
printMachineCode(); // only for DEBUGGING
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,73 +62,6 @@ typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
|
|||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Class RegStackOffsets:
|
||||
// This class is responsible for managing stack frame of the method for
|
||||
// register allocation.
|
||||
//
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
class RegStackOffsets {
|
||||
|
||||
private:
|
||||
int curSpilledVarOff; // cur pos of spilled LRs
|
||||
int curNewTmpPosOffset; // cur pos of tmp values on stack
|
||||
bool isTmpRegionUsable; // can we call getNewTmpPosOffFromFP
|
||||
|
||||
const int SizeOfStackItem; // size of an item on stack
|
||||
const int StackSpillStartFromFP; // start position of spill region
|
||||
int StartOfTmpRegion; // start of the tmp var region
|
||||
|
||||
public:
|
||||
|
||||
// constructor
|
||||
|
||||
RegStackOffsets(int SEnSize=8, int StartSpill=176 ) :
|
||||
SizeOfStackItem(SEnSize), StackSpillStartFromFP(StartSpill) {
|
||||
|
||||
curSpilledVarOff = StartSpill;
|
||||
isTmpRegionUsable = false;
|
||||
};
|
||||
|
||||
|
||||
int getNewSpillOffFromFP() {
|
||||
int tmp = curSpilledVarOff;
|
||||
curSpilledVarOff += SizeOfStackItem;
|
||||
return tmp; // **TODO: Is sending un-incremented value correct?
|
||||
};
|
||||
|
||||
|
||||
// The following method must be called only after allocating space
|
||||
// for spilled LRs and calling setEndOfSpillRegion()
|
||||
int getNewTmpPosOffFromFP() {
|
||||
assert( isTmpRegionUsable && "Spill region still open");
|
||||
int tmp = curNewTmpPosOffset;
|
||||
curNewTmpPosOffset += SizeOfStackItem;
|
||||
return tmp; //**TODO: Is sending un-incremented val correct?
|
||||
};
|
||||
|
||||
|
||||
// This method is called when we have allocated space for all spilled
|
||||
// LRs. The tmp region can be used only after a call to this method.
|
||||
|
||||
void setEndOfSpillRegion() {
|
||||
assert(( ! isTmpRegionUsable) && "setEndOfSpillRegion called again");
|
||||
isTmpRegionUsable = true;
|
||||
StartOfTmpRegion = curSpilledVarOff;
|
||||
}
|
||||
|
||||
|
||||
// called when temporary values allocated on stack are no longer needed
|
||||
void resetTmpPos() {
|
||||
curNewTmpPosOffset = StartOfTmpRegion;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// class PhyRegAlloc:
|
||||
// Main class the register allocator. Call allocateRegisters() to allocate
|
||||
|
@ -136,12 +69,13 @@ class RegStackOffsets {
|
|||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class PhyRegAlloc
|
||||
class PhyRegAlloc: public NonCopyable
|
||||
{
|
||||
|
||||
vector<RegClass *> RegClassList ; // vector of register classes
|
||||
const Method *const Meth; // name of the method we work on
|
||||
const TargetMachine &TM; // target machine
|
||||
const Method* Meth; // name of the method we work on
|
||||
MachineCodeForMethod& mcInfo; // descriptor for method's native code
|
||||
MethodLiveVarInfo *const LVI; // LV information for this method
|
||||
// (already computed for BBs)
|
||||
LiveRangeInfo LRI; // LR info (will be computed)
|
||||
|
@ -154,8 +88,6 @@ class PhyRegAlloc
|
|||
|
||||
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
||||
|
||||
RegStackOffsets StackOffsets;
|
||||
|
||||
//vector<const MachineInstr *> PhiInstList; // a list of all phi instrs
|
||||
|
||||
//------- private methods ---------------------------------------------------
|
||||
|
@ -178,10 +110,6 @@ class PhyRegAlloc
|
|||
void markUnusableSugColors();
|
||||
void allocateStackSpace4SpilledLRs();
|
||||
|
||||
RegStackOffsets & getStackOffsets() {
|
||||
return StackOffsets;
|
||||
}
|
||||
|
||||
|
||||
inline void constructLiveRanges()
|
||||
{ LRI.constructLiveRanges(); }
|
||||
|
@ -212,7 +140,7 @@ class PhyRegAlloc
|
|||
|
||||
public:
|
||||
|
||||
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
||||
PhyRegAlloc(Method *const M, const TargetMachine& TM,
|
||||
MethodLiveVarInfo *const Lvi);
|
||||
|
||||
void allocateRegisters(); // main method called for allocatin
|
||||
|
|
Loading…
Reference in New Issue