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(
327 auto ConstantGepIt = LDSVarsToConstantGEP.
find(GV);
328 if (ConstantGepIt != LDSVarsToConstantGEP.
end()) {
330 Elements.push_back(elt);
342 if (Variables.
empty()) {
347 const size_t NumberVariables = Variables.
size();
348 const size_t NumberKernels = kernels.
size();
357 std::vector<Constant *> overallConstantExprElts(NumberKernels);
358 for (
size_t i = 0; i < NumberKernels; i++) {
359 auto Replacement = KernelToReplacement.
find(kernels[i]);
360 overallConstantExprElts[i] =
361 (Replacement == KernelToReplacement.
end())
363 : getAddressesOfVariablesInKernel(
364 Ctx, Variables, Replacement->second.LDSVarsToConstantGEP);
379 Value *OptionalIndex) {
385 Value *tableKernelIndex = getTableLookupKernelIndex(M,
I->getFunction());
391 Builder.SetInsertPoint(
I);
395 ConstantInt::get(I32, 0),
401 Value *Address = Builder.CreateInBoundsGEP(
402 LookupTable->getValueType(), LookupTable, GEPIdx, GV->
getName());
404 Value *loaded = Builder.CreateLoad(I32, Address);
412 void replaceUsesInInstructionsWithTableLookup(
420 for (
size_t Index = 0; Index < ModuleScopeVariables.
size(); Index++) {
421 auto *GV = ModuleScopeVariables[Index];
428 replaceUseWithTableLookup(M, Builder, LookupTable, GV, U,
429 ConstantInt::get(I32, Index));
440 if (VariableSet.
empty())
443 for (
Function &Func : M.functions()) {
444 if (Func.isDeclaration() || !
isKernel(Func))
458 chooseBestVariableForModuleStrategy(
const DataLayout &
DL,
464 size_t UserCount = 0;
467 CandidateTy() =
default;
470 : GV(GV), UserCount(UserCount),
Size(AllocSize) {}
474 if (UserCount <
Other.UserCount) {
477 if (UserCount >
Other.UserCount) {
495 CandidateTy MostUsed;
497 for (
auto &K : LDSVars) {
499 if (K.second.size() <= 1) {
505 if (MostUsed < Candidate)
506 MostUsed = Candidate;
530 auto [It, Inserted] = tableKernelIndexCache.
try_emplace(
F);
532 auto InsertAt =
F->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
535 It->second = Builder.CreateIntrinsic(Intrinsic::amdgcn_lds_kernel_id, {});
541 static std::vector<Function *> assignLDSKernelIDToEachKernel(
549 std::vector<Function *> OrderedKernels;
550 if (!KernelsThatAllocateTableLDS.
empty() ||
551 !KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
553 for (
Function &Func : M->functions()) {
554 if (Func.isDeclaration())
559 if (KernelsThatAllocateTableLDS.
contains(&Func) ||
560 KernelsThatIndirectlyAllocateDynamicLDS.
contains(&Func)) {
562 OrderedKernels.push_back(&Func);
567 OrderedKernels = sortByName(std::move(OrderedKernels));
573 if (OrderedKernels.size() > UINT32_MAX) {
578 for (
size_t i = 0; i < OrderedKernels.size(); i++) {
582 OrderedKernels[i]->setMetadata(
"llvm.amdgcn.lds.kernel.id",
586 return OrderedKernels;
589 static void partitionVariablesIntoIndirectStrategies(
598 LoweringKindLoc != LoweringKind::hybrid
600 : chooseBestVariableForModuleStrategy(
601 M.getDataLayout(), LDSToKernelsThatNeedToAccessItIndirectly);
606 ? LDSToKernelsThatNeedToAccessItIndirectly[HybridModuleRoot]
609 for (
auto &K : LDSToKernelsThatNeedToAccessItIndirectly) {
615 assert(K.second.size() != 0);
618 DynamicVariables.
insert(GV);
622 switch (LoweringKindLoc) {
623 case LoweringKind::module:
624 ModuleScopeVariables.insert(GV);
627 case LoweringKind::table:
628 TableLookupVariables.
insert(GV);
631 case LoweringKind::kernel:
632 if (K.second.size() == 1) {
633 KernelAccessVariables.
insert(GV);
637 "cannot lower LDS '" + GV->
getName() +
638 "' to kernel access as it is reachable from multiple kernels");
642 case LoweringKind::hybrid: {
643 if (GV == HybridModuleRoot) {
644 assert(K.second.size() != 1);
645 ModuleScopeVariables.insert(GV);
646 }
else if (K.second.size() == 1) {
647 KernelAccessVariables.
insert(GV);
648 }
else if (K.second == HybridModuleRootKernels) {
649 ModuleScopeVariables.insert(GV);
651 TableLookupVariables.
insert(GV);
660 assert(ModuleScopeVariables.
size() + TableLookupVariables.
size() +
661 KernelAccessVariables.
size() + DynamicVariables.
size() ==
662 LDSToKernelsThatNeedToAccessItIndirectly.size());
675 if (ModuleScopeVariables.
empty()) {
681 LDSVariableReplacement ModuleScopeReplacement =
682 createLDSVariableReplacement(M,
"llvm.amdgcn.module.lds",
683 ModuleScopeVariables);
691 recordLDSAbsoluteAddress(&M, ModuleScopeReplacement.SGV, 0);
694 removeLocalVarsFromUsedLists(M, ModuleScopeVariables);
697 replaceLDSVariablesWithStruct(
698 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
711 for (
Function &Func : M.functions()) {
712 if (Func.isDeclaration() || !
isKernel(Func))
715 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
716 replaceLDSVariablesWithStruct(
717 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
726 markUsedByKernel(&Func, ModuleScopeReplacement.SGV);
730 return ModuleScopeReplacement.SGV;
734 lowerKernelScopeStructVariables(
743 for (
Function &Func : M.functions()) {
744 if (Func.isDeclaration() || !
isKernel(Func))
752 KernelUsedVariables.
insert(v);
760 KernelUsedVariables.
insert(v);
766 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
768 KernelUsedVariables.
erase(v);
772 if (KernelUsedVariables.
empty()) {
784 if (!Func.hasName()) {
788 std::string VarName =
789 (
Twine(
"llvm.amdgcn.kernel.") + Func.getName() +
".lds").str();
792 createLDSVariableReplacement(M, VarName, KernelUsedVariables);
800 markUsedByKernel(&Func, Replacement.SGV);
803 removeLocalVarsFromUsedLists(M, KernelUsedVariables);
804 KernelToReplacement[&Func] = Replacement;
807 replaceLDSVariablesWithStruct(
808 M, KernelUsedVariables, Replacement, [&Func](
Use &U) {
810 return I &&
I->getFunction() == &Func;
813 return KernelToReplacement;
833 Align MaxDynamicAlignment(1);
837 MaxDynamicAlignment =
843 UpdateMaxAlignment(GV);
847 UpdateMaxAlignment(GV);
856 N->setAlignment(MaxDynamicAlignment);
866 std::vector<Function *>
const &OrderedKernels) {
868 if (!KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
873 std::vector<Constant *> newDynamicLDS;
876 for (
auto &func : OrderedKernels) {
878 if (KernelsThatIndirectlyAllocateDynamicLDS.
contains(func)) {
885 buildRepresentativeDynamicLDSInstance(M, LDSUsesInfo, func);
887 KernelToCreatedDynamicLDS[func] =
N;
889 markUsedByKernel(func,
N);
893 emptyCharArray,
N, ConstantInt::get(I32, 0),
true);
899 assert(OrderedKernels.size() == newDynamicLDS.size());
905 "llvm.amdgcn.dynlds.offset.table",
nullptr,
916 replaceUseWithTableLookup(M, Builder, table, GV, U,
nullptr);
920 return KernelToCreatedDynamicLDS;
923 bool runOnModule(
Module &M) {
925 bool Changed = superAlignLDSGlobals(M);
941 LDSToKernelsThatNeedToAccessItIndirectly[GV].insert(
F);
950 partitionVariablesIntoIndirectStrategies(
951 M, LDSUsesInfo, LDSToKernelsThatNeedToAccessItIndirectly,
952 ModuleScopeVariables, TableLookupVariables, KernelAccessVariables,
959 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
960 ModuleScopeVariables);
962 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
963 TableLookupVariables);
966 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
969 GlobalVariable *MaybeModuleScopeStruct = lowerModuleScopeStructVariables(
970 M, ModuleScopeVariables, KernelsThatAllocateModuleLDS);
973 lowerKernelScopeStructVariables(M, LDSUsesInfo, ModuleScopeVariables,
974 KernelsThatAllocateModuleLDS,
975 MaybeModuleScopeStruct);
978 for (
auto &GV : KernelAccessVariables) {
979 auto &funcs = LDSToKernelsThatNeedToAccessItIndirectly[GV];
980 assert(funcs.size() == 1);
981 LDSVariableReplacement Replacement =
982 KernelToReplacement[*(funcs.begin())];
987 replaceLDSVariablesWithStruct(M, Vec, Replacement, [](
Use &U) {
993 std::vector<Function *> OrderedKernels =
994 assignLDSKernelIDToEachKernel(&M, KernelsThatAllocateTableLDS,
995 KernelsThatIndirectlyAllocateDynamicLDS);
997 if (!KernelsThatAllocateTableLDS.
empty()) {
1003 auto TableLookupVariablesOrdered =
1004 sortByName(std::vector<GlobalVariable *>(TableLookupVariables.
begin(),
1005 TableLookupVariables.
end()));
1008 M, TableLookupVariablesOrdered, OrderedKernels, KernelToReplacement);
1009 replaceUsesInInstructionsWithTableLookup(M, TableLookupVariablesOrdered,
1014 lowerDynamicLDSVariables(M, LDSUsesInfo,
1015 KernelsThatIndirectlyAllocateDynamicLDS,
1016 DynamicVariables, OrderedKernels);
1021 for (
auto *KernelSet : {&KernelsThatIndirectlyAllocateDynamicLDS,
1022 &KernelsThatAllocateTableLDS})
1031 for (
Function &Func : M.functions()) {
1032 if (Func.isDeclaration() || !
isKernel(Func))
1046 const bool AllocateModuleScopeStruct =
1047 MaybeModuleScopeStruct &&
1048 KernelsThatAllocateModuleLDS.
contains(&Func);
1050 auto Replacement = KernelToReplacement.
find(&Func);
1051 const bool AllocateKernelScopeStruct =
1052 Replacement != KernelToReplacement.
end();
1054 const bool AllocateDynamicVariable =
1055 KernelToCreatedDynamicLDS.
contains(&Func);
1059 if (AllocateModuleScopeStruct) {
1065 if (AllocateKernelScopeStruct) {
1068 recordLDSAbsoluteAddress(&M, KernelStruct,
Offset);
1076 if (AllocateDynamicVariable) {
1077 GlobalVariable *DynamicVariable = KernelToCreatedDynamicLDS[&Func];
1079 recordLDSAbsoluteAddress(&M, DynamicVariable,
Offset);
1094 if (AllocateDynamicVariable)
1097 Func.addFnAttr(
"amdgpu-lds-size", Buffer);
1116 static bool superAlignLDSGlobals(
Module &M) {
1119 if (!SuperAlignLDSGlobals) {
1123 for (
auto &GV : M.globals()) {
1143 Alignment = std::max(Alignment,
Align(16));
1144 }
else if (GVSize > 4) {
1146 Alignment = std::max(Alignment,
Align(8));
1147 }
else if (GVSize > 2) {
1149 Alignment = std::max(Alignment,
Align(4));
1150 }
else if (GVSize > 1) {
1152 Alignment = std::max(Alignment,
Align(2));
1163 static LDSVariableReplacement createLDSVariableReplacement(
1164 Module &M, std::string VarName,
1181 auto Sorted = sortByName(std::vector<GlobalVariable *>(
1182 LDSVarsToTransform.
begin(), LDSVarsToTransform.
end()));
1193 std::vector<GlobalVariable *> LocalVars;
1195 LocalVars.reserve(LDSVarsToTransform.
size());
1196 IsPaddingField.
reserve(LDSVarsToTransform.
size());
1199 for (
auto &
F : LayoutFields) {
1202 Align DataAlign =
F.Alignment;
1205 if (
uint64_t Rem = CurrentOffset % DataAlignV) {
1206 uint64_t Padding = DataAlignV - Rem;
1218 CurrentOffset += Padding;
1221 LocalVars.push_back(FGV);
1223 CurrentOffset +=
F.Size;
1227 std::vector<Type *> LocalVarTypes;
1228 LocalVarTypes.reserve(LocalVars.size());
1230 LocalVars.cbegin(), LocalVars.cend(), std::back_inserter(LocalVarTypes),
1245 for (
size_t I = 0;
I < LocalVars.size();
I++) {
1247 Constant *GEPIdx[] = {ConstantInt::get(I32, 0), ConstantInt::get(I32,
I)};
1249 if (IsPaddingField[
I]) {
1256 assert(Map.size() == LDSVarsToTransform.
size());
1257 return {SGV, std::move(Map)};
1260 template <
typename PredicateTy>
1261 static void replaceLDSVariablesWithStruct(
1263 const LDSVariableReplacement &Replacement, PredicateTy
Predicate) {
1270 auto LDSVarsToTransform = sortByName(std::vector<GlobalVariable *>(
1271 LDSVarsToTransformArg.
begin(), LDSVarsToTransformArg.
end()));
1277 const size_t NumberVars = LDSVarsToTransform.
size();
1278 if (NumberVars > 1) {
1280 AliasScopes.
reserve(NumberVars);
1282 for (
size_t I = 0;
I < NumberVars;
I++) {
1286 NoAliasList.
append(&AliasScopes[1], AliasScopes.
end());
1291 for (
size_t I = 0;
I < NumberVars;
I++) {
1293 Constant *
GEP = Replacement.LDSVarsToConstantGEP.at(GV);
1297 APInt APOff(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
1298 GEP->stripAndAccumulateInBoundsConstantOffsets(
DL, APOff);
1305 NoAliasList[
I - 1] = AliasScopes[
I - 1];
1311 refineUsesAlignmentAndAA(
GEP,
A,
DL, AliasScope, NoAlias);
1315 static void refineUsesAlignmentAndAA(
Value *Ptr,
Align A,
1317 MDNode *NoAlias,
unsigned MaxDepth = 5) {
1318 if (!MaxDepth || (
A == 1 && !AliasScope))
1325 if (AliasScope &&
I->mayReadOrWriteMemory()) {
1326 MDNode *AS =
I->getMetadata(LLVMContext::MD_alias_scope);
1329 I->setMetadata(LLVMContext::MD_alias_scope, AS);
1331 MDNode *NA =
I->getMetadata(LLVMContext::MD_noalias);
1355 if (Intersection.empty()) {
1360 I->setMetadata(LLVMContext::MD_noalias, NA);
1365 LI->setAlignment(std::max(
A, LI->getAlign()));
1369 if (
SI->getPointerOperand() == Ptr)
1370 SI->setAlignment(std::max(
A,
SI->getAlign()));
1376 if (AI->getPointerOperand() == Ptr)
1377 AI->setAlignment(std::max(
A, AI->getAlign()));
1381 if (AI->getPointerOperand() == Ptr)
1382 AI->setAlignment(std::max(
A, AI->getAlign()));
1386 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1388 if (
GEP->getPointerOperand() == Ptr) {
1390 if (
GEP->accumulateConstantOffset(
DL, Off))
1392 refineUsesAlignmentAndAA(
GEP, GA,
DL, AliasScope, NoAlias,
1398 if (
I->getOpcode() == Instruction::BitCast ||
1399 I->getOpcode() == Instruction::AddrSpaceCast)
1400 refineUsesAlignmentAndAA(
I,
A,
DL, AliasScope, NoAlias, MaxDepth - 1);
1406class AMDGPULowerModuleLDSLegacy :
public ModulePass {
1419 bool runOnModule(
Module &M)
override {
1421 auto &TPC = getAnalysis<TargetPassConfig>();
1430char AMDGPULowerModuleLDSLegacy::ID = 0;
1435 "Lower uses of LDS variables from non-kernel functions",
1439 "Lower uses of LDS variables from non-kernel functions",
1444 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 LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
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 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.