LLVM 24.0.0git
GCNRematStrategy.cpp
Go to the documentation of this file.
1//===-- GCNRematStrategy.cpp - Rematerialization strategy -*- C++ -*-------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Implements the rematerialization strategy.
11//
12//===----------------------------------------------------------------------===//
13
14#include "GCNRematStrategy.h"
15#include "GCNRegPressure.h"
17#include "llvm/ADT/BitVector.h"
22#include "llvm/MC/LaneBitmask.h"
23#include "llvm/Support/Debug.h"
24
25#define DEBUG_TYPE "gcn-rematerialization-strategy"
26
27using namespace llvm;
30
31GCNRematStrategy::RematRegions::RematRegions(
36 : Bounds(Regions), LiveIns(LiveIns), LiveOuts(LiveOuts),
37 Frequencies(Regions.size(), 0), LIS(LIS), MRI(MRI) {
38 assert(LiveIns.size() == Regions.size());
39 assert(LiveOuts.size() == Regions.size());
40
41 // Derive frequency of each region. Frequencies are scaled down if they are
42 // high to avoid overflow/underflow when combining them.
43 MinFreq = MBFI.getEntryFreq().getFrequency();
44 MaxFreq = 0;
45 for (unsigned RegionIdx : seq(Regions.size())) {
46 MachineBasicBlock *MBB = Regions[RegionIdx].first->getParent();
47 uint64_t BlockFreq = MBFI.getBlockFreq(MBB).getFrequency();
48 Frequencies[RegionIdx] = BlockFreq;
49 if (BlockFreq && BlockFreq < MinFreq)
50 MinFreq = BlockFreq;
51 else if (BlockFreq > MaxFreq)
52 MaxFreq = BlockFreq;
53 }
54 if (!MinFreq)
55 return;
56
57 // Scale everything down if frequencies are high.
58 if (MinFreq >= FreqScaleFactor * FreqScaleFactor) {
59 for (uint64_t &Freq : Frequencies)
60 Freq /= FreqScaleFactor;
61 MinFreq /= FreqScaleFactor;
62 MaxFreq /= FreqScaleFactor;
63 }
64}
65
66GCNRegPressure GCNRematStrategy::RematRegions::computeMaxRegPressure(
67 unsigned RegionIdx) const {
68 assert(RegionIdx < Bounds.size() && "out of bounds");
69 const auto &[Begin, End] = Bounds[RegionIdx];
70 if (Begin == End)
71 return llvm::getRegPressure(MRI, LiveIns[RegionIdx]);
72 GCNDownwardRPTracker RPTracker(LIS);
73 RPTracker.advance(Begin, End, &LiveIns[RegionIdx]);
74 return RPTracker.moveMaxPressure();
75}
76
77void GCNRematStrategy::RematRegions::removeFromLiveMaps(
78 Register Reg, const BitVector &LiveIn, const BitVector &LiveOut) {
79 for (unsigned I : LiveIn.set_bits())
80 LiveIns[I].erase(Reg);
81 for (unsigned I : LiveOut.set_bits())
82 LiveOuts[I].erase(Reg);
83}
84
85void GCNRematStrategy::RematRegions::addToLiveMaps(Register Reg,
86 LaneBitmask Mask,
87 const BitVector &LiveIn,
88 const BitVector &LiveOut) {
89 std::pair<Register, LaneBitmask> LiveReg(Reg, Mask);
90 for (unsigned I : LiveIn.set_bits())
91 LiveIns[I].insert(LiveReg);
92 for (unsigned I : LiveOut.set_bits())
93 LiveOuts[I].insert(LiveReg);
94}
95
96GCNRematStrategy::RematTargets::RematTargets(
97 unsigned MaxSGPRs, unsigned MaxVGPRs, bool SpillReduction,
98 const MachineFunction &MF, const RematRegions &Regions,
99 ArrayRef<GCNRegPressure> *MaxPressure)
100 : ExcessRP(Regions.size()), Regions(Regions),
101 SpillReduction(SpillReduction) {
102 RPTargets.reserve(Regions.size());
103 for (unsigned RegionIdx : seq(Regions.size())) {
104 if (MaxPressure) {
105 RPTargets.emplace_back(MaxSGPRs, MaxVGPRs, MF, (*MaxPressure)[RegionIdx]);
106 } else {
107 RPTargets.emplace_back(MaxSGPRs, MaxVGPRs, MF,
108 Regions.computeMaxRegPressure(RegionIdx));
109 }
110 if (!RPTargets.back().satisfied())
111 ExcessRP.set(RegionIdx);
112 }
113}
114
115void GCNRematStrategy::RematTargets::updateRPTargets(
116 const BitVector &UpdateRegions, const GCNRegPressure &RPSave) {
117 for (unsigned I : UpdateRegions.set_bits()) {
118 RPTargets[I].saveRP(RPSave);
119 if (ExcessRP[I] && RPTargets[I].satisfied()) {
120 LLVM_DEBUG(dbgs() << " [" << I << "] Target reached!\n");
121 ExcessRP.reset(I);
122 }
123 }
124}
125
126bool GCNRematStrategy::RematTargets::updateAndVerifyRPTargets(
127 const BitVector &UpdateRegions) {
128 bool TooOptimistic = false;
129 for (unsigned RegionIdx : UpdateRegions.set_bits()) {
130 GCNRPTarget &Target = RPTargets[RegionIdx];
131 Target.setRP(Regions.computeMaxRegPressure(RegionIdx));
132
133 // Since we were optimistic in assessing RP decreases in these regions, we
134 // may need to remark the target as a target region if RP didn't decrease
135 // as expected.
136 if (!ExcessRP.test(RegionIdx) && !Target.satisfied()) {
137 LLVM_DEBUG(dbgs() << " [" << RegionIdx << "] Incorrect RP estimation\n");
138 TooOptimistic = true;
139 ExcessRP.set(RegionIdx);
140 }
141 }
142 return TooOptimistic;
143}
144
145void GCNRematStrategy::RematCandidate::init(const RematRegions &RF,
146 const Rematerializer &Remater,
147 const MachineRegisterInfo &MRI) {
148 const Rematerializer::Reg &Reg = Remater.getReg(RegIdx);
149 Register DefReg = Reg.getDefReg();
150
151 Live |= LiveIn;
152 Live |= LiveOut;
153
154 for (unsigned I : Live.set_bits()) {
155 // If the register is both unused and live-through in the region, the
156 // latter's RP is guaranteed to decrease.
157 if (!LiveIn[I] || !LiveOut[I] || Reg.Uses.contains(I))
158 UnpredictableRPSave.set(I);
159 }
160 RPSave.inc(DefReg, LaneBitmask::getNone(), Reg.Mask, MRI);
161
162 // Estimate the difference in instruction execution frequency that will be
163 // induced by the rematerialization. A rematerialization from the least
164 // frequent region to the most frequent region should yield the greatest
165 // frequency penalty (most negative frequency difference). When the register
166 // has users in its defining region the original instruction(s) won't be
167 // deleted so there is no frequency gain in the defining region.
168 int64_t DefOrMin =
169 Reg.hasUsersInDefRegion() ? 0 : RF.getFrequencyOrMin(Reg.DefRegion);
170 int64_t UseOrMax = 0;
171 for (const auto &[UseRegion, _] : Reg.Uses) {
172 if (Reg.DefRegion == UseRegion)
173 continue;
174 UseOrMax += RF.getFrequencyOrMax(UseRegion);
175 }
176 FreqDiff = DefOrMin - UseOrMax;
177}
178
179void GCNRematStrategy::RematCandidate::update(const RematTargets &Targets) {
180 MaxFreq = RegionImpact = 0;
181 for (unsigned RegionIdx : Targets.ExcessRP.set_bits()) {
182 if (!Live[RegionIdx])
183 continue;
184
185 // The rematerialization must contribute positively in at least one
186 // register class with usage above the RP target for this region to
187 // contribute to the score.
188 const GCNRPTarget &RegionTarget = Targets.RPTargets[RegionIdx];
189 const unsigned NumRegsBenefit = RegionTarget.getNumRegsBenefit(RPSave);
190 if (!NumRegsBenefit)
191 continue;
192
193 // Regions in which RP is guaranteed to decrease have more weight.
194 RegionImpact += (UnpredictableRPSave[RegionIdx] ? 1 : 2) * NumRegsBenefit;
195
196 if (Targets.SpillReduction) {
197 uint64_t Freq = Targets.Regions.getFrequency(RegionIdx);
198 if (UnpredictableRPSave[RegionIdx]) {
199 // Apply a frequency penalty in regions in which we are not sure that RP
200 // will decrease.
201 Freq /= 2;
202 }
203 MaxFreq = std::max(MaxFreq, Freq);
204 }
205 }
206}
207
208bool GCNRematStrategy::RematCandidate::maybeBeneficial(
209 const RematTargets &Targets) const {
210 for (unsigned I : Targets.ExcessRP.set_bits()) {
211 if (Live[I] && Targets.RPTargets[I].isSaveBeneficial(RPSave))
212 return true;
213 }
214 return false;
215}
216
217void GCNRematStrategy::RematCandidate::rematerialize(
218 Rematerializer &Remater) const {
219 const Rematerializer::Reg &Reg = Remater.getReg(RegIdx);
220
221 // All rematerializable dependencies are re-used for all rematerializations.
222 Rematerializer::DependencyReuseInfo DRI;
223 for (RegisterIdx DepRegIdx : Reg.Dependencies)
224 DRI.reuse(DepRegIdx);
225
226 // Rematerialize once per using region, except in the defining region.
227 SmallVector<unsigned, 8> RematRegions;
228 RematRegions.reserve(Reg.Uses.size());
229 for (const auto &[UseRegion, _] : Reg.Uses) {
230 if (Reg.DefRegion != UseRegion)
231 RematRegions.push_back(UseRegion);
232 }
233 for (const unsigned UseRegion : RematRegions) {
234 Rematerializer::DependencyReuseInfo RegionDRI(DRI);
235 Remater.rematerializeToRegion(RegIdx, UseRegion, RegionDRI);
236 }
237}
238
240 unsigned MaxSGPRs, unsigned MaxVGPRs, bool SpillReduction,
241 BitVector &AffectedRegions, MutableArrayRef<GCNRegPressure> *MaxPressure) {
242 assert(AffectedRegions.size() == Regions.size());
243 assert(!MaxPressure || MaxPressure->size() == Regions.size());
244
245 RematTargets Targets(MaxSGPRs, MaxVGPRs, SpillReduction, MF, Regions,
246 MaxPressure);
247 if (Targets.allAchieved())
248 return;
249 if (!CandidatesCreated) {
250 Remater.analyze();
251 createCandidates();
252 }
253
254 LLVM_DEBUG({
255 dbgs() << "Rematerializing across regions to reduce RP below target in "
256 "function ";
257 MF.getFunction().printAsOperand(dbgs(), /*PrintType=*/false);
258 dbgs() << '\n'
259 << Candidates.size()
260 << " rematerialization candidates were identified in the function\n"
261 << Targets.print() << '\n';
262 MF.print(dbgs(), LIS.getSlotIndexes());
263 });
264
265 // Keep track of all useful candidates.
266 SmallVector<unsigned, 8> CandidateOrder;
267 for (auto [CandIdx, Cand] : enumerate(Candidates)) {
268 Cand.update(Targets);
269 if (!Cand.hasNullScore())
270 CandidateOrder.push_back(CandIdx);
271 }
272
273 // Rematerialize registers in successive rounds until all RP targets are
274 // satisifed or until we run out of rematerialization candidates.
275 BitVector RecomputeRP(Regions.size());
276 for (;;) {
277 RecomputeRP.reset();
278
279 // Sort candidates in increasing score order.
280 sort(CandidateOrder, [&](unsigned LHSIndex, unsigned RHSIndex) {
281 return Candidates[LHSIndex] < Candidates[RHSIndex];
282 });
283
284 LLVM_DEBUG({
285 dbgs() << "==== NEW REMAT ROUND ====\n"
286 << "Candidates with non-null score, in rematerialization order:\n";
287 for (const RematCandidate &Cand : reverse(Candidates)) {
288 dbgs() << " " << Cand.print() << " | "
289 << Remater.printRematReg(Cand.RegIdx) << '\n';
290 }
291 dbgs() << Targets.print();
292 });
293
294 // Rematerialize registers in decreasing score order until we estimate
295 // that all RP targets are satisfied or until rematerialization candidates
296 // are no longer useful to decrease RP.
297 while (!CandidateOrder.empty()) {
298 const RematCandidate &Cand = Candidates[CandidateOrder.back()];
299 const Rematerializer::Reg &Reg = Remater.getReg(Cand.RegIdx);
300
301 // When previous rematerializations in this round have already satisfied
302 // RP targets in all regions this rematerialization can impact, we have a
303 // good indication that our scores have diverged significantly from
304 // reality, in which case we interrupt this round and re-score. This also
305 // ensures that every rematerialization we perform is possibly impactful
306 // in at least one target region.
307 if (!Cand.maybeBeneficial(Targets)) {
308 LLVM_DEBUG(dbgs() << "Interrupt round on stale score for "
309 << Cand.print() << " | "
310 << Remater.printRematReg(Cand.RegIdx));
311 break;
312 }
313 CandidateOrder.pop_back();
314
315#ifdef EXPENSIVE_CHECKS
316 // All uses outside the defining region are known to be available / live
317 // at the remat points. Thus, the uses should already be live in to
318 // those using regions.
319 const TargetRegisterInfo &TRI = *MRI.getTargetRegisterInfo();
320 for (const MachineInstr *DefMI : Reg.Defs) {
321 for (const MachineOperand &MO : DefMI->operands()) {
322 // Exclude the defined register. We are rematerializing all
323 // instructions defining it so we don't care that its value is
324 // available at the remat point.
325 if (!MO.isReg() || !MO.getReg() || !MO.readsReg() || MO.isDef())
326 continue;
327
328 Register UseReg = MO.getReg();
329 if (!UseReg.isVirtual())
330 continue;
331
332 LiveInterval &LI = LIS.getInterval(UseReg);
333 LaneBitmask LM = MRI.getMaxLaneMaskForVReg(MO.getReg());
334 if (LI.hasSubRanges() && MO.getSubReg())
335 LM = TRI.getSubRegIndexLaneMask(MO.getSubReg());
336
337 for (const auto &[UseRegion, _] : Reg.Uses) {
338 if (UseRegion == Reg.DefRegion)
339 continue;
340 LaneBitmask LiveInMask = Regions.getLiveIns(UseRegion).at(UseReg);
341 LaneBitmask UncoveredLanes = LM & ~(LiveInMask & LM);
342 // If this register has lanes not covered by the LiveIns, be sure
343 // they do not map to any subrange. ref:
344 // machine-scheduler-sink-trivial-remats.mir::omitted_subrange
345 if (UncoveredLanes.any()) {
346 assert(LI.hasSubRanges());
347 for (LiveInterval::SubRange &SR : LI.subranges())
348 assert((SR.LaneMask & UncoveredLanes).none());
349 }
350 }
351 }
352 }
353#endif
354
355 // Remove the register from all regions where it is a live-in or live-out,
356 // then rematerialize the register.
357 LLVM_DEBUG(dbgs() << "** REMAT " << Remater.printRematReg(Cand.RegIdx)
358 << '\n');
359 Regions.removeFromLiveMaps(Reg.getDefReg(), Cand.LiveIn, Cand.LiveOut);
360 if (Recorder) {
361 Recorder->LiveMapUpdates.emplace_back(Cand.RegIdx, Cand.LiveIn,
362 Cand.LiveOut);
363 }
364 Cand.rematerialize(Remater);
365
366 // Adjust RP targets. The save is guaranteed in regions in which the
367 // register is live-through and unused but optimistic in all other regions
368 // where the register is live.
369 Targets.updateRPTargets(Cand.Live, Cand.RPSave);
370 RecomputeRP |= Cand.UnpredictableRPSave;
371 AffectedRegions |= Cand.Live;
372 if (Targets.allAchieved()) {
373 LLVM_DEBUG(dbgs() << "All targets cleared, verifying...\n");
374 break;
375 }
376 }
377
378 if (!Targets.updateAndVerifyRPTargets(RecomputeRP) &&
379 Targets.allAchieved()) {
380 LLVM_DEBUG(dbgs() << "Objectives achieved!\n");
381 break;
382 }
383
384 // Update the score of remaining candidates and filter out those that have
385 // become useless from the vector. Candidates never become useful after
386 // having been useless for a round, so we can freely drop them without
387 // losing any future rematerialization opportunity.
388 unsigned NumUsefulCandidates = 0;
389 for (unsigned CandIdx : CandidateOrder) {
390 RematCandidate &Candidate = Candidates[CandIdx];
391 Candidate.update(Targets);
392 if (!Candidate.hasNullScore())
393 CandidateOrder[NumUsefulCandidates++] = CandIdx;
394 }
395 if (NumUsefulCandidates == 0) {
396 LLVM_DEBUG(dbgs() << "Stop on exhausted rematerialization candidates\n");
397 break;
398 }
399 CandidateOrder.truncate(NumUsefulCandidates);
400 }
401
402 if (!MaxPressure)
403 return;
404 for (unsigned RegionIdx : AffectedRegions.set_bits())
405 (*MaxPressure)[RegionIdx] = Targets.RPTargets[RegionIdx].getCurrentRP();
406}
407
408void GCNRematStrategy::createCandidates() {
409 CandidatesCreated = true;
410
411 // Set of registers already marked for potential remterialization; used to
412 // avoid rematerialization chains.
413 SmallSet<Register, 4> MarkedRegs;
414
415 // Map registers to candidate indices. Use ~0u as null value since 0 is a
416 // valid index.
418 DefRegToCandIdx.resize(MRI.getNumVirtRegs());
419 const unsigned NumRegions = Regions.size();
420
421 for (unsigned RegIdx = 0, E = Remater.getNumRegs(); RegIdx < E; ++RegIdx) {
422 const Rematerializer::Reg &CandReg = Remater.getReg(RegIdx);
423 if (!CandReg.hasUsersOutsideDefRegion())
424 continue;
425
426 // Rematerialization moves the defining instruction into the region of its
427 // uses, which may sit under different control dependencies (e.g., across a
428 // change of EXEC). Convergent operations must not be made control-dependent
429 // on additional values, so they cannot be safely relocated this way. This
430 // mirrors the check MachineSink performs before sinking an instruction.
431 if (any_of(CandReg.Defs,
432 [](const MachineInstr *DefMI) { return DefMI->isConvergent(); }))
433 continue;
434
435 // Rematerializing a load into multiple using regions duplicates the
436 // memory access itself. Conservatively restrict rematerialization of loads
437 // to a single region.
438 if (CandReg.Uses.size() > 1 &&
439 any_of(CandReg.Defs,
440 [](const MachineInstr *DefMI) { return DefMI->mayLoad(); }))
441 continue;
442
443 // We further filter the registers that we can rematerialize based on our
444 // current tracking capabilities in the strategy. This ensures that we are
445 // not extending any live range while rematerializing, and that
446 // rematerializing any register candidate will not affect other candidates.
447
448 // All register dependencies should not already be considered
449 // rematerializable.
450 if (llvm::any_of(CandReg.Dependencies, [&](RegisterIdx DepRegIdx) {
451 return MarkedRegs.contains(Remater.getReg(DepRegIdx).getDefReg());
452 }))
453 continue;
454
455 if (!candidateHasValidUsers(RegIdx, MarkedRegs))
456 continue;
457
458 Register DefReg = CandReg.getDefReg();
459 MarkedRegs.insert(DefReg);
460 DefRegToCandIdx[DefReg] = static_cast<unsigned>(Candidates.size());
461 Candidates.emplace_back(RegIdx, NumRegions);
462 }
463
464 // Initialize the LiveIn and LiveOut sets of all candidates. This is more
465 // efficient than querying those structures for each candidate separately.
466 for (unsigned RegionIdx = 0; RegionIdx < NumRegions; ++RegionIdx) {
467 for (const auto &[Reg, Mask] : Regions.getLiveIns(RegionIdx)) {
469 continue;
470 unsigned CandIdx = DefRegToCandIdx[Reg];
471 if (CandIdx != ~0u)
472 Candidates[CandIdx].LiveIn.set(RegionIdx);
473 }
474 for (const auto &[Reg, Mask] : Regions.getLiveOuts(RegionIdx)) {
476 continue;
477 unsigned CandIdx = DefRegToCandIdx[Reg];
478 if (CandIdx != ~0u)
479 Candidates[CandIdx].LiveOut.set(RegionIdx);
480 }
481 }
482
483 for (RematCandidate &Cand : Candidates)
484 Cand.init(Regions, Remater, MRI);
485}
486
487bool GCNRematStrategy::candidateHasValidUsers(
488 RegisterIdx CandIdx, const SmallSet<Register, 4> &MarkedRegs) const {
489 const Rematerializer::Reg &CandReg = Remater.getReg(CandIdx);
490 SlotIndex RefIdx =
491 LIS.getInstructionIndex(*CandReg.getLastDef()).getRegSlot(true);
492
493 for (const auto &[UseRegion, Users] : CandReg.Uses) {
494 // Users cannot themselves be rematerializable.
495 if (llvm::any_of(Users, [&](const MachineInstr *UserMI) {
496 assert(UserMI->getNumOperands() > 0 &&
497 "user must have at least one operand");
498 // A user is rematerializable if its first register operand (its
499 // register def) was marked already.
500 const MachineOperand &DefMO = UserMI->getOperand(0);
501 return DefMO.isReg() && MarkedRegs.contains(DefMO.getReg());
502 }))
503 return false;
504
505 MachineInstr *FirstUseMI = CandReg.getRegionUseBounds(UseRegion, LIS).first;
506 assert(FirstUseMI && "there must be a user in the region");
507 SlotIndex FirstUseIdx =
508 LIS.getInstructionIndex(*FirstUseMI).getRegSlot(true);
509
510 // All dependencies must be available at the first use in the region.
511 if (llvm::any_of(CandReg.Dependencies, [&](RegisterIdx DepRegIdx) {
512 const Rematerializer::Reg &DepReg = Remater.getReg(DepRegIdx);
513 Register DepDefReg = DepReg.getDefReg();
514 return !Remater.isRegIdenticalAtUses(DepDefReg, DepReg.Mask, RefIdx,
515 {FirstUseIdx});
516 }))
517 return false;
518 if (llvm::any_of(Remater.getUnrematableDeps(CandIdx),
519 [&](const std::pair<Register, LaneBitmask> &RegAndMask) {
520 const auto &[Reg, Mask] = RegAndMask;
521 return !Remater.isRegIdenticalAtUses(Reg, Mask, RefIdx,
522 {FirstUseIdx});
523 }))
524 return false;
525 }
526 return true;
527}
528
530 // Roll back changes made by the strategy.
531 assert(Recorder && "recorder should be defined");
532 Recorder->Listener.rollback(Remater);
533 for (const auto &[RegIdx, LiveIn, LiveOut] : Recorder->LiveMapUpdates) {
534 const Rematerializer::Reg &Reg = Remater.getReg(RegIdx);
535 Regions.addToLiveMaps(Reg.getDefReg(), Reg.Mask, LiveIn, LiveOut);
536 }
537}
538
539#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
540Printable GCNRematStrategy::RematCandidate::print() const {
541 return Printable([&](raw_ostream &OS) {
542 OS << '(' << MaxFreq << ", " << FreqDiff << ", " << RegionImpact << ')';
543 });
544}
545
546Printable GCNRematStrategy::RematTargets::print() const {
547 return Printable([&](raw_ostream &OS) {
548 if (allAchieved()) {
549 OS << "No target regions\n";
550 return;
551 }
552 OS << "Target regions:\n";
553 for (unsigned I : ExcessRP.set_bits())
554 OS << " [" << I << "] " << RPTargets[I] << '\n';
555 });
556}
557#endif
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
MachineBasicBlock & MBB
This file implements the BitVector class.
This file defines the GCNRegPressure class, which tracks registry pressure by bookkeeping number of S...
Rematerialization strategy, based on the target-independent rematerializer.
static Register UseReg(const MachineOperand &MO)
#define _
iv Induction Variable Users
Definition IVUsers.cpp:48
A common definition of LaneBitmask for use in TableGen and CodeGen.
#define I(x, y, z)
Definition MD5.cpp:57
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
if(PassOpts->AAPipeline)
MachineRegisterInfo & MRI
Rematerializer::RegisterIdx RegisterIdx
#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
size_t size() const
Get the array size.
Definition ArrayRef.h:141
BitVector & reset()
Reset all bits in the bitvector.
Definition BitVector.h:409
iterator_range< const_set_bits_iterator > set_bits() const
Definition BitVector.h:159
size_type size() const
Returns the number of bits in this bitvector.
Definition BitVector.h:178
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
unsigned getNumRegsBenefit(const GCNRegPressure &SaveRP) const
Returns the benefit towards achieving the RP target that saving SaveRP represents,...
void rollbackRecordedRemats()
Rolls back all recorded rematerializations.
void rematerializeFor(unsigned MaxSGPRs, unsigned MaxVGPRs, bool SpillReduction, BitVector &AffectedRegions, MutableArrayRef< GCNRegPressure > *MaxPressure=nullptr)
Rematerializes with the goal of reducing the maximum pressure in all Regions to MaxSGPRs SGPRs and Ma...
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasSubRanges() const
Returns true if subregister liveness information is available.
iterator_range< subrange_iterator > subranges()
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
LLVM_ABI BlockFrequency getEntryFreq() const
Divide a block's BlockFrequency::getFrequency() value by this value to obtain the entry block - relat...
Representation of each machine instruction.
unsigned getNumOperands() const
Retuns the total number of operands.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition Register.h:60
unsigned getNumRegs() const
const Reg & getReg(RegisterIdx RegIdx) const
unsigned RegisterIdx
Index type for rematerializable registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition SmallSet.h:134
bool contains(const T &V) const
Check if the SmallSet contains the given element.
Definition SmallSet.h:229
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
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This is an optimization pass for GlobalISel generic memory operations.
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
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
GCNRegPressure getRegPressure(const MachineRegisterInfo &MRI, Range &&LiveRegs)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
ArrayRef(const T &OneElt) -> ArrayRef< T >
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
Definition Sequence.h:341
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:320
void inc(unsigned Reg, LaneBitmask PrevMask, LaneBitmask NewMask, const MachineRegisterInfo &MRI)
constexpr bool any() const
Definition LaneBitmask.h:53
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
DependencyReuseInfo & reuse(RegisterIdx DepIdx)
A rematerializable register, potentially defined by multiple instructions.
LLVM_ABI std::pair< MachineInstr *, MachineInstr * > getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const
Returns the first and last user of the register in region UseRegion.
SmallVector< MachineInstr *, 1 > Defs
All instructions that define the register, in program order.
bool hasUsersOutsideDefRegion() const
SmallDenseMap< unsigned, RegionUsers, 2 > Uses
Uses of the register, mapped by region.
MachineInstr * getLastDef() const
Register getDefReg() const
Returns the rematerializable register from one of its defining instructions.
SmallVector< RegisterIdx, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand over ...
A pair composed of a register and a sub-register index.