LLVM  16.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 SampleContextTracker::moveContextSamples(ContextTrieNode &ToNodeParent,
68  const LineLocation &CallSite,
69  ContextTrieNode &&NodeToMove) {
70  uint64_t Hash =
71  FunctionSamples::getCallSiteHash(NodeToMove.getFuncName(), CallSite);
72  std::map<uint64_t, ContextTrieNode> &AllChildContext =
73  ToNodeParent.getAllChildContext();
74  assert(!AllChildContext.count(Hash) && "Node to remove must exist");
75  AllChildContext[Hash] = NodeToMove;
76  ContextTrieNode &NewNode = AllChildContext[Hash];
77  NewNode.setCallSiteLoc(CallSite);
78 
79  // Walk through nodes in the moved the subtree, and update
80  // FunctionSamples' context as for the context promotion.
81  // We also need to set new parant link for all children.
82  std::queue<ContextTrieNode *> NodeToUpdate;
83  NewNode.setParentContext(&ToNodeParent);
84  NodeToUpdate.push(&NewNode);
85 
86  while (!NodeToUpdate.empty()) {
87  ContextTrieNode *Node = NodeToUpdate.front();
88  NodeToUpdate.pop();
89  FunctionSamples *FSamples = Node->getFunctionSamples();
90 
91  if (FSamples) {
92  setContextNode(FSamples, Node);
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  return NewNode;
104 }
105 
107  StringRef CalleeName) {
108  uint64_t Hash = FunctionSamples::getCallSiteHash(CalleeName, CallSite);
109  // Note this essentially calls dtor and destroys that child context
110  AllChildContext.erase(Hash);
111 }
112 
113 std::map<uint64_t, ContextTrieNode> &ContextTrieNode::getAllChildContext() {
114  return AllChildContext;
115 }
116 
117 StringRef ContextTrieNode::getFuncName() const { return FuncName; }
118 
120  return FuncSamples;
121 }
122 
124  FuncSamples = FSamples;
125 }
126 
128 
130  if (!FuncSize)
131  FuncSize = 0;
132 
133  FuncSize = FuncSize.value() + FSize;
134 }
135 
136 LineLocation ContextTrieNode::getCallSiteLoc() const { return CallSiteLoc; }
137 
139  return ParentContext;
140 }
141 
143  ParentContext = Parent;
144 }
145 
147  CallSiteLoc = Loc;
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");
206  assert(!NewNode->getFunctionSamples() &&
207  "New node can't have sample profile");
208  NewNode->setFunctionSamples(FSamples);
209  }
211 }
212 
214  for (auto *Node : *this) {
215  FunctionSamples *FSamples = Node->getFunctionSamples();
216  if (FSamples) {
217  FSamples->getContext().setState(RawContext);
218  setContextNode(FSamples, Node);
219  FuncToCtxtProfiles[Node->getFuncName()].push_back(FSamples);
220  }
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: " << getContextString(CalleeContext)
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 
346  ContextTrieNode *FromNode = getContextNodeForProfile(CSamples);
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  << getContextString(*InlinedSamples) << "\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  (void)FromSamples; // Unused in release build.
419 
420  LLVM_DEBUG(dbgs() << " Found context tree root to promote: "
421  << getContextString(&NodeToPromo) << "\n");
422 
423  assert(!FromSamples->getContext().hasState(InlinedContext) &&
424  "Shouldn't promote inlined context profile");
425  return promoteMergeContextSamplesTree(NodeToPromo, RootContext);
426 }
427 
428 #ifndef NDEBUG
429 std::string
431  return getContextString(getContextNodeForProfile(&FSamples));
432 }
433 
434 std::string
437  if (Node == &RootContext)
438  return std::string();
439  Res.emplace_back(Node->getFuncName(), LineLocation(0, 0));
440 
441  ContextTrieNode *PreNode = Node;
442  Node = Node->getParentContext();
443  while (Node && Node != &RootContext) {
444  Res.emplace_back(Node->getFuncName(), PreNode->getCallSiteLoc());
445  PreNode = Node;
446  Node = Node->getParentContext();
447  }
448 
449  std::reverse(Res.begin(), Res.end());
450 
452 }
453 #endif
454 
455 void SampleContextTracker::dump() { RootContext.dumpTree(); }
456 
459  return Node->getFuncName();
460  assert(GUIDToFuncNameMap && "GUIDToFuncNameMap needs to be populated first");
461  return GUIDToFuncNameMap->lookup(std::stoull(Node->getFuncName().data()));
462 }
463 
466  return getOrCreateContextPath(Context, false);
467 }
468 
470 SampleContextTracker::getCalleeContextFor(const DILocation *DIL,
471  StringRef CalleeName) {
472  assert(DIL && "Expect non-null location");
473 
474  ContextTrieNode *CallContext = getContextFor(DIL);
475  if (!CallContext)
476  return nullptr;
477 
478  // When CalleeName is empty, the child context profile with max
479  // total samples will be returned.
480  return CallContext->getChildContext(
481  FunctionSamples::getCallSiteIdentifier(DIL), CalleeName);
482 }
483 
485  assert(DIL && "Expect non-null location");
487 
488  // Use C++ linkage name if possible.
489  const DILocation *PrevDIL = DIL;
490  for (DIL = DIL->getInlinedAt(); DIL; DIL = DIL->getInlinedAt()) {
491  StringRef Name = PrevDIL->getScope()->getSubprogram()->getLinkageName();
492  if (Name.empty())
493  Name = PrevDIL->getScope()->getSubprogram()->getName();
494  S.push_back(
495  std::make_pair(FunctionSamples::getCallSiteIdentifier(DIL), Name));
496  PrevDIL = DIL;
497  }
498 
499  // Push root node, note that root node like main may only
500  // a name, but not linkage name.
501  StringRef RootName = PrevDIL->getScope()->getSubprogram()->getLinkageName();
502  if (RootName.empty())
503  RootName = PrevDIL->getScope()->getSubprogram()->getName();
504  S.push_back(std::make_pair(LineLocation(0, 0), RootName));
505 
506  // Convert real function names to MD5 names, if the input profile is
507  // MD5-based.
508  std::list<std::string> MD5Names;
510  for (auto &Location : S) {
511  MD5Names.emplace_back();
512  getRepInFormat(Location.second, FunctionSamples::UseMD5, MD5Names.back());
513  Location.second = MD5Names.back();
514  }
515  }
516 
517  ContextTrieNode *ContextNode = &RootContext;
518  int I = S.size();
519  while (--I >= 0 && ContextNode) {
520  LineLocation &CallSite = S[I].first;
521  StringRef CalleeName = S[I].second;
522  ContextNode = ContextNode->getChildContext(CallSite, CalleeName);
523  }
524 
525  if (I < 0)
526  return ContextNode;
527 
528  return nullptr;
529 }
530 
533  bool AllowCreate) {
534  ContextTrieNode *ContextNode = &RootContext;
535  LineLocation CallSiteLoc(0, 0);
536 
537  for (const auto &Callsite : Context.getContextFrames()) {
538  // Create child node at parent line/disc location
539  if (AllowCreate) {
540  ContextNode =
541  ContextNode->getOrCreateChildContext(CallSiteLoc, Callsite.FuncName);
542  } else {
543  ContextNode =
544  ContextNode->getChildContext(CallSiteLoc, Callsite.FuncName);
545  }
546  CallSiteLoc = Callsite.Location;
547  }
548 
549  assert((!AllowCreate || ContextNode) &&
550  "Node must exist if creation is allowed");
551  return ContextNode;
552 }
553 
554 ContextTrieNode *SampleContextTracker::getTopLevelContextNode(StringRef FName) {
555  assert(!FName.empty() && "Top level node query must provide valid name");
556  return RootContext.getChildContext(LineLocation(0, 0), FName);
557 }
558 
559 ContextTrieNode &SampleContextTracker::addTopLevelContextNode(StringRef FName) {
560  assert(!getTopLevelContextNode(FName) && "Node to add must not exist");
561  return *RootContext.getOrCreateChildContext(LineLocation(0, 0), FName);
562 }
563 
564 void SampleContextTracker::mergeContextNode(ContextTrieNode &FromNode,
565  ContextTrieNode &ToNode) {
566  FunctionSamples *FromSamples = FromNode.getFunctionSamples();
567  FunctionSamples *ToSamples = ToNode.getFunctionSamples();
568  if (FromSamples && ToSamples) {
569  // Merge/duplicate FromSamples into ToSamples
570  ToSamples->merge(*FromSamples);
571  ToSamples->getContext().setState(SyntheticContext);
572  FromSamples->getContext().setState(MergedContext);
573  if (FromSamples->getContext().hasAttribute(ContextShouldBeInlined))
575  } else if (FromSamples) {
576  // Transfer FromSamples from FromNode to ToNode
577  ToNode.setFunctionSamples(FromSamples);
578  setContextNode(FromSamples, &ToNode);
579  FromSamples->getContext().setState(SyntheticContext);
580  }
581 }
582 
584  ContextTrieNode &FromNode, ContextTrieNode &ToNodeParent) {
585 
586  // Ignore call site location if destination is top level under root
587  LineLocation NewCallSiteLoc = LineLocation(0, 0);
588  LineLocation OldCallSiteLoc = FromNode.getCallSiteLoc();
589  ContextTrieNode &FromNodeParent = *FromNode.getParentContext();
590  ContextTrieNode *ToNode = nullptr;
591  bool MoveToRoot = (&ToNodeParent == &RootContext);
592  if (!MoveToRoot) {
593  NewCallSiteLoc = OldCallSiteLoc;
594  }
595 
596  // Locate destination node, create/move if not existing
597  ToNode = ToNodeParent.getChildContext(NewCallSiteLoc, FromNode.getFuncName());
598  if (!ToNode) {
599  // Do not delete node to move from its parent here because
600  // caller is iterating over children of that parent node.
601  ToNode =
602  &moveContextSamples(ToNodeParent, NewCallSiteLoc, std::move(FromNode));
603  LLVM_DEBUG({
604  dbgs() << " Context promoted and merged to: " << getContextString(ToNode)
605  << "\n";
606  });
607  } else {
608  // Destination node exists, merge samples for the context tree
609  mergeContextNode(FromNode, *ToNode);
610  LLVM_DEBUG({
611  if (ToNode->getFunctionSamples())
612  dbgs() << " Context promoted and merged to: "
613  << getContextString(ToNode) << "\n";
614  });
615 
616  // Recursively promote and merge children
617  for (auto &It : FromNode.getAllChildContext()) {
618  ContextTrieNode &FromChildNode = It.second;
619  promoteMergeContextSamplesTree(FromChildNode, *ToNode);
620  }
621 
622  // Remove children once they're all merged
623  FromNode.getAllChildContext().clear();
624  }
625 
626  // For root of subtree, remove itself from old parent too
627  if (MoveToRoot)
628  FromNodeParent.removeChildContext(OldCallSiteLoc, ToNode->getFuncName());
629 
630  return *ToNode;
631 }
632 
634  SampleProfileMap &ContextLessProfiles) {
635  for (auto *Node : *this) {
636  FunctionSamples *FProfile = Node->getFunctionSamples();
637  // Profile's context can be empty, use ContextNode's func name.
638  if (FProfile)
639  ContextLessProfiles[Node->getFuncName()].merge(*FProfile);
640  }
641 }
642 } // namespace llvm
llvm::SampleContextTracker::getCalleeContextSamplesFor
FunctionSamples * getCalleeContextSamplesFor(const CallBase &Inst, StringRef CalleeName)
Definition: SampleContextTracker.cpp:225
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::SampleContextTracker::getContextString
std::string getContextString(const FunctionSamples &FSamples) const
Definition: SampleContextTracker.cpp:430
llvm::SampleContextTracker::getFuncNameFor
StringRef getFuncNameFor(ContextTrieNode *Node) const
Definition: SampleContextTracker.cpp:457
llvm::ContextTrieNode::dumpNode
void dumpNode()
Definition: SampleContextTracker.cpp:150
llvm::sampleprof::RawContext
@ RawContext
Definition: SampleProf.h:433
DebugInfoMetadata.h
llvm::sampleprof::SampleContext::hasAttribute
bool hasAttribute(ContextAttributeMask A)
Definition: SampleProf.h:581
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:1181
llvm::ContextTrieNode::getFuncName
StringRef getFuncName() const
Definition: SampleContextTracker.cpp:117
llvm::SampleContextTracker::populateFuncToCtxtMap
void populateFuncToCtxtMap()
Definition: SampleContextTracker.cpp:213
llvm::ContextTrieNode::setParentContext
void setParentContext(ContextTrieNode *Parent)
Definition: SampleContextTracker.cpp:142
llvm::sampleprof::SampleProfileMap
std::unordered_map< SampleContext, FunctionSamples, SampleContext::Hash > SampleProfileMap
Definition: SampleProf.h:1188
llvm::SampleContextTracker::markContextSamplesInlined
void markContextSamplesInlined(const FunctionSamples *InlinedSamples)
Definition: SampleContextTracker.cpp:363
llvm::SampleContextTracker::getContextFor
ContextTrieNode * getContextFor(const SampleContext &Context)
Definition: SampleContextTracker.cpp:465
llvm::DILocation
Debug location.
Definition: DebugInfoMetadata.h:1557
llvm::sampleprof::ContextShouldBeInlined
@ ContextShouldBeInlined
Definition: SampleProf.h:443
llvm::SampleContextTracker::ContextSamplesTy
std::vector< FunctionSamples * > ContextSamplesTy
Definition: SampleContextTracker.h:92
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:136
llvm::sampleprof::MergedContext
@ MergedContext
Definition: SampleProf.h:436
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
llvm::ContextTrieNode::setCallSiteLoc
void setCallSiteLoc(const LineLocation &Loc)
Definition: SampleContextTracker.cpp:146
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:108
llvm::sampleprof::FunctionSamples::getTotalSamples
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition: SampleProf.h:876
llvm::sampleprof::SampleContext::hasState
bool hasState(ContextStateMask S)
Definition: SampleProf.h:585
InstrTypes.h
llvm::sampleprof::SyntheticContext
@ SyntheticContext
Definition: SampleProf.h:434
SampleProf.h
llvm::Instruction
Definition: Instruction.h:42
llvm::ContextTrieNode::setFunctionSamples
void setFunctionSamples(FunctionSamples *FSamples)
Definition: SampleContextTracker.cpp:123
llvm::sampleprof::SampleContext
Definition: SampleProf.h:502
llvm::SampleContextTracker::dump
void dump()
Definition: SampleContextTracker.cpp:455
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
llvm::ContextTrieNode::getParentContext
ContextTrieNode * getParentContext() const
Definition: SampleContextTracker.cpp:138
llvm::sampleprof::SampleContext::setAttribute
void setAttribute(ContextAttributeMask A)
Definition: SampleProf.h:582
uint64_t
llvm::sampleprof::FunctionSamples
Representation of the samples collected for a function.
Definition: SampleProf.h:711
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:238
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::SampleContextTracker::getContextNodeForProfile
ContextTrieNode * getContextNodeForProfile(const FunctionSamples *FSamples) const
Definition: SampleContextTracker.h:137
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:586
llvm::sampleprof::FunctionSamples::UseMD5
static bool UseMD5
Whether the profile uses MD5 to represent string.
Definition: SampleProf.h:1118
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:304
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:113
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:50
uint32_t
llvm::ContextTrieNode::getFunctionSamples
FunctionSamples * getFunctionSamples() const
Definition: SampleContextTracker.cpp:119
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:35
llvm::ContextTrieNode::getFunctionSize
Optional< uint32_t > getFunctionSize() const
Definition: SampleContextTracker.cpp:127
llvm::SampleContextTracker::SampleContextTracker
SampleContextTracker()=default
SampleContextTracker.h
llvm::sampleprof::InlinedContext
@ InlinedContext
Definition: SampleProf.h:435
llvm::SampleContextTracker::getOrCreateContextPath
ContextTrieNode * getOrCreateContextPath(const SampleContext &Context, bool AllowCreate)
Definition: SampleContextTracker.cpp:532
llvm::SampleContextTracker::getRootContext
ContextTrieNode & getRootContext()
Definition: SampleContextTracker.cpp:371
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: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:936
llvm::sampleprof::FunctionSamples::getContext
SampleContext & getContext() const
Definition: SampleProf.h:1113
llvm::ContextTrieNode::addFunctionSize
void addFunctionSize(uint32_t FSize)
Definition: SampleContextTracker.cpp:129
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:1017
llvm::SampleContextTracker::createContextLessProfileMap
void createContextLessProfileMap(SampleProfileMap &ContextLessProfiles)
Definition: SampleContextTracker.cpp:633
llvm::Instruction::getDebugLoc
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:354
llvm::SampleContextTracker::getContextSamplesFor
FunctionSamples * getContextSamplesFor(const DILocation *DIL)
Definition: SampleContextTracker.cpp:274
llvm::ContextTrieNode::removeChildContext
void removeChildContext(const LineLocation &CallSite, StringRef ChildName)
Definition: SampleContextTracker.cpp:106
llvm::sampleprof::SampleContext::getContextString
static std::string getContextString(SampleContextFrames Context, bool IncludeLeafLineLocation=false)
Definition: SampleProf.h:593
llvm::reverse
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:365
llvm::CallBase
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1174
StringMap.h
llvm::SampleContextTracker::getIndirectCalleeContextSamplesFor
std::vector< const FunctionSamples * > getIndirectCalleeContextSamplesFor(const DILocation *DIL)
Definition: SampleContextTracker.cpp:254
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:221
llvm::SmallVectorImpl::emplace_back
reference emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:923