mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 04:38:24 +00:00
When compiled with GCC 4.0, a latent bug was exposed where both SparcV9
and the target independant register allocator were both using a class named 'LiveRange'. This lead to the target independant code calling code in the SparcV9 backend, which crashed. Fixed by renaming SparcV9's LiveRange to V9LiveRange. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22208 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -55,10 +55,10 @@ class IGNode {
|
|||||||
// Decremented when a neighbor is pushed on to the stack.
|
// Decremented when a neighbor is pushed on to the stack.
|
||||||
// After that, never incremented/set again nor used.
|
// After that, never incremented/set again nor used.
|
||||||
|
|
||||||
LiveRange *const ParentLR;
|
V9LiveRange *const ParentLR;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
IGNode(LiveRange *LR, unsigned index) : Index(index), ParentLR(LR) {
|
IGNode(V9LiveRange *LR, unsigned index) : Index(index), ParentLR(LR) {
|
||||||
OnStack = false;
|
OnStack = false;
|
||||||
CurDegree = -1;
|
CurDegree = -1;
|
||||||
ParentLR->setUserIGNode(this);
|
ParentLR->setUserIGNode(this);
|
||||||
@ -115,7 +115,7 @@ public:
|
|||||||
|
|
||||||
inline void setColor(unsigned Col) { ParentLR->setColor(Col); }
|
inline void setColor(unsigned Col) { ParentLR->setColor(Col); }
|
||||||
|
|
||||||
inline LiveRange *getParentLR() const { return ParentLR; }
|
inline V9LiveRange *getParentLR() const { return ParentLR; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
@ -74,7 +74,7 @@ void InterferenceGraph::createGraph()
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// creates a new IGNode for the given live range and add to IG
|
// creates a new IGNode for the given live range and add to IG
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
void InterferenceGraph::addLRToIG(V9LiveRange *const LR)
|
||||||
{
|
{
|
||||||
IGNodeList.push_back(new IGNode(LR, IGNodeList.size()));
|
IGNodeList.push_back(new IGNode(LR, IGNodeList.size()));
|
||||||
}
|
}
|
||||||
@ -87,8 +87,8 @@ void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
|||||||
// are not updated. LR1 and LR2 must be distinct since if not, it suggests
|
// are not updated. LR1 and LR2 must be distinct since if not, it suggests
|
||||||
// that there is some wrong logic in some other method.
|
// that there is some wrong logic in some other method.
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
void InterferenceGraph::setInterference(const V9LiveRange *const LR1,
|
||||||
const LiveRange *const LR2 ) {
|
const V9LiveRange *const LR2 ) {
|
||||||
assert(LR1 != LR2);
|
assert(LR1 != LR2);
|
||||||
|
|
||||||
IGNode *IGNode1 = LR1->getUserIGNode();
|
IGNode *IGNode1 = LR1->getUserIGNode();
|
||||||
@ -119,8 +119,9 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// return whether two live ranges interfere
|
// return whether two live ranges interfere
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
unsigned InterferenceGraph::getInterference(const V9LiveRange *const LR1,
|
||||||
const LiveRange *const LR2) const {
|
const V9LiveRange *const LR2)
|
||||||
|
const {
|
||||||
assert(LR1 != LR2);
|
assert(LR1 != LR2);
|
||||||
assertIGNode(this, LR1->getUserIGNode());
|
assertIGNode(this, LR1->getUserIGNode());
|
||||||
assertIGNode(this, LR2->getUserIGNode());
|
assertIGNode(this, LR2->getUserIGNode());
|
||||||
@ -145,8 +146,8 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
|||||||
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
|
void InterferenceGraph::mergeIGNodesOfLRs(const V9LiveRange *LR1,
|
||||||
LiveRange *LR2) {
|
V9LiveRange *LR2) {
|
||||||
|
|
||||||
assert( LR1 != LR2); // cannot merge the same live range
|
assert( LR1 != LR2); // cannot merge the same live range
|
||||||
|
|
||||||
@ -168,7 +169,7 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *LR1,
|
|||||||
for(unsigned i=0; i < SrcDegree; i++) {
|
for(unsigned i=0; i < SrcDegree; i++) {
|
||||||
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
|
IGNode *NeighNode = SrcNode->getAdjIGNode(i);
|
||||||
|
|
||||||
LiveRange *const LROfNeigh = NeighNode->getParentLR();
|
V9LiveRange *const LROfNeigh = NeighNode->getParentLR();
|
||||||
|
|
||||||
// delete edge between src and neigh - even neigh == dest
|
// delete edge between src and neigh - even neigh == dest
|
||||||
NeighNode->delAdjIGNode(SrcNode);
|
NeighNode->delAdjIGNode(SrcNode);
|
||||||
|
@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class LiveRange;
|
class V9LiveRange;
|
||||||
class RegClass;
|
class RegClass;
|
||||||
class IGNode;
|
class IGNode;
|
||||||
|
|
||||||
@ -51,15 +51,15 @@ class InterferenceGraph {
|
|||||||
|
|
||||||
void createGraph();
|
void createGraph();
|
||||||
|
|
||||||
void addLRToIG(LiveRange *LR);
|
void addLRToIG(V9LiveRange *LR);
|
||||||
|
|
||||||
void setInterference(const LiveRange *LR1,
|
void setInterference(const V9LiveRange *LR1,
|
||||||
const LiveRange *LR2);
|
const V9LiveRange *LR2);
|
||||||
|
|
||||||
unsigned getInterference(const LiveRange *LR1,
|
unsigned getInterference(const V9LiveRange *LR1,
|
||||||
const LiveRange *LR2) const ;
|
const V9LiveRange *LR2) const ;
|
||||||
|
|
||||||
void mergeIGNodesOfLRs(const LiveRange *LR1, LiveRange *LR2);
|
void mergeIGNodesOfLRs(const V9LiveRange *LR1, V9LiveRange *LR2);
|
||||||
|
|
||||||
std::vector<IGNode *> &getIGNodeList() { return IGNodeList; }
|
std::vector<IGNode *> &getIGNodeList() { return IGNodeList; }
|
||||||
const std::vector<IGNode *> &getIGNodeList() const { return IGNodeList; }
|
const std::vector<IGNode *> &getIGNodeList() const { return IGNodeList; }
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// Implements a live range using a SetVector of Value *s. We keep only
|
// Implements a live range using a SetVector of Value *s. We keep only
|
||||||
// defs in a LiveRange.
|
// defs in a V9LiveRange.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
@ -24,14 +24,14 @@ namespace llvm {
|
|||||||
class RegClass;
|
class RegClass;
|
||||||
class IGNode;
|
class IGNode;
|
||||||
|
|
||||||
class LiveRange {
|
class V9LiveRange {
|
||||||
public:
|
public:
|
||||||
typedef SetVector<const Value *> ValueContainerType;
|
typedef SetVector<const Value *> ValueContainerType;
|
||||||
typedef ValueContainerType::iterator iterator;
|
typedef ValueContainerType::iterator iterator;
|
||||||
typedef ValueContainerType::const_iterator const_iterator;
|
typedef ValueContainerType::const_iterator const_iterator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueContainerType MyValues; // Values in this LiveRange
|
ValueContainerType MyValues; // Values in this V9LiveRange
|
||||||
RegClass *MyRegClass; // register class (e.g., int, FP) for this LR
|
RegClass *MyRegClass; // register class (e.g., int, FP) for this LR
|
||||||
|
|
||||||
/// doesSpanAcrossCalls - Does this live range span across calls?
|
/// doesSpanAcrossCalls - Does this live range span across calls?
|
||||||
@ -82,7 +82,7 @@ public:
|
|||||||
bool insert(const Value *&X) { return MyValues.insert (X); }
|
bool insert(const Value *&X) { return MyValues.insert (X); }
|
||||||
void insert(iterator b, iterator e) { MyValues.insert (b, e); }
|
void insert(iterator b, iterator e) { MyValues.insert (b, e); }
|
||||||
|
|
||||||
LiveRange() {
|
V9LiveRange() {
|
||||||
Color = SuggestedColor = -1; // not yet colored
|
Color = SuggestedColor = -1; // not yet colored
|
||||||
mustSpill = false;
|
mustSpill = false;
|
||||||
MyRegClass = 0;
|
MyRegClass = 0;
|
||||||
@ -184,7 +184,8 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline std::ostream &operator << (std::ostream &os, const LiveRange &lr) {
|
static inline std::ostream &operator << (std::ostream &os,
|
||||||
|
const V9LiveRange &lr) {
|
||||||
os << "LiveRange@" << (void *)(&lr);
|
os << "LiveRange@" << (void *)(&lr);
|
||||||
return os;
|
return os;
|
||||||
};
|
};
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
unsigned LiveRange::getRegClassID() const { return getRegClass()->getID(); }
|
unsigned V9LiveRange::getRegClassID() const { return getRegClass()->getID(); }
|
||||||
|
|
||||||
LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
|
LiveRangeInfo::LiveRangeInfo(const Function *F, const TargetMachine &tm,
|
||||||
std::vector<RegClass *> &RCL)
|
std::vector<RegClass *> &RCL)
|
||||||
@ -39,14 +39,14 @@ LiveRangeInfo::~LiveRangeInfo() {
|
|||||||
MI != LiveRangeMap.end(); ++MI) {
|
MI != LiveRangeMap.end(); ++MI) {
|
||||||
|
|
||||||
if (MI->first && MI->second) {
|
if (MI->first && MI->second) {
|
||||||
LiveRange *LR = MI->second;
|
V9LiveRange *LR = MI->second;
|
||||||
|
|
||||||
// we need to be careful in deleting LiveRanges in LiveRangeMap
|
// we need to be careful in deleting LiveRanges in LiveRangeMap
|
||||||
// since two/more Values in the live range map can point to the same
|
// since two/more Values in the live range map can point to the same
|
||||||
// live range. We have to make the other entries NULL when we delete
|
// live range. We have to make the other entries NULL when we delete
|
||||||
// a live range.
|
// a live range.
|
||||||
|
|
||||||
for (LiveRange::iterator LI = LR->begin(); LI != LR->end(); ++LI)
|
for (V9LiveRange::iterator LI = LR->begin(); LI != LR->end(); ++LI)
|
||||||
LiveRangeMap[*LI] = 0;
|
LiveRangeMap[*LI] = 0;
|
||||||
|
|
||||||
delete LR;
|
delete LR;
|
||||||
@ -61,14 +61,14 @@ LiveRangeInfo::~LiveRangeInfo() {
|
|||||||
// LRs don't have suggested colors
|
// LRs don't have suggested colors
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
|
void LiveRangeInfo::unionAndUpdateLRs(V9LiveRange *L1, V9LiveRange *L2) {
|
||||||
assert(L1 != L2 && (!L1->hasSuggestedColor() || !L2->hasSuggestedColor()));
|
assert(L1 != L2 && (!L1->hasSuggestedColor() || !L2->hasSuggestedColor()));
|
||||||
assert(! (L1->hasColor() && L2->hasColor()) ||
|
assert(! (L1->hasColor() && L2->hasColor()) ||
|
||||||
L1->getColor() == L2->getColor());
|
L1->getColor() == L2->getColor());
|
||||||
|
|
||||||
L2->insert (L1->begin(), L1->end()); // add elements of L2 to L1
|
L2->insert (L1->begin(), L1->end()); // add elements of L2 to L1
|
||||||
|
|
||||||
for(LiveRange::iterator L2It = L2->begin(); L2It != L2->end(); ++L2It) {
|
for(V9LiveRange::iterator L2It = L2->begin(); L2It != L2->end(); ++L2It) {
|
||||||
L1->insert(*L2It); // add the var in L2 to L1
|
L1->insert(*L2It); // add the var in L2 to L1
|
||||||
LiveRangeMap[*L2It] = L1; // now the elements in L2 should map
|
LiveRangeMap[*L2It] = L1; // now the elements in L2 should map
|
||||||
//to L1
|
//to L1
|
||||||
@ -101,10 +101,10 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *L1, LiveRange *L2) {
|
|||||||
// Note: this function does *not* check that no live range exists for def.
|
// Note: this function does *not* check that no live range exists for def.
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
LiveRange*
|
V9LiveRange*
|
||||||
LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
|
LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
|
||||||
{
|
{
|
||||||
LiveRange* DefRange = new LiveRange(); // Create a new live range,
|
V9LiveRange* DefRange = new V9LiveRange(); // Create a new live range,
|
||||||
DefRange->insert(Def); // add Def to it,
|
DefRange->insert(Def); // add Def to it,
|
||||||
LiveRangeMap[Def] = DefRange; // and update the map.
|
LiveRangeMap[Def] = DefRange; // and update the map.
|
||||||
|
|
||||||
@ -121,10 +121,10 @@ LiveRangeInfo::createNewLiveRange(const Value* Def, bool isCC /* = false*/)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LiveRange*
|
V9LiveRange*
|
||||||
LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/)
|
LiveRangeInfo::createOrAddToLiveRange(const Value* Def, bool isCC /* = false*/)
|
||||||
{
|
{
|
||||||
LiveRange *DefRange = LiveRangeMap[Def];
|
V9LiveRange *DefRange = LiveRangeMap[Def];
|
||||||
|
|
||||||
// check if the LR is already there (because of multiple defs)
|
// check if the LR is already there (because of multiple defs)
|
||||||
if (!DefRange) {
|
if (!DefRange) {
|
||||||
@ -188,10 +188,10 @@ void LiveRangeInfo::constructLiveRanges() {
|
|||||||
const Value *Def = *OpI;
|
const Value *Def = *OpI;
|
||||||
bool isCC = (OpI.getMachineOperand().getType()
|
bool isCC = (OpI.getMachineOperand().getType()
|
||||||
== MachineOperand::MO_CCRegister);
|
== MachineOperand::MO_CCRegister);
|
||||||
LiveRange* LR = createOrAddToLiveRange(Def, isCC);
|
V9LiveRange* LR = createOrAddToLiveRange(Def, isCC);
|
||||||
|
|
||||||
// If the operand has a pre-assigned register,
|
// If the operand has a pre-assigned register,
|
||||||
// set it directly in the LiveRange
|
// set it directly in the V9LiveRange
|
||||||
if (OpI.getMachineOperand().hasAllocatedReg()) {
|
if (OpI.getMachineOperand().hasAllocatedReg()) {
|
||||||
unsigned getClassId;
|
unsigned getClassId;
|
||||||
LR->setColor(MRI.getClassRegNum(OpI.getMachineOperand().getReg(),
|
LR->setColor(MRI.getClassRegNum(OpI.getMachineOperand().getReg(),
|
||||||
@ -204,10 +204,10 @@ void LiveRangeInfo::constructLiveRanges() {
|
|||||||
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
|
for (unsigned i = 0; i < MInst->getNumImplicitRefs(); ++i)
|
||||||
if (MInst->getImplicitOp(i).isDef()) {
|
if (MInst->getImplicitOp(i).isDef()) {
|
||||||
const Value *Def = MInst->getImplicitRef(i);
|
const Value *Def = MInst->getImplicitRef(i);
|
||||||
LiveRange* LR = createOrAddToLiveRange(Def, /*isCC*/ false);
|
V9LiveRange* LR = createOrAddToLiveRange(Def, /*isCC*/ false);
|
||||||
|
|
||||||
// If the implicit operand has a pre-assigned register,
|
// If the implicit operand has a pre-assigned register,
|
||||||
// set it directly in the LiveRange
|
// set it directly in the V9LiveRange
|
||||||
if (MInst->getImplicitOp(i).hasAllocatedReg()) {
|
if (MInst->getImplicitOp(i).hasAllocatedReg()) {
|
||||||
unsigned getClassId;
|
unsigned getClassId;
|
||||||
LR->setColor(MRI.getClassRegNum(
|
LR->setColor(MRI.getClassRegNum(
|
||||||
@ -277,10 +277,10 @@ void LiveRangeInfo::suggestRegs4CallRets() {
|
|||||||
// Checks if live range LR interferes with any node assigned or suggested to
|
// Checks if live range LR interferes with any node assigned or suggested to
|
||||||
// be assigned the specified color
|
// be assigned the specified color
|
||||||
//
|
//
|
||||||
inline bool InterferesWithColor(const LiveRange& LR, unsigned color) {
|
inline bool InterferesWithColor(const V9LiveRange& LR, unsigned color) {
|
||||||
IGNode* lrNode = LR.getUserIGNode();
|
IGNode* lrNode = LR.getUserIGNode();
|
||||||
for (unsigned n=0, NN = lrNode->getNumOfNeighbors(); n < NN; n++) {
|
for (unsigned n=0, NN = lrNode->getNumOfNeighbors(); n < NN; n++) {
|
||||||
LiveRange *neighLR = lrNode->getAdjIGNode(n)->getParentLR();
|
V9LiveRange *neighLR = lrNode->getAdjIGNode(n)->getParentLR();
|
||||||
if (neighLR->hasColor() && neighLR->getColor() == color)
|
if (neighLR->hasColor() && neighLR->getColor() == color)
|
||||||
return true;
|
return true;
|
||||||
if (neighLR->hasSuggestedColor() && neighLR->getSuggestedColor() == color)
|
if (neighLR->hasSuggestedColor() && neighLR->getSuggestedColor() == color)
|
||||||
@ -296,8 +296,8 @@ inline bool InterferesWithColor(const LiveRange& LR, unsigned color) {
|
|||||||
// (3) LR1 has color and LR2 interferes with any LR that has the same color
|
// (3) LR1 has color and LR2 interferes with any LR that has the same color
|
||||||
// (4) LR2 has color and LR1 interferes with any LR that has the same color
|
// (4) LR2 has color and LR1 interferes with any LR that has the same color
|
||||||
//
|
//
|
||||||
inline bool InterfsPreventCoalescing(const LiveRange& LROfDef,
|
inline bool InterfsPreventCoalescing(const V9LiveRange& LROfDef,
|
||||||
const LiveRange& LROfUse) {
|
const V9LiveRange& LROfUse) {
|
||||||
// (4) if they have different suggested colors, cannot coalesce
|
// (4) if they have different suggested colors, cannot coalesce
|
||||||
if (LROfDef.hasSuggestedColor() && LROfUse.hasSuggestedColor())
|
if (LROfDef.hasSuggestedColor() && LROfUse.hasSuggestedColor())
|
||||||
return true;
|
return true;
|
||||||
@ -341,13 +341,13 @@ void LiveRangeInfo::coalesceLRs()
|
|||||||
for(MachineInstr::const_val_op_iterator DefI = MI->begin(),
|
for(MachineInstr::const_val_op_iterator DefI = MI->begin(),
|
||||||
DefE = MI->end(); DefI != DefE; ++DefI) {
|
DefE = MI->end(); DefI != DefE; ++DefI) {
|
||||||
if (DefI.isDef()) { // this operand is modified
|
if (DefI.isDef()) { // this operand is modified
|
||||||
LiveRange *LROfDef = getLiveRangeForValue( *DefI );
|
V9LiveRange *LROfDef = getLiveRangeForValue( *DefI );
|
||||||
RegClass *RCOfDef = LROfDef->getRegClass();
|
RegClass *RCOfDef = LROfDef->getRegClass();
|
||||||
|
|
||||||
MachineInstr::const_val_op_iterator UseI = MI->begin(),
|
MachineInstr::const_val_op_iterator UseI = MI->begin(),
|
||||||
UseE = MI->end();
|
UseE = MI->end();
|
||||||
for( ; UseI != UseE; ++UseI) { // for all uses
|
for( ; UseI != UseE; ++UseI) { // for all uses
|
||||||
LiveRange *LROfUse = getLiveRangeForValue( *UseI );
|
V9LiveRange *LROfUse = getLiveRangeForValue( *UseI );
|
||||||
if (!LROfUse) { // if LR of use is not found
|
if (!LROfUse) { // if LR of use is not found
|
||||||
//don't warn about labels
|
//don't warn about labels
|
||||||
if (!isa<BasicBlock>(*UseI) && DEBUG_RA >= RA_DEBUG_LiveRanges)
|
if (!isa<BasicBlock>(*UseI) && DEBUG_RA >= RA_DEBUG_LiveRanges)
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class LiveRange;
|
class V9LiveRange;
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class RegClass;
|
class RegClass;
|
||||||
class SparcV9RegInfo;
|
class SparcV9RegInfo;
|
||||||
@ -40,7 +40,7 @@ class Value;
|
|||||||
class Function;
|
class Function;
|
||||||
class Instruction;
|
class Instruction;
|
||||||
|
|
||||||
typedef hash_map<const Value*, LiveRange*> LiveRangeMapType;
|
typedef hash_map<const Value*, V9LiveRange*> LiveRangeMapType;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// Class LiveRangeInfo
|
// Class LiveRangeInfo
|
||||||
@ -51,7 +51,7 @@ typedef hash_map<const Value*, LiveRange*> LiveRangeMapType;
|
|||||||
|
|
||||||
class LiveRangeInfo {
|
class LiveRangeInfo {
|
||||||
const Function *const Meth; // Func for which live range info is held
|
const Function *const Meth; // Func for which live range info is held
|
||||||
LiveRangeMapType LiveRangeMap; // A map from Value * to LiveRange * to
|
LiveRangeMapType LiveRangeMap; // A map from Value * to V9LiveRange * to
|
||||||
// record all live ranges in a method
|
// record all live ranges in a method
|
||||||
// created by constructLiveRanges
|
// created by constructLiveRanges
|
||||||
|
|
||||||
@ -65,14 +65,14 @@ class LiveRangeInfo {
|
|||||||
|
|
||||||
//------------ Private methods (see LiveRangeInfo.cpp for description)-------
|
//------------ Private methods (see LiveRangeInfo.cpp for description)-------
|
||||||
|
|
||||||
LiveRange* createNewLiveRange (const Value* Def,
|
V9LiveRange* createNewLiveRange (const Value* Def,
|
||||||
bool isCC = false);
|
bool isCC = false);
|
||||||
|
|
||||||
LiveRange* createOrAddToLiveRange (const Value* Def,
|
V9LiveRange* createOrAddToLiveRange (const Value* Def,
|
||||||
bool isCC = false);
|
bool isCC = false);
|
||||||
|
|
||||||
void unionAndUpdateLRs (LiveRange *L1,
|
void unionAndUpdateLRs (V9LiveRange *L1,
|
||||||
LiveRange *L2);
|
V9LiveRange *L2);
|
||||||
|
|
||||||
void suggestRegs4CallRets ();
|
void suggestRegs4CallRets ();
|
||||||
public:
|
public:
|
||||||
@ -82,7 +82,7 @@ public:
|
|||||||
std::vector<RegClass *> & RCList);
|
std::vector<RegClass *> & RCList);
|
||||||
|
|
||||||
|
|
||||||
/// Destructor to destroy all LiveRanges in the LiveRange Map
|
/// Destructor to destroy all LiveRanges in the V9LiveRange Map
|
||||||
///
|
///
|
||||||
~LiveRangeInfo();
|
~LiveRangeInfo();
|
||||||
|
|
||||||
@ -98,10 +98,10 @@ public:
|
|||||||
/// Method used to get the live range containing a Value.
|
/// Method used to get the live range containing a Value.
|
||||||
/// This may return NULL if no live range exists for a Value (eg, some consts)
|
/// This may return NULL if no live range exists for a Value (eg, some consts)
|
||||||
///
|
///
|
||||||
inline LiveRange *getLiveRangeForValue(const Value *Val) {
|
inline V9LiveRange *getLiveRangeForValue(const Value *Val) {
|
||||||
return LiveRangeMap[Val];
|
return LiveRangeMap[Val];
|
||||||
}
|
}
|
||||||
inline const LiveRange *getLiveRangeForValue(const Value *Val) const {
|
inline const V9LiveRange *getLiveRangeForValue(const Value *Val) const {
|
||||||
LiveRangeMapType::const_iterator I = LiveRangeMap.find(Val);
|
LiveRangeMapType::const_iterator I = LiveRangeMap.find(Val);
|
||||||
return I->second;
|
return I->second;
|
||||||
}
|
}
|
||||||
|
@ -92,10 +92,10 @@ construction is complete, there is a live range for all variables defined in
|
|||||||
the instruction stream. Note however that, live ranges are not constructed for
|
the instruction stream. Note however that, live ranges are not constructed for
|
||||||
constants which are not defined in the instruction stream.
|
constants which are not defined in the instruction stream.
|
||||||
|
|
||||||
A LiveRange is a set of Values (only defs) in that live range. Live range
|
A V9LiveRange is a set of Values (only defs) in that live range. Live range
|
||||||
construction is done in combination for all register classes. All the live
|
construction is done in combination for all register classes. All the live
|
||||||
ranges for a method are entered to a LiveRangeMap which can be accessed using
|
ranges for a method are entered to a LiveRangeMap which can be accessed using
|
||||||
any Value in the LiveRange.
|
any Value in the V9LiveRange.
|
||||||
|
|
||||||
After live ranges have been constructed, we call machine specific code to
|
After live ranges have been constructed, we call machine specific code to
|
||||||
suggest colors for speical live ranges. For instance, incoming args, call args,
|
suggest colors for speical live ranges. For instance, incoming args, call args,
|
||||||
@ -109,7 +109,7 @@ live range does not receive the suggested color, we have to insert explicit
|
|||||||
copy instructions to move the value into requred registers and its done in
|
copy instructions to move the value into requred registers and its done in
|
||||||
step 5 above.
|
step 5 above.
|
||||||
|
|
||||||
See LiveRange.h, LiveRangeInfo.h (and LiveRange.cpp, LiveRangeInfo.cpp) for
|
See LiveRange.h, LiveRangeInfo.h (and LiveRange.cpp, LiveRangeInfo.cpp) for
|
||||||
algorithms and details. See SparcRegInfo.cpp for suggesting colors for
|
algorithms and details. See SparcRegInfo.cpp for suggesting colors for
|
||||||
incoming/call arguments and return values.
|
incoming/call arguments and return values.
|
||||||
|
|
||||||
@ -121,7 +121,7 @@ register class. Though each register class must have a separate interference
|
|||||||
graph, building all interference graphs is performed in one pass. Also, the
|
graph, building all interference graphs is performed in one pass. Also, the
|
||||||
adjacency list for each live range is built in this phase. Consequently, each
|
adjacency list for each live range is built in this phase. Consequently, each
|
||||||
register class has an interference graph (which is a bit matrix) and each
|
register class has an interference graph (which is a bit matrix) and each
|
||||||
LiveRange has an adjacency list to record its neighbors. Live variable info
|
V9LiveRange has an adjacency list to record its neighbors. Live variable info
|
||||||
is used for finding the interferences.
|
is used for finding the interferences.
|
||||||
|
|
||||||
See IGNode.h, InterferenceGraph.h (and IGNode.h, InterferenceGraph.h) for
|
See IGNode.h, InterferenceGraph.h (and IGNode.h, InterferenceGraph.h) for
|
||||||
|
@ -98,7 +98,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
|
|||||||
|
|
||||||
for (; HMI != HMIEnd ; ++HMI ) {
|
for (; HMI != HMIEnd ; ++HMI ) {
|
||||||
if (HMI->first) {
|
if (HMI->first) {
|
||||||
LiveRange *L = HMI->second; // get the LiveRange
|
V9LiveRange *L = HMI->second; // get the V9LiveRange
|
||||||
if (!L) {
|
if (!L) {
|
||||||
if (DEBUG_RA && !isa<ConstantIntegral> (HMI->first))
|
if (DEBUG_RA && !isa<ConstantIntegral> (HMI->first))
|
||||||
std::cerr << "\n**** ?!?WARNING: NULL LIVE RANGE FOUND FOR: "
|
std::cerr << "\n**** ?!?WARNING: NULL LIVE RANGE FOUND FOR: "
|
||||||
@ -133,7 +133,7 @@ void PhyRegAlloc::addInterference(const Value *Def, const ValueSet *LVSet,
|
|||||||
ValueSet::const_iterator LIt = LVSet->begin();
|
ValueSet::const_iterator LIt = LVSet->begin();
|
||||||
|
|
||||||
// get the live range of instruction
|
// get the live range of instruction
|
||||||
const LiveRange *const LROfDef = LRI->getLiveRangeForValue( Def );
|
const V9LiveRange *const LROfDef = LRI->getLiveRangeForValue( Def );
|
||||||
|
|
||||||
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
||||||
assert( IGNodeOfDef );
|
assert( IGNodeOfDef );
|
||||||
@ -147,7 +147,7 @@ void PhyRegAlloc::addInterference(const Value *Def, const ValueSet *LVSet,
|
|||||||
std::cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
|
std::cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
|
||||||
|
|
||||||
// get the live range corresponding to live var
|
// get the live range corresponding to live var
|
||||||
LiveRange *LROfVar = LRI->getLiveRangeForValue(*LIt);
|
V9LiveRange *LROfVar = LRI->getLiveRangeForValue(*LIt);
|
||||||
|
|
||||||
// LROfVar can be null if it is a const since a const
|
// LROfVar can be null if it is a const since a const
|
||||||
// doesn't have a dominating def - see Assumptions above
|
// doesn't have a dominating def - see Assumptions above
|
||||||
@ -174,7 +174,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
LIt != LEnd; ++LIt) {
|
LIt != LEnd; ++LIt) {
|
||||||
|
|
||||||
// get the live range corresponding to live var
|
// get the live range corresponding to live var
|
||||||
LiveRange *const LR = LRI->getLiveRangeForValue(*LIt);
|
V9LiveRange *const LR = LRI->getLiveRangeForValue(*LIt);
|
||||||
|
|
||||||
// LR 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
|
// doesn't have a dominating def - see Assumptions above
|
||||||
@ -195,7 +195,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
CallArgsDescriptor* argDesc = CallArgsDescriptor::get(MInst);
|
CallArgsDescriptor* argDesc = CallArgsDescriptor::get(MInst);
|
||||||
|
|
||||||
if (const Value *RetVal = argDesc->getReturnValue()) {
|
if (const Value *RetVal = argDesc->getReturnValue()) {
|
||||||
LiveRange *RetValLR = LRI->getLiveRangeForValue( RetVal );
|
V9LiveRange *RetValLR = LRI->getLiveRangeForValue( RetVal );
|
||||||
assert( RetValLR && "No LR for RetValue of call");
|
assert( RetValLR && "No LR for RetValue of call");
|
||||||
RetValLR->clearCallInterference();
|
RetValLR->clearCallInterference();
|
||||||
}
|
}
|
||||||
@ -203,7 +203,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
// If the CALL is an indirect call, find the LR of the function pointer.
|
// If the CALL is an indirect call, find the LR of the function pointer.
|
||||||
// That has a call interference because it conflicts with outgoing args.
|
// That has a call interference because it conflicts with outgoing args.
|
||||||
if (const Value *AddrVal = argDesc->getIndirectFuncPtr()) {
|
if (const Value *AddrVal = argDesc->getIndirectFuncPtr()) {
|
||||||
LiveRange *AddrValLR = LRI->getLiveRangeForValue( AddrVal );
|
V9LiveRange *AddrValLR = LRI->getLiveRangeForValue( AddrVal );
|
||||||
// LR can be null if the function pointer is a constant.
|
// LR can be null if the function pointer is a constant.
|
||||||
if (AddrValLR)
|
if (AddrValLR)
|
||||||
AddrValLR->setCallInterference();
|
AddrValLR->setCallInterference();
|
||||||
@ -254,7 +254,7 @@ void PhyRegAlloc::buildInterferenceGraphs() {
|
|||||||
addInterference(*OpI, &LVSetAI, isCallInst);
|
addInterference(*OpI, &LVSetAI, isCallInst);
|
||||||
|
|
||||||
// Calculate the spill cost of each live range
|
// Calculate the spill cost of each live range
|
||||||
LiveRange *LR = LRI->getLiveRangeForValue(*OpI);
|
V9LiveRange *LR = LRI->getLiveRangeForValue(*OpI);
|
||||||
if (LR) LR->addSpillCost(BBLoopDepthCost);
|
if (LR) LR->addSpillCost(BBLoopDepthCost);
|
||||||
}
|
}
|
||||||
// Also add interference for any implicit definitions in a machine
|
// Also add interference for any implicit definitions in a machine
|
||||||
@ -284,12 +284,12 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
// iterate over MI operands to find defs
|
// iterate over MI operands to find defs
|
||||||
for (MachineInstr::const_val_op_iterator It1 = MInst->begin(),
|
for (MachineInstr::const_val_op_iterator It1 = MInst->begin(),
|
||||||
ItE = MInst->end(); It1 != ItE; ++It1) {
|
ItE = MInst->end(); It1 != ItE; ++It1) {
|
||||||
const LiveRange *LROfOp1 = LRI->getLiveRangeForValue(*It1);
|
const V9LiveRange *LROfOp1 = LRI->getLiveRangeForValue(*It1);
|
||||||
assert((LROfOp1 || It1.isDef()) && "No LR for Def in PSEUDO insruction");
|
assert((LROfOp1 || It1.isDef()) && "No LR for Def in PSEUDO insruction");
|
||||||
|
|
||||||
MachineInstr::const_val_op_iterator It2 = It1;
|
MachineInstr::const_val_op_iterator It2 = It1;
|
||||||
for (++It2; It2 != ItE; ++It2) {
|
for (++It2; It2 != ItE; ++It2) {
|
||||||
const LiveRange *LROfOp2 = LRI->getLiveRangeForValue(*It2);
|
const V9LiveRange *LROfOp2 = LRI->getLiveRangeForValue(*It2);
|
||||||
|
|
||||||
if (LROfOp2) {
|
if (LROfOp2) {
|
||||||
RegClass *RCOfOp1 = LROfOp1->getRegClass();
|
RegClass *RCOfOp1 = LROfOp1->getRegClass();
|
||||||
@ -398,7 +398,7 @@ bool PhyRegAlloc::markAllocatedRegs(MachineInstr* MInst)
|
|||||||
if (Op.getType() == MachineOperand::MO_VirtualRegister ||
|
if (Op.getType() == MachineOperand::MO_VirtualRegister ||
|
||||||
Op.getType() == MachineOperand::MO_CCRegister) {
|
Op.getType() == MachineOperand::MO_CCRegister) {
|
||||||
const Value *const Val = Op.getVRegValue();
|
const Value *const Val = Op.getVRegValue();
|
||||||
if (const LiveRange* LR = LRI->getLiveRangeForValue(Val)) {
|
if (const V9LiveRange* LR = LRI->getLiveRangeForValue(Val)) {
|
||||||
// Remember if any operand needs spilling
|
// Remember if any operand needs spilling
|
||||||
instrNeedsSpills |= LR->isMarkedForSpill();
|
instrNeedsSpills |= LR->isMarkedForSpill();
|
||||||
|
|
||||||
@ -456,7 +456,7 @@ void PhyRegAlloc::updateInstruction(MachineBasicBlock::iterator& MII,
|
|||||||
if (Op.getType() == MachineOperand::MO_VirtualRegister ||
|
if (Op.getType() == MachineOperand::MO_VirtualRegister ||
|
||||||
Op.getType() == MachineOperand::MO_CCRegister) {
|
Op.getType() == MachineOperand::MO_CCRegister) {
|
||||||
const Value* Val = Op.getVRegValue();
|
const Value* Val = Op.getVRegValue();
|
||||||
if (const LiveRange *LR = LRI->getLiveRangeForValue(Val))
|
if (const V9LiveRange *LR = LRI->getLiveRangeForValue(Val))
|
||||||
if (LR->isMarkedForSpill())
|
if (LR->isMarkedForSpill())
|
||||||
insertCode4SpilledLR(LR, MII, MBB, OpNum);
|
insertCode4SpilledLR(LR, MII, MBB, OpNum);
|
||||||
}
|
}
|
||||||
@ -609,7 +609,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
/// instruction. Then it uses this register temporarily to accommodate the
|
/// instruction. Then it uses this register temporarily to accommodate the
|
||||||
/// spilled value.
|
/// spilled value.
|
||||||
///
|
///
|
||||||
void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
void PhyRegAlloc::insertCode4SpilledLR(const V9LiveRange *LR,
|
||||||
MachineBasicBlock::iterator& MII,
|
MachineBasicBlock::iterator& MII,
|
||||||
MachineBasicBlock &MBB,
|
MachineBasicBlock &MBB,
|
||||||
const unsigned OpNum) {
|
const unsigned OpNum) {
|
||||||
@ -754,7 +754,7 @@ PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore,
|
|||||||
assert(tmpRetVal->getOperand(0) == origRetVal &&
|
assert(tmpRetVal->getOperand(0) == origRetVal &&
|
||||||
tmpRetVal->getType() == origRetVal->getType() &&
|
tmpRetVal->getType() == origRetVal->getType() &&
|
||||||
"Wrong implicit ref?");
|
"Wrong implicit ref?");
|
||||||
LiveRange *RetValLR = LRI->getLiveRangeForValue(tmpRetVal);
|
V9LiveRange *RetValLR = LRI->getLiveRangeForValue(tmpRetVal);
|
||||||
assert(RetValLR && "No LR for RetValue of call");
|
assert(RetValLR && "No LR for RetValue of call");
|
||||||
|
|
||||||
if (! RetValLR->isMarkedForSpill())
|
if (! RetValLR->isMarkedForSpill())
|
||||||
@ -768,7 +768,7 @@ PhyRegAlloc::insertCallerSavingCode(std::vector<MachineInstr*> &instrnsBefore,
|
|||||||
// for each live var in live variable set after machine inst
|
// for each live var in live variable set after machine inst
|
||||||
for( ; LIt != LVSetAft.end(); ++LIt) {
|
for( ; LIt != LVSetAft.end(); ++LIt) {
|
||||||
// get the live range corresponding to live var
|
// get the live range corresponding to live var
|
||||||
LiveRange *const LR = LRI->getLiveRangeForValue(*LIt);
|
V9LiveRange *const LR = LRI->getLiveRangeForValue(*LIt);
|
||||||
|
|
||||||
// LR 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
|
// doesn't have a dominating def - see Assumptions above
|
||||||
@ -945,7 +945,7 @@ int PhyRegAlloc::getUnusedUniRegAtMI(RegClass *RC, const int RegType,
|
|||||||
// for each live var in live variable set after machine inst
|
// for each live var in live variable set after machine inst
|
||||||
for ( ; LIt != LVSetBef->end(); ++LIt) {
|
for ( ; LIt != LVSetBef->end(); ++LIt) {
|
||||||
// Get the live range corresponding to live var, and its RegClass
|
// Get the live range corresponding to live var, and its RegClass
|
||||||
LiveRange *const LRofLV = LRI->getLiveRangeForValue(*LIt );
|
V9LiveRange *const LRofLV = LRI->getLiveRangeForValue(*LIt );
|
||||||
|
|
||||||
// LR 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
|
// doesn't have a dominating def - see Assumptions above
|
||||||
@ -1023,7 +1023,7 @@ void PhyRegAlloc::setRelRegsUsedByThisInst(RegClass *RC, int RegType,
|
|||||||
|
|
||||||
// If there are implicit references, mark their allocated regs as well
|
// If there are implicit references, mark their allocated regs as well
|
||||||
for (unsigned z=0; z < MI->getNumImplicitRefs(); z++)
|
for (unsigned z=0; z < MI->getNumImplicitRefs(); z++)
|
||||||
if (const LiveRange*
|
if (const V9LiveRange*
|
||||||
LRofImpRef = LRI->getLiveRangeForValue(MI->getImplicitRef(z)))
|
LRofImpRef = LRI->getLiveRangeForValue(MI->getImplicitRef(z)))
|
||||||
if (LRofImpRef->hasColor())
|
if (LRofImpRef->hasColor())
|
||||||
// this implicit reference is in a LR that received a color
|
// this implicit reference is in a LR that received a color
|
||||||
@ -1080,7 +1080,7 @@ void PhyRegAlloc::markUnusableSugColors()
|
|||||||
|
|
||||||
for (; HMI != HMIEnd ; ++HMI ) {
|
for (; HMI != HMIEnd ; ++HMI ) {
|
||||||
if (HMI->first) {
|
if (HMI->first) {
|
||||||
LiveRange *L = HMI->second; // get the LiveRange
|
V9LiveRange *L = HMI->second; // get the V9LiveRange
|
||||||
if (L && L->hasSuggestedColor ())
|
if (L && L->hasSuggestedColor ())
|
||||||
L->setSuggestedColorUsable
|
L->setSuggestedColorUsable
|
||||||
(!(MRI.isRegVolatile (L->getRegClassID (), L->getSuggestedColor ())
|
(!(MRI.isRegVolatile (L->getRegClassID (), L->getSuggestedColor ())
|
||||||
@ -1102,7 +1102,7 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs() {
|
|||||||
|
|
||||||
for ( ; HMI != HMIEnd ; ++HMI) {
|
for ( ; HMI != HMIEnd ; ++HMI) {
|
||||||
if (HMI->first && HMI->second) {
|
if (HMI->first && HMI->second) {
|
||||||
LiveRange *L = HMI->second; // get the LiveRange
|
V9LiveRange *L = HMI->second; // get the V9LiveRange
|
||||||
if (L->isMarkedForSpill()) { // NOTE: allocating size of long Type **
|
if (L->isMarkedForSpill()) { // NOTE: allocating size of long Type **
|
||||||
int stackOffset = MF->getInfo<SparcV9FunctionInfo>()->allocateSpilledValue(Type::LongTy);
|
int stackOffset = MF->getInfo<SparcV9FunctionInfo>()->allocateSpilledValue(Type::LongTy);
|
||||||
L->setSpillOffFromFP(stackOffset);
|
L->setSpillOffFromFP(stackOffset);
|
||||||
@ -1122,7 +1122,7 @@ void PhyRegAlloc::saveStateForValue (std::vector<AllocInfo> &state,
|
|||||||
AllocInfo::AllocStateTy AllocState = AllocInfo::NotAllocated;
|
AllocInfo::AllocStateTy AllocState = AllocInfo::NotAllocated;
|
||||||
int Placement = -1;
|
int Placement = -1;
|
||||||
if ((HMI != HMIEnd) && HMI->second) {
|
if ((HMI != HMIEnd) && HMI->second) {
|
||||||
LiveRange *L = HMI->second;
|
V9LiveRange *L = HMI->second;
|
||||||
assert ((L->hasColor () || L->isMarkedForSpill ())
|
assert ((L->hasColor () || L->isMarkedForSpill ())
|
||||||
&& "Live range exists but not colored or spilled");
|
&& "Live range exists but not colored or spilled");
|
||||||
if (L->hasColor ()) {
|
if (L->hasColor ()) {
|
||||||
|
@ -139,7 +139,7 @@ private:
|
|||||||
void markUnusableSugColors();
|
void markUnusableSugColors();
|
||||||
void allocateStackSpace4SpilledLRs();
|
void allocateStackSpace4SpilledLRs();
|
||||||
|
|
||||||
void insertCode4SpilledLR(const LiveRange *LR,
|
void insertCode4SpilledLR(const V9LiveRange *LR,
|
||||||
MachineBasicBlock::iterator& MII,
|
MachineBasicBlock::iterator& MII,
|
||||||
MachineBasicBlock &MBB, unsigned OpNum);
|
MachineBasicBlock &MBB, unsigned OpNum);
|
||||||
|
|
||||||
|
@ -197,11 +197,11 @@ void RegClass::colorIGNode(IGNode *const Node) {
|
|||||||
clearColorsUsed();
|
clearColorsUsed();
|
||||||
|
|
||||||
// initialize all colors used by neighbors of this node to true
|
// initialize all colors used by neighbors of this node to true
|
||||||
LiveRange *LR = Node->getParentLR();
|
V9LiveRange *LR = Node->getParentLR();
|
||||||
unsigned NumNeighbors = Node->getNumOfNeighbors();
|
unsigned NumNeighbors = Node->getNumOfNeighbors();
|
||||||
for (unsigned n=0; n < NumNeighbors; n++) {
|
for (unsigned n=0; n < NumNeighbors; n++) {
|
||||||
IGNode *NeighIGNode = Node->getAdjIGNode(n);
|
IGNode *NeighIGNode = Node->getAdjIGNode(n);
|
||||||
LiveRange *NeighLR = NeighIGNode->getParentLR();
|
V9LiveRange *NeighLR = NeighIGNode->getParentLR();
|
||||||
|
|
||||||
// Don't use a color if it is in use by the neighbor,
|
// Don't use a color if it is in use by the neighbor,
|
||||||
// or is suggested for use by the neighbor,
|
// or is suggested for use by the neighbor,
|
||||||
|
@ -109,19 +109,19 @@ class RegClass {
|
|||||||
// --- following methods are provided to access the IG contained within this
|
// --- following methods are provided to access the IG contained within this
|
||||||
// ---- RegClass easilly.
|
// ---- RegClass easilly.
|
||||||
|
|
||||||
inline void addLRToIG(LiveRange *const LR)
|
inline void addLRToIG(V9LiveRange *const LR)
|
||||||
{ IG.addLRToIG(LR); }
|
{ IG.addLRToIG(LR); }
|
||||||
|
|
||||||
inline void setInterference(const LiveRange *const LR1,
|
inline void setInterference(const V9LiveRange *const LR1,
|
||||||
const LiveRange *const LR2)
|
const V9LiveRange *const LR2)
|
||||||
{ IG.setInterference(LR1, LR2); }
|
{ IG.setInterference(LR1, LR2); }
|
||||||
|
|
||||||
inline unsigned getInterference(const LiveRange *const LR1,
|
inline unsigned getInterference(const V9LiveRange *const LR1,
|
||||||
const LiveRange *const LR2) const
|
const V9LiveRange *const LR2) const
|
||||||
{ return IG.getInterference(LR1, LR2); }
|
{ return IG.getInterference(LR1, LR2); }
|
||||||
|
|
||||||
inline void mergeIGNodesOfLRs(const LiveRange *const LR1,
|
inline void mergeIGNodesOfLRs(const V9LiveRange *const LR1,
|
||||||
LiveRange *const LR2)
|
V9LiveRange *const LR2)
|
||||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class LiveRange;
|
class V9LiveRange;
|
||||||
class SparcV9TargetMachine;
|
class SparcV9TargetMachine;
|
||||||
class ModulePass;
|
class ModulePass;
|
||||||
class GetElementPtrInst;
|
class GetElementPtrInst;
|
||||||
|
@ -39,7 +39,7 @@ namespace llvm {
|
|||||||
void SparcV9IntRegClass::colorIGNode(IGNode * Node,
|
void SparcV9IntRegClass::colorIGNode(IGNode * Node,
|
||||||
const std::vector<bool> &IsColorUsedArr) const
|
const std::vector<bool> &IsColorUsedArr) const
|
||||||
{
|
{
|
||||||
LiveRange *LR = Node->getParentLR();
|
V9LiveRange *LR = Node->getParentLR();
|
||||||
|
|
||||||
if (DEBUG_RA)
|
if (DEBUG_RA)
|
||||||
std::cerr << "\nColoring LR [CallInt=" << LR->isCallInterference() <<"]:"
|
std::cerr << "\nColoring LR [CallInt=" << LR->isCallInterference() <<"]:"
|
||||||
@ -152,7 +152,7 @@ void SparcV9IntCCRegClass::colorIGNode(IGNode *Node,
|
|||||||
// spill algorithm cannot find it. In particular, we have to choose
|
// spill algorithm cannot find it. In particular, we have to choose
|
||||||
// whether to use %xcc or %icc based on type of value compared
|
// whether to use %xcc or %icc based on type of value compared
|
||||||
//
|
//
|
||||||
const LiveRange* ccLR = Node->getParentLR();
|
const V9LiveRange* ccLR = Node->getParentLR();
|
||||||
const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
|
const Type* setCCType = (* ccLR->begin())->getType(); // any Value in LR
|
||||||
assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
|
assert(setCCType->isIntegral() || isa<PointerType>(setCCType));
|
||||||
int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
|
int ccReg = ((isa<PointerType>(setCCType) || setCCType == Type::LongTy)
|
||||||
@ -161,7 +161,7 @@ void SparcV9IntCCRegClass::colorIGNode(IGNode *Node,
|
|||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Let's just make sure values of two different types have not been
|
// Let's just make sure values of two different types have not been
|
||||||
// coalesced into this LR.
|
// coalesced into this LR.
|
||||||
for (LiveRange::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
|
for (V9LiveRange::const_iterator I=ccLR->begin(), E=ccLR->end(); I!=E; ++I) {
|
||||||
const Type* ccType = (*I)->getType();
|
const Type* ccType = (*I)->getType();
|
||||||
assert((ccReg == xcc && (isa<PointerType>(ccType)
|
assert((ccReg == xcc && (isa<PointerType>(ccType)
|
||||||
|| ccType == Type::LongTy)) ||
|
|| ccType == Type::LongTy)) ||
|
||||||
@ -205,7 +205,7 @@ void SparcV9FloatCCRegClass::colorIGNode(IGNode *Node,
|
|||||||
void SparcV9FloatRegClass::colorIGNode(IGNode * Node,
|
void SparcV9FloatRegClass::colorIGNode(IGNode * Node,
|
||||||
const std::vector<bool> &IsColorUsedArr) const
|
const std::vector<bool> &IsColorUsedArr) const
|
||||||
{
|
{
|
||||||
LiveRange *LR = Node->getParentLR();
|
V9LiveRange *LR = Node->getParentLR();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// Check that the correct colors have been are marked for fp-doubles.
|
// Check that the correct colors have been are marked for fp-doubles.
|
||||||
@ -222,7 +222,7 @@ void SparcV9FloatRegClass::colorIGNode(IGNode * Node,
|
|||||||
unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
|
unsigned NumNeighbors = Node->getNumOfNeighbors(); // total # of neighbors
|
||||||
for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
|
for(unsigned n=0; n < NumNeighbors; n++) { // for each neigh
|
||||||
IGNode *NeighIGNode = Node->getAdjIGNode(n);
|
IGNode *NeighIGNode = Node->getAdjIGNode(n);
|
||||||
LiveRange *NeighLR = NeighIGNode->getParentLR();
|
V9LiveRange *NeighLR = NeighIGNode->getParentLR();
|
||||||
|
|
||||||
if (NeighLR->hasColor()) {
|
if (NeighLR->hasColor()) {
|
||||||
assert(IsColorUsedArr[ NeighLR->getColor() ]);
|
assert(IsColorUsedArr[ NeighLR->getColor() ]);
|
||||||
@ -369,7 +369,7 @@ int SparcV9FloatRegClass::findUnusedColor(int RegTypeWanted,
|
|||||||
// type of the Node (i.e., float/double)
|
// type of the Node (i.e., float/double)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
int SparcV9FloatRegClass::findFloatColor(const LiveRange *LR,
|
int SparcV9FloatRegClass::findFloatColor(const V9LiveRange *LR,
|
||||||
unsigned Start,
|
unsigned Start,
|
||||||
unsigned End,
|
unsigned End,
|
||||||
const std::vector<bool> &IsColorUsedArr) const
|
const std::vector<bool> &IsColorUsedArr) const
|
||||||
|
@ -89,7 +89,7 @@ struct SparcV9IntRegClass : public TargetRegClassInfo {
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
class SparcV9FloatRegClass : public TargetRegClassInfo {
|
class SparcV9FloatRegClass : public TargetRegClassInfo {
|
||||||
int findFloatColor(const LiveRange *LR, unsigned Start,
|
int findFloatColor(const V9LiveRange *LR, unsigned Start,
|
||||||
unsigned End,
|
unsigned End,
|
||||||
const std::vector<bool> &IsColorUsedArr) const;
|
const std::vector<bool> &IsColorUsedArr) const;
|
||||||
public:
|
public:
|
||||||
|
@ -221,7 +221,7 @@ SparcV9RegInfo::regNumForFPArg(unsigned regType,
|
|||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
// The following 4 methods are used to find the RegType (SparcV9Internals.h)
|
// The following 4 methods are used to find the RegType (SparcV9Internals.h)
|
||||||
// of a LiveRange, a Value, and for a given register unified reg number.
|
// of a V9LiveRange, a Value, and for a given register unified reg number.
|
||||||
//
|
//
|
||||||
int SparcV9RegInfo::getRegTypeForClassAndType(unsigned regClassID,
|
int SparcV9RegInfo::getRegTypeForClassAndType(unsigned regClassID,
|
||||||
const Type* type) const
|
const Type* type) const
|
||||||
@ -244,7 +244,7 @@ int SparcV9RegInfo::getRegTypeForDataType(const Type* type) const
|
|||||||
return getRegTypeForClassAndType(getRegClassIDOfType(type), type);
|
return getRegTypeForClassAndType(getRegClassIDOfType(type), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SparcV9RegInfo::getRegTypeForLR(const LiveRange *LR) const
|
int SparcV9RegInfo::getRegTypeForLR(const V9LiveRange *LR) const
|
||||||
{
|
{
|
||||||
return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType());
|
return getRegTypeForClassAndType(LR->getRegClassID(), LR->getType());
|
||||||
}
|
}
|
||||||
@ -330,7 +330,7 @@ void SparcV9RegInfo::suggestReg4RetAddr(MachineInstr *RetMI,
|
|||||||
// MachineOperand & MO = RetMI->getOperand(0);
|
// MachineOperand & MO = RetMI->getOperand(0);
|
||||||
// const Value *RetAddrVal = MO.getVRegValue();
|
// const Value *RetAddrVal = MO.getVRegValue();
|
||||||
// assert( RetAddrVal && "LR for ret address must be created at start");
|
// assert( RetAddrVal && "LR for ret address must be created at start");
|
||||||
// LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);
|
// V9LiveRange * RetAddrLR = LRI.getLiveRangeForValue( RetAddrVal);
|
||||||
// RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID,
|
// RetAddrLR->setSuggestedColor(getUnifiedRegNum( IntRegClassID,
|
||||||
// SparcV9IntRegOrdr::i7) );
|
// SparcV9IntRegOrdr::i7) );
|
||||||
}
|
}
|
||||||
@ -349,7 +349,7 @@ SparcV9RegInfo::suggestReg4CallAddr(MachineInstr * CallMI,
|
|||||||
assert(RetAddrVal && "INTERNAL ERROR: Return address value is required");
|
assert(RetAddrVal && "INTERNAL ERROR: Return address value is required");
|
||||||
|
|
||||||
// A LR must already exist for the return address.
|
// A LR must already exist for the return address.
|
||||||
LiveRange *RetAddrLR = LRI.getLiveRangeForValue(RetAddrVal);
|
V9LiveRange *RetAddrLR = LRI.getLiveRangeForValue(RetAddrVal);
|
||||||
assert(RetAddrLR && "INTERNAL ERROR: No LR for return address of call!");
|
assert(RetAddrLR && "INTERNAL ERROR: No LR for return address of call!");
|
||||||
|
|
||||||
unsigned RegClassID = RetAddrLR->getRegClassID();
|
unsigned RegClassID = RetAddrLR->getRegClassID();
|
||||||
@ -376,7 +376,7 @@ void SparcV9RegInfo::suggestRegs4MethodArgs(const Function *Meth,
|
|||||||
unsigned argNo=0;
|
unsigned argNo=0;
|
||||||
for(Function::const_arg_iterator I = Meth->arg_begin(), E = Meth->arg_end();
|
for(Function::const_arg_iterator I = Meth->arg_begin(), E = Meth->arg_end();
|
||||||
I != E; ++I, ++argNo) {
|
I != E; ++I, ++argNo) {
|
||||||
LiveRange *LR = LRI.getLiveRangeForValue(I);
|
V9LiveRange *LR = LRI.getLiveRangeForValue(I);
|
||||||
assert(LR && "No live range found for method arg");
|
assert(LR && "No live range found for method arg");
|
||||||
|
|
||||||
unsigned regType = getRegTypeForLR(LR);
|
unsigned regType = getRegTypeForLR(LR);
|
||||||
@ -413,7 +413,7 @@ void SparcV9RegInfo::colorMethodArgs(const Function *Meth,
|
|||||||
for(Function::const_arg_iterator I = Meth->arg_begin(), E = Meth->arg_end();
|
for(Function::const_arg_iterator I = Meth->arg_begin(), E = Meth->arg_end();
|
||||||
I != E; ++I, ++argNo) {
|
I != E; ++I, ++argNo) {
|
||||||
// get the LR of arg
|
// get the LR of arg
|
||||||
LiveRange *LR = LRI.getLiveRangeForValue(I);
|
V9LiveRange *LR = LRI.getLiveRangeForValue(I);
|
||||||
assert( LR && "No live range found for method arg");
|
assert( LR && "No live range found for method arg");
|
||||||
|
|
||||||
unsigned regType = getRegTypeForLR(LR);
|
unsigned regType = getRegTypeForLR(LR);
|
||||||
@ -584,7 +584,7 @@ void SparcV9RegInfo::suggestRegs4CallArgs(MachineInstr *CallMI,
|
|||||||
// or in %f0 if the value is a float type.
|
// or in %f0 if the value is a float type.
|
||||||
//
|
//
|
||||||
if (const Value *RetVal = argDesc->getReturnValue()) {
|
if (const Value *RetVal = argDesc->getReturnValue()) {
|
||||||
LiveRange *RetValLR = LRI.getLiveRangeForValue(RetVal);
|
V9LiveRange *RetValLR = LRI.getLiveRangeForValue(RetVal);
|
||||||
assert(RetValLR && "No LR for return Value of call!");
|
assert(RetValLR && "No LR for return Value of call!");
|
||||||
|
|
||||||
unsigned RegClassID = RetValLR->getRegClassID();
|
unsigned RegClassID = RetValLR->getRegClassID();
|
||||||
@ -610,7 +610,7 @@ void SparcV9RegInfo::suggestRegs4CallArgs(MachineInstr *CallMI,
|
|||||||
const Value *CallArg = argDesc->getArgInfo(i).getArgVal();
|
const Value *CallArg = argDesc->getArgInfo(i).getArgVal();
|
||||||
|
|
||||||
// get the LR of call operand (parameter)
|
// get the LR of call operand (parameter)
|
||||||
LiveRange *const LR = LRI.getLiveRangeForValue(CallArg);
|
V9LiveRange *const LR = LRI.getLiveRangeForValue(CallArg);
|
||||||
if (!LR)
|
if (!LR)
|
||||||
continue; // no live ranges for constants and labels
|
continue; // no live ranges for constants and labels
|
||||||
|
|
||||||
@ -651,7 +651,7 @@ void SparcV9RegInfo::suggestReg4RetValue(MachineInstr *RetMI,
|
|||||||
Value* tmpI = RetMI->getOperand(0).getVRegValue();
|
Value* tmpI = RetMI->getOperand(0).getVRegValue();
|
||||||
ReturnInst* retI=cast<ReturnInst>(cast<TmpInstruction>(tmpI)->getOperand(0));
|
ReturnInst* retI=cast<ReturnInst>(cast<TmpInstruction>(tmpI)->getOperand(0));
|
||||||
if (const Value *RetVal = retI->getReturnValue())
|
if (const Value *RetVal = retI->getReturnValue())
|
||||||
if (LiveRange *const LR = LRI.getLiveRangeForValue(RetVal))
|
if (V9LiveRange *const LR = LRI.getLiveRangeForValue(RetVal))
|
||||||
LR->setSuggestedColor(LR->getRegClassID() == IntRegClassID
|
LR->setSuggestedColor(LR->getRegClassID() == IntRegClassID
|
||||||
? (unsigned) SparcV9IntRegClass::i0
|
? (unsigned) SparcV9IntRegClass::i0
|
||||||
: (unsigned) SparcV9FloatRegClass::f0);
|
: (unsigned) SparcV9FloatRegClass::f0);
|
||||||
@ -948,7 +948,7 @@ SparcV9RegInfo::cpValue2Value(Value *Src, Value *Dest,
|
|||||||
// Print the register assigned to a LR
|
// Print the register assigned to a LR
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void SparcV9RegInfo::printReg(const LiveRange *LR) const {
|
void SparcV9RegInfo::printReg(const V9LiveRange *LR) const {
|
||||||
unsigned RegClassID = LR->getRegClassID();
|
unsigned RegClassID = LR->getRegClassID();
|
||||||
std::cerr << " Node ";
|
std::cerr << " Node ";
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ class Type;
|
|||||||
class Value;
|
class Value;
|
||||||
class LiveRangeInfo;
|
class LiveRangeInfo;
|
||||||
class Function;
|
class Function;
|
||||||
class LiveRange;
|
class V9LiveRange;
|
||||||
class AddedInstrns;
|
class AddedInstrns;
|
||||||
class MachineInstr;
|
class MachineInstr;
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
@ -324,7 +324,7 @@ public:
|
|||||||
|
|
||||||
// method used for printing a register for debugging purposes
|
// method used for printing a register for debugging purposes
|
||||||
//
|
//
|
||||||
void printReg(const LiveRange *LR) const;
|
void printReg(const V9LiveRange *LR) const;
|
||||||
|
|
||||||
// To obtain the return value and the indirect call address (if any)
|
// To obtain the return value and the indirect call address (if any)
|
||||||
// contained in a CALL machine instruction
|
// contained in a CALL machine instruction
|
||||||
@ -369,7 +369,7 @@ public:
|
|||||||
// The reg class of a LR depends both on the Value types in it and whether
|
// The reg class of a LR depends both on the Value types in it and whether
|
||||||
// they are CC registers or not (for example).
|
// they are CC registers or not (for example).
|
||||||
int getRegTypeForDataType(const Type* type) const;
|
int getRegTypeForDataType(const Type* type) const;
|
||||||
int getRegTypeForLR(const LiveRange *LR) const;
|
int getRegTypeForLR(const V9LiveRange *LR) const;
|
||||||
int getRegType(int unifiedRegNum) const;
|
int getRegType(int unifiedRegNum) const;
|
||||||
|
|
||||||
unsigned getFramePointer() const;
|
unsigned getFramePointer() const;
|
||||||
|
Reference in New Issue
Block a user