diff --git a/lib/CodeGen/InstrSched/InstrScheduling.cpp b/lib/CodeGen/InstrSched/InstrScheduling.cpp index dea628a40a6..6cc271a7d30 100644 --- a/lib/CodeGen/InstrSched/InstrScheduling.cpp +++ b/lib/CodeGen/InstrSched/InstrScheduling.cpp @@ -221,16 +221,15 @@ ScheduleIterator<_NodeType>::skipToNextInstr() 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 @@ -239,11 +238,10 @@ ScheduleIterator<_NodeType>& 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 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue) // 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 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue) // 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 ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() > 0) { + 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 (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 @@ MarkSuccessorsReady(SchedulingManager& S, const SchedGraphNode* node) 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 @@ FindSlotChoices(SchedulingManager& S, 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 @@ FindSlotChoices(SchedulingManager& S, // 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 + 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 + 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 @@ FindSlotChoices(SchedulingManager& S, // 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. - // + } 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?"); + 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); + const SchedGraphNode* delayedNode = S.getChoice(indexForDelayedInstr); + MachineOpCode delayOpCode = delayedNode->getOpCode(); + unsigned ndelays= S.getInstrInfo().getNumDelaySlots(delayOpCode); - unsigned delayedNodeSlot = S.nslots; - int highestSlotUsed; + 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; - } + // 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; - } + 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); - } - - 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; + highestSlotUsed = std::max(highestSlotUsed, (int) s); } - 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(); + 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; - // 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! - } + // 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! + } - S.addChoiceToSlot(s, S.getChoice(i)); - } + S.addChoiceToSlot(s, S.getChoice(i)); + } - if (!foundLowerSlot) - breakingSlot = INT_MAX; // disable breaking instr - } + 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; + // 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 @@ ChooseOneGroup(SchedulingManager& S) // 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 @@ ChooseOneGroup(SchedulingManager& S) 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 << "\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 << "\n"; + } } + } return numIssued; } @@ -1011,40 +975,37 @@ ForwardListSchedule(SchedulingManager& S) S.schedPrio.initialize(); - while ((N = S.schedPrio.getNumReady()) > 0) - { - cycles_t nextCycle = S.getTime(); + 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?"); + // 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); - } + // 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 @@ NodeCanFillDelaySlot(const SchedulingManager& S, // 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 @@ MarkNodeForDelaySlot(SchedulingManager& S, 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 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S, 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 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S, // static void ReplaceNopsWithUsefulInstr(SchedulingManager& S, SchedGraphNode* node, + // FIXME: passing vector BY VALUE!!! std::vector sdelayNodeVec, SchedGraph* graph) { @@ -1234,21 +1193,20 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S, 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 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB, 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."); - - 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); - } + ++first; } + 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. // Simply passing in an empty delayNodeVec will have this effect. @@ -1325,10 +1282,10 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB, 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 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S) 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 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S) 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 @@ bool InstructionSchedulingWithSSA::runOnFunction(Function &F) { 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()); - SchedulingManager S(target, graph, schedPrio); + // expensive! + SchedPriorities schedPrio(&F, graph, getAnalysis()); + 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; } diff --git a/lib/CodeGen/InstrSched/SchedGraph.cpp b/lib/CodeGen/InstrSched/SchedGraph.cpp index 58fbb93c098..fa7920309f8 100644 --- a/lib/CodeGen/InstrSched/SchedGraph.cpp +++ b/lib/CodeGen/InstrSched/SchedGraph.cpp @@ -249,20 +249,21 @@ SchedGraph::eraseIncomingEdges(SchedGraphNode* node, bool addDummyEdges) // 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; + { + 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); - } + 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 @@ SchedGraph::eraseOutgoingEdges(SchedGraphNode* node, bool addDummyEdges) // 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; + { + 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); - } + 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 @@ SchedGraph::addDummyEdges() 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 @@ SchedGraph::addCDEdges(const TerminatorInst* term, // 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?"); + { + 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 - } - } + 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, + 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++) { - 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, + 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 @@ SchedGraph::addMemEdges(const std::vector& memNodeVec, // so simply look at all pairs 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 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 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 @@ SchedGraph::addCallCCEdges(const std::vector& memNodeVec, 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 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap, // for (RegToRefVecMap::iterator I = regToRefVecMap.begin(); I != regToRefVecMap.end(); ++I) - { - int regNum = (*I).first; - RefVec& regRefVec = (*I).second; + { + 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); + // 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 @@ SchedGraph::addEdgesForValue(SchedGraphNode* refNode, // 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 == 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->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 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& MI, // 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(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(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 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& MI, MI.implicitRefIsDefinedAndUsed(i)) if (const Instruction *srcI = dyn_cast_or_null(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 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, // const MachineInstr& minstr = *node->getMachineInstr(); for (int i=0, numOps = (int) minstr.getNumOperands(); i < numOps; 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) { - 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!"); - - const Instruction* defInstr = cast(mop.getVRegValue()); - valueToDefVecMap[defInstr].push_back(std::make_pair(node, i)); + 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(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 @@ std::ostream &operator<<(std::ostream &os, const SchedGraphNode& node) 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]; + 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]; - } + 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; } diff --git a/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp b/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp index dea628a40a6..6cc271a7d30 100644 --- a/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp +++ b/lib/Target/SparcV9/InstrSched/InstrScheduling.cpp @@ -221,16 +221,15 @@ ScheduleIterator<_NodeType>::skipToNextInstr() 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 @@ -239,11 +238,10 @@ ScheduleIterator<_NodeType>& 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 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue) // 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 @@ AssignInstructionsToSlots(class SchedulingManager& S, unsigned maxIssue) // 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 ((*igroup)[s] == NULL && S.getChoicesForSlot(s).size() > 0) { + 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 (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 @@ MarkSuccessorsReady(SchedulingManager& S, const SchedGraphNode* node) 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 @@ FindSlotChoices(SchedulingManager& S, 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 @@ FindSlotChoices(SchedulingManager& S, // 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 + 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 + 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 @@ FindSlotChoices(SchedulingManager& S, // 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. - // + } 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?"); + 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); + const SchedGraphNode* delayedNode = S.getChoice(indexForDelayedInstr); + MachineOpCode delayOpCode = delayedNode->getOpCode(); + unsigned ndelays= S.getInstrInfo().getNumDelaySlots(delayOpCode); - unsigned delayedNodeSlot = S.nslots; - int highestSlotUsed; + 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; - } + // 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; - } + 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); - } - - 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; + highestSlotUsed = std::max(highestSlotUsed, (int) s); } - 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(); + 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; - // 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! - } + // 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! + } - S.addChoiceToSlot(s, S.getChoice(i)); - } + S.addChoiceToSlot(s, S.getChoice(i)); + } - if (!foundLowerSlot) - breakingSlot = INT_MAX; // disable breaking instr - } + 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; + // 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 @@ ChooseOneGroup(SchedulingManager& S) // 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 @@ ChooseOneGroup(SchedulingManager& S) 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 << "\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 << "\n"; + } } + } return numIssued; } @@ -1011,40 +975,37 @@ ForwardListSchedule(SchedulingManager& S) S.schedPrio.initialize(); - while ((N = S.schedPrio.getNumReady()) > 0) - { - cycles_t nextCycle = S.getTime(); + 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?"); + // 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); - } + // 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 @@ NodeCanFillDelaySlot(const SchedulingManager& S, // 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 @@ MarkNodeForDelaySlot(SchedulingManager& S, 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 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S, 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 @@ FindUsefulInstructionsForDelaySlots(SchedulingManager& S, // static void ReplaceNopsWithUsefulInstr(SchedulingManager& S, SchedGraphNode* node, + // FIXME: passing vector BY VALUE!!! std::vector sdelayNodeVec, SchedGraph* graph) { @@ -1234,21 +1193,20 @@ static void ReplaceNopsWithUsefulInstr(SchedulingManager& S, 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 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB, 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."); - - 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); - } + ++first; } + 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. // Simply passing in an empty delayNodeVec will have this effect. @@ -1325,10 +1282,10 @@ ChooseInstructionsForDelaySlots(SchedulingManager& S, MachineBasicBlock &MBB, 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 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S) 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 @@ DelaySlotInfo::scheduleDelayedNode(SchedulingManager& S) 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 @@ bool InstructionSchedulingWithSSA::runOnFunction(Function &F) { 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()); - SchedulingManager S(target, graph, schedPrio); + // expensive! + SchedPriorities schedPrio(&F, graph, getAnalysis()); + 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; } diff --git a/lib/Target/SparcV9/InstrSched/SchedGraph.cpp b/lib/Target/SparcV9/InstrSched/SchedGraph.cpp index 58fbb93c098..fa7920309f8 100644 --- a/lib/Target/SparcV9/InstrSched/SchedGraph.cpp +++ b/lib/Target/SparcV9/InstrSched/SchedGraph.cpp @@ -249,20 +249,21 @@ SchedGraph::eraseIncomingEdges(SchedGraphNode* node, bool addDummyEdges) // 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; + { + 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); - } + 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 @@ SchedGraph::eraseOutgoingEdges(SchedGraphNode* node, bool addDummyEdges) // 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; + { + 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); - } + 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 @@ SchedGraph::addDummyEdges() 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 @@ SchedGraph::addCDEdges(const TerminatorInst* term, // 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?"); + { + 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 - } - } + 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, + 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++) { - 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, + 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 @@ SchedGraph::addMemEdges(const std::vector& memNodeVec, // so simply look at all pairs 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 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 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 @@ SchedGraph::addCallCCEdges(const std::vector& memNodeVec, 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 @@ SchedGraph::addMachineRegEdges(RegToRefVecMap& regToRefVecMap, // for (RegToRefVecMap::iterator I = regToRefVecMap.begin(); I != regToRefVecMap.end(); ++I) - { - int regNum = (*I).first; - RefVec& regRefVec = (*I).second; + { + 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); + // 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 @@ SchedGraph::addEdgesForValue(SchedGraphNode* refNode, // 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 == 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->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 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& MI, // 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(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(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 @@ SchedGraph::addEdgesForInstruction(const MachineInstr& MI, MI.implicitRefIsDefinedAndUsed(i)) if (const Instruction *srcI = dyn_cast_or_null(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 @@ SchedGraph::findDefUseInfoAtInstr(const TargetMachine& target, // const MachineInstr& minstr = *node->getMachineInstr(); for (int i=0, numOps = (int) minstr.getNumOperands(); i < numOps; 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) { - 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!"); - - const Instruction* defInstr = cast(mop.getVRegValue()); - valueToDefVecMap[defInstr].push_back(std::make_pair(node, i)); + 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(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 @@ std::ostream &operator<<(std::ostream &os, const SchedGraphNode& node) 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]; + 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]; - } + 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; }