196#include "llvm/IR/IntrinsicsAMDGPU.h"
212#define DEBUG_TYPE "amdgpu-lower-module-lds"
219 "amdgpu-super-align-lds-globals",
220 cl::desc(
"Increase alignment of LDS if it is not on align boundary"),
223enum class LoweringKind { module, table, kernel, hybrid };
225 "amdgpu-lower-module-lds-strategy",
229 clEnumValN(LoweringKind::table,
"table",
"Lower via table lookup"),
230 clEnumValN(LoweringKind::module,
"module",
"Lower via module struct"),
232 LoweringKind::kernel,
"kernel",
233 "Lower variables reachable from one kernel, otherwise abort"),
235 "Lower via mixture of above strategies")));
248class AMDGPULowerModuleLDS :
public ModulePass {
251 removeLocalVarsFromUsedLists(
Module &M,
257 LocalVarsSet.
insert(cast<Constant>(LocalVar->stripPointerCasts()));
263 LocalVar->removeDeadConstantUsers();
291 Builder.SetInsertPoint(Func->getEntryBlock().getFirstNonPHI());
301 Builder.CreateCall(FTy, Decl, {},
306 static bool eliminateConstantExprUsesOfLDSFromAllInstructions(
Module &M) {
321 for (
auto &GV : M.globals())
340 FunctionVariableMap &kernels,
345 for (
auto &GV : M.globals()) {
351 for (
User *V : GV.users()) {
352 if (
auto *
I = dyn_cast<Instruction>(V)) {
354 if (isKernelLDS(
F)) {
355 kernels[
F].insert(&GV);
364 struct LDSUsesInfoTy {
365 FunctionVariableMap direct_access;
366 FunctionVariableMap indirect_access;
369 static LDSUsesInfoTy getTransitiveUsesOfLDS(
CallGraph const &CG,
Module &M) {
371 FunctionVariableMap direct_map_kernel;
372 FunctionVariableMap direct_map_function;
373 getUsesOfLDSByFunction(CG, M, direct_map_kernel, direct_map_function);
378 if (!isKernelLDS(&
F))
379 if (
F.hasAddressTaken(
nullptr,
384 set_union(VariablesReachableThroughFunctionPointer,
385 direct_map_function[&
F]);
389 auto functionMakesUnknownCall = [&](
const Function *
F) ->
bool {
392 if (!R.second->getFunction()) {
400 FunctionVariableMap transitive_map_function = direct_map_function;
405 if (!
F.isDeclaration() && functionMakesUnknownCall(&
F)) {
406 if (!isKernelLDS(&
F)) {
408 VariablesReachableThroughFunctionPointer);
415 for (
Function &Func : M.functions()) {
416 if (Func.isDeclaration() || isKernelLDS(&Func))
422 while (!wip.empty()) {
427 set_union(transitive_map_function[&Func], direct_map_function[
F]);
430 Function *ith = R.second->getFunction();
443 FunctionVariableMap indirect_map_kernel;
445 for (
Function &Func : M.functions()) {
446 if (Func.isDeclaration() || !isKernelLDS(&Func))
450 Function *ith = R.second->getFunction();
452 set_union(indirect_map_kernel[&Func], transitive_map_function[ith]);
455 VariablesReachableThroughFunctionPointer);
460 return {std::move(direct_map_kernel), std::move(indirect_map_kernel)};
463 struct LDSVariableReplacement {
473 static Constant *getAddressesOfVariablesInKernel(
486 for (
size_t i = 0; i < Variables.
size(); i++) {
488 if (LDSVarsToConstantGEP.
count(GV) != 0) {
490 Elements.push_back(elt);
502 if (Variables.
empty()) {
507 const size_t NumberVariables = Variables.
size();
508 const size_t NumberKernels = kernels.size();
516 std::vector<Constant *> overallConstantExprElts(NumberKernels);
517 for (
size_t i = 0; i < NumberKernels; i++) {
518 LDSVariableReplacement Replacement = KernelToReplacement[kernels[i]];
519 overallConstantExprElts[i] = getAddressesOfVariablesInKernel(
520 Ctx, Variables, Replacement.LDSVarsToConstantGEP);
535 Value *OptionalIndex) {
539 auto *
I = cast<Instruction>(U.getUser());
541 Value *tableKernelIndex = getTableLookupKernelIndex(M,
I->getFunction());
543 if (
auto *Phi = dyn_cast<PHINode>(
I)) {
558 LookupTable->getValueType(), LookupTable, GEPIdx, GV->
getName());
568 void replaceUsesInInstructionsWithTableLookup(
577 auto *GV = ModuleScopeVariables[
Index];
580 auto *
I = dyn_cast<Instruction>(U.getUser());
584 replaceUseWithTableLookup(M,
Builder, LookupTable, GV, U,
591 Module &M, LDSUsesInfoTy &LDSUsesInfo,
596 if (VariableSet.
empty())
599 for (
Function &Func : M.functions()) {
600 if (Func.isDeclaration() || !isKernelLDS(&Func))
604 KernelSet.insert(&Func);
614 chooseBestVariableForModuleStrategy(
const DataLayout &
DL,
615 VariableFunctionMap &LDSVars) {
620 size_t UserCount = 0;
623 CandidateTy() =
default;
626 : GV(GV), UserCount(UserCount),
Size(AllocSize) {}
630 if (UserCount <
Other.UserCount) {
633 if (UserCount >
Other.UserCount) {
651 CandidateTy MostUsed;
653 for (
auto &K : LDSVars) {
655 if (K.second.size() <= 1) {
660 CandidateTy Candidate(
663 if (MostUsed < Candidate)
664 MostUsed = Candidate;
688 if (tableKernelIndexCache.
count(
F) == 0) {
696 F->getEntryBlock().getFirstNonPHIOrDbgOrAlloca();
700 tableKernelIndexCache[
F] =
Builder.CreateCall(FTy, Decl, {});
703 return tableKernelIndexCache[
F];
706 static std::vector<Function *> assignLDSKernelIDToEachKernel(
714 std::vector<Function *> OrderedKernels;
715 if (!KernelsThatAllocateTableLDS.
empty() ||
716 !KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
718 for (
Function &Func : M->functions()) {
719 if (Func.isDeclaration())
721 if (!isKernelLDS(&Func))
724 if (KernelsThatAllocateTableLDS.
contains(&Func) ||
725 KernelsThatIndirectlyAllocateDynamicLDS.
contains(&Func)) {
727 OrderedKernels.push_back(&Func);
732 llvm::sort(OrderedKernels.begin(), OrderedKernels.end(),
734 return lhs->getName() < rhs->getName();
741 if (OrderedKernels.size() > UINT32_MAX) {
746 for (
size_t i = 0; i < OrderedKernels.size(); i++) {
750 OrderedKernels[i]->setMetadata(
"llvm.amdgcn.lds.kernel.id",
754 return OrderedKernels;
757 static void partitionVariablesIntoIndirectStrategies(
758 Module &M, LDSUsesInfoTy
const &LDSUsesInfo,
759 VariableFunctionMap &LDSToKernelsThatNeedToAccessItIndirectly,
766 LoweringKindLoc != LoweringKind::hybrid
768 : chooseBestVariableForModuleStrategy(
769 M.getDataLayout(), LDSToKernelsThatNeedToAccessItIndirectly);
774 ? LDSToKernelsThatNeedToAccessItIndirectly[HybridModuleRoot]
777 for (
auto &K : LDSToKernelsThatNeedToAccessItIndirectly) {
783 assert(K.second.size() != 0);
786 DynamicVariables.
insert(GV);
790 switch (LoweringKindLoc) {
791 case LoweringKind::module:
792 ModuleScopeVariables.insert(GV);
795 case LoweringKind::table:
796 TableLookupVariables.
insert(GV);
799 case LoweringKind::kernel:
800 if (K.second.size() == 1) {
801 KernelAccessVariables.
insert(GV);
804 "cannot lower LDS '" + GV->
getName() +
805 "' to kernel access as it is reachable from multiple kernels");
809 case LoweringKind::hybrid: {
810 if (GV == HybridModuleRoot) {
811 assert(K.second.size() != 1);
812 ModuleScopeVariables.insert(GV);
813 }
else if (K.second.size() == 1) {
814 KernelAccessVariables.
insert(GV);
815 }
else if (
set_is_subset(K.second, HybridModuleRootKernels)) {
816 ModuleScopeVariables.insert(GV);
818 TableLookupVariables.
insert(GV);
827 assert(ModuleScopeVariables.
size() + TableLookupVariables.
size() +
828 KernelAccessVariables.
size() + DynamicVariables.
size() ==
829 LDSToKernelsThatNeedToAccessItIndirectly.size());
842 if (ModuleScopeVariables.
empty()) {
848 LDSVariableReplacement ModuleScopeReplacement =
849 createLDSVariableReplacement(M,
"llvm.amdgcn.module.lds",
850 ModuleScopeVariables);
854 cast<Constant>(ModuleScopeReplacement.SGV),
858 recordLDSAbsoluteAddress(&M, ModuleScopeReplacement.SGV, 0);
861 removeLocalVarsFromUsedLists(M, ModuleScopeVariables);
864 replaceLDSVariablesWithStruct(
865 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
871 return !isKernelLDS(
F);
880 for (
Function &Func : M.functions()) {
881 if (Func.isDeclaration() || !isKernelLDS(&Func))
884 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
885 replaceLDSVariablesWithStruct(
886 M, ModuleScopeVariables, ModuleScopeReplacement, [&](
Use &U) {
895 markUsedByKernel(
Builder, &Func, ModuleScopeReplacement.SGV);
898 markElideModuleLDS(Func);
902 return ModuleScopeReplacement.SGV;
906 lowerKernelScopeStructVariables(
907 Module &M, LDSUsesInfoTy &LDSUsesInfo,
915 for (
Function &Func : M.functions()) {
916 if (Func.isDeclaration() || !isKernelLDS(&Func))
922 for (
auto &v : LDSUsesInfo.direct_access[&Func]) {
924 KernelUsedVariables.
insert(v);
930 for (
auto &v : LDSUsesInfo.indirect_access[&Func]) {
932 KernelUsedVariables.
insert(v);
938 if (KernelsThatAllocateModuleLDS.
contains(&Func)) {
940 KernelUsedVariables.
erase(v);
944 if (KernelUsedVariables.
empty()) {
956 if (!Func.hasName()) {
960 std::string VarName =
961 (
Twine(
"llvm.amdgcn.kernel.") + Func.getName() +
".lds").str();
964 createLDSVariableReplacement(M, VarName, KernelUsedVariables);
967 removeLocalVarsFromUsedLists(M, KernelUsedVariables);
968 KernelToReplacement[&Func] = Replacement;
971 replaceLDSVariablesWithStruct(
972 M, KernelUsedVariables, Replacement, [&Func](
Use &U) {
974 return I &&
I->getFunction() == &Func;
977 return KernelToReplacement;
981 buildRepresentativeDynamicLDSInstance(
Module &M, LDSUsesInfoTy &LDSUsesInfo,
993 assert(isKernelLDS(func));
997 Align MaxDynamicAlignment(1);
1001 MaxDynamicAlignment =
1007 UpdateMaxAlignment(GV);
1011 UpdateMaxAlignment(GV);
1020 N->setAlignment(MaxDynamicAlignment);
1027 Module &M, LDSUsesInfoTy &LDSUsesInfo,
1030 std::vector<Function *>
const &OrderedKernels) {
1032 if (!KernelsThatIndirectlyAllocateDynamicLDS.
empty()) {
1037 std::vector<Constant *> newDynamicLDS;
1040 for (
auto &func : OrderedKernels) {
1042 if (KernelsThatIndirectlyAllocateDynamicLDS.
contains(func)) {
1043 assert(isKernelLDS(func));
1049 buildRepresentativeDynamicLDSInstance(M, LDSUsesInfo, func);
1051 KernelToCreatedDynamicLDS[func] =
N;
1053 markUsedByKernel(
Builder, func,
N);
1063 assert(OrderedKernels.size() == newDynamicLDS.size());
1069 "llvm.amdgcn.dynlds.offset.table",
nullptr,
1074 auto *
I = dyn_cast<Instruction>(U.getUser());
1077 if (isKernelLDS(
I->getFunction()))
1080 replaceUseWithTableLookup(M,
Builder, table, GV, U,
nullptr);
1084 return KernelToCreatedDynamicLDS;
1088 return F.hasFnAttribute(
"amdgpu-elide-module-lds");
1091 static void markElideModuleLDS(
Function &
F) {
1092 F.addFnAttr(
"amdgpu-elide-module-lds");
1097 bool Changed = superAlignLDSGlobals(M);
1099 Changed |= eliminateConstantExprUsesOfLDSFromAllInstructions(M);
1105 LDSUsesInfoTy LDSUsesInfo = getTransitiveUsesOfLDS(CG, M);
1108 VariableFunctionMap LDSToKernelsThatNeedToAccessItIndirectly;
1109 for (
auto &K : LDSUsesInfo.indirect_access) {
1113 LDSToKernelsThatNeedToAccessItIndirectly[GV].insert(
F);
1122 partitionVariablesIntoIndirectStrategies(
1123 M, LDSUsesInfo, LDSToKernelsThatNeedToAccessItIndirectly,
1124 ModuleScopeVariables, TableLookupVariables, KernelAccessVariables,
1131 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1132 ModuleScopeVariables);
1134 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1135 TableLookupVariables);
1138 kernelsThatIndirectlyAccessAnyOfPassedVariables(M, LDSUsesInfo,
1141 GlobalVariable *MaybeModuleScopeStruct = lowerModuleScopeStructVariables(
1142 M, ModuleScopeVariables, KernelsThatAllocateModuleLDS);
1145 lowerKernelScopeStructVariables(M, LDSUsesInfo, ModuleScopeVariables,
1146 KernelsThatAllocateModuleLDS,
1147 MaybeModuleScopeStruct);
1150 for (
auto &GV : KernelAccessVariables) {
1151 auto &funcs = LDSToKernelsThatNeedToAccessItIndirectly[GV];
1152 assert(funcs.size() == 1);
1153 LDSVariableReplacement Replacement =
1154 KernelToReplacement[*(funcs.begin())];
1161 replaceLDSVariablesWithStruct(M, Vec, Replacement, [](
Use &U) {
1162 return isa<Instruction>(U.getUser());
1167 std::vector<Function *> OrderedKernels =
1168 assignLDSKernelIDToEachKernel(&M, KernelsThatAllocateTableLDS,
1169 KernelsThatIndirectlyAllocateDynamicLDS);
1171 if (!KernelsThatAllocateTableLDS.
empty()) {
1175 for (
size_t i = 0; i < OrderedKernels.size(); i++) {
1176 markUsedByKernel(
Builder, OrderedKernels[i],
1177 KernelToReplacement[OrderedKernels[i]].SGV);
1182 std::vector<GlobalVariable *> TableLookupVariablesOrdered(
1183 TableLookupVariables.
begin(), TableLookupVariables.
end());
1184 llvm::sort(TableLookupVariablesOrdered.begin(),
1185 TableLookupVariablesOrdered.end(),
1187 return lhs->getName() < rhs->getName();
1191 M, TableLookupVariablesOrdered, OrderedKernels, KernelToReplacement);
1192 replaceUsesInInstructionsWithTableLookup(M, TableLookupVariablesOrdered,
1197 lowerDynamicLDSVariables(M, LDSUsesInfo,
1198 KernelsThatIndirectlyAllocateDynamicLDS,
1199 DynamicVariables, OrderedKernels);
1207 for (
Function &Func : M.functions()) {
1208 if (Func.isDeclaration() || !isKernelLDS(&Func))
1222 const bool AllocateModuleScopeStruct =
1225 const bool AllocateKernelScopeStruct =
1226 KernelToReplacement.
contains(&Func);
1228 const bool AllocateDynamicVariable =
1229 KernelToCreatedDynamicLDS.
contains(&Func);
1233 if (AllocateModuleScopeStruct) {
1239 if (AllocateKernelScopeStruct) {
1244 recordLDSAbsoluteAddress(&M, KernelStruct,
Offset);
1250 if (AllocateDynamicVariable) {
1251 GlobalVariable *DynamicVariable = KernelToCreatedDynamicLDS[&Func];
1255 recordLDSAbsoluteAddress(&M, DynamicVariable,
Offset);
1274 static bool superAlignLDSGlobals(
Module &M) {
1276 bool Changed =
false;
1277 if (!SuperAlignLDSGlobals) {
1281 for (
auto &GV : M.globals()) {
1296 Alignment = std::max(Alignment,
Align(16));
1297 }
else if (GVSize > 4) {
1299 Alignment = std::max(Alignment,
Align(8));
1300 }
else if (GVSize > 2) {
1302 Alignment = std::max(Alignment,
Align(4));
1303 }
else if (GVSize > 1) {
1305 Alignment = std::max(Alignment,
Align(2));
1316 static LDSVariableReplacement createLDSVariableReplacement(
1317 Module &M, std::string VarName,
1334 std::vector<GlobalVariable *> Sorted(LDSVarsToTransform.
begin(),
1335 LDSVarsToTransform.
end());
1338 return lhs->getName() < rhs->getName();
1350 std::vector<GlobalVariable *> LocalVars;
1353 IsPaddingField.
reserve(LDSVarsToTransform.
size());
1356 for (
size_t I = 0;
I < LayoutFields.
size();
I++) {
1358 const_cast<void *
>(LayoutFields[
I].Id));
1359 Align DataAlign = LayoutFields[
I].Alignment;
1362 if (
uint64_t Rem = CurrentOffset % DataAlignV) {
1363 uint64_t Padding = DataAlignV - Rem;
1375 CurrentOffset += Padding;
1378 LocalVars.push_back(FGV);
1380 CurrentOffset += LayoutFields[
I].
Size;
1384 std::vector<Type *> LocalVarTypes;
1385 LocalVarTypes.reserve(LocalVars.size());
1387 LocalVars.cbegin(), LocalVars.cend(), std::back_inserter(LocalVarTypes),
1402 for (
size_t I = 0;
I < LocalVars.size();
I++) {
1406 if (IsPaddingField[
I]) {
1413 assert(Map.size() == LDSVarsToTransform.
size());
1414 return {SGV, std::move(Map)};
1417 template <
typename PredicateTy>
1418 static void replaceLDSVariablesWithStruct(
1420 LDSVariableReplacement Replacement, PredicateTy Predicate) {
1427 std::vector<GlobalVariable *> LDSVarsToTransform(
1428 LDSVarsToTransformArg.
begin(), LDSVarsToTransformArg.
end());
1429 llvm::sort(LDSVarsToTransform.begin(), LDSVarsToTransform.end(),
1431 return lhs->getName() < rhs->getName();
1438 const size_t NumberVars = LDSVarsToTransform.
size();
1439 if (NumberVars > 1) {
1441 AliasScopes.
reserve(NumberVars);
1443 for (
size_t I = 0;
I < NumberVars;
I++) {
1447 NoAliasList.
append(&AliasScopes[1], AliasScopes.
end());
1452 for (
size_t I = 0;
I < NumberVars;
I++) {
1454 Constant *
GEP = Replacement.LDSVarsToConstantGEP[GV];
1458 APInt APOff(
DL.getIndexTypeSizeInBits(
GEP->getType()), 0);
1459 GEP->stripAndAccumulateInBoundsConstantOffsets(
DL, APOff);
1466 NoAliasList[
I - 1] = AliasScopes[
I - 1];
1472 refineUsesAlignmentAndAA(
GEP,
A,
DL, AliasScope, NoAlias);
1479 if (!
MaxDepth || (
A == 1 && !AliasScope))
1482 for (
User *U :
Ptr->users()) {
1483 if (
auto *
I = dyn_cast<Instruction>(U)) {
1484 if (AliasScope &&
I->mayReadOrWriteMemory()) {
1485 MDNode *AS =
I->getMetadata(LLVMContext::MD_alias_scope);
1488 I->setMetadata(LLVMContext::MD_alias_scope, AS);
1490 MDNode *NA =
I->getMetadata(LLVMContext::MD_noalias);
1492 I->setMetadata(LLVMContext::MD_noalias, NA);
1496 if (
auto *LI = dyn_cast<LoadInst>(U)) {
1497 LI->setAlignment(std::max(
A, LI->getAlign()));
1500 if (
auto *
SI = dyn_cast<StoreInst>(U)) {
1501 if (
SI->getPointerOperand() ==
Ptr)
1502 SI->setAlignment(std::max(
A,
SI->getAlign()));
1505 if (
auto *AI = dyn_cast<AtomicRMWInst>(U)) {
1508 if (AI->getPointerOperand() ==
Ptr)
1509 AI->setAlignment(std::max(
A, AI->getAlign()));
1512 if (
auto *AI = dyn_cast<AtomicCmpXchgInst>(U)) {
1513 if (AI->getPointerOperand() ==
Ptr)
1514 AI->setAlignment(std::max(
A, AI->getAlign()));
1517 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(U)) {
1518 unsigned BitWidth =
DL.getIndexTypeSizeInBits(
GEP->getType());
1520 if (
GEP->getPointerOperand() ==
Ptr) {
1522 if (
GEP->accumulateConstantOffset(
DL, Off))
1524 refineUsesAlignmentAndAA(
GEP, GA,
DL, AliasScope, NoAlias,
1529 if (
auto *
I = dyn_cast<Instruction>(U)) {
1530 if (
I->getOpcode() == Instruction::BitCast ||
1531 I->getOpcode() == Instruction::AddrSpaceCast)
1532 refineUsesAlignmentAndAA(
I,
A,
DL, AliasScope, NoAlias,
MaxDepth - 1);
1539char AMDGPULowerModuleLDS::ID = 0;
1544 "Lower uses of LDS variables from non-kernel functions",
false,
1548 return new AMDGPULowerModuleLDS();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool canElideModuleLDS(const Function &F)
amdgpu propagate attributes Late propagate attributes from kernels to functions
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...
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::optional< std::vector< StOtherPiece > > Other
static const unsigned MaxDepth
This file provides an interface for laying out a sequence of fields as a struct in a way that attempt...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines generic set operations that may be used on set's of different types,...
This file implements a set that has insertion order iteration characteristics.
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
A container for analyses that lazily runs them and caches their results.
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 ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM Basic Block Representation.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
InstListType::iterator iterator
Instruction iterators...
std::pair< std::optional< WeakTrackingVH >, CallGraphNode * > CallRecord
A pair of the calling instruction (a call or invoke) and the call graph node being called.
The basic data container for the call graph of a Module of IR.
static Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, std::optional< unsigned > InRangeIndex=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
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.
This is an important base class in LLVM.
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.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
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.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
void setAlignment(Align Align)
Sets the alignment attribute of the GlobalObject.
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.
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
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 MDNode * getMostGenericAliasScope(MDNode *A, MDNode *B)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDNode * intersect(MDNode *A, MDNode *B)
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
virtual bool runOnModule(Module &M)=0
runOnModule - Virtual method overriden by subclasses to process the module being operated on.
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 PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static 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.
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 StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
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.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
static Type * getVoidTy(LLVMContext &C)
static IntegerType * getInt8Ty(LLVMContext &C)
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
static IntegerType * getInt32Ty(LLVMContext &C)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
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()
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)
@ LOCAL_ADDRESS
Address space for local memory.
@ CONSTANT_ADDRESS
Address space for constant memory (VTX2).
LLVM_READNONE bool isKernel(CallingConv::ID CC)
bool isDynamicLDS(const GlobalVariable &GV)
Align getAlign(DataLayout const &DL, const GlobalVariable *GV)
bool isLDSVariableToLower(const GlobalVariable &GV)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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)
bool convertUsersOfConstantsToInstructions(ArrayRef< Constant * > Consts)
Replace constant expressions users of the given constants with instructions.
char & AMDGPULowerModuleLDSID
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
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...
ModulePass * createAMDGPULowerModuleLDSPass()
void sort(IteratorTy Start, IteratorTy End)
void initializeAMDGPULowerModuleLDSPass(PassRegistry &)
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
void removeFromUsedLists(Module &M, function_ref< bool(Constant *)> ShouldRemove)
Removes global values from the llvm.used and llvm.compiler.used arrays.
void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
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
Align commonAlignment(Align A, uint64_t Offset)
Returns the alignment that satisfies both alignments.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.