LLVM  15.0.0git
SampleContextTracker.cpp
Go to the documentation of this file.
1 //===- SampleContextTracker.cpp - Context-sensitive Profile Tracker -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the SampleContextTracker used by CSSPGO.
10 //
11 //===----------------------------------------------------------------------===//
12 
14 #include "llvm/ADT/StringMap.h"
15 #include "llvm/ADT/StringRef.h"
17 #include "llvm/IR/InstrTypes.h"
18 #include "llvm/IR/Instruction.h"
20 #include <map>
21 #include <queue>
22 #include <vector>
23 
24 using namespace llvm;
25 using namespace sampleprof;
26 
27 #define DEBUG_TYPE "sample-context-tracker"
28 
29 namespace llvm {
30 
32  StringRef CalleeName) {
33  if (CalleeName.empty())
34  return getHottestChildContext(CallSite);
35 
36  uint64_t Hash = FunctionSamples::getCallSiteHash(CalleeName, CallSite);
37  auto It = AllChildContext.find(Hash);
38  if (It != AllChildContext.end())
39  return &It->second;
40  return nullptr;
41 }
42 
45  // CSFDO-TODO: This could be slow, change AllChildContext so we can
46  // do point look up for child node by call site alone.
47  // Retrieve the child node with max count for indirect call
48  ContextTrieNode *ChildNodeRet = nullptr;
49  uint64_t MaxCalleeSamples = 0;
50  for (auto &It : AllChildContext) {
51  ContextTrieNode &ChildNode = It.second;
52  if (ChildNode.CallSiteLoc != CallSite)
53  continue;
54  FunctionSamples *Samples = ChildNode.getFunctionSamples();
55  if (!Samples)
56  continue;
57  if (Samples->getTotalSamples() > MaxCalleeSamples) {
58  ChildNodeRet = &ChildNode;
59  MaxCalleeSamples = Samples->getTotalSamples();
60  }
61  }
62 
63  return ChildNodeRet;
64 }
65 
67  const LineLocation &CallSite, ContextTrieNode &&NodeToMove,
68  uint32_t ContextFramesToRemove, bool DeleteNode) {
69  uint64_t Hash =
70  FunctionSamples::getCallSiteHash(NodeToMove.getFuncName(), CallSite);
71  assert(!AllChildContext.count(Hash) && "Node to remove must exist");
72  LineLocation OldCallSite = NodeToMove.CallSiteLoc;
73  ContextTrieNode &OldParentContext = *NodeToMove.getParentContext();
74  AllChildContext[Hash] = NodeToMove;
75  ContextTrieNode &NewNode = AllChildContext[Hash];
76  NewNode.CallSiteLoc = CallSite;
77 
78  // Walk through nodes in the moved the subtree, and update
79  // FunctionSamples' context as for the context promotion.
80  // We also need to set new parant link for all children.
81  std::queue<ContextTrieNode *> NodeToUpdate;
82  NewNode.setParentContext(this);
83  NodeToUpdate.push(&NewNode);
84 
85  while (!NodeToUpdate.empty()) {
86  ContextTrieNode *Node = NodeToUpdate.front();
87  NodeToUpdate.pop();
88  FunctionSamples *FSamples = Node->getFunctionSamples();
89 
90  if (FSamples) {
91  FSamples->getContext().promoteOnPath(ContextFramesToRemove);
93  LLVM_DEBUG(dbgs() << " Context promoted to: "
94  << FSamples->getContext().toString() << "\n");
95  }
96 
97  for (auto &It : Node->getAllChildContext()) {
98  ContextTrieNode *ChildNode = &It.second;
99  ChildNode->setParentContext(Node);
100  NodeToUpdate.push(ChildNode);
101  }
102  }
103 
104  // Original context no longer needed, destroy if requested.
105  if (DeleteNode)
106  OldParentContext.removeChildContext(OldCallSite, NewNode.getFuncName());
107 
108  return NewNode;
109 }
110 
112  StringRef CalleeName) {
113  uint64_t Hash = FunctionSamples::getCallSiteHash(CalleeName, CallSite);
114  // Note this essentially calls dtor and destroys that child context
115  AllChildContext.erase(Hash);
116 }
117 
118 std::map<uint64_t, ContextTrieNode> &ContextTrieNode::getAllChildContext() {
119  return AllChildContext;
120 }
121 
122 StringRef ContextTrieNode::getFuncName() const { return FuncName; }
123 
125  return FuncSamples;
126 }
127 
129  FuncSamples = FSamples;
130 }
131 
133 
135  if (!FuncSize.hasValue())
136  FuncSize = 0;
137 
138  FuncSize = FuncSize.getValue() + FSize;
139 }
140 
141 LineLocation ContextTrieNode::getCallSiteLoc() const { return CallSiteLoc; }
142 
144  return ParentContext;
145 }
146 
148  ParentContext = Parent;
149 }
150 
152  dbgs() << "Node: " << FuncName << "\n"
153  << " Callsite: " << CallSiteLoc << "\n"
154  << " Size: " << FuncSize << "\n"
155  << " Children:\n";
156 
157  for (auto &It : AllChildContext) {
158  dbgs() << " Node: " << It.second.getFuncName() << "\n";
159  }
160 }
161 
163  dbgs() << "Context Profile Tree:\n";
164  std::queue<ContextTrieNode *> NodeQueue;
165  NodeQueue.push(this);
166 
167  while (!NodeQueue.empty()) {
168  ContextTrieNode *Node = NodeQueue.front();
169  NodeQueue.pop();
170  Node->dumpNode();
171 
172  for (auto &It : Node->getAllChildContext()) {
173  ContextTrieNode *ChildNode = &It.second;
174  NodeQueue.push(ChildNode);
175  }
176  }
177 }
178 
180  const LineLocation &CallSite, StringRef CalleeName, bool AllowCreate) {
181  uint64_t Hash = FunctionSamples::getCallSiteHash(CalleeName, CallSite);
182  auto It = AllChildContext.find(Hash);
183  if (It != AllChildContext.end()) {
184  assert(It->second.getFuncName() == CalleeName &&
185  "Hash collision for child context node");
186  return &It->second;
187  }
188 
189  if (!AllowCreate)
190  return nullptr;
191 
192  AllChildContext[Hash] = ContextTrieNode(this, CalleeName, nullptr, CallSite);
193  return &AllChildContext[Hash];
194 }
195 
196 // Profiler tracker than manages profiles and its associated context
198  SampleProfileMap &Profiles,
199  const DenseMap<uint64_t, StringRef> *GUIDToFuncNameMap)
200  : GUIDToFuncNameMap(GUIDToFuncNameMap) {
201  for (auto &FuncSample : Profiles) {
202  FunctionSamples *FSamples = &FuncSample.second;
203  SampleContext Context = FuncSample.first;
204  LLVM_DEBUG(dbgs() << "Tracking Context for function: " << Context.toString()
205  << "\n");
206  if (!Context.isBaseContext())
207  FuncToCtxtProfiles[Context.getName()].insert(FSamples);
208  ContextTrieNode *NewNode = getOrCreateContextPath(Context, true);
209  assert(!NewNode->getFunctionSamples() &&
210  "New node can't have sample profile");
211  NewNode->setFunctionSamples(FSamples);
212  }
213 }
214 
217  StringRef CalleeName) {
218  LLVM_DEBUG(dbgs() << "Getting callee context for instr: " << Inst << "\n");
219  DILocation *DIL = Inst.getDebugLoc();
220  if (!DIL)
221  return nullptr;
222 
223  CalleeName = FunctionSamples::getCanonicalFnName(CalleeName);
224  // Convert real function names to MD5 names, if the input profile is
225  // MD5-based.
226  std::string FGUID;
227  CalleeName = getRepInFormat(CalleeName, FunctionSamples::UseMD5, FGUID);
228 
229  // For indirect call, CalleeName will be empty, in which case the context
230  // profile for callee with largest total samples will be returned.
231  ContextTrieNode *CalleeContext = getCalleeContextFor(DIL, CalleeName);
232  if (CalleeContext) {
233  FunctionSamples *FSamples = CalleeContext->getFunctionSamples();
234  LLVM_DEBUG(if (FSamples) {
235  dbgs() << " Callee context found: " << FSamples->getContext().toString()
236  << "\n";
237  });
238  return FSamples;
239  }
240 
241  return nullptr;
242 }
243 
244 std::vector<const FunctionSamples *>
246  const DILocation *DIL) {
247  std::vector<const FunctionSamples *> R;
248  if (!DIL)
249  return R;
250 
251  ContextTrieNode *CallerNode = getContextFor(DIL);
253  for (auto &It : CallerNode->getAllChildContext()) {
254  ContextTrieNode &ChildNode = It.second;
255  if (ChildNode.getCallSiteLoc() != CallSite)
256  continue;
257  if (FunctionSamples *CalleeSamples = ChildNode.getFunctionSamples())
258  R.push_back(CalleeSamples);
259  }
260 
261  return R;
262 }
263 
266  assert(DIL && "Expect non-null location");
267 
268  ContextTrieNode *ContextNode = getContextFor(DIL);
269  if (!ContextNode)
270  return nullptr;
271 
272  // We may have inlined callees during pre-LTO compilation, in which case
273  // we need to rely on the inline stack from !dbg to mark context profile
274  // as inlined, instead of `MarkContextSamplesInlined` during inlining.
275  // Sample profile loader walks through all instructions to get profile,
276  // which calls this function. So once that is done, all previously inlined
277  // context profile should be marked properly.
278  FunctionSamples *Samples = ContextNode->getFunctionSamples();
279  if (Samples && ContextNode->getParentContext() != &RootContext)
280  Samples->getContext().setState(InlinedContext);
281 
282  return Samples;
283 }
284 
288  if (!Node)
289  return nullptr;
290 
291  return Node->getFunctionSamples();
292 }
293 
297  return FuncToCtxtProfiles[CanonName];
298 }
299 
302  return FuncToCtxtProfiles[Name];
303 }
304 
306  bool MergeContext) {
308  return getBaseSamplesFor(CanonName, MergeContext);
309 }
310 
312  bool MergeContext) {
313  LLVM_DEBUG(dbgs() << "Getting base profile for function: " << Name << "\n");
314  // Convert real function names to MD5 names, if the input profile is
315  // MD5-based.
316  std::string FGUID;
318 
319  // Base profile is top-level node (child of root node), so try to retrieve
320  // existing top-level node for given function first. If it exists, it could be
321  // that we've merged base profile before, or there's actually context-less
322  // profile from the input (e.g. due to unreliable stack walking).
323  ContextTrieNode *Node = getTopLevelContextNode(Name);
324  if (MergeContext) {
325  LLVM_DEBUG(dbgs() << " Merging context profile into base profile: " << Name
326  << "\n");
327 
328  // We have profile for function under different contexts,
329  // create synthetic base profile and merge context profiles
330  // into base profile.
331  for (auto *CSamples : FuncToCtxtProfiles[Name]) {
332  SampleContext &Context = CSamples->getContext();
333  // Skip inlined context profile and also don't re-merge any context
334  if (Context.hasState(InlinedContext) || Context.hasState(MergedContext))
335  continue;
336 
338  if (FromNode == Node)
339  continue;
340 
341  ContextTrieNode &ToNode = promoteMergeContextSamplesTree(*FromNode);
342  assert((!Node || Node == &ToNode) && "Expect only one base profile");
343  Node = &ToNode;
344  }
345  }
346 
347  // Still no profile even after merge/promotion (if allowed)
348  if (!Node)
349  return nullptr;
350 
351  return Node->getFunctionSamples();
352 }
353 
355  const FunctionSamples *InlinedSamples) {
356  assert(InlinedSamples && "Expect non-null inlined samples");
357  LLVM_DEBUG(dbgs() << "Marking context profile as inlined: "
358  << InlinedSamples->getContext().toString() << "\n");
359  InlinedSamples->getContext().setState(InlinedContext);
360 }
361 
363 
365  const Instruction &Inst, StringRef CalleeName) {
366  LLVM_DEBUG(dbgs() << "Promoting and merging context tree for instr: \n"
367  << Inst << "\n");
368  // Get the caller context for the call instruction, we don't use callee
369  // name from call because there can be context from indirect calls too.
370  DILocation *DIL = Inst.getDebugLoc();
371  ContextTrieNode *CallerNode = getContextFor(DIL);
372  if (!CallerNode)
373  return;
374 
375  // Get the context that needs to be promoted
377  // For indirect call, CalleeName will be empty, in which case we need to
378  // promote all non-inlined child context profiles.
379  if (CalleeName.empty()) {
380  for (auto &It : CallerNode->getAllChildContext()) {
381  ContextTrieNode *NodeToPromo = &It.second;
382  if (CallSite != NodeToPromo->getCallSiteLoc())
383  continue;
384  FunctionSamples *FromSamples = NodeToPromo->getFunctionSamples();
385  if (FromSamples && FromSamples->getContext().hasState(InlinedContext))
386  continue;
387  promoteMergeContextSamplesTree(*NodeToPromo);
388  }
389  return;
390  }
391 
392  // Get the context for the given callee that needs to be promoted
393  ContextTrieNode *NodeToPromo =
394  CallerNode->getChildContext(CallSite, CalleeName);
395  if (!NodeToPromo)
396  return;
397 
398  promoteMergeContextSamplesTree(*NodeToPromo);
399 }
400 
402  ContextTrieNode &NodeToPromo) {
403  // Promote the input node to be directly under root. This can happen
404  // when we decided to not inline a function under context represented
405  // by the input node. The promote and merge is then needed to reflect
406  // the context profile in the base (context-less) profile.
407  FunctionSamples *FromSamples = NodeToPromo.getFunctionSamples();
408  assert(FromSamples && "Shouldn't promote a context without profile");
409  LLVM_DEBUG(dbgs() << " Found context tree root to promote: "
410  << FromSamples->getContext().toString() << "\n");
411 
412  assert(!FromSamples->getContext().hasState(InlinedContext) &&
413  "Shouldn't promote inlined context profile");
414  uint32_t ContextFramesToRemove =
415  FromSamples->getContext().getContextFrames().size() - 1;
416  return promoteMergeContextSamplesTree(NodeToPromo, RootContext,
417  ContextFramesToRemove);
418 }
419 
420 void SampleContextTracker::dump() { RootContext.dumpTree(); }
421 
424  return Node->getFuncName();
425  assert(GUIDToFuncNameMap && "GUIDToFuncNameMap needs to be populated first");
426  return GUIDToFuncNameMap->lookup(std::stoull(Node->getFuncName().data()));
427 }
428 
431  return getOrCreateContextPath(Context, false);
432 }
433 
435 SampleContextTracker::getCalleeContextFor(const DILocation *DIL,
436  StringRef CalleeName) {
437  assert(DIL && "Expect non-null location");
438 
439  ContextTrieNode *CallContext = getContextFor(DIL);
440  if (!CallContext)
441  return nullptr;
442 
443  // When CalleeName is empty, the child context profile with max
444  // total samples will be returned.
445  return CallContext->getChildContext(
446  FunctionSamples::getCallSiteIdentifier(DIL), CalleeName);
447 }
448 
450  assert(DIL && "Expect non-null location");
452 
453  // Use C++ linkage name if possible.
454  const DILocation *PrevDIL = DIL;
455  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
456  StringRef Name = PrevDIL->getScope()->getSubprogram()->getLinkageName();
457  if (Name.empty())
458  Name = PrevDIL->getScope()->getSubprogram()->getName();
459  S.push_back(
460  std::make_pair(FunctionSamples::getCallSiteIdentifier(DIL), Name));
461  PrevDIL = DIL;
462  }
463 
464  // Push root node, note that root node like main may only
465  // a name, but not linkage name.
466  StringRef RootName = PrevDIL->getScope()->getSubprogram()->getLinkageName();
467  if (RootName.empty())
468  RootName = PrevDIL->getScope()->getSubprogram()->getName();
469  S.push_back(std::make_pair(LineLocation(0, 0), RootName));
470 
471  // Convert real function names to MD5 names, if the input profile is
472  // MD5-based.
473  std::list<std::string> MD5Names;
475  for (auto &Location : S) {
476  MD5Names.emplace_back();
477  getRepInFormat(Location.second, FunctionSamples::UseMD5, MD5Names.back());
478  Location.second = MD5Names.back();
479  }
480  }
481 
482  ContextTrieNode *ContextNode = &RootContext;
483  int I = S.size();
484  while (--I >= 0 && ContextNode) {
485  LineLocation &CallSite = S[I].first;
486  StringRef CalleeName = S[I].second;
487  ContextNode = ContextNode->getChildContext(CallSite, CalleeName);
488  }
489 
490  if (I < 0)
491  return ContextNode;
492 
493  return nullptr;
494 }
495 
497 SampleContextTracker::getOrCreateContextPath(const SampleContext &Context,
498  bool AllowCreate) {
499  ContextTrieNode *ContextNode = &RootContext;
500  LineLocation CallSiteLoc(0, 0);
501 
502  for (auto &Callsite : Context.getContextFrames()) {
503  // Create child node at parent line/disc location
504  if (AllowCreate) {
505  ContextNode =
506  ContextNode->getOrCreateChildContext(CallSiteLoc, Callsite.FuncName);
507  } else {
508  ContextNode =
509  ContextNode->getChildContext(CallSiteLoc, Callsite.FuncName);
510  }
511  CallSiteLoc = Callsite.Location;
512  }
513 
514  assert((!AllowCreate || ContextNode) &&
515  "Node must exist if creation is allowed");
516  return ContextNode;
517 }
518 
519 ContextTrieNode *SampleContextTracker::getTopLevelContextNode(StringRef FName) {
520  assert(!FName.empty() && "Top level node query must provide valid name");
521  return RootContext.getChildContext(LineLocation(0, 0), FName);
522 }
523 
524 ContextTrieNode &SampleContextTracker::addTopLevelContextNode(StringRef FName) {
525  assert(!getTopLevelContextNode(FName) && "Node to add must not exist");
526  return *RootContext.getOrCreateChildContext(LineLocation(0, 0), FName);
527 }
528 
529 void SampleContextTracker::mergeContextNode(ContextTrieNode &FromNode,
530  ContextTrieNode &ToNode,
531  uint32_t ContextFramesToRemove) {
532  FunctionSamples *FromSamples = FromNode.getFunctionSamples();
533  FunctionSamples *ToSamples = ToNode.getFunctionSamples();
534  if (FromSamples && ToSamples) {
535  // Merge/duplicate FromSamples into ToSamples
536  ToSamples->merge(*FromSamples);
537  ToSamples->getContext().setState(SyntheticContext);
538  FromSamples->getContext().setState(MergedContext);
539  if (FromSamples->getContext().hasAttribute(ContextShouldBeInlined))
541  } else if (FromSamples) {
542  // Transfer FromSamples from FromNode to ToNode
543  ToNode.setFunctionSamples(FromSamples);
544  FromSamples->getContext().setState(SyntheticContext);
545  FromSamples->getContext().promoteOnPath(ContextFramesToRemove);
546  FromNode.setFunctionSamples(nullptr);
547  }
548 }
549 
551  ContextTrieNode &FromNode, ContextTrieNode &ToNodeParent,
552  uint32_t ContextFramesToRemove) {
553  assert(ContextFramesToRemove && "Context to remove can't be empty");
554 
555  // Ignore call site location if destination is top level under root
556  LineLocation NewCallSiteLoc = LineLocation(0, 0);
557  LineLocation OldCallSiteLoc = FromNode.getCallSiteLoc();
558  ContextTrieNode &FromNodeParent = *FromNode.getParentContext();
559  ContextTrieNode *ToNode = nullptr;
560  bool MoveToRoot = (&ToNodeParent == &RootContext);
561  if (!MoveToRoot) {
562  NewCallSiteLoc = OldCallSiteLoc;
563  }
564 
565  // Locate destination node, create/move if not existing
566  ToNode = ToNodeParent.getChildContext(NewCallSiteLoc, FromNode.getFuncName());
567  if (!ToNode) {
568  // Do not delete node to move from its parent here because
569  // caller is iterating over children of that parent node.
570  ToNode = &ToNodeParent.moveToChildContext(
571  NewCallSiteLoc, std::move(FromNode), ContextFramesToRemove, false);
572  } else {
573  // Destination node exists, merge samples for the context tree
574  mergeContextNode(FromNode, *ToNode, ContextFramesToRemove);
575  LLVM_DEBUG({
576  if (ToNode->getFunctionSamples())
577  dbgs() << " Context promoted and merged to: "
578  << ToNode->getFunctionSamples()->getContext().toString() << "\n";
579  });
580 
581  // Recursively promote and merge children
582  for (auto &It : FromNode.getAllChildContext()) {
583  ContextTrieNode &FromChildNode = It.second;
584  promoteMergeContextSamplesTree(FromChildNode, *ToNode,
585  ContextFramesToRemove);
586  }
587 
588  // Remove children once they're all merged
589  FromNode.getAllChildContext().clear();
590  }
591 
592  // For root of subtree, remove itself from old parent too
593  if (MoveToRoot)
594  FromNodeParent.removeChildContext(OldCallSiteLoc, ToNode->getFuncName());
595 
596  return *ToNode;
597 }
598 } // namespace llvm
llvm::SampleContextTracker::getCalleeContextSamplesFor
FunctionSamples * getCalleeContextSamplesFor(const CallBase &Inst, StringRef CalleeName)
Definition: SampleContextTracker.cpp:216
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::SampleContextTracker::getFuncNameFor
StringRef getFuncNameFor(ContextTrieNode *Node) const
Definition: SampleContextTracker.cpp:422
llvm::ContextTrieNode::dumpNode
void dumpNode()
Definition: SampleContextTracker.cpp:151
DebugInfoMetadata.h
llvm::sampleprof::SampleContext::hasAttribute
bool hasAttribute(ContextAttributeMask A)
Definition: SampleProf.h:590
llvm::Function
Definition: Function.h:60
StringRef.h
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::ContextTrieNode::getFuncName
StringRef getFuncName() const
Definition: SampleContextTracker.cpp:122
llvm::ContextTrieNode::setParentContext
void setParentContext(ContextTrieNode *Parent)
Definition: SampleContextTracker.cpp:147
llvm::sampleprof::SampleContext::toString
std::string toString() const
Definition: SampleProf.h:615
llvm::sampleprof::SampleProfileMap
std::unordered_map< SampleContext, FunctionSamples, SampleContext::Hash > SampleProfileMap
Definition: SampleProf.h:1193
llvm::SampleContextTracker::markContextSamplesInlined
void markContextSamplesInlined(const FunctionSamples *InlinedSamples)
Definition: SampleContextTracker.cpp:354
llvm::SampleContextTracker::getContextFor
ContextTrieNode * getContextFor(const SampleContext &Context)
Definition: SampleContextTracker.cpp:430
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1551
llvm::sampleprof::ContextShouldBeInlined
@ ContextShouldBeInlined
Definition: SampleProf.h:442
llvm::Optional< uint32_t >
llvm::ContextTrieNode::getHottestChildContext
ContextTrieNode * getHottestChildContext(const LineLocation &CallSite)
Definition: SampleContextTracker.cpp:44
llvm::ContextTrieNode::getCallSiteLoc
LineLocation getCallSiteLoc() const
Definition: SampleContextTracker.cpp:141
llvm::sampleprof::MergedContext
@ MergedContext
Definition: SampleProf.h:435
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
Context
LLVMContext & Context
Definition: NVVMIntrRange.cpp:66
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
Instruction.h
llvm::sampleprof::getRepInFormat
static StringRef getRepInFormat(StringRef Name, bool UseMD5, std::string &GUIDBuf)
Get the proper representation of a string according to whether the current Format uses MD5 to represe...
Definition: SampleProf.h:107
llvm::sampleprof::FunctionSamples::getTotalSamples
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition: SampleProf.h:885
llvm::sampleprof::SampleContext::hasState
bool hasState(ContextStateMask S)
Definition: SampleProf.h:594
InstrTypes.h
llvm::StringMap::insert
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:276
llvm::sampleprof::SyntheticContext
@ SyntheticContext
Definition: SampleProf.h:433
SampleProf.h
llvm::Instruction
Definition: Instruction.h:42
StringMap.h
llvm::ContextTrieNode::setFunctionSamples
void setFunctionSamples(FunctionSamples *FSamples)
Definition: SampleContextTracker.cpp:128
llvm::sampleprof::SampleContext
Definition: SampleProf.h:501
llvm::SampleContextTracker::ContextSamplesTy
std::set< FunctionSamples *, ProfileComparer > ContextSamplesTy
Definition: SampleContextTracker.h:106
llvm::SampleContextTracker::dump
void dump()
Definition: SampleContextTracker.cpp:420
llvm::sampleprof::SampleContext::getContextFrames
SampleContextFrames getContextFrames() const
Definition: SampleProf.h:600
llvm::ContextTrieNode::getParentContext
ContextTrieNode * getParentContext() const
Definition: SampleContextTracker.cpp:143
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::sampleprof::SampleContext::setAttribute
void setAttribute(ContextAttributeMask A)
Definition: SampleProf.h:591
uint64_t
llvm::ContextTrieNode::moveToChildContext
ContextTrieNode & moveToChildContext(const LineLocation &CallSite, ContextTrieNode &&NodeToMove, uint32_t ContextFramesToRemove, bool DeleteNode=true)
Definition: SampleContextTracker.cpp:66
llvm::sampleprof::FunctionSamples
Representation of the samples collected for a function.
Definition: SampleProf.h:720
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap
Definition: DenseMap.h:716
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::sampleprof::FunctionSamples::getCallSiteHash
static uint64_t getCallSiteHash(StringRef CalleeName, const LineLocation &Callsite)
Returns a unique hash code for a combination of a callsite location and the callee function name.
Definition: SampleProf.cpp:240
llvm::sampleprof::SampleContext::promoteOnPath
void promoteOnPath(uint32_t ContextFramesToRemove)
Definition: SampleProf.h:560
llvm::SampleContextTracker::SampleContextTracker
SampleContextTracker(SampleProfileMap &Profiles, const DenseMap< uint64_t, StringRef > *GUIDToFuncNameMap)
Definition: SampleContextTracker.cpp:197
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SampleContextTracker::promoteMergeContextSamplesTree
void promoteMergeContextSamplesTree(const Instruction &Inst, StringRef CalleeName)
Definition: SampleContextTracker.cpp:364
llvm::sampleprof::SampleContext::setState
void setState(ContextStateMask S)
Definition: SampleProf.h:595
llvm::sampleprof::FunctionSamples::UseMD5
static bool UseMD5
Whether the profile uses MD5 to represent string.
Definition: SampleProf.h:1123
llvm::sampleprof::LineLocation
Represents the relative location of an instruction.
Definition: SampleProf.h:282
llvm::SampleContextTracker::getAllContextSamplesFor
ContextSamplesTy & getAllContextSamplesFor(const Function &Func)
Definition: SampleContextTracker.cpp:295
llvm::ContextTrieNode::getChildContext
ContextTrieNode * getChildContext(const LineLocation &CallSite, StringRef ChildName)
Definition: SampleContextTracker.cpp:31
llvm::ContextTrieNode::getAllChildContext
std::map< uint64_t, ContextTrieNode > & getAllChildContext()
Definition: SampleContextTracker.cpp:118
llvm::ContextTrieNode::getOrCreateChildContext
ContextTrieNode * getOrCreateChildContext(const LineLocation &CallSite, StringRef ChildName, bool AllowCreate=true)
Definition: SampleContextTracker.cpp:179
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
uint32_t
llvm::ContextTrieNode::getFunctionSamples
FunctionSamples * getFunctionSamples() const
Definition: SampleContextTracker.cpp:124
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::ContextTrieNode
Definition: SampleContextTracker.h:33
llvm::ContextTrieNode::getFunctionSize
Optional< uint32_t > getFunctionSize() const
Definition: SampleContextTracker.cpp:132
SampleContextTracker.h
llvm::sampleprof::InlinedContext
@ InlinedContext
Definition: SampleProf.h:434
llvm::SampleContextTracker::getRootContext
ContextTrieNode & getRootContext()
Definition: SampleContextTracker.cpp:362
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::ContextTrieNode::dumpTree
void dumpTree()
Definition: SampleContextTracker.cpp:162
llvm::pdb::PDB_SymType::CallSite
@ CallSite
llvm::SampleContextTracker::getBaseSamplesFor
FunctionSamples * getBaseSamplesFor(const Function &Func, bool MergeContext=true)
Definition: SampleContextTracker.cpp:305
llvm::sampleprof::FunctionSamples::merge
sampleprof_error merge(const FunctionSamples &Other, uint64_t Weight=1)
Merge the samples in Other into this one.
Definition: SampleProf.h:941
llvm::sampleprof::FunctionSamples::getContext
SampleContext & getContext() const
Definition: SampleProf.h:1118
llvm::ContextTrieNode::addFunctionSize
void addFunctionSize(uint32_t FSize)
Definition: SampleContextTracker.cpp:134
llvm::sampleprof::FunctionSamples::getCanonicalFnName
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition: SampleProf.h:1022
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:367
llvm::SampleContextTracker::getContextSamplesFor
FunctionSamples * getContextSamplesFor(const DILocation *DIL)
Definition: SampleContextTracker.cpp:265
llvm::SPIRV::Decoration::Location
@ Location
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
llvm::ContextTrieNode::removeChildContext
void removeChildContext(const LineLocation &CallSite, StringRef ChildName)
Definition: SampleContextTracker.cpp:111
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1174
llvm::SampleContextTracker::getIndirectCalleeContextSamplesFor
std::vector< const FunctionSamples * > getIndirectCalleeContextSamplesFor(const DILocation *DIL)
Definition: SampleContextTracker.cpp:245
llvm::sampleprof::FunctionSamples::getCallSiteIdentifier
static LineLocation getCallSiteIdentifier(const DILocation *DIL, bool ProfileIsFS=false)
Returns a unique call site identifier for a given debug location of a call instruction.
Definition: SampleProf.cpp:223