45#define GET_GICOMBINER_DEPS
46#include "AArch64GenPostLegalizeGICombiner.inc"
47#undef GET_GICOMBINER_DEPS
49#define DEBUG_TYPE "aarch64-postlegalizer-combiner"
54#define GET_GICOMBINER_TYPES
55#include "AArch64GenPostLegalizeGICombiner.inc"
56#undef GET_GICOMBINER_TYPES
68bool matchExtractVecEltPairwiseAdd(
70 std::tuple<unsigned, LLT, Register> &MatchInfo) {
76 if (!Cst || Cst->Value != 0)
81 auto *FAddMI =
getOpcodeDef(TargetOpcode::G_FADD, Src1, MRI);
87 if (DstSize != 16 && DstSize != 32 && DstSize != 64)
90 Register Src1Op1 = FAddMI->getOperand(1).getReg();
91 Register Src1Op2 = FAddMI->getOperand(2).getReg();
93 getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op2, MRI);
96 Shuffle =
getOpcodeDef(TargetOpcode::G_SHUFFLE_VECTOR, Src1Op1, MRI);
103 std::get<0>(MatchInfo) = TargetOpcode::G_FADD;
104 std::get<1>(MatchInfo) = DstTy;
105 std::get<2>(MatchInfo) =
Other->getOperand(0).getReg();
111void applyExtractVecEltPairwiseAdd(
113 std::tuple<unsigned, LLT, Register> &MatchInfo) {
114 unsigned Opc = std::get<0>(MatchInfo);
115 assert(
Opc == TargetOpcode::G_FADD &&
"Unexpected opcode!");
117 LLT Ty = std::get<1>(MatchInfo);
118 Register Src = std::get<2>(MatchInfo);
120 B.setInstrAndDebugLoc(
MI);
121 auto Elt0 =
B.buildExtractVectorElement(Ty, Src,
B.buildConstant(s64, 0));
122 auto Elt1 =
B.buildExtractVectorElement(Ty, Src,
B.buildConstant(s64, 1));
123 B.buildInstr(
Opc, {
MI.getOperand(0).getReg()}, {Elt0, Elt1});
124 MI.eraseFromParent();
138bool matchAArch64MulConstCombine(
141 assert(
MI.getOpcode() == TargetOpcode::G_MUL);
152 APInt ConstValue = Const->Value.sext(Ty.getSizeInBits());
166 unsigned TrailingZeroes = ConstValue.
countr_zero();
167 if (TrailingZeroes) {
177 unsigned UseOpc =
UseMI.getOpcode();
178 if (UseOpc == TargetOpcode::G_ADD || UseOpc == TargetOpcode::G_PTR_ADD ||
179 UseOpc == TargetOpcode::G_SUB)
185 APInt ShiftedConstValue = ConstValue.
ashr(TrailingZeroes);
187 unsigned ShiftAmt, AddSubOpc;
189 bool ShiftValUseIsLHS =
true;
191 bool NegateResult =
false;
197 APInt SCVMinus1 = ShiftedConstValue - 1;
198 APInt CVPlus1 = ConstValue + 1;
201 AddSubOpc = TargetOpcode::G_ADD;
204 AddSubOpc = TargetOpcode::G_SUB;
210 APInt CVNegPlus1 = -ConstValue + 1;
211 APInt CVNegMinus1 = -ConstValue - 1;
214 AddSubOpc = TargetOpcode::G_SUB;
215 ShiftValUseIsLHS =
false;
218 AddSubOpc = TargetOpcode::G_ADD;
224 if (NegateResult && TrailingZeroes)
229 auto ShiftedVal =
B.buildShl(Ty,
LHS, Shift);
231 Register AddSubLHS = ShiftValUseIsLHS ? ShiftedVal.getReg(0) :
LHS;
232 Register AddSubRHS = ShiftValUseIsLHS ?
LHS : ShiftedVal.getReg(0);
233 auto Res =
B.buildInstr(AddSubOpc, {Ty}, {AddSubLHS, AddSubRHS});
234 assert(!(NegateResult && TrailingZeroes) &&
235 "NegateResult and TrailingZeroes cannot both be true for now.");
238 B.buildSub(DstReg,
B.buildConstant(Ty, 0), Res);
242 if (TrailingZeroes) {
243 B.buildShl(DstReg, Res,
247 B.buildCopy(DstReg, Res.getReg(0));
252void applyAArch64MulConstCombine(
255 B.setInstrAndDebugLoc(
MI);
256 ApplyFn(
B,
MI.getOperand(0).getReg());
257 MI.eraseFromParent();
276 MI.setDesc(
B.getTII().get(TargetOpcode::G_ZEXT));
291 assert(
MI.getOpcode() == TargetOpcode::G_ANYEXT);
304 MI.setDesc(
B.getTII().get(TargetOpcode::G_ZEXT));
312 if (!
Store.isSimple())
324 return MaybeCst && MaybeCst->isZero();
330 B.setInstrAndDebugLoc(
MI);
333 "Expected a vector store value");
336 auto Zero =
B.buildConstant(NewTy, 0);
338 B.buildPtrAdd(MRI.
getType(PtrReg), PtrReg,
B.buildConstant(NewTy, 8));
339 auto &MF = *
MI.getMF();
340 auto *LowMMO = MF.getMachineMemOperand(&
Store.getMMO(), 0, NewTy);
341 auto *HighMMO = MF.getMachineMemOperand(&
Store.getMMO(), 8, NewTy);
342 B.buildStore(Zero, PtrReg, *LowMMO);
343 B.buildStore(Zero, HighPtr, *HighMMO);
344 Store.eraseFromParent();
348 std::tuple<Register, Register, Register> &MatchInfo) {
349 const LLT DstTy = MRI.
getType(
MI.getOperand(0).getReg());
369 if (!ValAndVReg1 || !ValAndVReg2 ||
370 ValAndVReg1->Value != ~ValAndVReg2->Value)
374 MatchInfo = {AO1, AO2, BVO1};
380 std::tuple<Register, Register, Register> &MatchInfo) {
381 B.setInstrAndDebugLoc(
MI);
383 AArch64::G_BSP, {
MI.getOperand(0).getReg()},
384 {std::get<2>(MatchInfo), std::get<0>(MatchInfo), std::get<1>(MatchInfo)});
385 MI.eraseFromParent();
411 if (
UseMI.getOpcode() == TargetOpcode::G_ANYEXT &&
435 if (AndMI->getOpcode() != TargetOpcode::G_AND)
438 if (LShrMI->getOpcode() != TargetOpcode::G_LSHR)
446 if (!
V1.has_value() || !V2.has_value() || !
V3.has_value())
449 if (!
V1.value().isMask(HalfSize) || V2.value() != (1ULL | 1ULL << HalfSize) ||
450 V3 != (HalfSize - 1))
453 SrcReg = LShrMI->getOperand(1).getReg();
465 Register ZeroVec =
B.buildConstant(HalfTy, 0).getReg(0);
467 B.buildInstr(TargetOpcode::G_BITCAST, {HalfTy}, {SrcReg}).
getReg(0);
472 B.buildInstr(TargetOpcode::G_BITCAST, {DstReg}, {CMLTReg}).
getReg(0);
473 MI.eraseFromParent();
479 std::tuple<bool, Register, Register> &MatchInfo) {
484 unsigned I1Opc = I1->getOpcode();
491 auto IsAtLeastDoubleExtend = [&](
Register R) {
493 return EltSize >= Ty.getScalarSizeInBits() * 2;
498 I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_ANYEXT;
500 I2Opc == TargetOpcode::G_ZEXT || I2Opc == TargetOpcode::G_ANYEXT;
501 if (IsZExt1 && IsZExt2 && IsAtLeastDoubleExtend(I1->getOperand(1).getReg()) &&
504 get<1>(MatchInfo) = I1->getOperand(1).getReg();
510 I1Opc == TargetOpcode::G_SEXT || I1Opc == TargetOpcode::G_ANYEXT;
512 I2Opc == TargetOpcode::G_SEXT || I2Opc == TargetOpcode::G_ANYEXT;
513 if (IsSExt1 && IsSExt2 && IsAtLeastDoubleExtend(I1->getOperand(1).getReg()) &&
515 get<0>(MatchInfo) =
false;
516 get<1>(MatchInfo) = I1->getOperand(1).getReg();
523 if (KB && (IsZExt1 || IsZExt2) &&
524 IsAtLeastDoubleExtend(IsZExt1 ? I1->getOperand(1).getReg()
527 IsZExt1 ?
MI.getOperand(2).getReg() :
MI.getOperand(1).getReg();
530 get<1>(MatchInfo) = IsZExt1 ? I1->getOperand(1).getReg() : ZExtOp;
538 get<1>(MatchInfo) =
MI.getOperand(1).getReg();
539 get<2>(MatchInfo) =
MI.getOperand(2).getReg();
543 if (KB && (IsSExt1 || IsSExt2) &&
544 IsAtLeastDoubleExtend(IsSExt1 ? I1->getOperand(1).getReg()
547 IsSExt1 ?
MI.getOperand(2).getReg() :
MI.getOperand(1).getReg();
549 get<0>(MatchInfo) =
false;
550 get<1>(MatchInfo) = IsSExt1 ? I1->getOperand(1).getReg() : SExtOp;
557 get<0>(MatchInfo) =
false;
558 get<1>(MatchInfo) =
MI.getOperand(1).getReg();
559 get<2>(MatchInfo) =
MI.getOperand(2).getReg();
568 std::tuple<bool, Register, Register> &MatchInfo) {
569 assert(
MI.getOpcode() == TargetOpcode::G_MUL &&
570 "Expected a G_MUL instruction");
574 bool IsZExt =
get<0>(MatchInfo);
580 unsigned ExtOpc = IsZExt ? TargetOpcode::G_ZEXT : TargetOpcode::G_SEXT;
583 Src1Reg =
B.buildExtOrTrunc(ExtOpc, {HalfDstTy}, {Src1Reg}).
getReg(0);
585 Src2Reg =
B.buildExtOrTrunc(ExtOpc, {HalfDstTy}, {Src2Reg}).
getReg(0);
587 B.buildInstr(IsZExt ? AArch64::G_UMULL : AArch64::G_SMULL,
588 {
MI.getOperand(0).getReg()}, {Src1Reg, Src2Reg});
589 MI.eraseFromParent();
599 if (
M1->getOpcode() != AArch64::G_MUL &&
600 M1->getOpcode() != AArch64::G_SMULL &&
601 M1->getOpcode() != AArch64::G_UMULL)
619 B.buildInstr(AArch64::G_SUB, {Tmp}, {Src, Mul1});
620 MI.getOperand(1).setReg(Tmp);
621 MI.getOperand(2).setReg(Mul2);
622 Sub.eraseFromParent();
626class AArch64PostLegalizerCombinerImpl :
public Combiner {
629 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig;
633 AArch64PostLegalizerCombinerImpl(
636 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
640 static const char *
getName() {
return "AArch64PostLegalizerCombiner"; }
645#define GET_GICOMBINER_CLASS_MEMBERS
646#include "AArch64GenPostLegalizeGICombiner.inc"
647#undef GET_GICOMBINER_CLASS_MEMBERS
650#define GET_GICOMBINER_IMPL
651#include "AArch64GenPostLegalizeGICombiner.inc"
652#undef GET_GICOMBINER_IMPL
654AArch64PostLegalizerCombinerImpl::AArch64PostLegalizerCombinerImpl(
657 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
660 :
Combiner(MF, CInfo, &VT, CSEInfo),
661 Helper(Observer,
B,
false, &VT, MDT, LI),
662 RuleConfig(RuleConfig), STI(STI),
664#include
"AArch64GenPostLegalizeGICombiner.inc"
670 GStore *St =
nullptr;
673 GPtrAdd *Ptr =
nullptr;
681 if (Stores.
size() <= 2)
685 int64_t BaseOffset = Stores[0].Offset;
686 unsigned NumPairsExpected = Stores.
size() / 2;
687 unsigned TotalInstsExpected = NumPairsExpected + (Stores.
size() % 2);
691 if (!TLI.isLegalAddImmediate(BaseOffset))
692 TotalInstsExpected++;
693 int SavingsExpected = Stores.
size() - TotalInstsExpected;
694 if (SavingsExpected <= 0)
701 Register NewBase = Stores[0].Ptr->getReg(0);
702 for (
auto &SInfo : Stores) {
711 SInfo.St->getOperand(1).setReg(NewPtr.getReg(0));
716 <<
" stores into a base pointer and offsets.\n");
721 EnableConsecutiveMemOpOpt(
"aarch64-postlegalizer-consecutive-memops",
723 cl::desc(
"Enable consecutive memop optimization "
724 "in AArch64PostLegalizerCombiner"));
752 if (!EnableConsecutiveMemOpOpt)
768 if (
Last.Ptr->getBaseReg() !=
New.Ptr->getBaseReg() ||
769 (
Last.Offset +
static_cast<int64_t
>(
Last.StoredType.getSizeInBytes()) !=
771 Last.StoredType !=
New.StoredType)
777 return New.St->getValueReg() == LoadVal;
784 int64_t MaxLegalOffset;
785 switch (
New.StoredType.getSizeInBits()) {
787 MaxLegalOffset = 252;
790 MaxLegalOffset = 504;
793 MaxLegalOffset = 1008;
798 if (
New.Offset < MaxLegalOffset)
802 return New.Offset - Stores[0].Offset <= MaxLegalOffset;
805 auto resetState = [&]() {
807 LoadValsSinceLastStore.
clear();
810 for (
auto &
MBB : MF) {
814 for (
auto &
MI :
MBB) {
823 LLT StoredValTy = MRI.
getType(St->getValueReg());
825 if (ValSize < 32 || St->getMMO().getSizeInBits() != ValSize)
828 Register PtrReg = St->getPointerReg();
835 if (Stores.
empty()) {
842 if (storeIsValid(
Last, New)) {
844 LoadValsSinceLastStore.
clear();
848 Changed |= tryOptimizeConsecStores(Stores, MIB);
854 LoadValsSinceLastStore.
push_back(Ld->getDstReg());
857 Changed |= tryOptimizeConsecStores(Stores, MIB);
866 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
867 bool EnableOpt,
bool IsOptNone) {
876 LI, EnableOpt,
F.hasOptSize(),
879 CInfo.MaxIterations = 1;
882 CInfo.EnableFullDCE =
false;
883 AArch64PostLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
885 bool Changed = Impl.combineMachineInstrs();
889 Changed |= optimizeConsecutiveMemOpAddressing(MF, MIB);
897 AArch64PostLegalizerCombinerLegacy(
bool IsOptNone =
false);
899 StringRef getPassName()
const override {
900 return "AArch64PostLegalizerCombiner";
904 void getAnalysisUsage(AnalysisUsage &AU)
const override;
906 MachineFunctionProperties getRequiredProperties()
const override {
907 return MachineFunctionProperties().set(
908 MachineFunctionProperties::Property::Legalized);
913 AArch64PostLegalizerCombinerImplRuleConfig RuleConfig;
917void AArch64PostLegalizerCombinerLegacy::getAnalysisUsage(
921 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
931AArch64PostLegalizerCombinerLegacy::AArch64PostLegalizerCombinerLegacy(
933 : MachineFunctionPass(
ID), IsOptNone(IsOptNone) {
934 if (!RuleConfig.parseCommandLineOption())
938bool AArch64PostLegalizerCombinerLegacy::runOnMachineFunction(
943 GISelValueTracking *VT =
944 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
945 MachineDominatorTree *MDT =
947 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
948 GISelCSEAnalysisWrapper &
Wrapper =
949 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
956 return runCombiner(MF, CSEInfo, VT, MDT, RuleConfig, EnableOpt, IsOptNone);
959char AArch64PostLegalizerCombinerLegacy::ID = 0;
961 "Combine AArch64 MachineInstrs after legalization",
false,
965 "Combine AArch64 MachineInstrs after legalization",
false,
971 std::make_unique<AArch64PostLegalizerCombinerImplRuleConfig>()),
973 if (!RuleConfig->parseCommandLineOption())
988 const bool IsOptNone = TM->isGlobalISelOptNone();
989 bool EnableOpt = !IsOptNone;
996 if (!runCombiner(MF, CSEInfo, VT, MDT, *RuleConfig, EnableOpt, IsOptNone))
1008 return new AArch64PostLegalizerCombinerLegacy(IsOptNone);
MachineInstrBuilder & UseMI
static bool isZeroExtended(SDValue N, SelectionDAG &DAG)
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
This contains common combine transformations that may be used in a combine pass,or by the target else...
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
This contains common code to allow clients to notify changes to machine instr.
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static StringRef getName(Value *V)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
AArch64PostLegalizerCombinerPass(const AArch64TargetMachine *TM)
~AArch64PostLegalizerCombinerPass()
Class for arbitrary precision integers.
unsigned countr_zero() const
Count the number of trailing zero bits.
unsigned logBase2() const
APInt ashr(unsigned ShiftAmt) const
Arithmetic right-shift function.
bool isNonNegative() const
Determine if this APInt Value is non-negative (>= 0)
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
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()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val) override
Build and insert Res = G_CONSTANT Val.
@ ICMP_SLT
signed less than
FunctionPass class - This class is used to implement most global optimizations.
Abstract class that contains various methods for clients to notify about changes.
virtual void changingInstr(MachineInstr &MI)=0
This instruction is about to be mutated in some way.
virtual void changedInstr(MachineInstr &MI)=0
This instruction was mutated in some way.
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
bool maskedValueIsZero(Register Val, const APInt &Mask)
unsigned computeNumSignBits(Register R, const APInt &DemandedElts, unsigned Depth=0)
LLT changeElementCount(ElementCount EC) const
Return a vector or scalar with the same element type and the new element count.
constexpr bool isScalableVector() const
Returns true if the LLT is a scalable vector.
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 uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr ElementCount getElementCount() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
static LLT integer(unsigned SizeInBits)
LLT changeElementSize(unsigned NewEltSize) const
If this type is a vector, return a vector with the same number of elements but the new element size.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
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.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Helper class to build MachineInstr.
GISelChangeObserver * getObserver()
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_PTR_ADD Op0, Op1.
MachineFunction & getMF()
Getter for the function we currently build.
void setInstrAndDebugLoc(MachineInstr &MI)
Set the insertion point to before MI, and set the debug loc to MI's loc.
void setCSEInfo(GISelCSEInfo *Info)
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
unsigned getNumOperands() const
Retuns the total number of operands.
const MachineOperand & getOperand(unsigned i) const
ArrayRef< int > getShuffleMask() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
use_instr_iterator use_instr_begin(Register RegNo) const
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool hasOneUse(Register RegNo) const
hasOneUse - Return true if there is exactly one instruction using the specified register.
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Wrapper class representing virtual and physical registers.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
virtual const TargetLowering * getTargetLowering() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
operand_type_match m_Pred()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
OneNonDBGUse_match< SubPat > m_OneNonDBGUse(const SubPat &SP)
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_ICMP > m_GICmp(const Pred &P, 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_AND, true > m_GAnd(const LHS &L, const RHS &R)
SrcImmOp_match< SrcTy, AnyImmMatch, TargetOpcode::G_SEXT_INREG > m_GSExtInReg(const SrcTy &Src)
Matches a G_SEXT_INREG, binding its source and immediate width.
CompareOp_match< Pred, LHS, RHS, TargetOpcode::G_FCMP > m_GFCmp(const Pred &P, const LHS &L, const RHS &R)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI std::optional< APInt > isConstantOrConstantSplatVector(Register Def, const MachineRegisterInfo &MRI)
Determines if Def defines a constant integer or a splat vector of constant integers.
LLVM_ABI MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
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).
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
FunctionPass * createAArch64PostLegalizerCombinerLegacy(bool IsOptNone)
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
unsigned M1(unsigned Val)
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
@ Sub
Subtraction of integers.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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...
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Implement std::hash so that hash_code can be used in STL containers.
@ SinglePass
Enables Observer-based DCE and additional heuristics that retry combining defined and used instructio...