35#include "llvm/IR/IntrinsicsARM.h"
47#define DEBUG_TYPE "arm-mve-gather-scatter-lowering"
51 cl::desc(
"Enable the generation of masked gathers and scatters"));
65 StringRef getPassName()
const override {
66 return "MVE gather/scatter lowering";
69 void getAnalysisUsage(AnalysisUsage &AU)
const override {
73 FunctionPass::getAnalysisUsage(AU);
77 LoopInfo *LI =
nullptr;
81 bool isLegalTypeAndAlignment(
unsigned NumElements,
unsigned ElemSize,
84 void lookThroughBitcast(
Value *&Ptr);
89 FixedVectorType *Ty,
Type *MemoryTy,
97 int computeScale(
unsigned GEPElemSize,
unsigned MemoryElemSize);
100 std::optional<int64_t> getIfConst(
const Value *V);
104 std::pair<Value *, int64_t> getVarAndConst(
Value *Inst,
int TypeScale);
141 Value *Ptr,
unsigned TypeScale,
145 bool optimiseAddress(
Value *
Address, BasicBlock *BB, LoopInfo *LI);
147 Value *foldGEP(GetElementPtrInst *
GEP,
Value *&Offsets,
unsigned &Scale,
150 bool optimiseOffsets(
Value *Offsets, BasicBlock *BB, LoopInfo *LI);
152 void pushOutAdd(PHINode *&Phi,
Value *OffsSecondOperand,
unsigned StartIndex);
154 void pushOutMulShl(
unsigned Opc, PHINode *&Phi,
Value *IncrementPerRound,
155 Value *OffsSecondOperand,
unsigned LoopIncrement,
161char MVEGatherScatterLowering::ID = 0;
164 "MVE gather/scattering lowering pass",
false,
false)
167 return new MVEGatherScatterLowering();
170bool MVEGatherScatterLowering::isLegalTypeAndAlignment(
unsigned NumElements,
173 if (((NumElements == 4 &&
174 (ElemSize == 32 || ElemSize == 16 || ElemSize == 8)) ||
175 (NumElements == 8 && (ElemSize == 16 || ElemSize == 8)) ||
176 (NumElements == 16 && ElemSize == 8)) &&
177 Alignment >= ElemSize / 8)
179 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: instruction does not have "
180 <<
"valid alignment or vector type \n");
195 unsigned TargetElemSize = 128 / TargetElemCount;
198 ->getScalarSizeInBits();
199 if (OffsetElemSize != TargetElemSize || OffsetElemSize != 32) {
203 int64_t TargetElemMaxSize = (1ULL << TargetElemSize);
204 auto CheckValueSize = [TargetElemMaxSize](
Value *OffsetElem) {
209 if (SExtValue >= TargetElemMaxSize || SExtValue < 0)
214 for (
unsigned i = 0; i < TargetElemCount; i++) {
219 if (!CheckValueSize(ConstOff))
226Value *MVEGatherScatterLowering::decomposePtr(
Value *Ptr,
Value *&Offsets,
227 int &Scale, FixedVectorType *Ty,
233 computeScale(
DL->getTypeAllocSizeInBits(
GEP->getSourceElementType()),
235 return Scale == -1 ? nullptr :
V;
253Value *MVEGatherScatterLowering::decomposeGEP(
Value *&Offsets,
255 GetElementPtrInst *
GEP,
258 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: no getelementpointer "
262 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: getelementpointer found."
263 <<
" Looking at intrinsic for base + vector of offsets\n");
264 Value *GEPPtr =
GEP->getPointerOperand();
270 if (
GEP->getNumOperands() != 2) {
271 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: getelementptr with too many"
272 <<
" operands. Expanding.\n");
276 unsigned OffsetsElemCount =
290 ->getScalarSizeInBits() != 32)
296 if (Ty !=
Offsets->getType()) {
305 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: found correct offsets\n");
309void MVEGatherScatterLowering::lookThroughBitcast(
Value *&Ptr) {
314 if (BCTy->getNumElements() == BCSrcTy->getNumElements()) {
317 Ptr = BitCast->getOperand(0);
322int MVEGatherScatterLowering::computeScale(
unsigned GEPElemSize,
323 unsigned MemoryElemSize) {
326 if (GEPElemSize == 32 && MemoryElemSize == 32)
328 else if (GEPElemSize == 16 && MemoryElemSize == 16)
330 else if (GEPElemSize == 8)
332 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: incorrect scale. Can't "
333 <<
"create intrinsic\n");
337std::optional<int64_t> MVEGatherScatterLowering::getIfConst(
const Value *V) {
339 if (
C &&
C->getSplatValue())
340 return std::optional<int64_t>{
C->getUniqueInteger().getSExtValue()};
342 return std::optional<int64_t>{};
345 if (
I->getOpcode() == Instruction::Add ||
I->getOpcode() == Instruction::Or ||
346 I->getOpcode() == Instruction::Mul ||
347 I->getOpcode() == Instruction::Shl) {
348 std::optional<int64_t> Op0 = getIfConst(
I->getOperand(0));
349 std::optional<int64_t> Op1 = getIfConst(
I->getOperand(1));
351 return std::optional<int64_t>{};
352 if (
I->getOpcode() == Instruction::Add)
353 return std::optional<int64_t>{*Op0 + *Op1};
354 if (
I->getOpcode() == Instruction::Mul)
355 return std::optional<int64_t>{*Op0 * *Op1};
356 if (
I->getOpcode() == Instruction::Shl)
357 return std::optional<int64_t>{*Op0 << *Op1};
358 if (
I->getOpcode() == Instruction::Or)
359 return std::optional<int64_t>{*Op0 | *Op1};
361 return std::optional<int64_t>{};
367 return I->getOpcode() == Instruction::Or &&
371std::pair<Value *, int64_t>
372MVEGatherScatterLowering::getVarAndConst(
Value *Inst,
int TypeScale) {
373 std::pair<Value *, int64_t> ReturnFalse =
374 std::pair<Value *, int64_t>(
nullptr, 0);
378 if (
Add ==
nullptr ||
383 std::optional<int64_t>
Const;
385 if ((Const = getIfConst(
Add->getOperand(0))))
386 Summand =
Add->getOperand(1);
387 else if ((Const = getIfConst(
Add->getOperand(1))))
388 Summand =
Add->getOperand(0);
393 int64_t Immediate = *
Const << TypeScale;
394 if (Immediate > 512 || Immediate < -512 || Immediate % 4 != 0)
397 return std::pair<Value *, int64_t>(Summand, Immediate);
400Instruction *MVEGatherScatterLowering::lowerGather(IntrinsicInst *
I) {
401 using namespace PatternMatch;
402 LLVM_DEBUG(
dbgs() <<
"masked gathers: checking transform preconditions\n"
409 Value *Ptr =
I->getArgOperand(0);
412 Value *PassThru =
I->getArgOperand(2);
417 lookThroughBitcast(Ptr);
425 Load = tryCreateMaskedGatherOffset(
I, Ptr, Root, Builder);
427 Load = tryCreateMaskedGatherBase(
I, Ptr, Builder);
432 LLVM_DEBUG(
dbgs() <<
"masked gathers: found non-trivial passthru - "
433 <<
"creating select\n");
443 I->eraseFromParent();
445 LLVM_DEBUG(
dbgs() <<
"masked gathers: successfully built masked gather\n"
450Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherBase(
452 using namespace PatternMatch;
454 LLVM_DEBUG(
dbgs() <<
"masked gathers: loading from vector of pointers\n");
461 Intrinsic::arm_mve_vldr_gather_base, {Ty, Ptr->
getType()},
464 Intrinsic::arm_mve_vldr_gather_base_predicated,
469Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherBaseWB(
471 using namespace PatternMatch;
473 LLVM_DEBUG(
dbgs() <<
"masked gathers: loading from vector of pointers with "
481 Intrinsic::arm_mve_vldr_gather_base_wb, {Ty, Ptr->
getType()},
484 Intrinsic::arm_mve_vldr_gather_base_wb_predicated,
489Instruction *MVEGatherScatterLowering::tryCreateMaskedGatherOffset(
491 using namespace PatternMatch;
493 Type *MemoryTy =
I->getType();
494 Type *ResultTy = MemoryTy;
500 bool TruncResult =
false;
502 if (
I->hasOneUse()) {
508 User->getType()->getPrimitiveSizeInBits() == 128) {
512 ResultTy =
User->getType();
515 User->getType()->getPrimitiveSizeInBits() == 128) {
517 << *ResultTy <<
"\n");
519 ResultTy =
User->getType();
530 LLVM_DEBUG(
dbgs() <<
"masked gathers: Small input type, truncing to: "
531 << *ResultTy <<
"\n");
536 LLVM_DEBUG(
dbgs() <<
"masked gathers: Extend needed but not provided "
537 "from the correct type. Expanding\n");
554 Intrinsic::arm_mve_vldr_gather_offset_predicated,
560 Intrinsic::arm_mve_vldr_gather_offset,
566 Load = TruncInst::Create(Instruction::Trunc,
Load, MemoryTy);
572Instruction *MVEGatherScatterLowering::lowerScatter(IntrinsicInst *
I) {
573 using namespace PatternMatch;
574 LLVM_DEBUG(
dbgs() <<
"masked scatters: checking transform preconditions\n"
580 Value *Input =
I->getArgOperand(0);
581 Value *Ptr =
I->getArgOperand(1);
589 lookThroughBitcast(Ptr);
595 Store = tryCreateMaskedScatterOffset(
I, Ptr, Builder);
597 Store = tryCreateMaskedScatterBase(
I, Ptr, Builder);
601 LLVM_DEBUG(
dbgs() <<
"masked scatters: successfully built masked scatter\n"
603 I->eraseFromParent();
607Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterBase(
609 using namespace PatternMatch;
610 Value *Input =
I->getArgOperand(0);
619 LLVM_DEBUG(
dbgs() <<
"masked scatters: storing to a vector of pointers\n");
622 Intrinsic::arm_mve_vstr_scatter_base,
626 Intrinsic::arm_mve_vstr_scatter_base_predicated,
631Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterBaseWB(
633 using namespace PatternMatch;
634 Value *Input =
I->getArgOperand(0);
636 LLVM_DEBUG(
dbgs() <<
"masked scatters: storing to a vector of pointers "
637 <<
"with writeback\n");
644 Intrinsic::arm_mve_vstr_scatter_base_wb,
648 Intrinsic::arm_mve_vstr_scatter_base_wb_predicated,
653Instruction *MVEGatherScatterLowering::tryCreateMaskedScatterOffset(
655 using namespace PatternMatch;
656 Value *Input =
I->getArgOperand(0);
659 Type *MemoryTy = InputTy;
661 LLVM_DEBUG(
dbgs() <<
"masked scatters: getelementpointer found. Storing"
662 <<
" to base + vector of offsets\n");
666 Value *PreTrunc = Trunc->getOperand(0);
670 InputTy = PreTruncTy;
673 bool ExtendInput =
false;
683 LLVM_DEBUG(
dbgs() <<
"masked scatters: Small input type, will extend:\n"
687 LLVM_DEBUG(
dbgs() <<
"masked scatters: cannot create scatters for "
688 "non-standard input types. Expanding.\n");
703 Intrinsic::arm_mve_vstr_scatter_offset_predicated,
710 Intrinsic::arm_mve_vstr_scatter_offset,
717Instruction *MVEGatherScatterLowering::tryCreateIncrementingGatScat(
720 if (
I->getIntrinsicID() == Intrinsic::masked_gather)
740 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to build incrementing "
741 "wb gather/scatter\n");
746 computeScale(
DL->getTypeAllocSizeInBits(
GEP->getSourceElementType()),
747 DL->getTypeSizeInBits(
GEP->getType()) /
752 if (
GEP->hasOneUse()) {
756 if (
auto *
Load = tryCreateIncrementingWBGatScat(
I, BasePtr, Offsets,
761 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to build incrementing "
762 "non-wb gather/scatter\n");
764 std::pair<Value *, int64_t>
Add = getVarAndConst(Offsets, TypeScale);
765 if (
Add.first ==
nullptr)
768 int64_t Immediate =
Add.second;
772 Instruction::Shl, OffsetsIncoming,
775 "ScaledIndex",
I->getIterator());
778 Instruction::Add, ScaledOffsets,
784 "StartIndex",
I->getIterator());
786 if (
I->getIntrinsicID() == Intrinsic::masked_gather)
787 return tryCreateMaskedGatherBase(
I, OffsetsIncoming, Builder, Immediate);
789 return tryCreateMaskedScatterBase(
I, OffsetsIncoming, Builder, Immediate);
792Instruction *MVEGatherScatterLowering::tryCreateIncrementingWBGatScat(
793 IntrinsicInst *
I,
Value *BasePtr,
Value *Offsets,
unsigned TypeScale,
801 if (Phi ==
nullptr ||
Phi->getNumIncomingValues() != 2 ||
802 Phi->getParent() !=
L->getHeader() || !
Phi->hasNUses(2))
809 unsigned IncrementIndex =
810 Phi->getIncomingBlock(0) ==
L->getLoopLatch() ? 0 : 1;
812 Offsets =
Phi->getIncomingValue(IncrementIndex);
814 std::pair<Value *, int64_t>
Add = getVarAndConst(Offsets, TypeScale);
815 if (
Add.first ==
nullptr)
818 int64_t Immediate =
Add.second;
819 if (OffsetsIncoming != Phi)
830 Instruction::Shl,
Phi->getIncomingValue(1 - IncrementIndex),
833 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
836 Instruction::Add, ScaledOffsets,
843 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
846 Instruction::Sub, OffsetsIncoming,
848 "PreIncrementStartIndex",
849 Phi->getIncomingBlock(1 - IncrementIndex)->back().getIterator());
850 Phi->setIncomingValue(1 - IncrementIndex, OffsetsIncoming);
856 if (
I->getIntrinsicID() == Intrinsic::masked_gather) {
858 Value *
Load = tryCreateMaskedGatherBaseWB(
I, Phi, Builder, Immediate);
863 Builder.
Insert(EndResult);
864 Builder.
Insert(NewInduction);
867 EndResult = NewInduction =
868 tryCreateMaskedScatterBaseWB(
I, Phi, Builder, Immediate);
873 Phi->setIncomingValue(IncrementIndex, NewInduction);
878void MVEGatherScatterLowering::pushOutAdd(PHINode *&Phi,
879 Value *OffsSecondOperand,
880 unsigned StartIndex) {
881 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: optimising add instruction\n");
882 assert(
Phi->getNumIncomingValues() == 2);
883 BasicBlock *NewIndexBlock =
Phi->getIncomingBlock(StartIndex);
887 Instruction::Add,
Phi->getIncomingValue(StartIndex), OffsSecondOperand,
888 "PushedOutAdd", InsertionPoint);
889 unsigned IncrementIndex = StartIndex == 0 ? 1 : 0;
892 Value *IncrementIndexValue =
Phi->getIncomingValue(IncrementIndex);
893 BasicBlock *IncrementIndexBlock =
Phi->getIncomingBlock(IncrementIndex);
894 Phi->setIncomingValue(0, NewIndex);
895 Phi->setIncomingBlock(0, NewIndexBlock);
896 Phi->setIncomingValue(1, IncrementIndexValue);
897 Phi->setIncomingBlock(1, IncrementIndexBlock);
900void MVEGatherScatterLowering::pushOutMulShl(
unsigned Opcode, PHINode *&Phi,
901 Value *IncrementPerRound,
902 Value *OffsSecondOperand,
903 unsigned LoopIncrement,
905 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: optimising mul instruction\n");
906 assert(
Phi->getNumIncomingValues() == 2);
911 Phi->getIncomingBlock(LoopIncrement == 1 ? 0 : 1);
917 Phi->getIncomingValue(LoopIncrement == 1 ? 0 : 1),
918 OffsSecondOperand,
"PushedOutMul", InsertionPoint);
922 OffsSecondOperand,
"Product", InsertionPoint);
923 BasicBlock *NewIncrementBlock =
Phi->getIncomingBlock(LoopIncrement);
926 NewIncrInsertPt = std::prev(NewIncrInsertPt);
930 Instruction::Add, Phi, Product,
"IncrementPushedOutMul", NewIncrInsertPt);
932 Phi->setIncomingValue(0, StartIndex);
933 Phi->setIncomingBlock(0, StartIndexBlock);
934 Phi->setIncomingValue(1, NewIncrement);
935 Phi->setIncomingBlock(1, NewIncrementBlock);
941 if (
I->use_empty()) {
945 for (
User *U :
I->users()) {
953 if ((OpCode == Instruction::Add || OpCode == Instruction::Mul ||
954 OpCode == Instruction::Shl ||
965bool MVEGatherScatterLowering::optimiseOffsets(
Value *Offsets, BasicBlock *BB,
967 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: trying to optimize: "
968 << *Offsets <<
"\n");
1018 if (
Phi->getParent() !=
L->getHeader())
1022 BinaryOperator *IncInstruction;
1025 IncInstruction->
getOpcode() != Instruction::Add)
1028 int IncrementingBlock =
Phi->getIncomingValue(0) == IncInstruction ? 0 : 1;
1033 if (IncrementPerRound->
getType() != OffsSecondOperand->
getType() ||
1034 !
L->isLoopInvariant(OffsSecondOperand))
1048 if (
Phi->hasNUses(2)) {
1056 IncrementPerRound,
"LoopIncrement", IncInstruction->
getIterator());
1057 Phi->setIncomingValue(IncrementingBlock, IncInstruction);
1064 NewPhi->
addIncoming(
Phi->getIncomingValue(IncrementingBlock == 1 ? 0 : 1),
1065 Phi->getIncomingBlock(IncrementingBlock == 1 ? 0 : 1));
1068 IncrementPerRound,
"LoopIncrement", IncInstruction->
getIterator());
1070 Phi->getIncomingBlock(IncrementingBlock));
1071 IncrementingBlock = 1;
1078 case Instruction::Add:
1079 case Instruction::Or:
1080 pushOutAdd(NewPhi, OffsSecondOperand, IncrementingBlock == 1 ? 0 : 1);
1082 case Instruction::Mul:
1083 case Instruction::Shl:
1084 pushOutMulShl(Offs->
getOpcode(), NewPhi, IncrementPerRound,
1085 OffsSecondOperand, IncrementingBlock, Builder);
1090 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: simplified loop variable "
1115 if (
N < (
unsigned)(1 << (TargetElemSize - 1))) {
1116 NonVectorVal = Builder.CreateVectorSplat(
1129 if (XElType && !YElType) {
1130 FixSummands(XElType,
Y);
1132 }
else if (YElType && !XElType) {
1133 FixSummands(YElType,
X);
1136 assert(XElType && YElType &&
"Unknown vector types");
1138 if (XElType != YElType) {
1139 LLVM_DEBUG(
dbgs() <<
"masked gathers/scatters: incompatible gep offsets\n");
1148 if (!ConstX || !ConstY)
1156 if (!ConstXEl || !ConstYEl ||
1159 (
unsigned)(1 << (TargetElemSize - 1)))
1164 Value *XScale = Builder.CreateVectorSplat(
1167 Value *YScale = Builder.CreateVectorSplat(
1170 Value *
Add = Builder.CreateAdd(Builder.CreateMul(
X, XScale),
1171 Builder.CreateMul(
Y, YScale));
1179Value *MVEGatherScatterLowering::foldGEP(GetElementPtrInst *
GEP,
1180 Value *&Offsets,
unsigned &Scale,
1182 Value *GEPPtr =
GEP->getPointerOperand();
1184 Scale =
DL->getTypeAllocSize(
GEP->getSourceElementType());
1191 Value *BaseBasePtr = foldGEP(BaseGEP, Offsets, Scale, Builder);
1195 Offsets, Scale,
GEP->getOperand(1),
1196 DL->getTypeAllocSize(
GEP->getSourceElementType()), Builder);
1197 if (Offsets ==
nullptr)
1205bool MVEGatherScatterLowering::optimiseAddress(
Value *
Address, BasicBlock *BB,
1221 assert(Scale == 1 &&
"Expected to fold GEP to a scale of 1");
1227 "gep.merged",
GEP->getIterator());
1229 <<
"\n new : " << *NewAddress <<
"\n");
1230 GEP->replaceAllUsesWith(
1236 Changed |= optimiseOffsets(
GEP->getOperand(1),
GEP->getParent(), LI);
1240bool MVEGatherScatterLowering::runOnFunction(
Function &
F) {
1243 auto &TPC = getAnalysis<TargetPassConfig>();
1244 auto &TM = TPC.getTM<TargetMachine>();
1245 auto *
ST = &TM.getSubtarget<ARMSubtarget>(
F);
1246 if (!
ST->hasMVEIntegerOps())
1248 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1249 DL = &
F.getDataLayout();
1255 for (BasicBlock &BB :
F) {
1258 for (Instruction &
I : BB) {
1260 if (
II &&
II->getIntrinsicID() == Intrinsic::masked_gather &&
1263 Changed |= optimiseAddress(
II->getArgOperand(0),
II->getParent(), LI);
1264 }
else if (
II &&
II->getIntrinsicID() == Intrinsic::masked_scatter &&
1267 Changed |= optimiseAddress(
II->getArgOperand(1),
II->getParent(), LI);
1271 for (IntrinsicInst *
I : Gathers) {
1281 for (IntrinsicInst *
I : Scatters) {
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Decomposition decomposeGEP(GEPOperator &GEP, ConstraintInfo &Info, bool IsSigned, const DataLayout &DL)
static bool runOnFunction(Function &F, bool PostInlining)
static bool isAddLikeOr(Instruction *I, const DataLayout &DL)
static bool hasAllGatScatUsers(Instruction *I, const DataLayout &DL)
static bool checkOffsetSize(Value *Offsets, unsigned TargetElemCount)
static Value * CheckAndCreateOffsetAdd(Value *X, unsigned ScaleX, Value *Y, unsigned ScaleY, IRBuilder<> &Builder)
cl::opt< bool > EnableMaskedGatherScatters("enable-arm-maskedgatscat", cl::Hidden, cl::init(true), cl::desc("Enable the generation of masked gathers and scatters"))
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
This file describes how to lower LLVM code to machine code.
Target-Independent Code Generator Pass Configuration Options pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
const Instruction & back() const
InstListType::iterator iterator
Instruction iterators...
BinaryOps getOpcode() const
static LLVM_ABI BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
Type * getDestTy() const
Return the destination type, as a convenience.
This is the shared class of boolean and integer constants.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
This is an important base class in LLVM.
LLVM_ABI Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
A parsed version of the target data layout string in and methods for querying it.
Class to represent fixed width SIMD vectors.
unsigned getNumElements() const
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
FunctionPass class - This class is used to implement most global optimizations.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
LLVM_ABI Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
Value * CreateIntToPtr(Value *V, Type *DestTy, const Twine &Name="")
void SetCurrentDebugLocation(const DebugLoc &L)
Set location information used by debugging information.
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
ConstantInt * getInt32(uint32_t C)
Get a constant 32-bit value.
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
PointerType * getPtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
void push_back(const T &Elt)
bool isVectorTy() const
True if this is an instance of VectorType.
bool isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
LLVM_ABI TypeSize getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM_ABI Type * getWithNewBitWidth(unsigned NewBitWidth) const
Given an integer or vector type, change the lane bitwidth to NewBitwidth, whilst keeping the old numb...
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Type * getElementType() const
const ParentTy * getParent() const
self_iterator getIterator()
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
bool match(Val *V, const Pattern &P)
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< PhiNode * > Phi
friend class Instruction
Iterator for Instructions in a `BasicBlock.
unsigned getNumElements(Type *Ty)
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool haveNoCommonBitsSet(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return true if LHS and RHS have no common bits set.
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).
Pass * createMVEGatherScatterLoweringPass()
LLVM_ABI bool SimplifyInstructionsInBlock(BasicBlock *BB, const TargetLibraryInfo *TLI=nullptr)
Scan the specified basic block and try to simplify any instructions in it and recursively delete dead...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI bool matchSimpleRecurrence(const PHINode *P, BinaryOperator *&BO, Value *&Start, Value *&Step)
Attempt to match a simple first order recurrence cycle of the form: iv = phi Ty [Start,...
bool isGatherScatter(IntrinsicInst *IntInst)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void initializeMVEGatherScatterLoweringPass(PassRegistry &)
@ Increment
Incrementally increasing token ID.
This struct is a compact representation of a valid (non-zero power of two) alignment.