/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/IR/LLVMContext.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===// |
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 implements LLVMContext, as a wrapper around the opaque |
10 | | // class LLVMContextImpl. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "llvm/IR/LLVMContext.h" |
15 | | #include "LLVMContextImpl.h" |
16 | | #include "llvm/ADT/SmallVector.h" |
17 | | #include "llvm/ADT/StringMap.h" |
18 | | #include "llvm/ADT/StringRef.h" |
19 | | #include "llvm/ADT/Twine.h" |
20 | | #include "llvm/IR/DiagnosticInfo.h" |
21 | | #include "llvm/IR/DiagnosticPrinter.h" |
22 | | #include "llvm/IR/Metadata.h" |
23 | | #include "llvm/IR/Module.h" |
24 | | #include "llvm/IR/RemarkStreamer.h" |
25 | | #include "llvm/Support/Casting.h" |
26 | | #include "llvm/Support/ErrorHandling.h" |
27 | | #include "llvm/Support/raw_ostream.h" |
28 | | #include <cassert> |
29 | | #include <cstdlib> |
30 | | #include <string> |
31 | | #include <utility> |
32 | | |
33 | | using namespace llvm; |
34 | | |
35 | 107k | LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) { |
36 | 107k | // Create the fixed metadata kinds. This is done in the same order as the |
37 | 107k | // MD_* enum values so that they correspond. |
38 | 107k | std::pair<unsigned, StringRef> MDKinds[] = { |
39 | 107k | {MD_dbg, "dbg"}, |
40 | 107k | {MD_tbaa, "tbaa"}, |
41 | 107k | {MD_prof, "prof"}, |
42 | 107k | {MD_fpmath, "fpmath"}, |
43 | 107k | {MD_range, "range"}, |
44 | 107k | {MD_tbaa_struct, "tbaa.struct"}, |
45 | 107k | {MD_invariant_load, "invariant.load"}, |
46 | 107k | {MD_alias_scope, "alias.scope"}, |
47 | 107k | {MD_noalias, "noalias"}, |
48 | 107k | {MD_nontemporal, "nontemporal"}, |
49 | 107k | {MD_mem_parallel_loop_access, "llvm.mem.parallel_loop_access"}, |
50 | 107k | {MD_nonnull, "nonnull"}, |
51 | 107k | {MD_dereferenceable, "dereferenceable"}, |
52 | 107k | {MD_dereferenceable_or_null, "dereferenceable_or_null"}, |
53 | 107k | {MD_make_implicit, "make.implicit"}, |
54 | 107k | {MD_unpredictable, "unpredictable"}, |
55 | 107k | {MD_invariant_group, "invariant.group"}, |
56 | 107k | {MD_align, "align"}, |
57 | 107k | {MD_loop, "llvm.loop"}, |
58 | 107k | {MD_type, "type"}, |
59 | 107k | {MD_section_prefix, "section_prefix"}, |
60 | 107k | {MD_absolute_symbol, "absolute_symbol"}, |
61 | 107k | {MD_associated, "associated"}, |
62 | 107k | {MD_callees, "callees"}, |
63 | 107k | {MD_irr_loop, "irr_loop"}, |
64 | 107k | {MD_access_group, "llvm.access.group"}, |
65 | 107k | {MD_callback, "callback"}, |
66 | 107k | {MD_preserve_access_index, "llvm.preserve.access.index"}, |
67 | 107k | }; |
68 | 107k | |
69 | 3.01M | for (auto &MDKind : MDKinds) { |
70 | 3.01M | unsigned ID = getMDKindID(MDKind.second); |
71 | 3.01M | assert(ID == MDKind.first && "metadata kind id drifted"); |
72 | 3.01M | (void)ID; |
73 | 3.01M | } |
74 | 107k | |
75 | 107k | auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt"); |
76 | 107k | assert(DeoptEntry->second == LLVMContext::OB_deopt && |
77 | 107k | "deopt operand bundle id drifted!"); |
78 | 107k | (void)DeoptEntry; |
79 | 107k | |
80 | 107k | auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet"); |
81 | 107k | assert(FuncletEntry->second == LLVMContext::OB_funclet && |
82 | 107k | "funclet operand bundle id drifted!"); |
83 | 107k | (void)FuncletEntry; |
84 | 107k | |
85 | 107k | auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition"); |
86 | 107k | assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition && |
87 | 107k | "gc-transition operand bundle id drifted!"); |
88 | 107k | (void)GCTransitionEntry; |
89 | 107k | |
90 | 107k | SyncScope::ID SingleThreadSSID = |
91 | 107k | pImpl->getOrInsertSyncScopeID("singlethread"); |
92 | 107k | assert(SingleThreadSSID == SyncScope::SingleThread && |
93 | 107k | "singlethread synchronization scope ID drifted!"); |
94 | 107k | (void)SingleThreadSSID; |
95 | 107k | |
96 | 107k | SyncScope::ID SystemSSID = |
97 | 107k | pImpl->getOrInsertSyncScopeID(""); |
98 | 107k | assert(SystemSSID == SyncScope::System && |
99 | 107k | "system synchronization scope ID drifted!"); |
100 | 107k | (void)SystemSSID; |
101 | 107k | } |
102 | | |
103 | 94.3k | LLVMContext::~LLVMContext() { delete pImpl; } |
104 | | |
105 | 68.7k | void LLVMContext::addModule(Module *M) { |
106 | 68.7k | pImpl->OwnedModules.insert(M); |
107 | 68.7k | } |
108 | | |
109 | 55.7k | void LLVMContext::removeModule(Module *M) { |
110 | 55.7k | pImpl->OwnedModules.erase(M); |
111 | 55.7k | } |
112 | | |
113 | | //===----------------------------------------------------------------------===// |
114 | | // Recoverable Backend Errors |
115 | | //===----------------------------------------------------------------------===// |
116 | | |
117 | | void LLVMContext:: |
118 | | setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, |
119 | 63.8k | void *DiagContext) { |
120 | 63.8k | pImpl->InlineAsmDiagHandler = DiagHandler; |
121 | 63.8k | pImpl->InlineAsmDiagContext = DiagContext; |
122 | 63.8k | } |
123 | | |
124 | | /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by |
125 | | /// setInlineAsmDiagnosticHandler. |
126 | | LLVMContext::InlineAsmDiagHandlerTy |
127 | 20.7k | LLVMContext::getInlineAsmDiagnosticHandler() const { |
128 | 20.7k | return pImpl->InlineAsmDiagHandler; |
129 | 20.7k | } |
130 | | |
131 | | /// getInlineAsmDiagnosticContext - Return the diagnostic context set by |
132 | | /// setInlineAsmDiagnosticHandler. |
133 | 19.0k | void *LLVMContext::getInlineAsmDiagnosticContext() const { |
134 | 19.0k | return pImpl->InlineAsmDiagContext; |
135 | 19.0k | } |
136 | | |
137 | | void LLVMContext::setDiagnosticHandlerCallBack( |
138 | | DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler, |
139 | 18 | void *DiagnosticContext, bool RespectFilters) { |
140 | 18 | pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler; |
141 | 18 | pImpl->DiagHandler->DiagnosticContext = DiagnosticContext; |
142 | 18 | pImpl->RespectDiagnosticFilters = RespectFilters; |
143 | 18 | } |
144 | | |
145 | | void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH, |
146 | 64.2k | bool RespectFilters) { |
147 | 64.2k | pImpl->DiagHandler = std::move(DH); |
148 | 64.2k | pImpl->RespectDiagnosticFilters = RespectFilters; |
149 | 64.2k | } |
150 | | |
151 | 60 | void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) { |
152 | 60 | pImpl->DiagnosticsHotnessRequested = Requested; |
153 | 60 | } |
154 | 13.9M | bool LLVMContext::getDiagnosticsHotnessRequested() const { |
155 | 13.9M | return pImpl->DiagnosticsHotnessRequested; |
156 | 13.9M | } |
157 | | |
158 | 18 | void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) { |
159 | 18 | pImpl->DiagnosticsHotnessThreshold = Threshold; |
160 | 18 | } |
161 | 697k | uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const { |
162 | 697k | return pImpl->DiagnosticsHotnessThreshold; |
163 | 697k | } |
164 | | |
165 | 10.9M | RemarkStreamer *LLVMContext::getRemarkStreamer() { |
166 | 10.9M | return pImpl->RemarkDiagStreamer.get(); |
167 | 10.9M | } |
168 | 0 | const RemarkStreamer *LLVMContext::getRemarkStreamer() const { |
169 | 0 | return const_cast<LLVMContext *>(this)->getRemarkStreamer(); |
170 | 0 | } |
171 | | void LLVMContext::setRemarkStreamer( |
172 | 91 | std::unique_ptr<RemarkStreamer> RemarkStreamer) { |
173 | 91 | pImpl->RemarkDiagStreamer = std::move(RemarkStreamer); |
174 | 91 | } |
175 | | |
176 | | DiagnosticHandler::DiagnosticHandlerTy |
177 | 2 | LLVMContext::getDiagnosticHandlerCallBack() const { |
178 | 2 | return pImpl->DiagHandler->DiagHandlerCallback; |
179 | 2 | } |
180 | | |
181 | 2 | void *LLVMContext::getDiagnosticContext() const { |
182 | 2 | return pImpl->DiagHandler->DiagnosticContext; |
183 | 2 | } |
184 | | |
185 | | void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle) |
186 | 1 | { |
187 | 1 | pImpl->YieldCallback = Callback; |
188 | 1 | pImpl->YieldOpaqueHandle = OpaqueHandle; |
189 | 1 | } |
190 | | |
191 | 5.00M | void LLVMContext::yield() { |
192 | 5.00M | if (pImpl->YieldCallback) |
193 | 2 | pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle); |
194 | 5.00M | } |
195 | | |
196 | 126 | void LLVMContext::emitError(const Twine &ErrorStr) { |
197 | 126 | diagnose(DiagnosticInfoInlineAsm(ErrorStr)); |
198 | 126 | } |
199 | | |
200 | 106 | void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) { |
201 | 106 | assert (I && "Invalid instruction"); |
202 | 106 | diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr)); |
203 | 106 | } |
204 | | |
205 | 342k | static bool isDiagnosticEnabled(const DiagnosticInfo &DI) { |
206 | 342k | // Optimization remarks are selective. They need to check whether the regexp |
207 | 342k | // pattern, passed via one of the -pass-remarks* flags, matches the name of |
208 | 342k | // the pass that is emitting the diagnostic. If there is no match, ignore the |
209 | 342k | // diagnostic and return. |
210 | 342k | // |
211 | 342k | // Also noisy remarks are only enabled if we have hotness information to sort |
212 | 342k | // them. |
213 | 342k | if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) |
214 | 328k | return Remark->isEnabled() && |
215 | 328k | (771 !Remark->isVerbose()771 || Remark->getHotness()8 ); |
216 | 13.4k | |
217 | 13.4k | return true; |
218 | 13.4k | } |
219 | | |
220 | | const char * |
221 | 15.6k | LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) { |
222 | 15.6k | switch (Severity) { |
223 | 15.6k | case DS_Error: |
224 | 647 | return "error"; |
225 | 15.6k | case DS_Warning: |
226 | 13.8k | return "warning"; |
227 | 15.6k | case DS_Remark: |
228 | 1.17k | return "remark"; |
229 | 15.6k | case DS_Note: |
230 | 2 | return "note"; |
231 | 0 | } |
232 | 0 | llvm_unreachable("Unknown DiagnosticSeverity"); |
233 | 0 | } |
234 | | |
235 | 714k | void LLVMContext::diagnose(const DiagnosticInfo &DI) { |
236 | 714k | if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) |
237 | 697k | if (RemarkStreamer *RS = getRemarkStreamer()) |
238 | 465 | RS->emit(*OptDiagBase); |
239 | 714k | |
240 | 714k | // If there is a report handler, use it. |
241 | 714k | if (pImpl->DiagHandler && |
242 | 714k | (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)776 ) && |
243 | 714k | pImpl->DiagHandler->handleDiagnostics(DI)714k ) |
244 | 373k | return; |
245 | 341k | |
246 | 341k | if (!isDiagnosticEnabled(DI)) |
247 | 327k | return; |
248 | 14.1k | |
249 | 14.1k | // Otherwise, print the message with a prefix based on the severity. |
250 | 14.1k | DiagnosticPrinterRawOStream DP(errs()); |
251 | 14.1k | errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; |
252 | 14.1k | DI.print(DP); |
253 | 14.1k | errs() << "\n"; |
254 | 14.1k | if (DI.getSeverity() == DS_Error) |
255 | 18 | exit(1); |
256 | 14.1k | } |
257 | | |
258 | 113 | void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) { |
259 | 113 | diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr)); |
260 | 113 | } |
261 | | |
262 | | //===----------------------------------------------------------------------===// |
263 | | // Metadata Kind Uniquing |
264 | | //===----------------------------------------------------------------------===// |
265 | | |
266 | | /// Return a unique non-zero ID for the specified metadata kind. |
267 | 5.03M | unsigned LLVMContext::getMDKindID(StringRef Name) const { |
268 | 5.03M | // If this is new, assign it its ID. |
269 | 5.03M | return pImpl->CustomMDKindNames.insert( |
270 | 5.03M | std::make_pair( |
271 | 5.03M | Name, pImpl->CustomMDKindNames.size())) |
272 | 5.03M | .first->second; |
273 | 5.03M | } |
274 | | |
275 | | /// getHandlerNames - Populate client-supplied smallvector using custom |
276 | | /// metadata name and ID. |
277 | 12.2k | void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const { |
278 | 12.2k | Names.resize(pImpl->CustomMDKindNames.size()); |
279 | 12.2k | for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(), |
280 | 357k | E = pImpl->CustomMDKindNames.end(); I != E; ++I345k ) |
281 | 345k | Names[I->second] = I->first(); |
282 | 12.2k | } |
283 | | |
284 | 4.97k | void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const { |
285 | 4.97k | pImpl->getOperandBundleTags(Tags); |
286 | 4.97k | } |
287 | | |
288 | 70 | uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const { |
289 | 70 | return pImpl->getOperandBundleTagID(Tag); |
290 | 70 | } |
291 | | |
292 | 29.3k | SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) { |
293 | 29.3k | return pImpl->getOrInsertSyncScopeID(SSN); |
294 | 29.3k | } |
295 | | |
296 | 5.11k | void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const { |
297 | 5.11k | pImpl->getSyncScopeNames(SSNs); |
298 | 5.11k | } |
299 | | |
300 | 549 | void LLVMContext::setGC(const Function &Fn, std::string GCName) { |
301 | 549 | auto It = pImpl->GCNames.find(&Fn); |
302 | 549 | |
303 | 549 | if (It == pImpl->GCNames.end()) { |
304 | 549 | pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName))); |
305 | 549 | return; |
306 | 549 | } |
307 | 0 | It->second = std::move(GCName); |
308 | 0 | } |
309 | | |
310 | 1.03k | const std::string &LLVMContext::getGC(const Function &Fn) { |
311 | 1.03k | return pImpl->GCNames[&Fn]; |
312 | 1.03k | } |
313 | | |
314 | 549 | void LLVMContext::deleteGC(const Function &Fn) { |
315 | 549 | pImpl->GCNames.erase(&Fn); |
316 | 549 | } |
317 | | |
318 | 84.2M | bool LLVMContext::shouldDiscardValueNames() const { |
319 | 84.2M | return pImpl->DiscardValueNames; |
320 | 84.2M | } |
321 | | |
322 | 111k | bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; } |
323 | | |
324 | 14.7k | void LLVMContext::enableDebugTypeODRUniquing() { |
325 | 14.7k | if (pImpl->DITypeMap) |
326 | 0 | return; |
327 | 14.7k | |
328 | 14.7k | pImpl->DITypeMap.emplace(); |
329 | 14.7k | } |
330 | | |
331 | 2 | void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); } |
332 | | |
333 | 57.0k | void LLVMContext::setDiscardValueNames(bool Discard) { |
334 | 57.0k | pImpl->DiscardValueNames = Discard; |
335 | 57.0k | } |
336 | | |
337 | 43.7M | OptPassGate &LLVMContext::getOptPassGate() const { |
338 | 43.7M | return pImpl->getOptPassGate(); |
339 | 43.7M | } |
340 | | |
341 | 2 | void LLVMContext::setOptPassGate(OptPassGate& OPG) { |
342 | 2 | pImpl->setOptPassGate(OPG); |
343 | 2 | } |
344 | | |
345 | 74.0M | const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const { |
346 | 74.0M | return pImpl->DiagHandler.get(); |
347 | 74.0M | } |
348 | | |
349 | 17.3k | std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() { |
350 | 17.3k | return std::move(pImpl->DiagHandler); |
351 | 17.3k | } |