* Code Cleanups

* Introduce RAV to allow stream I/O instead of using printValue


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1710 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-02-05 01:43:49 +00:00
parent f39f379f9e
commit 0665a5f1f5
16 changed files with 300 additions and 462 deletions

View File

@ -16,7 +16,7 @@ struct LiveVarSet : public ValueSet {
// This function applies a machine instr to a live var set (accepts OutSet)
// and makes necessary changes to it (produces InSet).
//
void applyTranferFuncForMInst(const MachineInstr *const MInst);
void applyTranferFuncForMInst(const MachineInstr *MInst);
};

View File

@ -8,13 +8,20 @@
#ifndef VALUE_SET_H
#define VALUE_SET_H
class Value;
#include <set>
class Value;
// RAV - Used to print values in a form used by the register allocator.
//
struct RAV { // Register Allocator Value
const Value *V;
RAV(const Value *v) : V(v) {}
};
ostream &operator<<(ostream &out, RAV Val);
//------------------- Class Definition for ValueSet --------------------------
void printValue( const Value *v); // func to print a Value
struct ValueSet : public std::set<const Value*> {
bool setUnion( const ValueSet *const set1); // for performing set union
void setSubtract( const ValueSet *const set1); // for performing set diff

View File

@ -8,13 +8,20 @@
#ifndef VALUE_SET_H
#define VALUE_SET_H
class Value;
#include <set>
class Value;
// RAV - Used to print values in a form used by the register allocator.
//
struct RAV { // Register Allocator Value
const Value *V;
RAV(const Value *v) : V(v) {}
};
ostream &operator<<(ostream &out, RAV Val);
//------------------- Class Definition for ValueSet --------------------------
void printValue( const Value *v); // func to print a Value
struct ValueSet : public std::set<const Value*> {
bool setUnion( const ValueSet *const set1); // for performing set union
void setSubtract( const ValueSet *const set1); // for performing set diff

View File

@ -70,13 +70,9 @@ void BBLiveVar::calcDefUseSets() {
PhiArgMap[ArgVal] = cast<BasicBlock>(BBVal);
if (DEBUG_LV > 1) {
cerr << " - phi operand ";
printValue(ArgVal);
cerr << " came from BB ";
printValue(PhiArgMap[ArgVal]);
cerr << "\n";
}
if (DEBUG_LV > 1)
cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
<< RAV(PhiArgMap[ArgVal]) << "\n";
} // if( IsPhi )
} // if a use
} // for all operands
@ -105,9 +101,7 @@ void BBLiveVar::addDef(const Value *Op) {
InSet.erase(Op); // this definition kills any uses
InSetChanged = true;
if (DEBUG_LV > 1) {
cerr << " +Def: "; printValue( Op ); cerr << "\n";
}
if (DEBUG_LV > 1) cerr << " +Def: " << RAV(Op) << "\n";
}
@ -119,9 +113,7 @@ void BBLiveVar::addUse(const Value *Op) {
OutSet.erase(Op); // remove if there is a def below this use
InSetChanged = true;
if (DEBUG_LV > 1) {
cerr << " Use: "; printValue( Op ); cerr << "\n";
}
if (DEBUG_LV > 1) cerr << " Use: " << RAV(Op) << "\n";
}

View File

@ -62,7 +62,7 @@ void MethodLiveVarInfo::constructBBs(const Method *M) {
BBI != BBE; ++BBI, ++POId) {
const BasicBlock *BB = *BBI; // get the current BB
if (DEBUG_LV) { std::cerr << " For BB "; printValue(BB); cerr << ":\n"; }
if (DEBUG_LV) std::cerr << " For BB " << RAV(BB) << ":\n";
// create a new BBLiveVar
BBLiveVar *LVBB = new BBLiveVar(BB, POId);

View File

@ -1,64 +1,42 @@
#include "llvm/Analysis/LiveVar/ValueSet.h"
#include "llvm/ConstantVals.h"
#include <algorithm>
#include <iostream>
using std::cerr;
using std::endl;
using std::pair;
using std::hash_set;
void printValue(const Value *v) { // func to print a Value
ostream &operator<<(ostream &O, RAV V) { // func to print a Value
const Value *v = V.V;
if (v->hasName())
cerr << v << "(" << v->getName() << ") ";
return O << v << "(" << v->getName() << ") ";
else if (Constant *C = dyn_cast<Constant>(v))
cerr << v << "(" << C->getStrValue() << ") ";
return O << v << "(" << C->getStrValue() << ") ";
else
cerr << v << " ";
return O << v << " ";
}
bool ValueSet::setUnion( const ValueSet *S) {
bool Changed = false;
//---------------- Method implementations --------------------------
// for performing two set unions
bool ValueSet::setUnion( const ValueSet *set1) {
pair<iterator, bool> result;
bool changed = false;
for (const_iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
if (insert(*SI).second)
Changed = true;
for(const_iterator set1it = set1->begin() ; set1it != set1->end(); ++set1it) {
// for all all elements in set1
result = insert(*set1it); // insert to this set
if(result.second == true) changed = true;
}
return changed;
return Changed;
}
// for performing set difference
void ValueSet::setDifference( const ValueSet *const set1,
const ValueSet *const set2) {
const_iterator set1it, set2it;
for( set1it = set1->begin() ; set1it != set1->end(); ++set1it) {
// for all elements in set1
iterator set2it = set2->find( *set1it ); // find wether the elem is in set2
if( set2it == set2->end() ) // if the element is not in set2
insert( *set1it ); // insert to this set
}
void ValueSet::setDifference(const ValueSet *S1, const ValueSet *S2) {
for (const_iterator SI = S1->begin(), SE = S1->end() ; SI != SE; ++SI)
if (S2->find(*SI) == S2->end()) // if the element is not in set2
insert(*SI);
}
// for performing set subtraction
void ValueSet::setSubtract( const ValueSet *const set1) {
const_iterator set1it;
for( set1it = set1->begin() ; set1it != set1->end(); ++set1it)
// for all elements in set1
erase( *set1it ); // erase that element from this set
void ValueSet::setSubtract(const ValueSet *S) {
for (const_iterator SI = S->begin() ; SI != S->end(); ++SI)
erase(*SI);
}
void ValueSet::printSet() const { // for printing a live variable set
for_each(begin(), end(), printValue);
void ValueSet::printSet() const {
for (const_iterator I = begin(), E = end(); I != E; ++I)
std::cerr << RAV(*I);
}

View File

@ -1,12 +1,12 @@
/* Title: LiveRange.h -*- C++ -*-
Author: Ruchira Sasanka
Date: July 25, 01
Purpose: To keep info about a live range.
Asuumptions:
Since the Value pointed by a use is the same as of its def, it is sufficient
to keep only defs in a LiveRange.
*/
//===-- LiveRange.h - Store info about a live range --------------*- C++ -*--=//
//
// Implements a live range using a ValueSet. A LiveRange is a simple set
// of Values.
//
// Since the Value pointed by a use is the same as of its def, it is sufficient
// to keep only defs in a LiveRange.
//
//===----------------------------------------------------------------------===//
#ifndef LIVE_RANGE_H
#define LIVE_RANGE_H
@ -18,149 +18,120 @@
class RegClass;
class IGNode;
//----------------------------------------------------------------------------
// Class LiveRange
//
// Implements a live range using a ValueSet. A LiveRange is a simple set
// of Values.
//----------------------------------------------------------------------------
class LiveRange : public ValueSet {
RegClass *MyRegClass; // register classs (e.g., int, FP) for this LR
bool doesSpanAcrossCalls;
//
// Does this live range span across calls?
// doesSpanAcrossCalls - Does this live range span across calls?
// This information is used by graph
// coloring algo to avoid allocating volatile colors to live ranges
// that span across calls (since they have to be saved/restored)
//
bool doesSpanAcrossCalls;
IGNode *UserIGNode; // IGNode which uses this LR
int Color; // color assigned to this live range
bool mustSpill; // whether this LR must be spilt
// mustSaveAcrossCalls - whether this LR must be saved accross calls
// ***TODO REMOVE this
//
bool mustSaveAcrossCalls;
//
// whether this LR must be saved accross calls ***TODO REMOVE this
// SuggestedColor - if this LR has a suggested color, can it be
// really alloated? A suggested color cannot be allocated when the
// suggested color is volatile and when there are call
// interferences.
//
int SuggestedColor; // The suggested color for this LR
//
// if this LR has a suggested color, can it be really alloated?
// A suggested color cannot be allocated when the suggested color is
// volatile and when there are call interferences.
bool CanUseSuggestedCol;
// CanUseSuggestedCol - It is possible that a suggested color for
// this live range is not available before graph coloring (e.g., it
// can be allocated to another live range which interferes with
// this)
//
// It is possible that a suggested color for this live range is not
// available before graph coloring (e.g., it can be allocated to another
// live range which interferes with this)
bool CanUseSuggestedCol;
// SpilledStackOffsetFromFP - If this LR is spilled, its stack
// offset from *FP*. The spilled offsets must always be relative to
// the FP.
//
int SpilledStackOffsetFromFP;
//
// if this LR is spilled, its stack offset from *FP*. The spilled offsets
// must always be relative to the FP.
// HasSpillOffset 0 Whether this live range has a spill offset
//
bool HasSpillOffset;
//
// Whether this live range has a spill offset
unsigned SpillCost;
//
// The spill cost of this live range. Calculated using loop depth of
// each reference to each Value in the live range
public:
// constructor
//
LiveRange() : ValueSet() {
unsigned SpillCost;
public:
LiveRange() {
Color = SuggestedColor = -1; // not yet colored
mustSpill = mustSaveAcrossCalls = false;
MyRegClass = NULL;
UserIGNode = NULL;
MyRegClass = 0;
UserIGNode = 0;
doesSpanAcrossCalls = false;
CanUseSuggestedCol = true;
HasSpillOffset = false;
HasSpillOffset = false;
SpillCost = 0;
}
// empty destructor since there are nothing to be deleted
//
~LiveRange() {}
void setRegClass(RegClass *RC) { MyRegClass = RC; }
RegClass *getRegClass() const { assert(MyRegClass); return MyRegClass; }
void setRegClass(RegClass *const RC)
{ MyRegClass = RC; }
inline RegClass *const getRegClass() const
{ assert(MyRegClass); return MyRegClass; }
inline bool hasColor() const
{ return Color != -1; }
bool hasColor() const { return Color != -1; }
inline unsigned int getColor() const
{ assert( Color != -1); return (unsigned) Color ; }
unsigned getColor() const { assert(Color != -1); return (unsigned)Color; }
inline void setColor(unsigned int Col)
{ Color = (int) Col ; }
void setColor(unsigned Col) { Color = (int)Col; }
inline void setCallInterference() {
doesSpanAcrossCalls = 1;
}
inline bool isCallInterference() const {
return (doesSpanAcrossCalls == 1);
return doesSpanAcrossCalls == 1;
}
inline void markForSpill() { mustSpill = true; }
inline bool isMarkedForSpill() { return mustSpill; }
inline bool isMarkedForSpill() { return mustSpill; }
inline void setSpillOffFromFP(int StackOffset) {
assert( mustSpill && "This LR is not spilled");
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline void modifySpillOffFromFP(int StackOffset) {
assert( mustSpill && "This LR is not spilled");
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline bool hasSpillOffset() const {
return HasSpillOffset;
return HasSpillOffset;
}
inline int getSpillOffFromFP() const {
assert( HasSpillOffset && "This LR is not spilled");
assert(HasSpillOffset && "This LR is not spilled");
return SpilledStackOffsetFromFP;
}
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
inline void setUserIGNode( IGNode *const IGN)
{ assert( !UserIGNode); UserIGNode = IGN; }
inline void setUserIGNode(IGNode *IGN) {
assert(!UserIGNode); UserIGNode = IGN;
}
inline IGNode * getUserIGNode() const
{ return UserIGNode; } // NULL if the user is not allocated
// getUserIGNode - NULL if the user is not allocated
inline IGNode *getUserIGNode() const { return UserIGNode; }
inline const Type* getType() const {
const Value *val = *begin();
assert(val && "Can't find type - Live range is empty" );
return val->getType();
inline const Type *getType() const {
return (*begin())->getType(); // set's don't have a front
}
inline Type::PrimitiveID getTypeID() const {
@ -168,9 +139,7 @@ class LiveRange : public ValueSet {
}
inline void setSuggestedColor(int Col) {
//assert( (SuggestedColor == -1) && "Changing an already suggested color");
if(SuggestedColor == -1 )
if (SuggestedColor == -1)
SuggestedColor = Col;
#if 0
else if (DEBUG_RA)
@ -179,21 +148,21 @@ class LiveRange : public ValueSet {
}
inline unsigned getSuggestedColor() const {
assert( SuggestedColor != -1); // only a valid color is obtained
return (unsigned) SuggestedColor;
assert(SuggestedColor != -1); // only a valid color is obtained
return (unsigned)SuggestedColor;
}
inline bool hasSuggestedColor() const {
return ( SuggestedColor > -1);
return SuggestedColor != -1;
}
inline bool isSuggestedColorUsable() const {
assert( hasSuggestedColor() && "No suggested color");
assert(hasSuggestedColor() && "No suggested color");
return CanUseSuggestedCol;
}
inline void setSuggestedColorUsable(const bool val) {
assert( hasSuggestedColor() && "No suggested color");
inline void setSuggestedColorUsable(bool val) {
assert(hasSuggestedColor() && "No suggested color");
CanUseSuggestedCol = val;
}

View File

@ -118,8 +118,8 @@ void LiveRangeInfo::constructLiveRanges()
if( DEBUG_RA > 1) {
cerr << " adding LiveRange for argument ";
printValue((const Value *) *ArgIt); cerr << "\n";
cerr << " adding LiveRange for argument "
<< RAV((const Value *)*ArgIt) << "\n";
}
}
@ -163,11 +163,9 @@ void LiveRangeInfo::constructLiveRanges()
MachineOperand::MachineOperandType OpTyp =
OpI.getMachineOperand().getOperandType();
if (OpTyp == MachineOperand::MO_CCRegister) {
cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
printValue( OpI.getMachineOperand().getVRegValue() );
cerr << "\n";
}
if (OpTyp == MachineOperand::MO_CCRegister)
cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:"
<< RAV(OpI.getMachineOperand().getVRegValue()) << "\n";
}
// create a new LR iff this operand is a def
@ -175,9 +173,9 @@ void LiveRangeInfo::constructLiveRanges()
const Value *Def = *OpI;
// Only instruction values are accepted for live ranges here
if( Def->getValueType() != Value::InstructionVal ) {
cerr << "\n**%%Error: Def is not an instruction val. Def=";
printValue( Def ); cerr << "\n";
if (Def->getValueType() != Value::InstructionVal ) {
cerr << "\n**%%Error: Def is not an instruction val. Def="
<< RAV(Def) << "\n";
continue;
}
@ -189,10 +187,8 @@ void LiveRangeInfo::constructLiveRanges()
DefRange->insert(Def); // add the instruction (def) to it
LiveRangeMap[ Def ] = DefRange; // update the map
if (DEBUG_RA > 1) {
cerr << " creating a LR for def: ";
printValue(Def); cerr << "\n";
}
if (DEBUG_RA > 1)
cerr << " creating a LR for def: " << RAV(Def) << "\n";
// set the register class of the new live range
//assert( RegClassList.size() );
@ -204,24 +200,20 @@ void LiveRangeInfo::constructLiveRanges()
OpI.getMachineOperand().getVRegValue(), isCC );
if(isCC && DEBUG_RA) {
cerr << "\a**created a LR for a CC reg:";
printValue( OpI.getMachineOperand().getVRegValue() );
}
if (isCC && DEBUG_RA)
cerr << "\a**created a LR for a CC reg:"
<< RAV(OpI.getMachineOperand().getVRegValue());
DefRange->setRegClass( RegClassList[ rcid ] );
}
else {
DefRange->setRegClass(RegClassList[rcid]);
} else {
DefRange->insert(Def); // add the opearand to def range
// update the map - Operand points
// to the merged set
LiveRangeMap[ Def ] = DefRange;
LiveRangeMap[Def] = DefRange;
if( DEBUG_RA > 1) {
cerr << " added to an existing LR for def: ";
printValue( Def ); cerr << "\n";
}
if (DEBUG_RA > 1)
cerr << " added to an existing LR for def: "
<< RAV(Def) << "\n";
}
} // if isDef()
@ -336,10 +328,8 @@ void LiveRangeInfo::coalesceLRs()
if( ! LROfUse ) { // if LR of use is not found
//don't warn about labels
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
cerr<<" !! Warning: No LR for use "; printValue(*UseI);
cerr << "\n";
}
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA)
cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n";
continue; // ignore and continue
}
@ -398,13 +388,12 @@ void LiveRangeInfo::coalesceLRs()
/*--------------------------- Debug code for printing ---------------*/
void LiveRangeInfo::printLiveRanges()
{
void LiveRangeInfo::printLiveRanges() {
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end() ; ++HMI) {
if( HMI->first && HMI->second ) {
cerr <<" "; printValue((*HMI).first); cerr << "\t: ";
for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) {
cerr << " " << RAV(HMI->first) << "\t: ";
HMI->second->printSet(); cerr << "\n";
}
}

View File

@ -118,8 +118,8 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
LiveRange *L = HMI->second; // get the LiveRange
if (!L) {
if( DEBUG_RA) {
cerr << "\n*?!?Warning: Null liver range found for: ";
printValue(HMI->first); cerr << "\n";
cerr << "\n*?!?Warning: Null liver range found for: "
<< RAV(HMI->first) << "\n";
}
continue;
}
@ -170,14 +170,12 @@ void PhyRegAlloc::addInterference(const Value *const Def,
//
for( ; LIt != LVSet->end(); ++LIt) {
if( DEBUG_RA > 1) {
cerr << "< Def="; printValue(Def);
cerr << ", Lvar="; printValue( *LIt); cerr << "> ";
}
if (DEBUG_RA > 1)
cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
// get the live range corresponding to live var
//
LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );
LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt);
// LROfVar can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
@ -188,13 +186,12 @@ void PhyRegAlloc::addInterference(const Value *const Def,
// if 2 reg classes are the same set interference
//
if(RCOfDef == LROfVar->getRegClass()) {
if (RCOfDef == LROfVar->getRegClass()) {
RCOfDef->setInterference( LROfDef, LROfVar);
} else if(DEBUG_RA > 1) {
} else if (DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cerr << " warning: no live range for " ;
printValue(*LIt); cerr << "\n";
cerr << " warning: no live range for " << RAV(*LIt) << "\n";
}
}
}
@ -434,10 +431,9 @@ void PhyRegAlloc::addInterferencesForArgs()
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
addInterference((Value*)*ArgIt, InSet, false); // add interferences between
// args and LVars at start
if( DEBUG_RA > 1) {
cerr << " - %% adding interference for argument ";
printValue((const Value *)*ArgIt); cerr << "\n";
}
if( DEBUG_RA > 1)
cerr << " - %% adding interference for argument "
<< RAV((const Value *)*ArgIt) << "\n";
}
}
@ -1051,15 +1047,11 @@ void PhyRegAlloc::printMachineCode()
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
if( NumOfImpRefs > 0 ) {
if( NumOfImpRefs > 0) {
cerr << "\tImplicit:";
for(unsigned z=0; z < NumOfImpRefs; z++) {
printValue( MInst->getImplicitRef(z) );
cerr << "\t";
}
for(unsigned z=0; z < NumOfImpRefs; z++)
cerr << RAV(MInst->getImplicitRef(z)) << "\t";
}
} // for all machine instructions

View File

@ -70,13 +70,9 @@ void BBLiveVar::calcDefUseSets() {
PhiArgMap[ArgVal] = cast<BasicBlock>(BBVal);
if (DEBUG_LV > 1) {
cerr << " - phi operand ";
printValue(ArgVal);
cerr << " came from BB ";
printValue(PhiArgMap[ArgVal]);
cerr << "\n";
}
if (DEBUG_LV > 1)
cerr << " - phi operand " << RAV(ArgVal) << " came from BB "
<< RAV(PhiArgMap[ArgVal]) << "\n";
} // if( IsPhi )
} // if a use
} // for all operands
@ -105,9 +101,7 @@ void BBLiveVar::addDef(const Value *Op) {
InSet.erase(Op); // this definition kills any uses
InSetChanged = true;
if (DEBUG_LV > 1) {
cerr << " +Def: "; printValue( Op ); cerr << "\n";
}
if (DEBUG_LV > 1) cerr << " +Def: " << RAV(Op) << "\n";
}
@ -119,9 +113,7 @@ void BBLiveVar::addUse(const Value *Op) {
OutSet.erase(Op); // remove if there is a def below this use
InSetChanged = true;
if (DEBUG_LV > 1) {
cerr << " Use: "; printValue( Op ); cerr << "\n";
}
if (DEBUG_LV > 1) cerr << " Use: " << RAV(Op) << "\n";
}

View File

@ -62,7 +62,7 @@ void MethodLiveVarInfo::constructBBs(const Method *M) {
BBI != BBE; ++BBI, ++POId) {
const BasicBlock *BB = *BBI; // get the current BB
if (DEBUG_LV) { std::cerr << " For BB "; printValue(BB); cerr << ":\n"; }
if (DEBUG_LV) std::cerr << " For BB " << RAV(BB) << ":\n";
// create a new BBLiveVar
BBLiveVar *LVBB = new BBLiveVar(BB, POId);

View File

@ -1,64 +1,42 @@
#include "llvm/Analysis/LiveVar/ValueSet.h"
#include "llvm/ConstantVals.h"
#include <algorithm>
#include <iostream>
using std::cerr;
using std::endl;
using std::pair;
using std::hash_set;
void printValue(const Value *v) { // func to print a Value
ostream &operator<<(ostream &O, RAV V) { // func to print a Value
const Value *v = V.V;
if (v->hasName())
cerr << v << "(" << v->getName() << ") ";
return O << v << "(" << v->getName() << ") ";
else if (Constant *C = dyn_cast<Constant>(v))
cerr << v << "(" << C->getStrValue() << ") ";
return O << v << "(" << C->getStrValue() << ") ";
else
cerr << v << " ";
return O << v << " ";
}
bool ValueSet::setUnion( const ValueSet *S) {
bool Changed = false;
//---------------- Method implementations --------------------------
// for performing two set unions
bool ValueSet::setUnion( const ValueSet *set1) {
pair<iterator, bool> result;
bool changed = false;
for (const_iterator SI = S->begin(), SE = S->end(); SI != SE; ++SI)
if (insert(*SI).second)
Changed = true;
for(const_iterator set1it = set1->begin() ; set1it != set1->end(); ++set1it) {
// for all all elements in set1
result = insert(*set1it); // insert to this set
if(result.second == true) changed = true;
}
return changed;
return Changed;
}
// for performing set difference
void ValueSet::setDifference( const ValueSet *const set1,
const ValueSet *const set2) {
const_iterator set1it, set2it;
for( set1it = set1->begin() ; set1it != set1->end(); ++set1it) {
// for all elements in set1
iterator set2it = set2->find( *set1it ); // find wether the elem is in set2
if( set2it == set2->end() ) // if the element is not in set2
insert( *set1it ); // insert to this set
}
void ValueSet::setDifference(const ValueSet *S1, const ValueSet *S2) {
for (const_iterator SI = S1->begin(), SE = S1->end() ; SI != SE; ++SI)
if (S2->find(*SI) == S2->end()) // if the element is not in set2
insert(*SI);
}
// for performing set subtraction
void ValueSet::setSubtract( const ValueSet *const set1) {
const_iterator set1it;
for( set1it = set1->begin() ; set1it != set1->end(); ++set1it)
// for all elements in set1
erase( *set1it ); // erase that element from this set
void ValueSet::setSubtract(const ValueSet *S) {
for (const_iterator SI = S->begin() ; SI != S->end(); ++SI)
erase(*SI);
}
void ValueSet::printSet() const { // for printing a live variable set
for_each(begin(), end(), printValue);
void ValueSet::printSet() const {
for (const_iterator I = begin(), E = end(); I != E; ++I)
std::cerr << RAV(*I);
}

View File

@ -1,12 +1,12 @@
/* Title: LiveRange.h -*- C++ -*-
Author: Ruchira Sasanka
Date: July 25, 01
Purpose: To keep info about a live range.
Asuumptions:
Since the Value pointed by a use is the same as of its def, it is sufficient
to keep only defs in a LiveRange.
*/
//===-- LiveRange.h - Store info about a live range --------------*- C++ -*--=//
//
// Implements a live range using a ValueSet. A LiveRange is a simple set
// of Values.
//
// Since the Value pointed by a use is the same as of its def, it is sufficient
// to keep only defs in a LiveRange.
//
//===----------------------------------------------------------------------===//
#ifndef LIVE_RANGE_H
#define LIVE_RANGE_H
@ -18,149 +18,120 @@
class RegClass;
class IGNode;
//----------------------------------------------------------------------------
// Class LiveRange
//
// Implements a live range using a ValueSet. A LiveRange is a simple set
// of Values.
//----------------------------------------------------------------------------
class LiveRange : public ValueSet {
RegClass *MyRegClass; // register classs (e.g., int, FP) for this LR
bool doesSpanAcrossCalls;
//
// Does this live range span across calls?
// doesSpanAcrossCalls - Does this live range span across calls?
// This information is used by graph
// coloring algo to avoid allocating volatile colors to live ranges
// that span across calls (since they have to be saved/restored)
//
bool doesSpanAcrossCalls;
IGNode *UserIGNode; // IGNode which uses this LR
int Color; // color assigned to this live range
bool mustSpill; // whether this LR must be spilt
// mustSaveAcrossCalls - whether this LR must be saved accross calls
// ***TODO REMOVE this
//
bool mustSaveAcrossCalls;
//
// whether this LR must be saved accross calls ***TODO REMOVE this
// SuggestedColor - if this LR has a suggested color, can it be
// really alloated? A suggested color cannot be allocated when the
// suggested color is volatile and when there are call
// interferences.
//
int SuggestedColor; // The suggested color for this LR
//
// if this LR has a suggested color, can it be really alloated?
// A suggested color cannot be allocated when the suggested color is
// volatile and when there are call interferences.
bool CanUseSuggestedCol;
// CanUseSuggestedCol - It is possible that a suggested color for
// this live range is not available before graph coloring (e.g., it
// can be allocated to another live range which interferes with
// this)
//
// It is possible that a suggested color for this live range is not
// available before graph coloring (e.g., it can be allocated to another
// live range which interferes with this)
bool CanUseSuggestedCol;
// SpilledStackOffsetFromFP - If this LR is spilled, its stack
// offset from *FP*. The spilled offsets must always be relative to
// the FP.
//
int SpilledStackOffsetFromFP;
//
// if this LR is spilled, its stack offset from *FP*. The spilled offsets
// must always be relative to the FP.
// HasSpillOffset 0 Whether this live range has a spill offset
//
bool HasSpillOffset;
//
// Whether this live range has a spill offset
unsigned SpillCost;
//
// The spill cost of this live range. Calculated using loop depth of
// each reference to each Value in the live range
public:
// constructor
//
LiveRange() : ValueSet() {
unsigned SpillCost;
public:
LiveRange() {
Color = SuggestedColor = -1; // not yet colored
mustSpill = mustSaveAcrossCalls = false;
MyRegClass = NULL;
UserIGNode = NULL;
MyRegClass = 0;
UserIGNode = 0;
doesSpanAcrossCalls = false;
CanUseSuggestedCol = true;
HasSpillOffset = false;
HasSpillOffset = false;
SpillCost = 0;
}
// empty destructor since there are nothing to be deleted
//
~LiveRange() {}
void setRegClass(RegClass *RC) { MyRegClass = RC; }
RegClass *getRegClass() const { assert(MyRegClass); return MyRegClass; }
void setRegClass(RegClass *const RC)
{ MyRegClass = RC; }
inline RegClass *const getRegClass() const
{ assert(MyRegClass); return MyRegClass; }
inline bool hasColor() const
{ return Color != -1; }
bool hasColor() const { return Color != -1; }
inline unsigned int getColor() const
{ assert( Color != -1); return (unsigned) Color ; }
unsigned getColor() const { assert(Color != -1); return (unsigned)Color; }
inline void setColor(unsigned int Col)
{ Color = (int) Col ; }
void setColor(unsigned Col) { Color = (int)Col; }
inline void setCallInterference() {
doesSpanAcrossCalls = 1;
}
inline bool isCallInterference() const {
return (doesSpanAcrossCalls == 1);
return doesSpanAcrossCalls == 1;
}
inline void markForSpill() { mustSpill = true; }
inline bool isMarkedForSpill() { return mustSpill; }
inline bool isMarkedForSpill() { return mustSpill; }
inline void setSpillOffFromFP(int StackOffset) {
assert( mustSpill && "This LR is not spilled");
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline void modifySpillOffFromFP(int StackOffset) {
assert( mustSpill && "This LR is not spilled");
assert(mustSpill && "This LR is not spilled");
SpilledStackOffsetFromFP = StackOffset;
HasSpillOffset = true;
}
inline bool hasSpillOffset() const {
return HasSpillOffset;
return HasSpillOffset;
}
inline int getSpillOffFromFP() const {
assert( HasSpillOffset && "This LR is not spilled");
assert(HasSpillOffset && "This LR is not spilled");
return SpilledStackOffsetFromFP;
}
inline void markForSaveAcrossCalls() { mustSaveAcrossCalls = true; }
inline void setUserIGNode( IGNode *const IGN)
{ assert( !UserIGNode); UserIGNode = IGN; }
inline void setUserIGNode(IGNode *IGN) {
assert(!UserIGNode); UserIGNode = IGN;
}
inline IGNode * getUserIGNode() const
{ return UserIGNode; } // NULL if the user is not allocated
// getUserIGNode - NULL if the user is not allocated
inline IGNode *getUserIGNode() const { return UserIGNode; }
inline const Type* getType() const {
const Value *val = *begin();
assert(val && "Can't find type - Live range is empty" );
return val->getType();
inline const Type *getType() const {
return (*begin())->getType(); // set's don't have a front
}
inline Type::PrimitiveID getTypeID() const {
@ -168,9 +139,7 @@ class LiveRange : public ValueSet {
}
inline void setSuggestedColor(int Col) {
//assert( (SuggestedColor == -1) && "Changing an already suggested color");
if(SuggestedColor == -1 )
if (SuggestedColor == -1)
SuggestedColor = Col;
#if 0
else if (DEBUG_RA)
@ -179,21 +148,21 @@ class LiveRange : public ValueSet {
}
inline unsigned getSuggestedColor() const {
assert( SuggestedColor != -1); // only a valid color is obtained
return (unsigned) SuggestedColor;
assert(SuggestedColor != -1); // only a valid color is obtained
return (unsigned)SuggestedColor;
}
inline bool hasSuggestedColor() const {
return ( SuggestedColor > -1);
return SuggestedColor != -1;
}
inline bool isSuggestedColorUsable() const {
assert( hasSuggestedColor() && "No suggested color");
assert(hasSuggestedColor() && "No suggested color");
return CanUseSuggestedCol;
}
inline void setSuggestedColorUsable(const bool val) {
assert( hasSuggestedColor() && "No suggested color");
inline void setSuggestedColorUsable(bool val) {
assert(hasSuggestedColor() && "No suggested color");
CanUseSuggestedCol = val;
}

View File

@ -118,8 +118,8 @@ void LiveRangeInfo::constructLiveRanges()
if( DEBUG_RA > 1) {
cerr << " adding LiveRange for argument ";
printValue((const Value *) *ArgIt); cerr << "\n";
cerr << " adding LiveRange for argument "
<< RAV((const Value *)*ArgIt) << "\n";
}
}
@ -163,11 +163,9 @@ void LiveRangeInfo::constructLiveRanges()
MachineOperand::MachineOperandType OpTyp =
OpI.getMachineOperand().getOperandType();
if (OpTyp == MachineOperand::MO_CCRegister) {
cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:";
printValue( OpI.getMachineOperand().getVRegValue() );
cerr << "\n";
}
if (OpTyp == MachineOperand::MO_CCRegister)
cerr << "\n**CC reg found. Is Def=" << OpI.isDef() << " Val:"
<< RAV(OpI.getMachineOperand().getVRegValue()) << "\n";
}
// create a new LR iff this operand is a def
@ -175,9 +173,9 @@ void LiveRangeInfo::constructLiveRanges()
const Value *Def = *OpI;
// Only instruction values are accepted for live ranges here
if( Def->getValueType() != Value::InstructionVal ) {
cerr << "\n**%%Error: Def is not an instruction val. Def=";
printValue( Def ); cerr << "\n";
if (Def->getValueType() != Value::InstructionVal ) {
cerr << "\n**%%Error: Def is not an instruction val. Def="
<< RAV(Def) << "\n";
continue;
}
@ -189,10 +187,8 @@ void LiveRangeInfo::constructLiveRanges()
DefRange->insert(Def); // add the instruction (def) to it
LiveRangeMap[ Def ] = DefRange; // update the map
if (DEBUG_RA > 1) {
cerr << " creating a LR for def: ";
printValue(Def); cerr << "\n";
}
if (DEBUG_RA > 1)
cerr << " creating a LR for def: " << RAV(Def) << "\n";
// set the register class of the new live range
//assert( RegClassList.size() );
@ -204,24 +200,20 @@ void LiveRangeInfo::constructLiveRanges()
OpI.getMachineOperand().getVRegValue(), isCC );
if(isCC && DEBUG_RA) {
cerr << "\a**created a LR for a CC reg:";
printValue( OpI.getMachineOperand().getVRegValue() );
}
if (isCC && DEBUG_RA)
cerr << "\a**created a LR for a CC reg:"
<< RAV(OpI.getMachineOperand().getVRegValue());
DefRange->setRegClass( RegClassList[ rcid ] );
}
else {
DefRange->setRegClass(RegClassList[rcid]);
} else {
DefRange->insert(Def); // add the opearand to def range
// update the map - Operand points
// to the merged set
LiveRangeMap[ Def ] = DefRange;
LiveRangeMap[Def] = DefRange;
if( DEBUG_RA > 1) {
cerr << " added to an existing LR for def: ";
printValue( Def ); cerr << "\n";
}
if (DEBUG_RA > 1)
cerr << " added to an existing LR for def: "
<< RAV(Def) << "\n";
}
} // if isDef()
@ -336,10 +328,8 @@ void LiveRangeInfo::coalesceLRs()
if( ! LROfUse ) { // if LR of use is not found
//don't warn about labels
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA) {
cerr<<" !! Warning: No LR for use "; printValue(*UseI);
cerr << "\n";
}
if (!((*UseI)->getType())->isLabelType() && DEBUG_RA)
cerr << " !! Warning: No LR for use " << RAV(*UseI) << "\n";
continue; // ignore and continue
}
@ -398,13 +388,12 @@ void LiveRangeInfo::coalesceLRs()
/*--------------------------- Debug code for printing ---------------*/
void LiveRangeInfo::printLiveRanges()
{
void LiveRangeInfo::printLiveRanges() {
LiveRangeMapType::iterator HMI = LiveRangeMap.begin(); // hash map iterator
cerr << "\nPrinting Live Ranges from Hash Map:\n";
for( ; HMI != LiveRangeMap.end() ; ++HMI) {
if( HMI->first && HMI->second ) {
cerr <<" "; printValue((*HMI).first); cerr << "\t: ";
for( ; HMI != LiveRangeMap.end(); ++HMI) {
if (HMI->first && HMI->second) {
cerr << " " << RAV(HMI->first) << "\t: ";
HMI->second->printSet(); cerr << "\n";
}
}

View File

@ -118,8 +118,8 @@ void PhyRegAlloc::createIGNodeListsAndIGs() {
LiveRange *L = HMI->second; // get the LiveRange
if (!L) {
if( DEBUG_RA) {
cerr << "\n*?!?Warning: Null liver range found for: ";
printValue(HMI->first); cerr << "\n";
cerr << "\n*?!?Warning: Null liver range found for: "
<< RAV(HMI->first) << "\n";
}
continue;
}
@ -170,14 +170,12 @@ void PhyRegAlloc::addInterference(const Value *const Def,
//
for( ; LIt != LVSet->end(); ++LIt) {
if( DEBUG_RA > 1) {
cerr << "< Def="; printValue(Def);
cerr << ", Lvar="; printValue( *LIt); cerr << "> ";
}
if (DEBUG_RA > 1)
cerr << "< Def=" << RAV(Def) << ", Lvar=" << RAV(*LIt) << "> ";
// get the live range corresponding to live var
//
LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );
LiveRange *LROfVar = LRI.getLiveRangeForValue(*LIt);
// LROfVar can be null if it is a const since a const
// doesn't have a dominating def - see Assumptions above
@ -188,13 +186,12 @@ void PhyRegAlloc::addInterference(const Value *const Def,
// if 2 reg classes are the same set interference
//
if(RCOfDef == LROfVar->getRegClass()) {
if (RCOfDef == LROfVar->getRegClass()) {
RCOfDef->setInterference( LROfDef, LROfVar);
} else if(DEBUG_RA > 1) {
} else if (DEBUG_RA > 1) {
// we will not have LRs for values not explicitly allocated in the
// instruction stream (e.g., constants)
cerr << " warning: no live range for " ;
printValue(*LIt); cerr << "\n";
cerr << " warning: no live range for " << RAV(*LIt) << "\n";
}
}
}
@ -434,10 +431,9 @@ void PhyRegAlloc::addInterferencesForArgs()
for( ; ArgIt != ArgList.end() ; ++ArgIt) { // for each argument
addInterference((Value*)*ArgIt, InSet, false); // add interferences between
// args and LVars at start
if( DEBUG_RA > 1) {
cerr << " - %% adding interference for argument ";
printValue((const Value *)*ArgIt); cerr << "\n";
}
if( DEBUG_RA > 1)
cerr << " - %% adding interference for argument "
<< RAV((const Value *)*ArgIt) << "\n";
}
}
@ -1051,15 +1047,11 @@ void PhyRegAlloc::printMachineCode()
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
if( NumOfImpRefs > 0 ) {
if( NumOfImpRefs > 0) {
cerr << "\tImplicit:";
for(unsigned z=0; z < NumOfImpRefs; z++) {
printValue( MInst->getImplicitRef(z) );
cerr << "\t";
}
for(unsigned z=0; z < NumOfImpRefs; z++)
cerr << RAV(MInst->getImplicitRef(z)) << "\t";
}
} // for all machine instructions

View File

@ -563,11 +563,8 @@ void UltraSparcRegInfo::suggestRegs4CallArgs(const MachineInstr *CallMI,
// not possible to have a null LR since all args (even consts)
// must be defined before
if( !LR ) {
if( DEBUG_RA) {
cerr << " ERROR: In call instr, no LR for arg: " ;
printValue(CallArg); cerr << "\n";
}
if (!LR) {
cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) << "\n";
assert(0 && "NO LR for call arg");
}
@ -624,16 +621,12 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *CallMI,
const Value *RetVal = getCallInstRetVal( CallMI );
if( RetVal ) {
if (RetVal) {
LiveRange *RetValLR = LRI.getLiveRangeForValue( RetVal );
LiveRange * RetValLR = LRI.getLiveRangeForValue( RetVal );
if( !RetValLR ) {
cerr << "\nNo LR for:";
printValue( RetVal );
cerr << "\n";
assert( RetValLR && "ERR:No LR for non-void return value");
//return;
if (!RetValLR) {
cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
assert(0 && "ERR:No LR for non-void return value");
}
unsigned RegClassID = (RetValLR->getRegClass())->getID();
@ -755,13 +748,9 @@ void UltraSparcRegInfo::colorCallArgs(const MachineInstr *CallMI,
// not possible to have a null LR since all args (even consts)
// must be defined before
if( !LR ) {
if( DEBUG_RA) {
cerr << " ERROR: In call instr, no LR for arg: " ;
printValue(CallArg); cerr << "\n";
}
if (!LR) {
cerr << " ERROR: In call instr, no LR for arg: " << RAV(CallArg) << "\n";
assert(0 && "NO LR for call arg");
// continue;
}
@ -942,13 +931,10 @@ void UltraSparcRegInfo::suggestReg4RetValue(const MachineInstr *RetMI,
LiveRange *const LR = LRI.getLiveRangeForValue( RetVal );
if( !LR ) {
cerr << "\nNo LR for:";
printValue( RetVal );
cerr << "\n";
assert( LR && "No LR for return value of non-void method");
//return;
}
if (!LR) {
cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
assert(0 && "No LR for return value of non-void method");
}
unsigned RegClassID = (LR->getRegClass())->getID();
@ -981,12 +967,10 @@ void UltraSparcRegInfo::colorRetValue(const MachineInstr *RetMI,
LiveRange *LR = LRI.getLiveRangeForValue(RetVal);
if( ! LR ) {
cerr << "\nNo LR for:";
printValue( RetVal );
cerr << "\n";
// assert( LR && "No LR for return value of non-void method");
return;
if (!LR) {
cerr << "\nNo LR for:" << RAV(RetVal) << "\n";
// assert( LR && "No LR for return value of non-void method");
return;
}
unsigned RegClassID = getRegClassIDOfValue(RetVal);