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