Index: include/llvm/CodeGen/MachineScheduler.h =================================================================== --- include/llvm/CodeGen/MachineScheduler.h +++ include/llvm/CodeGen/MachineScheduler.h @@ -84,6 +84,7 @@ #include "llvm/Analysis/AliasAnalysis.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachinePassRegistry.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/ScheduleDAGInstrs.h" @@ -681,6 +682,14 @@ unsigned MaxObservedStall; #endif + // Return true if checks should be done for the current issue group, + // involving NumMicroOps, BeginGroup and EndGroup of the instruction. + // Only do this post-RA if target enables late scheduling. + bool checkIssueGroupConstraints() { + return ((DAG->MF.getRegInfo().getNumVirtRegs() == 0) || + !DAG->MF.getSubtarget().enablePostRAScheduler()); + } + public: /// Pending queues extend the ready queues with the same ID and the /// PendingFlag set. Index: lib/CodeGen/MachineScheduler.cpp =================================================================== --- lib/CodeGen/MachineScheduler.cpp +++ lib/CodeGen/MachineScheduler.cpp @@ -1931,27 +1931,27 @@ /// simple counters that the scheduler itself maintains. It explicitly checks /// for instruction dispatch limitations, including the number of micro-ops that /// can dispatch per cycle. -/// -/// TODO: Also check whether the SU must start a new group. bool SchedBoundary::checkHazard(SUnit *SU) { if (HazardRec->isEnabled() && HazardRec->getHazardType(SU) != ScheduleHazardRecognizer::NoHazard) { return true; } - unsigned uops = SchedModel->getNumMicroOps(SU->getInstr()); - if ((CurrMOps > 0) && (CurrMOps + uops > SchedModel->getIssueWidth())) { - LLVM_DEBUG(dbgs() << " SU(" << SU->NodeNum << ") uops=" - << SchedModel->getNumMicroOps(SU->getInstr()) << '\n'); - return true; - } + if (checkIssueGroupConstraints()) { + unsigned uops = SchedModel->getNumMicroOps(SU->getInstr()); + if ((CurrMOps > 0) && (CurrMOps + uops > SchedModel->getIssueWidth())) { + LLVM_DEBUG(dbgs() << " SU(" << SU->NodeNum << ") uops=" + << SchedModel->getNumMicroOps(SU->getInstr()) << '\n'); + return true; + } - if (CurrMOps > 0 && - ((isTop() && SchedModel->mustBeginGroup(SU->getInstr())) || - (!isTop() && SchedModel->mustEndGroup(SU->getInstr())))) { - LLVM_DEBUG(dbgs() << " hazard: SU(" << SU->NodeNum << ") must " - << (isTop() ? "begin" : "end") << " group\n"); - return true; + if (CurrMOps > 0 && + ((isTop() && SchedModel->mustBeginGroup(SU->getInstr())) || + (!isTop() && SchedModel->mustEndGroup(SU->getInstr())))) { + LLVM_DEBUG(dbgs() << " hazard: SU(" << SU->NodeNum << ") must " + << (isTop() ? "begin" : "end") << " group\n"); + return true; + } } if (SchedModel->hasInstrSchedModel() && SU->hasReservedResource) { @@ -2147,9 +2147,9 @@ // exceed the issue width. const MCSchedClassDesc *SC = DAG->getSchedClass(SU); unsigned IncMOps = SchedModel->getNumMicroOps(SU->getInstr()); - assert( - (CurrMOps == 0 || (CurrMOps + IncMOps) <= SchedModel->getIssueWidth()) && - "Cannot schedule this instruction's MicroOps in the current cycle."); + assert((!checkIssueGroupConstraints() || (CurrMOps == 0 || + (CurrMOps + IncMOps) <= SchedModel->getIssueWidth())) && + "Cannot schedule this instruction's MicroOps in the current cycle."); unsigned ReadyCycle = (isTop() ? SU->TopReadyCycle : SU->BotReadyCycle); LLVM_DEBUG(dbgs() << " Ready @" << ReadyCycle << "c\n"); @@ -2257,11 +2257,12 @@ // This must be done after NextCycle has been adjust for all other stalls. // Calling bumpCycle(X) will reduce CurrMOps by one issue group and set // currCycle to X. - if ((isTop() && SchedModel->mustEndGroup(SU->getInstr())) || - (!isTop() && SchedModel->mustBeginGroup(SU->getInstr()))) { - LLVM_DEBUG(dbgs() << " Bump cycle to " << (isTop() ? "end" : "begin") - << " group\n"); - bumpCycle(++NextCycle); + if (checkIssueGroupConstraints() && + ((isTop() && SchedModel->mustEndGroup(SU->getInstr())) || + (!isTop() && SchedModel->mustBeginGroup(SU->getInstr())))) { + LLVM_DEBUG(dbgs() << " Bump cycle to " << (isTop() ? "end" : "begin") + << " group\n"); + bumpCycle(++NextCycle); } while (CurrMOps >= SchedModel->getIssueWidth()) { Index: test/CodeGen/ARM/single-issue-r52.mir =================================================================== --- test/CodeGen/ARM/single-issue-r52.mir +++ test/CodeGen/ARM/single-issue-r52.mir @@ -31,12 +31,12 @@ # CHECK: Single Issue : false; # TOPDOWN: Scheduling SU(1) %1:qqpr = VLD4d8Pseudo -# TOPDOWN: Bump cycle to end group +# TOPDOWN: *** Max MOps 7 at cycle 3 # TOPDOWN: Scheduling SU(2) %4:dpr = VADDv8i8 # BOTTOMUP: Scheduling SU(2) %4:dpr = VADDv8i8 # BOTTOMUP: Scheduling SU(1) %1:qqpr = VLD4d8Pseudo -# BOTTOMUP: Bump cycle to begin group +# BOTTOMUP: *** Max MOps 7 at cycle 19 ... --- Index: test/CodeGen/SystemZ/int-conv-11.ll =================================================================== --- test/CodeGen/SystemZ/int-conv-11.ll +++ test/CodeGen/SystemZ/int-conv-11.ll @@ -6,7 +6,7 @@ ; to use LLC(H) if possible. define void @f1(i32 *%ptr) { ; CHECK-LABEL: f1: -; CHECK: llc{{h?}} {{%r[0-9]+}}, 16{{[37]}}(%r15) +; CHECK: llc{{h?}} {{%r[0-9]+}}, 1{{[67]}}{{[379]}}(%r15) ; CHECK: br %r14 %val0 = load volatile i32 , i32 *%ptr %val1 = load volatile i32 , i32 *%ptr @@ -179,7 +179,7 @@ ; Same again with i16, which should use LLH(H). define void @f2(i32 *%ptr) { ; CHECK-LABEL: f2: -; CHECK: llh{{h?}} {{%r[0-9]+}}, 16{{[26]}}(%r15) +; CHECK: llh{{h?}} {{%r[0-9]+}}, 1{{[67]}}{{[268]}}(%r15) ; CHECK: br %r14 %val0 = load volatile i32 , i32 *%ptr %val1 = load volatile i32 , i32 *%ptr