34#include "llvm/IR/IntrinsicsAArch64.h"
37#define GET_GICOMBINER_DEPS
38#include "AArch64GenPreLegalizeGICombiner.inc"
39#undef GET_GICOMBINER_DEPS
41#define DEBUG_TYPE "aarch64-prelegalizer-combiner"
46#define GET_GICOMBINER_TYPES
47#include "AArch64GenPreLegalizeGICombiner.inc"
48#undef GET_GICOMBINER_TYPES
57 assert(
MI.getOpcode() == TargetOpcode::G_ICMP && VT);
75 LLT WideTy =
MRI.getType(WideReg);
87 assert(
MI.getOpcode() == TargetOpcode::G_ICMP);
89 LLT WideTy =
MRI.getType(WideReg);
92 Builder.setInstrAndDebugLoc(
MI);
93 auto WideZero = Builder.buildConstant(WideTy, 0);
95 MI.getOperand(2).setReg(WideReg);
96 MI.getOperand(3).setReg(WideZero.getReg(0));
106 std::pair<uint64_t, uint64_t> &MatchInfo) {
107 assert(
MI.getOpcode() == TargetOpcode::G_GLOBAL_VALUE);
109 auto &GlobalOp =
MI.getOperand(1);
110 auto *GV = GlobalOp.getGlobal();
111 if (GV->isThreadLocal())
135 for (
auto &UseInstr :
MRI.use_nodbg_instructions(Dst)) {
136 if (UseInstr.getOpcode() != TargetOpcode::G_PTR_ADD)
139 UseInstr.getOperand(2).getReg(),
MRI);
142 MinOffset = std::min(MinOffset, Cst->Value.getZExtValue());
147 uint64_t CurrOffset = GlobalOp.getOffset();
148 uint64_t NewOffset = MinOffset + CurrOffset;
149 if (NewOffset <= CurrOffset)
161 if (NewOffset >= (1 << 20))
164 Type *
T = GV->getValueType();
166 NewOffset > GV->getDataLayout().getTypeAllocSize(
T))
168 MatchInfo = std::make_pair(NewOffset, MinOffset);
174 std::pair<uint64_t, uint64_t> &MatchInfo) {
196 std::tie(
Offset, MinOffset) = MatchInfo;
197 B.setInstrAndDebugLoc(*std::next(
MI.getIterator()));
199 auto &GlobalOp =
MI.getOperand(1);
200 auto *GV = GlobalOp.getGlobal();
201 GlobalOp.ChangeToGA(GV,
Offset, GlobalOp.getTargetFlags());
204 MI.getOperand(0).setReg(NewGVDst);
208 B.buildConstant(
LLT::scalar(64), -
static_cast<int64_t
>(MinOffset)));
217 std::tuple<Register, Register, bool> &MatchInfo) {
218 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
219 "Expected a G_VECREDUCE_ADD instruction");
220 assert(STI.hasDotProd() &&
"Target should have Dot Product feature");
224 Register MidReg = I1->getOperand(0).getReg();
225 LLT DstTy =
MRI.getType(DstReg);
226 LLT MidTy =
MRI.getType(MidReg);
237 if (!
MRI.hasOneNonDBGUse(
MI->getOperand(0).getReg()))
249 if ((I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_SEXT) &&
259 unsigned I1Opc = I1->getOpcode();
260 if (I1Opc == TargetOpcode::G_MUL) {
262 if (!tryMatchingMulOfExt(I1, Out1, Out2, I1Opc))
264 SrcTy =
MRI.getType(Out1);
265 std::get<0>(MatchInfo) = Out1;
266 std::get<1>(MatchInfo) = Out2;
267 }
else if (I1Opc == TargetOpcode::G_ZEXT || I1Opc == TargetOpcode::G_SEXT) {
268 Register I1Op = I1->getOperand(1).getReg();
271 if (M->getOpcode() == TargetOpcode::G_MUL &&
272 tryMatchingMulOfExt(M, Out1, Out2, I1Opc)) {
273 SrcTy =
MRI.getType(Out1);
274 std::get<0>(MatchInfo) = Out1;
275 std::get<1>(MatchInfo) = Out2;
277 SrcTy =
MRI.getType(I1Op);
278 std::get<0>(MatchInfo) = I1Op;
279 std::get<1>(MatchInfo) = 0;
285 if (I1Opc == TargetOpcode::G_ZEXT)
286 std::get<2>(MatchInfo) = 0;
287 else if (I1Opc == TargetOpcode::G_SEXT)
288 std::get<2>(MatchInfo) = 1;
292 if (SrcTy.getScalarSizeInBits() != 8 || SrcTy.getNumElements() % 8 != 0)
302 std::tuple<Register, Register, bool> &MatchInfo) {
303 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
304 "Expected a G_VECREDUCE_ADD instruction");
305 assert(STI.hasDotProd() &&
"Target should have Dot Product feature");
309 std::get<2>(MatchInfo) ? AArch64::G_SDOT : AArch64::G_UDOT;
310 Register Ext1SrcReg = std::get<0>(MatchInfo);
315 if (std::get<1>(MatchInfo) == 0)
316 Ext2SrcReg = Builder.buildConstant(
MRI.getType(Ext1SrcReg), 1)
320 Ext2SrcReg = std::get<1>(MatchInfo);
323 LLT SrcTy =
MRI.getType(Ext1SrcReg);
326 if (SrcTy.getNumElements() % 16 == 0) {
327 NumOfDotMI = SrcTy.getNumElements() / 16;
329 }
else if (SrcTy.getNumElements() % 8 == 0) {
330 NumOfDotMI = SrcTy.getNumElements() / 8;
337 if (NumOfDotMI == 1) {
338 auto Zeroes = Builder.buildConstant(MidTy, 0)->getOperand(0).getReg();
339 auto Dot = Builder.buildInstr(DotOpcode, {MidTy},
340 {Zeroes, Ext1SrcReg, Ext2SrcReg});
341 Builder.buildVecReduceAdd(
MI.getOperand(0), Dot->getOperand(0));
346 if (SrcTy.getNumElements() % 16 != 0) {
352 LLT LeftoverTy1, LeftoverTy2;
354 LeftoverTy1, Ext1UnmergeReg, Leftover1, Builder,
MRI) ||
356 LeftoverTy2, Ext2UnmergeReg, Leftover2, Builder,
MRI)) {
367 {Leftover1[0], v8Zeroes})
372 {Leftover2[0], v8Zeroes})
377 unsigned SrcNumElts = SrcTy.getNumElements();
379 SrcNumElts / 16, Ext1UnmergeReg, Builder,
MRI);
381 SrcNumElts / 16, Ext2UnmergeReg, Builder,
MRI);
386 unsigned NumElements = 0;
387 for (
unsigned i = 0; i < Ext1UnmergeReg.
size(); i++) {
390 if (
MRI.getType(Ext1UnmergeReg[i]).getNumElements() == 16) {
397 auto Zeroes = Builder.buildConstant(ZeroesLLT, 0);
400 .buildInstr(DotOpcode, {ZeroesLLT},
401 {Zeroes, Ext1UnmergeReg[i], Ext2UnmergeReg[i]})
406 auto ConcatMI = Builder.buildConcatVectors(
410 Builder.buildVecReduceAdd(
MI.getOperand(0).getReg(),
411 ConcatMI->getOperand(0).getReg());
415 MI.eraseFromParent();
421 std::pair<Register, bool> &MatchInfo) {
422 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
423 "Expected G_VECREDUCE_ADD Opcode");
429 if (ExtOpc == TargetOpcode::G_ZEXT)
430 std::get<1>(MatchInfo) = 0;
431 else if (ExtOpc == TargetOpcode::G_SEXT)
432 std::get<1>(MatchInfo) = 1;
438 LLT ExtSrcTy =
MRI.getType(ExtSrcReg);
439 LLT DstTy =
MRI.getType(
MI.getOperand(0).getReg());
448 std::get<0>(MatchInfo) = ExtSrcReg;
456 std::pair<Register, bool> &MatchInfo) {
457 assert(
MI.getOpcode() == TargetOpcode::G_VECREDUCE_ADD &&
458 "Expected G_VECREDUCE_ADD Opcode");
460 unsigned Opc = std::get<1>(MatchInfo) ? AArch64::G_SADDLV : AArch64::G_UADDLV;
461 Register SrcReg = std::get<0>(MatchInfo);
463 LLT SrcTy =
MRI.getType(SrcReg);
464 LLT DstTy =
MRI.getType(DstReg);
470 unsigned SrcScalSize = SrcTy.getScalarSizeInBits();
471 unsigned SrcNumElem = SrcTy.getNumElements();
472 if ((SrcScalSize == 8 && SrcNumElem > 16) ||
473 (SrcScalSize == 16 && SrcNumElem > 8) ||
474 (SrcScalSize == 32 && SrcNumElem > 4)) {
478 if (SrcScalSize == 8)
480 else if (SrcScalSize == 16)
482 else if (SrcScalSize == 32)
489 extractParts(SrcReg, SrcTy, MainTy, LeftoverTy, WorkingRegisters,
490 LeftoverRegs,
B,
MRI);
500 for (
unsigned I = 0;
I < WorkingRegisters.
size();
I++) {
503 LLT WorkingRegTy =
MRI.getType(WorkingRegisters[
I]);
506 WorkingRegisters[
I] =
507 B.buildInstr(std::get<1>(MatchInfo) ? TargetOpcode::G_SEXT
508 : TargetOpcode::G_ZEXT,
510 {WorkingRegisters[
I]})
519 B.buildInstr(
Opc, {AddlvTy}, {WorkingRegisters[
I]}).
getReg(0);
526 if (MidScalarSize == 32 || MidScalarSize == 64) {
527 WorkingRegisters[
I] =
B.buildInstr(AArch64::G_EXTRACT_VECTOR_ELT,
528 {MidScalarLLT}, {AddlvReg, ZeroReg})
532 B.buildInstr(AArch64::G_EXTRACT_VECTOR_ELT, {
LLT::integer(32)},
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");
575 LLT DstTy =
MRI.getType(DstReg);
580 Register ExtDstReg =
MI.getOperand(1).getReg();
581 LLT Ext1SrcTy =
MRI.getType(SrcReg1);
582 LLT Ext2SrcTy =
MRI.getType(SrcReg2);
583 unsigned ExtDstScal =
MRI.getType(ExtDstReg).getScalarSizeInBits();
585 if (((Ext1SrcScal == 8 && ExtDstScal == 32) ||
586 ((Ext1SrcScal == 8 || Ext1SrcScal == 16) && ExtDstScal == 64)) &&
587 Ext1SrcTy == Ext2SrcTy)
596 LLT SrcTy =
MRI.getType(SrcReg1);
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();
617 std::pair<Register, Register> &MatchInfo) {
653 LLT WideTy0 =
MRI.getType(Op0Wide);
654 LLT WideTy1 =
MRI.getType(Op1Wide);
657 unsigned OpTySize =
OpTy.getScalarSizeInBits();
668 (OpTySize != 8 && OpTySize != 16))
672 Register ResStatus =
MI.getOperand(1).getReg();
673 if (!
MRI.hasOneNonDBGUse(ResStatus))
676 if (CondUser->
getOpcode() != TargetOpcode::G_BRCOND)
684 if (
any_of(
MRI.use_nodbg_instructions(ResVal),
687 (I.getParent() == FailMBB || I.getParent() == CurrentMBB);
691 MatchInfo = {Op0Wide, Op1Wide};
698 const std::pair<Register, Register> &MatchInfo) {
700 Register Op1Wide = MatchInfo.second;
702 Register ResStatus =
MI.getOperand(1).getReg();
703 unsigned OpTySize =
MRI.getType(ResVal).getScalarSizeInBits();
706 B.setInstrAndDebugLoc(*
MI.getNextNode());
707 MI.eraseFromParent();
710 Register AddDst =
MRI.cloneVirtualRegister(Op0Wide);
711 B.buildInstr(TargetOpcode::G_ADD, {AddDst}, {Op0Wide, Op1Wide});
715 Register CondBit =
MRI.cloneVirtualRegister(Op0Wide);
718 B.buildConstant(
LLT::integer(32), OpTySize == 8 ? 1 << 8 : 1 << 16));
724 B.buildZExtOrTrunc(ResVal, AddDst);
728 auto OldR = U.getParent()->getOperand(0).getReg();
730 U.getParent()->eraseFromParent();
741 if (!Ty.isVector() || !
Load.isSimple() ||
742 Load.getMemSizeInBits() != Ty.getSizeInBits())
745 switch (Ty.getScalarSizeInBits()) {
760 if (!Shuf || Shuf->getSrc1Reg() !=
Load.getDstReg())
777 LLT SubTy =
MRI.getType(Shuf->getReg(0));
784 Index >= Factor || Srcs[Index].
isValid())
786 Srcs[Index] = Shuf->getReg(0);
794 unsigned Factor = Srcs.
size();
798 IID = Intrinsic::aarch64_neon_ld2;
801 IID = Intrinsic::aarch64_neon_ld3;
804 IID = Intrinsic::aarch64_neon_ld4;
811 assert(
MI.getNumMemOperands() == 1);
819 auto PtrOffset = Pointer;
822 B.buildObjectPtrOffset(
MRI.getType(Pointer), Pointer,
827 S =
MRI.createGenericVirtualRegister(Ty);
828 auto LD =
B.buildIntrinsic(IID, Srcs);
829 LD.addReg(PtrOffset);
837 MRI.getVRegDef(Src)->eraseFromParent();
843 if (Ty == MainTy || Ty == MainTy.
divide(2)) {
845 generateLoad(Srcs, Ty, 0);
849 unsigned NumVecs = Ty.getSizeInBits() / 128;
851 for (
unsigned I = 0;
I < NumVecs;
I++) {
853 generateLoad(Regs.
back(), MainTy,
I * 16 * Factor);
855 if (Ty.getSizeInBits() % 128 == 0) {
857 for (
unsigned R = 0; R < Factor; R++) {
861 for (
unsigned I = 0;
I < NumVecs;
I++)
862 Ops.push_back(Regs[
I][R]);
863 B.buildMergeLikeInstr(Srcs[R],
Ops);
868 generateLoad(LeftOverRegs, LeftOverTy, NumVecs * 16 * Factor);
871 for (
unsigned R = 0; R < Factor; R++) {
875 for (
unsigned I = 0;
I < NumVecs;
I++) {
876 auto Unmerge =
B.buildUnmerge(LeftOverTy, Regs[
I][R]);
877 Ops.push_back(Unmerge.getReg(0));
878 Ops.push_back(Unmerge.getReg(1));
880 Ops.push_back(LeftOverRegs[R]);
881 B.buildMergeLikeInstr(Srcs[R],
Ops);
886 MI.eraseFromParent();
894 if (!Ty.isVector() || !
Store.isSimple() ||
895 Store.getMemSizeInBits() != Ty.getSizeInBits() ||
896 !
MRI.hasOneNonDBGUse(
Store.getValueReg()))
899 switch (Ty.getScalarSizeInBits()) {
912 if (Ty.getSizeInBits() % 128 == 0 &&
914 if (
MRI.getType(Shuf->getOperand(1).getReg()).getNumElements() ==
916 Srcs.
push_back(Shuf->getOperand(1).getReg());
917 Srcs.
push_back(Shuf->getOperand(2).getReg());
922 if (
MRI.getType(Shuf->getOperand(1).getReg()).getNumElements() !=
924 C1->getOpcode() != TargetOpcode::G_CONCAT_VECTORS ||
925 C1->getNumOperands() != 3)
931 if (Ty.getSizeInBits() % 192 == 0 &&
935 if (
C1->getOpcode() != TargetOpcode::G_CONCAT_VECTORS ||
936 C1->getNumOperands() != 3 ||
937 C2->
getOpcode() != TargetOpcode::G_CONCAT_VECTORS ||
945 if (Ty.getSizeInBits() % 256 == 0 &&
949 if (
C1->getOpcode() != TargetOpcode::G_CONCAT_VECTORS ||
950 C1->getNumOperands() != 3 ||
951 C2->
getOpcode() != TargetOpcode::G_CONCAT_VECTORS ||
968 switch (Srcs.
size()) {
970 IID = Intrinsic::aarch64_neon_st2;
973 IID = Intrinsic::aarch64_neon_st3;
976 IID = Intrinsic::aarch64_neon_st4;
983 LLT Ty =
MRI.getType(Srcs[0]);
989 for (
unsigned I = 0;
I < Srcs.
size();
I++)
990 Regs[
I].push_back(Srcs[
I]);
991 }
else if (Ty == MainTy.
divide(2)) {
992 for (
unsigned I = 0;
I < Srcs.
size();
I++)
993 LeftOver[
I].push_back(Srcs[
I]);
994 LeftOverTy = MainTy.
divide(2);
996 for (
unsigned I = 0;
I < Srcs.
size();
I++)
1000 (LeftOver[0].
size() == 1 && LeftOverTy == MainTy.
divide(2)));
1003 Register Pointer =
MI.getOperand(1).getReg();
1004 assert(
MI.getNumMemOperands() == 1);
1011 auto PtrOffset = Pointer;
1014 B.buildObjectPtrOffset(
MRI.getType(Pointer), Pointer,
1020 ST.addReg(PtrOffset);
1024 for (
unsigned I = 0;
I < Regs[0].size();
I++) {
1025 for (
unsigned S = 0; S < Srcs.
size(); S++)
1026 Srcs[S] = Regs[S][
I];
1027 generateStore(Srcs, MainTy,
I * 16 * Srcs.
size());
1029 if (!LeftOver[0].empty()) {
1030 for (
unsigned S = 0; S < Srcs.
size(); S++)
1031 Srcs[S] = LeftOver[S][0];
1032 generateStore(Srcs, LeftOverTy, Regs[0].
size() * 16 * Srcs.
size());
1034 MI.eraseFromParent();
1037class AArch64PreLegalizerCombinerImpl :
public Combiner {
1040 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig;
1045 AArch64PreLegalizerCombinerImpl(
1048 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
1052 static const char *
getName() {
return "AArch6400PreLegalizerCombiner"; }
1059#define GET_GICOMBINER_CLASS_MEMBERS
1060#include "AArch64GenPreLegalizeGICombiner.inc"
1061#undef GET_GICOMBINER_CLASS_MEMBERS
1064#define GET_GICOMBINER_IMPL
1065#include "AArch64GenPreLegalizeGICombiner.inc"
1066#undef GET_GICOMBINER_IMPL
1068AArch64PreLegalizerCombinerImpl::AArch64PreLegalizerCombinerImpl(
1071 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
1074 :
Combiner(MF, CInfo, &VT, CSEInfo),
1075 Helper(Observer,
B,
true, &VT, MDT, LI),
1076 RuleConfig(RuleConfig), STI(STI), Libcalls(Libcalls),
1078#include
"AArch64GenPreLegalizeGICombiner.inc"
1083bool AArch64PreLegalizerCombinerImpl::tryCombineAll(
MachineInstr &
MI)
const {
1084 if (tryCombineAllImpl(
MI))
1091 GISelValueTracking *VT, MachineDominatorTree *MDT,
1092 const LibcallLoweringInfo &Libcalls,
1093 const AArch64PreLegalizerCombinerImplRuleConfig &RuleConfig,
1095 const AArch64Subtarget &
ST = MF.
getSubtarget<AArch64Subtarget>();
1096 const auto *LI =
ST.getLegalizerInfo();
1100 CombinerInfo CInfo(
true,
false,
1101 nullptr, EnableOpt,
F.hasOptSize(),
1104 CInfo.MaxIterations = 1;
1105 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
1108 CInfo.EnableFullDCE =
true;
1109 AArch64PreLegalizerCombinerImpl Impl(MF, CInfo, *VT, CSEInfo, RuleConfig, ST,
1111 return Impl.combineMachineInstrs();
1117class AArch64PreLegalizerCombinerLegacy :
public MachineFunctionPass {
1121 AArch64PreLegalizerCombinerLegacy();
1123 StringRef getPassName()
const override {
1124 return "AArch64PreLegalizerCombiner";
1129 void getAnalysisUsage(AnalysisUsage &AU)
const override;
1132 AArch64PreLegalizerCombinerImplRuleConfig RuleConfig;
1136void AArch64PreLegalizerCombinerLegacy::getAnalysisUsage(
1137 AnalysisUsage &AU)
const {
1140 AU.
addRequired<GISelValueTrackingAnalysisLegacy>();
1142 AU.
addRequired<MachineDominatorTreeWrapperPass>();
1149AArch64PreLegalizerCombinerLegacy::AArch64PreLegalizerCombinerLegacy()
1150 : MachineFunctionPass(
ID) {
1151 if (!RuleConfig.parseCommandLineOption())
1155bool AArch64PreLegalizerCombinerLegacy::runOnMachineFunction(
1160 GISelCSEAnalysisWrapper &
Wrapper =
1161 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
1165 const AArch64Subtarget &
ST = MF.
getSubtarget<AArch64Subtarget>();
1166 const LibcallLoweringInfo &Libcalls =
1167 getAnalysis<LibcallLoweringInfoWrapper>().getLibcallLowering(
1170 GISelValueTracking *VT =
1171 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
1172 MachineDominatorTree *MDT =
1173 &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1176 return runCombiner(MF, CSEInfo, VT, MDT, Libcalls, RuleConfig, EnableOpt);
1179char AArch64PreLegalizerCombinerLegacy::ID = 0;
1181 "Combine AArch64 machine instrs before legalization",
1187 "Combine AArch64 machine instrs before legalization",
false,
1192 std::make_unique<AArch64PreLegalizerCombinerImplRuleConfig>()) {
1193 if (!RuleConfig->parseCommandLineOption())
1225 if (!runCombiner(MF, CSEInfo, &VT, &MDT, Libcalls, *RuleConfig, EnableOpt))
1237 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.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
~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:
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents analyses that only rely on functions' control flow.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
LLVM_ABI void replaceRegWith(MachineRegisterInfo &MRI, Register FromReg, Register ToReg) const
MachineRegisterInfo::replaceRegWith() and inform the observer of the changes.
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.
LLT divide(int Factor) const
Return a type that is Factor times smaller.
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.
Tracks which library functions to use for a particular subtarget or function.
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.
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.
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
unsigned getNumOperands() const
Retuns the total number of operands.
const MachineOperand & getOperand(unsigned i) const
A description of a memory reference used in the backend.
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,...
Records a mapping from an opaque lowering context to its LibcallLoweringInfo.
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.
static LLVM_ABI bool isDeInterleaveMaskOfFactor(ArrayRef< int > Mask, unsigned Factor, unsigned &Index)
Check if the mask is a DE-interleave mask of the given factor Factor like: <Index,...
static LLVM_ABI bool isInterleaveMask(ArrayRef< int > Mask, unsigned Factor, unsigned NumInputElts, SmallVectorImpl< unsigned > &StartIndexes)
Return true if the mask interleaves one or more input vectors together.
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.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
#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.
SrcImmOp_match< SrcTy, AnyImmMatch, TargetOpcode::G_ASSERT_ZEXT > m_GAssertZext(const SrcTy &Src)
Matches a G_ASSERT_ZEXT, binding its source and immediate bit width.
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
SpecificImmMatch m_SpecificImm(int64_t RequestedValue)
Matches an immediate operand equal to RequestedValue.
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()
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
@ Load
The value being inserted comes from a load (InsertElement only).
@ Store
The extracted value is stored (ExtractElement only).
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.
LLVM_ABI const LibcallLoweringInfo & getLibcallLowering(const ModuleLibcallLoweringInfo &ModuleInfo, const TargetSubtargetInfo &Subtarget)
Resolve the LibcallLoweringInfo for Subtarget from the module-level ModuleInfo, applying the subtarge...
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.
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...
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
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.