Home | History | Annotate | Download | only in IR
      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 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   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 =
     94       pImpl->getOrInsertSyncScopeID("");
     95   assert(SystemSSID == SyncScope::System &&
     96          "system synchronization scope ID drifted!");
     97   (void)SystemSSID;
     98 }
     99 
    100 LLVMContext::~LLVMContext() { delete pImpl; }
    101 
    102 void LLVMContext::addModule(Module *M) {
    103   pImpl->OwnedModules.insert(M);
    104 }
    105 
    106 void LLVMContext::removeModule(Module *M) {
    107   pImpl->OwnedModules.erase(M);
    108 }
    109 
    110 //===----------------------------------------------------------------------===//
    111 // Recoverable Backend Errors
    112 //===----------------------------------------------------------------------===//
    113 
    114 void LLVMContext::
    115 setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
    116                               void *DiagContext) {
    117   pImpl->InlineAsmDiagHandler = DiagHandler;
    118   pImpl->InlineAsmDiagContext = DiagContext;
    119 }
    120 
    121 /// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
    122 /// setInlineAsmDiagnosticHandler.
    123 LLVMContext::InlineAsmDiagHandlerTy
    124 LLVMContext::getInlineAsmDiagnosticHandler() const {
    125   return pImpl->InlineAsmDiagHandler;
    126 }
    127 
    128 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
    129 /// setInlineAsmDiagnosticHandler.
    130 void *LLVMContext::getInlineAsmDiagnosticContext() const {
    131   return pImpl->InlineAsmDiagContext;
    132 }
    133 
    134 void LLVMContext::setDiagnosticHandlerCallBack(
    135     DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
    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 
    148 void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
    149   pImpl->DiagnosticsHotnessRequested = Requested;
    150 }
    151 bool LLVMContext::getDiagnosticsHotnessRequested() const {
    152   return pImpl->DiagnosticsHotnessRequested;
    153 }
    154 
    155 void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
    156   pImpl->DiagnosticsHotnessThreshold = Threshold;
    157 }
    158 uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
    159   return pImpl->DiagnosticsHotnessThreshold;
    160 }
    161 
    162 yaml::Output *LLVMContext::getDiagnosticsOutputFile() {
    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 
    170 DiagnosticHandler::DiagnosticHandlerTy
    171 LLVMContext::getDiagnosticHandlerCallBack() const {
    172   return pImpl->DiagHandler->DiagHandlerCallback;
    173 }
    174 
    175 void *LLVMContext::getDiagnosticContext() const {
    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 
    185 void LLVMContext::yield() {
    186   if (pImpl->YieldCallback)
    187     pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
    188 }
    189 
    190 void LLVMContext::emitError(const Twine &ErrorStr) {
    191   diagnose(DiagnosticInfoInlineAsm(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 *
    215 LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
    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 
    229 void LLVMContext::diagnose(const DiagnosticInfo &DI) {
    230   if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) {
    231     yaml::Output *Out = getDiagnosticsOutputFile();
    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 &&
    240       (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
    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.
    248   DiagnosticPrinterRawOStream DP(errs());
    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.
    265 unsigned LLVMContext::getMDKindID(StringRef Name) const {
    266   // If this is new, assign it its ID.
    267   return pImpl->CustomMDKindNames.insert(
    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.
    275 void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
    276   Names.resize(pImpl->CustomMDKindNames.size());
    277   for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
    278        E = pImpl->CustomMDKindNames.end(); I != E; ++I)
    279     Names[I->second] = I->first();
    280 }
    281 
    282 void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
    283   pImpl->getOperandBundleTags(Tags);
    284 }
    285 
    286 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
    287   return pImpl->getOperandBundleTagID(Tag);
    288 }
    289 
    290 SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
    291   return pImpl->getOrInsertSyncScopeID(SSN);
    292 }
    293 
    294 void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
    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 
    312 void LLVMContext::deleteGC(const Function &Fn) {
    313   pImpl->GCNames.erase(&Fn);
    314 }
    315 
    316 bool LLVMContext::shouldDiscardValueNames() const {
    317   return pImpl->DiscardValueNames;
    318 }
    319 
    320 bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }
    321 
    322 void LLVMContext::enableDebugTypeODRUniquing() {
    323   if (pImpl->DITypeMap)
    324     return;
    325 
    326   pImpl->DITypeMap.emplace();
    327 }
    328 
    329 void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }
    330 
    331 void LLVMContext::setDiscardValueNames(bool Discard) {
    332   pImpl->DiscardValueNames = Discard;
    333 }
    334 
    335 OptPassGate &LLVMContext::getOptPassGate() const {
    336   return pImpl->getOptPassGate();
    337 }
    338 
    339 void LLVMContext::setOptPassGate(OptPassGate& OPG) {
    340   pImpl->setOptPassGate(OPG);
    341 }
    342 
    343 const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
    344   return pImpl->DiagHandler.get();
    345 }
    346 
    347 std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
    348   return std::move(pImpl->DiagHandler);
    349 }
    350