A single MachineInstr operand may now be both a def and a use,

so additional dep. edges have to be added.
This was needed to correctly handle conditional move instructions!
MachineCodeForBasicBlock is now an annotation on BasicBlock.
Renamed "earliestForNode" to "earliestReadyTimeForNode".


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2826 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Vikram S. Adve 2002-07-08 22:59:23 +00:00
parent 9afa88c3a7
commit 0baf1c0911
10 changed files with 182 additions and 204 deletions

View File

@ -8,6 +8,7 @@
#include "SchedPriorities.h" #include "SchedPriorities.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
#include "llvm/CodeGen/MachineCodeForMethod.h" #include "llvm/CodeGen/MachineCodeForMethod.h"
#include "llvm/Analysis/LiveVar/FunctionLiveVarInfo.h" // FIXME: Remove when modularized better #include "llvm/Analysis/LiveVar/FunctionLiveVarInfo.h" // FIXME: Remove when modularized better
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -631,7 +632,7 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue)
static void static void
RecordSchedule(const BasicBlock* bb, const SchedulingManager& S) RecordSchedule(const BasicBlock* bb, const SchedulingManager& S)
{ {
MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
const MachineInstrInfo& mii = S.schedInfo.getInstrInfo(); const MachineInstrInfo& mii = S.schedInfo.getInstrInfo();
#ifndef NDEBUG #ifndef NDEBUG
@ -1220,7 +1221,7 @@ ReplaceNopsWithUsefulInstr(SchedulingManager& S,
// fill delay slots, otherwise, just discard them. // fill delay slots, otherwise, just discard them.
// //
unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1; unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
MachineCodeForBasicBlock& bbMvec = node->getBB()->getMachineInstrVec(); MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(node->getBB());
assert(bbMvec[firstDelaySlotIdx - 1] == brInstr && assert(bbMvec[firstDelaySlotIdx - 1] == brInstr &&
"Incorrect instr. index in basic block for brInstr"); "Incorrect instr. index in basic block for brInstr");
@ -1313,7 +1314,7 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S,
// Simply passing in an empty delayNodeVec will have this effect. // Simply passing in an empty delayNodeVec will have this effect.
// //
delayNodeVec.clear(); delayNodeVec.clear();
const MachineCodeForBasicBlock& bbMvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0; i < bbMvec.size(); i++) for (unsigned i=0; i < bbMvec.size(); i++)
if (bbMvec[i] != brInstr && if (bbMvec[i] != brInstr &&
mii.getNumDelaySlots(bbMvec[i]->getOpCode()) > 0) mii.getNumDelaySlots(bbMvec[i]->getOpCode()) > 0)

View File

@ -15,6 +15,7 @@
#include "SchedGraph.h" #include "SchedGraph.h"
#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrSelection.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
#include "llvm/Target/MachineRegInfo.h" #include "llvm/Target/MachineRegInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
@ -393,7 +394,7 @@ SchedGraph::addCDEdges(const TerminatorInst* term,
// all preceding instructions in the basic block. Use 0 latency again. // all preceding instructions in the basic block. Use 0 latency again.
// //
const BasicBlock* bb = firstBrNode->getBB(); const BasicBlock* bb = firstBrNode->getBB();
const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0, N=mvec.size(); i < N; i++) for (unsigned i=0, N=mvec.size(); i < N; i++)
{ {
if (mvec[i] == termMvec[first]) // reached the first branch if (mvec[i] == termMvec[first]) // reached the first branch
@ -550,7 +551,9 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
SchedGraphNode* node = regRefVec[i].first; SchedGraphNode* node = regRefVec[i].first;
unsigned int opNum = regRefVec[i].second; unsigned int opNum = regRefVec[i].second;
bool isDef = node->getMachineInstr()->operandIsDefined(opNum); bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
bool isDefAndUse =
node->getMachineInstr()->operandIsDefinedAndUsed(opNum);
for (unsigned p=0; p < i; ++p) for (unsigned p=0; p < i; ++p)
{ {
SchedGraphNode* prevNode = regRefVec[p].first; SchedGraphNode* prevNode = regRefVec[p].first;
@ -559,14 +562,22 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
unsigned int prevOpNum = regRefVec[p].second; unsigned int prevOpNum = regRefVec[p].second;
bool prevIsDef = bool prevIsDef =
prevNode->getMachineInstr()->operandIsDefined(prevOpNum); prevNode->getMachineInstr()->operandIsDefined(prevOpNum);
bool prevIsDefAndUse =
prevNode->getMachineInstr()->operandIsDefinedAndUsed(prevOpNum);
if (isDef) if (isDef)
new SchedGraphEdge(prevNode, node, regNum, {
(prevIsDef)? SchedGraphEdge::OutputDep if (prevIsDef)
: SchedGraphEdge::AntiDep); new SchedGraphEdge(prevNode, node, regNum,
else if (prevIsDef) SchedGraphEdge::OutputDep);
new SchedGraphEdge(prevNode, node, regNum, if (!prevIsDef || prevIsDefAndUse)
SchedGraphEdge::TrueDep); new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::AntiDep);
}
if (prevIsDef)
if (!isDef || isDefAndUse)
new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::TrueDep);
} }
} }
} }
@ -574,13 +585,20 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
} }
// Adds dependences to/from refNode from/to all other defs
// in the basic block. refNode may be a use, a def, or both.
// We do not consider other uses because we are not building use-use deps.
//
void void
SchedGraph::addEdgesForValue(SchedGraphNode* refNode, SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
const RefVec& defVec, const RefVec& defVec,
const Value* defValue, const Value* defValue,
bool refNodeIsDef, bool refNodeIsDef,
bool refNodeIsDefAndUse,
const TargetMachine& target) const TargetMachine& target)
{ {
bool refNodeIsUse = !refNodeIsDef || refNodeIsDefAndUse;
// Add true or output dep edges from all def nodes before refNode in BB. // Add true or output dep edges from all def nodes before refNode in BB.
// Add anti or output dep edges to all def nodes after refNode. // Add anti or output dep edges to all def nodes after refNode.
for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I)
@ -589,15 +607,23 @@ SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
continue; // Dont add any self-loops continue; // Dont add any self-loops
if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB())
// (*).first is before refNode { // (*).first is before refNode
(void) new SchedGraphEdge((*I).first, refNode, defValue, if (refNodeIsDef)
(refNodeIsDef)? SchedGraphEdge::OutputDep (void) new SchedGraphEdge((*I).first, refNode, defValue,
: SchedGraphEdge::TrueDep); SchedGraphEdge::OutputDep);
if (refNodeIsUse)
(void) new SchedGraphEdge((*I).first, refNode, defValue,
SchedGraphEdge::TrueDep);
}
else else
// (*).first is after refNode { // (*).first is after refNode
(void) new SchedGraphEdge(refNode, (*I).first, defValue, if (refNodeIsDef)
(refNodeIsDef)? SchedGraphEdge::OutputDep (void) new SchedGraphEdge(refNode, (*I).first, defValue,
: SchedGraphEdge::AntiDep); SchedGraphEdge::OutputDep);
if (refNodeIsUse)
(void) new SchedGraphEdge(refNode, (*I).first, defValue,
SchedGraphEdge::AntiDep);
}
} }
} }
@ -626,7 +652,8 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& minstr,
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end()) if (I != valueToDefVecMap.end())
addEdgesForValue(node, (*I).second, mop.getVRegValue(), addEdgesForValue(node, (*I).second, mop.getVRegValue(),
minstr.operandIsDefined(i), target); minstr.operandIsDefined(i),
minstr.operandIsDefinedAndUsed(i), target);
} }
break; break;
@ -649,73 +676,20 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& minstr,
// value of a Ret instruction. // value of a Ret instruction.
// //
for (unsigned i=0, N=minstr.getNumImplicitRefs(); i < N; ++i) for (unsigned i=0, N=minstr.getNumImplicitRefs(); i < N; ++i)
if (! minstr.implicitRefIsDefined(i)) if (! minstr.implicitRefIsDefined(i) ||
minstr.implicitRefIsDefinedAndUsed(i))
if (const Instruction* srcI = if (const Instruction* srcI =
dyn_cast_or_null<Instruction>(minstr.getImplicitRef(i))) dyn_cast_or_null<Instruction>(minstr.getImplicitRef(i)))
{ {
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end()) if (I != valueToDefVecMap.end())
addEdgesForValue(node, (*I).second, minstr.getImplicitRef(i), addEdgesForValue(node, (*I).second, minstr.getImplicitRef(i),
minstr.implicitRefIsDefined(i), target); minstr.implicitRefIsDefined(i),
minstr.implicitRefIsDefinedAndUsed(i), target);
} }
} }
#undef NEED_SEPARATE_NONSSA_EDGES_CODE
#ifdef NEED_SEPARATE_NONSSA_EDGES_CODE
void
SchedGraph::addNonSSAEdgesForValue(const Instruction* instr,
const TargetMachine& target)
{
if (isa<PHINode>(instr))
return;
MachineCodeForVMInstr& mvec = instr->getMachineInstrVec();
const MachineInstrInfo& mii = target.getInstrInfo();
RefVec refVec;
for (unsigned i=0, N=mvec.size(); i < N; i++)
for (int o=0, N = mii.getNumOperands(mvec[i]->getOpCode()); o < N; o++)
{
const MachineOperand& mop = mvec[i]->getOperand(o);
if ((mop.getOperandType() == MachineOperand::MO_VirtualRegister ||
mop.getOperandType() == MachineOperand::MO_CCRegister)
&& mop.getVRegValue() == (Value*) instr)
{
// this operand is a definition or use of value `instr'
SchedGraphNode* node = this->getGraphNodeForInstr(mvec[i]);
assert(node && "No node for machine instruction in this BB?");
refVec.push_back(std::make_pair(node, o));
}
}
// refVec is ordered by control flow order of the machine instructions
for (unsigned i=0; i < refVec.size(); ++i)
{
SchedGraphNode* node = refVec[i].first;
unsigned int opNum = refVec[i].second;
bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
if (isDef)
// add output and/or anti deps to this definition
for (unsigned p=0; p < i; ++p)
{
SchedGraphNode* prevNode = refVec[p].first;
if (prevNode != node)
{
bool prevIsDef = prevNode->getMachineInstr()->
operandIsDefined(refVec[p].second);
new SchedGraphEdge(prevNode, node, SchedGraphEdge::ValueDep,
(prevIsDef)? SchedGraphEdge::OutputDep
: SchedGraphEdge::AntiDep);
}
}
}
}
#endif //NEED_SEPARATE_NONSSA_EDGES_CODE
void void
SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
SchedGraphNode* node, SchedGraphNode* node,
@ -786,7 +760,7 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
// Build graph nodes for each VM instruction and gather def/use info. // Build graph nodes for each VM instruction and gather def/use info.
// Do both those together in a single pass over all machine instructions. // Do both those together in a single pass over all machine instructions.
const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0; i < mvec.size(); i++) for (unsigned i=0; i < mvec.size(); i++)
if (! mii.isDummyPhiInstr(mvec[i]->getOpCode())) if (! mii.isDummyPhiInstr(mvec[i]->getOpCode()))
{ {
@ -822,7 +796,7 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
// Find the machine instruction that makes a copy of inval to (*PI). // Find the machine instruction that makes a copy of inval to (*PI).
// This must be in the current basic block (bb). // This must be in the current basic block (bb).
const MachineCodeForVMInstr& mvec = (*PI)->getMachineInstrVec(); const MachineCodeForVMInstr& mvec = MachineCodeForBasicBlock::get(*PI);
const MachineInstr* theCopy = NULL; const MachineInstr* theCopy = NULL;
for (unsigned i=0; i < mvec.size() && theCopy == NULL; i++) for (unsigned i=0; i < mvec.size() && theCopy == NULL; i++)
if (! mii.isDummyPhiInstr(mvec[i]->getOpCode())) if (! mii.isDummyPhiInstr(mvec[i]->getOpCode()))
@ -830,13 +804,17 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
for (int o=0, N=(int) mvec[i]->getNumOperands(); o < N; o++) for (int o=0, N=(int) mvec[i]->getNumOperands(); o < N; o++)
{ {
const MachineOperand& mop = mvec[i]->getOperand(o); const MachineOperand& mop = mvec[i]->getOperand(o);
if (mvec[i]->operandIsDefined(o)) if (mvec[i]->operandIsDefined(o))
assert(mop.getVRegValue() == (*PI) && "dest shd be my Phi"); assert(mop.getVRegValue() == (*PI) && "dest shd be my Phi");
else if (mop.getVRegValue() == inVal)
{ // found the copy! if (! mvec[i]->operandIsDefined(o) ||
theCopy = mvec[i]; NOT NEEDED? mvec[i]->operandIsDefinedAndUsed(o))
break; if (mop.getVRegValue() == inVal)
} { // found the copy!
theCopy = mvec[i];
break;
}
} }
// Found the dang instruction. Now create a node and do the rest... // Found the dang instruction. Now create a node and do the rest...
@ -911,7 +889,7 @@ SchedGraph::buildGraph(const TargetMachine& target)
// //
//---------------------------------------------------------------- //----------------------------------------------------------------
MachineCodeForBasicBlock& bbMvec = bb->getMachineInstrVec(); MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(bb);
// First, add edges to the terminator instruction of the basic block. // First, add edges to the terminator instruction of the basic block.
this->addCDEdges(bb->getTerminator(), target); this->addCDEdges(bb->getTerminator(), target);

View File

@ -327,6 +327,7 @@ private:
const RefVec& defVec, const RefVec& defVec,
const Value* defValue, const Value* defValue,
bool refNodeIsDef, bool refNodeIsDef,
bool refNodeIsDefAndUse,
const TargetMachine& target); const TargetMachine& target);
void addDummyEdges (); void addDummyEdges ();

View File

@ -28,9 +28,10 @@ SchedPriorities::SchedPriorities(const Function *, const SchedGraph *G,
FunctionLiveVarInfo &LVI) FunctionLiveVarInfo &LVI)
: curTime(0), graph(G), methodLiveVarInfo(LVI), : curTime(0), graph(G), methodLiveVarInfo(LVI),
nodeDelayVec(G->getNumNodes(), INVALID_LATENCY), // make errors obvious nodeDelayVec(G->getNumNodes(), INVALID_LATENCY), // make errors obvious
earliestForNode(G->getNumNodes(), 0), earliestReadyTimeForNode(G->getNumNodes(), 0),
earliestReadyTime(0), earliestReadyTime(0),
nextToTry(candsAsHeap.begin()) { nextToTry(candsAsHeap.begin())
{
computeDelays(graph); computeDelays(graph);
} }
@ -51,7 +52,7 @@ SchedPriorities::computeDelays(const SchedGraph* graph)
const SchedGraphNode* node = *poIter; const SchedGraphNode* node = *poIter;
cycles_t nodeDelay; cycles_t nodeDelay;
if (node->beginOutEdges() == node->endOutEdges()) if (node->beginOutEdges() == node->endOutEdges())
nodeDelay = node->getLatency(); nodeDelay = node->getLatency();
else else
{ {
// Iterate over the out-edges of the node to compute delay // Iterate over the out-edges of the node to compute delay
@ -59,7 +60,7 @@ SchedPriorities::computeDelays(const SchedGraph* graph)
for (SchedGraphNode::const_iterator E=node->beginOutEdges(); for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) E != node->endOutEdges(); ++E)
{ {
cycles_t sinkDelay = getNodeDelayRef((*E)->getSink()); cycles_t sinkDelay = getNodeDelay((*E)->getSink());
nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay()); nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay());
} }
} }
@ -104,13 +105,13 @@ SchedPriorities::insertReady(const SchedGraphNode* node)
candsAsSet.insert(node); candsAsSet.insert(node);
mcands.clear(); // ensure reset choices is called before any more choices mcands.clear(); // ensure reset choices is called before any more choices
earliestReadyTime = std::min(earliestReadyTime, earliestReadyTime = std::min(earliestReadyTime,
earliestForNode[node->getNodeId()]); getEarliestReadyTimeForNode(node));
if (SchedDebugLevel >= Sched_PrintSchedTrace) if (SchedDebugLevel >= Sched_PrintSchedTrace)
{ {
cerr << " Node " << node->getNodeId() << " will be ready in Cycle " cerr << " Node " << node->getNodeId() << " will be ready in Cycle "
<< earliestForNode[node->getNodeId()] << "; " << getEarliestReadyTimeForNode(node) << "; "
<< " Delay = " <<(long)getNodeDelayRef(node) << "; Instruction: \n"; << " Delay = " <<(long)getNodeDelay(node) << "; Instruction: \n";
cerr << " " << *node->getMachineInstr() << "\n"; cerr << " " << *node->getMachineInstr() << "\n";
} }
} }
@ -123,21 +124,21 @@ SchedPriorities::issuedReadyNodeAt(cycles_t curTime,
candsAsSet.erase(node); candsAsSet.erase(node);
mcands.clear(); // ensure reset choices is called before any more choices mcands.clear(); // ensure reset choices is called before any more choices
if (earliestReadyTime == getEarliestForNodeRef(node)) if (earliestReadyTime == getEarliestReadyTimeForNode(node))
{// earliestReadyTime may have been due to this node, so recompute it {// earliestReadyTime may have been due to this node, so recompute it
earliestReadyTime = HUGE_LATENCY; earliestReadyTime = HUGE_LATENCY;
for (NodeHeap::const_iterator I=candsAsHeap.begin(); for (NodeHeap::const_iterator I=candsAsHeap.begin();
I != candsAsHeap.end(); ++I) I != candsAsHeap.end(); ++I)
if (candsAsHeap.getNode(I)) if (candsAsHeap.getNode(I))
earliestReadyTime = std::min(earliestReadyTime, earliestReadyTime = std::min(earliestReadyTime,
getEarliestForNodeRef(candsAsHeap.getNode(I))); getEarliestReadyTimeForNode(candsAsHeap.getNode(I)));
} }
// Now update ready times for successors // Now update ready times for successors
for (SchedGraphNode::const_iterator E=node->beginOutEdges(); for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) E != node->endOutEdges(); ++E)
{ {
cycles_t& etime = getEarliestForNodeRef((*E)->getSink()); cycles_t& etime = getEarliestReadyTimeForNodeRef((*E)->getSink());
etime = std::max(etime, curTime + (*E)->getMinDelay()); etime = std::max(etime, curTime + (*E)->getMinDelay());
} }
} }
@ -216,7 +217,7 @@ SchedPriorities::getNextHighest(const SchedulingManager& S,
// If not, remove it from mcands and continue. Refill mcands if // If not, remove it from mcands and continue. Refill mcands if
// it becomes empty. // it becomes empty.
nextChoice = candsAsHeap.getNode(mcands[nextIdx]); nextChoice = candsAsHeap.getNode(mcands[nextIdx]);
if (getEarliestForNodeRef(nextChoice) > curTime if (getEarliestReadyTimeForNode(nextChoice) > curTime
|| ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode())) || ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode()))
{ {
mcands.erase(mcands.begin() + nextIdx); mcands.erase(mcands.begin() + nextIdx);

View File

@ -159,7 +159,8 @@ private:
FunctionLiveVarInfo &methodLiveVarInfo; FunctionLiveVarInfo &methodLiveVarInfo;
std::hash_map<const MachineInstr*, bool> lastUseMap; std::hash_map<const MachineInstr*, bool> lastUseMap;
std::vector<cycles_t> nodeDelayVec; std::vector<cycles_t> nodeDelayVec;
std::vector<cycles_t> earliestForNode; std::vector<cycles_t> nodeEarliestUseVec;
std::vector<cycles_t> earliestReadyTimeForNode;
cycles_t earliestReadyTime; cycles_t earliestReadyTime;
NodeHeap candsAsHeap; // candidate nodes, ready to go NodeHeap candsAsHeap; // candidate nodes, ready to go
std::hash_set<const SchedGraphNode*> candsAsSet;//same entries as candsAsHeap, std::hash_set<const SchedGraphNode*> candsAsSet;//same entries as candsAsHeap,
@ -183,14 +184,21 @@ private:
const SchedGraphNode* graphNode); const SchedGraphNode* graphNode);
// NOTE: The next two return references to the actual vector entries. // NOTE: The next two return references to the actual vector entries.
// Use with care. // Use the following two if you don't need to modify the value.
cycles_t& getNodeDelayRef (const SchedGraphNode* node) { cycles_t& getNodeDelayRef (const SchedGraphNode* node) {
assert(node->getNodeId() < nodeDelayVec.size()); assert(node->getNodeId() < nodeDelayVec.size());
return nodeDelayVec[node->getNodeId()]; return nodeDelayVec[node->getNodeId()];
} }
cycles_t& getEarliestForNodeRef (const SchedGraphNode* node) { cycles_t& getEarliestReadyTimeForNodeRef (const SchedGraphNode* node) {
assert(node->getNodeId() < earliestForNode.size()); assert(node->getNodeId() < earliestReadyTimeForNode.size());
return earliestForNode[node->getNodeId()]; return earliestReadyTimeForNode[node->getNodeId()];
}
cycles_t getNodeDelay (const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getNodeDelayRef(node);
}
cycles_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
} }
}; };

View File

@ -8,6 +8,7 @@
#include "SchedPriorities.h" #include "SchedPriorities.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
#include "llvm/CodeGen/MachineCodeForMethod.h" #include "llvm/CodeGen/MachineCodeForMethod.h"
#include "llvm/Analysis/LiveVar/FunctionLiveVarInfo.h" // FIXME: Remove when modularized better #include "llvm/Analysis/LiveVar/FunctionLiveVarInfo.h" // FIXME: Remove when modularized better
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -631,7 +632,7 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue)
static void static void
RecordSchedule(const BasicBlock* bb, const SchedulingManager& S) RecordSchedule(const BasicBlock* bb, const SchedulingManager& S)
{ {
MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
const MachineInstrInfo& mii = S.schedInfo.getInstrInfo(); const MachineInstrInfo& mii = S.schedInfo.getInstrInfo();
#ifndef NDEBUG #ifndef NDEBUG
@ -1220,7 +1221,7 @@ ReplaceNopsWithUsefulInstr(SchedulingManager& S,
// fill delay slots, otherwise, just discard them. // fill delay slots, otherwise, just discard them.
// //
unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1; unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
MachineCodeForBasicBlock& bbMvec = node->getBB()->getMachineInstrVec(); MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(node->getBB());
assert(bbMvec[firstDelaySlotIdx - 1] == brInstr && assert(bbMvec[firstDelaySlotIdx - 1] == brInstr &&
"Incorrect instr. index in basic block for brInstr"); "Incorrect instr. index in basic block for brInstr");
@ -1313,7 +1314,7 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S,
// Simply passing in an empty delayNodeVec will have this effect. // Simply passing in an empty delayNodeVec will have this effect.
// //
delayNodeVec.clear(); delayNodeVec.clear();
const MachineCodeForBasicBlock& bbMvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0; i < bbMvec.size(); i++) for (unsigned i=0; i < bbMvec.size(); i++)
if (bbMvec[i] != brInstr && if (bbMvec[i] != brInstr &&
mii.getNumDelaySlots(bbMvec[i]->getOpCode()) > 0) mii.getNumDelaySlots(bbMvec[i]->getOpCode()) > 0)

View File

@ -15,6 +15,7 @@
#include "SchedGraph.h" #include "SchedGraph.h"
#include "llvm/CodeGen/InstrSelection.h" #include "llvm/CodeGen/InstrSelection.h"
#include "llvm/CodeGen/MachineCodeForInstruction.h" #include "llvm/CodeGen/MachineCodeForInstruction.h"
#include "llvm/CodeGen/MachineCodeForBasicBlock.h"
#include "llvm/Target/MachineRegInfo.h" #include "llvm/Target/MachineRegInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
@ -393,7 +394,7 @@ SchedGraph::addCDEdges(const TerminatorInst* term,
// all preceding instructions in the basic block. Use 0 latency again. // all preceding instructions in the basic block. Use 0 latency again.
// //
const BasicBlock* bb = firstBrNode->getBB(); const BasicBlock* bb = firstBrNode->getBB();
const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0, N=mvec.size(); i < N; i++) for (unsigned i=0, N=mvec.size(); i < N; i++)
{ {
if (mvec[i] == termMvec[first]) // reached the first branch if (mvec[i] == termMvec[first]) // reached the first branch
@ -550,7 +551,9 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
SchedGraphNode* node = regRefVec[i].first; SchedGraphNode* node = regRefVec[i].first;
unsigned int opNum = regRefVec[i].second; unsigned int opNum = regRefVec[i].second;
bool isDef = node->getMachineInstr()->operandIsDefined(opNum); bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
bool isDefAndUse =
node->getMachineInstr()->operandIsDefinedAndUsed(opNum);
for (unsigned p=0; p < i; ++p) for (unsigned p=0; p < i; ++p)
{ {
SchedGraphNode* prevNode = regRefVec[p].first; SchedGraphNode* prevNode = regRefVec[p].first;
@ -559,14 +562,22 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
unsigned int prevOpNum = regRefVec[p].second; unsigned int prevOpNum = regRefVec[p].second;
bool prevIsDef = bool prevIsDef =
prevNode->getMachineInstr()->operandIsDefined(prevOpNum); prevNode->getMachineInstr()->operandIsDefined(prevOpNum);
bool prevIsDefAndUse =
prevNode->getMachineInstr()->operandIsDefinedAndUsed(prevOpNum);
if (isDef) if (isDef)
new SchedGraphEdge(prevNode, node, regNum, {
(prevIsDef)? SchedGraphEdge::OutputDep if (prevIsDef)
: SchedGraphEdge::AntiDep); new SchedGraphEdge(prevNode, node, regNum,
else if (prevIsDef) SchedGraphEdge::OutputDep);
new SchedGraphEdge(prevNode, node, regNum, if (!prevIsDef || prevIsDefAndUse)
SchedGraphEdge::TrueDep); new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::AntiDep);
}
if (prevIsDef)
if (!isDef || isDefAndUse)
new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::TrueDep);
} }
} }
} }
@ -574,13 +585,20 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
} }
// Adds dependences to/from refNode from/to all other defs
// in the basic block. refNode may be a use, a def, or both.
// We do not consider other uses because we are not building use-use deps.
//
void void
SchedGraph::addEdgesForValue(SchedGraphNode* refNode, SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
const RefVec& defVec, const RefVec& defVec,
const Value* defValue, const Value* defValue,
bool refNodeIsDef, bool refNodeIsDef,
bool refNodeIsDefAndUse,
const TargetMachine& target) const TargetMachine& target)
{ {
bool refNodeIsUse = !refNodeIsDef || refNodeIsDefAndUse;
// Add true or output dep edges from all def nodes before refNode in BB. // Add true or output dep edges from all def nodes before refNode in BB.
// Add anti or output dep edges to all def nodes after refNode. // Add anti or output dep edges to all def nodes after refNode.
for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I)
@ -589,15 +607,23 @@ SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
continue; // Dont add any self-loops continue; // Dont add any self-loops
if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB())
// (*).first is before refNode { // (*).first is before refNode
(void) new SchedGraphEdge((*I).first, refNode, defValue, if (refNodeIsDef)
(refNodeIsDef)? SchedGraphEdge::OutputDep (void) new SchedGraphEdge((*I).first, refNode, defValue,
: SchedGraphEdge::TrueDep); SchedGraphEdge::OutputDep);
if (refNodeIsUse)
(void) new SchedGraphEdge((*I).first, refNode, defValue,
SchedGraphEdge::TrueDep);
}
else else
// (*).first is after refNode { // (*).first is after refNode
(void) new SchedGraphEdge(refNode, (*I).first, defValue, if (refNodeIsDef)
(refNodeIsDef)? SchedGraphEdge::OutputDep (void) new SchedGraphEdge(refNode, (*I).first, defValue,
: SchedGraphEdge::AntiDep); SchedGraphEdge::OutputDep);
if (refNodeIsUse)
(void) new SchedGraphEdge(refNode, (*I).first, defValue,
SchedGraphEdge::AntiDep);
}
} }
} }
@ -626,7 +652,8 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& minstr,
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end()) if (I != valueToDefVecMap.end())
addEdgesForValue(node, (*I).second, mop.getVRegValue(), addEdgesForValue(node, (*I).second, mop.getVRegValue(),
minstr.operandIsDefined(i), target); minstr.operandIsDefined(i),
minstr.operandIsDefinedAndUsed(i), target);
} }
break; break;
@ -649,73 +676,20 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& minstr,
// value of a Ret instruction. // value of a Ret instruction.
// //
for (unsigned i=0, N=minstr.getNumImplicitRefs(); i < N; ++i) for (unsigned i=0, N=minstr.getNumImplicitRefs(); i < N; ++i)
if (! minstr.implicitRefIsDefined(i)) if (! minstr.implicitRefIsDefined(i) ||
minstr.implicitRefIsDefinedAndUsed(i))
if (const Instruction* srcI = if (const Instruction* srcI =
dyn_cast_or_null<Instruction>(minstr.getImplicitRef(i))) dyn_cast_or_null<Instruction>(minstr.getImplicitRef(i)))
{ {
ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI); ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
if (I != valueToDefVecMap.end()) if (I != valueToDefVecMap.end())
addEdgesForValue(node, (*I).second, minstr.getImplicitRef(i), addEdgesForValue(node, (*I).second, minstr.getImplicitRef(i),
minstr.implicitRefIsDefined(i), target); minstr.implicitRefIsDefined(i),
minstr.implicitRefIsDefinedAndUsed(i), target);
} }
} }
#undef NEED_SEPARATE_NONSSA_EDGES_CODE
#ifdef NEED_SEPARATE_NONSSA_EDGES_CODE
void
SchedGraph::addNonSSAEdgesForValue(const Instruction* instr,
const TargetMachine& target)
{
if (isa<PHINode>(instr))
return;
MachineCodeForVMInstr& mvec = instr->getMachineInstrVec();
const MachineInstrInfo& mii = target.getInstrInfo();
RefVec refVec;
for (unsigned i=0, N=mvec.size(); i < N; i++)
for (int o=0, N = mii.getNumOperands(mvec[i]->getOpCode()); o < N; o++)
{
const MachineOperand& mop = mvec[i]->getOperand(o);
if ((mop.getOperandType() == MachineOperand::MO_VirtualRegister ||
mop.getOperandType() == MachineOperand::MO_CCRegister)
&& mop.getVRegValue() == (Value*) instr)
{
// this operand is a definition or use of value `instr'
SchedGraphNode* node = this->getGraphNodeForInstr(mvec[i]);
assert(node && "No node for machine instruction in this BB?");
refVec.push_back(std::make_pair(node, o));
}
}
// refVec is ordered by control flow order of the machine instructions
for (unsigned i=0; i < refVec.size(); ++i)
{
SchedGraphNode* node = refVec[i].first;
unsigned int opNum = refVec[i].second;
bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
if (isDef)
// add output and/or anti deps to this definition
for (unsigned p=0; p < i; ++p)
{
SchedGraphNode* prevNode = refVec[p].first;
if (prevNode != node)
{
bool prevIsDef = prevNode->getMachineInstr()->
operandIsDefined(refVec[p].second);
new SchedGraphEdge(prevNode, node, SchedGraphEdge::ValueDep,
(prevIsDef)? SchedGraphEdge::OutputDep
: SchedGraphEdge::AntiDep);
}
}
}
}
#endif //NEED_SEPARATE_NONSSA_EDGES_CODE
void void
SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target,
SchedGraphNode* node, SchedGraphNode* node,
@ -786,7 +760,7 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
// Build graph nodes for each VM instruction and gather def/use info. // Build graph nodes for each VM instruction and gather def/use info.
// Do both those together in a single pass over all machine instructions. // Do both those together in a single pass over all machine instructions.
const MachineCodeForBasicBlock& mvec = bb->getMachineInstrVec(); const MachineCodeForBasicBlock& mvec = MachineCodeForBasicBlock::get(bb);
for (unsigned i=0; i < mvec.size(); i++) for (unsigned i=0; i < mvec.size(); i++)
if (! mii.isDummyPhiInstr(mvec[i]->getOpCode())) if (! mii.isDummyPhiInstr(mvec[i]->getOpCode()))
{ {
@ -822,7 +796,7 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
// Find the machine instruction that makes a copy of inval to (*PI). // Find the machine instruction that makes a copy of inval to (*PI).
// This must be in the current basic block (bb). // This must be in the current basic block (bb).
const MachineCodeForVMInstr& mvec = (*PI)->getMachineInstrVec(); const MachineCodeForVMInstr& mvec = MachineCodeForBasicBlock::get(*PI);
const MachineInstr* theCopy = NULL; const MachineInstr* theCopy = NULL;
for (unsigned i=0; i < mvec.size() && theCopy == NULL; i++) for (unsigned i=0; i < mvec.size() && theCopy == NULL; i++)
if (! mii.isDummyPhiInstr(mvec[i]->getOpCode())) if (! mii.isDummyPhiInstr(mvec[i]->getOpCode()))
@ -830,13 +804,17 @@ SchedGraph::buildNodesforBB(const TargetMachine& target,
for (int o=0, N=(int) mvec[i]->getNumOperands(); o < N; o++) for (int o=0, N=(int) mvec[i]->getNumOperands(); o < N; o++)
{ {
const MachineOperand& mop = mvec[i]->getOperand(o); const MachineOperand& mop = mvec[i]->getOperand(o);
if (mvec[i]->operandIsDefined(o)) if (mvec[i]->operandIsDefined(o))
assert(mop.getVRegValue() == (*PI) && "dest shd be my Phi"); assert(mop.getVRegValue() == (*PI) && "dest shd be my Phi");
else if (mop.getVRegValue() == inVal)
{ // found the copy! if (! mvec[i]->operandIsDefined(o) ||
theCopy = mvec[i]; NOT NEEDED? mvec[i]->operandIsDefinedAndUsed(o))
break; if (mop.getVRegValue() == inVal)
} { // found the copy!
theCopy = mvec[i];
break;
}
} }
// Found the dang instruction. Now create a node and do the rest... // Found the dang instruction. Now create a node and do the rest...
@ -911,7 +889,7 @@ SchedGraph::buildGraph(const TargetMachine& target)
// //
//---------------------------------------------------------------- //----------------------------------------------------------------
MachineCodeForBasicBlock& bbMvec = bb->getMachineInstrVec(); MachineCodeForBasicBlock& bbMvec = MachineCodeForBasicBlock::get(bb);
// First, add edges to the terminator instruction of the basic block. // First, add edges to the terminator instruction of the basic block.
this->addCDEdges(bb->getTerminator(), target); this->addCDEdges(bb->getTerminator(), target);

View File

@ -327,6 +327,7 @@ private:
const RefVec& defVec, const RefVec& defVec,
const Value* defValue, const Value* defValue,
bool refNodeIsDef, bool refNodeIsDef,
bool refNodeIsDefAndUse,
const TargetMachine& target); const TargetMachine& target);
void addDummyEdges (); void addDummyEdges ();

View File

@ -28,9 +28,10 @@ SchedPriorities::SchedPriorities(const Function *, const SchedGraph *G,
FunctionLiveVarInfo &LVI) FunctionLiveVarInfo &LVI)
: curTime(0), graph(G), methodLiveVarInfo(LVI), : curTime(0), graph(G), methodLiveVarInfo(LVI),
nodeDelayVec(G->getNumNodes(), INVALID_LATENCY), // make errors obvious nodeDelayVec(G->getNumNodes(), INVALID_LATENCY), // make errors obvious
earliestForNode(G->getNumNodes(), 0), earliestReadyTimeForNode(G->getNumNodes(), 0),
earliestReadyTime(0), earliestReadyTime(0),
nextToTry(candsAsHeap.begin()) { nextToTry(candsAsHeap.begin())
{
computeDelays(graph); computeDelays(graph);
} }
@ -51,7 +52,7 @@ SchedPriorities::computeDelays(const SchedGraph* graph)
const SchedGraphNode* node = *poIter; const SchedGraphNode* node = *poIter;
cycles_t nodeDelay; cycles_t nodeDelay;
if (node->beginOutEdges() == node->endOutEdges()) if (node->beginOutEdges() == node->endOutEdges())
nodeDelay = node->getLatency(); nodeDelay = node->getLatency();
else else
{ {
// Iterate over the out-edges of the node to compute delay // Iterate over the out-edges of the node to compute delay
@ -59,7 +60,7 @@ SchedPriorities::computeDelays(const SchedGraph* graph)
for (SchedGraphNode::const_iterator E=node->beginOutEdges(); for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) E != node->endOutEdges(); ++E)
{ {
cycles_t sinkDelay = getNodeDelayRef((*E)->getSink()); cycles_t sinkDelay = getNodeDelay((*E)->getSink());
nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay()); nodeDelay = std::max(nodeDelay, sinkDelay + (*E)->getMinDelay());
} }
} }
@ -104,13 +105,13 @@ SchedPriorities::insertReady(const SchedGraphNode* node)
candsAsSet.insert(node); candsAsSet.insert(node);
mcands.clear(); // ensure reset choices is called before any more choices mcands.clear(); // ensure reset choices is called before any more choices
earliestReadyTime = std::min(earliestReadyTime, earliestReadyTime = std::min(earliestReadyTime,
earliestForNode[node->getNodeId()]); getEarliestReadyTimeForNode(node));
if (SchedDebugLevel >= Sched_PrintSchedTrace) if (SchedDebugLevel >= Sched_PrintSchedTrace)
{ {
cerr << " Node " << node->getNodeId() << " will be ready in Cycle " cerr << " Node " << node->getNodeId() << " will be ready in Cycle "
<< earliestForNode[node->getNodeId()] << "; " << getEarliestReadyTimeForNode(node) << "; "
<< " Delay = " <<(long)getNodeDelayRef(node) << "; Instruction: \n"; << " Delay = " <<(long)getNodeDelay(node) << "; Instruction: \n";
cerr << " " << *node->getMachineInstr() << "\n"; cerr << " " << *node->getMachineInstr() << "\n";
} }
} }
@ -123,21 +124,21 @@ SchedPriorities::issuedReadyNodeAt(cycles_t curTime,
candsAsSet.erase(node); candsAsSet.erase(node);
mcands.clear(); // ensure reset choices is called before any more choices mcands.clear(); // ensure reset choices is called before any more choices
if (earliestReadyTime == getEarliestForNodeRef(node)) if (earliestReadyTime == getEarliestReadyTimeForNode(node))
{// earliestReadyTime may have been due to this node, so recompute it {// earliestReadyTime may have been due to this node, so recompute it
earliestReadyTime = HUGE_LATENCY; earliestReadyTime = HUGE_LATENCY;
for (NodeHeap::const_iterator I=candsAsHeap.begin(); for (NodeHeap::const_iterator I=candsAsHeap.begin();
I != candsAsHeap.end(); ++I) I != candsAsHeap.end(); ++I)
if (candsAsHeap.getNode(I)) if (candsAsHeap.getNode(I))
earliestReadyTime = std::min(earliestReadyTime, earliestReadyTime = std::min(earliestReadyTime,
getEarliestForNodeRef(candsAsHeap.getNode(I))); getEarliestReadyTimeForNode(candsAsHeap.getNode(I)));
} }
// Now update ready times for successors // Now update ready times for successors
for (SchedGraphNode::const_iterator E=node->beginOutEdges(); for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) E != node->endOutEdges(); ++E)
{ {
cycles_t& etime = getEarliestForNodeRef((*E)->getSink()); cycles_t& etime = getEarliestReadyTimeForNodeRef((*E)->getSink());
etime = std::max(etime, curTime + (*E)->getMinDelay()); etime = std::max(etime, curTime + (*E)->getMinDelay());
} }
} }
@ -216,7 +217,7 @@ SchedPriorities::getNextHighest(const SchedulingManager& S,
// If not, remove it from mcands and continue. Refill mcands if // If not, remove it from mcands and continue. Refill mcands if
// it becomes empty. // it becomes empty.
nextChoice = candsAsHeap.getNode(mcands[nextIdx]); nextChoice = candsAsHeap.getNode(mcands[nextIdx]);
if (getEarliestForNodeRef(nextChoice) > curTime if (getEarliestReadyTimeForNode(nextChoice) > curTime
|| ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode())) || ! instrIsFeasible(S, nextChoice->getMachineInstr()->getOpCode()))
{ {
mcands.erase(mcands.begin() + nextIdx); mcands.erase(mcands.begin() + nextIdx);

View File

@ -159,7 +159,8 @@ private:
FunctionLiveVarInfo &methodLiveVarInfo; FunctionLiveVarInfo &methodLiveVarInfo;
std::hash_map<const MachineInstr*, bool> lastUseMap; std::hash_map<const MachineInstr*, bool> lastUseMap;
std::vector<cycles_t> nodeDelayVec; std::vector<cycles_t> nodeDelayVec;
std::vector<cycles_t> earliestForNode; std::vector<cycles_t> nodeEarliestUseVec;
std::vector<cycles_t> earliestReadyTimeForNode;
cycles_t earliestReadyTime; cycles_t earliestReadyTime;
NodeHeap candsAsHeap; // candidate nodes, ready to go NodeHeap candsAsHeap; // candidate nodes, ready to go
std::hash_set<const SchedGraphNode*> candsAsSet;//same entries as candsAsHeap, std::hash_set<const SchedGraphNode*> candsAsSet;//same entries as candsAsHeap,
@ -183,14 +184,21 @@ private:
const SchedGraphNode* graphNode); const SchedGraphNode* graphNode);
// NOTE: The next two return references to the actual vector entries. // NOTE: The next two return references to the actual vector entries.
// Use with care. // Use the following two if you don't need to modify the value.
cycles_t& getNodeDelayRef (const SchedGraphNode* node) { cycles_t& getNodeDelayRef (const SchedGraphNode* node) {
assert(node->getNodeId() < nodeDelayVec.size()); assert(node->getNodeId() < nodeDelayVec.size());
return nodeDelayVec[node->getNodeId()]; return nodeDelayVec[node->getNodeId()];
} }
cycles_t& getEarliestForNodeRef (const SchedGraphNode* node) { cycles_t& getEarliestReadyTimeForNodeRef (const SchedGraphNode* node) {
assert(node->getNodeId() < earliestForNode.size()); assert(node->getNodeId() < earliestReadyTimeForNode.size());
return earliestForNode[node->getNodeId()]; return earliestReadyTimeForNode[node->getNodeId()];
}
cycles_t getNodeDelay (const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getNodeDelayRef(node);
}
cycles_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
} }
}; };