xref: /llvm-project/llvm/include/llvm/CodeGen/BasicBlockSectionsProfileReader.h (revision 1753008bbbc317511c07ed30eef21e0494d63de8)
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/CodeGen/MachineBasicBlock.h"
23 #include "llvm/IR/Module.h"
24 #include "llvm/IR/PassManager.h"
25 #include "llvm/InitializePasses.h"
26 #include "llvm/Pass.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/LineIterator.h"
29 #include "llvm/Support/MemoryBuffer.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 ID (`MachineBasicBlock::BBID`).
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 // Provides DenseMapInfo for UniqueBBID.
56 template <> struct DenseMapInfo<UniqueBBID> {
57   static inline UniqueBBID getEmptyKey() {
58     unsigned EmptyKey = DenseMapInfo<unsigned>::getEmptyKey();
59     return UniqueBBID{EmptyKey, EmptyKey};
60   }
61   static inline UniqueBBID getTombstoneKey() {
62     unsigned TombstoneKey = DenseMapInfo<unsigned>::getTombstoneKey();
63     return UniqueBBID{TombstoneKey, TombstoneKey};
64   }
65   static unsigned getHashValue(const UniqueBBID &Val) {
66     std::pair<unsigned, unsigned> PairVal =
67         std::make_pair(Val.BaseID, Val.CloneID);
68     return DenseMapInfo<std::pair<unsigned, unsigned>>::getHashValue(PairVal);
69   }
70   static bool isEqual(const UniqueBBID &LHS, const UniqueBBID &RHS) {
71     return DenseMapInfo<unsigned>::isEqual(LHS.BaseID, RHS.BaseID) &&
72            DenseMapInfo<unsigned>::isEqual(LHS.CloneID, RHS.CloneID);
73   }
74 };
75 
76 class BasicBlockSectionsProfileReader {
77 public:
78   friend class BasicBlockSectionsProfileReaderWrapperPass;
79   BasicBlockSectionsProfileReader(const MemoryBuffer *Buf)
80       : MBuf(Buf), LineIt(*Buf, /*SkipBlanks=*/true, /*CommentMarker=*/'#'){};
81 
82   BasicBlockSectionsProfileReader(){};
83 
84   // Returns true if basic block sections profile exist for function \p
85   // FuncName.
86   bool isFunctionHot(StringRef FuncName) const;
87 
88   // Returns a pair with first element representing whether basic block sections
89   // profile exist for the function \p FuncName, and the second element
90   // representing the basic block sections profile (cluster info) for this
91   // function. If the first element is true and the second element is empty, it
92   // means unique basic block sections are desired for all basic blocks of the
93   // function.
94   std::pair<bool, SmallVector<BBClusterInfo>>
95   getClusterInfoForFunction(StringRef FuncName) const;
96 
97   // Returns the path clonings for the given function.
98   SmallVector<SmallVector<unsigned>>
99   getClonePathsForFunction(StringRef FuncName) const;
100 
101 private:
102   StringRef getAliasName(StringRef FuncName) const {
103     auto R = FuncAliasMap.find(FuncName);
104     return R == FuncAliasMap.end() ? FuncName : R->second;
105   }
106 
107   // Returns a profile parsing error for the current line.
108   Error createProfileParseError(Twine Message) const {
109     return make_error<StringError>(
110         Twine("invalid profile " + MBuf->getBufferIdentifier() + " at line " +
111               Twine(LineIt.line_number()) + ": " + Message),
112         inconvertibleErrorCode());
113   }
114 
115   // Parses a `UniqueBBID` from `S`. `S` must be in the form "<bbid>"
116   // (representing an original block) or "<bbid>.<cloneid>" (representing a
117   // cloned block) where bbid is a non-negative integer and cloneid is a
118   // positive integer.
119   Expected<UniqueBBID> parseUniqueBBID(StringRef S) const;
120 
121   // Reads the basic block sections profile for functions in this module.
122   Error ReadProfile();
123 
124   // Reads version 0 profile.
125   // TODO: Remove this function once version 0 is deprecated.
126   Error ReadV0Profile();
127 
128   // Reads version 1 profile.
129   Error ReadV1Profile();
130 
131   // This contains the basic-block-sections profile.
132   const MemoryBuffer *MBuf = nullptr;
133 
134   // Iterator to the line being parsed.
135   line_iterator LineIt;
136 
137   // Map from every function name in the module to its debug info filename or
138   // empty string if no debug info is available.
139   StringMap<SmallString<128>> FunctionNameToDIFilename;
140 
141   // This contains the BB cluster information for the whole program.
142   //
143   // For every function name, it contains the cloning and cluster information
144   // for (all or some of) its basic blocks. The cluster information for every
145   // basic block includes its cluster ID along with the position of the basic
146   // block in that cluster.
147   StringMap<FunctionPathAndClusterInfo> ProgramPathAndClusterInfo;
148 
149   // Some functions have alias names. We use this map to find the main alias
150   // name which appears in ProgramPathAndClusterInfo as a key.
151   StringMap<StringRef> FuncAliasMap;
152 };
153 
154 // Creates a BasicBlockSectionsProfileReader pass to parse the basic block
155 // sections profile. \p Buf is a memory buffer that contains the list of
156 // functions and basic block ids to selectively enable basic block sections.
157 ImmutablePass *
158 createBasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf);
159 
160 /// Analysis pass providing the \c BasicBlockSectionsProfileReader.
161 ///
162 /// Note that this pass's result cannot be invalidated, it is immutable for the
163 /// life of the module.
164 class BasicBlockSectionsProfileReaderAnalysis
165     : public AnalysisInfoMixin<BasicBlockSectionsProfileReaderAnalysis> {
166 
167 public:
168   static AnalysisKey Key;
169   typedef BasicBlockSectionsProfileReader Result;
170   BasicBlockSectionsProfileReaderAnalysis(const TargetMachine *TM) : TM(TM) {}
171 
172   Result run(Function &F, FunctionAnalysisManager &AM);
173 
174 private:
175   const TargetMachine *TM;
176 };
177 
178 class BasicBlockSectionsProfileReaderWrapperPass : public ImmutablePass {
179 public:
180   static char ID;
181   BasicBlockSectionsProfileReader BBSPR;
182 
183   BasicBlockSectionsProfileReaderWrapperPass(const MemoryBuffer *Buf)
184       : ImmutablePass(ID), BBSPR(BasicBlockSectionsProfileReader(Buf)) {
185     initializeBasicBlockSectionsProfileReaderWrapperPassPass(
186         *PassRegistry::getPassRegistry());
187   };
188 
189   BasicBlockSectionsProfileReaderWrapperPass()
190       : ImmutablePass(ID), BBSPR(BasicBlockSectionsProfileReader()) {
191     initializeBasicBlockSectionsProfileReaderWrapperPassPass(
192         *PassRegistry::getPassRegistry());
193   }
194 
195   StringRef getPassName() const override {
196     return "Basic Block Sections Profile Reader";
197   }
198 
199   bool isFunctionHot(StringRef FuncName) const;
200 
201   std::pair<bool, SmallVector<BBClusterInfo>>
202   getClusterInfoForFunction(StringRef FuncName) const;
203 
204   SmallVector<SmallVector<unsigned>>
205   getClonePathsForFunction(StringRef FuncName) const;
206 
207   // Initializes the FunctionNameToDIFilename map for the current module and
208   // then reads the profile for the matching functions.
209   bool doInitialization(Module &M) override;
210 
211   BasicBlockSectionsProfileReader &getBBSPR();
212 };
213 
214 } // namespace llvm
215 #endif // LLVM_CODEGEN_BASICBLOCKSECTIONSPROFILEREADER_H
216