LLVM 20.0.0git
LoadStoreOpt.cpp
Go to the documentation of this file.
1//===- LoadStoreOpt.cpp ----------- Generic memory optimizations -*- 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/// \file
9/// This file implements the LoadStoreOpt optimization pass.
10//===----------------------------------------------------------------------===//
11
13#include "llvm/ADT/STLExtras.h"
15#include "llvm/ADT/Statistic.h"
37#include "llvm/Support/Debug.h"
39#include <algorithm>
40
41#define DEBUG_TYPE "loadstore-opt"
42
43using namespace llvm;
44using namespace ore;
45using namespace MIPatternMatch;
46
47STATISTIC(NumStoresMerged, "Number of stores merged");
48
49const unsigned MaxStoreSizeToForm = 128;
50
51char LoadStoreOpt::ID = 0;
52INITIALIZE_PASS_BEGIN(LoadStoreOpt, DEBUG_TYPE, "Generic memory optimizations",
53 false, false)
56
58 : MachineFunctionPass(ID), DoNotRunPass(F) {}
59
61 : LoadStoreOpt([](const MachineFunction &) { return false; }) {}
62
63void LoadStoreOpt::init(MachineFunction &MF) {
64 this->MF = &MF;
65 MRI = &MF.getRegInfo();
66 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
69 Builder.setMF(MF);
70 IsPreLegalizer = !MF.getProperties().hasProperty(
72 InstsToErase.clear();
73}
74
77 AU.setPreservesAll();
80}
81
85 Register PtrAddRHS;
86 Register BaseReg;
87 if (!mi_match(Ptr, MRI, m_GPtrAdd(m_Reg(BaseReg), m_Reg(PtrAddRHS)))) {
88 Info.setBase(Ptr);
89 Info.setOffset(0);
90 return Info;
91 }
92 Info.setBase(BaseReg);
93 auto RHSCst = getIConstantVRegValWithLookThrough(PtrAddRHS, MRI);
94 if (RHSCst)
95 Info.setOffset(RHSCst->Value.getSExtValue());
96
97 // Just recognize a simple case for now. In future we'll need to match
98 // indexing patterns for base + index + constant.
99 Info.setIndex(PtrAddRHS);
100 return Info;
101}
102
104 const MachineInstr &MI2,
105 bool &IsAlias,
107 auto *LdSt1 = dyn_cast<GLoadStore>(&MI1);
108 auto *LdSt2 = dyn_cast<GLoadStore>(&MI2);
109 if (!LdSt1 || !LdSt2)
110 return false;
111
112 BaseIndexOffset BasePtr0 = getPointerInfo(LdSt1->getPointerReg(), MRI);
113 BaseIndexOffset BasePtr1 = getPointerInfo(LdSt2->getPointerReg(), MRI);
114
115 if (!BasePtr0.getBase().isValid() || !BasePtr1.getBase().isValid())
116 return false;
117
118 LocationSize Size1 = LdSt1->getMemSize();
119 LocationSize Size2 = LdSt2->getMemSize();
120
121 int64_t PtrDiff;
122 if (BasePtr0.getBase() == BasePtr1.getBase() && BasePtr0.hasValidOffset() &&
123 BasePtr1.hasValidOffset()) {
124 PtrDiff = BasePtr1.getOffset() - BasePtr0.getOffset();
125 // If the size of memory access is unknown, do not use it to do analysis.
126 // One example of unknown size memory access is to load/store scalable
127 // vector objects on the stack.
128 // BasePtr1 is PtrDiff away from BasePtr0. They alias if none of the
129 // following situations arise:
130 if (PtrDiff >= 0 && Size1.hasValue() && !Size1.isScalable()) {
131 // [----BasePtr0----]
132 // [---BasePtr1--]
133 // ========PtrDiff========>
134 IsAlias = !((int64_t)Size1.getValue() <= PtrDiff);
135 return true;
136 }
137 if (PtrDiff < 0 && Size2.hasValue() && !Size2.isScalable()) {
138 // [----BasePtr0----]
139 // [---BasePtr1--]
140 // =====(-PtrDiff)====>
141 IsAlias = !((PtrDiff + (int64_t)Size2.getValue()) <= 0);
142 return true;
143 }
144 return false;
145 }
146
147 // If both BasePtr0 and BasePtr1 are FrameIndexes, we will not be
148 // able to calculate their relative offset if at least one arises
149 // from an alloca. However, these allocas cannot overlap and we
150 // can infer there is no alias.
151 auto *Base0Def = getDefIgnoringCopies(BasePtr0.getBase(), MRI);
152 auto *Base1Def = getDefIgnoringCopies(BasePtr1.getBase(), MRI);
153 if (!Base0Def || !Base1Def)
154 return false; // Couldn't tell anything.
155
156
157 if (Base0Def->getOpcode() != Base1Def->getOpcode())
158 return false;
159
160 if (Base0Def->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
161 MachineFrameInfo &MFI = Base0Def->getMF()->getFrameInfo();
162 // If the bases have the same frame index but we couldn't find a
163 // constant offset, (indices are different) be conservative.
164 if (Base0Def != Base1Def &&
165 (!MFI.isFixedObjectIndex(Base0Def->getOperand(1).getIndex()) ||
166 !MFI.isFixedObjectIndex(Base1Def->getOperand(1).getIndex()))) {
167 IsAlias = false;
168 return true;
169 }
170 }
171
172 // This implementation is a lot more primitive than the SDAG one for now.
173 // FIXME: what about constant pools?
174 if (Base0Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
175 auto GV0 = Base0Def->getOperand(1).getGlobal();
176 auto GV1 = Base1Def->getOperand(1).getGlobal();
177 if (GV0 != GV1) {
178 IsAlias = false;
179 return true;
180 }
181 }
182
183 // Can't tell anything about aliasing.
184 return false;
185}
186
188 const MachineInstr &Other,
190 AliasAnalysis *AA) {
191 struct MemUseCharacteristics {
192 bool IsVolatile;
193 bool IsAtomic;
194 Register BasePtr;
195 int64_t Offset;
196 LocationSize NumBytes;
198 };
199
200 auto getCharacteristics =
201 [&](const MachineInstr *MI) -> MemUseCharacteristics {
202 if (const auto *LS = dyn_cast<GLoadStore>(MI)) {
203 Register BaseReg;
204 int64_t Offset = 0;
205 // No pre/post-inc addressing modes are considered here, unlike in SDAG.
206 if (!mi_match(LS->getPointerReg(), MRI,
207 m_GPtrAdd(m_Reg(BaseReg), m_ICst(Offset)))) {
208 BaseReg = LS->getPointerReg();
209 Offset = 0;
210 }
211
212 LocationSize Size = LS->getMMO().getSize();
213 return {LS->isVolatile(), LS->isAtomic(), BaseReg,
214 Offset /*base offset*/, Size, &LS->getMMO()};
215 }
216 // FIXME: support recognizing lifetime instructions.
217 // Default.
218 return {false /*isvolatile*/,
219 /*isAtomic*/ false,
220 Register(),
221 (int64_t)0 /*offset*/,
223 (MachineMemOperand *)nullptr};
224 };
225 MemUseCharacteristics MUC0 = getCharacteristics(&MI),
226 MUC1 = getCharacteristics(&Other);
227
228 // If they are to the same address, then they must be aliases.
229 if (MUC0.BasePtr.isValid() && MUC0.BasePtr == MUC1.BasePtr &&
230 MUC0.Offset == MUC1.Offset)
231 return true;
232
233 // If they are both volatile then they cannot be reordered.
234 if (MUC0.IsVolatile && MUC1.IsVolatile)
235 return true;
236
237 // Be conservative about atomics for the moment
238 // TODO: This is way overconservative for unordered atomics (see D66309)
239 if (MUC0.IsAtomic && MUC1.IsAtomic)
240 return true;
241
242 // If one operation reads from invariant memory, and the other may store, they
243 // cannot alias.
244 if (MUC0.MMO && MUC1.MMO) {
245 if ((MUC0.MMO->isInvariant() && MUC1.MMO->isStore()) ||
246 (MUC1.MMO->isInvariant() && MUC0.MMO->isStore()))
247 return false;
248 }
249
250 // If NumBytes is scalable and offset is not 0, conservatively return may
251 // alias
252 if ((MUC0.NumBytes.isScalable() && MUC0.Offset != 0) ||
253 (MUC1.NumBytes.isScalable() && MUC1.Offset != 0))
254 return true;
255
256 const bool BothNotScalable =
257 !MUC0.NumBytes.isScalable() && !MUC1.NumBytes.isScalable();
258
259 // Try to prove that there is aliasing, or that there is no aliasing. Either
260 // way, we can return now. If nothing can be proved, proceed with more tests.
261 bool IsAlias;
262 if (BothNotScalable &&
264 return IsAlias;
265
266 // The following all rely on MMO0 and MMO1 being valid.
267 if (!MUC0.MMO || !MUC1.MMO)
268 return true;
269
270 // FIXME: port the alignment based alias analysis from SDAG's isAlias().
271 int64_t SrcValOffset0 = MUC0.MMO->getOffset();
272 int64_t SrcValOffset1 = MUC1.MMO->getOffset();
273 LocationSize Size0 = MUC0.NumBytes;
274 LocationSize Size1 = MUC1.NumBytes;
275 if (AA && MUC0.MMO->getValue() && MUC1.MMO->getValue() && Size0.hasValue() &&
276 Size1.hasValue()) {
277 // Use alias analysis information.
278 int64_t MinOffset = std::min(SrcValOffset0, SrcValOffset1);
279 int64_t Overlap0 =
280 Size0.getValue().getKnownMinValue() + SrcValOffset0 - MinOffset;
281 int64_t Overlap1 =
282 Size1.getValue().getKnownMinValue() + SrcValOffset1 - MinOffset;
283 LocationSize Loc0 =
284 Size0.isScalable() ? Size0 : LocationSize::precise(Overlap0);
285 LocationSize Loc1 =
286 Size1.isScalable() ? Size1 : LocationSize::precise(Overlap1);
287
288 if (AA->isNoAlias(
289 MemoryLocation(MUC0.MMO->getValue(), Loc0, MUC0.MMO->getAAInfo()),
290 MemoryLocation(MUC1.MMO->getValue(), Loc1, MUC1.MMO->getAAInfo())))
291 return false;
292 }
293
294 // Otherwise we have to assume they alias.
295 return true;
296}
297
298/// Returns true if the instruction creates an unavoidable hazard that
299/// forces a boundary between store merge candidates.
301 return MI.hasUnmodeledSideEffects() || MI.hasOrderedMemoryRef();
302}
303
304bool LoadStoreOpt::mergeStores(SmallVectorImpl<GStore *> &StoresToMerge) {
305 // Try to merge all the stores in the vector, splitting into separate segments
306 // as necessary.
307 assert(StoresToMerge.size() > 1 && "Expected multiple stores to merge");
308 LLT OrigTy = MRI->getType(StoresToMerge[0]->getValueReg());
309 LLT PtrTy = MRI->getType(StoresToMerge[0]->getPointerReg());
310 unsigned AS = PtrTy.getAddressSpace();
311 // Ensure the legal store info is computed for this address space.
312 initializeStoreMergeTargetInfo(AS);
313 const auto &LegalSizes = LegalStoreSizes[AS];
314
315#ifndef NDEBUG
316 for (auto *StoreMI : StoresToMerge)
317 assert(MRI->getType(StoreMI->getValueReg()) == OrigTy);
318#endif
319
320 bool AnyMerged = false;
321 do {
322 unsigned NumPow2 = llvm::bit_floor(StoresToMerge.size());
323 unsigned MaxSizeBits = NumPow2 * OrigTy.getSizeInBits().getFixedValue();
324 // Compute the biggest store we can generate to handle the number of stores.
325 unsigned MergeSizeBits;
326 for (MergeSizeBits = MaxSizeBits; MergeSizeBits > 1; MergeSizeBits /= 2) {
327 LLT StoreTy = LLT::scalar(MergeSizeBits);
328 EVT StoreEVT =
330 if (LegalSizes.size() > MergeSizeBits && LegalSizes[MergeSizeBits] &&
331 TLI->canMergeStoresTo(AS, StoreEVT, *MF) &&
332 (TLI->isTypeLegal(StoreEVT)))
333 break; // We can generate a MergeSize bits store.
334 }
335 if (MergeSizeBits <= OrigTy.getSizeInBits())
336 return AnyMerged; // No greater merge.
337
338 unsigned NumStoresToMerge = MergeSizeBits / OrigTy.getSizeInBits();
339 // Perform the actual merging.
340 SmallVector<GStore *, 8> SingleMergeStores(
341 StoresToMerge.begin(), StoresToMerge.begin() + NumStoresToMerge);
342 AnyMerged |= doSingleStoreMerge(SingleMergeStores);
343 StoresToMerge.erase(StoresToMerge.begin(),
344 StoresToMerge.begin() + NumStoresToMerge);
345 } while (StoresToMerge.size() > 1);
346 return AnyMerged;
347}
348
349bool LoadStoreOpt::isLegalOrBeforeLegalizer(const LegalityQuery &Query,
350 MachineFunction &MF) const {
351 auto Action = LI->getAction(Query).Action;
352 // If the instruction is unsupported, it can't be legalized at all.
353 if (Action == LegalizeActions::Unsupported)
354 return false;
355 return IsPreLegalizer || Action == LegalizeAction::Legal;
356}
357
358bool LoadStoreOpt::doSingleStoreMerge(SmallVectorImpl<GStore *> &Stores) {
359 assert(Stores.size() > 1);
360 // We know that all the stores are consecutive and there are no aliasing
361 // operations in the range. However, the values that are being stored may be
362 // generated anywhere before each store. To ensure we have the values
363 // available, we materialize the wide value and new store at the place of the
364 // final store in the merge sequence.
365 GStore *FirstStore = Stores[0];
366 const unsigned NumStores = Stores.size();
367 LLT SmallTy = MRI->getType(FirstStore->getValueReg());
368 LLT WideValueTy =
369 LLT::scalar(NumStores * SmallTy.getSizeInBits().getFixedValue());
370
371 // For each store, compute pairwise merged debug locs.
372 DebugLoc MergedLoc = Stores.front()->getDebugLoc();
373 for (auto *Store : drop_begin(Stores))
374 MergedLoc = DILocation::getMergedLocation(MergedLoc, Store->getDebugLoc());
375
376 Builder.setInstr(*Stores.back());
377 Builder.setDebugLoc(MergedLoc);
378
379 // If all of the store values are constants, then create a wide constant
380 // directly. Otherwise, we need to generate some instructions to merge the
381 // existing values together into a wider type.
382 SmallVector<APInt, 8> ConstantVals;
383 for (auto *Store : Stores) {
384 auto MaybeCst =
385 getIConstantVRegValWithLookThrough(Store->getValueReg(), *MRI);
386 if (!MaybeCst) {
387 ConstantVals.clear();
388 break;
389 }
390 ConstantVals.emplace_back(MaybeCst->Value);
391 }
392
393 Register WideReg;
394 auto *WideMMO =
395 MF->getMachineMemOperand(&FirstStore->getMMO(), 0, WideValueTy);
396 if (ConstantVals.empty()) {
397 // Mimic the SDAG behaviour here and don't try to do anything for unknown
398 // values. In future, we should also support the cases of loads and
399 // extracted vector elements.
400 return false;
401 }
402
403 assert(ConstantVals.size() == NumStores);
404 // Check if our wide constant is legal.
405 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_CONSTANT, {WideValueTy}}, *MF))
406 return false;
407 APInt WideConst(WideValueTy.getSizeInBits(), 0);
408 for (unsigned Idx = 0; Idx < ConstantVals.size(); ++Idx) {
409 // Insert the smaller constant into the corresponding position in the
410 // wider one.
411 WideConst.insertBits(ConstantVals[Idx], Idx * SmallTy.getSizeInBits());
412 }
413 WideReg = Builder.buildConstant(WideValueTy, WideConst).getReg(0);
414 auto NewStore =
415 Builder.buildStore(WideReg, FirstStore->getPointerReg(), *WideMMO);
416 (void) NewStore;
417 LLVM_DEBUG(dbgs() << "Merged " << Stores.size()
418 << " stores into merged store: " << *NewStore);
419 LLVM_DEBUG(for (auto *MI : Stores) dbgs() << " " << *MI;);
420 NumStoresMerged += Stores.size();
421
423 MORE.emit([&]() {
425 FirstStore->getDebugLoc(),
426 FirstStore->getParent());
427 R << "Merged " << NV("NumMerged", Stores.size()) << " stores of "
428 << NV("OrigWidth", SmallTy.getSizeInBytes())
429 << " bytes into a single store of "
430 << NV("NewWidth", WideValueTy.getSizeInBytes()) << " bytes";
431 return R;
432 });
433
434 for (auto *MI : Stores)
435 InstsToErase.insert(MI);
436 return true;
437}
438
439bool LoadStoreOpt::processMergeCandidate(StoreMergeCandidate &C) {
440 if (C.Stores.size() < 2) {
441 C.reset();
442 return false;
443 }
444
445 LLVM_DEBUG(dbgs() << "Checking store merge candidate with " << C.Stores.size()
446 << " stores, starting with " << *C.Stores[0]);
447 // We know that the stores in the candidate are adjacent.
448 // Now we need to check if any potential aliasing instructions recorded
449 // during the search alias with load/stores added to the candidate after.
450 // For example, if we have the candidate:
451 // C.Stores = [ST1, ST2, ST3, ST4]
452 // and after seeing ST2 we saw a load LD1, which did not alias with ST1 or
453 // ST2, then we would have recorded it into the PotentialAliases structure
454 // with the associated index value of "1". Then we see ST3 and ST4 and add
455 // them to the candidate group. We know that LD1 does not alias with ST1 or
456 // ST2, since we already did that check. However we don't yet know if it
457 // may alias ST3 and ST4, so we perform those checks now.
458 SmallVector<GStore *> StoresToMerge;
459
460 auto DoesStoreAliasWithPotential = [&](unsigned Idx, GStore &CheckStore) {
461 for (auto AliasInfo : reverse(C.PotentialAliases)) {
462 MachineInstr *PotentialAliasOp = AliasInfo.first;
463 unsigned PreCheckedIdx = AliasInfo.second;
464 if (static_cast<unsigned>(Idx) < PreCheckedIdx) {
465 // Once our store index is lower than the index associated with the
466 // potential alias, we know that we've already checked for this alias
467 // and all of the earlier potential aliases too.
468 return false;
469 }
470 // Need to check this alias.
471 if (GISelAddressing::instMayAlias(CheckStore, *PotentialAliasOp, *MRI,
472 AA)) {
473 LLVM_DEBUG(dbgs() << "Potential alias " << *PotentialAliasOp
474 << " detected\n");
475 return true;
476 }
477 }
478 return false;
479 };
480 // Start from the last store in the group, and check if it aliases with any
481 // of the potential aliasing operations in the list.
482 for (int StoreIdx = C.Stores.size() - 1; StoreIdx >= 0; --StoreIdx) {
483 auto *CheckStore = C.Stores[StoreIdx];
484 if (DoesStoreAliasWithPotential(StoreIdx, *CheckStore))
485 continue;
486 StoresToMerge.emplace_back(CheckStore);
487 }
488
489 LLVM_DEBUG(dbgs() << StoresToMerge.size()
490 << " stores remaining after alias checks. Merging...\n");
491
492 // Now we've checked for aliasing hazards, merge any stores left.
493 C.reset();
494 if (StoresToMerge.size() < 2)
495 return false;
496 return mergeStores(StoresToMerge);
497}
498
499bool LoadStoreOpt::operationAliasesWithCandidate(MachineInstr &MI,
500 StoreMergeCandidate &C) {
501 if (C.Stores.empty())
502 return false;
503 return llvm::any_of(C.Stores, [&](MachineInstr *OtherMI) {
504 return instMayAlias(MI, *OtherMI, *MRI, AA);
505 });
506}
507
508void LoadStoreOpt::StoreMergeCandidate::addPotentialAlias(MachineInstr &MI) {
509 PotentialAliases.emplace_back(std::make_pair(&MI, Stores.size() - 1));
510}
511
512bool LoadStoreOpt::addStoreToCandidate(GStore &StoreMI,
513 StoreMergeCandidate &C) {
514 // Check if the given store writes to an adjacent address, and other
515 // requirements.
516 LLT ValueTy = MRI->getType(StoreMI.getValueReg());
517 LLT PtrTy = MRI->getType(StoreMI.getPointerReg());
518
519 // Only handle scalars.
520 if (!ValueTy.isScalar())
521 return false;
522
523 // Don't allow truncating stores for now.
524 if (StoreMI.getMemSizeInBits() != ValueTy.getSizeInBits())
525 return false;
526
527 // Avoid adding volatile or ordered stores to the candidate. We already have a
528 // check for this in instMayAlias() but that only get's called later between
529 // potential aliasing hazards.
530 if (!StoreMI.isSimple())
531 return false;
532
533 Register StoreAddr = StoreMI.getPointerReg();
534 auto BIO = getPointerInfo(StoreAddr, *MRI);
535 Register StoreBase = BIO.getBase();
536 if (C.Stores.empty()) {
537 C.BasePtr = StoreBase;
538 if (!BIO.hasValidOffset()) {
539 C.CurrentLowestOffset = 0;
540 } else {
541 C.CurrentLowestOffset = BIO.getOffset();
542 }
543 // This is the first store of the candidate.
544 // If the offset can't possibly allow for a lower addressed store with the
545 // same base, don't bother adding it.
546 if (BIO.hasValidOffset() &&
547 BIO.getOffset() < static_cast<int64_t>(ValueTy.getSizeInBytes()))
548 return false;
549 C.Stores.emplace_back(&StoreMI);
550 LLVM_DEBUG(dbgs() << "Starting a new merge candidate group with: "
551 << StoreMI);
552 return true;
553 }
554
555 // Check the store is the same size as the existing ones in the candidate.
556 if (MRI->getType(C.Stores[0]->getValueReg()).getSizeInBits() !=
557 ValueTy.getSizeInBits())
558 return false;
559
560 if (MRI->getType(C.Stores[0]->getPointerReg()).getAddressSpace() !=
561 PtrTy.getAddressSpace())
562 return false;
563
564 // There are other stores in the candidate. Check that the store address
565 // writes to the next lowest adjacent address.
566 if (C.BasePtr != StoreBase)
567 return false;
568 // If we don't have a valid offset, we can't guarantee to be an adjacent
569 // offset.
570 if (!BIO.hasValidOffset())
571 return false;
572 if ((C.CurrentLowestOffset -
573 static_cast<int64_t>(ValueTy.getSizeInBytes())) != BIO.getOffset())
574 return false;
575
576 // This writes to an adjacent address. Allow it.
577 C.Stores.emplace_back(&StoreMI);
578 C.CurrentLowestOffset = C.CurrentLowestOffset - ValueTy.getSizeInBytes();
579 LLVM_DEBUG(dbgs() << "Candidate added store: " << StoreMI);
580 return true;
581}
582
583bool LoadStoreOpt::mergeBlockStores(MachineBasicBlock &MBB) {
584 bool Changed = false;
585 // Walk through the block bottom-up, looking for merging candidates.
586 StoreMergeCandidate Candidate;
587 for (MachineInstr &MI : llvm::reverse(MBB)) {
588 if (InstsToErase.contains(&MI))
589 continue;
590
591 if (auto *StoreMI = dyn_cast<GStore>(&MI)) {
592 // We have a G_STORE. Add it to the candidate if it writes to an adjacent
593 // address.
594 if (!addStoreToCandidate(*StoreMI, Candidate)) {
595 // Store wasn't eligible to be added. May need to record it as a
596 // potential alias.
597 if (operationAliasesWithCandidate(*StoreMI, Candidate)) {
598 Changed |= processMergeCandidate(Candidate);
599 continue;
600 }
601 Candidate.addPotentialAlias(*StoreMI);
602 }
603 continue;
604 }
605
606 // If we don't have any stores yet, this instruction can't pose a problem.
607 if (Candidate.Stores.empty())
608 continue;
609
610 // We're dealing with some other kind of instruction.
612 Changed |= processMergeCandidate(Candidate);
613 Candidate.Stores.clear();
614 continue;
615 }
616
617 if (!MI.mayLoadOrStore())
618 continue;
619
620 if (operationAliasesWithCandidate(MI, Candidate)) {
621 // We have a potential alias, so process the current candidate if we can
622 // and then continue looking for a new candidate.
623 Changed |= processMergeCandidate(Candidate);
624 continue;
625 }
626
627 // Record this instruction as a potential alias for future stores that are
628 // added to the candidate.
629 Candidate.addPotentialAlias(MI);
630 }
631
632 // Process any candidate left after finishing searching the entire block.
633 Changed |= processMergeCandidate(Candidate);
634
635 // Erase instructions now that we're no longer iterating over the block.
636 for (auto *MI : InstsToErase)
637 MI->eraseFromParent();
638 InstsToErase.clear();
639 return Changed;
640}
641
642/// Check if the store \p Store is a truncstore that can be merged. That is,
643/// it's a store of a shifted value of \p SrcVal. If \p SrcVal is an empty
644/// Register then it does not need to match and SrcVal is set to the source
645/// value found.
646/// On match, returns the start byte offset of the \p SrcVal that is being
647/// stored.
648static std::optional<int64_t>
651 Register TruncVal;
652 if (!mi_match(Store.getValueReg(), MRI, m_GTrunc(m_Reg(TruncVal))))
653 return std::nullopt;
654
655 // The shift amount must be a constant multiple of the narrow type.
656 // It is translated to the offset address in the wide source value "y".
657 //
658 // x = G_LSHR y, ShiftAmtC
659 // s8 z = G_TRUNC x
660 // store z, ...
661 Register FoundSrcVal;
662 int64_t ShiftAmt;
663 if (!mi_match(TruncVal, MRI,
664 m_any_of(m_GLShr(m_Reg(FoundSrcVal), m_ICst(ShiftAmt)),
665 m_GAShr(m_Reg(FoundSrcVal), m_ICst(ShiftAmt))))) {
666 if (!SrcVal.isValid() || TruncVal == SrcVal) {
667 if (!SrcVal.isValid())
668 SrcVal = TruncVal;
669 return 0; // If it's the lowest index store.
670 }
671 return std::nullopt;
672 }
673
674 unsigned NarrowBits = Store.getMMO().getMemoryType().getScalarSizeInBits();
675 if (ShiftAmt % NarrowBits != 0)
676 return std::nullopt;
677 const unsigned Offset = ShiftAmt / NarrowBits;
678
679 if (SrcVal.isValid() && FoundSrcVal != SrcVal)
680 return std::nullopt;
681
682 if (!SrcVal.isValid())
683 SrcVal = FoundSrcVal;
684 else if (MRI.getType(SrcVal) != MRI.getType(FoundSrcVal))
685 return std::nullopt;
686 return Offset;
687}
688
689/// Match a pattern where a wide type scalar value is stored by several narrow
690/// stores. Fold it into a single store or a BSWAP and a store if the targets
691/// supports it.
692///
693/// Assuming little endian target:
694/// i8 *p = ...
695/// i32 val = ...
696/// p[0] = (val >> 0) & 0xFF;
697/// p[1] = (val >> 8) & 0xFF;
698/// p[2] = (val >> 16) & 0xFF;
699/// p[3] = (val >> 24) & 0xFF;
700/// =>
701/// *((i32)p) = val;
702///
703/// i8 *p = ...
704/// i32 val = ...
705/// p[0] = (val >> 24) & 0xFF;
706/// p[1] = (val >> 16) & 0xFF;
707/// p[2] = (val >> 8) & 0xFF;
708/// p[3] = (val >> 0) & 0xFF;
709/// =>
710/// *((i32)p) = BSWAP(val);
711bool LoadStoreOpt::mergeTruncStore(GStore &StoreMI,
712 SmallPtrSetImpl<GStore *> &DeletedStores) {
713 LLT MemTy = StoreMI.getMMO().getMemoryType();
714
715 // We only handle merging simple stores of 1-4 bytes.
716 if (!MemTy.isScalar())
717 return false;
718 switch (MemTy.getSizeInBits()) {
719 case 8:
720 case 16:
721 case 32:
722 break;
723 default:
724 return false;
725 }
726 if (!StoreMI.isSimple())
727 return false;
728
729 // We do a simple search for mergeable stores prior to this one.
730 // Any potential alias hazard along the way terminates the search.
731 SmallVector<GStore *> FoundStores;
732
733 // We're looking for:
734 // 1) a (store(trunc(...)))
735 // 2) of an LSHR/ASHR of a single wide value, by the appropriate shift to get
736 // the partial value stored.
737 // 3) where the offsets form either a little or big-endian sequence.
738
739 auto &LastStore = StoreMI;
740
741 // The single base pointer that all stores must use.
742 Register BaseReg;
743 int64_t LastOffset;
744 if (!mi_match(LastStore.getPointerReg(), *MRI,
745 m_GPtrAdd(m_Reg(BaseReg), m_ICst(LastOffset)))) {
746 BaseReg = LastStore.getPointerReg();
747 LastOffset = 0;
748 }
749
750 GStore *LowestIdxStore = &LastStore;
751 int64_t LowestIdxOffset = LastOffset;
752
753 Register WideSrcVal;
754 auto LowestShiftAmt = getTruncStoreByteOffset(LastStore, WideSrcVal, *MRI);
755 if (!LowestShiftAmt)
756 return false; // Didn't match a trunc.
757 assert(WideSrcVal.isValid());
758
759 LLT WideStoreTy = MRI->getType(WideSrcVal);
760 // The wide type might not be a multiple of the memory type, e.g. s48 and s32.
761 if (WideStoreTy.getSizeInBits() % MemTy.getSizeInBits() != 0)
762 return false;
763 const unsigned NumStoresRequired =
764 WideStoreTy.getSizeInBits() / MemTy.getSizeInBits();
765
766 SmallVector<int64_t, 8> OffsetMap(NumStoresRequired, INT64_MAX);
767 OffsetMap[*LowestShiftAmt] = LastOffset;
768 FoundStores.emplace_back(&LastStore);
769
770 const int MaxInstsToCheck = 10;
771 int NumInstsChecked = 0;
772 for (auto II = ++LastStore.getReverseIterator();
773 II != LastStore.getParent()->rend() && NumInstsChecked < MaxInstsToCheck;
774 ++II) {
775 NumInstsChecked++;
776 GStore *NewStore;
777 if ((NewStore = dyn_cast<GStore>(&*II))) {
778 if (NewStore->getMMO().getMemoryType() != MemTy || !NewStore->isSimple())
779 break;
780 } else if (II->isLoadFoldBarrier() || II->mayLoad()) {
781 break;
782 } else {
783 continue; // This is a safe instruction we can look past.
784 }
785
786 Register NewBaseReg;
787 int64_t MemOffset;
788 // Check we're storing to the same base + some offset.
789 if (!mi_match(NewStore->getPointerReg(), *MRI,
790 m_GPtrAdd(m_Reg(NewBaseReg), m_ICst(MemOffset)))) {
791 NewBaseReg = NewStore->getPointerReg();
792 MemOffset = 0;
793 }
794 if (BaseReg != NewBaseReg)
795 break;
796
797 auto ShiftByteOffset = getTruncStoreByteOffset(*NewStore, WideSrcVal, *MRI);
798 if (!ShiftByteOffset)
799 break;
800 if (MemOffset < LowestIdxOffset) {
801 LowestIdxOffset = MemOffset;
802 LowestIdxStore = NewStore;
803 }
804
805 // Map the offset in the store and the offset in the combined value, and
806 // early return if it has been set before.
807 if (*ShiftByteOffset < 0 || *ShiftByteOffset >= NumStoresRequired ||
808 OffsetMap[*ShiftByteOffset] != INT64_MAX)
809 break;
810 OffsetMap[*ShiftByteOffset] = MemOffset;
811
812 FoundStores.emplace_back(NewStore);
813 // Reset counter since we've found a matching inst.
814 NumInstsChecked = 0;
815 if (FoundStores.size() == NumStoresRequired)
816 break;
817 }
818
819 if (FoundStores.size() != NumStoresRequired) {
820 if (FoundStores.size() == 1)
821 return false;
822 // We didn't find enough stores to merge into the size of the original
823 // source value, but we may be able to generate a smaller store if we
824 // truncate the source value.
825 WideStoreTy = LLT::scalar(FoundStores.size() * MemTy.getScalarSizeInBits());
826 }
827
828 unsigned NumStoresFound = FoundStores.size();
829
830 const auto &DL = LastStore.getMF()->getDataLayout();
831 auto &C = LastStore.getMF()->getFunction().getContext();
832 // Check that a store of the wide type is both allowed and fast on the target
833 unsigned Fast = 0;
834 bool Allowed = TLI->allowsMemoryAccess(
835 C, DL, WideStoreTy, LowestIdxStore->getMMO(), &Fast);
836 if (!Allowed || !Fast)
837 return false;
838
839 // Check if the pieces of the value are going to the expected places in memory
840 // to merge the stores.
841 unsigned NarrowBits = MemTy.getScalarSizeInBits();
842 auto checkOffsets = [&](bool MatchLittleEndian) {
843 if (MatchLittleEndian) {
844 for (unsigned i = 0; i != NumStoresFound; ++i)
845 if (OffsetMap[i] != i * (NarrowBits / 8) + LowestIdxOffset)
846 return false;
847 } else { // MatchBigEndian by reversing loop counter.
848 for (unsigned i = 0, j = NumStoresFound - 1; i != NumStoresFound;
849 ++i, --j)
850 if (OffsetMap[j] != i * (NarrowBits / 8) + LowestIdxOffset)
851 return false;
852 }
853 return true;
854 };
855
856 // Check if the offsets line up for the native data layout of this target.
857 bool NeedBswap = false;
858 bool NeedRotate = false;
859 if (!checkOffsets(DL.isLittleEndian())) {
860 // Special-case: check if byte offsets line up for the opposite endian.
861 if (NarrowBits == 8 && checkOffsets(DL.isBigEndian()))
862 NeedBswap = true;
863 else if (NumStoresFound == 2 && checkOffsets(DL.isBigEndian()))
864 NeedRotate = true;
865 else
866 return false;
867 }
868
869 if (NeedBswap &&
870 !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {WideStoreTy}}, *MF))
871 return false;
872 if (NeedRotate &&
873 !isLegalOrBeforeLegalizer(
874 {TargetOpcode::G_ROTR, {WideStoreTy, WideStoreTy}}, *MF))
875 return false;
876
877 Builder.setInstrAndDebugLoc(StoreMI);
878
879 if (WideStoreTy != MRI->getType(WideSrcVal))
880 WideSrcVal = Builder.buildTrunc(WideStoreTy, WideSrcVal).getReg(0);
881
882 if (NeedBswap) {
883 WideSrcVal = Builder.buildBSwap(WideStoreTy, WideSrcVal).getReg(0);
884 } else if (NeedRotate) {
885 assert(WideStoreTy.getSizeInBits() % 2 == 0 &&
886 "Unexpected type for rotate");
887 auto RotAmt =
888 Builder.buildConstant(WideStoreTy, WideStoreTy.getSizeInBits() / 2);
889 WideSrcVal =
890 Builder.buildRotateRight(WideStoreTy, WideSrcVal, RotAmt).getReg(0);
891 }
892
893 Builder.buildStore(WideSrcVal, LowestIdxStore->getPointerReg(),
894 LowestIdxStore->getMMO().getPointerInfo(),
895 LowestIdxStore->getMMO().getAlign());
896
897 // Erase the old stores.
898 for (auto *ST : FoundStores) {
899 ST->eraseFromParent();
900 DeletedStores.insert(ST);
901 }
902 return true;
903}
904
905bool LoadStoreOpt::mergeTruncStoresBlock(MachineBasicBlock &BB) {
906 bool Changed = false;
908 SmallPtrSet<GStore *, 8> DeletedStores;
909 // Walk up the block so we can see the most eligible stores.
910 for (MachineInstr &MI : llvm::reverse(BB))
911 if (auto *StoreMI = dyn_cast<GStore>(&MI))
912 Stores.emplace_back(StoreMI);
913
914 for (auto *StoreMI : Stores) {
915 if (DeletedStores.count(StoreMI))
916 continue;
917 if (mergeTruncStore(*StoreMI, DeletedStores))
918 Changed = true;
919 }
920 return Changed;
921}
922
923bool LoadStoreOpt::mergeFunctionStores(MachineFunction &MF) {
924 bool Changed = false;
925 for (auto &BB : MF){
926 Changed |= mergeBlockStores(BB);
927 Changed |= mergeTruncStoresBlock(BB);
928 }
929
930 // Erase all dead instructions left over by the merging.
931 if (Changed) {
932 for (auto &BB : MF) {
933 for (auto &I : make_early_inc_range(make_range(BB.rbegin(), BB.rend()))) {
934 if (isTriviallyDead(I, *MRI))
935 I.eraseFromParent();
936 }
937 }
938 }
939
940 return Changed;
941}
942
943void LoadStoreOpt::initializeStoreMergeTargetInfo(unsigned AddrSpace) {
944 // Query the legalizer info to record what store types are legal.
945 // We record this because we don't want to bother trying to merge stores into
946 // illegal ones, which would just result in being split again.
947
948 if (LegalStoreSizes.count(AddrSpace)) {
949 assert(LegalStoreSizes[AddrSpace].any());
950 return; // Already cached sizes for this address space.
951 }
952
953 // Need to reserve at least MaxStoreSizeToForm + 1 bits.
954 BitVector LegalSizes(MaxStoreSizeToForm * 2);
955 const auto &LI = *MF->getSubtarget().getLegalizerInfo();
956 const auto &DL = MF->getFunction().getDataLayout();
957 Type *IRPtrTy = PointerType::get(MF->getFunction().getContext(), AddrSpace);
958 LLT PtrTy = getLLTForType(*IRPtrTy, DL);
959 // We assume that we're not going to be generating any stores wider than
960 // MaxStoreSizeToForm bits for now.
961 for (unsigned Size = 2; Size <= MaxStoreSizeToForm; Size *= 2) {
962 LLT Ty = LLT::scalar(Size);
965 SmallVector<LLT> StoreTys({Ty, PtrTy});
966 LegalityQuery Q(TargetOpcode::G_STORE, StoreTys, MemDescrs);
967 LegalizeActionStep ActionStep = LI.getAction(Q);
968 if (ActionStep.Action == LegalizeActions::Legal)
969 LegalSizes.set(Size);
970 }
971 assert(LegalSizes.any() && "Expected some store sizes to be legal!");
972 LegalStoreSizes[AddrSpace] = LegalSizes;
973}
974
976 // If the ISel pipeline failed, do not bother running that pass.
977 if (MF.getProperties().hasProperty(
979 return false;
980
981 LLVM_DEBUG(dbgs() << "Begin memory optimizations for: " << MF.getName()
982 << '\n');
983
984 init(MF);
985 bool Changed = false;
986 Changed |= mergeFunctionStores(MF);
987
988 LegalStoreSizes.clear();
989 return Changed;
990}
unsigned const MachineRegisterInfo * MRI
@ Generic
aarch64 promote const
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
Performs the initial survey of the specified function
#define LLVM_DEBUG(...)
Definition: Debug.h:106
uint64_t Size
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
Interface for Targets to specify which operations they can successfully select and how the others sho...
Generic memory optimizations
const unsigned MaxStoreSizeToForm
static std::optional< int64_t > getTruncStoreByteOffset(GStore &Store, Register &SrcVal, MachineRegisterInfo &MRI)
Check if the store Store is a truncstore that can be merged.
#define DEBUG_TYPE
static bool isInstHardMergeHazard(MachineInstr &MI)
Returns true if the instruction creates an unavoidable hazard that forces a boundary between store me...
Implement a low-level type suitable for MachineInstr level instruction selection.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Contains matchers for matching SSA Machine Instructions.
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:57
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallPtrSet class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:166
This file describes how to lower LLVM code to machine code.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Class for arbitrary precision integers.
Definition: APInt.h:78
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
A debug info location.
Definition: DebugLoc.h:33
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:369
Helper struct to store a base, index and offset that forms an address.
Definition: LoadStoreOpt.h:38
Register getPointerReg() const
Get the source register of the pointer value.
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
Represents a G_STORE.
Register getValueReg() const
Get the stored value register.
constexpr unsigned getScalarSizeInBits() const
Definition: LowLevelType.h:264
constexpr bool isScalar() const
Definition: LowLevelType.h:146
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelType.h:190
constexpr unsigned getAddressSpace() const
Definition: LowLevelType.h:270
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
Definition: LowLevelType.h:200
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
static char ID
Definition: LoadStoreOpt.h:78
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
bool hasValue() const
static LocationSize precise(uint64_t Value)
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
bool isScalable() const
TypeSize getValue() const
reverse_iterator rend()
reverse_iterator rbegin()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
bool hasProperty(Property P) const
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
MachineInstrBuilder buildRotateRight(const DstOp &Dst, const SrcOp &Src, const SrcOp &Amt)
Build and insert Dst = G_ROTR Src, Amt.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0)
Build and insert Dst = G_BSWAP Src0.
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
void setMF(MachineFunction &MF)
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Register getReg(unsigned Idx) const
Get the register for the operand index.
Representation of each machine instruction.
Definition: MachineInstr.h:69
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:347
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition: MachineInstr.h:499
A description of a memory reference used in the backend.
LLT getMemoryType() const
Return the memory type of the memory reference.
const MachinePointerInfo & getPointerInfo() const
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
Diagnostic information for applied optimization remarks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Representation for a specific memory location.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
constexpr bool isValid() const
Definition: Register.h:116
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:363
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:452
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:384
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
bool empty() const
Definition: SmallVector.h:81
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:937
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
virtual bool allowsMemoryAccess(LLVMContext &Context, const DataLayout &DL, EVT VT, unsigned AddrSpace=0, Align Alignment=Align(1), MachineMemOperand::Flags Flags=MachineMemOperand::MONone, unsigned *Fast=nullptr) const
Return true if the target supports a memory access of this type for the given address space and align...
virtual bool canMergeStoresTo(unsigned AS, EVT MemVT, const MachineFunction &MF) const
Returns if it's reasonable to merge stores to MemVT size.
virtual const LegalizerInfo * getLegalizerInfo() const
virtual const TargetLowering * getTargetLowering() const
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
constexpr ScalarTy getFixedValue() const
Definition: TypeSize.h:202
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition: TypeSize.h:168
#define INT64_MAX
Definition: DataTypes.h:71
constexpr bool any(E Val)
Definition: BitmaskEnum.h:145
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition: CallingConv.h:41
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
bool aliasIsKnownForLoadStore(const MachineInstr &MI1, const MachineInstr &MI2, bool &IsAlias, MachineRegisterInfo &MRI)
Compute whether or not a memory access at MI1 aliases with an access at MI2.
BaseIndexOffset getPointerInfo(Register Ptr, MachineRegisterInfo &MRI)
Returns a BaseIndexOffset which describes the pointer in Ptr.
bool instMayAlias(const MachineInstr &MI, const MachineInstr &Other, MachineRegisterInfo &MRI, AliasAnalysis *AA)
Returns true if the instruction MI may alias Other.
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:47
@ Unsupported
This operation is completely unsupported on the target.
Definition: LegalizerInfo.h:91
operand_type_match m_Reg()
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ASHR, false > m_GAShr(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
DiagnosticInfoOptimizationBase::Argument NV
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
@ Offset
Definition: DWP.cpp:480
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
Definition: Utils.cpp:471
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:1746
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:420
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
EVT getApproximateEVTForLLT(LLT Ty, LLVMContext &Ctx)
@ Other
Any other memory.
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition: Utils.cpp:1153
std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
Definition: Utils.cpp:418
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition: bit.h:327
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
bool isTriviallyDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
Check whether an instruction MI is dead: it only defines dead virtual registers, and doesn't have oth...
Definition: Utils.cpp:222
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#define MORE()
Definition: regcomp.c:252
Extended Value Type.
Definition: ValueTypes.h:35
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
The result of a query.
LegalizeAction Action
The action to take or the final answer.