36#define GET_GICOMBINER_DEPS
37#include "AArch64GenPreLegalizeGICombiner.inc"
38#undef GET_GICOMBINER_DEPS
40#define DEBUG_TYPE "aarch64-prelegalizer-combiner"
45#define GET_GICOMBINER_TYPES
46#include "AArch64GenPreLegalizeGICombiner.inc"
47#undef GET_GICOMBINER_TYPES
56 assert(
MI.getOpcode() == TargetOpcode::G_ICMP && VT);
86 assert(
MI.getOpcode() == TargetOpcode::G_ICMP);
91 Builder.setInstrAndDebugLoc(
MI);
92 auto WideZero = Builder.buildConstant(WideTy, 0);
94 MI.getOperand(2).setReg(WideReg);
95 MI.getOperand(3).setReg(WideZero.getReg(0));
105 std::pair<uint64_t, uint64_t> &MatchInfo) {
106 assert(
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
108 auto &GlobalOp =
MI.getOperand(1);
109 auto *GV = GlobalOp.getGlobal();
110 if (GV->isThreadLocal())
135 if (UseInstr.getOpcode() != TargetOpcode::G_PTR_ADD)
138 UseInstr.getOperand(2).getReg(), MRI);
141 MinOffset = std::min(MinOffset, Cst->Value.getZExtValue());
146 uint64_t CurrOffset = GlobalOp.getOffset();
147 uint64_t NewOffset = MinOffset + CurrOffset;
148 if (NewOffset <= CurrOffset)
160 if (NewOffset >= (1 << 20))
163 Type *
T = GV->getValueType();
165 NewOffset > GV->getDataLayout().getTypeAllocSize(
T))
167 MatchInfo = std::make_pair(NewOffset, MinOffset);
173 std::pair<uint64_t, uint64_t> &MatchInfo) {
195 std::tie(
Offset, MinOffset) = MatchInfo;
196 B.setInstrAndDebugLoc(*std::next(
MI.getIterator()));
198 auto &GlobalOp =
MI.getOperand(1);
199 auto *GV = GlobalOp.getGlobal();
200 GlobalOp.ChangeToGA(GV,
Offset, GlobalOp.getTargetFlags());
203 MI.getOperand(0).setReg(NewGVDst);
207 B.buildConstant(
LLT::scalar(64), -
static_cast<int64_t
>(MinOffset)));
216 std::tuple<Register, Register, bool> &MatchInfo) {
217 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
218 "Expected a G_VECREDUCE_ADD instruction");
219 assert(STI.hasDotProd() &&
"Target should have Dot Product feature");
223 Register MidReg = I1->getOperand(0).getReg();
248 if ((I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_SEXT) &&
258 unsigned I1Opc = I1->getOpcode();
259 if (I1Opc == TargetOpcode::G_MUL) {
261 if (!tryMatchingMulOfExt(I1, Out1, Out2, I1Opc))
264 std::get<0>(MatchInfo) = Out1;
265 std::get<1>(MatchInfo) = Out2;
266 }
else if (I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_SEXT) {
267 Register I1Op = I1->getOperand(1).getReg();
270 if (M->getOpcode() == TargetOpcode::G_MUL &&
271 tryMatchingMulOfExt(M, Out1, Out2, I1Opc)) {
273 std::get<0>(MatchInfo) = Out1;
274 std::get<1>(MatchInfo) = Out2;
277 std::get<0>(MatchInfo) = I1Op;
278 std::get<1>(MatchInfo) = 0;
284 if (I1Opc == TargetOpcode::G_ZEXT)
285 std::get<2>(MatchInfo) = 0;
286 else if (I1Opc == TargetOpcode::G_SEXT)
287 std::get<2>(MatchInfo) = 1;
291 if (SrcTy.getScalarSizeInBits() != 8 || SrcTy.getNumElements() % 8 != 0)
301 std::tuple<Register, Register, bool> &MatchInfo) {
302 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
303 "Expected a G_VECREDUCE_ADD instruction");
304 assert(STI.hasDotProd() &&
"Target should have Dot Product feature");
308 std::get<2>(MatchInfo) ? AArch64::G_SDOT : AArch64::G_UDOT;
309 Register Ext1SrcReg = std::get<0>(MatchInfo);
314 if (std::get<1>(MatchInfo) == 0)
315 Ext2SrcReg = Builder.buildConstant(MRI.
getType(Ext1SrcReg), 1)
319 Ext2SrcReg = std::get<1>(MatchInfo);
325 if (SrcTy.getNumElements() % 16 == 0) {
326 NumOfDotMI = SrcTy.getNumElements() / 16;
328 }
else if (SrcTy.getNumElements() % 8 == 0) {
329 NumOfDotMI = SrcTy.getNumElements() / 8;
336 if (NumOfDotMI == 1) {
337 auto Zeroes = Builder.buildConstant(MidTy, 0)->getOperand(0).getReg();
338 auto Dot = Builder.buildInstr(DotOpcode, {MidTy},
339 {Zeroes, Ext1SrcReg, Ext2SrcReg});
340 Builder.buildVecReduceAdd(
MI.getOperand(0), Dot->getOperand(0));
345 if (SrcTy.getNumElements() % 16 != 0) {
351 LLT LeftoverTy1, LeftoverTy2;
353 LeftoverTy1, Ext1UnmergeReg, Leftover1, Builder,
356 LeftoverTy2, Ext2UnmergeReg, Leftover2, Builder,
369 {Leftover1[0], v8Zeroes})
374 {Leftover2[0], v8Zeroes})
379 unsigned SrcNumElts = SrcTy.getNumElements();
381 Ext1UnmergeReg, Builder, MRI);
383 Ext2UnmergeReg, Builder, MRI);
388 unsigned NumElements = 0;
389 for (
unsigned i = 0; i < Ext1UnmergeReg.
size(); i++) {
399 auto Zeroes = Builder.buildConstant(ZeroesLLT, 0)->getOperand(0).getReg();
402 .buildInstr(DotOpcode, {MRI.
getType(Zeroes)},
403 {Zeroes, Ext1UnmergeReg[i], Ext2UnmergeReg[i]})
412 Builder.buildVecReduceAdd(
MI.getOperand(0).getReg(),
413 ConcatMI->getOperand(0).getReg());
417 MI.eraseFromParent();
423 std::pair<Register, bool> &MatchInfo) {
424 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
425 "Expected G_VECREDUCE_ADD Opcode");
431 if (ExtOpc == TargetOpcode::G_ZEXT)
432 std::get<1>(MatchInfo) = 0;
433 else if (ExtOpc == TargetOpcode::G_SEXT)
434 std::get<1>(MatchInfo) = 1;
450 std::get<0>(MatchInfo) = ExtSrcReg;
458 std::pair<Register, bool> &MatchInfo) {
459 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
460 "Expected G_VECREDUCE_ADD Opcode");
462 unsigned Opc = std::get<1>(MatchInfo) ? AArch64::G_SADDLV : AArch64::G_UADDLV;
463 Register SrcReg = std::get<0>(MatchInfo);
472 unsigned SrcScalSize = SrcTy.getScalarSizeInBits();
473 unsigned SrcNumElem = SrcTy.getNumElements();
474 if ((SrcScalSize == 8 && SrcNumElem > 16) ||
475 (SrcScalSize == 16 && SrcNumElem > 8) ||
476 (SrcScalSize == 32 && SrcNumElem > 4)) {
480 if (SrcScalSize == 8)
482 else if (SrcScalSize == 16)
484 else if (SrcScalSize == 32)
491 extractParts(SrcReg, SrcTy, MainTy, LeftoverTy, WorkingRegisters,
492 LeftoverRegs,
B, MRI);
502 for (
unsigned I = 0;
I < WorkingRegisters.
size();
I++) {
505 LLT WorkingRegTy = MRI.
getType(WorkingRegisters[
I]);
508 WorkingRegisters[
I] =
509 B.buildInstr(std::get<1>(MatchInfo) ? TargetOpcode::G_SEXT
510 : TargetOpcode::G_ZEXT,
520 B.buildInstr(
Opc, {AddlvTy}, {WorkingRegisters[
I]}).
getReg(0);
527 if (MidScalarSize == 32 || MidScalarSize == 64) {
528 WorkingRegisters[
I] =
B.buildInstr(AArch64::G_EXTRACT_VECTOR_ELT,
529 {MidScalarLLT}, {AddlvReg, ZeroReg})
532 Register ExtractReg =
B.buildInstr(AArch64::G_EXTRACT_VECTOR_ELT,
535 WorkingRegisters[
I] =
536 B.buildTrunc({MidScalarLLT}, {ExtractReg}).
getReg(0);
541 if (WorkingRegisters.
size() > 1) {
542 OutReg =
B.buildAdd(MidScalarLLT, WorkingRegisters[0], WorkingRegisters[1])
544 for (
unsigned I = 2;
I < WorkingRegisters.
size();
I++) {
545 OutReg =
B.buildAdd(MidScalarLLT, OutReg, WorkingRegisters[
I]).getReg(0);
548 OutReg = WorkingRegisters[0];
554 B.buildInstr(std::get<1>(MatchInfo) ? TargetOpcode::G_SEXT
555 : TargetOpcode::G_ZEXT,
558 B.buildCopy(DstReg, OutReg);
561 MI.eraseFromParent();
569 assert((
MI.getOpcode() == TargetOpcode::G_ADD ||
570 MI.getOpcode() == TargetOpcode::G_SUB ||
571 MI.getOpcode() == TargetOpcode::G_MUL) &&
572 "Expected a G_ADD, G_SUB or G_MUL instruction\n");
580 Register ExtDstReg =
MI.getOperand(1).getReg();
585 if (((Ext1SrcScal == 8 && ExtDstScal == 32) ||
586 ((Ext1SrcScal == 8 || Ext1SrcScal == 16) && ExtDstScal == 64)) &&
587 Ext1SrcTy == Ext2SrcTy)
598 unsigned Opc = isSExt ? TargetOpcode::G_SEXT : TargetOpcode::G_ZEXT;
602 B.buildInstr(
MI.getOpcode(), {MidTy}, {Ext1Reg, Ext2Reg}).getReg(0);
607 if (
MI.getOpcode() == TargetOpcode::G_ADD ||
608 MI.getOpcode() == TargetOpcode::G_MUL)
609 B.buildInstr(
Opc, {DstReg}, {AddReg});
611 B.buildSExt(DstReg, AddReg);
613 MI.eraseFromParent();
647 auto &MRI = *
B.getMRI();
666 if (Op0WideDef->
getOpcode() != TargetOpcode::G_ASSERT_ZEXT ||
667 Op1WideDef->
getOpcode() != TargetOpcode::G_ASSERT_ZEXT ||
675 (OpTySize != 8 && OpTySize != 16))
679 Register ResStatus =
MI.getOperand(1).getReg();
683 if (CondUser->
getOpcode() != TargetOpcode::G_BRCOND)
694 (I.getParent() == FailMBB || I.getParent() == CurrentMBB);
699 B.setInstrAndDebugLoc(*
MI.getNextNode());
700 MI.eraseFromParent();
704 B.buildInstr(TargetOpcode::G_ADD, {AddDst}, {Op0Wide, Op1Wide});
711 B.buildConstant(
LLT::scalar(32), OpTySize == 8 ? 1 << 8 : 1 << 16));
717 B.buildZExtOrTrunc(ResVal, AddDst);
721 auto OldR = U.getParent()->getOperand(0).getReg();
723 U.getParent()->eraseFromParent();
731class AArch64PreLegalizerCombinerImpl :
public Combiner {
734 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig;
739 AArch64PreLegalizerCombinerImpl(
742 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
746 static const char *
getName() {
return "AArch6400PreLegalizerCombiner"; }
753#define GET_GICOMBINER_CLASS_MEMBERS
754#include "AArch64GenPreLegalizeGICombiner.inc"
755#undef GET_GICOMBINER_CLASS_MEMBERS
758#define GET_GICOMBINER_IMPL
759#include "AArch64GenPreLegalizeGICombiner.inc"
760#undef GET_GICOMBINER_IMPL
762AArch64PreLegalizerCombinerImpl::AArch64PreLegalizerCombinerImpl(
765 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
768 :
Combiner(MF, CInfo, &VT, CSEInfo),
769 Helper(Observer,
B,
true, &VT, MDT, LI),
770 RuleConfig(RuleConfig), STI(STI), Libcalls(Libcalls),
772#include
"AArch64GenPreLegalizeGICombiner.inc"
777bool AArch64PreLegalizerCombinerImpl::tryCombineAll(
MachineInstr &
MI)
const {
778 if (tryCombineAllImpl(
MI))
781 unsigned Opc =
MI.getOpcode();
783 case TargetOpcode::G_SHUFFLE_VECTOR:
785 case TargetOpcode::G_UADDO:
786 return tryToSimplifyUADDO(
MI,
B, Helper, Observer);
787 case TargetOpcode::G_MEMCPY_INLINE:
789 case TargetOpcode::G_MEMCPY:
790 case TargetOpcode::G_MEMMOVE:
791 case TargetOpcode::G_MEMSET: {
794 unsigned MaxLen = CInfo.EnableOpt ? 0 : 32;
798 if (
Opc == TargetOpcode::G_MEMSET)
800 CInfo.EnableMinSize);
808bool runCombiner(MachineFunction &MF, GISelCSEInfo *CSEInfo,
809 GISelValueTracking *VT, MachineDominatorTree *MDT,
810 const LibcallLoweringInfo &Libcalls,
811 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
814 const auto *LI =
ST.getLegalizerInfo();
818 CombinerInfo CInfo(
true,
false,
819 nullptr, EnableOpt,
F.hasOptSize(),
822 CInfo.MaxIterations = 1;
823 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
826 CInfo.EnableFullDCE =
true;
827 AArch64PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
829 return Impl.combineMachineInstrs();
835class AArch64PreLegalizerCombinerLegacy :
public MachineFunctionPass {
839 AArch64PreLegalizerCombinerLegacy();
841 StringRef getPassName()
const override {
842 return "AArch64PreLegalizerCombiner";
845 bool runOnMachineFunction(MachineFunction &MF)
override;
847 void getAnalysisUsage(AnalysisUsage &AU)
const override;
850 AArch64PreLegalizerCombinerImplRuleConfig RuleConfig;
854void AArch64PreLegalizerCombinerLegacy::getAnalysisUsage(
855 AnalysisUsage &AU)
const {
858 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
868AArch64PreLegalizerCombinerLegacy::AArch64PreLegalizerCombinerLegacy()
869 : MachineFunctionPass(
ID) {
870 if (!RuleConfig.parseCommandLineOption())
874bool AArch64PreLegalizerCombinerLegacy::runOnMachineFunction(
879 GISelCSEAnalysisWrapper &
Wrapper =
880 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
885 const LibcallLoweringInfo &Libcalls =
886 getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
889 GISelValueTracking *VT =
890 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
891 MachineDominatorTree *MDT =
892 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
895 return runCombiner(MF, CSEInfo, VT, MDT, Libcalls, RuleConfig, EnableOpt);
898char AArch64PreLegalizerCombinerLegacy::ID = 0;
900 "Combine AArch64 machine instrs before legalization",
906 "Combine AArch64 machine instrs before legalization",
false,
911 std::make_unique<AArch64PreLegalizerCombinerImplRuleConfig>()) {
912 if (!RuleConfig->parseCommandLineOption())
944 if (!runCombiner(MF, CSEInfo, &VT, &MDT, Libcalls, *RuleConfig, EnableOpt))
957 return new AArch64PreLegalizerCombinerLegacy();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
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.
Provides analysis for querying information about KnownBits during GISel passes.
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)
~AArch64PreLegalizerCombinerPass()
AArch64PreLegalizerCombinerPass()
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned ClassifyGlobalReference(const GlobalValue *GV, const TargetMachine &TM) const
ClassifyGlobalReference - Find the target operand flags that describe how a global value should be re...
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const
MachineRegisterInfo::replaceRegWith() and inform the observer of the changes.
bool tryEmitMemcpyInline(MachineInstr &MI) const
Emit loads and stores that perform the given memcpy.
bool tryCombineShuffleVector(MachineInstr &MI) const
Try to combine G_SHUFFLE_VECTOR into G_CONCAT_VECTORS.
bool tryCombineMemCpyFamily(MachineInstr &MI, unsigned MaxLen=0) const
Optimize memcpy intrinsics et al, e.g.
FunctionPass class - This class is used to implement most global optimizations.
The actual analysis pass wrapper.
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.
virtual void erasingInstr(MachineInstr &MI)=0
An instruction is about to be erased.
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
unsigned computeNumSignBits(Register R, const APInt &DemandedElts, unsigned Depth=0)
Module * getParent()
Get the module that this global value is contained inside of...
static bool isEquality(Predicate P)
Return true if this predicate is either EQ or NE.
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.
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
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.
Tracks which library functions to use for a particular subtarget.
Record a mapping from subtarget to LibcallLoweringInfo.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
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.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
MachineBasicBlock * getMBB() const
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
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 MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
MachineOperand * getOneDef(Register Reg) const
Returns the defining operand if there is exactly one operand defining the specified register,...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
LLVM_ABI Register cloneVirtualRegister(Register VReg, StringRef Name="")
Create and return a new virtual register in the function with the same attributes as the given regist...
iterator_range< use_iterator > use_operands(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.
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.
The instances of the Type class are immutable: once they are created, they are never changed.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool tryEmitBZero(MachineInstr &MI, MachineIRBuilder &MIRBuilder, const LibcallLoweringInfo &Libcalls, bool MinSize)
Replace a G_MEMSET with a value of 0 with a G_BZERO instruction if it is supported and beneficial to ...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createAArch64PreLegalizerCombiner()
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
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.
LLVM_ABI std::unique_ptr< CSEConfigBase > getStandardCSEConfigForOpt(CodeGenOptLevel Level)
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 void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI void extractParts(Register Reg, LLT Ty, int NumParts, SmallVectorImpl< Register > &VRegs, MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI)
Helper function to split a wide generic register into bitwise blocks with the given Type (which impli...
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
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.