Movatterモバイル変換


[0]ホーム

URL:


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
12#include "llvm/CodeGen/GlobalISel/LoadStoreOpt.h"
13#include "llvm/ADT/STLExtras.h"
14#include "llvm/ADT/SmallPtrSet.h"
15#include "llvm/ADT/Statistic.h"
16#include "llvm/Analysis/AliasAnalysis.h"
17#include "llvm/Analysis/MemoryLocation.h"
18#include "llvm/Analysis/OptimizationRemarkEmitter.h"
19#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"
20#include "llvm/CodeGen/GlobalISel/LegalizerInfo.h"
21#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"
22#include "llvm/CodeGen/GlobalISel/Utils.h"
23#include "llvm/CodeGen/LowLevelTypeUtils.h"
24#include "llvm/CodeGen/MachineBasicBlock.h"
25#include "llvm/CodeGen/MachineFrameInfo.h"
26#include "llvm/CodeGen/MachineFunction.h"
27#include "llvm/CodeGen/MachineInstr.h"
28#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
29#include "llvm/CodeGen/MachineRegisterInfo.h"
30#include "llvm/CodeGen/Register.h"
31#include "llvm/CodeGen/TargetLowering.h"
32#include "llvm/CodeGen/TargetOpcodes.h"
33#include "llvm/IR/DebugInfoMetadata.h"
34#include "llvm/InitializePasses.h"
35#include "llvm/Support/AtomicOrdering.h"
36#include "llvm/Support/Casting.h"
37#include "llvm/Support/Debug.h"
38#include "llvm/Support/ErrorHandling.h"
39#include <algorithm>
40
41#define DEBUG_TYPE "loadstore-opt"
42
43using namespacellvm;
44using namespaceore;
45using namespaceMIPatternMatch;
46
47STATISTIC(NumStoresMerged,"Number of stores merged");
48
49constunsignedMaxStoreSizeToForm = 128;
50
51charLoadStoreOpt::ID = 0;
52INITIALIZE_PASS_BEGIN(LoadStoreOpt,DEBUG_TYPE,"Generic memory optimizations",
53false,false)
54INITIALIZE_PASS_END(LoadStoreOpt,DEBUG_TYPE, "Generic memoryoptimizations",
55false,false)
56
57LoadStoreOpt::LoadStoreOpt(std::function<bool(constMachineFunction &)>F)
58 :MachineFunctionPass(ID), DoNotRunPass(F) {}
59
60LoadStoreOpt::LoadStoreOpt()
61 :LoadStoreOpt([](constMachineFunction &) {returnfalse; }) {}
62
63void LoadStoreOpt::init(MachineFunction &MF) {
64 this->MF = &MF;
65 MRI = &MF.getRegInfo();
66 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
67 TLI = MF.getSubtarget().getTargetLowering();
68 LI = MF.getSubtarget().getLegalizerInfo();
69 Builder.setMF(MF);
70 IsPreLegalizer = !MF.getProperties().hasProperty(
71MachineFunctionProperties::Property::Legalized);
72 InstsToErase.clear();
73}
74
75voidLoadStoreOpt::getAnalysisUsage(AnalysisUsage &AU) const{
76 AU.addRequired<AAResultsWrapperPass>();
77 AU.setPreservesAll();
78getSelectionDAGFallbackAnalysisUsage(AU);
79MachineFunctionPass::getAnalysisUsage(AU);
80}
81
82BaseIndexOffsetGISelAddressing::getPointerInfo(RegisterPtr,
83MachineRegisterInfo &MRI) {
84BaseIndexOffsetInfo;
85Register PtrAddRHS;
86Register BaseReg;
87if (!mi_match(Ptr,MRI,m_GPtrAdd(m_Reg(BaseReg),m_Reg(PtrAddRHS)))) {
88Info.setBase(Ptr);
89Info.setOffset(0);
90returnInfo;
91 }
92Info.setBase(BaseReg);
93auto RHSCst =getIConstantVRegValWithLookThrough(PtrAddRHS,MRI);
94if (RHSCst)
95Info.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.
99Info.setIndex(PtrAddRHS);
100returnInfo;
101}
102
103boolGISelAddressing::aliasIsKnownForLoadStore(constMachineInstr &MI1,
104constMachineInstr &MI2,
105bool &IsAlias,
106MachineRegisterInfo &MRI) {
107auto *LdSt1 = dyn_cast<GLoadStore>(&MI1);
108auto *LdSt2 = dyn_cast<GLoadStore>(&MI2);
109if (!LdSt1 || !LdSt2)
110returnfalse;
111
112BaseIndexOffset BasePtr0 =getPointerInfo(LdSt1->getPointerReg(),MRI);
113BaseIndexOffset BasePtr1 =getPointerInfo(LdSt2->getPointerReg(),MRI);
114
115if (!BasePtr0.getBase().isValid() || !BasePtr1.getBase().isValid())
116returnfalse;
117
118LocationSize Size1 = LdSt1->getMemSize();
119LocationSize Size2 = LdSt2->getMemSize();
120
121 int64_t PtrDiff;
122if (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:
130if (PtrDiff >= 0 && Size1.hasValue() && !Size1.isScalable()) {
131// [----BasePtr0----]
132// [---BasePtr1--]
133// ========PtrDiff========>
134 IsAlias = !((int64_t)Size1.getValue() <= PtrDiff);
135returntrue;
136 }
137if (PtrDiff < 0 && Size2.hasValue() && !Size2.isScalable()) {
138// [----BasePtr0----]
139// [---BasePtr1--]
140// =====(-PtrDiff)====>
141 IsAlias = !((PtrDiff + (int64_t)Size2.getValue()) <= 0);
142returntrue;
143 }
144returnfalse;
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.
151auto *Base0Def =getDefIgnoringCopies(BasePtr0.getBase(),MRI);
152auto *Base1Def =getDefIgnoringCopies(BasePtr1.getBase(),MRI);
153if (!Base0Def || !Base1Def)
154returnfalse;// Couldn't tell anything.
155
156
157if (Base0Def->getOpcode() != Base1Def->getOpcode())
158returnfalse;
159
160if (Base0Def->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
161MachineFrameInfo &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.
164if (Base0Def != Base1Def &&
165 (!MFI.isFixedObjectIndex(Base0Def->getOperand(1).getIndex()) ||
166 !MFI.isFixedObjectIndex(Base1Def->getOperand(1).getIndex()))) {
167 IsAlias =false;
168returntrue;
169 }
170 }
171
172// This implementation is a lot more primitive than the SDAG one for now.
173// FIXME: what about constant pools?
174if (Base0Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
175auto GV0 = Base0Def->getOperand(1).getGlobal();
176auto GV1 = Base1Def->getOperand(1).getGlobal();
177if (GV0 != GV1) {
178 IsAlias =false;
179returntrue;
180 }
181 }
182
183// Can't tell anything about aliasing.
184returnfalse;
185}
186
187boolGISelAddressing::instMayAlias(constMachineInstr &MI,
188constMachineInstr &Other,
189MachineRegisterInfo &MRI,
190AliasAnalysis *AA) {
191structMemUseCharacteristics {
192bool IsVolatile;
193bool IsAtomic;
194Register BasePtr;
195 int64_tOffset;
196LocationSize NumBytes;
197MachineMemOperand *MMO;
198 };
199
200auto getCharacteristics =
201 [&](constMachineInstr *MI) -> MemUseCharacteristics {
202if (constauto *LS = dyn_cast<GLoadStore>(MI)) {
203Register BaseReg;
204 int64_tOffset = 0;
205// No pre/post-inc addressing modes are considered here, unlike in SDAG.
206if (!mi_match(LS->getPointerReg(),MRI,
207m_GPtrAdd(m_Reg(BaseReg),m_ICst(Offset)))) {
208 BaseReg = LS->getPointerReg();
209Offset = 0;
210 }
211
212LocationSizeSize = LS->getMMO().getSize();
213return {LS->isVolatile(), LS->isAtomic(), BaseReg,
214Offset/*base offset*/,Size, &LS->getMMO()};
215 }
216// FIXME: support recognizing lifetime instructions.
217// Default.
218return {false/*isvolatile*/,
219/*isAtomic*/false,
220Register(),
221 (int64_t)0/*offset*/,
222LocationSize::beforeOrAfterPointer()/*size*/,
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.
229if (MUC0.BasePtr.isValid() && MUC0.BasePtr == MUC1.BasePtr &&
230 MUC0.Offset == MUC1.Offset)
231returntrue;
232
233// If they are both volatile then they cannot be reordered.
234if (MUC0.IsVolatile && MUC1.IsVolatile)
235returntrue;
236
237// Be conservative about atomics for the moment
238// TODO: This is way overconservative for unordered atomics (see D66309)
239if (MUC0.IsAtomic && MUC1.IsAtomic)
240returntrue;
241
242// If one operation reads from invariant memory, and the other may store, they
243// cannot alias.
244if (MUC0.MMO && MUC1.MMO) {
245if ((MUC0.MMO->isInvariant() && MUC1.MMO->isStore()) ||
246 (MUC1.MMO->isInvariant() && MUC0.MMO->isStore()))
247returnfalse;
248 }
249
250// If NumBytes is scalable and offset is not 0, conservatively return may
251// alias
252if ((MUC0.NumBytes.isScalable() && MUC0.Offset != 0) ||
253 (MUC1.NumBytes.isScalable() && MUC1.Offset != 0))
254returntrue;
255
256constbool 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.
261bool IsAlias;
262if (BothNotScalable &&
263GISelAddressing::aliasIsKnownForLoadStore(MI,Other, IsAlias,MRI))
264return IsAlias;
265
266// The following all rely on MMO0 and MMO1 being valid.
267if (!MUC0.MMO || !MUC1.MMO)
268returntrue;
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();
273LocationSize Size0 = MUC0.NumBytes;
274LocationSize Size1 = MUC1.NumBytes;
275if (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;
283LocationSize Loc0 =
284 Size0.isScalable() ? Size0 :LocationSize::precise(Overlap0);
285LocationSize Loc1 =
286 Size1.isScalable() ? Size1 :LocationSize::precise(Overlap1);
287
288if (AA->isNoAlias(
289MemoryLocation(MUC0.MMO->getValue(), Loc0, MUC0.MMO->getAAInfo()),
290MemoryLocation(MUC1.MMO->getValue(), Loc1, MUC1.MMO->getAAInfo())))
291returnfalse;
292 }
293
294// Otherwise we have to assume they alias.
295returntrue;
296}
297
298/// Returns true if the instruction creates an unavoidable hazard that
299/// forces a boundary between store merge candidates.
300staticboolisInstHardMergeHazard(MachineInstr &MI) {
301returnMI.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.
307assert(StoresToMerge.size() > 1 &&"Expected multiple stores to merge");
308LLT OrigTy = MRI->getType(StoresToMerge[0]->getValueReg());
309LLT PtrTy = MRI->getType(StoresToMerge[0]->getPointerReg());
310unsigned AS = PtrTy.getAddressSpace();
311// Ensure the legal store info is computed for this address space.
312 initializeStoreMergeTargetInfo(AS);
313constauto &LegalSizes = LegalStoreSizes[AS];
314
315#ifndef NDEBUG
316for (auto *StoreMI : StoresToMerge)
317assert(MRI->getType(StoreMI->getValueReg()) == OrigTy);
318#endif
319
320bool AnyMerged =false;
321do {
322unsigned NumPow2 =llvm::bit_floor(StoresToMerge.size());
323unsigned MaxSizeBits = NumPow2 * OrigTy.getSizeInBits().getFixedValue();
324// Compute the biggest store we can generate to handle the number of stores.
325unsigned MergeSizeBits;
326for (MergeSizeBits = MaxSizeBits; MergeSizeBits > 1; MergeSizeBits /= 2) {
327LLT StoreTy =LLT::scalar(MergeSizeBits);
328EVT StoreEVT =
329getApproximateEVTForLLT(StoreTy, MF->getFunction().getContext());
330if (LegalSizes.size() > MergeSizeBits && LegalSizes[MergeSizeBits] &&
331 TLI->canMergeStoresTo(AS, StoreEVT, *MF) &&
332 (TLI->isTypeLegal(StoreEVT)))
333break;// We can generate a MergeSize bits store.
334 }
335if (MergeSizeBits <= OrigTy.getSizeInBits())
336return AnyMerged;// No greater merge.
337
338unsigned NumStoresToMerge = MergeSizeBits / OrigTy.getSizeInBits();
339// Perform the actual merging.
340SmallVector<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);
346return AnyMerged;
347}
348
349bool LoadStoreOpt::isLegalOrBeforeLegalizer(constLegalityQuery &Query,
350MachineFunction &MF) const{
351auto Action = LI->getAction(Query).Action;
352// If the instruction is unsupported, it can't be legalized at all.
353if (Action ==LegalizeActions::Unsupported)
354returnfalse;
355return IsPreLegalizer || Action == LegalizeAction::Legal;
356}
357
358bool LoadStoreOpt::doSingleStoreMerge(SmallVectorImpl<GStore *> &Stores) {
359assert(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.
365GStore *FirstStore = Stores[0];
366constunsigned NumStores = Stores.size();
367LLT SmallTy = MRI->getType(FirstStore->getValueReg());
368LLT WideValueTy =
369LLT::scalar(NumStores * SmallTy.getSizeInBits().getFixedValue());
370
371// For each store, compute pairwise merged debug locs.
372DebugLoc MergedLoc = Stores.front()->getDebugLoc();
373for (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.
382SmallVector<APInt, 8> ConstantVals;
383for (auto *Store : Stores) {
384auto MaybeCst =
385getIConstantVRegValWithLookThrough(Store->getValueReg(), *MRI);
386if (!MaybeCst) {
387 ConstantVals.clear();
388break;
389 }
390 ConstantVals.emplace_back(MaybeCst->Value);
391 }
392
393Register WideReg;
394auto *WideMMO =
395 MF->getMachineMemOperand(&FirstStore->getMMO(), 0, WideValueTy);
396if (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.
400returnfalse;
401 }
402
403assert(ConstantVals.size() == NumStores);
404// Check if our wide constant is legal.
405if (!isLegalOrBeforeLegalizer({TargetOpcode::G_CONSTANT, {WideValueTy}}, *MF))
406returnfalse;
407APInt WideConst(WideValueTy.getSizeInBits(), 0);
408for (unsignedIdx = 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);
414auto NewStore =
415 Builder.buildStore(WideReg, FirstStore->getPointerReg(), *WideMMO);
416 (void) NewStore;
417LLVM_DEBUG(dbgs() <<"Merged " << Stores.size()
418 <<" stores into merged store: " << *NewStore);
419LLVM_DEBUG(for (auto *MI : Stores)dbgs() <<" " << *MI;);
420 NumStoresMerged += Stores.size();
421
422MachineOptimizationRemarkEmitterMORE(*MF,nullptr);
423MORE.emit([&]() {
424MachineOptimizationRemarkR(DEBUG_TYPE,"MergedStore",
425 FirstStore->getDebugLoc(),
426 FirstStore->getParent());
427R <<"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";
431returnR;
432 });
433
434for (auto *MI : Stores)
435 InstsToErase.insert(MI);
436returntrue;
437}
438
439bool LoadStoreOpt::processMergeCandidate(StoreMergeCandidate &C) {
440if (C.Stores.size() < 2) {
441C.reset();
442returnfalse;
443 }
444
445LLVM_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.
458SmallVector<GStore *> StoresToMerge;
459
460auto DoesStoreAliasWithPotential = [&](unsignedIdx,GStore &CheckStore) {
461for (auto AliasInfo :reverse(C.PotentialAliases)) {
462MachineInstr *PotentialAliasOp = AliasInfo.first;
463unsigned PreCheckedIdx = AliasInfo.second;
464if (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.
468returnfalse;
469 }
470// Need to check this alias.
471if (GISelAddressing::instMayAlias(CheckStore, *PotentialAliasOp, *MRI,
472 AA)) {
473LLVM_DEBUG(dbgs() <<"Potential alias " << *PotentialAliasOp
474 <<" detected\n");
475returntrue;
476 }
477 }
478returnfalse;
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.
482for (int StoreIdx =C.Stores.size() - 1; StoreIdx >= 0; --StoreIdx) {
483auto *CheckStore =C.Stores[StoreIdx];
484if (DoesStoreAliasWithPotential(StoreIdx, *CheckStore))
485continue;
486 StoresToMerge.emplace_back(CheckStore);
487 }
488
489LLVM_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.
493C.reset();
494if (StoresToMerge.size() < 2)
495returnfalse;
496return mergeStores(StoresToMerge);
497}
498
499bool LoadStoreOpt::operationAliasesWithCandidate(MachineInstr &MI,
500 StoreMergeCandidate &C) {
501if (C.Stores.empty())
502returnfalse;
503returnllvm::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.
516LLT ValueTy = MRI->getType(StoreMI.getValueReg());
517LLT PtrTy = MRI->getType(StoreMI.getPointerReg());
518
519// Only handle scalars.
520if (!ValueTy.isScalar())
521returnfalse;
522
523// Don't allow truncating stores for now.
524if (StoreMI.getMemSizeInBits() != ValueTy.getSizeInBits())
525returnfalse;
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.
530if (!StoreMI.isSimple())
531returnfalse;
532
533Register StoreAddr = StoreMI.getPointerReg();
534auto BIO =getPointerInfo(StoreAddr, *MRI);
535Register StoreBase = BIO.getBase();
536if (C.Stores.empty()) {
537C.BasePtr = StoreBase;
538if (!BIO.hasValidOffset()) {
539C.CurrentLowestOffset = 0;
540 }else {
541C.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.
546if (BIO.hasValidOffset() &&
547 BIO.getOffset() <static_cast<int64_t>(ValueTy.getSizeInBytes()))
548returnfalse;
549C.Stores.emplace_back(&StoreMI);
550LLVM_DEBUG(dbgs() <<"Starting a new merge candidate group with: "
551 << StoreMI);
552returntrue;
553 }
554
555// Check the store is the same size as the existing ones in the candidate.
556if (MRI->getType(C.Stores[0]->getValueReg()).getSizeInBits() !=
557 ValueTy.getSizeInBits())
558returnfalse;
559
560if (MRI->getType(C.Stores[0]->getPointerReg()).getAddressSpace() !=
561 PtrTy.getAddressSpace())
562returnfalse;
563
564// There are other stores in the candidate. Check that the store address
565// writes to the next lowest adjacent address.
566if (C.BasePtr != StoreBase)
567returnfalse;
568// If we don't have a valid offset, we can't guarantee to be an adjacent
569// offset.
570if (!BIO.hasValidOffset())
571returnfalse;
572if ((C.CurrentLowestOffset -
573static_cast<int64_t>(ValueTy.getSizeInBytes())) != BIO.getOffset())
574returnfalse;
575
576// This writes to an adjacent address. Allow it.
577C.Stores.emplace_back(&StoreMI);
578C.CurrentLowestOffset =C.CurrentLowestOffset - ValueTy.getSizeInBytes();
579LLVM_DEBUG(dbgs() <<"Candidate added store: " << StoreMI);
580returntrue;
581}
582
583bool LoadStoreOpt::mergeBlockStores(MachineBasicBlock &MBB) {
584bool Changed =false;
585// Walk through the block bottom-up, looking for merging candidates.
586 StoreMergeCandidate Candidate;
587for (MachineInstr &MI :llvm::reverse(MBB)) {
588if (InstsToErase.contains(&MI))
589continue;
590
591if (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.
594if (!addStoreToCandidate(*StoreMI, Candidate)) {
595// Store wasn't eligible to be added. May need to record it as a
596// potential alias.
597if (operationAliasesWithCandidate(*StoreMI, Candidate)) {
598 Changed |= processMergeCandidate(Candidate);
599continue;
600 }
601 Candidate.addPotentialAlias(*StoreMI);
602 }
603continue;
604 }
605
606// If we don't have any stores yet, this instruction can't pose a problem.
607if (Candidate.Stores.empty())
608continue;
609
610// We're dealing with some other kind of instruction.
611if (isInstHardMergeHazard(MI)) {
612 Changed |= processMergeCandidate(Candidate);
613 Candidate.Stores.clear();
614continue;
615 }
616
617if (!MI.mayLoadOrStore())
618continue;
619
620if (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);
624continue;
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.
636for (auto *MI : InstsToErase)
637MI->eraseFromParent();
638 InstsToErase.clear();
639return 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>
649getTruncStoreByteOffset(GStore &Store,Register &SrcVal,
650MachineRegisterInfo &MRI) {
651Register TruncVal;
652if (!mi_match(Store.getValueReg(),MRI,m_GTrunc(m_Reg(TruncVal))))
653return 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, ...
661Register FoundSrcVal;
662 int64_t ShiftAmt;
663if (!mi_match(TruncVal,MRI,
664m_any_of(m_GLShr(m_Reg(FoundSrcVal),m_ICst(ShiftAmt)),
665m_GAShr(m_Reg(FoundSrcVal),m_ICst(ShiftAmt))))) {
666if (!SrcVal.isValid() || TruncVal == SrcVal) {
667if (!SrcVal.isValid())
668 SrcVal = TruncVal;
669return 0;// If it's the lowest index store.
670 }
671return std::nullopt;
672 }
673
674unsigned NarrowBits = Store.getMMO().getMemoryType().getScalarSizeInBits();
675if (ShiftAmt % NarrowBits != 0)
676return std::nullopt;
677constunsignedOffset = ShiftAmt / NarrowBits;
678
679if (SrcVal.isValid() && FoundSrcVal != SrcVal)
680return std::nullopt;
681
682if (!SrcVal.isValid())
683 SrcVal = FoundSrcVal;
684elseif (MRI.getType(SrcVal) !=MRI.getType(FoundSrcVal))
685return std::nullopt;
686returnOffset;
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,
712SmallPtrSetImpl<GStore *> &DeletedStores) {
713LLT MemTy = StoreMI.getMMO().getMemoryType();
714
715// We only handle merging simple stores of 1-4 bytes.
716if (!MemTy.isScalar())
717returnfalse;
718switch (MemTy.getSizeInBits()) {
719case 8:
720case 16:
721case 32:
722break;
723default:
724returnfalse;
725 }
726if (!StoreMI.isSimple())
727returnfalse;
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.
731SmallVector<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
739auto &LastStore = StoreMI;
740
741// The single base pointer that all stores must use.
742Register BaseReg;
743 int64_t LastOffset;
744if (!mi_match(LastStore.getPointerReg(), *MRI,
745m_GPtrAdd(m_Reg(BaseReg),m_ICst(LastOffset)))) {
746 BaseReg = LastStore.getPointerReg();
747 LastOffset = 0;
748 }
749
750GStore *LowestIdxStore = &LastStore;
751 int64_t LowestIdxOffset = LastOffset;
752
753Register WideSrcVal;
754auto LowestShiftAmt =getTruncStoreByteOffset(LastStore, WideSrcVal, *MRI);
755if (!LowestShiftAmt)
756returnfalse;// Didn't match a trunc.
757assert(WideSrcVal.isValid());
758
759LLT WideStoreTy = MRI->getType(WideSrcVal);
760// The wide type might not be a multiple of the memory type, e.g. s48 and s32.
761if (WideStoreTy.getSizeInBits() % MemTy.getSizeInBits() != 0)
762returnfalse;
763constunsigned NumStoresRequired =
764 WideStoreTy.getSizeInBits() / MemTy.getSizeInBits();
765
766SmallVector<int64_t, 8> OffsetMap(NumStoresRequired,INT64_MAX);
767 OffsetMap[*LowestShiftAmt] = LastOffset;
768 FoundStores.emplace_back(&LastStore);
769
770constint MaxInstsToCheck = 10;
771int NumInstsChecked = 0;
772for (autoII = ++LastStore.getReverseIterator();
773II != LastStore.getParent()->rend() && NumInstsChecked < MaxInstsToCheck;
774 ++II) {
775 NumInstsChecked++;
776GStore *NewStore;
777if ((NewStore = dyn_cast<GStore>(&*II))) {
778if (NewStore->getMMO().getMemoryType() != MemTy || !NewStore->isSimple())
779break;
780 }elseif (II->isLoadFoldBarrier() ||II->mayLoad()) {
781break;
782 }else {
783continue;// This is a safe instruction we can look past.
784 }
785
786Register NewBaseReg;
787 int64_t MemOffset;
788// Check we're storing to the same base + some offset.
789if (!mi_match(NewStore->getPointerReg(), *MRI,
790m_GPtrAdd(m_Reg(NewBaseReg),m_ICst(MemOffset)))) {
791 NewBaseReg = NewStore->getPointerReg();
792 MemOffset = 0;
793 }
794if (BaseReg != NewBaseReg)
795break;
796
797auto ShiftByteOffset =getTruncStoreByteOffset(*NewStore, WideSrcVal, *MRI);
798if (!ShiftByteOffset)
799break;
800if (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.
807if (*ShiftByteOffset < 0 || *ShiftByteOffset >= NumStoresRequired ||
808 OffsetMap[*ShiftByteOffset] !=INT64_MAX)
809break;
810 OffsetMap[*ShiftByteOffset] = MemOffset;
811
812 FoundStores.emplace_back(NewStore);
813// Reset counter since we've found a matching inst.
814 NumInstsChecked = 0;
815if (FoundStores.size() == NumStoresRequired)
816break;
817 }
818
819if (FoundStores.size() != NumStoresRequired) {
820if (FoundStores.size() == 1)
821returnfalse;
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
828unsigned NumStoresFound = FoundStores.size();
829
830constauto &DL = LastStore.getMF()->getDataLayout();
831auto &C = LastStore.getMF()->getFunction().getContext();
832// Check that a store of the wide type is both allowed and fast on the target
833unsignedFast = 0;
834boolAllowed = TLI->allowsMemoryAccess(
835C,DL, WideStoreTy, LowestIdxStore->getMMO(), &Fast);
836if (!Allowed || !Fast)
837returnfalse;
838
839// Check if the pieces of the value are going to the expected places in memory
840// to merge the stores.
841unsigned NarrowBits = MemTy.getScalarSizeInBits();
842auto checkOffsets = [&](bool MatchLittleEndian) {
843if (MatchLittleEndian) {
844for (unsigned i = 0; i != NumStoresFound; ++i)
845if (OffsetMap[i] != i * (NarrowBits / 8) + LowestIdxOffset)
846returnfalse;
847 }else {// MatchBigEndian by reversing loop counter.
848for (unsigned i = 0, j = NumStoresFound - 1; i != NumStoresFound;
849 ++i, --j)
850if (OffsetMap[j] != i * (NarrowBits / 8) + LowestIdxOffset)
851returnfalse;
852 }
853returntrue;
854 };
855
856// Check if the offsets line up for the native data layout of this target.
857bool NeedBswap =false;
858bool NeedRotate =false;
859if (!checkOffsets(DL.isLittleEndian())) {
860// Special-case: check if byte offsets line up for the opposite endian.
861if (NarrowBits == 8 && checkOffsets(DL.isBigEndian()))
862 NeedBswap =true;
863elseif (NumStoresFound == 2 && checkOffsets(DL.isBigEndian()))
864 NeedRotate =true;
865else
866returnfalse;
867 }
868
869if (NeedBswap &&
870 !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {WideStoreTy}}, *MF))
871returnfalse;
872if (NeedRotate &&
873 !isLegalOrBeforeLegalizer(
874 {TargetOpcode::G_ROTR, {WideStoreTy, WideStoreTy}}, *MF))
875returnfalse;
876
877 Builder.setInstrAndDebugLoc(StoreMI);
878
879if (WideStoreTy != MRI->getType(WideSrcVal))
880 WideSrcVal = Builder.buildTrunc(WideStoreTy, WideSrcVal).getReg(0);
881
882if (NeedBswap) {
883 WideSrcVal = Builder.buildBSwap(WideStoreTy, WideSrcVal).getReg(0);
884 }elseif (NeedRotate) {
885assert(WideStoreTy.getSizeInBits() % 2 == 0 &&
886"Unexpected type for rotate");
887auto 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.
898for (auto *ST : FoundStores) {
899ST->eraseFromParent();
900 DeletedStores.insert(ST);
901 }
902returntrue;
903}
904
905bool LoadStoreOpt::mergeTruncStoresBlock(MachineBasicBlock &BB) {
906bool Changed =false;
907SmallVector<GStore *, 16> Stores;
908SmallPtrSet<GStore *, 8> DeletedStores;
909// Walk up the block so we can see the most eligible stores.
910for (MachineInstr &MI :llvm::reverse(BB))
911if (auto *StoreMI = dyn_cast<GStore>(&MI))
912 Stores.emplace_back(StoreMI);
913
914for (auto *StoreMI : Stores) {
915if (DeletedStores.count(StoreMI))
916continue;
917if (mergeTruncStore(*StoreMI, DeletedStores))
918 Changed =true;
919 }
920return Changed;
921}
922
923bool LoadStoreOpt::mergeFunctionStores(MachineFunction &MF) {
924bool Changed =false;
925for (auto &BB : MF){
926 Changed |= mergeBlockStores(BB);
927 Changed |= mergeTruncStoresBlock(BB);
928 }
929
930// Erase all dead instructions left over by the merging.
931if (Changed) {
932for (auto &BB : MF) {
933for (auto &I :make_early_inc_range(make_range(BB.rbegin(), BB.rend()))) {
934if (isTriviallyDead(I, *MRI))
935I.eraseFromParent();
936 }
937 }
938 }
939
940return 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
948if (LegalStoreSizes.count(AddrSpace)) {
949assert(LegalStoreSizes[AddrSpace].any());
950return;// Already cached sizes for this address space.
951 }
952
953// Need to reserve at least MaxStoreSizeToForm + 1 bits.
954BitVector LegalSizes(MaxStoreSizeToForm * 2);
955constauto &LI = *MF->getSubtarget().getLegalizerInfo();
956constauto &DL = MF->getFunction().getDataLayout();
957Type *IRPtrTy =PointerType::get(MF->getFunction().getContext(), AddrSpace);
958LLT PtrTy =getLLTForType(*IRPtrTy,DL);
959// We assume that we're not going to be generating any stores wider than
960// MaxStoreSizeToForm bits for now.
961for (unsignedSize = 2;Size <=MaxStoreSizeToForm;Size *= 2) {
962LLT Ty =LLT::scalar(Size);
963SmallVector<LegalityQuery::MemDesc, 2> MemDescrs(
964 {{Ty, Ty.getSizeInBits(),AtomicOrdering::NotAtomic}});
965SmallVector<LLT> StoreTys({Ty, PtrTy});
966LegalityQuery Q(TargetOpcode::G_STORE, StoreTys, MemDescrs);
967LegalizeActionStep ActionStep = LI.getAction(Q);
968if (ActionStep.Action ==LegalizeActions::Legal)
969 LegalSizes.set(Size);
970 }
971assert(LegalSizes.any() &&"Expected some store sizes to be legal!");
972 LegalStoreSizes[AddrSpace] = LegalSizes;
973}
974
975boolLoadStoreOpt::runOnMachineFunction(MachineFunction &MF) {
976// If the ISel pipeline failed, do not bother running that pass.
977if (MF.getProperties().hasProperty(
978MachineFunctionProperties::Property::FailedISel))
979returnfalse;
980
981LLVM_DEBUG(dbgs() <<"Begin memory optimizations for: " << MF.getName()
982 <<'\n');
983
984 init(MF);
985bool Changed =false;
986 Changed |= mergeFunctionStores(MF);
987
988 LegalStoreSizes.clear();
989return Changed;
990}
MRI
unsigned const MachineRegisterInfo * MRI
Definition:AArch64AdvSIMDScalarPass.cpp:105
Generic
@ Generic
Definition:AArch64MCAsmInfo.cpp:23
const
aarch64 promote const
Definition:AArch64PromoteConstant.cpp:230
MBB
MachineBasicBlock & MBB
Definition:ARMSLSHardening.cpp:71
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
AliasAnalysis.h
AtomicOrdering.h
Atomic ordering constants.
Info
Analysis containing CSE Info
Definition:CSEInfo.cpp:27
Casting.h
Utils.h
Idx
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
Definition:DeadArgumentElimination.cpp:353
function
Performs the initial survey of the specified function
Definition:DeadArgumentElimination.cpp:488
DebugInfoMetadata.h
Debug.h
LLVM_DEBUG
#define LLVM_DEBUG(...)
Definition:Debug.h:106
Size
uint64_t Size
Definition:ELFObjHandler.cpp:81
DEBUG_TYPE
#define DEBUG_TYPE
Definition:GenericCycleImpl.h:31
GenericMachineInstrs.h
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
MI
IRTranslator LLVM IR MI
Definition:IRTranslator.cpp:112
InitializePasses.h
LegalizerInfo.h
Interface for Targets to specify which operations they can successfully select and how the others sho...
optimizations
Generic memory optimizations
Definition:LoadStoreOpt.cpp:54
MaxStoreSizeToForm
const unsigned MaxStoreSizeToForm
Definition:LoadStoreOpt.cpp:49
getTruncStoreByteOffset
static std::optional< int64_t > getTruncStoreByteOffset(GStore &Store, Register &SrcVal, MachineRegisterInfo &MRI)
Check if the store Store is a truncstore that can be merged.
Definition:LoadStoreOpt.cpp:649
DEBUG_TYPE
#define DEBUG_TYPE
Definition:LoadStoreOpt.cpp:41
isInstHardMergeHazard
static bool isInstHardMergeHazard(MachineInstr &MI)
Returns true if the instruction creates an unavoidable hazard that forces a boundary between store me...
Definition:LoadStoreOpt.cpp:300
LoadStoreOpt.h
LowLevelTypeUtils.h
Implement a low-level type suitable for MachineInstr level instruction selection.
F
#define F(x, y, z)
Definition:MD5.cpp:55
I
#define I(x, y, z)
Definition:MD5.cpp:58
MIPatternMatch.h
Contains matchers for matching SSA Machine Instructions.
MachineBasicBlock.h
MachineFrameInfo.h
MachineFunction.h
MachineInstr.h
MachineOptimizationRemarkEmitter.h
===- MachineOptimizationRemarkEmitter.h - Opt Diagnostics -*- C++ -*-—===//
MachineRegisterInfo.h
MemoryLocation.h
This file provides utility analysis objects describing memory locations.
II
uint64_t IntrinsicInst * II
Definition:NVVMIntrRange.cpp:51
OptimizationRemarkEmitter.h
INITIALIZE_PASS_END
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:57
INITIALIZE_PASS_BEGIN
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition:PassSupport.h:52
Register.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
STLExtras.h
This file contains some templates that are useful if you are working with the STL at all.
SmallPtrSet.h
This file defines the SmallPtrSet class.
Statistic.h
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
STATISTIC
#define STATISTIC(VARNAME, DESC)
Definition:Statistic.h:166
Ptr
@ Ptr
Definition:TargetLibraryInfo.cpp:77
TargetLowering.h
This file describes how to lower LLVM code to machine code.
TargetOpcodes.h
llvm::AAResultsWrapperPass
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Definition:AliasAnalysis.h:981
llvm::AAResults
Definition:AliasAnalysis.h:314
llvm::AAResults::isNoAlias
bool isNoAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are no-alias.
Definition:AliasAnalysis.h:368
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::AnalysisUsage
Represent the analysis usage information of a pass.
Definition:PassAnalysisSupport.h:47
llvm::AnalysisUsage::addRequired
AnalysisUsage & addRequired()
Definition:PassAnalysisSupport.h:75
llvm::AnalysisUsage::setPreservesAll
void setPreservesAll()
Set by analyses that do not transform their input at all.
Definition:PassAnalysisSupport.h:130
llvm::BitVector
Definition:BitVector.h:82
llvm::DILocation::getMergedLocation
static DILocation * getMergedLocation(DILocation *LocA, DILocation *LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
Definition:DebugInfoMetadata.cpp:121
llvm::DebugLoc
A debug info location.
Definition:DebugLoc.h:33
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition:Function.cpp:369
llvm::GISelAddressing::BaseIndexOffset
Helper struct to store a base, index and offset that forms an address.
Definition:LoadStoreOpt.h:38
llvm::GISelAddressing::BaseIndexOffset::getOffset
int64_t getOffset() const
Definition:LoadStoreOpt.h:54
llvm::GISelAddressing::BaseIndexOffset::hasValidOffset
bool hasValidOffset() const
Definition:LoadStoreOpt.h:53
llvm::GISelAddressing::BaseIndexOffset::getBase
Register getBase()
Definition:LoadStoreOpt.h:46
llvm::GLoadStore::getPointerReg
Register getPointerReg() const
Get the source register of the pointer value.
Definition:GenericMachineInstrs.h:84
llvm::GMemOperation::getMMO
MachineMemOperand & getMMO() const
Get the MachineMemOperand on this instruction.
Definition:GenericMachineInstrs.h:56
llvm::GMemOperation::getMemSizeInBits
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
Definition:GenericMachineInstrs.h:72
llvm::GMemOperation::isSimple
bool isSimple() const
Returns true if the memory operation is neither atomic or volatile.
Definition:GenericMachineInstrs.h:63
llvm::GStore
Represents a G_STORE.
Definition:GenericMachineInstrs.h:238
llvm::GStore::getValueReg
Register getValueReg() const
Get the stored value register.
Definition:GenericMachineInstrs.h:241
llvm::LLT
Definition:LowLevelType.h:39
llvm::LLT::getScalarSizeInBits
constexpr unsigned getScalarSizeInBits() const
Definition:LowLevelType.h:264
llvm::LLT::isScalar
constexpr bool isScalar() const
Definition:LowLevelType.h:146
llvm::LLT::scalar
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition:LowLevelType.h:42
llvm::LLT::getSizeInBits
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition:LowLevelType.h:190
llvm::LLT::getAddressSpace
constexpr unsigned getAddressSpace() const
Definition:LowLevelType.h:270
llvm::LLT::getSizeInBytes
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
Definition:LowLevelType.h:200
llvm::LegalizerInfo::getAction
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
Definition:LegalizerInfo.cpp:323
llvm::LoadStoreOpt
Definition:LoadStoreOpt.h:76
llvm::LoadStoreOpt::ID
static char ID
Definition:LoadStoreOpt.h:78
llvm::LoadStoreOpt::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition:LoadStoreOpt.cpp:75
llvm::LoadStoreOpt::LoadStoreOpt
LoadStoreOpt()
Definition:LoadStoreOpt.cpp:60
llvm::LoadStoreOpt::runOnMachineFunction
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition:LoadStoreOpt.cpp:975
llvm::LocationSize
Definition:MemoryLocation.h:68
llvm::LocationSize::hasValue
bool hasValue() const
Definition:MemoryLocation.h:165
llvm::LocationSize::precise
static LocationSize precise(uint64_t Value)
Definition:MemoryLocation.h:108
llvm::LocationSize::beforeOrAfterPointer
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
Definition:MemoryLocation.h:137
llvm::LocationSize::isScalable
bool isScalable() const
Definition:MemoryLocation.h:168
llvm::LocationSize::getValue
TypeSize getValue() const
Definition:MemoryLocation.h:170
llvm::MachineBasicBlock
Definition:MachineBasicBlock.h:125
llvm::MachineBasicBlock::rend
reverse_iterator rend()
Definition:MachineBasicBlock.h:365
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition:MachineBasicBlock.h:359
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition:MachineFrameInfo.h:106
llvm::MachineFrameInfo::isFixedObjectIndex
bool isFixedObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a fixed stack object.
Definition:MachineFrameInfo.h:700
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition:MachineFunctionPass.h:30
llvm::MachineFunctionPass::getAnalysisUsage
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition:MachineFunctionPass.cpp:169
llvm::MachineFunctionProperties::hasProperty
bool hasProperty(Property P) const
Definition:MachineFunction.h:203
llvm::MachineFunctionProperties::Property::FailedISel
@ FailedISel
llvm::MachineFunctionProperties::Property::Legalized
@ Legalized
llvm::MachineFunction
Definition:MachineFunction.h:267
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition:MachineFunction.h:733
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition:MachineFunction.cpp:645
llvm::MachineFunction::getMachineMemOperand
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.
Definition:MachineFunction.cpp:536
llvm::MachineFunction::getRegInfo
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Definition:MachineFunction.h:743
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition:MachineFunction.h:704
llvm::MachineFunction::getProperties
const MachineFunctionProperties & getProperties() const
Get the function properties.
Definition:MachineFunction.h:824
llvm::MachineIRBuilder::buildRotateRight
MachineInstrBuilder buildRotateRight(const DstOp &Dst, const SrcOp &Src, const SrcOp &Amt)
Build and insert Dst = G_ROTR Src, Amt.
Definition:MachineIRBuilder.h:2303
llvm::MachineIRBuilder::setInstr
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
Definition:MachineIRBuilder.h:365
llvm::MachineIRBuilder::buildBSwap
MachineInstrBuilder buildBSwap(const DstOp &Dst, const SrcOp &Src0)
Build and insert Dst = G_BSWAP Src0.
Definition:MachineIRBuilder.h:1950
llvm::MachineIRBuilder::buildStore
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
Definition:MachineIRBuilder.cpp:468
llvm::MachineIRBuilder::setInstrAndDebugLoc
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
Definition:MachineIRBuilder.h:376
llvm::MachineIRBuilder::buildTrunc
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
Definition:MachineIRBuilder.cpp:909
llvm::MachineIRBuilder::setDebugLoc
void setDebugLoc(const DebugLoc &DL)
Set the debug location to DL for all the next build instructions.
Definition:MachineIRBuilder.h:393
llvm::MachineIRBuilder::setMF
void setMF(MachineFunction &MF)
Definition:MachineIRBuilder.cpp:24
llvm::MachineIRBuilder::buildConstant
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Definition:MachineIRBuilder.cpp:317
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition:MachineInstrBuilder.h:96
llvm::MachineInstr
Representation of each machine instruction.
Definition:MachineInstr.h:71
llvm::MachineInstr::getParent
const MachineBasicBlock * getParent() const
Definition:MachineInstr.h:349
llvm::MachineInstr::getDebugLoc
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
Definition:MachineInstr.h:501
llvm::MachineMemOperand
A description of a memory reference used in the backend.
Definition:MachineMemOperand.h:129
llvm::MachineMemOperand::getMemoryType
LLT getMemoryType() const
Return the memory type of the memory reference.
Definition:MachineMemOperand.h:237
llvm::MachineMemOperand::getPointerInfo
const MachinePointerInfo & getPointerInfo() const
Definition:MachineMemOperand.h:204
llvm::MachineMemOperand::getAlign
Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
Definition:MachineOperand.cpp:1146
llvm::MachineOptimizationRemarkEmitter
The optimization diagnostic interface.
Definition:MachineOptimizationRemarkEmitter.h:153
llvm::MachineOptimizationRemark
Diagnostic information for applied optimization remarks.
Definition:MachineOptimizationRemarkEmitter.h:59
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition:MachineRegisterInfo.h:51
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition:MachineRegisterInfo.h:777
llvm::MemoryLocation
Representation for a specific memory location.
Definition:MemoryLocation.h:227
llvm::PointerType::get
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
llvm::Register
Wrapper class representing virtual and physical registers.
Definition:Register.h:19
llvm::Register::isValid
constexpr bool isValid() const
Definition:Register.h:115
llvm::SmallPtrSetImpl
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition:SmallPtrSet.h:363
llvm::SmallPtrSetImpl::count
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition:SmallPtrSet.h:452
llvm::SmallPtrSetImpl::insert
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
llvm::SmallPtrSet
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition:SmallPtrSet.h:519
llvm::SmallVectorBase::empty
bool empty() const
Definition:SmallVector.h:81
llvm::SmallVectorBase::size
size_t size() const
Definition:SmallVector.h:78
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition:SmallVector.h:573
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition:SmallVector.h:937
llvm::SmallVectorImpl::clear
void clear()
Definition:SmallVector.h:610
llvm::SmallVectorTemplateCommon::front
reference front()
Definition:SmallVector.h:299
llvm::SmallVectorTemplateCommon::back
reference back()
Definition:SmallVector.h:308
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition:SmallVector.h:1196
llvm::TargetLoweringBase::isTypeLegal
bool isTypeLegal(EVT VT) const
Return true if the target has native support for the specified value type.
Definition:TargetLowering.h:1093
llvm::TargetLoweringBase::allowsMemoryAccess
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...
Definition:TargetLoweringBase.cpp:1735
llvm::TargetLoweringBase::canMergeStoresTo
virtual bool canMergeStoresTo(unsigned AS, EVT MemVT, const MachineFunction &MF) const
Returns if it's reasonable to merge stores to MemVT size.
Definition:TargetLowering.h:701
llvm::TargetSubtargetInfo::getLegalizerInfo
virtual const LegalizerInfo * getLegalizerInfo() const
Definition:TargetSubtargetInfo.h:125
llvm::TargetSubtargetInfo::getTargetLowering
virtual const TargetLowering * getTargetLowering() const
Definition:TargetSubtargetInfo.h:101
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
llvm::details::FixedOrScalableQuantity::getFixedValue
constexpr ScalarTy getFixedValue() const
Definition:TypeSize.h:202
llvm::details::FixedOrScalableQuantity::getKnownMinValue
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition:TypeSize.h:168
unsigned
INT64_MAX
#define INT64_MAX
Definition:DataTypes.h:71
ErrorHandling.h
false
Definition:StackSlotColoring.cpp:193
llvm::ARM_MB::ST
@ ST
Definition:ARMBaseInfo.h:73
llvm::BitmaskEnumDetail::any
constexpr bool any(E Val)
Definition:BitmaskEnum.h:145
llvm::CallingConv::Fast
@ Fast
Attempts to make calls as fast as possible (e.g.
Definition:CallingConv.h:41
llvm::CallingConv::C
@ C
The default llvm calling convention, compatible with C.
Definition:CallingConv.h:34
llvm::GISelAddressing::aliasIsKnownForLoadStore
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.
Definition:LoadStoreOpt.cpp:103
llvm::GISelAddressing::getPointerInfo
BaseIndexOffset getPointerInfo(Register Ptr, MachineRegisterInfo &MRI)
Returns a BaseIndexOffset which describes the pointer in Ptr.
Definition:LoadStoreOpt.cpp:82
llvm::GISelAddressing::instMayAlias
bool instMayAlias(const MachineInstr &MI, const MachineInstr &Other, MachineRegisterInfo &MRI, AliasAnalysis *AA)
Returns true if the instruction MI may alias Other.
Definition:LoadStoreOpt.cpp:187
llvm::LegalizeActions::Legal
@ Legal
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition:LegalizerInfo.h:47
llvm::LegalizeActions::Unsupported
@ Unsupported
This operation is completely unsupported on the target.
Definition:LegalizerInfo.h:91
llvm::M68k::MemAddrModeKind::j
@ j
llvm::MIPatternMatch::m_Reg
operand_type_match m_Reg()
Definition:MIPatternMatch.h:270
llvm::MIPatternMatch::m_ICst
ConstantMatch< APInt > m_ICst(APInt &Cst)
Definition:MIPatternMatch.h:93
llvm::MIPatternMatch::m_GAShr
BinaryOp_match< LHS, RHS, TargetOpcode::G_ASHR, false > m_GAShr(const LHS &L, const RHS &R)
Definition:MIPatternMatch.h:576
llvm::MIPatternMatch::mi_match
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
Definition:MIPatternMatch.h:25
llvm::MIPatternMatch::m_GPtrAdd
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
Definition:MIPatternMatch.h:510
llvm::MIPatternMatch::m_any_of
Or< Preds... > m_any_of(Preds &&... preds)
Definition:MIPatternMatch.h:314
llvm::MIPatternMatch::m_GLShr
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
Definition:MIPatternMatch.h:570
llvm::MIPatternMatch::m_GTrunc
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
Definition:MIPatternMatch.h:643
llvm::RISCVFenceField::R
@ R
Definition:RISCVBaseInfo.h:373
llvm::SPII::Store
@ Store
Definition:SparcInstrInfo.h:33
llvm::orc::Allowed
@ Allowed
Definition:LoadLinkableFile.h:32
llvm::ore::NV
DiagnosticInfoOptimizationBase::Argument NV
Definition:OptimizationRemarkEmitter.h:135
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::drop_begin
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition:STLExtras.h:329
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition:iterator_range.h:77
llvm::make_early_inc_range
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
llvm::getDefIgnoringCopies
MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
Definition:Utils.cpp:486
llvm::any_of
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
llvm::reverse
auto reverse(ContainerTy &&C)
Definition:STLExtras.h:420
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition:Debug.cpp:163
llvm::AtomicOrdering::NotAtomic
@ NotAtomic
llvm::getApproximateEVTForLLT
EVT getApproximateEVTForLLT(LLT Ty, LLVMContext &Ctx)
Definition:LowLevelTypeUtils.cpp:57
llvm::IRMemLocation::Other
@ Other
Any other memory.
llvm::getSelectionDAGFallbackAnalysisUsage
void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition:Utils.cpp:1168
llvm::getIConstantVRegValWithLookThrough
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:433
llvm::bit_floor
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
Definition:bit.h:327
llvm::getLLTForType
LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
Definition:LowLevelTypeUtils.cpp:20
llvm::isTriviallyDead
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
std
Implement std::hash so that hash_code can be used in STL containers.
Definition:BitVector.h:858
MORE
#define MORE()
Definition:regcomp.c:252
llvm::EVT
Extended Value Type.
Definition:ValueTypes.h:35
llvm::LegalityQuery
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
Definition:LegalizerInfo.h:109
llvm::LegalizeActionStep
The result of a query.
Definition:LegalizerInfo.h:143
llvm::LegalizeActionStep::Action
LegalizeAction Action
The action to take or the final answer.
Definition:LegalizerInfo.h:145

Generated on Sun Jul 20 2025 08:35:48 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp