[llvm-commits] CVS: llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp SchedGraph.cpp
Misha Brukman
brukman at cs.uiuc.edu
Thu May 22 16:50:01 PDT 2003
Changes in directory llvm/lib/CodeGen/InstrSched:
InstrScheduling.cpp updated: 1.52 -> 1.53
SchedGraph.cpp updated: 1.42 -> 1.43
---
Log message:
Cleaned up code layout. No functional changes.
---
Diffs of the changes:
Index: llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp
diff -u llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.52 llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.53
--- llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp:1.52 Thu May 22 16:24:35 2003
+++ llvm/lib/CodeGen/InstrSched/InstrScheduling.cpp Thu May 22 16:49:18 2003
@@ -221,16 +221,15 @@
while (cycleNum < S.groups.size() &&
(*S.groups[cycleNum])[slotNum] == NULL)
- {
- ++slotNum;
- if (slotNum == S.nslots)
- {
- ++cycleNum;
- slotNum = 0;
- while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
- ++cycleNum; // skip cycles with no instructions
- }
+ {
+ ++slotNum;
+ if (slotNum == S.nslots) {
+ ++cycleNum;
+ slotNum = 0;
+ while(cycleNum < S.groups.size() && S.groups[cycleNum] == NULL)
+ ++cycleNum; // skip cycles with no instructions
}
+ }
}
template<class _NodeType>
@@ -239,11 +238,10 @@
ScheduleIterator<_NodeType>::operator++() // Preincrement
{
++slotNum;
- if (slotNum == S.nslots)
- {
- ++cycleNum;
- slotNum = 0;
- }
+ if (slotNum == S.nslots) {
+ ++cycleNum;
+ slotNum = 0;
+ }
skipToNextInstr();
return *this;
}
@@ -574,11 +572,11 @@
// If only one instruction can be issued, do so.
if (maxIssue == 1)
for (unsigned s=startSlot; s < S.nslots; s++)
- if (S.getChoicesForSlot(s).size() > 0)
- {// found the one instruction
- S.scheduleInstr(*S.getChoicesForSlot(s).begin(), s, curTime);
- return;
- }
+ if (S.getChoicesForSlot(s).size() > 0) {
+ // found the one instruction
+ S.scheduleInstr(*S.getChoicesForSlot(s).begin(), s, curTime);
+ return;
+ }
// Otherwise, choose from the choices for each slot
//
@@ -589,31 +587,28 @@
// 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).
unsigned numIssued;
- for (numIssued = 0; numIssued < maxIssue; numIssued++)
- {
- int chosenSlot = -1;
+ for (numIssued = 0; numIssued < maxIssue; numIssued++) {
+ int chosenSlot = -1;
+ for (unsigned s=startSlot; s < S.nslots; s++)
+ if ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() == 1) {
+ chosenSlot = (int) s;
+ break;
+ }
+
+ if (chosenSlot == -1)
for (unsigned s=startSlot; s < S.nslots; s++)
- if ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() == 1)
- {
- 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.
- const SchedGraphNode* node= *S.getChoicesForSlot(chosenSlot).begin();
- S.scheduleInstr(node, chosenSlot, curTime);
- }
+ 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.
+ const SchedGraphNode* node= *S.getChoicesForSlot(chosenSlot).begin();
+ S.scheduleInstr(node, chosenSlot, curTime);
}
+ }
assert(numIssued > 0 && "Should not happen when maxIssue > 0!");
}
@@ -673,20 +668,19 @@
if (! (*SI)->isDummyNode()
&& ! S.isScheduled(*SI)
&& ! S.schedPrio.nodeIsReady(*SI))
- {// successor not scheduled and not marked ready; check *its* preds.
+ {
+ // successor not scheduled and not marked ready; check *its* preds.
- bool succIsReady = true;
- for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P)
- if (! (*P)->isDummyNode()
- && ! S.isScheduled(*P))
- {
- succIsReady = false;
- break;
- }
+ bool succIsReady = true;
+ for (sg_pred_const_iterator P=pred_begin(*SI); P != pred_end(*SI); ++P)
+ if (! (*P)->isDummyNode() && ! S.isScheduled(*P)) {
+ succIsReady = false;
+ break;
+ }
- if (succIsReady) // add the successor to the ready list
- S.schedPrio.insertReady(*SI);
- }
+ if (succIsReady) // add the successor to the ready list
+ S.schedPrio.insertReady(*SI);
+ }
}
@@ -710,11 +704,10 @@
unsigned int startSlot = 0;
InstrGroup* igroup = S.isched.getIGroup(S.getTime());
for (int s = S.nslots - 1; s >= 0; s--)
- if ((*igroup)[s] != NULL)
- {
- startSlot = s+1;
- break;
- }
+ if ((*igroup)[s] != NULL) {
+ 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.
@@ -729,49 +722,42 @@
// 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)
- {
- if (indexForBreakingNode < S.nslots)
- // cannot issue a delayed instr in the same cycle as one
- // that breaks the issue group or as another delayed instr
- nextNode = NULL;
- else
- indexForDelayedInstr = S.getNumChoices();
- }
- }
- else if (S.schedInfo.breaksIssueGroup(nextNode->getOpCode()))
- {
- if (indexForBreakingNode < S.nslots)
- // have a breaking instruction already so throw this one away
- nextNode = NULL;
- 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
+ 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) {
+ if (indexForBreakingNode < S.nslots)
+ // cannot issue a delayed instr in the same cycle as one
+ // that breaks the issue group or as another delayed instr
+ nextNode = NULL;
+ else
+ indexForDelayedInstr = S.getNumChoices();
+ }
+ } else if (S.schedInfo.breaksIssueGroup(nextNode->getOpCode())) {
+ if (indexForBreakingNode < S.nslots)
+ // have a breaking instruction already so throw this one away
+ nextNode = NULL;
+ 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 &&
@@ -783,176 +769,158 @@
//
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.
+ { // 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;
- for (s=startSlot; s < S.nslots; s++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- break;
- assert(s < S.nslots && "No feasible slot for this opCode?");
- S.addChoiceToSlot(s, S.getChoice(0));
- }
- else
- {
- for (unsigned i=0; i < S.getNumChoices(); i++)
- {
- MachineOpCode opCode = S.getChoice(i)->getOpCode();
- for (unsigned int s=startSlot; s < S.nslots; s++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- S.addChoiceToSlot(s, S.getChoice(i));
- }
- }
+ if (S.getNumChoices() == 1) {
+ MachineOpCode opCode = S.getChoice(0)->getOpCode();
+ unsigned int s;
+ for (s=startSlot; s < S.nslots; s++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s))
+ break;
+ assert(s < S.nslots && "No feasible slot for this opCode?");
+ S.addChoiceToSlot(s, S.getChoice(0));
+ } else {
+ for (unsigned i=0; i < S.getNumChoices(); i++) {
+ MachineOpCode opCode = S.getChoice(i)->getOpCode();
+ for (unsigned int s=startSlot; s < S.nslots; s++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s))
+ S.addChoiceToSlot(s, S.getChoice(i));
+ }
}
- else if (indexForDelayedInstr < S.nslots)
- {
- // There is an instruction that needs delay slots.
- // 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--)
- if (S.schedInfo.instrCanUseSlot(delayOpCode, s))
- {
- delayedNodeSlot = s;
- break;
- }
-
- highestSlotUsed = -1;
- for (unsigned i=0; i < S.getNumChoices() - 1; i++)
- {
- // Try to assign every other instruction to a lower numbered
- // slot than delayedNodeSlot.
- MachineOpCode opCode =S.getChoice(i)->getOpCode();
- bool noSlotFound = true;
- unsigned int s;
- for (s=startSlot; s < delayedNodeSlot; s++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- {
- S.addChoiceToSlot(s, S.getChoice(i));
- noSlotFound = false;
- }
+ } else if (indexForDelayedInstr < S.nslots) {
+ // There is an instruction that needs delay slots.
+ // 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--)
+ if (S.schedInfo.instrCanUseSlot(delayOpCode, s)) {
+ delayedNodeSlot = s;
+ break;
+ }
+
+ highestSlotUsed = -1;
+ for (unsigned i=0; i < S.getNumChoices() - 1; i++) {
+ // Try to assign every other instruction to a lower numbered
+ // slot than delayedNodeSlot.
+ MachineOpCode opCode =S.getChoice(i)->getOpCode();
+ bool noSlotFound = true;
+ unsigned int s;
+ for (s=startSlot; s < delayedNodeSlot; s++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s)) {
+ 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.
- if (noSlotFound)
- for ( ; s < S.nslots; s++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- {
- S.addChoiceToSlot(s, S.getChoice(i));
- break;
- }
+ // No slot before `delayedNodeSlot' was found for this opCode
+ // Use a later slot, and allow some delay slots to fall in
+ // the next cycle.
+ if (noSlotFound)
+ for ( ; s < S.nslots; s++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s)) {
+ S.addChoiceToSlot(s, S.getChoice(i));
+ break;
+ }
- assert(s < S.nslots && "No feasible slot for instruction?");
+ assert(s < S.nslots && "No feasible slot for instruction?");
- highestSlotUsed = std::max(highestSlotUsed, (int) s);
- }
+ highestSlotUsed = std::max(highestSlotUsed, (int) s);
+ }
- assert(highestSlotUsed <= (int) S.nslots-1 && "Invalid slot used?");
+ 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
- // slots for the node at the same time.
- cycles_t dcycle = S.getTime();
- unsigned int dslot = highestSlotUsed + 1;
- if (dslot == S.nslots)
- {
- dslot = 0;
- ++dcycle;
- }
- delaySlotInfo->recordChosenSlot(dcycle, dslot);
- getDelaySlotInfo = delaySlotInfo;
- }
- else
- { // There is an instruction that breaks the issue group.
- // For such an instruction, assign to the last possible slot in
- // the current group, and then don't assign any other instructions
- // to later slots.
- assert(indexForBreakingNode < S.nslots);
- const SchedGraphNode* breakingNode=S.getChoice(indexForBreakingNode);
- unsigned breakingSlot = INT_MAX;
- unsigned int nslotsToUse = S.nslots;
+ // 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
+ // slots for the node at the same time.
+ cycles_t dcycle = S.getTime();
+ unsigned int dslot = highestSlotUsed + 1;
+ if (dslot == S.nslots) {
+ dslot = 0;
+ ++dcycle;
+ }
+ delaySlotInfo->recordChosenSlot(dcycle, dslot);
+ getDelaySlotInfo = delaySlotInfo;
+ } else {
+ // There is an instruction that breaks the issue group.
+ // For such an instruction, assign to the last possible slot in
+ // the current group, and then don't assign any other instructions
+ // to later slots.
+ assert(indexForBreakingNode < S.nslots);
+ 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))
- {
- breakingSlot = s;
- break;
- }
- 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.
- for (unsigned i=0;
- i < S.getNumChoices() && i < indexForBreakingNode; i++)
- {
- MachineOpCode opCode =S.getChoice(i)->getOpCode();
+ // 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)) {
+ breakingSlot = s;
+ break;
+ }
+ 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.
+ for (unsigned i=0;
+ 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++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- {
- if (breakingSlot < S.nslots && s < breakingSlot)
- {
- foundLowerSlot = true;
- nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
- }
+ // 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++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s)) {
+ if (breakingSlot < S.nslots && s < breakingSlot) {
+ foundLowerSlot = true;
+ nslotsToUse = breakingSlot; // RESETS LOOP UPPER BOUND!
+ }
- S.addChoiceToSlot(s, S.getChoice(i));
- }
+ 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.
- if (breakingSlot < S.nslots)
- {
- S.addChoiceToSlot(breakingSlot, breakingNode);
- nslotsToUse = breakingSlot;
- }
- else
- nslotsToUse = S.nslots;
+ 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.
+ if (breakingSlot < S.nslots) {
+ S.addChoiceToSlot(breakingSlot, breakingNode);
+ 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.
- for (unsigned i=indexForBreakingNode+1; i < S.getNumChoices(); i++)
- {
- MachineOpCode opCode = S.getChoice(i)->getOpCode();
- for (unsigned int s=startSlot; s < nslotsToUse; s++)
- if (S.schedInfo.instrCanUseSlot(opCode, s))
- S.addChoiceToSlot(s, S.getChoice(i));
- }
- } // endif (no delay slots and no breaking slots)
+ // 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.
+ for (unsigned i=indexForBreakingNode+1; i < S.getNumChoices(); i++) {
+ MachineOpCode opCode = S.getChoice(i)->getOpCode();
+ for (unsigned int s=startSlot; s < nslotsToUse; s++)
+ if (S.schedInfo.instrCanUseSlot(opCode, s))
+ S.addChoiceToSlot(s, S.getChoice(i));
+ }
+ } // endif (no delay slots and no breaking slots)
return S.getNumChoices();
}
@@ -970,11 +938,10 @@
// 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);
- }
+ while (numIssued == 0) {
+ S.updateTime(S.getTime()+1);
+ numIssued = FindSlotChoices(S, getDelaySlotInfo);
+ }
AssignInstructionsToSlots(S, numIssued);
@@ -982,22 +949,19 @@
numIssued += getDelaySlotInfo->scheduleDelayedNode(S);
// Print trace of scheduled instructions before newly ready ones
- if (SchedDebugLevel >= Sched_PrintSchedTrace)
- {
- for (cycles_t c = firstCycle; c <= S.getTime(); c++)
- {
- std::cerr << " Cycle " << (long)c <<" : Scheduled instructions:\n";
- const InstrGroup* igroup = S.isched.getIGroup(c);
- for (unsigned int s=0; s < S.nslots; s++)
- {
- std::cerr << " ";
- if ((*igroup)[s] != NULL)
- std::cerr << * ((*igroup)[s])->getMachineInstr() << "\n";
- else
- std::cerr << "<none>\n";
- }
- }
+ if (SchedDebugLevel >= Sched_PrintSchedTrace) {
+ for (cycles_t c = firstCycle; c <= S.getTime(); c++) {
+ std::cerr << " Cycle " << (long)c <<" : Scheduled instructions:\n";
+ const InstrGroup* igroup = S.isched.getIGroup(c);
+ for (unsigned int s=0; s < S.nslots; s++) {
+ std::cerr << " ";
+ if ((*igroup)[s] != NULL)
+ std::cerr << * ((*igroup)[s])->getMachineInstr() << "\n";
+ else
+ std::cerr << "<none>\n";
+ }
}
+ }
return numIssued;
}
@@ -1011,40 +975,37 @@
S.schedPrio.initialize();
- while ((N = S.schedPrio.getNumReady()) > 0)
- {
- cycles_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?");
+ while ((N = S.schedPrio.getNumReady()) > 0) {
+ cycles_t nextCycle = S.getTime();
- // Notify the priority manager of scheduled instructions and mark
- // any successors that may now be ready
- //
- for (cycles_t c = nextCycle; c <= S.getTime(); c++)
- {
- const InstrGroup* igroup = S.isched.getIGroup(c);
- for (unsigned int s=0; s < S.nslots; s++)
- if ((node = (*igroup)[s]) != NULL)
- {
- S.schedPrio.issuedReadyNodeAt(S.getTime(), node);
- MarkSuccessorsReady(S, node);
- }
+ // 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 (cycles_t c = nextCycle; c <= S.getTime(); c++) {
+ const InstrGroup* igroup = S.isched.getIGroup(c);
+ for (unsigned int s=0; s < S.nslots; s++)
+ if ((node = (*igroup)[s]) != NULL) {
+ S.schedPrio.issuedReadyNodeAt(S.getTime(), node);
+ 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())));
}
+
+ // 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())));
+ }
}
@@ -1092,22 +1053,21 @@
// 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();
- OEI != node->endOutEdges(); ++OEI)
- if (! (*OEI)->getSink()->isDummyNode()
- && ((*OEI)->getSink() != brNode
- || (*OEI)->getDepType() != SchedGraphEdge::CtrlDep))
- {
- onlyCDEdgeToBranch = false;
- break;
- }
+ if (nodeIsPredecessor) {
+ bool onlyCDEdgeToBranch = true;
+ for (SchedGraphNode::const_iterator OEI = node->beginOutEdges();
+ OEI != node->endOutEdges(); ++OEI)
+ if (! (*OEI)->getSink()->isDummyNode()
+ && ((*OEI)->getSink() != brNode
+ || (*OEI)->getDepType() != SchedGraphEdge::CtrlDep))
+ {
+ onlyCDEdgeToBranch = false;
+ break;
+ }
- if (!onlyCDEdgeToBranch)
- return false;
- }
+ if (!onlyCDEdgeToBranch)
+ return false;
+ }
return true;
}
@@ -1120,17 +1080,16 @@
const SchedGraphNode* brNode,
bool nodeIsPredecessor)
{
- if (nodeIsPredecessor)
- { // If node is in the same basic block (i.e., preceeds brNode),
- // 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
- { // 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");
- }
+ if (nodeIsPredecessor) {
+ // If node is in the same basic block (i.e., preceeds brNode),
+ // 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 {
+ // 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);
@@ -1161,37 +1120,36 @@
if (! (*P)->isDummyNode() &&
! mii.isNop((*P)->getOpCode()) &&
NodeCanFillDelaySlot(S, *P, brNode, /*pred*/ true))
- {
- if (mii.maxLatency((*P)->getOpCode()) > 1)
- mdelayNodeVec.push_back(*P);
- else
- sdelayNodeVec.push_back(*P);
- }
+ {
+ if (mii.maxLatency((*P)->getOpCode()) > 1)
+ mdelayNodeVec.push_back(*P);
+ 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)
+ 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 lmin =
- mii.maxLatency(mdelayNodeVec[0]->getOpCode());
- unsigned minIndex = 0;
- for (unsigned i=1; i < mdelayNodeVec.size(); i++)
- {
- unsigned li =
- mii.maxLatency(mdelayNodeVec[i]->getOpCode());
- if (lmin >= li)
- {
- lmin = li;
- minIndex = i;
- }
- }
- sdelayNodeVec.push_back(mdelayNodeVec[minIndex]);
- if (sdelayNodeVec.size() < ndelays) // avoid the last erase!
- mdelayNodeVec.erase(mdelayNodeVec.begin() + minIndex);
+ unsigned li =
+ mii.maxLatency(mdelayNodeVec[i]->getOpCode());
+ if (lmin >= li)
+ {
+ lmin = li;
+ minIndex = i;
+ }
}
+ sdelayNodeVec.push_back(mdelayNodeVec[minIndex]);
+ if (sdelayNodeVec.size() < ndelays) // avoid the last erase!
+ mdelayNodeVec.erase(mdelayNodeVec.begin() + minIndex);
+ }
}
@@ -1202,6 +1160,7 @@
//
static void ReplaceNopsWithUsefulInstr(SchedulingManager& S,
SchedGraphNode* node,
+ // FIXME: passing vector BY VALUE!!!
std::vector<SchedGraphNode*> sdelayNodeVec,
SchedGraph* graph)
{
@@ -1234,21 +1193,20 @@
if (mii.isNop(MBB[i]->getOpCode()))
if (sdelayNodeVec.size() < ndelays)
sdelayNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
- else
- {
- nopNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
+ else {
+ nopNodeVec.push_back(graph->getGraphNodeForInstr(MBB[i]));
- //remove the MI from the Machine Code For Instruction
- TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
- MachineCodeForInstruction& llvmMvec =
- MachineCodeForInstruction::get((Instruction *)TI);
+ //remove the MI from the Machine Code For Instruction
+ TerminatorInst *TI = MBB.getBasicBlock()->getTerminator();
+ MachineCodeForInstruction& llvmMvec =
+ MachineCodeForInstruction::get((Instruction *)TI);
- for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(),
- mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
- if (*mciI==MBB[i])
- llvmMvec.erase(mciI);
- }
- }
+ for(MachineCodeForInstruction::iterator mciI=llvmMvec.begin(),
+ mciE=llvmMvec.end(); mciI!=mciE; ++mciI){
+ if (*mciI==MBB[i])
+ llvmMvec.erase(mciI);
+ }
+ }
assert(sdelayNodeVec.size() >= ndelays);
@@ -1290,33 +1248,32 @@
const MachineInstr* brInstr = NULL;
if (termInstr->getOpcode() != Instruction::Ret)
+ {
+ // To find instructions that need delay slots without searching the full
+ // 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()))
{
- // To find instructions that need delay slots without searching the full
- // 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()))
- {
- ++first;
- }
- assert(first < termMvec.size() &&
- "No branch instructions for BR? Ok, but weird! Delete assertion.");
+ ++first;
+ }
+ assert(first < termMvec.size() &&
+ "No branch instructions for BR? Ok, but weird! Delete assertion.");
- brInstr = (first < termMvec.size())? termMvec[first] : NULL;
+ 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);
- }
+ // 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.
// Simply passing in an empty delayNodeVec will have this effect.
@@ -1325,10 +1282,10 @@
for (unsigned i=0; i < MBB.size(); ++i)
if (MBB[i] != brInstr &&
mii.getNumDelaySlots(MBB[i]->getOpCode()) > 0)
- {
- SchedGraphNode* node = graph->getGraphNodeForInstr(MBB[i]);
- ReplaceNopsWithUsefulInstr(S, node, delayNodeVec, graph);
- }
+ {
+ SchedGraphNode* node = graph->getGraphNodeForInstr(MBB[i]);
+ ReplaceNopsWithUsefulInstr(S, node, delayNodeVec, graph);
+ }
}
@@ -1347,35 +1304,32 @@
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
- // interlocks to resolve them. Machines without interlocks
- // will require this code to be modified.
- for (unsigned i=0; i < delayNodeVec.size(); i++)
- {
- const SchedGraphNode* dnode = delayNodeVec[i];
- if ( ! S.isScheduled(dnode)
- && S.schedInfo.instrCanUseSlot(dnode->getOpCode(), nextSlot)
- && instrIsFeasible(S, dnode->getOpCode()))
- {
- assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpCode())
- && "Instructions without interlocks not yet supported "
- "when filling branch delay slots");
- S.scheduleInstr(dnode, nextSlot, nextTime);
- break;
- }
- }
+ 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
+ // interlocks to resolve them. Machines without interlocks
+ // will require this code to be modified.
+ for (unsigned i=0; i < delayNodeVec.size(); i++) {
+ const SchedGraphNode* dnode = delayNodeVec[i];
+ if ( ! S.isScheduled(dnode)
+ && S.schedInfo.instrCanUseSlot(dnode->getOpCode(), nextSlot)
+ && instrIsFeasible(S, dnode->getOpCode()))
+ {
+ assert(S.getInstrInfo().hasOperandInterlock(dnode->getOpCode())
+ && "Instructions without interlocks not yet supported "
+ "when filling branch delay slots");
+ S.scheduleInstr(dnode, nextSlot, nextTime);
+ break;
+ }
}
+ }
// Update current time if delay slots overflowed into later cycles.
// Do this here because we know exactly which cycle is the last cycle
@@ -1388,20 +1342,18 @@
nextSlot = delayedNodeSlotNum;
nextTime = delayedNodeCycle;
for (unsigned i=0; i < delayNodeVec.size(); i++)
- if (! S.isScheduled(delayNodeVec[i]))
- {
- do { // find the next empty slot
- ++nextSlot;
- if (nextSlot == S.nslots)
- {
- nextSlot = 0;
- nextTime++;
- }
- } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
+ if (! S.isScheduled(delayNodeVec[i])) {
+ do { // find the next empty slot
+ ++nextSlot;
+ if (nextSlot == S.nslots) {
+ nextSlot = 0;
+ nextTime++;
+ }
+ } while (S.isched.getInstr(nextSlot, nextTime) != NULL);
- S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
- break;
- }
+ S.scheduleInstr(delayNodeVec[i], nextSlot, nextTime);
+ break;
+ }
return 1 + ndelays;
}
@@ -1507,35 +1459,33 @@
{
SchedGraphSet graphSet(&F, target);
- if (SchedDebugLevel >= Sched_PrintSchedGraphs)
- {
+ 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();
+ {
+ SchedGraph* graph = (*GI);
+ MachineBasicBlock &MBB = graph->getBasicBlock();
- if (SchedDebugLevel >= Sched_PrintSchedTrace)
- std::cerr << "\n*** TRACE OF INSTRUCTION SCHEDULING OPERATIONS\n\n";
+ 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);
+ // 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
- }
+ 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();
- }
+ if (SchedDebugLevel >= Sched_PrintMachineCode) {
+ std::cerr << "\n*** Machine instructions after INSTRUCTION SCHEDULING\n";
+ MachineFunction::get(&F).dump();
+ }
return false;
}
Index: llvm/lib/CodeGen/InstrSched/SchedGraph.cpp
diff -u llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.42 llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.43
--- llvm/lib/CodeGen/InstrSched/SchedGraph.cpp:1.42 Thu May 22 16:24:35 2003
+++ llvm/lib/CodeGen/InstrSched/SchedGraph.cpp Thu May 22 16:49:18 2003
@@ -249,20 +249,21 @@
// Delete and disconnect all in-edges for the node
for (SchedGraphNode::iterator I = node->beginInEdges();
I != node->endInEdges(); ++I)
- {
- SchedGraphNode* srcNode = (*I)->getSrc();
- srcNode->removeOutEdge(*I);
- delete *I;
-
- if (addDummyEdges &&
- srcNode != getRoot() &&
- 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::NonDataDep, 0);
- }
+ {
+ SchedGraphNode* srcNode = (*I)->getSrc();
+ srcNode->removeOutEdge(*I);
+ delete *I;
+
+ if (addDummyEdges &&
+ srcNode != getRoot() &&
+ 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::NonDataDep, 0);
}
+ }
node->inEdges.clear();
}
@@ -273,20 +274,20 @@
// Delete and disconnect all out-edges for the node
for (SchedGraphNode::iterator I = node->beginOutEdges();
I != node->endOutEdges(); ++I)
- {
- SchedGraphNode* 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::NonDataDep, 0);
- }
+ {
+ SchedGraphNode* 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::NonDataDep, 0);
}
+ }
node->outEdges.clear();
}
@@ -305,16 +306,16 @@
assert(graphRoot->outEdges.size() == 0);
for (const_iterator I=begin(); I != end(); ++I)
- {
- SchedGraphNode* node = (*I).second;
- assert(node != graphRoot && node != graphLeaf);
- if (node->beginInEdges() == node->endInEdges())
- (void) new SchedGraphEdge(graphRoot, node, SchedGraphEdge::CtrlDep,
- SchedGraphEdge::NonDataDep, 0);
- if (node->beginOutEdges() == node->endOutEdges())
- (void) new SchedGraphEdge(node, graphLeaf, SchedGraphEdge::CtrlDep,
- SchedGraphEdge::NonDataDep, 0);
- }
+ {
+ SchedGraphNode* node = (*I).second;
+ assert(node != graphRoot && node != graphLeaf);
+ if (node->beginInEdges() == node->endInEdges())
+ (void) new SchedGraphEdge(graphRoot, node, SchedGraphEdge::CtrlDep,
+ SchedGraphEdge::NonDataDep, 0);
+ if (node->beginOutEdges() == node->endOutEdges())
+ (void) new SchedGraphEdge(node, graphLeaf, SchedGraphEdge::CtrlDep,
+ SchedGraphEdge::NonDataDep, 0);
+ }
}
@@ -343,65 +344,65 @@
// 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)
- if (mii.isBranch(termMvec[j-1]->getOpCode()) ||
- mii.isReturn(termMvec[j-1]->getOpCode()))
- {
- SchedGraphNode* brNode = getGraphNodeForInstr(termMvec[j-1]);
- assert(brNode && "No node for instr generated for branch/ret?");
- (void) new SchedGraphEdge(brNode, toNode, SchedGraphEdge::CtrlDep,
- SchedGraphEdge::NonDataDep, 0);
- break; // only one incoming edge is enough
- }
- }
+ {
+ SchedGraphNode* toNode = getGraphNodeForInstr(termMvec[i-1]);
+ assert(toNode && "No node for instr generated for branch/ret?");
+
+ 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]);
+ assert(brNode && "No node for instr generated for branch/ret?");
+ (void) new SchedGraphEdge(brNode, toNode, SchedGraphEdge::CtrlDep,
+ SchedGraphEdge::NonDataDep, 0);
+ 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);
- }
+ {
+ 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 (unsigned i=0, N=MBB.size(); i < N; i++)
- {
- if (MBB[i] == termMvec[first]) // reached the first branch
- break;
-
- SchedGraphNode* fromNode = this->getGraphNodeForInstr(MBB[i]);
- if (fromNode == NULL)
- continue; // dummy instruction, e.g., PHI
-
- (void) new SchedGraphEdge(fromNode, firstBrNode,
+ {
+ if (MBB[i] == termMvec[first]) // reached the first branch
+ break;
+
+ SchedGraphNode* fromNode = this->getGraphNodeForInstr(MBB[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(MBB[i]->getOpCode());
+ assert(i+d < N && "Insufficient delay slots for instruction?");
+
+ for (unsigned j=1; j <= d; j++)
+ {
+ SchedGraphNode* toNode = this->getGraphNodeForInstr(MBB[i+j]);
+ assert(toNode && "No node for machine instr in delay slot?");
+ (void) new SchedGraphEdge(fromNode, toNode,
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(MBB[i]->getOpCode());
- assert(i+d < N && "Insufficient delay slots for instruction?");
-
- for (unsigned j=1; j <= d; j++)
- {
- SchedGraphNode* toNode = this->getGraphNodeForInstr(MBB[i+j]);
- assert(toNode && "No node for machine instr in delay slot?");
- (void) new SchedGraphEdge(fromNode, toNode,
- SchedGraphEdge::CtrlDep,
- SchedGraphEdge::NonDataDep, 0);
- }
}
+ }
}
static const int SG_LOAD_REF = 0;
@@ -437,24 +438,24 @@
// 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
- : mii.isLoad(fromOpCode)? SG_LOAD_REF
- : SG_STORE_REF;
- for (unsigned jm=im+1; jm < NM; jm++)
- {
- MachineOpCode toOpCode = memNodeVec[jm]->getOpCode();
- int toType = mii.isCall(toOpCode)? SG_CALL_REF
- : mii.isLoad(toOpCode)? SG_LOAD_REF
- : SG_STORE_REF;
+ {
+ MachineOpCode fromOpCode = memNodeVec[im]->getOpCode();
+ int fromType = mii.isCall(fromOpCode)? SG_CALL_REF
+ : mii.isLoad(fromOpCode)? SG_LOAD_REF
+ : SG_STORE_REF;
+ for (unsigned jm=im+1; jm < NM; jm++)
+ {
+ MachineOpCode toOpCode = memNodeVec[jm]->getOpCode();
+ 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);
- }
+ 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.
@@ -484,24 +485,23 @@
int lastCallNodeIdx = -1;
for (unsigned i=0, N=bbMvec.size(); i < N; i++)
if (mii.isCall(bbMvec[i]->getOpCode()))
- {
- ++lastCallNodeIdx;
- for ( ; lastCallNodeIdx < (int)callNodeVec.size(); ++lastCallNodeIdx)
- if (callNodeVec[lastCallNodeIdx]->getMachineInstr() == bbMvec[i])
- break;
- assert(lastCallNodeIdx < (int)callNodeVec.size() && "Missed Call?");
- }
- else if (mii.isCCInstr(bbMvec[i]->getOpCode()))
- { // Add incoming/outgoing edges from/to preceding/later calls
- SchedGraphNode* ccNode = this->getGraphNodeForInstr(bbMvec[i]);
- int j=0;
- for ( ; j <= lastCallNodeIdx; j++)
- (void) new SchedGraphEdge(callNodeVec[j], ccNode,
- MachineCCRegsRID, 0);
- for ( ; j < (int) callNodeVec.size(); j++)
- (void) new SchedGraphEdge(ccNode, callNodeVec[j],
- MachineCCRegsRID, 0);
- }
+ {
+ ++lastCallNodeIdx;
+ for ( ; lastCallNodeIdx < (int)callNodeVec.size(); ++lastCallNodeIdx)
+ if (callNodeVec[lastCallNodeIdx]->getMachineInstr() == bbMvec[i])
+ break;
+ assert(lastCallNodeIdx < (int)callNodeVec.size() && "Missed Call?");
+ } else if (mii.isCCInstr(bbMvec[i]->getOpCode())) {
+ // Add incoming/outgoing edges from/to preceding/later calls
+ SchedGraphNode* ccNode = this->getGraphNodeForInstr(bbMvec[i]);
+ int j=0;
+ for ( ; j <= lastCallNodeIdx; j++)
+ (void) new SchedGraphEdge(callNodeVec[j], ccNode,
+ MachineCCRegsRID, 0);
+ for ( ; j < (int) callNodeVec.size(); j++)
+ (void) new SchedGraphEdge(ccNode, callNodeVec[j],
+ MachineCCRegsRID, 0);
+ }
}
@@ -517,47 +517,43 @@
//
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;
- unsigned int opNum = regRefVec[i].second;
- bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
- bool isDefAndUse =
- node->getMachineInstr()->operandIsDefinedAndUsed(opNum);
+ {
+ 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;
+ unsigned int opNum = regRefVec[i].second;
+ bool isDef = node->getMachineInstr()->operandIsDefined(opNum);
+ bool isDefAndUse =
+ node->getMachineInstr()->operandIsDefinedAndUsed(opNum);
- for (unsigned p=0; p < i; ++p)
- {
- SchedGraphNode* prevNode = regRefVec[p].first;
- if (prevNode != node)
- {
- unsigned int prevOpNum = regRefVec[p].second;
- bool prevIsDef =
- prevNode->getMachineInstr()->operandIsDefined(prevOpNum);
- bool prevIsDefAndUse =
- prevNode->getMachineInstr()->operandIsDefinedAndUsed(prevOpNum);
- if (isDef)
- {
- if (prevIsDef)
- new SchedGraphEdge(prevNode, node, regNum,
- SchedGraphEdge::OutputDep);
- if (!prevIsDef || prevIsDefAndUse)
- new SchedGraphEdge(prevNode, node, regNum,
- SchedGraphEdge::AntiDep);
- }
+ for (unsigned p=0; p < i; ++p) {
+ SchedGraphNode* prevNode = regRefVec[p].first;
+ if (prevNode != node) {
+ unsigned int prevOpNum = regRefVec[p].second;
+ bool prevIsDef =
+ prevNode->getMachineInstr()->operandIsDefined(prevOpNum);
+ bool prevIsDefAndUse =
+ prevNode->getMachineInstr()->operandIsDefinedAndUsed(prevOpNum);
+ if (isDef) {
+ if (prevIsDef)
+ new SchedGraphEdge(prevNode, node, regNum,
+ SchedGraphEdge::OutputDep);
+ if (!prevIsDef || prevIsDefAndUse)
+ new SchedGraphEdge(prevNode, node, regNum,
+ SchedGraphEdge::AntiDep);
+ }
- if (prevIsDef)
- if (!isDef || isDefAndUse)
- new SchedGraphEdge(prevNode, node, regNum,
- SchedGraphEdge::TrueDep);
- }
- }
+ if (prevIsDef)
+ if (!isDef || isDefAndUse)
+ new SchedGraphEdge(prevNode, node, regNum,
+ SchedGraphEdge::TrueDep);
}
+ }
}
+ }
}
@@ -578,29 +574,28 @@
// 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.
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)
- (void) new SchedGraphEdge((*I).first, refNode, defValue,
- SchedGraphEdge::OutputDep);
- if (refNodeIsUse)
- (void) new SchedGraphEdge((*I).first, refNode, defValue,
- SchedGraphEdge::TrueDep);
- }
- else
- { // (*).first is after refNode
- if (refNodeIsDef)
- (void) new SchedGraphEdge(refNode, (*I).first, defValue,
- SchedGraphEdge::OutputDep);
- if (refNodeIsUse)
- (void) new SchedGraphEdge(refNode, (*I).first, defValue,
- SchedGraphEdge::AntiDep);
- }
+ {
+ if ((*I).first == refNode)
+ continue; // Dont add any self-loops
+
+ if ((*I).first->getOrigIndexInBB() < refNode->getOrigIndexInBB()) {
+ // (*).first is before refNode
+ if (refNodeIsDef)
+ (void) new SchedGraphEdge((*I).first, refNode, defValue,
+ SchedGraphEdge::OutputDep);
+ if (refNodeIsUse)
+ (void) new SchedGraphEdge((*I).first, refNode, defValue,
+ SchedGraphEdge::TrueDep);
+ } else {
+ // (*).first is after refNode
+ if (refNodeIsDef)
+ (void) new SchedGraphEdge(refNode, (*I).first, defValue,
+ SchedGraphEdge::OutputDep);
+ if (refNodeIsUse)
+ (void) new SchedGraphEdge(refNode, (*I).first, defValue,
+ SchedGraphEdge::AntiDep);
}
+ }
}
@@ -616,35 +611,35 @@
// Add edges for all operands of the machine instruction.
//
for (unsigned i = 0, numOps = MI.getNumOperands(); i != numOps; ++i)
+ {
+ switch (MI.getOperandType(i))
{
- switch (MI.getOperandType(i))
- {
- case MachineOperand::MO_VirtualRegister:
- case MachineOperand::MO_CCRegister:
- if (const Instruction* srcI =
- dyn_cast_or_null<Instruction>(MI.getOperand(i).getVRegValue()))
- {
- ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
- if (I != valueToDefVecMap.end())
- addEdgesForValue(node, I->second, srcI,
- MI.operandIsDefined(i),
- MI.operandIsDefinedAndUsed(i), target);
- }
- break;
+ case MachineOperand::MO_VirtualRegister:
+ case MachineOperand::MO_CCRegister:
+ if (const Instruction* srcI =
+ dyn_cast_or_null<Instruction>(MI.getOperand(i).getVRegValue()))
+ {
+ ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
+ if (I != valueToDefVecMap.end())
+ addEdgesForValue(node, I->second, srcI,
+ MI.operandIsDefined(i),
+ MI.operandIsDefinedAndUsed(i), target);
+ }
+ break;
- case MachineOperand::MO_MachineRegister:
- break;
+ case MachineOperand::MO_MachineRegister:
+ break;
- case MachineOperand::MO_SignExtendedImmed:
- case MachineOperand::MO_UnextendedImmed:
- case MachineOperand::MO_PCRelativeDisp:
- break; // nothing to do for immediate fields
+ case MachineOperand::MO_SignExtendedImmed:
+ case MachineOperand::MO_UnextendedImmed:
+ case MachineOperand::MO_PCRelativeDisp:
+ break; // nothing to do for immediate fields
- default:
- assert(0 && "Unknown machine operand type in SchedGraph builder");
- break;
- }
+ 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
@@ -655,13 +650,13 @@
MI.implicitRefIsDefinedAndUsed(i))
if (const Instruction *srcI =
dyn_cast_or_null<Instruction>(MI.getImplicitRef(i)))
- {
- ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
- if (I != valueToDefVecMap.end())
- addEdgesForValue(node, I->second, srcI,
- MI.implicitRefIsDefined(i),
- MI.implicitRefIsDefinedAndUsed(i), target);
- }
+ {
+ ValueToDefVecMap::const_iterator I = valueToDefVecMap.find(srcI);
+ if (I != valueToDefVecMap.end())
+ addEdgesForValue(node, I->second, srcI,
+ MI.implicitRefIsDefined(i),
+ MI.implicitRefIsDefinedAndUsed(i), target);
+ }
}
@@ -683,32 +678,32 @@
//
const MachineInstr& minstr = *node->getMachineInstr();
for (int i=0, numOps = (int) minstr.getNumOperands(); i < numOps; i++)
- {
- const MachineOperand& mop = minstr.getOperand(i);
+ {
+ const MachineOperand& mop = minstr.getOperand(i);
- // if this references a register other than the hardwired
- // "zero" register, record the reference.
- if (mop.getType() == MachineOperand::MO_MachineRegister)
- {
- int regNum = mop.getMachineRegNum();
- if (regNum != target.getRegInfo().getZeroRegNum())
- regToRefVecMap[mop.getMachineRegNum()].push_back(
- std::make_pair(node, i));
- continue; // nothing more to do
- }
-
- // ignore all other non-def operands
- if (! minstr.operandIsDefined(i))
- 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!");
+ // if this references a register other than the hardwired
+ // "zero" register, record the reference.
+ if (mop.getType() == MachineOperand::MO_MachineRegister)
+ {
+ int regNum = mop.getMachineRegNum();
+ if (regNum != target.getRegInfo().getZeroRegNum())
+ regToRefVecMap[mop.getMachineRegNum()]
+ .push_back(std::make_pair(node, i));
+ continue; // nothing more to do
+ }
+
+ // ignore all other non-def operands
+ if (! minstr.operandIsDefined(i))
+ 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!");
- const Instruction* defInstr = cast<Instruction>(mop.getVRegValue());
- valueToDefVecMap[defInstr].push_back(std::make_pair(node, i));
- }
+ const Instruction* defInstr = cast<Instruction>(mop.getVRegValue());
+ valueToDefVecMap[defInstr].push_back(std::make_pair(node, i));
+ }
//
// Collect value defs. for implicit operands. The interface to extract
@@ -903,18 +898,17 @@
if (node.getMachineInstr() == NULL)
os << "(Dummy node)\n";
- else
- {
- os << *node.getMachineInstr() << "\n" << std::string(12, ' ');
- os << node.inEdges.size() << " Incoming Edges:\n";
- for (unsigned i=0, N=node.inEdges.size(); i < N; i++)
- os << std::string(16, ' ') << *node.inEdges[i];
-
- os << std::string(12, ' ') << node.outEdges.size()
- << " Outgoing Edges:\n";
- for (unsigned i=0, N=node.outEdges.size(); i < N; i++)
- os << std::string(16, ' ') << *node.outEdges[i];
- }
+ else {
+ os << *node.getMachineInstr() << "\n" << std::string(12, ' ');
+ os << node.inEdges.size() << " Incoming Edges:\n";
+ for (unsigned i=0, N=node.inEdges.size(); i < N; i++)
+ os << std::string(16, ' ') << *node.inEdges[i];
+
+ os << std::string(12, ' ') << node.outEdges.size()
+ << " Outgoing Edges:\n";
+ for (unsigned i=0, N=node.outEdges.size(); i < N; i++)
+ os << std::string(16, ' ') << *node.outEdges[i];
+ }
return os;
}
More information about the llvm-commits
mailing list