mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-08 06:32:24 +00:00
Added destructors and comments.
Added correct spill candidate selection logic. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1493 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c1a29f10a6
commit
4f3eb22e1f
@ -1,6 +1,9 @@
|
|||||||
#include "llvm/CodeGen/IGNode.h"
|
#include "llvm/CodeGen/IGNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
||||||
AdjList(),
|
AdjList(),
|
||||||
ParentLR(PLR)
|
ParentLR(PLR)
|
||||||
@ -11,9 +14,11 @@ IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void IGNode::pushOnStack() // sets on to stack and
|
// Sets this IGNode on stack and reduce the degree of neighbors
|
||||||
{ // reduce the degree of neighbors
|
//-----------------------------------------------------------------------------
|
||||||
|
void IGNode::pushOnStack()
|
||||||
|
{
|
||||||
OnStack = true;
|
OnStack = true;
|
||||||
int neighs = AdjList.size();
|
int neighs = AdjList.size();
|
||||||
|
|
||||||
@ -25,7 +30,10 @@ void IGNode::pushOnStack() // sets on to stack and
|
|||||||
for(int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
for(int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Deletes an adjacency node. IGNodes are deleted when coalescing merges
|
||||||
|
// two IGNodes together.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
||||||
vector <IGNode *>::iterator It = AdjList.begin();
|
vector <IGNode *>::iterator It = AdjList.begin();
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor: Records the RegClass and initalizes IGNodeList.
|
||||||
|
// The matrix is NOT yet created by the constructor. Call createGraph()
|
||||||
|
// to create it after adding all IGNodes to the IGNodeList.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
||||||
IGNodeList()
|
IGNodeList()
|
||||||
{
|
{
|
||||||
@ -11,14 +15,34 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InterferenceGraph:: ~InterferenceGraph() { // destructor
|
|
||||||
if( IG )
|
//-----------------------------------------------------------------------------
|
||||||
delete []IG;
|
// destructor. Deletes the bit matrix and all IGNodes
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
InterferenceGraph:: ~InterferenceGraph() {
|
||||||
|
|
||||||
|
// delete the matrix
|
||||||
|
//
|
||||||
|
if( IG )
|
||||||
|
delete []IG;
|
||||||
|
|
||||||
|
// delete all IGNodes in the IGNodeList
|
||||||
|
//
|
||||||
|
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin();
|
||||||
|
for(unsigned i=0; i < IGNodeList.size() ; ++i) {
|
||||||
|
|
||||||
|
const IGNode *const Node = IGNodeList[i];
|
||||||
|
if( Node ) delete Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Creates (dynamically allocates) the bit matrix necessary to hold the
|
||||||
|
// interference graph.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::createGraph()
|
void InterferenceGraph::createGraph()
|
||||||
{
|
{
|
||||||
Size = IGNodeList.size();
|
Size = IGNodeList.size();
|
||||||
@ -32,21 +56,24 @@ void InterferenceGraph::createGraph()
|
|||||||
IG[i][j] = 0;
|
IG[i][j] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// creates a new IGNode for the given live range and add to IG
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
||||||
{
|
{
|
||||||
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
||||||
IGNodeList.push_back( Node );
|
IGNodeList.push_back( Node );
|
||||||
//Node->setRegClass( RegCl );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// set interference for two live ranges
|
||||||
// update both the matrix and AdjLists of nodes.
|
// update both the matrix and AdjLists of nodes.
|
||||||
// If there is already an interference between LR1 and LR2, adj lists
|
// If there is already an interference between LR1 and LR2, adj lists
|
||||||
// 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 LiveRange *const LR1,
|
||||||
const LiveRange *const LR2 ) {
|
const LiveRange *const LR2 ) {
|
||||||
assert(LR1 != LR2);
|
assert(LR1 != LR2);
|
||||||
@ -79,7 +106,9 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// return whether two live ranges interfere
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
||||||
const LiveRange *const LR2 ) const {
|
const LiveRange *const LR2 ) const {
|
||||||
|
|
||||||
@ -100,11 +129,12 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
||||||
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
||||||
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
||||||
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||||
LiveRange *const LR2 ) {
|
LiveRange *const LR2 ) {
|
||||||
@ -147,11 +177,6 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
|||||||
setInterference(LR1, LROfNeigh );
|
setInterference(LR1, LROfNeigh );
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
|
|
||||||
//cout << NeighNode->getNumOfNeighbors();
|
|
||||||
//cout << " Dest: [" << DestNode->getIndex() << "] ";
|
|
||||||
//cout << DestNode->getNumOfNeighbors() << endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IGNodeList[ SrcInd ] = NULL;
|
IGNodeList[ SrcInd ] = NULL;
|
||||||
@ -162,10 +187,10 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
// must be called after modifications to the graph are over but before
|
// must be called after modifications to the graph are over but before
|
||||||
// pushing IGNodes on to the stack for coloring.
|
// pushing IGNodes on to the stack for coloring.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::setCurDegreeOfIGNodes()
|
void InterferenceGraph::setCurDegreeOfIGNodes()
|
||||||
{
|
{
|
||||||
unsigned Size = IGNodeList.size();
|
unsigned Size = IGNodeList.size();
|
||||||
@ -183,7 +208,9 @@ void InterferenceGraph::setCurDegreeOfIGNodes()
|
|||||||
|
|
||||||
//--------------------- debugging (Printing) methods -----------------------
|
//--------------------- debugging (Printing) methods -----------------------
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Print the IGnodes
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::printIG() const
|
void InterferenceGraph::printIG() const
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -203,7 +230,9 @@ void InterferenceGraph::printIG() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Print the IGnodes in the IGNode List
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::printIGNodeList() const
|
void InterferenceGraph::printIGNodeList() const
|
||||||
{
|
{
|
||||||
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
||||||
const TargetMachine& tm,
|
const TargetMachine& tm,
|
||||||
vector<RegClass *> &RCL)
|
vector<RegClass *> &RCL)
|
||||||
@ -10,22 +13,58 @@ LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Destructor: Deletes all LiveRanges in the LiveRangeMap
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
LiveRangeInfo::~LiveRangeInfo() {
|
||||||
|
|
||||||
|
LiveRangeMapType::iterator MI = LiveRangeMap.begin();
|
||||||
|
|
||||||
|
for( ; MI != LiveRangeMap.end() ; ++MI) {
|
||||||
|
if( (*MI).first ) {
|
||||||
|
|
||||||
|
LiveRange *LR = (*MI).second;
|
||||||
|
|
||||||
|
if( LR ) {
|
||||||
|
|
||||||
|
// we need to be careful in deleting LiveRanges in LiveRangeMap
|
||||||
|
// 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
|
||||||
|
// a live range.
|
||||||
|
|
||||||
|
LiveRange::iterator LI = LR->begin();
|
||||||
|
|
||||||
|
for( ; LI != LR->end() ; ++LI) {
|
||||||
|
LiveRangeMap[*LI] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete LR;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
||||||
// Note: the caller must make sure that L1 and L2 are distinct and both
|
// Note: the caller must make sure that L1 and L2 are distinct and both
|
||||||
// LRs don't have suggested colors
|
// LRs don't have suggested colors
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
||||||
{
|
{
|
||||||
assert( L1 != L2);
|
assert( L1 != L2);
|
||||||
L1->setUnion( L2 ); // add elements of L2 to L1
|
L1->setUnion( L2 ); // add elements of L2 to L1
|
||||||
ValueSet::iterator L2It;
|
ValueSet::iterator L2It;
|
||||||
|
|
||||||
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
||||||
|
|
||||||
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
||||||
|
|
||||||
L1->add( *L2It ); // add the var in L2 to L1
|
L1->add( *L2It ); // add the var in L2 to L1
|
||||||
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map to L1
|
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map
|
||||||
|
//to L1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,13 +79,19 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
|||||||
if( L2->isCallInterference() )
|
if( L2->isCallInterference() )
|
||||||
L1->setCallInterference();
|
L1->setCallInterference();
|
||||||
|
|
||||||
|
|
||||||
|
L1->addSpillCost( L2->getSpillCost() ); // add the spill costs
|
||||||
|
|
||||||
delete ( L2 ); // delete L2 as it is no longer needed
|
delete ( L2 ); // delete L2 as it is no longer needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Method for constructing all live ranges in a method. It creates live
|
||||||
|
// ranges for all values defined in the instruction stream. Also, it
|
||||||
|
// creates live ranges for all incoming arguments of the method.
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::constructLiveRanges()
|
void LiveRangeInfo::constructLiveRanges()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -216,10 +261,14 @@ void LiveRangeInfo::constructLiveRanges()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
// Suggest colors for call and return args.
|
// If some live ranges must be colored with specific hardware registers
|
||||||
// Also create new LRs for implicit defs
|
// (e.g., for outgoing call args), suggesting of colors for such live
|
||||||
|
// ranges is done using target specific method. Those methods are called
|
||||||
|
// from this function. The target specific methods must:
|
||||||
|
// 1) suggest colors for call and return args.
|
||||||
|
// 2) create new LRs for implicit defs in machine instructions
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::suggestRegs4CallRets()
|
void LiveRangeInfo::suggestRegs4CallRets()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -243,11 +292,11 @@ void LiveRangeInfo::suggestRegs4CallRets()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// The following method coalesces live ranges when possible. This method
|
||||||
|
// must be called after the interference graph has been constructed.
|
||||||
|
|
||||||
|
|
||||||
void LiveRangeInfo::coalesceLRs()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Algorithm:
|
/* Algorithm:
|
||||||
for each BB in method
|
for each BB in method
|
||||||
for each machine instruction (inst)
|
for each machine instruction (inst)
|
||||||
@ -260,6 +309,11 @@ void LiveRangeInfo::coalesceLRs()
|
|||||||
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void LiveRangeInfo::coalesceLRs()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << endl << "Coalscing LRs ..." << endl;
|
cout << endl << "Coalscing LRs ..." << endl;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/MachineFrameInfo.h"
|
#include "llvm/Target/MachineFrameInfo.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
// ***TODO: There are several places we add instructions. Validate the order
|
// ***TODO: There are several places we add instructions. Validate the order
|
||||||
@ -41,22 +42,31 @@ PhyRegAlloc::PhyRegAlloc(Method *M,
|
|||||||
LVI(Lvi), LRI(M, tm, RegClassList),
|
LVI(Lvi), LRI(M, tm, RegClassList),
|
||||||
MRI( tm.getRegInfo() ),
|
MRI( tm.getRegInfo() ),
|
||||||
NumOfRegClasses(MRI.getNumOfRegClasses()),
|
NumOfRegClasses(MRI.getNumOfRegClasses()),
|
||||||
AddedInstrMap()
|
AddedInstrMap(), LoopDepthCalc(M), ResColList() {
|
||||||
|
|
||||||
{
|
|
||||||
// **TODO: use an actual reserved color list
|
|
||||||
ReservedColorListType *RCL = new ReservedColorListType();
|
|
||||||
|
|
||||||
// create each RegisterClass and put in RegClassList
|
// create each RegisterClass and put in RegClassList
|
||||||
|
//
|
||||||
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
||||||
RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), RCL) );
|
RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc),
|
||||||
|
&ResColList) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Destructor: Deletes register classes
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
PhyRegAlloc::~PhyRegAlloc() {
|
||||||
|
|
||||||
|
for( unsigned int rc=0; rc < NumOfRegClasses; rc++) {
|
||||||
|
RegClass *RC = RegClassList[rc];
|
||||||
|
delete RC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method initally creates interference graphs (one in each reg class)
|
// This method initally creates interference graphs (one in each reg class)
|
||||||
// and IGNodeList (one in each IG). The actual nodes will be pushed later.
|
// and IGNodeList (one in each IG). The actual nodes will be pushed later.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::createIGNodeListsAndIGs()
|
void PhyRegAlloc::createIGNodeListsAndIGs()
|
||||||
{
|
{
|
||||||
if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
|
if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
|
||||||
@ -71,7 +81,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
|
|||||||
|
|
||||||
if( (*HMI).first ) {
|
if( (*HMI).first ) {
|
||||||
|
|
||||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||||
|
|
||||||
if( !L) {
|
if( !L) {
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -103,13 +113,13 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will add all interferences at for a given instruction.
|
// This method will add all interferences at for a given instruction.
|
||||||
// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg
|
// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg
|
||||||
// class as that of live var. The live var passed to this function is the
|
// class as that of live var. The live var passed to this function is the
|
||||||
// LVset AFTER the instruction
|
// LVset AFTER the instruction
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::addInterference(const Value *const Def,
|
void PhyRegAlloc::addInterference(const Value *const Def,
|
||||||
const LiveVarSet *const LVSet,
|
const LiveVarSet *const LVSet,
|
||||||
const bool isCallInst) {
|
const bool isCallInst) {
|
||||||
@ -117,6 +127,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
LiveVarSet::const_iterator LIt = LVSet->begin();
|
LiveVarSet::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 LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );
|
||||||
|
|
||||||
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
||||||
@ -125,6 +136,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
RegClass *const RCOfDef = LROfDef->getRegClass();
|
RegClass *const RCOfDef = LROfDef->getRegClass();
|
||||||
|
|
||||||
// for each live var in live variable set
|
// for each live var in live variable set
|
||||||
|
//
|
||||||
for( ; LIt != LVSet->end(); ++LIt) {
|
for( ; LIt != LVSet->end(); ++LIt) {
|
||||||
|
|
||||||
if( DEBUG_RA > 1) {
|
if( DEBUG_RA > 1) {
|
||||||
@ -133,16 +145,19 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the live range corresponding to live var
|
// get the live range corresponding to live var
|
||||||
|
//
|
||||||
LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );
|
LiveRange *const 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
|
||||||
|
//
|
||||||
if( LROfVar) {
|
if( LROfVar) {
|
||||||
|
|
||||||
if(LROfDef == LROfVar) // do not set interf for same LR
|
if(LROfDef == LROfVar) // do not set interf for same LR
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// if 2 reg classes are the same set interference
|
// if 2 reg classes are the same set interference
|
||||||
|
//
|
||||||
if( RCOfDef == LROfVar->getRegClass() ){
|
if( RCOfDef == LROfVar->getRegClass() ){
|
||||||
RCOfDef->setInterference( LROfDef, LROfVar);
|
RCOfDef->setInterference( LROfDef, LROfVar);
|
||||||
|
|
||||||
@ -161,6 +176,8 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// For a call instruction, this method sets the CallInterference flag in
|
// For a call instruction, this method sets the CallInterference flag in
|
||||||
// the LR of each variable live int the Live Variable Set live after the
|
// the LR of each variable live int the Live Variable Set live after the
|
||||||
@ -169,18 +186,15 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
||||||
const LiveVarSet *const LVSetAft )
|
const LiveVarSet *const LVSetAft ) {
|
||||||
{
|
|
||||||
// Now find the LR of the return value of the call
|
// Now find the LR of the return value of the call
|
||||||
|
|
||||||
|
|
||||||
// We do this because, we look at the LV set *after* the instruction
|
// We do this because, we look at the LV set *after* the instruction
|
||||||
// to determine, which LRs must be saved across calls. The return value
|
// to determine, which LRs must be saved across calls. The return value
|
||||||
// of the call is live in this set - but it does not interfere with call
|
// of the call is live in this set - but it does not interfere with call
|
||||||
// (i.e., we can allocate a volatile register to the return value)
|
// (i.e., we can allocate a volatile register to the return value)
|
||||||
|
//
|
||||||
LiveRange *RetValLR = NULL;
|
LiveRange *RetValLR = NULL;
|
||||||
|
|
||||||
const Value *RetVal = MRI.getCallInstRetVal( MInst );
|
const Value *RetVal = MRI.getCallInstRetVal( MInst );
|
||||||
|
|
||||||
if( RetVal ) {
|
if( RetVal ) {
|
||||||
@ -194,9 +208,11 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
LiveVarSet::const_iterator LIt = LVSetAft->begin();
|
LiveVarSet::const_iterator LIt = LVSetAft->begin();
|
||||||
|
|
||||||
// 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 );
|
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
|
||||||
|
|
||||||
if( LR && DEBUG_RA) {
|
if( LR && DEBUG_RA) {
|
||||||
@ -207,6 +223,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
|
|
||||||
// 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
|
||||||
|
//
|
||||||
if( LR && (LR != RetValLR) ) {
|
if( LR && (LR != RetValLR) ) {
|
||||||
LR->setCallInterference();
|
LR->setCallInterference();
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -220,55 +237,72 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will walk thru code and create interferences in the IG of
|
// This method will walk thru code and create interferences in the IG of
|
||||||
// each RegClass.
|
// each RegClass. Also, this method calculates the spill cost of each
|
||||||
|
// Live Range (it is done in this method to save another pass over the code).
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::buildInterferenceGraphs()
|
void PhyRegAlloc::buildInterferenceGraphs()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
||||||
|
|
||||||
|
unsigned BBLoopDepthCost;
|
||||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||||
|
|
||||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||||
|
|
||||||
|
// find the 10^(loop_depth) of this BB
|
||||||
|
//
|
||||||
|
BBLoopDepthCost = (unsigned) pow( 10.0, LoopDepthCalc.getLoopDepth(*BBI));
|
||||||
|
|
||||||
// get the iterator for machine instructions
|
// get the iterator for machine instructions
|
||||||
|
//
|
||||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||||
MachineCodeForBasicBlock::const_iterator
|
MachineCodeForBasicBlock::const_iterator
|
||||||
MInstIterator = MIVec.begin();
|
MInstIterator = MIVec.begin();
|
||||||
|
|
||||||
// iterate over all the machine instructions in BB
|
// iterate over all the machine instructions in BB
|
||||||
|
//
|
||||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||||
|
|
||||||
const MachineInstr * MInst = *MInstIterator;
|
const MachineInstr * MInst = *MInstIterator;
|
||||||
|
|
||||||
// get the LV set after the instruction
|
// get the LV set after the instruction
|
||||||
|
//
|
||||||
const LiveVarSet *const LVSetAI =
|
const LiveVarSet *const LVSetAI =
|
||||||
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
||||||
|
|
||||||
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
||||||
|
|
||||||
if( isCallInst ) {
|
if( isCallInst ) {
|
||||||
//cout << "\nFor call inst: " << *MInst;
|
|
||||||
|
|
||||||
// set the isCallInterference flag of each live range wich extends
|
// set the isCallInterference flag of each live range wich extends
|
||||||
// accross this call instruction. This information is used by graph
|
// accross this call instruction. This information is used by graph
|
||||||
// coloring algo to avoid allocating volatile colors to live ranges
|
// coloring algo to avoid allocating volatile colors to live ranges
|
||||||
// that span across calls (since they have to be saved/restored)
|
// that span across calls (since they have to be saved/restored)
|
||||||
|
//
|
||||||
setCallInterferences( MInst, LVSetAI);
|
setCallInterferences( MInst, LVSetAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// iterate over MI operands to find defs
|
// iterate over all MI operands to find defs
|
||||||
|
//
|
||||||
for( MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
for( MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
||||||
|
|
||||||
if( OpI.isDef() ) {
|
if( OpI.isDef() ) {
|
||||||
// create a new LR iff this operand is a def
|
// create a new LR iff this operand is a def
|
||||||
|
//
|
||||||
addInterference(*OpI, LVSetAI, isCallInst );
|
addInterference(*OpI, LVSetAI, isCallInst );
|
||||||
} //if this is a def
|
}
|
||||||
} // for all operands
|
|
||||||
|
// Calculate the spill cost of each live range
|
||||||
|
//
|
||||||
|
LiveRange *LR = LRI.getLiveRangeForValue( *OpI );
|
||||||
|
if( LR )
|
||||||
|
LR->addSpillCost(BBLoopDepthCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if there are multiple defs in this instruction e.g. in SETX
|
// if there are multiple defs in this instruction e.g. in SETX
|
||||||
@ -279,7 +313,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
|
|
||||||
// Also add interference for any implicit definitions in a machine
|
// Also add interference for any implicit definitions in a machine
|
||||||
// instr (currently, only calls have this).
|
// instr (currently, only calls have this).
|
||||||
|
//
|
||||||
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
||||||
if( NumOfImpRefs > 0 ) {
|
if( NumOfImpRefs > 0 ) {
|
||||||
for(unsigned z=0; z < NumOfImpRefs; z++)
|
for(unsigned z=0; z < NumOfImpRefs; z++)
|
||||||
@ -287,11 +321,6 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
|
addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// record phi instrns in PhiInstList
|
|
||||||
if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) )
|
|
||||||
PhiInstList.push_back( MInst );
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // for all machine instructions in BB
|
} // for all machine instructions in BB
|
||||||
|
|
||||||
@ -300,24 +329,28 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
|
|
||||||
// add interferences for method arguments. Since there are no explict
|
// add interferences for method arguments. Since there are no explict
|
||||||
// defs in method for args, we have to add them manually
|
// defs in method for args, we have to add them manually
|
||||||
|
//
|
||||||
addInterferencesForArgs(); // add interference for method args
|
addInterferencesForArgs();
|
||||||
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << "Interference graphs calculted!" << endl;
|
cout << "Interference graphs calculted!" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Pseudo instructions will be exapnded to multiple instructions by the
|
// Pseudo instructions will be exapnded to multiple instructions by the
|
||||||
// assembler. Consequently, all the opernds must get distinct registers
|
// assembler. Consequently, all the opernds must get distinct registers.
|
||||||
|
// Therefore, we mark all operands of a pseudo instruction as they interfere
|
||||||
|
// with one another.
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
||||||
|
|
||||||
bool setInterf = false;
|
bool setInterf = false;
|
||||||
|
|
||||||
// iterate over MI operands to find defs
|
// iterate over MI operands to find defs
|
||||||
|
//
|
||||||
for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
|
for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
|
||||||
|
|
||||||
const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 );
|
const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 );
|
||||||
@ -325,8 +358,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
if( !LROfOp1 && It1.isDef() )
|
if( !LROfOp1 && It1.isDef() )
|
||||||
assert( 0 && "No LR for Def in PSEUDO insruction");
|
assert( 0 && "No LR for Def in PSEUDO insruction");
|
||||||
|
|
||||||
//if( !LROfOp1 ) continue;
|
|
||||||
|
|
||||||
MachineInstr::val_const_op_iterator It2 = It1;
|
MachineInstr::val_const_op_iterator It2 = It1;
|
||||||
++It2;
|
++It2;
|
||||||
|
|
||||||
@ -341,11 +372,9 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
|
|
||||||
if( RCOfOp1 == RCOfOp2 ){
|
if( RCOfOp1 == RCOfOp2 ){
|
||||||
RCOfOp1->setInterference( LROfOp1, LROfOp2 );
|
RCOfOp1->setInterference( LROfOp1, LROfOp2 );
|
||||||
//cerr << "\nSet interfs for PSEUDO inst: " << *MInst;
|
|
||||||
setInterf = true;
|
setInterf = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // if Op2 has a LR
|
} // if Op2 has a LR
|
||||||
|
|
||||||
} // for all other defs in machine instr
|
} // for all other defs in machine instr
|
||||||
@ -363,8 +392,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will add interferences for incoming arguments to a method.
|
// This method will add interferences for incoming arguments to a method.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -391,12 +418,16 @@ void PhyRegAlloc::addInterferencesForArgs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method is called after register allocation is complete to set the
|
// This method is called after register allocation is complete to set the
|
||||||
// allocated reisters in the machine code. This code will add register numbers
|
// allocated reisters in the machine code. This code will add register numbers
|
||||||
// to MachineOperands that contain a Value.
|
// to MachineOperands that contain a Value. Also it calls target specific
|
||||||
|
// methods to produce caller saving instructions. At the end, it adds all
|
||||||
|
// additional instructions produced by the register allocator to the
|
||||||
|
// instruction stream.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::updateMachineCode()
|
void PhyRegAlloc::updateMachineCode()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -405,35 +436,67 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||||
|
|
||||||
// get the iterator for machine instructions
|
// get the iterator for machine instructions
|
||||||
|
//
|
||||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||||
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
||||||
|
|
||||||
// iterate over all the machine instructions in BB
|
// iterate over all the machine instructions in BB
|
||||||
|
//
|
||||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||||
|
|
||||||
MachineInstr *MInst = *MInstIterator;
|
MachineInstr *MInst = *MInstIterator;
|
||||||
|
|
||||||
|
unsigned Opcode = MInst->getOpCode();
|
||||||
|
|
||||||
// do not process Phis
|
// do not process Phis
|
||||||
if( (TM.getInstrInfo()).isPhi( MInst->getOpCode()) )
|
if( (TM.getInstrInfo()).isPhi( Opcode ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Now insert speical instructions (if necessary) for call/return
|
||||||
|
// instructions.
|
||||||
|
//
|
||||||
|
if( (TM.getInstrInfo()).isCall( Opcode) ||
|
||||||
|
(TM.getInstrInfo()).isReturn( Opcode) ) {
|
||||||
|
|
||||||
|
AddedInstrns *AI = AddedInstrMap[ MInst];
|
||||||
|
if ( !AI ) {
|
||||||
|
AI = new AddedInstrns();
|
||||||
|
AddedInstrMap[ MInst ] = AI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tmp stack poistions are needed by some calls that have spilled args
|
||||||
|
// So reset it before we call each such method
|
||||||
|
// TODO: mcInfo.popAllTempValues(TM);
|
||||||
|
|
||||||
|
if( (TM.getInstrInfo()).isCall( Opcode ) )
|
||||||
|
MRI.colorCallArgs( MInst, LRI, AI, *this, *BBI );
|
||||||
|
|
||||||
|
else if ( (TM.getInstrInfo()).isReturn(Opcode) )
|
||||||
|
MRI.colorRetValue( MInst, LRI, AI );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -- Using above code instead of this
|
||||||
|
|
||||||
// if this machine instr is call, insert caller saving code
|
// if this machine instr is call, insert caller saving code
|
||||||
|
|
||||||
if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
||||||
MRI.insertCallerSavingCode(MInst, *BBI, *this );
|
MRI.insertCallerSavingCode(MInst, *BBI, *this );
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// reset the stack offset for temporary variables since we may
|
// reset the stack offset for temporary variables since we may
|
||||||
// need that to spill
|
// need that to spill
|
||||||
//mcInfo.popAllTempValues(TM);
|
// mcInfo.popAllTempValues(TM);
|
||||||
// TODO ** : do later
|
// TODO ** : do later
|
||||||
|
|
||||||
//for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
//for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||||
|
|
||||||
|
|
||||||
// Now replace set the registers for operands in the machine instruction
|
// Now replace set the registers for operands in the machine instruction
|
||||||
|
//
|
||||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||||
|
|
||||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||||
@ -490,9 +553,14 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
} // for each operand
|
} // for each operand
|
||||||
|
|
||||||
|
|
||||||
|
// Now add instructions that the register allocator inserts before/after
|
||||||
|
// this machine instructions (done only for calls/rets/incoming args)
|
||||||
|
// We do this here, to ensure that spill for an instruction is inserted
|
||||||
|
// closest as possible to an instruction (see above insertCode4Spill...)
|
||||||
|
//
|
||||||
// If there are instructions to be added, *before* this machine
|
// If there are instructions to be added, *before* this machine
|
||||||
// instruction, add them now.
|
// instruction, add them now.
|
||||||
|
//
|
||||||
if( AddedInstrMap[ MInst ] ) {
|
if( AddedInstrMap[ MInst ] ) {
|
||||||
|
|
||||||
deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
|
deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
|
||||||
@ -518,7 +586,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
|
|
||||||
// If there are instructions to be added *after* this machine
|
// If there are instructions to be added *after* this machine
|
||||||
// instruction, add them now
|
// instruction, add them now
|
||||||
|
//
|
||||||
if( AddedInstrMap[ MInst ] &&
|
if( AddedInstrMap[ MInst ] &&
|
||||||
! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
|
! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
|
||||||
|
|
||||||
@ -600,9 +668,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
|||||||
RegClass *RC = LR->getRegClass();
|
RegClass *RC = LR->getRegClass();
|
||||||
const LiveVarSet *LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB);
|
const LiveVarSet *LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB);
|
||||||
|
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
|
||||||
int TmpOff =
|
int TmpOff =
|
||||||
mcInfo.pushTempValue(TM, 8 /* TM.findOptimalStorageSize(LR->getType()) */);
|
mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
|
||||||
|
|
||||||
MachineInstr *MIBef=NULL, *AdIMid=NULL, *MIAft=NULL;
|
MachineInstr *MIBef=NULL, *AdIMid=NULL, *MIAft=NULL;
|
||||||
|
|
||||||
@ -696,8 +764,7 @@ int PhyRegAlloc::getUsableUniRegAtMI(RegClass *RC,
|
|||||||
// we couldn't find an unused register. Generate code to free up a reg by
|
// we couldn't find an unused register. Generate code to free up a reg by
|
||||||
// saving it on stack and restoring after the instruction
|
// saving it on stack and restoring after the instruction
|
||||||
|
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
int TmpOff = mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
|
||||||
int TmpOff = mcInfo.pushTempValue(TM, /*size*/ 8);
|
|
||||||
|
|
||||||
RegU = getUniRegNotUsedByThisInst(RC, MInst);
|
RegU = getUniRegNotUsedByThisInst(RC, MInst);
|
||||||
MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
|
MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
|
||||||
@ -1003,6 +1070,8 @@ void PhyRegAlloc::printMachineCode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1043,7 +1112,7 @@ void PhyRegAlloc::colorCallRetArgs()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1134,8 +1203,11 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs()
|
|||||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||||
if(L)
|
if(L)
|
||||||
if( ! L->hasColor() )
|
if( ! L->hasColor() )
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
|
||||||
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy /*L->getType()*/ ));
|
// NOTE: ** allocating the size of long Type **
|
||||||
|
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM,
|
||||||
|
Type::LongTy));
|
||||||
|
|
||||||
}
|
}
|
||||||
} // for all LR's in hash map
|
} // for all LR's in hash map
|
||||||
}
|
}
|
||||||
@ -1152,8 +1224,8 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
// make sure that we put all register classes into the RegClassList
|
// make sure that we put all register classes into the RegClassList
|
||||||
// before we call constructLiveRanges (now done in the constructor of
|
// before we call constructLiveRanges (now done in the constructor of
|
||||||
// PhyRegAlloc class).
|
// PhyRegAlloc class).
|
||||||
|
//
|
||||||
constructLiveRanges(); // create LR info
|
LRI.constructLiveRanges(); // create LR info
|
||||||
|
|
||||||
if( DEBUG_RA )
|
if( DEBUG_RA )
|
||||||
LRI.printLiveRanges();
|
LRI.printLiveRanges();
|
||||||
@ -1173,11 +1245,9 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
RegClassList[ rc ]->printIG();
|
RegClassList[ rc ]->printIG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LRI.coalesceLRs(); // coalesce all live ranges
|
LRI.coalesceLRs(); // coalesce all live ranges
|
||||||
|
|
||||||
// coalscing could not get rid of all phi's, add phi elimination
|
|
||||||
// instructions
|
|
||||||
// insertPhiEleminateInstrns();
|
|
||||||
|
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
// print all LRs in all reg classes
|
// print all LRs in all reg classes
|
||||||
@ -1193,6 +1263,7 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
// mark un-usable suggested color before graph coloring algorithm.
|
// mark un-usable suggested color before graph coloring algorithm.
|
||||||
// When this is done, the graph coloring algo will not reserve
|
// When this is done, the graph coloring algo will not reserve
|
||||||
// suggested color unnecessarily - they can be used by another LR
|
// suggested color unnecessarily - they can be used by another LR
|
||||||
|
//
|
||||||
markUnusableSugColors();
|
markUnusableSugColors();
|
||||||
|
|
||||||
// color all register classes using the graph coloring algo
|
// color all register classes using the graph coloring algo
|
||||||
@ -1201,32 +1272,29 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
|
|
||||||
// Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
|
// Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
|
||||||
// a poistion for such spilled LRs
|
// a poistion for such spilled LRs
|
||||||
|
//
|
||||||
allocateStackSpace4SpilledLRs();
|
allocateStackSpace4SpilledLRs();
|
||||||
|
|
||||||
mcInfo.popAllTempValues(TM); // TODO **Check
|
mcInfo.popAllTempValues(TM); // TODO **Check
|
||||||
|
|
||||||
// color incoming args and call args
|
// color incoming args - if the correct color was not received
|
||||||
|
// insert code to copy to the correct register
|
||||||
|
//
|
||||||
colorIncomingArgs();
|
colorIncomingArgs();
|
||||||
colorCallRetArgs();
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now update the machine code with register names and add any
|
||||||
|
// additional code inserted by the register allocator to the instruction
|
||||||
|
// stream
|
||||||
|
//
|
||||||
updateMachineCode();
|
updateMachineCode();
|
||||||
|
|
||||||
|
|
||||||
if (DEBUG_RA) {
|
if (DEBUG_RA) {
|
||||||
MachineCodeForMethod::get(Meth).dump();
|
MachineCodeForMethod::get(Meth).dump();
|
||||||
printMachineCode(); // only for DEBUGGING
|
printMachineCode(); // only for DEBUGGING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
printMachineCode(); // only for DEBUGGING
|
|
||||||
|
|
||||||
cout << "\nAllocted for method " << Meth->getName();
|
|
||||||
char ch;
|
|
||||||
cin >> ch;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,35 +1,37 @@
|
|||||||
#include "llvm/CodeGen/RegClass.h"
|
#include "llvm/CodeGen/RegClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// This constructor inits IG. The actual matrix is created by a call to
|
||||||
|
// createInterferenceGraph() above.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
RegClass::RegClass(const Method *const M,
|
RegClass::RegClass(const Method *const M,
|
||||||
const MachineRegClassInfo *const Mrc,
|
const MachineRegClassInfo *const Mrc,
|
||||||
const ReservedColorListType *const RCL)
|
const ReservedColorListType *const RCL)
|
||||||
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
||||||
IG(this), IGNodeStack(), ReservedColorList(RCL)
|
IG(this), IGNodeStack(), ReservedColorList(RCL) {
|
||||||
{
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << "Created Reg Class: " << RegClassID << endl;
|
cout << "Created Reg Class: " << RegClassID << endl;
|
||||||
|
|
||||||
// This constructor inits IG. The actual matrix is created by a call to
|
|
||||||
// createInterferenceGraph() above.
|
|
||||||
|
|
||||||
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Main entry point for coloring a register class.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::colorAllRegs()
|
void RegClass::colorAllRegs()
|
||||||
{
|
{
|
||||||
if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
|
if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
|
||||||
|
|
||||||
//preColorIGNodes(); // pre-color IGNodes
|
// pre-color IGNodes
|
||||||
pushAllIGNodes(); // push all IG Nodes
|
pushAllIGNodes(); // push all IG Nodes
|
||||||
|
|
||||||
unsigned int StackSize = IGNodeStack.size();
|
unsigned int StackSize = IGNodeStack.size();
|
||||||
IGNode *CurIGNode;
|
IGNode *CurIGNode;
|
||||||
|
|
||||||
// for all LRs on stack
|
// for all LRs on stack
|
||||||
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
||||||
|
|
||||||
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
||||||
@ -37,13 +39,13 @@ void RegClass::colorAllRegs()
|
|||||||
colorIGNode (CurIGNode); // color it
|
colorIGNode (CurIGNode); // color it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// InsertSpillCode; ********* TODO ********
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// The method for pushing all IGNodes on to the stack.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::pushAllIGNodes()
|
void RegClass::pushAllIGNodes()
|
||||||
{
|
{
|
||||||
bool NeedMoreSpills;
|
bool NeedMoreSpills;
|
||||||
@ -51,7 +53,7 @@ void RegClass::pushAllIGNodes()
|
|||||||
|
|
||||||
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
||||||
|
|
||||||
// push non-constrained IGNodes
|
// push non-constrained IGNodes
|
||||||
bool PushedAll = pushUnconstrainedIGNodes();
|
bool PushedAll = pushUnconstrainedIGNodes();
|
||||||
|
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -71,15 +73,19 @@ void RegClass::pushAllIGNodes()
|
|||||||
do{
|
do{
|
||||||
|
|
||||||
//get node with min spill cost
|
//get node with min spill cost
|
||||||
|
//
|
||||||
IGNode *IGNodeSpill = getIGNodeWithMinSpillCost();
|
IGNode *IGNodeSpill = getIGNodeWithMinSpillCost();
|
||||||
|
|
||||||
// push that node on to stack
|
// push that node on to stack
|
||||||
|
//
|
||||||
IGNodeStack.push( IGNodeSpill );
|
IGNodeStack.push( IGNodeSpill );
|
||||||
|
|
||||||
// set its OnStack flag and decrement degree of neighs
|
// set its OnStack flag and decrement degree of neighs
|
||||||
|
//
|
||||||
IGNodeSpill->pushOnStack();
|
IGNodeSpill->pushOnStack();
|
||||||
|
|
||||||
// now push NON-constrined ones, if any
|
// now push NON-constrined ones, if any
|
||||||
|
//
|
||||||
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
||||||
|
|
||||||
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
|
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
|
||||||
@ -137,46 +143,72 @@ bool RegClass::pushUnconstrainedIGNodes()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Get the IGNode withe the minimum spill cost
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
||||||
{
|
{
|
||||||
IGNode *IGNode=NULL;
|
|
||||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
|
||||||
|
|
||||||
// pass over IGNodeList
|
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||||
|
long MinSpillCost = -1;
|
||||||
|
IGNode *MinCostIGNode = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
// pass over IGNodeList to find the IGNode with minimum spill cost
|
||||||
|
// among all IGNodes that are not yet pushed on to the stack
|
||||||
|
//
|
||||||
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
||||||
IGNode = IG.getIGNodeList()[i];
|
IGNode *IGNode = IG.getIGNodeList()[i];
|
||||||
|
|
||||||
if( ! IGNode ) // can be null due to merging
|
if( ! IGNode ) // can be null due to merging
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if( ! IGNode->isOnStack() ) {
|
||||||
|
|
||||||
|
unsigned SpillCost = IGNode->getParentLR()->getSpillCost();
|
||||||
|
|
||||||
// return the first IGNode ########## Change this #######
|
if( MinSpillCost == -1) { // for the first IG node
|
||||||
if( ! IGNode->isOnStack() ) return IGNode;
|
MinSpillCost = SpillCost;
|
||||||
|
MinCostIGNode = IGNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( MinSpillCost > SpillCost) {
|
||||||
|
MinSpillCost = SpillCost;
|
||||||
|
MinCostIGNode = IGNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
assert( MinCostIGNode && "No IGNode to spill");
|
||||||
return NULL;
|
return MinCostIGNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Color the IGNode using the machine specific code.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::colorIGNode(IGNode *const Node)
|
void RegClass::colorIGNode(IGNode *const Node)
|
||||||
{
|
{
|
||||||
|
|
||||||
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
||||||
|
|
||||||
|
|
||||||
// init all elements to false;
|
// init all elements of to IsColorUsedAr false;
|
||||||
|
//
|
||||||
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
||||||
IsColorUsedArr[ i ] = false;
|
IsColorUsedArr[ i ] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init all reserved_regs to true - we can't use them
|
// init all reserved_regs to true - we can't use them
|
||||||
|
//
|
||||||
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
||||||
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call the target specific code for coloring
|
||||||
|
//
|
||||||
MRC->colorIGNode(Node, IsColorUsedArr);
|
MRC->colorIGNode(Node, IsColorUsedArr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#include "llvm/CodeGen/IGNode.h"
|
#include "llvm/CodeGen/IGNode.h"
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
||||||
AdjList(),
|
AdjList(),
|
||||||
ParentLR(PLR)
|
ParentLR(PLR)
|
||||||
@ -11,9 +14,11 @@ IGNode::IGNode(LiveRange *const PLR, unsigned int Ind): Index(Ind),
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void IGNode::pushOnStack() // sets on to stack and
|
// Sets this IGNode on stack and reduce the degree of neighbors
|
||||||
{ // reduce the degree of neighbors
|
//-----------------------------------------------------------------------------
|
||||||
|
void IGNode::pushOnStack()
|
||||||
|
{
|
||||||
OnStack = true;
|
OnStack = true;
|
||||||
int neighs = AdjList.size();
|
int neighs = AdjList.size();
|
||||||
|
|
||||||
@ -25,7 +30,10 @@ void IGNode::pushOnStack() // sets on to stack and
|
|||||||
for(int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
for(int i=0; i < neighs; i++) (AdjList[i])->decCurDegree();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Deletes an adjacency node. IGNodes are deleted when coalescing merges
|
||||||
|
// two IGNodes together.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
void IGNode::delAdjIGNode(const IGNode *const Node) {
|
||||||
vector <IGNode *>::iterator It = AdjList.begin();
|
vector <IGNode *>::iterator It = AdjList.begin();
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
#include "llvm/CodeGen/InterferenceGraph.h"
|
#include "llvm/CodeGen/InterferenceGraph.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Constructor: Records the RegClass and initalizes IGNodeList.
|
||||||
|
// The matrix is NOT yet created by the constructor. Call createGraph()
|
||||||
|
// to create it after adding all IGNodes to the IGNodeList.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
||||||
IGNodeList()
|
IGNodeList()
|
||||||
{
|
{
|
||||||
@ -11,14 +15,34 @@ InterferenceGraph::InterferenceGraph(RegClass *const RC) : RegCl(RC),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
InterferenceGraph:: ~InterferenceGraph() { // destructor
|
|
||||||
if( IG )
|
//-----------------------------------------------------------------------------
|
||||||
delete []IG;
|
// destructor. Deletes the bit matrix and all IGNodes
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
InterferenceGraph:: ~InterferenceGraph() {
|
||||||
|
|
||||||
|
// delete the matrix
|
||||||
|
//
|
||||||
|
if( IG )
|
||||||
|
delete []IG;
|
||||||
|
|
||||||
|
// delete all IGNodes in the IGNodeList
|
||||||
|
//
|
||||||
|
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin();
|
||||||
|
for(unsigned i=0; i < IGNodeList.size() ; ++i) {
|
||||||
|
|
||||||
|
const IGNode *const Node = IGNodeList[i];
|
||||||
|
if( Node ) delete Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Creates (dynamically allocates) the bit matrix necessary to hold the
|
||||||
|
// interference graph.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::createGraph()
|
void InterferenceGraph::createGraph()
|
||||||
{
|
{
|
||||||
Size = IGNodeList.size();
|
Size = IGNodeList.size();
|
||||||
@ -32,21 +56,24 @@ void InterferenceGraph::createGraph()
|
|||||||
IG[i][j] = 0;
|
IG[i][j] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// creates a new IGNode for the given live range and add to IG
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
void InterferenceGraph::addLRToIG(LiveRange *const LR)
|
||||||
{
|
{
|
||||||
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
IGNode *Node = new IGNode(LR, IGNodeList.size() );
|
||||||
IGNodeList.push_back( Node );
|
IGNodeList.push_back( Node );
|
||||||
//Node->setRegClass( RegCl );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// set interference for two live ranges
|
||||||
// update both the matrix and AdjLists of nodes.
|
// update both the matrix and AdjLists of nodes.
|
||||||
// If there is already an interference between LR1 and LR2, adj lists
|
// If there is already an interference between LR1 and LR2, adj lists
|
||||||
// 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 LiveRange *const LR1,
|
||||||
const LiveRange *const LR2 ) {
|
const LiveRange *const LR2 ) {
|
||||||
assert(LR1 != LR2);
|
assert(LR1 != LR2);
|
||||||
@ -79,7 +106,9 @@ void InterferenceGraph::setInterference(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// return whether two live ranges interfere
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
||||||
const LiveRange *const LR2 ) const {
|
const LiveRange *const LR2 ) const {
|
||||||
|
|
||||||
@ -100,11 +129,12 @@ unsigned InterferenceGraph::getInterference(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
// Merge 2 IGNodes. The neighbors of the SrcNode will be added to the DestNode.
|
||||||
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
// Then the IGNode2L will be deleted. Necessary for coalescing.
|
||||||
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
// IMPORTANT: The live ranges are NOT merged by this method. Use
|
||||||
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
// LiveRangeInfo::unionAndUpdateLRs for that purpose.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
||||||
LiveRange *const LR2 ) {
|
LiveRange *const LR2 ) {
|
||||||
@ -147,11 +177,6 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
|||||||
setInterference(LR1, LROfNeigh );
|
setInterference(LR1, LROfNeigh );
|
||||||
}
|
}
|
||||||
|
|
||||||
//cout<< " #Neighs - Neigh: ["<< NeighNode->getIndex()<< "] ";
|
|
||||||
//cout << NeighNode->getNumOfNeighbors();
|
|
||||||
//cout << " Dest: [" << DestNode->getIndex() << "] ";
|
|
||||||
//cout << DestNode->getNumOfNeighbors() << endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IGNodeList[ SrcInd ] = NULL;
|
IGNodeList[ SrcInd ] = NULL;
|
||||||
@ -162,10 +187,10 @@ void InterferenceGraph::mergeIGNodesOfLRs(const LiveRange *const LR1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
// must be called after modifications to the graph are over but before
|
// must be called after modifications to the graph are over but before
|
||||||
// pushing IGNodes on to the stack for coloring.
|
// pushing IGNodes on to the stack for coloring.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::setCurDegreeOfIGNodes()
|
void InterferenceGraph::setCurDegreeOfIGNodes()
|
||||||
{
|
{
|
||||||
unsigned Size = IGNodeList.size();
|
unsigned Size = IGNodeList.size();
|
||||||
@ -183,7 +208,9 @@ void InterferenceGraph::setCurDegreeOfIGNodes()
|
|||||||
|
|
||||||
//--------------------- debugging (Printing) methods -----------------------
|
//--------------------- debugging (Printing) methods -----------------------
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Print the IGnodes
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::printIG() const
|
void InterferenceGraph::printIG() const
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -203,7 +230,9 @@ void InterferenceGraph::printIG() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Print the IGnodes in the IGNode List
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void InterferenceGraph::printIGNodeList() const
|
void InterferenceGraph::printIGNodeList() const
|
||||||
{
|
{
|
||||||
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
vector<IGNode *>::const_iterator IGIt = IGNodeList.begin(); // hash map iter
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include "llvm/CodeGen/LiveRangeInfo.h"
|
#include "llvm/CodeGen/LiveRangeInfo.h"
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
||||||
const TargetMachine& tm,
|
const TargetMachine& tm,
|
||||||
vector<RegClass *> &RCL)
|
vector<RegClass *> &RCL)
|
||||||
@ -10,22 +13,58 @@ LiveRangeInfo::LiveRangeInfo(const Method *const M,
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Destructor: Deletes all LiveRanges in the LiveRangeMap
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
LiveRangeInfo::~LiveRangeInfo() {
|
||||||
|
|
||||||
|
LiveRangeMapType::iterator MI = LiveRangeMap.begin();
|
||||||
|
|
||||||
|
for( ; MI != LiveRangeMap.end() ; ++MI) {
|
||||||
|
if( (*MI).first ) {
|
||||||
|
|
||||||
|
LiveRange *LR = (*MI).second;
|
||||||
|
|
||||||
|
if( LR ) {
|
||||||
|
|
||||||
|
// we need to be careful in deleting LiveRanges in LiveRangeMap
|
||||||
|
// 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
|
||||||
|
// a live range.
|
||||||
|
|
||||||
|
LiveRange::iterator LI = LR->begin();
|
||||||
|
|
||||||
|
for( ; LI != LR->end() ; ++LI) {
|
||||||
|
LiveRangeMap[*LI] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete LR;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
// union two live ranges into one. The 2nd LR is deleted. Used for coalescing.
|
||||||
// Note: the caller must make sure that L1 and L2 are distinct and both
|
// Note: the caller must make sure that L1 and L2 are distinct and both
|
||||||
// LRs don't have suggested colors
|
// LRs don't have suggested colors
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
||||||
{
|
{
|
||||||
assert( L1 != L2);
|
assert( L1 != L2);
|
||||||
L1->setUnion( L2 ); // add elements of L2 to L1
|
L1->setUnion( L2 ); // add elements of L2 to L1
|
||||||
ValueSet::iterator L2It;
|
ValueSet::iterator L2It;
|
||||||
|
|
||||||
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
for( L2It = L2->begin() ; L2It != L2->end(); ++L2It) {
|
||||||
|
|
||||||
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
//assert(( L1->getTypeID() == L2->getTypeID()) && "Merge:Different types");
|
||||||
|
|
||||||
L1->add( *L2It ); // add the var in L2 to L1
|
L1->add( *L2It ); // add the var in L2 to L1
|
||||||
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map to L1
|
LiveRangeMap[ *L2It ] = L1; // now the elements in L2 should map
|
||||||
|
//to L1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -40,13 +79,19 @@ void LiveRangeInfo::unionAndUpdateLRs(LiveRange *const L1, LiveRange *L2)
|
|||||||
if( L2->isCallInterference() )
|
if( L2->isCallInterference() )
|
||||||
L1->setCallInterference();
|
L1->setCallInterference();
|
||||||
|
|
||||||
|
|
||||||
|
L1->addSpillCost( L2->getSpillCost() ); // add the spill costs
|
||||||
|
|
||||||
delete ( L2 ); // delete L2 as it is no longer needed
|
delete ( L2 ); // delete L2 as it is no longer needed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
// Method for constructing all live ranges in a method. It creates live
|
||||||
|
// ranges for all values defined in the instruction stream. Also, it
|
||||||
|
// creates live ranges for all incoming arguments of the method.
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::constructLiveRanges()
|
void LiveRangeInfo::constructLiveRanges()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -216,10 +261,14 @@ void LiveRangeInfo::constructLiveRanges()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
// Suggest colors for call and return args.
|
// If some live ranges must be colored with specific hardware registers
|
||||||
// Also create new LRs for implicit defs
|
// (e.g., for outgoing call args), suggesting of colors for such live
|
||||||
|
// ranges is done using target specific method. Those methods are called
|
||||||
|
// from this function. The target specific methods must:
|
||||||
|
// 1) suggest colors for call and return args.
|
||||||
|
// 2) create new LRs for implicit defs in machine instructions
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
void LiveRangeInfo::suggestRegs4CallRets()
|
void LiveRangeInfo::suggestRegs4CallRets()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -243,11 +292,11 @@ void LiveRangeInfo::suggestRegs4CallRets()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// The following method coalesces live ranges when possible. This method
|
||||||
|
// must be called after the interference graph has been constructed.
|
||||||
|
|
||||||
|
|
||||||
void LiveRangeInfo::coalesceLRs()
|
|
||||||
{
|
|
||||||
|
|
||||||
/* Algorithm:
|
/* Algorithm:
|
||||||
for each BB in method
|
for each BB in method
|
||||||
for each machine instruction (inst)
|
for each machine instruction (inst)
|
||||||
@ -260,6 +309,11 @@ void LiveRangeInfo::coalesceLRs()
|
|||||||
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
merge2IGNodes(def, op) // i.e., merge 2 LRs
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
//---------------------------------------------------------------------------
|
||||||
|
void LiveRangeInfo::coalesceLRs()
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << endl << "Coalscing LRs ..." << endl;
|
cout << endl << "Coalscing LRs ..." << endl;
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "llvm/CodeGen/MachineInstr.h"
|
#include "llvm/CodeGen/MachineInstr.h"
|
||||||
#include "llvm/Target/TargetMachine.h"
|
#include "llvm/Target/TargetMachine.h"
|
||||||
#include "llvm/Target/MachineFrameInfo.h"
|
#include "llvm/Target/MachineFrameInfo.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
// ***TODO: There are several places we add instructions. Validate the order
|
// ***TODO: There are several places we add instructions. Validate the order
|
||||||
@ -41,22 +42,31 @@ PhyRegAlloc::PhyRegAlloc(Method *M,
|
|||||||
LVI(Lvi), LRI(M, tm, RegClassList),
|
LVI(Lvi), LRI(M, tm, RegClassList),
|
||||||
MRI( tm.getRegInfo() ),
|
MRI( tm.getRegInfo() ),
|
||||||
NumOfRegClasses(MRI.getNumOfRegClasses()),
|
NumOfRegClasses(MRI.getNumOfRegClasses()),
|
||||||
AddedInstrMap()
|
AddedInstrMap(), LoopDepthCalc(M), ResColList() {
|
||||||
|
|
||||||
{
|
|
||||||
// **TODO: use an actual reserved color list
|
|
||||||
ReservedColorListType *RCL = new ReservedColorListType();
|
|
||||||
|
|
||||||
// create each RegisterClass and put in RegClassList
|
// create each RegisterClass and put in RegClassList
|
||||||
|
//
|
||||||
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
for( unsigned int rc=0; rc < NumOfRegClasses; rc++)
|
||||||
RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc), RCL) );
|
RegClassList.push_back( new RegClass(M, MRI.getMachineRegClass(rc),
|
||||||
|
&ResColList) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Destructor: Deletes register classes
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
PhyRegAlloc::~PhyRegAlloc() {
|
||||||
|
|
||||||
|
for( unsigned int rc=0; rc < NumOfRegClasses; rc++) {
|
||||||
|
RegClass *RC = RegClassList[rc];
|
||||||
|
delete RC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method initally creates interference graphs (one in each reg class)
|
// This method initally creates interference graphs (one in each reg class)
|
||||||
// and IGNodeList (one in each IG). The actual nodes will be pushed later.
|
// and IGNodeList (one in each IG). The actual nodes will be pushed later.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::createIGNodeListsAndIGs()
|
void PhyRegAlloc::createIGNodeListsAndIGs()
|
||||||
{
|
{
|
||||||
if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
|
if(DEBUG_RA ) cout << "Creating LR lists ..." << endl;
|
||||||
@ -71,7 +81,7 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
|
|||||||
|
|
||||||
if( (*HMI).first ) {
|
if( (*HMI).first ) {
|
||||||
|
|
||||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||||
|
|
||||||
if( !L) {
|
if( !L) {
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -103,13 +113,13 @@ void PhyRegAlloc::createIGNodeListsAndIGs()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will add all interferences at for a given instruction.
|
// This method will add all interferences at for a given instruction.
|
||||||
// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg
|
// Interence occurs only if the LR of Def (Inst or Arg) is of the same reg
|
||||||
// class as that of live var. The live var passed to this function is the
|
// class as that of live var. The live var passed to this function is the
|
||||||
// LVset AFTER the instruction
|
// LVset AFTER the instruction
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::addInterference(const Value *const Def,
|
void PhyRegAlloc::addInterference(const Value *const Def,
|
||||||
const LiveVarSet *const LVSet,
|
const LiveVarSet *const LVSet,
|
||||||
const bool isCallInst) {
|
const bool isCallInst) {
|
||||||
@ -117,6 +127,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
LiveVarSet::const_iterator LIt = LVSet->begin();
|
LiveVarSet::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 LiveRange *const LROfDef = LRI.getLiveRangeForValue( Def );
|
||||||
|
|
||||||
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
IGNode *const IGNodeOfDef = LROfDef->getUserIGNode();
|
||||||
@ -125,6 +136,7 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
RegClass *const RCOfDef = LROfDef->getRegClass();
|
RegClass *const RCOfDef = LROfDef->getRegClass();
|
||||||
|
|
||||||
// for each live var in live variable set
|
// for each live var in live variable set
|
||||||
|
//
|
||||||
for( ; LIt != LVSet->end(); ++LIt) {
|
for( ; LIt != LVSet->end(); ++LIt) {
|
||||||
|
|
||||||
if( DEBUG_RA > 1) {
|
if( DEBUG_RA > 1) {
|
||||||
@ -133,16 +145,19 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get the live range corresponding to live var
|
// get the live range corresponding to live var
|
||||||
|
//
|
||||||
LiveRange *const LROfVar = LRI.getLiveRangeForValue(*LIt );
|
LiveRange *const 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
|
||||||
|
//
|
||||||
if( LROfVar) {
|
if( LROfVar) {
|
||||||
|
|
||||||
if(LROfDef == LROfVar) // do not set interf for same LR
|
if(LROfDef == LROfVar) // do not set interf for same LR
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// if 2 reg classes are the same set interference
|
// if 2 reg classes are the same set interference
|
||||||
|
//
|
||||||
if( RCOfDef == LROfVar->getRegClass() ){
|
if( RCOfDef == LROfVar->getRegClass() ){
|
||||||
RCOfDef->setInterference( LROfDef, LROfVar);
|
RCOfDef->setInterference( LROfDef, LROfVar);
|
||||||
|
|
||||||
@ -161,6 +176,8 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// For a call instruction, this method sets the CallInterference flag in
|
// For a call instruction, this method sets the CallInterference flag in
|
||||||
// the LR of each variable live int the Live Variable Set live after the
|
// the LR of each variable live int the Live Variable Set live after the
|
||||||
@ -169,18 +186,15 @@ void PhyRegAlloc::addInterference(const Value *const Def,
|
|||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
||||||
const LiveVarSet *const LVSetAft )
|
const LiveVarSet *const LVSetAft ) {
|
||||||
{
|
|
||||||
// Now find the LR of the return value of the call
|
// Now find the LR of the return value of the call
|
||||||
|
|
||||||
|
|
||||||
// We do this because, we look at the LV set *after* the instruction
|
// We do this because, we look at the LV set *after* the instruction
|
||||||
// to determine, which LRs must be saved across calls. The return value
|
// to determine, which LRs must be saved across calls. The return value
|
||||||
// of the call is live in this set - but it does not interfere with call
|
// of the call is live in this set - but it does not interfere with call
|
||||||
// (i.e., we can allocate a volatile register to the return value)
|
// (i.e., we can allocate a volatile register to the return value)
|
||||||
|
//
|
||||||
LiveRange *RetValLR = NULL;
|
LiveRange *RetValLR = NULL;
|
||||||
|
|
||||||
const Value *RetVal = MRI.getCallInstRetVal( MInst );
|
const Value *RetVal = MRI.getCallInstRetVal( MInst );
|
||||||
|
|
||||||
if( RetVal ) {
|
if( RetVal ) {
|
||||||
@ -194,9 +208,11 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
LiveVarSet::const_iterator LIt = LVSetAft->begin();
|
LiveVarSet::const_iterator LIt = LVSetAft->begin();
|
||||||
|
|
||||||
// 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 );
|
LiveRange *const LR = LRI.getLiveRangeForValue(*LIt );
|
||||||
|
|
||||||
if( LR && DEBUG_RA) {
|
if( LR && DEBUG_RA) {
|
||||||
@ -207,6 +223,7 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
|
|
||||||
// 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
|
||||||
|
//
|
||||||
if( LR && (LR != RetValLR) ) {
|
if( LR && (LR != RetValLR) ) {
|
||||||
LR->setCallInterference();
|
LR->setCallInterference();
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -220,55 +237,72 @@ void PhyRegAlloc::setCallInterferences(const MachineInstr *MInst,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will walk thru code and create interferences in the IG of
|
// This method will walk thru code and create interferences in the IG of
|
||||||
// each RegClass.
|
// each RegClass. Also, this method calculates the spill cost of each
|
||||||
|
// Live Range (it is done in this method to save another pass over the code).
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::buildInterferenceGraphs()
|
void PhyRegAlloc::buildInterferenceGraphs()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
if(DEBUG_RA) cout << "Creating interference graphs ..." << endl;
|
||||||
|
|
||||||
|
unsigned BBLoopDepthCost;
|
||||||
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
Method::const_iterator BBI = Meth->begin(); // random iterator for BBs
|
||||||
|
|
||||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||||
|
|
||||||
|
// find the 10^(loop_depth) of this BB
|
||||||
|
//
|
||||||
|
BBLoopDepthCost = (unsigned) pow( 10.0, LoopDepthCalc.getLoopDepth(*BBI));
|
||||||
|
|
||||||
// get the iterator for machine instructions
|
// get the iterator for machine instructions
|
||||||
|
//
|
||||||
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
const MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||||
MachineCodeForBasicBlock::const_iterator
|
MachineCodeForBasicBlock::const_iterator
|
||||||
MInstIterator = MIVec.begin();
|
MInstIterator = MIVec.begin();
|
||||||
|
|
||||||
// iterate over all the machine instructions in BB
|
// iterate over all the machine instructions in BB
|
||||||
|
//
|
||||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||||
|
|
||||||
const MachineInstr * MInst = *MInstIterator;
|
const MachineInstr * MInst = *MInstIterator;
|
||||||
|
|
||||||
// get the LV set after the instruction
|
// get the LV set after the instruction
|
||||||
|
//
|
||||||
const LiveVarSet *const LVSetAI =
|
const LiveVarSet *const LVSetAI =
|
||||||
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
LVI->getLiveVarSetAfterMInst(MInst, *BBI);
|
||||||
|
|
||||||
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
const bool isCallInst = TM.getInstrInfo().isCall(MInst->getOpCode());
|
||||||
|
|
||||||
if( isCallInst ) {
|
if( isCallInst ) {
|
||||||
//cout << "\nFor call inst: " << *MInst;
|
|
||||||
|
|
||||||
// set the isCallInterference flag of each live range wich extends
|
// set the isCallInterference flag of each live range wich extends
|
||||||
// accross this call instruction. This information is used by graph
|
// accross this call instruction. This information is used by graph
|
||||||
// coloring algo to avoid allocating volatile colors to live ranges
|
// coloring algo to avoid allocating volatile colors to live ranges
|
||||||
// that span across calls (since they have to be saved/restored)
|
// that span across calls (since they have to be saved/restored)
|
||||||
|
//
|
||||||
setCallInterferences( MInst, LVSetAI);
|
setCallInterferences( MInst, LVSetAI);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// iterate over MI operands to find defs
|
// iterate over all MI operands to find defs
|
||||||
|
//
|
||||||
for( MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
for( MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done(); ++OpI) {
|
||||||
|
|
||||||
if( OpI.isDef() ) {
|
if( OpI.isDef() ) {
|
||||||
// create a new LR iff this operand is a def
|
// create a new LR iff this operand is a def
|
||||||
|
//
|
||||||
addInterference(*OpI, LVSetAI, isCallInst );
|
addInterference(*OpI, LVSetAI, isCallInst );
|
||||||
} //if this is a def
|
}
|
||||||
} // for all operands
|
|
||||||
|
// Calculate the spill cost of each live range
|
||||||
|
//
|
||||||
|
LiveRange *LR = LRI.getLiveRangeForValue( *OpI );
|
||||||
|
if( LR )
|
||||||
|
LR->addSpillCost(BBLoopDepthCost);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// if there are multiple defs in this instruction e.g. in SETX
|
// if there are multiple defs in this instruction e.g. in SETX
|
||||||
@ -279,7 +313,7 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
|
|
||||||
// Also add interference for any implicit definitions in a machine
|
// Also add interference for any implicit definitions in a machine
|
||||||
// instr (currently, only calls have this).
|
// instr (currently, only calls have this).
|
||||||
|
//
|
||||||
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
unsigned NumOfImpRefs = MInst->getNumImplicitRefs();
|
||||||
if( NumOfImpRefs > 0 ) {
|
if( NumOfImpRefs > 0 ) {
|
||||||
for(unsigned z=0; z < NumOfImpRefs; z++)
|
for(unsigned z=0; z < NumOfImpRefs; z++)
|
||||||
@ -287,11 +321,6 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
|
addInterference( MInst->getImplicitRef(z), LVSetAI, isCallInst );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// record phi instrns in PhiInstList
|
|
||||||
if( TM.getInstrInfo().isDummyPhiInstr(MInst->getOpCode()) )
|
|
||||||
PhiInstList.push_back( MInst );
|
|
||||||
*/
|
|
||||||
|
|
||||||
} // for all machine instructions in BB
|
} // for all machine instructions in BB
|
||||||
|
|
||||||
@ -300,24 +329,28 @@ void PhyRegAlloc::buildInterferenceGraphs()
|
|||||||
|
|
||||||
// add interferences for method arguments. Since there are no explict
|
// add interferences for method arguments. Since there are no explict
|
||||||
// defs in method for args, we have to add them manually
|
// defs in method for args, we have to add them manually
|
||||||
|
//
|
||||||
addInterferencesForArgs(); // add interference for method args
|
addInterferencesForArgs();
|
||||||
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << "Interference graphs calculted!" << endl;
|
cout << "Interference graphs calculted!" << endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
// Pseudo instructions will be exapnded to multiple instructions by the
|
// Pseudo instructions will be exapnded to multiple instructions by the
|
||||||
// assembler. Consequently, all the opernds must get distinct registers
|
// assembler. Consequently, all the opernds must get distinct registers.
|
||||||
|
// Therefore, we mark all operands of a pseudo instruction as they interfere
|
||||||
|
// with one another.
|
||||||
//--------------------------------------------------------------------------
|
//--------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
||||||
|
|
||||||
bool setInterf = false;
|
bool setInterf = false;
|
||||||
|
|
||||||
// iterate over MI operands to find defs
|
// iterate over MI operands to find defs
|
||||||
|
//
|
||||||
for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
|
for( MachineInstr::val_const_op_iterator It1(MInst);!It1.done(); ++It1) {
|
||||||
|
|
||||||
const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 );
|
const LiveRange *const LROfOp1 = LRI.getLiveRangeForValue( *It1 );
|
||||||
@ -325,8 +358,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
if( !LROfOp1 && It1.isDef() )
|
if( !LROfOp1 && It1.isDef() )
|
||||||
assert( 0 && "No LR for Def in PSEUDO insruction");
|
assert( 0 && "No LR for Def in PSEUDO insruction");
|
||||||
|
|
||||||
//if( !LROfOp1 ) continue;
|
|
||||||
|
|
||||||
MachineInstr::val_const_op_iterator It2 = It1;
|
MachineInstr::val_const_op_iterator It2 = It1;
|
||||||
++It2;
|
++It2;
|
||||||
|
|
||||||
@ -341,11 +372,9 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
|
|
||||||
if( RCOfOp1 == RCOfOp2 ){
|
if( RCOfOp1 == RCOfOp2 ){
|
||||||
RCOfOp1->setInterference( LROfOp1, LROfOp2 );
|
RCOfOp1->setInterference( LROfOp1, LROfOp2 );
|
||||||
//cerr << "\nSet interfs for PSEUDO inst: " << *MInst;
|
|
||||||
setInterf = true;
|
setInterf = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // if Op2 has a LR
|
} // if Op2 has a LR
|
||||||
|
|
||||||
} // for all other defs in machine instr
|
} // for all other defs in machine instr
|
||||||
@ -363,8 +392,6 @@ void PhyRegAlloc::addInterf4PseudoInstr(const MachineInstr *MInst) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method will add interferences for incoming arguments to a method.
|
// This method will add interferences for incoming arguments to a method.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -391,12 +418,16 @@ void PhyRegAlloc::addInterferencesForArgs()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
// This method is called after register allocation is complete to set the
|
// This method is called after register allocation is complete to set the
|
||||||
// allocated reisters in the machine code. This code will add register numbers
|
// allocated reisters in the machine code. This code will add register numbers
|
||||||
// to MachineOperands that contain a Value.
|
// to MachineOperands that contain a Value. Also it calls target specific
|
||||||
|
// methods to produce caller saving instructions. At the end, it adds all
|
||||||
|
// additional instructions produced by the register allocator to the
|
||||||
|
// instruction stream.
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
void PhyRegAlloc::updateMachineCode()
|
void PhyRegAlloc::updateMachineCode()
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -405,35 +436,67 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
for( ; BBI != Meth->end(); ++BBI) { // traverse BBs in random order
|
||||||
|
|
||||||
// get the iterator for machine instructions
|
// get the iterator for machine instructions
|
||||||
|
//
|
||||||
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
MachineCodeForBasicBlock& MIVec = (*BBI)->getMachineInstrVec();
|
||||||
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
MachineCodeForBasicBlock::iterator MInstIterator = MIVec.begin();
|
||||||
|
|
||||||
// iterate over all the machine instructions in BB
|
// iterate over all the machine instructions in BB
|
||||||
|
//
|
||||||
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
for( ; MInstIterator != MIVec.end(); ++MInstIterator) {
|
||||||
|
|
||||||
MachineInstr *MInst = *MInstIterator;
|
MachineInstr *MInst = *MInstIterator;
|
||||||
|
|
||||||
|
unsigned Opcode = MInst->getOpCode();
|
||||||
|
|
||||||
// do not process Phis
|
// do not process Phis
|
||||||
if( (TM.getInstrInfo()).isPhi( MInst->getOpCode()) )
|
if( (TM.getInstrInfo()).isPhi( Opcode ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
// Now insert speical instructions (if necessary) for call/return
|
||||||
|
// instructions.
|
||||||
|
//
|
||||||
|
if( (TM.getInstrInfo()).isCall( Opcode) ||
|
||||||
|
(TM.getInstrInfo()).isReturn( Opcode) ) {
|
||||||
|
|
||||||
|
AddedInstrns *AI = AddedInstrMap[ MInst];
|
||||||
|
if ( !AI ) {
|
||||||
|
AI = new AddedInstrns();
|
||||||
|
AddedInstrMap[ MInst ] = AI;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tmp stack poistions are needed by some calls that have spilled args
|
||||||
|
// So reset it before we call each such method
|
||||||
|
// TODO: mcInfo.popAllTempValues(TM);
|
||||||
|
|
||||||
|
if( (TM.getInstrInfo()).isCall( Opcode ) )
|
||||||
|
MRI.colorCallArgs( MInst, LRI, AI, *this, *BBI );
|
||||||
|
|
||||||
|
else if ( (TM.getInstrInfo()).isReturn(Opcode) )
|
||||||
|
MRI.colorRetValue( MInst, LRI, AI );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* -- Using above code instead of this
|
||||||
|
|
||||||
// if this machine instr is call, insert caller saving code
|
// if this machine instr is call, insert caller saving code
|
||||||
|
|
||||||
if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
if( (TM.getInstrInfo()).isCall( MInst->getOpCode()) )
|
||||||
MRI.insertCallerSavingCode(MInst, *BBI, *this );
|
MRI.insertCallerSavingCode(MInst, *BBI, *this );
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
// reset the stack offset for temporary variables since we may
|
// reset the stack offset for temporary variables since we may
|
||||||
// need that to spill
|
// need that to spill
|
||||||
//mcInfo.popAllTempValues(TM);
|
// mcInfo.popAllTempValues(TM);
|
||||||
// TODO ** : do later
|
// TODO ** : do later
|
||||||
|
|
||||||
//for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
//for(MachineInstr::val_const_op_iterator OpI(MInst);!OpI.done();++OpI) {
|
||||||
|
|
||||||
|
|
||||||
// Now replace set the registers for operands in the machine instruction
|
// Now replace set the registers for operands in the machine instruction
|
||||||
|
//
|
||||||
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
for(unsigned OpNum=0; OpNum < MInst->getNumOperands(); ++OpNum) {
|
||||||
|
|
||||||
MachineOperand& Op = MInst->getOperand(OpNum);
|
MachineOperand& Op = MInst->getOperand(OpNum);
|
||||||
@ -490,9 +553,14 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
} // for each operand
|
} // for each operand
|
||||||
|
|
||||||
|
|
||||||
|
// Now add instructions that the register allocator inserts before/after
|
||||||
|
// this machine instructions (done only for calls/rets/incoming args)
|
||||||
|
// We do this here, to ensure that spill for an instruction is inserted
|
||||||
|
// closest as possible to an instruction (see above insertCode4Spill...)
|
||||||
|
//
|
||||||
// If there are instructions to be added, *before* this machine
|
// If there are instructions to be added, *before* this machine
|
||||||
// instruction, add them now.
|
// instruction, add them now.
|
||||||
|
//
|
||||||
if( AddedInstrMap[ MInst ] ) {
|
if( AddedInstrMap[ MInst ] ) {
|
||||||
|
|
||||||
deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
|
deque<MachineInstr *> &IBef = (AddedInstrMap[MInst])->InstrnsBefore;
|
||||||
@ -518,7 +586,7 @@ void PhyRegAlloc::updateMachineCode()
|
|||||||
|
|
||||||
// If there are instructions to be added *after* this machine
|
// If there are instructions to be added *after* this machine
|
||||||
// instruction, add them now
|
// instruction, add them now
|
||||||
|
//
|
||||||
if( AddedInstrMap[ MInst ] &&
|
if( AddedInstrMap[ MInst ] &&
|
||||||
! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
|
! (AddedInstrMap[ MInst ]->InstrnsAfter).empty() ) {
|
||||||
|
|
||||||
@ -600,9 +668,9 @@ void PhyRegAlloc::insertCode4SpilledLR(const LiveRange *LR,
|
|||||||
RegClass *RC = LR->getRegClass();
|
RegClass *RC = LR->getRegClass();
|
||||||
const LiveVarSet *LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB);
|
const LiveVarSet *LVSetBef = LVI->getLiveVarSetBeforeMInst(MInst, BB);
|
||||||
|
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
|
||||||
int TmpOff =
|
int TmpOff =
|
||||||
mcInfo.pushTempValue(TM, 8 /* TM.findOptimalStorageSize(LR->getType()) */);
|
mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
|
||||||
|
|
||||||
MachineInstr *MIBef=NULL, *AdIMid=NULL, *MIAft=NULL;
|
MachineInstr *MIBef=NULL, *AdIMid=NULL, *MIAft=NULL;
|
||||||
|
|
||||||
@ -696,8 +764,7 @@ int PhyRegAlloc::getUsableUniRegAtMI(RegClass *RC,
|
|||||||
// we couldn't find an unused register. Generate code to free up a reg by
|
// we couldn't find an unused register. Generate code to free up a reg by
|
||||||
// saving it on stack and restoring after the instruction
|
// saving it on stack and restoring after the instruction
|
||||||
|
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
int TmpOff = mcInfo.pushTempValue(TM, MRI.getSpilledRegSize(RegType) );
|
||||||
int TmpOff = mcInfo.pushTempValue(TM, /*size*/ 8);
|
|
||||||
|
|
||||||
RegU = getUniRegNotUsedByThisInst(RC, MInst);
|
RegU = getUniRegNotUsedByThisInst(RC, MInst);
|
||||||
MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
|
MIBef = MRI.cpReg2MemMI(RegU, MRI.getFramePointer(), TmpOff, RegType );
|
||||||
@ -1003,6 +1070,8 @@ void PhyRegAlloc::printMachineCode()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
@ -1043,7 +1112,7 @@ void PhyRegAlloc::colorCallRetArgs()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -1134,8 +1203,11 @@ void PhyRegAlloc::allocateStackSpace4SpilledLRs()
|
|||||||
LiveRange *L = (*HMI).second; // get the LiveRange
|
LiveRange *L = (*HMI).second; // get the LiveRange
|
||||||
if(L)
|
if(L)
|
||||||
if( ! L->hasColor() )
|
if( ! L->hasColor() )
|
||||||
/**** NOTE: THIS SHOULD USE THE RIGHT SIZE FOR THE REG BEING PUSHED ****/
|
|
||||||
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM, Type::LongTy /*L->getType()*/ ));
|
// NOTE: ** allocating the size of long Type **
|
||||||
|
L->setSpillOffFromFP(mcInfo.allocateSpilledValue(TM,
|
||||||
|
Type::LongTy));
|
||||||
|
|
||||||
}
|
}
|
||||||
} // for all LR's in hash map
|
} // for all LR's in hash map
|
||||||
}
|
}
|
||||||
@ -1152,8 +1224,8 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
// make sure that we put all register classes into the RegClassList
|
// make sure that we put all register classes into the RegClassList
|
||||||
// before we call constructLiveRanges (now done in the constructor of
|
// before we call constructLiveRanges (now done in the constructor of
|
||||||
// PhyRegAlloc class).
|
// PhyRegAlloc class).
|
||||||
|
//
|
||||||
constructLiveRanges(); // create LR info
|
LRI.constructLiveRanges(); // create LR info
|
||||||
|
|
||||||
if( DEBUG_RA )
|
if( DEBUG_RA )
|
||||||
LRI.printLiveRanges();
|
LRI.printLiveRanges();
|
||||||
@ -1173,11 +1245,9 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
RegClassList[ rc ]->printIG();
|
RegClassList[ rc ]->printIG();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LRI.coalesceLRs(); // coalesce all live ranges
|
LRI.coalesceLRs(); // coalesce all live ranges
|
||||||
|
|
||||||
// coalscing could not get rid of all phi's, add phi elimination
|
|
||||||
// instructions
|
|
||||||
// insertPhiEleminateInstrns();
|
|
||||||
|
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
// print all LRs in all reg classes
|
// print all LRs in all reg classes
|
||||||
@ -1193,6 +1263,7 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
// mark un-usable suggested color before graph coloring algorithm.
|
// mark un-usable suggested color before graph coloring algorithm.
|
||||||
// When this is done, the graph coloring algo will not reserve
|
// When this is done, the graph coloring algo will not reserve
|
||||||
// suggested color unnecessarily - they can be used by another LR
|
// suggested color unnecessarily - they can be used by another LR
|
||||||
|
//
|
||||||
markUnusableSugColors();
|
markUnusableSugColors();
|
||||||
|
|
||||||
// color all register classes using the graph coloring algo
|
// color all register classes using the graph coloring algo
|
||||||
@ -1201,32 +1272,29 @@ void PhyRegAlloc::allocateRegisters()
|
|||||||
|
|
||||||
// Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
|
// Atter grpah coloring, if some LRs did not receive a color (i.e, spilled)
|
||||||
// a poistion for such spilled LRs
|
// a poistion for such spilled LRs
|
||||||
|
//
|
||||||
allocateStackSpace4SpilledLRs();
|
allocateStackSpace4SpilledLRs();
|
||||||
|
|
||||||
mcInfo.popAllTempValues(TM); // TODO **Check
|
mcInfo.popAllTempValues(TM); // TODO **Check
|
||||||
|
|
||||||
// color incoming args and call args
|
// color incoming args - if the correct color was not received
|
||||||
|
// insert code to copy to the correct register
|
||||||
|
//
|
||||||
colorIncomingArgs();
|
colorIncomingArgs();
|
||||||
colorCallRetArgs();
|
|
||||||
|
|
||||||
|
|
||||||
|
// Now update the machine code with register names and add any
|
||||||
|
// additional code inserted by the register allocator to the instruction
|
||||||
|
// stream
|
||||||
|
//
|
||||||
updateMachineCode();
|
updateMachineCode();
|
||||||
|
|
||||||
|
|
||||||
if (DEBUG_RA) {
|
if (DEBUG_RA) {
|
||||||
MachineCodeForMethod::get(Meth).dump();
|
MachineCodeForMethod::get(Meth).dump();
|
||||||
printMachineCode(); // only for DEBUGGING
|
printMachineCode(); // only for DEBUGGING
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
printMachineCode(); // only for DEBUGGING
|
|
||||||
|
|
||||||
cout << "\nAllocted for method " << Meth->getName();
|
|
||||||
char ch;
|
|
||||||
cin >> ch;
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,35 +1,37 @@
|
|||||||
#include "llvm/CodeGen/RegClass.h"
|
#include "llvm/CodeGen/RegClass.h"
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// This constructor inits IG. The actual matrix is created by a call to
|
||||||
|
// createInterferenceGraph() above.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
RegClass::RegClass(const Method *const M,
|
RegClass::RegClass(const Method *const M,
|
||||||
const MachineRegClassInfo *const Mrc,
|
const MachineRegClassInfo *const Mrc,
|
||||||
const ReservedColorListType *const RCL)
|
const ReservedColorListType *const RCL)
|
||||||
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
: Meth(M), MRC(Mrc), RegClassID( Mrc->getRegClassID() ),
|
||||||
IG(this), IGNodeStack(), ReservedColorList(RCL)
|
IG(this), IGNodeStack(), ReservedColorList(RCL) {
|
||||||
{
|
|
||||||
if( DEBUG_RA)
|
if( DEBUG_RA)
|
||||||
cout << "Created Reg Class: " << RegClassID << endl;
|
cout << "Created Reg Class: " << RegClassID << endl;
|
||||||
|
|
||||||
// This constructor inits IG. The actual matrix is created by a call to
|
|
||||||
// createInterferenceGraph() above.
|
|
||||||
|
|
||||||
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
IsColorUsedArr = new bool[ Mrc->getNumOfAllRegs() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Main entry point for coloring a register class.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::colorAllRegs()
|
void RegClass::colorAllRegs()
|
||||||
{
|
{
|
||||||
if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
|
if(DEBUG_RA) cout << "Coloring IG of reg class " << RegClassID << " ...\n";
|
||||||
|
|
||||||
//preColorIGNodes(); // pre-color IGNodes
|
// pre-color IGNodes
|
||||||
pushAllIGNodes(); // push all IG Nodes
|
pushAllIGNodes(); // push all IG Nodes
|
||||||
|
|
||||||
unsigned int StackSize = IGNodeStack.size();
|
unsigned int StackSize = IGNodeStack.size();
|
||||||
IGNode *CurIGNode;
|
IGNode *CurIGNode;
|
||||||
|
|
||||||
// for all LRs on stack
|
// for all LRs on stack
|
||||||
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
for( unsigned int IGN=0; IGN < StackSize; IGN++) {
|
||||||
|
|
||||||
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
CurIGNode = IGNodeStack.top(); // pop the IGNode on top of stack
|
||||||
@ -37,13 +39,13 @@ void RegClass::colorAllRegs()
|
|||||||
colorIGNode (CurIGNode); // color it
|
colorIGNode (CurIGNode); // color it
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// InsertSpillCode; ********* TODO ********
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// The method for pushing all IGNodes on to the stack.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::pushAllIGNodes()
|
void RegClass::pushAllIGNodes()
|
||||||
{
|
{
|
||||||
bool NeedMoreSpills;
|
bool NeedMoreSpills;
|
||||||
@ -51,7 +53,7 @@ void RegClass::pushAllIGNodes()
|
|||||||
|
|
||||||
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
IG.setCurDegreeOfIGNodes(); // calculate degree of IGNodes
|
||||||
|
|
||||||
// push non-constrained IGNodes
|
// push non-constrained IGNodes
|
||||||
bool PushedAll = pushUnconstrainedIGNodes();
|
bool PushedAll = pushUnconstrainedIGNodes();
|
||||||
|
|
||||||
if( DEBUG_RA) {
|
if( DEBUG_RA) {
|
||||||
@ -71,15 +73,19 @@ void RegClass::pushAllIGNodes()
|
|||||||
do{
|
do{
|
||||||
|
|
||||||
//get node with min spill cost
|
//get node with min spill cost
|
||||||
|
//
|
||||||
IGNode *IGNodeSpill = getIGNodeWithMinSpillCost();
|
IGNode *IGNodeSpill = getIGNodeWithMinSpillCost();
|
||||||
|
|
||||||
// push that node on to stack
|
// push that node on to stack
|
||||||
|
//
|
||||||
IGNodeStack.push( IGNodeSpill );
|
IGNodeStack.push( IGNodeSpill );
|
||||||
|
|
||||||
// set its OnStack flag and decrement degree of neighs
|
// set its OnStack flag and decrement degree of neighs
|
||||||
|
//
|
||||||
IGNodeSpill->pushOnStack();
|
IGNodeSpill->pushOnStack();
|
||||||
|
|
||||||
// now push NON-constrined ones, if any
|
// now push NON-constrined ones, if any
|
||||||
|
//
|
||||||
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
NeedMoreSpills = ! pushUnconstrainedIGNodes();
|
||||||
|
|
||||||
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
|
cerr << "\nConstrained IG Node found !@!" << IGNodeSpill->getIndex();
|
||||||
@ -137,46 +143,72 @@ bool RegClass::pushUnconstrainedIGNodes()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Get the IGNode withe the minimum spill cost
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
IGNode * RegClass::getIGNodeWithMinSpillCost()
|
||||||
{
|
{
|
||||||
IGNode *IGNode=NULL;
|
|
||||||
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
|
||||||
|
|
||||||
// pass over IGNodeList
|
unsigned int IGNodeListSize = IG.getIGNodeList().size();
|
||||||
|
long MinSpillCost = -1;
|
||||||
|
IGNode *MinCostIGNode = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
// pass over IGNodeList to find the IGNode with minimum spill cost
|
||||||
|
// among all IGNodes that are not yet pushed on to the stack
|
||||||
|
//
|
||||||
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
for( unsigned int i =0; i < IGNodeListSize; i++) {
|
||||||
IGNode = IG.getIGNodeList()[i];
|
IGNode *IGNode = IG.getIGNodeList()[i];
|
||||||
|
|
||||||
if( ! IGNode ) // can be null due to merging
|
if( ! IGNode ) // can be null due to merging
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if( ! IGNode->isOnStack() ) {
|
||||||
|
|
||||||
|
unsigned SpillCost = IGNode->getParentLR()->getSpillCost();
|
||||||
|
|
||||||
// return the first IGNode ########## Change this #######
|
if( MinSpillCost == -1) { // for the first IG node
|
||||||
if( ! IGNode->isOnStack() ) return IGNode;
|
MinSpillCost = SpillCost;
|
||||||
|
MinCostIGNode = IGNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if( MinSpillCost > SpillCost) {
|
||||||
|
MinSpillCost = SpillCost;
|
||||||
|
MinCostIGNode = IGNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(0);
|
assert( MinCostIGNode && "No IGNode to spill");
|
||||||
return NULL;
|
return MinCostIGNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
// Color the IGNode using the machine specific code.
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
void RegClass::colorIGNode(IGNode *const Node)
|
void RegClass::colorIGNode(IGNode *const Node)
|
||||||
{
|
{
|
||||||
|
|
||||||
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
if( ! Node->hasColor() ) { // not colored as an arg etc.
|
||||||
|
|
||||||
|
|
||||||
// init all elements to false;
|
// init all elements of to IsColorUsedAr false;
|
||||||
|
//
|
||||||
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
for( unsigned i=0; i < MRC->getNumOfAllRegs(); i++) {
|
||||||
IsColorUsedArr[ i ] = false;
|
IsColorUsedArr[ i ] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// init all reserved_regs to true - we can't use them
|
// init all reserved_regs to true - we can't use them
|
||||||
|
//
|
||||||
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
for( unsigned i=0; i < ReservedColorList->size() ; i++) {
|
||||||
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
IsColorUsedArr[ (*ReservedColorList)[i] ] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// call the target specific code for coloring
|
||||||
|
//
|
||||||
MRC->colorIGNode(Node, IsColorUsedArr);
|
MRC->colorIGNode(Node, IsColorUsedArr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user