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