43#define DEBUG_TYPE "load-store-opt"
50STATISTIC(NumStoresMerged,
"Number of stores merged");
56class LoadStoreOptImpl {
68 class StoreMergeCandidate {
76 int64_t CurrentLowestOffset;
92 PotentialAliases.
clear();
93 CurrentLowestOffset = 0;
102 bool addStoreToCandidate(
GStore &
MI, StoreMergeCandidate &
C);
105 bool operationAliasesWithCandidate(
MachineInstr &
MI, StoreMergeCandidate &
C);
116 bool processMergeCandidate(StoreMergeCandidate &
C);
120 bool mergeTruncStore(
GStore &StoreMI,
127 void initializeStoreMergeTargetInfo(
unsigned AddrSpace = 0);
133 bool IsPreLegalizer =
false;
146 "Generic memory optimizations",
false,
false)
161 InstsToErase.
clear();
181 Info.setBase(BaseReg);
184 Info.setOffset(RHSCst->Value.getSExtValue());
188 Info.setIndex(PtrAddRHS);
198 if (!LdSt1 || !LdSt2)
223 IsAlias = !((int64_t)Size1.
getValue() <= PtrDiff);
230 IsAlias = !((PtrDiff + (int64_t)Size2.
getValue()) <= 0);
242 if (!Base0Def || !Base1Def)
246 if (Base0Def->getOpcode() != Base1Def->getOpcode())
249 if (Base0Def->getOpcode() == TargetOpcode::G_FRAME_INDEX) {
253 if (Base0Def != Base1Def &&
263 if (Base0Def->getOpcode() == TargetOpcode::G_GLOBAL_VALUE) {
264 auto GV0 = Base0Def->getOperand(1).getGlobal();
265 auto GV1 = Base1Def->getOperand(1).getGlobal();
280 struct MemUseCharacteristics {
289 auto getCharacteristics =
295 if (!
mi_match(LS->getPointerReg(), MRI,
297 BaseReg = LS->getPointerReg();
302 return {LS->isVolatile(), LS->isAtomic(), BaseReg,
314 MemUseCharacteristics MUC0 = getCharacteristics(&
MI),
315 MUC1 = getCharacteristics(&
Other);
318 if (MUC0.BasePtr.isValid() && MUC0.BasePtr == MUC1.BasePtr &&
319 MUC0.Offset == MUC1.Offset)
323 if (MUC0.IsVolatile && MUC1.IsVolatile)
328 if (MUC0.IsAtomic && MUC1.IsAtomic)
333 if (MUC0.MMO && MUC1.MMO) {
334 if ((MUC0.MMO->isInvariant() && MUC1.MMO->isStore()) ||
335 (MUC1.MMO->isInvariant() && MUC0.MMO->isStore()))
341 if ((MUC0.NumBytes.isScalable() && MUC0.Offset != 0) ||
342 (MUC1.NumBytes.isScalable() && MUC1.Offset != 0))
345 const bool BothNotScalable =
346 !MUC0.NumBytes.isScalable() && !MUC1.NumBytes.isScalable();
351 if (BothNotScalable &&
356 if (!MUC0.MMO || !MUC1.MMO)
360 int64_t SrcValOffset0 = MUC0.MMO->getOffset();
361 int64_t SrcValOffset1 = MUC1.MMO->getOffset();
364 if (
AA && MUC0.MMO->getValue() && MUC1.MMO->getValue() && Size0.
hasValue() &&
367 int64_t MinOffset = std::min(SrcValOffset0, SrcValOffset1);
378 MemoryLocation(MUC0.MMO->getValue(), Loc0, MUC0.MMO->getAAInfo()),
379 MemoryLocation(MUC1.MMO->getValue(), Loc1, MUC1.MMO->getAAInfo())))
390 return MI.hasUnmodeledSideEffects() ||
MI.hasOrderedMemoryRef();
393bool LoadStoreOptImpl::mergeStores(SmallVectorImpl<GStore *> &StoresToMerge) {
396 assert(StoresToMerge.
size() > 1 &&
"Expected multiple stores to merge");
397 LLT OrigTy = MRI->
getType(StoresToMerge[0]->getValueReg());
398 LLT PtrTy = MRI->
getType(StoresToMerge[0]->getPointerReg());
401 initializeStoreMergeTargetInfo(AS);
402 const auto &LegalSizes = LegalStoreSizes[AS];
405 for (
auto *StoreMI : StoresToMerge)
406 if (MRI->
getType(StoreMI->getValueReg()) != OrigTy)
409 bool AnyMerged =
false;
414 unsigned MergeSizeBits;
415 for (MergeSizeBits = MaxSizeBits; MergeSizeBits > 1; MergeSizeBits /= 2) {
419 if (LegalSizes.size() > MergeSizeBits && LegalSizes[MergeSizeBits] &&
427 unsigned NumStoresToMerge = MergeSizeBits / OrigTy.
getSizeInBits();
430 StoresToMerge.begin(), StoresToMerge.begin() + NumStoresToMerge);
431 AnyMerged |= doSingleStoreMerge(SingleMergeStores);
432 StoresToMerge.erase(StoresToMerge.begin(),
433 StoresToMerge.begin() + NumStoresToMerge);
434 }
while (StoresToMerge.size() > 1);
438bool LoadStoreOptImpl::isLegalOrBeforeLegalizer(
const LegalityQuery &Query,
444 return IsPreLegalizer || Action == LegalizeAction::Legal;
447bool LoadStoreOptImpl::doSingleStoreMerge(SmallVectorImpl<GStore *> &Stores) {
454 GStore *FirstStore = Stores[0];
455 const unsigned NumStores = Stores.
size();
472 for (
auto *
Store : Stores) {
476 ConstantVals.
clear();
485 if (ConstantVals.
empty()) {
494 if (!isLegalOrBeforeLegalizer({TargetOpcode::G_CONSTANT, {WideValueTy}}, *MF))
497 for (
unsigned Idx = 0; Idx < ConstantVals.
size(); ++Idx) {
500 WideConst.insertBits(ConstantVals[Idx], Idx * SmallTy.
getSizeInBits());
507 <<
" stores into merged store: " << *NewStore);
509 NumStoresMerged += Stores.size();
511 MachineOptimizationRemarkEmitter
MORE(*MF,
nullptr);
513 MachineOptimizationRemark
R(
DEBUG_TYPE,
"MergedStore",
516 R <<
"Merged " <<
NV(
"NumMerged", Stores.size()) <<
" stores of "
518 <<
" bytes into a single store of "
527bool LoadStoreOptImpl::processMergeCandidate(StoreMergeCandidate &
C) {
528 if (
C.Stores.size() < 2) {
533 LLVM_DEBUG(
dbgs() <<
"Checking store merge candidate with " <<
C.Stores.size()
534 <<
" stores, starting with " << *
C.Stores[0]);
548 auto DoesStoreAliasWithPotential = [&](
unsigned Idx, GStore &CheckStore) {
549 for (
auto AliasInfo :
reverse(
C.PotentialAliases)) {
550 MachineInstr *PotentialAliasOp = AliasInfo.first;
551 unsigned PreCheckedIdx = AliasInfo.second;
552 if (Idx < PreCheckedIdx) {
570 for (
int StoreIdx =
C.Stores.size() - 1; StoreIdx >= 0; --StoreIdx) {
571 auto *CheckStore =
C.Stores[StoreIdx];
572 if (DoesStoreAliasWithPotential(StoreIdx, *CheckStore))
578 <<
" stores remaining after alias checks. Merging...\n");
582 if (StoresToMerge.
size() < 2)
584 return mergeStores(StoresToMerge);
587bool LoadStoreOptImpl::operationAliasesWithCandidate(MachineInstr &
MI,
588 StoreMergeCandidate &
C) {
589 if (
C.Stores.empty())
592 return instMayAlias(MI, *OtherMI, *MRI, AA);
596void LoadStoreOptImpl::StoreMergeCandidate::addPotentialAlias(
598 PotentialAliases.emplace_back(std::make_pair(&
MI, Stores.size() - 1));
601bool LoadStoreOptImpl::addStoreToCandidate(GStore &StoreMI,
602 StoreMergeCandidate &
C) {
625 if (
C.Stores.empty()) {
626 C.BasePtr = StoreBase;
627 if (!BIO.hasValidOffset()) {
628 C.CurrentLowestOffset = 0;
630 C.CurrentLowestOffset = BIO.getOffset();
635 if (BIO.hasValidOffset() &&
638 C.Stores.emplace_back(&StoreMI);
639 LLVM_DEBUG(
dbgs() <<
"Starting a new merge candidate group with: "
655 if (
C.BasePtr != StoreBase)
659 if (!BIO.hasValidOffset())
661 if ((
C.CurrentLowestOffset -
662 static_cast<int64_t
>(ValueTy.
getSizeInBytes())) != BIO.getOffset())
666 C.Stores.emplace_back(&StoreMI);
672bool LoadStoreOptImpl::mergeBlockStores(MachineBasicBlock &
MBB) {
675 StoreMergeCandidate Candidate;
683 if (!addStoreToCandidate(*StoreMI, Candidate)) {
686 if (operationAliasesWithCandidate(*StoreMI, Candidate)) {
687 Changed |= processMergeCandidate(Candidate);
690 Candidate.addPotentialAlias(*StoreMI);
696 if (Candidate.Stores.empty())
701 Changed |= processMergeCandidate(Candidate);
702 Candidate.Stores.clear();
706 if (!
MI.mayLoadOrStore())
709 if (operationAliasesWithCandidate(
MI, Candidate)) {
712 Changed |= processMergeCandidate(Candidate);
718 Candidate.addPotentialAlias(
MI);
722 Changed |= processMergeCandidate(Candidate);
725 for (
auto *
MI : InstsToErase)
726 MI->eraseFromParent();
727 InstsToErase.clear();
737static std::optional<int64_t>
755 if (!SrcVal.
isValid() || TruncVal == SrcVal) {
763 unsigned NarrowBits =
Store.getMMO().getMemoryType().getScalarSizeInBits();
764 if (ShiftAmt % NarrowBits != 0)
766 const unsigned Offset = ShiftAmt / NarrowBits;
768 if (SrcVal.
isValid() && FoundSrcVal != SrcVal)
772 SrcVal = FoundSrcVal;
800bool LoadStoreOptImpl::mergeTruncStore(
801 GStore &StoreMI, SmallPtrSetImpl<GStore *> &DeletedStores) {
828 auto &LastStore = StoreMI;
833 if (!
mi_match(LastStore.getPointerReg(), *MRI,
835 BaseReg = LastStore.getPointerReg();
839 GStore *LowestIdxStore = &LastStore;
840 int64_t LowestIdxOffset = LastOffset;
848 LLT WideStoreTy = MRI->
getType(WideSrcVal);
852 const unsigned NumStoresRequired =
856 OffsetMap[*LowestShiftAmt] = LastOffset;
859 const int MaxInstsToCheck = 10;
860 int NumInstsChecked = 0;
861 for (
auto II = ++LastStore.getReverseIterator();
862 II != LastStore.getParent()->rend() && NumInstsChecked < MaxInstsToCheck;
869 }
else if (
II->isLoadFoldBarrier() ||
II->mayLoad()) {
883 if (BaseReg != NewBaseReg)
887 if (!ShiftByteOffset)
889 if (MemOffset < LowestIdxOffset) {
890 LowestIdxOffset = MemOffset;
891 LowestIdxStore = NewStore;
896 if (*ShiftByteOffset < 0 || *ShiftByteOffset >= NumStoresRequired ||
897 OffsetMap[*ShiftByteOffset] !=
INT64_MAX)
899 OffsetMap[*ShiftByteOffset] = MemOffset;
904 if (FoundStores.
size() == NumStoresRequired)
908 if (FoundStores.
size() != NumStoresRequired) {
909 if (FoundStores.
size() == 1)
918 unsigned NumStoresFound = FoundStores.
size();
920 const auto &
DL = LastStore.getMF()->getDataLayout();
921 auto &
C = LastStore.getMF()->getFunction().getContext();
926 if (!Allowed || !
Fast)
932 auto checkOffsets = [&](
bool MatchLittleEndian) {
933 if (MatchLittleEndian) {
934 for (
unsigned i = 0; i != NumStoresFound; ++i)
935 if (OffsetMap[i] != i * (NarrowBits / 8) + LowestIdxOffset)
938 for (
unsigned i = 0, j = NumStoresFound - 1; i != NumStoresFound;
940 if (OffsetMap[j] != i * (NarrowBits / 8) + LowestIdxOffset)
947 bool NeedBswap =
false;
948 bool NeedRotate =
false;
949 if (!checkOffsets(
DL.isLittleEndian())) {
951 if (NarrowBits == 8 && checkOffsets(
DL.isBigEndian()))
953 else if (NumStoresFound == 2 && checkOffsets(
DL.isBigEndian()))
960 !isLegalOrBeforeLegalizer({TargetOpcode::G_BSWAP, {WideStoreTy}}, *MF))
963 !isLegalOrBeforeLegalizer(
964 {TargetOpcode::G_ROTR, {WideStoreTy, WideStoreTy}}, *MF))
969 if (WideStoreTy != MRI->
getType(WideSrcVal))
974 }
else if (NeedRotate) {
976 "Unexpected type for rotate");
988 for (
auto *ST : FoundStores) {
989 ST->eraseFromParent();
995bool LoadStoreOptImpl::mergeTruncStoresBlock(MachineBasicBlock &BB) {
998 SmallPtrSet<GStore *, 8> DeletedStores;
1004 for (
auto *StoreMI : Stores) {
1005 if (DeletedStores.
count(StoreMI))
1007 if (mergeTruncStore(*StoreMI, DeletedStores))
1015 for (
auto &BB : MF){
1016 Changed |= mergeBlockStores(BB);
1017 Changed |= mergeTruncStoresBlock(BB);
1022 for (
auto &BB : MF) {
1025 I.eraseFromParent();
1033void LoadStoreOptImpl::initializeStoreMergeTargetInfo(
unsigned AddrSpace) {
1038 if (LegalStoreSizes.count(AddrSpace)) {
1039 assert(LegalStoreSizes[AddrSpace].
any());
1045 const auto &LI = *MF->getSubtarget().getLegalizerInfo();
1046 const auto &
DL = MF->getFunction().getDataLayout();
1047 Type *IRPtrTy = PointerType::get(MF->getFunction().getContext(), AddrSpace);
1055 AtomicOrdering::NotAtomic}});
1057 LegalityQuery Q(TargetOpcode::G_STORE, StoreTys, MemDescrs);
1058 LegalizeActionStep ActionStep = LI.
getAction(Q);
1060 LegalSizes.set(
Size);
1062 assert(LegalSizes.any() &&
"Expected some store sizes to be legal!");
1063 LegalStoreSizes[AddrSpace] = std::move(LegalSizes);
1066bool LoadStoreOptImpl::runOnMachineFunction(
1077 Changed |= mergeFunctionStores(MF);
1079 LegalStoreSizes.clear();
1084 LoadStoreOptImpl Impl;
1085 return Impl.runOnMachineFunction(MF, [&]() {
1093 LoadStoreOptImpl Impl;
1094 Impl.runOnMachineFunction(MF, [&]() {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Atomic ordering constants.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Interface for Targets to specify which operations they can successfully select and how the others sho...
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.
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.
Contains matchers for matching SSA Machine Instructions.
Promote Memory to Register
This file provides utility analysis objects describing memory locations.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
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)
This file describes how to lower LLVM code to machine code.
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
static LLVM_ABI DebugLoc getMergedLocation(DebugLoc LocA, DebugLoc LocB)
When two instructions are combined into a single instruction we also need to combine the original loc...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Register getValueReg() const
Get the stored value register.
Helper struct to store a base, index and offset that forms an address.
int64_t getOffset() const
bool hasValidOffset() const
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.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr unsigned getAddressSpace() const
static LLT integer(unsigned SizeInBits)
constexpr TypeSize getSizeInBytes() const
Returns the total size of the type in bytes, i.e.
LegalizeActionStep getAction(const LegalityQuery &Query) const
Determine what action should be taken to legalize the described instruction.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
static LocationSize precise(uint64_t Value)
static constexpr LocationSize beforeOrAfterPointer()
Any location before or after the base pointer (but still within the underlying object).
TypeSize getValue() const
An RAII based helper class to modify MachineFunctionProperties when running pass.
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(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
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.
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.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Helper class to build MachineInstr.
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.
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.
const MachineBasicBlock * getParent() const
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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
LLVM_ABI Align getAlign() const
Return the minimum known alignment in bytes of the actual memory reference.
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.
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
virtual const LegalizerInfo * getLegalizerInfo() const
virtual const TargetLowering * getTargetLowering() const
constexpr ScalarTy getFixedValue() const
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
An efficient, type-erasing, non-owning reference to a callable.
Pass manager infrastructure for declaring and invalidating analyses.
Abstract Attribute helper functions.
constexpr bool any(E Val)
LLVM_ABI 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.
LLVM_ABI BaseIndexOffset getPointerInfo(Register Ptr, MachineRegisterInfo &MRI)
Returns a BaseIndexOffset which describes the pointer in Ptr.
LLVM_ABI 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...
@ Unsupported
This operation is completely unsupported on the target.
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)
initializer< Ty > init(const Ty &Val)
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
DiagnosticInfoOptimizationBase::Argument NV
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Store
The extracted value is stored (ExtractElement only).
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI EVT getApproximateEVTForLLT(LLT Ty, LLVMContext &Ctx)
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
@ Fast
Assign the register banks as fast as possible (default).
LLVM_ABI 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...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
T bit_floor(T Value)
Returns the largest integral power of two no greater than Value if Value is nonzero.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI LLT getLLTForType(Type &Ty, const DataLayout &DL)
Construct a low-level type based on an LLVM type.
LLVM_ABI 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...
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
LegalizeAction Action
The action to take or the final answer.