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