Go to the documentation of this file.
18 #define DEBUG_TYPE "machine-scheduler"
25 HasExcessPressure(
false), MF(nullptr) { }
36 const unsigned ErrorMargin = 3;
49 std::min(
ST.getMaxNumSGPRs(TargetOccupancy,
true), SGPRExcessLimit);
51 std::min(
ST.getMaxNumVGPRs(TargetOccupancy), VGPRExcessLimit);
55 std::min(SGPRCriticalLimit - ErrorMargin, SGPRCriticalLimit);
57 std::min(VGPRCriticalLimit - ErrorMargin, VGPRCriticalLimit);
58 SGPRExcessLimit =
std::min(SGPRExcessLimit - ErrorMargin, SGPRExcessLimit);
59 VGPRExcessLimit =
std::min(VGPRExcessLimit - ErrorMargin, VGPRExcessLimit);
62 void GCNMaxOccupancySchedStrategy::initCandidate(SchedCandidate &Cand,
SUnit *SU,
65 unsigned SGPRPressure,
66 unsigned VGPRPressure) {
86 unsigned NewSGPRPressure = Pressure[AMDGPU::RegisterPressureSets::SReg_32];
87 unsigned NewVGPRPressure = Pressure[AMDGPU::RegisterPressureSets::VGPR_32];
97 const unsigned MaxVGPRPressureInc = 16;
98 bool ShouldTrackVGPRs = VGPRPressure + MaxVGPRPressureInc >= VGPRExcessLimit;
99 bool ShouldTrackSGPRs = !ShouldTrackVGPRs && SGPRPressure >= SGPRExcessLimit;
111 if (ShouldTrackVGPRs && NewVGPRPressure >= VGPRExcessLimit) {
112 HasExcessPressure =
true;
113 Cand.RPDelta.Excess =
PressureChange(AMDGPU::RegisterPressureSets::VGPR_32);
114 Cand.RPDelta.Excess.setUnitInc(NewVGPRPressure - VGPRExcessLimit);
117 if (ShouldTrackSGPRs && NewSGPRPressure >= SGPRExcessLimit) {
118 HasExcessPressure =
true;
119 Cand.RPDelta.Excess =
PressureChange(AMDGPU::RegisterPressureSets::SReg_32);
120 Cand.RPDelta.Excess.setUnitInc(NewSGPRPressure - SGPRExcessLimit);
128 int SGPRDelta = NewSGPRPressure - SGPRCriticalLimit;
129 int VGPRDelta = NewVGPRPressure - VGPRCriticalLimit;
131 if (SGPRDelta >= 0 || VGPRDelta >= 0) {
132 HasExcessPressure =
true;
133 if (SGPRDelta > VGPRDelta) {
134 Cand.RPDelta.CriticalMax =
136 Cand.RPDelta.CriticalMax.setUnitInc(SGPRDelta);
138 Cand.RPDelta.CriticalMax =
140 Cand.RPDelta.CriticalMax.setUnitInc(VGPRDelta);
147 void GCNMaxOccupancySchedStrategy::pickNodeFromQueue(
SchedBoundary &Zone,
148 const CandPolicy &ZonePolicy,
150 SchedCandidate &Cand) {
153 unsigned SGPRPressure = Pressure[AMDGPU::RegisterPressureSets::SReg_32];
154 unsigned VGPRPressure = Pressure[AMDGPU::RegisterPressureSets::VGPR_32];
156 for (
SUnit *SU : Q) {
158 SchedCandidate TryCand(ZonePolicy);
159 initCandidate(TryCand, SU, Zone.
isTop(), RPTracker, SRI,
160 SGPRPressure, VGPRPressure);
162 SchedBoundary *ZoneArg = Cand.AtTop == TryCand.AtTop ? &Zone :
nullptr;
164 if (TryCand.Reason !=
NoCand) {
166 if (TryCand.ResDelta == SchedResourceDelta())
168 Cand.setBest(TryCand);
176 SUnit *GCNMaxOccupancySchedStrategy::pickNodeBidirectional(
bool &IsTopNode) {
189 CandPolicy BotPolicy;
193 CandPolicy TopPolicy;
207 SchedCandidate TCand;
208 TCand.reset(CandPolicy());
211 "Last pick result should correspond to re-picking right now");
227 SchedCandidate TCand;
228 TCand.reset(CandPolicy());
231 "Last pick result should correspond to re-picking right now");
247 IsTopNode = Cand.AtTop;
282 SU = pickNodeBidirectional(IsTopNode);
294 HasClusteredNodes =
true;
306 std::unique_ptr<MachineSchedStrategy>
S) :
310 StartingOccupancy(MFI.getOccupancy()),
311 MinOccupancy(StartingOccupancy), Stage(Collect), RegionIdx(0) {
313 LLVM_DEBUG(
dbgs() <<
"Starting occupancy is " << StartingOccupancy <<
".\n");
317 if (Stage == Collect) {
323 std::vector<MachineInstr*> Unsched;
325 for (
auto &
I : *
this) {
326 Unsched.push_back(&
I);
331 PressureBefore = Pressure[RegionIdx];
333 LLVM_DEBUG(
dbgs() <<
"Pressure before scheduling:\nRegion live-ins:";
335 dbgs() <<
"Region live-in pressure: ";
337 dbgs() <<
"Region register pressure: ";
344 S.HasClusteredNodes = Stage > InitialSchedule;
345 S.HasExcessPressure =
false;
348 RescheduleRegions[RegionIdx] =
false;
349 if (Stage == InitialSchedule &&
S.HasClusteredNodes)
350 RegionsWithClusters[RegionIdx] =
true;
351 if (
S.HasExcessPressure)
352 RegionsWithHighRP[RegionIdx] =
true;
358 auto PressureAfter = getRealRegPressure();
361 PressureAfter.print(
dbgs()));
363 if (PressureAfter.getSGPRNum() <=
S.SGPRCriticalLimit &&
364 PressureAfter.getVGPRNum(ST.
hasGFX90AInsts()) <=
S.VGPRCriticalLimit) {
365 Pressure[RegionIdx] = PressureAfter;
366 RegionsWithMinOcc[RegionIdx] =
367 PressureAfter.getOccupancy(ST) == MinOccupancy;
373 unsigned WavesAfter =
374 std::min(
S.TargetOccupancy, PressureAfter.getOccupancy(ST));
375 unsigned WavesBefore =
377 LLVM_DEBUG(
dbgs() <<
"Occupancy before scheduling: " << WavesBefore
378 <<
", after " << WavesAfter <<
".\n");
384 unsigned NewOccupancy =
std::max(WavesAfter, WavesBefore);
388 if (WavesAfter < WavesBefore && WavesAfter < MinOccupancy &&
390 LLVM_DEBUG(
dbgs() <<
"Function is memory bound, allow occupancy drop up to "
392 NewOccupancy = WavesAfter;
395 if (NewOccupancy < MinOccupancy) {
396 MinOccupancy = NewOccupancy;
398 RegionsWithMinOcc.
reset();
400 << MinOccupancy <<
".\n");
405 if (PressureAfter.getVGPRNum(
false) > MaxVGPRs ||
406 PressureAfter.getAGPRNum() > MaxVGPRs ||
407 PressureAfter.getSGPRNum() > MaxSGPRs) {
408 RescheduleRegions[RegionIdx] =
true;
409 RegionsWithHighRP[RegionIdx] =
true;
417 if (WavesAfter >= MinOccupancy) {
418 if (Stage == UnclusteredReschedule &&
419 !PressureAfter.less(ST, PressureBefore)) {
422 PressureAfter.less(ST, PressureBefore) ||
423 !RescheduleRegions[RegionIdx]) {
424 Pressure[RegionIdx] = PressureAfter;
425 RegionsWithMinOcc[RegionIdx] =
426 PressureAfter.getOccupancy(ST) == MinOccupancy;
427 if (!RegionsWithClusters[RegionIdx] &&
428 (Stage + 1) == UnclusteredReschedule)
429 RescheduleRegions[RegionIdx] =
false;
432 LLVM_DEBUG(
dbgs() <<
"New pressure will result in more spilling.\n");
436 RegionsWithMinOcc[RegionIdx] =
439 RescheduleRegions[RegionIdx] = RegionsWithClusters[RegionIdx] ||
440 (Stage + 1) != UnclusteredReschedule;
442 int SkippedDebugInstr = 0;
444 if (
MI->isDebugInstr()) {
452 if (!
MI->isDebugInstr())
456 for (
auto &
Op :
MI->operands())
457 if (
Op.isReg() &&
Op.isDef())
458 Op.setIsUndef(
false);
461 if (!
MI->isDebugInstr()) {
479 while (SkippedDebugInstr-- > 0)
488 if (
MI->isDebugInstr())
522 size_t CurRegion = RegionIdx;
523 for (
size_t E = Regions.size(); CurRegion !=
E; ++CurRegion)
524 if (Regions[CurRegion].first->getParent() !=
MBB)
529 auto LiveInIt = MBBLiveIns.find(
MBB);
530 auto &Rgn = Regions[CurRegion];
532 if (LiveInIt != MBBLiveIns.end()) {
533 auto LiveIn =
std::move(LiveInIt->second);
535 MBBLiveIns.erase(LiveInIt);
538 auto LRS = BBLiveInMap.lookup(NonDbgMI);
539 #ifdef EXPENSIVE_CHECKS
548 if (Regions[CurRegion].first ==
I || NonDbgMI ==
I) {
549 LiveIns[CurRegion] =
RPTracker.getLiveRegs();
553 if (Regions[CurRegion].second ==
I) {
554 Pressure[CurRegion] =
RPTracker.moveMaxPressure();
555 if (CurRegion-- == RegionIdx)
569 MBBLiveIns[OnlySucc] =
RPTracker.moveLiveRegs();
574 GCNScheduleDAGMILive::getBBLiveInMap()
const {
576 std::vector<MachineInstr *> BBStarters;
577 BBStarters.reserve(Regions.size());
578 auto I = Regions.rbegin(),
E = Regions.rend();
579 auto *
BB =
I->first->getParent();
582 BBStarters.push_back(
MI);
585 }
while (
I !=
E &&
I->first->getParent() ==
BB);
591 LLVM_DEBUG(
dbgs() <<
"All regions recorded, starting actual scheduling.\n");
593 LiveIns.resize(Regions.size());
594 Pressure.resize(Regions.size());
595 RescheduleRegions.
resize(Regions.size());
596 RegionsWithClusters.
resize(Regions.size());
597 RegionsWithHighRP.
resize(Regions.size());
598 RegionsWithMinOcc.
resize(Regions.size());
599 RescheduleRegions.
set();
600 RegionsWithClusters.
reset();
601 RegionsWithHighRP.
reset();
602 RegionsWithMinOcc.
reset();
604 if (!Regions.empty())
605 BBLiveInMap = getBBLiveInMap();
607 std::vector<std::unique_ptr<ScheduleDAGMutation>> SavedMutations;
614 if (Stage > InitialSchedule) {
623 if (Stage == UnclusteredReschedule) {
624 if (RescheduleRegions.
none())
627 "Retrying function scheduling without clustering.\n");
630 if (Stage == ClusteredLowOccupancyReschedule) {
631 if (StartingOccupancy <= MinOccupancy)
636 <<
"Retrying function scheduling with lowest recorded occupancy "
637 << MinOccupancy <<
".\n");
640 if (Stage == PreRARematerialize) {
641 if (RegionsWithMinOcc.
none() || Regions.size() == 1)
655 static_assert(LastStage == PreRARematerialize,
656 "Passes after PreRARematerialize are not supported");
658 collectRematerializableInstructions();
659 if (RematerializableInsts.empty() || !sinkTriviallyRematInsts(ST,
TII))
663 dbgs() <<
"Retrying function scheduling with improved occupancy of "
664 << MinOccupancy <<
" from rematerializing\n");
668 if (Stage == UnclusteredReschedule)
671 for (
auto Region : Regions) {
672 if (((Stage == UnclusteredReschedule || Stage == PreRARematerialize) &&
673 !RescheduleRegions[RegionIdx]) ||
674 (Stage == ClusteredLowOccupancyReschedule &&
675 !RegionsWithClusters[RegionIdx] && !RegionsWithHighRP[RegionIdx])) {
688 if (Stage == InitialSchedule)
689 computeBlockPressure(
MBB);
707 else dbgs() <<
"End";
717 if (Stage == UnclusteredReschedule)
719 }
while (Stage != LastStage);
722 void GCNScheduleDAGMILive::collectRematerializableInstructions() {
736 if (
Op->getSubReg() != 0 || !isTriviallyReMaterializable(*
Def,
AA))
746 bool AddedToRematList =
false;
747 for (
unsigned I = 0,
E = Regions.size();
I !=
E; ++
I) {
748 auto It = LiveIns[
I].find(
Reg);
749 if (It != LiveIns[
I].
end() && !It->second.none()) {
750 if (RegionsWithMinOcc[
I]) {
751 RematerializableInsts[
I][
Def] = UseI;
752 AddedToRematList =
true;
757 RematDefToLiveInRegions[
Def].push_back(
I);
760 if (!AddedToRematList)
761 RematDefToLiveInRegions.erase(
Def);
765 bool GCNScheduleDAGMILive::sinkTriviallyRematInsts(
const GCNSubtarget &
ST,
770 std::pair<MachineBasicBlock::iterator, MachineBasicBlock::iterator>, 32>
776 NewRegions.
resize(Regions.size());
777 NewRescheduleRegions.
resize(Regions.size());
781 for (
const auto &It : RematDefToLiveInRegions)
782 ImpactedRegions.
insert(It.second.begin(), It.second.end());
786 for (
auto Idx : ImpactedRegions) {
787 NewPressure[Idx] = Pressure[Idx];
788 NewLiveIns[Idx] = LiveIns[Idx];
790 NewRegions = Regions;
791 NewRescheduleRegions.
reset();
794 bool Improved =
false;
795 for (
auto I : ImpactedRegions) {
796 if (!RegionsWithMinOcc[
I])
800 int VGPRUsage = NewPressure[
I].getVGPRNum(
ST.hasGFX90AInsts());
801 int SGPRUsage = NewPressure[
I].getSGPRNum();
805 if (
ST.getOccupancyWithNumSGPRs(SGPRUsage) == MinOccupancy)
810 if (NewPressure[
I].getOccupancy(ST) > MinOccupancy) {
811 NewRescheduleRegions[
I] =
true;
819 int TotalSinkableRegs = 0;
820 for (
const auto &It : RematerializableInsts[
I]) {
826 int VGPRsAfterSink = VGPRUsage - TotalSinkableRegs;
827 unsigned OptimisticOccupancy =
ST.getOccupancyWithNumVGPRs(VGPRsAfterSink);
830 if (OptimisticOccupancy <= MinOccupancy)
833 unsigned ImproveOccupancy = 0;
835 for (
auto &It : RematerializableInsts[
I]) {
845 Def->getOperand(0).getSubReg(), *
Def, *
TRI);
850 InsertedMIToOldDef[NewMI] =
Def;
854 updateRegionBoundaries(NewRegions,
Def,
nullptr,
858 updateRegionBoundaries(NewRegions, InsertPos, NewMI);
864 for (
auto Idx : RematDefToLiveInRegions[
Def]) {
866 if (InsertPos->getParent() != Regions[Idx].first->getParent()) {
873 NewRegions[Idx].first, NewRegions[Idx].second);
874 RPT.reset(*NonDbgMI, &NewLiveIns[Idx]);
875 RPT.advance(NewRegions[Idx].second);
876 NewPressure[Idx] = RPT.moveMaxPressure();
880 SinkedDefs.push_back(
Def);
881 ImproveOccupancy = NewPressure[
I].getOccupancy(ST);
882 if (ImproveOccupancy > MinOccupancy)
887 for (
auto &
Def : SinkedDefs)
888 for (
auto TrackedIdx : RematDefToLiveInRegions[
Def])
889 RematerializableInsts[TrackedIdx].erase(
Def);
891 if (ImproveOccupancy <= MinOccupancy)
894 NewRescheduleRegions[
I] =
true;
901 for (
auto &Entry : InsertedMIToOldDef) {
906 MI->eraseFromParent();
915 for (
auto &Entry : InsertedMIToOldDef) {
920 BBLiveInMap.erase(OldMI);
931 for (
auto Idx : ImpactedRegions) {
932 LiveIns[Idx] = NewLiveIns[Idx];
933 Pressure[Idx] = NewPressure[Idx];
934 MBBLiveIns.erase(Regions[Idx].first->getParent());
936 Regions = NewRegions;
937 RescheduleRegions = NewRescheduleRegions;
946 bool GCNScheduleDAGMILive::isTriviallyReMaterializable(
const MachineInstr &
MI,
952 if (MO.isReg() && MO.isUse() && MO.getReg().isVirtual())
962 void GCNScheduleDAGMILive::updateRegionBoundaries(
966 unsigned I = 0,
E = RegionBoundaries.size();
968 while (
I !=
E &&
MI->getParent() != RegionBoundaries[
I].first->getParent())
971 for (;
I !=
E; ++
I) {
972 if (
MI->getParent() != RegionBoundaries[
I].first->getParent())
975 if (Removing &&
MI == RegionBoundaries[
I].first &&
976 MI == RegionBoundaries[
I].second) {
979 RegionBoundaries[
I] =
980 std::make_pair(
MI->getParent()->end(),
MI->getParent()->end());
983 if (
MI == RegionBoundaries[
I].first) {
985 RegionBoundaries[
I] =
986 std::make_pair(std::next(
MI), RegionBoundaries[
I].second);
990 RegionBoundaries[
I].second);
993 if (Removing &&
MI == RegionBoundaries[
I].second) {
994 RegionBoundaries[
I] =
995 std::make_pair(RegionBoundaries[
I].first, std::prev(
MI));
MachineRegisterInfo & MRI
Virtual/real register map.
unsigned succ_size() const
const TargetRegisterInfo * TRI
void clearRegisterDeads(Register Reg)
Clear all dead flags on operands defining register Reg.
void detectDeadDefs(const MachineInstr &MI, const LiveIntervals &LIS)
Use liveness information to find dead defs not marked with a dead flag and move them to the DeadDefs ...
This is an optimization pass for GlobalISel generic memory operations.
GCNRPTracker::LiveRegSet getLiveRegsBefore(const MachineInstr &MI, const LiveIntervals &LIS)
SlotIndexes * getSlotIndexes() const
unsigned getMinAllowedOccupancy() const
RegisterClassInfo * RegClassInfo
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
DenseMap< MachineInstr *, GCNRPTracker::LiveRegSet > getLiveRegMap(Range &&R, bool After, LiveIntervals &LIS)
creates a map MachineInstr -> LiveRegSet R - range of iterators on instructions After - upon entry or...
MachineBasicBlock::iterator begin() const
Returns an iterator to the top of the current scheduling region.
List of registers defined and used by a machine instruction.
virtual const TargetInstrInfo * getInstrInfo() const
bool none() const
none - Returns true if none of the bits are set.
void reset(const CandPolicy &NewPolicy)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void getUpwardPressure(const MachineInstr *MI, std::vector< unsigned > &PressureResult, std::vector< unsigned > &MaxPressureResult)
Get the pressure of each PSet after traversing this instruction bottom-up.
unsigned NumRegionInstrs
Instructions in this region (distance(RegionBegin, RegionEnd)).
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
const TargetSchedModel * SchedModel
Reg
All possible values of the reg field in the ModR/M byte.
virtual bool tryCandidate(SchedCandidate &Cand, SchedCandidate &TryCand, SchedBoundary *Zone) const
Apply a set of heuristics to a new candidate.
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
bool erase(const KeyT &Val)
uint32_t getLDSSize() const
void removeInterval(Register Reg)
Interval removal.
Track the current register pressure at some position in the instruction stream, and remember the high...
void setPolicy(CandPolicy &Policy, bool IsPostRA, SchedBoundary &CurrZone, SchedBoundary *OtherZone)
Set the CandPolicy given a scheduling zone given the current resources and latencies inside and outsi...
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void initialize(ScheduleDAGMI *dag) override
Initialize the strategy after building the DAG for a new region.
void increaseOccupancy(const MachineFunction &MF, unsigned Limit)
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
MachineBasicBlock::iterator end() const
Returns an iterator to the bottom of the current scheduling region.
bool isEqual(const GCNRPTracker::LiveRegSet &S1, const GCNRPTracker::LiveRegSet &S2)
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void finalizeSchedule() override
Allow targets to perform final scheduling actions at the level of the whole MachineFunction.
std::vector< std::unique_ptr< ScheduleDAGMutation > > Mutations
Ordered list of DAG postprocessing steps.
void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
SchedCandidate TopCand
Candidate last picked from Top boundary.
TargetInstrInfo - Interface to description of machine instruction set.
MachineInstr * remove(MachineInstr *I)
Remove the unbundled instruction from the instruction list without deleting it.
bool isBottomReady() const
unsigned getMaxNumSGPRs(unsigned WavesPerEU, bool Addressable) const
This is a minimal scheduler strategy.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
(vector float) vec_cmpeq(*A, *B) C
unsigned getOccupancy(const GCNSubtarget &ST) const
virtual void exitRegion()
Called when the scheduler has finished scheduling the current region.
void getDownwardPressure(const MachineInstr *MI, std::vector< unsigned > &PressureResult, std::vector< unsigned > &MaxPressureResult)
Get the pressure of each PSet after traversing this instruction top-down.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
unsigned NodeNum
Entry # of node in the node vector.
static constexpr LaneBitmask getNone()
const HexagonInstrInfo * TII
MachineOperand class - Representation of each machine instruction operand.
Policy for scheduling the next instruction in the candidate's zone.
void startBlock(MachineBasicBlock *bb) override
Prepares to perform scheduling in the given block.
MachineBasicBlock::iterator RegionEnd
The end of the range to be scheduled.
SlotIndex - An opaque wrapper around machine indexes.
unsigned getMaxNumVGPRs(unsigned WavesPerEU) const
RegPressureTracker RPTracker
MachineSchedPolicy RegionPolicy
void collect(const MachineInstr &MI, const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, bool TrackLaneMasks, bool IgnoreDead)
Analyze the given instruction MI and fill in the Uses, Defs and DeadDefs list based on the MachineOpe...
unsigned getNumAllocatableRegs(const TargetRegisterClass *RC) const
getNumAllocatableRegs - Returns the number of actually allocatable registers in RC in the current fun...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const std::vector< unsigned > & getRegSetPressureAtPos() const
Get the register set pressure at the current position, which may be less than the pressure across the...
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
Representation of each machine instruction.
static bool isVGPRClass(const TargetRegisterClass *RC)
const MachineSchedContext * Context
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
MachineSchedContext provides enough context from the MachineScheduler pass for the target to instanti...
MachineInstr * getInstr() const
Returns the representative MachineInstr for this SUnit.
void advance()
Advance across the current instruction.
bool isScheduled
True once scheduled.
unsigned getMinWavesPerEU() const
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineOperand * getOneDef(Register Reg) const
Returns the defining operand if there is exactly one operand defining the specified register,...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
succ_iterator succ_begin()
std::unique_ptr< MachineSchedStrategy > SchedImpl
bool hasGFX90AInsts() const
SchedCandidate BotCand
Candidate last picked from Bot boundary.
bool hasOneDef(Register RegNo) const
Return true if there is exactly one operand defining the specified register.
ScheduleDAGMI is an implementation of ScheduleDAGInstrs that simply schedules machine instructions ac...
void placeDebugValues()
Reinsert debug_values recorded in ScheduleDAGInstrs::DbgValues.
unsigned getOccupancy() const
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
bool isCluster() const
Tests if this is an Order dependence that is marked as "cluster", meaning it is artificial and wants ...
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
const TargetRegisterInfo * TRI
Target processor register info.
MachineInstrBundleIterator< MachineInstr > iterator
void schedule() override
Implement ScheduleDAGInstrs interface for scheduling a sequence of reorderable instructions.
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
static unsigned getNumCoveredRegs(LaneBitmask LM)
void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs) override
Implement the ScheduleDAGInstrs interface for handling the next scheduling region.
bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
const RegPressureTracker & getBotRPTracker() const
MachineFunction & MF
Machine function.
virtual void reMaterialize(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register DestReg, unsigned SubIdx, const MachineInstr &Orig, const TargetRegisterInfo &TRI) const
Re-issue the specified 'original' instruction at the specific location targeting a new destination re...
SUnit * pickNode(bool &IsTopNode) override
Pick the best node to balance the schedule. Implements MachineSchedStrategy.
void limitOccupancy(const MachineFunction &MF)
bool ShouldTrackLaneMasks
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
void traceCandidate(const SchedCandidate &Cand)
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
const MachineBasicBlock * getParent() const
GCNMaxOccupancySchedStrategy(const MachineSchedContext *C)
cl::opt< bool > VerifyScheduling
SUnit * pickOnlyChoice()
Call this before applying any other heuristics to the Available queue.
Wrapper class representing virtual and physical registers.
bool isTriviallyReMaterializable(const MachineInstr &MI, AAResults *AA=nullptr) const
Return true if the instruction is trivially rematerializable, meaning it has no side effects and requ...
void initialize(ScheduleDAGMI *DAG) override
Initialize the strategy after building the DAG for a new region.
MachineBasicBlock::iterator RegionBegin
The beginning of the range to be scheduled.
Function & getFunction()
Return the LLVM function that this machine code represents.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
MachineBasicBlock::iterator bottom() const
const TargetInstrInfo * TII
Target instruction information.
void finishBlock() override
Cleans up after scheduling in the given block.
Capture a change in pressure for a single pressure set.
Each Scheduling boundary is associated with ready queues.
void adjustLaneLiveness(const LiveIntervals &LIS, const MachineRegisterInfo &MRI, SlotIndex Pos, MachineInstr *AddFlagsMI=nullptr)
Use liveness information to find out which uses/defs are partially undefined/dead and adjust the Regi...
MachineBasicBlock * BB
The block in which to insert instructions.
void schedule() override
Implement ScheduleDAGInstrs interface for scheduling a sequence of reorderable instructions.
static void printLiveRegs(raw_ostream &OS, const LiveRegSet &LiveRegs, const MachineRegisterInfo &MRI)
void RemoveMachineInstrFromMaps(MachineInstr &MI)
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
const RegPressureTracker & getTopRPTracker() const
MachineBasicBlock::iterator top() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
SmallVector< SDep, 4 > Preds
All sunit predecessors.
Scheduling unit. This is a node in the scheduling DAG.
bool hasInterval(Register Reg) const
ScheduleDAGMILive is an implementation of ScheduleDAGInstrs that schedules machine instructions while...
void print(raw_ostream &OS, const GCNSubtarget *ST=nullptr) const
Helpers for implementing custom MachineSchedStrategy classes.
GenericScheduler shrinks the unscheduled zone using heuristics to balance the schedule.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
void removeReady(SUnit *SU)
Remove SU from the ready set for this boundary.
GCNScheduleDAGMILive(MachineSchedContext *C, std::unique_ptr< MachineSchedStrategy > S)