LLVM  6.0.0svn
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  };
65 
66  for (auto &MDKind : MDKinds) {
67  unsigned ID = getMDKindID(MDKind.second);
68  assert(ID == MDKind.first && "metadata kind id drifted");
69  (void)ID;
70  }
71 
72  auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
73  assert(DeoptEntry->second == LLVMContext::OB_deopt &&
74  "deopt operand bundle id drifted!");
75  (void)DeoptEntry;
76 
77  auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
78  assert(FuncletEntry->second == LLVMContext::OB_funclet &&
79  "funclet operand bundle id drifted!");
80  (void)FuncletEntry;
81 
82  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  pImpl->getOrInsertSyncScopeID("singlethread");
89  assert(SingleThreadSSID == SyncScope::SingleThread &&
90  "singlethread synchronization scope ID drifted!");
91  (void)SingleThreadSSID;
92 
93  SyncScope::ID SystemSSID =
95  assert(SystemSSID == SyncScope::System &&
96  "system synchronization scope ID drifted!");
97  (void)SystemSSID;
98 }
99 
101 
102 void LLVMContext::addModule(Module *M) {
104 }
105 
106 void LLVMContext::removeModule(Module *M) {
108 }
109 
110 //===----------------------------------------------------------------------===//
111 // Recoverable Backend Errors
112 //===----------------------------------------------------------------------===//
113 
114 void LLVMContext::
116  void *DiagContext) {
117  pImpl->InlineAsmDiagHandler = DiagHandler;
118  pImpl->InlineAsmDiagContext = DiagContext;
119 }
120 
121 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
122 /// setInlineAsmDiagnosticHandler.
125  return pImpl->InlineAsmDiagHandler;
126 }
127 
128 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
129 /// setInlineAsmDiagnosticHandler.
131  return pImpl->InlineAsmDiagContext;
132 }
133 
136  void *DiagnosticContext, bool RespectFilters) {
137  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
138  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
139  pImpl->RespectDiagnosticFilters = RespectFilters;
140 }
141 
142 void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
143  bool RespectFilters) {
144  pImpl->DiagHandler = std::move(DH);
145  pImpl->RespectDiagnosticFilters = RespectFilters;
146 }
147 
149  pImpl->DiagnosticsHotnessRequested = Requested;
150 }
153 }
154 
157 }
160 }
161 
163  return pImpl->DiagnosticsOutputFile.get();
164 }
165 
166 void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) {
167  pImpl->DiagnosticsOutputFile = std::move(F);
168 }
169 
172  return pImpl->DiagHandler->DiagHandlerCallback;
173 }
174 
176  return pImpl->DiagHandler->DiagnosticContext;
177 }
178 
179 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
180 {
181  pImpl->YieldCallback = Callback;
182  pImpl->YieldOpaqueHandle = OpaqueHandle;
183 }
184 
186  if (pImpl->YieldCallback)
188 }
189 
190 void LLVMContext::emitError(const Twine &ErrorStr) {
192 }
193 
194 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
195  assert (I && "Invalid instruction");
196  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
197 }
198 
199 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  return Remark->isEnabled() &&
209  (!Remark->isVerbose() || Remark->getHotness());
210 
211  return true;
212 }
213 
214 const char *
216  switch (Severity) {
217  case DS_Error:
218  return "error";
219  case DS_Warning:
220  return "warning";
221  case DS_Remark:
222  return "remark";
223  case DS_Note:
224  return "note";
225  }
226  llvm_unreachable("Unknown DiagnosticSeverity");
227 }
228 
230  if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) {
232  if (Out) {
233  // For remarks the << operator takes a reference to a pointer.
234  auto *P = const_cast<DiagnosticInfoOptimizationBase *>(OptDiagBase);
235  *Out << P;
236  }
237  }
238  // If there is a report handler, use it.
239  if (pImpl->DiagHandler &&
241  pImpl->DiagHandler->handleDiagnostics(DI))
242  return;
243 
244  if (!isDiagnosticEnabled(DI))
245  return;
246 
247  // Otherwise, print the message with a prefix based on the severity.
249  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
250  DI.print(DP);
251  errs() << "\n";
252  if (DI.getSeverity() == DS_Error)
253  exit(1);
254 }
255 
256 void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
257  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
258 }
259 
260 //===----------------------------------------------------------------------===//
261 // Metadata Kind Uniquing
262 //===----------------------------------------------------------------------===//
263 
264 /// Return a unique non-zero ID for the specified metadata kind.
266  // If this is new, assign it its ID.
268  std::make_pair(
269  Name, pImpl->CustomMDKindNames.size()))
270  .first->second;
271 }
272 
273 /// getHandlerNames - Populate client-supplied smallvector using custom
274 /// metadata name and ID.
278  E = pImpl->CustomMDKindNames.end(); I != E; ++I)
279  Names[I->second] = I->first();
280 }
281 
284 }
285 
287  return pImpl->getOperandBundleTagID(Tag);
288 }
289 
291  return pImpl->getOrInsertSyncScopeID(SSN);
292 }
293 
295  pImpl->getSyncScopeNames(SSNs);
296 }
297 
298 void LLVMContext::setGC(const Function &Fn, std::string GCName) {
299  auto It = pImpl->GCNames.find(&Fn);
300 
301  if (It == pImpl->GCNames.end()) {
302  pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
303  return;
304  }
305  It->second = std::move(GCName);
306 }
307 
308 const std::string &LLVMContext::getGC(const Function &Fn) {
309  return pImpl->GCNames[&Fn];
310 }
311 
313  pImpl->GCNames.erase(&Fn);
314 }
315 
317  return pImpl->DiscardValueNames;
318 }
319 
321 
323  if (pImpl->DITypeMap)
324  return;
325 
326  pImpl->DITypeMap.emplace();
327 }
328 
330 
332  pImpl->DiscardValueNames = Discard;
333 }
334 
336  return pImpl->getOptBisect();
337 }
338 
340  return pImpl->DiagHandler.get();
341 }
342 
343 std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
344  return std::move(pImpl->DiagHandler);
345 }
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
Compute iterated dominance frontiers using a linear time algorithm.
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:63
const std::string & getGC(const Function &Fn)
Return the GC for a function.
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:175
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...
DiagnosticSeverity
Defines the different supported severity of a diagnostic.
unsigned size() const
Definition: StringMap.h:112
OptBisect & getOptBisect()
Access the object which manages optimization bisection for failure analysis.
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...
void setDiagnosticsHotnessRequested(bool Requested)
Set if a code hotness metric should be included in optimization diagnostics.
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 ...
This class implements a mechanism to disable passes and individual optimizations at compile time base...
Definition: OptBisect.h:28
#define P(N)
StringMap< unsigned > CustomMDKindNames
CustomMDKindNames - Map to hold the metadata string to ID mapping.
This is the base abstract class for diagnostic reporting in the backend.
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
The Output class is used to generate a yaml document from in-memory structs and vectors.
Definition: YAMLTraits.h:1260
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
Synchronized with respect to all concurrently executing threads.
Definition: LLVMContext.h:59
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:370
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:224
void(*)(const SMDiagnostic &, void *Context, unsigned LocCookie) InlineAsmDiagHandlerTy
Definition: LLVMContext.h:171
SyncScope::ID getOrInsertSyncScopeID(StringRef SSN)
getOrInsertSyncScopeID - Maps synchronization scope name to synchronization scope ID...
Basic diagnostic printer that uses an underlying raw_ostream.
Synchronized with respect to signal handlers executing in the same thread.
Definition: LLVMContext.h:56
iterator begin()
Definition: StringMap.h:319
OptBisect & getOptBisect()
Access the object which manages optimization bisection for failure analysis.
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.
static int const Threshold
TODO: Write a new FunctionPass AliasAnalysis so that it can keep a cache.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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:322
uint32_t getOperandBundleTagID(StringRef Tag) const
getOperandBundleTagID - Maps a bundle tag to an integer ID.
void resize(size_type N)
Definition: SmallVector.h:355