LLVM 24.0.0git
MachinePipeliner.cpp
Go to the documentation of this file.
1//===- MachinePipeliner.cpp - Machine Software Pipeliner Pass -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// An implementation of the Swing Modulo Scheduling (SMS) software pipeliner.
10//
11// This SMS implementation is a target-independent back-end pass. When enabled,
12// the pass runs just prior to the register allocation pass, while the machine
13// IR is in SSA form. If software pipelining is successful, then the original
14// loop is replaced by the optimized loop. The optimized loop contains one or
15// more prolog blocks, the pipelined kernel, and one or more epilog blocks. If
16// the instructions cannot be scheduled in a given MII, we increase the MII by
17// one and try again.
18//
19// The SMS implementation is an extension of the ScheduleDAGInstrs class. We
20// represent loop carried dependences in the DAG as order edges to the Phi
21// nodes. We also perform several passes over the DAG to eliminate unnecessary
22// edges that inhibit the ability to pipeline. The implementation uses the
23// DFAPacketizer class to compute the minimum initiation interval and the check
24// where an instruction may be inserted in the pipelined schedule.
25//
26// In order for the SMS pass to work, several target specific hooks need to be
27// implemented to get information about the loop structure and to rewrite
28// instructions.
29//
30//===----------------------------------------------------------------------===//
31
33#include "llvm/ADT/ArrayRef.h"
34#include "llvm/ADT/BitVector.h"
35#include "llvm/ADT/DenseMap.h"
37#include "llvm/ADT/STLExtras.h"
39#include "llvm/ADT/SetVector.h"
41#include "llvm/ADT/SmallSet.h"
43#include "llvm/ADT/Statistic.h"
71#include "llvm/Config/llvm-config.h"
72#include "llvm/IR/Attributes.h"
73#include "llvm/IR/Function.h"
75#include "llvm/MC/LaneBitmask.h"
76#include "llvm/MC/MCInstrDesc.h"
78#include "llvm/Pass.h"
81#include "llvm/Support/Debug.h"
83#include <algorithm>
84#include <cassert>
85#include <climits>
86#include <cstdint>
87#include <deque>
88#include <functional>
89#include <iomanip>
90#include <iterator>
91#include <map>
92#include <memory>
93#include <sstream>
94#include <tuple>
95#include <utility>
96#include <vector>
97
98using namespace llvm;
99
100#define DEBUG_TYPE "pipeliner"
101
102STATISTIC(NumTrytoPipeline, "Number of loops that we attempt to pipeline");
103STATISTIC(NumPipelined, "Number of loops software pipelined");
104STATISTIC(NumNodeOrderIssues, "Number of node order issues found");
105STATISTIC(NumFailBranch, "Pipeliner abort due to unknown branch");
106STATISTIC(NumFailLoop, "Pipeliner abort due to unsupported loop");
107STATISTIC(NumFailPreheader, "Pipeliner abort due to missing preheader");
108STATISTIC(NumFailLargeMaxMII, "Pipeliner abort due to MaxMII too large");
109STATISTIC(NumFailZeroMII, "Pipeliner abort due to zero MII");
110STATISTIC(NumFailNoSchedule, "Pipeliner abort due to no schedule found");
111STATISTIC(NumFailZeroStage, "Pipeliner abort due to zero stage");
112STATISTIC(NumFailLargeMaxStage, "Pipeliner abort due to too many stages");
113STATISTIC(NumFailTooManyStores, "Pipeliner abort due to too many stores");
114
115/// A command line option to turn software pipelining on or off.
116static cl::opt<bool> EnableSWP("enable-pipeliner", cl::Hidden, cl::init(true),
117 cl::desc("Enable Software Pipelining"));
118
119/// A command line option to enable SWP at -Os.
120static cl::opt<bool> EnableSWPOptSize("enable-pipeliner-opt-size",
121 cl::desc("Enable SWP at Os."), cl::Hidden,
122 cl::init(false));
123
124/// A command line argument to limit minimum initial interval for pipelining.
125static cl::opt<int> SwpMaxMii("pipeliner-max-mii",
126 cl::desc("Size limit for the MII."),
127 cl::Hidden, cl::init(27));
128
129/// A command line argument to force pipeliner to use specified initial
130/// interval.
131static cl::opt<int> SwpForceII("pipeliner-force-ii",
132 cl::desc("Force pipeliner to use specified II."),
133 cl::Hidden, cl::init(-1));
134
135/// A command line argument to limit the number of stages in the pipeline.
136static cl::opt<int>
137 SwpMaxStages("pipeliner-max-stages",
138 cl::desc("Maximum stages allowed in the generated scheduled."),
139 cl::Hidden, cl::init(3));
140
141/// A command line option to disable the pruning of chain dependences due to
142/// an unrelated Phi.
143static cl::opt<bool>
144 SwpPruneDeps("pipeliner-prune-deps",
145 cl::desc("Prune dependences between unrelated Phi nodes."),
146 cl::Hidden, cl::init(true));
147
148/// A command line option to disable the pruning of loop carried order
149/// dependences.
150static cl::opt<bool>
151 SwpPruneLoopCarried("pipeliner-prune-loop-carried",
152 cl::desc("Prune loop carried order dependences."),
153 cl::Hidden, cl::init(true));
154
155#ifndef NDEBUG
156static cl::opt<int> SwpLoopLimit("pipeliner-max", cl::Hidden, cl::init(-1));
157#endif
158
159static cl::opt<bool> SwpIgnoreRecMII("pipeliner-ignore-recmii",
161 cl::desc("Ignore RecMII"));
162
163static cl::opt<bool> SwpShowResMask("pipeliner-show-mask", cl::Hidden,
164 cl::init(false));
165static cl::opt<bool> SwpDebugResource("pipeliner-dbg-res", cl::Hidden,
166 cl::init(false));
167
169 "pipeliner-annotate-for-testing", cl::Hidden, cl::init(false),
170 cl::desc("Instead of emitting the pipelined code, annotate instructions "
171 "with the generated schedule for feeding into the "
172 "-modulo-schedule-test pass"));
173
175 "pipeliner-experimental-cg", cl::Hidden, cl::init(false),
176 cl::desc(
177 "Use the experimental peeling code generator for software pipelining"));
178
179static cl::opt<int> SwpIISearchRange("pipeliner-ii-search-range",
180 cl::desc("Range to search for II"),
181 cl::Hidden, cl::init(10));
182
183static cl::opt<bool>
184 LimitRegPressure("pipeliner-register-pressure", cl::Hidden, cl::init(false),
185 cl::desc("Limit register pressure of scheduled loop"));
186
187static cl::opt<int>
188 RegPressureMargin("pipeliner-register-pressure-margin", cl::Hidden,
189 cl::init(5),
190 cl::desc("Margin representing the unused percentage of "
191 "the register pressure limit"));
192
193static cl::opt<bool>
194 MVECodeGen("pipeliner-mve-cg", cl::Hidden, cl::init(false),
195 cl::desc("Use the MVE code generator for software pipelining"));
196
197/// A command line argument to limit the number of store instructions in the
198/// target basic block.
200 "pipeliner-max-num-stores",
201 cl::desc("Maximum number of stores allwed in the target loop."), cl::Hidden,
202 cl::init(200));
203
204// A command line option to enable the CopyToPhi DAG mutation.
206 llvm::SwpEnableCopyToPhi("pipeliner-enable-copytophi", cl::ReallyHidden,
207 cl::init(true),
208 cl::desc("Enable CopyToPhi DAG Mutation"));
209
210/// A command line argument to force pipeliner to use specified issue
211/// width.
213 "pipeliner-force-issue-width",
214 cl::desc("Force pipeliner to use specified issue width."), cl::Hidden,
215 cl::init(-1));
216
217/// A command line argument to set the window scheduling option.
220 cl::desc("Set how to use window scheduling algorithm."),
222 "Turn off window algorithm."),
224 "Use window algorithm after SMS algorithm fails."),
226 "Use window algorithm instead of SMS algorithm.")));
227
228unsigned SwingSchedulerDAG::Circuits::MaxPaths = 5;
229char MachinePipeliner::ID = 0;
230#ifndef NDEBUG
232#endif
234
236 "Modulo Software Pipelining", false, false)
242 "Modulo Software Pipelining", false, false)
243
244namespace {
245
246/// This class holds an SUnit corresponding to a memory operation and other
247/// information related to the instruction.
251
252 /// The value of a memory operand.
253 const Value *MemOpValue = nullptr;
254
255 /// The offset of a memory operand.
256 int64_t MemOpOffset = 0;
257
259
260 /// True if all the underlying objects are identified.
261 bool IsAllIdentified = false;
262
264
265 bool isTriviallyDisjoint(const SUnitWithMemInfo &Other) const;
266
267 bool isUnknown() const { return MemOpValue == nullptr; }
268
269private:
271};
272
273/// Add loop-carried chain dependencies. This class handles the same type of
274/// dependencies added by `ScheduleDAGInstrs::buildSchedGraph`, but takes into
275/// account dependencies across iterations.
277 // Type of instruction that is relevant to order-dependencies
278 enum class InstrTag {
279 Barrier = 0, ///< A barrier event instruction.
280 LoadOrStore = 1, ///< An instruction that may load or store memory, but is
281 ///< not a barrier event.
282 FPExceptions = 2, ///< An instruction that does not match above, but may
283 ///< raise floatin-point exceptions.
284 };
285
286 struct TaggedSUnit : PointerIntPair<SUnit *, 2> {
287 TaggedSUnit(SUnit *SU, InstrTag Tag)
288 : PointerIntPair<SUnit *, 2>(SU, unsigned(Tag)) {}
289
290 InstrTag getTag() const { return InstrTag(getInt()); }
291 };
292
293 /// Holds instructions that may form loop-carried order-dependencies, but not
294 /// global barriers.
295 struct NoBarrierInstsChunk {
299
300 void append(SUnit *SU);
301 };
302
304 BatchAAResults *BAA;
305 std::vector<SUnit> &SUnits;
306
307 /// The size of SUnits, for convenience.
308 const unsigned N;
309
310 /// Loop-carried Edges.
311 std::vector<BitVector> LoopCarried;
312
313 /// Instructions related to chain dependencies. They are one of the
314 /// following:
315 ///
316 /// 1. Barrier event.
317 /// 2. Load, but neither a barrier event, invariant load, nor may load trap
318 /// value.
319 /// 3. Store, but not a barrier event.
320 /// 4. None of them, but may raise floating-point exceptions.
321 ///
322 /// This is used when analyzing loop-carried dependencies that access global
323 /// barrier instructions.
324 std::vector<TaggedSUnit> TaggedSUnits;
325
326 const TargetInstrInfo *TII = nullptr;
327 const TargetRegisterInfo *TRI = nullptr;
328
329public:
331 const TargetInstrInfo *TII,
332 const TargetRegisterInfo *TRI);
333
334 /// The main function to compute loop-carried order-dependencies.
335 void computeDependencies();
336
337 const BitVector &getLoopCarried(unsigned Idx) const {
338 return LoopCarried[Idx];
339 }
340
341private:
342 /// Tags to \p SU if the instruction may affect the order-dependencies.
343 std::optional<InstrTag> getInstrTag(SUnit *SU) const;
344
345 void addLoopCarriedDepenenciesForChunks(const NoBarrierInstsChunk &From,
346 const NoBarrierInstsChunk &To);
347
348 /// Add a loop-carried order dependency between \p Src and \p Dst if we
349 /// cannot prove they are independent.
350 void addDependenciesBetweenSUs(const SUnitWithMemInfo &Src,
351 const SUnitWithMemInfo &Dst);
352
353 void computeDependenciesAux();
354
355 void setLoopCarriedDep(const SUnit *Src, const SUnit *Dst) {
356 LoopCarried[Src->NodeNum].set(Dst->NodeNum);
357 }
358};
359
360} // end anonymous namespace
361
362/// The "main" function for implementing Swing Modulo Scheduling.
364 if (skipFunction(mf.getFunction()))
365 return false;
366
367 if (!EnableSWP)
368 return false;
369
370 if (mf.getFunction().getAttributes().hasFnAttr(Attribute::OptimizeForSize) &&
371 !EnableSWPOptSize.getPosition())
372 return false;
373
375 return false;
376
377 // Cannot pipeline loops without instruction itineraries if we are using
378 // DFA for the pipeliner.
379 if (mf.getSubtarget().useDFAforSMS() &&
382 return false;
383
384 MF = &mf;
388 TII = MF->getSubtarget().getInstrInfo();
389
390 for (const auto &L : *MLI)
391 scheduleLoop(*L);
392
393 return false;
394}
395
396/// Attempt to perform the SMS algorithm on the specified loop. This function is
397/// the main entry point for the algorithm. The function identifies candidate
398/// loops, calculates the minimum initiation interval, and attempts to schedule
399/// the loop.
400bool MachinePipeliner::scheduleLoop(MachineLoop &L) {
401 bool Changed = false;
402 for (const auto &InnerLoop : L)
403 Changed |= scheduleLoop(*InnerLoop);
404
405#ifndef NDEBUG
406 // Stop trying after reaching the limit (if any).
407 int Limit = SwpLoopLimit;
408 if (Limit >= 0) {
409 if (NumTries >= SwpLoopLimit)
410 return Changed;
411 NumTries++;
412 }
413#endif
414
415 setPragmaPipelineOptions(L);
416 if (!canPipelineLoop(L)) {
417 LLVM_DEBUG(dbgs() << "\n!!! Can not pipeline loop.\n");
418 ORE->emit([&]() {
419 return MachineOptimizationRemarkMissed(DEBUG_TYPE, "canPipelineLoop",
420 L.getStartLoc(), L.getHeader())
421 << "Failed to pipeline loop";
422 });
423
424 LI.LoopPipelinerInfo.reset();
425 return Changed;
426 }
427
428 ++NumTrytoPipeline;
429 if (useSwingModuloScheduler())
430 Changed = swingModuloScheduler(L);
431
432 if (useWindowScheduler(Changed))
433 Changed = runWindowScheduler(L);
434
435 LI.LoopPipelinerInfo.reset();
436 return Changed;
437}
438
439void MachinePipeliner::setPragmaPipelineOptions(MachineLoop &L) {
440 // Reset the pragma for the next loop in iteration.
441 disabledByPragma = false;
442 II_setByPragma = 0;
443
444 MachineBasicBlock *LBLK = L.getTopBlock();
445
446 if (LBLK == nullptr)
447 return;
448
449 const BasicBlock *BBLK = LBLK->getBasicBlock();
450 if (BBLK == nullptr)
451 return;
452
453 const Instruction *TI = BBLK->getTerminator();
454 if (TI == nullptr)
455 return;
456
457 MDNode *LoopID = TI->getMetadata(LLVMContext::MD_loop);
458 if (LoopID == nullptr)
459 return;
460
461 assert(LoopID->getNumOperands() > 0 && "requires atleast one operand");
462 assert(LoopID->getOperand(0) == LoopID && "invalid loop");
463
464 for (const MDOperand &MDO : llvm::drop_begin(LoopID->operands())) {
465 MDNode *MD = dyn_cast<MDNode>(MDO);
466
467 if (MD == nullptr)
468 continue;
469
470 MDString *S = dyn_cast<MDString>(MD->getOperand(0));
471
472 if (S == nullptr)
473 continue;
474
475 if (S->getString() == "llvm.loop.pipeline.initiationinterval") {
476 assert(MD->getNumOperands() == 2 &&
477 "Pipeline initiation interval hint metadata should have two operands.");
479 mdconst::extract<ConstantInt>(MD->getOperand(1))->getZExtValue();
480 assert(II_setByPragma >= 1 && "Pipeline initiation interval must be positive.");
481 } else if (S->getString() == "llvm.loop.pipeline.disable") {
482 disabledByPragma = true;
483 }
484 }
485}
486
487/// Depth-first search to detect cycles among PHI dependencies.
488/// Returns true if a cycle is detected within the PHI-only subgraph.
489static bool hasPHICycleDFS(
490 unsigned Reg, const DenseMap<unsigned, SmallVector<unsigned, 2>> &PhiDeps,
491 SmallSet<unsigned, 8> &Visited, SmallSet<unsigned, 8> &RecStack) {
492
493 // If Reg is not a PHI-def it cannot contribute to a PHI cycle.
494 auto It = PhiDeps.find(Reg);
495 if (It == PhiDeps.end())
496 return false;
497
498 if (RecStack.count(Reg))
499 return true; // backedge.
500 if (Visited.count(Reg))
501 return false;
502
503 Visited.insert(Reg);
504 RecStack.insert(Reg);
505
506 for (unsigned Dep : It->second) {
507 if (hasPHICycleDFS(Dep, PhiDeps, Visited, RecStack))
508 return true;
509 }
510
511 RecStack.erase(Reg);
512 return false;
513}
514
515static bool hasPHICycle(const MachineBasicBlock *LoopHeader,
516 const MachineRegisterInfo &MRI) {
518
519 // Collect PHI nodes and their dependencies.
520 for (const MachineInstr &MI : LoopHeader->phis()) {
521 unsigned DefReg = MI.getOperand(0).getReg();
522 auto Ins = PhiDeps.try_emplace(DefReg).first;
523
524 // PHI operands are (Reg, MBB) pairs starting at index 1.
525 for (unsigned I = 1; I < MI.getNumOperands(); I += 2)
526 Ins->second.push_back(MI.getOperand(I).getReg());
527 }
528
529 // DFS to detect cycles among PHI nodes.
530 SmallSet<unsigned, 8> Visited, RecStack;
531
532 // Start DFS from each PHI-def.
533 for (const auto &KV : PhiDeps) {
534 unsigned Reg = KV.first;
535 if (hasPHICycleDFS(Reg, PhiDeps, Visited, RecStack))
536 return true;
537 }
538
539 return false;
540}
541
542/// Return true if the loop can be software pipelined. The algorithm is
543/// restricted to loops with a single basic block. Make sure that the
544/// branch in the loop can be analyzed.
545bool MachinePipeliner::canPipelineLoop(MachineLoop &L) {
546 if (L.getNumBlocks() != 1) {
547 ORE->emit([&]() {
548 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
549 L.getStartLoc(), L.getHeader())
550 << "Not a single basic block: "
551 << ore::NV("NumBlocks", L.getNumBlocks());
552 });
553 return false;
554 }
555
556 if (hasPHICycle(L.getHeader(), MF->getRegInfo())) {
557 LLVM_DEBUG(dbgs() << "Cannot pipeline loop due to PHI cycle\n");
558 return false;
559 }
560
561 if (disabledByPragma) {
562 ORE->emit([&]() {
563 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
564 L.getStartLoc(), L.getHeader())
565 << "Disabled by Pragma.";
566 });
567 return false;
568 }
569
570 // Check if the branch can't be understood because we can't do pipelining
571 // if that's the case.
572 LI.TBB = nullptr;
573 LI.FBB = nullptr;
574 LI.BrCond.clear();
575 if (TII->analyzeBranch(*L.getHeader(), LI.TBB, LI.FBB, LI.BrCond)) {
576 LLVM_DEBUG(dbgs() << "Unable to analyzeBranch, can NOT pipeline Loop\n");
577 NumFailBranch++;
578 ORE->emit([&]() {
579 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
580 L.getStartLoc(), L.getHeader())
581 << "The branch can't be understood";
582 });
583 return false;
584 }
585
586 LI.LoopInductionVar = nullptr;
587 LI.LoopCompare = nullptr;
588 LI.LoopPipelinerInfo = TII->analyzeLoopForPipelining(L.getTopBlock());
589 if (!LI.LoopPipelinerInfo) {
590 LLVM_DEBUG(dbgs() << "Unable to analyzeLoop, can NOT pipeline Loop\n");
591 NumFailLoop++;
592 ORE->emit([&]() {
593 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
594 L.getStartLoc(), L.getHeader())
595 << "The loop structure is not supported";
596 });
597 return false;
598 }
599
600 if (!L.getLoopPreheader()) {
601 LLVM_DEBUG(dbgs() << "Preheader not found, can NOT pipeline Loop\n");
602 NumFailPreheader++;
603 ORE->emit([&]() {
604 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
605 L.getStartLoc(), L.getHeader())
606 << "No loop preheader found";
607 });
608 return false;
609 }
610
611 unsigned NumStores = 0;
612 for (MachineInstr &MI : *L.getHeader())
613 if (MI.mayStore())
614 ++NumStores;
615 if (NumStores > SwpMaxNumStores) {
616 LLVM_DEBUG(dbgs() << "Too many stores\n");
617 NumFailTooManyStores++;
618 ORE->emit([&]() {
619 return MachineOptimizationRemarkAnalysis(DEBUG_TYPE, "canPipelineLoop",
620 L.getStartLoc(), L.getHeader())
621 << "Too many store instructions in the loop: "
622 << ore::NV("NumStores", NumStores) << " > "
623 << ore::NV("SwpMaxNumStores", SwpMaxNumStores) << ".";
624 });
625 return false;
626 }
627
628 // Remove any subregisters from inputs to phi nodes.
629 preprocessPhiNodes(*L.getHeader());
630 return true;
631}
632
633void MachinePipeliner::preprocessPhiNodes(MachineBasicBlock &B) {
634 MachineRegisterInfo &MRI = MF->getRegInfo();
635 SlotIndexes &Slots =
636 *getAnalysis<LiveIntervalsWrapperPass>().getLIS().getSlotIndexes();
637
638 for (MachineInstr &PI : B.phis()) {
639 MachineOperand &DefOp = PI.getOperand(0);
640 assert(DefOp.getSubReg() == 0);
641 auto *RC = MRI.getRegClass(DefOp.getReg());
642
643 for (unsigned i = 1, n = PI.getNumOperands(); i != n; i += 2) {
644 MachineOperand &RegOp = PI.getOperand(i);
645 if (RegOp.getSubReg() == 0)
646 continue;
647
648 // If the operand uses a subregister, replace it with a new register
649 // without subregisters, and generate a copy to the new register.
650 Register NewReg = MRI.createVirtualRegister(RC);
651 MachineBasicBlock &PredB = *PI.getOperand(i+1).getMBB();
653 const DebugLoc &DL = PredB.findDebugLoc(At);
654 auto Copy = BuildMI(PredB, At, DL, TII->get(TargetOpcode::COPY), NewReg)
655 .addReg(RegOp.getReg(), getRegState(RegOp),
656 RegOp.getSubReg());
657 Slots.insertMachineInstrInMaps(*Copy);
658 RegOp.setReg(NewReg);
659 RegOp.setSubReg(0);
660 }
661 }
662}
663
664/// The SMS algorithm consists of the following main steps:
665/// 1. Computation and analysis of the dependence graph.
666/// 2. Ordering of the nodes (instructions).
667/// 3. Attempt to Schedule the loop.
668bool MachinePipeliner::swingModuloScheduler(MachineLoop &L) {
669 assert(L.getBlocks().size() == 1 && "SMS works on single blocks only.");
670
671 AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
672 SwingSchedulerDAG SMS(
674 II_setByPragma, LI.LoopPipelinerInfo.get(), AA);
675
676 MachineBasicBlock *MBB = L.getHeader();
677 // The kernel should not include any terminator instructions. These
678 // will be added back later.
679 SMS.startBlock(MBB);
680
681 // Compute the number of 'real' instructions in the basic block by
682 // ignoring terminators.
683 unsigned size = MBB->size();
685 E = MBB->instr_end();
686 I != E; ++I, --size)
687 ;
688
689 SMS.enterRegion(MBB, MBB->begin(), MBB->getFirstTerminator(), size);
690 SMS.schedule();
691 SMS.exitRegion();
692
693 SMS.finishBlock();
694 return SMS.hasNewSchedule();
695}
696
708
709bool MachinePipeliner::runWindowScheduler(MachineLoop &L) {
710 MachineSchedContext Context;
711 Context.MF = MF;
712 Context.MLI = MLI;
713 Context.TM = &getAnalysis<TargetPassConfig>().getTM<TargetMachine>();
714 Context.AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
715 Context.LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
716 Context.RegClassInfo =
718 WindowScheduler WS(&Context, L);
719 return WS.run();
720}
721
722bool MachinePipeliner::useSwingModuloScheduler() {
723 // SwingModuloScheduler does not work when WindowScheduler is forced.
725}
726
727bool MachinePipeliner::useWindowScheduler(bool Changed) {
728 // WindowScheduler does not work for following cases:
729 // 1. when it is off.
730 // 2. when SwingModuloScheduler is successfully scheduled.
731 // 3. when pragma II is enabled.
732 if (II_setByPragma) {
733 LLVM_DEBUG(dbgs() << "Window scheduling is disabled when "
734 "llvm.loop.pipeline.initiationinterval is set.\n");
735 return false;
736 }
737
740}
741
742void SwingSchedulerDAG::setMII(unsigned ResMII, unsigned RecMII) {
743 if (SwpForceII > 0)
744 MII = SwpForceII;
745 else if (II_setByPragma > 0)
746 MII = II_setByPragma;
747 else
748 MII = std::max(ResMII, RecMII);
749}
750
751void SwingSchedulerDAG::setMAX_II() {
752 if (SwpForceII > 0)
753 MAX_II = SwpForceII;
754 else if (II_setByPragma > 0)
755 MAX_II = II_setByPragma;
756 else
757 MAX_II = MII + SwpIISearchRange;
758}
759
760/// We override the schedule function in ScheduleDAGInstrs to implement the
761/// scheduling part of the Swing Modulo Scheduling algorithm.
763 buildSchedGraph(AA);
764 const LoopCarriedEdges LCE = addLoopCarriedDependences();
765 updatePhiDependences();
766 Topo.InitDAGTopologicalSorting();
767 changeDependences();
768 postProcessDAG();
769 DDG = std::make_unique<SwingSchedulerDDG>(SUnits, &EntrySU, &ExitSU, LCE);
770 LLVM_DEBUG({
771 dump();
772 dbgs() << "===== Loop Carried Edges Begin =====\n";
773 for (SUnit &SU : SUnits)
774 LCE.dump(&SU, TRI, &MRI);
775 dbgs() << "===== Loop Carried Edges End =====\n";
776 });
777
778 NodeSetType NodeSets;
779 findCircuits(NodeSets);
780 NodeSetType Circuits = NodeSets;
781
782 // Calculate the MII.
783 unsigned ResMII = calculateResMII();
784 unsigned RecMII = calculateRecMII(NodeSets);
785
786 fuseRecs(NodeSets);
787
788 // This flag is used for testing and can cause correctness problems.
789 if (SwpIgnoreRecMII)
790 RecMII = 0;
791
792 setMII(ResMII, RecMII);
793 setMAX_II();
794
795 LLVM_DEBUG(dbgs() << "MII = " << MII << " MAX_II = " << MAX_II
796 << " (rec=" << RecMII << ", res=" << ResMII << ")\n");
797
798 // Can't schedule a loop without a valid MII.
799 if (MII == 0) {
800 LLVM_DEBUG(dbgs() << "Invalid Minimal Initiation Interval: 0\n");
801 NumFailZeroMII++;
802 Pass.ORE->emit([&]() {
804 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
805 << "Invalid Minimal Initiation Interval: 0";
806 });
807 return;
808 }
809
810 // Don't pipeline large loops.
811 if (SwpMaxMii != -1 && (int)MII > SwpMaxMii) {
812 LLVM_DEBUG(dbgs() << "MII > " << SwpMaxMii
813 << ", we don't pipeline large loops\n");
814 NumFailLargeMaxMII++;
815 Pass.ORE->emit([&]() {
817 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
818 << "Minimal Initiation Interval too large: "
819 << ore::NV("MII", (int)MII) << " > "
820 << ore::NV("SwpMaxMii", SwpMaxMii) << "."
821 << "Refer to -pipeliner-max-mii.";
822 });
823 return;
824 }
825
826 computeNodeFunctions(NodeSets);
827
828 registerPressureFilter(NodeSets);
829
830 colocateNodeSets(NodeSets);
831
832 checkNodeSets(NodeSets);
833
834 LLVM_DEBUG({
835 for (auto &I : NodeSets) {
836 dbgs() << " Rec NodeSet ";
837 I.dump();
838 }
839 });
840
841 llvm::stable_sort(NodeSets, std::greater<NodeSet>());
842
843 groupRemainingNodes(NodeSets);
844
845 removeDuplicateNodes(NodeSets);
846
847 LLVM_DEBUG({
848 for (auto &I : NodeSets) {
849 dbgs() << " NodeSet ";
850 I.dump();
851 }
852 });
853
854 computeNodeOrder(NodeSets);
855
856 // check for node order issues
857 checkValidNodeOrder(Circuits);
858
859 SMSchedule Schedule(Pass.MF, this);
860 Scheduled = schedulePipeline(Schedule);
861
862 if (!Scheduled){
863 LLVM_DEBUG(dbgs() << "No schedule found, return\n");
864 NumFailNoSchedule++;
865 Pass.ORE->emit([&]() {
867 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
868 << "Unable to find schedule";
869 });
870 return;
871 }
872
873 unsigned numStages = Schedule.getMaxStageCount();
874 // No need to generate pipeline if there are no overlapped iterations.
875 if (numStages == 0) {
876 LLVM_DEBUG(dbgs() << "No overlapped iterations, skip.\n");
877 NumFailZeroStage++;
878 Pass.ORE->emit([&]() {
880 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
881 << "No need to pipeline - no overlapped iterations in schedule.";
882 });
883 return;
884 }
885 // Check that the maximum stage count is less than user-defined limit.
886 if (SwpMaxStages > -1 && (int)numStages > SwpMaxStages) {
887 LLVM_DEBUG(dbgs() << "numStages:" << numStages << ">" << SwpMaxStages
888 << " : too many stages, abort\n");
889 NumFailLargeMaxStage++;
890 Pass.ORE->emit([&]() {
892 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
893 << "Too many stages in schedule: "
894 << ore::NV("numStages", (int)numStages) << " > "
895 << ore::NV("SwpMaxStages", SwpMaxStages)
896 << ". Refer to -pipeliner-max-stages.";
897 });
898 return;
899 }
900
901 Pass.ORE->emit([&]() {
902 return MachineOptimizationRemark(DEBUG_TYPE, "schedule", Loop.getStartLoc(),
903 Loop.getHeader())
904 << "Pipelined succesfully!";
905 });
906
907 // Generate the schedule as a ModuloSchedule.
908 DenseMap<MachineInstr *, int> Cycles, Stages;
909 std::vector<MachineInstr *> OrderedInsts;
910 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
911 ++Cycle) {
912 for (SUnit *SU : Schedule.getInstructions(Cycle)) {
913 OrderedInsts.push_back(SU->getInstr());
914 Cycles[SU->getInstr()] = Cycle;
915 Stages[SU->getInstr()] = Schedule.stageScheduled(SU);
916 }
917 }
919 for (auto &KV : NewMIs) {
920 Cycles[KV.first] = Cycles[KV.second];
921 Stages[KV.first] = Stages[KV.second];
922 NewInstrChanges[KV.first] = InstrChanges[getSUnit(KV.first)];
923 }
924
925 ModuloSchedule MS(MF, &Loop, std::move(OrderedInsts), std::move(Cycles),
926 std::move(Stages));
928 assert(NewInstrChanges.empty() &&
929 "Cannot serialize a schedule with InstrChanges!");
931 MSTI.annotate();
932 return;
933 }
934 // The experimental code generator can't work if there are InstChanges.
935 if (ExperimentalCodeGen && NewInstrChanges.empty()) {
936 PeelingModuloScheduleExpander MSE(MF, MS, &LIS);
937 MSE.expand();
938 } else if (MVECodeGen && NewInstrChanges.empty() &&
939 LoopPipelinerInfo->isMVEExpanderSupported() &&
941 ModuloScheduleExpanderMVE MSE(MF, MS, LIS);
942 MSE.expand();
943 } else {
944 ModuloScheduleExpander MSE(MF, MS, LIS, std::move(NewInstrChanges));
945 MSE.expand();
946 MSE.cleanup();
947 }
948 ++NumPipelined;
949}
950
951/// Clean up after the software pipeliner runs.
953 for (auto &KV : NewMIs)
954 MF.deleteMachineInstr(KV.second);
955 NewMIs.clear();
956
957 // Call the superclass.
959}
960
961/// Return the register values for the operands of a Phi instruction.
962/// This function assume the instruction is a Phi.
964 Register &InitVal, Register &LoopVal) {
965 assert(Phi.isPHI() && "Expecting a Phi.");
966
967 InitVal = Register();
968 LoopVal = Register();
969 for (unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
970 if (Phi.getOperand(i + 1).getMBB() != Loop)
971 InitVal = Phi.getOperand(i).getReg();
972 else
973 LoopVal = Phi.getOperand(i).getReg();
974
975 assert(InitVal && LoopVal && "Unexpected Phi structure.");
976}
977
978/// Return the Phi register value that comes the loop block.
980 const MachineBasicBlock *LoopBB) {
981 for (unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
982 if (Phi.getOperand(i + 1).getMBB() == LoopBB)
983 return Phi.getOperand(i).getReg();
984 return Register();
985}
986
987/// Return true if SUb can be reached from SUa following the chain edges.
988static bool isSuccOrder(SUnit *SUa, SUnit *SUb) {
991 Worklist.push_back(SUa);
992 while (!Worklist.empty()) {
993 const SUnit *SU = Worklist.pop_back_val();
994 for (const auto &SI : SU->Succs) {
995 SUnit *SuccSU = SI.getSUnit();
996 if (SI.getKind() == SDep::Order) {
997 if (Visited.count(SuccSU))
998 continue;
999 if (SuccSU == SUb)
1000 return true;
1001 Worklist.push_back(SuccSU);
1002 Visited.insert(SuccSU);
1003 }
1004 }
1005 }
1006 return false;
1007}
1008
1010 if (!getUnderlyingObjects())
1011 return;
1012 for (const Value *Obj : UnderlyingObjs)
1013 if (!isIdentifiedObject(Obj)) {
1014 IsAllIdentified = false;
1015 break;
1016 }
1017}
1018
1020 const SUnitWithMemInfo &Other) const {
1021 // If all underlying objects are identified objects and there is no overlap
1022 // between them, then these two instructions are disjoint.
1023 if (!IsAllIdentified || !Other.IsAllIdentified)
1024 return false;
1025 for (const Value *Obj : UnderlyingObjs)
1026 if (llvm::is_contained(Other.UnderlyingObjs, Obj))
1027 return false;
1028 return true;
1029}
1030
1031/// Collect the underlying objects for the memory references of an instruction.
1032/// This function calls the code in ValueTracking, but first checks that the
1033/// instruction has a memory operand.
1034/// Returns false if we cannot find the underlying objects.
1035bool SUnitWithMemInfo::getUnderlyingObjects() {
1036 const MachineInstr *MI = SU->getInstr();
1037 if (!MI->hasOneMemOperand())
1038 return false;
1039 MachineMemOperand *MM = *MI->memoperands_begin();
1040 if (!MM->getValue())
1041 return false;
1042 MemOpValue = MM->getValue();
1043 MemOpOffset = MM->getOffset();
1045
1046 // TODO: A no alias scope may be valid only in a single iteration. In this
1047 // case we need to peel off it like LoopAccessAnalysis does.
1048 AATags = MM->getAAInfo();
1049 return true;
1050}
1051
1052/// Returns true if there is a loop-carried order dependency from \p Src to \p
1053/// Dst.
1054static bool hasLoopCarriedMemDep(const SUnitWithMemInfo &Src,
1055 const SUnitWithMemInfo &Dst,
1056 BatchAAResults &BAA,
1057 const TargetInstrInfo *TII,
1058 const TargetRegisterInfo *TRI,
1059 const SwingSchedulerDAG *SSD) {
1060 if (Src.isTriviallyDisjoint(Dst))
1061 return false;
1062 if (isSuccOrder(Src.SU, Dst.SU))
1063 return false;
1064
1065 MachineInstr &SrcMI = *Src.SU->getInstr();
1066 MachineInstr &DstMI = *Dst.SU->getInstr();
1067
1068 if (!SSD->mayOverlapInLaterIter(&SrcMI, &DstMI))
1069 return false;
1070
1071 // Second, the more expensive check that uses alias analysis on the
1072 // base registers. If they alias, and the load offset is less than
1073 // the store offset, the mark the dependence as loop carried.
1074 if (Src.isUnknown() || Dst.isUnknown())
1075 return true;
1076 if (Src.MemOpValue == Dst.MemOpValue && Src.MemOpOffset <= Dst.MemOpOffset)
1077 return true;
1078
1079 if (BAA.isNoAlias(
1080 MemoryLocation::getBeforeOrAfter(Src.MemOpValue, Src.AATags),
1081 MemoryLocation::getBeforeOrAfter(Dst.MemOpValue, Dst.AATags)))
1082 return false;
1083
1084 // AliasAnalysis sometimes gives up on following the underlying
1085 // object. In such a case, separate checks for underlying objects may
1086 // prove that there are no aliases between two accesses.
1087 for (const Value *SrcObj : Src.UnderlyingObjs)
1088 for (const Value *DstObj : Dst.UnderlyingObjs)
1089 if (!BAA.isNoAlias(MemoryLocation::getBeforeOrAfter(SrcObj, Src.AATags),
1090 MemoryLocation::getBeforeOrAfter(DstObj, Dst.AATags)))
1091 return true;
1092
1093 return false;
1094}
1095
1096void LoopCarriedOrderDepsTracker::NoBarrierInstsChunk::append(SUnit *SU) {
1097 const MachineInstr *MI = SU->getInstr();
1098 if (MI->mayStore())
1099 Stores.emplace_back(SU);
1100 else if (MI->mayLoad())
1101 Loads.emplace_back(SU);
1102 else if (MI->mayRaiseFPException())
1103 FPExceptions.emplace_back(SU);
1104 else
1105 llvm_unreachable("Unexpected instruction type.");
1106}
1107
1109 SwingSchedulerDAG *SSD, BatchAAResults *BAA, const TargetInstrInfo *TII,
1110 const TargetRegisterInfo *TRI)
1111 : DAG(SSD), BAA(BAA), SUnits(DAG->SUnits), N(SUnits.size()),
1112 LoopCarried(N, BitVector(N)), TII(TII), TRI(TRI) {}
1113
1115 // Traverse all instructions and extract only what we are targetting.
1116 for (auto &SU : SUnits) {
1117 auto Tagged = getInstrTag(&SU);
1118
1119 // This instruction has no loop-carried order-dependencies.
1120 if (!Tagged)
1121 continue;
1122 TaggedSUnits.emplace_back(&SU, *Tagged);
1123 }
1124
1125 computeDependenciesAux();
1126}
1127
1128std::optional<LoopCarriedOrderDepsTracker::InstrTag>
1129LoopCarriedOrderDepsTracker::getInstrTag(SUnit *SU) const {
1130 MachineInstr *MI = SU->getInstr();
1131 if (TII->isGlobalMemoryObject(MI))
1132 return InstrTag::Barrier;
1133
1134 if (MI->mayStore() ||
1135 (MI->mayLoad() && !MI->isDereferenceableInvariantLoad()))
1136 return InstrTag::LoadOrStore;
1137
1138 if (MI->mayRaiseFPException())
1139 return InstrTag::FPExceptions;
1140
1141 return std::nullopt;
1142}
1143
1144void LoopCarriedOrderDepsTracker::addDependenciesBetweenSUs(
1145 const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst) {
1146 // Avoid self-dependencies.
1147 if (Src.SU == Dst.SU)
1148 return;
1149
1150 if (hasLoopCarriedMemDep(Src, Dst, *BAA, TII, TRI, DAG))
1151 setLoopCarriedDep(Src.SU, Dst.SU);
1152}
1153
1154void LoopCarriedOrderDepsTracker::addLoopCarriedDepenenciesForChunks(
1155 const NoBarrierInstsChunk &From, const NoBarrierInstsChunk &To) {
1156 // Add load-to-store dependencies (WAR).
1157 for (const SUnitWithMemInfo &Src : From.Loads)
1158 for (const SUnitWithMemInfo &Dst : To.Stores)
1159 addDependenciesBetweenSUs(Src, Dst);
1160
1161 // Add store-to-load dependencies (RAW).
1162 for (const SUnitWithMemInfo &Src : From.Stores)
1163 for (const SUnitWithMemInfo &Dst : To.Loads)
1164 addDependenciesBetweenSUs(Src, Dst);
1165
1166 // Add store-to-store dependencies (WAW).
1167 for (const SUnitWithMemInfo &Src : From.Stores)
1168 for (const SUnitWithMemInfo &Dst : To.Stores)
1169 addDependenciesBetweenSUs(Src, Dst);
1170}
1171
1172void LoopCarriedOrderDepsTracker::computeDependenciesAux() {
1174 SUnit *FirstBarrier = nullptr;
1175 SUnit *LastBarrier = nullptr;
1176 for (const auto &TSU : TaggedSUnits) {
1177 InstrTag Tag = TSU.getTag();
1178 SUnit *SU = TSU.getPointer();
1179 switch (Tag) {
1180 case InstrTag::Barrier:
1181 if (!FirstBarrier)
1182 FirstBarrier = SU;
1183 LastBarrier = SU;
1184 Chunks.emplace_back();
1185 break;
1186 case InstrTag::LoadOrStore:
1187 case InstrTag::FPExceptions:
1188 Chunks.back().append(SU);
1189 break;
1190 }
1191 }
1192
1193 // Add dependencies between memory operations. If there are one or more
1194 // barrier events between two memory instructions, we don't add a
1195 // loop-carried dependence for them.
1196 for (const NoBarrierInstsChunk &Chunk : Chunks)
1197 addLoopCarriedDepenenciesForChunks(Chunk, Chunk);
1198
1199 // There is no barrier instruction between load/store/fp-exception
1200 // instructions in the same chunk. If there are one or more barrier
1201 // instructions, the instructions sequence is as follows:
1202 //
1203 // Loads/Stores/FPExceptions (Chunks.front())
1204 // Barrier (FirstBarrier)
1205 // Loads/Stores/FPExceptions
1206 // Barrier
1207 // ...
1208 // Loads/Stores/FPExceptions
1209 // Barrier (LastBarrier)
1210 // Loads/Stores/FPExceptions (Chunks.back())
1211 //
1212 // Since loads/stores/fp-exceptions must not be reordered across barrier
1213 // instructions, and the order of barrier instructions must be preserved, add
1214 // the following loop-carried dependences:
1215 //
1216 // Loads/Stores/FPExceptions (Chunks.front()) <-----+
1217 // +--> Barrier (FirstBarrier) <----------------------+ |
1218 // | Loads/Stores/FPExceptions | |
1219 // | Barrier | |
1220 // | ... | |
1221 // | Loads/Stores/FPExceptions | |
1222 // | Barrier (LastBarrier) ------------------------+--+
1223 // +--- Loads/Stores/FPExceptions (Chunks.back())
1224 //
1225 if (FirstBarrier) {
1226 assert(LastBarrier && "Both barriers should be set.");
1227
1228 // LastBarrier -> Loads/Stores/FPExceptions in Chunks.front()
1229 for (const SUnitWithMemInfo &Dst : Chunks.front().Loads)
1230 setLoopCarriedDep(LastBarrier, Dst.SU);
1231 for (const SUnitWithMemInfo &Dst : Chunks.front().Stores)
1232 setLoopCarriedDep(LastBarrier, Dst.SU);
1233 for (const SUnitWithMemInfo &Dst : Chunks.front().FPExceptions)
1234 setLoopCarriedDep(LastBarrier, Dst.SU);
1235
1236 // Loads/Stores/FPExceptions in Chunks.back() -> FirstBarrier
1237 for (const SUnitWithMemInfo &Src : Chunks.back().Loads)
1238 setLoopCarriedDep(Src.SU, FirstBarrier);
1239 for (const SUnitWithMemInfo &Src : Chunks.back().Stores)
1240 setLoopCarriedDep(Src.SU, FirstBarrier);
1241 for (const SUnitWithMemInfo &Src : Chunks.back().FPExceptions)
1242 setLoopCarriedDep(Src.SU, FirstBarrier);
1243
1244 // LastBarrier -> FirstBarrier (if they are different)
1245 if (FirstBarrier != LastBarrier)
1246 setLoopCarriedDep(LastBarrier, FirstBarrier);
1247 }
1248}
1249
1250/// Add a chain edge between a load and store if the store can be an
1251/// alias of the load on a subsequent iteration, i.e., a loop carried
1252/// dependence. This code is very similar to the code in ScheduleDAGInstrs
1253/// but that code doesn't create loop carried dependences.
1254/// TODO: Also compute output-dependencies.
1255LoopCarriedEdges SwingSchedulerDAG::addLoopCarriedDependences() {
1256 LoopCarriedEdges LCE;
1257
1258 // Add loop-carried order-dependencies
1259 LoopCarriedOrderDepsTracker LCODTracker(this, &BAA, TII, TRI);
1260 LCODTracker.computeDependencies();
1261 for (unsigned I = 0; I != SUnits.size(); I++)
1262 for (const int Succ : LCODTracker.getLoopCarried(I).set_bits())
1263 LCE.OrderDeps[&SUnits[I]].insert(&SUnits[Succ]);
1264
1265 LCE.modifySUnits(SUnits, TII);
1266 return LCE;
1267}
1268
1269/// Update the phi dependences to the DAG because ScheduleDAGInstrs no longer
1270/// processes dependences for PHIs. This function adds true dependences
1271/// from a PHI to a use, and a loop carried dependence from the use to the
1272/// PHI. The loop carried dependence is represented as an anti dependence
1273/// edge. This function also removes chain dependences between unrelated
1274/// PHIs.
1275void SwingSchedulerDAG::updatePhiDependences() {
1276 SmallVector<SDep, 4> RemoveDeps;
1277 const TargetSubtargetInfo &ST = MF.getSubtarget<TargetSubtargetInfo>();
1278
1279 // Iterate over each DAG node.
1280 for (SUnit &I : SUnits) {
1281 RemoveDeps.clear();
1282 // Set to true if the instruction has an operand defined by a Phi.
1283 Register HasPhiUse;
1284 Register HasPhiDef;
1285 MachineInstr *MI = I.getInstr();
1286 // Iterate over each operand, and we process the definitions.
1287 for (const MachineOperand &MO : MI->operands()) {
1288 if (!MO.isReg())
1289 continue;
1290 Register Reg = MO.getReg();
1291 if (MO.isDef()) {
1292 // If the register is used by a Phi, then create an anti dependence.
1294 UI = MRI.use_instr_begin(Reg),
1295 UE = MRI.use_instr_end();
1296 UI != UE; ++UI) {
1297 MachineInstr *UseMI = &*UI;
1298 SUnit *SU = getSUnit(UseMI);
1299 if (SU != nullptr && UseMI->isPHI()) {
1300 if (!MI->isPHI()) {
1301 SDep Dep(SU, SDep::Anti, Reg);
1302 Dep.setLatency(1);
1303 I.addPred(Dep);
1304 } else {
1305 HasPhiDef = Reg;
1306 // Add a chain edge to a dependent Phi that isn't an existing
1307 // predecessor.
1308
1309 // %3:intregs = PHI %21:intregs, %bb.6, %7:intregs, %bb.1 - SU0
1310 // %7:intregs = PHI %21:intregs, %bb.6, %13:intregs, %bb.1 - SU1
1311 // %27:intregs = A2_zxtb %3:intregs - SU2
1312 // %13:intregs = C2_muxri %45:predregs, 0, %46:intreg
1313 // If we have dependent phis, SU0 should be the successor of SU1
1314 // not the other way around. (it used to be SU1 is the successor
1315 // of SU0). In some cases, SU0 is scheduled earlier than SU1
1316 // resulting in bad IR as we do not have a value that can be used
1317 // by SU2.
1318
1319 if (SU->NodeNum < I.NodeNum && !SU->isPred(&I))
1320 SU->addPred(SDep(&I, SDep::Barrier));
1321 }
1322 }
1323 }
1324 } else if (MO.isUse()) {
1325 // If the register is defined by a Phi, then create a true dependence.
1326 MachineInstr *DefMI = MRI.getUniqueVRegDef(Reg);
1327 if (DefMI == nullptr)
1328 continue;
1329 SUnit *SU = getSUnit(DefMI);
1330 if (SU != nullptr && DefMI->isPHI()) {
1331 if (!MI->isPHI()) {
1332 SDep Dep(SU, SDep::Data, Reg);
1333 Dep.setLatency(0);
1334 ST.adjustSchedDependency(SU, 0, &I, MO.getOperandNo(), Dep,
1335 &SchedModel);
1336 I.addPred(Dep);
1337 } else {
1338 HasPhiUse = Reg;
1339 // Add a chain edge to a dependent Phi that isn't an existing
1340 // predecessor.
1341 if (SU->NodeNum < I.NodeNum && !I.isPred(SU))
1342 I.addPred(SDep(SU, SDep::Barrier));
1343 }
1344 }
1345 }
1346 }
1347 // Remove order dependences from an unrelated Phi.
1348 if (!SwpPruneDeps)
1349 continue;
1350 for (auto &PI : I.Preds) {
1351 MachineInstr *PMI = PI.getSUnit()->getInstr();
1352 if (PMI->isPHI() && PI.getKind() == SDep::Order) {
1353 if (I.getInstr()->isPHI()) {
1354 if (PMI->getOperand(0).getReg() == HasPhiUse)
1355 continue;
1356 if (getLoopPhiReg(*PMI, PMI->getParent()) == HasPhiDef)
1357 continue;
1358 }
1359 RemoveDeps.push_back(PI);
1360 }
1361 }
1362 for (const SDep &D : RemoveDeps)
1363 I.removePred(D);
1364 }
1365}
1366
1367/// Iterate over each DAG node and see if we can change any dependences
1368/// in order to reduce the recurrence MII.
1369void SwingSchedulerDAG::changeDependences() {
1370 // See if an instruction can use a value from the previous iteration.
1371 // If so, we update the base and offset of the instruction and change
1372 // the dependences.
1373 for (SUnit &I : SUnits) {
1374 unsigned BasePos = 0, OffsetPos = 0;
1375 Register NewBase;
1376 int64_t NewOffset = 0;
1377 if (!canUseLastOffsetValue(I.getInstr(), BasePos, OffsetPos, NewBase,
1378 NewOffset))
1379 continue;
1380
1381 // Get the MI and SUnit for the instruction that defines the original base.
1382 Register OrigBase = I.getInstr()->getOperand(BasePos).getReg();
1383 MachineInstr *DefMI = MRI.getUniqueVRegDef(OrigBase);
1384 if (!DefMI)
1385 continue;
1386 SUnit *DefSU = getSUnit(DefMI);
1387 if (!DefSU)
1388 continue;
1389 // Get the MI and SUnit for the instruction that defins the new base.
1390 MachineInstr *LastMI = MRI.getUniqueVRegDef(NewBase);
1391 if (!LastMI)
1392 continue;
1393 SUnit *LastSU = getSUnit(LastMI);
1394 if (!LastSU)
1395 continue;
1396
1397 if (Topo.IsReachable(&I, LastSU))
1398 continue;
1399
1400 // Remove the dependence. The value now depends on a prior iteration.
1402 for (const SDep &P : I.Preds)
1403 if (P.getSUnit() == DefSU)
1404 Deps.push_back(P);
1405 for (const SDep &D : Deps) {
1406 Topo.RemovePred(&I, D.getSUnit());
1407 I.removePred(D);
1408 }
1409 // Remove the chain dependence between the instructions.
1410 Deps.clear();
1411 for (auto &P : LastSU->Preds)
1412 if (P.getSUnit() == &I && P.getKind() == SDep::Order)
1413 Deps.push_back(P);
1414 for (const SDep &D : Deps) {
1415 Topo.RemovePred(LastSU, D.getSUnit());
1416 LastSU->removePred(D);
1417 }
1418
1419 // Add a dependence between the new instruction and the instruction
1420 // that defines the new base.
1421 SDep Dep(&I, SDep::Anti, NewBase);
1422 Topo.AddPred(LastSU, &I);
1423 LastSU->addPred(Dep);
1424
1425 // Remember the base and offset information so that we can update the
1426 // instruction during code generation.
1427 InstrChanges[&I] = std::make_pair(NewBase, NewOffset);
1428 }
1429}
1430
1431/// Create an instruction stream that represents a single iteration and stage of
1432/// each instruction. This function differs from SMSchedule::finalizeSchedule in
1433/// that this doesn't have any side-effect to SwingSchedulerDAG. That is, this
1434/// function is an approximation of SMSchedule::finalizeSchedule with all
1435/// non-const operations removed.
1437 SMSchedule &Schedule,
1438 std::vector<MachineInstr *> &OrderedInsts,
1441
1442 // Move all instructions to the first stage from the later stages.
1443 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
1444 ++Cycle) {
1445 for (int Stage = 0, LastStage = Schedule.getMaxStageCount();
1446 Stage <= LastStage; ++Stage) {
1447 for (SUnit *SU : llvm::reverse(Schedule.getInstructions(
1448 Cycle + Stage * Schedule.getInitiationInterval()))) {
1449 Instrs[Cycle].push_front(SU);
1450 }
1451 }
1452 }
1453
1454 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
1455 ++Cycle) {
1456 std::deque<SUnit *> &CycleInstrs = Instrs[Cycle];
1457 CycleInstrs = Schedule.reorderInstructions(SSD, CycleInstrs);
1458 for (SUnit *SU : CycleInstrs) {
1459 MachineInstr *MI = SU->getInstr();
1460 OrderedInsts.push_back(MI);
1461 Stages[MI] = Schedule.stageScheduled(SU);
1462 }
1463 }
1464}
1465
1466namespace {
1467
1468// FuncUnitSorter - Comparison operator used to sort instructions by
1469// the number of functional unit choices.
1470struct FuncUnitSorter {
1471 const InstrItineraryData *InstrItins;
1472 const MCSubtargetInfo *STI;
1473 DenseMap<InstrStage::FuncUnits, unsigned> Resources;
1474
1475 FuncUnitSorter(const TargetSubtargetInfo &TSI)
1476 : InstrItins(TSI.getInstrItineraryData()), STI(&TSI) {}
1477
1478 // Compute the number of functional unit alternatives needed
1479 // at each stage, and take the minimum value. We prioritize the
1480 // instructions by the least number of choices first.
1481 unsigned minFuncUnits(const MachineInstr *Inst,
1482 InstrStage::FuncUnits &F) const {
1483 unsigned SchedClass = Inst->getDesc().getSchedClass();
1484 unsigned min = UINT_MAX;
1485 if (InstrItins && !InstrItins->isEmpty()) {
1486 for (const InstrStage &IS :
1487 make_range(InstrItins->beginStage(SchedClass),
1488 InstrItins->endStage(SchedClass))) {
1489 InstrStage::FuncUnits funcUnits = IS.getUnits();
1490 unsigned numAlternatives = llvm::popcount(funcUnits);
1491 if (numAlternatives < min) {
1492 min = numAlternatives;
1493 F = funcUnits;
1494 }
1495 }
1496 return min;
1497 }
1498 if (STI && STI->getSchedModel().hasInstrSchedModel()) {
1499 const MCSchedClassDesc *SCDesc =
1500 STI->getSchedModel().getSchedClassDesc(SchedClass);
1501 if (!SCDesc->isValid())
1502 // No valid Schedule Class Desc for schedClass, should be
1503 // Pseudo/PostRAPseudo
1504 return min;
1505
1506 for (const MCWriteProcResEntry &PRE :
1507 make_range(STI->getWriteProcResBegin(SCDesc),
1508 STI->getWriteProcResEnd(SCDesc))) {
1509 if (!PRE.ReleaseAtCycle)
1510 continue;
1511 const MCProcResourceDesc *ProcResource =
1512 STI->getSchedModel().getProcResource(PRE.ProcResourceIdx);
1513 unsigned NumUnits = ProcResource->NumUnits;
1514 if (NumUnits < min) {
1515 min = NumUnits;
1516 F = PRE.ProcResourceIdx;
1517 }
1518 }
1519 return min;
1520 }
1521 llvm_unreachable("Should have non-empty InstrItins or hasInstrSchedModel!");
1522 }
1523
1524 // Compute the critical resources needed by the instruction. This
1525 // function records the functional units needed by instructions that
1526 // must use only one functional unit. We use this as a tie breaker
1527 // for computing the resource MII. The instrutions that require
1528 // the same, highly used, functional unit have high priority.
1529 void calcCriticalResources(MachineInstr &MI) {
1530 unsigned SchedClass = MI.getDesc().getSchedClass();
1531 if (InstrItins && !InstrItins->isEmpty()) {
1532 for (const InstrStage &IS :
1533 make_range(InstrItins->beginStage(SchedClass),
1534 InstrItins->endStage(SchedClass))) {
1535 InstrStage::FuncUnits FuncUnits = IS.getUnits();
1536 if (llvm::popcount(FuncUnits) == 1)
1537 Resources[FuncUnits]++;
1538 }
1539 return;
1540 }
1541 if (STI && STI->getSchedModel().hasInstrSchedModel()) {
1542 const MCSchedClassDesc *SCDesc =
1543 STI->getSchedModel().getSchedClassDesc(SchedClass);
1544 if (!SCDesc->isValid())
1545 // No valid Schedule Class Desc for schedClass, should be
1546 // Pseudo/PostRAPseudo
1547 return;
1548
1549 for (const MCWriteProcResEntry &PRE :
1550 make_range(STI->getWriteProcResBegin(SCDesc),
1551 STI->getWriteProcResEnd(SCDesc))) {
1552 if (!PRE.ReleaseAtCycle)
1553 continue;
1554 Resources[PRE.ProcResourceIdx]++;
1555 }
1556 return;
1557 }
1558 llvm_unreachable("Should have non-empty InstrItins or hasInstrSchedModel!");
1559 }
1560
1561 /// Return true if IS1 has less priority than IS2.
1562 bool operator()(const MachineInstr *IS1, const MachineInstr *IS2) const {
1563 InstrStage::FuncUnits F1 = 0, F2 = 0;
1564 unsigned MFUs1 = minFuncUnits(IS1, F1);
1565 unsigned MFUs2 = minFuncUnits(IS2, F2);
1566 if (MFUs1 == MFUs2)
1567 return Resources.lookup(F1) < Resources.lookup(F2);
1568 return MFUs1 > MFUs2;
1569 }
1570};
1571
1572/// Calculate the maximum register pressure of the scheduled instructions stream
1573class HighRegisterPressureDetector {
1574 MachineBasicBlock *OrigMBB;
1575 const MachineRegisterInfo &MRI;
1576 const TargetRegisterInfo *TRI;
1577
1578 const unsigned PSetNum;
1579
1580 // Indexed by PSet ID
1581 // InitSetPressure takes into account the register pressure of live-in
1582 // registers. It's not depend on how the loop is scheduled, so it's enough to
1583 // calculate them once at the beginning.
1584 std::vector<unsigned> InitSetPressure;
1585
1586 // Indexed by PSet ID
1587 // Upper limit for each register pressure set
1588 std::vector<unsigned> PressureSetLimit;
1589
1590 DenseMap<MachineInstr *, RegisterOperands> ROMap;
1591
1592 using Instr2LastUsesTy = DenseMap<MachineInstr *, SmallDenseSet<Register, 4>>;
1593
1594public:
1595 using OrderedInstsTy = std::vector<MachineInstr *>;
1596 using Instr2StageTy = DenseMap<MachineInstr *, unsigned>;
1597
1598private:
1599 static void dumpRegisterPressures(const std::vector<unsigned> &Pressures) {
1600 if (Pressures.size() == 0) {
1601 dbgs() << "[]";
1602 } else {
1603 char Prefix = '[';
1604 for (unsigned P : Pressures) {
1605 dbgs() << Prefix << P;
1606 Prefix = ' ';
1607 }
1608 dbgs() << ']';
1609 }
1610 }
1611
1612 void dumpPSet(Register Reg) const {
1613 dbgs() << "Reg=" << printReg(Reg, TRI, 0, &MRI) << " PSet=";
1614 // FIXME: The static_cast is a bug compensating bugs in the callers.
1615 VirtRegOrUnit VRegOrUnit =
1616 Reg.isVirtual() ? VirtRegOrUnit(Reg)
1617 : VirtRegOrUnit(static_cast<MCRegUnit>(Reg.id()));
1618 for (auto PSetIter = MRI.getPressureSets(VRegOrUnit); PSetIter.isValid();
1619 ++PSetIter) {
1620 dbgs() << *PSetIter << ' ';
1621 }
1622 dbgs() << '\n';
1623 }
1624
1625 void increaseRegisterPressure(std::vector<unsigned> &Pressure,
1626 Register Reg) const {
1627 // FIXME: The static_cast is a bug compensating bugs in the callers.
1628 VirtRegOrUnit VRegOrUnit =
1629 Reg.isVirtual() ? VirtRegOrUnit(Reg)
1630 : VirtRegOrUnit(static_cast<MCRegUnit>(Reg.id()));
1631 auto PSetIter = MRI.getPressureSets(VRegOrUnit);
1632 unsigned Weight = PSetIter.getWeight();
1633 for (; PSetIter.isValid(); ++PSetIter)
1634 Pressure[*PSetIter] += Weight;
1635 }
1636
1637 void decreaseRegisterPressure(std::vector<unsigned> &Pressure,
1638 Register Reg) const {
1639 auto PSetIter = MRI.getPressureSets(VirtRegOrUnit(Reg));
1640 unsigned Weight = PSetIter.getWeight();
1641 for (; PSetIter.isValid(); ++PSetIter) {
1642 auto &P = Pressure[*PSetIter];
1643 assert(P >= Weight &&
1644 "register pressure must be greater than or equal weight");
1645 P -= Weight;
1646 }
1647 }
1648
1649 // Return true if Reg is reserved one, for example, stack pointer
1650 bool isReservedRegister(Register Reg) const {
1651 return Reg.isPhysical() && MRI.isReserved(Reg.asMCReg());
1652 }
1653
1654 bool isDefinedInThisLoop(Register Reg) const {
1655 return Reg.isVirtual() && MRI.getVRegDef(Reg)->getParent() == OrigMBB;
1656 }
1657
1658 // Search for live-in variables. They are factored into the register pressure
1659 // from the begining. Live-in variables used by every iteration should be
1660 // considered as alive throughout the loop. For example, the variable `c` in
1661 // following code. \code
1662 // int c = ...;
1663 // for (int i = 0; i < n; i++)
1664 // a[i] += b[i] + c;
1665 // \endcode
1666 void computeLiveIn() {
1667 DenseSet<Register> Used;
1668 for (auto &MI : *OrigMBB) {
1669 if (MI.isDebugInstr())
1670 continue;
1671 for (auto &Use : ROMap[&MI].Uses) {
1672 // FIXME: The static_cast is a bug.
1673 Register Reg =
1674 Use.VRegOrUnit.isVirtualReg()
1675 ? Use.VRegOrUnit.asVirtualReg()
1676 : Register(static_cast<unsigned>(Use.VRegOrUnit.asMCRegUnit()));
1677 // Ignore the variable that appears only on one side of phi instruction
1678 // because it's used only at the first iteration.
1679 if (MI.isPHI() && Reg != getLoopPhiReg(MI, OrigMBB))
1680 continue;
1681 if (isReservedRegister(Reg))
1682 continue;
1683 if (isDefinedInThisLoop(Reg))
1684 continue;
1685 Used.insert(Reg);
1686 }
1687 }
1688
1689 for (auto LiveIn : Used)
1690 increaseRegisterPressure(InitSetPressure, LiveIn);
1691 }
1692
1693 // Calculate the upper limit of each pressure set
1694 void computePressureSetLimit(const RegisterClassInfo &RCI) {
1695 for (unsigned PSet = 0; PSet < PSetNum; PSet++)
1696 PressureSetLimit[PSet] = RCI.getRegPressureSetLimit(PSet);
1697 }
1698
1699 // There are two patterns of last-use.
1700 // - by an instruction of the current iteration
1701 // - by a phi instruction of the next iteration (loop carried value)
1702 //
1703 // Furthermore, following two groups of instructions are executed
1704 // simultaneously
1705 // - next iteration's phi instructions in i-th stage
1706 // - current iteration's instructions in i+1-th stage
1707 //
1708 // This function calculates the last-use of each register while taking into
1709 // account the above two patterns.
1710 Instr2LastUsesTy computeLastUses(const OrderedInstsTy &OrderedInsts,
1711 Instr2StageTy &Stages) const {
1712 // We treat virtual registers that are defined and used in this loop.
1713 // Following virtual register will be ignored
1714 // - live-in one
1715 // - defined but not used in the loop (potentially live-out)
1716 DenseSet<Register> TargetRegs;
1717 const auto UpdateTargetRegs = [this, &TargetRegs](Register Reg) {
1718 if (isDefinedInThisLoop(Reg))
1719 TargetRegs.insert(Reg);
1720 };
1721 for (MachineInstr *MI : OrderedInsts) {
1722 if (MI->isPHI()) {
1723 Register Reg = getLoopPhiReg(*MI, OrigMBB);
1724 UpdateTargetRegs(Reg);
1725 } else {
1726 for (auto &Use : ROMap.find(MI)->getSecond().Uses) {
1727 // FIXME: The static_cast is a bug.
1728 Register Reg = Use.VRegOrUnit.isVirtualReg()
1729 ? Use.VRegOrUnit.asVirtualReg()
1730 : Register(static_cast<unsigned>(
1731 Use.VRegOrUnit.asMCRegUnit()));
1732 UpdateTargetRegs(Reg);
1733 }
1734 }
1735 }
1736
1737 const auto InstrScore = [&Stages](MachineInstr *MI) {
1738 return Stages[MI] + MI->isPHI();
1739 };
1740
1741 DenseMap<Register, MachineInstr *> LastUseMI;
1742 for (MachineInstr *MI : llvm::reverse(OrderedInsts)) {
1743 for (auto &Use : ROMap.find(MI)->getSecond().Uses) {
1744 // FIXME: The static_cast is a bug.
1745 Register Reg =
1746 Use.VRegOrUnit.isVirtualReg()
1747 ? Use.VRegOrUnit.asVirtualReg()
1748 : Register(static_cast<unsigned>(Use.VRegOrUnit.asMCRegUnit()));
1749 if (!TargetRegs.contains(Reg))
1750 continue;
1751 auto [Ite, Inserted] = LastUseMI.try_emplace(Reg, MI);
1752 if (!Inserted) {
1753 MachineInstr *Orig = Ite->second;
1754 MachineInstr *New = MI;
1755 if (InstrScore(Orig) < InstrScore(New))
1756 Ite->second = New;
1757 }
1758 }
1759 }
1760
1761 Instr2LastUsesTy LastUses;
1762 for (auto [Reg, MI] : LastUseMI)
1763 LastUses[MI].insert(Reg);
1764 return LastUses;
1765 }
1766
1767 // Compute the maximum register pressure of the kernel. We'll simulate #Stage
1768 // iterations and check the register pressure at the point where all stages
1769 // overlapping.
1770 //
1771 // An example of unrolled loop where #Stage is 4..
1772 // Iter i+0 i+1 i+2 i+3
1773 // ------------------------
1774 // Stage 0
1775 // Stage 1 0
1776 // Stage 2 1 0
1777 // Stage 3 2 1 0 <- All stages overlap
1778 //
1779 std::vector<unsigned>
1780 computeMaxSetPressure(const OrderedInstsTy &OrderedInsts,
1781 Instr2StageTy &Stages,
1782 const unsigned StageCount) const {
1783 using RegSetTy = SmallDenseSet<Register, 16>;
1784
1785 // Indexed by #Iter. To treat "local" variables of each stage separately, we
1786 // manage the liveness of the registers independently by iterations.
1787 SmallVector<RegSetTy> LiveRegSets(StageCount);
1788
1789 auto CurSetPressure = InitSetPressure;
1790 auto MaxSetPressure = InitSetPressure;
1791 auto LastUses = computeLastUses(OrderedInsts, Stages);
1792
1793 LLVM_DEBUG({
1794 dbgs() << "Ordered instructions:\n";
1795 for (MachineInstr *MI : OrderedInsts) {
1796 dbgs() << "Stage " << Stages[MI] << ": ";
1797 MI->dump();
1798 }
1799 });
1800
1801 const auto InsertReg = [this, &CurSetPressure](RegSetTy &RegSet,
1802 VirtRegOrUnit VRegOrUnit) {
1803 // FIXME: The static_cast is a bug.
1804 Register Reg =
1805 VRegOrUnit.isVirtualReg()
1806 ? VRegOrUnit.asVirtualReg()
1807 : Register(static_cast<unsigned>(VRegOrUnit.asMCRegUnit()));
1808 if (!Reg.isValid() || isReservedRegister(Reg))
1809 return;
1810
1811 bool Inserted = RegSet.insert(Reg).second;
1812 if (!Inserted)
1813 return;
1814
1815 LLVM_DEBUG(dbgs() << "insert " << printReg(Reg, TRI, 0, &MRI) << "\n");
1816 increaseRegisterPressure(CurSetPressure, Reg);
1817 LLVM_DEBUG(dumpPSet(Reg));
1818 };
1819
1820 const auto EraseReg = [this, &CurSetPressure](RegSetTy &RegSet,
1821 Register Reg) {
1822 if (!Reg.isValid() || isReservedRegister(Reg))
1823 return;
1824
1825 // live-in register
1826 if (!RegSet.contains(Reg))
1827 return;
1828
1829 LLVM_DEBUG(dbgs() << "erase " << printReg(Reg, TRI, 0, &MRI) << "\n");
1830 RegSet.erase(Reg);
1831 decreaseRegisterPressure(CurSetPressure, Reg);
1832 LLVM_DEBUG(dumpPSet(Reg));
1833 };
1834
1835 for (unsigned I = 0; I < StageCount; I++) {
1836 for (MachineInstr *MI : OrderedInsts) {
1837 const auto Stage = Stages[MI];
1838 if (I < Stage)
1839 continue;
1840
1841 const unsigned Iter = I - Stage;
1842
1843 for (auto &Def : ROMap.find(MI)->getSecond().Defs)
1844 InsertReg(LiveRegSets[Iter], Def.VRegOrUnit);
1845
1846 for (auto LastUse : LastUses[MI]) {
1847 if (MI->isPHI()) {
1848 if (Iter != 0)
1849 EraseReg(LiveRegSets[Iter - 1], LastUse);
1850 } else {
1851 EraseReg(LiveRegSets[Iter], LastUse);
1852 }
1853 }
1854
1855 for (unsigned PSet = 0; PSet < PSetNum; PSet++)
1856 MaxSetPressure[PSet] =
1857 std::max(MaxSetPressure[PSet], CurSetPressure[PSet]);
1858
1859 LLVM_DEBUG({
1860 dbgs() << "CurSetPressure=";
1861 dumpRegisterPressures(CurSetPressure);
1862 dbgs() << " iter=" << Iter << " stage=" << Stage << ":";
1863 MI->dump();
1864 });
1865 }
1866 }
1867
1868 return MaxSetPressure;
1869 }
1870
1871public:
1872 HighRegisterPressureDetector(MachineBasicBlock *OrigMBB,
1873 const MachineFunction &MF)
1874 : OrigMBB(OrigMBB), MRI(MF.getRegInfo()),
1875 TRI(MF.getSubtarget().getRegisterInfo()),
1876 PSetNum(TRI->getNumRegPressureSets()), InitSetPressure(PSetNum, 0),
1877 PressureSetLimit(PSetNum, 0) {}
1878
1879 // Used to calculate register pressure, which is independent of loop
1880 // scheduling.
1881 void init(const RegisterClassInfo &RCI) {
1882 for (MachineInstr &MI : *OrigMBB) {
1883 if (MI.isDebugInstr())
1884 continue;
1885 ROMap[&MI].collect(MI, *TRI, MRI, false, true);
1886 }
1887
1888 computeLiveIn();
1889 computePressureSetLimit(RCI);
1890 }
1891
1892 // Calculate the maximum register pressures of the loop and check if they
1893 // exceed the limit
1894 bool detect(const SwingSchedulerDAG *SSD, SMSchedule &Schedule,
1895 const unsigned MaxStage) const {
1897 "the percentage of the margin must be between 0 to 100");
1898
1899 OrderedInstsTy OrderedInsts;
1900 Instr2StageTy Stages;
1901 computeScheduledInsts(SSD, Schedule, OrderedInsts, Stages);
1902 const auto MaxSetPressure =
1903 computeMaxSetPressure(OrderedInsts, Stages, MaxStage + 1);
1904
1905 LLVM_DEBUG({
1906 dbgs() << "Dump MaxSetPressure:\n";
1907 for (unsigned I = 0; I < MaxSetPressure.size(); I++) {
1908 dbgs() << format("MaxSetPressure[%d]=%d\n", I, MaxSetPressure[I]);
1909 }
1910 dbgs() << '\n';
1911 });
1912
1913 for (unsigned PSet = 0; PSet < PSetNum; PSet++) {
1914 unsigned Limit = PressureSetLimit[PSet];
1915 unsigned Margin = Limit * RegPressureMargin / 100;
1916 LLVM_DEBUG(dbgs() << "PSet=" << PSet << " Limit=" << Limit
1917 << " Margin=" << Margin << "\n");
1918 if (Limit < MaxSetPressure[PSet] + Margin) {
1919 LLVM_DEBUG(
1920 dbgs()
1921 << "Rejected the schedule because of too high register pressure\n");
1922 return true;
1923 }
1924 }
1925 return false;
1926 }
1927};
1928
1929} // end anonymous namespace
1930
1931/// Calculate the resource constrained minimum initiation interval for the
1932/// specified loop. We use the DFA to model the resources needed for
1933/// each instruction, and we ignore dependences. A different DFA is created
1934/// for each cycle that is required. When adding a new instruction, we attempt
1935/// to add it to each existing DFA, until a legal space is found. If the
1936/// instruction cannot be reserved in an existing DFA, we create a new one.
1937unsigned SwingSchedulerDAG::calculateResMII() {
1938 LLVM_DEBUG(dbgs() << "calculateResMII:\n");
1939 ResourceManager RM(&MF.getSubtarget(), this);
1940 return RM.calculateResMII();
1941}
1942
1943/// Calculate the recurrence-constrainted minimum initiation interval.
1944/// Iterate over each circuit. Compute the delay(c) and distance(c)
1945/// for each circuit. The II needs to satisfy the inequality
1946/// delay(c) - II*distance(c) <= 0. For each circuit, choose the smallest
1947/// II that satisfies the inequality, and the RecMII is the maximum
1948/// of those values.
1949unsigned SwingSchedulerDAG::calculateRecMII(NodeSetType &NodeSets) {
1950 unsigned RecMII = 0;
1951
1952 for (NodeSet &Nodes : NodeSets) {
1953 if (Nodes.empty())
1954 continue;
1955
1956 unsigned Delay = Nodes.getLatency();
1957 unsigned Distance = 1;
1958
1959 // ii = ceil(delay / distance)
1960 unsigned CurMII = (Delay + Distance - 1) / Distance;
1961 Nodes.setRecMII(CurMII);
1962 if (CurMII > RecMII)
1963 RecMII = CurMII;
1964 }
1965
1966 return RecMII;
1967}
1968
1969/// Create the adjacency structure of the nodes in the graph.
1970void SwingSchedulerDAG::Circuits::createAdjacencyStructure(
1971 SwingSchedulerDDG *DDG) {
1972 BitVector Added(SUnits.size());
1973 DenseMap<int, int> OutputDeps;
1974 for (int i = 0, e = SUnits.size(); i != e; ++i) {
1975 Added.reset();
1976 // Add any successor to the adjacency matrix and exclude duplicates.
1977 for (auto &OE : DDG->getOutEdges(&SUnits[i])) {
1978 // Only create a back-edge on the first and last nodes of a dependence
1979 // chain. This records any chains and adds them later.
1980 if (OE.isOutputDep()) {
1981 int N = OE.getDst()->NodeNum;
1982 int BackEdge = i;
1983 auto Dep = OutputDeps.find(BackEdge);
1984 if (Dep != OutputDeps.end()) {
1985 BackEdge = Dep->second;
1986 OutputDeps.erase(Dep);
1987 }
1988 OutputDeps[N] = BackEdge;
1989 }
1990 // Do not process a boundary node, an artificial node.
1991 if (OE.getDst()->isBoundaryNode() || OE.isArtificial())
1992 continue;
1993
1994 // This code is retained o preserve previous behavior and prevent
1995 // regression. This condition means that anti-dependnecies within an
1996 // iteration are ignored when searching circuits. Therefore it's natural
1997 // to consider this dependence as well.
1998 // FIXME: Remove this code if it doesn't have significant impact on
1999 // performance.
2000 if (OE.isAntiDep())
2001 continue;
2002
2003 int N = OE.getDst()->NodeNum;
2004 if (!Added.test(N)) {
2005 AdjK[i].push_back(N);
2006 Added.set(N);
2007 }
2008 }
2009
2010 // Also add any extra out edges to the adjacency matrix.
2011 for (const SUnit *Dst : DDG->getExtraOutEdges(&SUnits[i])) {
2012 int N = Dst->NodeNum;
2013 if (!Added.test(N)) {
2014 AdjK[i].push_back(N);
2015 Added.set(N);
2016 }
2017 }
2018 }
2019
2020 // Add back-edges in the adjacency matrix for the output dependences.
2021 for (auto &OD : OutputDeps)
2022 if (!Added.test(OD.second)) {
2023 AdjK[OD.first].push_back(OD.second);
2024 Added.set(OD.second);
2025 }
2026}
2027
2028/// Identify an elementary circuit in the dependence graph starting at the
2029/// specified node.
2030bool SwingSchedulerDAG::Circuits::circuit(int V, int S, NodeSetType &NodeSets,
2031 const SwingSchedulerDAG *DAG,
2032 bool HasBackedge) {
2033 SUnit *SV = &SUnits[V];
2034 bool F = false;
2035 Stack.insert(SV);
2036 Blocked.set(V);
2037
2038 for (auto W : AdjK[V]) {
2039 if (NumPaths > MaxPaths)
2040 break;
2041 if (W < S)
2042 continue;
2043 if (W == S) {
2044 if (!HasBackedge)
2045 NodeSets.push_back(NodeSet(Stack.begin(), Stack.end(), DAG));
2046 F = true;
2047 ++NumPaths;
2048 break;
2049 }
2050 if (!Blocked.test(W)) {
2051 if (circuit(W, S, NodeSets, DAG,
2052 Node2Idx->at(W) < Node2Idx->at(V) ? true : HasBackedge))
2053 F = true;
2054 }
2055 }
2056
2057 if (F)
2058 unblock(V);
2059 else {
2060 for (auto W : AdjK[V]) {
2061 if (W < S)
2062 continue;
2063 B[W].insert(SV);
2064 }
2065 }
2066 Stack.pop_back();
2067 return F;
2068}
2069
2070/// Unblock a node in the circuit finding algorithm.
2071void SwingSchedulerDAG::Circuits::unblock(int U) {
2072 Blocked.reset(U);
2073 SmallPtrSet<SUnit *, 4> &BU = B[U];
2074 while (!BU.empty()) {
2075 SmallPtrSet<SUnit *, 4>::iterator SI = BU.begin();
2076 assert(SI != BU.end() && "Invalid B set.");
2077 SUnit *W = *SI;
2078 BU.erase(W);
2079 if (Blocked.test(W->NodeNum))
2080 unblock(W->NodeNum);
2081 }
2082}
2083
2084/// Identify all the elementary circuits in the dependence graph using
2085/// Johnson's circuit algorithm.
2086void SwingSchedulerDAG::findCircuits(NodeSetType &NodeSets) {
2087 Circuits Cir(SUnits, Topo);
2088 // Create the adjacency structure.
2089 Cir.createAdjacencyStructure(&*DDG);
2090 for (int I = 0, E = SUnits.size(); I != E; ++I) {
2091 Cir.reset();
2092 Cir.circuit(I, I, NodeSets, this);
2093 }
2094}
2095
2096// Create artificial dependencies between the source of COPY/REG_SEQUENCE that
2097// is loop-carried to the USE in next iteration. This will help pipeliner avoid
2098// additional copies that are needed across iterations. An artificial dependence
2099// edge is added from USE to SOURCE of COPY/REG_SEQUENCE.
2100
2101// PHI-------Anti-Dep-----> COPY/REG_SEQUENCE (loop-carried)
2102// SRCOfCopY------True-Dep---> COPY/REG_SEQUENCE
2103// PHI-------True-Dep------> USEOfPhi
2104
2105// The mutation creates
2106// USEOfPHI -------Artificial-Dep---> SRCOfCopy
2107
2108// This overall will ensure, the USEOfPHI is scheduled before SRCOfCopy
2109// (since USE is a predecessor), implies, the COPY/ REG_SEQUENCE is scheduled
2110// late to avoid additional copies across iterations. The possible scheduling
2111// order would be
2112// USEOfPHI --- SRCOfCopy--- COPY/REG_SEQUENCE.
2113
2114void SwingSchedulerDAG::CopyToPhiMutation::apply(ScheduleDAGInstrs *DAG) {
2115 for (SUnit &SU : DAG->SUnits) {
2116 // Find the COPY/REG_SEQUENCE instruction.
2117 if (!SU.getInstr()->isCopy() && !SU.getInstr()->isRegSequence())
2118 continue;
2119
2120 // Record the loop carried PHIs.
2122 // Record the SrcSUs that feed the COPY/REG_SEQUENCE instructions.
2124
2125 for (auto &Dep : SU.Preds) {
2126 SUnit *TmpSU = Dep.getSUnit();
2127 MachineInstr *TmpMI = TmpSU->getInstr();
2128 SDep::Kind DepKind = Dep.getKind();
2129 // Save the loop carried PHI.
2130 if (DepKind == SDep::Anti && TmpMI->isPHI())
2131 PHISUs.push_back(TmpSU);
2132 // Save the source of COPY/REG_SEQUENCE.
2133 // If the source has no pre-decessors, we will end up creating cycles.
2134 else if (DepKind == SDep::Data && !TmpMI->isPHI() && TmpSU->NumPreds > 0)
2135 SrcSUs.push_back(TmpSU);
2136 }
2137
2138 if (PHISUs.size() == 0 || SrcSUs.size() == 0)
2139 continue;
2140
2141 // Find the USEs of PHI. If the use is a PHI or REG_SEQUENCE, push back this
2142 // SUnit to the container.
2144 // Do not use iterator based loop here as we are updating the container.
2145 for (size_t Index = 0; Index < PHISUs.size(); ++Index) {
2146 for (auto &Dep : PHISUs[Index]->Succs) {
2147 if (Dep.getKind() != SDep::Data)
2148 continue;
2149
2150 SUnit *TmpSU = Dep.getSUnit();
2151 MachineInstr *TmpMI = TmpSU->getInstr();
2152 if (TmpMI->isPHI() || TmpMI->isRegSequence()) {
2153 PHISUs.push_back(TmpSU);
2154 continue;
2155 }
2156 UseSUs.push_back(TmpSU);
2157 }
2158 }
2159
2160 if (UseSUs.size() == 0)
2161 continue;
2162
2163 SwingSchedulerDAG *SDAG = cast<SwingSchedulerDAG>(DAG);
2164 // Add the artificial dependencies if it does not form a cycle.
2165 for (auto *I : UseSUs) {
2166 for (auto *Src : SrcSUs) {
2167 if (!SDAG->Topo.IsReachable(I, Src) && Src != I) {
2168 Src->addPred(SDep(I, SDep::Artificial));
2169 SDAG->Topo.AddPred(Src, I);
2170 }
2171 }
2172 }
2173 }
2174}
2175
2176/// Compute several functions need to order the nodes for scheduling.
2177/// ASAP - Earliest time to schedule a node.
2178/// ALAP - Latest time to schedule a node.
2179/// MOV - Mobility function, difference between ALAP and ASAP.
2180/// D - Depth of each node.
2181/// H - Height of each node.
2182void SwingSchedulerDAG::computeNodeFunctions(NodeSetType &NodeSets) {
2183 ScheduleInfo.resize(SUnits.size());
2184
2185 LLVM_DEBUG({
2186 for (int I : Topo) {
2187 const SUnit &SU = SUnits[I];
2188 dumpNode(SU);
2189 }
2190 });
2191
2192 int maxASAP = 0;
2193 // Compute ASAP and ZeroLatencyDepth.
2194 for (int I : Topo) {
2195 int asap = 0;
2196 int zeroLatencyDepth = 0;
2197 SUnit *SU = &SUnits[I];
2198 for (const auto &IE : DDG->getInEdges(SU)) {
2199 SUnit *Pred = IE.getSrc();
2200 if (IE.getLatency() == 0)
2201 zeroLatencyDepth =
2202 std::max(zeroLatencyDepth, getZeroLatencyDepth(Pred) + 1);
2203 if (IE.ignoreDependence(true))
2204 continue;
2205 asap = std::max(asap, (int)(getASAP(Pred) + IE.getLatency() -
2206 IE.getDistance() * MII));
2207 }
2208 maxASAP = std::max(maxASAP, asap);
2209 ScheduleInfo[I].ASAP = asap;
2210 ScheduleInfo[I].ZeroLatencyDepth = zeroLatencyDepth;
2211 }
2212
2213 // Compute ALAP, ZeroLatencyHeight, and MOV.
2214 for (int I : llvm::reverse(Topo)) {
2215 int alap = maxASAP;
2216 int zeroLatencyHeight = 0;
2217 SUnit *SU = &SUnits[I];
2218 for (const auto &OE : DDG->getOutEdges(SU)) {
2219 SUnit *Succ = OE.getDst();
2220 if (Succ->isBoundaryNode())
2221 continue;
2222 if (OE.getLatency() == 0)
2223 zeroLatencyHeight =
2224 std::max(zeroLatencyHeight, getZeroLatencyHeight(Succ) + 1);
2225 if (OE.ignoreDependence(true))
2226 continue;
2227 alap = std::min(alap, (int)(getALAP(Succ) - OE.getLatency() +
2228 OE.getDistance() * MII));
2229 }
2230
2231 ScheduleInfo[I].ALAP = alap;
2232 ScheduleInfo[I].ZeroLatencyHeight = zeroLatencyHeight;
2233 }
2234
2235 // After computing the node functions, compute the summary for each node set.
2236 for (NodeSet &I : NodeSets)
2237 I.computeNodeSetInfo(this);
2238
2239 LLVM_DEBUG({
2240 for (unsigned i = 0; i < SUnits.size(); i++) {
2241 dbgs() << "\tNode " << i << ":\n";
2242 dbgs() << "\t ASAP = " << getASAP(&SUnits[i]) << "\n";
2243 dbgs() << "\t ALAP = " << getALAP(&SUnits[i]) << "\n";
2244 dbgs() << "\t MOV = " << getMOV(&SUnits[i]) << "\n";
2245 dbgs() << "\t D = " << getDepth(&SUnits[i]) << "\n";
2246 dbgs() << "\t H = " << getHeight(&SUnits[i]) << "\n";
2247 dbgs() << "\t ZLD = " << getZeroLatencyDepth(&SUnits[i]) << "\n";
2248 dbgs() << "\t ZLH = " << getZeroLatencyHeight(&SUnits[i]) << "\n";
2249 }
2250 });
2251}
2252
2253/// Compute the Pred_L(O) set, as defined in the paper. The set is defined
2254/// as the predecessors of the elements of NodeOrder that are not also in
2255/// NodeOrder.
2258 const NodeSet *S = nullptr) {
2259 Preds.clear();
2260
2261 for (SUnit *SU : NodeOrder) {
2262 for (const auto &IE : DDG->getInEdges(SU)) {
2263 SUnit *PredSU = IE.getSrc();
2264 if (S && S->count(PredSU) == 0)
2265 continue;
2266 if (IE.ignoreDependence(true))
2267 continue;
2268 if (NodeOrder.count(PredSU) == 0)
2269 Preds.insert(PredSU);
2270 }
2271
2272 // FIXME: The following loop-carried dependencies may also need to be
2273 // considered.
2274 // - Physical register dependencies (true-dependence and WAW).
2275 // - Memory dependencies.
2276 for (const auto &OE : DDG->getOutEdges(SU)) {
2277 SUnit *SuccSU = OE.getDst();
2278 if (!OE.isAntiDep())
2279 continue;
2280 if (S && S->count(SuccSU) == 0)
2281 continue;
2282 if (NodeOrder.count(SuccSU) == 0)
2283 Preds.insert(SuccSU);
2284 }
2285 }
2286 return !Preds.empty();
2287}
2288
2289/// Compute the Succ_L(O) set, as defined in the paper. The set is defined
2290/// as the successors of the elements of NodeOrder that are not also in
2291/// NodeOrder.
2294 const NodeSet *S = nullptr) {
2295 Succs.clear();
2296
2297 for (SUnit *SU : NodeOrder) {
2298 for (const auto &OE : DDG->getOutEdges(SU)) {
2299 SUnit *SuccSU = OE.getDst();
2300 if (S && S->count(SuccSU) == 0)
2301 continue;
2302 if (OE.ignoreDependence(false))
2303 continue;
2304 if (NodeOrder.count(SuccSU) == 0)
2305 Succs.insert(SuccSU);
2306 }
2307
2308 // FIXME: The following loop-carried dependencies may also need to be
2309 // considered.
2310 // - Physical register dependnecies (true-dependnece and WAW).
2311 // - Memory dependencies.
2312 for (const auto &IE : DDG->getInEdges(SU)) {
2313 SUnit *PredSU = IE.getSrc();
2314 if (!IE.isAntiDep())
2315 continue;
2316 if (S && S->count(PredSU) == 0)
2317 continue;
2318 if (NodeOrder.count(PredSU) == 0)
2319 Succs.insert(PredSU);
2320 }
2321 }
2322 return !Succs.empty();
2323}
2324
2325/// Return true if there is a path from the specified node to any of the nodes
2326/// in DestNodes. Keep track and return the nodes in any path.
2327static bool computePath(SUnit *Cur, SetVector<SUnit *> &Path,
2328 SetVector<SUnit *> &DestNodes,
2329 SetVector<SUnit *> &Exclude,
2330 SmallPtrSet<SUnit *, 8> &Visited,
2331 SwingSchedulerDDG *DDG) {
2332 if (Cur->isBoundaryNode())
2333 return false;
2334 if (Exclude.contains(Cur))
2335 return false;
2336 if (DestNodes.contains(Cur))
2337 return true;
2338 if (!Visited.insert(Cur).second)
2339 return Path.contains(Cur);
2340 bool FoundPath = false;
2341 for (const auto &OE : DDG->getOutEdges(Cur))
2342 if (!OE.ignoreDependence(false))
2343 FoundPath |=
2344 computePath(OE.getDst(), Path, DestNodes, Exclude, Visited, DDG);
2345 for (const auto &IE : DDG->getInEdges(Cur))
2346 if (IE.isAntiDep() && IE.getDistance() == 0)
2347 FoundPath |=
2348 computePath(IE.getSrc(), Path, DestNodes, Exclude, Visited, DDG);
2349 if (FoundPath)
2350 Path.insert(Cur);
2351 return FoundPath;
2352}
2353
2354/// Compute the live-out registers for the instructions in a node-set.
2355/// The live-out registers are those that are defined in the node-set,
2356/// but not used. Except for use operands of Phis.
2358 NodeSet &NS) {
2360 MachineRegisterInfo &MRI = MF.getRegInfo();
2363 for (SUnit *SU : NS) {
2364 const MachineInstr *MI = SU->getInstr();
2365 if (MI->isPHI())
2366 continue;
2367 for (const MachineOperand &MO : MI->all_uses()) {
2368 Register Reg = MO.getReg();
2369 if (Reg.isVirtual())
2370 Uses.insert(VirtRegOrUnit(Reg));
2371 else if (MRI.isAllocatable(Reg))
2372 for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
2373 Uses.insert(VirtRegOrUnit(Unit));
2374 }
2375 }
2376 for (SUnit *SU : NS)
2377 for (const MachineOperand &MO : SU->getInstr()->all_defs())
2378 if (!MO.isDead()) {
2379 Register Reg = MO.getReg();
2380 if (Reg.isVirtual()) {
2381 if (!Uses.count(VirtRegOrUnit(Reg)))
2382 LiveOutRegs.emplace_back(VirtRegOrUnit(Reg),
2384 } else if (MRI.isAllocatable(Reg)) {
2385 for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
2386 if (!Uses.count(VirtRegOrUnit(Unit)))
2387 LiveOutRegs.emplace_back(VirtRegOrUnit(Unit),
2389 }
2390 }
2391 RPTracker.addLiveRegs(LiveOutRegs);
2392}
2393
2394/// A heuristic to filter nodes in recurrent node-sets if the register
2395/// pressure of a set is too high.
2396void SwingSchedulerDAG::registerPressureFilter(NodeSetType &NodeSets) {
2397 for (auto &NS : NodeSets) {
2398 // Skip small node-sets since they won't cause register pressure problems.
2399 if (NS.size() <= 2)
2400 continue;
2401 IntervalPressure RecRegPressure;
2402 RegPressureTracker RecRPTracker(RecRegPressure);
2403 RecRPTracker.init(&MF, &RegClassInfo, &LIS, BB, BB->end(), false, true);
2404 computeLiveOuts(MF, RecRPTracker, NS);
2405 RecRPTracker.closeBottom();
2406
2407 std::vector<SUnit *> SUnits(NS.begin(), NS.end());
2408 llvm::sort(SUnits, [](const SUnit *A, const SUnit *B) {
2409 return A->NodeNum > B->NodeNum;
2410 });
2411
2412 for (auto &SU : SUnits) {
2413 // Since we're computing the register pressure for a subset of the
2414 // instructions in a block, we need to set the tracker for each
2415 // instruction in the node-set. The tracker is set to the instruction
2416 // just after the one we're interested in.
2418 RecRPTracker.setPos(std::next(CurInstI));
2419
2420 RegPressureDelta RPDelta;
2421 ArrayRef<PressureChange> CriticalPSets;
2422 RecRPTracker.getMaxUpwardPressureDelta(SU->getInstr(), nullptr, RPDelta,
2423 CriticalPSets,
2424 RecRegPressure.MaxSetPressure);
2425 if (RPDelta.Excess.isValid()) {
2426 LLVM_DEBUG(
2427 dbgs() << "Excess register pressure: SU(" << SU->NodeNum << ") "
2428 << TRI->getRegPressureSetName(RPDelta.Excess.getPSet())
2429 << ":" << RPDelta.Excess.getUnitInc() << "\n");
2430 NS.setExceedPressure(SU);
2431 break;
2432 }
2433 RecRPTracker.recede();
2434 }
2435 }
2436}
2437
2438/// A heuristic to colocate node sets that have the same set of
2439/// successors.
2440void SwingSchedulerDAG::colocateNodeSets(NodeSetType &NodeSets) {
2441 unsigned Colocate = 0;
2442 for (int i = 0, e = NodeSets.size(); i < e; ++i) {
2443 NodeSet &N1 = NodeSets[i];
2444 SmallSetVector<SUnit *, 8> S1;
2445 if (N1.empty() || !succ_L(N1, S1, DDG.get()))
2446 continue;
2447 for (int j = i + 1; j < e; ++j) {
2448 NodeSet &N2 = NodeSets[j];
2449 if (N1.compareRecMII(N2) != 0)
2450 continue;
2451 SmallSetVector<SUnit *, 8> S2;
2452 if (N2.empty() || !succ_L(N2, S2, DDG.get()))
2453 continue;
2454 if (llvm::set_is_subset(S1, S2) && S1.size() == S2.size()) {
2455 N1.setColocate(++Colocate);
2456 N2.setColocate(Colocate);
2457 break;
2458 }
2459 }
2460 }
2461}
2462
2463/// Check if the existing node-sets are profitable. If not, then ignore the
2464/// recurrent node-sets, and attempt to schedule all nodes together. This is
2465/// a heuristic. If the MII is large and all the recurrent node-sets are small,
2466/// then it's best to try to schedule all instructions together instead of
2467/// starting with the recurrent node-sets.
2468void SwingSchedulerDAG::checkNodeSets(NodeSetType &NodeSets) {
2469 // Look for loops with a large MII.
2470 if (MII < 17)
2471 return;
2472 // Check if the node-set contains only a simple add recurrence.
2473 for (auto &NS : NodeSets) {
2474 if (NS.getRecMII() > 2)
2475 return;
2476 if (NS.getMaxDepth() > MII)
2477 return;
2478 }
2479 NodeSets.clear();
2480 LLVM_DEBUG(dbgs() << "Clear recurrence node-sets\n");
2481}
2482
2483/// Add the nodes that do not belong to a recurrence set into groups
2484/// based upon connected components.
2485void SwingSchedulerDAG::groupRemainingNodes(NodeSetType &NodeSets) {
2486 SetVector<SUnit *> NodesAdded;
2487 SmallPtrSet<SUnit *, 8> Visited;
2488 // Add the nodes that are on a path between the previous node sets and
2489 // the current node set.
2490 for (NodeSet &I : NodeSets) {
2491 SmallSetVector<SUnit *, 8> N;
2492 // Add the nodes from the current node set to the previous node set.
2493 if (succ_L(I, N, DDG.get())) {
2494 SetVector<SUnit *> Path;
2495 for (SUnit *NI : N) {
2496 Visited.clear();
2497 computePath(NI, Path, NodesAdded, I, Visited, DDG.get());
2498 }
2499 if (!Path.empty())
2500 I.insert(Path.begin(), Path.end());
2501 }
2502 // Add the nodes from the previous node set to the current node set.
2503 N.clear();
2504 if (succ_L(NodesAdded, N, DDG.get())) {
2505 SetVector<SUnit *> Path;
2506 for (SUnit *NI : N) {
2507 Visited.clear();
2508 computePath(NI, Path, I, NodesAdded, Visited, DDG.get());
2509 }
2510 if (!Path.empty())
2511 I.insert(Path.begin(), Path.end());
2512 }
2513 NodesAdded.insert_range(I);
2514 }
2515
2516 // Create a new node set with the connected nodes of any successor of a node
2517 // in a recurrent set.
2518 NodeSet NewSet;
2519 SmallSetVector<SUnit *, 8> N;
2520 if (succ_L(NodesAdded, N, DDG.get()))
2521 for (SUnit *I : N)
2522 addConnectedNodes(I, NewSet, NodesAdded);
2523 if (!NewSet.empty())
2524 NodeSets.push_back(NewSet);
2525
2526 // Create a new node set with the connected nodes of any predecessor of a node
2527 // in a recurrent set.
2528 NewSet.clear();
2529 if (pred_L(NodesAdded, N, DDG.get()))
2530 for (SUnit *I : N)
2531 addConnectedNodes(I, NewSet, NodesAdded);
2532 if (!NewSet.empty())
2533 NodeSets.push_back(NewSet);
2534
2535 // Create new nodes sets with the connected nodes any remaining node that
2536 // has no predecessor.
2537 for (SUnit &SU : SUnits) {
2538 if (NodesAdded.count(&SU) == 0) {
2539 NewSet.clear();
2540 addConnectedNodes(&SU, NewSet, NodesAdded);
2541 if (!NewSet.empty())
2542 NodeSets.push_back(NewSet);
2543 }
2544 }
2545}
2546
2547/// Add the node to the set, and add all of its connected nodes to the set.
2548void SwingSchedulerDAG::addConnectedNodes(SUnit *SU, NodeSet &NewSet,
2549 SetVector<SUnit *> &NodesAdded) {
2550 NewSet.insert(SU);
2551 NodesAdded.insert(SU);
2552 for (auto &OE : DDG->getOutEdges(SU)) {
2553 SUnit *Successor = OE.getDst();
2554 if (!OE.isArtificial() && !Successor->isBoundaryNode() &&
2555 NodesAdded.count(Successor) == 0)
2556 addConnectedNodes(Successor, NewSet, NodesAdded);
2557 }
2558 for (auto &IE : DDG->getInEdges(SU)) {
2559 SUnit *Predecessor = IE.getSrc();
2560 if (!IE.isArtificial() && NodesAdded.count(Predecessor) == 0)
2561 addConnectedNodes(Predecessor, NewSet, NodesAdded);
2562 }
2563}
2564
2565/// Return true if Set1 contains elements in Set2. The elements in common
2566/// are returned in a different container.
2567static bool isIntersect(SmallSetVector<SUnit *, 8> &Set1, const NodeSet &Set2,
2569 Result.clear();
2570 for (SUnit *SU : Set1) {
2571 if (Set2.count(SU) != 0)
2572 Result.insert(SU);
2573 }
2574 return !Result.empty();
2575}
2576
2577/// Merge the recurrence node sets that have the same initial node.
2578void SwingSchedulerDAG::fuseRecs(NodeSetType &NodeSets) {
2579 for (NodeSetType::iterator I = NodeSets.begin(), E = NodeSets.end(); I != E;
2580 ++I) {
2581 NodeSet &NI = *I;
2582 for (NodeSetType::iterator J = I + 1; J != E;) {
2583 NodeSet &NJ = *J;
2584 if (NI.getNode(0)->NodeNum == NJ.getNode(0)->NodeNum) {
2585 if (NJ.compareRecMII(NI) > 0)
2586 NI.setRecMII(NJ.getRecMII());
2587 for (SUnit *SU : *J)
2588 I->insert(SU);
2589 NodeSets.erase(J);
2590 E = NodeSets.end();
2591 } else {
2592 ++J;
2593 }
2594 }
2595 }
2596}
2597
2598/// Remove nodes that have been scheduled in previous NodeSets.
2599void SwingSchedulerDAG::removeDuplicateNodes(NodeSetType &NodeSets) {
2600 for (NodeSetType::iterator I = NodeSets.begin(), E = NodeSets.end(); I != E;
2601 ++I)
2602 for (NodeSetType::iterator J = I + 1; J != E;) {
2603 J->remove_if([&](SUnit *SUJ) { return I->count(SUJ); });
2604
2605 if (J->empty()) {
2606 NodeSets.erase(J);
2607 E = NodeSets.end();
2608 } else {
2609 ++J;
2610 }
2611 }
2612}
2613
2614/// Compute an ordered list of the dependence graph nodes, which
2615/// indicates the order that the nodes will be scheduled. This is a
2616/// two-level algorithm. First, a partial order is created, which
2617/// consists of a list of sets ordered from highest to lowest priority.
2618void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
2619 SmallSetVector<SUnit *, 8> R;
2620 NodeOrder.clear();
2621
2622 for (auto &Nodes : NodeSets) {
2623 LLVM_DEBUG(dbgs() << "NodeSet size " << Nodes.size() << "\n");
2624 OrderKind Order;
2625 SmallSetVector<SUnit *, 8> N;
2626 if (pred_L(NodeOrder, N, DDG.get()) && llvm::set_is_subset(N, Nodes)) {
2627 R.insert_range(N);
2628 Order = BottomUp;
2629 LLVM_DEBUG(dbgs() << " Bottom up (preds) ");
2630 } else if (succ_L(NodeOrder, N, DDG.get()) &&
2631 llvm::set_is_subset(N, Nodes)) {
2632 R.insert_range(N);
2633 Order = TopDown;
2634 LLVM_DEBUG(dbgs() << " Top down (succs) ");
2635 } else if (isIntersect(N, Nodes, R)) {
2636 // If some of the successors are in the existing node-set, then use the
2637 // top-down ordering.
2638 Order = TopDown;
2639 LLVM_DEBUG(dbgs() << " Top down (intersect) ");
2640 } else if (NodeSets.size() == 1) {
2641 for (const auto &N : Nodes)
2642 if (N->Succs.size() == 0)
2643 R.insert(N);
2644 Order = BottomUp;
2645 LLVM_DEBUG(dbgs() << " Bottom up (all) ");
2646 } else {
2647 // Find the node with the highest ASAP.
2648 SUnit *maxASAP = nullptr;
2649 for (SUnit *SU : Nodes) {
2650 if (maxASAP == nullptr || getASAP(SU) > getASAP(maxASAP) ||
2651 (getASAP(SU) == getASAP(maxASAP) && SU->NodeNum > maxASAP->NodeNum))
2652 maxASAP = SU;
2653 }
2654 R.insert(maxASAP);
2655 Order = BottomUp;
2656 LLVM_DEBUG(dbgs() << " Bottom up (default) ");
2657 }
2658
2659 while (!R.empty()) {
2660 if (Order == TopDown) {
2661 // Choose the node with the maximum height. If more than one, choose
2662 // the node wiTH the maximum ZeroLatencyHeight. If still more than one,
2663 // choose the node with the lowest MOV.
2664 while (!R.empty()) {
2665 SUnit *maxHeight = nullptr;
2666 for (SUnit *I : R) {
2667 if (maxHeight == nullptr || getHeight(I) > getHeight(maxHeight))
2668 maxHeight = I;
2669 else if (getHeight(I) == getHeight(maxHeight) &&
2670 getZeroLatencyHeight(I) > getZeroLatencyHeight(maxHeight))
2671 maxHeight = I;
2672 else if (getHeight(I) == getHeight(maxHeight) &&
2673 getZeroLatencyHeight(I) ==
2674 getZeroLatencyHeight(maxHeight) &&
2675 getMOV(I) < getMOV(maxHeight))
2676 maxHeight = I;
2677 }
2678 NodeOrder.insert(maxHeight);
2679 LLVM_DEBUG(dbgs() << maxHeight->NodeNum << " ");
2680 R.remove(maxHeight);
2681 for (const auto &OE : DDG->getOutEdges(maxHeight)) {
2682 SUnit *SU = OE.getDst();
2683 if (Nodes.count(SU) == 0)
2684 continue;
2685 if (NodeOrder.contains(SU))
2686 continue;
2687 if (OE.ignoreDependence(false))
2688 continue;
2689 R.insert(SU);
2690 }
2691
2692 // FIXME: The following loop-carried dependencies may also need to be
2693 // considered.
2694 // - Physical register dependnecies (true-dependnece and WAW).
2695 // - Memory dependencies.
2696 for (const auto &IE : DDG->getInEdges(maxHeight)) {
2697 SUnit *SU = IE.getSrc();
2698 if (!IE.isAntiDep())
2699 continue;
2700 if (Nodes.count(SU) == 0)
2701 continue;
2702 if (NodeOrder.contains(SU))
2703 continue;
2704 R.insert(SU);
2705 }
2706 }
2707 Order = BottomUp;
2708 LLVM_DEBUG(dbgs() << "\n Switching order to bottom up ");
2709 SmallSetVector<SUnit *, 8> N;
2710 if (pred_L(NodeOrder, N, DDG.get(), &Nodes))
2711 R.insert_range(N);
2712 } else {
2713 // Choose the node with the maximum depth. If more than one, choose
2714 // the node with the maximum ZeroLatencyDepth. If still more than one,
2715 // choose the node with the lowest MOV.
2716 while (!R.empty()) {
2717 SUnit *maxDepth = nullptr;
2718 for (SUnit *I : R) {
2719 if (maxDepth == nullptr || getDepth(I) > getDepth(maxDepth))
2720 maxDepth = I;
2721 else if (getDepth(I) == getDepth(maxDepth) &&
2722 getZeroLatencyDepth(I) > getZeroLatencyDepth(maxDepth))
2723 maxDepth = I;
2724 else if (getDepth(I) == getDepth(maxDepth) &&
2725 getZeroLatencyDepth(I) == getZeroLatencyDepth(maxDepth) &&
2726 getMOV(I) < getMOV(maxDepth))
2727 maxDepth = I;
2728 }
2729 NodeOrder.insert(maxDepth);
2730 LLVM_DEBUG(dbgs() << maxDepth->NodeNum << " ");
2731 R.remove(maxDepth);
2732 if (Nodes.isExceedSU(maxDepth)) {
2733 Order = TopDown;
2734 R.clear();
2735 R.insert(Nodes.getNode(0));
2736 break;
2737 }
2738 for (const auto &IE : DDG->getInEdges(maxDepth)) {
2739 SUnit *SU = IE.getSrc();
2740 if (Nodes.count(SU) == 0)
2741 continue;
2742 if (NodeOrder.contains(SU))
2743 continue;
2744 R.insert(SU);
2745 }
2746
2747 // FIXME: The following loop-carried dependencies may also need to be
2748 // considered.
2749 // - Physical register dependnecies (true-dependnece and WAW).
2750 // - Memory dependencies.
2751 for (const auto &OE : DDG->getOutEdges(maxDepth)) {
2752 SUnit *SU = OE.getDst();
2753 if (!OE.isAntiDep())
2754 continue;
2755 if (Nodes.count(SU) == 0)
2756 continue;
2757 if (NodeOrder.contains(SU))
2758 continue;
2759 R.insert(SU);
2760 }
2761 }
2762 Order = TopDown;
2763 LLVM_DEBUG(dbgs() << "\n Switching order to top down ");
2764 SmallSetVector<SUnit *, 8> N;
2765 if (succ_L(NodeOrder, N, DDG.get(), &Nodes))
2766 R.insert_range(N);
2767 }
2768 }
2769 LLVM_DEBUG(dbgs() << "\nDone with Nodeset\n");
2770 }
2771
2772 LLVM_DEBUG({
2773 dbgs() << "Node order: ";
2774 for (SUnit *I : NodeOrder)
2775 dbgs() << " " << I->NodeNum << " ";
2776 dbgs() << "\n";
2777 });
2778}
2779
2780/// Process the nodes in the computed order and create the pipelined schedule
2781/// of the instructions, if possible. Return true if a schedule is found.
2782bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
2783
2784 if (NodeOrder.empty()){
2785 LLVM_DEBUG(dbgs() << "NodeOrder is empty! abort scheduling\n" );
2786 return false;
2787 }
2788
2789 bool scheduleFound = false;
2790 std::unique_ptr<HighRegisterPressureDetector> HRPDetector;
2791 if (LimitRegPressure) {
2792 HRPDetector =
2793 std::make_unique<HighRegisterPressureDetector>(Loop.getHeader(), MF);
2794 HRPDetector->init(RegClassInfo);
2795 }
2796 // Keep increasing II until a valid schedule is found.
2797 for (unsigned II = MII; II <= MAX_II && !scheduleFound; ++II) {
2798 Schedule.reset();
2799 Schedule.setInitiationInterval(II);
2800 LLVM_DEBUG(dbgs() << "Try to schedule with " << II << "\n");
2801
2804 do {
2805 SUnit *SU = *NI;
2806
2807 // Compute the schedule time for the instruction, which is based
2808 // upon the scheduled time for any predecessors/successors.
2809 int EarlyStart = INT_MIN;
2810 int LateStart = INT_MAX;
2811 Schedule.computeStart(SU, &EarlyStart, &LateStart, II, this);
2812 LLVM_DEBUG({
2813 dbgs() << "\n";
2814 dbgs() << "Inst (" << SU->NodeNum << ") ";
2815 SU->getInstr()->dump();
2816 dbgs() << "\n";
2817 });
2818 LLVM_DEBUG(
2819 dbgs() << format("\tes: %8x ls: %8x\n", EarlyStart, LateStart));
2820
2821 if (EarlyStart > LateStart)
2822 scheduleFound = false;
2823 else if (EarlyStart != INT_MIN && LateStart == INT_MAX)
2824 scheduleFound =
2825 Schedule.insert(SU, EarlyStart, EarlyStart + (int)II - 1, II);
2826 else if (EarlyStart == INT_MIN && LateStart != INT_MAX)
2827 scheduleFound =
2828 Schedule.insert(SU, LateStart, LateStart - (int)II + 1, II);
2829 else if (EarlyStart != INT_MIN && LateStart != INT_MAX) {
2830 LateStart = std::min(LateStart, EarlyStart + (int)II - 1);
2831 // When scheduling a Phi it is better to start at the late cycle and
2832 // go backwards. The default order may insert the Phi too far away
2833 // from its first dependence.
2834 // Also, do backward search when all scheduled predecessors are
2835 // loop-carried output/order dependencies. Empirically, there are also
2836 // cases where scheduling becomes possible with backward search.
2837 if (SU->getInstr()->isPHI() ||
2838 Schedule.onlyHasLoopCarriedOutputOrOrderPreds(SU, this->getDDG()))
2839 scheduleFound = Schedule.insert(SU, LateStart, EarlyStart, II);
2840 else
2841 scheduleFound = Schedule.insert(SU, EarlyStart, LateStart, II);
2842 } else {
2843 int FirstCycle = Schedule.getFirstCycle();
2844 scheduleFound = Schedule.insert(SU, FirstCycle + getASAP(SU),
2845 FirstCycle + getASAP(SU) + II - 1, II);
2846 }
2847
2848 // Even if we find a schedule, make sure the schedule doesn't exceed the
2849 // allowable number of stages. We keep trying if this happens.
2850 if (scheduleFound)
2851 if (SwpMaxStages > -1 &&
2852 Schedule.getMaxStageCount() > (unsigned)SwpMaxStages)
2853 scheduleFound = false;
2854
2855 LLVM_DEBUG({
2856 if (!scheduleFound)
2857 dbgs() << "\tCan't schedule\n";
2858 });
2859 } while (++NI != NE && scheduleFound);
2860
2861 // If a schedule is found, validate it against the validation-only
2862 // dependencies.
2863 if (scheduleFound)
2864 scheduleFound = DDG->isValidSchedule(Schedule);
2865
2866 // If a schedule is found, ensure non-pipelined instructions are in stage 0
2867 if (scheduleFound)
2868 scheduleFound =
2869 Schedule.normalizeNonPipelinedInstructions(this, LoopPipelinerInfo);
2870
2871 // If a schedule is found, check if it is a valid schedule too.
2872 if (scheduleFound)
2873 scheduleFound = Schedule.isValidSchedule(this);
2874
2875 // If a schedule was found and the option is enabled, check if the schedule
2876 // might generate additional register spills/fills.
2877 if (scheduleFound && LimitRegPressure)
2878 scheduleFound =
2879 !HRPDetector->detect(this, Schedule, Schedule.getMaxStageCount());
2880 }
2881
2882 LLVM_DEBUG(dbgs() << "Schedule Found? " << scheduleFound
2883 << " (II=" << Schedule.getInitiationInterval()
2884 << ")\n");
2885
2886 if (scheduleFound) {
2887 scheduleFound = LoopPipelinerInfo->shouldUseSchedule(*this, Schedule);
2888 if (!scheduleFound)
2889 LLVM_DEBUG(dbgs() << "Target rejected schedule\n");
2890 }
2891
2892 if (scheduleFound) {
2893 Schedule.finalizeSchedule(this);
2894 Pass.ORE->emit([&]() {
2895 return MachineOptimizationRemarkAnalysis(
2896 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
2897 << "Schedule found with Initiation Interval: "
2898 << ore::NV("II", Schedule.getInitiationInterval())
2899 << ", MaxStageCount: "
2900 << ore::NV("MaxStageCount", Schedule.getMaxStageCount());
2901 });
2902 } else
2903 Schedule.reset();
2904
2905 return scheduleFound && Schedule.getMaxStageCount() > 0;
2906}
2907
2909 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
2910 Register Result;
2911 for (const MachineOperand &Use : MI.all_uses()) {
2912 Register Reg = Use.getReg();
2913 if (!Reg.isVirtual())
2914 return Register();
2915 if (MRI.getVRegDef(Reg)->getParent() != MI.getParent())
2916 continue;
2917 if (Result)
2918 return Register();
2919 Result = Reg;
2920 }
2921 return Result;
2922}
2923
2924/// When Op is a value that is incremented recursively in a loop and there is a
2925/// unique instruction that increments it, returns true and sets Value.
2927 if (!Op.isReg() || !Op.getReg().isVirtual())
2928 return false;
2929
2930 Register OrgReg = Op.getReg();
2931 Register CurReg = OrgReg;
2932 const MachineBasicBlock *LoopBB = Op.getParent()->getParent();
2933 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
2934
2935 const TargetInstrInfo *TII =
2936 LoopBB->getParent()->getSubtarget().getInstrInfo();
2937 const TargetRegisterInfo *TRI =
2938 LoopBB->getParent()->getSubtarget().getRegisterInfo();
2939
2940 MachineInstr *Phi = nullptr;
2941 MachineInstr *Increment = nullptr;
2942
2943 // Traverse definitions until it reaches Op or an instruction that does not
2944 // satisfy the condition.
2945 // Acceptable example:
2946 // bb.0:
2947 // %0 = PHI %3, %bb.0, ...
2948 // %2 = ADD %0, Value
2949 // ... = LOAD %2(Op)
2950 // %3 = COPY %2
2951 while (true) {
2952 if (!CurReg.isValid() || !CurReg.isVirtual())
2953 return false;
2954 MachineInstr *Def = MRI.getVRegDef(CurReg);
2955 if (Def->getParent() != LoopBB)
2956 return false;
2957
2958 if (Def->isCopy()) {
2959 // Ignore copy instructions unless they contain subregisters
2960 if (Def->getOperand(0).getSubReg() || Def->getOperand(1).getSubReg())
2961 return false;
2962 CurReg = Def->getOperand(1).getReg();
2963 } else if (Def->isPHI()) {
2964 // There must be just one Phi
2965 if (Phi)
2966 return false;
2967 Phi = Def;
2968 CurReg = getLoopPhiReg(*Def, LoopBB);
2969 } else if (TII->getIncrementValue(*Def, Value)) {
2970 // Potentially a unique increment
2971 if (Increment)
2972 // Multiple increments exist
2973 return false;
2974
2975 const MachineOperand *BaseOp;
2976 int64_t Offset;
2977 bool OffsetIsScalable;
2978 if (TII->getMemOperandWithOffset(*Def, BaseOp, Offset, OffsetIsScalable,
2979 TRI)) {
2980 // Pre/post increment instruction
2981 CurReg = BaseOp->getReg();
2982 } else {
2983 // If only one of the operands is defined within the loop, it is assumed
2984 // to be an incremented value.
2985 CurReg = findUniqueOperandDefinedInLoop(*Def);
2986 if (!CurReg.isValid())
2987 return false;
2988 }
2989 Increment = Def;
2990 } else {
2991 return false;
2992 }
2993 if (CurReg == OrgReg)
2994 break;
2995 }
2996
2997 if (!Phi || !Increment)
2998 return false;
2999
3000 return true;
3001}
3002
3003/// Return true if we can compute the amount the instruction changes
3004/// during each iteration. Set Delta to the amount of the change.
3005bool SwingSchedulerDAG::computeDelta(const MachineInstr &MI, int &Delta) const {
3006 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
3007 const MachineOperand *BaseOp;
3008 int64_t Offset;
3009 bool OffsetIsScalable;
3010 if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable, TRI))
3011 return false;
3012
3013 // FIXME: This algorithm assumes instructions have fixed-size offsets.
3014 if (OffsetIsScalable)
3015 return false;
3016
3017 if (!BaseOp->isReg())
3018 return false;
3019
3020 return findLoopIncrementValue(*BaseOp, Delta);
3021}
3022
3023/// Check if we can change the instruction to use an offset value from the
3024/// previous iteration. If so, return true and set the base and offset values
3025/// so that we can rewrite the load, if necessary.
3026/// v1 = Phi(v0, v3)
3027/// v2 = load v1, 0
3028/// v3 = post_store v1, 4, x
3029/// This function enables the load to be rewritten as v2 = load v3, 4.
3030bool SwingSchedulerDAG::canUseLastOffsetValue(MachineInstr *MI,
3031 unsigned &BasePos,
3032 unsigned &OffsetPos,
3033 Register &NewBase,
3034 int64_t &Offset) {
3035 // Get the load instruction.
3036 if (TII->isPostIncrement(*MI))
3037 return false;
3038 unsigned BasePosLd, OffsetPosLd;
3039 if (!TII->getBaseAndOffsetPosition(*MI, BasePosLd, OffsetPosLd))
3040 return false;
3041 Register BaseReg = MI->getOperand(BasePosLd).getReg();
3042
3043 // Look for the Phi instruction.
3044 MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
3045 MachineInstr *Phi = MRI.getVRegDef(BaseReg);
3046 if (!Phi || !Phi->isPHI())
3047 return false;
3048 // Get the register defined in the loop block.
3049 Register PrevReg = getLoopPhiReg(*Phi, MI->getParent());
3050 if (!PrevReg)
3051 return false;
3052
3053 // Check for the post-increment load/store instruction.
3054 MachineInstr *PrevDef = MRI.getVRegDef(PrevReg);
3055 if (!PrevDef || PrevDef == MI)
3056 return false;
3057
3058 if (!TII->isPostIncrement(*PrevDef))
3059 return false;
3060
3061 unsigned BasePos1 = 0, OffsetPos1 = 0;
3062 if (!TII->getBaseAndOffsetPosition(*PrevDef, BasePos1, OffsetPos1))
3063 return false;
3064
3065 // Make sure that the instructions do not access the same memory location in
3066 // the next iteration.
3067 int64_t LoadOffset = MI->getOperand(OffsetPosLd).getImm();
3068 int64_t StoreOffset = PrevDef->getOperand(OffsetPos1).getImm();
3069 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3070 NewMI->getOperand(OffsetPosLd).setImm(LoadOffset + StoreOffset);
3071 bool Disjoint = TII->areMemAccessesTriviallyDisjoint(*NewMI, *PrevDef);
3072 MF.deleteMachineInstr(NewMI);
3073 if (!Disjoint)
3074 return false;
3075
3076 // Set the return value once we determine that we return true.
3077 BasePos = BasePosLd;
3078 OffsetPos = OffsetPosLd;
3079 NewBase = PrevReg;
3080 Offset = StoreOffset;
3081 return true;
3082}
3083
3084/// Apply changes to the instruction if needed. The changes are need
3085/// to improve the scheduling and depend up on the final schedule.
3087 SMSchedule &Schedule) {
3088 SUnit *SU = getSUnit(MI);
3090 InstrChanges.find(SU);
3091 if (It != InstrChanges.end()) {
3092 std::pair<Register, int64_t> RegAndOffset = It->second;
3093 unsigned BasePos, OffsetPos;
3094 if (!TII->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos))
3095 return;
3096 Register BaseReg = MI->getOperand(BasePos).getReg();
3097 MachineInstr *LoopDef = findDefInLoop(BaseReg);
3098 int DefStageNum = Schedule.stageScheduled(getSUnit(LoopDef));
3099 int DefCycleNum = Schedule.cycleScheduled(getSUnit(LoopDef));
3100 int BaseStageNum = Schedule.stageScheduled(SU);
3101 int BaseCycleNum = Schedule.cycleScheduled(SU);
3102 if (BaseStageNum < DefStageNum) {
3103 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3104 int OffsetDiff = DefStageNum - BaseStageNum;
3105 if (DefCycleNum < BaseCycleNum) {
3106 NewMI->getOperand(BasePos).setReg(RegAndOffset.first);
3107 if (OffsetDiff > 0)
3108 --OffsetDiff;
3109 }
3110 int64_t NewOffset =
3111 MI->getOperand(OffsetPos).getImm() + RegAndOffset.second * OffsetDiff;
3112 NewMI->getOperand(OffsetPos).setImm(NewOffset);
3113 SU->setInstr(NewMI);
3114 MISUnitMap[NewMI] = SU;
3115 NewMIs[MI] = NewMI;
3116 }
3117 }
3118}
3119
3120/// Return the instruction in the loop that defines the register.
3121/// If the definition is a Phi, then follow the Phi operand to
3122/// the instruction in the loop.
3123MachineInstr *SwingSchedulerDAG::findDefInLoop(Register Reg) {
3125 MachineInstr *Def = MRI.getVRegDef(Reg);
3126 while (Def->isPHI()) {
3127 if (!Visited.insert(Def).second)
3128 break;
3129 for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2)
3130 if (Def->getOperand(i + 1).getMBB() == BB) {
3131 Def = MRI.getVRegDef(Def->getOperand(i).getReg());
3132 break;
3133 }
3134 }
3135 return Def;
3136}
3137
3138/// Return false if there is no overlap between the region accessed by BaseMI in
3139/// an iteration and the region accessed by OtherMI in subsequent iterations.
3141 const MachineInstr *BaseMI, const MachineInstr *OtherMI) const {
3142 int DeltaB, DeltaO, Delta;
3143 if (!computeDelta(*BaseMI, DeltaB) || !computeDelta(*OtherMI, DeltaO) ||
3144 DeltaB != DeltaO)
3145 return true;
3146 Delta = DeltaB;
3147
3148 const MachineOperand *BaseOpB, *BaseOpO;
3149 int64_t OffsetB, OffsetO;
3150 bool OffsetBIsScalable, OffsetOIsScalable;
3151 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
3152 if (!TII->getMemOperandWithOffset(*BaseMI, BaseOpB, OffsetB,
3153 OffsetBIsScalable, TRI) ||
3154 !TII->getMemOperandWithOffset(*OtherMI, BaseOpO, OffsetO,
3155 OffsetOIsScalable, TRI))
3156 return true;
3157
3158 if (OffsetBIsScalable || OffsetOIsScalable)
3159 return true;
3160
3161 if (!BaseOpB->isIdenticalTo(*BaseOpO)) {
3162 // Pass cases with different base operands but same initial values.
3163 // Typically for when pre/post increment is used.
3164
3165 if (!BaseOpB->isReg() || !BaseOpO->isReg())
3166 return true;
3167 Register RegB = BaseOpB->getReg(), RegO = BaseOpO->getReg();
3168 if (!RegB.isVirtual() || !RegO.isVirtual())
3169 return true;
3170
3171 MachineInstr *DefB = MRI.getVRegDef(BaseOpB->getReg());
3172 MachineInstr *DefO = MRI.getVRegDef(BaseOpO->getReg());
3173 if (!DefB || !DefO || !DefB->isPHI() || !DefO->isPHI())
3174 return true;
3175
3176 Register InitValB;
3177 Register LoopValB;
3178 Register InitValO;
3179 Register LoopValO;
3180 getPhiRegs(*DefB, BB, InitValB, LoopValB);
3181 getPhiRegs(*DefO, BB, InitValO, LoopValO);
3182 MachineInstr *InitDefB = MRI.getVRegDef(InitValB);
3183 MachineInstr *InitDefO = MRI.getVRegDef(InitValO);
3184
3185 if (!InitDefB->isIdenticalTo(*InitDefO))
3186 return true;
3187 }
3188
3189 LocationSize AccessSizeB = (*BaseMI->memoperands_begin())->getSize();
3190 LocationSize AccessSizeO = (*OtherMI->memoperands_begin())->getSize();
3191
3192 // This is the main test, which checks the offset values and the loop
3193 // increment value to determine if the accesses may be loop carried.
3194 if (!AccessSizeB.hasValue() || !AccessSizeO.hasValue())
3195 return true;
3196
3197 LLVM_DEBUG({
3198 dbgs() << "Overlap check:\n";
3199 dbgs() << " BaseMI: ";
3200 BaseMI->dump();
3201 dbgs() << " Base + " << OffsetB << " + I * " << Delta
3202 << ", Len: " << AccessSizeB.getValue() << "\n";
3203 dbgs() << " OtherMI: ";
3204 OtherMI->dump();
3205 dbgs() << " Base + " << OffsetO << " + I * " << Delta
3206 << ", Len: " << AccessSizeO.getValue() << "\n";
3207 });
3208
3209 // Excessive overlap may be detected in strided patterns.
3210 // For example, the memory addresses of the store and the load in
3211 // for (i=0; i<n; i+=2) a[i+1] = a[i];
3212 // are assumed to overlap.
3213 if (Delta < 0) {
3214 int64_t BaseMinAddr = OffsetB;
3215 int64_t OhterNextIterMaxAddr = OffsetO + Delta + AccessSizeO.getValue() - 1;
3216 if (BaseMinAddr > OhterNextIterMaxAddr) {
3217 LLVM_DEBUG(dbgs() << " Result: No overlap\n");
3218 return false;
3219 }
3220 } else {
3221 int64_t BaseMaxAddr = OffsetB + AccessSizeB.getValue() - 1;
3222 int64_t OtherNextIterMinAddr = OffsetO + Delta;
3223 if (BaseMaxAddr < OtherNextIterMinAddr) {
3224 LLVM_DEBUG(dbgs() << " Result: No overlap\n");
3225 return false;
3226 }
3227 }
3228 LLVM_DEBUG(dbgs() << " Result: Overlap\n");
3229 return true;
3230}
3231
3232void SwingSchedulerDAG::postProcessDAG() {
3233 for (auto &M : Mutations)
3234 M->apply(this);
3235}
3236
3237/// Try to schedule the node at the specified StartCycle and continue
3238/// until the node is schedule or the EndCycle is reached. This function
3239/// returns true if the node is scheduled. This routine may search either
3240/// forward or backward for a place to insert the instruction based upon
3241/// the relative values of StartCycle and EndCycle.
3242bool SMSchedule::insert(SUnit *SU, int StartCycle, int EndCycle, int II) {
3243 bool forward = true;
3244 LLVM_DEBUG({
3245 dbgs() << "Trying to insert node between " << StartCycle << " and "
3246 << EndCycle << " II: " << II << "\n";
3247 });
3248 if (StartCycle > EndCycle)
3249 forward = false;
3250
3251 // The terminating condition depends on the direction.
3252 int termCycle = forward ? EndCycle + 1 : EndCycle - 1;
3253 for (int curCycle = StartCycle; curCycle != termCycle;
3254 forward ? ++curCycle : --curCycle) {
3255
3256 if (ST.getInstrInfo()->isZeroCost(SU->getInstr()->getOpcode()) ||
3257 ProcItinResources.canReserveResources(*SU, curCycle)) {
3258 LLVM_DEBUG({
3259 dbgs() << "\tinsert at cycle " << curCycle << " ";
3260 SU->getInstr()->dump();
3261 });
3262
3263 if (!ST.getInstrInfo()->isZeroCost(SU->getInstr()->getOpcode()))
3264 ProcItinResources.reserveResources(*SU, curCycle);
3265 ScheduledInstrs[curCycle].push_back(SU);
3266 InstrToCycle.insert(std::make_pair(SU, curCycle));
3267 if (curCycle > LastCycle)
3268 LastCycle = curCycle;
3269 if (curCycle < FirstCycle)
3270 FirstCycle = curCycle;
3271 return true;
3272 }
3273 LLVM_DEBUG({
3274 dbgs() << "\tfailed to insert at cycle " << curCycle << " ";
3275 SU->getInstr()->dump();
3276 });
3277 }
3278 return false;
3279}
3280
3281/// If an instruction has a use that spans multiple iterations, then
3282/// return true. These instructions are characterized by having a back-ege
3283/// to a Phi, which contains a reference to another Phi.
3285 for (auto &P : SU->Preds)
3286 if (P.getKind() == SDep::Anti && P.getSUnit()->getInstr()->isPHI())
3287 for (auto &S : P.getSUnit()->Succs)
3288 if (S.getKind() == SDep::Data && S.getSUnit()->getInstr()->isPHI())
3289 return P.getSUnit();
3290 return nullptr;
3291}
3292
3293/// Compute the scheduling start slot for the instruction. The start slot
3294/// depends on any predecessor or successor nodes scheduled already.
3295void SMSchedule::computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
3296 int II, SwingSchedulerDAG *DAG) {
3297 const SwingSchedulerDDG *DDG = DAG->getDDG();
3298
3299 // Iterate over each instruction that has been scheduled already. The start
3300 // slot computation depends on whether the previously scheduled instruction
3301 // is a predecessor or successor of the specified instruction.
3302 for (int cycle = getFirstCycle(); cycle <= LastCycle; ++cycle) {
3303 for (SUnit *I : getInstructions(cycle)) {
3304 for (const auto &IE : DDG->getInEdges(SU)) {
3305 if (IE.getSrc() == I) {
3306 int EarlyStart = cycle + IE.getLatency() - IE.getDistance() * II;
3307 *MaxEarlyStart = std::max(*MaxEarlyStart, EarlyStart);
3308 }
3309 }
3310
3311 for (const auto &OE : DDG->getOutEdges(SU)) {
3312 if (OE.getDst() == I) {
3313 int LateStart = cycle - OE.getLatency() + OE.getDistance() * II;
3314 *MinLateStart = std::min(*MinLateStart, LateStart);
3315 }
3316 }
3317
3318 SUnit *BE = multipleIterations(I, DAG);
3319 for (const auto &Dep : SU->Preds) {
3320 // For instruction that requires multiple iterations, make sure that
3321 // the dependent instruction is not scheduled past the definition.
3322 if (BE && Dep.getSUnit() == BE && !SU->getInstr()->isPHI() &&
3323 !SU->isPred(I))
3324 *MinLateStart = std::min(*MinLateStart, cycle);
3325 }
3326 }
3327 }
3328}
3329
3330/// Order the instructions within a cycle so that the definitions occur
3331/// before the uses. Returns true if the instruction is added to the start
3332/// of the list, or false if added to the end.
3334 std::deque<SUnit *> &Insts) const {
3335 MachineInstr *MI = SU->getInstr();
3336 bool OrderBeforeUse = false;
3337 bool OrderAfterDef = false;
3338 bool OrderBeforeDef = false;
3339 unsigned MoveDef = 0;
3340 unsigned MoveUse = 0;
3341 int StageInst1 = stageScheduled(SU);
3342 const SwingSchedulerDDG *DDG = SSD->getDDG();
3343
3344 unsigned Pos = 0;
3345 for (std::deque<SUnit *>::iterator I = Insts.begin(), E = Insts.end(); I != E;
3346 ++I, ++Pos) {
3347 for (MachineOperand &MO : MI->operands()) {
3348 if (!MO.isReg() || !MO.getReg().isVirtual())
3349 continue;
3350
3351 Register Reg = MO.getReg();
3352 unsigned BasePos, OffsetPos;
3353 if (ST.getInstrInfo()->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos))
3354 if (MI->getOperand(BasePos).getReg() == Reg)
3355 if (Register NewReg = SSD->getInstrBaseReg(SU))
3356 Reg = NewReg;
3357 bool Reads, Writes;
3358 std::tie(Reads, Writes) =
3359 (*I)->getInstr()->readsWritesVirtualRegister(Reg);
3360 if (MO.isDef() && Reads && stageScheduled(*I) <= StageInst1) {
3361 OrderBeforeUse = true;
3362 if (MoveUse == 0)
3363 MoveUse = Pos;
3364 } else if (MO.isDef() && Reads && stageScheduled(*I) > StageInst1) {
3365 // Add the instruction after the scheduled instruction.
3366 OrderAfterDef = true;
3367 MoveDef = Pos;
3368 } else if (MO.isUse() && Writes && stageScheduled(*I) == StageInst1) {
3369 if (cycleScheduled(*I) == cycleScheduled(SU) && !(*I)->isSucc(SU)) {
3370 OrderBeforeUse = true;
3371 if (MoveUse == 0)
3372 MoveUse = Pos;
3373 } else {
3374 OrderAfterDef = true;
3375 MoveDef = Pos;
3376 }
3377 } else if (MO.isUse() && Writes && stageScheduled(*I) > StageInst1) {
3378 OrderBeforeUse = true;
3379 if (MoveUse == 0)
3380 MoveUse = Pos;
3381 if (MoveUse != 0) {
3382 OrderAfterDef = true;
3383 MoveDef = Pos - 1;
3384 }
3385 } else if (MO.isUse() && Writes && stageScheduled(*I) < StageInst1) {
3386 // Add the instruction before the scheduled instruction.
3387 OrderBeforeUse = true;
3388 if (MoveUse == 0)
3389 MoveUse = Pos;
3390 } else if (MO.isUse() && stageScheduled(*I) == StageInst1 &&
3391 isLoopCarriedDefOfUse(SSD, (*I)->getInstr(), MO)) {
3392 if (MoveUse == 0) {
3393 OrderBeforeDef = true;
3394 MoveUse = Pos;
3395 }
3396 }
3397 }
3398 // Check for order dependences between instructions. Make sure the source
3399 // is ordered before the destination.
3400 for (auto &OE : DDG->getOutEdges(SU)) {
3401 if (OE.getDst() != *I)
3402 continue;
3403 if (OE.isOrderDep() && stageScheduled(*I) == StageInst1) {
3404 OrderBeforeUse = true;
3405 if (Pos < MoveUse)
3406 MoveUse = Pos;
3407 }
3408 // We did not handle HW dependences in previous for loop,
3409 // and we normally set Latency = 0 for Anti/Output deps,
3410 // so may have nodes in same cycle with Anti/Output dependent on HW regs.
3411 else if ((OE.isAntiDep() || OE.isOutputDep()) &&
3412 stageScheduled(*I) == StageInst1) {
3413 OrderBeforeUse = true;
3414 if ((MoveUse == 0) || (Pos < MoveUse))
3415 MoveUse = Pos;
3416 }
3417 }
3418 for (auto &IE : DDG->getInEdges(SU)) {
3419 if (IE.getSrc() != *I)
3420 continue;
3421 if ((IE.isAntiDep() || IE.isOutputDep() || IE.isOrderDep()) &&
3422 stageScheduled(*I) == StageInst1) {
3423 OrderAfterDef = true;
3424 MoveDef = Pos;
3425 }
3426 }
3427 }
3428
3429 // A circular dependence.
3430 if (OrderAfterDef && OrderBeforeUse && MoveUse == MoveDef)
3431 OrderBeforeUse = false;
3432
3433 // OrderAfterDef takes precedences over OrderBeforeDef. The latter is due
3434 // to a loop-carried dependence.
3435 if (OrderBeforeDef)
3436 OrderBeforeUse = !OrderAfterDef || (MoveUse > MoveDef);
3437
3438 // The uncommon case when the instruction order needs to be updated because
3439 // there is both a use and def.
3440 if (OrderBeforeUse && OrderAfterDef) {
3441 SUnit *UseSU = Insts.at(MoveUse);
3442 SUnit *DefSU = Insts.at(MoveDef);
3443 if (MoveUse > MoveDef) {
3444 Insts.erase(Insts.begin() + MoveUse);
3445 Insts.erase(Insts.begin() + MoveDef);
3446 } else {
3447 Insts.erase(Insts.begin() + MoveDef);
3448 Insts.erase(Insts.begin() + MoveUse);
3449 }
3450 orderDependence(SSD, UseSU, Insts);
3451 orderDependence(SSD, SU, Insts);
3452 orderDependence(SSD, DefSU, Insts);
3453 return;
3454 }
3455 // Put the new instruction first if there is a use in the list. Otherwise,
3456 // put it at the end of the list.
3457 if (OrderBeforeUse)
3458 Insts.push_front(SU);
3459 else
3460 Insts.push_back(SU);
3461}
3462
3463/// Return true if the scheduled Phi has a loop carried operand.
3465 MachineInstr &Phi) const {
3466 if (!Phi.isPHI())
3467 return false;
3468 assert(Phi.isPHI() && "Expecting a Phi.");
3469 SUnit *DefSU = SSD->getSUnit(&Phi);
3470 unsigned DefCycle = cycleScheduled(DefSU);
3471 int DefStage = stageScheduled(DefSU);
3472
3473 Register InitVal;
3474 Register LoopVal;
3475 getPhiRegs(Phi, Phi.getParent(), InitVal, LoopVal);
3476 SUnit *UseSU = SSD->getSUnit(MRI.getVRegDef(LoopVal));
3477 if (!UseSU)
3478 return true;
3479 if (UseSU->getInstr()->isPHI())
3480 return true;
3481 unsigned LoopCycle = cycleScheduled(UseSU);
3482 int LoopStage = stageScheduled(UseSU);
3483 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
3484}
3485
3486/// Return true if the instruction is a definition that is loop carried
3487/// and defines the use on the next iteration.
3488/// v1 = phi(v2, v3)
3489/// (Def) v3 = op v1
3490/// (MO) = v1
3491/// If MO appears before Def, then v1 and v3 may get assigned to the same
3492/// register.
3494 MachineInstr *Def,
3495 MachineOperand &MO) const {
3496 if (!MO.isReg())
3497 return false;
3498 if (Def->isPHI())
3499 return false;
3500 MachineInstr *Phi = MRI.getVRegDef(MO.getReg());
3501 if (!Phi || !Phi->isPHI() || Phi->getParent() != Def->getParent())
3502 return false;
3503 if (!isLoopCarried(SSD, *Phi))
3504 return false;
3505 Register LoopReg = getLoopPhiReg(*Phi, Phi->getParent());
3506 for (MachineOperand &DMO : Def->all_defs()) {
3507 if (DMO.getReg() == LoopReg)
3508 return true;
3509 }
3510 return false;
3511}
3512
3513/// Return true if all scheduled predecessors are loop-carried output/order
3514/// dependencies.
3516 SUnit *SU, const SwingSchedulerDDG *DDG) const {
3517 for (const auto &IE : DDG->getInEdges(SU))
3518 if (InstrToCycle.count(IE.getSrc()))
3519 return false;
3520 return true;
3521}
3522
3523/// Determine transitive dependences of unpipelineable instructions
3526 SmallPtrSet<SUnit *, 8> DoNotPipeline;
3527 SmallVector<SUnit *, 8> Worklist;
3528
3529 for (auto &SU : SSD->SUnits)
3530 if (SU.isInstr() && PLI->shouldIgnoreForPipelining(SU.getInstr()))
3531 Worklist.push_back(&SU);
3532
3533 const SwingSchedulerDDG *DDG = SSD->getDDG();
3534 while (!Worklist.empty()) {
3535 auto SU = Worklist.pop_back_val();
3536 if (DoNotPipeline.count(SU))
3537 continue;
3538 LLVM_DEBUG(dbgs() << "Do not pipeline SU(" << SU->NodeNum << ")\n");
3539 DoNotPipeline.insert(SU);
3540 for (const auto &IE : DDG->getInEdges(SU))
3541 Worklist.push_back(IE.getSrc());
3542
3543 // To preserve previous behavior and prevent regression
3544 // FIXME: Remove if this doesn't have significant impact on
3545 for (const auto &OE : DDG->getOutEdges(SU))
3546 if (OE.getDistance() == 1)
3547 Worklist.push_back(OE.getDst());
3548 }
3549 return DoNotPipeline;
3550}
3551
3552// Determine all instructions upon which any unpipelineable instruction depends
3553// and ensure that they are in stage 0. If unable to do so, return false.
3557
3558 int NewLastCycle = INT_MIN;
3559 for (SUnit &SU : SSD->SUnits) {
3560 if (!SU.isInstr())
3561 continue;
3562 if (!DNP.contains(&SU) || stageScheduled(&SU) == 0) {
3563 NewLastCycle = std::max(NewLastCycle, InstrToCycle[&SU]);
3564 continue;
3565 }
3566
3567 // Put the non-pipelined instruction as early as possible in the schedule
3568 int NewCycle = getFirstCycle();
3569 for (const auto &IE : SSD->getDDG()->getInEdges(&SU))
3570 if (IE.getDistance() == 0)
3571 NewCycle = std::max(InstrToCycle[IE.getSrc()], NewCycle);
3572
3573 // To preserve previous behavior and prevent regression
3574 // FIXME: Remove if this doesn't have significant impact on performance
3575 for (auto &OE : SSD->getDDG()->getOutEdges(&SU))
3576 if (OE.getDistance() == 1)
3577 NewCycle = std::max(InstrToCycle[OE.getDst()], NewCycle);
3578
3579 int OldCycle = InstrToCycle[&SU];
3580 if (OldCycle != NewCycle) {
3581 InstrToCycle[&SU] = NewCycle;
3582 auto &OldS = getInstructions(OldCycle);
3583 llvm::erase(OldS, &SU);
3584 getInstructions(NewCycle).emplace_back(&SU);
3585 LLVM_DEBUG(dbgs() << "SU(" << SU.NodeNum
3586 << ") is not pipelined; moving from cycle " << OldCycle
3587 << " to " << NewCycle << " Instr:" << *SU.getInstr());
3588 }
3589
3590 // We traverse the SUs in the order of the original basic block. Computing
3591 // NewCycle in this order normally works fine because all dependencies
3592 // (except for loop-carried dependencies) don't violate the original order.
3593 // However, an artificial dependency (e.g., added by CopyToPhiMutation) can
3594 // break it. That is, there may be exist an artificial dependency from
3595 // bottom to top. In such a case, NewCycle may become too large to be
3596 // scheduled in Stage 0. For example, assume that Inst0 is in DNP in the
3597 // following case:
3598 //
3599 // | Inst0 <-+
3600 // SU order | | artificial dep
3601 // | Inst1 --+
3602 // v
3603 //
3604 // If Inst1 is scheduled at cycle N and is not at Stage 0, then NewCycle of
3605 // Inst0 must be greater than or equal to N so that Inst0 is not be
3606 // scheduled at Stage 0. In such cases, we reject this schedule at this
3607 // time.
3608 // FIXME: The reason for this is the existence of artificial dependencies
3609 // that are contradict to the original SU order. If ignoring artificial
3610 // dependencies does not affect correctness, then it is better to ignore
3611 // them.
3612 if (FirstCycle + InitiationInterval <= NewCycle)
3613 return false;
3614
3615 NewLastCycle = std::max(NewLastCycle, NewCycle);
3616 }
3617 LastCycle = NewLastCycle;
3618 return true;
3619}
3620
3621// Check if the generated schedule is valid. This function checks if
3622// an instruction that uses a physical register is scheduled in a
3623// different stage than the definition. The pipeliner does not handle
3624// physical register values that may cross a basic block boundary.
3625// Furthermore, if a physical def/use pair is assigned to the same
3626// cycle, orderDependence does not guarantee def/use ordering, so that
3627// case should be considered invalid. (The test checks for both
3628// earlier and same-cycle use to be more robust.)
3630 for (SUnit &SU : SSD->SUnits) {
3631 if (!SU.hasPhysRegDefs)
3632 continue;
3633 int StageDef = stageScheduled(&SU);
3634 int CycleDef = InstrToCycle[&SU];
3635 assert(StageDef != -1 && "Instruction should have been scheduled.");
3636 for (auto &OE : SSD->getDDG()->getOutEdges(&SU)) {
3637 SUnit *Dst = OE.getDst();
3638 if (OE.isAssignedRegDep() && !Dst->isBoundaryNode())
3639 if (OE.getReg().isPhysical()) {
3640 if (stageScheduled(Dst) != StageDef)
3641 return false;
3642 if (InstrToCycle[Dst] <= CycleDef)
3643 return false;
3644 }
3645 }
3646 }
3647 return true;
3648}
3649
3650/// A property of the node order in swing-modulo-scheduling is
3651/// that for nodes outside circuits the following holds:
3652/// none of them is scheduled after both a successor and a
3653/// predecessor.
3654/// The method below checks whether the property is met.
3655/// If not, debug information is printed and statistics information updated.
3656/// Note that we do not use an assert statement.
3657/// The reason is that although an invalid node order may prevent
3658/// the pipeliner from finding a pipelined schedule for arbitrary II,
3659/// it does not lead to the generation of incorrect code.
3660void SwingSchedulerDAG::checkValidNodeOrder(const NodeSetType &Circuits) const {
3661
3662 // a sorted vector that maps each SUnit to its index in the NodeOrder
3663 typedef std::pair<SUnit *, unsigned> UnitIndex;
3664 std::vector<UnitIndex> Indices(NodeOrder.size(), std::make_pair(nullptr, 0));
3665
3666 for (unsigned i = 0, s = NodeOrder.size(); i < s; ++i)
3667 Indices.push_back(std::make_pair(NodeOrder[i], i));
3668
3669 auto CompareKey = [](UnitIndex i1, UnitIndex i2) {
3670 return std::get<0>(i1) < std::get<0>(i2);
3671 };
3672
3673 // sort, so that we can perform a binary search
3674 llvm::sort(Indices, CompareKey);
3675
3676 bool Valid = true;
3677 (void)Valid;
3678 // for each SUnit in the NodeOrder, check whether
3679 // it appears after both a successor and a predecessor
3680 // of the SUnit. If this is the case, and the SUnit
3681 // is not part of circuit, then the NodeOrder is not
3682 // valid.
3683 for (unsigned i = 0, s = NodeOrder.size(); i < s; ++i) {
3684 SUnit *SU = NodeOrder[i];
3685 unsigned Index = i;
3686
3687 bool PredBefore = false;
3688 bool SuccBefore = false;
3689
3690 SUnit *Succ;
3691 SUnit *Pred;
3692 (void)Succ;
3693 (void)Pred;
3694
3695 for (const auto &IE : DDG->getInEdges(SU)) {
3696 SUnit *PredSU = IE.getSrc();
3697 unsigned PredIndex = std::get<1>(
3698 *llvm::lower_bound(Indices, std::make_pair(PredSU, 0), CompareKey));
3699 if (!PredSU->getInstr()->isPHI() && PredIndex < Index) {
3700 PredBefore = true;
3701 Pred = PredSU;
3702 break;
3703 }
3704 }
3705
3706 for (const auto &OE : DDG->getOutEdges(SU)) {
3707 SUnit *SuccSU = OE.getDst();
3708 // Do not process a boundary node, it was not included in NodeOrder,
3709 // hence not in Indices either, call to std::lower_bound() below will
3710 // return Indices.end().
3711 if (SuccSU->isBoundaryNode())
3712 continue;
3713 unsigned SuccIndex = std::get<1>(
3714 *llvm::lower_bound(Indices, std::make_pair(SuccSU, 0), CompareKey));
3715 if (!SuccSU->getInstr()->isPHI() && SuccIndex < Index) {
3716 SuccBefore = true;
3717 Succ = SuccSU;
3718 break;
3719 }
3720 }
3721
3722 if (PredBefore && SuccBefore && !SU->getInstr()->isPHI()) {
3723 // instructions in circuits are allowed to be scheduled
3724 // after both a successor and predecessor.
3725 bool InCircuit = llvm::any_of(
3726 Circuits, [SU](const NodeSet &Circuit) { return Circuit.count(SU); });
3727 if (InCircuit)
3728 LLVM_DEBUG(dbgs() << "In a circuit, predecessor ");
3729 else {
3730 Valid = false;
3731 NumNodeOrderIssues++;
3732 LLVM_DEBUG(dbgs() << "Predecessor ");
3733 }
3734 LLVM_DEBUG(dbgs() << Pred->NodeNum << " and successor " << Succ->NodeNum
3735 << " are scheduled before node " << SU->NodeNum
3736 << "\n");
3737 }
3738 }
3739
3740 LLVM_DEBUG({
3741 if (!Valid)
3742 dbgs() << "Invalid node order found!\n";
3743 });
3744}
3745
3746/// Attempt to fix the degenerate cases when the instruction serialization
3747/// causes the register lifetimes to overlap. For example,
3748/// p' = store_pi(p, b)
3749/// = load p, offset
3750/// In this case p and p' overlap, which means that two registers are needed.
3751/// Instead, this function changes the load to use p' and updates the offset.
3752void SwingSchedulerDAG::fixupRegisterOverlaps(std::deque<SUnit *> &Instrs) {
3753 Register OverlapReg;
3754 Register NewBaseReg;
3755 for (SUnit *SU : Instrs) {
3756 MachineInstr *MI = SU->getInstr();
3757 for (unsigned i = 0, e = MI->getNumOperands(); i < e; ++i) {
3758 const MachineOperand &MO = MI->getOperand(i);
3759 // Look for an instruction that uses p. The instruction occurs in the
3760 // same cycle but occurs later in the serialized order.
3761 if (MO.isReg() && MO.isUse() && MO.getReg() == OverlapReg) {
3762 // Check that the instruction appears in the InstrChanges structure,
3763 // which contains instructions that can have the offset updated.
3765 InstrChanges.find(SU);
3766 if (It != InstrChanges.end()) {
3767 unsigned BasePos, OffsetPos;
3768 // Update the base register and adjust the offset.
3769 if (TII->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos)) {
3770 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3771 NewMI->getOperand(BasePos).setReg(NewBaseReg);
3772 int64_t NewOffset =
3773 MI->getOperand(OffsetPos).getImm() - It->second.second;
3774 NewMI->getOperand(OffsetPos).setImm(NewOffset);
3775 SU->setInstr(NewMI);
3776 MISUnitMap[NewMI] = SU;
3777 NewMIs[MI] = NewMI;
3778 }
3779 }
3780 OverlapReg = Register();
3781 NewBaseReg = Register();
3782 break;
3783 }
3784 // Look for an instruction of the form p' = op(p), which uses and defines
3785 // two virtual registers that get allocated to the same physical register.
3786 unsigned TiedUseIdx = 0;
3787 if (MI->isRegTiedToUseOperand(i, &TiedUseIdx)) {
3788 // OverlapReg is p in the example above.
3789 OverlapReg = MI->getOperand(TiedUseIdx).getReg();
3790 // NewBaseReg is p' in the example above.
3791 NewBaseReg = MI->getOperand(i).getReg();
3792 break;
3793 }
3794 }
3795 }
3796}
3797
3798std::deque<SUnit *>
3800 const std::deque<SUnit *> &Instrs) const {
3801 std::deque<SUnit *> NewOrderPhi;
3802 for (SUnit *SU : Instrs) {
3803 if (SU->getInstr()->isPHI())
3804 NewOrderPhi.push_back(SU);
3805 }
3806 std::deque<SUnit *> NewOrderI;
3807 for (SUnit *SU : Instrs) {
3808 if (!SU->getInstr()->isPHI())
3809 orderDependence(SSD, SU, NewOrderI);
3810 }
3811 llvm::append_range(NewOrderPhi, NewOrderI);
3812 return NewOrderPhi;
3813}
3814
3815/// After the schedule has been formed, call this function to combine
3816/// the instructions from the different stages/cycles. That is, this
3817/// function creates a schedule that represents a single iteration.
3819 // Move all instructions to the first stage from later stages.
3820 for (int cycle = getFirstCycle(); cycle <= getFinalCycle(); ++cycle) {
3821 for (int stage = 1, lastStage = getMaxStageCount(); stage <= lastStage;
3822 ++stage) {
3823 std::deque<SUnit *> &cycleInstrs =
3824 ScheduledInstrs[cycle + (stage * InitiationInterval)];
3825 for (SUnit *SU : llvm::reverse(cycleInstrs))
3826 ScheduledInstrs[cycle].push_front(SU);
3827 }
3828 }
3829
3830 // Erase all the elements in the later stages. Only one iteration should
3831 // remain in the scheduled list, and it contains all the instructions.
3832 for (int cycle = getFinalCycle() + 1; cycle <= LastCycle; ++cycle)
3833 ScheduledInstrs.erase(cycle);
3834
3835 // Change the registers in instruction as specified in the InstrChanges
3836 // map. We need to use the new registers to create the correct order.
3837 for (const SUnit &SU : SSD->SUnits)
3838 SSD->applyInstrChange(SU.getInstr(), *this);
3839
3840 // Reorder the instructions in each cycle to fix and improve the
3841 // generated code.
3842 for (int Cycle = getFirstCycle(), E = getFinalCycle(); Cycle <= E; ++Cycle) {
3843 std::deque<SUnit *> &cycleInstrs = ScheduledInstrs[Cycle];
3844 cycleInstrs = reorderInstructions(SSD, cycleInstrs);
3845 SSD->fixupRegisterOverlaps(cycleInstrs);
3846 }
3847
3848 LLVM_DEBUG(dump(););
3849}
3850
3852 os << "Num nodes " << size() << " rec " << RecMII << " mov " << MaxMOV
3853 << " depth " << MaxDepth << " col " << Colocate << "\n";
3854 for (const auto &I : Nodes)
3855 os << " SU(" << I->NodeNum << ") " << *(I->getInstr());
3856 os << "\n";
3857}
3858
3859#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3860/// Print the schedule information to the given output.
3862 // Iterate over each cycle.
3863 for (int cycle = getFirstCycle(); cycle <= getFinalCycle(); ++cycle) {
3864 // Iterate over each instruction in the cycle.
3865 const_sched_iterator cycleInstrs = ScheduledInstrs.find(cycle);
3866 for (SUnit *CI : cycleInstrs->second) {
3867 os << "cycle " << cycle << " (" << stageScheduled(CI) << ") ";
3868 os << "(" << CI->NodeNum << ") ";
3869 CI->getInstr()->print(os);
3870 os << "\n";
3871 }
3872 }
3873}
3874
3875/// Utility function used for debugging to print the schedule.
3878
3879void ResourceManager::dumpMRT() const {
3880 LLVM_DEBUG({
3881 if (UseDFA)
3882 return;
3883 std::stringstream SS;
3884 SS << "MRT:\n";
3885 SS << std::setw(4) << "Slot";
3886 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I)
3887 SS << std::setw(3) << I;
3888 SS << std::setw(7) << "#Mops"
3889 << "\n";
3890 for (int Slot = 0; Slot < InitiationInterval; ++Slot) {
3891 SS << std::setw(4) << Slot;
3892 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I)
3893 SS << std::setw(3) << MRT[Slot][I];
3894 SS << std::setw(7) << NumScheduledMops[Slot] << "\n";
3895 }
3896 dbgs() << SS.str();
3897 });
3898}
3899#endif
3900
3902 const MCSchedModel &SM, SmallVectorImpl<uint64_t> &Masks) {
3903 unsigned ProcResourceID = 0;
3904
3905 // We currently limit the resource kinds to 64 and below so that we can use
3906 // uint64_t for Masks
3907 assert(SM.getNumProcResourceKinds() < 64 &&
3908 "Too many kinds of resources, unsupported");
3909 // Create a unique bitmask for every processor resource unit.
3910 // Skip resource at index 0, since it always references 'InvalidUnit'.
3911 Masks.resize(SM.getNumProcResourceKinds());
3912 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
3913 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
3914 if (Desc.SubUnitsIdxBegin)
3915 continue;
3916 Masks[I] = 1ULL << ProcResourceID;
3917 ProcResourceID++;
3918 }
3919 // Create a unique bitmask for every processor resource group.
3920 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
3921 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
3922 if (!Desc.SubUnitsIdxBegin)
3923 continue;
3924 Masks[I] = 1ULL << ProcResourceID;
3925 for (unsigned U = 0; U < Desc.NumUnits; ++U)
3926 Masks[I] |= Masks[Desc.SubUnitsIdxBegin[U]];
3927 ProcResourceID++;
3928 }
3929 LLVM_DEBUG({
3930 if (SwpShowResMask) {
3931 dbgs() << "ProcResourceDesc:\n";
3932 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
3933 const MCProcResourceDesc *ProcResource = SM.getProcResource(I);
3934 dbgs() << format(" %16s(%2d): Mask: 0x%08x, NumUnits:%2d\n",
3935 ProcResource->Name, I, Masks[I],
3936 ProcResource->NumUnits);
3937 }
3938 dbgs() << " -----------------\n";
3939 }
3940 });
3941}
3942
3944 LLVM_DEBUG({
3945 if (SwpDebugResource)
3946 dbgs() << "canReserveResources:\n";
3947 });
3948 if (UseDFA)
3949 return DFAResources[positiveModulo(Cycle, InitiationInterval)]
3950 ->canReserveResources(&SU.getInstr()->getDesc());
3951
3952 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
3953 if (!SCDesc->isValid()) {
3954 LLVM_DEBUG({
3955 dbgs() << "No valid Schedule Class Desc for schedClass!\n";
3956 dbgs() << "isPseudo:" << SU.getInstr()->isPseudo() << "\n";
3957 });
3958 return true;
3959 }
3960
3961 reserveResources(SCDesc, Cycle);
3962 bool Result = !isOverbooked();
3963 unreserveResources(SCDesc, Cycle);
3964
3965 LLVM_DEBUG(if (SwpDebugResource) dbgs() << "return " << Result << "\n\n");
3966 return Result;
3967}
3968
3969void ResourceManager::reserveResources(SUnit &SU, int Cycle) {
3970 LLVM_DEBUG({
3971 if (SwpDebugResource)
3972 dbgs() << "reserveResources:\n";
3973 });
3974 if (UseDFA)
3975 return DFAResources[positiveModulo(Cycle, InitiationInterval)]
3976 ->reserveResources(&SU.getInstr()->getDesc());
3977
3978 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
3979 if (!SCDesc->isValid()) {
3980 LLVM_DEBUG({
3981 dbgs() << "No valid Schedule Class Desc for schedClass!\n";
3982 dbgs() << "isPseudo:" << SU.getInstr()->isPseudo() << "\n";
3983 });
3984 return;
3985 }
3986
3987 reserveResources(SCDesc, Cycle);
3988
3989 LLVM_DEBUG({
3990 if (SwpDebugResource) {
3991 dumpMRT();
3992 dbgs() << "reserveResources: done!\n\n";
3993 }
3994 });
3995}
3996
3997void ResourceManager::reserveResources(const MCSchedClassDesc *SCDesc,
3998 int Cycle) {
3999 assert(!UseDFA);
4000 for (const MCWriteProcResEntry &PRE : make_range(
4001 STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
4002 for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
4003 ++MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];
4004
4005 for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
4006 ++NumScheduledMops[positiveModulo(C, InitiationInterval)];
4007}
4008
4009void ResourceManager::unreserveResources(const MCSchedClassDesc *SCDesc,
4010 int Cycle) {
4011 assert(!UseDFA);
4012 for (const MCWriteProcResEntry &PRE : make_range(
4013 STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
4014 for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
4015 --MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];
4016
4017 for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
4018 --NumScheduledMops[positiveModulo(C, InitiationInterval)];
4019}
4020
4021bool ResourceManager::isOverbooked() const {
4022 assert(!UseDFA);
4023 for (int Slot = 0; Slot < InitiationInterval; ++Slot) {
4024 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4025 const MCProcResourceDesc *Desc = SM.getProcResource(I);
4026 if (MRT[Slot][I] > Desc->NumUnits)
4027 return true;
4028 }
4029 if (NumScheduledMops[Slot] > IssueWidth)
4030 return true;
4031 }
4032 return false;
4033}
4034
4035int ResourceManager::calculateResMIIDFA() const {
4036 assert(UseDFA);
4037
4038 // Sort the instructions by the number of available choices for scheduling,
4039 // least to most. Use the number of critical resources as the tie breaker.
4040 FuncUnitSorter FUS = FuncUnitSorter(*ST);
4041 for (SUnit &SU : DAG->SUnits)
4042 FUS.calcCriticalResources(*SU.getInstr());
4043 PriorityQueue<MachineInstr *, std::vector<MachineInstr *>, FuncUnitSorter>
4044 FuncUnitOrder(FUS);
4045
4046 for (SUnit &SU : DAG->SUnits)
4047 FuncUnitOrder.push(SU.getInstr());
4048
4050 Resources.push_back(
4051 std::unique_ptr<DFAPacketizer>(TII->CreateTargetScheduleState(*ST)));
4052
4053 while (!FuncUnitOrder.empty()) {
4054 MachineInstr *MI = FuncUnitOrder.top();
4055 FuncUnitOrder.pop();
4056 if (TII->isZeroCost(MI->getOpcode()))
4057 continue;
4058
4059 // Attempt to reserve the instruction in an existing DFA. At least one
4060 // DFA is needed for each cycle.
4061 unsigned NumCycles = DAG->getSUnit(MI)->Latency;
4062 unsigned ReservedCycles = 0;
4063 auto *RI = Resources.begin();
4064 auto *RE = Resources.end();
4065 LLVM_DEBUG({
4066 dbgs() << "Trying to reserve resource for " << NumCycles
4067 << " cycles for \n";
4068 MI->dump();
4069 });
4070 for (unsigned C = 0; C < NumCycles; ++C)
4071 while (RI != RE) {
4072 if ((*RI)->canReserveResources(*MI)) {
4073 (*RI)->reserveResources(*MI);
4074 ++ReservedCycles;
4075 break;
4076 }
4077 RI++;
4078 }
4079 LLVM_DEBUG(dbgs() << "ReservedCycles:" << ReservedCycles
4080 << ", NumCycles:" << NumCycles << "\n");
4081 // Add new DFAs, if needed, to reserve resources.
4082 for (unsigned C = ReservedCycles; C < NumCycles; ++C) {
4084 << "NewResource created to reserve resources"
4085 << "\n");
4086 auto *NewResource = TII->CreateTargetScheduleState(*ST);
4087 assert(NewResource->canReserveResources(*MI) && "Reserve error.");
4088 NewResource->reserveResources(*MI);
4089 Resources.push_back(std::unique_ptr<DFAPacketizer>(NewResource));
4090 }
4091 }
4092
4093 int Resmii = Resources.size();
4094 LLVM_DEBUG(dbgs() << "Return Res MII:" << Resmii << "\n");
4095 return Resmii;
4096}
4097
4099 if (UseDFA)
4100 return calculateResMIIDFA();
4101
4102 // Count each resource consumption and divide it by the number of units.
4103 // ResMII is the max value among them.
4104
4105 int NumMops = 0;
4106 SmallVector<uint64_t> ResourceCount(SM.getNumProcResourceKinds());
4107 for (SUnit &SU : DAG->SUnits) {
4108 if (TII->isZeroCost(SU.getInstr()->getOpcode()))
4109 continue;
4110
4111 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
4112 if (!SCDesc->isValid())
4113 continue;
4114
4115 LLVM_DEBUG({
4116 if (SwpDebugResource) {
4117 DAG->dumpNode(SU);
4118 dbgs() << " #Mops: " << SCDesc->NumMicroOps << "\n"
4119 << " WriteProcRes: ";
4120 }
4121 });
4122 NumMops += SCDesc->NumMicroOps;
4123 for (const MCWriteProcResEntry &PRE :
4124 make_range(STI->getWriteProcResBegin(SCDesc),
4125 STI->getWriteProcResEnd(SCDesc))) {
4126 LLVM_DEBUG({
4127 if (SwpDebugResource) {
4128 const MCProcResourceDesc *Desc =
4129 SM.getProcResource(PRE.ProcResourceIdx);
4130 dbgs() << Desc->Name << ": " << PRE.ReleaseAtCycle << ", ";
4131 }
4132 });
4133 ResourceCount[PRE.ProcResourceIdx] += PRE.ReleaseAtCycle;
4134 }
4135 LLVM_DEBUG(if (SwpDebugResource) dbgs() << "\n");
4136 }
4137
4138 int Result = (NumMops + IssueWidth - 1) / IssueWidth;
4139 LLVM_DEBUG({
4140 if (SwpDebugResource)
4141 dbgs() << "#Mops: " << NumMops << ", "
4142 << "IssueWidth: " << IssueWidth << ", "
4143 << "Cycles: " << Result << "\n";
4144 });
4145
4146 LLVM_DEBUG({
4147 if (SwpDebugResource) {
4148 std::stringstream SS;
4149 SS << std::setw(2) << "ID" << std::setw(16) << "Name" << std::setw(10)
4150 << "Units" << std::setw(10) << "Consumed" << std::setw(10) << "Cycles"
4151 << "\n";
4152 dbgs() << SS.str();
4153 }
4154 });
4155 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4156 const MCProcResourceDesc *Desc = SM.getProcResource(I);
4157 int Cycles = (ResourceCount[I] + Desc->NumUnits - 1) / Desc->NumUnits;
4158 LLVM_DEBUG({
4159 if (SwpDebugResource) {
4160 std::stringstream SS;
4161 SS << std::setw(2) << I << std::setw(16) << Desc->Name << std::setw(10)
4162 << Desc->NumUnits << std::setw(10) << ResourceCount[I]
4163 << std::setw(10) << Cycles << "\n";
4164 dbgs() << SS.str();
4165 }
4166 });
4167 if (Cycles > Result)
4168 Result = Cycles;
4169 }
4170 return Result;
4171}
4172
4174 InitiationInterval = II;
4175 DFAResources.clear();
4176 DFAResources.resize(II);
4177 for (auto &I : DFAResources)
4178 I.reset(ST->getInstrInfo()->CreateTargetScheduleState(*ST));
4179 MRT.clear();
4180 MRT.resize(II, SmallVector<uint64_t>(SM.getNumProcResourceKinds()));
4181 NumScheduledMops.clear();
4182 NumScheduledMops.resize(II);
4183}
4184
4185bool SwingSchedulerDDGEdge::ignoreDependence(bool IgnoreAnti) const {
4186 if (Pred.isArtificial() || Dst->isBoundaryNode())
4187 return true;
4188 // Currently, dependence that is an anti-dependences but not a loop-carried is
4189 // also ignored. This behavior is preserved to prevent regression.
4190 // FIXME: Remove if this doesn't have significant impact on performance
4191 return IgnoreAnti && (Pred.getKind() == SDep::Kind::Anti || Distance != 0);
4192}
4193
4194SwingSchedulerDDG::SwingSchedulerDDGEdges &
4195SwingSchedulerDDG::getEdges(const SUnit *SU) {
4196 if (SU == EntrySU)
4197 return EntrySUEdges;
4198 if (SU == ExitSU)
4199 return ExitSUEdges;
4200 return EdgesVec[SU->NodeNum];
4201}
4202
4203const SwingSchedulerDDG::SwingSchedulerDDGEdges &
4204SwingSchedulerDDG::getEdges(const SUnit *SU) const {
4205 if (SU == EntrySU)
4206 return EntrySUEdges;
4207 if (SU == ExitSU)
4208 return ExitSUEdges;
4209 return EdgesVec[SU->NodeNum];
4210}
4211
4212void SwingSchedulerDDG::addEdge(const SUnit *SU,
4213 const SwingSchedulerDDGEdge &Edge) {
4214 assert(!Edge.isValidationOnly() &&
4215 "Validation-only edges are not expected here.");
4216
4217 auto &Edges = getEdges(SU);
4218 if (Edge.getSrc() == SU)
4219 Edges.Succs.push_back(Edge);
4220 else
4221 Edges.Preds.push_back(Edge);
4222}
4223
4224void SwingSchedulerDDG::initEdges(SUnit *SU) {
4225 for (const auto &PI : SU->Preds) {
4226 SwingSchedulerDDGEdge Edge(SU, PI, /*IsSucc=*/false,
4227 /*IsValidationOnly=*/false);
4228 addEdge(SU, Edge);
4229 }
4230
4231 for (const auto &SI : SU->Succs) {
4232 SwingSchedulerDDGEdge Edge(SU, SI, /*IsSucc=*/true,
4233 /*IsValidationOnly=*/false);
4234 addEdge(SU, Edge);
4235 }
4236}
4237
4238SwingSchedulerDDG::SwingSchedulerDDG(std::vector<SUnit> &SUnits, SUnit *EntrySU,
4239 SUnit *ExitSU, const LoopCarriedEdges &LCE)
4240 : EntrySU(EntrySU), ExitSU(ExitSU) {
4241 EdgesVec.resize(SUnits.size());
4242
4243 // Add non-loop-carried edges based on the DAG.
4244 initEdges(EntrySU);
4245 initEdges(ExitSU);
4246 for (auto &SU : SUnits)
4247 initEdges(&SU);
4248
4249 // Add loop-carried edges, which are not represented in the DAG.
4250 for (SUnit &SU : SUnits) {
4251 SUnit *Src = &SU;
4252 if (const LoopCarriedEdges::OrderDep *OD = LCE.getOrderDepOrNull(Src)) {
4253 SDep Base(Src, SDep::Barrier);
4254 Base.setLatency(1);
4255 for (SUnit *Dst : *OD) {
4256 SwingSchedulerDDGEdge Edge(Dst, Base, /*IsSucc=*/false,
4257 /*IsValidationOnly=*/true);
4258 Edge.setDistance(1);
4259 ValidationOnlyEdges.push_back(Edge);
4260
4261 // Store the edge as an extra edge if it meets the following conditions:
4262 //
4263 // - The edge is a loop-carried order dependency.
4264 // - The edge is a back edge in terms of the original instruction
4265 // order.
4266 // - The destination instruction may load.
4267 // - The source instruction may store but does not load.
4268 //
4269 // These conditions are inherited from a previous implementation to
4270 // preserve the existing behavior and avoid regressions.
4271 bool UseAsExtraEdge = [&]() {
4272 if (Edge.getDistance() == 0 || !Edge.isOrderDep())
4273 return false;
4274
4275 SUnit *Src = Edge.getSrc();
4276 SUnit *Dst = Edge.getDst();
4277 if (Src->NodeNum < Dst->NodeNum)
4278 return false;
4279
4280 MachineInstr *SrcMI = Src->getInstr();
4281 MachineInstr *DstMI = Dst->getInstr();
4282 return DstMI->mayLoad() && !SrcMI->mayLoad() && SrcMI->mayStore();
4283 }();
4284 if (UseAsExtraEdge)
4285 getEdges(Edge.getSrc()).ExtraSuccs.push_back(Edge.getDst());
4286 }
4287 }
4288 }
4289}
4290
4291const SwingSchedulerDDG::EdgesType &
4293 return getEdges(SU).Preds;
4294}
4295
4296const SwingSchedulerDDG::EdgesType &
4298 return getEdges(SU).Succs;
4299}
4300
4302 return getEdges(SU).ExtraSuccs;
4303}
4304
4305/// Check if \p Schedule doesn't violate the validation-only dependencies.
4307 unsigned II = Schedule.getInitiationInterval();
4308
4309 auto ExpandCycle = [&](SUnit *SU) {
4310 int Stage = Schedule.stageScheduled(SU);
4311 int Cycle = Schedule.cycleScheduled(SU);
4312 return Cycle + (Stage * II);
4313 };
4314
4315 for (const SwingSchedulerDDGEdge &Edge : ValidationOnlyEdges) {
4316 SUnit *Src = Edge.getSrc();
4317 SUnit *Dst = Edge.getDst();
4318 if (!Src->isInstr() || !Dst->isInstr())
4319 continue;
4320 int CycleSrc = ExpandCycle(Src);
4321 int CycleDst = ExpandCycle(Dst);
4322 int MaxLateStart = CycleDst + Edge.getDistance() * II - Edge.getLatency();
4323 if (CycleSrc > MaxLateStart) {
4324 LLVM_DEBUG({
4325 dbgs() << "Validation failed for edge from " << Src->NodeNum << " to "
4326 << Dst->NodeNum << "\n";
4327 });
4328 return false;
4329 }
4330 }
4331 return true;
4332}
4333
4334void LoopCarriedEdges::modifySUnits(std::vector<SUnit> &SUnits,
4335 const TargetInstrInfo *TII) {
4336 for (SUnit &SU : SUnits) {
4337 SUnit *Src = &SU;
4338 if (auto *OrderDep = getOrderDepOrNull(Src)) {
4339 SDep Dep(Src, SDep::Barrier);
4340 Dep.setLatency(1);
4341 for (SUnit *Dst : *OrderDep) {
4342 SUnit *From = Src;
4343 SUnit *To = Dst;
4344 if (From->NodeNum > To->NodeNum)
4345 std::swap(From, To);
4346
4347 // Add a forward edge if the following conditions are met:
4348 //
4349 // - The instruction of the source node (FromMI) may read memory.
4350 // - The instruction of the target node (ToMI) may modify memory, but
4351 // does not read it.
4352 // - Neither instruction is a global barrier.
4353 // - The load appears before the store in the original basic block.
4354 // - There are no barrier or store instructions between the two nodes.
4355 // - The target node is unreachable from the source node in the current
4356 // DAG.
4357 //
4358 // TODO: These conditions are inherited from a previous implementation,
4359 // and some may no longer be necessary. For now, we conservatively
4360 // retain all of them to avoid regressions, but the logic could
4361 // potentially be simplified
4362 MachineInstr *FromMI = From->getInstr();
4363 MachineInstr *ToMI = To->getInstr();
4364 if (FromMI->mayLoad() && !ToMI->mayLoad() && ToMI->mayStore() &&
4365 !TII->isGlobalMemoryObject(FromMI) &&
4366 !TII->isGlobalMemoryObject(ToMI) && !isSuccOrder(From, To)) {
4367 SDep Pred = Dep;
4368 Pred.setSUnit(From);
4369 To->addPred(Pred);
4370 }
4371 }
4372 }
4373 }
4374}
4375
4377 const MachineRegisterInfo *MRI) const {
4378 const auto *Order = getOrderDepOrNull(SU);
4379
4380 if (!Order)
4381 return;
4382
4383 const auto DumpSU = [](const SUnit *SU) {
4384 std::ostringstream OSS;
4385 OSS << "SU(" << SU->NodeNum << ")";
4386 return OSS.str();
4387 };
4388
4389 dbgs() << " Loop carried edges from " << DumpSU(SU) << "\n"
4390 << " Order\n";
4391 for (SUnit *Dst : *Order)
4392 dbgs() << " " << DumpSU(Dst) << "\n";
4393}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
DXIL Remove Unused Resources
This file defines the DenseMap class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
A common definition of LaneBitmask for use in TableGen and CodeGen.
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
print mir2vec MIR2Vec Vocabulary Printer Pass
Definition MIR2Vec.cpp:621
static cl::opt< int > SwpForceII("pipeliner-force-ii", cl::desc("Force pipeliner to use specified II."), cl::Hidden, cl::init(-1))
A command line argument to force pipeliner to use specified initial interval.
static cl::opt< bool > ExperimentalCodeGen("pipeliner-experimental-cg", cl::Hidden, cl::init(false), cl::desc("Use the experimental peeling code generator for software pipelining"))
static bool hasPHICycleDFS(unsigned Reg, const DenseMap< unsigned, SmallVector< unsigned, 2 > > &PhiDeps, SmallSet< unsigned, 8 > &Visited, SmallSet< unsigned, 8 > &RecStack)
Depth-first search to detect cycles among PHI dependencies.
static cl::opt< bool > MVECodeGen("pipeliner-mve-cg", cl::Hidden, cl::init(false), cl::desc("Use the MVE code generator for software pipelining"))
static cl::opt< int > RegPressureMargin("pipeliner-register-pressure-margin", cl::Hidden, cl::init(5), cl::desc("Margin representing the unused percentage of " "the register pressure limit"))
static void getPhiRegs(MachineInstr &Phi, MachineBasicBlock *Loop, Register &InitVal, Register &LoopVal)
Return the register values for the operands of a Phi instruction.
static cl::opt< bool > SwpDebugResource("pipeliner-dbg-res", cl::Hidden, cl::init(false))
static void computeLiveOuts(MachineFunction &MF, RegPressureTracker &RPTracker, NodeSet &NS)
Compute the live-out registers for the instructions in a node-set.
static void computeScheduledInsts(const SwingSchedulerDAG *SSD, SMSchedule &Schedule, std::vector< MachineInstr * > &OrderedInsts, DenseMap< MachineInstr *, unsigned > &Stages)
Create an instruction stream that represents a single iteration and stage of each instruction.
static cl::opt< bool > EmitTestAnnotations("pipeliner-annotate-for-testing", cl::Hidden, cl::init(false), cl::desc("Instead of emitting the pipelined code, annotate instructions " "with the generated schedule for feeding into the " "-modulo-schedule-test pass"))
static Register getLoopPhiReg(const MachineInstr &Phi, const MachineBasicBlock *LoopBB)
Return the Phi register value that comes the loop block.
static bool isIntersect(SmallSetVector< SUnit *, 8 > &Set1, const NodeSet &Set2, SmallSetVector< SUnit *, 8 > &Result)
Return true if Set1 contains elements in Set2.
static bool findLoopIncrementValue(const MachineOperand &Op, int &Value)
When Op is a value that is incremented recursively in a loop and there is a unique instruction that i...
static cl::opt< bool > SwpIgnoreRecMII("pipeliner-ignore-recmii", cl::ReallyHidden, cl::desc("Ignore RecMII"))
static cl::opt< int > SwpLoopLimit("pipeliner-max", cl::Hidden, cl::init(-1))
static cl::opt< bool > SwpPruneLoopCarried("pipeliner-prune-loop-carried", cl::desc("Prune loop carried order dependences."), cl::Hidden, cl::init(true))
A command line option to disable the pruning of loop carried order dependences.
static cl::opt< unsigned > SwpMaxNumStores("pipeliner-max-num-stores", cl::desc("Maximum number of stores allwed in the target loop."), cl::Hidden, cl::init(200))
A command line argument to limit the number of store instructions in the target basic block.
static cl::opt< int > SwpMaxMii("pipeliner-max-mii", cl::desc("Size limit for the MII."), cl::Hidden, cl::init(27))
A command line argument to limit minimum initial interval for pipelining.
static bool isSuccOrder(SUnit *SUa, SUnit *SUb)
Return true if SUb can be reached from SUa following the chain edges.
static cl::opt< int > SwpMaxStages("pipeliner-max-stages", cl::desc("Maximum stages allowed in the generated scheduled."), cl::Hidden, cl::init(3))
A command line argument to limit the number of stages in the pipeline.
static cl::opt< bool > EnableSWPOptSize("enable-pipeliner-opt-size", cl::desc("Enable SWP at Os."), cl::Hidden, cl::init(false))
A command line option to enable SWP at -Os.
static bool hasPHICycle(const MachineBasicBlock *LoopHeader, const MachineRegisterInfo &MRI)
static cl::opt< WindowSchedulingFlag > WindowSchedulingOption("window-sched", cl::Hidden, cl::init(WindowSchedulingFlag::WS_On), cl::desc("Set how to use window scheduling algorithm."), cl::values(clEnumValN(WindowSchedulingFlag::WS_Off, "off", "Turn off window algorithm."), clEnumValN(WindowSchedulingFlag::WS_On, "on", "Use window algorithm after SMS algorithm fails."), clEnumValN(WindowSchedulingFlag::WS_Force, "force", "Use window algorithm instead of SMS algorithm.")))
A command line argument to set the window scheduling option.
static bool pred_L(SetVector< SUnit * > &NodeOrder, SmallSetVector< SUnit *, 8 > &Preds, SwingSchedulerDDG *DDG, const NodeSet *S=nullptr)
Compute the Pred_L(O) set, as defined in the paper.
static cl::opt< bool > SwpShowResMask("pipeliner-show-mask", cl::Hidden, cl::init(false))
static cl::opt< int > SwpIISearchRange("pipeliner-ii-search-range", cl::desc("Range to search for II"), cl::Hidden, cl::init(10))
static bool computePath(SUnit *Cur, SetVector< SUnit * > &Path, SetVector< SUnit * > &DestNodes, SetVector< SUnit * > &Exclude, SmallPtrSet< SUnit *, 8 > &Visited, SwingSchedulerDDG *DDG)
Return true if there is a path from the specified node to any of the nodes in DestNodes.
static bool succ_L(SetVector< SUnit * > &NodeOrder, SmallSetVector< SUnit *, 8 > &Succs, SwingSchedulerDDG *DDG, const NodeSet *S=nullptr)
Compute the Succ_L(O) set, as defined in the paper.
static cl::opt< bool > LimitRegPressure("pipeliner-register-pressure", cl::Hidden, cl::init(false), cl::desc("Limit register pressure of scheduled loop"))
static cl::opt< bool > EnableSWP("enable-pipeliner", cl::Hidden, cl::init(true), cl::desc("Enable Software Pipelining"))
A command line option to turn software pipelining on or off.
static bool hasLoopCarriedMemDep(const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst, BatchAAResults &BAA, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI, const SwingSchedulerDAG *SSD)
Returns true if there is a loop-carried order dependency from Src to Dst.
static cl::opt< bool > SwpPruneDeps("pipeliner-prune-deps", cl::desc("Prune dependences between unrelated Phi nodes."), cl::Hidden, cl::init(true))
A command line option to disable the pruning of chain dependences due to an unrelated Phi.
static SUnit * multipleIterations(SUnit *SU, SwingSchedulerDAG *DAG)
If an instruction has a use that spans multiple iterations, then return true.
static Register findUniqueOperandDefinedInLoop(const MachineInstr &MI)
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
This file provides utility analysis objects describing memory locations.
static constexpr unsigned SM(unsigned Version)
uint64_t IntrinsicInst * II
#define P(N)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
This file defines the PriorityQueue class.
Remove Loads Into Fake Uses
std::pair< BasicBlock *, BasicBlock * > Edge
This file contains some templates that are useful if you are working with the STL at all.
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Target-Independent Code Generator Pass Configuration Options pass.
Add loop-carried chain dependencies.
void computeDependencies()
The main function to compute loop-carried order-dependencies.
const BitVector & getLoopCarried(unsigned Idx) const
LoopCarriedOrderDepsTracker(SwingSchedulerDAG *SSD, BatchAAResults *BAA, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:299
bool erase(const KeyT &Val)
Definition DenseMap.h:377
bool empty() const
Definition DenseMap.h:171
iterator end()
Definition DenseMap.h:141
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
Definition Pass.cpp:193
AttributeList getAttributes() const
Return the attribute list for this Function.
Definition Function.h:328
bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa, const MachineInstr &MIb) const override
bool isPostIncrement(const MachineInstr &MI) const override
Return true for post-incremented instructions.
DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override
Create machine specific model for scheduling.
bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
For instructions with a base and offset, return the position of the base register and offset operands...
const InstrStage * beginStage(unsigned ItinClassIndx) const
Return the first stage of the itinerary.
const InstrStage * endStage(unsigned ItinClassIndx) const
Return the last+1 stage of the itinerary.
bool isEmpty() const
Returns true if there are no itineraries.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
bool hasValue() const
TypeSize getValue() const
Represents a single loop in the control flow graph.
Definition LoopInfo.h:40
unsigned getSchedClass() const
Return the scheduling class for this instruction.
const MCWriteProcResEntry * getWriteProcResEnd(const MCSchedClassDesc *SC) const
const MCWriteProcResEntry * getWriteProcResBegin(const MCSchedClassDesc *SC) const
Return an iterator at the first process resource consumed by the given scheduling class.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1426
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1424
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1432
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:633
MachineInstrBundleIterator< const MachineInstr > const_iterator
iterator_range< iterator > phis()
Returns a range that iterates over the phis in the basic block.
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
bool isCopy() const
const MachineBasicBlock * getParent() const
filtered_mop_range all_defs()
Returns an iterator range over all operands that are (explicit or implicit) register defs.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
bool isRegSequence() const
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
LLVM_ABI bool isIdenticalTo(const MachineInstr &Other, MICheckType Check=CheckDefs) const
Return true if this instruction is identical to Other.
LLVM_ABI void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isPseudo(QueryType Type=IgnoreBundle) const
Return true if this is a pseudo instruction that doesn't correspond to a real machine instruction.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
AAMDNodes getAAInfo() const
Return the AA tags for the memory reference.
const Value * getValue() const
Return the base address of the memory access.
int64_t getOffset() const
For normal values, this is a byte offset added to the base address.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
void setImm(int64_t immVal)
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
Diagnostic information for optimization analysis remarks.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Emit an optimization remark.
Diagnostic information for missed-optimization remarks.
Diagnostic information for applied optimization remarks.
The main class in the implementation of the target independent software pipeliner pass.
bool runOnMachineFunction(MachineFunction &MF) override
The "main" function for implementing Swing Modulo Scheduling.
const TargetInstrInfo * TII
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const MachineLoopInfo * MLI
const RegisterClassInfo * RegClassInfo
MachineOptimizationRemarkEmitter * ORE
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_instr_iterator< true, false, false, true > use_instr_iterator
use_instr_iterator/use_instr_begin/use_instr_end - Walk all uses of the specified register,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
PSetIterator getPressureSets(VirtRegOrUnit VRegOrUnit) const
Get an iterator over the pressure sets affected by the virtual register or register unit.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
static use_instr_iterator use_instr_end()
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
LLVM_ABI MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
Expand the kernel using modulo variable expansion algorithm (MVE).
static LLVM_ABI bool canApply(MachineLoop &L)
Check if ModuloScheduleExpanderMVE can be applied to L.
The ModuloScheduleExpander takes a ModuloSchedule and expands it in-place, rewriting the old loop and...
LLVM_ABI void cleanup()
Performs final cleanup after expansion.
LLVM_ABI void expand()
Performs the actual expansion.
Expander that simply annotates each scheduled instruction with a post-instr symbol that can be consum...
LLVM_ABI void annotate()
Performs the annotation.
Represents a schedule for a single-block loop.
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
SUnit * getNode(unsigned i) const
LLVM_ABI void print(raw_ostream &os) const
void setRecMII(unsigned mii)
unsigned count(SUnit *SU) const
void setColocate(unsigned c)
int compareRecMII(NodeSet &RHS)
bool insert(SUnit *SU)
LLVM_DUMP_METHOD void dump() const
bool empty() const
unsigned getWeight() const
void dump() const
Definition Pass.cpp:146
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A reimplementation of ModuloScheduleExpander.
PointerIntPair - This class implements a pair of a pointer and small integer.
unsigned getPSet() const
Track the current register pressure at some position in the instruction stream, and remember the high...
LLVM_ABI void addLiveRegs(ArrayRef< VRegMaskOrUnit > Regs)
Force liveness of virtual registers or physical register units.
unsigned getRegPressureSetLimit(unsigned Idx) const
Get the register unit limit for the given pressure set index.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:107
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
LLVM_ABI int calculateResMII() const
LLVM_ABI void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
LLVM_ABI void init(int II)
Initialize resources with the initiation interval II.
LLVM_ABI bool canReserveResources(SUnit &SU, int Cycle)
Check if the resources occupied by a machine instruction are available in the current state.
Scheduling dependency.
Definition ScheduleDAG.h:52
Kind
These are the different kinds of scheduling dependencies.
Definition ScheduleDAG.h:55
@ Order
Any other ordering dependency.
Definition ScheduleDAG.h:59
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:57
@ Data
Regular data dependence (aka true-dependence).
Definition ScheduleDAG.h:56
void setLatency(unsigned Lat)
Sets the latency for this edge.
@ Barrier
An unknown scheduling barrier.
Definition ScheduleDAG.h:72
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition ScheduleDAG.h:75
void setSUnit(SUnit *SU)
This class represents the scheduled code.
LLVM_ABI std::deque< SUnit * > reorderInstructions(const SwingSchedulerDAG *SSD, const std::deque< SUnit * > &Instrs) const
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
LLVM_ABI void dump() const
Utility function used for debugging to print the schedule.
LLVM_ABI bool insert(SUnit *SU, int StartCycle, int EndCycle, int II)
Try to schedule the node at the specified StartCycle and continue until the node is schedule or the E...
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
LLVM_ABI void print(raw_ostream &os) const
Print the schedule information to the given output.
LLVM_ABI bool onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU, const SwingSchedulerDDG *DDG) const
Return true if all scheduled predecessors are loop-carried output/order dependencies.
int stageScheduled(SUnit *SU) const
Return the stage for a scheduled instruction.
LLVM_ABI void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU, std::deque< SUnit * > &Insts) const
Order the instructions within a cycle so that the definitions occur before the uses.
LLVM_ABI bool isValidSchedule(SwingSchedulerDAG *SSD)
int getInitiationInterval() const
Return the initiation interval for this schedule.
std::deque< SUnit * > & getInstructions(int cycle)
Return the instructions that are scheduled at the specified cycle.
int getFirstCycle() const
Return the first cycle in the completed schedule.
DenseMap< int, std::deque< SUnit * > >::const_iterator const_sched_iterator
LLVM_ABI bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def, MachineOperand &MO) const
Return true if the instruction is a definition that is loop carried and defines the use on the next i...
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
LLVM_ABI SmallPtrSet< SUnit *, 8 > computeUnpipelineableNodes(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
Determine transitive dependences of unpipelineable instructions.
LLVM_ABI void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int II, SwingSchedulerDAG *DAG)
Compute the scheduling start slot for the instruction.
LLVM_ABI bool normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
LLVM_ABI bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const
Return true if the scheduled Phi has a loop carried operand.
int getFinalCycle() const
Return the last cycle in the finalized schedule.
LLVM_ABI void finalizeSchedule(SwingSchedulerDAG *SSD)
After the schedule has been formed, call this function to combine the instructions from the different...
Scheduling unit. This is a node in the scheduling DAG.
unsigned NumPreds
bool isInstr() const
Returns true if this SUnit refers to a machine instruction as opposed to an SDNode.
unsigned NodeNum
Entry # of node in the node vector.
void setInstr(MachineInstr *MI)
Assigns the instruction for the SUnit.
LLVM_ABI void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
bool isPred(const SUnit *N) const
Tests if node N is a predecessor of this node.
unsigned short Latency
Node latency.
bool isBoundaryNode() const
Boundary nodes are placeholders for the boundary of the scheduling region.
bool hasPhysRegDefs
Has physreg defs that are being used.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
DenseMap< MachineInstr *, SUnit * > MISUnitMap
After calling BuildSchedGraph, each machine instruction in the current scheduling region is mapped to...
virtual void finishBlock()
Cleans up after scheduling in the given block.
MachineBasicBlock * BB
The block in which to insert instructions.
void buildSchedGraph(AAResults *AA, RegPressureTracker *RPTracker=nullptr, PressureDiffs *PDiffs=nullptr, LiveIntervals *LIS=nullptr, bool TrackLaneMasks=false)
Builds SUnits for the current region.
SUnit * getSUnit(MachineInstr *MI) const
Returns an existing SUnit for this MI, or nullptr.
void dump() const override
LLVM_ABI void AddPred(SUnit *Y, SUnit *X)
Updates the topological ordering to accommodate an edge to be added from SUnit X to SUnit Y.
LLVM_ABI bool IsReachable(const SUnit *SU, const SUnit *TargetSU)
Checks if SU is reachable from TargetSU.
MachineRegisterInfo & MRI
Virtual/real register map.
const TargetInstrInfo * TII
Target instruction information.
std::vector< SUnit > SUnits
The scheduling units.
const TargetRegisterInfo * TRI
Target processor register info.
SUnit EntrySU
Special node for the region entry.
MachineFunction & MF
Machine function.
SUnit ExitSU
Special node for the region exit.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
Definition SetVector.h:268
typename vector_type::const_iterator iterator
Definition SetVector.h:72
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
void clear()
Completely clear the SetVector.
Definition SetVector.h:273
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
iterator end() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator begin() const
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
bool erase(const T &V)
Definition SmallSet.h:200
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class builds the dependence graph for the instructions in a loop, and attempts to schedule the i...
void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule)
Apply changes to the instruction if needed.
const SwingSchedulerDDG * getDDG() const
void finishBlock() override
Clean up after the software pipeliner runs.
void fixupRegisterOverlaps(std::deque< SUnit * > &Instrs)
Attempt to fix the degenerate cases when the instruction serialization causes the register lifetimes ...
void schedule() override
We override the schedule function in ScheduleDAGInstrs to implement the scheduling part of the Swing ...
bool mayOverlapInLaterIter(const MachineInstr *BaseMI, const MachineInstr *OtherMI) const
Return false if there is no overlap between the region accessed by BaseMI in an iteration and the reg...
Register getInstrBaseReg(SUnit *SU) const
Return the new base register that was stored away for the changed instruction.
Represents a dependence between two instruction.
LLVM_ABI bool ignoreDependence(bool IgnoreAnti) const
Returns true for DDG nodes that we ignore when computing the cost functions.
This class provides APIs to retrieve edges from/to an SUnit node, with a particular focus on loop-car...
LLVM_ABI SwingSchedulerDDG(std::vector< SUnit > &SUnits, SUnit *EntrySU, SUnit *ExitSU, const LoopCarriedEdges &LCE)
LLVM_ABI ArrayRef< SUnit * > getExtraOutEdges(const SUnit *SU) const
LLVM_ABI const EdgesType & getInEdges(const SUnit *SU) const
LLVM_ABI bool isValidSchedule(const SMSchedule &Schedule) const
Check if Schedule doesn't violate the validation-only dependencies.
LLVM_ABI const EdgesType & getOutEdges(const SUnit *SU) const
Object returned by analyzeLoopForPipelining.
virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const =0
Return true if the given instruction should not be pipelined and should be ignored.
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool enableMachinePipeliner() const
True if the subtarget should run MachinePipeliner.
virtual bool useDFAforSMS() const
Default to DFA for resource management, return false when target will use ProcResource in InstrSchedM...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const InstrItineraryData * getInstrItineraryData() const
getInstrItineraryData - Returns instruction itinerary data for the target or specific subtarget.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
Wrapper class representing a virtual register or register unit.
Definition Register.h:175
constexpr bool isVirtualReg() const
Definition Register.h:191
constexpr MCRegUnit asMCRegUnit() const
Definition Register.h:195
constexpr Register asVirtualReg() const
Definition Register.h:200
The main class in the implementation of the target independent window scheduler.
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
@ Valid
The data is already valid.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
std::set< NodeId > NodeSet
Definition RDFGraph.h:551
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:578
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr NextUseDistance min(NextUseDistance A, NextUseDistance B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
Op::Description Desc
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
Definition bit.h:156
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
Definition STLExtras.h:2200
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
static int64_t computeDelta(SectionEntry *A, SectionEntry *B)
@ WS_Force
Use window algorithm after SMS algorithm fails.
@ WS_On
Turn off window algorithm.
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:94
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI cl::opt< bool > SwpEnableCopyToPhi
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2052
LLVM_ABI char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
This class holds an SUnit corresponding to a memory operation and other information related to the in...
const Value * MemOpValue
The value of a memory operand.
SmallVector< const Value *, 2 > UnderlyingObjs
bool isTriviallyDisjoint(const SUnitWithMemInfo &Other) const
int64_t MemOpOffset
The offset of a memory operand.
bool IsAllIdentified
True if all the underlying objects are identified.
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
Definition Metadata.h:763
uint64_t FuncUnits
Bitmask representing a set of functional units.
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
Represents loop-carried dependencies.
SmallSetVector< SUnit *, 8 > OrderDep
const OrderDep * getOrderDepOrNull(SUnit *Key) const
LLVM_ABI void modifySUnits(std::vector< SUnit > &SUnits, const TargetInstrInfo *TII)
Adds some edges to the original DAG that correspond to loop-carried dependencies.
LLVM_ABI void dump(SUnit *SU, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI) const
Define a kind of processor resource that will be modeled by the scheduler.
Definition MCSchedule.h:42
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:129
Machine model for scheduling, bundling, and heuristics.
Definition MCSchedule.h:273
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
Definition MCSchedule.h:381
bool hasInstrSchedModel() const
Does this machine model include instruction-level scheduling.
Definition MCSchedule.h:355
const MCProcResourceDesc * getProcResource(unsigned ProcResourceIdx) const
Definition MCSchedule.h:374
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition MCSchedule.h:74
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.