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