mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-01 00:33:09 +00:00
Committed for compliation. Not yet final.
--Ruchira git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@505 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c7136d2b09
commit
7cd2ca13c1
76
include/llvm/CodeGen/InterferenceGraph.h
Normal file
76
include/llvm/CodeGen/InterferenceGraph.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* Title: InterferenceGraph.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: July 20, 01
|
||||
Purpose: Interference Graph used for register coloring.
|
||||
|
||||
Notes:
|
||||
Adj Info is stored in the lower trangular matrix (i.e., row > col )
|
||||
|
||||
This class must be used in the following way:
|
||||
|
||||
* Construct class
|
||||
* call addLRToIG as many times to add ALL LRs to this IG
|
||||
* call createGraph to create the actual matrix
|
||||
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
|
||||
called as desired to modify the graph.
|
||||
* Once the modifications to the graph are over, call
|
||||
setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INTERFERENCE_GRAPH_H
|
||||
#define INTERFERENCE_GRAPH_H
|
||||
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
typedef vector <IGNode *> IGNodeListType;
|
||||
|
||||
|
||||
class InterferenceGraph
|
||||
{
|
||||
char **IG; // a poiner to the interference graph
|
||||
unsigned int Size; // size of a side of the IG
|
||||
RegClass *const RegCl; // RegCl contains this IG
|
||||
IGNodeListType IGNodeList; // a list of all IGNodes in a reg class
|
||||
|
||||
// for asserting this IG node is infact in the IGNodeList of this class
|
||||
inline void assertIGNode(const IGNode *const Node) const {
|
||||
assert( IGNodeList[ Node->getIndex() ] == Node );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// the matrix is not yet created by the constructor. Call createGraph()
|
||||
// to create it after adding all IGNodes to the IGNodeList
|
||||
|
||||
InterferenceGraph(RegClass *const RC);
|
||||
void createGraph();
|
||||
|
||||
void addLRToIG(LiveRange *const LR);
|
||||
|
||||
void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 );
|
||||
|
||||
unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) const ;
|
||||
|
||||
void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2);
|
||||
|
||||
inline IGNodeListType &getIGNodeList() { return IGNodeList; }
|
||||
|
||||
void setCurDegreeOfIGNodes();
|
||||
|
||||
void printIG() const;
|
||||
void printIGNodeList() const;
|
||||
|
||||
~InterferenceGraph();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -135,6 +135,17 @@ private:
|
||||
friend class MachineInstr;
|
||||
friend class ValOpIterator<const MachineInstr, const Value>;
|
||||
friend class ValOpIterator< MachineInstr, Value>;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// this replaces a value with a register after register allcoation
|
||||
void setRegForValue(int Reg) {
|
||||
assert(opType == MO_VirtualRegister || opType == MO_CCRegister);
|
||||
opType = MO_MachineRegister;
|
||||
regNum = Reg;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -244,6 +255,10 @@ public:
|
||||
bool operandIsDefined(unsigned int i) const;
|
||||
|
||||
void dump (unsigned int indent = 0) const;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
friend ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||
@ -395,10 +410,10 @@ MachineCodeForVMInstr::~MachineCodeForVMInstr()
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
||||
class MachineCodeForBasicBlock: public vector<const MachineInstr*> {
|
||||
class MachineCodeForBasicBlock: public vector<MachineInstr*> {
|
||||
public:
|
||||
typedef vector<const MachineInstr*>::iterator iterator;
|
||||
typedef vector<const MachineInstr*>::const_iterator const_iterator;
|
||||
typedef vector<MachineInstr*>::iterator iterator;
|
||||
typedef vector<MachineInstr*>::const_iterator const_iterator;
|
||||
};
|
||||
|
||||
|
||||
@ -461,7 +476,7 @@ ostream& operator<<(ostream& os, const MachineInstr& minstr);
|
||||
ostream& operator<<(ostream& os, const MachineOperand& mop);
|
||||
|
||||
|
||||
void PrintMachineInstructions (Method* method);
|
||||
void PrintMachineInstructions (const Method *const method);
|
||||
|
||||
|
||||
//**************************************************************************/
|
||||
|
121
include/llvm/CodeGen/MachineRegInfo.h
Normal file
121
include/llvm/CodeGen/MachineRegInfo.h
Normal file
@ -0,0 +1,121 @@
|
||||
/* Title: MachineRegInfo.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: Contains the description of machine register classes.
|
||||
|
||||
Notes:
|
||||
|
||||
A machine will have several register classes. For each register class, the
|
||||
machine has to provide a class which is derived class of the virtual class
|
||||
MachineRegClass. This virtual class itself is machine independent but
|
||||
the derived classes are all machine dependent.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MACHINE_REG_INFO_H
|
||||
#define MACHINE_REG_INFO_H
|
||||
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
|
||||
|
||||
|
||||
// This is the virtual class which must be subclassed by all machine specific
|
||||
// register classes.
|
||||
|
||||
unsigned RegClassID; // integer ID of a reg class
|
||||
unsigned NumOfAvailRegs; // # of avail for coloring (without SP, g0 etc)
|
||||
unsigned NumOfAllRegs; // # of all registers (including SP, g0 etc
|
||||
|
||||
|
||||
class MachineRegClass
|
||||
{
|
||||
|
||||
private:
|
||||
const unsigned RegClassID;
|
||||
|
||||
public:
|
||||
|
||||
virtual unsigned getRegClassID() const = 0;
|
||||
|
||||
// Number of registes available for coloring (e.g., without SP, g0 etc)
|
||||
virtual unsigned getNumOfAvailRegs() const = 0;
|
||||
|
||||
// Number of all registers (e.g., including SP, g0 etc)
|
||||
virtual unsigned getNumOfAllRegs() const = 0;
|
||||
|
||||
// This method should find a color which is not used by neighbors
|
||||
// (i.e., a false position in IsColorUsedArr) and
|
||||
virtual void colorIGNode(IGNode * Node, bool IsColorUsedArr[] ) const = 0;
|
||||
|
||||
|
||||
MachineRegClass(const unsigned ID) : RegClassID(ID) { }
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
// include .h files that describes machine reg classes here
|
||||
|
||||
#include "RegAlloc/Sparc/SparcIntRegClass.h"
|
||||
|
||||
typedef vector<const MachineRegClass *> MachineRegClassArrayType;
|
||||
|
||||
|
||||
|
||||
class MachineRegInfo
|
||||
{
|
||||
private:
|
||||
|
||||
// A vector of all machine register classes
|
||||
MachineRegClassArrayType MachineRegClassArr;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
MachineRegInfo() : MachineRegClassArr() {
|
||||
|
||||
MachineRegClassArr.push_back( new SparcIntRegClass(0) );
|
||||
// RegClassArr.pushback( new SparcFloatRegClass(1) );
|
||||
// RegClassArr.pushback( new SparcFloatCCRegClass(2) );
|
||||
|
||||
if(DEBUG_RA)
|
||||
cout << "Created machine register classes." << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
inline unsigned int getNumOfRegClasses() const {
|
||||
return MachineRegClassArr.size();
|
||||
}
|
||||
|
||||
unsigned getRegClassIDOfValue (const Value *const Val) const ;
|
||||
|
||||
const MachineRegClass *const getMachineRegClass(unsigned i) const {
|
||||
return MachineRegClassArr[i];
|
||||
}
|
||||
|
||||
inline bool isCallInst(const MachineInstr *const MI) const {
|
||||
MachineOpCode Op = MI->getOpCode();
|
||||
return false; // ########################################
|
||||
// return (Op == CALL || Op == JMPL);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
// This function should detrmine the register class of a value. This can be
|
||||
// done on type information in the value class. The register class returned
|
||||
// must be same as the array index of RegClassArr.
|
||||
|
||||
unsigned MachineRegInfo::getRegClassIDOfValue (const Value *const Val) const
|
||||
{
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
10
include/llvm/CodeGen/RegAllocCommon.h
Normal file
10
include/llvm/CodeGen/RegAllocCommon.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef REG_ALLOC_COMMON_H
|
||||
#define REG_ALLOC_COMMON_H
|
||||
|
||||
// set DEBUG_RA for printing out debug messages
|
||||
// if DEBUG_RA is 1 normal output messages
|
||||
// if DEBUG_RA is 2 extensive debug info for each instr
|
||||
|
||||
#define DEBUG_RA (1)
|
||||
|
||||
#endif
|
125
include/llvm/CodeGen/RegClass.h
Normal file
125
include/llvm/CodeGen/RegClass.h
Normal file
@ -0,0 +1,125 @@
|
||||
/* Title: RegClass.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: Contains machine independent methods for register coloring.
|
||||
|
||||
This is the class that contains all data structures and common algos
|
||||
for coloring a particular register class (e.g., int class, fp class).
|
||||
This class is hardware independent. This class accepts a hardware
|
||||
dependent description of machine registers (MachineRegInfo class) to
|
||||
get hardware specific info and color and indidual IG node.
|
||||
|
||||
This class contains the InterferenceGraph (IG).
|
||||
Also it contains an IGNode stack that can be used for coloring.
|
||||
The class provides some easy access methods to the IG methods, since these
|
||||
methods are called thru a register class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef REG_CLASS_H
|
||||
#define REG_CLASS_H
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||
#include "llvm/CodeGen/TargetMachine.h"
|
||||
|
||||
|
||||
#include <stack>
|
||||
|
||||
|
||||
typedef vector<unsigned int> ReservedColorListType;
|
||||
|
||||
|
||||
class RegClass
|
||||
{
|
||||
|
||||
private:
|
||||
const Method *const Meth; // Method we are working on
|
||||
|
||||
const MachineRegClassInfo *const MRC; // corresponding MRC
|
||||
|
||||
const unsigned RegClassID; // my int ID
|
||||
|
||||
InterferenceGraph IG; // Interference graph - constructed by
|
||||
// buildInterferenceGraph
|
||||
stack <IGNode *> IGNodeStack; // the stack used for coloring
|
||||
|
||||
// for passing registered that are pre-allocated (e.g., %g's)
|
||||
const ReservedColorListType *const ReservedColorList;
|
||||
|
||||
// An array used for coloring each node. This array must be of size
|
||||
// MRC->getNumOfAllRegs(). Allocated once in the constructor
|
||||
// for efficiency.
|
||||
bool *IsColorUsedArr;
|
||||
|
||||
|
||||
//------------ private methods ------------------
|
||||
|
||||
void pushAllIGNodes();
|
||||
bool pushUnconstrainedIGNodes();
|
||||
IGNode * getIGNodeWithMinSpillCost();
|
||||
void colorIGNode(IGNode *const Node);
|
||||
|
||||
public:
|
||||
|
||||
RegClass(const Method *const M,
|
||||
const MachineRegClassInfo *const MRC,
|
||||
const ReservedColorListType *const RCL = NULL);
|
||||
|
||||
inline void createInterferenceGraph()
|
||||
{ IG.createGraph(); }
|
||||
|
||||
inline InterferenceGraph &getIG() { return IG; }
|
||||
|
||||
inline const unsigned getID() const { return RegClassID; }
|
||||
|
||||
void colorAllRegs(); // main method called for coloring regs
|
||||
|
||||
inline unsigned getNumOfAvailRegs() const
|
||||
{ return MRC->getNumOfAvailRegs(); }
|
||||
|
||||
~RegClass() { delete[] IsColorUsedArr; };
|
||||
|
||||
|
||||
|
||||
// --- following methods are provided to access the IG contained within this
|
||||
// ---- RegClass easilly.
|
||||
|
||||
|
||||
inline void addLRToIG(LiveRange *const LR)
|
||||
{ IG.addLRToIG(LR); }
|
||||
|
||||
inline void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2)
|
||||
{ IG.setInterference(LR1, LR2); }
|
||||
|
||||
inline unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2) const
|
||||
{ return IG.getInterference(LR1, LR2); }
|
||||
|
||||
inline void mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||
LiveRange *const LR2)
|
||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||
|
||||
|
||||
inline void printIGNodeList() const {
|
||||
cout << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIGNodeList();
|
||||
}
|
||||
|
||||
inline void printIG() {
|
||||
cout << "IG for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIG();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
37
include/llvm/CodeGen/RegColorMap.h
Normal file
37
include/llvm/CodeGen/RegColorMap.h
Normal file
@ -0,0 +1,37 @@
|
||||
#ifndef REG_COLOR_MAP
|
||||
#define REG_COLOR_MAP
|
||||
|
||||
#include <hash_map>
|
||||
|
||||
|
||||
#ifndef VALUE_SET_H
|
||||
|
||||
struct hashFuncValue { // sturcture containing the hash func
|
||||
inline size_t operator () (const Value *const val) const
|
||||
{ return (size_t) val; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef int RegColorType;
|
||||
|
||||
|
||||
class RegColorMap : hash_map <const Value *, RegColorType, hashFuncValue>
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
inline void setRegColor(const Value *const Val, RegColorType Col) {
|
||||
(*this)[Val] = Col;
|
||||
}
|
||||
|
||||
|
||||
inline RegColorType getRegColor(const Value *const Val) {
|
||||
return (*this)[Val];
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -933,10 +933,40 @@ class UltraSparcRegInfo : public MachineRegInfo
|
||||
|
||||
void colorArgs(const Method *const Meth, LiveRangeInfo& LRI) const;
|
||||
|
||||
static void printReg(const LiveRange *const LR);
|
||||
static void printReg(const LiveRange *const LR) ;
|
||||
|
||||
void colorCallArgs(vector<const Instruction *> & CallInstrList,
|
||||
LiveRangeInfo& LRI ) const;
|
||||
LiveRangeInfo& LRI,
|
||||
AddedInstrMapType& AddedInstrMap ) const;
|
||||
|
||||
// this method provides a unique number for each register
|
||||
inline int getUnifiedRegNum(int RegClassID, int reg) const {
|
||||
|
||||
if( RegClassID == IntRegClassID && reg < 32 )
|
||||
return reg;
|
||||
else if ( RegClassID == FloatRegClassID && reg < 64)
|
||||
return reg + 32; // we have 32 int regs
|
||||
else if( RegClassID == FloatCCREgClassID && reg < 4)
|
||||
return reg + 32 + 64; // 32 int, 64 float
|
||||
else
|
||||
assert(0 && "Invalid register class or reg number");
|
||||
|
||||
}
|
||||
|
||||
// given the unified register number, this gives the name
|
||||
inline const string getUnifiedRegName(int reg) const {
|
||||
|
||||
if( reg < 32 )
|
||||
return SparcIntRegOrder::getRegName(reg);
|
||||
else if ( reg < (64 + 32) )
|
||||
return SparcFloatRegOrder::getRegName( reg - 32);
|
||||
else if( reg < (64+32+4) )
|
||||
assert( 0 && "no float condition reg class yet");
|
||||
// return reg + 32 + 64;
|
||||
else
|
||||
assert(0 && "Invalid register number");
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -54,9 +54,9 @@ class SparcIntRegOrder{
|
||||
// --- following colors are not available for allocation within this phase
|
||||
// --- but can appear for pre-colored ranges
|
||||
|
||||
g0, i6, i7, o6,
|
||||
g0, i6, i7, o6
|
||||
|
||||
NumOfAllRegs // place holder to count all possilbe colors
|
||||
|
||||
|
||||
};
|
||||
|
||||
@ -65,6 +65,7 @@ class SparcIntRegOrder{
|
||||
|
||||
static unsigned int const StartOfNonVolatileRegs = l0;
|
||||
static unsigned int const StartOfAllRegs = g1;
|
||||
static unsigned int const NumOfAllRegs = o6 + 1;
|
||||
|
||||
|
||||
static const string getRegName(const unsigned reg) {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define LLVM_CODEGEN_TARGETDATA_H
|
||||
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Annotation.h"
|
||||
#include <vector>
|
||||
|
||||
class StructType;
|
||||
|
@ -224,8 +224,12 @@ public:
|
||||
return getDescriptor(opCode).iclass & M_DUMMY_PHI_FLAG;
|
||||
}
|
||||
|
||||
|
||||
// delete this later *******
|
||||
bool isPhi(MachineOpCode opCode) { return isDummyPhiInstr(opCode); }
|
||||
|
||||
//
|
||||
|
||||
|
||||
// Check if an instruction can be issued before its operands are ready,
|
||||
// or if a subsequent instruction that uses its result can be issued
|
||||
// before the results are ready.
|
||||
@ -685,6 +689,10 @@ class Value;
|
||||
class LiveRangeInfo;
|
||||
class Method;
|
||||
class Instruction;
|
||||
class LiveRange;
|
||||
class AddedInstrns;
|
||||
class MachineInstr;
|
||||
typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
|
||||
|
||||
// A vector of all machine register classes
|
||||
typedef vector<const MachineRegClassInfo *> MachineRegClassArrayType;
|
||||
@ -715,8 +723,14 @@ public:
|
||||
LiveRangeInfo & LRI) const = 0;
|
||||
|
||||
virtual void colorCallArgs(vector<const Instruction *> & CallInstrList,
|
||||
LiveRangeInfo& LRI ) const = 0 ;
|
||||
LiveRangeInfo& LRI,
|
||||
AddedInstrMapType& AddedInstrMap ) const = 0 ;
|
||||
|
||||
virtual int getUnifiedRegNum(int RegClassID, int reg) const = 0;
|
||||
|
||||
virtual const string getUnifiedRegName(int reg) const = 0;
|
||||
|
||||
//virtual void printReg(const LiveRange *const LR) const =0;
|
||||
|
||||
MachineRegInfo() { }
|
||||
|
||||
|
76
lib/CodeGen/RegAlloc/InterferenceGraph.h
Normal file
76
lib/CodeGen/RegAlloc/InterferenceGraph.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* Title: InterferenceGraph.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: July 20, 01
|
||||
Purpose: Interference Graph used for register coloring.
|
||||
|
||||
Notes:
|
||||
Adj Info is stored in the lower trangular matrix (i.e., row > col )
|
||||
|
||||
This class must be used in the following way:
|
||||
|
||||
* Construct class
|
||||
* call addLRToIG as many times to add ALL LRs to this IG
|
||||
* call createGraph to create the actual matrix
|
||||
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
|
||||
called as desired to modify the graph.
|
||||
* Once the modifications to the graph are over, call
|
||||
setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INTERFERENCE_GRAPH_H
|
||||
#define INTERFERENCE_GRAPH_H
|
||||
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
typedef vector <IGNode *> IGNodeListType;
|
||||
|
||||
|
||||
class InterferenceGraph
|
||||
{
|
||||
char **IG; // a poiner to the interference graph
|
||||
unsigned int Size; // size of a side of the IG
|
||||
RegClass *const RegCl; // RegCl contains this IG
|
||||
IGNodeListType IGNodeList; // a list of all IGNodes in a reg class
|
||||
|
||||
// for asserting this IG node is infact in the IGNodeList of this class
|
||||
inline void assertIGNode(const IGNode *const Node) const {
|
||||
assert( IGNodeList[ Node->getIndex() ] == Node );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// the matrix is not yet created by the constructor. Call createGraph()
|
||||
// to create it after adding all IGNodes to the IGNodeList
|
||||
|
||||
InterferenceGraph(RegClass *const RC);
|
||||
void createGraph();
|
||||
|
||||
void addLRToIG(LiveRange *const LR);
|
||||
|
||||
void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 );
|
||||
|
||||
unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) const ;
|
||||
|
||||
void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2);
|
||||
|
||||
inline IGNodeListType &getIGNodeList() { return IGNodeList; }
|
||||
|
||||
void setCurDegreeOfIGNodes();
|
||||
|
||||
void printIG() const;
|
||||
void printIGNodeList() const;
|
||||
|
||||
~InterferenceGraph();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
106
lib/CodeGen/RegAlloc/PhyRegAlloc.h
Normal file
106
lib/CodeGen/RegAlloc/PhyRegAlloc.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* Title: PhyRegAlloc.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: This is the main entry point for register allocation.
|
||||
|
||||
Notes:
|
||||
|
||||
* RegisterClasses: Each RegClass accepts a
|
||||
MachineRegClass which contains machine specific info about that register
|
||||
class. The code in the RegClass is machine independent and they use
|
||||
access functions in the MachineRegClass object passed into it to get
|
||||
machine specific info.
|
||||
|
||||
* Machine dependent work: All parts of the register coloring algorithm
|
||||
except coloring of an individual node are machine independent.
|
||||
|
||||
Register allocation must be done as:
|
||||
|
||||
static const MachineRegInfo MRI = MachineRegInfo(); // machine reg info
|
||||
|
||||
MethodLiveVarInfo LVI(*MethodI ); // compute LV info
|
||||
LVI.analyze();
|
||||
|
||||
PhyRegAlloc PRA(*MethodI, &MRI, &LVI); // allocate regs
|
||||
PRA.allocateRegisters();
|
||||
|
||||
Assumptions:
|
||||
All values in a live range will be of the same physical reg class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef PHY_REG_ALLOC_H
|
||||
#define PHY_REG_ALLOC_H
|
||||
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/Sparc.h"
|
||||
|
||||
#include "llvm/CodeGen/RegClass.h"
|
||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||
#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
|
||||
|
||||
|
||||
class AddedInstrns
|
||||
{
|
||||
public:
|
||||
vector<const MachineInstr *> InstrnsBefore;
|
||||
vector<const MachineInstr *> InstrnsAfter;
|
||||
|
||||
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
||||
};
|
||||
|
||||
typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
|
||||
|
||||
|
||||
|
||||
class PhyRegAlloc
|
||||
{
|
||||
|
||||
vector<RegClass *> RegClassList ; // vector of register classes
|
||||
const Method *const Meth; // name of the method we work on
|
||||
const TargetMachine &TM; // target machine
|
||||
MethodLiveVarInfo *const LVI; // LV information for this method
|
||||
// (already computed for BBs)
|
||||
LiveRangeInfo LRI; // LR info (will be computed)
|
||||
const MachineRegInfo &MRI; // Machine Register information
|
||||
const unsigned NumOfRegClasses; // recorded here for efficiency
|
||||
|
||||
vector<const Instruction *> CallInstrList; // a list of all call instrs
|
||||
|
||||
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
||||
|
||||
|
||||
//------- private methods ---------------------------------------------------
|
||||
|
||||
void addInterference(const Value *const Def, const LiveVarSet *const LVSet,
|
||||
const bool isCallInst);
|
||||
|
||||
void addInterferencesForArgs();
|
||||
void createIGNodeListsAndIGs();
|
||||
void buildInterferenceGraphs();
|
||||
|
||||
inline void constructLiveRanges()
|
||||
{ LRI.constructLiveRanges(); }
|
||||
|
||||
void colorIncomingArgs();
|
||||
void updateMachineCode();
|
||||
|
||||
public:
|
||||
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
||||
MethodLiveVarInfo *const Lvi);
|
||||
|
||||
void allocateRegisters(); // main method called for allocatin
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
10
lib/CodeGen/RegAlloc/RegAllocCommon.h
Normal file
10
lib/CodeGen/RegAlloc/RegAllocCommon.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef REG_ALLOC_COMMON_H
|
||||
#define REG_ALLOC_COMMON_H
|
||||
|
||||
// set DEBUG_RA for printing out debug messages
|
||||
// if DEBUG_RA is 1 normal output messages
|
||||
// if DEBUG_RA is 2 extensive debug info for each instr
|
||||
|
||||
#define DEBUG_RA (1)
|
||||
|
||||
#endif
|
125
lib/CodeGen/RegAlloc/RegClass.h
Normal file
125
lib/CodeGen/RegAlloc/RegClass.h
Normal file
@ -0,0 +1,125 @@
|
||||
/* Title: RegClass.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: Contains machine independent methods for register coloring.
|
||||
|
||||
This is the class that contains all data structures and common algos
|
||||
for coloring a particular register class (e.g., int class, fp class).
|
||||
This class is hardware independent. This class accepts a hardware
|
||||
dependent description of machine registers (MachineRegInfo class) to
|
||||
get hardware specific info and color and indidual IG node.
|
||||
|
||||
This class contains the InterferenceGraph (IG).
|
||||
Also it contains an IGNode stack that can be used for coloring.
|
||||
The class provides some easy access methods to the IG methods, since these
|
||||
methods are called thru a register class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef REG_CLASS_H
|
||||
#define REG_CLASS_H
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||
#include "llvm/CodeGen/TargetMachine.h"
|
||||
|
||||
|
||||
#include <stack>
|
||||
|
||||
|
||||
typedef vector<unsigned int> ReservedColorListType;
|
||||
|
||||
|
||||
class RegClass
|
||||
{
|
||||
|
||||
private:
|
||||
const Method *const Meth; // Method we are working on
|
||||
|
||||
const MachineRegClassInfo *const MRC; // corresponding MRC
|
||||
|
||||
const unsigned RegClassID; // my int ID
|
||||
|
||||
InterferenceGraph IG; // Interference graph - constructed by
|
||||
// buildInterferenceGraph
|
||||
stack <IGNode *> IGNodeStack; // the stack used for coloring
|
||||
|
||||
// for passing registered that are pre-allocated (e.g., %g's)
|
||||
const ReservedColorListType *const ReservedColorList;
|
||||
|
||||
// An array used for coloring each node. This array must be of size
|
||||
// MRC->getNumOfAllRegs(). Allocated once in the constructor
|
||||
// for efficiency.
|
||||
bool *IsColorUsedArr;
|
||||
|
||||
|
||||
//------------ private methods ------------------
|
||||
|
||||
void pushAllIGNodes();
|
||||
bool pushUnconstrainedIGNodes();
|
||||
IGNode * getIGNodeWithMinSpillCost();
|
||||
void colorIGNode(IGNode *const Node);
|
||||
|
||||
public:
|
||||
|
||||
RegClass(const Method *const M,
|
||||
const MachineRegClassInfo *const MRC,
|
||||
const ReservedColorListType *const RCL = NULL);
|
||||
|
||||
inline void createInterferenceGraph()
|
||||
{ IG.createGraph(); }
|
||||
|
||||
inline InterferenceGraph &getIG() { return IG; }
|
||||
|
||||
inline const unsigned getID() const { return RegClassID; }
|
||||
|
||||
void colorAllRegs(); // main method called for coloring regs
|
||||
|
||||
inline unsigned getNumOfAvailRegs() const
|
||||
{ return MRC->getNumOfAvailRegs(); }
|
||||
|
||||
~RegClass() { delete[] IsColorUsedArr; };
|
||||
|
||||
|
||||
|
||||
// --- following methods are provided to access the IG contained within this
|
||||
// ---- RegClass easilly.
|
||||
|
||||
|
||||
inline void addLRToIG(LiveRange *const LR)
|
||||
{ IG.addLRToIG(LR); }
|
||||
|
||||
inline void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2)
|
||||
{ IG.setInterference(LR1, LR2); }
|
||||
|
||||
inline unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2) const
|
||||
{ return IG.getInterference(LR1, LR2); }
|
||||
|
||||
inline void mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||
LiveRange *const LR2)
|
||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||
|
||||
|
||||
inline void printIGNodeList() const {
|
||||
cout << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIGNodeList();
|
||||
}
|
||||
|
||||
inline void printIG() {
|
||||
cout << "IG for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIG();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
76
lib/Target/SparcV9/RegAlloc/InterferenceGraph.h
Normal file
76
lib/Target/SparcV9/RegAlloc/InterferenceGraph.h
Normal file
@ -0,0 +1,76 @@
|
||||
/* Title: InterferenceGraph.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: July 20, 01
|
||||
Purpose: Interference Graph used for register coloring.
|
||||
|
||||
Notes:
|
||||
Adj Info is stored in the lower trangular matrix (i.e., row > col )
|
||||
|
||||
This class must be used in the following way:
|
||||
|
||||
* Construct class
|
||||
* call addLRToIG as many times to add ALL LRs to this IG
|
||||
* call createGraph to create the actual matrix
|
||||
* Then setInterference, getInterference, mergeIGNodesOfLRs can be
|
||||
called as desired to modify the graph.
|
||||
* Once the modifications to the graph are over, call
|
||||
setCurDegreeOfIGNodes() before pushing IGNodes on to stack for coloring.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef INTERFERENCE_GRAPH_H
|
||||
#define INTERFERENCE_GRAPH_H
|
||||
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
|
||||
typedef vector <IGNode *> IGNodeListType;
|
||||
|
||||
|
||||
class InterferenceGraph
|
||||
{
|
||||
char **IG; // a poiner to the interference graph
|
||||
unsigned int Size; // size of a side of the IG
|
||||
RegClass *const RegCl; // RegCl contains this IG
|
||||
IGNodeListType IGNodeList; // a list of all IGNodes in a reg class
|
||||
|
||||
// for asserting this IG node is infact in the IGNodeList of this class
|
||||
inline void assertIGNode(const IGNode *const Node) const {
|
||||
assert( IGNodeList[ Node->getIndex() ] == Node );
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// the matrix is not yet created by the constructor. Call createGraph()
|
||||
// to create it after adding all IGNodes to the IGNodeList
|
||||
|
||||
InterferenceGraph(RegClass *const RC);
|
||||
void createGraph();
|
||||
|
||||
void addLRToIG(LiveRange *const LR);
|
||||
|
||||
void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 );
|
||||
|
||||
unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2 ) const ;
|
||||
|
||||
void mergeIGNodesOfLRs(const LiveRange *const LR1, LiveRange *const LR2);
|
||||
|
||||
inline IGNodeListType &getIGNodeList() { return IGNodeList; }
|
||||
|
||||
void setCurDegreeOfIGNodes();
|
||||
|
||||
void printIG() const;
|
||||
void printIGNodeList() const;
|
||||
|
||||
~InterferenceGraph();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
106
lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h
Normal file
106
lib/Target/SparcV9/RegAlloc/PhyRegAlloc.h
Normal file
@ -0,0 +1,106 @@
|
||||
/* Title: PhyRegAlloc.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: This is the main entry point for register allocation.
|
||||
|
||||
Notes:
|
||||
|
||||
* RegisterClasses: Each RegClass accepts a
|
||||
MachineRegClass which contains machine specific info about that register
|
||||
class. The code in the RegClass is machine independent and they use
|
||||
access functions in the MachineRegClass object passed into it to get
|
||||
machine specific info.
|
||||
|
||||
* Machine dependent work: All parts of the register coloring algorithm
|
||||
except coloring of an individual node are machine independent.
|
||||
|
||||
Register allocation must be done as:
|
||||
|
||||
static const MachineRegInfo MRI = MachineRegInfo(); // machine reg info
|
||||
|
||||
MethodLiveVarInfo LVI(*MethodI ); // compute LV info
|
||||
LVI.analyze();
|
||||
|
||||
PhyRegAlloc PRA(*MethodI, &MRI, &LVI); // allocate regs
|
||||
PRA.allocateRegisters();
|
||||
|
||||
Assumptions:
|
||||
All values in a live range will be of the same physical reg class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef PHY_REG_ALLOC_H
|
||||
#define PHY_REG_ALLOC_H
|
||||
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/Sparc.h"
|
||||
|
||||
#include "llvm/CodeGen/RegClass.h"
|
||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||
#include "llvm/Analysis/LiveVar/MethodLiveVarInfo.h"
|
||||
|
||||
|
||||
class AddedInstrns
|
||||
{
|
||||
public:
|
||||
vector<const MachineInstr *> InstrnsBefore;
|
||||
vector<const MachineInstr *> InstrnsAfter;
|
||||
|
||||
AddedInstrns() : InstrnsBefore(), InstrnsAfter() { }
|
||||
};
|
||||
|
||||
typedef hash_map<const MachineInstr *, AddedInstrns *> AddedInstrMapType;
|
||||
|
||||
|
||||
|
||||
class PhyRegAlloc
|
||||
{
|
||||
|
||||
vector<RegClass *> RegClassList ; // vector of register classes
|
||||
const Method *const Meth; // name of the method we work on
|
||||
const TargetMachine &TM; // target machine
|
||||
MethodLiveVarInfo *const LVI; // LV information for this method
|
||||
// (already computed for BBs)
|
||||
LiveRangeInfo LRI; // LR info (will be computed)
|
||||
const MachineRegInfo &MRI; // Machine Register information
|
||||
const unsigned NumOfRegClasses; // recorded here for efficiency
|
||||
|
||||
vector<const Instruction *> CallInstrList; // a list of all call instrs
|
||||
|
||||
AddedInstrMapType AddedInstrMap; // to store instrns added in this phase
|
||||
|
||||
|
||||
//------- private methods ---------------------------------------------------
|
||||
|
||||
void addInterference(const Value *const Def, const LiveVarSet *const LVSet,
|
||||
const bool isCallInst);
|
||||
|
||||
void addInterferencesForArgs();
|
||||
void createIGNodeListsAndIGs();
|
||||
void buildInterferenceGraphs();
|
||||
|
||||
inline void constructLiveRanges()
|
||||
{ LRI.constructLiveRanges(); }
|
||||
|
||||
void colorIncomingArgs();
|
||||
void updateMachineCode();
|
||||
|
||||
public:
|
||||
PhyRegAlloc(const Method *const M, const TargetMachine& TM,
|
||||
MethodLiveVarInfo *const Lvi);
|
||||
|
||||
void allocateRegisters(); // main method called for allocatin
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
10
lib/Target/SparcV9/RegAlloc/RegAllocCommon.h
Normal file
10
lib/Target/SparcV9/RegAlloc/RegAllocCommon.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef REG_ALLOC_COMMON_H
|
||||
#define REG_ALLOC_COMMON_H
|
||||
|
||||
// set DEBUG_RA for printing out debug messages
|
||||
// if DEBUG_RA is 1 normal output messages
|
||||
// if DEBUG_RA is 2 extensive debug info for each instr
|
||||
|
||||
#define DEBUG_RA (1)
|
||||
|
||||
#endif
|
125
lib/Target/SparcV9/RegAlloc/RegClass.h
Normal file
125
lib/Target/SparcV9/RegAlloc/RegClass.h
Normal file
@ -0,0 +1,125 @@
|
||||
/* Title: RegClass.h
|
||||
Author: Ruchira Sasanka
|
||||
Date: Aug 20, 01
|
||||
Purpose: Contains machine independent methods for register coloring.
|
||||
|
||||
This is the class that contains all data structures and common algos
|
||||
for coloring a particular register class (e.g., int class, fp class).
|
||||
This class is hardware independent. This class accepts a hardware
|
||||
dependent description of machine registers (MachineRegInfo class) to
|
||||
get hardware specific info and color and indidual IG node.
|
||||
|
||||
This class contains the InterferenceGraph (IG).
|
||||
Also it contains an IGNode stack that can be used for coloring.
|
||||
The class provides some easy access methods to the IG methods, since these
|
||||
methods are called thru a register class.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef REG_CLASS_H
|
||||
#define REG_CLASS_H
|
||||
|
||||
#include "llvm/CodeGen/IGNode.h"
|
||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||
#include "llvm/CodeGen/TargetMachine.h"
|
||||
|
||||
|
||||
#include <stack>
|
||||
|
||||
|
||||
typedef vector<unsigned int> ReservedColorListType;
|
||||
|
||||
|
||||
class RegClass
|
||||
{
|
||||
|
||||
private:
|
||||
const Method *const Meth; // Method we are working on
|
||||
|
||||
const MachineRegClassInfo *const MRC; // corresponding MRC
|
||||
|
||||
const unsigned RegClassID; // my int ID
|
||||
|
||||
InterferenceGraph IG; // Interference graph - constructed by
|
||||
// buildInterferenceGraph
|
||||
stack <IGNode *> IGNodeStack; // the stack used for coloring
|
||||
|
||||
// for passing registered that are pre-allocated (e.g., %g's)
|
||||
const ReservedColorListType *const ReservedColorList;
|
||||
|
||||
// An array used for coloring each node. This array must be of size
|
||||
// MRC->getNumOfAllRegs(). Allocated once in the constructor
|
||||
// for efficiency.
|
||||
bool *IsColorUsedArr;
|
||||
|
||||
|
||||
//------------ private methods ------------------
|
||||
|
||||
void pushAllIGNodes();
|
||||
bool pushUnconstrainedIGNodes();
|
||||
IGNode * getIGNodeWithMinSpillCost();
|
||||
void colorIGNode(IGNode *const Node);
|
||||
|
||||
public:
|
||||
|
||||
RegClass(const Method *const M,
|
||||
const MachineRegClassInfo *const MRC,
|
||||
const ReservedColorListType *const RCL = NULL);
|
||||
|
||||
inline void createInterferenceGraph()
|
||||
{ IG.createGraph(); }
|
||||
|
||||
inline InterferenceGraph &getIG() { return IG; }
|
||||
|
||||
inline const unsigned getID() const { return RegClassID; }
|
||||
|
||||
void colorAllRegs(); // main method called for coloring regs
|
||||
|
||||
inline unsigned getNumOfAvailRegs() const
|
||||
{ return MRC->getNumOfAvailRegs(); }
|
||||
|
||||
~RegClass() { delete[] IsColorUsedArr; };
|
||||
|
||||
|
||||
|
||||
// --- following methods are provided to access the IG contained within this
|
||||
// ---- RegClass easilly.
|
||||
|
||||
|
||||
inline void addLRToIG(LiveRange *const LR)
|
||||
{ IG.addLRToIG(LR); }
|
||||
|
||||
inline void setInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2)
|
||||
{ IG.setInterference(LR1, LR2); }
|
||||
|
||||
inline unsigned getInterference(const LiveRange *const LR1,
|
||||
const LiveRange *const LR2) const
|
||||
{ return IG.getInterference(LR1, LR2); }
|
||||
|
||||
inline void mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||
LiveRange *const LR2)
|
||||
{ IG.mergeIGNodesOfLRs(LR1, LR2); }
|
||||
|
||||
|
||||
inline void printIGNodeList() const {
|
||||
cout << "IG Nodes for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIGNodeList();
|
||||
}
|
||||
|
||||
inline void printIG() {
|
||||
cout << "IG for Register Class " << RegClassID << ":" << endl;
|
||||
IG.printIG();
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user