LLVM 23.0.0git
GCNSchedStrategy.h
Go to the documentation of this file.
1//===-- GCNSchedStrategy.h - GCN Scheduler Strategy -*- C++ -*-------------===//
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/// \file
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
14#define LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
15
16#include "GCNRegPressure.h"
17#include "llvm/ADT/DenseMap.h"
22
23namespace llvm {
24
26class SIRegisterInfo;
27class GCNSubtarget;
28class GCNSchedStage;
29
39
40#ifndef NDEBUG
41raw_ostream &operator<<(raw_ostream &OS, const GCNSchedStageID &StageID);
42#endif
43
44/// This is a minimal scheduler strategy. The main difference between this
45/// and the GenericScheduler is that GCNSchedStrategy uses different
46/// heuristics to determine excess/critical pressure sets.
48protected:
49 SUnit *pickNodeBidirectional(bool &IsTopNode, bool &PickedPending);
50
51 void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy,
52 const RegPressureTracker &RPTracker,
53 SchedCandidate &Cand, bool &IsPending,
54 bool IsBottomUp);
55
56 void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop,
57 const RegPressureTracker &RPTracker,
58 const SIRegisterInfo *SRI, unsigned SGPRPressure,
59 unsigned VGPRPressure, bool IsBottomUp);
60
61 /// Estimate how many cycles \p SU must wait due to structural hazards at the
62 /// current boundary cycle. Returns zero when no stall is required.
63 unsigned getStructuralStallCycles(SchedBoundary &Zone, SUnit *SU) const;
64
65 /// Evaluates instructions in the pending queue using a subset of scheduling
66 /// heuristics.
67 ///
68 /// Instructions that cannot be issued due to hardware constraints are placed
69 /// in the pending queue rather than the available queue, making them normally
70 /// invisible to scheduling heuristics. However, in certain scenarios (such as
71 /// avoiding register spilling), it may be beneficial to consider scheduling
72 /// these not-yet-ready instructions.
74 SchedBoundary *Zone) const;
75
76 void printCandidateDecision(const SchedCandidate &Current,
77 const SchedCandidate &Preferred);
78
79 void getRegisterPressures(bool AtTop, const RegPressureTracker &RPTracker,
80 SUnit *SU, std::vector<unsigned> &Pressure,
81 std::vector<unsigned> &MaxPressure,
84 ScheduleDAGMI *DAG, const SIRegisterInfo *SRI);
85
86 std::vector<unsigned> Pressure;
87
88 std::vector<unsigned> MaxPressure;
89
91
93
95
97
98 // Scheduling stages for this strategy.
100
101 // Pointer to the current SchedStageID.
103
104 // GCN RP Tracker for top-down scheduling
106
107 // GCN RP Tracker for botttom-up scheduling
109
110 bool UseGCNTrackers = false;
111
112 std::optional<bool> GCNTrackersOverride;
113
114public:
115 // schedule() have seen register pressure over the critical limits and had to
116 // track register pressure for actual scheduling heuristics.
118
119 // Schedule known to have excess register pressure. Be more conservative in
120 // increasing ILP and preserving VGPRs.
121 bool KnownExcessRP = false;
122
123 // An error margin is necessary because of poor performance of the generic RP
124 // tracker and can be adjusted up for tuning heuristics to try and more
125 // aggressively reduce register pressure.
126 unsigned ErrorMargin = 3;
127
128 // Bias for SGPR limits under a high register pressure.
129 const unsigned HighRPSGPRBias = 7;
130
131 // Bias for VGPR limits under a high register pressure.
132 const unsigned HighRPVGPRBias = 7;
133
135
137
138 unsigned SGPRLimitBias = 0;
139
140 unsigned VGPRLimitBias = 0;
141
143
144 SUnit *pickNode(bool &IsTopNode) override;
145
146 void schedNode(SUnit *SU, bool IsTopNode) override;
147
148 void initialize(ScheduleDAGMI *DAG) override;
149
150 unsigned getTargetOccupancy() { return TargetOccupancy; }
151
152 void setTargetOccupancy(unsigned Occ) { TargetOccupancy = Occ; }
153
155
156 // Advances stage. Returns true if there are remaining stages.
157 bool advanceStage();
158
159 bool hasNextStage() const;
160
161 bool useGCNTrackers() const {
162 return GCNTrackersOverride.value_or(UseGCNTrackers);
163 }
164
166
168
170};
171
172/// The goal of this scheduling strategy is to maximize kernel occupancy (i.e.
173/// maximum number of waves per simd).
175public:
177 bool IsLegacyScheduler = false);
178};
179
180/// The goal of this scheduling strategy is to maximize ILP for a single wave
181/// (i.e. latency hiding).
183protected:
184 bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand,
185 SchedBoundary *Zone) const override;
186
187public:
189};
190
191/// The goal of this scheduling strategy is to maximize memory clause for a
192/// single wave.
194protected:
195 bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand,
196 SchedBoundary *Zone) const override;
197
198public:
200};
201
203 unsigned ScheduleLength;
204 unsigned BubbleCycles;
205
206public:
207 ScheduleMetrics() = default;
208 ScheduleMetrics(unsigned L, unsigned BC)
209 : ScheduleLength(L), BubbleCycles(BC) {}
210 unsigned getLength() const { return ScheduleLength; }
211 unsigned getBubbles() const { return BubbleCycles; }
212 unsigned getMetric() const {
213 unsigned Metric = (BubbleCycles * ScaleFactor) / ScheduleLength;
214 // Metric is zero if the amount of bubbles is less than 1% which is too
215 // small. So, return 1.
216 return Metric ? Metric : 1;
217 }
218 static const unsigned ScaleFactor;
219};
220
222 dbgs() << "\n Schedule Metric (scaled by " << ScheduleMetrics::ScaleFactor
223 << " ) is: " << Sm.getMetric() << " [ " << Sm.getBubbles() << "/"
224 << Sm.getLength() << " ]\n";
225 return OS;
226}
227
228class GCNScheduleDAGMILive;
231 // The live in/out pressure as indexed by the first or last MI in the region
232 // before scheduling.
234 // The mapping of RegionIDx to key instruction
235 DenseMap<unsigned, MachineInstr *> IdxToInstruction;
236 // Whether we are calculating LiveOuts or LiveIns
237 bool IsLiveOut;
238
239public:
240 RegionPressureMap() = default;
242 : DAG(GCNDAG), IsLiveOut(LiveOut) {}
243 // Build the Instr->LiveReg and RegionIdx->Instr maps
244 void buildLiveRegMap();
245
246 // Retrieve the LiveReg for a given RegionIdx
248 assert(IdxToInstruction.contains(RegionIdx));
249 MachineInstr *Key = IdxToInstruction[RegionIdx];
250 return RegionLiveRegMap[Key];
251 }
252};
253
254/// A region's boundaries i.e. a pair of instruction bundle iterators. The lower
255/// boundary is inclusive, the upper boundary is exclusive.
257 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>;
258
260 friend class GCNSchedStage;
265 friend class PreRARematStage;
267 friend class RegionPressureMap;
268
269 const GCNSubtarget &ST;
270
272
273 // Occupancy target at the beginning of function scheduling cycle.
274 unsigned StartingOccupancy;
275
276 // Minimal real occupancy recorder for the function.
277 unsigned MinOccupancy;
278
279 // Vector of regions recorder for later rescheduling
281
282 // Record regions with high register pressure.
283 BitVector RegionsWithHighRP;
284
285 // Record regions with excess register pressure over the physical register
286 // limit. Register pressure in these regions usually will result in spilling.
287 BitVector RegionsWithExcessRP;
288
289 // Regions that have IGLP instructions (SCHED_GROUP_BARRIER or IGLP_OPT).
290 BitVector RegionsWithIGLPInstrs;
291
292 // Region live-in cache.
294
295 // Region pressure cache.
297
298 // Temporary basic block live-in cache.
300
301 // The map of the initial first region instruction to region live in registers
303
304 // Calculate the map of the initial first region instruction to region live in
305 // registers
307
308 // Calculate the map of the initial last region instruction to region live out
309 // registers
311 getRegionLiveOutMap() const;
312
313 // The live out registers per region. These are internally stored as a map of
314 // the initial last region instruction to region live out registers, but can
315 // be retreived with the regionIdx by calls to getLiveRegsForRegionIdx.
316 RegionPressureMap RegionLiveOuts;
317
318 // Return current region pressure.
319 GCNRegPressure getRealRegPressure(unsigned RegionIdx) const;
320
321 // Compute and cache live-ins and pressure for all regions in block.
322 void computeBlockPressure(unsigned RegionIdx, const MachineBasicBlock *MBB);
323
324 /// Makes the scheduler try to achieve an occupancy of \p TargetOccupancy.
325 void setTargetOccupancy(unsigned TargetOccupancy);
326
327 void runSchedStages();
328
329 std::unique_ptr<GCNSchedStage> createSchedStage(GCNSchedStageID SchedStageID);
330
331 void deleteMI(unsigned RegionIdx, MachineInstr *MI);
332
333public:
335 std::unique_ptr<MachineSchedStrategy> S);
336
337 void schedule() override;
338
339 void finalizeSchedule() override;
340};
341
342// GCNSchedStrategy applies multiple scheduling stages to a function.
344protected:
346
348
350
352
354
356
357 // The current block being scheduled.
359
360 // Current region index.
361 unsigned RegionIdx = 0;
362
363 // Record the original order of instructions before scheduling.
364 std::vector<MachineInstr *> Unsched;
365
366 // RP before scheduling the current region.
368
369 // RP after scheduling the current region.
371
372 std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations;
373
375
376public:
377 // Initialize state for a scheduling stage. Returns false if the current stage
378 // should be skipped.
379 virtual bool initGCNSchedStage();
380
381 // Finalize state after finishing a scheduling pass on the function.
382 virtual void finalizeGCNSchedStage();
383
384 // Setup for scheduling a region. Returns false if the current region should
385 // be skipped.
386 virtual bool initGCNRegion();
387
388 // Finalize state after scheduling a region.
389 virtual void finalizeGCNRegion();
390
391 // Track whether a new region is also a new MBB.
392 void setupNewBlock();
393
394 // Check result of scheduling.
395 void checkScheduling();
396
397 // computes the given schedule virtual execution time in clocks
398 ScheduleMetrics getScheduleMetrics(const std::vector<SUnit> &InputSchedule);
400 unsigned computeSUnitReadyCycle(const SUnit &SU, unsigned CurrCycle,
401 DenseMap<unsigned, unsigned> &ReadyCycles,
402 const TargetSchedModel &SM);
403
404 // Returns true if scheduling should be reverted.
405 virtual bool shouldRevertScheduling(unsigned WavesAfter);
406
407 // Returns true if current region has known excess pressure.
408 bool isRegionWithExcessRP() const {
409 return DAG.RegionsWithExcessRP[RegionIdx];
410 }
411
412 // The region number this stage is currently working on
413 unsigned getRegionIdx() { return RegionIdx; }
414
415 // Returns true if the new schedule may result in more spilling.
416 bool mayCauseSpilling(unsigned WavesAfter);
417
418 /// Sets the schedule of region \p RegionIdx to \p MIOrder. The MIs in \p
419 /// MIOrder must be exactly the same as the ones currently existing inside the
420 /// region, only in a different order that honors def-use chains.
421 void modifyRegionSchedule(unsigned RegionIdx,
423
425
426 virtual ~GCNSchedStage() = default;
427};
428
436
438private:
439 // Record regions with excess archvgpr register pressure over the physical
440 // register limit. Register pressure in these regions usually will result in
441 // spilling.
442 BitVector RegionsWithExcessArchVGPR;
443
444 const SIInstrInfo *TII;
445 const SIRegisterInfo *SRI;
446
447 /// Do a speculative rewrite and collect copy locations. The speculative
448 /// rewrite allows us to calculate the RP of the code after the rewrite, and
449 /// the copy locations allow us to calculate the total cost of copies required
450 /// for the rewrite. Stores the rewritten instructions in \p RewriteCands ,
451 /// the copy locations for uses (of the MFMA result) in \p CopyForUse and the
452 /// copy locations for defs (of the MFMA operands) in \p CopyForDef
453 bool
454 initHeuristics(std::vector<std::pair<MachineInstr *, unsigned>> &RewriteCands,
455 DenseMap<MachineBasicBlock *, std::set<Register>> &CopyForUse,
457
458 /// Calculate the rewrite cost and undo the state change (e.g. rewriting) done
459 /// in initHeuristics. Uses \p CopyForUse and \p CopyForDef to calculate copy
460 /// costs, and \p RewriteCands to undo rewriting.
461 int64_t getRewriteCost(
462 const std::vector<std::pair<MachineInstr *, unsigned>> &RewriteCands,
463 const DenseMap<MachineBasicBlock *, std::set<Register>> &CopyForUse,
464 const SmallPtrSetImpl<MachineInstr *> &CopyForDef);
465
466 /// Do the final rewrite on \p RewriteCands and insert any needed copies.
467 bool
468 rewrite(const std::vector<std::pair<MachineInstr *, unsigned>> &RewriteCands);
469
470 /// \returns true if this MI is a rewrite candidate.
471 bool isRewriteCandidate(MachineInstr *MI) const;
472
473 /// Finds all the reaching defs of \p UseMO and stores the SlotIndexes into \p
474 /// DefIdxs
475 void findReachingDefs(MachineOperand &UseMO, LiveIntervals *LIS,
477
478 /// Finds all the reaching uses of \p DefMI and stores the use operands in \p
479 /// ReachingUses
480 void findReachingUses(MachineInstr *DefMI, LiveIntervals *LIS,
482
483public:
484 bool initGCNSchedStage() override;
485
488};
489
491private:
492 // Save the initial occupancy before starting this stage.
493 unsigned InitialOccupancy;
494 // Save the temporary target occupancy before starting this stage.
495 unsigned TempTargetOccupancy;
496 // Track whether any region was scheduled by this stage.
497 bool IsAnyRegionScheduled;
498
499public:
500 bool initGCNSchedStage() override;
501
502 void finalizeGCNSchedStage() override;
503
504 bool initGCNRegion() override;
505
506 bool shouldRevertScheduling(unsigned WavesAfter) override;
507
510};
511
512// Retry function scheduling if we found resulting occupancy and it is
513// lower than used for other scheduling passes. This will give more freedom
514// to schedule low register pressure blocks.
516public:
517 bool initGCNSchedStage() override;
518
519 bool initGCNRegion() override;
520
521 bool shouldRevertScheduling(unsigned WavesAfter) override;
522
525};
526
527/// Attempts to reduce function spilling or, if there is no spilling, to
528/// increase function occupancy by one with respect to register usage by sinking
529/// rematerializable instructions to their use. When the stage estimates that
530/// reducing spilling or increasing occupancy is possible, it tries to
531/// rematerialize as few registers as possible to reduce potential negative
532/// effects on function latency.
533///
534/// The stage only supports rematerializing registers that meet all of the
535/// following constraints.
536/// 1. The register is virtual and has a single defining instruction.
537/// 2. The single defining instruction is either deemed rematerializable by the
538/// target-independent logic, or if not, has no non-constant and
539/// non-ignorable physical register use.
540/// 3 The register has no virtual register use whose live range would be
541/// extended by the rematerialization.
542/// 4. The register has a single non-debug user in a different region from its
543/// defining region.
544/// 5. The register is not used by or using another register that is going to be
545/// rematerialized.
547private:
548 /// A rematerializable register.
549 struct RematReg {
550 /// Single MI defining the rematerializable register.
552 /// Single user of the rematerializable register.
554 /// Defining and using regions.
555 unsigned DefRegion, UseRegion;
556 /// The rematerializable register's lane bitmask.
557 LaneBitmask Mask;
558
561 const DenseMap<MachineInstr *, unsigned> &MIRegion);
562
563 /// Returns the rematerializable register. Do not call after deleting the
564 /// original defining instruction.
565 Register getReg() const { return DefMI->getOperand(0).getReg(); }
566 };
567
568 /// A scored rematerialization candidate. Higher scores indicate more
569 /// beneficial rematerializations. A null score indicate the rematerialization
570 /// is not helpful to reduce RP in target regions.
571 struct ScoredRemat {
572 /// The rematerializable register under consideration.
573 RematReg *Remat;
574 /// Regions in which the register is live-in/live-out/live anywhere.
575 BitVector LiveIn, LiveOut, Live;
576 /// Subset of \ref Live regions in which the rematerialization is not
577 /// guaranteed to reduce RP (i.e., regions in which the register is not
578 /// live-through and unused).
579 BitVector UnpredictableRPSave;
580 /// Expected register pressure decrease induced by rematerializing this
581 /// candidate.
582 GCNRegPressure RPSave;
583
584 /// Execution frequency information required by scoring heuristics.
585 /// Frequencies are scaled down if they are high to avoid overflow/underflow
586 /// when combining them.
587 struct FreqInfo {
588 /// Per-region execution frequencies. 0 when unknown.
590 /// Minimum and maximum observed frequencies.
592
594
595 private:
596 static const uint64_t ScaleFactor = 1024;
597 };
598
599 /// Initializes the candidate with state-independent characteristics for a
600 /// particular \p Remat. This doesn't update the actual score (call \ref
601 /// update for this).
602 void init(RematReg *Remat, const FreqInfo &Freq, GCNScheduleDAGMILive &DAG);
603
604 /// Rematerializes the candidate at its use and returns the new MI.
605 MachineInstr *rematerialize(GCNScheduleDAGMILive &DAG) const;
606
607 /// Determines whether this rematerialization may be beneficial in at least
608 /// one target region.
609 bool maybeBeneficial(const BitVector &TargetRegions,
610 ArrayRef<GCNRPTarget> RPTargets) const;
611
612 /// Updates internal structures following a MI rematerialization. Part of
613 /// the stage instead of the DAG because it makes assumptions that are
614 /// specific to the rematerialization process.
615 void insertMI(unsigned RegionIdx, MachineInstr *RematMI,
617
618 /// Rematerializes the candidate and returns the new MI. This removes the
619 /// rematerialized register from live-in/out lists in the \p DAG and updates
620 /// \p RPTargets in all affected regions. Regions in which RP savings are
621 /// not guaranteed are set in \p RecomputeRP.
622 MachineInstr *rematerialize(BitVector &RecomputeRP,
625
626 /// Updates the rematerialization's score w.r.t. the current \p RPTargets.
627 /// \p RegionFreq indicates the frequency of each region.
628 void update(const BitVector &TargetRegions, ArrayRef<GCNRPTarget> RPTargets,
629 const FreqInfo &Freq, bool ReduceSpill);
630
631 /// Returns whether the current score is null, indicating the
632 /// rematerialization is useless.
633 bool hasNullScore() const { return !RegionImpact; }
634
635 /// Compare score components of non-null scores pair-wise. Scores shouldn't
636 /// be null (as defined by \ref hasNullScore).
637 bool operator<(const ScoredRemat &O) const {
638 assert(!hasNullScore() && "this has null score");
639 assert(!O.hasNullScore() && "other has null score");
640 if (MaxFreq != O.MaxFreq)
641 return MaxFreq < O.MaxFreq;
642 if (FreqDiff != O.FreqDiff)
643 return FreqDiff < O.FreqDiff;
644 if (RegionImpact != O.RegionImpact)
645 return RegionImpact < O.RegionImpact;
646 // Break ties using pointer to rematerializable register. Rematerializable
647 // registers are collected in instruction order so, within the same
648 // region, this will prefer registers defined earlier that have longer
649 // live ranges in their defining region (since the registers we consider
650 // are always live-out in their defining region).
651 return Remat > O.Remat;
652 }
653
654#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
655 Printable print() const;
656#endif
657
658 private:
659 // The three members below are the scoring components, top to bottom from
660 // most important to least important when comparing candidates.
661
662 /// Frequency of impacted target region with highest known frequency. This
663 /// only matters when the stage is trying to reduce spilling, so it is
664 /// always 0 when it is not.
665 uint64_t MaxFreq;
666 /// Frequency difference between defining and using regions. Negative values
667 /// indicate we are rematerializing to higher frequency regions; positive
668 /// values indicate the contrary.
669 int64_t FreqDiff;
670 /// Expected number of target regions impacted by the rematerialization,
671 /// scaled by the size of the register being rematerialized.
672 unsigned RegionImpact;
673 };
674
675 /// Register pressure targets for all regions.
676 SmallVector<GCNRPTarget> RPTargets;
677 /// Regions which are above the stage's RP target.
678 BitVector TargetRegions;
679 /// The target occupancy the set is trying to achieve. Empty when the
680 /// objective is spilling reduction.
681 std::optional<unsigned> TargetOcc;
682 /// Achieved occupancy *only* through rematerializations (pre-rescheduling).
683 unsigned AchievedOcc;
684 /// After successful stage initialization, indicates which regions should be
685 /// rescheduled.
686 BitVector RescheduleRegions;
687
688 /// List of rematerializable registers.
689 SmallVector<RematReg> RematRegs;
690
691 /// Holds enough information to rollback a rematerialization decision post
692 /// re-scheduling.
693 struct RollbackInfo {
694 /// The rematerializable register under consideration.
695 const RematReg *Remat;
696 /// Regions in which the original register was live-in or live-out.
697 BitVector LiveIn, LiveOut;
698 /// The rematerialized MI replacing the original defining MI.
699 MachineInstr *RematMI;
700 /// Maps register machine operand indices to their original register.
701 SmallDenseMap<unsigned, Register, 4> RegMap;
702
703 RollbackInfo(const RematReg *Remat, const BitVector &LiveIn,
704 const BitVector &LiveOut)
705 : Remat(Remat), LiveIn(LiveIn), LiveOut(LiveOut) {}
706 };
707 /// List of rematerializations to rollback if rematerialization does not end
708 /// up being beneficial.
709 SmallVector<RollbackInfo> Rollbacks;
710
711 /// State of a region pre-re-scheduling but post-rematerializations that we
712 /// must keep to be able to revert re-scheduling effects.
713 struct RegionSchedRevert {
714 /// Region number;
715 unsigned RegionIdx;
716 /// Original instruction order (both debug and non-debug MIs).
717 std::vector<MachineInstr *> OrigMIOrder;
718 /// Maximum pressure recorded in the region.
719 GCNRegPressure MaxPressure;
720
721 RegionSchedRevert(unsigned RegionIdx, ArrayRef<MachineInstr *> OrigMIOrder,
722 const GCNRegPressure &MaxPressure)
723 : RegionIdx(RegionIdx), OrigMIOrder(OrigMIOrder),
724 MaxPressure(MaxPressure) {}
725 };
726 /// After re-scheduling, contains pre-re-scheduling data for all re-scheduled
727 /// regions.
728 SmallVector<RegionSchedRevert> RegionReverts;
729 /// Whether we should revert all re-scheduled regions.
730 bool RevertAllRegions = false;
731
732 /// Returns the occupancy the stage is trying to achieve.
733 unsigned getStageTargetOccupancy() const;
734
735 /// Determines the stage's objective (increasing occupancy or reducing
736 /// spilling, set in \ref TargetOcc). Defines \ref RPTargets in all regions to
737 /// achieve that objective and mark those that don't achieve it in \ref
738 /// TargetRegions. Returns whether there is any target region.
739 bool setObjective();
740
741 /// In all regions set in \p Regions, saves pressure \p RPSave and clear it as
742 /// a target if its RP target has been reached.
743 void updateRPTargets(const BitVector &Regions, const GCNRegPressure &RPSave);
744
745 /// Fully recomputes RP from the DAG in \p Regions. Among those regions, sets
746 /// again all \ref TargetRegions that were optimistically marked as satisfied
747 /// but are actually not, and returns whether there were any such regions.
748 bool updateAndVerifyRPTargets(const BitVector &Regions);
749
750 /// Collects all rematerializable registers and appends them to \ref
751 /// RematRegs. \p MIRegion maps MIs to their region. Returns whether any
752 /// rematerializable register was found.
753 bool collectRematRegs(const DenseMap<MachineInstr *, unsigned> &MIRegion);
754
755 /// Deletes all rematerialized MIs from the MIR when they were kept around for
756 /// potential rollback.
757 void commitRematerializations() const;
758
759 /// Whether the MI is rematerializable
760 bool isReMaterializable(const MachineInstr &MI);
761
762 /// Removes register \p Reg from the live-ins of regions set in \p LiveIn and
763 /// the live-outs of regions set in \p LiveOut.
764 void removeFromLiveMaps(Register Reg, const BitVector &LiveIn,
765 const BitVector &LiveOut);
766
767 /// Adds register \p Reg with mask \p Mask to the live-ins of regions set in
768 /// \p LiveIn and the live-outs of regions set in \p LiveOut.
769 void addToLiveMaps(Register Reg, LaneBitmask Mask, const BitVector &LiveIn,
770 const BitVector &LiveOut);
771
772 /// If remat alone did not increase occupancy to the target one, rollbacks all
773 /// rematerializations and resets live-ins/RP in all regions impacted by the
774 /// stage to their pre-stage values.
775 void finalizeGCNSchedStage() override;
776
777public:
778 bool initGCNSchedStage() override;
779
780 bool initGCNRegion() override;
781
782 void finalizeGCNRegion() override;
783
784 bool shouldRevertScheduling(unsigned WavesAfter) override;
785
787 : GCNSchedStage(StageID, DAG), TargetRegions(DAG.Regions.size()),
788 RescheduleRegions(DAG.Regions.size()) {
789 const unsigned NumRegions = DAG.Regions.size();
790 RPTargets.reserve(NumRegions);
791 }
792};
793
801
810
812private:
813 std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations;
814
815 bool HasIGLPInstrs = false;
816
817public:
818 void schedule() override;
819
820 void finalizeSchedule() override;
821
823 std::unique_ptr<MachineSchedStrategy> S,
824 bool RemoveKillFlags);
825};
826
827} // End namespace llvm
828
829#endif // LLVM_LIB_TARGET_AMDGPU_GCNSCHEDSTRATEGY_H
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file defines the DenseMap class.
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
IRTranslator LLVM IR MI
Register Reg
Promote Memory to Register
Definition Mem2Reg.cpp:110
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static constexpr unsigned SM(unsigned Version)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool shouldRevertScheduling(unsigned WavesAfter) override
ClusteredLowOccStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
GCNMaxILPSchedStrategy(const MachineSchedContext *C)
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const override
Apply a set of heuristics to a new candidate.
bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const override
GCNMaxMemoryClauseSchedStrategy tries best to clause memory instructions as much as possible.
GCNMaxMemoryClauseSchedStrategy(const MachineSchedContext *C)
GCNMaxOccupancySchedStrategy(const MachineSchedContext *C, bool IsLegacyScheduler=false)
void finalizeSchedule() override
Allow targets to perform final scheduling actions at the level of the whole MachineFunction.
void schedule() override
Orders nodes according to selected style.
GCNPostScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S, bool RemoveKillFlags)
DenseMap< unsigned, LaneBitmask > LiveRegSet
GCNSchedStrategy & S
GCNRegPressure PressureBefore
bool isRegionWithExcessRP() const
void modifyRegionSchedule(unsigned RegionIdx, ArrayRef< MachineInstr * > MIOrder)
Sets the schedule of region RegionIdx to MIOrder.
bool mayCauseSpilling(unsigned WavesAfter)
ScheduleMetrics getScheduleMetrics(const std::vector< SUnit > &InputSchedule)
GCNScheduleDAGMILive & DAG
const GCNSchedStageID StageID
std::vector< MachineInstr * > Unsched
GCNRegPressure PressureAfter
MachineFunction & MF
virtual void finalizeGCNRegion()
SIMachineFunctionInfo & MFI
unsigned computeSUnitReadyCycle(const SUnit &SU, unsigned CurrCycle, DenseMap< unsigned, unsigned > &ReadyCycles, const TargetSchedModel &SM)
virtual ~GCNSchedStage()=default
virtual void finalizeGCNSchedStage()
virtual bool initGCNSchedStage()
virtual bool shouldRevertScheduling(unsigned WavesAfter)
std::vector< std::unique_ptr< ScheduleDAGMutation > > SavedMutations
GCNSchedStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
MachineBasicBlock * CurrentMBB
const GCNSubtarget & ST
This is a minimal scheduler strategy.
const unsigned HighRPSGPRBias
GCNDownwardRPTracker DownwardTracker
void getRegisterPressures(bool AtTop, const RegPressureTracker &RPTracker, SUnit *SU, std::vector< unsigned > &Pressure, std::vector< unsigned > &MaxPressure, GCNDownwardRPTracker &DownwardTracker, GCNUpwardRPTracker &UpwardTracker, ScheduleDAGMI *DAG, const SIRegisterInfo *SRI)
GCNSchedStrategy(const MachineSchedContext *C)
SmallVector< GCNSchedStageID, 4 > SchedStages
std::vector< unsigned > MaxPressure
SUnit * pickNodeBidirectional(bool &IsTopNode, bool &PickedPending)
GCNSchedStageID getCurrentStage()
bool tryPendingCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const
Evaluates instructions in the pending queue using a subset of scheduling heuristics.
SmallVectorImpl< GCNSchedStageID >::iterator CurrentStage
void schedNode(SUnit *SU, bool IsTopNode) override
Notify MachineSchedStrategy that ScheduleDAGMI has scheduled an instruction and updated scheduled/rem...
std::optional< bool > GCNTrackersOverride
GCNDownwardRPTracker * getDownwardTracker()
std::vector< unsigned > Pressure
void initialize(ScheduleDAGMI *DAG) override
Initialize the strategy after building the DAG for a new region.
GCNUpwardRPTracker UpwardTracker
void printCandidateDecision(const SchedCandidate &Current, const SchedCandidate &Preferred)
const unsigned HighRPVGPRBias
void pickNodeFromQueue(SchedBoundary &Zone, const CandPolicy &ZonePolicy, const RegPressureTracker &RPTracker, SchedCandidate &Cand, bool &IsPending, bool IsBottomUp)
unsigned getStructuralStallCycles(SchedBoundary &Zone, SUnit *SU) const
Estimate how many cycles SU must wait due to structural hazards at the current boundary cycle.
void initCandidate(SchedCandidate &Cand, SUnit *SU, bool AtTop, const RegPressureTracker &RPTracker, const SIRegisterInfo *SRI, unsigned SGPRPressure, unsigned VGPRPressure, bool IsBottomUp)
void setTargetOccupancy(unsigned Occ)
SUnit * pickNode(bool &IsTopNode) override
Pick the next node to schedule, or return NULL.
GCNUpwardRPTracker * getUpwardTracker()
GCNSchedStageID getNextStage() const
void finalizeSchedule() override
Allow targets to perform final scheduling actions at the level of the whole MachineFunction.
void schedule() override
Orders nodes according to selected style.
GCNScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)
ScheduleDAGMILive * DAG
GenericScheduler(const MachineSchedContext *C)
bool shouldRevertScheduling(unsigned WavesAfter) override
ILPInitialScheduleStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
Representation of each machine instruction.
MachineOperand class - Representation of each machine instruction operand.
bool shouldRevertScheduling(unsigned WavesAfter) override
MemoryClauseInitialScheduleStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
bool shouldRevertScheduling(unsigned WavesAfter) override
OccInitialScheduleStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
PreRARematStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
bool shouldRevertScheduling(unsigned WavesAfter) override
void finalizeGCNRegion() override
bool initGCNSchedStage() override
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
Track the current register pressure at some position in the instruction stream, and remember the high...
GCNRPTracker::LiveRegSet & getLiveRegsForRegionIdx(unsigned RegionIdx)
RegionPressureMap(GCNScheduleDAGMILive *GCNDAG, bool LiveOut)
Wrapper class representing virtual and physical registers.
Definition Register.h:20
RewriteMFMAFormStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Scheduling unit. This is a node in the scheduling DAG.
Each Scheduling boundary is associated with ready queues.
bool RemoveKillFlags
True if the DAG builder should remove kill flags (in preparation for rescheduling).
ScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
ScheduleDAGMI(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S, bool RemoveKillFlags)
unsigned getBubbles() const
ScheduleMetrics(unsigned L, unsigned BC)
unsigned getLength() const
static const unsigned ScaleFactor
unsigned getMetric() const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
typename SuperClass::iterator iterator
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Provide an instruction scheduling machine model to CodeGen passes.
UnclusteredHighRPStage(GCNSchedStageID StageID, GCNScheduleDAGMILive &DAG)
bool shouldRevertScheduling(unsigned WavesAfter) override
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
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
std::pair< MachineBasicBlock::iterator, MachineBasicBlock::iterator > RegionBoundaries
A region's boundaries i.e.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
Policy for scheduling the next instruction in the candidate's zone.
Store the state used by GenericScheduler heuristics, required for the lifetime of one invocation of p...
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
Execution frequency information required by scoring heuristics.
SmallVector< uint64_t > Regions
Per-region execution frequencies. 0 when unknown.
uint64_t MinFreq
Minimum and maximum observed frequencies.
FreqInfo(MachineFunction &MF, const GCNScheduleDAGMILive &DAG)