LLVM 24.0.0git
ScheduleDAGInstrs.cpp
Go to the documentation of this file.
1//===---- ScheduleDAGInstrs.cpp - MachineInstr Rescheduling ---------------===//
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 This implements the ScheduleDAGInstrs class, which implements
10/// re-scheduling of MachineInstrs.
11//
12//===----------------------------------------------------------------------===//
13
15
17#include "llvm/ADT/MapVector.h"
19#include "llvm/ADT/SparseSet.h"
41#include "llvm/Config/llvm-config.h"
42#include "llvm/IR/Constants.h"
43#include "llvm/IR/Function.h"
44#include "llvm/IR/Type.h"
45#include "llvm/IR/Value.h"
46#include "llvm/MC/LaneBitmask.h"
51#include "llvm/Support/Debug.h"
53#include "llvm/Support/Format.h"
55#include <algorithm>
56#include <cassert>
57#include <iterator>
58#include <list>
59#include <utility>
60#include <vector>
61
62using namespace llvm;
63
64#define DEBUG_TYPE "machine-scheduler"
65
66static cl::opt<bool>
67 EnableAASchedMI("enable-aa-sched-mi", cl::Hidden,
68 cl::desc("Enable use of AA during MI DAG construction"));
69
70static cl::opt<bool> UseTBAA("use-tbaa-in-sched-mi", cl::Hidden,
71 cl::init(true), cl::desc("Enable use of TBAA during MI DAG construction"));
72
73static cl::opt<bool>
74 EnableSchedModel("schedmodel", cl::Hidden, cl::init(true),
75 cl::desc("Use TargetSchedModel for latency lookup"));
76
77static cl::opt<bool>
78 EnableSchedItins("scheditins", cl::Hidden, cl::init(true),
79 cl::desc("Use InstrItineraryData for latency lookup"));
80
81// Note: the two options below might be used in tuning compile time vs
82// output quality. Setting HugeRegion so large that it will never be
83// reached means best-effort, but may be slow.
84
85// When Stores and Loads maps together hold this many SUs, a reduction of maps
86// will be done.
88 HugeRegion("dag-maps-huge-region", cl::Hidden, cl::init(500),
89 cl::desc("The limit to use while constructing the DAG "
90 "prior to scheduling, at which point a trade-off "
91 "is made to avoid excessive compile time."));
92
94 "enable-store-sequencing", cl::Hidden, cl::init(false),
95 cl::desc("Enable the store-sequencing DAG construction algorithm. This can "
96 "eliminate a large number of redundant control dependencies and "
97 "spurious alias analysis queries at the cost of some unnecessary "
98 "dependencies."));
99
100#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
102 "sched-print-cycles", cl::Hidden, cl::init(false),
103 cl::desc("Report top/bottom cycles when dumping SUnit instances"));
104#endif
105
107 const MachineLoopInfo *mli,
108 bool RemoveKillFlags)
109 : ScheduleDAG(mf), MLI(mli), MFI(mf.getFrameInfo()),
111 DbgValues.clear();
112
113 const TargetSubtargetInfo &ST = mf.getSubtarget();
115}
116
117/// If this machine instruction has memory reference information, collect the
118/// list of underlying objects in \p Objects. If any of these objects are
119/// unknown or may alias anything, return false. Atomic and volatile memory
120/// operands are skipped.
122 const MachineFrameInfo &MFI,
124 const DataLayout &DL) {
125 bool AllObjectsIdentified = true;
126
127 for (const MachineMemOperand *MMO : MI->memoperands()) {
128 // TODO: Figure out whether isAtomic is really necessary (see D57601).
129 if (MMO->isVolatile() || MMO->isAtomic()) {
130 AllObjectsIdentified = false;
131 continue;
132 }
133
134 if (const PseudoSourceValue *PSV = MMO->getPseudoValue()) {
135 if (MFI.hasTailCall()) {
136 // Function that contain tail calls don't have unique PseudoSourceValue
137 // objects. Two PseudoSourceValues might refer to the same or
138 // overlapping locations. The client code calling this function assumes
139 // this is not the case. So return a conservative answer of no known
140 // object.
141 AllObjectsIdentified = false;
142 } else if (PSV->isAliased(&MFI)) {
143 // For now, ignore PseudoSourceValues which may alias LLVM IR values
144 // because the code that uses this function has no way to cope with such
145 // aliases.
146 AllObjectsIdentified = false;
147 }
148
149 Objects.push_back(PSV);
150 } else if (const Value *V = MMO->getValue()) {
152 bool ObjectsIdentified = getUnderlyingObjectsForCodeGen(V, Objs);
153 AllObjectsIdentified &= ObjectsIdentified;
154
155 for (Value *V : Objs) {
156 assert(!ObjectsIdentified || isIdentifiedObject(V));
157 Objects.push_back(V);
158 }
159 } else {
160 AllObjectsIdentified = false;
161 }
162 }
163
164 return AllObjectsIdentified;
165}
166
170
172 // Subclasses should no longer refer to the old block.
173 BB = nullptr;
174}
175
179 unsigned regioninstrs) {
180 assert(bb == BB && "startBlock should set BB");
182 RegionEnd = end;
183 NumRegionInstrs = regioninstrs;
184}
185
187 // Nothing to do.
188}
189
191 MachineInstr *ExitMI =
192 RegionEnd != BB->end()
194 : nullptr;
195 ExitSU.setInstr(ExitMI);
196 // Add dependencies on the defs and uses of the instruction.
197 if (ExitMI) {
198 const MCInstrDesc &MIDesc = ExitMI->getDesc();
199 for (const MachineOperand &MO : ExitMI->all_uses()) {
200 unsigned OpIdx = MO.getOperandNo();
201 Register Reg = MO.getReg();
202 if (Reg.isPhysical()) {
203 // addPhysRegDataDeps uses the provided operand index to retrieve
204 // the operand use cycle from the scheduling model. If the operand
205 // is "fake" (e.g., an operand of a call instruction used to pass
206 // an argument to the called function.), the scheduling model may not
207 // have an entry for it. If this is the case, pass -1 as operand index,
208 // which will cause addPhysRegDataDeps to add an artificial dependency.
209 // FIXME: Using hasImplicitUseOfPhysReg here is inaccurate as it misses
210 // aliases. When fixing, make sure to update addPhysRegDataDeps, too.
211 bool IsRealUse = OpIdx < MIDesc.getNumOperands() ||
212 MIDesc.hasImplicitUseOfPhysReg(Reg);
213 for (MCRegUnit Unit : TRI->regunits(Reg))
214 Uses.insert(PhysRegSUOper(&ExitSU, IsRealUse ? OpIdx : -1, Unit));
215 } else if (Reg.isVirtual() && MO.readsReg()) {
216 addVRegUseDeps(&ExitSU, OpIdx);
217 }
218 }
219 }
220 if (!ExitMI || (!ExitMI->isCall() && !ExitMI->isBarrier())) {
221 // For others, e.g. fallthrough, conditional branch, assume the exit
222 // uses all the registers that are livein to the successor blocks.
223 for (const MachineBasicBlock *Succ : BB->successors()) {
224 for (const auto &LI : Succ->liveins()) {
225 for (MCRegUnitMaskIterator U(LI.PhysReg, TRI); U.isValid(); ++U) {
226 auto [Unit, Mask] = *U;
227 if ((Mask & LI.LaneMask).any() && !Uses.contains(Unit))
228 Uses.insert(PhysRegSUOper(&ExitSU, -1, Unit));
229 }
230 }
231 }
232 }
233}
234
235/// MO is an operand of SU's instruction that defines a physical register. Adds
236/// data dependencies from SU to any uses of the physical register.
237void ScheduleDAGInstrs::addPhysRegDataDeps(SUnit *SU, unsigned OperIdx) {
238 const MachineOperand &MO = SU->getInstr()->getOperand(OperIdx);
239 assert(MO.isDef() && "expect physreg def");
240 Register Reg = MO.getReg();
241
242 // Ask the target if address-backscheduling is desirable, and if so how much.
243 const TargetSubtargetInfo &ST = MF.getSubtarget();
244
245 // Only use any non-zero latency for real defs/uses, in contrast to
246 // "fake" operands added by regalloc.
247 const MCInstrDesc &DefMIDesc = SU->getInstr()->getDesc();
248 bool ImplicitPseudoDef = (OperIdx >= DefMIDesc.getNumOperands() &&
249 !DefMIDesc.hasImplicitDefOfPhysReg(Reg));
250 for (MCRegUnit Unit : TRI->regunits(Reg)) {
251 for (RegUnit2SUnitsMap::iterator I = Uses.find(Unit); I != Uses.end();
252 ++I) {
253 SUnit *UseSU = I->SU;
254 if (UseSU == SU)
255 continue;
256
257 // Adjust the dependence latency using operand def/use information,
258 // then allow the target to perform its own adjustments.
259 MachineInstr *UseInstr = nullptr;
260 int UseOpIdx = I->OpIdx;
261 bool ImplicitPseudoUse = false;
262 SDep Dep;
263 if (UseOpIdx < 0) {
264 Dep = SDep(SU, SDep::Artificial);
265 } else {
266 // Set the hasPhysRegDefs only for physreg defs that have a use within
267 // the scheduling region.
268 SU->hasPhysRegDefs = true;
269
270 UseInstr = UseSU->getInstr();
271 Register UseReg = UseInstr->getOperand(UseOpIdx).getReg();
272 const MCInstrDesc &UseMIDesc = UseInstr->getDesc();
273 ImplicitPseudoUse = UseOpIdx >= ((int)UseMIDesc.getNumOperands()) &&
275
276 Dep = SDep(SU, SDep::Data, UseReg);
277 }
278 if (!ImplicitPseudoDef && !ImplicitPseudoUse) {
279 Dep.setLatency(SchedModel.computeOperandLatency(SU->getInstr(), OperIdx,
280 UseInstr, UseOpIdx));
281 } else {
282 Dep.setLatency(0);
283 }
284 ST.adjustSchedDependency(SU, OperIdx, UseSU, UseOpIdx, Dep, &SchedModel);
285 UseSU->addPred(Dep);
286 }
287 }
288}
289
290/// Adds register dependencies (data, anti, and output) from this SUnit
291/// to following instructions in the same scheduling region that depend the
292/// physical register referenced at OperIdx.
293void ScheduleDAGInstrs::addPhysRegDeps(SUnit *SU, unsigned OperIdx) {
294 MachineInstr *MI = SU->getInstr();
295 MachineOperand &MO = MI->getOperand(OperIdx);
296 Register Reg = MO.getReg();
297 // We do not need to track any dependencies for constant registers.
298 if (MRI.isConstantPhysReg(Reg))
299 return;
300
301 const TargetSubtargetInfo &ST = MF.getSubtarget();
302
303 // Optionally add output and anti dependencies. For anti
304 // dependencies we use a latency of 0 because for a multi-issue
305 // target we want to allow the defining instruction to issue
306 // in the same cycle as the using instruction.
307 // TODO: Using a latency of 1 here for output dependencies assumes
308 // there's no cost for reusing registers.
309 SDep::Kind Kind = MO.isUse() ? SDep::Anti : SDep::Output;
310 for (MCRegUnit Unit : TRI->regunits(Reg)) {
311 for (RegUnit2SUnitsMap::iterator I = Defs.find(Unit); I != Defs.end();
312 ++I) {
313 SUnit *DefSU = I->SU;
314 if (DefSU == &ExitSU)
315 continue;
316 MachineInstr *DefInstr = DefSU->getInstr();
317 MachineOperand &DefMO = DefInstr->getOperand(I->OpIdx);
318 if (DefSU != SU &&
319 (Kind != SDep::Output || !MO.isDead() || !DefMO.isDead())) {
320 SDep Dep(SU, Kind, DefMO.getReg());
321 if (Kind != SDep::Anti) {
322 Dep.setLatency(
323 SchedModel.computeOutputLatency(MI, OperIdx, DefInstr));
324 }
325 ST.adjustSchedDependency(SU, OperIdx, DefSU, I->OpIdx, Dep,
326 &SchedModel);
327 DefSU->addPred(Dep);
328 }
329 }
330 }
331
332 if (MO.isUse()) {
333 SU->hasPhysRegUses = true;
334 // Either insert a new Reg2SUnits entry with an empty SUnits list, or
335 // retrieve the existing SUnits list for this register's uses.
336 // Push this SUnit on the use list.
337 for (MCRegUnit Unit : TRI->regunits(Reg))
338 Uses.insert(PhysRegSUOper(SU, OperIdx, Unit));
339 if (RemoveKillFlags)
340 MO.setIsKill(false);
341 } else {
342 addPhysRegDataDeps(SU, OperIdx);
343
344 // Clear previous uses and defs of this register and its subregisters.
345 for (MCRegUnit Unit : TRI->regunits(Reg)) {
346 Uses.eraseAll(Unit);
347 if (!MO.isDead())
348 Defs.eraseAll(Unit);
349 }
350
351 if (MO.isDead() && SU->isCall) {
352 // Calls will not be reordered because of chain dependencies (see
353 // below). Since call operands are dead, calls may continue to be added
354 // to the DefList making dependence checking quadratic in the size of
355 // the block. Instead, we leave only one call at the back of the
356 // DefList.
357 for (MCRegUnit Unit : TRI->regunits(Reg)) {
358 RegUnit2SUnitsMap::RangePair P = Defs.equal_range(Unit);
361 for (bool isBegin = I == B; !isBegin; /* empty */) {
362 isBegin = (--I) == B;
363 if (!I->SU->isCall)
364 break;
365 I = Defs.erase(I);
366 }
367 }
368 }
369
370 // Defs are pushed in the order they are visited and never reordered.
371 for (MCRegUnit Unit : TRI->regunits(Reg))
372 Defs.insert(PhysRegSUOper(SU, OperIdx, Unit));
373 }
374}
375
377{
378 Register Reg = MO.getReg();
379 // No point in tracking lanemasks if we don't have interesting subregisters.
380 const TargetRegisterClass &RC = *MRI.getRegClass(Reg);
381 if (!RC.HasDisjunctSubRegs)
382 return LaneBitmask::getAll();
383
384 unsigned SubReg = MO.getSubReg();
385 if (SubReg == 0)
386 return RC.getLaneMask();
387 return TRI->getSubRegIndexLaneMask(SubReg);
388}
389
391 auto RegUse = CurrentVRegUses.find(MO.getReg());
392 if (RegUse == CurrentVRegUses.end())
393 return true;
394 return (RegUse->LaneMask & getLaneMaskForMO(MO)).none();
395}
396
397/// Adds register output and data dependencies from this SUnit to instructions
398/// that occur later in the same scheduling region if they read from or write to
399/// the virtual register defined at OperIdx.
400///
401/// TODO: Hoist loop induction variable increments. This has to be
402/// reevaluated. Generally, IV scheduling should be done before coalescing.
403void ScheduleDAGInstrs::addVRegDefDeps(SUnit *SU, unsigned OperIdx) {
404 MachineInstr *MI = SU->getInstr();
405 MachineOperand &MO = MI->getOperand(OperIdx);
406 Register Reg = MO.getReg();
407
408 LaneBitmask DefLaneMask;
409 LaneBitmask KillLaneMask;
410 if (TrackLaneMasks) {
411 bool IsKill = MO.getSubReg() == 0 || MO.isUndef();
412 DefLaneMask = getLaneMaskForMO(MO);
413 // If we have a <read-undef> flag, none of the lane values comes from an
414 // earlier instruction.
415 KillLaneMask = IsKill ? LaneBitmask::getAll() : DefLaneMask;
416
417 if (MO.getSubReg() != 0 && MO.isUndef()) {
418 // There may be other subregister defs on the same instruction of the same
419 // register in later operands. The lanes of other defs will now be live
420 // after this instruction, so these should not be treated as killed by the
421 // instruction even though they appear to be killed in this one operand.
422 for (const MachineOperand &OtherMO :
423 llvm::drop_begin(MI->operands(), OperIdx + 1))
424 if (OtherMO.isReg() && OtherMO.isDef() && OtherMO.getReg() == Reg)
425 KillLaneMask &= ~getLaneMaskForMO(OtherMO);
426 }
427
428 // Clear undef flag, we'll re-add it later once we know which subregister
429 // Def is first.
430 MO.setIsUndef(false);
431 } else {
432 DefLaneMask = LaneBitmask::getAll();
433 KillLaneMask = LaneBitmask::getAll();
434 }
435
436 if (MO.isDead()) {
437 assert(deadDefHasNoUse(MO) && "Dead defs should have no uses");
438 } else {
439 // Add data dependence to all uses we found so far.
440 const TargetSubtargetInfo &ST = MF.getSubtarget();
442 E = CurrentVRegUses.end(); I != E; /*empty*/) {
443 LaneBitmask LaneMask = I->LaneMask;
444 // Ignore uses of other lanes.
445 if ((LaneMask & KillLaneMask).none()) {
446 ++I;
447 continue;
448 }
449
450 if ((LaneMask & DefLaneMask).any()) {
451 SUnit *UseSU = I->SU;
452 MachineInstr *Use = UseSU->getInstr();
453 SDep Dep(SU, SDep::Data, Reg);
454 Dep.setLatency(SchedModel.computeOperandLatency(MI, OperIdx, Use,
455 I->OperandIndex));
456 ST.adjustSchedDependency(SU, OperIdx, UseSU, I->OperandIndex, Dep,
457 &SchedModel);
458 UseSU->addPred(Dep);
459 }
460
461 LaneMask &= ~KillLaneMask;
462 // If we found a Def for all lanes of this use, remove it from the list.
463 if (LaneMask.any()) {
464 I->LaneMask = LaneMask;
465 ++I;
466 } else
467 I = CurrentVRegUses.erase(I);
468 }
469 }
470
471 // Shortcut: Singly defined vregs do not have output/anti dependencies.
472 if (MRI.hasOneDef(Reg))
473 return;
474
475 // Add output dependence to the next nearest defs of this vreg.
476 //
477 // Unless this definition is dead, the output dependence should be
478 // transitively redundant with antidependencies from this definition's
479 // uses. We're conservative for now until we have a way to guarantee the uses
480 // are not eliminated sometime during scheduling. The output dependence edge
481 // is also useful if output latency exceeds def-use latency.
482 LaneBitmask LaneMask = DefLaneMask;
483 for (VReg2SUnit &V2SU : make_range(CurrentVRegDefs.find(Reg),
484 CurrentVRegDefs.end())) {
485 // Ignore defs for other lanes.
486 if ((V2SU.LaneMask & LaneMask).none())
487 continue;
488 // Add an output dependence.
489 SUnit *DefSU = V2SU.SU;
490 // Ignore additional defs of the same lanes in one instruction. This can
491 // happen because lanemasks are shared for targets with too many
492 // subregisters. We also use some representration tricks/hacks where we
493 // add super-register defs/uses, to imply that although we only access parts
494 // of the reg we care about the full one.
495 if (DefSU == SU)
496 continue;
497 SDep Dep(SU, SDep::Output, Reg);
498 Dep.setLatency(
499 SchedModel.computeOutputLatency(MI, OperIdx, DefSU->getInstr()));
500 DefSU->addPred(Dep);
501
502 // Update current definition. This can get tricky if the def was about a
503 // bigger lanemask before. We then have to shrink it and create a new
504 // VReg2SUnit for the non-overlapping part.
505 LaneBitmask OverlapMask = V2SU.LaneMask & LaneMask;
506 LaneBitmask NonOverlapMask = V2SU.LaneMask & ~LaneMask;
507 V2SU.SU = SU;
508 V2SU.LaneMask = OverlapMask;
509 if (NonOverlapMask.any())
510 CurrentVRegDefs.insert(VReg2SUnit(Reg, NonOverlapMask, DefSU));
511 }
512 // If there was no CurrentVRegDefs entry for some lanes yet, create one.
513 if (LaneMask.any())
514 CurrentVRegDefs.insert(VReg2SUnit(Reg, LaneMask, SU));
515}
516
517/// Adds a register data dependency if the instruction that defines the
518/// virtual register used at OperIdx is mapped to an SUnit. Add a register
519/// antidependency from this SUnit to instructions that occur later in the same
520/// scheduling region if they write the virtual register.
521///
522/// TODO: Handle ExitSU "uses" properly.
523void ScheduleDAGInstrs::addVRegUseDeps(SUnit *SU, unsigned OperIdx) {
524 const MachineInstr *MI = SU->getInstr();
525 assert(!MI->isDebugOrPseudoInstr());
526
527 const MachineOperand &MO = MI->getOperand(OperIdx);
528 Register Reg = MO.getReg();
529
530 // Remember the use. Data dependencies will be added when we find the def.
533 CurrentVRegUses.insert(VReg2SUnitOperIdx(Reg, LaneMask, OperIdx, SU));
534
535 // Add antidependences to the following defs of the vreg.
536 for (VReg2SUnit &V2SU : make_range(CurrentVRegDefs.find(Reg),
537 CurrentVRegDefs.end())) {
538 // Ignore defs for unrelated lanes.
539 LaneBitmask PrevDefLaneMask = V2SU.LaneMask;
540 if ((PrevDefLaneMask & LaneMask).none())
541 continue;
542 if (V2SU.SU == SU)
543 continue;
544
545 V2SU.SU->addPred(SDep(SU, SDep::Anti, Reg));
546 }
547}
548
549/// Creates an SUnit for each real instruction, numbered in top-down
550/// topological order. The instruction order A < B, implies that no edge exists
551/// from B to A.
552///
553/// Map each real instruction to its SUnit.
554///
555/// After initSUnits, the SUnits vector cannot be resized and the scheduler may
556/// hang onto SUnit pointers. We may relax this in the future by using SUnit IDs
557/// instead of pointers.
558///
559/// MachineScheduler relies on initSUnits numbering the nodes by their order in
560/// the original instruction list.
562 // We'll be allocating one SUnit for each real instruction in the region,
563 // which is contained within a basic block.
564 SUnits.reserve(NumRegionInstrs);
565
567 if (MI.isDebugOrPseudoInstr())
568 continue;
569
570 SUnit *SU = newSUnit(&MI);
571 MISUnitMap[&MI] = SU;
572
573 SU->isCall = MI.isCall();
574 SU->isCommutable = MI.isCommutable();
575
576 // Assign the Latency field of SU using target-provided information.
577 SU->Latency = SchedModel.computeInstrLatency(SU->getInstr());
578
579 // If this SUnit uses a reserved or unbuffered resource, mark it as such.
580 //
581 // Reserved resources block an instruction from issuing and stall the
582 // entire pipeline. These are identified by BufferSize=0.
583 //
584 // Unbuffered resources prevent execution of subsequent instructions that
585 // require the same resources. This is used for in-order execution pipelines
586 // within an out-of-order core. These are identified by BufferSize=1.
587 if (SchedModel.hasInstrSchedModel()) {
588 const MCSchedClassDesc *SC = getSchedClass(SU);
589 for (const MCWriteProcResEntry &PRE :
590 make_range(SchedModel.getWriteProcResBegin(SC),
591 SchedModel.getWriteProcResEnd(SC))) {
592 switch (SchedModel.getResourceBufferSize(PRE.ProcResourceIdx)) {
593 case 0:
594 SU->hasReservedResource = true;
595 break;
596 case 1:
597 SU->isUnbuffered = true;
598 break;
599 default:
600 break;
601 }
602 }
603 }
604 }
605}
606
607namespace {
608/// A list of SUnits, used during DAG construction.
609/// FIXME: to gain speed it might be worth investigating an optimized
610/// implementation of this data structure, such as a singly linked list
611/// with a memory pool (SmallVector was tried but slow and SparseSet is not
612/// applicable).
613using SUList = std::list<SUnit *>;
614} // end anonymous namespace
615
616namespace llvm {
618private:
620
621 BatchAAResults *AA;
622 RegPressureTracker *RPTracker;
623 PressureDiffs *PDiffs;
624 LiveIntervals *LIS;
625
626 // Track all instructions that may raise floating-point exceptions.
627 // These do not depend on one other (or normal loads or stores), but
628 // must not be rescheduled across global barriers.
629 SUList FPExceptions;
630
631 /// A frontier of unanalyzable memory operations.
632 ///
633 /// As we process memory operations (bottom to top), each new memory operation
634 /// needs to be checked for required control dependencies against later memory
635 /// operations. A naive implementation issues AA calls quadratically in the
636 /// number of memory operations and is therefore unacceptable.
637 ///
638 /// To bound the complexity, we only ever consider a frontier of memory
639 /// operations which we frequently clear, modeled by this struct. To ensure
640 /// that we are not missing any necessary control dependencies, we promote
641 /// certain store instructions to what we term 'sequencing stores'. These
642 /// sequencing stores are treated carefully to ensure that all previously seen
643 /// unanalyzable memory operations that do not belong to the frontier
644 /// necessarily transitively succeed the current sequencing store.
645 ///
646 /// By frequently updating the sequencing store, we bound the number of alias
647 /// analysis queries and transitively redundant control dependencies we
648 /// generate. However, doing so we necessarily overconstrain the DAG. Indeed,
649 /// if we were to update the sequencing store every time we see a store
650 /// instruction, the effect would be to linearize the stores.
651 struct MemopFrontier {
652 // The current sequencing store.
653 SUnit *SequencingStore = nullptr;
654 /// The memory operations in the frontier.
655 SUList Stores, Loads;
656
657 /// The number of memops in the frontier, excluding the sequencing store.
658 unsigned size() const;
659
660 /// Clears the frontier.
661 void clear();
662 };
663
664 // For memory operations that can be analyzed to an identified underlying
665 // object, we maintain one frontier per underlying object. Two SUs are
666 // trivially non-aliasing if they both depend on only identified Values and do
667 // not share any common Value. We expect the analyzable frontiers to remain
668 // small and benefit from alias analysis, so only clear when they grow too
669 // large.
670 MapVector<ValueType, MemopFrontier> AnalyzableFrontiers;
671
672 /// We maintain an additional frontier of unanalyzable memory operations,
673 /// equipped with some extra state designed to clear the frontier more
674 /// frequently. The conditions we choose to update the sequencing store are as
675 /// follows:
676 ///
677 /// The conditions we choose to update the sequencing store are as follows:
678 /// 1. If an incoming store instruction refers to an underlying object outside
679 /// of the set of underlying objects of the current sequencing store;
680 /// 2. If an incoming store instruction precedes an intervening load from an
681 /// underlying object outside of the set of underlying objects of the
682 /// current sequencing store (a 'sequencing load').
683 /// In these cases, a BasicAA query will (generally) already induce a
684 /// (transitive) edge from the incoming store to the current sequencing store.
685 /// However, this process introduces spurious (transitive) barrier edges in
686 /// the following cases:
687 /// 1. From all preceding loads to the new sequencing store;
688 /// 2. From the new sequencing store to all stores in the current frontier;
689 /// 3. From all preceding unanalyzable stores to (a subset of) the same base
690 /// objects, independent of AA results;
691 /// 4. From all preceding analyzable stores, independent of AA results.
692 struct UnanalyzableMemopFrontier {
693 /// The underlying memop frontier.
694 MemopFrontier Frontier;
695 /// The underlying objects of the current sequencing store.
696 UnderlyingObjectsVector BaseObjects;
697 /// `true` if the frontier contains a load whose underlying objects escape
698 /// #BaseObjects.
699 bool SeenSequencingLoad = false;
700
701 /// Given a store instruction with underlying objects \p Objs, returns true
702 /// if the store should be promoted to a sequencing store and false
703 /// otherwise.
704 bool shouldUpdate(const UnderlyingObjectsVector &Objs);
705
706 /// Returns true if any of \p Objs does not belong to #BaseObjects.
707 bool escapesBaseObjects(const UnderlyingObjectsVector &Objs);
708
709 /// Clears the frontier and resets the associated state.
710 void clear();
711 };
712
713 /// Track a frontier of unanalyzable memory operations.
714 ///
715 /// FIXME(@cofibrant): For some platforms, a single frontier is too coarse and
716 /// we should be maintaining one frontier per address space.
717 UnanalyzableMemopFrontier UnanalyzableFrontier;
718
719 /// Remember a generic side-effecting instruction as we proceed.
720 /// No other SU ever gets scheduled around it (except in the special
721 /// case of a huge region that gets reduced).
722 SUnit *BarrierChain = nullptr;
723
724 unsigned MemOpsProcessed = 0;
725
726public:
728 RegPressureTracker *RPTracker,
729 PressureDiffs *PDiffs, LiveIntervals *LIS)
730 : DAG(DAG), AA(AA), RPTracker(RPTracker), PDiffs(PDiffs), LIS(LIS) {}
731
732private:
733 /// Adds a chain edge between SUa and SUb, but only if both
734 /// AAResults and Target fail to deny the dependency.
735 ///
736 /// Returns true if an edge was inserted.
737 bool addChainDependency(SUnit *SUa, SUnit *SUb, unsigned Latency = 0);
738
739 /// Adds dependencies as needed from all SUs in list to SU.
740 void addChainDependencies(SUnit *SU, SUList &SUs, unsigned Latency);
741 void addChainDependencies(SUnit *SU, MemopFrontier &F, bool IsStore);
742
743 void addBarrierChain(SUList &SUs);
744 void addBarrierChain(MemopFrontier &F);
745
746 /// Add dependencies from the barrier chain to all in flight memory operations
747 /// and clear the memop frontiers.
748 void addBarrierMemoryDeps();
749
750 /// Promote the store \p SU to be a new sequencing store in the frontier \p F.
751 void updateSequencingStore(MemopFrontier &F, SUnit *SU);
752
753 /// Promote the store \p SU with underlying objects \p Objs to be a new
754 /// sequencing store in the frontier \p UF.
755 void updateSequencingStore(UnanalyzableMemopFrontier &UF, SUnit *SU,
757
758public:
759 void buildDeps();
760};
761} // end namespace llvm
762
763unsigned ScheduleDAGDependencyBuilder::MemopFrontier::size() const {
764 return Loads.size() + Stores.size();
765}
766
767void ScheduleDAGDependencyBuilder::MemopFrontier::clear() {
768 SequencingStore = nullptr;
769 Stores.clear();
770 Loads.clear();
771}
772
773bool ScheduleDAGDependencyBuilder::UnanalyzableMemopFrontier::shouldUpdate(
774 const UnderlyingObjectsVector &Objs) {
776 return false;
777 return !Frontier.SequencingStore || SeenSequencingLoad ||
778 escapesBaseObjects(Objs);
779}
780
781bool ScheduleDAGDependencyBuilder::UnanalyzableMemopFrontier::
782 escapesBaseObjects(const UnderlyingObjectsVector &Objs) {
783 for (const ValueType V : Objs) {
784 if (!is_contained(BaseObjects, V))
785 return true;
786 }
787
788 return false;
789}
790
791void ScheduleDAGDependencyBuilder::UnanalyzableMemopFrontier::clear() {
792 Frontier.clear();
793 SeenSequencingLoad = false;
794 BaseObjects.clear();
795}
796
797bool ScheduleDAGDependencyBuilder::addChainDependency(SUnit *SUa, SUnit *SUb,
798 unsigned Latency) {
799 if (!SUa->getInstr()->mayAlias(AA, *SUb->getInstr(), UseTBAA))
800 return false;
801
802 SDep Dep(SUa, SDep::MayAliasMem);
803 Dep.setLatency(Latency);
804 SUb->addPred(Dep);
805 return true;
806}
807
808void ScheduleDAGDependencyBuilder::addChainDependencies(SUnit *SU, SUList &SUs,
809 unsigned Latency) {
810 for (SUnit *Entry : SUs)
811 addChainDependency(SU, Entry, Latency);
812}
813
814void ScheduleDAGDependencyBuilder::addChainDependencies(SUnit *SU,
815 MemopFrontier &F,
816 bool IsStore) {
817 if (F.SequencingStore)
818 F.SequencingStore->addPredBarrier(SU);
819
820 addChainDependencies(SU, F.Stores, /*Latency=*/0);
821 if (IsStore)
822 addChainDependencies(SU, F.Loads, /*Latency=*/1);
823}
824
825void ScheduleDAGDependencyBuilder::addBarrierChain(SUList &SUs) {
826 assert(BarrierChain != nullptr);
827
828 for (auto *SU : SUs)
829 SU->addPredBarrier(BarrierChain);
830
831 SUs.clear();
832}
833
834void ScheduleDAGDependencyBuilder::addBarrierChain(MemopFrontier &F) {
835 assert(BarrierChain != nullptr);
836
837 addBarrierChain(F.Stores);
838 addBarrierChain(F.Loads);
839
840 if (F.SequencingStore)
841 F.SequencingStore->addPredBarrier(BarrierChain);
842
843 F.clear();
844}
845
846void ScheduleDAGDependencyBuilder::addBarrierMemoryDeps() {
847 assert(BarrierChain != nullptr);
848
849 addBarrierChain(UnanalyzableFrontier.Frontier);
850 UnanalyzableFrontier.clear();
851
852 for (auto &[_, AF] : AnalyzableFrontiers)
853 addBarrierChain(AF);
854 AnalyzableFrontiers.clear();
855}
856
857void ScheduleDAGDependencyBuilder::updateSequencingStore(MemopFrontier &F,
858 SUnit *SU) {
859 assert(SU->getInstr()->mayStore() &&
860 "Only store instructions should be used as sequencing stores");
861 LLVM_DEBUG(dbgs() << "Promoting " << *SU << " to sequencing store\n");
862
863 if (F.SequencingStore)
864 F.SequencingStore->addPredBarrier(SU);
865
866 // Sequence all stores against the sequencing store and clear the map.
867 for (SUnit *S : F.Stores)
868 S->addPredBarrier(SU);
869
870 F.Stores.clear();
871
872 // For loads, we can do slightly better. Rather than naively adding pred
873 // barriers and clearing the map, we check whether each load genuinely needs
874 // to sequence against the new sequencing store. Wherever an edge is not
875 // required, we retain the load and avoid the spurious control dependency.
876 for (auto It = F.Loads.begin(); It != F.Loads.end();) {
877 if (addChainDependency(SU, *It, /*TrueMemOrderLatency=*/1)) {
878 It = F.Loads.erase(It);
879 } else {
880 ++It;
881 }
882 }
883
884 F.SequencingStore = SU;
885}
886
887void ScheduleDAGDependencyBuilder::updateSequencingStore(
888 UnanalyzableMemopFrontier &UF, SUnit *SU, UnderlyingObjectsVector &&Objs) {
889 assert(SU->getInstr()->mayStore() &&
890 "Only store instructions should be used as sequencing stores");
891 updateSequencingStore(UF.Frontier, SU);
892 UF.BaseObjects = std::move(Objs);
893 UF.SeenSequencingLoad = false;
894}
895
897 const TargetSubtargetInfo &ST = DAG.MF.getSubtarget();
898
899 // We build scheduling units by walking a block's instruction list
900 // from bottom to top.
901
902 // Model data dependencies between instructions being scheduled and the
903 // ExitSU.
904 DAG.addSchedBarrierDeps();
905
906 // Walk the list of instructions, from bottom moving up.
907 MachineInstr *DbgMI = nullptr;
908 for (MachineBasicBlock::iterator MII = DAG.RegionEnd, MIE = DAG.RegionBegin;
909 MII != MIE; --MII) {
910 MachineInstr &MI = *std::prev(MII);
911 if (DbgMI) {
912 DAG.DbgValues.emplace_back(DbgMI, &MI);
913 DbgMI = nullptr;
914 }
915
916 if (MI.isDebugValue() || MI.isDebugPHI()) {
917 DbgMI = &MI;
918 continue;
919 }
920
921 if (MI.isDebugLabel() || MI.isDebugRef() || MI.isPseudoProbe())
922 continue;
923
924 SUnit *SU = DAG.MISUnitMap[&MI];
925 assert(SU && "No SUnit mapped to this MI");
926
927 if (RPTracker) {
928 RegisterOperands RegOpers;
929 RegOpers.collect(MI, *DAG.TRI, DAG.MRI, DAG.TrackLaneMasks, false);
930 if (DAG.TrackLaneMasks) {
931 SlotIndex SlotIdx = LIS->getInstructionIndex(MI);
932 RegOpers.adjustLaneLiveness(*LIS, DAG.MRI, SlotIdx);
933 } else if (LIS) {
934 // Detect dead defs from LiveIntervals instead of trusting operand dead
935 // flags.
936 RegOpers.detectDeadDefs(MI, *LIS, DAG.MRI);
937 }
938 if (PDiffs != nullptr)
939 PDiffs->addInstruction(SU->NodeNum, RegOpers, DAG.MRI);
940
941 if (RPTracker->getPos() == DAG.RegionEnd || &*RPTracker->getPos() != &MI)
942 RPTracker->recedeSkipDebugValues();
943 assert(&*RPTracker->getPos() == &MI && "RPTracker in sync");
944 RPTracker->recede(RegOpers);
945 }
946
947 assert((DAG.CanHandleTerminators ||
948 (!MI.isTerminator() && !MI.isPosition())) &&
949 "Cannot schedule terminators or labels!");
950
951 // Add register-based dependencies (data, anti, and output).
952 // For some instructions (calls, returns, inline-asm, etc.) there can
953 // be explicit uses and implicit defs, in which case the use will appear
954 // on the operand list before the def. Do two passes over the operand
955 // list to make sure that defs are processed before any uses.
956 bool HasVRegDef = false;
957 for (unsigned j = 0, n = MI.getNumOperands(); j != n; ++j) {
958 const MachineOperand &MO = MI.getOperand(j);
959 if (!MO.isReg() || !MO.isDef())
960 continue;
961 Register Reg = MO.getReg();
962 if (Reg.isPhysical()) {
963 DAG.addPhysRegDeps(SU, j);
964 } else if (Reg.isVirtual()) {
965 HasVRegDef = true;
966 DAG.addVRegDefDeps(SU, j);
967 }
968 }
969 // Now process all uses.
970 for (unsigned j = 0, n = MI.getNumOperands(); j != n; ++j) {
971 const MachineOperand &MO = MI.getOperand(j);
972 // Only look at use operands.
973 // We do not need to check for MO.readsReg() here because subsequent
974 // subregister defs will get output dependence edges and need no
975 // additional use dependencies.
976 if (!MO.isReg() || !MO.isUse())
977 continue;
978 Register Reg = MO.getReg();
979 if (Reg.isPhysical()) {
980 DAG.addPhysRegDeps(SU, j);
981 } else if (Reg.isVirtual() && MO.readsReg()) {
982 DAG.addVRegUseDeps(SU, j);
983 }
984 }
985
986 // If we haven't seen any uses in this scheduling region, create a
987 // dependence edge to ExitSU to model the live-out latency. This is required
988 // for vreg defs with no in-region use, and prefetches with no vreg def.
989 //
990 // FIXME: NumDataSuccs would be more precise than NumSuccs here. This
991 // check currently relies on being called before adding chain deps.
992 if (SU->NumSuccs == 0 && SU->Latency > 1 && (HasVRegDef || MI.mayLoad())) {
993 SDep Dep(SU, SDep::Artificial);
994 Dep.setLatency(SU->Latency - 1);
995 DAG.ExitSU.addPred(Dep);
996 }
997
998 // Add memory dependencies (Note: isStoreToStackSlot and
999 // isLoadFromStackSLot are not usable after stack slots are lowered to
1000 // actual addresses).
1001
1002 const TargetInstrInfo *TII = ST.getInstrInfo();
1003 // This is a barrier event that acts as a pivotal node in the DAG.
1004 if (TII->isGlobalMemoryObject(&MI)) {
1005
1006 // Become the barrier chain.
1007 if (BarrierChain)
1008 BarrierChain->addPredBarrier(SU);
1009 BarrierChain = SU;
1010
1011 LLVM_DEBUG(dbgs() << "Global memory object and new barrier chain: "
1012 << *BarrierChain << ".\n");
1013
1014 // Add dependencies against everything below it and clear maps.
1015 addBarrierChain(FPExceptions);
1016 addBarrierMemoryDeps();
1017
1018 continue;
1019 }
1020
1021 // Instructions that may raise FP exceptions may not be moved
1022 // across any global barriers.
1023 if (MI.mayRaiseFPException()) {
1024 if (BarrierChain)
1025 BarrierChain->addPredBarrier(SU);
1026
1027 if (FPExceptions.size() + 1 >= HugeRegion) {
1028 LLVM_DEBUG(
1029 dbgs()
1030 << "Creating barrier chain and clearing FPExceptions map.\n");
1031 BarrierChain = SU;
1032 addBarrierChain(FPExceptions);
1033 } else {
1034 FPExceptions.push_back(SU);
1035 }
1036 }
1037
1038 // If it's not a store or a variant load, we're done.
1039 if (!MI.mayStore() &&
1040 !(MI.mayLoad() && !MI.isDereferenceableInvariantLoad()))
1041 continue;
1042
1043 MemOpsProcessed++;
1044
1045 // Always add dependecy edge to BarrierChain if present.
1046 if (BarrierChain && BarrierChain != SU)
1047 BarrierChain->addPredBarrier(SU);
1048
1049 // Reduce maps if they grow huge.
1050 //
1051 // FIXME(@cofibrant): With store-sequencing, this condition can be relaxed
1052 // and improved. Specifically, we are not so worried about `Stores` and
1053 // `Loads` growing too large, but more interested in making sure that the
1054 // frontier(s) themselves stay sufficiently small. This is best achieved by
1055 // measuring the size of the frontier(s) and, if sufficiently large,
1056 // promoting the next store to a sequencing store.
1057 if (MemOpsProcessed >= HugeRegion) {
1058 LLVM_DEBUG(dbgs() << "Creating barrier chain and clearing maps.\n");
1059
1060 BarrierChain = SU;
1061 addBarrierMemoryDeps();
1062
1063 MemOpsProcessed = 0;
1064 continue;
1065 }
1066
1067 // Find the underlying objects for MI. The Objs vector is either
1068 // empty, or filled with the Values of memory locations which this
1069 // SU depends on.
1071 bool ObjsIdentified = getUnderlyingObjectsForInstr(&MI, DAG.MFI, Objs,
1072 DAG.MF.getDataLayout());
1073 bool IsStore = MI.mayStore();
1074
1075 if (!ObjsIdentified) {
1076 // An unanalyzable memory operation depends on all analyzable frontiers.
1077 for (auto &[_, AF] : AnalyzableFrontiers)
1078 addChainDependencies(SU, AF, IsStore);
1079
1080 if (IsStore && UnanalyzableFrontier.shouldUpdate(Objs)) {
1081 updateSequencingStore(UnanalyzableFrontier, SU, std::move(Objs));
1082 } else {
1083 if (!IsStore && UnanalyzableFrontier.escapesBaseObjects(Objs))
1084 UnanalyzableFrontier.SeenSequencingLoad = true;
1085 addChainDependencies(SU, UnanalyzableFrontier.Frontier, IsStore);
1086 (IsStore ? UnanalyzableFrontier.Frontier.Stores
1087 : UnanalyzableFrontier.Frontier.Loads)
1088 .push_back(SU);
1089 }
1090 } else {
1091 // Add precise dependencies against all previously seen memory
1092 // accesses mapped to the same Value(s).
1093 SmallSet<ValueType, 2> SeenValues;
1094 for (const ValueType V : Objs) {
1095 // Deduplicate values to avoid adding self loops.
1096 if (!SeenValues.insert(V).second)
1097 continue;
1098
1099 MemopFrontier &Frontier = AnalyzableFrontiers[V];
1100 addChainDependencies(SU, Frontier, IsStore);
1101 (IsStore ? Frontier.Stores : Frontier.Loads).push_back(SU);
1102 }
1103
1104 // The memop may have dependencies to unanalyzable stores.
1105 addChainDependencies(SU, UnanalyzableFrontier.Frontier, IsStore);
1106 }
1107 }
1108
1109 if (DbgMI)
1110 DAG.FirstDbgValue = DbgMI;
1111}
1112
1114 RegPressureTracker *RPTracker,
1115 PressureDiffs *PDiffs,
1116 LiveIntervals *LIS,
1117 bool TrackLaneMasks) {
1118 const TargetSubtargetInfo &ST = MF.getSubtarget();
1119 bool UseAA =
1120 EnableAASchedMI.getNumOccurrences() > 0 ? EnableAASchedMI : ST.useAA();
1121 this->TrackLaneMasks = TrackLaneMasks;
1122 MISUnitMap.clear();
1124
1125 // Create an SUnit for each real instruction.
1126 initSUnits();
1127
1128 if (PDiffs)
1129 PDiffs->init(SUnits.size());
1130
1131 // Remove any stale debug info; sometimes BuildSchedGraph is called again
1132 // without emitting the info from the previous call.
1133 DbgValues.clear();
1134 FirstDbgValue = nullptr;
1135
1136 assert(Defs.empty() && Uses.empty() &&
1137 "Only BuildGraph should update Defs/Uses");
1138 Defs.setUniverse(TRI->getNumRegs());
1139 Uses.setUniverse(TRI->getNumRegs());
1140
1141 assert(CurrentVRegDefs.empty() && "nobody else should use CurrentVRegDefs");
1142 assert(CurrentVRegUses.empty() && "nobody else should use CurrentVRegUses");
1143 unsigned NumVirtRegs = MRI.getNumVirtRegs();
1144 CurrentVRegDefs.setUniverse(NumVirtRegs);
1145 CurrentVRegUses.setUniverse(NumVirtRegs);
1146
1147 std::optional<BatchAAResults> BatchAA;
1148 if (UseAA && AA)
1149 BatchAA.emplace(*AA);
1150
1152 *this, BatchAA.has_value() ? &BatchAA.value() : nullptr, RPTracker,
1153 PDiffs, LIS);
1154 DepBuilder.buildDeps();
1155
1156 Defs.clear();
1157 Uses.clear();
1158 CurrentVRegDefs.clear();
1159 CurrentVRegUses.clear();
1160
1161 Topo.MarkDirty();
1162}
1163
1165 PSV->printCustom(OS);
1166 return OS;
1167}
1168
1170 MachineInstr &MI, bool addToLiveRegs) {
1171 for (MachineOperand &MO : MI.operands()) {
1172 if (!MO.isReg() || !MO.readsReg())
1173 continue;
1174 Register Reg = MO.getReg();
1175 if (!Reg)
1176 continue;
1177
1178 // Things that are available after the instruction are killed by it.
1179 bool IsKill = LiveRegs.available(Reg);
1180
1181 // Exception: Do not kill reserved registers
1182 MO.setIsKill(IsKill && !MRI.isReserved(Reg));
1183 if (addToLiveRegs)
1184 LiveRegs.addReg(Reg);
1185 }
1186}
1187
1189 LLVM_DEBUG(dbgs() << "Fixup kills for " << printMBBReference(MBB) << '\n');
1190
1191 LiveRegs.init(*TRI);
1192 LiveRegs.addLiveOuts(MBB);
1193
1194 // Examine block from end to start...
1195 for (MachineInstr &MI : llvm::reverse(MBB)) {
1196 if (MI.isDebugOrPseudoInstr())
1197 continue;
1198
1199 // Update liveness. Registers that are defed but not used in this
1200 // instruction are now dead. Mark register and all subregs as they
1201 // are completely defined.
1202 for (ConstMIBundleOperands O(MI); O.isValid(); ++O) {
1203 const MachineOperand &MO = *O;
1204 if (MO.isReg()) {
1205 if (!MO.isDef())
1206 continue;
1207 Register Reg = MO.getReg();
1208 if (!Reg)
1209 continue;
1210 LiveRegs.removeReg(Reg);
1211 } else if (MO.isRegMask()) {
1212 LiveRegs.removeRegsNotPreserved(MO.getRegMask());
1213 }
1214 }
1215
1216 // If there is a bundle header fix it up first.
1217 if (!MI.isBundled()) {
1218 toggleKills(MRI, LiveRegs, MI, true);
1219 } else {
1220 MachineBasicBlock::instr_iterator Bundle = MI.getIterator();
1221 if (MI.isBundle())
1222 toggleKills(MRI, LiveRegs, MI, false);
1223
1224 // Some targets make the (questionable) assumtion that the instructions
1225 // inside the bundle are ordered and consequently only the last use of
1226 // a register inside the bundle can kill it.
1227 MachineBasicBlock::instr_iterator I = std::next(Bundle);
1228 while (I->isBundledWithSucc())
1229 ++I;
1230 do {
1231 if (!I->isDebugOrPseudoInstr())
1232 toggleKills(MRI, LiveRegs, *I, true);
1233 --I;
1234 } while (I != Bundle);
1235 }
1236 }
1237}
1238
1239void ScheduleDAGInstrs::dumpNode(const SUnit &SU) const {
1240#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1241 dumpNodeName(SU);
1242 if (SchedPrintCycles)
1243 dbgs() << " [TopReadyCycle = " << SU.TopReadyCycle
1244 << ", BottomReadyCycle = " << SU.BotReadyCycle << "]";
1245 dbgs() << ": ";
1246 SU.getInstr()->dump();
1247#endif
1248}
1249
1251#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1252 if (EntrySU.getInstr() != nullptr)
1254 for (const SUnit &SU : SUnits)
1255 dumpNodeAll(SU);
1256 if (ExitSU.getInstr() != nullptr)
1258#endif
1259}
1260
1261#if !defined(NDEBUG) && LLVM_ENABLE_ABI_BREAKING_CHECKS
1262std::string ScheduleDAGInstrs::getGraphNodeLabel(const SUnit *SU) const {
1263 std::string s;
1264 raw_string_ostream oss(s);
1265 if (SU == &EntrySU)
1266 oss << "<entry>";
1267 else if (SU == &ExitSU)
1268 oss << "<exit>";
1269 else
1270 SU->getInstr()->print(oss, /*IsStandalone=*/true);
1271 return s;
1272}
1273#endif
1274
1275/// Return the basic block label. It is not necessarily unique because a block
1276/// contains multiple scheduling regions. But it is fine for visualization.
1278 return "dag." + BB->getFullName();
1279}
1280
1282 return SuccSU == &ExitSU || !Topo.IsReachable(PredSU, SuccSU);
1283}
1284
1285bool ScheduleDAGInstrs::addEdge(SUnit *SuccSU, const SDep &PredDep) {
1286 if (SuccSU != &ExitSU) {
1287 // Do not use WillCreateCycle, it assumes SD scheduling.
1288 // If Pred is reachable from Succ, then the edge creates a cycle.
1289 if (Topo.IsReachable(PredDep.getSUnit(), SuccSU))
1290 return false;
1291 Topo.AddPredQueued(SuccSU, PredDep.getSUnit());
1292 }
1293 SuccSU->addPred(PredDep, /*Required=*/!PredDep.isArtificial());
1294 // Return true regardless of whether a new edge needed to be inserted.
1295 return true;
1296}
1297
1298//===----------------------------------------------------------------------===//
1299// SchedDFSResult Implementation
1300//===----------------------------------------------------------------------===//
1301
1302namespace llvm {
1303
1304/// Internal state used to compute SchedDFSResult.
1306 SchedDFSResult &R;
1307
1308 /// Join DAG nodes into equivalence classes by their subtree.
1309 IntEqClasses SubtreeClasses;
1310 /// List PredSU, SuccSU pairs that represent data edges between subtrees.
1311 std::vector<std::pair<const SUnit *, const SUnit*>> ConnectionPairs;
1312
1313 struct RootData {
1314 unsigned NodeID;
1315 unsigned ParentNodeID; ///< Parent node (member of the parent subtree).
1316 unsigned SubInstrCount = 0; ///< Instr count in this tree only, not
1317 /// children.
1318
1319 RootData(unsigned id): NodeID(id),
1320 ParentNodeID(SchedDFSResult::InvalidSubtreeID) {}
1321
1322 unsigned getSparseSetIndex() const { return NodeID; }
1323 };
1324
1325 SparseSet<RootData> RootSet;
1326
1327public:
1328 SchedDFSImpl(SchedDFSResult &r): R(r), SubtreeClasses(R.DFSNodeData.size()) {
1329 RootSet.setUniverse(R.DFSNodeData.size());
1330 }
1331
1332 /// Returns true if this node been visited by the DFS traversal.
1333 ///
1334 /// During visitPostorderNode the Node's SubtreeID is assigned to the Node
1335 /// ID. Later, SubtreeID is updated but remains valid.
1336 bool isVisited(const SUnit *SU) const {
1337 return R.DFSNodeData[SU->NodeNum].SubtreeID
1338 != SchedDFSResult::InvalidSubtreeID;
1339 }
1340
1341 /// Initializes this node's instruction count. We don't need to flag the node
1342 /// visited until visitPostorder because the DAG cannot have cycles.
1343 void visitPreorder(const SUnit *SU) {
1344 R.DFSNodeData[SU->NodeNum].InstrCount =
1345 SU->getInstr()->isTransient() ? 0 : 1;
1346 }
1347
1348 /// Called once for each node after all predecessors are visited. Revisit this
1349 /// node's predecessors and potentially join them now that we know the ILP of
1350 /// the other predecessors.
1351 void visitPostorderNode(const SUnit *SU) {
1352 // Mark this node as the root of a subtree. It may be joined with its
1353 // successors later.
1354 R.DFSNodeData[SU->NodeNum].SubtreeID = SU->NodeNum;
1355 RootData RData(SU->NodeNum);
1356 RData.SubInstrCount = SU->getInstr()->isTransient() ? 0 : 1;
1357
1358 // If any predecessors are still in their own subtree, they either cannot be
1359 // joined or are large enough to remain separate. If this parent node's
1360 // total instruction count is not greater than a child subtree by at least
1361 // the subtree limit, then try to join it now since splitting subtrees is
1362 // only useful if multiple high-pressure paths are possible.
1363 unsigned InstrCount = R.DFSNodeData[SU->NodeNum].InstrCount;
1364 for (const SDep &PredDep : SU->Preds) {
1365 if (PredDep.getKind() != SDep::Data)
1366 continue;
1367 unsigned PredNum = PredDep.getSUnit()->NodeNum;
1368 if ((InstrCount - R.DFSNodeData[PredNum].InstrCount) < R.SubtreeLimit)
1369 joinPredSubtree(PredDep, SU, /*CheckLimit=*/false);
1370
1371 // Either link or merge the TreeData entry from the child to the parent.
1372 if (R.DFSNodeData[PredNum].SubtreeID == PredNum) {
1373 // If the predecessor's parent is invalid, this is a tree edge and the
1374 // current node is the parent.
1375 if (RootSet[PredNum].ParentNodeID == SchedDFSResult::InvalidSubtreeID)
1376 RootSet[PredNum].ParentNodeID = SU->NodeNum;
1377 }
1378 else if (RootSet.count(PredNum)) {
1379 // The predecessor is not a root, but is still in the root set. This
1380 // must be the new parent that it was just joined to. Note that
1381 // RootSet[PredNum].ParentNodeID may either be invalid or may still be
1382 // set to the original parent.
1383 RData.SubInstrCount += RootSet[PredNum].SubInstrCount;
1384 RootSet.erase(PredNum);
1385 }
1386 }
1387 RootSet[SU->NodeNum] = RData;
1388 }
1389
1390 /// Called once for each tree edge after calling visitPostOrderNode on
1391 /// the predecessor. Increment the parent node's instruction count and
1392 /// preemptively join this subtree to its parent's if it is small enough.
1393 void visitPostorderEdge(const SDep &PredDep, const SUnit *Succ) {
1394 R.DFSNodeData[Succ->NodeNum].InstrCount
1395 += R.DFSNodeData[PredDep.getSUnit()->NodeNum].InstrCount;
1396 joinPredSubtree(PredDep, Succ);
1397 }
1398
1399 /// Adds a connection for cross edges.
1400 void visitCrossEdge(const SDep &PredDep, const SUnit *Succ) {
1401 ConnectionPairs.emplace_back(PredDep.getSUnit(), Succ);
1402 }
1403
1404 /// Sets each node's subtree ID to the representative ID and record
1405 /// connections between trees.
1407 SubtreeClasses.compress();
1408 R.DFSTreeData.resize(SubtreeClasses.getNumClasses());
1409 assert(SubtreeClasses.getNumClasses() == RootSet.size()
1410 && "number of roots should match trees");
1411 for (const RootData &Root : RootSet) {
1412 unsigned TreeID = SubtreeClasses[Root.NodeID];
1413 if (Root.ParentNodeID != SchedDFSResult::InvalidSubtreeID)
1414 R.DFSTreeData[TreeID].ParentTreeID = SubtreeClasses[Root.ParentNodeID];
1415 R.DFSTreeData[TreeID].SubInstrCount = Root.SubInstrCount;
1416 // Note that SubInstrCount may be greater than InstrCount if we joined
1417 // subtrees across a cross edge. InstrCount will be attributed to the
1418 // original parent, while SubInstrCount will be attributed to the joined
1419 // parent.
1420 }
1421 R.SubtreeConnections.resize(SubtreeClasses.getNumClasses());
1422 R.SubtreeConnectLevels.resize(SubtreeClasses.getNumClasses());
1423 LLVM_DEBUG(dbgs() << R.getNumSubtrees() << " subtrees:\n");
1424 for (unsigned Idx = 0, End = R.DFSNodeData.size(); Idx != End; ++Idx) {
1425 R.DFSNodeData[Idx].SubtreeID = SubtreeClasses[Idx];
1426 LLVM_DEBUG(dbgs() << " " << SUnits[Idx] << " in tree "
1427 << R.DFSNodeData[Idx].SubtreeID << '\n');
1428 }
1429 for (const auto &[Pred, Succ] : ConnectionPairs) {
1430 unsigned PredTree = SubtreeClasses[Pred->NodeNum];
1431 unsigned SuccTree = SubtreeClasses[Succ->NodeNum];
1432 if (PredTree == SuccTree)
1433 continue;
1434 unsigned Depth = Pred->getDepth();
1435 addConnection(PredTree, SuccTree, Depth);
1436 addConnection(SuccTree, PredTree, Depth);
1437 }
1438 }
1439
1440protected:
1441 /// Joins the predecessor subtree with the successor that is its DFS parent.
1442 /// Applies some heuristics before joining.
1443 bool joinPredSubtree(const SDep &PredDep, const SUnit *Succ,
1444 bool CheckLimit = true) {
1445 assert(PredDep.getKind() == SDep::Data && "Subtrees are for data edges");
1446
1447 // Check if the predecessor is already joined.
1448 const SUnit *PredSU = PredDep.getSUnit();
1449 unsigned PredNum = PredSU->NodeNum;
1450 if (R.DFSNodeData[PredNum].SubtreeID != PredNum)
1451 return false;
1452
1453 // Four is the magic number of successors before a node is considered a
1454 // pinch point.
1455 unsigned NumDataSucs = 0;
1456 for (const SDep &SuccDep : PredSU->Succs) {
1457 if (SuccDep.getKind() == SDep::Data) {
1458 if (++NumDataSucs >= 4)
1459 return false;
1460 }
1461 }
1462 if (CheckLimit && R.DFSNodeData[PredNum].InstrCount > R.SubtreeLimit)
1463 return false;
1464 R.DFSNodeData[PredNum].SubtreeID = Succ->NodeNum;
1465 SubtreeClasses.join(Succ->NodeNum, PredNum);
1466 return true;
1467 }
1468
1469 /// Called by finalize() to record a connection between trees.
1470 void addConnection(unsigned FromTree, unsigned ToTree, unsigned Depth) {
1471 if (!Depth)
1472 return;
1473
1474 do {
1476 R.SubtreeConnections[FromTree];
1477 for (SchedDFSResult::Connection &C : Connections) {
1478 if (C.TreeID == ToTree) {
1479 C.Level = std::max(C.Level, Depth);
1480 return;
1481 }
1482 }
1483 Connections.push_back(SchedDFSResult::Connection(ToTree, Depth));
1484 FromTree = R.DFSTreeData[FromTree].ParentTreeID;
1485 } while (FromTree != SchedDFSResult::InvalidSubtreeID);
1486 }
1487};
1488
1489} // end namespace llvm
1490
1491namespace {
1492
1493/// Manage the stack used by a reverse depth-first search over the DAG.
1494class SchedDAGReverseDFS {
1495 std::vector<std::pair<const SUnit *, SUnit::const_pred_iterator>> DFSStack;
1496
1497public:
1498 bool isComplete() const { return DFSStack.empty(); }
1499
1500 void follow(const SUnit *SU) {
1501 DFSStack.emplace_back(SU, SU->Preds.begin());
1502 }
1503 void advance() { ++DFSStack.back().second; }
1504
1505 const SDep *backtrack() {
1506 DFSStack.pop_back();
1507 return DFSStack.empty() ? nullptr : std::prev(DFSStack.back().second);
1508 }
1509
1510 const SUnit *getCurr() const { return DFSStack.back().first; }
1511
1512 SUnit::const_pred_iterator getPred() const { return DFSStack.back().second; }
1513
1514 SUnit::const_pred_iterator getPredEnd() const {
1515 return getCurr()->Preds.end();
1516 }
1517};
1518
1519} // end anonymous namespace
1520
1521static bool hasDataSucc(const SUnit *SU) {
1522 for (const SDep &SuccDep : SU->Succs) {
1523 if (SuccDep.getKind() == SDep::Data &&
1524 !SuccDep.getSUnit()->isBoundaryNode())
1525 return true;
1526 }
1527 return false;
1528}
1529
1530/// Computes an ILP metric for all nodes in the subDAG reachable via depth-first
1531/// search from this root.
1533 if (!IsBottomUp)
1534 llvm_unreachable("Top-down ILP metric is unimplemented");
1535
1536 SchedDFSImpl Impl(*this);
1537 for (const SUnit &SU : SUnits) {
1538 if (Impl.isVisited(&SU) || hasDataSucc(&SU))
1539 continue;
1540
1541 SchedDAGReverseDFS DFS;
1542 Impl.visitPreorder(&SU);
1543 DFS.follow(&SU);
1544 while (true) {
1545 // Traverse the leftmost path as far as possible.
1546 while (DFS.getPred() != DFS.getPredEnd()) {
1547 const SDep &PredDep = *DFS.getPred();
1548 DFS.advance();
1549 // Ignore non-data edges.
1550 if (PredDep.getKind() != SDep::Data
1551 || PredDep.getSUnit()->isBoundaryNode()) {
1552 continue;
1553 }
1554 // An already visited edge is a cross edge, assuming an acyclic DAG.
1555 if (Impl.isVisited(PredDep.getSUnit())) {
1556 Impl.visitCrossEdge(PredDep, DFS.getCurr());
1557 continue;
1558 }
1559 Impl.visitPreorder(PredDep.getSUnit());
1560 DFS.follow(PredDep.getSUnit());
1561 }
1562 // Visit the top of the stack in postorder and backtrack.
1563 const SUnit *Child = DFS.getCurr();
1564 const SDep *PredDep = DFS.backtrack();
1565 Impl.visitPostorderNode(Child);
1566 if (PredDep)
1567 Impl.visitPostorderEdge(*PredDep, DFS.getCurr());
1568 if (DFS.isComplete())
1569 break;
1570 }
1571 }
1572 Impl.finalize(SUnits);
1573}
1574
1575/// The root of the given SubtreeID was just scheduled. For all subtrees
1576/// connected to this tree, record the depth of the connection so that the
1577/// nearest connected subtrees can be prioritized.
1578void SchedDFSResult::scheduleTree(unsigned SubtreeID) {
1579 for (const Connection &C : SubtreeConnections[SubtreeID]) {
1580 SubtreeConnectLevels[C.TreeID] =
1581 std::max(SubtreeConnectLevels[C.TreeID], C.Level);
1582 LLVM_DEBUG(dbgs() << " Tree: " << C.TreeID << " @"
1583 << SubtreeConnectLevels[C.TreeID] << '\n');
1584 }
1585}
1586
1587#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1589 OS << InstrCount << " / " << Length << " = ";
1590 if (!Length)
1591 OS << "BADILP";
1592 else
1593 OS << format("%g", ((double)InstrCount / Length));
1594}
1595
1597 dbgs() << *this << '\n';
1598}
1599
1600[[maybe_unused]]
1602 Val.print(OS);
1603 return OS;
1604}
1605
1606#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:686
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static unsigned InstrCount
static cl::opt< bool > UseAA("amdgpu-use-aa-in-codegen", cl::desc("Enable the use of AA during codegen."), cl::init(true))
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
#define _
IRTranslator LLVM IR MI
Equivalence classes for small integers.
A common definition of LaneBitmask for use in TableGen and CodeGen.
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
This file implements a map that provides insertion order iteration.
#define P(N)
static void toggleKills(const MachineRegisterInfo &MRI, LiveRegUnits &LiveRegs, MachineInstr &MI, bool addToLiveRegs)
static bool getUnderlyingObjectsForInstr(const MachineInstr *MI, const MachineFrameInfo &MFI, UnderlyingObjectsVector &Objects, const DataLayout &DL)
If this machine instruction has memory reference information, collect the list of underlying objects ...
static bool hasDataSucc(const SUnit *SU)
static cl::opt< bool > EnableSchedModel("schedmodel", cl::Hidden, cl::init(true), cl::desc("Use TargetSchedModel for latency lookup"))
static cl::opt< bool > EnableAASchedMI("enable-aa-sched-mi", cl::Hidden, cl::desc("Enable use of AA during MI DAG construction"))
static cl::opt< bool > UseTBAA("use-tbaa-in-sched-mi", cl::Hidden, cl::init(true), cl::desc("Enable use of TBAA during MI DAG construction"))
static cl::opt< unsigned > HugeRegion("dag-maps-huge-region", cl::Hidden, cl::init(500), cl::desc("The limit to use while constructing the DAG " "prior to scheduling, at which point a trade-off " "is made to avoid excessive compile time."))
static cl::opt< bool > EnableSchedItins("scheditins", cl::Hidden, cl::init(true), cl::desc("Use InstrItineraryData for latency lookup"))
static cl::opt< bool > EnableStoreSequencing("enable-store-sequencing", cl::Hidden, cl::init(false), cl::desc("Enable the store-sequencing DAG construction algorithm. This can " "eliminate a large number of redundant control dependencies and " "spurious alias analysis queries at the cost of some unnecessary " "dependencies."))
static cl::opt< bool > SchedPrintCycles("sched-print-cycles", cl::Hidden, cl::init(false), cl::desc("Report top/bottom cycles when dumping SUnit instances"))
This file defines the SmallVector class.
This file defines the SparseSet class derived from the version described in Briggs,...
#define LLVM_DEBUG(...)
Definition Debug.h:119
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ConstMIBundleOperands - Iterate over all operands in a const bundle of machine instructions.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A set of register units used to track register liveness.
Describe properties that are true of each instruction in the target description file.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
bool hasImplicitUseOfPhysReg(MCRegister Reg) const
Return true if this instruction implicitly uses the specified physical register.
LLVM_ABI bool hasImplicitDefOfPhysReg(MCRegister Reg, const MCRegisterInfo *MRI=nullptr) const
Return true if this instruction implicitly defines the specified physical register.
MCRegUnitMaskIterator enumerates a list of register units and their associated lane masks for Reg.
bool isValid() const
Returns true if this iterator is not yet at the end.
LaneBitmask getLaneMask() const
Returns the combination of all lane masks of register in this class.
const bool HasDisjunctSubRegs
Whether the class supports two (or more) disjunct subregister indices.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr > iterator
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool hasTailCall() const
Returns true if the function contains a tail call.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Representation of each machine instruction.
bool isBarrier(QueryType Type=AnyInBundle) const
Returns true if the specified instruction stops control flow from executing the instruction immediate...
bool isCall(QueryType Type=AnyInBundle) const
LLVM_ABI bool mayAlias(BatchAAResults *AA, const MachineInstr &Other, bool UseTBAA) const
Returns true if this instruction's memory access aliases the memory access of Other.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
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.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
bool isTransient() const
Return true if this is a transient instruction that is either very likely to be eliminated during reg...
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
void setIsKill(bool Val=true)
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
Array of PressureDiffs.
LLVM_ABI void init(unsigned N)
Initialize an array of N PressureDiffs.
Special value supplied for machine level alias analysis.
Track the current register pressure at some position in the instruction stream, and remember the high...
List of registers defined and used by a machine instruction.
LLVM_ABI void detectDeadDefs(const MachineInstr &MI, LiveIntervals &LIS, const MachineRegisterInfo &MRI)
Use liveness information to find dead defs at MI's dead slot not marked with a dead flag and move the...
LLVM_ABI void adjustLaneLiveness(LiveIntervals &LIS, const MachineRegisterInfo &MRI, SlotIndex Pos)
Use liveness information to find out which uses/defs are partially undefined/dead at Pos and adjust t...
LLVM_ABI 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...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
Scheduling dependency.
Definition ScheduleDAG.h:54
SUnit * getSUnit() const
Kind getKind() const
Returns an enum value representing the kind of the dependence.
Kind
These are the different kinds of scheduling dependencies.
Definition ScheduleDAG.h:57
@ Output
A register output-dependence (aka WAW).
Definition ScheduleDAG.h:60
@ Anti
A register anti-dependence (aka WAR).
Definition ScheduleDAG.h:59
@ Data
Regular data dependence (aka true-dependence).
Definition ScheduleDAG.h:58
void setLatency(unsigned Lat)
Sets the latency for this edge.
@ Artificial
Arbitrary strong DAG edge (no real dependence).
Definition ScheduleDAG.h:77
@ MayAliasMem
Nonvolatile load/Store instructions that may alias.
Definition ScheduleDAG.h:75
bool isArtificial() const
Tests if this is an Order dependence that is marked as "artificial", meaning it isn't necessary for c...
Scheduling unit. This is a node in the scheduling DAG.
bool isCall
Is a function call.
bool addPredBarrier(SUnit *SU)
Adds a barrier edge to SU by calling addPred(), with latency 0 generally or latency 1 for a store fol...
unsigned NumSuccs
unsigned TopReadyCycle
Cycle relative to start when node is ready.
unsigned NodeNum
Entry # of node in the node vector.
bool isUnbuffered
Uses an unbuffered resource.
SmallVectorImpl< SDep >::const_iterator const_pred_iterator
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.
unsigned BotReadyCycle
Cycle relative to end when node is ready.
SmallVector< SDep, 4 > Succs
All sunit successors.
bool hasReservedResource
Uses a reserved resource.
bool isCommutable
Is a commutable instruction.
bool hasPhysRegUses
Has physreg uses.
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.
void visitPostorderNode(const SUnit *SU)
Called once for each node after all predecessors are visited.
bool joinPredSubtree(const SDep &PredDep, const SUnit *Succ, bool CheckLimit=true)
Joins the predecessor subtree with the successor that is its DFS parent.
void addConnection(unsigned FromTree, unsigned ToTree, unsigned Depth)
Called by finalize() to record a connection between trees.
void visitCrossEdge(const SDep &PredDep, const SUnit *Succ)
Adds a connection for cross edges.
void finalize(ArrayRef< SUnit > SUnits)
Sets each node's subtree ID to the representative ID and record connections between trees.
void visitPostorderEdge(const SDep &PredDep, const SUnit *Succ)
Called once for each tree edge after calling visitPostOrderNode on the predecessor.
void visitPreorder(const SUnit *SU)
Initializes this node's instruction count.
bool isVisited(const SUnit *SU) const
Returns true if this node been visited by the DFS traversal.
SchedDFSImpl(SchedDFSResult &r)
Compute the values of each DAG node for various metrics during DFS.
Definition ScheduleDFS.h:65
friend class SchedDFSImpl
Definition ScheduleDFS.h:66
LLVM_ABI void compute(ArrayRef< SUnit > SUnits)
Compute various metrics for the DAG with given roots.
LLVM_ABI void scheduleTree(unsigned SubtreeID)
Scheduler callback to update SubtreeConnectLevels when a tree is initially scheduled.
ScheduleDAGDependencyBuilder(ScheduleDAGInstrs &DAG, BatchAAResults *AA, RegPressureTracker *RPTracker, PressureDiffs *PDiffs, LiveIntervals *LIS)
A ScheduleDAG for scheduling lists of MachineInstr.
LiveRegUnits LiveRegs
Set of live physical registers for updating kill flags.
DenseMap< MachineInstr *, SUnit * > MISUnitMap
After calling BuildSchedGraph, each machine instruction in the current scheduling region is mapped to...
void addVRegUseDeps(SUnit *SU, unsigned OperIdx)
Adds a register data dependency if the instruction that defines the virtual register used at OperIdx ...
void addVRegDefDeps(SUnit *SU, unsigned OperIdx)
Adds register output and data dependencies from this SUnit to instructions that occur later in the sa...
virtual void finishBlock()
Cleans up after scheduling in the given block.
MachineBasicBlock::iterator end() const
Returns an iterator to the bottom of the current scheduling region.
std::string getDAGName() const override
Returns a label for the region of code covered by the DAG.
MachineBasicBlock * BB
The block in which to insert instructions.
virtual void startBlock(MachineBasicBlock *BB)
Prepares to perform scheduling in the given block.
void addPhysRegDeps(SUnit *SU, unsigned OperIdx)
Adds register dependencies (data, anti, and output) from this SUnit to following instructions in the ...
friend class ScheduleDAGDependencyBuilder
MachineBasicBlock::iterator RegionEnd
The end of the range to be scheduled.
VReg2SUnitOperIdxMultiMap CurrentVRegUses
Tracks the last instructions in this region using each virtual register.
const MCSchedClassDesc * getSchedClass(SUnit *SU) const
Resolves and cache a resolved scheduling class for an SUnit.
void fixupKills(MachineBasicBlock &MBB)
Fixes register kill flags that scheduling has made invalid.
void addPhysRegDataDeps(SUnit *SU, unsigned OperIdx)
MO is an operand of SU's instruction that defines a physical register.
ScheduleDAGInstrs(MachineFunction &mf, const MachineLoopInfo *mli, bool RemoveKillFlags=false)
LaneBitmask getLaneMaskForMO(const MachineOperand &MO) const
Returns a mask for which lanes get read/written by the given (register) machine operand.
DbgValueVector DbgValues
Remember instruction that precedes DBG_VALUE.
SUnit * newSUnit(MachineInstr *MI)
Creates a new SUnit and return a ptr to it.
void initSUnits()
Creates an SUnit for each real instruction, numbered in top-down topological order.
bool addEdge(SUnit *SuccSU, const SDep &PredDep)
Add a DAG edge to the given SU with the given predecessor dependence data.
ScheduleDAGTopologicalSort Topo
Topo - A topological ordering for SUnits which permits fast IsReachable and similar queries.
bool TrackLaneMasks
Whether lane masks should get tracked.
void dumpNode(const SUnit &SU) const override
RegUnit2SUnitsMap Defs
Defs, Uses - Remember where defs and uses of each register are as we iterate upward through the instr...
VReg2SUnitMultiMap CurrentVRegDefs
Tracks the last instruction(s) in this region defining each virtual register.
MachineBasicBlock::iterator begin() const
Returns an iterator to the top of the current scheduling region.
void buildSchedGraph(AAResults *AA, RegPressureTracker *RPTracker=nullptr, PressureDiffs *PDiffs=nullptr, LiveIntervals *LIS=nullptr, bool TrackLaneMasks=false)
Builds SUnits for the current region.
TargetSchedModel SchedModel
TargetSchedModel provides an interface to the machine model.
virtual void exitRegion()
Called when the scheduler has finished scheduling the current region.
bool canAddEdge(SUnit *SuccSU, SUnit *PredSU)
True if an edge can be added from PredSU to SuccSU without creating a cycle.
const MachineLoopInfo * MLI
bool RemoveKillFlags
True if the DAG builder should remove kill flags (in preparation for rescheduling).
MachineBasicBlock::iterator RegionBegin
The beginning of the range to be scheduled.
void addSchedBarrierDeps()
Adds dependencies from instructions in the current list of instructions being scheduled to scheduling...
virtual void enterRegion(MachineBasicBlock *bb, MachineBasicBlock::iterator begin, MachineBasicBlock::iterator end, unsigned regioninstrs)
Initialize the DAG and common scheduler state for a new scheduling region.
void dump() const override
unsigned NumRegionInstrs
Instructions in this region (distance(RegionBegin, RegionEnd)).
const MachineFrameInfo & MFI
bool deadDefHasNoUse(const MachineOperand &MO)
Returns true if the def register in MO has no uses.
MachineRegisterInfo & MRI
Virtual/real register map.
void clearDAG()
Clears the DAG state (between regions).
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.
ScheduleDAG(const ScheduleDAG &)=delete
void dumpNodeAll(const SUnit &SU) const
void dumpNodeName(const SUnit &SU) const
SUnit ExitSU
Special node for the region exit.
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
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...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseSet - Fast set implementation for objects that can be identified by small unsigned keys.
Definition SparseSet.h:117
TargetInstrInfo - Interface to description of machine instruction set.
TargetSubtargetInfo - Generic base class for all target subtargets.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
LLVM Value Representation.
Definition Value.h:75
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an std::string.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
Definition Attributor.h:165
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1685
SmallVector< ValueType, 4 > UnderlyingObjectsVector
LLVM_ABI bool getUnderlyingObjectsForCodeGen(const Value *V, SmallVectorImpl< Value * > &Objects)
This is a wrapper around getUnderlyingObjects and adds support for basic ptrtoint+arithmetic+inttoptr...
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IterT skipDebugInstructionsBackward(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition Format.h:102
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
Represent the ILP of the subDAG rooted at a DAG node.
Definition ScheduleDFS.h:34
unsigned Length
Length may either correspond to depth or height, depending on direction, and cycles or nodes dependin...
Definition ScheduleDFS.h:38
LLVM_ABI void dump() const
LLVM_ABI void print(raw_ostream &OS) const
unsigned InstrCount
Definition ScheduleDFS.h:35
static constexpr LaneBitmask getAll()
Definition LaneBitmask.h:82
constexpr bool any() const
Definition LaneBitmask.h:53
Summarize the scheduling resources required for an instruction of a particular scheduling class.
Definition MCSchedule.h:129
Identify one of the processor resource kinds consumed by a particular scheduling class for the specif...
Definition MCSchedule.h:74
Record a physical register access.
Mapping from virtual register to SUnit including an operand index.
An individual mapping from virtual register number to SUnit.