LLVM  8.0.1
LLVMContext.cpp
Go to the documentation of this file.
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"
23 #include "llvm/IR/Metadata.h"
24 #include "llvm/IR/Module.h"
25 #include "llvm/Support/Casting.h"
28 #include <cassert>
29 #include <cstdlib>
30 #include <string>
31 #include <utility>
32 
33 using namespace llvm;
34 
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  {MD_access_group, "llvm.access.group"},
65  };
66 
67  for (auto &MDKind : MDKinds) {
68  unsigned ID = getMDKindID(MDKind.second);
69  assert(ID == MDKind.first && "metadata kind id drifted");
70  (void)ID;
71  }
72 
73  auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
74  assert(DeoptEntry->second == LLVMContext::OB_deopt &&
75  "deopt operand bundle id drifted!");
76  (void)DeoptEntry;
77 
78  auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
79  assert(FuncletEntry->second == LLVMContext::OB_funclet &&
80  "funclet operand bundle id drifted!");
81  (void)FuncletEntry;
82 
83  auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
84  assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
85  "gc-transition operand bundle id drifted!");
86  (void)GCTransitionEntry;
87 
88  SyncScope::ID SingleThreadSSID =
89  pImpl->getOrInsertSyncScopeID("singlethread");
90  assert(SingleThreadSSID == SyncScope::SingleThread &&
91  "singlethread synchronization scope ID drifted!");
92  (void)SingleThreadSSID;
93 
94  SyncScope::ID SystemSSID =
96  assert(SystemSSID == SyncScope::System &&
97  "system synchronization scope ID drifted!");
98  (void)SystemSSID;
99 }
100 
102 
103 void LLVMContext::addModule(Module *M) {
105 }
106 
107 void LLVMContext::removeModule(Module *M) {
109 }
110 
111 //===----------------------------------------------------------------------===//
112 // Recoverable Backend Errors
113 //===----------------------------------------------------------------------===//
114 
115 void LLVMContext::
117  void *DiagContext) {
118  pImpl->InlineAsmDiagHandler = DiagHandler;
119  pImpl->InlineAsmDiagContext = DiagContext;
120 }
121 
122 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
123 /// setInlineAsmDiagnosticHandler.
126  return pImpl->InlineAsmDiagHandler;
127 }
128 
129 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
130 /// setInlineAsmDiagnosticHandler.
132  return pImpl->InlineAsmDiagContext;
133 }
134 
137  void *DiagnosticContext, bool RespectFilters) {
138  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
139  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
140  pImpl->RespectDiagnosticFilters = RespectFilters;
141 }
142 
143 void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
144  bool RespectFilters) {
145  pImpl->DiagHandler = std::move(DH);
146  pImpl->RespectDiagnosticFilters = RespectFilters;
147 }
148 
150  pImpl->DiagnosticsHotnessRequested = Requested;
151 }
154 }
155 
158 }
161 }
162 
164  return pImpl->DiagnosticsOutputFile.get();
165 }
166 
167 void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) {
168  pImpl->DiagnosticsOutputFile = std::move(F);
169 }
170 
173  return pImpl->DiagHandler->DiagHandlerCallback;
174 }
175 
177  return pImpl->DiagHandler->DiagnosticContext;
178 }
179 
180 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
181 {
182  pImpl->YieldCallback = Callback;
183  pImpl->YieldOpaqueHandle = OpaqueHandle;
184 }
185 
187  if (pImpl->YieldCallback)
189 }
190 
191 void LLVMContext::emitError(const Twine &ErrorStr) {
193 }
194 
195 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
196  assert (I && "Invalid instruction");
197  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
198 }
199 
200 static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
201  // Optimization remarks are selective. They need to check whether the regexp
202  // pattern, passed via one of the -pass-remarks* flags, matches the name of
203  // the pass that is emitting the diagnostic. If there is no match, ignore the
204  // diagnostic and return.
205  //
206  // Also noisy remarks are only enabled if we have hotness information to sort
207  // them.
208  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
209  return Remark->isEnabled() &&
210  (!Remark->isVerbose() || Remark->getHotness());
211 
212  return true;
213 }
214 
215 const char *
217  switch (Severity) {
218  case DS_Error:
219  return "error";
220  case DS_Warning:
221  return "warning";
222  case DS_Remark:
223  return "remark";
224  case DS_Note:
225  return "note";
226  }
227  llvm_unreachable("Unknown DiagnosticSeverity");
228 }
229 
231  if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) {
232  yaml::Output *Out = getDiagnosticsOutputFile();
233  if (Out) {
234  // For remarks the << operator takes a reference to a pointer.
235  auto *P = const_cast<DiagnosticInfoOptimizationBase *>(OptDiagBase);
236  *Out << P;
237  }
238  }
239  // If there is a report handler, use it.
240  if (pImpl->DiagHandler &&
242  pImpl->DiagHandler->handleDiagnostics(DI))
243  return;
244 
245  if (!isDiagnosticEnabled(DI))
246  return;
247 
248  // Otherwise, print the message with a prefix based on the severity.
250  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
251  DI.print(DP);
252  errs() << "\n";
253  if (DI.getSeverity() == DS_Error)
254  exit(1);
255 }
256 
257 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
258  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
259 }
260 
261 //===----------------------------------------------------------------------===//
262 // Metadata Kind Uniquing
263 //===----------------------------------------------------------------------===//
264 
265 /// Return a unique non-zero ID for the specified metadata kind.
267  // If this is new, assign it its ID.
269  std::make_pair(
270  Name, pImpl->CustomMDKindNames.size()))
271  .first->second;
272 }
273 
274 /// getHandlerNames - Populate client-supplied smallvector using custom
275 /// metadata name and ID.
279  E = pImpl->CustomMDKindNames.end(); I != E; ++I)
280  Names[I->second] = I->first();
281 }
282 
285 }
286 
288  return pImpl->getOperandBundleTagID(Tag);
289 }
290 
292  return pImpl->getOrInsertSyncScopeID(SSN);
293 }
294 
296  pImpl->getSyncScopeNames(SSNs);
297 }
298 
299 void LLVMContext::setGC(const Function &Fn, std::string GCName) {
300  auto It = pImpl->GCNames.find(&Fn);
301 
302  if (It == pImpl->GCNames.end()) {
303  pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
304  return;
305  }
306  It->second = std::move(GCName);
307 }
308 
309 const std::string &LLVMContext::getGC(const Function &Fn) {
310  return pImpl->GCNames[&Fn];
311 }
312 
314  pImpl->GCNames.erase(&Fn);
315 }
316 
318  return pImpl->DiscardValueNames;
319 }
320 
322 
324  if (pImpl->DITypeMap)
325  return;
326 
327  pImpl->DITypeMap.emplace();
328 }
329 
331 
333  pImpl->DiscardValueNames = Discard;
334 }
335 
337  return pImpl->getOptPassGate();
338 }
339 
341  pImpl->setOptPassGate(OPG);
342 }
343 
345  return pImpl->DiagHandler.get();
346 }
347 
348 std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
349  return std::move(pImpl->DiagHandler);
350 }
void setDiagnosticHandler(std::unique_ptr< DiagnosticHandler > &&DH, bool RespectFilters=false)
setDiagnosticHandler - This method sets unique_ptr to object of DiagnosticHandler to provide custom d...
This is the base class for diagnostic handling in LLVM.
raw_ostream & errs()
This returns a reference to a raw_ostream for standard error.
void getOperandBundleTags(SmallVectorImpl< StringRef > &Tags) const
This class represents lattice values for constants.
Definition: AllocatorList.h:24
void setDiagnosticsOutputFile(std::unique_ptr< yaml::Output > F)
Set the diagnostics output file used for optimization diagnostics.
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
const std::string & getGC(const Function &Fn)
Return the GC for a function.
Extensions to this class implement mechanisms to disable passes and individual optimizations at compi...
Definition: OptBisect.h:32
std::unique_ptr< DiagnosticHandler > getDiagnosticHandler()
getDiagnosticHandler - transfers owenership of DiagnosticHandler unique_ptr to caller.
void(*)(LLVMContext *Context, void *OpaqueHandle) YieldCallbackTy
Defines the type of a yield callback.
Definition: LLVMContext.h:176
uint32_t getOperandBundleTagID(StringRef Tag) const
void setGC(const Function &Fn, std::string GCName)
Define the GC for a function.
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID...
This file contains the declarations for metadata subclasses.
void enableDebugTypeODRUniquing()
void * getInlineAsmDiagnosticContext() const
getInlineAsmDiagnosticContext - Return the diagnostic context set by setInlineAsmDiagnosticHandler.
void setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler, void *DiagContext=nullptr)
setInlineAsmDiagnosticHandler - This method sets a handler that is invoked when problems with inline ...
void setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
Registers a yield callback with the given context.
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
F(f)
void yield()
Calls the yield callback (if applicable).
LLVMContext::InlineAsmDiagHandlerTy InlineAsmDiagHandler
void setDiscardValueNames(bool Discard)
Set the Context runtime configuration to discard all value name (but GlobalValue).
void disableDebugTypeODRUniquing()
unsigned getMDKindID(StringRef Name) const
getMDKindID - Return a unique non-zero ID for the specified metadata kind.
void setDiagnosticsHotnessThreshold(uint64_t Threshold)
Set the minimum hotness value a diagnostic needs in order to be included in optimization diagnostics...
amdgpu Simplify well known AMD library false Value Value const Twine & Name
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
unsigned size() const
Definition: StringMap.h:112
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
void getMDKindNames(SmallVectorImpl< StringRef > &Result) const
getMDKindNames - Populate client supplied SmallVector with the name for custom metadata IDs registere...
void deleteGC(const Function &Fn)
Remove the GC for a function.
std::unique_ptr< DiagnosticHandler > DiagHandler
bool DiscardValueNames
Flag to indicate if Value (other than GlobalValue) retains their name or not.
void emitError(unsigned LocCookie, const Twine &ErrorStr)
emitError - Emit an error message to the currently installed error handler with optional location inf...
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time...
void setDiagnosticsHotnessRequested(bool Requested)
Set if a code hotness metric should be included in optimization diagnostics.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time...
void(*)(const DiagnosticInfo &DI, void *Context) DiagnosticHandlerTy
yaml::Output * getDiagnosticsOutputFile()
Return the YAML file used by the backend to save optimization diagnostics.
LLVMContext::YieldCallbackTy YieldCallback
void setDiagnosticHandlerCallBack(DiagnosticHandler::DiagnosticHandlerTy DiagHandler, void *DiagContext=nullptr, bool RespectFilters=false)
setDiagnosticHandlerCallBack - This method sets a handler call back that is invoked when the backend ...
#define P(N)
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
void setOptPassGate(OptPassGate &)
Set the object which can disable optional passes and individual optimizations at compile time...
This is the base abstract class for diagnostic reporting in the backend.
OptPassGate & getOptPassGate() const
Access the object which can disable optional passes and individual optimizations at compile time...
StringMapEntry< uint32_t > * getOrInsertBundleTag(StringRef Tag)
bool shouldDiscardValueNames() const
Return true if the Context runtime configuration is set to discard all value names.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void getOperandBundleTags(SmallVectorImpl< StringRef > &Result) const
getOperandBundleTags - Populate client supplied SmallVector with the bundle tags registered in this L...
void getSyncScopeNames(SmallVectorImpl< StringRef > &SSNs) const
getSyncScopeNames - Populates client supplied SmallVector with synchronization scope names registered...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:371
uint64_t getDiagnosticsHotnessThreshold() const
Return the minimum hotness value a diagnostic would need in order to be included in optimization diag...
bool getDiagnosticsHotnessRequested() const
Return if a code hotness metric should be included in optimization diagnostics.
bool isODRUniquingDebugTypes() const
Whether there is a string map for uniquing debug info identifiers across the context.
uint64_t DiagnosticsHotnessThreshold
Diagnostic information for inline asm reporting.
virtual void print(DiagnosticPrinter &DP) const =0
Print using the given DP a user-friendly message.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:71
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
Definition: SmallPtrSet.h:378
Common features for diagnostics dealing with optimization remarks that are used by both IR and MIR pa...
Module.h This file contains the declarations for the Module class.
static const char * getDiagnosticMessagePrefix(DiagnosticSeverity Severity)
Get the prefix that should be printed in front of a diagnostic of the given Severity.
bool insert(MapEntryTy *KeyValue)
insert - Insert the specified key/value pair into the map.
Definition: StringMap.h:366
SmallPtrSet< Module *, 4 > OwnedModules
OwnedModules - The set of modules instantiated in this context, and which will be automatically delet...
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:220
void(*)(const SMDiagnostic &, void *Context, unsigned LocCookie) InlineAsmDiagHandlerTy
Definition: LLVMContext.h:172
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID...
Basic diagnostic printer that uses an underlying raw_ostream.
iterator begin()
Definition: StringMap.h:315
std::unique_ptr< yaml::Output > DiagnosticsOutputFile
#define I(x, y, z)
Definition: MD5.cpp:58
DenseMap< const Function *, std::string > GCNames
Maintain the GC name for each function.
DiagnosticSeverity getSeverity() const
InlineAsmDiagHandlerTy getInlineAsmDiagnosticHandler() const
getInlineAsmDiagnosticHandler - Return the diagnostic handler set by setInlineAsmDiagnosticHandler.
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
const DiagnosticHandler * getDiagHandlerPtr() const
getDiagHandlerPtr - Returns const raw pointer of DiagnosticHandler set by setDiagnosticHandler.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:56
Synchronized with respect to all concurrently executing threads.
Definition: LLVMContext.h:59
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
void * getDiagnosticContext() const
getDiagnosticContext - Return the diagnostic context set by setDiagnosticContext. ...
static bool isDiagnosticEnabled(const DiagnosticInfo &DI)
DiagnosticHandler::DiagnosticHandlerTy getDiagnosticHandlerCallBack() const
getDiagnosticHandlerCallBack - Return the diagnostic handler call back set by setDiagnosticHandlerCal...
Optional< DenseMap< const MDString *, DICompositeType * > > DITypeMap
iterator end()
Definition: StringMap.h:318
uint32_t getOperandBundleTagID(StringRef Tag) const
getOperandBundleTagID - Maps a bundle tag to an integer ID.
void resize(size_type N)
Definition: SmallVector.h:351