mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-05-18 06:38:41 +00:00
Added support for spilling
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@992 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
78d63ee313
commit
20c82b12c9
@ -100,6 +100,9 @@ class RegClass
|
|||||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||||
|
|
||||||
|
|
||||||
|
inline bool * getIsColorUsedArr() { return IsColorUsedArr; }
|
||||||
|
|
||||||
|
|
||||||
inline void printIGNodeList() const {
|
inline void printIGNodeList() const {
|
||||||
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||||
IG.printIGNodeList();
|
IG.printIGNodeList();
|
||||||
|
@ -55,6 +55,11 @@ class LiveRange : public ValueSet
|
|||||||
|
|
||||||
bool CanUseSuggestedCol;
|
bool CanUseSuggestedCol;
|
||||||
|
|
||||||
|
// if this LR is spilled, its stack offset from *FP*. The spilled offsets
|
||||||
|
// must always be relative to the FP.
|
||||||
|
int SpilledStackOffsetFromFP;
|
||||||
|
bool HasSpillOffset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +93,33 @@ class LiveRange : public ValueSet
|
|||||||
|
|
||||||
inline void markForSpill() { mustSpill = true; }
|
inline void markForSpill() { mustSpill = true; }
|
||||||
|
|
||||||
|
inline bool isMarkedForSpill() { return mustSpill; }
|
||||||
|
|
||||||
|
inline void setSpillOffFromFP(int StackOffset) {
|
||||||
|
assert( mustSpill && "This LR is not spilled");
|
||||||
|
SpilledStackOffsetFromFP = StackOffset;
|
||||||
|
HasSpillOffset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void modifySpillOffFromFP(int StackOffset) {
|
||||||
|
assert( mustSpill && "This LR is not spilled");
|
||||||
|
SpilledStackOffsetFromFP = StackOffset;
|
||||||
|
HasSpillOffset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool hasSpillOffset() {
|
||||||
|
return HasSpillOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int getSpillOffFromFP() const {
|
||||||
|
assert( HasSpillOffset && "This LR is not spilled");
|
||||||
|
return SpilledStackOffsetFromFP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
|
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
|
||||||
|
|
||||||
// inline void markForLoadFromStack() { mustLoadFromStack = true;
|
// inline void markForLoadFromStack() { mustLoadFromStack = true;
|
||||||
@ -135,6 +167,11 @@ class LiveRange : public ValueSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline LiveRange() : ValueSet() /* , CallInterferenceList() */
|
inline LiveRange() : ValueSet() /* , CallInterferenceList() */
|
||||||
{
|
{
|
||||||
Color = SuggestedColor = -1; // not yet colored
|
Color = SuggestedColor = -1; // not yet colored
|
||||||
@ -143,6 +180,7 @@ class LiveRange : public ValueSet
|
|||||||
UserIGNode = NULL;
|
UserIGNode = NULL;
|
||||||
doesSpanAcrossCalls = false;
|
doesSpanAcrossCalls = false;
|
||||||
CanUseSuggestedCol = true;
|
CanUseSuggestedCol = true;
|
||||||
|
HasSpillOffset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PHY_REG_ALLOC_H
|
#ifndef PHY_REG_ALLOC_H
|
||||||
#define PHY_REG_ALLOC_H
|
#define PHY_REG_ALLOC_H
|
||||||
|
|
||||||
@ -41,11 +39,21 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Class AddedInstrns:
|
||||||
|
// When register allocator inserts new instructions in to the existing
|
||||||
|
// instruction stream, it does NOT directly modify the instruction stream.
|
||||||
|
// Rather, it creates an object of AddedInstrns and stick it in the
|
||||||
|
// AddedInstrMap for an existing instruction. This class contains two vectors
|
||||||
|
// to store such instructions added before and after an existing instruction.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
class AddedInstrns
|
class AddedInstrns
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
deque<MachineInstr *> InstrnsBefore;
|
deque<MachineInstr *> InstrnsBefore; // Added insts BEFORE an existing inst
|
||||||
deque<MachineInstr *> InstrnsAfter;
|
deque<MachineInstr *> InstrnsAfter; // Added insts AFTER an existing inst
|
||||||
|
|
||||||
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
||||||
};
|
};
|
||||||
@ -54,6 +62,80 @@ 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
|
||||||
|
// registers for a Method.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class PhyRegAlloc
|
class PhyRegAlloc
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -71,7 +153,7 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
||||||
|
|
||||||
|
RegStackOffsets StackOffsets;
|
||||||
|
|
||||||
//------- private methods ---------------------------------------------------
|
//------- private methods ---------------------------------------------------
|
||||||
|
|
||||||
@ -81,8 +163,8 @@ class PhyRegAlloc
|
|||||||
void addInterferencesForArgs();
|
void addInterferencesForArgs();
|
||||||
void createIGNodeListsAndIGs();
|
void createIGNodeListsAndIGs();
|
||||||
void buildInterferenceGraphs();
|
void buildInterferenceGraphs();
|
||||||
void insertCallerSavingCode(const MachineInstr *MInst,
|
//void insertCallerSavingCode(const MachineInstr *MInst,
|
||||||
const BasicBlock *BB );
|
// const BasicBlock *BB );
|
||||||
|
|
||||||
void setCallInterferences(const MachineInstr *MInst,
|
void setCallInterferences(const MachineInstr *MInst,
|
||||||
const LiveVarSet *const LVSetAft );
|
const LiveVarSet *const LVSetAft );
|
||||||
@ -91,6 +173,12 @@ class PhyRegAlloc
|
|||||||
const MachineInstr *DelayedMI );
|
const MachineInstr *DelayedMI );
|
||||||
|
|
||||||
void markUnusableSugColors();
|
void markUnusableSugColors();
|
||||||
|
void allocateStackSpace4SpilledLRs();
|
||||||
|
|
||||||
|
RegStackOffsets & getStackOffsets() {
|
||||||
|
return StackOffsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void constructLiveRanges()
|
inline void constructLiveRanges()
|
||||||
{ LRI.constructLiveRanges(); }
|
{ LRI.constructLiveRanges(); }
|
||||||
@ -101,8 +189,14 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
void printLabel(const Value *const Val);
|
void printLabel(const Value *const Val);
|
||||||
void printMachineCode();
|
void printMachineCode();
|
||||||
|
|
||||||
|
friend class UltraSparcRegInfo;
|
||||||
|
void setRegsUsedByThisInst(RegClass *RC, const MachineInstr *MInst );
|
||||||
|
int getRegNotUsedByThisInst(RegClass *RC, const MachineInstr *MInst);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
||||||
MethodLiveVarInfo *const Lvi);
|
MethodLiveVarInfo *const Lvi);
|
||||||
|
|
||||||
@ -117,5 +211,8 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -100,6 +100,9 @@ class RegClass
|
|||||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||||
|
|
||||||
|
|
||||||
|
inline bool * getIsColorUsedArr() { return IsColorUsedArr; }
|
||||||
|
|
||||||
|
|
||||||
inline void printIGNodeList() const {
|
inline void printIGNodeList() const {
|
||||||
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||||
IG.printIGNodeList();
|
IG.printIGNodeList();
|
||||||
|
@ -55,6 +55,11 @@ class LiveRange : public ValueSet
|
|||||||
|
|
||||||
bool CanUseSuggestedCol;
|
bool CanUseSuggestedCol;
|
||||||
|
|
||||||
|
// if this LR is spilled, its stack offset from *FP*. The spilled offsets
|
||||||
|
// must always be relative to the FP.
|
||||||
|
int SpilledStackOffsetFromFP;
|
||||||
|
bool HasSpillOffset;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
@ -88,6 +93,33 @@ class LiveRange : public ValueSet
|
|||||||
|
|
||||||
inline void markForSpill() { mustSpill = true; }
|
inline void markForSpill() { mustSpill = true; }
|
||||||
|
|
||||||
|
inline bool isMarkedForSpill() { return mustSpill; }
|
||||||
|
|
||||||
|
inline void setSpillOffFromFP(int StackOffset) {
|
||||||
|
assert( mustSpill && "This LR is not spilled");
|
||||||
|
SpilledStackOffsetFromFP = StackOffset;
|
||||||
|
HasSpillOffset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void modifySpillOffFromFP(int StackOffset) {
|
||||||
|
assert( mustSpill && "This LR is not spilled");
|
||||||
|
SpilledStackOffsetFromFP = StackOffset;
|
||||||
|
HasSpillOffset = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool hasSpillOffset() {
|
||||||
|
return HasSpillOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int getSpillOffFromFP() const {
|
||||||
|
assert( HasSpillOffset && "This LR is not spilled");
|
||||||
|
return SpilledStackOffsetFromFP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
|
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
|
||||||
|
|
||||||
// inline void markForLoadFromStack() { mustLoadFromStack = true;
|
// inline void markForLoadFromStack() { mustLoadFromStack = true;
|
||||||
@ -135,6 +167,11 @@ class LiveRange : public ValueSet
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inline LiveRange() : ValueSet() /* , CallInterferenceList() */
|
inline LiveRange() : ValueSet() /* , CallInterferenceList() */
|
||||||
{
|
{
|
||||||
Color = SuggestedColor = -1; // not yet colored
|
Color = SuggestedColor = -1; // not yet colored
|
||||||
@ -143,6 +180,7 @@ class LiveRange : public ValueSet
|
|||||||
UserIGNode = NULL;
|
UserIGNode = NULL;
|
||||||
doesSpanAcrossCalls = false;
|
doesSpanAcrossCalls = false;
|
||||||
CanUseSuggestedCol = true;
|
CanUseSuggestedCol = true;
|
||||||
|
HasSpillOffset = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -29,8 +29,6 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef PHY_REG_ALLOC_H
|
#ifndef PHY_REG_ALLOC_H
|
||||||
#define PHY_REG_ALLOC_H
|
#define PHY_REG_ALLOC_H
|
||||||
|
|
||||||
@ -41,11 +39,21 @@
|
|||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Class AddedInstrns:
|
||||||
|
// When register allocator inserts new instructions in to the existing
|
||||||
|
// instruction stream, it does NOT directly modify the instruction stream.
|
||||||
|
// Rather, it creates an object of AddedInstrns and stick it in the
|
||||||
|
// AddedInstrMap for an existing instruction. This class contains two vectors
|
||||||
|
// to store such instructions added before and after an existing instruction.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
class AddedInstrns
|
class AddedInstrns
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
deque<MachineInstr *> InstrnsBefore;
|
deque<MachineInstr *> InstrnsBefore; // Added insts BEFORE an existing inst
|
||||||
deque<MachineInstr *> InstrnsAfter;
|
deque<MachineInstr *> InstrnsAfter; // Added insts AFTER an existing inst
|
||||||
|
|
||||||
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
||||||
};
|
};
|
||||||
@ -54,6 +62,80 @@ 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
|
||||||
|
// registers for a Method.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class PhyRegAlloc
|
class PhyRegAlloc
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -71,7 +153,7 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
||||||
|
|
||||||
|
RegStackOffsets StackOffsets;
|
||||||
|
|
||||||
//------- private methods ---------------------------------------------------
|
//------- private methods ---------------------------------------------------
|
||||||
|
|
||||||
@ -81,8 +163,8 @@ class PhyRegAlloc
|
|||||||
void addInterferencesForArgs();
|
void addInterferencesForArgs();
|
||||||
void createIGNodeListsAndIGs();
|
void createIGNodeListsAndIGs();
|
||||||
void buildInterferenceGraphs();
|
void buildInterferenceGraphs();
|
||||||
void insertCallerSavingCode(const MachineInstr *MInst,
|
//void insertCallerSavingCode(const MachineInstr *MInst,
|
||||||
const BasicBlock *BB );
|
// const BasicBlock *BB );
|
||||||
|
|
||||||
void setCallInterferences(const MachineInstr *MInst,
|
void setCallInterferences(const MachineInstr *MInst,
|
||||||
const LiveVarSet *const LVSetAft );
|
const LiveVarSet *const LVSetAft );
|
||||||
@ -91,6 +173,12 @@ class PhyRegAlloc
|
|||||||
const MachineInstr *DelayedMI );
|
const MachineInstr *DelayedMI );
|
||||||
|
|
||||||
void markUnusableSugColors();
|
void markUnusableSugColors();
|
||||||
|
void allocateStackSpace4SpilledLRs();
|
||||||
|
|
||||||
|
RegStackOffsets & getStackOffsets() {
|
||||||
|
return StackOffsets;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void constructLiveRanges()
|
inline void constructLiveRanges()
|
||||||
{ LRI.constructLiveRanges(); }
|
{ LRI.constructLiveRanges(); }
|
||||||
@ -101,8 +189,14 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
void printLabel(const Value *const Val);
|
void printLabel(const Value *const Val);
|
||||||
void printMachineCode();
|
void printMachineCode();
|
||||||
|
|
||||||
|
friend class UltraSparcRegInfo;
|
||||||
|
void setRegsUsedByThisInst(RegClass *RC, const MachineInstr *MInst );
|
||||||
|
int getRegNotUsedByThisInst(RegClass *RC, const MachineInstr *MInst);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
||||||
MethodLiveVarInfo *const Lvi);
|
MethodLiveVarInfo *const Lvi);
|
||||||
|
|
||||||
@ -117,5 +211,8 @@ class PhyRegAlloc
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -100,6 +100,9 @@ class RegClass
|
|||||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||||
|
|
||||||
|
|
||||||
|
inline bool * getIsColorUsedArr() { return IsColorUsedArr; }
|
||||||
|
|
||||||
|
|
||||||
inline void printIGNodeList() const {
|
inline void printIGNodeList() const {
|
||||||
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
cerr << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||||
IG.printIGNodeList();
|
IG.printIGNodeList();
|
||||||
|
@ -113,9 +113,17 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// class UltraSparcRegInfo
|
||||||
|
//
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class LiveRange;
|
class LiveRange;
|
||||||
class UltraSparc;
|
class UltraSparc;
|
||||||
|
class PhyRegAlloc;
|
||||||
|
|
||||||
|
|
||||||
class UltraSparcRegInfo : public MachineRegInfo
|
class UltraSparcRegInfo : public MachineRegInfo
|
||||||
@ -144,6 +152,9 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
FloatCCRegType
|
FloatCCRegType
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// the size of a value (int, float, etc..) stored in the stack frame
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// WARNING: If the above enum order must be changed, also modify
|
// WARNING: If the above enum order must be changed, also modify
|
||||||
// getRegisterClassOfValue method below since it assumes this particular
|
// getRegisterClassOfValue method below since it assumes this particular
|
||||||
@ -158,6 +169,9 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
unsigned const NumOfIntArgRegs;
|
unsigned const NumOfIntArgRegs;
|
||||||
unsigned const NumOfFloatArgRegs;
|
unsigned const NumOfFloatArgRegs;
|
||||||
int const InvalidRegNum;
|
int const InvalidRegNum;
|
||||||
|
int SizeOfOperandOnStack;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
|
//void setCallArgColor(LiveRange *const LR, const unsigned RegNo) const;
|
||||||
|
|
||||||
@ -246,7 +260,8 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
|
UltraSparcRegInfo(const UltraSparc *const USI ) : UltraSparcInfo(USI),
|
||||||
NumOfIntArgRegs(6),
|
NumOfIntArgRegs(6),
|
||||||
NumOfFloatArgRegs(32),
|
NumOfFloatArgRegs(32),
|
||||||
InvalidRegNum(1000)
|
InvalidRegNum(1000),
|
||||||
|
SizeOfOperandOnStack(8)
|
||||||
{
|
{
|
||||||
MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
|
MachineRegClassArr.push_back( new SparcIntRegClass(IntRegClassID) );
|
||||||
MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
|
MachineRegClassArr.push_back( new SparcFloatRegClass(FloatRegClassID) );
|
||||||
@ -255,6 +270,7 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
|
|
||||||
assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
|
assert( SparcFloatRegOrder::StartOfNonVolatileRegs == 32 &&
|
||||||
"32 Float regs are used for float arg passing");
|
"32 Float regs are used for float arg passing");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ***** TODO Delete
|
// ***** TODO Delete
|
||||||
@ -317,7 +333,7 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
AddedInstrns *const FirstAI) const;
|
AddedInstrns *const FirstAI) const;
|
||||||
|
|
||||||
void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
|
void colorCallArgs(const MachineInstr *const CallMI, LiveRangeInfo& LRI,
|
||||||
AddedInstrns *const CallAI) const;
|
AddedInstrns *const CallAI, PhyRegAlloc &PRA) const;
|
||||||
|
|
||||||
void colorRetValue(const MachineInstr *const RetI, LiveRangeInfo& LRI,
|
void colorRetValue(const MachineInstr *const RetI, LiveRangeInfo& LRI,
|
||||||
AddedInstrns *const RetAI) const;
|
AddedInstrns *const RetAI) const;
|
||||||
@ -402,6 +418,11 @@ class UltraSparcRegInfo : public MachineRegInfo
|
|||||||
return InvalidRegNum;
|
return InvalidRegNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void insertCallerSavingCode(const MachineInstr *MInst,
|
||||||
|
const BasicBlock *BB, PhyRegAlloc &PRA ) const;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1115,7 +1136,9 @@ public:
|
|||||||
static const int FirstOutgoingArgOffsetFromSP = 128;
|
static const int FirstOutgoingArgOffsetFromSP = 128;
|
||||||
static const int FirstOptionalOutgoingArgOffsetFromSP = 176;
|
static const int FirstOptionalOutgoingArgOffsetFromSP = 176;
|
||||||
static const int StaticStackAreaOffsetFromFP = -1;
|
static const int StaticStackAreaOffsetFromFP = -1;
|
||||||
|
|
||||||
|
static const int FirstIncomingArgOffsetFromFP = 126;
|
||||||
|
|
||||||
static int getFirstAutomaticVarOffsetFromFP (const Method* method);
|
static int getFirstAutomaticVarOffsetFromFP (const Method* method);
|
||||||
static int getRegSpillAreaOffsetFromFP (const Method* method);
|
static int getRegSpillAreaOffsetFromFP (const Method* method);
|
||||||
static int getFrameSizeBelowDynamicArea (const Method* method);
|
static int getFrameSizeBelowDynamicArea (const Method* method);
|
||||||
|
@ -129,7 +129,7 @@ UltraSparcRegInfo::getCallInstNumArgs(const MachineInstr *CallMI) const {
|
|||||||
assert( (NumArgs != -1) && "Internal error in getCallInstNumArgs" );
|
assert( (NumArgs != -1) && "Internal error in getCallInstNumArgs" );
|
||||||
return (unsigned) NumArgs;
|
return (unsigned) NumArgs;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -321,21 +321,57 @@ void UltraSparcRegInfo::colorMethodArgs(const Method *const Meth,
|
|||||||
if( isArgInReg )
|
if( isArgInReg )
|
||||||
AdMI = cpReg2RegMI( UniArgReg, UniLRReg, RegType );
|
AdMI = cpReg2RegMI( UniArgReg, UniLRReg, RegType );
|
||||||
|
|
||||||
else
|
else {
|
||||||
assert(0 && "TODO: Color an Incoming arg on stack");
|
|
||||||
|
|
||||||
// Now add the instruction
|
// Now the arg is coming on stack. Since the LR recieved a register,
|
||||||
FirstAI->InstrnsBefore.push_back( AdMI );
|
// we just have to load the arg on stack into that register
|
||||||
|
int ArgStakOffFromFP =
|
||||||
|
UltraSparcFrameInfo::FirstIncomingArgOffsetFromFP +
|
||||||
|
argNo * SizeOfOperandOnStack;
|
||||||
|
|
||||||
|
AdMI = cpMem2RegMI(getFramePointer(), ArgStakOffFromFP,
|
||||||
|
UniLRReg, RegType );
|
||||||
|
}
|
||||||
|
|
||||||
|
FirstAI->InstrnsBefore.push_back( AdMI );
|
||||||
|
|
||||||
|
} // if LR received a color
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Now, the LR did not receive a color. But it has a stack offset for
|
||||||
|
// spilling.
|
||||||
|
|
||||||
|
// So, if the arg is coming in UniArgReg register, we can just move
|
||||||
|
// that on to the stack pos of LR
|
||||||
|
|
||||||
|
|
||||||
|
if( isArgInReg ) {
|
||||||
|
|
||||||
|
MachineInstr *AdIBef =
|
||||||
|
cpReg2MemMI(UniArgReg, getFramePointer(),
|
||||||
|
LR->getSpillOffFromFP(), RegType );
|
||||||
|
|
||||||
|
FirstAI->InstrnsBefore.push_back( AdMI );
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
|
||||||
|
// Now the arg is coming on stack. Since the LR did NOT
|
||||||
|
// recieved a register as well, it is allocated a stack position. We
|
||||||
|
// can simply change the stack poistion of the LR. We can do this,
|
||||||
|
// since this method is called before any other method that makes
|
||||||
|
// uses of the stack pos of the LR (e.g., updateMachineInstr)
|
||||||
|
|
||||||
|
int ArgStakOffFromFP =
|
||||||
|
UltraSparcFrameInfo::FirstIncomingArgOffsetFromFP +
|
||||||
|
argNo * SizeOfOperandOnStack;
|
||||||
|
|
||||||
|
LR->modifySpillOffFromFP( ArgStakOffFromFP );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // LR is not colored (i.e., spilled)
|
|
||||||
|
|
||||||
assert(0 && "TODO: Color a spilled arg ");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // for each incoming argument
|
} // for each incoming argument
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -452,10 +488,10 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *const CallMI,
|
|||||||
// to instert copy instructions.
|
// to instert copy instructions.
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
|
void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
|
||||||
LiveRangeInfo& LRI,
|
LiveRangeInfo& LRI,
|
||||||
AddedInstrns *const CallAI) const {
|
AddedInstrns *const CallAI,
|
||||||
|
PhyRegAlloc &PRA) const {
|
||||||
|
|
||||||
assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
|
assert ( (UltraSparcInfo->getInstrInfo()).isCall(CallMI->getOpCode()) );
|
||||||
|
|
||||||
@ -502,30 +538,33 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
|
|||||||
// put copy instruction
|
// put copy instruction
|
||||||
|
|
||||||
if( !recvCorrectColor ) {
|
if( !recvCorrectColor ) {
|
||||||
|
|
||||||
|
unsigned RegType = getRegType( RetValLR );
|
||||||
|
|
||||||
|
// the reg that LR must be colored with
|
||||||
|
unsigned UniRetReg = getUnifiedRegNum( RegClassID, CorrectCol);
|
||||||
|
|
||||||
if( RetValLR->hasColor() ) {
|
if( RetValLR->hasColor() ) {
|
||||||
|
|
||||||
unsigned RegType = getRegType( RetValLR );
|
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
|
UniRetLRReg=getUnifiedRegNum(RegClassID,RetValLR->getColor());
|
||||||
|
|
||||||
// the reg that LR must be colored with
|
|
||||||
unsigned UniRetReg = getUnifiedRegNum( RegClassID, CorrectCol);
|
|
||||||
|
|
||||||
// the return value is coming in UniRetReg but has to go into
|
// the return value is coming in UniRetReg but has to go into
|
||||||
// the UniRetLRReg
|
// the UniRetLRReg
|
||||||
|
|
||||||
AdMI = cpReg2RegMI( UniRetReg, UniRetLRReg, RegType );
|
AdMI = cpReg2RegMI( UniRetReg, UniRetLRReg, RegType );
|
||||||
CallAI->InstrnsAfter.push_back( AdMI );
|
|
||||||
|
|
||||||
|
|
||||||
} // if LR has color
|
} // if LR has color
|
||||||
else {
|
else {
|
||||||
|
|
||||||
|
// if the LR did NOT receive a color, we have to move the return
|
||||||
|
// value coming in UniRetReg to the stack pos of spilled LR
|
||||||
|
|
||||||
assert(0 && "LR of return value is splilled");
|
AdMI = cpReg2MemMI(UniRetReg, getFramePointer(),
|
||||||
|
RetValLR->getSpillOffFromFP(), RegType );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CallAI->InstrnsAfter.push_back( AdMI );
|
||||||
|
|
||||||
} // the LR didn't receive the suggested color
|
} // the LR didn't receive the suggested color
|
||||||
|
|
||||||
@ -600,18 +639,74 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *const CallMI,
|
|||||||
if( isArgInReg )
|
if( isArgInReg )
|
||||||
AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
|
AdMI = cpReg2RegMI(UniLRReg, UniArgReg, RegType );
|
||||||
|
|
||||||
else
|
else {
|
||||||
assert(0 && "TODO: Push an outgoing arg on stack");
|
// Now, we have to pass the arg on stack. Since LR received a register
|
||||||
|
// we just have to move that register to the stack position where
|
||||||
|
// the argument must be passed
|
||||||
|
|
||||||
// Now add the instruction
|
int ArgStakOffFromSP =
|
||||||
CallAI->InstrnsBefore.push_back( AdMI );
|
UltraSparcFrameInfo::FirstOutgoingArgOffsetFromSP +
|
||||||
|
argNo * SizeOfOperandOnStack;
|
||||||
|
|
||||||
|
AdMI = cpReg2MemMI(UniLRReg, getStackPointer(), ArgStakOffFromSP,
|
||||||
|
RegType );
|
||||||
|
}
|
||||||
|
|
||||||
|
CallAI->InstrnsBefore.push_back( AdMI ); // Now add the instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
else { // LR is not colored (i.e., spilled)
|
else { // LR is not colored (i.e., spilled)
|
||||||
|
|
||||||
assert(0 && "TODO: Copy a spilled call arg to an output reg ");
|
|
||||||
|
|
||||||
|
if( isArgInReg ) {
|
||||||
|
|
||||||
|
// Now the LR did NOT recieve a register but has a stack poistion.
|
||||||
|
// Since, the outgoing arg goes in a register we just have to insert
|
||||||
|
// a load instruction to load the LR to outgoing register
|
||||||
|
|
||||||
|
|
||||||
|
AdMI = cpMem2RegMI(getStackPointer(), LR->getSpillOffFromFP(),
|
||||||
|
UniArgReg, RegType );
|
||||||
|
|
||||||
|
CallAI->InstrnsBefore.push_back( AdMI ); // Now add the instruction
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
// Now, we have to pass the arg on stack. Since LR also did NOT
|
||||||
|
// receive a register we have to move an argument in memory to
|
||||||
|
// outgoing parameter on stack.
|
||||||
|
|
||||||
|
// Optoimize: Optimize when reverse pointers in MahineInstr are
|
||||||
|
// introduced.
|
||||||
|
// call PRA.getUnusedRegAtMI(....) to get an unused reg. Only if this
|
||||||
|
// fails, then use the following code. Currently, we cannot call the
|
||||||
|
// above method since we cannot find LVSetBefore without the BB
|
||||||
|
|
||||||
|
int TReg = PRA.getRegNotUsedByThisInst( LR->getRegClass(), CallMI );
|
||||||
|
int TmpOff = PRA.getStackOffsets().getNewTmpPosOffFromFP();
|
||||||
|
int ArgStakOffFromSP =
|
||||||
|
UltraSparcFrameInfo::FirstOutgoingArgOffsetFromSP +
|
||||||
|
argNo * SizeOfOperandOnStack;
|
||||||
|
|
||||||
|
MachineInstr *Ad1, *Ad2, *Ad3, *Ad4;
|
||||||
|
|
||||||
|
// Sequence:
|
||||||
|
// (1) Save TReg on stack
|
||||||
|
// (2) Load LR value into TReg from stack pos of LR
|
||||||
|
// (3) Store Treg on outgoing Arg pos on stack
|
||||||
|
// (4) Load the old value of TReg from stack to TReg (restore it)
|
||||||
|
|
||||||
|
Ad1 = cpReg2MemMI(TReg, getFramePointer(), TmpOff, RegType );
|
||||||
|
Ad2 = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
|
||||||
|
TReg, RegType );
|
||||||
|
Ad3 = cpReg2MemMI(TReg, getStackPointer(), ArgStakOffFromSP, RegType );
|
||||||
|
Ad4 = cpMem2RegMI(getFramePointer(), TmpOff, TReg, RegType );
|
||||||
|
|
||||||
|
CallAI->InstrnsBefore.push_back( Ad1 );
|
||||||
|
CallAI->InstrnsBefore.push_back( Ad2 );
|
||||||
|
CallAI->InstrnsBefore.push_back( Ad3 );
|
||||||
|
CallAI->InstrnsBefore.push_back( Ad4 );
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // for each parameter in call instruction
|
} // for each parameter in call instruction
|
||||||
@ -658,8 +753,13 @@ void UltraSparcRegInfo::suggestReg4RetValue(const MachineInstr *const RetMI,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Colors the return value of a method to %i0 or %f0, if possible. If it is
|
||||||
|
// not possilbe to directly color the LR, insert a copy instruction to move
|
||||||
|
// the LR to %i0 or %f0. When the LR is spilled, instead of the copy, we
|
||||||
|
// have to put a load instruction.
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
void UltraSparcRegInfo::colorRetValue(const MachineInstr *const RetMI,
|
void UltraSparcRegInfo::colorRetValue(const MachineInstr *const RetMI,
|
||||||
LiveRangeInfo& LRI,
|
LiveRangeInfo& LRI,
|
||||||
@ -682,7 +782,7 @@ void UltraSparcRegInfo::colorRetValue(const MachineInstr *const RetMI,
|
|||||||
cerr << endl;
|
cerr << endl;
|
||||||
// assert( LR && "No LR for return value of non-void method");
|
// assert( LR && "No LR for return value of non-void method");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned RegClassID = getRegClassIDOfValue(RetVal);
|
unsigned RegClassID = getRegClassIDOfValue(RetVal);
|
||||||
unsigned RegType = getRegType( RetVal );
|
unsigned RegType = getRegType( RetVal );
|
||||||
@ -720,9 +820,14 @@ void UltraSparcRegInfo::colorRetValue(const MachineInstr *const RetMI,
|
|||||||
AdMI = cpReg2RegMI( UniLRReg, UniRetReg, RegType);
|
AdMI = cpReg2RegMI( UniLRReg, UniRetReg, RegType);
|
||||||
RetAI->InstrnsBefore.push_back( AdMI );
|
RetAI->InstrnsBefore.push_back( AdMI );
|
||||||
}
|
}
|
||||||
else
|
else { // if the LR is spilled
|
||||||
assert(0 && "TODO: Copy the return value from stack\n");
|
|
||||||
|
|
||||||
|
AdMI = cpMem2RegMI(getFramePointer(), LR->getSpillOffFromFP(),
|
||||||
|
UniRetReg, RegType);
|
||||||
|
RetAI->InstrnsBefore.push_back( AdMI );
|
||||||
|
cout << "\nCopied the return value from stack";
|
||||||
|
}
|
||||||
|
|
||||||
} // if there is a return value
|
} // if there is a return value
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -878,80 +983,115 @@ MachineInstr * UltraSparcRegInfo::cpMem2RegMI(const unsigned SrcPtrReg,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// This method inserts caller saving/restoring instructons before/after
|
||||||
|
// a call machine instruction.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
void UltraSparcRegInfo::insertCallerSavingCode(const MachineInstr *MInst,
|
||||||
|
const BasicBlock *BB,
|
||||||
|
PhyRegAlloc &PRA) const {
|
||||||
|
// assert( (getInstrInfo()).isCall( MInst->getOpCode() ) );
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
|
||||||
// Only constant/label values are accepted.
|
PRA.StackOffsets.resetTmpPos();
|
||||||
// ***This code is temporary ***
|
|
||||||
//---------------------------------------------------------------------------
|
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.
|
||||||
|
|
||||||
|
|
||||||
MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val,
|
const Value *RetVal = getCallInstRetVal( MInst );
|
||||||
const unsigned DestReg,
|
|
||||||
const int RegType) const {
|
|
||||||
|
|
||||||
assert( ((int)DestReg != InvalidRegNum) && "Invalid Register");
|
if( RetVal ) {
|
||||||
|
|
||||||
/*
|
LiveRange *RetValLR = PRA.LRI.getLiveRangeForValue( RetVal );
|
||||||
unsigned MReg;
|
assert( RetValLR && "No LR for RetValue of call");
|
||||||
int64_t Imm;
|
|
||||||
|
|
||||||
MachineOperand::MachineOperandType MOTypeInt =
|
PushedRegSet.insert(
|
||||||
ChooseRegOrImmed(Val, ADD, *UltraSparcInfo, true, MReg, Imm);
|
getUnifiedRegNum((RetValLR->getRegClass())->getID(),
|
||||||
*/
|
RetValLR->getColor() ) );
|
||||||
|
|
||||||
MachineOperand::MachineOperandType MOType;
|
|
||||||
|
|
||||||
switch( Val->getValueType() ) {
|
|
||||||
|
|
||||||
case Value::ConstantVal:
|
|
||||||
case Value::GlobalVariableVal:
|
|
||||||
MOType = MachineOperand:: MO_UnextendedImmed; // TODO**** correct???
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Value::BasicBlockVal:
|
|
||||||
case Value::MethodVal:
|
|
||||||
MOType = MachineOperand::MO_PCRelativeDisp;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
cerr << "Value Type: " << Val->getValueType() << endl;
|
|
||||||
assert(0 && "Unknown val type - Only constants/globals/labels are valid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const LiveVarSet *LVSetAft = PRA.LVI->getLiveVarSetAfterMInst(MInst, BB);
|
||||||
|
|
||||||
MachineInstr * MI = NULL;
|
LiveVarSet::const_iterator LIt = LVSetAft->begin();
|
||||||
|
|
||||||
switch( RegType ) {
|
// 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 = PRA.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 ( isRegVolatile(RCID, Color) ) {
|
||||||
|
|
||||||
|
// if the value is in both LV sets (i.e., live before and after
|
||||||
|
// the call machine instruction)
|
||||||
|
|
||||||
|
unsigned Reg = getUnifiedRegNum(RCID, Color);
|
||||||
|
|
||||||
|
if( PushedRegSet.find(Reg) == PushedRegSet.end() ) {
|
||||||
|
|
||||||
|
// if we haven't already pushed that register
|
||||||
|
|
||||||
|
unsigned RegType = 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 = PRA.StackOffsets. getNewTmpPosOffFromFP();
|
||||||
|
|
||||||
|
/**** TODO - Handle IntCCRegType
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
MachineInstr *AdIBef =
|
||||||
|
cpReg2MemMI(Reg, getStackPointer(), StackOff, RegType );
|
||||||
|
|
||||||
|
MachineInstr *AdIAft =
|
||||||
|
cpMem2RegMI(getStackPointer(), StackOff, Reg, RegType );
|
||||||
|
|
||||||
|
((PRA.AddedInstrMap[MInst])->InstrnsBefore).push_front(AdIBef);
|
||||||
|
((PRA.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
|
||||||
|
|
||||||
case IntRegType:
|
} // for each value in the LV set after instruction
|
||||||
MI = new MachineInstr(ADD);
|
|
||||||
MI->SetMachineOperand(0, MOType, Val, false);
|
|
||||||
MI->SetMachineOperand(1, SparcIntRegOrder::g0, false);
|
|
||||||
MI->SetMachineOperand(2, DestReg, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPSingleRegType:
|
|
||||||
assert(0 && "FP const move not yet implemented");
|
|
||||||
MI = new MachineInstr(FMOVS);
|
|
||||||
MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
|
|
||||||
MI->SetMachineOperand(1, DestReg, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FPDoubleRegType:
|
|
||||||
assert(0 && "FP const move not yet implemented");
|
|
||||||
MI = new MachineInstr(FMOVD);
|
|
||||||
MI->SetMachineOperand(0, MachineOperand::MO_SignExtendedImmed, Val, false);
|
|
||||||
MI->SetMachineOperand(1, DestReg, true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0 && "Unknow RegType");
|
|
||||||
}
|
|
||||||
|
|
||||||
return MI;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -960,6 +1100,8 @@ MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
// Print the register assigned to a LR
|
// Print the register assigned to a LR
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
Loading…
x
Reference in New Issue
Block a user