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 "
40 return AllocationType::Cold;
41 return AllocationType::NotCold;
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"))
69 return AllocationType::Cold;
70 return AllocationType::NotCold;
75 case AllocationType::NotCold:
78 case AllocationType::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(
159bool 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();
248 return mdconst::dyn_extract<ConstantInt>(
N->operands().back())
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
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"))
static std::string getAllocTypeAttributeString(AllocationType Type)
static MDNode * createMIBNode(LLVMContext &Ctx, std::vector< uint64_t > &MIBCallStack, AllocationType AllocType)
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"))
static void addAllocTypeAttribute(LLVMContext &Ctx, CallBase *CI, AllocationType AllocType)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void addFnAttr(Attribute::AttrKind Kind)
Adds the attribute to the function.
This is the shared class of boolean and integer constants.
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.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is an important class for using LLVM in a threaded context.
const MDOperand & getOperand(unsigned I) const
ArrayRef< MDOperand > operands() const
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
unsigned getNumOperands() const
Return number of MDNode operands.
static MDString * get(LLVMContext &Context, StringRef Str)
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt64Ty(LLVMContext &C)
LLVMContext & getContext() const
All values hold a context through their type.
void addCallStack(AllocationType AllocType, ArrayRef< uint64_t > StackIds)
Add a call stack context with the given allocation type to the Trie.
bool buildAndAttachMIBMetadata(CallBase *CI)
Build and attach the minimal necessary MIB metadata.
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
initializer< Ty > init(const Ty &Val)
MDNode * buildCallstackMetadata(ArrayRef< uint64_t > CallStack, LLVMContext &Ctx)
Build callstack metadata from the provided list of call stack ids.
AllocationType getMIBAllocType(const MDNode *MIB)
Returns the allocation type from an MIB metadata node.
bool hasSingleAllocType(uint8_t AllocTypes)
True if the AllocTypes bitmask contains just a single type.
MDNode * getMIBStackNode(const MDNode *MIB)
Returns the stack node from an MIB metadata node.
AllocationType getAllocType(uint64_t MaxAccessCount, uint64_t MinSize, uint64_t MinLifetime)
Return the allocation type for a given set of memory profile values.
This is an optimization pass for GlobalISel generic memory operations.
int popcount(T Value) noexcept
Count the number of set bits in a value.
CallStackIterator(const NodeT *N, bool End)