Go to the documentation of this file.
19 #define DEBUG_TYPE "memory-profile-info"
24 cl::desc(
"The threshold the accesses per byte must be under to consider "
25 "an allocation cold"));
31 cl::desc(
"The minimum lifetime (s) for an allocation to be considered "
46 std::vector<Metadata *> StackVals;
50 StackVals.push_back(StackValMD);
66 auto *MDS = dyn_cast<MDString>(MIB->
getOperand(1));
68 if (MDS->getString().equals(
"cold"))
82 assert(
false &&
"Unexpected alloc type");
96 assert(NumAllocTypes != 0);
97 return NumAllocTypes == 1;
103 CallStackTrieNode *Curr =
nullptr;
104 for (
auto StackId : StackIds) {
109 assert(AllocStackId == StackId);
110 Alloc->AllocTypes |=
static_cast<uint8_t
>(
AllocType);
112 AllocStackId = StackId;
113 Alloc =
new CallStackTrieNode(
AllocType);
119 auto Next = Curr->Callers.find(StackId);
120 if (Next != Curr->Callers.end()) {
122 Curr->AllocTypes |=
static_cast<uint8_t
>(
AllocType);
126 auto *New =
new CallStackTrieNode(
AllocType);
127 Curr->Callers[StackId] = New;
138 for (
const auto &MIBStackIter : StackMD->
operands()) {
139 auto *StackId = mdconst::dyn_extract<ConstantInt>(MIBStackIter);
141 CallStack.push_back(StackId->getZExtValue());
147 std::vector<uint64_t> &MIBCallStack,
149 std::vector<Metadata *> MIBPayload(
151 MIBPayload.push_back(
159 bool CallStackTrie::buildMIBNodes(CallStackTrieNode *Node,
LLVMContext &Ctx,
160 std::vector<uint64_t> &MIBCallStack,
161 std::vector<Metadata *> &MIBNodes,
162 bool CalleeHasAmbiguousCallerContext) {
173 if (!Node->Callers.empty()) {
174 bool NodeHasAmbiguousCallerContext = Node->Callers.size() > 1;
175 bool AddedMIBNodesForAllCallerContexts =
true;
176 for (
auto &Caller : Node->Callers) {
177 MIBCallStack.push_back(
Caller.first);
178 AddedMIBNodesForAllCallerContexts &=
179 buildMIBNodes(
Caller.second, Ctx, MIBCallStack, MIBNodes,
180 NodeHasAmbiguousCallerContext);
182 MIBCallStack.pop_back();
184 if (AddedMIBNodesForAllCallerContexts)
188 assert(!NodeHasAmbiguousCallerContext);
201 if (!CalleeHasAmbiguousCallerContext)
216 std::vector<uint64_t> MIBCallStack;
217 MIBCallStack.push_back(AllocStackId);
218 std::vector<Metadata *> MIBNodes;
219 assert(!Alloc->Callers.empty() &&
"addCallStack has not been called yet");
220 buildMIBNodes(Alloc, Ctx, MIBCallStack, MIBNodes,
222 assert(MIBCallStack.size() == 1 &&
223 "Should only be left with Alloc's location in stack");
234 Iter = End ?
N->op_end() :
N->op_begin();
This is an optimization pass for GlobalISel generic memory operations.
AllocationType getAllocType(uint64_t MaxAccessCount, uint64_t MinSize, uint64_t MinLifetime)
Return the allocation type for a given set of memory profile values.
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
CallStackIterator(const NodeT *N, bool End)
The instances of the Type class are immutable: once they are created, they are never changed.
AllocationType getMIBAllocType(const MDNode *MIB)
Returns the allocation type from an MIB metadata node.
bool buildAndAttachMIBMetadata(CallBase *CI)
Build and attach the minimal necessary MIB metadata.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
unsigned getNumOperands() const
Return number of MDNode operands.
This is the shared class of boolean and integer constants.
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
int popcount(T Value) noexcept
Count the number of set bits in a value.
ArrayRef< MDOperand > operands() const
into llvm powi allowing the code generator to produce balanced multiplication trees First
cl::opt< float > MemProfAccessesPerByteColdThreshold("memprof-accesses-per-byte-cold-threshold", cl::init(10.0), cl::Hidden, cl::desc("The threshold the accesses per byte must be under to consider " "an allocation cold"))
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
static std::string getAllocTypeAttributeString(AllocationType Type)
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.
static bool hasSingleAllocType(uint8_t AllocTypes)
const MDOperand & getOperand(unsigned I) const
This is an important class for using LLVM in a threaded context.
initializer< Ty > init(const Ty &Val)
static MDString * get(LLVMContext &Context, StringRef Str)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static MDNode * createMIBNode(LLVMContext &Ctx, std::vector< uint64_t > &MIBCallStack, AllocationType AllocType)
MDNode * getMIBStackNode(const MDNode *MIB)
Returns the stack node from an MIB metadata node.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMContext & getContext() const
All values hold a context through their type.
cl::opt< unsigned > MemProfMinLifetimeColdThreshold("memprof-min-lifetime-cold-threshold", cl::init(200), cl::Hidden, cl::desc("The minimum lifetime (s) for an allocation to be considered " "cold"))
MDNode * buildCallstackMetadata(ArrayRef< uint64_t > CallStack, LLVMContext &Ctx)
Build callstack metadata from the provided list of call stack ids.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static IntegerType * getInt64Ty(LLVMContext &C)
static void addAllocTypeAttribute(LLVMContext &Ctx, CallBase *CI, AllocationType AllocType)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void addCallStack(AllocationType AllocType, ArrayRef< uint64_t > StackIds)
Add a call stack context with the given allocation type to the Trie.