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.
207 llvm::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
870/// We override the schedule function in ScheduleDAGInstrs to implement the
871/// scheduling part of the Swing Modulo Scheduling algorithm.
873 buildSchedGraph(AA);
874 const LoopCarriedEdges LCE = addLoopCarriedDependences();
875 updatePhiDependences();
876 Topo.InitDAGTopologicalSorting();
877 changeDependences();
878 postProcessDAG();
879 DDG = std::make_unique<SwingSchedulerDDG>(SUnits, &EntrySU, &ExitSU, LCE);
880 LLVM_DEBUG({
881 dump();
882 dbgs() << "===== Loop Carried Edges Begin =====\n";
883 for (SUnit &SU : SUnits)
884 LCE.dump(&SU, TRI, &MRI);
885 dbgs() << "===== Loop Carried Edges End =====\n";
886 });
887
888 NodeSetType NodeSets;
889 findCircuits(NodeSets);
890 NodeSetType Circuits = NodeSets;
891
892 // Calculate the MII.
893 unsigned ResMII = calculateResMII();
894 unsigned RecMII = calculateRecMII(NodeSets);
895
896 fuseRecs(NodeSets);
897
898 // This flag is used for testing and can cause correctness problems.
899 if (SwpIgnoreRecMII)
900 RecMII = 0;
901
902 setMII(ResMII, RecMII);
903 setMAX_II();
904
905 LLVM_DEBUG(dbgs() << "MII = " << MII << " MAX_II = " << MAX_II
906 << " (rec=" << RecMII << ", res=" << ResMII << ")\n");
907
908 // Can't schedule a loop without a valid MII.
909 if (MII == 0) {
910 LLVM_DEBUG(dbgs() << "Invalid Minimal Initiation Interval: 0\n");
911 NumFailZeroMII++;
912 ORE->emit([&]() {
914 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
915 << "Invalid Minimal Initiation Interval: 0";
916 });
917 return;
918 }
919
920 // Don't pipeline large loops.
921 if (SwpMaxMii != -1 && (int)MII > SwpMaxMii) {
922 LLVM_DEBUG(dbgs() << "MII > " << SwpMaxMii
923 << ", we don't pipeline large loops\n");
924 NumFailLargeMaxMII++;
925 ORE->emit([&]() {
927 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
928 << "Minimal Initiation Interval too large: "
929 << ore::NV("MII", (int)MII) << " > "
930 << ore::NV("SwpMaxMii", SwpMaxMii) << "."
931 << "Refer to -pipeliner-max-mii.";
932 });
933 return;
934 }
935
936 computeNodeFunctions(NodeSets);
937
938 registerPressureFilter(NodeSets);
939
940 colocateNodeSets(NodeSets);
941
942 checkNodeSets(NodeSets);
943
944 LLVM_DEBUG({
945 for (auto &I : NodeSets) {
946 dbgs() << " Rec NodeSet ";
947 I.dump();
948 }
949 });
950
951 llvm::stable_sort(NodeSets, std::greater<NodeSet>());
952
953 groupRemainingNodes(NodeSets);
954
955 removeDuplicateNodes(NodeSets);
956
957 LLVM_DEBUG({
958 for (auto &I : NodeSets) {
959 dbgs() << " NodeSet ";
960 I.dump();
961 }
962 });
963
964 computeNodeOrder(NodeSets);
965
966 // check for node order issues
967 checkValidNodeOrder(Circuits);
968
969 SMSchedule Schedule(&MF, this);
970 Scheduled = schedulePipeline(Schedule);
971
972 if (!Scheduled){
973 LLVM_DEBUG(dbgs() << "No schedule found, return\n");
974 NumFailNoSchedule++;
975 ORE->emit([&]() {
977 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
978 << "Unable to find schedule";
979 });
980 return;
981 }
982
983 unsigned numStages = Schedule.getMaxStageCount();
984 // No need to generate pipeline if there are no overlapped iterations.
985 if (numStages == 0) {
986 LLVM_DEBUG(dbgs() << "No overlapped iterations, skip.\n");
987 NumFailZeroStage++;
988 ORE->emit([&]() {
990 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
991 << "No need to pipeline - no overlapped iterations in schedule.";
992 });
993 return;
994 }
995 // Check that the maximum stage count is less than user-defined limit.
996 if (SwpMaxStages > -1 && (int)numStages > SwpMaxStages) {
997 LLVM_DEBUG(dbgs() << "numStages:" << numStages << ">" << SwpMaxStages
998 << " : too many stages, abort\n");
999 NumFailLargeMaxStage++;
1000 ORE->emit([&]() {
1002 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
1003 << "Too many stages in schedule: "
1004 << ore::NV("numStages", (int)numStages) << " > "
1005 << ore::NV("SwpMaxStages", SwpMaxStages)
1006 << ". Refer to -pipeliner-max-stages.";
1007 });
1008 return;
1009 }
1010
1011 ORE->emit([&]() {
1012 return MachineOptimizationRemark(DEBUG_TYPE, "schedule", Loop.getStartLoc(),
1013 Loop.getHeader())
1014 << "Pipelined succesfully!";
1015 });
1016
1017 // Generate the schedule as a ModuloSchedule.
1018 DenseMap<MachineInstr *, int> Cycles, Stages;
1019 std::vector<MachineInstr *> OrderedInsts;
1020 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
1021 ++Cycle) {
1022 for (SUnit *SU : Schedule.getInstructions(Cycle)) {
1023 OrderedInsts.push_back(SU->getInstr());
1024 Cycles[SU->getInstr()] = Cycle;
1025 Stages[SU->getInstr()] = Schedule.stageScheduled(SU);
1026 }
1027 }
1029 for (auto &KV : NewMIs) {
1030 Cycles[KV.first] = Cycles[KV.second];
1031 Stages[KV.first] = Stages[KV.second];
1032 NewInstrChanges[KV.first] = InstrChanges[getSUnit(KV.first)];
1033 }
1034
1035 ModuloSchedule MS(MF, &Loop, std::move(OrderedInsts), std::move(Cycles),
1036 std::move(Stages));
1037 if (EmitTestAnnotations) {
1038 assert(NewInstrChanges.empty() &&
1039 "Cannot serialize a schedule with InstrChanges!");
1041 MSTI.annotate();
1042 return;
1043 }
1044 // The experimental code generator can't work if there are InstChanges.
1045 if (ExperimentalCodeGen && NewInstrChanges.empty()) {
1046 PeelingModuloScheduleExpander MSE(MF, MS, &LIS);
1047 MSE.expand();
1048 } else if (MVECodeGen && NewInstrChanges.empty() &&
1049 LoopPipelinerInfo->isMVEExpanderSupported() &&
1051 ModuloScheduleExpanderMVE MSE(MF, MS, LIS);
1052 MSE.expand();
1053 } else {
1054 ModuloScheduleExpander MSE(MF, MS, LIS, std::move(NewInstrChanges));
1055 MSE.expand();
1056 MSE.cleanup();
1057 }
1058 ++NumPipelined;
1059}
1060
1061/// Clean up after the software pipeliner runs.
1063 for (auto &KV : NewMIs)
1064 MF.deleteMachineInstr(KV.second);
1065 NewMIs.clear();
1066
1067 // Call the superclass.
1069}
1070
1071/// Return the register values for the operands of a Phi instruction.
1072/// This function assume the instruction is a Phi.
1074 Register &InitVal, Register &LoopVal) {
1075 assert(Phi.isPHI() && "Expecting a Phi.");
1076
1077 InitVal = Register();
1078 LoopVal = Register();
1079 for (unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
1080 if (Phi.getOperand(i + 1).getMBB() != Loop)
1081 InitVal = Phi.getOperand(i).getReg();
1082 else
1083 LoopVal = Phi.getOperand(i).getReg();
1084
1085 assert(InitVal && LoopVal && "Unexpected Phi structure.");
1086}
1087
1088/// Return the Phi register value that comes the loop block.
1090 const MachineBasicBlock *LoopBB) {
1091 for (unsigned i = 1, e = Phi.getNumOperands(); i != e; i += 2)
1092 if (Phi.getOperand(i + 1).getMBB() == LoopBB)
1093 return Phi.getOperand(i).getReg();
1094 return Register();
1095}
1096
1097/// Return true if SUb can be reached from SUa following the chain edges.
1098static bool isSuccOrder(SUnit *SUa, SUnit *SUb) {
1100 SmallVector<SUnit *, 8> Worklist;
1101 Worklist.push_back(SUa);
1102 while (!Worklist.empty()) {
1103 const SUnit *SU = Worklist.pop_back_val();
1104 for (const auto &SI : SU->Succs) {
1105 SUnit *SuccSU = SI.getSUnit();
1106 if (SI.getKind() == SDep::Order) {
1107 if (Visited.count(SuccSU))
1108 continue;
1109 if (SuccSU == SUb)
1110 return true;
1111 Worklist.push_back(SuccSU);
1112 Visited.insert(SuccSU);
1113 }
1114 }
1115 }
1116 return false;
1117}
1118
1120 if (!getUnderlyingObjects())
1121 return;
1122 for (const Value *Obj : UnderlyingObjs)
1123 if (!isIdentifiedObject(Obj)) {
1124 IsAllIdentified = false;
1125 break;
1126 }
1127}
1128
1130 const SUnitWithMemInfo &Other) const {
1131 // If all underlying objects are identified objects and there is no overlap
1132 // between them, then these two instructions are disjoint.
1133 if (!IsAllIdentified || !Other.IsAllIdentified)
1134 return false;
1135 for (const Value *Obj : UnderlyingObjs)
1136 if (llvm::is_contained(Other.UnderlyingObjs, Obj))
1137 return false;
1138 return true;
1139}
1140
1141/// Collect the underlying objects for the memory references of an instruction.
1142/// This function calls the code in ValueTracking, but first checks that the
1143/// instruction has a memory operand.
1144/// Returns false if we cannot find the underlying objects.
1145bool SUnitWithMemInfo::getUnderlyingObjects() {
1146 const MachineInstr *MI = SU->getInstr();
1147 if (!MI->hasOneMemOperand())
1148 return false;
1149 MachineMemOperand *MM = *MI->memoperands_begin();
1150 if (!MM->getValue())
1151 return false;
1152 MemOpValue = MM->getValue();
1153 MemOpOffset = MM->getOffset();
1155
1156 // TODO: A no alias scope may be valid only in a single iteration. In this
1157 // case we need to peel off it like LoopAccessAnalysis does.
1158 AATags = MM->getAAInfo();
1159 return true;
1160}
1161
1162/// Returns true if there is a loop-carried order dependency from \p Src to \p
1163/// Dst.
1164static bool hasLoopCarriedMemDep(const SUnitWithMemInfo &Src,
1165 const SUnitWithMemInfo &Dst,
1166 BatchAAResults &BAA,
1167 const TargetInstrInfo *TII,
1168 const TargetRegisterInfo *TRI,
1169 const SwingSchedulerDAG *SSD) {
1170 if (Src.isTriviallyDisjoint(Dst))
1171 return false;
1172 if (isSuccOrder(Src.SU, Dst.SU))
1173 return false;
1174
1175 MachineInstr &SrcMI = *Src.SU->getInstr();
1176 MachineInstr &DstMI = *Dst.SU->getInstr();
1177
1178 if (!SSD->mayOverlapInLaterIter(&SrcMI, &DstMI))
1179 return false;
1180
1181 // Second, the more expensive check that uses alias analysis on the
1182 // base registers. If they alias, and the load offset is less than
1183 // the store offset, the mark the dependence as loop carried.
1184 if (Src.isUnknown() || Dst.isUnknown())
1185 return true;
1186 if (Src.MemOpValue == Dst.MemOpValue && Src.MemOpOffset <= Dst.MemOpOffset)
1187 return true;
1188
1189 if (BAA.isNoAlias(
1190 MemoryLocation::getBeforeOrAfter(Src.MemOpValue, Src.AATags),
1191 MemoryLocation::getBeforeOrAfter(Dst.MemOpValue, Dst.AATags)))
1192 return false;
1193
1194 // AliasAnalysis sometimes gives up on following the underlying
1195 // object. In such a case, separate checks for underlying objects may
1196 // prove that there are no aliases between two accesses.
1197 for (const Value *SrcObj : Src.UnderlyingObjs)
1198 for (const Value *DstObj : Dst.UnderlyingObjs)
1199 if (!BAA.isNoAlias(MemoryLocation::getBeforeOrAfter(SrcObj, Src.AATags),
1200 MemoryLocation::getBeforeOrAfter(DstObj, Dst.AATags)))
1201 return true;
1202
1203 return false;
1204}
1205
1206void LoopCarriedOrderDepsTracker::NoBarrierInstsChunk::append(SUnit *SU) {
1207 const MachineInstr *MI = SU->getInstr();
1208 if (MI->mayStore())
1209 Stores.emplace_back(SU);
1210 else if (MI->mayLoad())
1211 Loads.emplace_back(SU);
1212 else if (MI->mayRaiseFPException())
1213 FPExceptions.emplace_back(SU);
1214 else
1215 llvm_unreachable("Unexpected instruction type.");
1216}
1217
1219 SwingSchedulerDAG *SSD, BatchAAResults *BAA, const TargetInstrInfo *TII,
1220 const TargetRegisterInfo *TRI)
1221 : DAG(SSD), BAA(BAA), SUnits(DAG->SUnits), N(SUnits.size()),
1222 LoopCarried(N, BitVector(N)), TII(TII), TRI(TRI) {}
1223
1225 // Traverse all instructions and extract only what we are targetting.
1226 for (auto &SU : SUnits) {
1227 auto Tagged = getInstrTag(&SU);
1228
1229 // This instruction has no loop-carried order-dependencies.
1230 if (!Tagged)
1231 continue;
1232 TaggedSUnits.emplace_back(&SU, *Tagged);
1233 }
1234
1235 computeDependenciesAux();
1236}
1237
1238std::optional<LoopCarriedOrderDepsTracker::InstrTag>
1239LoopCarriedOrderDepsTracker::getInstrTag(SUnit *SU) const {
1240 MachineInstr *MI = SU->getInstr();
1241 if (TII->isGlobalMemoryObject(MI))
1242 return InstrTag::Barrier;
1243
1244 if (MI->mayStore() ||
1245 (MI->mayLoad() && !MI->isDereferenceableInvariantLoad()))
1246 return InstrTag::LoadOrStore;
1247
1248 if (MI->mayRaiseFPException())
1249 return InstrTag::FPExceptions;
1250
1251 return std::nullopt;
1252}
1253
1254void LoopCarriedOrderDepsTracker::addDependenciesBetweenSUs(
1255 const SUnitWithMemInfo &Src, const SUnitWithMemInfo &Dst) {
1256 // Avoid self-dependencies.
1257 if (Src.SU == Dst.SU)
1258 return;
1259
1260 if (hasLoopCarriedMemDep(Src, Dst, *BAA, TII, TRI, DAG))
1261 setLoopCarriedDep(Src.SU, Dst.SU);
1262}
1263
1264void LoopCarriedOrderDepsTracker::addLoopCarriedDepenenciesForChunks(
1265 const NoBarrierInstsChunk &From, const NoBarrierInstsChunk &To) {
1266 // Add load-to-store dependencies (WAR).
1267 for (const SUnitWithMemInfo &Src : From.Loads)
1268 for (const SUnitWithMemInfo &Dst : To.Stores)
1269 addDependenciesBetweenSUs(Src, Dst);
1270
1271 // Add store-to-load dependencies (RAW).
1272 for (const SUnitWithMemInfo &Src : From.Stores)
1273 for (const SUnitWithMemInfo &Dst : To.Loads)
1274 addDependenciesBetweenSUs(Src, Dst);
1275
1276 // Add store-to-store dependencies (WAW).
1277 for (const SUnitWithMemInfo &Src : From.Stores)
1278 for (const SUnitWithMemInfo &Dst : To.Stores)
1279 addDependenciesBetweenSUs(Src, Dst);
1280}
1281
1282void LoopCarriedOrderDepsTracker::computeDependenciesAux() {
1284 SUnit *FirstBarrier = nullptr;
1285 SUnit *LastBarrier = nullptr;
1286 for (const auto &TSU : TaggedSUnits) {
1287 InstrTag Tag = TSU.getTag();
1288 SUnit *SU = TSU.getPointer();
1289 switch (Tag) {
1290 case InstrTag::Barrier:
1291 if (!FirstBarrier)
1292 FirstBarrier = SU;
1293 LastBarrier = SU;
1294 Chunks.emplace_back();
1295 break;
1296 case InstrTag::LoadOrStore:
1297 case InstrTag::FPExceptions:
1298 Chunks.back().append(SU);
1299 break;
1300 }
1301 }
1302
1303 // Add dependencies between memory operations. If there are one or more
1304 // barrier events between two memory instructions, we don't add a
1305 // loop-carried dependence for them.
1306 for (const NoBarrierInstsChunk &Chunk : Chunks)
1307 addLoopCarriedDepenenciesForChunks(Chunk, Chunk);
1308
1309 // There is no barrier instruction between load/store/fp-exception
1310 // instructions in the same chunk. If there are one or more barrier
1311 // instructions, the instructions sequence is as follows:
1312 //
1313 // Loads/Stores/FPExceptions (Chunks.front())
1314 // Barrier (FirstBarrier)
1315 // Loads/Stores/FPExceptions
1316 // Barrier
1317 // ...
1318 // Loads/Stores/FPExceptions
1319 // Barrier (LastBarrier)
1320 // Loads/Stores/FPExceptions (Chunks.back())
1321 //
1322 // Since loads/stores/fp-exceptions must not be reordered across barrier
1323 // instructions, and the order of barrier instructions must be preserved, add
1324 // the following loop-carried dependences:
1325 //
1326 // Loads/Stores/FPExceptions (Chunks.front()) <-----+
1327 // +--> Barrier (FirstBarrier) <----------------------+ |
1328 // | Loads/Stores/FPExceptions | |
1329 // | Barrier | |
1330 // | ... | |
1331 // | Loads/Stores/FPExceptions | |
1332 // | Barrier (LastBarrier) ------------------------+--+
1333 // +--- Loads/Stores/FPExceptions (Chunks.back())
1334 //
1335 if (FirstBarrier) {
1336 assert(LastBarrier && "Both barriers should be set.");
1337
1338 // LastBarrier -> Loads/Stores/FPExceptions in Chunks.front()
1339 for (const SUnitWithMemInfo &Dst : Chunks.front().Loads)
1340 setLoopCarriedDep(LastBarrier, Dst.SU);
1341 for (const SUnitWithMemInfo &Dst : Chunks.front().Stores)
1342 setLoopCarriedDep(LastBarrier, Dst.SU);
1343 for (const SUnitWithMemInfo &Dst : Chunks.front().FPExceptions)
1344 setLoopCarriedDep(LastBarrier, Dst.SU);
1345
1346 // Loads/Stores/FPExceptions in Chunks.back() -> FirstBarrier
1347 for (const SUnitWithMemInfo &Src : Chunks.back().Loads)
1348 setLoopCarriedDep(Src.SU, FirstBarrier);
1349 for (const SUnitWithMemInfo &Src : Chunks.back().Stores)
1350 setLoopCarriedDep(Src.SU, FirstBarrier);
1351 for (const SUnitWithMemInfo &Src : Chunks.back().FPExceptions)
1352 setLoopCarriedDep(Src.SU, FirstBarrier);
1353
1354 // LastBarrier -> FirstBarrier (if they are different)
1355 if (FirstBarrier != LastBarrier)
1356 setLoopCarriedDep(LastBarrier, FirstBarrier);
1357 }
1358}
1359
1360/// Add a chain edge between a load and store if the store can be an
1361/// alias of the load on a subsequent iteration, i.e., a loop carried
1362/// dependence. This code is very similar to the code in ScheduleDAGInstrs
1363/// but that code doesn't create loop carried dependences.
1364/// TODO: Also compute output-dependencies.
1365LoopCarriedEdges SwingSchedulerDAG::addLoopCarriedDependences() {
1366 LoopCarriedEdges LCE;
1367
1368 // Add loop-carried order-dependencies
1369 LoopCarriedOrderDepsTracker LCODTracker(this, &BAA, TII, TRI);
1370 LCODTracker.computeDependencies();
1371 for (unsigned I = 0; I != SUnits.size(); I++)
1372 for (const int Succ : LCODTracker.getLoopCarried(I).set_bits())
1373 LCE.OrderDeps[&SUnits[I]].insert(&SUnits[Succ]);
1374
1375 LCE.modifySUnits(SUnits, TII);
1376 return LCE;
1377}
1378
1379/// Update the phi dependences to the DAG because ScheduleDAGInstrs no longer
1380/// processes dependences for PHIs. This function adds true dependences
1381/// from a PHI to a use, and a loop carried dependence from the use to the
1382/// PHI. The loop carried dependence is represented as an anti dependence
1383/// edge. This function also removes chain dependences between unrelated
1384/// PHIs.
1385void SwingSchedulerDAG::updatePhiDependences() {
1386 SmallVector<SDep, 4> RemoveDeps;
1387 const TargetSubtargetInfo &ST = MF.getSubtarget<TargetSubtargetInfo>();
1388
1389 // Iterate over each DAG node.
1390 for (SUnit &I : SUnits) {
1391 RemoveDeps.clear();
1392 // Set to true if the instruction has an operand defined by a Phi.
1393 Register HasPhiUse;
1394 Register HasPhiDef;
1395 MachineInstr *MI = I.getInstr();
1396 // Iterate over each operand, and we process the definitions.
1397 for (const MachineOperand &MO : MI->operands()) {
1398 if (!MO.isReg())
1399 continue;
1400 Register Reg = MO.getReg();
1401 if (!Reg.isVirtual())
1402 continue;
1403
1404 if (MO.isDef()) {
1405 // If the register is used by a Phi, then create an anti dependence.
1407 UI = MRI.use_instr_begin(Reg),
1408 UE = MRI.use_instr_end();
1409 UI != UE; ++UI) {
1410 MachineInstr *UseMI = &*UI;
1411 SUnit *SU = getSUnit(UseMI);
1412 if (SU != nullptr && UseMI->isPHI()) {
1413 if (!MI->isPHI()) {
1414 SDep Dep(SU, SDep::Anti, Reg);
1415 Dep.setLatency(1);
1416 I.addPred(Dep);
1417 } else {
1418 HasPhiDef = Reg;
1419 // Add a chain edge to a dependent Phi that isn't an existing
1420 // predecessor.
1421
1422 // %3:intregs = PHI %21:intregs, %bb.6, %7:intregs, %bb.1 - SU0
1423 // %7:intregs = PHI %21:intregs, %bb.6, %13:intregs, %bb.1 - SU1
1424 // %27:intregs = A2_zxtb %3:intregs - SU2
1425 // %13:intregs = C2_muxri %45:predregs, 0, %46:intreg
1426 // If we have dependent phis, SU0 should be the successor of SU1
1427 // not the other way around. (it used to be SU1 is the successor
1428 // of SU0). In some cases, SU0 is scheduled earlier than SU1
1429 // resulting in bad IR as we do not have a value that can be used
1430 // by SU2.
1431
1432 if (SU->NodeNum < I.NodeNum && !SU->isPred(&I))
1433 SU->addPred(SDep(&I, SDep::Barrier));
1434 }
1435 }
1436 }
1437 } else if (MO.isUse()) {
1438 // If the register is defined by a Phi, then create a true dependence.
1439 MachineInstr *DefMI = MRI.getUniqueVRegDef(Reg);
1440 if (DefMI == nullptr)
1441 continue;
1442 SUnit *SU = getSUnit(DefMI);
1443 if (SU != nullptr && DefMI->isPHI()) {
1444 if (!MI->isPHI()) {
1445 SDep Dep(SU, SDep::Data, Reg);
1446 Dep.setLatency(0);
1447 ST.adjustSchedDependency(SU, 0, &I, MO.getOperandNo(), Dep,
1448 &SchedModel);
1449 I.addPred(Dep);
1450 } else {
1451 HasPhiUse = Reg;
1452 // Add a chain edge to a dependent Phi that isn't an existing
1453 // predecessor.
1454 if (SU->NodeNum < I.NodeNum && !I.isPred(SU))
1455 I.addPred(SDep(SU, SDep::Barrier));
1456 }
1457 }
1458 }
1459 }
1460 // Remove order dependences from an unrelated Phi.
1461 if (!SwpPruneDeps)
1462 continue;
1463 for (auto &PI : I.Preds) {
1464 MachineInstr *PMI = PI.getSUnit()->getInstr();
1465 if (PMI->isPHI() && PI.getKind() == SDep::Order) {
1466 if (I.getInstr()->isPHI()) {
1467 if (PMI->getOperand(0).getReg() == HasPhiUse)
1468 continue;
1469 if (getLoopPhiReg(*PMI, PMI->getParent()) == HasPhiDef)
1470 continue;
1471 }
1472 RemoveDeps.push_back(PI);
1473 }
1474 }
1475 for (const SDep &D : RemoveDeps)
1476 I.removePred(D);
1477 }
1478}
1479
1480/// Iterate over each DAG node and see if we can change any dependences
1481/// in order to reduce the recurrence MII.
1482void SwingSchedulerDAG::changeDependences() {
1483 // See if an instruction can use a value from the previous iteration.
1484 // If so, we update the base and offset of the instruction and change
1485 // the dependences.
1486 for (SUnit &I : SUnits) {
1487 unsigned BasePos = 0, OffsetPos = 0;
1488 Register NewBase;
1489 int64_t NewOffset = 0;
1490 if (!canUseLastOffsetValue(I.getInstr(), BasePos, OffsetPos, NewBase,
1491 NewOffset))
1492 continue;
1493
1494 // Get the MI and SUnit for the instruction that defines the original base.
1495 Register OrigBase = I.getInstr()->getOperand(BasePos).getReg();
1496 MachineInstr *DefMI = MRI.getUniqueVRegDef(OrigBase);
1497 if (!DefMI)
1498 continue;
1499 SUnit *DefSU = getSUnit(DefMI);
1500 if (!DefSU)
1501 continue;
1502 // Get the MI and SUnit for the instruction that defins the new base.
1503 MachineInstr *LastMI = MRI.getUniqueVRegDef(NewBase);
1504 if (!LastMI)
1505 continue;
1506 SUnit *LastSU = getSUnit(LastMI);
1507 if (!LastSU)
1508 continue;
1509
1510 if (Topo.IsReachable(&I, LastSU))
1511 continue;
1512
1513 // Remove the dependence. The value now depends on a prior iteration.
1515 for (const SDep &P : I.Preds)
1516 if (P.getSUnit() == DefSU)
1517 Deps.push_back(P);
1518 for (const SDep &D : Deps) {
1519 Topo.RemovePred(&I, D.getSUnit());
1520 I.removePred(D);
1521 }
1522 // Remove the chain dependence between the instructions.
1523 Deps.clear();
1524 for (auto &P : LastSU->Preds)
1525 if (P.getSUnit() == &I && P.getKind() == SDep::Order)
1526 Deps.push_back(P);
1527 for (const SDep &D : Deps) {
1528 Topo.RemovePred(LastSU, D.getSUnit());
1529 LastSU->removePred(D);
1530 }
1531
1532 // Add a dependence between the new instruction and the instruction
1533 // that defines the new base.
1534 SDep Dep(&I, SDep::Anti, NewBase);
1535 Topo.AddPred(LastSU, &I);
1536 LastSU->addPred(Dep);
1537
1538 // Remember the base and offset information so that we can update the
1539 // instruction during code generation.
1540 InstrChanges[&I] = std::make_pair(NewBase, NewOffset);
1541 }
1542}
1543
1544/// Create an instruction stream that represents a single iteration and stage of
1545/// each instruction. This function differs from SMSchedule::finalizeSchedule in
1546/// that this doesn't have any side-effect to SwingSchedulerDAG. That is, this
1547/// function is an approximation of SMSchedule::finalizeSchedule with all
1548/// non-const operations removed.
1550 SMSchedule &Schedule,
1551 std::vector<MachineInstr *> &OrderedInsts,
1554
1555 // Move all instructions to the first stage from the later stages.
1556 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
1557 ++Cycle) {
1558 for (int Stage = 0, LastStage = Schedule.getMaxStageCount();
1559 Stage <= LastStage; ++Stage) {
1560 for (SUnit *SU : llvm::reverse(Schedule.getInstructions(
1561 Cycle + Stage * Schedule.getInitiationInterval()))) {
1562 Instrs[Cycle].push_front(SU);
1563 }
1564 }
1565 }
1566
1567 for (int Cycle = Schedule.getFirstCycle(); Cycle <= Schedule.getFinalCycle();
1568 ++Cycle) {
1569 std::deque<SUnit *> &CycleInstrs = Instrs[Cycle];
1570 CycleInstrs = Schedule.reorderInstructions(SSD, CycleInstrs);
1571 for (SUnit *SU : CycleInstrs) {
1572 MachineInstr *MI = SU->getInstr();
1573 OrderedInsts.push_back(MI);
1574 Stages[MI] = Schedule.stageScheduled(SU);
1575 }
1576 }
1577}
1578
1579namespace {
1580
1581// FuncUnitSorter - Comparison operator used to sort instructions by
1582// the number of functional unit choices.
1583struct FuncUnitSorter {
1584 const InstrItineraryData *InstrItins;
1585 const MCSubtargetInfo *STI;
1586 DenseMap<InstrStage::FuncUnits, unsigned> Resources;
1587
1588 FuncUnitSorter(const TargetSubtargetInfo &TSI)
1589 : InstrItins(TSI.getInstrItineraryData()), STI(&TSI) {}
1590
1591 // Compute the number of functional unit alternatives needed
1592 // at each stage, and take the minimum value. We prioritize the
1593 // instructions by the least number of choices first.
1594 unsigned minFuncUnits(const MachineInstr *Inst,
1595 InstrStage::FuncUnits &F) const {
1596 unsigned SchedClass = Inst->getDesc().getSchedClass();
1597 unsigned min = UINT_MAX;
1598 if (InstrItins && !InstrItins->isEmpty()) {
1599 for (const InstrStage &IS :
1600 make_range(InstrItins->beginStage(SchedClass),
1601 InstrItins->endStage(SchedClass))) {
1602 InstrStage::FuncUnits funcUnits = IS.getUnits();
1603 unsigned numAlternatives = llvm::popcount(funcUnits);
1604 if (numAlternatives < min) {
1605 min = numAlternatives;
1606 F = funcUnits;
1607 }
1608 }
1609 return min;
1610 }
1611 if (STI && STI->getSchedModel().hasInstrSchedModel()) {
1612 const MCSchedClassDesc *SCDesc =
1613 STI->getSchedModel().getSchedClassDesc(SchedClass);
1614 if (!SCDesc->isValid())
1615 // No valid Schedule Class Desc for schedClass, should be
1616 // Pseudo/PostRAPseudo
1617 return min;
1618
1619 for (const MCWriteProcResEntry &PRE :
1620 make_range(STI->getWriteProcResBegin(SCDesc),
1621 STI->getWriteProcResEnd(SCDesc))) {
1622 if (!PRE.ReleaseAtCycle)
1623 continue;
1624 const MCProcResourceDesc *ProcResource =
1625 STI->getSchedModel().getProcResource(PRE.ProcResourceIdx);
1626 unsigned NumUnits = ProcResource->NumUnits;
1627 if (NumUnits < min) {
1628 min = NumUnits;
1629 F = PRE.ProcResourceIdx;
1630 }
1631 }
1632 return min;
1633 }
1634 llvm_unreachable("Should have non-empty InstrItins or hasInstrSchedModel!");
1635 }
1636
1637 // Compute the critical resources needed by the instruction. This
1638 // function records the functional units needed by instructions that
1639 // must use only one functional unit. We use this as a tie breaker
1640 // for computing the resource MII. The instrutions that require
1641 // the same, highly used, functional unit have high priority.
1642 void calcCriticalResources(MachineInstr &MI) {
1643 unsigned SchedClass = MI.getDesc().getSchedClass();
1644 if (InstrItins && !InstrItins->isEmpty()) {
1645 for (const InstrStage &IS :
1646 make_range(InstrItins->beginStage(SchedClass),
1647 InstrItins->endStage(SchedClass))) {
1648 InstrStage::FuncUnits FuncUnits = IS.getUnits();
1649 if (llvm::popcount(FuncUnits) == 1)
1650 Resources[FuncUnits]++;
1651 }
1652 return;
1653 }
1654 if (STI && STI->getSchedModel().hasInstrSchedModel()) {
1655 const MCSchedClassDesc *SCDesc =
1656 STI->getSchedModel().getSchedClassDesc(SchedClass);
1657 if (!SCDesc->isValid())
1658 // No valid Schedule Class Desc for schedClass, should be
1659 // Pseudo/PostRAPseudo
1660 return;
1661
1662 for (const MCWriteProcResEntry &PRE :
1663 make_range(STI->getWriteProcResBegin(SCDesc),
1664 STI->getWriteProcResEnd(SCDesc))) {
1665 if (!PRE.ReleaseAtCycle)
1666 continue;
1667 Resources[PRE.ProcResourceIdx]++;
1668 }
1669 return;
1670 }
1671 llvm_unreachable("Should have non-empty InstrItins or hasInstrSchedModel!");
1672 }
1673
1674 /// Return true if IS1 has less priority than IS2.
1675 bool operator()(const MachineInstr *IS1, const MachineInstr *IS2) const {
1676 InstrStage::FuncUnits F1 = 0, F2 = 0;
1677 unsigned MFUs1 = minFuncUnits(IS1, F1);
1678 unsigned MFUs2 = minFuncUnits(IS2, F2);
1679 if (MFUs1 == MFUs2)
1680 return Resources.lookup(F1) < Resources.lookup(F2);
1681 return MFUs1 > MFUs2;
1682 }
1683};
1684
1685/// Calculate the maximum register pressure of the scheduled instructions stream
1686class HighRegisterPressureDetector {
1687 MachineBasicBlock *OrigMBB;
1688 const MachineRegisterInfo &MRI;
1689 const TargetRegisterInfo *TRI;
1690
1691 const unsigned PSetNum;
1692
1693 // Indexed by PSet ID
1694 // InitSetPressure takes into account the register pressure of live-in
1695 // registers. It's not depend on how the loop is scheduled, so it's enough to
1696 // calculate them once at the beginning.
1697 std::vector<unsigned> InitSetPressure;
1698
1699 // Indexed by PSet ID
1700 // Upper limit for each register pressure set
1701 std::vector<unsigned> PressureSetLimit;
1702
1703 DenseMap<MachineInstr *, RegisterOperands> ROMap;
1704
1705 using Instr2LastUsesTy = DenseMap<MachineInstr *, SmallDenseSet<Register, 4>>;
1706
1707public:
1708 using OrderedInstsTy = std::vector<MachineInstr *>;
1709 using Instr2StageTy = DenseMap<MachineInstr *, unsigned>;
1710
1711private:
1712 static void dumpRegisterPressures(const std::vector<unsigned> &Pressures) {
1713 if (Pressures.size() == 0) {
1714 dbgs() << "[]";
1715 } else {
1716 char Prefix = '[';
1717 for (unsigned P : Pressures) {
1718 dbgs() << Prefix << P;
1719 Prefix = ' ';
1720 }
1721 dbgs() << ']';
1722 }
1723 }
1724
1725 void dumpPSet(Register Reg) const {
1726 dbgs() << "Reg=" << printReg(Reg, TRI, 0, &MRI) << " PSet=";
1727 // FIXME: The static_cast is a bug compensating bugs in the callers.
1728 VirtRegOrUnit VRegOrUnit =
1729 Reg.isVirtual() ? VirtRegOrUnit(Reg)
1730 : VirtRegOrUnit(static_cast<MCRegUnit>(Reg.id()));
1731 for (auto PSetIter = MRI.getPressureSets(VRegOrUnit); PSetIter.isValid();
1732 ++PSetIter) {
1733 dbgs() << *PSetIter << ' ';
1734 }
1735 dbgs() << '\n';
1736 }
1737
1738 void increaseRegisterPressure(std::vector<unsigned> &Pressure,
1739 Register Reg) const {
1740 // FIXME: The static_cast is a bug compensating bugs in the callers.
1741 VirtRegOrUnit VRegOrUnit =
1742 Reg.isVirtual() ? VirtRegOrUnit(Reg)
1743 : VirtRegOrUnit(static_cast<MCRegUnit>(Reg.id()));
1744 auto PSetIter = MRI.getPressureSets(VRegOrUnit);
1745 unsigned Weight = PSetIter.getWeight();
1746 for (; PSetIter.isValid(); ++PSetIter)
1747 Pressure[*PSetIter] += Weight;
1748 }
1749
1750 void decreaseRegisterPressure(std::vector<unsigned> &Pressure,
1751 Register Reg) const {
1752 auto PSetIter = MRI.getPressureSets(VirtRegOrUnit(Reg));
1753 unsigned Weight = PSetIter.getWeight();
1754 for (; PSetIter.isValid(); ++PSetIter) {
1755 auto &P = Pressure[*PSetIter];
1756 assert(P >= Weight &&
1757 "register pressure must be greater than or equal weight");
1758 P -= Weight;
1759 }
1760 }
1761
1762 // Return true if Reg is reserved one, for example, stack pointer
1763 bool isReservedRegister(Register Reg) const {
1764 return Reg.isPhysical() && MRI.isReserved(Reg.asMCReg());
1765 }
1766
1767 bool isDefinedInThisLoop(Register Reg) const {
1768 return Reg.isVirtual() && MRI.getDefBlock(Reg) == OrigMBB;
1769 }
1770
1771 // Search for live-in variables. They are factored into the register pressure
1772 // from the begining. Live-in variables used by every iteration should be
1773 // considered as alive throughout the loop. For example, the variable `c` in
1774 // following code. \code
1775 // int c = ...;
1776 // for (int i = 0; i < n; i++)
1777 // a[i] += b[i] + c;
1778 // \endcode
1779 void computeLiveIn() {
1780 DenseSet<Register> Used;
1781 for (auto &MI : *OrigMBB) {
1782 if (MI.isDebugInstr())
1783 continue;
1784 for (auto &Use : ROMap[&MI].Uses) {
1785 // FIXME: The static_cast is a bug.
1786 Register Reg =
1787 Use.VRegOrUnit.isVirtualReg()
1788 ? Use.VRegOrUnit.asVirtualReg()
1789 : Register(static_cast<unsigned>(Use.VRegOrUnit.asMCRegUnit()));
1790 // Ignore the variable that appears only on one side of phi instruction
1791 // because it's used only at the first iteration.
1792 if (MI.isPHI() && Reg != getLoopPhiReg(MI, OrigMBB))
1793 continue;
1794 if (isReservedRegister(Reg))
1795 continue;
1796 if (isDefinedInThisLoop(Reg))
1797 continue;
1798 Used.insert(Reg);
1799 }
1800 }
1801
1802 for (auto LiveIn : Used)
1803 increaseRegisterPressure(InitSetPressure, LiveIn);
1804 }
1805
1806 // Calculate the upper limit of each pressure set
1807 void computePressureSetLimit(const RegisterClassInfo &RCI) {
1808 for (unsigned PSet = 0; PSet < PSetNum; PSet++)
1809 PressureSetLimit[PSet] = RCI.getRegPressureSetLimit(PSet);
1810 }
1811
1812 // There are two patterns of last-use.
1813 // - by an instruction of the current iteration
1814 // - by a phi instruction of the next iteration (loop carried value)
1815 //
1816 // Furthermore, following two groups of instructions are executed
1817 // simultaneously
1818 // - next iteration's phi instructions in i-th stage
1819 // - current iteration's instructions in i+1-th stage
1820 //
1821 // This function calculates the last-use of each register while taking into
1822 // account the above two patterns.
1823 Instr2LastUsesTy computeLastUses(const OrderedInstsTy &OrderedInsts,
1824 Instr2StageTy &Stages) const {
1825 // We treat virtual registers that are defined and used in this loop.
1826 // Following virtual register will be ignored
1827 // - live-in one
1828 // - defined but not used in the loop (potentially live-out)
1829 DenseSet<Register> TargetRegs;
1830 const auto UpdateTargetRegs = [this, &TargetRegs](Register Reg) {
1831 if (isDefinedInThisLoop(Reg))
1832 TargetRegs.insert(Reg);
1833 };
1834 for (MachineInstr *MI : OrderedInsts) {
1835 if (MI->isPHI()) {
1836 Register Reg = getLoopPhiReg(*MI, OrigMBB);
1837 UpdateTargetRegs(Reg);
1838 } else {
1839 for (auto &Use : ROMap.find(MI)->getSecond().Uses) {
1840 // FIXME: The static_cast is a bug.
1841 Register Reg = Use.VRegOrUnit.isVirtualReg()
1842 ? Use.VRegOrUnit.asVirtualReg()
1843 : Register(static_cast<unsigned>(
1844 Use.VRegOrUnit.asMCRegUnit()));
1845 UpdateTargetRegs(Reg);
1846 }
1847 }
1848 }
1849
1850 const auto InstrScore = [&Stages](MachineInstr *MI) {
1851 return Stages[MI] + MI->isPHI();
1852 };
1853
1854 DenseMap<Register, MachineInstr *> LastUseMI;
1855 for (MachineInstr *MI : llvm::reverse(OrderedInsts)) {
1856 for (auto &Use : ROMap.find(MI)->getSecond().Uses) {
1857 // FIXME: The static_cast is a bug.
1858 Register Reg =
1859 Use.VRegOrUnit.isVirtualReg()
1860 ? Use.VRegOrUnit.asVirtualReg()
1861 : Register(static_cast<unsigned>(Use.VRegOrUnit.asMCRegUnit()));
1862 if (!TargetRegs.contains(Reg))
1863 continue;
1864 auto [Ite, Inserted] = LastUseMI.try_emplace(Reg, MI);
1865 if (!Inserted) {
1866 MachineInstr *Orig = Ite->second;
1867 MachineInstr *New = MI;
1868 if (InstrScore(Orig) < InstrScore(New))
1869 Ite->second = New;
1870 }
1871 }
1872 }
1873
1874 Instr2LastUsesTy LastUses;
1875 for (auto [Reg, MI] : LastUseMI)
1876 LastUses[MI].insert(Reg);
1877 return LastUses;
1878 }
1879
1880 // Compute the maximum register pressure of the kernel. We'll simulate #Stage
1881 // iterations and check the register pressure at the point where all stages
1882 // overlapping.
1883 //
1884 // An example of unrolled loop where #Stage is 4..
1885 // Iter i+0 i+1 i+2 i+3
1886 // ------------------------
1887 // Stage 0
1888 // Stage 1 0
1889 // Stage 2 1 0
1890 // Stage 3 2 1 0 <- All stages overlap
1891 //
1892 std::vector<unsigned>
1893 computeMaxSetPressure(const OrderedInstsTy &OrderedInsts,
1894 Instr2StageTy &Stages,
1895 const unsigned StageCount) const {
1896 using RegSetTy = SmallDenseSet<Register, 16>;
1897
1898 // Indexed by #Iter. To treat "local" variables of each stage separately, we
1899 // manage the liveness of the registers independently by iterations.
1900 SmallVector<RegSetTy> LiveRegSets(StageCount);
1901
1902 auto CurSetPressure = InitSetPressure;
1903 auto MaxSetPressure = InitSetPressure;
1904 auto LastUses = computeLastUses(OrderedInsts, Stages);
1905
1906 LLVM_DEBUG({
1907 dbgs() << "Ordered instructions:\n";
1908 for (MachineInstr *MI : OrderedInsts) {
1909 dbgs() << "Stage " << Stages[MI] << ": ";
1910 MI->dump();
1911 }
1912 });
1913
1914 const auto InsertReg = [this, &CurSetPressure](RegSetTy &RegSet,
1915 VirtRegOrUnit VRegOrUnit) {
1916 // FIXME: The static_cast is a bug.
1917 Register Reg =
1918 VRegOrUnit.isVirtualReg()
1919 ? VRegOrUnit.asVirtualReg()
1920 : Register(static_cast<unsigned>(VRegOrUnit.asMCRegUnit()));
1921 if (!Reg.isValid() || isReservedRegister(Reg))
1922 return;
1923
1924 bool Inserted = RegSet.insert(Reg).second;
1925 if (!Inserted)
1926 return;
1927
1928 LLVM_DEBUG(dbgs() << "insert " << printReg(Reg, TRI, 0, &MRI) << "\n");
1929 increaseRegisterPressure(CurSetPressure, Reg);
1930 LLVM_DEBUG(dumpPSet(Reg));
1931 };
1932
1933 const auto EraseReg = [this, &CurSetPressure](RegSetTy &RegSet,
1934 Register Reg) {
1935 if (!Reg.isValid() || isReservedRegister(Reg))
1936 return;
1937
1938 // live-in register
1939 if (!RegSet.contains(Reg))
1940 return;
1941
1942 LLVM_DEBUG(dbgs() << "erase " << printReg(Reg, TRI, 0, &MRI) << "\n");
1943 RegSet.erase(Reg);
1944 decreaseRegisterPressure(CurSetPressure, Reg);
1945 LLVM_DEBUG(dumpPSet(Reg));
1946 };
1947
1948 for (unsigned I = 0; I < StageCount; I++) {
1949 for (MachineInstr *MI : OrderedInsts) {
1950 const auto Stage = Stages[MI];
1951 if (I < Stage)
1952 continue;
1953
1954 const unsigned Iter = I - Stage;
1955
1956 for (auto &Def : ROMap.find(MI)->getSecond().Defs)
1957 InsertReg(LiveRegSets[Iter], Def.VRegOrUnit);
1958
1959 for (auto LastUse : LastUses[MI]) {
1960 if (MI->isPHI()) {
1961 if (Iter != 0)
1962 EraseReg(LiveRegSets[Iter - 1], LastUse);
1963 } else {
1964 EraseReg(LiveRegSets[Iter], LastUse);
1965 }
1966 }
1967
1968 for (unsigned PSet = 0; PSet < PSetNum; PSet++)
1969 MaxSetPressure[PSet] =
1970 std::max(MaxSetPressure[PSet], CurSetPressure[PSet]);
1971
1972 LLVM_DEBUG({
1973 dbgs() << "CurSetPressure=";
1974 dumpRegisterPressures(CurSetPressure);
1975 dbgs() << " iter=" << Iter << " stage=" << Stage << ":";
1976 MI->dump();
1977 });
1978 }
1979 }
1980
1981 return MaxSetPressure;
1982 }
1983
1984public:
1985 HighRegisterPressureDetector(MachineBasicBlock *OrigMBB,
1986 const MachineFunction &MF)
1987 : OrigMBB(OrigMBB), MRI(MF.getRegInfo()),
1988 TRI(MF.getSubtarget().getRegisterInfo()),
1989 PSetNum(TRI->getNumRegPressureSets()), InitSetPressure(PSetNum, 0),
1990 PressureSetLimit(PSetNum, 0) {}
1991
1992 // Used to calculate register pressure, which is independent of loop
1993 // scheduling.
1994 void init(const RegisterClassInfo &RCI) {
1995 for (MachineInstr &MI : *OrigMBB) {
1996 if (MI.isDebugInstr())
1997 continue;
1998 ROMap[&MI].collect(MI, *TRI, MRI, false, true);
1999 }
2000
2001 computeLiveIn();
2002 computePressureSetLimit(RCI);
2003 }
2004
2005 // Calculate the maximum register pressures of the loop and check if they
2006 // exceed the limit
2007 bool detect(const SwingSchedulerDAG *SSD, SMSchedule &Schedule,
2008 const unsigned MaxStage) const {
2010 "the percentage of the margin must be between 0 to 100");
2011
2012 OrderedInstsTy OrderedInsts;
2013 Instr2StageTy Stages;
2014 computeScheduledInsts(SSD, Schedule, OrderedInsts, Stages);
2015 const auto MaxSetPressure =
2016 computeMaxSetPressure(OrderedInsts, Stages, MaxStage + 1);
2017
2018 LLVM_DEBUG({
2019 dbgs() << "Dump MaxSetPressure:\n";
2020 for (unsigned I = 0; I < MaxSetPressure.size(); I++) {
2021 dbgs() << format("MaxSetPressure[%d]=%d\n", I, MaxSetPressure[I]);
2022 }
2023 dbgs() << '\n';
2024 });
2025
2026 for (unsigned PSet = 0; PSet < PSetNum; PSet++) {
2027 unsigned Limit = PressureSetLimit[PSet];
2028 unsigned Margin = Limit * RegPressureMargin / 100;
2029 LLVM_DEBUG(dbgs() << "PSet=" << PSet << " Limit=" << Limit
2030 << " Margin=" << Margin << "\n");
2031 if (Limit < MaxSetPressure[PSet] + Margin) {
2032 LLVM_DEBUG(
2033 dbgs()
2034 << "Rejected the schedule because of too high register pressure\n");
2035 return true;
2036 }
2037 }
2038 return false;
2039 }
2040};
2041
2042} // end anonymous namespace
2043
2044/// Calculate the resource constrained minimum initiation interval for the
2045/// specified loop. We use the DFA to model the resources needed for
2046/// each instruction, and we ignore dependences. A different DFA is created
2047/// for each cycle that is required. When adding a new instruction, we attempt
2048/// to add it to each existing DFA, until a legal space is found. If the
2049/// instruction cannot be reserved in an existing DFA, we create a new one.
2050unsigned SwingSchedulerDAG::calculateResMII() {
2051 LLVM_DEBUG(dbgs() << "calculateResMII:\n");
2052 ResourceManager RM(&MF.getSubtarget(), this);
2053 return RM.calculateResMII();
2054}
2055
2056/// Calculate the recurrence-constrainted minimum initiation interval.
2057/// Iterate over each circuit. Compute the delay(c) and distance(c)
2058/// for each circuit. The II needs to satisfy the inequality
2059/// delay(c) - II*distance(c) <= 0. For each circuit, choose the smallest
2060/// II that satisfies the inequality, and the RecMII is the maximum
2061/// of those values.
2062unsigned SwingSchedulerDAG::calculateRecMII(NodeSetType &NodeSets) {
2063 unsigned RecMII = 0;
2064
2065 for (NodeSet &Nodes : NodeSets) {
2066 if (Nodes.empty())
2067 continue;
2068
2069 unsigned Delay = Nodes.getLatency();
2070 unsigned Distance = 1;
2071
2072 // ii = ceil(delay / distance)
2073 unsigned CurMII = (Delay + Distance - 1) / Distance;
2074 Nodes.setRecMII(CurMII);
2075 if (CurMII > RecMII)
2076 RecMII = CurMII;
2077 }
2078
2079 return RecMII;
2080}
2081
2082/// Create the adjacency structure of the nodes in the graph.
2083void SwingSchedulerDAG::Circuits::createAdjacencyStructure(
2084 SwingSchedulerDDG *DDG) {
2085 BitVector Added(SUnits.size());
2086 DenseMap<int, int> OutputDeps;
2087 for (int i = 0, e = SUnits.size(); i != e; ++i) {
2088 Added.reset();
2089 // Add any successor to the adjacency matrix and exclude duplicates.
2090 for (auto &OE : DDG->getOutEdges(&SUnits[i])) {
2091 // Only create a back-edge on the first and last nodes of a dependence
2092 // chain. This records any chains and adds them later.
2093 if (OE.isOutputDep()) {
2094 int N = OE.getDst()->NodeNum;
2095 int BackEdge = i;
2096 auto Dep = OutputDeps.find(BackEdge);
2097 if (Dep != OutputDeps.end()) {
2098 BackEdge = Dep->second;
2099 OutputDeps.erase(Dep);
2100 }
2101 OutputDeps[N] = BackEdge;
2102 }
2103 // Do not process a boundary node, an artificial node.
2104 if (OE.getDst()->isBoundaryNode() || OE.isArtificial())
2105 continue;
2106
2107 // This code is retained o preserve previous behavior and prevent
2108 // regression. This condition means that anti-dependnecies within an
2109 // iteration are ignored when searching circuits. Therefore it's natural
2110 // to consider this dependence as well.
2111 // FIXME: Remove this code if it doesn't have significant impact on
2112 // performance.
2113 if (OE.isAntiDep())
2114 continue;
2115
2116 int N = OE.getDst()->NodeNum;
2117 if (!Added.test(N)) {
2118 AdjK[i].push_back(N);
2119 Added.set(N);
2120 }
2121 }
2122
2123 // Also add any extra out edges to the adjacency matrix.
2124 for (const SUnit *Dst : DDG->getExtraOutEdges(&SUnits[i])) {
2125 int N = Dst->NodeNum;
2126 if (!Added.test(N)) {
2127 AdjK[i].push_back(N);
2128 Added.set(N);
2129 }
2130 }
2131 }
2132
2133 // Add back-edges in the adjacency matrix for the output dependences.
2134 for (auto &OD : OutputDeps)
2135 if (!Added.test(OD.second)) {
2136 AdjK[OD.first].push_back(OD.second);
2137 Added.set(OD.second);
2138 }
2139}
2140
2141/// Identify an elementary circuit in the dependence graph starting at the
2142/// specified node.
2143bool SwingSchedulerDAG::Circuits::circuit(int V, int S, NodeSetType &NodeSets,
2144 const SwingSchedulerDAG *DAG,
2145 bool HasBackedge) {
2146 SUnit *SV = &SUnits[V];
2147 bool F = false;
2148 Stack.insert(SV);
2149 Blocked.set(V);
2150
2151 for (auto W : AdjK[V]) {
2152 if (NumPaths > MaxPaths)
2153 break;
2154 if (W < S)
2155 continue;
2156 if (W == S) {
2157 if (!HasBackedge)
2158 NodeSets.push_back(NodeSet(Stack.begin(), Stack.end(), DAG));
2159 F = true;
2160 ++NumPaths;
2161 break;
2162 }
2163 if (!Blocked.test(W)) {
2164 if (circuit(W, S, NodeSets, DAG,
2165 Node2Idx->at(W) < Node2Idx->at(V) ? true : HasBackedge))
2166 F = true;
2167 }
2168 }
2169
2170 if (F)
2171 unblock(V);
2172 else {
2173 for (auto W : AdjK[V]) {
2174 if (W < S)
2175 continue;
2176 B[W].insert(SV);
2177 }
2178 }
2179 Stack.pop_back();
2180 return F;
2181}
2182
2183/// Unblock a node in the circuit finding algorithm.
2184void SwingSchedulerDAG::Circuits::unblock(int U) {
2185 Blocked.reset(U);
2186 SmallPtrSet<SUnit *, 4> &BU = B[U];
2187 while (!BU.empty()) {
2188 SmallPtrSet<SUnit *, 4>::iterator SI = BU.begin();
2189 assert(SI != BU.end() && "Invalid B set.");
2190 SUnit *W = *SI;
2191 BU.erase(W);
2192 if (Blocked.test(W->NodeNum))
2193 unblock(W->NodeNum);
2194 }
2195}
2196
2197/// Identify all the elementary circuits in the dependence graph using
2198/// Johnson's circuit algorithm.
2199void SwingSchedulerDAG::findCircuits(NodeSetType &NodeSets) {
2200 Circuits Cir(SUnits, Topo);
2201 // Create the adjacency structure.
2202 Cir.createAdjacencyStructure(&*DDG);
2203 for (int I = 0, E = SUnits.size(); I != E; ++I) {
2204 Cir.reset();
2205 Cir.circuit(I, I, NodeSets, this);
2206 }
2207}
2208
2209// Create artificial dependencies between the source of COPY/REG_SEQUENCE that
2210// is loop-carried to the USE in next iteration. This will help pipeliner avoid
2211// additional copies that are needed across iterations. An artificial dependence
2212// edge is added from USE to SOURCE of COPY/REG_SEQUENCE.
2213
2214// PHI-------Anti-Dep-----> COPY/REG_SEQUENCE (loop-carried)
2215// SRCOfCopY------True-Dep---> COPY/REG_SEQUENCE
2216// PHI-------True-Dep------> USEOfPhi
2217
2218// The mutation creates
2219// USEOfPHI -------Artificial-Dep---> SRCOfCopy
2220
2221// This overall will ensure, the USEOfPHI is scheduled before SRCOfCopy
2222// (since USE is a predecessor), implies, the COPY/ REG_SEQUENCE is scheduled
2223// late to avoid additional copies across iterations. The possible scheduling
2224// order would be
2225// USEOfPHI --- SRCOfCopy--- COPY/REG_SEQUENCE.
2226
2227void SwingSchedulerDAG::CopyToPhiMutation::apply(ScheduleDAGInstrs *DAG) {
2228 for (SUnit &SU : DAG->SUnits) {
2229 // Find the COPY/REG_SEQUENCE instruction.
2230 if (!SU.getInstr()->isCopy() && !SU.getInstr()->isRegSequence())
2231 continue;
2232
2233 // Record the loop carried PHIs.
2235 // Record the SrcSUs that feed the COPY/REG_SEQUENCE instructions.
2237
2238 for (auto &Dep : SU.Preds) {
2239 SUnit *TmpSU = Dep.getSUnit();
2240 MachineInstr *TmpMI = TmpSU->getInstr();
2241 SDep::Kind DepKind = Dep.getKind();
2242 // Save the loop carried PHI.
2243 if (DepKind == SDep::Anti && TmpMI->isPHI())
2244 PHISUs.push_back(TmpSU);
2245 // Save the source of COPY/REG_SEQUENCE.
2246 // If the source has no pre-decessors, we will end up creating cycles.
2247 else if (DepKind == SDep::Data && !TmpMI->isPHI() && TmpSU->NumPreds > 0)
2248 SrcSUs.push_back(TmpSU);
2249 }
2250
2251 if (PHISUs.size() == 0 || SrcSUs.size() == 0)
2252 continue;
2253
2254 // Find the USEs of PHI. If the use is a PHI or REG_SEQUENCE, push back this
2255 // SUnit to the container.
2257 // Do not use iterator based loop here as we are updating the container.
2258 for (size_t Index = 0; Index < PHISUs.size(); ++Index) {
2259 for (auto &Dep : PHISUs[Index]->Succs) {
2260 if (Dep.getKind() != SDep::Data)
2261 continue;
2262
2263 SUnit *TmpSU = Dep.getSUnit();
2264 MachineInstr *TmpMI = TmpSU->getInstr();
2265 if (TmpMI->isPHI() || TmpMI->isRegSequence()) {
2266 PHISUs.push_back(TmpSU);
2267 continue;
2268 }
2269 UseSUs.push_back(TmpSU);
2270 }
2271 }
2272
2273 if (UseSUs.size() == 0)
2274 continue;
2275
2276 SwingSchedulerDAG *SDAG = cast<SwingSchedulerDAG>(DAG);
2277 // Add the artificial dependencies if it does not form a cycle.
2278 for (auto *I : UseSUs) {
2279 for (auto *Src : SrcSUs) {
2280 if (!SDAG->Topo.IsReachable(I, Src) && Src != I) {
2281 Src->addPred(SDep(I, SDep::Artificial));
2282 SDAG->Topo.AddPred(Src, I);
2283 }
2284 }
2285 }
2286 }
2287}
2288
2289/// Compute several functions need to order the nodes for scheduling.
2290/// ASAP - Earliest time to schedule a node.
2291/// ALAP - Latest time to schedule a node.
2292/// MOV - Mobility function, difference between ALAP and ASAP.
2293/// D - Depth of each node.
2294/// H - Height of each node.
2295void SwingSchedulerDAG::computeNodeFunctions(NodeSetType &NodeSets) {
2296 ScheduleInfo.resize(SUnits.size());
2297
2298 LLVM_DEBUG({
2299 for (int I : Topo) {
2300 const SUnit &SU = SUnits[I];
2301 dumpNode(SU);
2302 }
2303 });
2304
2305 int maxASAP = 0;
2306 // Compute ASAP and ZeroLatencyDepth.
2307 for (int I : Topo) {
2308 int asap = 0;
2309 int zeroLatencyDepth = 0;
2310 SUnit *SU = &SUnits[I];
2311 for (const auto &IE : DDG->getInEdges(SU)) {
2312 SUnit *Pred = IE.getSrc();
2313 if (IE.getLatency() == 0)
2314 zeroLatencyDepth =
2315 std::max(zeroLatencyDepth, getZeroLatencyDepth(Pred) + 1);
2316 if (IE.ignoreDependence(true))
2317 continue;
2318 asap = std::max(asap, (int)(getASAP(Pred) + IE.getLatency() -
2319 IE.getDistance() * MII));
2320 }
2321 maxASAP = std::max(maxASAP, asap);
2322 ScheduleInfo[I].ASAP = asap;
2323 ScheduleInfo[I].ZeroLatencyDepth = zeroLatencyDepth;
2324 }
2325
2326 // Compute ALAP, ZeroLatencyHeight, and MOV.
2327 for (int I : llvm::reverse(Topo)) {
2328 int alap = maxASAP;
2329 int zeroLatencyHeight = 0;
2330 SUnit *SU = &SUnits[I];
2331 for (const auto &OE : DDG->getOutEdges(SU)) {
2332 SUnit *Succ = OE.getDst();
2333 if (Succ->isBoundaryNode())
2334 continue;
2335 if (OE.getLatency() == 0)
2336 zeroLatencyHeight =
2337 std::max(zeroLatencyHeight, getZeroLatencyHeight(Succ) + 1);
2338 if (OE.ignoreDependence(true))
2339 continue;
2340 alap = std::min(alap, (int)(getALAP(Succ) - OE.getLatency() +
2341 OE.getDistance() * MII));
2342 }
2343
2344 ScheduleInfo[I].ALAP = alap;
2345 ScheduleInfo[I].ZeroLatencyHeight = zeroLatencyHeight;
2346 }
2347
2348 // After computing the node functions, compute the summary for each node set.
2349 for (NodeSet &I : NodeSets)
2350 I.computeNodeSetInfo(this);
2351
2352 LLVM_DEBUG({
2353 for (unsigned i = 0; i < SUnits.size(); i++) {
2354 dbgs() << "\tNode " << i << ":\n";
2355 dbgs() << "\t ASAP = " << getASAP(&SUnits[i]) << "\n";
2356 dbgs() << "\t ALAP = " << getALAP(&SUnits[i]) << "\n";
2357 dbgs() << "\t MOV = " << getMOV(&SUnits[i]) << "\n";
2358 dbgs() << "\t D = " << getDepth(&SUnits[i]) << "\n";
2359 dbgs() << "\t H = " << getHeight(&SUnits[i]) << "\n";
2360 dbgs() << "\t ZLD = " << getZeroLatencyDepth(&SUnits[i]) << "\n";
2361 dbgs() << "\t ZLH = " << getZeroLatencyHeight(&SUnits[i]) << "\n";
2362 }
2363 });
2364}
2365
2366/// Compute the Pred_L(O) set, as defined in the paper. The set is defined
2367/// as the predecessors of the elements of NodeOrder that are not also in
2368/// NodeOrder.
2371 const NodeSet *S = nullptr) {
2372 Preds.clear();
2373
2374 for (SUnit *SU : NodeOrder) {
2375 for (const auto &IE : DDG->getInEdges(SU)) {
2376 SUnit *PredSU = IE.getSrc();
2377 if (S && S->count(PredSU) == 0)
2378 continue;
2379 if (IE.ignoreDependence(true))
2380 continue;
2381 if (NodeOrder.count(PredSU) == 0)
2382 Preds.insert(PredSU);
2383 }
2384
2385 // FIXME: The following loop-carried dependencies may also need to be
2386 // considered.
2387 // - Physical register dependencies (true-dependence and WAW).
2388 // - Memory dependencies.
2389 for (const auto &OE : DDG->getOutEdges(SU)) {
2390 SUnit *SuccSU = OE.getDst();
2391 if (!OE.isAntiDep())
2392 continue;
2393 if (S && S->count(SuccSU) == 0)
2394 continue;
2395 if (NodeOrder.count(SuccSU) == 0)
2396 Preds.insert(SuccSU);
2397 }
2398 }
2399 return !Preds.empty();
2400}
2401
2402/// Compute the Succ_L(O) set, as defined in the paper. The set is defined
2403/// as the successors of the elements of NodeOrder that are not also in
2404/// NodeOrder.
2407 const NodeSet *S = nullptr) {
2408 Succs.clear();
2409
2410 for (SUnit *SU : NodeOrder) {
2411 for (const auto &OE : DDG->getOutEdges(SU)) {
2412 SUnit *SuccSU = OE.getDst();
2413 if (S && S->count(SuccSU) == 0)
2414 continue;
2415 if (OE.ignoreDependence(false))
2416 continue;
2417 if (NodeOrder.count(SuccSU) == 0)
2418 Succs.insert(SuccSU);
2419 }
2420
2421 // FIXME: The following loop-carried dependencies may also need to be
2422 // considered.
2423 // - Physical register dependnecies (true-dependnece and WAW).
2424 // - Memory dependencies.
2425 for (const auto &IE : DDG->getInEdges(SU)) {
2426 SUnit *PredSU = IE.getSrc();
2427 if (!IE.isAntiDep())
2428 continue;
2429 if (S && S->count(PredSU) == 0)
2430 continue;
2431 if (NodeOrder.count(PredSU) == 0)
2432 Succs.insert(PredSU);
2433 }
2434 }
2435 return !Succs.empty();
2436}
2437
2438/// Return true if there is a path from the specified node to any of the nodes
2439/// in DestNodes. Keep track and return the nodes in any path.
2440static bool computePath(SUnit *Cur, SetVector<SUnit *> &Path,
2441 SetVector<SUnit *> &DestNodes,
2442 SetVector<SUnit *> &Exclude,
2443 SmallPtrSet<SUnit *, 8> &Visited,
2444 SwingSchedulerDDG *DDG) {
2445 if (Cur->isBoundaryNode())
2446 return false;
2447 if (Exclude.contains(Cur))
2448 return false;
2449 if (DestNodes.contains(Cur))
2450 return true;
2451 if (!Visited.insert(Cur).second)
2452 return Path.contains(Cur);
2453 bool FoundPath = false;
2454 for (const auto &OE : DDG->getOutEdges(Cur))
2455 if (!OE.ignoreDependence(false))
2456 FoundPath |=
2457 computePath(OE.getDst(), Path, DestNodes, Exclude, Visited, DDG);
2458 for (const auto &IE : DDG->getInEdges(Cur))
2459 if (IE.isAntiDep() && IE.getDistance() == 0)
2460 FoundPath |=
2461 computePath(IE.getSrc(), Path, DestNodes, Exclude, Visited, DDG);
2462 if (FoundPath)
2463 Path.insert(Cur);
2464 return FoundPath;
2465}
2466
2467/// Compute the live-out registers for the instructions in a node-set.
2468/// The live-out registers are those that are defined in the node-set,
2469/// but not used. Except for use operands of Phis.
2471 NodeSet &NS) {
2473 MachineRegisterInfo &MRI = MF.getRegInfo();
2476 for (SUnit *SU : NS) {
2477 const MachineInstr *MI = SU->getInstr();
2478 if (MI->isPHI())
2479 continue;
2480 for (const MachineOperand &MO : MI->all_uses()) {
2481 Register Reg = MO.getReg();
2482 if (Reg.isVirtual())
2483 Uses.insert(VirtRegOrUnit(Reg));
2484 else if (MRI.isAllocatable(Reg))
2485 for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
2486 Uses.insert(VirtRegOrUnit(Unit));
2487 }
2488 }
2489 for (SUnit *SU : NS)
2490 for (const MachineOperand &MO : SU->getInstr()->all_defs())
2491 if (!MO.isDead()) {
2492 Register Reg = MO.getReg();
2493 if (Reg.isVirtual()) {
2494 if (!Uses.count(VirtRegOrUnit(Reg)))
2495 LiveOutRegs.emplace_back(VirtRegOrUnit(Reg),
2497 } else if (MRI.isAllocatable(Reg)) {
2498 for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
2499 if (!Uses.count(VirtRegOrUnit(Unit)))
2500 LiveOutRegs.emplace_back(VirtRegOrUnit(Unit),
2502 }
2503 }
2504 RPTracker.addLiveRegs(LiveOutRegs);
2505}
2506
2507/// A heuristic to filter nodes in recurrent node-sets if the register
2508/// pressure of a set is too high.
2509void SwingSchedulerDAG::registerPressureFilter(NodeSetType &NodeSets) {
2510 for (auto &NS : NodeSets) {
2511 // Skip small node-sets since they won't cause register pressure problems.
2512 if (NS.size() <= 2)
2513 continue;
2514 IntervalPressure RecRegPressure;
2515 RegPressureTracker RecRPTracker(RecRegPressure);
2516 RecRPTracker.init(&MF, &RegClassInfo, &LIS, BB, BB->end(), false, true);
2517 computeLiveOuts(MF, RecRPTracker, NS);
2518 RecRPTracker.closeBottom();
2519
2520 std::vector<SUnit *> SUnits(NS.begin(), NS.end());
2521 llvm::sort(SUnits, [](const SUnit *A, const SUnit *B) {
2522 return A->NodeNum > B->NodeNum;
2523 });
2524
2525 for (auto &SU : SUnits) {
2526 // Since we're computing the register pressure for a subset of the
2527 // instructions in a block, we need to set the tracker for each
2528 // instruction in the node-set. The tracker is set to the instruction
2529 // just after the one we're interested in.
2531 RecRPTracker.setPos(std::next(CurInstI));
2532
2533 RegPressureDelta RPDelta;
2534 ArrayRef<PressureChange> CriticalPSets;
2535 RecRPTracker.getMaxUpwardPressureDelta(SU->getInstr(), nullptr, RPDelta,
2536 CriticalPSets,
2537 RecRegPressure.MaxSetPressure);
2538 if (RPDelta.Excess.isValid()) {
2539 LLVM_DEBUG(
2540 dbgs() << "Excess register pressure: SU(" << SU->NodeNum << ") "
2541 << TRI->getRegPressureSetName(RPDelta.Excess.getPSet())
2542 << ":" << RPDelta.Excess.getUnitInc() << "\n");
2543 NS.setExceedPressure(SU);
2544 break;
2545 }
2546 RecRPTracker.recede();
2547 }
2548 }
2549}
2550
2551/// A heuristic to colocate node sets that have the same set of
2552/// successors.
2553void SwingSchedulerDAG::colocateNodeSets(NodeSetType &NodeSets) {
2554 unsigned Colocate = 0;
2555 for (int i = 0, e = NodeSets.size(); i < e; ++i) {
2556 NodeSet &N1 = NodeSets[i];
2557 SmallSetVector<SUnit *, 8> S1;
2558 if (N1.empty() || !succ_L(N1, S1, DDG.get()))
2559 continue;
2560 for (int j = i + 1; j < e; ++j) {
2561 NodeSet &N2 = NodeSets[j];
2562 if (N1.compareRecMII(N2) != 0)
2563 continue;
2564 SmallSetVector<SUnit *, 8> S2;
2565 if (N2.empty() || !succ_L(N2, S2, DDG.get()))
2566 continue;
2567 if (llvm::set_is_subset(S1, S2) && S1.size() == S2.size()) {
2568 N1.setColocate(++Colocate);
2569 N2.setColocate(Colocate);
2570 break;
2571 }
2572 }
2573 }
2574}
2575
2576/// Check if the existing node-sets are profitable. If not, then ignore the
2577/// recurrent node-sets, and attempt to schedule all nodes together. This is
2578/// a heuristic. If the MII is large and all the recurrent node-sets are small,
2579/// then it's best to try to schedule all instructions together instead of
2580/// starting with the recurrent node-sets.
2581void SwingSchedulerDAG::checkNodeSets(NodeSetType &NodeSets) {
2582 // Look for loops with a large MII.
2583 if (MII < 17)
2584 return;
2585 // Check if the node-set contains only a simple add recurrence.
2586 for (auto &NS : NodeSets) {
2587 if (NS.getRecMII() > 2)
2588 return;
2589 if (NS.getMaxDepth() > MII)
2590 return;
2591 }
2592 NodeSets.clear();
2593 LLVM_DEBUG(dbgs() << "Clear recurrence node-sets\n");
2594}
2595
2596/// Add the nodes that do not belong to a recurrence set into groups
2597/// based upon connected components.
2598void SwingSchedulerDAG::groupRemainingNodes(NodeSetType &NodeSets) {
2599 SetVector<SUnit *> NodesAdded;
2600 SmallPtrSet<SUnit *, 8> Visited;
2601 // Add the nodes that are on a path between the previous node sets and
2602 // the current node set.
2603 for (NodeSet &I : NodeSets) {
2604 SmallSetVector<SUnit *, 8> N;
2605 // Add the nodes from the current node set to the previous node set.
2606 if (succ_L(I, N, DDG.get())) {
2607 SetVector<SUnit *> Path;
2608 for (SUnit *NI : N) {
2609 Visited.clear();
2610 computePath(NI, Path, NodesAdded, I, Visited, DDG.get());
2611 }
2612 if (!Path.empty())
2613 I.insert(Path.begin(), Path.end());
2614 }
2615 // Add the nodes from the previous node set to the current node set.
2616 N.clear();
2617 if (succ_L(NodesAdded, N, DDG.get())) {
2618 SetVector<SUnit *> Path;
2619 for (SUnit *NI : N) {
2620 Visited.clear();
2621 computePath(NI, Path, I, NodesAdded, Visited, DDG.get());
2622 }
2623 if (!Path.empty())
2624 I.insert(Path.begin(), Path.end());
2625 }
2626 NodesAdded.insert_range(I);
2627 }
2628
2629 // Create a new node set with the connected nodes of any successor of a node
2630 // in a recurrent set.
2631 NodeSet NewSet;
2632 SmallSetVector<SUnit *, 8> N;
2633 if (succ_L(NodesAdded, N, DDG.get()))
2634 for (SUnit *I : N)
2635 addConnectedNodes(I, NewSet, NodesAdded);
2636 if (!NewSet.empty())
2637 NodeSets.push_back(NewSet);
2638
2639 // Create a new node set with the connected nodes of any predecessor of a node
2640 // in a recurrent set.
2641 NewSet.clear();
2642 if (pred_L(NodesAdded, N, DDG.get()))
2643 for (SUnit *I : N)
2644 addConnectedNodes(I, NewSet, NodesAdded);
2645 if (!NewSet.empty())
2646 NodeSets.push_back(NewSet);
2647
2648 // Create new nodes sets with the connected nodes any remaining node that
2649 // has no predecessor.
2650 for (SUnit &SU : SUnits) {
2651 if (NodesAdded.count(&SU) == 0) {
2652 NewSet.clear();
2653 addConnectedNodes(&SU, NewSet, NodesAdded);
2654 if (!NewSet.empty())
2655 NodeSets.push_back(NewSet);
2656 }
2657 }
2658}
2659
2660/// Add the node to the set, and add all of its connected nodes to the set.
2661void SwingSchedulerDAG::addConnectedNodes(SUnit *SU, NodeSet &NewSet,
2662 SetVector<SUnit *> &NodesAdded) {
2663 NewSet.insert(SU);
2664 NodesAdded.insert(SU);
2665 for (auto &OE : DDG->getOutEdges(SU)) {
2666 SUnit *Successor = OE.getDst();
2667 if (!OE.isArtificial() && !Successor->isBoundaryNode() &&
2668 NodesAdded.count(Successor) == 0)
2669 addConnectedNodes(Successor, NewSet, NodesAdded);
2670 }
2671 for (auto &IE : DDG->getInEdges(SU)) {
2672 SUnit *Predecessor = IE.getSrc();
2673 if (!IE.isArtificial() && NodesAdded.count(Predecessor) == 0)
2674 addConnectedNodes(Predecessor, NewSet, NodesAdded);
2675 }
2676}
2677
2678/// Return true if Set1 contains elements in Set2. The elements in common
2679/// are returned in a different container.
2680static bool isIntersect(SmallSetVector<SUnit *, 8> &Set1, const NodeSet &Set2,
2682 Result.clear();
2683 for (SUnit *SU : Set1) {
2684 if (Set2.count(SU) != 0)
2685 Result.insert(SU);
2686 }
2687 return !Result.empty();
2688}
2689
2690/// Merge the recurrence node sets that have the same initial node.
2691void SwingSchedulerDAG::fuseRecs(NodeSetType &NodeSets) {
2692 for (NodeSetType::iterator I = NodeSets.begin(), E = NodeSets.end(); I != E;
2693 ++I) {
2694 NodeSet &NI = *I;
2695 for (NodeSetType::iterator J = I + 1; J != E;) {
2696 NodeSet &NJ = *J;
2697 if (NI.getNode(0)->NodeNum == NJ.getNode(0)->NodeNum) {
2698 if (NJ.compareRecMII(NI) > 0)
2699 NI.setRecMII(NJ.getRecMII());
2700 for (SUnit *SU : *J)
2701 I->insert(SU);
2702 NodeSets.erase(J);
2703 E = NodeSets.end();
2704 } else {
2705 ++J;
2706 }
2707 }
2708 }
2709}
2710
2711/// Remove nodes that have been scheduled in previous NodeSets.
2712void SwingSchedulerDAG::removeDuplicateNodes(NodeSetType &NodeSets) {
2713 for (NodeSetType::iterator I = NodeSets.begin(), E = NodeSets.end(); I != E;
2714 ++I)
2715 for (NodeSetType::iterator J = I + 1; J != E;) {
2716 J->remove_if([&](SUnit *SUJ) { return I->count(SUJ); });
2717
2718 if (J->empty()) {
2719 NodeSets.erase(J);
2720 E = NodeSets.end();
2721 } else {
2722 ++J;
2723 }
2724 }
2725}
2726
2727/// Compute an ordered list of the dependence graph nodes, which
2728/// indicates the order that the nodes will be scheduled. This is a
2729/// two-level algorithm. First, a partial order is created, which
2730/// consists of a list of sets ordered from highest to lowest priority.
2731void SwingSchedulerDAG::computeNodeOrder(NodeSetType &NodeSets) {
2732 SmallSetVector<SUnit *, 8> R;
2733 NodeOrder.clear();
2734
2735 for (auto &Nodes : NodeSets) {
2736 LLVM_DEBUG(dbgs() << "NodeSet size " << Nodes.size() << "\n");
2737 OrderKind Order;
2738 SmallSetVector<SUnit *, 8> N;
2739 if (pred_L(NodeOrder, N, DDG.get()) && llvm::set_is_subset(N, Nodes)) {
2740 R.insert_range(N);
2741 Order = BottomUp;
2742 LLVM_DEBUG(dbgs() << " Bottom up (preds) ");
2743 } else if (succ_L(NodeOrder, N, DDG.get()) &&
2744 llvm::set_is_subset(N, Nodes)) {
2745 R.insert_range(N);
2746 Order = TopDown;
2747 LLVM_DEBUG(dbgs() << " Top down (succs) ");
2748 } else if (isIntersect(N, Nodes, R)) {
2749 // If some of the successors are in the existing node-set, then use the
2750 // top-down ordering.
2751 Order = TopDown;
2752 LLVM_DEBUG(dbgs() << " Top down (intersect) ");
2753 } else if (NodeSets.size() == 1) {
2754 for (const auto &N : Nodes)
2755 if (N->Succs.size() == 0)
2756 R.insert(N);
2757 Order = BottomUp;
2758 LLVM_DEBUG(dbgs() << " Bottom up (all) ");
2759 } else {
2760 // Find the node with the highest ASAP.
2761 SUnit *maxASAP = nullptr;
2762 for (SUnit *SU : Nodes) {
2763 if (maxASAP == nullptr || getASAP(SU) > getASAP(maxASAP) ||
2764 (getASAP(SU) == getASAP(maxASAP) && SU->NodeNum > maxASAP->NodeNum))
2765 maxASAP = SU;
2766 }
2767 R.insert(maxASAP);
2768 Order = BottomUp;
2769 LLVM_DEBUG(dbgs() << " Bottom up (default) ");
2770 }
2771
2772 while (!R.empty()) {
2773 if (Order == TopDown) {
2774 // Choose the node with the maximum height. If more than one, choose
2775 // the node wiTH the maximum ZeroLatencyHeight. If still more than one,
2776 // choose the node with the lowest MOV.
2777 while (!R.empty()) {
2778 SUnit *maxHeight = nullptr;
2779 for (SUnit *I : R) {
2780 if (maxHeight == nullptr || getHeight(I) > getHeight(maxHeight))
2781 maxHeight = I;
2782 else if (getHeight(I) == getHeight(maxHeight) &&
2783 getZeroLatencyHeight(I) > getZeroLatencyHeight(maxHeight))
2784 maxHeight = I;
2785 else if (getHeight(I) == getHeight(maxHeight) &&
2786 getZeroLatencyHeight(I) ==
2787 getZeroLatencyHeight(maxHeight) &&
2788 getMOV(I) < getMOV(maxHeight))
2789 maxHeight = I;
2790 }
2791 NodeOrder.insert(maxHeight);
2792 LLVM_DEBUG(dbgs() << maxHeight->NodeNum << " ");
2793 R.remove(maxHeight);
2794 for (const auto &OE : DDG->getOutEdges(maxHeight)) {
2795 SUnit *SU = OE.getDst();
2796 if (Nodes.count(SU) == 0)
2797 continue;
2798 if (NodeOrder.contains(SU))
2799 continue;
2800 if (OE.ignoreDependence(false))
2801 continue;
2802 R.insert(SU);
2803 }
2804
2805 // FIXME: The following loop-carried dependencies may also need to be
2806 // considered.
2807 // - Physical register dependnecies (true-dependnece and WAW).
2808 // - Memory dependencies.
2809 for (const auto &IE : DDG->getInEdges(maxHeight)) {
2810 SUnit *SU = IE.getSrc();
2811 if (!IE.isAntiDep())
2812 continue;
2813 if (Nodes.count(SU) == 0)
2814 continue;
2815 if (NodeOrder.contains(SU))
2816 continue;
2817 R.insert(SU);
2818 }
2819 }
2820 Order = BottomUp;
2821 LLVM_DEBUG(dbgs() << "\n Switching order to bottom up ");
2822 SmallSetVector<SUnit *, 8> N;
2823 if (pred_L(NodeOrder, N, DDG.get(), &Nodes))
2824 R.insert_range(N);
2825 } else {
2826 // Choose the node with the maximum depth. If more than one, choose
2827 // the node with the maximum ZeroLatencyDepth. If still more than one,
2828 // choose the node with the lowest MOV.
2829 while (!R.empty()) {
2830 SUnit *maxDepth = nullptr;
2831 for (SUnit *I : R) {
2832 if (maxDepth == nullptr || getDepth(I) > getDepth(maxDepth))
2833 maxDepth = I;
2834 else if (getDepth(I) == getDepth(maxDepth) &&
2835 getZeroLatencyDepth(I) > getZeroLatencyDepth(maxDepth))
2836 maxDepth = I;
2837 else if (getDepth(I) == getDepth(maxDepth) &&
2838 getZeroLatencyDepth(I) == getZeroLatencyDepth(maxDepth) &&
2839 getMOV(I) < getMOV(maxDepth))
2840 maxDepth = I;
2841 }
2842 NodeOrder.insert(maxDepth);
2843 LLVM_DEBUG(dbgs() << maxDepth->NodeNum << " ");
2844 R.remove(maxDepth);
2845 if (Nodes.isExceedSU(maxDepth)) {
2846 Order = TopDown;
2847 R.clear();
2848 R.insert(Nodes.getNode(0));
2849 break;
2850 }
2851 for (const auto &IE : DDG->getInEdges(maxDepth)) {
2852 SUnit *SU = IE.getSrc();
2853 if (Nodes.count(SU) == 0)
2854 continue;
2855 if (NodeOrder.contains(SU))
2856 continue;
2857 R.insert(SU);
2858 }
2859
2860 // FIXME: The following loop-carried dependencies may also need to be
2861 // considered.
2862 // - Physical register dependnecies (true-dependnece and WAW).
2863 // - Memory dependencies.
2864 for (const auto &OE : DDG->getOutEdges(maxDepth)) {
2865 SUnit *SU = OE.getDst();
2866 if (!OE.isAntiDep())
2867 continue;
2868 if (Nodes.count(SU) == 0)
2869 continue;
2870 if (NodeOrder.contains(SU))
2871 continue;
2872 R.insert(SU);
2873 }
2874 }
2875 Order = TopDown;
2876 LLVM_DEBUG(dbgs() << "\n Switching order to top down ");
2877 SmallSetVector<SUnit *, 8> N;
2878 if (succ_L(NodeOrder, N, DDG.get(), &Nodes))
2879 R.insert_range(N);
2880 }
2881 }
2882 LLVM_DEBUG(dbgs() << "\nDone with Nodeset\n");
2883 }
2884
2885 LLVM_DEBUG({
2886 dbgs() << "Node order: ";
2887 for (SUnit *I : NodeOrder)
2888 dbgs() << " " << I->NodeNum << " ";
2889 dbgs() << "\n";
2890 });
2891}
2892
2893/// Set the policy for this loop, allowing the target to override it.
2894void SwingSchedulerDAG::initPolicy() {
2896
2897 // After subtarget overrides, apply command line options.
2899 Policy.ShouldLimitRegPressure = LimitRegPressure;
2900}
2901
2902/// Process the nodes in the computed order and create the pipelined schedule
2903/// of the instructions, if possible. Return true if a schedule is found.
2904bool SwingSchedulerDAG::schedulePipeline(SMSchedule &Schedule) {
2905
2906 if (NodeOrder.empty()){
2907 LLVM_DEBUG(dbgs() << "NodeOrder is empty! abort scheduling\n" );
2908 return false;
2909 }
2910
2911 bool scheduleFound = false;
2912 std::unique_ptr<HighRegisterPressureDetector> HRPDetector;
2913 if (Policy.ShouldLimitRegPressure) {
2914 HRPDetector =
2915 std::make_unique<HighRegisterPressureDetector>(Loop.getHeader(), MF);
2916 HRPDetector->init(RegClassInfo);
2917 }
2918 // Keep increasing II until a valid schedule is found.
2919 for (unsigned II = MII; II <= MAX_II && !scheduleFound; ++II) {
2920 Schedule.reset();
2921 Schedule.setInitiationInterval(II);
2922 LLVM_DEBUG(dbgs() << "Try to schedule with " << II << "\n");
2923
2926 do {
2927 SUnit *SU = *NI;
2928
2929 // Compute the schedule time for the instruction, which is based
2930 // upon the scheduled time for any predecessors/successors.
2931 int EarlyStart = INT_MIN;
2932 int LateStart = INT_MAX;
2933 Schedule.computeStart(SU, &EarlyStart, &LateStart, II, this);
2934 LLVM_DEBUG({
2935 dbgs() << "\n";
2936 dbgs() << "Inst (" << SU->NodeNum << ") ";
2937 SU->getInstr()->dump();
2938 dbgs() << "\n";
2939 });
2940 LLVM_DEBUG(
2941 dbgs() << format("\tes: %8x ls: %8x\n", EarlyStart, LateStart));
2942
2943 if (EarlyStart > LateStart)
2944 scheduleFound = false;
2945 else if (EarlyStart != INT_MIN && LateStart == INT_MAX)
2946 scheduleFound =
2947 Schedule.insert(SU, EarlyStart, EarlyStart + (int)II - 1, II);
2948 else if (EarlyStart == INT_MIN && LateStart != INT_MAX)
2949 scheduleFound =
2950 Schedule.insert(SU, LateStart, LateStart - (int)II + 1, II);
2951 else if (EarlyStart != INT_MIN && LateStart != INT_MAX) {
2952 LateStart = std::min(LateStart, EarlyStart + (int)II - 1);
2953 // When scheduling a Phi it is better to start at the late cycle and
2954 // go backwards. The default order may insert the Phi too far away
2955 // from its first dependence.
2956 // Also, do backward search when all scheduled predecessors are
2957 // loop-carried output/order dependencies. Empirically, there are also
2958 // cases where scheduling becomes possible with backward search.
2959 if (SU->getInstr()->isPHI() ||
2960 Schedule.onlyHasLoopCarriedOutputOrOrderPreds(SU, this->getDDG()))
2961 scheduleFound = Schedule.insert(SU, LateStart, EarlyStart, II);
2962 else
2963 scheduleFound = Schedule.insert(SU, EarlyStart, LateStart, II);
2964 } else {
2965 int FirstCycle = Schedule.getFirstCycle();
2966 scheduleFound = Schedule.insert(SU, FirstCycle + getASAP(SU),
2967 FirstCycle + getASAP(SU) + II - 1, II);
2968 }
2969
2970 // Even if we find a schedule, make sure the schedule doesn't exceed the
2971 // allowable number of stages. We keep trying if this happens.
2972 if (scheduleFound)
2973 if (SwpMaxStages > -1 &&
2974 Schedule.getMaxStageCount() > (unsigned)SwpMaxStages)
2975 scheduleFound = false;
2976
2977 LLVM_DEBUG({
2978 if (!scheduleFound)
2979 dbgs() << "\tCan't schedule\n";
2980 });
2981 } while (++NI != NE && scheduleFound);
2982
2983 // If a schedule is found, validate it against the validation-only
2984 // dependencies.
2985 if (scheduleFound)
2986 scheduleFound = DDG->isValidSchedule(Schedule);
2987
2988 // If a schedule is found, ensure non-pipelined instructions are in stage 0
2989 if (scheduleFound)
2990 scheduleFound =
2991 Schedule.normalizeNonPipelinedInstructions(this, LoopPipelinerInfo);
2992
2993 // If a schedule is found, check if it is a valid schedule too.
2994 if (scheduleFound)
2995 scheduleFound = Schedule.isValidSchedule(this);
2996
2997 // If a schedule was found and the detector is enabled, check if the
2998 // schedule might generate additional register spills/fills.
2999 if (scheduleFound && HRPDetector)
3000 scheduleFound =
3001 !HRPDetector->detect(this, Schedule, Schedule.getMaxStageCount());
3002 }
3003
3004 LLVM_DEBUG(dbgs() << "Schedule Found? " << scheduleFound
3005 << " (II=" << Schedule.getInitiationInterval()
3006 << ")\n");
3007
3008 if (scheduleFound) {
3009 scheduleFound = LoopPipelinerInfo->shouldUseSchedule(*this, Schedule);
3010 if (!scheduleFound)
3011 LLVM_DEBUG(dbgs() << "Target rejected schedule\n");
3012 }
3013
3014 if (scheduleFound) {
3015 Schedule.finalizeSchedule(this);
3016 ORE->emit([&]() {
3017 return MachineOptimizationRemarkAnalysis(
3018 DEBUG_TYPE, "schedule", Loop.getStartLoc(), Loop.getHeader())
3019 << "Schedule found with Initiation Interval: "
3020 << ore::NV("II", Schedule.getInitiationInterval())
3021 << ", MaxStageCount: "
3022 << ore::NV("MaxStageCount", Schedule.getMaxStageCount());
3023 });
3024 } else
3025 Schedule.reset();
3026
3027 return scheduleFound && Schedule.getMaxStageCount() > 0;
3028}
3029
3031 const MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
3032 Register Result;
3033 for (const MachineOperand &Use : MI.all_uses()) {
3034 Register Reg = Use.getReg();
3035 if (!Reg.isVirtual())
3036 return Register();
3037 if (MRI.getDefBlock(Reg) != MI.getParent())
3038 continue;
3039 if (Result)
3040 return Register();
3041 Result = Reg;
3042 }
3043 return Result;
3044}
3045
3046/// When Op is a value that is incremented recursively in a loop and there is a
3047/// unique instruction that increments it, returns true and sets Value.
3049 const MachineOperand &Op, int &Value) {
3050 if (!Op.isReg() || !Op.getReg().isVirtual())
3051 return false;
3052
3053 Register OrgReg = Op.getReg();
3054 Register CurReg = OrgReg;
3055 const MachineBasicBlock *LoopBB = MI.getParent();
3056 const MachineRegisterInfo &MRI = LoopBB->getParent()->getRegInfo();
3057
3058 const TargetInstrInfo *TII =
3059 LoopBB->getParent()->getSubtarget().getInstrInfo();
3060 const TargetRegisterInfo *TRI =
3061 LoopBB->getParent()->getSubtarget().getRegisterInfo();
3062
3063 MachineInstr *Phi = nullptr;
3064 MachineInstr *Increment = nullptr;
3065
3066 // Traverse definitions until it reaches Op or an instruction that does not
3067 // satisfy the condition.
3068 // Acceptable example:
3069 // bb.0:
3070 // %0 = PHI %3, %bb.0, ...
3071 // %2 = ADD %0, Value
3072 // ... = LOAD %2(Op)
3073 // %3 = COPY %2
3074 while (true) {
3075 if (!CurReg.isValid() || !CurReg.isVirtual())
3076 return false;
3077 MachineInstr *Def = MRI.getVRegDef(CurReg);
3078 if (Def->getParent() != LoopBB)
3079 return false;
3080
3081 if (Def->isCopy()) {
3082 // Ignore copy instructions unless they contain subregisters
3083 if (Def->getOperand(0).getSubReg() || Def->getOperand(1).getSubReg())
3084 return false;
3085 CurReg = Def->getOperand(1).getReg();
3086 } else if (Def->isPHI()) {
3087 // There must be just one Phi
3088 if (Phi)
3089 return false;
3090 Phi = Def;
3091 CurReg = getLoopPhiReg(*Def, LoopBB);
3092 } else if (TII->getIncrementValue(*Def, Value)) {
3093 // Potentially a unique increment
3094 if (Increment)
3095 // Multiple increments exist
3096 return false;
3097
3098 const MachineOperand *BaseOp;
3099 int64_t Offset;
3100 bool OffsetIsScalable;
3101 if (TII->getMemOperandWithOffset(*Def, BaseOp, Offset, OffsetIsScalable,
3102 TRI)) {
3103 // Pre/post increment instruction
3104 CurReg = BaseOp->getReg();
3105 } else {
3106 // If only one of the operands is defined within the loop, it is assumed
3107 // to be an incremented value.
3108 CurReg = findUniqueOperandDefinedInLoop(*Def);
3109 if (!CurReg.isValid())
3110 return false;
3111 }
3112 Increment = Def;
3113 } else {
3114 return false;
3115 }
3116 if (CurReg == OrgReg)
3117 break;
3118 }
3119
3120 if (!Phi || !Increment)
3121 return false;
3122
3123 return true;
3124}
3125
3126/// Return true if we can compute the amount the instruction changes
3127/// during each iteration. Set Delta to the amount of the change.
3128bool SwingSchedulerDAG::computeDelta(const MachineInstr &MI, int &Delta) const {
3129 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
3130 const MachineOperand *BaseOp;
3131 int64_t Offset;
3132 bool OffsetIsScalable;
3133 if (!TII->getMemOperandWithOffset(MI, BaseOp, Offset, OffsetIsScalable, TRI))
3134 return false;
3135
3136 // FIXME: This algorithm assumes instructions have fixed-size offsets.
3137 if (OffsetIsScalable)
3138 return false;
3139
3140 if (!BaseOp->isReg())
3141 return false;
3142
3143 return findLoopIncrementValue(MI, *BaseOp, Delta);
3144}
3145
3146/// Check if we can change the instruction to use an offset value from the
3147/// previous iteration. If so, return true and set the base and offset values
3148/// so that we can rewrite the load, if necessary.
3149/// v1 = Phi(v0, v3)
3150/// v2 = load v1, 0
3151/// v3 = post_store v1, 4, x
3152/// This function enables the load to be rewritten as v2 = load v3, 4.
3153bool SwingSchedulerDAG::canUseLastOffsetValue(MachineInstr *MI,
3154 unsigned &BasePos,
3155 unsigned &OffsetPos,
3156 Register &NewBase,
3157 int64_t &Offset) {
3158 // Get the load instruction.
3159 if (TII->isPostIncrement(*MI))
3160 return false;
3161 unsigned BasePosLd, OffsetPosLd;
3162 if (!TII->getBaseAndOffsetPosition(*MI, BasePosLd, OffsetPosLd))
3163 return false;
3164 Register BaseReg = MI->getOperand(BasePosLd).getReg();
3165
3166 // Look for the Phi instruction.
3167 MachineRegisterInfo &MRI = MI->getMF()->getRegInfo();
3168 MachineInstr *Phi = MRI.getVRegDef(BaseReg);
3169 if (!Phi || !Phi->isPHI())
3170 return false;
3171 // Get the register defined in the loop block.
3172 Register PrevReg = getLoopPhiReg(*Phi, MI->getParent());
3173 if (!PrevReg)
3174 return false;
3175
3176 // Check for the post-increment load/store instruction.
3177 MachineInstr *PrevDef = MRI.getVRegDef(PrevReg);
3178 if (!PrevDef || PrevDef == MI)
3179 return false;
3180
3181 if (!TII->isPostIncrement(*PrevDef))
3182 return false;
3183
3184 unsigned BasePos1 = 0, OffsetPos1 = 0;
3185 if (!TII->getBaseAndOffsetPosition(*PrevDef, BasePos1, OffsetPos1))
3186 return false;
3187
3188 // Make sure that the instructions do not access the same memory location in
3189 // the next iteration.
3190 int64_t LoadOffset = MI->getOperand(OffsetPosLd).getImm();
3191 int64_t StoreOffset = PrevDef->getOperand(OffsetPos1).getImm();
3192 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3193 NewMI->getOperand(OffsetPosLd).setImm(LoadOffset + StoreOffset);
3194 bool Disjoint = TII->areMemAccessesTriviallyDisjoint(*NewMI, *PrevDef);
3195 MF.deleteMachineInstr(NewMI);
3196 if (!Disjoint)
3197 return false;
3198
3199 // Set the return value once we determine that we return true.
3200 BasePos = BasePosLd;
3201 OffsetPos = OffsetPosLd;
3202 NewBase = PrevReg;
3203 Offset = StoreOffset;
3204 return true;
3205}
3206
3207/// Apply changes to the instruction if needed. The changes are need
3208/// to improve the scheduling and depend up on the final schedule.
3210 SMSchedule &Schedule) {
3211 SUnit *SU = getSUnit(MI);
3213 InstrChanges.find(SU);
3214 if (It != InstrChanges.end()) {
3215 std::pair<Register, int64_t> RegAndOffset = It->second;
3216 unsigned BasePos, OffsetPos;
3217 if (!TII->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos))
3218 return;
3219 Register BaseReg = MI->getOperand(BasePos).getReg();
3220 MachineInstr *LoopDef = findDefInLoop(BaseReg);
3221 int DefStageNum = Schedule.stageScheduled(getSUnit(LoopDef));
3222 int DefCycleNum = Schedule.cycleScheduled(getSUnit(LoopDef));
3223 int BaseStageNum = Schedule.stageScheduled(SU);
3224 int BaseCycleNum = Schedule.cycleScheduled(SU);
3225 if (BaseStageNum < DefStageNum) {
3226 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3227 int OffsetDiff = DefStageNum - BaseStageNum;
3228 if (DefCycleNum < BaseCycleNum) {
3229 NewMI->getOperand(BasePos).setReg(RegAndOffset.first);
3230 if (OffsetDiff > 0)
3231 --OffsetDiff;
3232 }
3233 int64_t NewOffset =
3234 MI->getOperand(OffsetPos).getImm() + RegAndOffset.second * OffsetDiff;
3235 NewMI->getOperand(OffsetPos).setImm(NewOffset);
3236 SU->setInstr(NewMI);
3237 MISUnitMap[NewMI] = SU;
3238 NewMIs[MI] = NewMI;
3239 }
3240 }
3241}
3242
3243/// Return the instruction in the loop that defines the register.
3244/// If the definition is a Phi, then follow the Phi operand to
3245/// the instruction in the loop.
3246MachineInstr *SwingSchedulerDAG::findDefInLoop(Register Reg) {
3248 MachineInstr *Def = MRI.getVRegDef(Reg);
3249 while (Def->isPHI()) {
3250 if (!Visited.insert(Def).second)
3251 break;
3252 for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2)
3253 if (Def->getOperand(i + 1).getMBB() == BB) {
3254 Def = MRI.getVRegDef(Def->getOperand(i).getReg());
3255 break;
3256 }
3257 }
3258 return Def;
3259}
3260
3261/// Return false if there is no overlap between the region accessed by BaseMI in
3262/// an iteration and the region accessed by OtherMI in subsequent iterations.
3264 const MachineInstr *BaseMI, const MachineInstr *OtherMI) const {
3265 int DeltaB, DeltaO, Delta;
3266 if (!computeDelta(*BaseMI, DeltaB) || !computeDelta(*OtherMI, DeltaO) ||
3267 DeltaB != DeltaO)
3268 return true;
3269 Delta = DeltaB;
3270
3271 const MachineOperand *BaseOpB, *BaseOpO;
3272 int64_t OffsetB, OffsetO;
3273 bool OffsetBIsScalable, OffsetOIsScalable;
3274 const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
3275 if (!TII->getMemOperandWithOffset(*BaseMI, BaseOpB, OffsetB,
3276 OffsetBIsScalable, TRI) ||
3277 !TII->getMemOperandWithOffset(*OtherMI, BaseOpO, OffsetO,
3278 OffsetOIsScalable, TRI))
3279 return true;
3280
3281 if (OffsetBIsScalable || OffsetOIsScalable)
3282 return true;
3283
3284 if (!BaseOpB->isIdenticalTo(*BaseOpO)) {
3285 // Pass cases with different base operands but same initial values.
3286 // Typically for when pre/post increment is used.
3287
3288 if (!BaseOpB->isReg() || !BaseOpO->isReg())
3289 return true;
3290 Register RegB = BaseOpB->getReg(), RegO = BaseOpO->getReg();
3291 if (!RegB.isVirtual() || !RegO.isVirtual())
3292 return true;
3293
3294 MachineInstr *DefB = MRI.getVRegDef(BaseOpB->getReg());
3295 MachineInstr *DefO = MRI.getVRegDef(BaseOpO->getReg());
3296 if (!DefB || !DefO || !DefB->isPHI() || !DefO->isPHI())
3297 return true;
3298
3299 Register InitValB;
3300 Register LoopValB;
3301 Register InitValO;
3302 Register LoopValO;
3303 getPhiRegs(*DefB, BB, InitValB, LoopValB);
3304 getPhiRegs(*DefO, BB, InitValO, LoopValO);
3305 MachineInstr *InitDefB = MRI.getVRegDef(InitValB);
3306 MachineInstr *InitDefO = MRI.getVRegDef(InitValO);
3307
3308 if (!InitDefB->isIdenticalTo(*InitDefO))
3309 return true;
3310 }
3311
3312 LocationSize AccessSizeB = (*BaseMI->memoperands_begin())->getSize();
3313 LocationSize AccessSizeO = (*OtherMI->memoperands_begin())->getSize();
3314
3315 // This is the main test, which checks the offset values and the loop
3316 // increment value to determine if the accesses may be loop carried.
3317 if (!AccessSizeB.hasValue() || !AccessSizeO.hasValue())
3318 return true;
3319
3320 LLVM_DEBUG({
3321 dbgs() << "Overlap check:\n";
3322 dbgs() << " BaseMI: ";
3323 BaseMI->dump();
3324 dbgs() << " Base + " << OffsetB << " + I * " << Delta
3325 << ", Len: " << AccessSizeB.getValue() << "\n";
3326 dbgs() << " OtherMI: ";
3327 OtherMI->dump();
3328 dbgs() << " Base + " << OffsetO << " + I * " << Delta
3329 << ", Len: " << AccessSizeO.getValue() << "\n";
3330 });
3331
3332 // Excessive overlap may be detected in strided patterns.
3333 // For example, the memory addresses of the store and the load in
3334 // for (i=0; i<n; i+=2) a[i+1] = a[i];
3335 // are assumed to overlap.
3336 if (Delta < 0) {
3337 int64_t BaseMinAddr = OffsetB;
3338 int64_t OhterNextIterMaxAddr = OffsetO + Delta + AccessSizeO.getValue() - 1;
3339 if (BaseMinAddr > OhterNextIterMaxAddr) {
3340 LLVM_DEBUG(dbgs() << " Result: No overlap\n");
3341 return false;
3342 }
3343 } else {
3344 int64_t BaseMaxAddr = OffsetB + AccessSizeB.getValue() - 1;
3345 int64_t OtherNextIterMinAddr = OffsetO + Delta;
3346 if (BaseMaxAddr < OtherNextIterMinAddr) {
3347 LLVM_DEBUG(dbgs() << " Result: No overlap\n");
3348 return false;
3349 }
3350 }
3351 LLVM_DEBUG(dbgs() << " Result: Overlap\n");
3352 return true;
3353}
3354
3355void SwingSchedulerDAG::postProcessDAG() {
3356 for (auto &M : Mutations)
3357 M->apply(this);
3358}
3359
3360/// Try to schedule the node at the specified StartCycle and continue
3361/// until the node is schedule or the EndCycle is reached. This function
3362/// returns true if the node is scheduled. This routine may search either
3363/// forward or backward for a place to insert the instruction based upon
3364/// the relative values of StartCycle and EndCycle.
3365bool SMSchedule::insert(SUnit *SU, int StartCycle, int EndCycle, int II) {
3366 bool forward = true;
3367 LLVM_DEBUG({
3368 dbgs() << "Trying to insert node between " << StartCycle << " and "
3369 << EndCycle << " II: " << II << "\n";
3370 });
3371 if (StartCycle > EndCycle)
3372 forward = false;
3373
3374 // The terminating condition depends on the direction.
3375 int termCycle = forward ? EndCycle + 1 : EndCycle - 1;
3376 for (int curCycle = StartCycle; curCycle != termCycle;
3377 forward ? ++curCycle : --curCycle) {
3378
3379 if (ST.getInstrInfo()->isZeroCost(SU->getInstr()->getOpcode()) ||
3380 ProcItinResources.canReserveResources(*SU, curCycle)) {
3381 LLVM_DEBUG({
3382 dbgs() << "\tinsert at cycle " << curCycle << " ";
3383 SU->getInstr()->dump();
3384 });
3385
3386 if (!ST.getInstrInfo()->isZeroCost(SU->getInstr()->getOpcode()))
3387 ProcItinResources.reserveResources(*SU, curCycle);
3388 ScheduledInstrs[curCycle].push_back(SU);
3389 InstrToCycle.insert(std::make_pair(SU, curCycle));
3390 if (curCycle > LastCycle)
3391 LastCycle = curCycle;
3392 if (curCycle < FirstCycle)
3393 FirstCycle = curCycle;
3394 return true;
3395 }
3396 LLVM_DEBUG({
3397 dbgs() << "\tfailed to insert at cycle " << curCycle << " ";
3398 SU->getInstr()->dump();
3399 });
3400 }
3401 return false;
3402}
3403
3404/// If an instruction has a use that spans multiple iterations, then
3405/// return true. These instructions are characterized by having a back-ege
3406/// to a Phi, which contains a reference to another Phi.
3408 for (auto &P : SU->Preds)
3409 if (P.getKind() == SDep::Anti && P.getSUnit()->getInstr()->isPHI())
3410 for (auto &S : P.getSUnit()->Succs)
3411 if (S.getKind() == SDep::Data && S.getSUnit()->getInstr()->isPHI())
3412 return P.getSUnit();
3413 return nullptr;
3414}
3415
3416/// Compute the scheduling start slot for the instruction. The start slot
3417/// depends on any predecessor or successor nodes scheduled already.
3418void SMSchedule::computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart,
3419 int II, SwingSchedulerDAG *DAG) {
3420 const SwingSchedulerDDG *DDG = DAG->getDDG();
3421
3422 // Iterate over each instruction that has been scheduled already. The start
3423 // slot computation depends on whether the previously scheduled instruction
3424 // is a predecessor or successor of the specified instruction.
3425 for (int cycle = getFirstCycle(); cycle <= LastCycle; ++cycle) {
3426 for (SUnit *I : getInstructions(cycle)) {
3427 for (const auto &IE : DDG->getInEdges(SU)) {
3428 if (IE.getSrc() == I) {
3429 int EarlyStart = cycle + IE.getLatency() - IE.getDistance() * II;
3430 *MaxEarlyStart = std::max(*MaxEarlyStart, EarlyStart);
3431 }
3432 }
3433
3434 for (const auto &OE : DDG->getOutEdges(SU)) {
3435 if (OE.getDst() == I) {
3436 int LateStart = cycle - OE.getLatency() + OE.getDistance() * II;
3437 *MinLateStart = std::min(*MinLateStart, LateStart);
3438 }
3439 }
3440
3441 SUnit *BE = multipleIterations(I, DAG);
3442 for (const auto &Dep : SU->Preds) {
3443 // For instruction that requires multiple iterations, make sure that
3444 // the dependent instruction is not scheduled past the definition.
3445 if (BE && Dep.getSUnit() == BE && !SU->getInstr()->isPHI() &&
3446 !SU->isPred(I))
3447 *MinLateStart = std::min(*MinLateStart, cycle);
3448 }
3449 }
3450 }
3451}
3452
3453/// Order the instructions within a cycle so that the definitions occur
3454/// before the uses. Returns true if the instruction is added to the start
3455/// of the list, or false if added to the end.
3457 std::deque<SUnit *> &Insts) const {
3458 MachineInstr *MI = SU->getInstr();
3459 bool OrderBeforeUse = false;
3460 bool OrderAfterDef = false;
3461 bool OrderBeforeDef = false;
3462 unsigned MoveDef = 0;
3463 unsigned MoveUse = 0;
3464 int StageInst1 = stageScheduled(SU);
3465 const SwingSchedulerDDG *DDG = SSD->getDDG();
3466
3467 unsigned Pos = 0;
3468 for (std::deque<SUnit *>::iterator I = Insts.begin(), E = Insts.end(); I != E;
3469 ++I, ++Pos) {
3470 for (MachineOperand &MO : MI->operands()) {
3471 if (!MO.isReg() || !MO.getReg().isVirtual())
3472 continue;
3473
3474 Register Reg = MO.getReg();
3475 unsigned BasePos, OffsetPos;
3476 if (ST.getInstrInfo()->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos))
3477 if (MI->getOperand(BasePos).getReg() == Reg)
3478 if (Register NewReg = SSD->getInstrBaseReg(SU))
3479 Reg = NewReg;
3480 bool Reads, Writes;
3481 std::tie(Reads, Writes) =
3482 (*I)->getInstr()->readsWritesVirtualRegister(Reg);
3483 if (MO.isDef() && Reads && stageScheduled(*I) <= StageInst1) {
3484 OrderBeforeUse = true;
3485 if (MoveUse == 0)
3486 MoveUse = Pos;
3487 } else if (MO.isDef() && Reads && stageScheduled(*I) > StageInst1) {
3488 // Add the instruction after the scheduled instruction.
3489 OrderAfterDef = true;
3490 MoveDef = Pos;
3491 } else if (MO.isUse() && Writes && stageScheduled(*I) == StageInst1) {
3492 if (cycleScheduled(*I) == cycleScheduled(SU) && !(*I)->isSucc(SU)) {
3493 OrderBeforeUse = true;
3494 if (MoveUse == 0)
3495 MoveUse = Pos;
3496 } else {
3497 OrderAfterDef = true;
3498 MoveDef = Pos;
3499 }
3500 } else if (MO.isUse() && Writes && stageScheduled(*I) > StageInst1) {
3501 OrderBeforeUse = true;
3502 if (MoveUse == 0)
3503 MoveUse = Pos;
3504 if (MoveUse != 0) {
3505 OrderAfterDef = true;
3506 MoveDef = Pos - 1;
3507 }
3508 } else if (MO.isUse() && Writes && stageScheduled(*I) < StageInst1) {
3509 // Add the instruction before the scheduled instruction.
3510 OrderBeforeUse = true;
3511 if (MoveUse == 0)
3512 MoveUse = Pos;
3513 } else if (MO.isUse() && stageScheduled(*I) == StageInst1 &&
3514 isLoopCarriedDefOfUse(SSD, (*I)->getInstr(), MO)) {
3515 if (MoveUse == 0) {
3516 OrderBeforeDef = true;
3517 MoveUse = Pos;
3518 }
3519 }
3520 }
3521 // Check for order dependences between instructions. Make sure the source
3522 // is ordered before the destination.
3523 for (auto &OE : DDG->getOutEdges(SU)) {
3524 if (OE.getDst() != *I)
3525 continue;
3526 if (OE.isOrderDep() && stageScheduled(*I) == StageInst1) {
3527 OrderBeforeUse = true;
3528 if (Pos < MoveUse)
3529 MoveUse = Pos;
3530 }
3531 // We did not handle HW dependences in previous for loop,
3532 // and we normally set Latency = 0 for Anti/Output deps,
3533 // so may have nodes in same cycle with Anti/Output dependent on HW regs.
3534 else if ((OE.isAntiDep() || OE.isOutputDep()) &&
3535 stageScheduled(*I) == StageInst1) {
3536 OrderBeforeUse = true;
3537 if ((MoveUse == 0) || (Pos < MoveUse))
3538 MoveUse = Pos;
3539 }
3540 }
3541 for (auto &IE : DDG->getInEdges(SU)) {
3542 if (IE.getSrc() != *I)
3543 continue;
3544 if ((IE.isAntiDep() || IE.isOutputDep() || IE.isOrderDep()) &&
3545 stageScheduled(*I) == StageInst1) {
3546 OrderAfterDef = true;
3547 MoveDef = Pos;
3548 }
3549 }
3550 }
3551
3552 // A circular dependence.
3553 if (OrderAfterDef && OrderBeforeUse && MoveUse == MoveDef)
3554 OrderBeforeUse = false;
3555
3556 // OrderAfterDef takes precedences over OrderBeforeDef. The latter is due
3557 // to a loop-carried dependence.
3558 if (OrderBeforeDef)
3559 OrderBeforeUse = !OrderAfterDef || (MoveUse > MoveDef);
3560
3561 // The uncommon case when the instruction order needs to be updated because
3562 // there is both a use and def.
3563 if (OrderBeforeUse && OrderAfterDef) {
3564 SUnit *UseSU = Insts.at(MoveUse);
3565 SUnit *DefSU = Insts.at(MoveDef);
3566 if (MoveUse > MoveDef) {
3567 Insts.erase(Insts.begin() + MoveUse);
3568 Insts.erase(Insts.begin() + MoveDef);
3569 } else {
3570 Insts.erase(Insts.begin() + MoveDef);
3571 Insts.erase(Insts.begin() + MoveUse);
3572 }
3573 orderDependence(SSD, UseSU, Insts);
3574 orderDependence(SSD, SU, Insts);
3575 orderDependence(SSD, DefSU, Insts);
3576 return;
3577 }
3578 // Put the new instruction first if there is a use in the list. Otherwise,
3579 // put it at the end of the list.
3580 if (OrderBeforeUse)
3581 Insts.push_front(SU);
3582 else
3583 Insts.push_back(SU);
3584}
3585
3586/// Return true if the scheduled Phi has a loop carried operand.
3588 MachineInstr &Phi) const {
3589 if (!Phi.isPHI())
3590 return false;
3591 assert(Phi.isPHI() && "Expecting a Phi.");
3592 SUnit *DefSU = SSD->getSUnit(&Phi);
3593 unsigned DefCycle = cycleScheduled(DefSU);
3594 int DefStage = stageScheduled(DefSU);
3595
3596 Register InitVal;
3597 Register LoopVal;
3598 getPhiRegs(Phi, Phi.getParent(), InitVal, LoopVal);
3599 SUnit *UseSU = SSD->getSUnit(MRI.getVRegDef(LoopVal));
3600 if (!UseSU)
3601 return true;
3602 if (UseSU->getInstr()->isPHI())
3603 return true;
3604 unsigned LoopCycle = cycleScheduled(UseSU);
3605 int LoopStage = stageScheduled(UseSU);
3606 return (LoopCycle > DefCycle) || (LoopStage <= DefStage);
3607}
3608
3609/// Return true if the instruction is a definition that is loop carried
3610/// and defines the use on the next iteration.
3611/// v1 = phi(v2, v3)
3612/// (Def) v3 = op v1
3613/// (MO) = v1
3614/// If MO appears before Def, then v1 and v3 may get assigned to the same
3615/// register.
3617 MachineInstr *Def,
3618 MachineOperand &MO) const {
3619 if (!MO.isReg())
3620 return false;
3621 if (Def->isPHI())
3622 return false;
3623 MachineInstr *Phi = MRI.getVRegDef(MO.getReg());
3624 if (!Phi || !Phi->isPHI() || Phi->getParent() != Def->getParent())
3625 return false;
3626 if (!isLoopCarried(SSD, *Phi))
3627 return false;
3628 Register LoopReg = getLoopPhiReg(*Phi, Phi->getParent());
3629 for (MachineOperand &DMO : Def->all_defs()) {
3630 if (DMO.getReg() == LoopReg)
3631 return true;
3632 }
3633 return false;
3634}
3635
3636/// Return true if all scheduled predecessors are loop-carried output/order
3637/// dependencies.
3639 SUnit *SU, const SwingSchedulerDDG *DDG) const {
3640 for (const auto &IE : DDG->getInEdges(SU))
3641 if (InstrToCycle.count(IE.getSrc()))
3642 return false;
3643 return true;
3644}
3645
3646/// Determine transitive dependences of unpipelineable instructions
3649 SmallPtrSet<SUnit *, 8> DoNotPipeline;
3650 SmallVector<SUnit *, 8> Worklist;
3651
3652 for (auto &SU : SSD->SUnits)
3653 if (SU.isInstr() && PLI->shouldIgnoreForPipelining(SU.getInstr()))
3654 Worklist.push_back(&SU);
3655
3656 const SwingSchedulerDDG *DDG = SSD->getDDG();
3657 while (!Worklist.empty()) {
3658 auto SU = Worklist.pop_back_val();
3659 if (DoNotPipeline.count(SU))
3660 continue;
3661 LLVM_DEBUG(dbgs() << "Do not pipeline SU(" << SU->NodeNum << ")\n");
3662 DoNotPipeline.insert(SU);
3663 for (const auto &IE : DDG->getInEdges(SU))
3664 Worklist.push_back(IE.getSrc());
3665
3666 // To preserve previous behavior and prevent regression
3667 // FIXME: Remove if this doesn't have significant impact on
3668 for (const auto &OE : DDG->getOutEdges(SU))
3669 if (OE.getDistance() == 1)
3670 Worklist.push_back(OE.getDst());
3671 }
3672 return DoNotPipeline;
3673}
3674
3675// Determine all instructions upon which any unpipelineable instruction depends
3676// and ensure that they are in stage 0. If unable to do so, return false.
3680
3681 int NewLastCycle = INT_MIN;
3682 for (SUnit &SU : SSD->SUnits) {
3683 if (!SU.isInstr())
3684 continue;
3685 if (!DNP.contains(&SU) || stageScheduled(&SU) == 0) {
3686 NewLastCycle = std::max(NewLastCycle, InstrToCycle[&SU]);
3687 continue;
3688 }
3689
3690 // Put the non-pipelined instruction as early as possible in the schedule
3691 int NewCycle = getFirstCycle();
3692 for (const auto &IE : SSD->getDDG()->getInEdges(&SU))
3693 if (IE.getDistance() == 0)
3694 NewCycle = std::max(InstrToCycle[IE.getSrc()], NewCycle);
3695
3696 // To preserve previous behavior and prevent regression
3697 // FIXME: Remove if this doesn't have significant impact on performance
3698 for (auto &OE : SSD->getDDG()->getOutEdges(&SU))
3699 if (OE.getDistance() == 1)
3700 NewCycle = std::max(InstrToCycle[OE.getDst()], NewCycle);
3701
3702 int OldCycle = InstrToCycle[&SU];
3703 if (OldCycle != NewCycle) {
3704 InstrToCycle[&SU] = NewCycle;
3705 auto &OldS = getInstructions(OldCycle);
3706 llvm::erase(OldS, &SU);
3707 getInstructions(NewCycle).emplace_back(&SU);
3708 LLVM_DEBUG(dbgs() << "SU(" << SU.NodeNum
3709 << ") is not pipelined; moving from cycle " << OldCycle
3710 << " to " << NewCycle << " Instr:" << *SU.getInstr());
3711 }
3712
3713 // We traverse the SUs in the order of the original basic block. Computing
3714 // NewCycle in this order normally works fine because all dependencies
3715 // (except for loop-carried dependencies) don't violate the original order.
3716 // However, an artificial dependency (e.g., added by CopyToPhiMutation) can
3717 // break it. That is, there may be exist an artificial dependency from
3718 // bottom to top. In such a case, NewCycle may become too large to be
3719 // scheduled in Stage 0. For example, assume that Inst0 is in DNP in the
3720 // following case:
3721 //
3722 // | Inst0 <-+
3723 // SU order | | artificial dep
3724 // | Inst1 --+
3725 // v
3726 //
3727 // If Inst1 is scheduled at cycle N and is not at Stage 0, then NewCycle of
3728 // Inst0 must be greater than or equal to N so that Inst0 is not be
3729 // scheduled at Stage 0. In such cases, we reject this schedule at this
3730 // time.
3731 // FIXME: The reason for this is the existence of artificial dependencies
3732 // that are contradict to the original SU order. If ignoring artificial
3733 // dependencies does not affect correctness, then it is better to ignore
3734 // them.
3735 if (FirstCycle + InitiationInterval <= NewCycle)
3736 return false;
3737
3738 NewLastCycle = std::max(NewLastCycle, NewCycle);
3739 }
3740 LastCycle = NewLastCycle;
3741 return true;
3742}
3743
3744// Check if the generated schedule is valid. This function checks if
3745// an instruction that uses a physical register is scheduled in a
3746// different stage than the definition. The pipeliner does not handle
3747// physical register values that may cross a basic block boundary.
3748// Furthermore, if a physical def/use pair is assigned to the same
3749// cycle, orderDependence does not guarantee def/use ordering, so that
3750// case should be considered invalid. (The test checks for both
3751// earlier and same-cycle use to be more robust.)
3753 for (SUnit &SU : SSD->SUnits) {
3754 if (!SU.hasPhysRegDefs)
3755 continue;
3756 int StageDef = stageScheduled(&SU);
3757 int CycleDef = InstrToCycle[&SU];
3758 assert(StageDef != -1 && "Instruction should have been scheduled.");
3759 for (auto &OE : SSD->getDDG()->getOutEdges(&SU)) {
3760 SUnit *Dst = OE.getDst();
3761 if (OE.isAssignedRegDep() && !Dst->isBoundaryNode())
3762 if (OE.getReg().isPhysical()) {
3763 if (stageScheduled(Dst) != StageDef)
3764 return false;
3765 if (InstrToCycle[Dst] <= CycleDef)
3766 return false;
3767 }
3768 }
3769 }
3770 return true;
3771}
3772
3773/// A property of the node order in swing-modulo-scheduling is
3774/// that for nodes outside circuits the following holds:
3775/// none of them is scheduled after both a successor and a
3776/// predecessor.
3777/// The method below checks whether the property is met.
3778/// If not, debug information is printed and statistics information updated.
3779/// Note that we do not use an assert statement.
3780/// The reason is that although an invalid node order may prevent
3781/// the pipeliner from finding a pipelined schedule for arbitrary II,
3782/// it does not lead to the generation of incorrect code.
3783void SwingSchedulerDAG::checkValidNodeOrder(const NodeSetType &Circuits) const {
3784
3785 // a sorted vector that maps each SUnit to its index in the NodeOrder
3786 typedef std::pair<SUnit *, unsigned> UnitIndex;
3787 std::vector<UnitIndex> Indices(NodeOrder.size(), std::make_pair(nullptr, 0));
3788
3789 for (unsigned i = 0, s = NodeOrder.size(); i < s; ++i)
3790 Indices.push_back(std::make_pair(NodeOrder[i], i));
3791
3792 auto CompareKey = [](UnitIndex i1, UnitIndex i2) {
3793 return std::get<0>(i1) < std::get<0>(i2);
3794 };
3795
3796 // sort, so that we can perform a binary search
3797 llvm::sort(Indices, CompareKey);
3798
3799 bool Valid = true;
3800 (void)Valid;
3801 // for each SUnit in the NodeOrder, check whether
3802 // it appears after both a successor and a predecessor
3803 // of the SUnit. If this is the case, and the SUnit
3804 // is not part of circuit, then the NodeOrder is not
3805 // valid.
3806 for (unsigned i = 0, s = NodeOrder.size(); i < s; ++i) {
3807 SUnit *SU = NodeOrder[i];
3808 unsigned Index = i;
3809
3810 bool PredBefore = false;
3811 bool SuccBefore = false;
3812
3813 SUnit *Succ;
3814 SUnit *Pred;
3815 (void)Succ;
3816 (void)Pred;
3817
3818 for (const auto &IE : DDG->getInEdges(SU)) {
3819 SUnit *PredSU = IE.getSrc();
3820 unsigned PredIndex = std::get<1>(
3821 *llvm::lower_bound(Indices, std::make_pair(PredSU, 0), CompareKey));
3822 if (!PredSU->getInstr()->isPHI() && PredIndex < Index) {
3823 PredBefore = true;
3824 Pred = PredSU;
3825 break;
3826 }
3827 }
3828
3829 for (const auto &OE : DDG->getOutEdges(SU)) {
3830 SUnit *SuccSU = OE.getDst();
3831 // Do not process a boundary node, it was not included in NodeOrder,
3832 // hence not in Indices either, call to std::lower_bound() below will
3833 // return Indices.end().
3834 if (SuccSU->isBoundaryNode())
3835 continue;
3836 unsigned SuccIndex = std::get<1>(
3837 *llvm::lower_bound(Indices, std::make_pair(SuccSU, 0), CompareKey));
3838 if (!SuccSU->getInstr()->isPHI() && SuccIndex < Index) {
3839 SuccBefore = true;
3840 Succ = SuccSU;
3841 break;
3842 }
3843 }
3844
3845 if (PredBefore && SuccBefore && !SU->getInstr()->isPHI()) {
3846 // instructions in circuits are allowed to be scheduled
3847 // after both a successor and predecessor.
3848 bool InCircuit = llvm::any_of(
3849 Circuits, [SU](const NodeSet &Circuit) { return Circuit.count(SU); });
3850 if (InCircuit)
3851 LLVM_DEBUG(dbgs() << "In a circuit, predecessor ");
3852 else {
3853 Valid = false;
3854 NumNodeOrderIssues++;
3855 LLVM_DEBUG(dbgs() << "Predecessor ");
3856 }
3857 LLVM_DEBUG(dbgs() << Pred->NodeNum << " and successor " << Succ->NodeNum
3858 << " are scheduled before node " << SU->NodeNum
3859 << "\n");
3860 }
3861 }
3862
3863 LLVM_DEBUG({
3864 if (!Valid)
3865 dbgs() << "Invalid node order found!\n";
3866 });
3867}
3868
3869/// Attempt to fix the degenerate cases when the instruction serialization
3870/// causes the register lifetimes to overlap. For example,
3871/// p' = store_pi(p, b)
3872/// = load p, offset
3873/// In this case p and p' overlap, which means that two registers are needed.
3874/// Instead, this function changes the load to use p' and updates the offset.
3875void SwingSchedulerDAG::fixupRegisterOverlaps(std::deque<SUnit *> &Instrs) {
3876 Register OverlapReg;
3877 Register NewBaseReg;
3878 for (SUnit *SU : Instrs) {
3879 MachineInstr *MI = SU->getInstr();
3880 for (unsigned i = 0, e = MI->getNumOperands(); i < e; ++i) {
3881 const MachineOperand &MO = MI->getOperand(i);
3882 // Look for an instruction that uses p. The instruction occurs in the
3883 // same cycle but occurs later in the serialized order.
3884 if (MO.isReg() && MO.isUse() && MO.getReg() == OverlapReg) {
3885 // Check that the instruction appears in the InstrChanges structure,
3886 // which contains instructions that can have the offset updated.
3888 InstrChanges.find(SU);
3889 if (It != InstrChanges.end()) {
3890 unsigned BasePos, OffsetPos;
3891 // Update the base register and adjust the offset.
3892 if (TII->getBaseAndOffsetPosition(*MI, BasePos, OffsetPos)) {
3893 MachineInstr *NewMI = MF.CloneMachineInstr(MI);
3894 NewMI->getOperand(BasePos).setReg(NewBaseReg);
3895 int64_t NewOffset =
3896 MI->getOperand(OffsetPos).getImm() - It->second.second;
3897 NewMI->getOperand(OffsetPos).setImm(NewOffset);
3898 SU->setInstr(NewMI);
3899 MISUnitMap[NewMI] = SU;
3900 NewMIs[MI] = NewMI;
3901 }
3902 }
3903 OverlapReg = Register();
3904 NewBaseReg = Register();
3905 break;
3906 }
3907 // Look for an instruction of the form p' = op(p), which uses and defines
3908 // two virtual registers that get allocated to the same physical register.
3909 unsigned TiedUseIdx = 0;
3910 if (MI->isRegTiedToUseOperand(i, &TiedUseIdx)) {
3911 // OverlapReg is p in the example above.
3912 OverlapReg = MI->getOperand(TiedUseIdx).getReg();
3913 // NewBaseReg is p' in the example above.
3914 NewBaseReg = MI->getOperand(i).getReg();
3915 break;
3916 }
3917 }
3918 }
3919}
3920
3921std::deque<SUnit *>
3923 const std::deque<SUnit *> &Instrs) const {
3924 std::deque<SUnit *> NewOrderPhi;
3925 for (SUnit *SU : Instrs) {
3926 if (SU->getInstr()->isPHI())
3927 NewOrderPhi.push_back(SU);
3928 }
3929 std::deque<SUnit *> NewOrderI;
3930 for (SUnit *SU : Instrs) {
3931 if (!SU->getInstr()->isPHI())
3932 orderDependence(SSD, SU, NewOrderI);
3933 }
3934 llvm::append_range(NewOrderPhi, NewOrderI);
3935 return NewOrderPhi;
3936}
3937
3938/// After the schedule has been formed, call this function to combine
3939/// the instructions from the different stages/cycles. That is, this
3940/// function creates a schedule that represents a single iteration.
3942 // Move all instructions to the first stage from later stages.
3943 for (int cycle = getFirstCycle(); cycle <= getFinalCycle(); ++cycle) {
3944 for (int stage = 1, lastStage = getMaxStageCount(); stage <= lastStage;
3945 ++stage) {
3946 std::deque<SUnit *> &cycleInstrs =
3947 ScheduledInstrs[cycle + (stage * InitiationInterval)];
3948 for (SUnit *SU : llvm::reverse(cycleInstrs))
3949 ScheduledInstrs[cycle].push_front(SU);
3950 }
3951 }
3952
3953 // Erase all the elements in the later stages. Only one iteration should
3954 // remain in the scheduled list, and it contains all the instructions.
3955 for (int cycle = getFinalCycle() + 1; cycle <= LastCycle; ++cycle)
3956 ScheduledInstrs.erase(cycle);
3957
3958 // Change the registers in instruction as specified in the InstrChanges
3959 // map. We need to use the new registers to create the correct order.
3960 for (const SUnit &SU : SSD->SUnits)
3961 SSD->applyInstrChange(SU.getInstr(), *this);
3962
3963 // Reorder the instructions in each cycle to fix and improve the
3964 // generated code.
3965 for (int Cycle = getFirstCycle(), E = getFinalCycle(); Cycle <= E; ++Cycle) {
3966 std::deque<SUnit *> &cycleInstrs = ScheduledInstrs[Cycle];
3967 cycleInstrs = reorderInstructions(SSD, cycleInstrs);
3968 SSD->fixupRegisterOverlaps(cycleInstrs);
3969 }
3970
3971 LLVM_DEBUG(dump(););
3972}
3973
3975 os << "Num nodes " << size() << " rec " << RecMII << " mov " << MaxMOV
3976 << " depth " << MaxDepth << " col " << Colocate << "\n";
3977 for (const auto &I : Nodes)
3978 os << " SU(" << I->NodeNum << ") " << *(I->getInstr());
3979 os << "\n";
3980}
3981
3982#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3983/// Print the schedule information to the given output.
3985 // Iterate over each cycle.
3986 for (int cycle = getFirstCycle(); cycle <= getFinalCycle(); ++cycle) {
3987 // Iterate over each instruction in the cycle.
3988 const_sched_iterator cycleInstrs = ScheduledInstrs.find(cycle);
3989 for (SUnit *CI : cycleInstrs->second) {
3990 os << "cycle " << cycle << " (" << stageScheduled(CI) << ") ";
3991 os << "(" << CI->NodeNum << ") ";
3992 CI->getInstr()->print(os);
3993 os << "\n";
3994 }
3995 }
3996}
3997
3998/// Utility function used for debugging to print the schedule.
4001
4002void ResourceManager::dumpMRT() const {
4003 LLVM_DEBUG({
4004 if (UseDFA)
4005 return;
4006 std::stringstream SS;
4007 SS << "MRT:\n";
4008 SS << std::setw(4) << "Slot";
4009 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I)
4010 SS << std::setw(3) << I;
4011 SS << std::setw(7) << "#Mops"
4012 << "\n";
4013 for (int Slot = 0; Slot < InitiationInterval; ++Slot) {
4014 SS << std::setw(4) << Slot;
4015 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I)
4016 SS << std::setw(3) << MRT[Slot][I];
4017 SS << std::setw(7) << NumScheduledMops[Slot] << "\n";
4018 }
4019 dbgs() << SS.str();
4020 });
4021}
4022#endif
4023
4025 const MCSchedModel &SM, SmallVectorImpl<uint64_t> &Masks) {
4026 unsigned ProcResourceID = 0;
4027
4028 // We currently limit the resource kinds to 64 and below so that we can use
4029 // uint64_t for Masks
4030 assert(SM.getNumProcResourceKinds() < 64 &&
4031 "Too many kinds of resources, unsupported");
4032 // Create a unique bitmask for every processor resource unit.
4033 // Skip resource at index 0, since it always references 'InvalidUnit'.
4034 Masks.resize(SM.getNumProcResourceKinds());
4035 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4036 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
4037 if (Desc.SubUnitsIdxBegin)
4038 continue;
4039 Masks[I] = 1ULL << ProcResourceID;
4040 ProcResourceID++;
4041 }
4042 // Create a unique bitmask for every processor resource group.
4043 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4044 const MCProcResourceDesc &Desc = *SM.getProcResource(I);
4045 if (!Desc.SubUnitsIdxBegin)
4046 continue;
4047 Masks[I] = 1ULL << ProcResourceID;
4048 for (unsigned U = 0; U < Desc.NumUnits; ++U)
4049 Masks[I] |= Masks[Desc.SubUnitsIdxBegin[U]];
4050 ProcResourceID++;
4051 }
4052 LLVM_DEBUG({
4053 if (SwpShowResMask) {
4054 dbgs() << "ProcResourceDesc:\n";
4055 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4056 const MCProcResourceDesc *ProcResource = SM.getProcResource(I);
4057 dbgs() << format(" %16s(%2d): Mask: 0x%08x, NumUnits:%2d\n",
4058 ProcResource->Name, I, Masks[I],
4059 ProcResource->NumUnits);
4060 }
4061 dbgs() << " -----------------\n";
4062 }
4063 });
4064}
4065
4067 LLVM_DEBUG({
4068 if (SwpDebugResource)
4069 dbgs() << "canReserveResources:\n";
4070 });
4071 if (UseDFA)
4072 return DFAResources[positiveModulo(Cycle, InitiationInterval)]
4073 ->canReserveResources(&SU.getInstr()->getDesc());
4074
4075 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
4076 if (!SCDesc->isValid()) {
4077 LLVM_DEBUG({
4078 dbgs() << "No valid Schedule Class Desc for schedClass!\n";
4079 dbgs() << "isPseudo:" << SU.getInstr()->isPseudo() << "\n";
4080 });
4081 return true;
4082 }
4083
4084 reserveResources(SCDesc, Cycle);
4085 bool Result = !isOverbooked();
4086 unreserveResources(SCDesc, Cycle);
4087
4088 LLVM_DEBUG(if (SwpDebugResource) dbgs() << "return " << Result << "\n\n");
4089 return Result;
4090}
4091
4092void ResourceManager::reserveResources(SUnit &SU, int Cycle) {
4093 LLVM_DEBUG({
4094 if (SwpDebugResource)
4095 dbgs() << "reserveResources:\n";
4096 });
4097 if (UseDFA)
4098 return DFAResources[positiveModulo(Cycle, InitiationInterval)]
4099 ->reserveResources(&SU.getInstr()->getDesc());
4100
4101 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
4102 if (!SCDesc->isValid()) {
4103 LLVM_DEBUG({
4104 dbgs() << "No valid Schedule Class Desc for schedClass!\n";
4105 dbgs() << "isPseudo:" << SU.getInstr()->isPseudo() << "\n";
4106 });
4107 return;
4108 }
4109
4110 reserveResources(SCDesc, Cycle);
4111
4112 LLVM_DEBUG({
4113 if (SwpDebugResource) {
4114 dumpMRT();
4115 dbgs() << "reserveResources: done!\n\n";
4116 }
4117 });
4118}
4119
4120void ResourceManager::reserveResources(const MCSchedClassDesc *SCDesc,
4121 int Cycle) {
4122 assert(!UseDFA);
4123 for (const MCWriteProcResEntry &PRE : make_range(
4124 STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
4125 for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
4126 ++MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];
4127
4128 for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
4129 ++NumScheduledMops[positiveModulo(C, InitiationInterval)];
4130}
4131
4132void ResourceManager::unreserveResources(const MCSchedClassDesc *SCDesc,
4133 int Cycle) {
4134 assert(!UseDFA);
4135 for (const MCWriteProcResEntry &PRE : make_range(
4136 STI->getWriteProcResBegin(SCDesc), STI->getWriteProcResEnd(SCDesc)))
4137 for (int C = Cycle; C < Cycle + PRE.ReleaseAtCycle; ++C)
4138 --MRT[positiveModulo(C, InitiationInterval)][PRE.ProcResourceIdx];
4139
4140 for (int C = Cycle; C < Cycle + SCDesc->NumMicroOps; ++C)
4141 --NumScheduledMops[positiveModulo(C, InitiationInterval)];
4142}
4143
4144bool ResourceManager::isOverbooked() const {
4145 assert(!UseDFA);
4146 for (int Slot = 0; Slot < InitiationInterval; ++Slot) {
4147 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4148 const MCProcResourceDesc *Desc = SM.getProcResource(I);
4149 if (MRT[Slot][I] > Desc->NumUnits)
4150 return true;
4151 }
4152 if (NumScheduledMops[Slot] > IssueWidth)
4153 return true;
4154 }
4155 return false;
4156}
4157
4158int ResourceManager::calculateResMIIDFA() const {
4159 assert(UseDFA);
4160
4161 // Sort the instructions by the number of available choices for scheduling,
4162 // least to most. Use the number of critical resources as the tie breaker.
4163 FuncUnitSorter FUS = FuncUnitSorter(*ST);
4164 for (SUnit &SU : DAG->SUnits)
4165 FUS.calcCriticalResources(*SU.getInstr());
4166 PriorityQueue<MachineInstr *, std::vector<MachineInstr *>, FuncUnitSorter>
4167 FuncUnitOrder(FUS);
4168
4169 for (SUnit &SU : DAG->SUnits)
4170 FuncUnitOrder.push(SU.getInstr());
4171
4173 Resources.push_back(
4174 std::unique_ptr<DFAPacketizer>(TII->CreateTargetScheduleState(*ST)));
4175
4176 while (!FuncUnitOrder.empty()) {
4177 MachineInstr *MI = FuncUnitOrder.top();
4178 FuncUnitOrder.pop();
4179 if (TII->isZeroCost(MI->getOpcode()))
4180 continue;
4181
4182 // Attempt to reserve the instruction in an existing DFA. At least one
4183 // DFA is needed for each cycle.
4184 unsigned NumCycles = DAG->getSUnit(MI)->Latency;
4185 unsigned ReservedCycles = 0;
4186 auto *RI = Resources.begin();
4187 auto *RE = Resources.end();
4188 LLVM_DEBUG({
4189 dbgs() << "Trying to reserve resource for " << NumCycles
4190 << " cycles for \n";
4191 MI->dump();
4192 });
4193 for (unsigned C = 0; C < NumCycles; ++C)
4194 while (RI != RE) {
4195 if ((*RI)->canReserveResources(*MI)) {
4196 (*RI)->reserveResources(*MI);
4197 ++ReservedCycles;
4198 break;
4199 }
4200 RI++;
4201 }
4202 LLVM_DEBUG(dbgs() << "ReservedCycles:" << ReservedCycles
4203 << ", NumCycles:" << NumCycles << "\n");
4204 // Add new DFAs, if needed, to reserve resources.
4205 for (unsigned C = ReservedCycles; C < NumCycles; ++C) {
4207 << "NewResource created to reserve resources"
4208 << "\n");
4209 auto *NewResource = TII->CreateTargetScheduleState(*ST);
4210 assert(NewResource->canReserveResources(*MI) && "Reserve error.");
4211 NewResource->reserveResources(*MI);
4212 Resources.push_back(std::unique_ptr<DFAPacketizer>(NewResource));
4213 }
4214 }
4215
4216 int Resmii = Resources.size();
4217 LLVM_DEBUG(dbgs() << "Return Res MII:" << Resmii << "\n");
4218 return Resmii;
4219}
4220
4222 if (UseDFA)
4223 return calculateResMIIDFA();
4224
4225 // Count each resource consumption and divide it by the number of units.
4226 // ResMII is the max value among them.
4227
4228 int NumMops = 0;
4229 SmallVector<uint64_t> ResourceCount(SM.getNumProcResourceKinds());
4230 for (SUnit &SU : DAG->SUnits) {
4231 if (TII->isZeroCost(SU.getInstr()->getOpcode()))
4232 continue;
4233
4234 const MCSchedClassDesc *SCDesc = DAG->getSchedClass(&SU);
4235 if (!SCDesc->isValid())
4236 continue;
4237
4238 LLVM_DEBUG({
4239 if (SwpDebugResource) {
4240 DAG->dumpNode(SU);
4241 dbgs() << " #Mops: " << SCDesc->NumMicroOps << "\n"
4242 << " WriteProcRes: ";
4243 }
4244 });
4245 NumMops += SCDesc->NumMicroOps;
4246 for (const MCWriteProcResEntry &PRE :
4247 make_range(STI->getWriteProcResBegin(SCDesc),
4248 STI->getWriteProcResEnd(SCDesc))) {
4249 LLVM_DEBUG({
4250 if (SwpDebugResource) {
4251 const MCProcResourceDesc *Desc =
4252 SM.getProcResource(PRE.ProcResourceIdx);
4253 dbgs() << Desc->Name << ": " << PRE.ReleaseAtCycle << ", ";
4254 }
4255 });
4256 ResourceCount[PRE.ProcResourceIdx] += PRE.ReleaseAtCycle;
4257 }
4258 LLVM_DEBUG(if (SwpDebugResource) dbgs() << "\n");
4259 }
4260
4261 int Result = (NumMops + IssueWidth - 1) / IssueWidth;
4262 LLVM_DEBUG({
4263 if (SwpDebugResource)
4264 dbgs() << "#Mops: " << NumMops << ", "
4265 << "IssueWidth: " << IssueWidth << ", "
4266 << "Cycles: " << Result << "\n";
4267 });
4268
4269 LLVM_DEBUG({
4270 if (SwpDebugResource) {
4271 std::stringstream SS;
4272 SS << std::setw(2) << "ID" << std::setw(16) << "Name" << std::setw(10)
4273 << "Units" << std::setw(10) << "Consumed" << std::setw(10) << "Cycles"
4274 << "\n";
4275 dbgs() << SS.str();
4276 }
4277 });
4278 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
4279 const MCProcResourceDesc *Desc = SM.getProcResource(I);
4280 int Cycles = (ResourceCount[I] + Desc->NumUnits - 1) / Desc->NumUnits;
4281 LLVM_DEBUG({
4282 if (SwpDebugResource) {
4283 std::stringstream SS;
4284 SS << std::setw(2) << I << std::setw(16) << Desc->Name << std::setw(10)
4285 << Desc->NumUnits << std::setw(10) << ResourceCount[I]
4286 << std::setw(10) << Cycles << "\n";
4287 dbgs() << SS.str();
4288 }
4289 });
4290 if (Cycles > Result)
4291 Result = Cycles;
4292 }
4293 return Result;
4294}
4295
4297 InitiationInterval = II;
4298 DFAResources.clear();
4299 DFAResources.resize(II);
4300 for (auto &I : DFAResources)
4301 I.reset(ST->getInstrInfo()->CreateTargetScheduleState(*ST));
4302 MRT.clear();
4303 MRT.resize(II, SmallVector<uint64_t>(SM.getNumProcResourceKinds()));
4304 NumScheduledMops.clear();
4305 NumScheduledMops.resize(II);
4306}
4307
4308bool SwingSchedulerDDGEdge::ignoreDependence(bool IgnoreAnti) const {
4309 if (Pred.isArtificial() || Dst->isBoundaryNode())
4310 return true;
4311 // Currently, dependence that is an anti-dependences but not a loop-carried is
4312 // also ignored. This behavior is preserved to prevent regression.
4313 // FIXME: Remove if this doesn't have significant impact on performance
4314 return IgnoreAnti && (Pred.getKind() == SDep::Kind::Anti || Distance != 0);
4315}
4316
4317SwingSchedulerDDG::SwingSchedulerDDGEdges &
4318SwingSchedulerDDG::getEdges(const SUnit *SU) {
4319 if (SU == EntrySU)
4320 return EntrySUEdges;
4321 if (SU == ExitSU)
4322 return ExitSUEdges;
4323 return EdgesVec[SU->NodeNum];
4324}
4325
4326const SwingSchedulerDDG::SwingSchedulerDDGEdges &
4327SwingSchedulerDDG::getEdges(const SUnit *SU) const {
4328 if (SU == EntrySU)
4329 return EntrySUEdges;
4330 if (SU == ExitSU)
4331 return ExitSUEdges;
4332 return EdgesVec[SU->NodeNum];
4333}
4334
4335void SwingSchedulerDDG::addEdge(const SUnit *SU,
4336 const SwingSchedulerDDGEdge &Edge) {
4337 assert(!Edge.isValidationOnly() &&
4338 "Validation-only edges are not expected here.");
4339
4340 auto &Edges = getEdges(SU);
4341 if (Edge.getSrc() == SU)
4342 Edges.Succs.push_back(Edge);
4343 else
4344 Edges.Preds.push_back(Edge);
4345}
4346
4347void SwingSchedulerDDG::initEdges(SUnit *SU) {
4348 for (const auto &PI : SU->Preds) {
4349 SwingSchedulerDDGEdge Edge(SU, PI, /*IsSucc=*/false,
4350 /*IsValidationOnly=*/false);
4351 addEdge(SU, Edge);
4352 }
4353
4354 for (const auto &SI : SU->Succs) {
4355 SwingSchedulerDDGEdge Edge(SU, SI, /*IsSucc=*/true,
4356 /*IsValidationOnly=*/false);
4357 addEdge(SU, Edge);
4358 }
4359}
4360
4361SwingSchedulerDDG::SwingSchedulerDDG(std::vector<SUnit> &SUnits, SUnit *EntrySU,
4362 SUnit *ExitSU, const LoopCarriedEdges &LCE)
4363 : EntrySU(EntrySU), ExitSU(ExitSU) {
4364 EdgesVec.resize(SUnits.size());
4365
4366 // Add non-loop-carried edges based on the DAG.
4367 initEdges(EntrySU);
4368 initEdges(ExitSU);
4369 for (auto &SU : SUnits)
4370 initEdges(&SU);
4371
4372 // Add loop-carried edges, which are not represented in the DAG.
4373 for (SUnit &SU : SUnits) {
4374 SUnit *Src = &SU;
4375 if (const LoopCarriedEdges::OrderDep *OD = LCE.getOrderDepOrNull(Src)) {
4376 SDep Base(Src, SDep::Barrier);
4377 Base.setLatency(1);
4378 for (SUnit *Dst : *OD) {
4379 SwingSchedulerDDGEdge Edge(Dst, Base, /*IsSucc=*/false,
4380 /*IsValidationOnly=*/true);
4381 Edge.setDistance(1);
4382 ValidationOnlyEdges.push_back(Edge);
4383
4384 // Store the edge as an extra edge if it meets the following conditions:
4385 //
4386 // - The edge is a loop-carried order dependency.
4387 // - The edge is a back edge in terms of the original instruction
4388 // order.
4389 // - The destination instruction may load.
4390 // - The source instruction may store but does not load.
4391 //
4392 // These conditions are inherited from a previous implementation to
4393 // preserve the existing behavior and avoid regressions.
4394 bool UseAsExtraEdge = [&]() {
4395 if (Edge.getDistance() == 0 || !Edge.isOrderDep())
4396 return false;
4397
4398 SUnit *Src = Edge.getSrc();
4399 SUnit *Dst = Edge.getDst();
4400 if (Src->NodeNum < Dst->NodeNum)
4401 return false;
4402
4403 MachineInstr *SrcMI = Src->getInstr();
4404 MachineInstr *DstMI = Dst->getInstr();
4405 return DstMI->mayLoad() && !SrcMI->mayLoad() && SrcMI->mayStore();
4406 }();
4407 if (UseAsExtraEdge)
4408 getEdges(Edge.getSrc()).ExtraSuccs.push_back(Edge.getDst());
4409 }
4410 }
4411 }
4412}
4413
4414const SwingSchedulerDDG::EdgesType &
4416 return getEdges(SU).Preds;
4417}
4418
4419const SwingSchedulerDDG::EdgesType &
4421 return getEdges(SU).Succs;
4422}
4423
4425 return getEdges(SU).ExtraSuccs;
4426}
4427
4428/// Check if \p Schedule doesn't violate the validation-only dependencies.
4430 unsigned II = Schedule.getInitiationInterval();
4431
4432 auto ExpandCycle = [&](SUnit *SU) {
4433 int Stage = Schedule.stageScheduled(SU);
4434 int Cycle = Schedule.cycleScheduled(SU);
4435 return Cycle + (Stage * II);
4436 };
4437
4438 for (const SwingSchedulerDDGEdge &Edge : ValidationOnlyEdges) {
4439 SUnit *Src = Edge.getSrc();
4440 SUnit *Dst = Edge.getDst();
4441 if (!Src->isInstr() || !Dst->isInstr())
4442 continue;
4443 int CycleSrc = ExpandCycle(Src);
4444 int CycleDst = ExpandCycle(Dst);
4445 int MaxLateStart = CycleDst + Edge.getDistance() * II - Edge.getLatency();
4446 if (CycleSrc > MaxLateStart) {
4447 LLVM_DEBUG({
4448 dbgs() << "Validation failed for edge from " << Src->NodeNum << " to "
4449 << Dst->NodeNum << "\n";
4450 });
4451 return false;
4452 }
4453 }
4454 return true;
4455}
4456
4457void LoopCarriedEdges::modifySUnits(std::vector<SUnit> &SUnits,
4458 const TargetInstrInfo *TII) {
4459 for (SUnit &SU : SUnits) {
4460 SUnit *Src = &SU;
4461 if (auto *OrderDep = getOrderDepOrNull(Src)) {
4462 SDep Dep(Src, SDep::Barrier);
4463 Dep.setLatency(1);
4464 for (SUnit *Dst : *OrderDep) {
4465 SUnit *From = Src;
4466 SUnit *To = Dst;
4467 if (From->NodeNum > To->NodeNum)
4468 std::swap(From, To);
4469
4470 // Add a forward edge if the following conditions are met:
4471 //
4472 // - The instruction of the source node (FromMI) may read memory.
4473 // - The instruction of the target node (ToMI) may modify memory, but
4474 // does not read it.
4475 // - Neither instruction is a global barrier.
4476 // - The load appears before the store in the original basic block.
4477 // - There are no barrier or store instructions between the two nodes.
4478 // - The target node is unreachable from the source node in the current
4479 // DAG.
4480 //
4481 // TODO: These conditions are inherited from a previous implementation,
4482 // and some may no longer be necessary. For now, we conservatively
4483 // retain all of them to avoid regressions, but the logic could
4484 // potentially be simplified
4485 MachineInstr *FromMI = From->getInstr();
4486 MachineInstr *ToMI = To->getInstr();
4487 if (FromMI->mayLoad() && !ToMI->mayLoad() && ToMI->mayStore() &&
4488 !TII->isGlobalMemoryObject(FromMI) &&
4489 !TII->isGlobalMemoryObject(ToMI) && !isSuccOrder(From, To)) {
4490 SDep Pred = Dep;
4491 Pred.setSUnit(From);
4492 To->addPred(Pred);
4493 }
4494 }
4495 }
4496 }
4497}
4498
4500 const MachineRegisterInfo *MRI) const {
4501 const auto *Order = getOrderDepOrNull(SU);
4502
4503 if (!Order)
4504 return;
4505
4506 const auto DumpSU = [](const SUnit *SU) {
4507 std::ostringstream OSS;
4508 OSS << "SU(" << SU->NodeNum << ")";
4509 return OSS.str();
4510 };
4511
4512 dbgs() << " Loop carried edges from " << DumpSU(SU) << "\n"
4513 << " Order\n";
4514 for (SUnit *Dst : *Order)
4515 dbgs() << " " << DumpSU(Dst) << "\n";
4516}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
static std::optional< unsigned > getTag(const TargetRegisterInfo *TRI, const MachineInstr &MI, const LoadInfo &LI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
constexpr LLT S1
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:678
DXIL Remove Unused Resources
This file defines the DenseMap class.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
A common definition of LaneBitmask for use in TableGen and CodeGen.
static void addEdge(SmallVectorImpl< LazyCallGraph::Edge > &Edges, DenseMap< LazyCallGraph::Node *, int > &EdgeIndexMap, LazyCallGraph::Node &N, LazyCallGraph::Edge::Kind EK)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static cl::opt< int > SwpForceII("pipeliner-force-ii", cl::desc("Force pipeliner to use specified II."), cl::Hidden, cl::init(-1))
A command line argument to force pipeliner to use specified initial interval.
static cl::opt< bool > ExperimentalCodeGen("pipeliner-experimental-cg", cl::Hidden, cl::init(false), cl::desc("Use the experimental peeling code generator for software pipelining"))
static bool hasPHICycleDFS(unsigned Reg, const DenseMap< unsigned, SmallVector< unsigned, 2 > > &PhiDeps, SmallSet< unsigned, 8 > &Visited, SmallSet< unsigned, 8 > &RecStack)
Depth-first search to detect cycles among PHI dependencies.
static cl::opt< bool > MVECodeGen("pipeliner-mve-cg", cl::Hidden, cl::init(false), cl::desc("Use the MVE code generator for software pipelining"))
static cl::opt< int > RegPressureMargin("pipeliner-register-pressure-margin", cl::Hidden, cl::init(5), cl::desc("Margin representing the unused percentage of " "the register pressure limit"))
static void getPhiRegs(MachineInstr &Phi, MachineBasicBlock *Loop, Register &InitVal, Register &LoopVal)
Return the register values for the operands of a Phi instruction.
static cl::opt< bool > SwpDebugResource("pipeliner-dbg-res", cl::Hidden, cl::init(false))
static void computeLiveOuts(MachineFunction &MF, RegPressureTracker &RPTracker, NodeSet &NS)
Compute the live-out registers for the instructions in a node-set.
static void computeScheduledInsts(const SwingSchedulerDAG *SSD, SMSchedule &Schedule, std::vector< MachineInstr * > &OrderedInsts, DenseMap< MachineInstr *, unsigned > &Stages)
Create an instruction stream that represents a single iteration and stage of each instruction.
static cl::opt< bool > EmitTestAnnotations("pipeliner-annotate-for-testing", cl::Hidden, cl::init(false), cl::desc("Instead of emitting the pipelined code, annotate instructions " "with the generated schedule for feeding into the " "-modulo-schedule-test pass"))
static 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 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)
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:251
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:341
bool erase(const KeyT &Val)
Definition DenseMap.h:419
bool empty() const
Definition DenseMap.h:199
iterator end()
Definition DenseMap.h:169
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:312
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.
DFAPacketizer * CreateTargetScheduleState(const TargetSubtargetInfo &STI) const override
Create machine specific model for scheduling.
bool getBaseAndOffsetPosition(const MachineInstr &MI, unsigned &BasePos, unsigned &OffsetPos) const override
For instructions with a base and offset, return the position of the base register and offset operands...
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:1426
ArrayRef< MDOperand > operands() const
Definition Metadata.h:1424
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1432
LLVM_ABI StringRef getString() const
Definition Metadata.cpp:629
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.
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
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 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
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition Register.h:107
constexpr bool isValid() const
Definition Register.h:112
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
LLVM_ABI int calculateResMII() const
LLVM_ABI void initProcResourceVectors(const MCSchedModel &SM, SmallVectorImpl< uint64_t > &Masks)
LLVM_ABI void init(int II)
Initialize resources with the initiation interval II.
LLVM_ABI bool canReserveResources(SUnit &SU, int Cycle)
Check if the resources occupied by a machine instruction are available in the current state.
Scheduling dependency.
Definition ScheduleDAG.h:52
Kind
These are the different kinds of scheduling dependencies.
Definition ScheduleDAG.h:55
@ Order
Any other ordering dependency.
Definition ScheduleDAG.h:59
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:57
@ Data
Regular data dependence (aka true-dependence).
Definition ScheduleDAG.h:56
void setLatency(unsigned Lat)
Sets the latency for this edge.
@ Barrier
An unknown scheduling barrier.
Definition ScheduleDAG.h:72
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition ScheduleDAG.h:75
void setSUnit(SUnit *SU)
This class represents the scheduled code.
LLVM_ABI std::deque< SUnit * > reorderInstructions(const SwingSchedulerDAG *SSD, const std::deque< SUnit * > &Instrs) const
void setInitiationInterval(int ii)
Set the initiation interval for this schedule.
LLVM_ABI void dump() const
Utility function used for debugging to print the schedule.
LLVM_ABI bool insert(SUnit *SU, int StartCycle, int EndCycle, int II)
Try to schedule the node at the specified StartCycle and continue until the node is schedule or the E...
unsigned getMaxStageCount()
Return the maximum stage count needed for this schedule.
LLVM_ABI void print(raw_ostream &os) const
Print the schedule information to the given output.
LLVM_ABI bool onlyHasLoopCarriedOutputOrOrderPreds(SUnit *SU, const SwingSchedulerDDG *DDG) const
Return true if all scheduled predecessors are loop-carried output/order dependencies.
int stageScheduled(SUnit *SU) const
Return the stage for a scheduled instruction.
LLVM_ABI void orderDependence(const SwingSchedulerDAG *SSD, SUnit *SU, std::deque< SUnit * > &Insts) const
Order the instructions within a cycle so that the definitions occur before the uses.
LLVM_ABI bool isValidSchedule(SwingSchedulerDAG *SSD)
int getInitiationInterval() const
Return the initiation interval for this schedule.
std::deque< SUnit * > & getInstructions(int cycle)
Return the instructions that are scheduled at the specified cycle.
int getFirstCycle() const
Return the first cycle in the completed schedule.
DenseMap< int, std::deque< SUnit * > >::const_iterator const_sched_iterator
LLVM_ABI bool isLoopCarriedDefOfUse(const SwingSchedulerDAG *SSD, MachineInstr *Def, MachineOperand &MO) const
Return true if the instruction is a definition that is loop carried and defines the use on the next i...
unsigned cycleScheduled(SUnit *SU) const
Return the cycle for a scheduled instruction.
LLVM_ABI SmallPtrSet< SUnit *, 8 > computeUnpipelineableNodes(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
Determine transitive dependences of unpipelineable instructions.
LLVM_ABI void computeStart(SUnit *SU, int *MaxEarlyStart, int *MinLateStart, int II, SwingSchedulerDAG *DAG)
Compute the scheduling start slot for the instruction.
LLVM_ABI bool normalizeNonPipelinedInstructions(SwingSchedulerDAG *SSD, TargetInstrInfo::PipelinerLoopInfo *PLI)
LLVM_ABI bool isLoopCarried(const SwingSchedulerDAG *SSD, MachineInstr &Phi) const
Return true if the scheduled Phi has a loop carried operand.
int getFinalCycle() const
Return the last cycle in the finalized schedule.
LLVM_ABI void finalizeSchedule(SwingSchedulerDAG *SSD)
After the schedule has been formed, call this function to combine the instructions from the different...
Scheduling unit. This is a node in the scheduling DAG.
unsigned NumPreds
bool isInstr() const
Returns true if this SUnit refers to a machine instruction as opposed to an SDNode.
unsigned NodeNum
Entry # of node in the node vector.
void setInstr(MachineInstr *MI)
Assigns the instruction for the SUnit.
LLVM_ABI void removePred(const SDep &D)
Removes the specified edge as a pred of the current node if it exists.
bool isPred(const SUnit *N) const
Tests if node N is a predecessor of this node.
unsigned short Latency
Node latency.
bool isBoundaryNode() const
Boundary nodes are placeholders for the boundary of the scheduling region.
bool hasPhysRegDefs
Has physreg defs that are being used.
SmallVector< SDep, 4 > Succs
All sunit successors.
SmallVector< SDep, 4 > Preds
All sunit predecessors.
LLVM_ABI bool addPred(const SDep &D, bool Required=true)
Adds the specified edge as a pred of the current node if not already.
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
DenseMap< MachineInstr *, SUnit * > MISUnitMap
After calling BuildSchedGraph, each machine instruction in the current scheduling region is mapped to...
virtual void finishBlock()
Cleans up after scheduling in the given block.
MachineBasicBlock * BB
The block in which to insert instructions.
void buildSchedGraph(AAResults *AA, RegPressureTracker *RPTracker=nullptr, PressureDiffs *PDiffs=nullptr, LiveIntervals *LIS=nullptr, bool TrackLaneMasks=false)
Builds SUnits for the current region.
SUnit * getSUnit(MachineInstr *MI) const
Returns an existing SUnit for this MI, or nullptr.
LLVM_ABI void AddPred(SUnit *Y, SUnit *X)
Updates the topological ordering to accommodate an edge to be added from SUnit X to SUnit Y.
LLVM_ABI bool IsReachable(const SUnit *SU, const SUnit *TargetSU)
Checks if SU is reachable from TargetSU.
MachineRegisterInfo & MRI
Virtual/real register map.
const TargetInstrInfo * TII
Target instruction information.
std::vector< SUnit > SUnits
The scheduling units.
const TargetRegisterInfo * TRI
Target processor register info.
SUnit EntrySU
Special node for the region entry.
MachineFunction & MF
Machine function.
SUnit ExitSU
Special node for the region exit.
A vector that has set insertion semantics.
Definition SetVector.h:57
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
Definition SetVector.h:268
typename vector_type::const_iterator iterator
Definition SetVector.h:72
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
void clear()
Completely clear the SetVector.
Definition SetVector.h:273
bool empty() const
Determine if the SetVector is empty or not.
Definition SetVector.h:100
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
SlotIndex insertMachineInstrInMaps(MachineInstr &MI, bool Late=false)
Insert the given machine instruction into the mapping.
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
iterator end() const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
iterator begin() const
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
Definition SmallSet.h:176
bool erase(const T &V)
Definition SmallSet.h:200
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition SmallSet.h:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
This class builds the dependence graph for the instructions in a loop, and attempts to schedule the i...
void applyInstrChange(MachineInstr *MI, SMSchedule &Schedule)
Apply changes to the instruction if needed.
const SwingSchedulerDDG * getDDG() const
void finishBlock() override
Clean up after the software pipeliner runs.
void fixupRegisterOverlaps(std::deque< SUnit * > &Instrs)
Attempt to fix the degenerate cases when the instruction serialization causes the register lifetimes ...
void schedule() override
We override the schedule function in ScheduleDAGInstrs to implement the scheduling part of the Swing ...
bool mayOverlapInLaterIter(const MachineInstr *BaseMI, const MachineInstr *OtherMI) const
Return false if there is no overlap between the region accessed by BaseMI in an iteration and the reg...
Register getInstrBaseReg(SUnit *SU) const
Return the new base register that was stored away for the changed instruction.
Represents a dependence between two instruction.
LLVM_ABI bool ignoreDependence(bool IgnoreAnti) const
Returns true for DDG nodes that we ignore when computing the cost functions.
This class provides APIs to retrieve edges from/to an SUnit node, with a particular focus on loop-car...
LLVM_ABI SwingSchedulerDDG(std::vector< SUnit > &SUnits, SUnit *EntrySU, SUnit *ExitSU, const LoopCarriedEdges &LCE)
LLVM_ABI ArrayRef< SUnit * > getExtraOutEdges(const SUnit *SU) const
LLVM_ABI const EdgesType & getInEdges(const SUnit *SU) const
LLVM_ABI bool isValidSchedule(const SMSchedule &Schedule) const
Check if Schedule doesn't violate the validation-only dependencies.
LLVM_ABI const EdgesType & getOutEdges(const SUnit *SU) const
Object returned by analyzeLoopForPipelining.
virtual bool shouldIgnoreForPipelining(const MachineInstr *MI) const =0
Return true if the given instruction should not be pipelined and should be ignored.
TargetInstrInfo - Interface to description of machine instruction set.
Primary interface to the complete machine description for the target machine.
Target-Independent Code Generator Pass Configuration Options.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual 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
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
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
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:81
@ Valid
The data is already valid.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract(Y &&MD)
Extract a Value from Metadata.
Definition Metadata.h:668
constexpr double e
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< DefNode * > Def
Definition RDFGraph.h:384
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
std::set< NodeId > NodeSet
Definition RDFGraph.h:551
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
Definition SFrame.h:77
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
@ Offset
Definition DWP.cpp:577
void stable_sort(R &&Range)
Definition STLExtras.h:2116
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr NextUseDistance min(NextUseDistance A, NextUseDistance B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
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:2200
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
static int64_t computeDelta(SectionEntry *A, SectionEntry *B)
@ WS_Force
Use window algorithm after SMS algorithm fails.
@ WS_On
Turn off window algorithm.
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:102
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI cl::opt< bool > SwpEnableCopyToPhi
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2052
LLVM_ABI char & MachinePipelinerID
This pass performs software pipelining on machine instructions.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI cl::opt< int > SwpForceIssueWidth
A command line argument to force pipeliner to use specified issue width.
@ Increment
Incrementally increasing token ID.
Definition AllocToken.h:26
LLVM_ABI void getUnderlyingObjects(const Value *V, SmallVectorImpl< const Value * > &Objects, const LoopInfo *LI=nullptr, unsigned MaxLookup=MaxLookupSearchDepth)
This method is similar to getUnderlyingObject except that it can look through phi and select instruct...
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
#define N
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:763
uint64_t FuncUnits
Bitmask representing a set of functional units.
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
Represents loop-carried dependencies.
SmallSetVector< SUnit *, 8 > OrderDep
const OrderDep * getOrderDepOrNull(SUnit *Key) const
LLVM_ABI void modifySUnits(std::vector< SUnit > &SUnits, const TargetInstrInfo *TII)
Adds some edges to the original DAG that correspond to loop-carried dependencies.
LLVM_ABI void dump(SUnit *SU, const TargetRegisterInfo *TRI, const MachineRegisterInfo *MRI) const
Define a kind of processor resource that will be modeled by the scheduler.
Definition MCSchedule.h:42
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:129
Machine model for scheduling, bundling, and heuristics.
Definition MCSchedule.h:273
const MCSchedClassDesc * getSchedClassDesc(unsigned SchedClassIdx) const
Definition MCSchedule.h:381
bool hasInstrSchedModel() const
Does this machine model include instruction-level scheduling.
Definition MCSchedule.h:355
const MCProcResourceDesc * getProcResource(unsigned ProcResourceIdx) const
Definition MCSchedule.h:374
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition MCSchedule.h:74
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
std::vector< unsigned > MaxSetPressure
Map of max reg pressure indexed by pressure set ID, not class ID.