44#include "llvm/IR/IntrinsicsAArch64.h"
47#define GET_GICOMBINER_DEPS
48#include "AArch64GenPostLegalizeGICombiner.inc"
49#undef GET_GICOMBINER_DEPS
51#define DEBUG_TYPE "aarch64-postlegalizer-combiner"
56#define GET_GICOMBINER_TYPES
57#include "AArch64GenPostLegalizeGICombiner.inc"
58#undef GET_GICOMBINER_TYPES
70bool matchExtractVecEltPairwiseAdd(
72 std::tuple<unsigned, LLT, Register> &MatchInfo) {
75 LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
78 if (!Cst || Cst->Value != 0)
89 if (DstSize != 16 && DstSize != 32 && DstSize != 64)
92 Register Src1Op1 = FAddMI->getOperand(1).getReg();
93 Register Src1Op2 = FAddMI->getOperand(2).getReg();
105 std::get<0>(MatchInfo) = TargetOpcode::G_FADD;
106 std::get<1>(MatchInfo) = DstTy;
107 std::get<2>(MatchInfo) =
Other->getOperand(0).getReg();
113void applyExtractVecEltPairwiseAdd(
115 std::tuple<unsigned, LLT, Register> &MatchInfo) {
116 unsigned Opc = std::get<0>(MatchInfo);
117 assert(
Opc == TargetOpcode::G_FADD &&
"Unexpected opcode!");
119 LLT Ty = std::get<1>(MatchInfo);
120 Register Src = std::get<2>(MatchInfo);
122 B.setInstrAndDebugLoc(
MI);
123 auto Elt0 =
B.buildExtractVectorElement(Ty, Src,
B.buildConstant(s64, 0));
124 auto Elt1 =
B.buildExtractVectorElement(Ty, Src,
B.buildConstant(s64, 1));
125 B.buildInstr(
Opc, {
MI.getOperand(0).getReg()}, {Elt0, Elt1});
126 MI.eraseFromParent();
140bool matchAArch64MulConstCombine(
143 assert(
MI.getOpcode() == TargetOpcode::G_MUL);
154 APInt ConstValue = Const->Value.sext(Ty.getSizeInBits());
168 unsigned TrailingZeroes = ConstValue.
countr_zero();
169 if (TrailingZeroes) {
172 if (
MRI.hasOneNonDBGUse(
LHS) &&
177 if (
MRI.hasOneNonDBGUse(Dst)) {
179 unsigned UseOpc =
UseMI.getOpcode();
180 if (UseOpc == TargetOpcode::G_ADD || UseOpc == TargetOpcode::G_PTR_ADD ||
181 UseOpc == TargetOpcode::G_SUB)
187 APInt ShiftedConstValue = ConstValue.
ashr(TrailingZeroes);
189 unsigned ShiftAmt, AddSubOpc;
191 bool ShiftValUseIsLHS =
true;
193 bool NegateResult =
false;
199 APInt SCVMinus1 = ShiftedConstValue - 1;
200 APInt CVPlus1 = ConstValue + 1;
203 AddSubOpc = TargetOpcode::G_ADD;
206 AddSubOpc = TargetOpcode::G_SUB;
212 APInt CVNegPlus1 = -ConstValue + 1;
213 APInt CVNegMinus1 = -ConstValue - 1;
216 AddSubOpc = TargetOpcode::G_SUB;
217 ShiftValUseIsLHS =
false;
220 AddSubOpc = TargetOpcode::G_ADD;
226 if (NegateResult && TrailingZeroes)
231 auto ShiftedVal =
B.buildShl(Ty,
LHS, Shift);
233 Register AddSubLHS = ShiftValUseIsLHS ? ShiftedVal.getReg(0) :
LHS;
234 Register AddSubRHS = ShiftValUseIsLHS ?
LHS : ShiftedVal.getReg(0);
235 auto Res =
B.buildInstr(AddSubOpc, {Ty}, {AddSubLHS, AddSubRHS});
236 assert(!(NegateResult && TrailingZeroes) &&
237 "NegateResult and TrailingZeroes cannot both be true for now.");
240 B.buildSub(DstReg,
B.buildConstant(Ty, 0), Res);
244 if (TrailingZeroes) {
245 B.buildShl(DstReg, Res,
249 B.buildCopy(DstReg, Res.getReg(0));
254void applyAArch64MulConstCombine(
257 B.setInstrAndDebugLoc(
MI);
258 ApplyFn(
B,
MI.getOperand(0).getReg());
259 MI.eraseFromParent();
266 if (!
Store.isSimple())
275 if (!
MRI.hasOneNonDBGUse(
Store.getValueReg()))
278 return MaybeCst && MaybeCst->isZero();
284 B.setInstrAndDebugLoc(
MI);
287 "Expected a vector store value");
290 auto Zero =
B.buildConstant(NewTy, 0);
292 B.buildPtrAdd(
MRI.getType(PtrReg), PtrReg,
B.buildConstant(NewTy, 8));
293 auto &MF = *
MI.getMF();
294 auto *LowMMO = MF.getMachineMemOperand(&
Store.getMMO(), 0, NewTy);
295 auto *HighMMO = MF.getMachineMemOperand(&
Store.getMMO(), 8, NewTy);
296 B.buildStore(
Zero, PtrReg, *LowMMO);
297 B.buildStore(
Zero, HighPtr, *HighMMO);
298 Store.eraseFromParent();
302 std::tuple<Register, Register, Register> &MatchInfo) {
303 const LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
323 if (!ValAndVReg1 || !ValAndVReg2 ||
324 ValAndVReg1->Value != ~ValAndVReg2->Value)
328 MatchInfo = {AO1, AO2, BVO1};
334 std::tuple<Register, Register, Register> &MatchInfo) {
335 B.setInstrAndDebugLoc(
MI);
337 AArch64::G_BSP, {
MI.getOperand(0).getReg()},
338 {std::get<2>(MatchInfo), std::get<0>(MatchInfo), std::get<1>(MatchInfo)});
339 MI.eraseFromParent();
348 if (!
MRI.hasOneUse(
Or))
351 LLT DstTy =
MRI.getType(Dst);
363 if (
MRI.hasOneNonDBGUse(Dst)) {
365 if (
UseMI.getOpcode() == TargetOpcode::G_ANYEXT &&
366 MRI.getType(
UseMI.getOperand(0).getReg()) == SrcTy)
370 unsigned EltSize = SrcTy.getScalarSizeInBits();
381 LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
389 if (AndMI->getOpcode() != TargetOpcode::G_AND)
392 if (LShrMI->getOpcode() != TargetOpcode::G_LSHR)
400 if (!
V1.has_value() || !V2.has_value() || !
V3.has_value())
403 if (!
V1.value().isMask(HalfSize) || V2.value() != (1ULL | 1ULL << HalfSize) ||
404 V3 != (HalfSize - 1))
407 SrcReg = LShrMI->getOperand(1).getReg();
415 LLT DstTy =
MRI.getType(DstReg);
419 Register ZeroVec =
B.buildConstant(HalfTy, 0).getReg(0);
421 B.buildInstr(TargetOpcode::G_BITCAST, {HalfTy}, {SrcReg}).
getReg(0);
426 B.buildInstr(TargetOpcode::G_BITCAST, {DstReg}, {CMLTReg}).
getReg(0);
427 MI.eraseFromParent();
433 std::tuple<bool, Register, Register> &MatchInfo) {
435 LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
438 unsigned I1Opc = I1->getOpcode();
445 auto IsAtLeastDoubleExtend = [&](
Register R) {
447 return EltSize >= Ty.getScalarSizeInBits() * 2;
452 I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_ANYEXT;
454 I2Opc == TargetOpcode::G_ZEXT || I2Opc == TargetOpcode::G_ANYEXT;
455 if (IsZExt1 && IsZExt2 && IsAtLeastDoubleExtend(I1->getOperand(1).getReg()) &&
458 get<1>(MatchInfo) = I1->getOperand(1).getReg();
464 I1Opc == TargetOpcode::G_SEXT || I1Opc == TargetOpcode::G_ANYEXT;
466 I2Opc == TargetOpcode::G_SEXT || I2Opc == TargetOpcode::G_ANYEXT;
467 if (IsSExt1 && IsSExt2 && IsAtLeastDoubleExtend(I1->getOperand(1).getReg()) &&
469 get<0>(MatchInfo) =
false;
470 get<1>(MatchInfo) = I1->getOperand(1).getReg();
477 if (KB && (IsZExt1 || IsZExt2) &&
478 IsAtLeastDoubleExtend(IsZExt1 ? I1->getOperand(1).getReg()
481 IsZExt1 ?
MI.getOperand(2).getReg() :
MI.getOperand(1).getReg();
484 get<1>(MatchInfo) = IsZExt1 ? I1->getOperand(1).getReg() : ZExtOp;
492 get<1>(MatchInfo) =
MI.getOperand(1).getReg();
493 get<2>(MatchInfo) =
MI.getOperand(2).getReg();
497 if (KB && (IsSExt1 || IsSExt2) &&
498 IsAtLeastDoubleExtend(IsSExt1 ? I1->getOperand(1).getReg()
501 IsSExt1 ?
MI.getOperand(2).getReg() :
MI.getOperand(1).getReg();
503 get<0>(MatchInfo) =
false;
504 get<1>(MatchInfo) = IsSExt1 ? I1->getOperand(1).getReg() : SExtOp;
511 get<0>(MatchInfo) =
false;
512 get<1>(MatchInfo) =
MI.getOperand(1).getReg();
513 get<2>(MatchInfo) =
MI.getOperand(2).getReg();
522 std::tuple<bool, Register, Register> &MatchInfo) {
523 assert(
MI.getOpcode() == TargetOpcode::G_MUL &&
524 "Expected a G_MUL instruction");
527 LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
528 bool IsZExt =
get<0>(MatchInfo);
531 LLT Src1Ty =
MRI.getType(Src1Reg);
532 LLT Src2Ty =
MRI.getType(Src2Reg);
534 unsigned ExtOpc = IsZExt ? TargetOpcode::G_ZEXT : TargetOpcode::G_SEXT;
537 Src1Reg =
B.buildExtOrTrunc(ExtOpc, {HalfDstTy}, {Src1Reg}).
getReg(0);
539 Src2Reg =
B.buildExtOrTrunc(ExtOpc, {HalfDstTy}, {Src2Reg}).
getReg(0);
541 B.buildInstr(IsZExt ? AArch64::G_UMULL : AArch64::G_SMULL,
542 {
MI.getOperand(0).getReg()}, {Src1Reg, Src2Reg});
543 MI.eraseFromParent();
553 if (
M1->getOpcode() != AArch64::G_MUL &&
554 M1->getOpcode() != AArch64::G_SMULL &&
555 M1->getOpcode() != AArch64::G_UMULL)
570 assert(
MI.getOpcode() == TargetOpcode::G_ASHR ||
571 MI.getOpcode() == TargetOpcode::G_LSHR);
572 LLT Ty =
MRI.getType(
MI.getOperand(0).getReg());
585class AArch64PostLegalizerCombinerImpl :
public Combiner {
588 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig;
592 AArch64PostLegalizerCombinerImpl(
595 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
599 static const char *
getName() {
return "AArch64PostLegalizerCombiner"; }
604#define GET_GICOMBINER_CLASS_MEMBERS
605#include "AArch64GenPostLegalizeGICombiner.inc"
606#undef GET_GICOMBINER_CLASS_MEMBERS
609#define GET_GICOMBINER_IMPL
610#include "AArch64GenPostLegalizeGICombiner.inc"
611#undef GET_GICOMBINER_IMPL
613AArch64PostLegalizerCombinerImpl::AArch64PostLegalizerCombinerImpl(
616 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
619 :
Combiner(MF, CInfo, &VT, CSEInfo),
620 Helper(Observer,
B,
false, &VT, MDT, LI),
621 RuleConfig(RuleConfig), STI(STI),
623#include
"AArch64GenPostLegalizeGICombiner.inc"
629 GStore *St =
nullptr;
632 GPtrAdd *Ptr =
nullptr;
640 if (Stores.
size() <= 2)
644 int64_t BaseOffset = Stores[0].Offset;
645 unsigned NumPairsExpected = Stores.
size() / 2;
646 unsigned TotalInstsExpected = NumPairsExpected + (Stores.
size() % 2);
650 if (!
TLI.isLegalAddImmediate(BaseOffset))
651 TotalInstsExpected++;
652 int SavingsExpected = Stores.
size() - TotalInstsExpected;
653 if (SavingsExpected <= 0)
660 Register NewBase = Stores[0].Ptr->getReg(0);
661 for (
auto &SInfo : Stores) {
666 auto NewPtr = MIB.
buildPtrAdd(
MRI.getType(SInfo.St->getPointerReg()),
670 SInfo.St->getOperand(1).setReg(NewPtr.getReg(0));
675 <<
" stores into a base pointer and offsets.\n");
707 .postlegalizer_consecutive_memops)
723 if (
Last.Ptr->getBaseReg() !=
New.Ptr->getBaseReg() ||
724 (
Last.Offset +
static_cast<int64_t
>(
Last.StoredType.getSizeInBytes()) !=
726 Last.StoredType !=
New.StoredType)
732 return New.St->getValueReg() == LoadVal;
739 int64_t MaxLegalOffset;
740 switch (
New.StoredType.getSizeInBits()) {
742 MaxLegalOffset = 252;
745 MaxLegalOffset = 504;
748 MaxLegalOffset = 1008;
753 if (
New.Offset < MaxLegalOffset)
757 return New.Offset - Stores[0].Offset <= MaxLegalOffset;
760 auto resetState = [&]() {
762 LoadValsSinceLastStore.
clear();
765 for (
auto &
MBB : MF) {
769 for (
auto &
MI :
MBB) {
772 LdSt &&
MRI.getType(LdSt->getOperand(0).getReg()).isScalableVector())
778 LLT StoredValTy =
MRI.getType(St->getValueReg());
780 if (ValSize < 32 || St->getMMO().getSizeInBits() != ValSize)
783 Register PtrReg = St->getPointerReg();
789 if (Stores.
empty()) {
796 if (storeIsValid(
Last, New)) {
798 LoadValsSinceLastStore.
clear();
802 Changed |= tryOptimizeConsecStores(Stores, MIB);
808 LoadValsSinceLastStore.
push_back(Ld->getDstReg());
811 Changed |= tryOptimizeConsecStores(Stores, MIB);
820 const AArch64PostLegalizerCombinerImplRuleConfig &RuleConfig,
821 bool EnableOpt,
bool IsOptNone) {
830 LI, EnableOpt,
F.hasOptSize(),
833 CInfo.MaxIterations = 1;
836 CInfo.EnableFullDCE =
false;
837 AArch64PostLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
839 bool Changed = Impl.combineMachineInstrs();
843 Changed |= optimizeConsecutiveMemOpAddressing(MF, MIB);
851 AArch64PostLegalizerCombinerLegacy(
bool IsOptNone =
false);
853 StringRef getPassName()
const override {
854 return "AArch64PostLegalizerCombiner";
858 void getAnalysisUsage(AnalysisUsage &AU)
const override;
860 MachineFunctionProperties getRequiredProperties()
const override {
861 return MachineFunctionProperties().set(
862 MachineFunctionProperties::Property::Legalized);
867 AArch64PostLegalizerCombinerImplRuleConfig RuleConfig;
871void AArch64PostLegalizerCombinerLegacy::getAnalysisUsage(
875 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
885AArch64PostLegalizerCombinerLegacy::AArch64PostLegalizerCombinerLegacy(
887 : MachineFunctionPass(
ID), IsOptNone(IsOptNone) {
888 if (!RuleConfig.parseCommandLineOption())
892bool AArch64PostLegalizerCombinerLegacy::runOnMachineFunction(
897 GISelValueTracking *VT =
898 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
899 MachineDominatorTree *MDT =
901 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
902 GISelCSEAnalysisWrapper &
Wrapper =
903 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
910 return runCombiner(MF, CSEInfo, VT, MDT, RuleConfig, EnableOpt, IsOptNone);
913char AArch64PostLegalizerCombinerLegacy::ID = 0;
915 "Combine AArch64 MachineInstrs after legalization",
false,
919 "Combine AArch64 MachineInstrs after legalization",
false,
925 std::make_unique<AArch64PostLegalizerCombinerImplRuleConfig>()),
927 if (!RuleConfig->parseCommandLineOption())
942 const bool IsOptNone = TM->isGlobalISelOptNone();
951 if (!runCombiner(MF, CSEInfo, VT, MDT, *RuleConfig, EnableOpt, IsOptNone))
963 return new AArch64PostLegalizerCombinerLegacy(IsOptNone);
MachineInstrBuilder & UseMI
static bool isZeroExtended(SDValue N, SelectionDAG &DAG)
static bool isSignExtended(SDValue N, SelectionDAG &DAG)
const TargetLowering & TLI
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)
MachineRegisterInfo & MRI
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
AArch64PostLegalizerCombinerPass(const AArch64TargetMachine *TM)
~AArch64PostLegalizerCombinerPass()
const AArch64Options & getCLOpts() const
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 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,...
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.
bool isVShiftRImm(Register Reg, const MachineRegisterInfo &MRI, LLT Ty, int64_t &Cnt)
operand_type_match m_Reg()
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)
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)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
SrcImmOp_match< SrcTy, AnyImmMatch, TargetOpcode::G_SEXT_INREG > m_GSExtInReg(const SrcTy &Src)
Matches a G_SEXT_INREG, binding its source and immediate width.
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 bool isBuildVectorAllZeros(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
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...
bool shouldSkipOptimizationForOptBisect(IRUnitRef IR)