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