Index: llvm/lib/CodeGen/MachinePipeliner.cpp =================================================================== --- llvm/lib/CodeGen/MachinePipeliner.cpp +++ llvm/lib/CodeGen/MachinePipeliner.cpp @@ -96,6 +96,14 @@ STATISTIC(NumTrytoPipeline, "Number of loops that we attempt to pipeline"); STATISTIC(NumPipelined, "Number of loops software pipelined"); STATISTIC(NumNodeOrderIssues, "Number of node order issues found"); +STATISTIC(NumFailBranch, "Pipeline failure due to unknown branch"); +STATISTIC(NumFailLoop, "Pipeline failure due to unsupported loop"); +STATISTIC(NumFailPreheader, "Pipeline failure due to missing preheader"); +STATISTIC(NumFailLargeMaxMII, "Pipeline failure due to MaxMII too large"); +STATISTIC(NumFailZeroMII, "Pipeline failure due to Zero MII "); +STATISTIC(NumFailNoSchedule, "Pipeline failure due to no schedule found"); +STATISTIC(NumFailZeroStage, "Pipeline failure due to Zero Stage "); +STATISTIC(NumFailLargeMaxStage, "Pipeline failure due to too many Stages "); /// A command line option to turn software pipelining on or off. static cl::opt EnableSWP("enable-pipeliner", cl::Hidden, cl::init(true), @@ -292,16 +300,28 @@ LI.TBB = nullptr; LI.FBB = nullptr; LI.BrCond.clear(); - if (TII->analyzeBranch(*L.getHeader(), LI.TBB, LI.FBB, LI.BrCond)) + if (TII->analyzeBranch(*L.getHeader(), LI.TBB, LI.FBB, LI.BrCond)) { + LLVM_DEBUG( + dbgs() << "Unable to analyzeBranch, can NOT pipeline current Loop\n"); + NumFailBranch++; return false; + } LI.LoopInductionVar = nullptr; LI.LoopCompare = nullptr; - if (TII->analyzeLoop(L, LI.LoopInductionVar, LI.LoopCompare)) + if (TII->analyzeLoop(L, LI.LoopInductionVar, LI.LoopCompare)) { + LLVM_DEBUG( + dbgs() << "Unable to analyzeLoop, can NOT pipeline current Loop\n"); + NumFailLoop++; return false; + } - if (!L.getLoopPreheader()) + if (!L.getLoopPreheader()) { + LLVM_DEBUG( + dbgs() << "Preheader not found, can NOT pipeline current Loop\n"); + NumFailPreheader++; return false; + } // Remove any subregisters from inputs to phi nodes. preprocessPhiNodes(*L.getHeader()); @@ -416,12 +436,21 @@ << " (rec=" << RecMII << ", res=" << ResMII << ")\n"); // Can't schedule a loop without a valid MII. - if (MII == 0) + if (MII == 0) { + LLVM_DEBUG( + dbgs() + << "0 is not a valid Minimal Initiation Interval, can NOT schedule\n"); + NumFailZeroMII++; return; + } // Don't pipeline large loops. - if (SwpMaxMii != -1 && (int)MII > SwpMaxMii) + if (SwpMaxMii != -1 && (int)MII > SwpMaxMii) { + LLVM_DEBUG(dbgs() << "MII > " << SwpMaxMii + << " ,we don't pipleline large loops\n"); + NumFailLargeMaxMII++; return; + } computeNodeFunctions(NodeSets); @@ -459,17 +488,27 @@ SMSchedule Schedule(Pass.MF); Scheduled = schedulePipeline(Schedule); - if (!Scheduled) + if (!Scheduled){ + LLVM_DEBUG(dbgs() << "No schedule found, return\n" ); + NumFailNoSchedule++; return; + } unsigned numStages = Schedule.getMaxStageCount(); // No need to generate pipeline if there are no overlapped iterations. - if (numStages == 0) + if (numStages == 0) { + LLVM_DEBUG( + dbgs() << "No overlapped iterations, no need to generate pipeline\n"); + NumFailZeroStage++; return; - + } // Check that the maximum stage count is less than user-defined limit. - if (SwpMaxStages > -1 && (int)numStages > SwpMaxStages) + if (SwpMaxStages > -1 && (int)numStages > SwpMaxStages) { + LLVM_DEBUG(dbgs() << "numStages:" << numStages << ">" << SwpMaxStages + << " : Too many stages, abort\n"); + NumFailLargeMaxStage++; return; + } generatePipelinedLoop(Schedule); ++NumPipelined; @@ -929,6 +968,7 @@ /// instruction cannot be reserved in an existing DFA, we create a new one. unsigned SwingSchedulerDAG::calculateResMII() { + LLVM_DEBUG(dbgs() << "calculateResMII:\n"); SmallVector Resources; MachineBasicBlock *MBB = Loop.getHeader(); Resources.push_back(new ResourceManager(&MF.getSubtarget())); @@ -959,6 +999,11 @@ unsigned ReservedCycles = 0; SmallVectorImpl::iterator RI = Resources.begin(); SmallVectorImpl::iterator RE = Resources.end(); + LLVM_DEBUG({ + dbgs() << "Trying to reserve resource for " << NumCycles + << " cycles for \n"; + MI->dump(); + }); for (unsigned C = 0; C < NumCycles; ++C) while (RI != RE) { if ((*RI++)->canReserveResources(*MI)) { @@ -971,8 +1016,13 @@ --RI; (*RI)->reserveResources(*MI); } + + LLVM_DEBUG(dbgs() << "ReservedCycles:" << ReservedCycles + << ", NumCycles:" << NumCycles << "\n"); // Add new DFAs, if needed, to reserve resources. for (unsigned C = ReservedCycles; C < NumCycles; ++C) { + LLVM_DEBUG(dbgs() << "NewResource created to reserve resources" + << "\n"); ResourceManager *NewResource = new ResourceManager(&MF.getSubtarget()); assert(NewResource->canReserveResources(*MI) && "Reserve error."); NewResource->reserveResources(*MI); @@ -980,6 +1030,7 @@ } } int Resmii = Resources.size(); + LLVM_DEBUG(dbgs() << "Retrun Res MII:" << Resmii << "\n"); // Delete the memory for each of the DFAs that were created earlier. for (ResourceManager *RI : Resources) { ResourceManager *D = RI; @@ -1865,8 +1916,11 @@ /// Process the nodes in the computed order and create the pipelined schedule /// of the instructions, if possible. Return true if a schedule is found. bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) { - if (NodeOrder.empty()) + + if (NodeOrder.empty()){ + LLVM_DEBUG(dbgs() << "NodeOrder is empty! abort scheduling\n" ); return false; + } bool scheduleFound = false; unsigned II = 0; @@ -1892,13 +1946,14 @@ Schedule.computeStart(SU, &EarlyStart, &LateStart, &SchedEnd, &SchedStart, II, this); LLVM_DEBUG({ + dbgs() << "\n"; dbgs() << "Inst (" << SU->NodeNum << ") "; SU->getInstr()->dump(); dbgs() << "\n"; }); LLVM_DEBUG({ - dbgs() << "\tes: " << EarlyStart << " ls: " << LateStart - << " me: " << SchedEnd << " ms: " << SchedStart << "\n"; + dbgs() << format("\tes: %8x ls: %8x me: %8x ms: %8x\n", EarlyStart, + LateStart, SchedEnd, SchedStart); }); if (EarlyStart > LateStart || SchedEnd < EarlyStart || @@ -3247,6 +3302,10 @@ /// the relative values of StartCycle and EndCycle. bool SMSchedule::insert(SUnit *SU, int StartCycle, int EndCycle, int II) { bool forward = true; + LLVM_DEBUG({ + dbgs() << "Try to insert node between " << StartCycle << " and " << EndCycle + << " II: " << II << "\n"; + }); if (StartCycle > EndCycle) forward = false;