1 //===-- CallContext.h - Call Context Handler ---------------------*- C++-*-===//
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 #ifndef LLVM_TOOLS_LLVM_PROFGEN_CALLCONTEXT_H
10 #define LLVM_TOOLS_LLVM_PROFGEN_CALLCONTEXT_H
11 
12 #include "llvm/ProfileData/SampleProf.h"
13 #include <sstream>
14 #include <string>
15 #include <vector>
16 
17 namespace llvm {
18 namespace sampleprof {
19 
20 // Function name, LineLocation
21 typedef std::pair<std::string, LineLocation> FrameLocation;
22 
23 typedef SmallVector<FrameLocation, 4> FrameLocationStack;
24 
getCallSite(const FrameLocation & Callsite)25 inline std::string getCallSite(const FrameLocation &Callsite) {
26   std::string CallsiteStr = Callsite.first;
27   CallsiteStr += ":";
28   CallsiteStr += Twine(Callsite.second.LineOffset).str();
29   if (Callsite.second.Discriminator > 0) {
30     CallsiteStr += ".";
31     CallsiteStr += Twine(Callsite.second.Discriminator).str();
32   }
33   return CallsiteStr;
34 }
35 
36 // TODO: This operation is expansive. If it ever gets called multiple times we
37 // may think of making a class wrapper with internal states for it.
getLocWithContext(const FrameLocationStack & Context)38 inline std::string getLocWithContext(const FrameLocationStack &Context) {
39   std::ostringstream OContextStr;
40   for (const auto &Callsite : Context) {
41     if (OContextStr.str().size())
42       OContextStr << " @ ";
43     OContextStr << getCallSite(Callsite);
44   }
45   return OContextStr.str();
46 }
47 
48 // Reverse call context, i.e., in the order of callee frames to caller frames,
49 // is useful during instruction printing or pseudo probe printing.
50 inline std::string
getReversedLocWithContext(const FrameLocationStack & Context)51 getReversedLocWithContext(const FrameLocationStack &Context) {
52   std::ostringstream OContextStr;
53   for (const auto &Callsite : reverse(Context)) {
54     if (OContextStr.str().size())
55       OContextStr << " @ ";
56     OContextStr << getCallSite(Callsite);
57   }
58   return OContextStr.str();
59 }
60 
61 } // end namespace sampleprof
62 } // end namespace llvm
63 
64 #endif
65