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