195#include "llvm/IR/IntrinsicsAMDGPU.h"
209#define DEBUG_TYPE "amdgpu-lower-module-lds"
217 "amdgpu-super-align-lds-globals",
218 cl::desc(
"Increase alignment of LDS if it is not on align boundary"),
221enum class LoweringKind { module, table, kernel, hybrid };
223 "amdgpu-lower-module-lds-strategy",
227 clEnumValN(LoweringKind::table,
"table",
"Lower via table lookup"),
228 clEnumValN(LoweringKind::module,
"module",
"Lower via module struct"),
230 LoweringKind::kernel,
"kernel",
231 "Lower variables reachable from one kernel, otherwise abort"),
233 "Lower via mixture of above strategies")));
235template <
typename T> std::vector<T> sortByName(std::vector<T> &&V) {
236 llvm::sort(V, [](
const auto *L,
const auto *R) {
237 return L->getName() < R->getName();
239 return {std::move(V)};
242class AMDGPULowerModuleLDS {
246 removeLocalVarsFromUsedLists(
Module &M,
258 LocalVar->removeDeadConstantUsers();
283 IRBuilder<> Builder(Entry, Entry->getFirstNonPHIIt());
286 Func->getParent(), Intrinsic::donothing, {});
288 Value *UseInstance[1] = {
289 Builder.CreateConstInBoundsGEP1_32(SGV->
getValueType(), SGV, 0)};
298 struct LDSVariableReplacement {
308 static Constant *getAddressesOfVariablesInKernel(
320 auto ConstantGepIt = LDSVarsToConstantGEP.
find(GV);
321 if (ConstantGepIt != LDSVarsToConstantGEP.
end()) {
322 Elements.push_back(ConstantGepIt->second);
334 if (Variables.
empty()) {
339 const size_t NumberVariables = Variables.
size();
340 const size_t NumberKernels = kernels.
size();
349 std::vector<Constant *> overallConstantExprElts(NumberKernels);
350 for (
size_t i = 0; i < NumberKernels; i++) {
351 auto Replacement = KernelToReplacement.
find(kernels[i]);
352 overallConstantExprElts[i] =
353 (Replacement == KernelToReplacement.
end())
355 : getAddressesOfVariablesInKernel(
356 Ctx, Variables, Replacement->second.LDSVarsToConstantGEP);
371 Value *OptionalIndex) {
377 Value *tableKernelIndex = getTableLookupKernelIndex(M,
I->getFunction());
383 Builder.SetInsertPoint(
I);
387 ConstantInt::get(I32, 0),
393 Value *Address = Builder.CreateInBoundsGEP(
394 LookupTable->getValueType(), LookupTable, GEPIdx, GV->
getName());
396 Value *Loaded = Builder.CreateLoad(GV->
getType(), Address);
400 void replaceUsesInInstructionsWithTableLookup(
408 for (
size_t Index = 0; Index < ModuleScopeVariables.
size(); Index++) {
409 auto *GV = ModuleScopeVariables[Index];
416 replaceUseWithTableLookup(M, Builder, LookupTable, GV, U,
417 ConstantInt::get(I32, Index));
428 if (VariableSet.
empty())
431 for (
Function &Func : M.functions()) {
432 if (Func.isDeclaration() || !
isKernel(Func))
446 chooseBestVariableForModuleStrategy(
const DataLayout &
DL,
452 size_t UserCount = 0;
455 CandidateTy() =
default;
458 : GV(GV), UserCount(UserCount),
Size(AllocSize) {}
462 if (UserCount <
Other.UserCount) {
465 if (UserCount >
Other.UserCount) {
483 CandidateTy MostUsed;
485 for (
auto &K : LDSVars) {
487 if (K.second.size() <= 1) {
493 if (MostUsed < Candidate)
494 MostUsed = Candidate;
518 auto [It, Inserted] = tableKernelIndexCache.
try_emplace(
F);
520 auto InsertAt =
F->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
523 It->second = Builder.CreateIntrinsic(Intrinsic::amdgcn_lds_kernel_id, {});
529 static std::vector<Function *> assignLDSKernelIDToEachKernel(
537 std::vector<Function *> OrderedKernels;
538 if (!KernelsThatAllocateTableLDS.
empty() ||
539 !KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
541 for (
Function &Func : M->functions()) {
542 if (Func.isDeclaration())
547 if (KernelsThatAllocateTableLDS.
contains(&Func) ||
548 KernelsThatIndirectlyAllocateDynamicLDS.
contains(&Func)) {
550 OrderedKernels.push_back(&Func);
555 OrderedKernels = sortByName(std::move(OrderedKernels));
561 if (OrderedKernels.size() > UINT32_MAX) {
566 for (
size_t i = 0; i < OrderedKernels.size(); i++) {
570 OrderedKernels[i]->setMetadata(
"llvm.amdgcn.lds.kernel.id",
574 return OrderedKernels;
577 static void partitionVariablesIntoIndirectStrategies(
586 LoweringKindLoc != LoweringKind::hybrid
588 : chooseBestVariableForModuleStrategy(
589 M.getDataLayout(), LDSToKernelsThatNeedToAccessItIndirectly);
594 ? LDSToKernelsThatNeedToAccessItIndirectly[HybridModuleRoot]
597 for (
auto &K : LDSToKernelsThatNeedToAccessItIndirectly) {
603 assert(!K.second.empty());
606 DynamicVariables.
insert(GV);
610 switch (LoweringKindLoc) {
611 case LoweringKind::module:
612 ModuleScopeVariables.insert(GV);
615 case LoweringKind::table:
616 TableLookupVariables.
insert(GV);
619 case LoweringKind::kernel:
620 if (K.second.size() == 1) {
621 KernelAccessVariables.
insert(GV);
625 "cannot lower LDS '" + GV->
getName() +
626 "' to kernel access as it is reachable from multiple kernels");
630 case LoweringKind::hybrid: {
631 if (GV == HybridModuleRoot) {
632 assert(K.second.size() != 1);
633 ModuleScopeVariables.insert(GV);
634 }
else if (K.second.size() == 1) {
635 KernelAccessVariables.
insert(GV);
636 }
else if (K.second == HybridModuleRootKernels) {
637 ModuleScopeVariables.insert(GV);
639 TableLookupVariables.
insert(GV);
648 assert(ModuleScopeVariables.
size() + TableLookupVariables.
size() +
649 KernelAccessVariables.
size() + DynamicVariables.
size() ==
650 LDSToKernelsThatNeedToAccessItIndirectly.size());
663 if (ModuleScopeVariables.
empty()) {
669 LDSVariableReplacement ModuleScopeReplacement =
670 createLDSVariableReplacement(M,
"llvm.amdgcn.module.lds",
671 ModuleScopeVariables);
679 recordLDSAbsoluteAddress(&M, ModuleScopeReplacement.SGV, 0);
682 removeLocalVarsFromUsedLists(M, ModuleScopeVariables);
685 replaceLDSVariablesWithStruct(
686 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
699 for (
Function &Func : M.functions()) {
700 if (Func.isDeclaration() || !
isKernel(Func))
703 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
704 replaceLDSVariablesWithStruct(
705 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
714 markUsedByKernel(&Func, ModuleScopeReplacement.SGV);
718 return ModuleScopeReplacement.SGV;
722 lowerKernelScopeStructVariables(
731 for (
Function &Func : M.functions()) {
732 if (Func.isDeclaration() || !
isKernel(Func))
740 KernelUsedVariables.
insert(v);
748 KernelUsedVariables.
insert(v);
754 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
756 KernelUsedVariables.
erase(v);
760 if (KernelUsedVariables.
empty()) {
772 if (!Func.hasName()) {
776 std::string VarName =
777 (
Twine(
"llvm.amdgcn.kernel.") + Func.getName() +
".lds").str();
780 createLDSVariableReplacement(M, VarName, KernelUsedVariables);
788 markUsedByKernel(&Func, Replacement.SGV);
791 removeLocalVarsFromUsedLists(M, KernelUsedVariables);
792 KernelToReplacement[&Func] = Replacement;
795 replaceLDSVariablesWithStruct(
796 M, KernelUsedVariables, Replacement, [&Func](
Use &U) {
798 return I &&
I->getFunction() == &Func;
801 return KernelToReplacement;
821 Align MaxDynamicAlignment(1);
825 MaxDynamicAlignment =
831 UpdateMaxAlignment(GV);
835 UpdateMaxAlignment(GV);
842 Twine(
"llvm.amdgcn." + func->
getName() +
".dynlds"),
nullptr,
844 N->setAlignment(MaxDynamicAlignment);
854 std::vector<Function *>
const &OrderedKernels) {
856 if (!KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
861 std::vector<Constant *> newDynamicLDS;
864 for (
auto &func : OrderedKernels) {
866 if (KernelsThatIndirectlyAllocateDynamicLDS.
contains(func)) {
873 buildRepresentativeDynamicLDSInstance(M, LDSUsesInfo, func);
875 KernelToCreatedDynamicLDS[func] =
N;
877 markUsedByKernel(func,
N);
879 newDynamicLDS.push_back(
N);
884 assert(OrderedKernels.size() == newDynamicLDS.size());
890 "llvm.amdgcn.dynlds.offset.table",
nullptr,
901 replaceUseWithTableLookup(M, Builder, table, GV, U,
nullptr);
905 return KernelToCreatedDynamicLDS;
911 bool runOnModuleLinkTime(
Module &M) {
912 bool Changed = superAlignLDSGlobals(M);
921 if (KernelLDSUses.empty() && FunctionLDSUses.empty())
925 assert(!ModuleId.empty() &&
926 "modules with LDS variables should have a unique ID");
929 for (
auto &[
F, Vars] : KernelLDSUses)
930 AllLDSUses[
F].insert(Vars.begin(), Vars.end());
931 for (
auto &[
F, Vars] : FunctionLDSUses)
932 AllLDSUses[
F].insert(Vars.begin(), Vars.end());
935 for (
auto &[
F, Vars] : AllLDSUses) {
946 for (
auto &[
F, Vars] : AllLDSUses) {
948 VarToFuncs[V].push_back(
F);
957 for (
auto &[V, Funcs] : VarToFuncs) {
958 if (!V->hasLocalLinkage() || Funcs.size() > 1) {
959 GlobalScopeVars.
insert(V);
960 if (V->hasLocalLinkage())
961 InternalMultiUserVars.
insert(V);
969 for (
auto &KV : AllLDSUses) {
973 if (!GlobalScopeVars.
count(V))
977 if (FuncScopeVars.
empty())
982 ? (
"__amdgpu_lds." +
F->getName() + ModuleId).str()
983 : (
"__amdgpu_lds." +
F->getName()).str();
984 LDSVariableReplacement Replacement =
985 createLDSVariableReplacement(M,
StructName, FuncScopeVars);
992 replaceLDSVariablesWithStruct(
993 M, FuncScopeVars, Replacement, [
F](
const Use &U) {
995 return I &&
I->getFunction() ==
F;
998 AllReplacedVars.
insert(FuncScopeVars.
begin(), FuncScopeVars.
end());
1005 if (!InternalMultiUserVars.
empty()) {
1006 std::string
StructName =
"__amdgpu_lds.__internal" + ModuleId;
1007 LDSVariableReplacement Replacement =
1008 createLDSVariableReplacement(M,
StructName, InternalMultiUserVars);
1014 replaceLDSVariablesWithStruct(
1015 M, InternalMultiUserVars, Replacement,
1021 FuncsUsingInternalVars.insert(
F);
1023 for (
Function *
F : FuncsUsingInternalVars)
1026 AllReplacedVars.
insert(InternalMultiUserVars.begin(),
1027 InternalMultiUserVars.end());
1033 V->setInitializer(
nullptr);
1040 NamedMDNode *LdsMD = M.getOrInsertNamedMetadata(
"amdgpu.lds.uses");
1042 for (
auto &[
F, SGV] : FuncToLdsStruct)
1046 for (
auto &[V, Funcs] : VarToFuncs) {
1047 if (GlobalScopeVars.
count(V) && !InternalMultiUserVars.
count(V)) {
1057 AllLDSVarsForCleanup.
insert(GlobalScopeVars.
begin(), GlobalScopeVars.
end());
1058 removeLocalVarsFromUsedLists(M, AllLDSVarsForCleanup);
1068 bool runOnModule(
Module &M) {
1070 return runOnModuleLinkTime(M);
1071 return runOnModuleNormal(M);
1074 bool runOnModuleNormal(
Module &M) {
1075 bool Changed = superAlignLDSGlobals(M);
1082 isNotYetLoweredLDSVariable);
1094 LDSToKernelsThatNeedToAccessItIndirectly[GV].insert(
F);
1103 partitionVariablesIntoIndirectStrategies(
1104 M, LDSUsesInfo, LDSToKernelsThatNeedToAccessItIndirectly,
1105 ModuleScopeVariables, TableLookupVariables, KernelAccessVariables,
1112 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1113 ModuleScopeVariables);
1115 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1116 TableLookupVariables);
1119 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1122 GlobalVariable *MaybeModuleScopeStruct = lowerModuleScopeStructVariables(
1123 M, ModuleScopeVariables, KernelsThatAllocateModuleLDS);
1126 lowerKernelScopeStructVariables(M, LDSUsesInfo, ModuleScopeVariables,
1127 KernelsThatAllocateModuleLDS,
1128 MaybeModuleScopeStruct);
1131 for (
auto &GV : KernelAccessVariables) {
1132 auto &funcs = LDSToKernelsThatNeedToAccessItIndirectly[GV];
1133 assert(funcs.size() == 1);
1134 LDSVariableReplacement Replacement =
1135 KernelToReplacement[*(funcs.begin())];
1140 replaceLDSVariablesWithStruct(M, Vec, Replacement, [](
Use &U) {
1146 std::vector<Function *> OrderedKernels =
1147 assignLDSKernelIDToEachKernel(&M, KernelsThatAllocateTableLDS,
1148 KernelsThatIndirectlyAllocateDynamicLDS);
1150 if (!KernelsThatAllocateTableLDS.
empty()) {
1156 auto TableLookupVariablesOrdered =
1157 sortByName(std::vector<GlobalVariable *>(TableLookupVariables.
begin(),
1158 TableLookupVariables.
end()));
1161 M, TableLookupVariablesOrdered, OrderedKernels, KernelToReplacement);
1162 replaceUsesInInstructionsWithTableLookup(M, TableLookupVariablesOrdered,
1167 lowerDynamicLDSVariables(M, LDSUsesInfo,
1168 KernelsThatIndirectlyAllocateDynamicLDS,
1169 DynamicVariables, OrderedKernels);
1174 for (
auto *KernelSet : {&KernelsThatIndirectlyAllocateDynamicLDS,
1175 &KernelsThatAllocateTableLDS})
1184 for (
Function &Func : M.functions()) {
1185 if (Func.isDeclaration() || !
isKernel(Func))
1199 const bool AllocateModuleScopeStruct =
1200 MaybeModuleScopeStruct &&
1201 KernelsThatAllocateModuleLDS.
contains(&Func);
1203 auto Replacement = KernelToReplacement.
find(&Func);
1204 const bool AllocateKernelScopeStruct =
1205 Replacement != KernelToReplacement.
end();
1207 const bool AllocateDynamicVariable =
1208 KernelToCreatedDynamicLDS.
contains(&Func);
1212 if (AllocateModuleScopeStruct) {
1218 if (AllocateKernelScopeStruct) {
1221 recordLDSAbsoluteAddress(&M, KernelStruct,
Offset);
1229 if (AllocateDynamicVariable) {
1230 GlobalVariable *DynamicVariable = KernelToCreatedDynamicLDS[&Func];
1232 recordLDSAbsoluteAddress(&M, DynamicVariable,
Offset);
1247 if (AllocateDynamicVariable)
1250 Func.addFnAttr(
"amdgpu-lds-size", Buffer);
1256 if (isNotYetLoweredLDSVariable(GV)) {
1268 static bool isNotYetLoweredLDSVariable(
const GlobalVariable &GV) {
1274 static bool superAlignLDSGlobals(
Module &M) {
1277 if (!SuperAlignLDSGlobals) {
1281 for (
auto &GV : M.globals()) {
1301 Alignment = std::max(Alignment,
Align(16));
1302 }
else if (GVSize > 4) {
1304 Alignment = std::max(Alignment,
Align(8));
1305 }
else if (GVSize > 2) {
1307 Alignment = std::max(Alignment,
Align(4));
1308 }
else if (GVSize > 1) {
1310 Alignment = std::max(Alignment,
Align(2));
1321 static LDSVariableReplacement createLDSVariableReplacement(
1322 Module &M, std::string VarName,
1339 auto Sorted = sortByName(std::vector<GlobalVariable *>(
1340 LDSVarsToTransform.
begin(), LDSVarsToTransform.
end()));
1351 std::vector<GlobalVariable *> LocalVars;
1353 LocalVars.reserve(LDSVarsToTransform.
size());
1354 IsPaddingField.
reserve(LDSVarsToTransform.
size());
1357 for (
auto &
F : LayoutFields) {
1360 Align DataAlign =
F.Alignment;
1363 if (
uint64_t Rem = CurrentOffset % DataAlignV) {
1364 uint64_t Padding = DataAlignV - Rem;
1376 CurrentOffset += Padding;
1379 LocalVars.push_back(FGV);
1381 CurrentOffset +=
F.Size;
1385 std::vector<Type *> LocalVarTypes;
1386 LocalVarTypes.reserve(LocalVars.size());
1388 LocalVars.cbegin(), LocalVars.cend(), std::back_inserter(LocalVarTypes),
1403 for (
size_t I = 0;
I < LocalVars.size();
I++) {
1405 Constant *GEPIdx[] = {ConstantInt::get(I32, 0), ConstantInt::get(I32,
I)};
1407 if (IsPaddingField[
I]) {
1414 assert(Map.size() == LDSVarsToTransform.
size());
1415 return {SGV, std::move(Map)};
1418 template <
typename PredicateTy>
1419 static void replaceLDSVariablesWithStruct(
1421 const LDSVariableReplacement &Replacement, PredicateTy
Predicate) {
1428 auto LDSVarsToTransform = sortByName(std::vector<GlobalVariable *>(
1429 LDSVarsToTransformArg.
begin(), LDSVarsToTransformArg.
end()));
1435 const size_t NumberVars = LDSVarsToTransform.
size();
1436 if (NumberVars > 1) {
1438 AliasScopes.
reserve(NumberVars);
1440 for (
size_t I = 0;
I < NumberVars;
I++) {
1444 NoAliasList.
append(&AliasScopes[1], AliasScopes.
end());
1449 for (
size_t I = 0;
I < NumberVars;
I++) {
1451 Constant *
GEP = Replacement.LDSVarsToConstantGEP.at(GV);
1455 APInt APOff(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
1456 GEP->stripAndAccumulateInBoundsConstantOffsets(
DL, APOff);
1463 NoAliasList[
I - 1] = AliasScopes[
I - 1];
1469 refineUsesAlignmentAndAA(
GEP,
A,
DL, AliasScope, NoAlias);
1473 static void refineUsesAlignmentAndAA(
Value *Ptr,
Align A,
1475 MDNode *NoAlias,
unsigned MaxDepth = 5) {
1476 if (!MaxDepth || (
A == 1 && !AliasScope))
1483 if (AliasScope &&
I->mayReadOrWriteMemory()) {
1484 MDNode *AS =
I->getMetadata(LLVMContext::MD_alias_scope);
1487 I->setMetadata(LLVMContext::MD_alias_scope, AS);
1489 MDNode *NA =
I->getMetadata(LLVMContext::MD_noalias);
1513 if (Intersection.empty()) {
1518 I->setMetadata(LLVMContext::MD_noalias, NA);
1523 LI->setAlignment(std::max(
A, LI->getAlign()));
1527 if (
SI->getPointerOperand() == Ptr)
1528 SI->setAlignment(std::max(
A,
SI->getAlign()));
1534 if (AI->getPointerOperand() == Ptr)
1535 AI->setAlignment(std::max(
A, AI->getAlign()));
1539 if (AI->getPointerOperand() == Ptr)
1540 AI->setAlignment(std::max(
A, AI->getAlign()));
1544 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1546 if (
GEP->getPointerOperand() == Ptr) {
1548 if (
GEP->accumulateConstantOffset(
DL,
Off))
1550 refineUsesAlignmentAndAA(
GEP, GA,
DL, AliasScope, NoAlias,
1556 if (
I->getOpcode() == Instruction::BitCast ||
1557 I->getOpcode() == Instruction::AddrSpaceCast)
1558 refineUsesAlignmentAndAA(
I,
A,
DL, AliasScope, NoAlias, MaxDepth - 1);
1564class AMDGPULowerModuleLDSLegacy :
public ModulePass {
1577 bool runOnModule(
Module &M)
override {
1579 auto &TPC = getAnalysis<TargetPassConfig>();
1588char AMDGPULowerModuleLDSLegacy::ID = 0;
1593 "Lower uses of LDS variables from non-kernel functions",
1597 "Lower uses of LDS variables from non-kernel functions",
1602 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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
const std::string FatArchTraits< MachO::fat_arch >::StructName
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.
static bool EnableObjectLinking
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
bool empty() const
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...
void reserve(unsigned N)
Reserve space for atleast N bits in the bitvector.
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.
void setLinkage(LinkageTypes LT)
PointerType * getType() const
Global values are always pointers.
@ InternalLinkage
Rename collisions when linking (static functions).
@ ExternalLinkage
Externally visible function.
Type * getValueType() const
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
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.
LLVM_ABI void addOperand(MDNode *M)
A container for an operand bundle being viewed as a set of values rather than a set of uses.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object 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 bool 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)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
A raw_ostream that writes to an std::string.
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
GVUsesInfoTy getTransitiveUsesOfLDSForLowering(const CallGraph &CG, Module &M)
Collects all uses of LDS Global Variables in M using getUsesOfGVByFunction, with isLDSVariableToLower...
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.
bool eliminateGVConstantExprUsesFromAllInstructions(Module &M, function_ref< bool(const GlobalVariable &)> Filter)
Iterates over all GlobalVariables in M, and whenever Filter returns true, replace all constant users ...
LLVM_READNONE constexpr bool isKernel(CallingConv::ID CC)
void getUsesOfGVByFunction(const CallGraph &CG, Module &M, function_ref< bool(const GlobalVariable &)> Filter, FunctionVariableMap &Kernels, FunctionVariableMap &Functions)
Finds uses of Global Variables on a per-function basis.
DenseMap< Function *, DenseSet< GlobalVariable * > > FunctionVariableMap
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
bool isLDSVariableToLower(const GlobalVariable &GV)
Align getAlign(const DataLayout &DL, const GlobalVariable *GV)
DenseMap< GlobalVariable *, DenseSet< Function * > > VariableFunctionMap
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
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...
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI std::string getUniqueModuleId(Module *M)
Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...
void sort(IteratorTy Start, IteratorTy End)
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
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...
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 DirectAccess
FunctionVariableMap IndirectAccess
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.