Go to the documentation of this file.
22 #include "llvm/IR/IntrinsicsAMDGPU.h"
23 #include "llvm/IR/IntrinsicsR600.h"
27 #define DEBUG_TYPE "amdgpu-promote-alloca"
34 "disable-promote-alloca-to-vector",
35 cl::desc(
"Disable promote alloca to vector"),
39 "disable-promote-alloca-to-lds",
40 cl::desc(
"Disable promote alloca to LDS"),
44 "amdgpu-promote-alloca-to-vector-limit",
45 cl::desc(
"Maximum byte size to consider promote alloca to vector"),
57 StringRef getPassName()
const override {
return "AMDGPU Promote Alloca"; }
59 bool handleAlloca(
AllocaInst &
I,
bool SufficientLDS);
67 class AMDGPUPromoteAllocaImpl {
78 bool IsAMDGCN =
false;
79 bool IsAMDHSA =
false;
86 bool collectUsesWithPtrTypes(
Value *BaseAlloca,
88 std::vector<Value*> &WorkList)
const;
94 bool binaryOpIsDerivedFromSameAlloca(
Value *Alloca,
Value *Val,
96 int OpIdx0,
int OpIdx1)
const;
99 bool hasSufficientLocalMem(
const Function &
F);
101 bool handleAlloca(
AllocaInst &
I,
bool SufficientLDS);
108 class AMDGPUPromoteAllocaToVector :
public FunctionPass {
117 return "AMDGPU Promote Alloca to vector";
132 "AMDGPU promote alloca to vector or LDS",
false,
false)
149 if (
auto *TPC = getAnalysisIfAvailable<TargetPassConfig>()) {
150 return AMDGPUPromoteAllocaImpl(TPC->getTM<
TargetMachine>()).run(
F);
157 bool Changed = AMDGPUPromoteAllocaImpl(TM).run(
F);
170 const Triple &TT =
TM.getTargetTriple();
175 if (!
ST.isPromoteAllocaEnabled())
180 MaxVGPRs =
ST.getMaxNumVGPRs(
ST.getWavesPerEU(
F).first);
189 bool SufficientLDS = hasSufficientLocalMem(
F);
190 bool Changed =
false;
196 Allocas.push_back(AI);
200 if (handleAlloca(*AI, SufficientLDS))
207 std::pair<Value *, Value *>
221 ST.makeLIDRangeMetadata(LocalSizeY);
222 ST.makeLIDRangeMetadata(LocalSizeZ);
224 return std::make_pair(LocalSizeY, LocalSizeZ);
267 F.removeFnAttr(
"amdgpu-no-dispatch-ptr");
279 Value *GEPXY =
Builder.CreateConstInBoundsGEP1_64(I32Ty, CastDispatchPtr, 1);
282 Value *GEPZU =
Builder.CreateConstInBoundsGEP1_64(I32Ty, CastDispatchPtr, 2);
286 LoadXY->
setMetadata(LLVMContext::MD_invariant_load, MD);
287 LoadZU->
setMetadata(LLVMContext::MD_invariant_load, MD);
288 ST.makeLIDRangeMetadata(LoadZU);
293 return std::make_pair(
Y, LoadZU);
305 IntrID = IsAMDGCN ? (
Intrinsic::ID)Intrinsic::amdgcn_workitem_id_x
307 AttrName =
"amdgpu-no-workitem-id-x";
310 IntrID = IsAMDGCN ? (
Intrinsic::ID)Intrinsic::amdgcn_workitem_id_y
312 AttrName =
"amdgpu-no-workitem-id-y";
316 IntrID = IsAMDGCN ? (
Intrinsic::ID)Intrinsic::amdgcn_workitem_id_z
318 AttrName =
"amdgpu-no-workitem-id-z";
326 ST.makeLIDRangeMetadata(CI);
327 F->removeFnAttr(AttrName);
339 const std::map<GetElementPtrInst *, Value *> &GEPIdx) {
344 auto I = GEPIdx.find(
GEP);
345 assert(
I != GEPIdx.end() &&
"Must have entry for GEP!");
353 unsigned BW =
DL.getIndexTypeSizeInBits(
GEP->getType());
355 APInt ConstOffset(BW, 0);
356 if (
GEP->getPointerOperand()->stripPointerCasts() != Alloca ||
357 !
GEP->collectOffset(
DL, BW, VarOffsets, ConstOffset))
360 unsigned VecElemSize =
DL.getTypeAllocSize(VecElemTy);
361 if (VarOffsets.
size() > 1)
364 if (VarOffsets.
size() == 1) {
367 const auto &VarOffset = VarOffsets.
front();
368 if (!ConstOffset.isZero() || VarOffset.second != VecElemSize)
370 return VarOffset.first;
385 if (DisablePromoteAllocaToVector) {
386 LLVM_DEBUG(
dbgs() <<
" Promotion alloca to vector is disabled\n");
391 auto *VectorTy = dyn_cast<FixedVectorType>(AllocaTy);
392 if (
auto *ArrayTy = dyn_cast<ArrayType>(AllocaTy)) {
394 ArrayTy->getNumElements() > 0)
399 unsigned Limit = PromoteAllocaToVectorLimit ? PromoteAllocaToVectorLimit * 8
402 if (
DL.getTypeSizeInBits(AllocaTy) * 4 > Limit) {
404 << MaxVGPRs <<
" registers available\n");
414 if (!VectorTy || VectorTy->getNumElements() > 16 ||
415 VectorTy->getNumElements() < 2) {
420 std::map<GetElementPtrInst*, Value*> GEPVectorIdx;
426 Type *VecEltTy = VectorTy->getElementType();
427 while (!
Uses.empty()) {
429 Instruction *Inst = dyn_cast<Instruction>(U->getUser());
433 if (isa<StoreInst>(Inst) &&
438 Ptr = Ptr->stripPointerCasts();
442 DL.getTypeStoreSize(AccessTy))
446 bool IsSimple = isa<LoadInst>(Inst) ? cast<LoadInst>(Inst)->isSimple()
447 : cast<StoreInst>(Inst)->isSimple();
452 WorkList.push_back(Inst);
456 if (isa<BitCastInst>(Inst)) {
463 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(Inst)) {
473 GEPVectorIdx[
GEP] = Index;
484 return isAssumeLikeIntrinsic(cast<Instruction>(U));
492 LLVM_DEBUG(
dbgs() <<
" Converting alloca to vector " << *AllocaTy <<
" -> "
493 << *VectorTy <<
'\n');
497 switch (Inst->getOpcode()) {
499 Value *Ptr = cast<LoadInst>(Inst)->getPointerOperand();
502 Value *BitCast =
Builder.CreateBitCast(Alloca, VecPtrTy);
503 Value *VecValue =
Builder.CreateLoad(VectorTy, BitCast);
504 Value *ExtractElement =
Builder.CreateExtractElement(VecValue, Index);
505 if (Inst->getType() != VecEltTy)
506 ExtractElement =
Builder.CreateBitOrPointerCast(ExtractElement, Inst->
getType());
507 Inst->replaceAllUsesWith(ExtractElement);
508 Inst->eraseFromParent();
513 Value *Ptr =
SI->getPointerOperand();
516 Value *BitCast =
Builder.CreateBitCast(Alloca, VecPtrTy);
517 Value *VecValue =
Builder.CreateLoad(VectorTy, BitCast);
518 Value *Elt =
SI->getValueOperand();
519 if (Elt->
getType() != VecEltTy)
520 Elt =
Builder.CreateBitOrPointerCast(Elt, VecEltTy);
521 Value *NewVecValue =
Builder.CreateInsertElement(VecValue, Elt, Index);
522 Builder.CreateStore(NewVecValue, BitCast);
523 Inst->eraseFromParent();
541 case Intrinsic::memmove:
542 case Intrinsic::memset:
543 case Intrinsic::lifetime_start:
544 case Intrinsic::lifetime_end:
545 case Intrinsic::invariant_start:
546 case Intrinsic::invariant_end:
547 case Intrinsic::launder_invariant_group:
548 case Intrinsic::strip_invariant_group:
549 case Intrinsic::objectsize:
556 bool AMDGPUPromoteAllocaImpl::binaryOpIsDerivedFromSameAlloca(
564 if (isa<ConstantPointerNull>(OtherOp))
568 if (!isa<AllocaInst>(OtherObj))
577 if (OtherObj != BaseAlloca) {
579 dbgs() <<
"Found a binary instruction with another alloca object\n");
586 bool AMDGPUPromoteAllocaImpl::collectUsesWithPtrTypes(
587 Value *BaseAlloca,
Value *Val, std::vector<Value *> &WorkList)
const {
597 WorkList.push_back(
User);
602 if (UseInst->
getOpcode() == Instruction::PtrToInt)
605 if (
LoadInst *LI = dyn_cast<LoadInst>(UseInst)) {
606 if (LI->isVolatile())
612 if (
StoreInst *
SI = dyn_cast<StoreInst>(UseInst)) {
613 if (
SI->isVolatile())
617 if (
SI->getPointerOperand() != Val)
619 }
else if (
AtomicRMWInst *RMW = dyn_cast<AtomicRMWInst>(UseInst)) {
620 if (RMW->isVolatile())
623 if (CAS->isVolatile())
629 if (
ICmpInst *ICmp = dyn_cast<ICmpInst>(UseInst)) {
630 if (!binaryOpIsDerivedFromSameAlloca(BaseAlloca, Val, ICmp, 0, 1))
634 WorkList.push_back(ICmp);
637 if (UseInst->
getOpcode() == Instruction::AddrSpaceCast) {
642 WorkList.push_back(
User);
648 if (isa<InsertValueInst>(
User) || isa<InsertElementInst>(
User))
657 if (!
GEP->isInBounds())
664 if (!binaryOpIsDerivedFromSameAlloca(BaseAlloca, Val,
SI, 1, 2))
669 if (
PHINode *Phi = dyn_cast<PHINode>(UseInst)) {
672 switch (Phi->getNumIncomingValues()) {
676 if (!binaryOpIsDerivedFromSameAlloca(BaseAlloca, Val, Phi, 0, 1))
684 WorkList.push_back(
User);
685 if (!collectUsesWithPtrTypes(BaseAlloca,
User, WorkList))
692 bool AMDGPUPromoteAllocaImpl::hasSufficientLocalMem(
const Function &
F) {
701 PointerType *PtrTy = dyn_cast<PointerType>(ParamTy);
704 LLVM_DEBUG(
dbgs() <<
"Function has local memory argument. Promoting to "
705 "local memory disabled.\n");
710 LocalMemLimit =
ST.getLocalMemorySize();
711 if (LocalMemLimit == 0)
721 if (
Use->getParent()->getParent() == &
F)
725 if (VisitedConstants.
insert(
C).second)
737 if (visitUsers(&GV, &GV)) {
745 while (!
Stack.empty()) {
747 if (visitUsers(&GV,
C)) {
768 LLVM_DEBUG(
dbgs() <<
"Function has a reference to externally allocated "
769 "local memory. Promoting to local memory "
781 llvm::sort(AllocatedSizes, [](std::pair<uint64_t, Align>
LHS,
782 std::pair<uint64_t, Align>
RHS) {
783 return LHS.second <
RHS.second;
787 CurrentLocalMemUsage = 0;
793 for (
auto Alloc : AllocatedSizes) {
794 CurrentLocalMemUsage =
alignTo(CurrentLocalMemUsage, Alloc.second);
795 CurrentLocalMemUsage += Alloc.first;
798 unsigned MaxOccupancy =
ST.getOccupancyWithLocalMemSize(CurrentLocalMemUsage,
806 unsigned OccupancyHint =
ST.getWavesPerEU(
F).second;
807 if (OccupancyHint == 0)
811 OccupancyHint =
std::min(OccupancyHint,
ST.getMaxWavesPerEU());
815 MaxOccupancy =
std::min(OccupancyHint, MaxOccupancy);
819 unsigned MaxSizeWithWaveCount
820 =
ST.getMaxLocalMemSizeWithWaveCount(MaxOccupancy,
F);
823 if (CurrentLocalMemUsage > MaxSizeWithWaveCount)
826 LocalMemLimit = MaxSizeWithWaveCount;
830 <<
" Rounding size to " << MaxSizeWithWaveCount
831 <<
" with a maximum occupancy of " << MaxOccupancy <<
'\n'
832 <<
" and " << (LocalMemLimit - CurrentLocalMemUsage)
833 <<
" available for promotion\n");
839 bool AMDGPUPromoteAllocaImpl::handleAlloca(
AllocaInst &
I,
bool SufficientLDS) {
842 if (!
I.isStaticAlloca() ||
I.isArrayAllocation())
849 Type *AllocaTy =
I.getAllocatedType();
856 if (DisablePromoteAllocaToLDS)
859 const Function &ContainingFunction = *
I.getParent()->getParent();
872 <<
" promote alloca to LDS not supported with calling convention.\n");
881 unsigned WorkGroupSize =
ST.getFlatWorkGroupSizes(ContainingFunction).second;
884 DL.getValueOrABITypeAlignment(
I.getAlign(),
I.getAllocatedType());
893 uint32_t AllocSize = WorkGroupSize *
DL.getTypeAllocSize(AllocaTy);
894 NewSize += AllocSize;
896 if (NewSize > LocalMemLimit) {
898 <<
" bytes of local memory not available to promote\n");
902 CurrentLocalMemUsage = NewSize;
904 std::vector<Value*> WorkList;
906 if (!collectUsesWithPtrTypes(&
I, &
I, WorkList)) {
926 Value *TCntY, *TCntZ;
928 std::tie(TCntY, TCntZ) = getLocalSizeYZ(
Builder);
933 Value *Tmp0 =
Builder.CreateMul(TCntY, TCntZ,
"",
true,
true);
934 Tmp0 =
Builder.CreateMul(Tmp0, TIdX);
935 Value *Tmp1 =
Builder.CreateMul(TIdY, TCntZ,
"",
true,
true);
937 TID =
Builder.CreateAdd(TID, TIdZ);
945 I.mutateType(
Offset->getType());
946 I.replaceAllUsesWith(Offset);
951 for (
Value *V : WorkList) {
954 if (
ICmpInst *CI = dyn_cast<ICmpInst>(V)) {
959 if (isa<ConstantPointerNull>(CI->
getOperand(0)))
962 if (isa<ConstantPointerNull>(CI->
getOperand(1)))
970 if (isa<AddrSpaceCastInst>(V))
978 V->mutateType(NewTy);
982 if (isa<ConstantPointerNull>(
SI->getOperand(1)))
985 if (isa<ConstantPointerNull>(
SI->getOperand(2)))
987 }
else if (
PHINode *Phi = dyn_cast<PHINode>(V)) {
988 for (
unsigned I = 0,
E = Phi->getNumIncomingValues();
I !=
E; ++
I) {
989 if (isa<ConstantPointerNull>(Phi->getIncomingValue(
I)))
999 switch (
Intr->getIntrinsicID()) {
1000 case Intrinsic::lifetime_start:
1001 case Intrinsic::lifetime_end:
1003 Intr->eraseFromParent();
1006 case Intrinsic::memmove:
1010 DeferredIntrs.push_back(
Intr);
1012 case Intrinsic::memset: {
1017 Intr->eraseFromParent();
1020 case Intrinsic::invariant_start:
1021 case Intrinsic::invariant_end:
1022 case Intrinsic::launder_invariant_group:
1023 case Intrinsic::strip_invariant_group:
1024 Intr->eraseFromParent();
1029 case Intrinsic::objectsize: {
1032 Mod, Intrinsic::objectsize,
1039 {Src,
Intr->getOperand(1),
Intr->getOperand(2),
Intr->getOperand(3)});
1040 Intr->replaceAllUsesWith(NewCall);
1041 Intr->eraseFromParent();
1057 Builder.CreateMemTransferInst(
ID,
MI->getRawDest(),
MI->getDestAlign(),
1058 MI->getRawSource(),
MI->getSourceAlign(),
1059 MI->getLength(),
MI->isVolatile());
1061 for (
unsigned I = 0;
I != 2; ++
I) {
1062 if (
uint64_t Bytes =
Intr->getParamDereferenceableBytes(
I)) {
1063 B->addDereferenceableParamAttr(
I, Bytes);
1067 Intr->eraseFromParent();
1076 if (!
I.isStaticAlloca() ||
I.isArrayAllocation())
1081 Module *
Mod =
I.getParent()->getParent()->getParent();
1086 if (DisablePromoteAllocaToVector)
1090 if (!
ST.isPromoteAllocaEnabled())
1096 MaxVGPRs =
ST.getMaxNumVGPRs(
ST.getWavesPerEU(
F).first);
1100 MaxVGPRs =
std::min(MaxVGPRs, 32u);
1105 bool Changed =
false;
1111 Allocas.push_back(AI);
1123 if (skipFunction(
F))
1125 if (
auto *TPC = getAnalysisIfAvailable<TargetPassConfig>()) {
1143 return new AMDGPUPromoteAlloca();
1147 return new AMDGPUPromoteAllocaToVector();
A set of analyses that are preserved following a run of a transformation pass.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
unsigned getDestAlignment() const
FIXME: Remove this function once transition to Align is over.
This is an optimization pass for GlobalISel generic memory operations.
static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient, APInt &Remainder)
Dual division/remainder interface.
A parsed version of the target data layout string in and methods for querying it.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
bool hasExternalLinkage() const
bool isPointerTy() const
True if this is an instance of PointerType.
This class wraps the llvm.memcpy/memmove intrinsics.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
std::pair< KeyT, ValueT > & front()
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Triple - Helper class for working with autoconf configuration names.
Type * getLoadStoreType(Value *I)
A helper function that returns the type of a load or store instruction.
The instances of the Type class are immutable: once they are created, they are never changed.
This class implements a map that also provides access to all stored values in a deterministic order.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void setUnnamedAddr(UnnamedAddr Val)
Class to represent array types.
unsigned getAddressSpace() const
Return the address space for the allocation.
Class to represent fixed width SIMD vectors.
static IntegerType * getInt32Ty(LLVMContext &C)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
SmallPtrSet< MachineInstr *, 2 > Uses
LLVM Basic Block Representation.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
static const AMDGPUSubtarget & get(const MachineFunction &MF)
uint64_t getNumElements() const
iterator_range< global_iterator > globals()
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
(vector float) vec_cmpeq(*A, *B) C
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
Represent the analysis usage information of a pass.
iterator_range< use_iterator > uses()
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
ArrayRef< Type * > params() const
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments and pointer casts from the specified value,...
static FixedVectorType * get(Type *ElementType, unsigned NumElts)
@ InternalLinkage
Rename collisions when linking (static functions).
This struct is a compact representation of a valid (non-zero power of two) alignment.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This class wraps the llvm.memset intrinsic.
bool isEntryFunctionCC(CallingConv::ID CC)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
static bool isValidElementType(Type *ElemTy)
Return true if the specified type is valid as a element type.
void addDereferenceableRetAttr(uint64_t Bytes)
adds the dereferenceable attribute to the list of attributes.
An instruction for storing to memory.
This is an important base class in LLVM.
@ AMDGPU_KERNEL
Calling convention for AMDGPU code object kernels.
This instruction compares its operands according to the predicate given to the constructor.
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
initializer< Ty > init(const Ty &Val)
Class to represent pointers.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
void addRetAttr(Attribute::AttrKind Kind)
Adds the attribute to the return value.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Primary interface to the complete machine description for the target machine.
<%struct.s * > cast struct s *S to sbyte *< sbyte * > sbyte uint cast struct s *agg result to sbyte *< sbyte * > sbyte uint cast struct s *memtmp to sbyte *< sbyte * > sbyte uint ret void llc ends up issuing two memcpy or custom lower memcpy(of small size) to be ldmia/stmia. I think option 2 is better but the current register allocator cannot allocate a chunk of registers at a time. A feasible temporary solution is to use specific physical registers at the lowering time for small(<
StandardInstrumentations SI(Debug, VerifyEach)
This class represents the LLVM 'select' instruction.
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
A Module instance is used to store all the information related to an LLVM module.
Class for arbitrary precision integers.
void setOperand(unsigned i, Value *Val)
bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, bool StoreCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
void setPreservesCFG()
This function should be called by the pass, iff they do not:
StringRef - Represent a constant reference to a string, i.e.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Type * getType() const
All values are typed, get the type of this value.
Represents analyses that only rely on functions' control flow.
LLVMContext & getContext() const
All values hold a context through their type.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
@ SPIR_KERNEL
SPIR_KERNEL - Calling convention for SPIR kernel functions.
An instruction for reading from memory.
bool isAssumeLikeIntrinsic(const Instruction *I)
Return true if it is an intrinsic that cannot be speculated but also cannot trap.
an instruction that atomically reads a memory location, combines it with another value,...
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
static bool runOnFunction(Function &F, bool PostInlining)
FunctionPass * createAMDGPUPromoteAllocaToVector()
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Value * getLength() const
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVMContext & getContext() const
Get the global data context.
char & AMDGPUPromoteAllocaID
void sort(IteratorTy Start, IteratorTy End)
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
FunctionPass * createAMDGPUPromoteAlloca()
@ LOCAL_ADDRESS
Address space for local memory.
A wrapper class for inspecting calls to intrinsic functions.
unsigned getAddressSpace() const
void preserveSet()
Mark an analysis set as preserved.
static PointerType * getWithSamePointeeType(PointerType *PT, unsigned AddressSpace)
This constructs a pointer type with the same pointee type as input PointerType (or opaque pointer is ...
char & AMDGPUPromoteAllocaToVectorID
Value * getRawDest() const
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
A container for analyses that lazily runs them and caches their results.
Type * getValueType() const
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
const char LLVMTargetMachineRef TM
FunctionPass class - This class is used to implement most global optimizations.
This class represents a function call, abstracting a target machine's calling convention.
an instruction to allocate memory on the stack
Value * getOperand(unsigned i) const
void setAlignment(MaybeAlign Align)
static unsigned getPointerOperandIndex()
void reserve(size_type N)
LLVM Value Representation.
An instruction that atomically checks whether a specified value is in a memory location,...
iterator_range< user_iterator > users()
Type * getElementType() const
Class to represent function types.
A Use represents the edge between a Value definition and its users.
reference emplace_back(ArgTypes &&... Args)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.