197#include "llvm/IR/IntrinsicsAMDGPU.h"
214#define DEBUG_TYPE "amdgpu-lower-module-lds"
222 "amdgpu-super-align-lds-globals",
223 cl::desc(
"Increase alignment of LDS if it is not on align boundary"),
226enum class LoweringKind { module, table, kernel, hybrid };
228 "amdgpu-lower-module-lds-strategy",
232 clEnumValN(LoweringKind::table,
"table",
"Lower via table lookup"),
233 clEnumValN(LoweringKind::module,
"module",
"Lower via module struct"),
235 LoweringKind::kernel,
"kernel",
236 "Lower variables reachable from one kernel, otherwise abort"),
238 "Lower via mixture of above strategies")));
240template <
typename T> std::vector<T> sortByName(std::vector<T> &&V) {
241 llvm::sort(V, [](
const auto *L,
const auto *R) {
242 return L->getName() < R->getName();
244 return {std::move(V)};
247class AMDGPULowerModuleLDS {
251 removeLocalVarsFromUsedLists(
Module &M,
263 LocalVar->removeDeadConstantUsers();
288 IRBuilder<> Builder(Entry, Entry->getFirstNonPHIIt());
291 Func->getParent(), Intrinsic::donothing, {});
293 Value *UseInstance[1] = {
294 Builder.CreateConstInBoundsGEP1_32(SGV->
getValueType(), SGV, 0)};
303 struct LDSVariableReplacement {
313 static Constant *getAddressesOfVariablesInKernel(
325 auto ConstantGepIt = LDSVarsToConstantGEP.
find(GV);
326 if (ConstantGepIt != LDSVarsToConstantGEP.
end()) {
327 Elements.push_back(ConstantGepIt->second);
339 if (Variables.
empty()) {
344 const size_t NumberVariables = Variables.
size();
345 const size_t NumberKernels = kernels.
size();
354 std::vector<Constant *> overallConstantExprElts(NumberKernels);
355 for (
size_t i = 0; i < NumberKernels; i++) {
356 auto Replacement = KernelToReplacement.
find(kernels[i]);
357 overallConstantExprElts[i] =
358 (Replacement == KernelToReplacement.
end())
360 : getAddressesOfVariablesInKernel(
361 Ctx, Variables, Replacement->second.LDSVarsToConstantGEP);
376 Value *OptionalIndex) {
382 Value *tableKernelIndex = getTableLookupKernelIndex(M,
I->getFunction());
388 Builder.SetInsertPoint(
I);
392 ConstantInt::get(I32, 0),
398 Value *Address = Builder.CreateInBoundsGEP(
399 LookupTable->getValueType(), LookupTable, GEPIdx, GV->
getName());
401 Value *Loaded = Builder.CreateLoad(GV->
getType(), Address);
405 void replaceUsesInInstructionsWithTableLookup(
413 for (
size_t Index = 0; Index < ModuleScopeVariables.
size(); Index++) {
414 auto *GV = ModuleScopeVariables[Index];
421 replaceUseWithTableLookup(M, Builder, LookupTable, GV, U,
422 ConstantInt::get(I32, Index));
433 if (VariableSet.
empty())
436 for (
Function &Func : M.functions()) {
437 if (Func.isDeclaration() || !
isKernel(Func))
451 chooseBestVariableForModuleStrategy(
const DataLayout &
DL,
457 size_t UserCount = 0;
460 CandidateTy() =
default;
463 : GV(GV), UserCount(UserCount),
Size(AllocSize) {}
467 if (UserCount <
Other.UserCount) {
470 if (UserCount >
Other.UserCount) {
488 CandidateTy MostUsed;
490 for (
auto &K : LDSVars) {
492 if (K.second.size() <= 1) {
498 if (MostUsed < Candidate)
499 MostUsed = Candidate;
523 auto [It, Inserted] = tableKernelIndexCache.
try_emplace(
F);
525 auto InsertAt =
F->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
528 It->second = Builder.CreateIntrinsic(Intrinsic::amdgcn_lds_kernel_id, {});
534 static std::vector<Function *> assignLDSKernelIDToEachKernel(
542 std::vector<Function *> OrderedKernels;
543 if (!KernelsThatAllocateTableLDS.
empty() ||
544 !KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
546 for (
Function &Func : M->functions()) {
547 if (Func.isDeclaration())
552 if (KernelsThatAllocateTableLDS.
contains(&Func) ||
553 KernelsThatIndirectlyAllocateDynamicLDS.
contains(&Func)) {
555 OrderedKernels.push_back(&Func);
560 OrderedKernels = sortByName(std::move(OrderedKernels));
566 if (OrderedKernels.size() > UINT32_MAX) {
571 for (
size_t i = 0; i < OrderedKernels.size(); i++) {
575 OrderedKernels[i]->setMetadata(
"llvm.amdgcn.lds.kernel.id",
579 return OrderedKernels;
582 static void partitionVariablesIntoIndirectStrategies(
591 LoweringKindLoc != LoweringKind::hybrid
593 : chooseBestVariableForModuleStrategy(
594 M.getDataLayout(), LDSToKernelsThatNeedToAccessItIndirectly);
599 ? LDSToKernelsThatNeedToAccessItIndirectly[HybridModuleRoot]
602 for (
auto &K : LDSToKernelsThatNeedToAccessItIndirectly) {
608 assert(K.second.size() != 0);
611 DynamicVariables.
insert(GV);
615 switch (LoweringKindLoc) {
616 case LoweringKind::module:
617 ModuleScopeVariables.insert(GV);
620 case LoweringKind::table:
621 TableLookupVariables.
insert(GV);
624 case LoweringKind::kernel:
625 if (K.second.size() == 1) {
626 KernelAccessVariables.
insert(GV);
630 "cannot lower LDS '" + GV->
getName() +
631 "' to kernel access as it is reachable from multiple kernels");
635 case LoweringKind::hybrid: {
636 if (GV == HybridModuleRoot) {
637 assert(K.second.size() != 1);
638 ModuleScopeVariables.insert(GV);
639 }
else if (K.second.size() == 1) {
640 KernelAccessVariables.
insert(GV);
641 }
else if (K.second == HybridModuleRootKernels) {
642 ModuleScopeVariables.insert(GV);
644 TableLookupVariables.
insert(GV);
653 assert(ModuleScopeVariables.
size() + TableLookupVariables.
size() +
654 KernelAccessVariables.
size() + DynamicVariables.
size() ==
655 LDSToKernelsThatNeedToAccessItIndirectly.size());
668 if (ModuleScopeVariables.
empty()) {
674 LDSVariableReplacement ModuleScopeReplacement =
675 createLDSVariableReplacement(M,
"llvm.amdgcn.module.lds",
676 ModuleScopeVariables);
684 recordLDSAbsoluteAddress(&M, ModuleScopeReplacement.SGV, 0);
687 removeLocalVarsFromUsedLists(M, ModuleScopeVariables);
690 replaceLDSVariablesWithStruct(
691 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
704 for (
Function &Func : M.functions()) {
705 if (Func.isDeclaration() || !
isKernel(Func))
708 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
709 replaceLDSVariablesWithStruct(
710 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
719 markUsedByKernel(&Func, ModuleScopeReplacement.SGV);
723 return ModuleScopeReplacement.SGV;
727 lowerKernelScopeStructVariables(
736 for (
Function &Func : M.functions()) {
737 if (Func.isDeclaration() || !
isKernel(Func))
745 KernelUsedVariables.
insert(v);
753 KernelUsedVariables.
insert(v);
759 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
761 KernelUsedVariables.
erase(v);
765 if (KernelUsedVariables.
empty()) {
777 if (!Func.hasName()) {
781 std::string VarName =
782 (
Twine(
"llvm.amdgcn.kernel.") + Func.getName() +
".lds").str();
785 createLDSVariableReplacement(M, VarName, KernelUsedVariables);
793 markUsedByKernel(&Func, Replacement.SGV);
796 removeLocalVarsFromUsedLists(M, KernelUsedVariables);
797 KernelToReplacement[&Func] = Replacement;
800 replaceLDSVariablesWithStruct(
801 M, KernelUsedVariables, Replacement, [&Func](
Use &U) {
803 return I &&
I->getFunction() == &Func;
806 return KernelToReplacement;
826 Align MaxDynamicAlignment(1);
830 MaxDynamicAlignment =
836 UpdateMaxAlignment(GV);
840 UpdateMaxAlignment(GV);
849 N->setAlignment(MaxDynamicAlignment);
859 std::vector<Function *>
const &OrderedKernels) {
861 if (!KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
866 std::vector<Constant *> newDynamicLDS;
869 for (
auto &func : OrderedKernels) {
871 if (KernelsThatIndirectlyAllocateDynamicLDS.
contains(func)) {
878 buildRepresentativeDynamicLDSInstance(M, LDSUsesInfo, func);
880 KernelToCreatedDynamicLDS[func] =
N;
882 markUsedByKernel(func,
N);
884 newDynamicLDS.push_back(
N);
889 assert(OrderedKernels.size() == newDynamicLDS.size());
895 "llvm.amdgcn.dynlds.offset.table",
nullptr,
906 replaceUseWithTableLookup(M, Builder, table, GV, U,
nullptr);
910 return KernelToCreatedDynamicLDS;
913 bool runOnModule(
Module &M) {
915 bool Changed = superAlignLDSGlobals(M);
931 LDSToKernelsThatNeedToAccessItIndirectly[GV].insert(
F);
940 partitionVariablesIntoIndirectStrategies(
941 M, LDSUsesInfo, LDSToKernelsThatNeedToAccessItIndirectly,
942 ModuleScopeVariables, TableLookupVariables, KernelAccessVariables,
949 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
950 ModuleScopeVariables);
952 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
953 TableLookupVariables);
956 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
959 GlobalVariable *MaybeModuleScopeStruct = lowerModuleScopeStructVariables(
960 M, ModuleScopeVariables, KernelsThatAllocateModuleLDS);
963 lowerKernelScopeStructVariables(M, LDSUsesInfo, ModuleScopeVariables,
964 KernelsThatAllocateModuleLDS,
965 MaybeModuleScopeStruct);
968 for (
auto &GV : KernelAccessVariables) {
969 auto &funcs = LDSToKernelsThatNeedToAccessItIndirectly[GV];
970 assert(funcs.size() == 1);
971 LDSVariableReplacement Replacement =
972 KernelToReplacement[*(funcs.begin())];
977 replaceLDSVariablesWithStruct(M, Vec, Replacement, [](
Use &U) {
983 std::vector<Function *> OrderedKernels =
984 assignLDSKernelIDToEachKernel(&M, KernelsThatAllocateTableLDS,
985 KernelsThatIndirectlyAllocateDynamicLDS);
987 if (!KernelsThatAllocateTableLDS.
empty()) {
993 auto TableLookupVariablesOrdered =
994 sortByName(std::vector<GlobalVariable *>(TableLookupVariables.
begin(),
995 TableLookupVariables.
end()));
998 M, TableLookupVariablesOrdered, OrderedKernels, KernelToReplacement);
999 replaceUsesInInstructionsWithTableLookup(M, TableLookupVariablesOrdered,
1004 lowerDynamicLDSVariables(M, LDSUsesInfo,
1005 KernelsThatIndirectlyAllocateDynamicLDS,
1006 DynamicVariables, OrderedKernels);
1011 for (
auto *KernelSet : {&KernelsThatIndirectlyAllocateDynamicLDS,
1012 &KernelsThatAllocateTableLDS})
1021 for (
Function &Func : M.functions()) {
1022 if (Func.isDeclaration() || !
isKernel(Func))
1036 const bool AllocateModuleScopeStruct =
1037 MaybeModuleScopeStruct &&
1038 KernelsThatAllocateModuleLDS.
contains(&Func);
1040 auto Replacement = KernelToReplacement.
find(&Func);
1041 const bool AllocateKernelScopeStruct =
1042 Replacement != KernelToReplacement.
end();
1044 const bool AllocateDynamicVariable =
1045 KernelToCreatedDynamicLDS.
contains(&Func);
1049 if (AllocateModuleScopeStruct) {
1055 if (AllocateKernelScopeStruct) {
1058 recordLDSAbsoluteAddress(&M, KernelStruct,
Offset);
1066 if (AllocateDynamicVariable) {
1067 GlobalVariable *DynamicVariable = KernelToCreatedDynamicLDS[&Func];
1069 recordLDSAbsoluteAddress(&M, DynamicVariable,
Offset);
1084 if (AllocateDynamicVariable)
1087 Func.addFnAttr(
"amdgpu-lds-size", Buffer);
1106 static bool superAlignLDSGlobals(
Module &M) {
1109 if (!SuperAlignLDSGlobals) {
1113 for (
auto &GV : M.globals()) {
1133 Alignment = std::max(Alignment,
Align(16));
1134 }
else if (GVSize > 4) {
1136 Alignment = std::max(Alignment,
Align(8));
1137 }
else if (GVSize > 2) {
1139 Alignment = std::max(Alignment,
Align(4));
1140 }
else if (GVSize > 1) {
1142 Alignment = std::max(Alignment,
Align(2));
1153 static LDSVariableReplacement createLDSVariableReplacement(
1154 Module &M, std::string VarName,
1171 auto Sorted = sortByName(std::vector<GlobalVariable *>(
1172 LDSVarsToTransform.
begin(), LDSVarsToTransform.
end()));
1183 std::vector<GlobalVariable *> LocalVars;
1185 LocalVars.reserve(LDSVarsToTransform.
size());
1186 IsPaddingField.
reserve(LDSVarsToTransform.
size());
1189 for (
auto &
F : LayoutFields) {
1192 Align DataAlign =
F.Alignment;
1195 if (
uint64_t Rem = CurrentOffset % DataAlignV) {
1196 uint64_t Padding = DataAlignV - Rem;
1208 CurrentOffset += Padding;
1211 LocalVars.push_back(FGV);
1213 CurrentOffset +=
F.Size;
1217 std::vector<Type *> LocalVarTypes;
1218 LocalVarTypes.reserve(LocalVars.size());
1220 LocalVars.cbegin(), LocalVars.cend(), std::back_inserter(LocalVarTypes),
1235 for (
size_t I = 0;
I < LocalVars.size();
I++) {
1237 Constant *GEPIdx[] = {ConstantInt::get(I32, 0), ConstantInt::get(I32,
I)};
1239 if (IsPaddingField[
I]) {
1246 assert(Map.size() == LDSVarsToTransform.
size());
1247 return {SGV, std::move(Map)};
1250 template <
typename PredicateTy>
1251 static void replaceLDSVariablesWithStruct(
1253 const LDSVariableReplacement &Replacement, PredicateTy
Predicate) {
1260 auto LDSVarsToTransform = sortByName(std::vector<GlobalVariable *>(
1261 LDSVarsToTransformArg.
begin(), LDSVarsToTransformArg.
end()));
1267 const size_t NumberVars = LDSVarsToTransform.
size();
1268 if (NumberVars > 1) {
1270 AliasScopes.
reserve(NumberVars);
1272 for (
size_t I = 0;
I < NumberVars;
I++) {
1276 NoAliasList.
append(&AliasScopes[1], AliasScopes.
end());
1281 for (
size_t I = 0;
I < NumberVars;
I++) {
1283 Constant *
GEP = Replacement.LDSVarsToConstantGEP.at(GV);
1287 APInt APOff(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
1288 GEP->stripAndAccumulateInBoundsConstantOffsets(
DL, APOff);
1295 NoAliasList[
I - 1] = AliasScopes[
I - 1];
1301 refineUsesAlignmentAndAA(
GEP,
A,
DL, AliasScope, NoAlias);
1305 static void refineUsesAlignmentAndAA(
Value *Ptr,
Align A,
1307 MDNode *NoAlias,
unsigned MaxDepth = 5) {
1308 if (!MaxDepth || (
A == 1 && !AliasScope))
1315 if (AliasScope &&
I->mayReadOrWriteMemory()) {
1316 MDNode *AS =
I->getMetadata(LLVMContext::MD_alias_scope);
1319 I->setMetadata(LLVMContext::MD_alias_scope, AS);
1321 MDNode *NA =
I->getMetadata(LLVMContext::MD_noalias);
1345 if (Intersection.empty()) {
1350 I->setMetadata(LLVMContext::MD_noalias, NA);
1355 LI->setAlignment(std::max(
A, LI->getAlign()));
1359 if (
SI->getPointerOperand() == Ptr)
1360 SI->setAlignment(std::max(
A,
SI->getAlign()));
1366 if (AI->getPointerOperand() == Ptr)
1367 AI->setAlignment(std::max(
A, AI->getAlign()));
1371 if (AI->getPointerOperand() == Ptr)
1372 AI->setAlignment(std::max(
A, AI->getAlign()));
1376 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1378 if (
GEP->getPointerOperand() == Ptr) {
1380 if (
GEP->accumulateConstantOffset(
DL, Off))
1382 refineUsesAlignmentAndAA(
GEP, GA,
DL, AliasScope, NoAlias,
1388 if (
I->getOpcode() == Instruction::BitCast ||
1389 I->getOpcode() == Instruction::AddrSpaceCast)
1390 refineUsesAlignmentAndAA(
I,
A,
DL, AliasScope, NoAlias, MaxDepth - 1);
1396class AMDGPULowerModuleLDSLegacy :
public ModulePass {
1409 bool runOnModule(
Module &M)
override {
1411 auto &TPC = getAnalysis<TargetPassConfig>();
1420char AMDGPULowerModuleLDSLegacy::ID = 0;
1425 "Lower uses of LDS variables from non-kernel functions",
1429 "Lower uses of LDS variables from non-kernel functions",
1434 return new AMDGPULowerModuleLDSLegacy(TM);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
The AMDGPU TargetMachine interface definition for hw codegen targets.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Forward Handle Accesses
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file provides an interface for laying out a sequence of fields as a struct in a way that attempt...
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This is the interface for a metadata-based scoped no-alias analysis.
This file defines generic set operations that may be used on set's of different types,...
Target-Independent Code Generator Pass Configuration Options pass.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
bool empty() const
empty - Check if the array is empty.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
The basic data container for the call graph of a Module of IR.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
This is an important base class in LLVM.
LLVM_ABI void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Implements a dense probed hash-table based set.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
LLVM_ABI bool isAbsoluteSymbolRef() const
Returns whether this is a reference to an absolute symbol.
PointerType * getType() const
Global values are always pointers.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
Type * getValueType() const
bool hasInitializer() const
Definitions have initializers, declarations don't.
LLVM_ABI uint64_t getGlobalSize(const DataLayout &DL) const
Get the size of this global variable in bytes.
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalVariable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
bool runOnModule(Module &) override
ImmutablePasses are never run.
This is an important class for using LLVM in a threaded context.
MDNode * createAnonymousAliasScope(MDNode *Domain, StringRef Name=StringRef())
Return metadata appropriate for an alias scope root node.
MDNode * createAnonymousAliasScopeDomain(StringRef Name=StringRef())
Return metadata appropriate for an alias scope domain node.
static LLVM_ABI MDNode * getMostGenericAliasScope(MDNode *A, MDNode *B)
static LLVM_ABI MDNode * concatenate(MDNode *A, MDNode *B)
Methods for metadata merging.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static LLVM_ABI MDNode * intersect(MDNode *A, MDNode *B)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
A Module instance is used to store all the information related to an LLVM module.
A container for an operand bundle being viewed as a set of values rather than a set of uses.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
A simple AA result which uses scoped-noalias metadata to answer queries.
static LLVM_ABI void collectScopedDomains(const MDNode *NoAlias, SmallPtrSetImpl< const MDNode * > &Domains)
Collect the set of scoped domains relevant to the noalias scopes.
bool insert(const value_type &X)
Insert a new element into the SetVector.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Class to represent struct types.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Target-Independent Code Generator Pass Configuration Options.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
iterator_range< user_iterator > users()
LLVM_ABI void replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
iterator_range< use_iterator > uses()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
A raw_ostream that writes to an std::string.
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
bool isDynamicLDS(const GlobalVariable &GV)
void removeFnAttrFromReachable(CallGraph &CG, Function *KernelRoot, ArrayRef< StringRef > FnAttrs)
Strip FnAttr attribute from any functions where we may have introduced its use.
LLVM_READNONE constexpr bool isKernel(CallingConv::ID CC)
LDSUsesInfoTy getTransitiveUsesOfLDS(const CallGraph &CG, Module &M)
bool isLDSVariableToLower(const GlobalVariable &GV)
bool eliminateConstantExprUsesOfLDSFromAllInstructions(Module &M)
Align getAlign(const DataLayout &DL, const GlobalVariable *GV)
DenseMap< GlobalVariable *, DenseSet< Function * > > VariableFunctionMap
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool operator<(int64_t V1, const APSInt &V2)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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...
void sort(IteratorTy Start, IteratorTy End)
char & AMDGPULowerModuleLDSLegacyPassID
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...
S1Ty set_intersection(const S1Ty &S1, const S2Ty &S2)
set_intersection(A, B) - Return A ^ B
LLVM_ABI void removeFromUsedLists(Module &M, function_ref< bool(Constant *)> ShouldRemove)
Removes global values from the llvm.used and llvm.compiler.used arrays.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
ModulePass * createAMDGPULowerModuleLDSLegacyPass(const AMDGPUTargetMachine *TM=nullptr)
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
LLVM_ABI std::pair< uint64_t, Align > performOptimizedStructLayout(MutableArrayRef< OptimizedStructLayoutField > Fields)
Compute a layout for a struct containing the given fields, making a best-effort attempt to minimize t...
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
constexpr unsigned BitWidth
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
const AMDGPUTargetMachine & TM
FunctionVariableMap direct_access
FunctionVariableMap indirect_access
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.