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