xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h (revision 944a4eb089b33241b21979253e0a373ce0bdf984)
1 //===-- BasicBlockSectionsProfileReader.h - BB sections profile reader pass ==//
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 pass creates the basic block cluster info by reading the basic block
10 // sections profile. The cluster info will be used by the basic-block-sections
11 // pass to arrange basic blocks in their sections.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #ifndef LLVM_CODEGEN_BASICBLOCKSECTIONSPROFILEREADER_H
16 #define LLVM_CODEGEN_BASICBLOCKSECTIONSPROFILEREADER_H
17 
18 #include "llvm/ADT/SmallString.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringMap.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/IR/Module.h"
23 #include "llvm/IR/PassManager.h"
24 #include "llvm/InitializePasses.h"
25 #include "llvm/Pass.h"
26 #include "llvm/Support/Error.h"
27 #include "llvm/Support/LineIterator.h"
28 #include "llvm/Support/MemoryBuffer.h"
29 #include "llvm/Support/UniqueBBID.h"
30 #include "llvm/Target/TargetMachine.h"
31 
32 namespace llvm {
33 
34 // This struct represents the cluster information for a machine basic block,
35 // which is specifed by a unique basic block ID.
36 struct BBClusterInfo {
37   // Basic block ID.
38   UniqueBBID BBID;
39   // Cluster ID this basic block belongs to.
40   unsigned ClusterID;
41   // Position of basic block within the cluster.
42   unsigned PositionInCluster;
43 };
44 
45 // This represents the raw input profile for one function.
46 struct FunctionPathAndClusterInfo {
47   // BB Cluster information specified by `UniqueBBID`s.
48   SmallVector<BBClusterInfo> ClusterInfo;
49   // Paths to clone. A path a -> b -> c -> d implies cloning b, c, and d along
50   // the edge a -> b (a is not cloned). The index of the path in this vector
51   // determines the `UniqueBBID::CloneID` of the cloned blocks in that path.
52   SmallVector<SmallVector<unsigned>> ClonePaths;
53 };
54 
55 class BasicBlockSectionsProfileReader {
56 public:
57   friend class BasicBlockSectionsProfileReaderWrapperPass;
58   BasicBlockSectionsProfileReader(const MemoryBuffer *Buf)
59       : MBuf(Buf), LineIt(*Buf, /*SkipBlanks=*/true, /*CommentMarker=*/'#'){};
60 
61   BasicBlockSectionsProfileReader(){};
62 
63   // Returns true if basic block sections profile exist for function \p
64   // FuncName.
65   bool isFunctionHot(StringRef FuncName) const;
66 
67   // Returns a pair with first element representing whether basic block sections
68   // profile exist for the function \p FuncName, and the second element
69   // representing the basic block sections profile (cluster info) for this
70   // function. If the first element is true and the second element is empty, it
71   // means unique basic block sections are desired for all basic blocks of the
72   // function.
73   std::pair<bool, SmallVector<BBClusterInfo>>
74   getClusterInfoForFunction(StringRef FuncName) const;
75 
76   // Returns the path clonings for the given function.
77   SmallVector<SmallVector<unsigned>>
78   getClonePathsForFunction(StringRef FuncName) const;
79 
80 private:
81   StringRef getAliasName(StringRef FuncName) const {
82     auto R = FuncAliasMap.find(FuncName);
83     return R == FuncAliasMap.end() ? FuncName : R->second;
84   }
85 
86   // Returns a profile parsing error for the current line.
87   Error createProfileParseError(Twine Message) const {
88     return make_error<StringError>(
89         Twine("invalid profile " + MBuf->getBufferIdentifier() + " at line " +
90               Twine(LineIt.line_number()) + ": " + Message),
91         inconvertibleErrorCode());
92   }
93 
94   // Parses a `UniqueBBID` from `S`. `S` must be in the form "<bbid>"
95   // (representing an original block) or "<bbid>.<cloneid>" (representing a
96   // cloned block) where bbid is a non-negative integer and cloneid is a
97   // positive integer.
98   Expected<UniqueBBID> parseUniqueBBID(StringRef S) const;
99 
100   // Reads the basic block sections profile for functions in this module.
101   Error ReadProfile();
102 
103   // Reads version 0 profile.
104   // TODO: Remove this function once version 0 is deprecated.
105   Error ReadV0Profile();
106 
107   // Reads version 1 profile.
108   Error ReadV1Profile();
109 
110   // This contains the basic-block-sections profile.
111   const MemoryBuffer *MBuf = nullptr;
112 
113   // Iterator to the line being parsed.
114   line_iterator LineIt;
115 
116   // Map from every function name in the module to its debug info filename or
117   // empty string if no debug info is available.
118   StringMap<SmallString<128>> FunctionNameToDIFilename;
119 
120   // This contains the BB cluster information for the whole program.
121   //
122   // For every function name, it contains the cloning and cluster information
123   // for (all or some of) its basic blocks. The cluster information for every
124   // basic block includes its cluster ID along with the position of the basic
125   // block in that cluster.
126   StringMap<FunctionPathAndClusterInfo> ProgramPathAndClusterInfo;
127 
128   // Some functions have alias names. We use this map to find the main alias
129   // name which appears in ProgramPathAndClusterInfo as a key.
130   StringMap<StringRef> FuncAliasMap;
131 };
132 
133 // Creates a BasicBlockSectionsProfileReader pass to parse the basic block
134 // sections profile. \p Buf is a memory buffer that contains the list of
135 // functions and basic block ids to selectively enable basic block sections.
136 ImmutablePass *
137 createBasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf);
138 
139 /// Analysis pass providing the \c BasicBlockSectionsProfileReader.
140 ///
141 /// Note that this pass's result cannot be invalidated, it is immutable for the
142 /// life of the module.
143 class BasicBlockSectionsProfileReaderAnalysis
144     : public AnalysisInfoMixin<BasicBlockSectionsProfileReaderAnalysis> {
145 
146 public:
147   static AnalysisKey Key;
148   typedef BasicBlockSectionsProfileReader Result;
149   BasicBlockSectionsProfileReaderAnalysis(const TargetMachine *TM) : TM(TM) {}
150 
151   Result run(Function &F, FunctionAnalysisManager &AM);
152 
153 private:
154   const TargetMachine *TM;
155 };
156 
157 class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
158 public:
159   static char ID;
160   BasicBlockSectionsProfileReader BBSPR;
161 
162   BasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf)
163       : ImmutablePass(ID), BBSPR(BasicBlockSectionsProfileReader(Buf)) {
164     initializeBasicBlockSectionsProfileReaderWrapperPassPass(
165         *PassRegistry::getPassRegistry());
166   };
167 
168   BasicBlockSectionsProfileReaderWrapperPass()
169       : ImmutablePass(ID), BBSPR(BasicBlockSectionsProfileReader()) {
170     initializeBasicBlockSectionsProfileReaderWrapperPassPass(
171         *PassRegistry::getPassRegistry());
172   }
173 
174   StringRef getPassName() const override {
175     return "Basic Block Sections Profile Reader";
176   }
177 
178   bool isFunctionHot(StringRef FuncName) const;
179 
180   std::pair<bool, SmallVector<BBClusterInfo>>
181   getClusterInfoForFunction(StringRef FuncName) const;
182 
183   SmallVector<SmallVector<unsigned>>
184   getClonePathsForFunction(StringRef FuncName) const;
185 
186   // Initializes the FunctionNameToDIFilename map for the current module and
187   // then reads the profile for the matching functions.
188   bool doInitialization(Module &M) override;
189 
190   BasicBlockSectionsProfileReader &getBBSPR();
191 };
192 
193 } // namespace llvm
194 #endif // LLVM_CODEGEN_BASICBLOCKSECTIONSPROFILEREADER_H
195