mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-07 14:33:15 +00:00
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:
parent
9afa88c3a7
commit
0baf1c0911
@ -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)
|
||||||
|
@ -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,6 +551,8 @@ 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)
|
||||||
{
|
{
|
||||||
@ -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);
|
||||||
|
@ -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 ();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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,6 +551,8 @@ 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)
|
||||||
{
|
{
|
||||||
@ -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);
|
||||||
|
@ -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 ();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user