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/IR/Constants.h"
18#include "llvm/IR/DebugLoc.h"
19#include "llvm/IR/DiagnosticInfo.h"
20#include "llvm/IR/DiagnosticPrinter.h"
21#include "llvm/IR/Instruction.h"
22#include "llvm/IR/Metadata.h"
23#include "llvm/Support/ManagedStatic.h"
24#include "llvm/Support/SourceMgr.h"
25#include <cctype>
26using namespace llvm;
27
28static ManagedStatic<LLVMContext> GlobalContext;
29
30LLVMContext& llvm::getGlobalContext() {
31  return *GlobalContext;
32}
33
34LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
35  // Create the fixed metadata kinds. This is done in the same order as the
36  // MD_* enum values so that they correspond.
37
38  // Create the 'dbg' metadata kind.
39  unsigned DbgID = getMDKindID("dbg");
40  assert(DbgID == MD_dbg && "dbg kind id drifted"); (void)DbgID;
41
42  // Create the 'tbaa' metadata kind.
43  unsigned TBAAID = getMDKindID("tbaa");
44  assert(TBAAID == MD_tbaa && "tbaa kind id drifted"); (void)TBAAID;
45
46  // Create the 'prof' metadata kind.
47  unsigned ProfID = getMDKindID("prof");
48  assert(ProfID == MD_prof && "prof kind id drifted"); (void)ProfID;
49
50  // Create the 'fpmath' metadata kind.
51  unsigned FPAccuracyID = getMDKindID("fpmath");
52  assert(FPAccuracyID == MD_fpmath && "fpmath kind id drifted");
53  (void)FPAccuracyID;
54
55  // Create the 'range' metadata kind.
56  unsigned RangeID = getMDKindID("range");
57  assert(RangeID == MD_range && "range kind id drifted");
58  (void)RangeID;
59
60  // Create the 'tbaa.struct' metadata kind.
61  unsigned TBAAStructID = getMDKindID("tbaa.struct");
62  assert(TBAAStructID == MD_tbaa_struct && "tbaa.struct kind id drifted");
63  (void)TBAAStructID;
64
65  // Create the 'invariant.load' metadata kind.
66  unsigned InvariantLdId = getMDKindID("invariant.load");
67  assert(InvariantLdId == MD_invariant_load && "invariant.load kind id drifted");
68  (void)InvariantLdId;
69
70  // Create the 'alias.scope' metadata kind.
71  unsigned AliasScopeID = getMDKindID("alias.scope");
72  assert(AliasScopeID == MD_alias_scope && "alias.scope kind id drifted");
73  (void)AliasScopeID;
74
75  // Create the 'noalias' metadata kind.
76  unsigned NoAliasID = getMDKindID("noalias");
77  assert(NoAliasID == MD_noalias && "noalias kind id drifted");
78  (void)NoAliasID;
79
80  // Create the 'nontemporal' metadata kind.
81  unsigned NonTemporalID = getMDKindID("nontemporal");
82  assert(NonTemporalID == MD_nontemporal && "nontemporal kind id drifted");
83  (void)NonTemporalID;
84
85  // Create the 'llvm.mem.parallel_loop_access' metadata kind.
86  unsigned MemParallelLoopAccessID = getMDKindID("llvm.mem.parallel_loop_access");
87  assert(MemParallelLoopAccessID == MD_mem_parallel_loop_access &&
88         "mem_parallel_loop_access kind id drifted");
89  (void)MemParallelLoopAccessID;
90
91  // Create the 'nonnull' metadata kind.
92  unsigned NonNullID = getMDKindID("nonnull");
93  assert(NonNullID == MD_nonnull && "nonnull kind id drifted");
94  (void)NonNullID;
95
96  // Create the 'dereferenceable' metadata kind.
97  unsigned DereferenceableID = getMDKindID("dereferenceable");
98  assert(DereferenceableID == MD_dereferenceable &&
99         "dereferenceable kind id drifted");
100  (void)DereferenceableID;
101
102  // Create the 'dereferenceable_or_null' metadata kind.
103  unsigned DereferenceableOrNullID = getMDKindID("dereferenceable_or_null");
104  assert(DereferenceableOrNullID == MD_dereferenceable_or_null &&
105         "dereferenceable_or_null kind id drifted");
106  (void)DereferenceableOrNullID;
107
108  // Create the 'make.implicit' metadata kind.
109  unsigned MakeImplicitID = getMDKindID("make.implicit");
110  assert(MakeImplicitID == MD_make_implicit &&
111         "make.implicit kind id drifted");
112  (void)MakeImplicitID;
113
114  // Create the 'unpredictable' metadata kind.
115  unsigned UnpredictableID = getMDKindID("unpredictable");
116  assert(UnpredictableID == MD_unpredictable &&
117         "unpredictable kind id drifted");
118  (void)UnpredictableID;
119
120  // Create the 'invariant.group' metadata kind.
121  unsigned InvariantGroupId = getMDKindID("invariant.group");
122  assert(InvariantGroupId == MD_invariant_group &&
123         "invariant.group kind id drifted");
124  (void)InvariantGroupId;
125
126  // Create the 'align' metadata kind.
127  unsigned AlignID = getMDKindID("align");
128  assert(AlignID == MD_align && "align kind id drifted");
129  (void)AlignID;
130
131  auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
132  assert(DeoptEntry->second == LLVMContext::OB_deopt &&
133         "deopt operand bundle id drifted!");
134  (void)DeoptEntry;
135
136  auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
137  assert(FuncletEntry->second == LLVMContext::OB_funclet &&
138         "funclet operand bundle id drifted!");
139  (void)FuncletEntry;
140}
141LLVMContext::~LLVMContext() { delete pImpl; }
142
143void LLVMContext::addModule(Module *M) {
144  pImpl->OwnedModules.insert(M);
145}
146
147void LLVMContext::removeModule(Module *M) {
148  pImpl->OwnedModules.erase(M);
149}
150
151//===----------------------------------------------------------------------===//
152// Recoverable Backend Errors
153//===----------------------------------------------------------------------===//
154
155void LLVMContext::
156setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
157                              void *DiagContext) {
158  pImpl->InlineAsmDiagHandler = DiagHandler;
159  pImpl->InlineAsmDiagContext = DiagContext;
160}
161
162/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
163/// setInlineAsmDiagnosticHandler.
164LLVMContext::InlineAsmDiagHandlerTy
165LLVMContext::getInlineAsmDiagnosticHandler() const {
166  return pImpl->InlineAsmDiagHandler;
167}
168
169/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
170/// setInlineAsmDiagnosticHandler.
171void *LLVMContext::getInlineAsmDiagnosticContext() const {
172  return pImpl->InlineAsmDiagContext;
173}
174
175void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
176                                       void *DiagnosticContext,
177                                       bool RespectFilters) {
178  pImpl->DiagnosticHandler = DiagnosticHandler;
179  pImpl->DiagnosticContext = DiagnosticContext;
180  pImpl->RespectDiagnosticFilters = RespectFilters;
181}
182
183LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
184  return pImpl->DiagnosticHandler;
185}
186
187void *LLVMContext::getDiagnosticContext() const {
188  return pImpl->DiagnosticContext;
189}
190
191void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
192{
193  pImpl->YieldCallback = Callback;
194  pImpl->YieldOpaqueHandle = OpaqueHandle;
195}
196
197void LLVMContext::yield() {
198  if (pImpl->YieldCallback)
199    pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
200}
201
202void LLVMContext::emitError(const Twine &ErrorStr) {
203  diagnose(DiagnosticInfoInlineAsm(ErrorStr));
204}
205
206void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
207  assert (I && "Invalid instruction");
208  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
209}
210
211static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
212  // Optimization remarks are selective. They need to check whether the regexp
213  // pattern, passed via one of the -pass-remarks* flags, matches the name of
214  // the pass that is emitting the diagnostic. If there is no match, ignore the
215  // diagnostic and return.
216  switch (DI.getKind()) {
217  case llvm::DK_OptimizationRemark:
218    if (!cast<DiagnosticInfoOptimizationRemark>(DI).isEnabled())
219      return false;
220    break;
221  case llvm::DK_OptimizationRemarkMissed:
222    if (!cast<DiagnosticInfoOptimizationRemarkMissed>(DI).isEnabled())
223      return false;
224    break;
225  case llvm::DK_OptimizationRemarkAnalysis:
226    if (!cast<DiagnosticInfoOptimizationRemarkAnalysis>(DI).isEnabled())
227      return false;
228    break;
229  case llvm::DK_OptimizationRemarkAnalysisFPCommute:
230    if (!cast<DiagnosticInfoOptimizationRemarkAnalysisFPCommute>(DI)
231             .isEnabled())
232      return false;
233    break;
234  default:
235    break;
236  }
237  return true;
238}
239
240static const char *getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
241  switch (Severity) {
242  case DS_Error:
243    return "error";
244  case DS_Warning:
245    return "warning";
246  case DS_Remark:
247    return "remark";
248  case DS_Note:
249    return "note";
250  }
251  llvm_unreachable("Unknown DiagnosticSeverity");
252}
253
254void LLVMContext::diagnose(const DiagnosticInfo &DI) {
255  // If there is a report handler, use it.
256  if (pImpl->DiagnosticHandler) {
257    if (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI))
258      pImpl->DiagnosticHandler(DI, pImpl->DiagnosticContext);
259    return;
260  }
261
262  if (!isDiagnosticEnabled(DI))
263    return;
264
265  // Otherwise, print the message with a prefix based on the severity.
266  DiagnosticPrinterRawOStream DP(errs());
267  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
268  DI.print(DP);
269  errs() << "\n";
270  if (DI.getSeverity() == DS_Error)
271    exit(1);
272}
273
274void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
275  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
276}
277
278//===----------------------------------------------------------------------===//
279// Metadata Kind Uniquing
280//===----------------------------------------------------------------------===//
281
282/// Return a unique non-zero ID for the specified metadata kind.
283unsigned LLVMContext::getMDKindID(StringRef Name) const {
284  // If this is new, assign it its ID.
285  return pImpl->CustomMDKindNames.insert(
286                                     std::make_pair(
287                                         Name, pImpl->CustomMDKindNames.size()))
288      .first->second;
289}
290
291/// getHandlerNames - Populate client-supplied smallvector using custom
292/// metadata name and ID.
293void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
294  Names.resize(pImpl->CustomMDKindNames.size());
295  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
296       E = pImpl->CustomMDKindNames.end(); I != E; ++I)
297    Names[I->second] = I->first();
298}
299
300void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
301  pImpl->getOperandBundleTags(Tags);
302}
303
304uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
305  return pImpl->getOperandBundleTagID(Tag);
306}
307
308void LLVMContext::setGC(const Function &Fn, std::string GCName) {
309  auto It = pImpl->GCNames.find(&Fn);
310
311  if (It == pImpl->GCNames.end()) {
312    pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
313    return;
314  }
315  It->second = std::move(GCName);
316}
317const std::string &LLVMContext::getGC(const Function &Fn) {
318  return pImpl->GCNames[&Fn];
319}
320void LLVMContext::deleteGC(const Function &Fn) {
321  pImpl->GCNames.erase(&Fn);
322}
323