[llvm-commits] CVS: llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp SchedGraph.cpp SchedGraph.h SchedGraphCommon.cpp SchedPriorities.cpp SchedPriorities.h
Misha Brukman
brukman at cs.uiuc.edu
Thu Apr 21 16:27:23 PDT 2005
Changes in directory llvm/lib/Target/SparcV9/InstrSched:
InstrScheduling.cpp updated: 1.81 -> 1.82
SchedGraph.cpp updated: 1.68 -> 1.69
SchedGraph.h updated: 1.40 -> 1.41
SchedGraphCommon.cpp updated: 1.8 -> 1.9
SchedPriorities.cpp updated: 1.36 -> 1.37
SchedPriorities.h updated: 1.28 -> 1.29
---
Log message:
Remove trailing whitespace
---
Diffs of the changes: (+407 -407)
InstrScheduling.cpp | 412 +++++++++++++++++++++++++--------------------------
SchedGraph.cpp | 186 +++++++++++------------
SchedGraph.h | 62 +++----
SchedGraphCommon.cpp | 40 ++--
SchedPriorities.cpp | 54 +++---
SchedPriorities.h | 60 +++----
6 files changed, 407 insertions(+), 407 deletions(-)
Index: llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp
diff -u llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp:1.81 llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp:1.82
--- llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp:1.81 Mon Mar 21 00:07:43 2005
+++ llvm/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp Thu Apr 21 18:27:12 2005
@@ -1,10 +1,10 @@
//===- InstrScheduling.cpp - Generic Instruction Scheduling support -------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This file implements the llvm/CodeGen/InstrScheduling.h interface, along with
@@ -50,7 +50,7 @@
//----------------------------------------------------------------------
// class InstrGroup:
-//
+//
// Represents a group of instructions scheduled to be issued
// in a single cycle.
//----------------------------------------------------------------------
@@ -58,26 +58,26 @@
class InstrGroup {
InstrGroup(const InstrGroup&); // DO NOT IMPLEMENT
void operator=(const InstrGroup&); // DO NOT IMPLEMENT
-
+
public:
inline const SchedGraphNode* operator[](unsigned int slotNum) const {
assert(slotNum < group.size());
return group[slotNum];
}
-
+
private:
friend class InstrSchedule;
-
+
inline void addInstr(const SchedGraphNode* node, unsigned int slotNum) {
assert(slotNum < group.size());
group[slotNum] = node;
}
-
+
/*ctor*/ InstrGroup(unsigned int nslots)
: group(nslots, NULL) {}
-
+
/*ctor*/ InstrGroup(); // disable: DO NOT IMPLEMENT
-
+
private:
std::vector<const SchedGraphNode*> group;
};
@@ -85,7 +85,7 @@
//----------------------------------------------------------------------
// class ScheduleIterator:
-//
+//
// Iterates over the machine instructions in the for a single basic block.
// The schedule is represented by an InstrSchedule object.
//----------------------------------------------------------------------
@@ -98,34 +98,34 @@
const InstrSchedule& S;
public:
typedef ScheduleIterator<_NodeType> _Self;
-
+
/*ctor*/ inline ScheduleIterator(const InstrSchedule& _schedule,
unsigned _cycleNum,
unsigned _slotNum)
: cycleNum(_cycleNum), slotNum(_slotNum), S(_schedule) {
- skipToNextInstr();
+ skipToNextInstr();
}
-
+
/*ctor*/ inline ScheduleIterator(const _Self& x)
: cycleNum(x.cycleNum), slotNum(x.slotNum), S(x.S) {}
-
+
inline bool operator==(const _Self& x) const {
return (slotNum == x.slotNum && cycleNum== x.cycleNum && &S==&x.S);
}
-
+
inline bool operator!=(const _Self& x) const { return !operator==(x); }
-
+
inline _NodeType* operator*() const;
inline _NodeType* operator->() const { return operator*(); }
-
+
_Self& operator++(); // Preincrement
inline _Self operator++(int) { // Postincrement
- _Self tmp(*this); ++*this; return tmp;
+ _Self tmp(*this); ++*this; return tmp;
}
-
+
static _Self begin(const InstrSchedule& _schedule);
static _Self end( const InstrSchedule& _schedule);
-
+
private:
inline _Self& operator=(const _Self& x); // DISABLE -- DO NOT IMPLEMENT
void skipToNextInstr();
@@ -134,7 +134,7 @@
//----------------------------------------------------------------------
// class InstrSchedule:
-//
+//
// Represents the schedule of machine instructions for a single basic block.
//----------------------------------------------------------------------
@@ -146,28 +146,28 @@
InstrSchedule(InstrSchedule&); // DO NOT IMPLEMENT
void operator=(InstrSchedule&); // DO NOT IMPLEMENT
-
+
public: // iterators
typedef ScheduleIterator<SchedGraphNode> iterator;
typedef ScheduleIterator<const SchedGraphNode> const_iterator;
-
+
iterator begin() { return iterator::begin(*this); }
const_iterator begin() const { return const_iterator::begin(*this); }
iterator end() { return iterator::end(*this); }
const_iterator end() const { return const_iterator::end(*this); }
-
+
public: // constructors and destructor
/*ctor*/ InstrSchedule (unsigned int _nslots,
unsigned int _numNodes);
/*dtor*/ ~InstrSchedule ();
-
+
public: // accessor functions to query chosen schedule
const SchedGraphNode* getInstr (unsigned int slotNum,
CycleCount_t c) {
const InstrGroup* igroup = this->getIGroup(c);
return (igroup == NULL)? NULL : (*igroup)[slotNum];
}
-
+
inline InstrGroup* getIGroup (CycleCount_t c) {
if ((unsigned)c >= groups.size())
groups.resize(c+1);
@@ -175,21 +175,21 @@
groups[c] = new InstrGroup(nslots);
return groups[c];
}
-
+
inline const InstrGroup* getIGroup (CycleCount_t c) const {
assert((unsigned)c < groups.size());
return groups[c];
}
-
+
inline CycleCount_t getStartTime (unsigned int nodeId) const {
assert(nodeId < startTime.size());
return startTime[nodeId];
}
-
+
unsigned int getNumInstructions() const {
return numInstr;
}
-
+
inline void scheduleInstr (const SchedGraphNode* node,
unsigned int slotNum,
CycleCount_t cycle) {
@@ -203,7 +203,7 @@
startTime[node->getNodeId()] = cycle;
++numInstr;
}
-
+
private:
friend class ScheduleIterator<SchedGraphNode>;
friend class ScheduleIterator<const SchedGraphNode>;
@@ -237,13 +237,13 @@
template<class _NodeType>
-inline
+inline
void
ScheduleIterator<_NodeType>::skipToNextInstr()
{
while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
++cycleNum; // skip cycles with no instructions
-
+
while (cycleNum < S.groups.size() &&
(*S.groups[cycleNum])[slotNum] == NULL)
{
@@ -258,7 +258,7 @@
}
template<class _NodeType>
-inline
+inline
ScheduleIterator<_NodeType>&
ScheduleIterator<_NodeType>::operator++() // Preincrement
{
@@ -267,7 +267,7 @@
++cycleNum;
slotNum = 0;
}
- skipToNextInstr();
+ skipToNextInstr();
return *this;
}
@@ -288,7 +288,7 @@
//----------------------------------------------------------------------
// class DelaySlotInfo:
-//
+//
// Record information about delay slots for a single branch instruction.
// Delay slots are simply indexed by slot number 1 ... numDelaySlots
//----------------------------------------------------------------------
@@ -299,7 +299,7 @@
std::vector<const SchedGraphNode*> delayNodeVec;
CycleCount_t delayedNodeCycle;
unsigned delayedNodeSlotNum;
-
+
DelaySlotInfo(const DelaySlotInfo &); // DO NOT IMPLEMENT
void operator=(const DelaySlotInfo&); // DO NOT IMPLEMENT
public:
@@ -307,32 +307,32 @@
unsigned _ndelays)
: brNode(_brNode), ndelays(_ndelays),
delayedNodeCycle(0), delayedNodeSlotNum(0) {}
-
+
inline unsigned getNumDelays () {
return ndelays;
}
-
+
inline const std::vector<const SchedGraphNode*>& getDelayNodeVec() {
return delayNodeVec;
}
-
+
inline void addDelayNode (const SchedGraphNode* node) {
delayNodeVec.push_back(node);
assert(delayNodeVec.size() <= ndelays && "Too many delay slot instrs!");
}
-
+
inline void recordChosenSlot (CycleCount_t cycle, unsigned slotNum) {
delayedNodeCycle = cycle;
delayedNodeSlotNum = slotNum;
}
-
+
unsigned scheduleDelayedNode (SchedulingManager& S);
};
//----------------------------------------------------------------------
// class SchedulingManager:
-//
+//
// Represents the schedule of machine instructions for a single basic block.
//----------------------------------------------------------------------
@@ -344,7 +344,7 @@
const TargetSchedInfo& schedInfo;
SchedPriorities& schedPrio;
InstrSchedule isched;
-
+
private:
unsigned totalInstrCount;
CycleCount_t curTime;
@@ -355,8 +355,8 @@
std::vector<int> numInClass; // indexed by sched class
std::vector<CycleCount_t> nextEarliestStartTime; // indexed by opCode
hash_map<const SchedGraphNode*, DelaySlotInfo*> delaySlotInfoForBranches;
- // indexed by branch node ptr
-
+ // indexed by branch node ptr
+
public:
SchedulingManager(const TargetMachine& _target, const SchedGraph* graph,
SchedPriorities& schedPrio);
@@ -366,38 +366,38 @@
E = delaySlotInfoForBranches.end(); I != E; ++I)
delete I->second;
}
-
+
//----------------------------------------------------------------------
// Simplify access to the machine instruction info
//----------------------------------------------------------------------
-
+
inline const TargetInstrInfo& getInstrInfo () const {
return schedInfo.getInstrInfo();
}
-
+
//----------------------------------------------------------------------
// Interface for checking and updating the current time
//----------------------------------------------------------------------
-
+
inline CycleCount_t getTime () const {
return curTime;
}
-
+
inline CycleCount_t getEarliestIssueTime() const {
return nextEarliestIssueTime;
}
-
+
inline CycleCount_t getEarliestStartTimeForOp(MachineOpCode opCode) const {
assert(opCode < (int) nextEarliestStartTime.size());
return nextEarliestStartTime[opCode];
}
-
+
// Update current time to specified cycle
inline void updateTime (CycleCount_t c) {
curTime = c;
schedPrio.updateTime(c);
}
-
+
//----------------------------------------------------------------------
// Functions to manage the choices for the current cycle including:
// -- a vector of choices by priority (choiceVec)
@@ -405,26 +405,26 @@
// -- number of choices in each sched class, used to check issue conflicts
// between choices for a single cycle
//----------------------------------------------------------------------
-
+
inline unsigned int getNumChoices () const {
return choiceVec.size();
}
-
+
inline unsigned getNumChoicesInClass (const InstrSchedClass& sc) const {
assert(sc < numInClass.size() && "Invalid op code or sched class!");
return numInClass[sc];
}
-
+
inline const SchedGraphNode* getChoice(unsigned int i) const {
// assert(i < choiceVec.size()); don't check here.
return choiceVec[i];
}
-
+
inline hash_set<const SchedGraphNode*>& getChoicesForSlot(unsigned slotNum) {
assert(slotNum < nslots);
return choicesForSlot[slotNum];
}
-
+
inline void addChoice (const SchedGraphNode* node) {
// Append the instruction to the vector of choices for current cycle.
// Increment numInClass[c] for the sched class to which the instr belongs.
@@ -433,14 +433,14 @@
assert(sc < numInClass.size());
numInClass[sc]++;
}
-
+
inline void addChoiceToSlot (unsigned int slotNum,
const SchedGraphNode* node) {
// Add the instruction to the choice set for the specified slot
assert(slotNum < nslots);
choicesForSlot[slotNum].insert(node);
}
-
+
inline void resetChoices () {
choiceVec.clear();
for (unsigned int s=0; s < nslots; s++)
@@ -448,40 +448,40 @@
for (unsigned int c=0; c < numInClass.size(); c++)
numInClass[c] = 0;
}
-
+
//----------------------------------------------------------------------
// Code to query and manage the partial instruction schedule so far
//----------------------------------------------------------------------
-
+
inline unsigned int getNumScheduled () const {
return isched.getNumInstructions();
}
-
+
inline unsigned int getNumUnscheduled() const {
return totalInstrCount - isched.getNumInstructions();
}
-
+
inline bool isScheduled (const SchedGraphNode* node) const {
return (isched.getStartTime(node->getNodeId()) >= 0);
}
-
+
inline void scheduleInstr (const SchedGraphNode* node,
unsigned int slotNum,
CycleCount_t cycle)
{
assert(! isScheduled(node) && "Instruction already scheduled?");
-
+
// add the instruction to the schedule
isched.scheduleInstr(node, slotNum, cycle);
-
+
// update the earliest start times of all nodes that conflict with `node'
// and the next-earliest time anything can issue if `node' causes bubbles
updateEarliestStartTimes(node, cycle);
-
+
// remove the instruction from the choice sets for all slots
for (unsigned s=0; s < nslots; s++)
choicesForSlot[s].erase(node);
-
+
// and decrement the instr count for the sched class to which it belongs
const InstrSchedClass& sc = schedInfo.getSchedClass(node->getOpcode());
assert(sc < numInClass.size());
@@ -491,7 +491,7 @@
//----------------------------------------------------------------------
// Create and retrieve delay slot info for delayed instructions
//----------------------------------------------------------------------
-
+
inline DelaySlotInfo* getDelaySlotInfoForInstr(const SchedGraphNode* bn,
bool createIfMissing=false)
{
@@ -506,7 +506,7 @@
new DelaySlotInfo(bn, getInstrInfo().getNumDelaySlots(bn->getOpcode()));
return delaySlotInfoForBranches[bn] = dinfo;
}
-
+
private:
SchedulingManager(); // DISABLED: DO NOT IMPLEMENT
void updateEarliestStartTimes(const SchedGraphNode* node, CycleCount_t schedTime);
@@ -529,7 +529,7 @@
(CycleCount_t) 0) // set all to 0
{
updateTime(0);
-
+
// Note that an upper bound on #choices for each slot is = nslots since
// we use this vector to hold a feasible set of instructions, and more
// would be infeasible. Reserve that much memory since it is probably small.
@@ -547,10 +547,10 @@
nextEarliestIssueTime = std::max(nextEarliestIssueTime,
curTime + 1 + schedInfo.numBubblesAfter(node->getOpcode()));
}
-
+
const std::vector<MachineOpCode>&
conflictVec = schedInfo.getConflictList(node->getOpcode());
-
+
for (unsigned i=0; i < conflictVec.size(); i++)
{
MachineOpCode toOp = conflictVec[i];
@@ -570,9 +570,9 @@
// find the slot to start from, in the current cycle
unsigned int startSlot = 0;
CycleCount_t curTime = S.getTime();
-
+
assert(maxIssue > 0 && maxIssue <= S.nslots - startSlot);
-
+
// If only one instruction can be issued, do so.
if (maxIssue == 1)
for (unsigned s=startSlot; s < S.nslots; s++)
@@ -581,12 +581,12 @@
S.scheduleInstr(*S.getChoicesForSlot(s).begin(), s, curTime);
return;
}
-
+
// Otherwise, choose from the choices for each slot
- //
+ //
InstrGroup* igroup = S.isched.getIGroup(S.getTime());
assert(igroup != NULL && "Group creation failed?");
-
+
// Find a slot that has only a single choice, and take it.
// If all slots have 0 or multiple choices, pick the first slot with
// choices and use its last instruction (just to avoid shifting the vector).
@@ -598,14 +598,14 @@
chosenSlot = (int) s;
break;
}
-
+
if (chosenSlot == -1)
for (unsigned s=startSlot; s < S.nslots; s++)
if ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() > 0) {
chosenSlot = (int) s;
break;
}
-
+
if (chosenSlot != -1) {
// Insert the chosen instr in the chosen slot and
// erase it from all slots.
@@ -613,23 +613,23 @@
S.scheduleInstr(node, chosenSlot, curTime);
}
}
-
+
assert(numIssued > 0 && "Should not happen when maxIssue > 0!");
}
-//
+//
// For now, just assume we are scheduling within a single basic block.
// Get the machine instruction vector for the basic block and clear it,
// then append instructions in scheduled order.
// Also, re-insert the dummy PHI instructions that were at the beginning
// of the basic block, since they are not part of the schedule.
-//
+//
static void
RecordSchedule(MachineBasicBlock &MBB, const SchedulingManager& S)
{
const TargetInstrInfo& mii = S.schedInfo.getInstrInfo();
-
+
// Lets make sure we didn't lose any instructions, except possibly
// some NOPs from delay slots. Also, PHIs are not included in the schedule.
unsigned numInstr = 0;
@@ -638,21 +638,21 @@
++numInstr;
assert(S.isched.getNumInstructions() >= numInstr &&
"Lost some non-NOP instructions during scheduling!");
-
+
if (S.isched.getNumInstructions() == 0)
return; // empty basic block!
-
+
// First find the dummy instructions at the start of the basic block
MachineBasicBlock::iterator I = MBB.begin();
for ( ; I != MBB.end(); ++I)
if (I->getOpcode() != V9::PHI)
break;
-
+
// Remove all except the dummy PHI instructions from MBB, and
// pre-allocate create space for the ones we will put back in.
while (I != MBB.end())
MBB.remove(I++);
-
+
InstrSchedule::const_iterator NIend = S.isched.end();
for (InstrSchedule::const_iterator NI = S.isched.begin(); NI != NIend; ++NI)
MBB.push_back(const_cast<MachineInstr*>((*NI)->getMachineInstr()));
@@ -665,7 +665,7 @@
{
// Check if any successors are now ready that were not already marked
// ready before, and that have not yet been scheduled.
- //
+ //
for (sg_succ_const_iterator SI = succ_begin(node); SI !=succ_end(node); ++SI)
if (! (*SI)->isDummyNode()
&& ! S.isScheduled(*SI)
@@ -690,18 +690,18 @@
// instruction to all possible slots that do not violate feasibility.
// FEASIBLE means it should be guaranteed that the set
// of chosen instructions can be issued in a single group.
-//
+//
// Return value:
// maxIssue : total number of feasible instructions
// S.choicesForSlot[i=0..nslots] : set of instructions feasible in slot i
-//
+//
static unsigned
FindSlotChoices(SchedulingManager& S,
DelaySlotInfo*& getDelaySlotInfo)
{
// initialize result vectors to empty
S.resetChoices();
-
+
// find the slot to start from, in the current cycle
unsigned int startSlot = 0;
InstrGroup* igroup = S.isched.getIGroup(S.getTime());
@@ -710,7 +710,7 @@
startSlot = s+1;
break;
}
-
+
// Make sure we pick at most one instruction that would break the group.
// Also, if we do pick one, remember which it was.
unsigned int indexForBreakingNode = S.nslots;
@@ -718,17 +718,17 @@
DelaySlotInfo* delaySlotInfo = NULL;
getDelaySlotInfo = NULL;
-
+
// Choose instructions in order of priority.
// Add choices to the choice vector in the SchedulingManager class as
// we choose them so that subsequent choices will be correctly tested
// for feasibility, w.r.t. higher priority choices for the same cycle.
- //
+ //
while (S.getNumChoices() < S.nslots - startSlot) {
const SchedGraphNode* nextNode=S.schedPrio.getNextHighest(S,S.getTime());
if (nextNode == NULL)
break; // no more instructions for this cycle
-
+
if (S.getInstrInfo().getNumDelaySlots(nextNode->getOpcode()) > 0) {
delaySlotInfo = S.getDelaySlotInfoForInstr(nextNode);
if (delaySlotInfo != NULL) {
@@ -746,34 +746,34 @@
else
indexForBreakingNode = S.getNumChoices();
}
-
+
if (nextNode != NULL) {
S.addChoice(nextNode);
-
+
if (S.schedInfo.isSingleIssue(nextNode->getOpcode())) {
assert(S.getNumChoices() == 1 &&
"Prioritizer returned invalid instr for this cycle!");
break;
}
}
-
+
if (indexForDelayedInstr < S.nslots)
break; // leave the rest for delay slots
}
-
+
assert(S.getNumChoices() <= S.nslots);
assert(! (indexForDelayedInstr < S.nslots &&
indexForBreakingNode < S.nslots) && "Cannot have both in a cycle");
-
+
// Assign each chosen instruction to all possible slots for that instr.
// But if only one instruction was chosen, put it only in the first
// feasible slot; no more analysis will be needed.
- //
- if (indexForDelayedInstr >= S.nslots &&
+ //
+ if (indexForDelayedInstr >= S.nslots &&
indexForBreakingNode >= S.nslots)
{ // No instructions that break the issue group or that have delay slots.
// This is the common case, so handle it separately for efficiency.
-
+
if (S.getNumChoices() == 1) {
MachineOpCode opCode = S.getChoice(0)->getOpcode();
unsigned int s;
@@ -795,19 +795,19 @@
// Try to assign that instruction to a higher slot than any other
// instructions in the group, so that its delay slots can go
// right after it.
- //
+ //
assert(indexForDelayedInstr == S.getNumChoices() - 1 &&
"Instruction with delay slots should be last choice!");
assert(delaySlotInfo != NULL && "No delay slot info for instr?");
-
+
const SchedGraphNode* delayedNode = S.getChoice(indexForDelayedInstr);
MachineOpCode delayOpCode = delayedNode->getOpcode();
unsigned ndelays= S.getInstrInfo().getNumDelaySlots(delayOpCode);
-
+
unsigned delayedNodeSlot = S.nslots;
int highestSlotUsed;
-
+
// Find the last possible slot for the delayed instruction that leaves
// at least `d' slots vacant after it (d = #delay slots)
for (int s = S.nslots-ndelays-1; s >= (int) startSlot; s--)
@@ -815,7 +815,7 @@
delayedNodeSlot = s;
break;
}
-
+
highestSlotUsed = -1;
for (unsigned i=0; i < S.getNumChoices() - 1; i++) {
// Try to assign every other instruction to a lower numbered
@@ -828,7 +828,7 @@
S.addChoiceToSlot(s, S.getChoice(i));
noSlotFound = false;
}
-
+
// No slot before `delayedNodeSlot' was found for this opCode
// Use a later slot, and allow some delay slots to fall in
// the next cycle.
@@ -838,14 +838,14 @@
S.addChoiceToSlot(s, S.getChoice(i));
break;
}
-
+
assert(s < S.nslots && "No feasible slot for instruction?");
-
+
highestSlotUsed = std::max(highestSlotUsed, (int) s);
}
-
+
assert(highestSlotUsed <= (int) S.nslots-1 && "Invalid slot used?");
-
+
// We will put the delayed node in the first slot after the
// highest slot used. But we just mark that for now, and
// schedule it separately because we want to schedule the delay
@@ -867,7 +867,7 @@
const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode);
unsigned breakingSlot = INT_MAX;
unsigned int nslotsToUse = S.nslots;
-
+
// Find the last possible slot for this instruction.
for (int s = S.nslots-1; s >= (int) startSlot; s--)
if (S.schedInfo.instrCanUseSlot(breakingNode->getOpcode(), s)) {
@@ -876,7 +876,7 @@
}
assert(breakingSlot < S.nslots &&
"No feasible slot for `breakingNode'?");
-
+
// Higher priority instructions than the one that breaks the group:
// These can be assigned to all slots, but will be assigned only
// to earlier slots if possible.
@@ -884,10 +884,10 @@
i < S.getNumChoices() && i < indexForBreakingNode; i++)
{
MachineOpCode opCode =S.getChoice(i)->getOpcode();
-
+
// If a higher priority instruction cannot be assigned to
// any earlier slots, don't schedule the breaking instruction.
- //
+ //
bool foundLowerSlot = false;
nslotsToUse = S.nslots; // May be modified in the loop
for (unsigned int s=startSlot; s < nslotsToUse; s++)
@@ -896,14 +896,14 @@
foundLowerSlot = true;
nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
}
-
+
S.addChoiceToSlot(s, S.getChoice(i));
}
-
+
if (!foundLowerSlot)
breakingSlot = INT_MAX; // disable breaking instr
}
-
+
// Assign the breaking instruction (if any) to a single slot
// Otherwise, just ignore the instruction. It will simply be
// scheduled in a later cycle.
@@ -912,7 +912,7 @@
nslotsToUse = breakingSlot;
} else
nslotsToUse = S.nslots;
-
+
// For lower priority instructions than the one that breaks the
// group, only assign them to slots lower than the breaking slot.
// Otherwise, just ignore the instruction.
@@ -923,7 +923,7 @@
S.addChoiceToSlot(s, S.getChoice(i));
}
} // endif (no delay slots and no breaking slots)
-
+
return S.getNumChoices();
}
@@ -933,23 +933,23 @@
{
assert(S.schedPrio.getNumReady() > 0
&& "Don't get here without ready instructions.");
-
+
CycleCount_t firstCycle = S.getTime();
DelaySlotInfo* getDelaySlotInfo = NULL;
-
+
// Choose up to `nslots' feasible instructions and their possible slots.
unsigned numIssued = FindSlotChoices(S, getDelaySlotInfo);
-
+
while (numIssued == 0) {
S.updateTime(S.getTime()+1);
numIssued = FindSlotChoices(S, getDelaySlotInfo);
}
-
+
AssignInstructionsToSlots(S, numIssued);
-
+
if (getDelaySlotInfo != NULL)
- numIssued += getDelaySlotInfo->scheduleDelayedNode(S);
-
+ numIssued += getDelaySlotInfo->scheduleDelayedNode(S);
+
// Print trace of scheduled instructions before newly ready ones
if (SchedDebugLevel >= Sched_PrintSchedTrace) {
for (CycleCount_t c = firstCycle; c <= S.getTime(); c++) {
@@ -964,7 +964,7 @@
}
}
}
-
+
return numIssued;
}
@@ -974,23 +974,23 @@
{
unsigned N;
const SchedGraphNode* node;
-
+
S.schedPrio.initialize();
-
+
while ((N = S.schedPrio.getNumReady()) > 0) {
CycleCount_t nextCycle = S.getTime();
-
+
// Choose one group of instructions for a cycle, plus any delay slot
// instructions (which may overflow into successive cycles).
// This will advance S.getTime() to the last cycle in which
// instructions are actually issued.
- //
+ //
unsigned numIssued = ChooseOneGroup(S);
assert(numIssued > 0 && "Deadlock in list scheduling algorithm?");
-
+
// Notify the priority manager of scheduled instructions and mark
// any successors that may now be ready
- //
+ //
for (CycleCount_t c = nextCycle; c <= S.getTime(); c++) {
const InstrGroup* igroup = S.isched.getIGroup(c);
for (unsigned int s=0; s < S.nslots; s++)
@@ -999,11 +999,11 @@
MarkSuccessorsReady(S, node);
}
}
-
+
// Move to the next the next earliest cycle for which
// an instruction can be issued, or the next earliest in which
// one will be ready, or to the next cycle, whichever is latest.
- //
+ //
S.updateTime(std::max(S.getTime() + 1,
std::max(S.getEarliestIssueTime(),
S.schedPrio.getEarliestReadyTime())));
@@ -1027,29 +1027,29 @@
bool nodeIsPredecessor)
{
assert(! node->isDummyNode());
-
+
// don't put a branch in the delay slot of another branch
if (S.getInstrInfo().isBranch(node->getOpcode()))
return false;
-
+
// don't put a single-issue instruction in the delay slot of a branch
if (S.schedInfo.isSingleIssue(node->getOpcode()))
return false;
-
+
// don't put a load-use dependence in the delay slot of a branch
const TargetInstrInfo& mii = S.getInstrInfo();
-
+
for (SchedGraphNode::const_iterator EI = node->beginInEdges();
EI != node->endInEdges(); ++EI)
if (! ((SchedGraphNode*)(*EI)->getSrc())->isDummyNode()
&& mii.isLoad(((SchedGraphNode*)(*EI)->getSrc())->getOpcode())
&& (*EI)->getDepType() == SchedGraphEdge::CtrlDep)
return false;
-
+
// Finally, if the instruction precedes the branch, we make sure the
// instruction can be reordered relative to the branch. We simply check
// if the instr. has only 1 outgoing edge, viz., a CD edge to the branch.
- //
+ //
if (nodeIsPredecessor) {
bool onlyCDEdgeToBranch = true;
for (SchedGraphNode::const_iterator OEI = node->beginOutEdges();
@@ -1061,11 +1061,11 @@
onlyCDEdgeToBranch = false;
break;
}
-
+
if (!onlyCDEdgeToBranch)
return false;
}
-
+
return true;
}
@@ -1082,12 +1082,12 @@
// remove it and all its incident edges from the graph. Make sure we
// add dummy edges for pred/succ nodes that become entry/exit nodes.
graph->eraseIncidentEdges(node, /*addDummyEdges*/ true);
- } else {
+ } else {
// If the node was from a target block, add the node to the graph
// and add a CD edge from brNode to node.
assert(0 && "NOT IMPLEMENTED YET");
}
-
+
DelaySlotInfo* dinfo = S.getDelaySlotInfoForInstr(brNode, /*create*/ true);
dinfo->addDelayNode(node);
}
@@ -1101,17 +1101,17 @@
const TargetInstrInfo& mii = S.getInstrInfo();
unsigned ndelays =
mii.getNumDelaySlots(brNode->getOpcode());
-
+
if (ndelays == 0)
return;
-
+
sdelayNodeVec.reserve(ndelays);
-
+
// Use a separate vector to hold the feasible multi-cycle nodes.
// These will be used if not enough single-cycle nodes are found.
- //
+ //
std::vector<SchedGraphNode*> mdelayNodeVec;
-
+
for (sg_pred_iterator P = pred_begin(brNode);
P != pred_end(brNode) && sdelayNodeVec.size() < ndelays; ++P)
if (! (*P)->isDummyNode() &&
@@ -1123,19 +1123,19 @@
else
sdelayNodeVec.push_back(*P);
}
-
+
// If not enough single-cycle instructions were found, select the
// lowest-latency multi-cycle instructions and use them.
// Note that this is the most efficient code when only 1 (or even 2)
// values need to be selected.
- //
+ //
while (sdelayNodeVec.size() < ndelays && mdelayNodeVec.size() > 0) {
unsigned lmin =
mii.maxLatency(mdelayNodeVec[0]->getOpcode());
unsigned minIndex = 0;
for (unsigned i=1; i < mdelayNodeVec.size(); i++)
{
- unsigned li =
+ unsigned li =
mii.maxLatency(mdelayNodeVec[i]->getOpcode());
if (lmin >= li)
{
@@ -1154,7 +1154,7 @@
// Mark instructions specified in sdelayNodeVec to replace them.
// If not enough useful instructions were found, mark the NOPs to be used
// for filling delay slots, otherwise, otherwise just discard them.
-//
+//
static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
SchedGraphNode* node,
// FIXME: passing vector BY VALUE!!!
@@ -1166,11 +1166,11 @@
const MachineInstr* brInstr = node->getMachineInstr();
unsigned ndelays= mii.getNumDelaySlots(brInstr->getOpcode());
assert(ndelays > 0 && "Unnecessary call to replace NOPs");
-
+
// Remove the NOPs currently in delay slots from the graph.
// If not enough useful instructions were found, use the NOPs to
// fill delay slots, otherwise, just discard them.
- //
+ //
unsigned int firstDelaySlotIdx = node->getOrigIndexInBB() + 1;
MachineBasicBlock& MBB = node->getMachineBasicBlock();
MachineBasicBlock::iterator MBBI = MBB.begin();
@@ -1179,10 +1179,10 @@
std::cerr << "Incorrect instr. index in basic block for brInstr";
abort();
}
-
+
// First find all useful instructions already in the delay slots
// and USE THEM. We'll throw away the unused alternatives below
- //
+ //
MachineBasicBlock::iterator Tmp = MBBI;
for (unsigned i = 0; i != ndelays; ++i, ++MBBI)
if (!mii.isNop(MBBI->getOpcode()))
@@ -1198,13 +1198,13 @@
sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
else {
nopNodeVec.push_back(graph->getGraphNodeForInstr(MBBI));
-
+
//remove the MI from the Machine Code For Instruction
const TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
- MachineCodeForInstruction& llvmMvec =
+ MachineCodeForInstruction& llvmMvec =
MachineCodeForInstruction::get((const Instruction *)TI);
-
- for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(),
+
+ for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(),
mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
if (*mciI == MBBI)
llvmMvec.erase(mciI);
@@ -1212,15 +1212,15 @@
}
assert(sdelayNodeVec.size() >= ndelays);
-
+
// If some delay slots were already filled, throw away that many new choices
if (sdelayNodeVec.size() > ndelays)
sdelayNodeVec.resize(ndelays);
-
+
// Mark the nodes chosen for delay slots. This removes them from the graph.
for (unsigned i=0; i < sdelayNodeVec.size(); i++)
MarkNodeForDelaySlot(S, graph, sdelayNodeVec[i], node, true);
-
+
// And remove the unused NOPs from the graph.
for (unsigned i=0; i < nopNodeVec.size(); i++)
graph->eraseIncidentEdges(nopNodeVec[i], /*addDummyEdges*/ true);
@@ -1231,14 +1231,14 @@
// slots and pull those out of the graph. Mark them for the delay slots
// in the DelaySlotInfo object for that graph node. If no useful work
// is found for a delay slot, use the NOP that is currently in that slot.
-//
+//
// We try to fill the delay slots with useful work for all instructions
// EXCEPT CALLS AND RETURNS.
// For CALLs and RETURNs, it is nearly always possible to use one of the
// call sequence instrs and putting anything else in the delay slot could be
// suboptimal. Also, it complicates generating the calling sequence code in
// regalloc.
-//
+//
static void
ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB,
SchedGraph *graph)
@@ -1249,7 +1249,7 @@
MachineCodeForInstruction &termMvec=MachineCodeForInstruction::get(termInstr);
std::vector<SchedGraphNode*> delayNodeVec;
const MachineInstr* brInstr = NULL;
-
+
if (EnableFillingDelaySlots &&
termInstr->getOpcode() != Instruction::Ret)
{
@@ -1257,7 +1257,7 @@
// machine code, we assume that the only delayed instructions are CALLs
// or instructions generated for the terminator inst.
// Find the first branch instr in the sequence of machine instrs for term
- //
+ //
unsigned first = 0;
while (first < termMvec.size() &&
! mii.isBranch(termMvec[first]->getOpcode()))
@@ -1266,24 +1266,24 @@
}
assert(first < termMvec.size() &&
"No branch instructions for BR? Ok, but weird! Delete assertion.");
-
+
brInstr = (first < termMvec.size())? termMvec[first] : NULL;
-
+
// Compute a vector of the nodes chosen for delay slots and then
// mark delay slots to replace NOPs with these useful instructions.
- //
+ //
if (brInstr != NULL) {
SchedGraphNode* brNode = graph->getGraphNodeForInstr(brInstr);
FindUsefulInstructionsForDelaySlots(S, brNode, delayNodeVec);
ReplaceNopsWithUsefulInstr(S, brNode, delayNodeVec, graph);
}
}
-
- // Also mark delay slots for other delayed instructions to hold NOPs.
+
+ // Also mark delay slots for other delayed instructions to hold NOPs.
// Simply passing in an empty delayNodeVec will have this effect.
// If brInstr is not handled above (EnableFillingDelaySlots == false),
// brInstr will be NULL so this will handle the branch instrs. as well.
- //
+ //
delayNodeVec.clear();
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
if (I != brInstr && mii.getNumDelaySlots(I->getOpcode()) > 0) {
@@ -1293,28 +1293,28 @@
}
-//
+//
// Schedule the delayed branch and its delay slots
-//
+//
unsigned
DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S)
{
assert(delayedNodeSlotNum < S.nslots && "Illegal slot for branch");
assert(S.isched.getInstr(delayedNodeSlotNum, delayedNodeCycle) == NULL
&& "Slot for branch should be empty");
-
+
unsigned int nextSlot = delayedNodeSlotNum;
CycleCount_t nextTime = delayedNodeCycle;
-
+
S.scheduleInstr(brNode, nextSlot, nextTime);
-
+
for (unsigned d=0; d < ndelays; d++) {
++nextSlot;
if (nextSlot == S.nslots) {
nextSlot = 0;
nextTime++;
}
-
+
// Find the first feasible instruction for this delay slot
// Note that we only check for issue restrictions here.
// We do *not* check for flow dependences but rely on pipeline
@@ -1330,13 +1330,13 @@
}
}
}
-
+
// Update current time if delay slots overflowed into later cycles.
// Do this here because we know exactly which cycle is the last cycle
// that contains delay slots. The next loop doesn't compute that.
if (nextTime > S.getTime())
S.updateTime(nextTime);
-
+
// Now put any remaining instructions in the unfilled delay slots.
// This could lead to suboptimal performance but needed for correctness.
nextSlot = delayedNodeSlotNum;
@@ -1361,7 +1361,7 @@
// Check if the instruction would conflict with instructions already
// chosen for the current cycle
-//
+//
static inline bool
ConflictsWithChoices(const SchedulingManager& S,
MachineOpCode opCode)
@@ -1370,10 +1370,10 @@
// choices have already been made for this cycle
if (S.getNumChoices() > 0 && S.schedInfo.isSingleIssue(opCode))
return true;
-
+
// For each class that opCode belongs to, check if there are too many
// instructions of that class.
- //
+ //
const InstrSchedClass sc = S.schedInfo.getSchedClass(opCode);
return (S.getNumChoicesInClass(sc) == S.schedInfo.getMaxIssueForClass(sc));
}
@@ -1384,7 +1384,7 @@
//---------------------------------------------------------------------------
// Function: ViolatesMinimumGap
-//
+//
// Purpose:
// Check minimum gap requirements relative to instructions scheduled in
// previous cycles.
@@ -1403,7 +1403,7 @@
//---------------------------------------------------------------------------
// Function: instrIsFeasible
-//
+//
// Purpose:
// Check if any issue restrictions would prevent the instruction from
// being issued in the current cycle
@@ -1417,18 +1417,18 @@
// caused by previously issued instructions
if (ViolatesMinimumGap(S, opCode, S.getTime()))
return false;
-
+
// skip the instruction if it cannot be issued due to issue restrictions
// caused by previously chosen instructions for the current cycle
if (ConflictsWithChoices(S, opCode))
return false;
-
+
return true;
}
//---------------------------------------------------------------------------
// Function: ScheduleInstructionsWithSSA
-//
+//
// Purpose:
// Entry point for instruction scheduling on SSA form.
// Schedules the machine instructions generated by instruction selection.
@@ -1443,13 +1443,13 @@
inline InstructionSchedulingWithSSA(const TargetMachine &T) : target(T) {}
const char *getPassName() const { return "Instruction Scheduling"; }
-
+
// getAnalysisUsage - We use LiveVarInfo...
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<FunctionLiveVarInfo>();
AU.setPreservesCFG();
}
-
+
bool runOnFunction(Function &F);
};
} // end anonymous namespace
@@ -1458,35 +1458,35 @@
bool InstructionSchedulingWithSSA::runOnFunction(Function &F)
{
SchedGraphSet graphSet(&F, target);
-
+
if (SchedDebugLevel >= Sched_PrintSchedGraphs) {
std::cerr << "\n*** SCHEDULING GRAPHS FOR INSTRUCTION SCHEDULING\n";
graphSet.dump();
}
-
+
for (SchedGraphSet::const_iterator GI=graphSet.begin(), GE=graphSet.end();
GI != GE; ++GI)
{
SchedGraph* graph = (*GI);
MachineBasicBlock &MBB = graph->getBasicBlock();
-
+
if (SchedDebugLevel >= Sched_PrintSchedTrace)
std::cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
-
+
// expensive!
SchedPriorities schedPrio(&F, graph, getAnalysis<FunctionLiveVarInfo>());
SchedulingManager S(target, graph, schedPrio);
-
+
ChooseInstructionsForDelaySlots(S, MBB, graph); // modifies graph
ForwardListSchedule(S); // computes schedule in S
RecordSchedule(MBB, S); // records schedule in BB
}
-
+
if (SchedDebugLevel >= Sched_PrintMachineCode) {
std::cerr << "\n*** Machine instructions after INSTRUCTION SCHEDULING\n";
MachineFunction::get(&F).dump();
}
-
+
return false;
}
Index: llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp
diff -u llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.68 llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.69
--- llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp:1.68 Fri Oct 8 13:30:22 2004
+++ llvm/lib/Target/SparcV9/InstrSched/SchedGraph.cpp Thu Apr 21 18:27:12 2005
@@ -1,10 +1,10 @@
//===- SchedGraph.cpp - Scheduling Graph Implementation -------------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// Scheduling graph based on SSA graph plus extra dependence edges capturing
@@ -31,7 +31,7 @@
// The following two types need to be classes, not typedefs, so we can use
// opaque declarations in SchedGraph.h
-//
+//
struct RefVec: public std::vector<std::pair<SchedGraphNode*, int> > {
typedef std::vector<std::pair<SchedGraphNode*,int> >::iterator iterator;
typedef
@@ -49,9 +49,9 @@
};
-//
+//
// class SchedGraphNode
-//
+//
SchedGraphNode::SchedGraphNode(unsigned NID, MachineBasicBlock *mbb,
int indexInBB, const TargetMachine& Target)
@@ -82,9 +82,9 @@
SchedGraphNode::~SchedGraphNode() {
}
-//
+//
// class SchedGraph
-//
+//
SchedGraph::SchedGraph(MachineBasicBlock &mbb, const TargetMachine& target)
: MBB(mbb) {
buildGraph(target);
@@ -124,7 +124,7 @@
void SchedGraph::addDummyEdges() {
assert(graphRoot->getNumOutEdges() == 0);
-
+
for (const_iterator I=begin(); I != end(); ++I) {
SchedGraphNode* node = (*I).second;
assert(node != graphRoot && node != graphLeaf);
@@ -142,9 +142,9 @@
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
MachineCodeForInstruction &termMvec = MachineCodeForInstruction::get(term);
-
+
// Find the first branch instr in the sequence of machine instrs for term
- //
+ //
unsigned first = 0;
while (! mii.isBranch(termMvec[first]->getOpcode()) &&
! mii.isReturn(termMvec[first]->getOpcode()))
@@ -153,18 +153,18 @@
"No branch instructions for terminator? Ok, but weird!");
if (first == termMvec.size())
return;
-
+
SchedGraphNode* firstBrNode = getGraphNodeForInstr(termMvec[first]);
-
+
// Add CD edges from each instruction in the sequence to the
- // *last preceding* branch instr. in the sequence
+ // *last preceding* branch instr. in the sequence
// Use a latency of 0 because we only need to prevent out-of-order issue.
- //
+ //
for (unsigned i = termMvec.size(); i > first+1; --i) {
SchedGraphNode* toNode = getGraphNodeForInstr(termMvec[i-1]);
assert(toNode && "No node for instr generated for branch/ret?");
-
- for (unsigned j = i-1; j != 0; --j)
+
+ for (unsigned j = i-1; j != 0; --j)
if (mii.isBranch(termMvec[j-1]->getOpcode()) ||
mii.isReturn(termMvec[j-1]->getOpcode())) {
SchedGraphNode* brNode = getGraphNodeForInstr(termMvec[j-1]);
@@ -174,36 +174,36 @@
break; // only one incoming edge is enough
}
}
-
+
// Add CD edges from each instruction preceding the first branch
// to the first branch. Use a latency of 0 as above.
- //
+ //
for (unsigned i = first; i != 0; --i) {
SchedGraphNode* fromNode = getGraphNodeForInstr(termMvec[i-1]);
assert(fromNode && "No node for instr generated for branch?");
(void) new SchedGraphEdge(fromNode, firstBrNode, SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
-
+
// Now add CD edges to the first branch instruction in the sequence from
// all preceding instructions in the basic block. Use 0 latency again.
- //
+ //
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I){
if (&*I == termMvec[first]) // reached the first branch
break;
-
+
SchedGraphNode* fromNode = getGraphNodeForInstr(I);
if (fromNode == NULL)
continue; // dummy instruction, e.g., PHI
-
+
(void) new SchedGraphEdge(fromNode, firstBrNode,
SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
-
+
// If we find any other machine instructions (other than due to
// the terminator) that also have delay slots, add an outgoing edge
// from the instruction to the instructions in the delay slots.
- //
+ //
unsigned d = mii.getNumDelaySlots(I->getOpcode());
MachineBasicBlock::iterator J = I; ++J;
@@ -239,14 +239,14 @@
// instructions, where at least one is a store or a call.
// Use latency 1 just to ensure that memory operations are ordered;
// latency does not otherwise matter (true dependences enforce that).
-//
+//
void SchedGraph::addMemEdges(const std::vector<SchedGraphNode*>& memNodeVec,
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
-
+
// Instructions in memNodeVec are in execution order within the basic block,
// so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
- //
+ //
for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++) {
MachineOpCode fromOpCode = memNodeVec[im]->getOpcode();
int fromType = (mii.isCall(fromOpCode)? SG_CALL_REF
@@ -257,28 +257,28 @@
int toType = (mii.isCall(toOpCode)? SG_CALL_REF
: (mii.isLoad(toOpCode)? SG_LOAD_REF
: SG_STORE_REF));
-
+
if (fromType != SG_LOAD_REF || toType != SG_LOAD_REF)
(void) new SchedGraphEdge(memNodeVec[im], memNodeVec[jm],
SchedGraphEdge::MemoryDep,
SG_DepOrderArray[fromType][toType], 1);
}
}
-}
+}
// Add edges from/to CC reg instrs to/from call instrs.
// Essentially this prevents anything that sets or uses a CC reg from being
// reordered w.r.t. a call.
// Use a latency of 0 because we only need to prevent out-of-order issue,
// like with control dependences.
-//
+//
void SchedGraph::addCallDepEdges(const std::vector<SchedGraphNode*>& callDepNodeVec,
const TargetMachine& target) {
const TargetInstrInfo& mii = *target.getInstrInfo();
-
+
// Instructions in memNodeVec are in execution order within the basic block,
// so simply look at all pairs <memNodeVec[i], memNodeVec[j: j > i]>.
- //
+ //
for (unsigned ic=0, NC=callDepNodeVec.size(); ic < NC; ic++)
if (mii.isCall(callDepNodeVec[ic]->getOpcode())) {
// Add SG_CALL_REF edges from all preds to this instruction.
@@ -286,26 +286,26 @@
(void) new SchedGraphEdge(callDepNodeVec[jc], callDepNodeVec[ic],
SchedGraphEdge::MachineRegister,
MachineIntRegsRID, 0);
-
+
// And do the same from this instruction to all successors.
for (unsigned jc=ic+1; jc < NC; jc++)
(void) new SchedGraphEdge(callDepNodeVec[ic], callDepNodeVec[jc],
SchedGraphEdge::MachineRegister,
MachineIntRegsRID, 0);
}
-
+
#ifdef CALL_DEP_NODE_VEC_CANNOT_WORK
// Find the call instruction nodes and put them in a vector.
std::vector<SchedGraphNode*> callNodeVec;
for (unsigned im=0, NM=memNodeVec.size(); im < NM; im++)
if (mii.isCall(memNodeVec[im]->getOpcode()))
callNodeVec.push_back(memNodeVec[im]);
-
+
// Now walk the entire basic block, looking for CC instructions *and*
// call instructions, and keep track of the order of the instructions.
// Use the call node vec to quickly find earlier and later call nodes
// relative to the current CC instruction.
- //
+ //
int lastCallNodeIdx = -1;
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
if (mii.isCall(bbMvec[i]->getOpcode())) {
@@ -334,12 +334,12 @@
const TargetMachine& target) {
// This code assumes that two registers with different numbers are
// not aliased!
- //
+ //
for (RegToRefVecMap::iterator I = regToRefVecMap.begin();
I != regToRefVecMap.end(); ++I) {
int regNum = (*I).first;
RefVec& regRefVec = (*I).second;
-
+
// regRefVec is ordered by control flow order in the basic block
for (unsigned i=0; i < regRefVec.size(); ++i) {
SchedGraphNode* node = regRefVec[i].first;
@@ -348,7 +348,7 @@
node->getMachineInstr()->getExplOrImplOperand(opNum);
bool isDef = mop.isDef() && !mop.isUse();
bool isDefAndUse = mop.isDef() && mop.isUse();
-
+
for (unsigned p=0; p < i; ++p) {
SchedGraphNode* prevNode = regRefVec[p].first;
if (prevNode != node) {
@@ -365,7 +365,7 @@
new SchedGraphEdge(prevNode, node, regNum,
SchedGraphEdge::AntiDep);
}
-
+
if (prevIsDef)
if (!isDef || isDefAndUse)
new SchedGraphEdge(prevNode, node, regNum,
@@ -380,7 +380,7 @@
// 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 SchedGraph::addEdgesForValue(SchedGraphNode* refNode,
const RefVec& defVec,
const Value* defValue,
@@ -392,7 +392,7 @@
for (RefVec::const_iterator I=defVec.begin(), E=defVec.end(); I != E; ++I) {
if ((*I).first == refNode)
continue; // Dont add any self-loops
-
+
if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) {
// (*).first is before refNode
if (refNodeIsDef && !refNodeIsUse)
@@ -420,9 +420,9 @@
SchedGraphNode* node = getGraphNodeForInstr(&MI);
if (node == NULL)
return;
-
+
// Add edges for all operands of the machine instruction.
- //
+ //
for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i) {
switch (MI.getOperand(i).getType()) {
case MachineOperand::MO_VirtualRegister:
@@ -435,26 +435,26 @@
target);
}
break;
-
+
case MachineOperand::MO_MachineRegister:
- break;
-
+ break;
+
case MachineOperand::MO_SignExtendedImmed:
case MachineOperand::MO_UnextendedImmed:
case MachineOperand::MO_PCRelativeDisp:
case MachineOperand::MO_ConstantPoolIndex:
break; // nothing to do for immediate fields
-
+
default:
assert(0 && "Unknown machine operand type in SchedGraph builder");
break;
}
}
-
+
// Add edges for values implicitly used by the machine instruction.
// Examples include function arguments to a Call instructions or the return
// value of a Ret instruction.
- //
+ //
for (unsigned i=0, N=MI.getNumImplicitRefs(); i < N; ++i)
if (MI.getImplicitOp(i).isUse())
if (const Value* srcI = MI.getImplicitRef(i)) {
@@ -474,26 +474,26 @@
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap) {
const TargetInstrInfo& mii = *target.getInstrInfo();
-
+
MachineOpCode opCode = node->getOpcode();
-
+
if (mii.isCall(opCode) || mii.isCCInstr(opCode))
callDepNodeVec.push_back(node);
-
+
if (mii.isLoad(opCode) || mii.isStore(opCode) || mii.isCall(opCode))
memNodeVec.push_back(node);
-
+
// Collect the register references and value defs. for explicit operands
- //
+ //
const MachineInstr& MI = *node->getMachineInstr();
for (int i=0, numOps = (int) MI.getNumOperands(); i < numOps; i++) {
const MachineOperand& mop = MI.getOperand(i);
-
+
// if this references a register other than the hardwired
// "zero" register, record the reference.
if (mop.hasAllocatedReg()) {
unsigned regNum = mop.getReg();
-
+
// If this is not a dummy zero register, record the reference in order
if (regNum != target.getRegInfo()->getZeroRegNum())
regToRefVecMap[mop.getReg()]
@@ -509,27 +509,27 @@
->isRegVolatile(regInClass))
callDepNodeVec.push_back(node);
}
-
+
continue; // nothing more to do
}
-
+
// ignore all other non-def operands
if (!MI.getOperand(i).isDef())
continue;
-
+
// We must be defining a value.
assert((mop.getType() == MachineOperand::MO_VirtualRegister ||
mop.getType() == MachineOperand::MO_CCRegister)
&& "Do not expect any other kind of operand to be defined!");
assert(mop.getVRegValue() != NULL && "Null value being defined?");
-
- valueToDefVecMap[mop.getVRegValue()].push_back(std::make_pair(node, i));
+
+ valueToDefVecMap[mop.getVRegValue()].push_back(std::make_pair(node, i));
}
-
- //
+
+ //
// Collect value defs. for implicit operands. They may have allocated
// physical registers also.
- //
+ //
for (unsigned i=0, N = MI.getNumImplicitRefs(); i != N; ++i) {
const MachineOperand& mop = MI.getImplicitOp(i);
if (mop.hasAllocatedReg()) {
@@ -543,7 +543,7 @@
if (mop.isDef()) {
assert(MI.getImplicitRef(i) != NULL && "Null value being defined?");
valueToDefVecMap[MI.getImplicitRef(i)].push_back(
- std::make_pair(node, -i));
+ std::make_pair(node, -i));
}
}
}
@@ -556,7 +556,7 @@
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap) {
const TargetInstrInfo& mii = *target.getInstrInfo();
-
+
// Build graph nodes for each VM instruction and gather def/use info.
// Do both those together in a single pass over all machine instructions.
unsigned i = 0;
@@ -565,7 +565,7 @@
if (I->getOpcode() != V9::PHI) {
SchedGraphNode* node = new SchedGraphNode(getNumNodes(), &MBB, i, target);
noteGraphNodeForInstr(I, node);
-
+
// Remember all register references and value defs
findDefUseInfoAtInstr(target, node, memNodeVec, callDepNodeVec,
regToRefVecMap, valueToDefVecMap);
@@ -575,11 +575,11 @@
void SchedGraph::buildGraph(const TargetMachine& target) {
// Use this data structure to note all machine operands that compute
- // ordinary LLVM values. These must be computed defs (i.e., instructions).
+ // ordinary LLVM values. These must be computed defs (i.e., instructions).
// Note that there may be multiple machine instructions that define
// each Value.
ValueToDefVecMap valueToDefVecMap;
-
+
// Use this data structure to note all memory instructions.
// We use this to add memory dependence edges without a second full walk.
std::vector<SchedGraphNode*> memNodeVec;
@@ -587,7 +587,7 @@
// Use this data structure to note all instructions that access physical
// registers that can be modified by a call (including call instructions)
std::vector<SchedGraphNode*> callDepNodeVec;
-
+
// Use this data structure to note any uses or definitions of
// machine registers so we can add edges for those later without
// extra passes over the nodes.
@@ -595,9 +595,9 @@
// ordered according to control-flow order. This only works for a
// single basic block, hence the assertion. Each reference is identified
// by the pair: <node, operand-number>.
- //
+ //
RegToRefVecMap regToRefVecMap;
-
+
// Make a dummy root node. We'll add edges to the real roots later.
graphRoot = new SchedGraphNode(0, NULL, -1, target);
graphLeaf = new SchedGraphNode(1, NULL, -1, target);
@@ -611,7 +611,7 @@
buildNodesForBB(target, MBB, memNodeVec, callDepNodeVec,
regToRefVecMap, valueToDefVecMap);
-
+
//----------------------------------------------------------------
// Now add edges for the following (all are incoming edges except (4)):
// (1) operands of the machine instruction, including hidden operands
@@ -625,19 +625,19 @@
// 2-way conditional branches, multiple CD edges are needed
// (see addCDEdges for details).
// Also, note any uses or defs of machine registers.
- //
+ //
//----------------------------------------------------------------
-
+
// First, add edges to the terminator instruction of the basic block.
this->addCDEdges(MBB.getBasicBlock()->getTerminator(), target);
-
+
// Then add memory dep edges: store->load, load->store, and store->store.
// Call instructions are treated as both load and store.
this->addMemEdges(memNodeVec, target);
// Then add edges between call instructions and CC set/use instructions
this->addCallDepEdges(callDepNodeVec, target);
-
+
// Then add incoming def-use (SSA) edges for each machine instruction.
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ++I)
addEdgesForInstruction(*I, valueToDefVecMap, target);
@@ -650,9 +650,9 @@
}
-//
+//
// class SchedGraphSet
-//
+//
SchedGraphSet::SchedGraphSet(const Function* _function,
const TargetMachine& target) :
function(_function) {
@@ -669,10 +669,10 @@
void SchedGraphSet::dump() const {
std::cerr << "======== Sched graphs for function `" << function->getName()
<< "' ========\n\n";
-
+
for (const_iterator I=begin(); I != end(); ++I)
(*I)->dump();
-
+
std::cerr << "\n====== End graphs for function `" << function->getName()
<< "' ========\n\n";
}
@@ -689,28 +689,28 @@
void SchedGraphEdge::print(std::ostream &os) const {
os << "edge [" << src->getNodeId() << "] -> ["
<< sink->getNodeId() << "] : ";
-
+
switch(depType) {
case SchedGraphEdge::CtrlDep:
- os<< "Control Dep";
+ os<< "Control Dep";
break;
- case SchedGraphEdge::ValueDep:
- os<< "Reg Value " << *val;
+ case SchedGraphEdge::ValueDep:
+ os<< "Reg Value " << *val;
break;
case SchedGraphEdge::MemoryDep:
- os<< "Memory Dep";
+ os<< "Memory Dep";
break;
- case SchedGraphEdge::MachineRegister:
+ case SchedGraphEdge::MachineRegister:
os<< "Reg " << machineRegNum;
break;
case SchedGraphEdge::MachineResource:
os<<"Resource "<< resourceId;
break;
- default:
- assert(0);
+ default:
+ assert(0);
break;
}
-
+
os << " : delay = " << minDelay << "\n";
}
@@ -718,7 +718,7 @@
os << std::string(8, ' ')
<< "Node " << ID << " : "
<< "latency = " << latency << "\n" << std::string(12, ' ');
-
+
if (getMachineInstr() == NULL)
os << "(Dummy node)\n";
else {
@@ -726,7 +726,7 @@
os << inEdges.size() << " Incoming Edges:\n";
for (unsigned i=0, N = inEdges.size(); i < N; i++)
os << std::string(16, ' ') << *inEdges[i];
-
+
os << std::string(12, ' ') << outEdges.size()
<< " Outgoing Edges:\n";
for (unsigned i=0, N= outEdges.size(); i < N; i++)
Index: llvm/lib/Target/SparcV9/InstrSched/SchedGraph.h
diff -u llvm/lib/Target/SparcV9/InstrSched/SchedGraph.h:1.40 llvm/lib/Target/SparcV9/InstrSched/SchedGraph.h:1.41
--- llvm/lib/Target/SparcV9/InstrSched/SchedGraph.h:1.40 Wed Sep 1 17:55:35 2004
+++ llvm/lib/Target/SparcV9/InstrSched/SchedGraph.h Thu Apr 21 18:27:12 2005
@@ -1,19 +1,19 @@
//===-- SchedGraph.h - Scheduling Graph -------------------------*- C++ -*-===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// This is a scheduling graph based on SSA graph plus extra dependence edges
// capturing dependences due to machine resources (machine registers, CC
// registers, and any others).
-//
+//
// This graph tries to leverage the SSA graph as much as possible, but captures
// the extra dependences through a common interface.
-//
+//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CODEGEN_SCHEDGRAPH_H
@@ -37,7 +37,7 @@
const MachineInstr *MI;
- SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
+ SchedGraphNode(unsigned nodeId, MachineBasicBlock *mbb, int indexInBB,
const TargetMachine& Target);
~SchedGraphNode();
@@ -58,21 +58,21 @@
class SchedGraph : public SchedGraphCommon {
MachineBasicBlock &MBB;
hash_map<const MachineInstr*, SchedGraphNode*> GraphMap;
-
+
public:
typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator iterator;
typedef hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator const_iterator;
-
+
MachineBasicBlock& getBasicBlock() const{return MBB;}
const unsigned int getNumNodes() const { return GraphMap.size()+2; }
SchedGraphNode* getGraphNodeForInstr(const MachineInstr* MI) const {
const_iterator onePair = find(MI);
return (onePair != end())? onePair->second : NULL;
}
-
+
// Debugging support
void dump() const;
-
+
protected:
SchedGraph(MachineBasicBlock& mbb, const TargetMachine& TM);
~SchedGraph();
@@ -86,17 +86,17 @@
hash_map<const MachineInstr*, SchedGraphNode*>::const_iterator end() const {
return GraphMap.end();
}
-
+
unsigned size() { return GraphMap.size(); }
iterator find(const MachineInstr *MI) const { return GraphMap.find(MI); }
-
+
SchedGraphNode *&operator[](const MachineInstr *MI) {
return GraphMap[MI];
}
-
+
private:
friend class SchedGraphSet; // give access to ctor
-
+
inline void noteGraphNodeForInstr (const MachineInstr* minstr,
SchedGraphNode* node) {
assert((*this)[minstr] == NULL);
@@ -107,39 +107,39 @@
// Graph builder
//
void buildGraph(const TargetMachine& target);
-
+
void buildNodesForBB(const TargetMachine& target,MachineBasicBlock &MBB,
std::vector<SchedGraphNode*>& memNV,
std::vector<SchedGraphNode*>& callNV,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
-
+
void findDefUseInfoAtInstr(const TargetMachine& target, SchedGraphNode* node,
std::vector<SchedGraphNode*>& memNV,
std::vector<SchedGraphNode*>& callNV,
RegToRefVecMap& regToRefVecMap,
ValueToDefVecMap& valueToDefVecMap);
-
+
void addEdgesForInstruction(const MachineInstr& minstr,
const ValueToDefVecMap& valueToDefVecMap,
const TargetMachine& target);
-
+
void addCDEdges(const TerminatorInst* term, const TargetMachine& target);
-
+
void addMemEdges(const std::vector<SchedGraphNode*>& memNod,
const TargetMachine& target);
-
+
void addCallCCEdges(const std::vector<SchedGraphNode*>& memNod,
MachineBasicBlock& bbMvec,
const TargetMachine& target);
void addCallDepEdges(const std::vector<SchedGraphNode*>& callNV,
const TargetMachine& target);
-
+
void addMachineRegEdges(RegToRefVecMap& regToRefVecMap,
const TargetMachine& target);
-
+
void addEdgesForValue(SchedGraphNode* refNode, const RefVec& defVec,
const Value* defValue, bool refNodeIsDef,
bool refNodeIsDefAndUse,
@@ -161,12 +161,12 @@
inline void addGraph(SchedGraph* graph) {
assert(graph != NULL);
Graphs.push_back(graph);
- }
+ }
public:
SchedGraphSet(const Function *function, const TargetMachine& target);
~SchedGraphSet();
-
+
//iterators
typedef std::vector<SchedGraph*>::const_iterator iterator;
typedef std::vector<SchedGraph*>::const_iterator const_iterator;
@@ -181,7 +181,7 @@
-//
+//
// sg_pred_iterator
// sg_pred_const_iterator
//
@@ -204,7 +204,7 @@
}
-//
+//
// sg_succ_iterator
// sg_succ_const_iterator
//
@@ -234,10 +234,10 @@
typedef sg_succ_iterator ChildIteratorType;
static inline NodeType *getEntryNode(SchedGraph *SG) { return (NodeType*)SG->getRoot(); }
- static inline ChildIteratorType child_begin(NodeType *N) {
- return succ_begin(N);
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
}
- static inline ChildIteratorType child_end(NodeType *N) {
+ static inline ChildIteratorType child_end(NodeType *N) {
return succ_end(N);
}
};
@@ -249,10 +249,10 @@
static inline NodeType *getEntryNode(const SchedGraph *SG) {
return (NodeType*)SG->getRoot();
}
- static inline ChildIteratorType child_begin(NodeType *N) {
- return succ_begin(N);
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return succ_begin(N);
}
- static inline ChildIteratorType child_end(NodeType *N) {
+ static inline ChildIteratorType child_end(NodeType *N) {
return succ_end(N);
}
};
Index: llvm/lib/Target/SparcV9/InstrSched/SchedGraphCommon.cpp
diff -u llvm/lib/Target/SparcV9/InstrSched/SchedGraphCommon.cpp:1.8 llvm/lib/Target/SparcV9/InstrSched/SchedGraphCommon.cpp:1.9
--- llvm/lib/Target/SparcV9/InstrSched/SchedGraphCommon.cpp:1.8 Tue Sep 28 09:42:44 2004
+++ llvm/lib/Target/SparcV9/InstrSched/SchedGraphCommon.cpp Thu Apr 21 18:27:12 2005
@@ -1,10 +1,10 @@
//===- SchedGraphCommon.cpp - Scheduling Graphs Base Class- ---------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
//
// Scheduling graph base class that contains common information for SchedGraph
@@ -23,7 +23,7 @@
//
// class SchedGraphEdge
-//
+//
SchedGraphEdge::SchedGraphEdge(SchedGraphNodeCommon* _src,
SchedGraphNodeCommon* _sink,
SchedGraphEdgeDepType _depType,
@@ -31,7 +31,7 @@
int _minDelay)
: src(_src), sink(_sink), depType(_depType), depOrderType(_depOrderType),
minDelay((_minDelay >= 0)? _minDelay : _src->getLatency()), val(NULL) {
-
+
iteDiff=0;
assert(src != sink && "Self-loop in scheduling graph!");
src->addOutEdge(this);
@@ -81,7 +81,7 @@
void SchedGraphEdge::dump(int indent) const {
- std::cerr << std::string(indent*2, ' ') << *this;
+ std::cerr << std::string(indent*2, ' ') << *this;
}
/*dtor*/
@@ -94,7 +94,7 @@
void SchedGraphNodeCommon::removeInEdge(const SchedGraphEdge* edge) {
assert(edge->getSink() == this);
-
+
for (iterator I = beginInEdges(); I != endInEdges(); ++I)
if ((*I) == edge) {
inEdges.erase(I);
@@ -104,7 +104,7 @@
void SchedGraphNodeCommon::removeOutEdge(const SchedGraphEdge* edge) {
assert(edge->getSrc() == this);
-
+
for (iterator I = beginOutEdges(); I != endOutEdges(); ++I)
if ((*I) == edge) {
outEdges.erase(I);
@@ -113,7 +113,7 @@
}
void SchedGraphNodeCommon::dump(int indent) const {
- std::cerr << std::string(indent*2, ' ') << *this;
+ std::cerr << std::string(indent*2, ' ') << *this;
}
//class SchedGraphCommon
@@ -124,7 +124,7 @@
}
-void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
+void SchedGraphCommon::eraseIncomingEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
// Delete and disconnect all in-edges for the node
for (SchedGraphNodeCommon::iterator I = node->beginInEdges();
@@ -132,22 +132,22 @@
SchedGraphNodeCommon* srcNode = (*I)->getSrc();
srcNode->removeOutEdge(*I);
delete *I;
-
+
if (addDummyEdges && srcNode != getRoot() &&
- srcNode->beginOutEdges() == srcNode->endOutEdges()) {
-
+ srcNode->beginOutEdges() == srcNode->endOutEdges()) {
+
// srcNode has no more out edges, so add an edge to dummy EXIT node
assert(node != getLeaf() && "Adding edge that was just removed?");
(void) new SchedGraphEdge(srcNode, getLeaf(),
- SchedGraphEdge::CtrlDep,
+ SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
}
-
+
node->inEdges.clear();
}
-void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
+void SchedGraphCommon::eraseOutgoingEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
// Delete and disconnect all out-edges for the node
for (SchedGraphNodeCommon::iterator I = node->beginOutEdges();
@@ -155,23 +155,23 @@
SchedGraphNodeCommon* sinkNode = (*I)->getSink();
sinkNode->removeInEdge(*I);
delete *I;
-
+
if (addDummyEdges &&
sinkNode != getLeaf() &&
sinkNode->beginInEdges() == sinkNode->endInEdges()) {
-
+
//sinkNode has no more in edges, so add an edge from dummy ENTRY node
assert(node != getRoot() && "Adding edge that was just removed?");
(void) new SchedGraphEdge(getRoot(), sinkNode,
- SchedGraphEdge::CtrlDep,
+ SchedGraphEdge::CtrlDep,
SchedGraphEdge::NonDataDep, 0);
}
}
-
+
node->outEdges.clear();
}
-void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
+void SchedGraphCommon::eraseIncidentEdges(SchedGraphNodeCommon* node,
bool addDummyEdges) {
this->eraseIncomingEdges(node, addDummyEdges);
this->eraseOutgoingEdges(node, addDummyEdges);
Index: llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.cpp
diff -u llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.cpp:1.36 llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.cpp:1.37
--- llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.cpp:1.36 Sat Jan 15 22:20:30 2005
+++ llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.cpp Thu Apr 21 18:27:12 2005
@@ -1,12 +1,12 @@
//===-- SchedPriorities.h - Encapsulate scheduling heuristics -------------===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
-//
+//
// Strategy:
// Priority ordering rules:
// (1) Max delay, which is the order of the heap S.candsAsHeap.
@@ -76,23 +76,23 @@
SchedPriorities::initializeReadyHeap(const SchedGraph* graph) {
const SchedGraphNode* graphRoot = (const SchedGraphNode*)graph->getRoot();
assert(graphRoot->getMachineInstr() == NULL && "Expect dummy root");
-
+
// Insert immediate successors of dummy root, which are the actual roots
sg_succ_const_iterator SEnd = succ_end(graphRoot);
for (sg_succ_const_iterator S = succ_begin(graphRoot); S != SEnd; ++S)
this->insertReady(*S);
-
+
#undef TEST_HEAP_CONVERSION
#ifdef TEST_HEAP_CONVERSION
std::cerr << "Before heap conversion:\n";
copy(candsAsHeap.begin(), candsAsHeap.end(),
ostream_iterator<NodeDelayPair*>(std::cerr,"\n"));
#endif
-
+
candsAsHeap.makeHeap();
-
+
nextToTry = candsAsHeap.begin();
-
+
#ifdef TEST_HEAP_CONVERSION
std::cerr << "After heap conversion:\n";
copy(candsAsHeap.begin(), candsAsHeap.end(),
@@ -107,7 +107,7 @@
mcands.clear(); // ensure reset choices is called before any more choices
earliestReadyTime = std::min(earliestReadyTime,
getEarliestReadyTimeForNode(node));
-
+
if (SchedDebugLevel >= Sched_PrintSchedTrace) {
std::cerr << " Node " << node->getNodeId() << " will be ready in Cycle "
<< getEarliestReadyTimeForNode(node) << "; "
@@ -122,26 +122,26 @@
candsAsHeap.removeNode(node);
candsAsSet.erase(node);
mcands.clear(); // ensure reset choices is called before any more choices
-
+
if (earliestReadyTime == getEarliestReadyTimeForNode(node)) {
// earliestReadyTime may have been due to this node, so recompute it
earliestReadyTime = HUGE_LATENCY;
for (NodeHeap::const_iterator I=candsAsHeap.begin();
I != candsAsHeap.end(); ++I)
if (candsAsHeap.getNode(I)) {
- earliestReadyTime =
- std::min(earliestReadyTime,
+ earliestReadyTime =
+ std::min(earliestReadyTime,
getEarliestReadyTimeForNode(candsAsHeap.getNode(I)));
}
}
-
+
// Now update ready times for successors
for (SchedGraphNode::const_iterator E=node->beginOutEdges();
E != node->endOutEdges(); ++E) {
CycleCount_t& etime =
getEarliestReadyTimeForNodeRef((SchedGraphNode*)(*E)->getSink());
etime = std::max(etime, curTime + (*E)->getMinDelay());
- }
+ }
}
@@ -182,7 +182,7 @@
indexWithMaxUses = i;
}
}
- return indexWithMaxUses;
+ return indexWithMaxUses;
}
const SchedGraphNode*
@@ -190,22 +190,22 @@
CycleCount_t curTime) {
int nextIdx = -1;
const SchedGraphNode* nextChoice = NULL;
-
+
if (mcands.size() == 0)
findSetWithMaxDelay(mcands, S);
-
+
while (nextIdx < 0 && mcands.size() > 0) {
nextIdx = chooseByRule1(mcands); // rule 1
-
+
if (nextIdx == -1)
nextIdx = chooseByRule2(mcands); // rule 2
-
+
if (nextIdx == -1)
nextIdx = chooseByRule3(mcands); // rule 3
-
+
if (nextIdx == -1)
nextIdx = 0; // default to first choice by delays
-
+
// We have found the next best candidate. Check if it ready in
// the current cycle, and if it is feasible.
// If not, remove it from mcands and continue. Refill mcands if
@@ -220,7 +220,7 @@
findSetWithMaxDelay(mcands, S);
}
}
-
+
if (nextIdx >= 0) {
mcands.erase(mcands.begin() + nextIdx);
return nextChoice;
@@ -241,9 +241,9 @@
for (; next != candsAsHeap.end()
&& candsAsHeap.getDelay(next) == maxDelay; ++next)
mcands.push_back(next);
-
+
nextToTry = next;
-
+
if (SchedDebugLevel >= Sched_PrintSchedTrace) {
std::cerr << " Cycle " << (long)getTime() << ": "
<< "Next highest delay = " << (long)maxDelay << " : "
@@ -260,17 +260,17 @@
SchedPriorities::instructionHasLastUse(FunctionLiveVarInfo &LVI,
const SchedGraphNode* graphNode) {
const MachineInstr *MI = graphNode->getMachineInstr();
-
+
hash_map<const MachineInstr*, bool>::const_iterator
ui = lastUseMap.find(MI);
if (ui != lastUseMap.end())
return ui->second;
-
+
// else check if instruction is a last use and save it in the hash_map
bool hasLastUse = false;
const BasicBlock* bb = graphNode->getMachineBasicBlock().getBasicBlock();
const ValueSet &LVs = LVI.getLiveVarSetBeforeMInst(MI, bb);
-
+
for (MachineInstr::const_val_op_iterator OI = MI->begin(), OE = MI->end();
OI != OE; ++OI)
if (!LVs.count(*OI)) {
Index: llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.h
diff -u llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.h:1.28 llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.h:1.29
--- llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.h:1.28 Sat Jan 15 22:20:30 2005
+++ llvm/lib/Target/SparcV9/InstrSched/SchedPriorities.h Thu Apr 21 18:27:12 2005
@@ -1,12 +1,12 @@
//===-- SchedPriorities.h - Encapsulate scheduling heuristics --*- C++ -*--===//
-//
+//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
-//
+//
//===----------------------------------------------------------------------===//
-//
+//
// Strategy:
// Priority ordering rules:
// (1) Max delay, which is the order of the heap S.candsAsHeap.
@@ -39,7 +39,7 @@
enum SchedDebugLevel_t {
Sched_NoDebugInfo,
Sched_Disable,
- Sched_PrintMachineCode,
+ Sched_PrintMachineCode,
Sched_PrintSchedTrace,
Sched_PrintSchedGraphs,
};
@@ -48,7 +48,7 @@
//---------------------------------------------------------------------------
// Function: instrIsFeasible
-//
+//
// Purpose:
// Used by the priority analysis to filter out instructions
// that are not feasible to issue in the current cycle.
@@ -78,26 +78,26 @@
public:
typedef std::list<NodeDelayPair*>::iterator iterator;
typedef std::list<NodeDelayPair*>::const_iterator const_iterator;
-
+
public:
NodeHeap() : _size(0) {}
-
+
inline unsigned size() const { return _size; }
-
+
const SchedGraphNode* getNode (const_iterator i) const { return (*i)->node; }
CycleCount_t getDelay(const_iterator i) const { return (*i)->delay;}
-
- inline void makeHeap() {
+
+ inline void makeHeap() {
// make_heap(begin(), end(), NDPLessThan);
}
-
+
inline iterator findNode(const SchedGraphNode* node) {
for (iterator I=begin(); I != end(); ++I)
if (getNode(I) == node)
return I;
return end();
}
-
+
inline void removeNode (const SchedGraphNode* node) {
iterator ndpPtr = findNode(node);
if (ndpPtr != end())
@@ -107,7 +107,7 @@
--_size;
}
};
-
+
void insert(const SchedGraphNode* node, CycleCount_t delay) {
NodeDelayPair* ndp = new NodeDelayPair(node, delay);
if (_size == 0 || front()->delay < delay)
@@ -132,32 +132,32 @@
public:
SchedPriorities(const Function *F, const SchedGraph *G,
FunctionLiveVarInfo &LVI);
-
-
+
+
// This must be called before scheduling begins.
void initialize ();
-
+
CycleCount_t getTime () const { return curTime; }
CycleCount_t getEarliestReadyTime () const { return earliestReadyTime; }
unsigned getNumReady () const { return candsAsHeap.size(); }
bool nodeIsReady (const SchedGraphNode* node) const {
return (candsAsSet.find(node) != candsAsSet.end());
}
-
+
void issuedReadyNodeAt (CycleCount_t curTime,
const SchedGraphNode* node);
-
+
void insertReady (const SchedGraphNode* node);
-
+
void updateTime (CycleCount_t /*unused*/);
-
+
const SchedGraphNode* getNextHighest (const SchedulingManager& S,
CycleCount_t curTime);
// choose next highest priority instr
-
+
private:
typedef NodeHeap::iterator candIndex;
-
+
private:
CycleCount_t curTime;
const SchedGraph* graph;
@@ -173,21 +173,21 @@
std::vector<candIndex> mcands; // holds pointers into cands
candIndex nextToTry; // next cand after the last
// one tried in this cycle
-
+
int chooseByRule1 (std::vector<candIndex>& mcands);
int chooseByRule2 (std::vector<candIndex>& mcands);
int chooseByRule3 (std::vector<candIndex>& mcands);
-
+
void findSetWithMaxDelay (std::vector<candIndex>& mcands,
const SchedulingManager& S);
-
+
void computeDelays (const SchedGraph* graph);
-
+
void initializeReadyHeap (const SchedGraph* graph);
-
+
bool instructionHasLastUse (FunctionLiveVarInfo& LVI,
const SchedGraphNode* graphNode);
-
+
// NOTE: The next two return references to the actual vector entries.
// Use the following two if you don't need to modify the value.
CycleCount_t& getNodeDelayRef (const SchedGraphNode* node) {
@@ -198,9 +198,9 @@
assert(node->getNodeId() < earliestReadyTimeForNode.size());
return earliestReadyTimeForNode[node->getNodeId()];
}
-
+
CycleCount_t getNodeDelay (const SchedGraphNode* node) const {
- return ((SchedPriorities*) this)->getNodeDelayRef(node);
+ return ((SchedPriorities*) this)->getNodeDelayRef(node);
}
CycleCount_t getEarliestReadyTimeForNode(const SchedGraphNode* node) const {
return ((SchedPriorities*) this)->getEarliestReadyTimeForNodeRef(node);
More information about the llvm-commits
mailing list