19#include "llvm/IR/IntrinsicsAMDGPU.h"
23#define DEBUG_TYPE "amdgpu-memory-utils"
36 Source.getAllMetadata(MD);
37 for (
const auto [
ID,
N] : MD) {
39 case LLVMContext::MD_dbg:
40 case LLVMContext::MD_invariant_load:
41 case LLVMContext::MD_nontemporal:
65 if (STy->getNumElements() != 1)
67 Ty = STy->getElementType(0);
71 Ty = ATy->getElementType();
80 return Ty->
getName() ==
"amdgcn.named.barrier" ? Ty :
nullptr;
117 for (
auto &GV : M.globals())
129 for (
auto &GV : M.globals()) {
136 Kernels[
F].insert(&GV);
138 Functions[
F].insert(&GV);
156 if (
F.hasAddressTaken(
nullptr,
168 set_union(VariablesReachableThroughFunctionPointer, DirectMapFunction[
F]);
171 auto FunctionMakesUnknownCall = [&](
const Function *
F) ->
bool {
174 if (!R.second->getFunction())
186 if (!
F.isDeclaration() && FunctionMakesUnknownCall(&
F)) {
189 VariablesReachableThroughFunctionPointer);
196 for (
Function &Func : M.functions()) {
197 if (Func.isDeclaration() ||
isKernel(Func))
203 while (!wip.
empty()) {
208 set_union(TransitiveMapFunction[&Func], DirectMapFunction[
F]);
211 Function *Ith = R.second->getFunction();
225 set_union(VariablesReachableThroughFunctionPointer,
226 TransitiveMapFunction[
F]);
233 for (
Function &Func : M.functions()) {
234 if (Func.isDeclaration() || !
isKernel(Func))
238 Function *Ith = R.second->getFunction();
240 set_union(IndirectMapKernel[&Func], TransitiveMapFunction[Ith]);
246 bool SeesUnknownCalls = [&]() {
250 while (!WorkList.
empty()) {
254 if (!CallRecord.second)
257 Function *Callee = CallRecord.second->getFunction();
261 if (Visited.
insert(Callee).second)
268 if (SeesUnknownCalls) {
270 VariablesReachableThroughFunctionPointer);
274 return {std::move(DirectMapKernel), std::move(IndirectMapKernel)};
285 std::optional<bool> HasAbsoluteGVs;
287 for (
auto &[Fn, GVs] : Map) {
288 for (
auto *GV : GVs) {
289 bool IsAbsolute = GV->isAbsoluteSymbolRef();
290 bool IsDirectMapDynLDSGV =
292 if (IsDirectMapDynLDSGV)
304 if (HasAbsoluteGVs.has_value()) {
305 if (*HasAbsoluteGVs != IsAbsolute) {
307 "module cannot mix absolute and non-absolute LDS GVs");
310 HasAbsoluteGVs = IsAbsolute;
317 if (HasAbsoluteGVs && *HasAbsoluteGVs)
330 bool SeenUnknownCall =
false;
332 while (!WorkList.
empty()) {
335 for (
auto &CallRecord : *CG[
F]) {
336 if (!CallRecord.second)
339 Function *Callee = CallRecord.second->getFunction();
341 if (!SeenUnknownCall) {
342 SeenUnknownCall =
true;
359 Callee->removeFnAttr(Attr);
360 if (Visited.
insert(Callee).second)
374 switch (
II->getIntrinsicID()) {
375 case Intrinsic::amdgcn_s_barrier:
376 case Intrinsic::amdgcn_s_cluster_barrier:
377 case Intrinsic::amdgcn_s_barrier_signal:
378 case Intrinsic::amdgcn_s_barrier_signal_var:
379 case Intrinsic::amdgcn_s_barrier_signal_isfirst:
380 case Intrinsic::amdgcn_s_barrier_init:
381 case Intrinsic::amdgcn_s_barrier_join:
382 case Intrinsic::amdgcn_s_barrier_wait:
383 case Intrinsic::amdgcn_s_barrier_leave:
384 case Intrinsic::amdgcn_s_get_barrier_state:
385 case Intrinsic::amdgcn_s_wakeup_barrier:
386 case Intrinsic::amdgcn_wave_barrier:
387 case Intrinsic::amdgcn_sched_barrier:
388 case Intrinsic::amdgcn_sched_group_barrier:
389 case Intrinsic::amdgcn_iglp_opt:
398 const auto checkNoAlias = [
AA, Ptr](
auto I) ->
bool {
399 return I &&
AA->isNoAlias(
I->getPointerOperand(), Ptr);
416 LLVM_DEBUG(
dbgs() <<
"Checking clobbering of: " << *Load <<
'\n');
426 while (!WorkList.
empty()) {
428 if (!Visited.
insert(MA).second)
448 for (
const auto &
Use : Phi->incoming_values())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
uint64_t IntrinsicInst * II
This file defines generic set operations that may be used on set's of different types,...
Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
CallGraphNode * getExternalCallingNode() const
Returns the CallGraphNode which is used to represent undetermined calls into the callgraph.
A parsed version of the target data layout string in and methods for querying it.
Implements a dense probed hash-table based set.
const Function & getFunction() const
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Module * getParent()
Get the module that this global value is contained inside of...
PointerType * getType() const
Global values are always pointers.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
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.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
Represents phi nodes for memory accesses.
This is the generic walker interface for walkers of MemorySSA.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI MemorySSAWalker * getWalker()
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
A Module instance is used to store all the information related to an LLVM module.
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.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Class to represent target extensions types, which are generally unintrospectable from target-independ...
StringRef getName() const
Return the name for this target extension type.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
iterator_range< user_iterator > users()
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
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.
An efficient, type-erasing, non-owning reference to a callable.
Abstract Attribute helper functions.
@ LOCAL_ADDRESS
Address space for local memory.
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.
bool isReallyAClobber(const Value *Ptr, MemoryDef *Def, AAResults *AA)
Given a Def clobbering a load from Ptr according to the MSSA check if this is actually a memory updat...
static TargetExtType * getTargetExtType(const GlobalVariable &GV)
DenseMap< Function *, DenseSet< GlobalVariable * > > FunctionVariableMap
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
bool isLDSVariableToLower(const GlobalVariable &GV)
Align getAlign(const DataLayout &DL, const GlobalVariable *GV)
void copyMetadataForWidenedLoad(LoadInst &Dest, const LoadInst &Source)
bool isClobberedInFunction(const LoadInst *Load, MemorySSA *MSSA, AAResults *AA)
Check is a Load is clobbered in its function.
GVUsesInfoTy getTransitiveUsesOfGV(const CallGraph &CG, Module &M, function_ref< bool(const GlobalVariable &)> Filter)
Collects all uses of Global Variables in M using getUsesOfGVByFunction.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI bool convertUsersOfConstantsToInstructions(ArrayRef< Constant * > Consts, Function *RestrictToFunc=nullptr, bool RemoveDeadConstants=true, bool IncludeSelf=false)
Replace constant expressions users of the given constants with instructions.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool set_union(S1Ty &S1, const S2Ty &S2)
set_union(A, B) - Compute A := A u B, return whether A changed.
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
FunctionVariableMap DirectAccess
FunctionVariableMap IndirectAccess
This struct is a compact representation of a valid (non-zero power of two) alignment.