// $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>
#include <hash_map>
#include <vector>
//*********************** Internal Data Structures *************************/
// The following two types need to be classes, not typedefs, so we can use
// opaque declarations in SchedGraph.h
//
struct RefVec: public vector< pair<SchedGraphNode*, int> > {
typedef vector< pair<SchedGraphNode*, int> >:: iterator iterator;
typedef vector< pair<SchedGraphNode*, int> >::const_iterator const_iterator;
};
struct RegToRefVecMap: public hash_map<int, RefVec> {
typedef hash_map<int, RefVec>:: iterator iterator;
typedef hash_map<int, RefVec>::const_iterator const_iterator;
};
struct ValueToDefVecMap: public hash_map<const Instruction*, RefVec> {
typedef hash_map<const Instruction*, RefVec>:: iterator iterator;
typedef hash_map<const Instruction*, RefVec>::const_iterator const_iterator;
};
//
// class SchedGraphEdge
//
/*ctor*/
SchedGraphEdge::SchedGraphEdge(SchedGraphNode* _src,
SchedGraphNode* _sink,
SchedGraphEdgeDepType _depType,
unsigned int _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,
unsigned int _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,
unsigned int _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)
: