1 //===- bolt/Profile/ProfileReaderBase.h -------------------------*- 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 //  Interface to be implemented by all profile readers.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef BOLT_PROFILE_PROFILE_READER_BASE_H
14 #define BOLT_PROFILE_PROFILE_READER_BASE_H
15 
16 #include "llvm/ADT/StringSet.h"
17 #include "llvm/Support/Error.h"
18 
19 namespace llvm {
20 namespace bolt {
21 
22 class BinaryContext;
23 class BinaryFunction;
24 class BoltAddressTranslation;
25 
26 /// LTO-generated function names take a form:
27 ///
28 ///   <function_name>.lto_priv.<decimal_number>/...
29 ///     or
30 ///   <function_name>.constprop.<decimal_number>/...
31 ///
32 /// they can also be:
33 ///
34 ///   <function_name>.lto_priv.<decimal_number1>.lto_priv.<decimal_number2>/...
35 ///
36 /// The <decimal_number> is a global counter used for the whole program. As a
37 /// result, a tiny change in a program may affect the naming of many LTO
38 /// functions. For us this means that if we do a precise name matching, then
39 /// a large set of functions could be left without a profile.
40 ///
41 /// To solve this issue, we try to match a function to any profile:
42 ///
43 ///   <function_name>.(lto_priv|consprop).*
44 ///
45 /// The name before an asterisk above represents a common LTO name for a family
46 /// of functions. Later, out of all matching profiles we pick the one with the
47 /// best match.
48 ///
49 /// Return a common part of LTO name for a given \p Name.
50 Optional<StringRef> getLTOCommonName(const StringRef Name);
51 
52 class ProfileReaderBase {
53 protected:
54   /// Name of the file with profile.
55   std::string Filename;
56 
57 public:
58   ProfileReaderBase() = delete;
59   ProfileReaderBase(const ProfileReaderBase &) = delete;
60   ProfileReaderBase &operator=(const ProfileReaderBase &) = delete;
61   ProfileReaderBase(ProfileReaderBase &&) = delete;
62   ProfileReaderBase &operator=(ProfileReaderBase &&) = delete;
63 
64   /// Construct a reader for a given file.
ProfileReaderBase(StringRef Filename)65   explicit ProfileReaderBase(StringRef Filename) : Filename(Filename) {}
66 
67   virtual ~ProfileReaderBase() = default;
68 
69   /// Return the name of the file containing the profile.
getFilename()70   StringRef getFilename() const { return Filename; }
71 
72   /// Instruct the profiler to use address-translation tables.
setBAT(BoltAddressTranslation * BAT)73   virtual void setBAT(BoltAddressTranslation *BAT) {}
74 
75   /// Pre-process the profile when functions in \p BC are discovered,
76   /// but not yet disassembled. Once the profile is pre-processed, calls to
77   /// mayHaveProfileData() should be able to identify if the function possibly
78   /// has a profile available.
79   virtual Error preprocessProfile(BinaryContext &BC) = 0;
80 
81   /// Assign profile to all objects in the \p BC while functions are
82   /// in pre-CFG state with instruction addresses available.
83   virtual Error readProfilePreCFG(BinaryContext &BC) = 0;
84 
85   /// Assign profile to all objects in the \p BC.
86   virtual Error readProfile(BinaryContext &BC) = 0;
87 
88   /// Return the string identifying the reader.
89   virtual StringRef getReaderName() const = 0;
90 
91   /// Return true if the function \p BF may have a profile available.
92   /// The result is based on the name(s) of the function alone and the profile
93   /// match is not guaranteed.
94   virtual bool mayHaveProfileData(const BinaryFunction &BF);
95 
96   /// Return true if the profile contains an entry for a local object
97   /// that has an associated file name.
hasLocalsWithFileName()98   virtual bool hasLocalsWithFileName() const { return true; }
99 
100   /// Return all event names used to collect this profile.
getEventNames()101   virtual StringSet<> getEventNames() const { return StringSet<>(); }
102 
103   /// Return true if the source of the profile should be trusted. E.g., even
104   /// good source of profile data may contain discrepancies. Nevertheless, the
105   /// rest of the profile is correct.
106   virtual bool isTrustedSource() const = 0;
107 };
108 
109 } // namespace bolt
110 } // namespace llvm
111 
112 #endif
113