Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===- Transforms/Instrumentation.h - Instrumentation passes ----*- 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 | // This file defines constructor functions for instrumentation passes. |
||
10 | // |
||
11 | //===----------------------------------------------------------------------===// |
||
12 | |||
13 | #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_H |
||
14 | #define LLVM_TRANSFORMS_INSTRUMENTATION_H |
||
15 | |||
16 | #include "llvm/ADT/StringRef.h" |
||
17 | #include "llvm/IR/BasicBlock.h" |
||
18 | #include "llvm/IR/DebugInfoMetadata.h" |
||
19 | #include "llvm/IR/Function.h" |
||
20 | #include "llvm/IR/IRBuilder.h" |
||
21 | #include "llvm/IR/Instruction.h" |
||
22 | #include <cassert> |
||
23 | #include <cstdint> |
||
24 | #include <limits> |
||
25 | #include <string> |
||
26 | #include <vector> |
||
27 | |||
28 | namespace llvm { |
||
29 | |||
30 | class Triple; |
||
31 | class OptimizationRemarkEmitter; |
||
32 | class Comdat; |
||
33 | class CallBase; |
||
34 | |||
35 | /// Instrumentation passes often insert conditional checks into entry blocks. |
||
36 | /// Call this function before splitting the entry block to move instructions |
||
37 | /// that must remain in the entry block up before the split point. Static |
||
38 | /// allocas and llvm.localescape calls, for example, must remain in the entry |
||
39 | /// block. |
||
40 | BasicBlock::iterator PrepareToSplitEntryBlock(BasicBlock &BB, |
||
41 | BasicBlock::iterator IP); |
||
42 | |||
43 | // Create a constant for Str so that we can pass it to the run-time lib. |
||
44 | GlobalVariable *createPrivateGlobalForString(Module &M, StringRef Str, |
||
45 | bool AllowMerging, |
||
46 | const char *NamePrefix = ""); |
||
47 | |||
48 | // Returns F.getComdat() if it exists. |
||
49 | // Otherwise creates a new comdat, sets F's comdat, and returns it. |
||
50 | // Returns nullptr on failure. |
||
51 | Comdat *getOrCreateFunctionComdat(Function &F, Triple &T); |
||
52 | |||
53 | // Insert GCOV profiling instrumentation |
||
54 | struct GCOVOptions { |
||
55 | static GCOVOptions getDefault(); |
||
56 | |||
57 | // Specify whether to emit .gcno files. |
||
58 | bool EmitNotes; |
||
59 | |||
60 | // Specify whether to modify the program to emit .gcda files when run. |
||
61 | bool EmitData; |
||
62 | |||
63 | // A four-byte version string. The meaning of a version string is described in |
||
64 | // gcc's gcov-io.h |
||
65 | char Version[4]; |
||
66 | |||
67 | // Add the 'noredzone' attribute to added runtime library calls. |
||
68 | bool NoRedZone; |
||
69 | |||
70 | // Use atomic profile counter increments. |
||
71 | bool Atomic = false; |
||
72 | |||
73 | // Regexes separated by a semi-colon to filter the files to instrument. |
||
74 | std::string Filter; |
||
75 | |||
76 | // Regexes separated by a semi-colon to filter the files to not instrument. |
||
77 | std::string Exclude; |
||
78 | }; |
||
79 | |||
80 | // The pgo-specific indirect call promotion function declared below is used by |
||
81 | // the pgo-driven indirect call promotion and sample profile passes. It's a |
||
82 | // wrapper around llvm::promoteCall, et al. that additionally computes !prof |
||
83 | // metadata. We place it in a pgo namespace so it's not confused with the |
||
84 | // generic utilities. |
||
85 | namespace pgo { |
||
86 | |||
87 | // Helper function that transforms CB (either an indirect-call instruction, or |
||
88 | // an invoke instruction , to a conditional call to F. This is like: |
||
89 | // if (Inst.CalledValue == F) |
||
90 | // F(...); |
||
91 | // else |
||
92 | // Inst(...); |
||
93 | // end |
||
94 | // TotalCount is the profile count value that the instruction executes. |
||
95 | // Count is the profile count value that F is the target function. |
||
96 | // These two values are used to update the branch weight. |
||
97 | // If \p AttachProfToDirectCall is true, a prof metadata is attached to the |
||
98 | // new direct call to contain \p Count. |
||
99 | // Returns the promoted direct call instruction. |
||
100 | CallBase &promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count, |
||
101 | uint64_t TotalCount, bool AttachProfToDirectCall, |
||
102 | OptimizationRemarkEmitter *ORE); |
||
103 | } // namespace pgo |
||
104 | |||
105 | /// Options for the frontend instrumentation based profiling pass. |
||
106 | struct InstrProfOptions { |
||
107 | // Add the 'noredzone' attribute to added runtime library calls. |
||
108 | bool NoRedZone = false; |
||
109 | |||
110 | // Do counter register promotion |
||
111 | bool DoCounterPromotion = false; |
||
112 | |||
113 | // Use atomic profile counter increments. |
||
114 | bool Atomic = false; |
||
115 | |||
116 | // Use BFI to guide register promotion |
||
117 | bool UseBFIInPromotion = false; |
||
118 | |||
119 | // Name of the profile file to use as output |
||
120 | std::string InstrProfileOutput; |
||
121 | |||
122 | InstrProfOptions() = default; |
||
123 | }; |
||
124 | |||
125 | // Options for sanitizer coverage instrumentation. |
||
126 | struct SanitizerCoverageOptions { |
||
127 | enum Type { |
||
128 | SCK_None = 0, |
||
129 | SCK_Function, |
||
130 | SCK_BB, |
||
131 | SCK_Edge |
||
132 | } CoverageType = SCK_None; |
||
133 | bool IndirectCalls = false; |
||
134 | bool TraceBB = false; |
||
135 | bool TraceCmp = false; |
||
136 | bool TraceDiv = false; |
||
137 | bool TraceGep = false; |
||
138 | bool Use8bitCounters = false; |
||
139 | bool TracePC = false; |
||
140 | bool TracePCGuard = false; |
||
141 | bool Inline8bitCounters = false; |
||
142 | bool InlineBoolFlag = false; |
||
143 | bool PCTable = false; |
||
144 | bool NoPrune = false; |
||
145 | bool StackDepth = false; |
||
146 | bool TraceLoads = false; |
||
147 | bool TraceStores = false; |
||
148 | bool CollectControlFlow = false; |
||
149 | |||
150 | SanitizerCoverageOptions() = default; |
||
151 | }; |
||
152 | |||
153 | /// Calculate what to divide by to scale counts. |
||
154 | /// |
||
155 | /// Given the maximum count, calculate a divisor that will scale all the |
||
156 | /// weights to strictly less than std::numeric_limits<uint32_t>::max(). |
||
157 | static inline uint64_t calculateCountScale(uint64_t MaxCount) { |
||
158 | return MaxCount < std::numeric_limits<uint32_t>::max() |
||
159 | ? 1 |
||
160 | : MaxCount / std::numeric_limits<uint32_t>::max() + 1; |
||
161 | } |
||
162 | |||
163 | /// Scale an individual branch count. |
||
164 | /// |
||
165 | /// Scale a 64-bit weight down to 32-bits using \c Scale. |
||
166 | /// |
||
167 | static inline uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale) { |
||
168 | uint64_t Scaled = Count / Scale; |
||
169 | assert(Scaled <= std::numeric_limits<uint32_t>::max() && "overflow 32-bits"); |
||
170 | return Scaled; |
||
171 | } |
||
172 | |||
173 | // Use to ensure the inserted instrumentation has a DebugLocation; if none is |
||
174 | // attached to the source instruction, try to use a DILocation with offset 0 |
||
175 | // scoped to surrounding function (if it has a DebugLocation). |
||
176 | // |
||
177 | // Some non-call instructions may be missing debug info, but when inserting |
||
178 | // instrumentation calls, some builds (e.g. LTO) want calls to have debug info |
||
179 | // if the enclosing function does. |
||
180 | struct InstrumentationIRBuilder : IRBuilder<> { |
||
181 | static void ensureDebugInfo(IRBuilder<> &IRB, const Function &F) { |
||
182 | if (IRB.getCurrentDebugLocation()) |
||
183 | return; |
||
184 | if (DISubprogram *SP = F.getSubprogram()) |
||
185 | IRB.SetCurrentDebugLocation(DILocation::get(SP->getContext(), 0, 0, SP)); |
||
186 | } |
||
187 | |||
188 | explicit InstrumentationIRBuilder(Instruction *IP) : IRBuilder<>(IP) { |
||
189 | ensureDebugInfo(*this, *IP->getFunction()); |
||
190 | } |
||
191 | }; |
||
192 | } // end namespace llvm |
||
193 | |||
194 | #endif // LLVM_TRANSFORMS_INSTRUMENTATION_H |