// $Id$
//***************************************************************************
// File:
// SchedGraph.cpp
//
// Purpose:
// Scheduling graph based on SSA graph plus extra dependence edges
// capturing dependences due to machine resources (machine registers,
// CC registers, and any others).
//
// History:
// 7/20/01 - Vikram Adve - Created
//**************************************************************************/
#include "SchedGraph.h"
#include "llvm/InstrTypes.h"
#include "llvm/Instruction.h"
#include "llvm/BasicBlock.h"
#include "llvm/Method.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/InstrSelection.h"
#include "llvm/Target/MachineInstrInfo.h"
#include "llvm/Target/MachineRegInfo.h"
#include "llvm/Support/StringExtras.h"
#include "llvm/iOther.h"
#include <algorithm>
//*********************** Internal Data Structures *************************/
typedef vector< pair<SchedGraphNode*, unsigned int> > RefVec;
// The following needs to be a class, not a typedef, so we can use
// an opaque declaration in SchedGraph.h
struct RegToRefVecMap: public hash_map<int, RefVec> {
typedef hash_map<int, RefVec>:: iterator iterator;
typedef hash_map<int, RefVec>::const_iterator const_iterator;
};
//
// class SchedGraphEdge
//
/*ctor*/
SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src,
SchedGraphNode* _sink,
SchedGraphEdgeDepType _depType,
DataDepOrderType _depOrderType,
int _minDelay)
: src(_src),
sink(_sink),
depType(_depType),
depOrderType(_depOrderType),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
val(NULL)
{
src->addOutEdge(this);
sink->addInEdge(this);
}
/*ctor*/
SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src,
SchedGraphNode* _sink,
const Value* _val,
DataDepOrderType _depOrderType,
int _minDelay)
: src(_src),
sink(_sink),
depType(DefUseDep),
depOrderType(_depOrderType),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
val(_val)
{
src->addOutEdge(this);
sink->addInEdge(this);
}
/*ctor*/
SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src,
SchedGraphNode* _sink,
unsigned int _regNum,
DataDepOrderType _depOrderType,
int _minDelay)
: src(_src),
sink(_sink),
depType(MachineRegister),
depOrderType(_depOrderType),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
machineRegNum(_regNum)
{
src->addOutEdge(this);
sink->addInEdge(this);
}
/*ctor*/
SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src,
SchedGraphNode* _sink,
ResourceId _resourceId,
int _minDelay)
: src(_src),
sink(_sink),
depType(MachineResource),
depOrderType(NonDataDep),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()),
resourceId(_resourceId)
{
src->addOutEdge(this);
sink->addInEdge(this);
}
/*dtor*/
SchedGraphEdge::~SchedGraphEdge()
{
}
void SchedGraphEdge::dump(int indent=0) const {
printIndent(indent); cout << *this;
}
//
// class SchedGraphNode
//
/*ctor*/
SchedGraphNode::SchedGraphNode(unsigned int _nodeId,
const Instruction* _instr,
const MachineInstr* _minstr,
const TargetMachine& target)
: nodeId(_nodeId),
instr(_instr),
minstr(_minstr),
latency(0)
{
if (minstr)
{
MachineOpCode mopCode = minstr->getOpCode();
latency = target.getInstrInfo().hasResultInterlock(mopCode)
? target.getInstrInfo().minLatency(mopCode)
: target.getInstrInfo().maxLatency(mopCode);
}
}
/*dtor*/
SchedGraphNode::~SchedGraphNode()
{
}
void SchedGraphNode::dump(int indent=0) const {
printIndent(indent); cout << *this;
}
inline void
SchedGraphNode::addInEdge(SchedGraphEdge* edge)
{
inEdges.push_back(edge);
}
inline void
SchedGraphNode::addOutEdge(SchedGraphEdge* edge)
{
outEdges.push_back(edge);
}
inline void
SchedGraphNode::removeInEdge(const SchedGraphEdge* edge)
{
assert(edge->getSink() == this);
for (iterator I = beginInEdges(); I != endInEdges(); ++I)
if ((*I) == edge)
{
inEdges.erase(I);
break;
}
}
inline void
SchedGraphNode::removeOutEdge(co