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/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>
     26 using namespace llvm;
     27 
     28 static ManagedStatic<LLVMContext> GlobalContext;
     29 
     30 LLVMContext& llvm::getGlobalContext() {
     31   return *GlobalContext;
     32 }
     33 
     34 LLVMContext::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 }
    141 LLVMContext::~LLVMContext() { delete pImpl; }
    142 
    143 void LLVMContext::addModule(Module *M) {
    144   pImpl->OwnedModules.insert(M);
    145 }
    146 
    147 void LLVMContext::removeModule(Module *M) {
    148   pImpl->OwnedModules.erase(M);
    149 }
    150 
    151 //===----------------------------------------------------------------------===//
    152 // Recoverable Backend Errors
    153 //===----------------------------------------------------------------------===//
    154 
    155 void LLVMContext::
    156 setInlineAsmDiagnosticHandler(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.
    164 LLVMContext::InlineAsmDiagHandlerTy
    165 LLVMContext::getInlineAsmDiagnosticHandler() const {
    166   return pImpl->InlineAsmDiagHandler;
    167 }
    168 
    169 /// getInlineAsmDiagnosticContext - Return the diagnostic context set by
    170 /// setInlineAsmDiagnosticHandler.
    171 void *LLVMContext::getInlineAsmDiagnosticContext() const {
    172   return pImpl->InlineAsmDiagContext;
    173 }
    174 
    175 void LLVMContext::setDiagnosticHandler(DiagnosticHandlerTy DiagnosticHandler,
    176                                        void *DiagnosticContext,
    177                                        bool RespectFilters) {
    178   pImpl->DiagnosticHandler = DiagnosticHandler;
    179   pImpl->DiagnosticContext = DiagnosticContext;
    180   pImpl->RespectDiagnosticFilters = RespectFilters;
    181 }
    182 
    183 LLVMContext::DiagnosticHandlerTy LLVMContext::getDiagnosticHandler() const {
    184   return pImpl->DiagnosticHandler;
    185 }
    186 
    187 void *LLVMContext::getDiagnosticContext() const {
    188   return pImpl->DiagnosticContext;
    189 }
    190 
    191 void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
    192 {
    193   pImpl->YieldCallback = Callback;
    194   pImpl->YieldOpaqueHandle = OpaqueHandle;
    195 }
    196 
    197 void LLVMContext::yield() {
    198   if (pImpl->YieldCallback)
    199     pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
    200 }
    201 
    202 void LLVMContext::emitError(const Twine &ErrorStr) {
    203   diagnose(DiagnosticInfoInlineAsm(ErrorStr));
    204 }
    205 
    206 void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
    207   assert (I && "Invalid instruction");
    208   diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
    209 }
    210 
    211 static 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 
    240 static 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 
    254 void 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 
    274 void 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.
    283 unsigned 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.
    293 void 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 
    300 void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
    301   pImpl->getOperandBundleTags(Tags);
    302 }
    303 
    304 uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
    305   return pImpl->getOperandBundleTagID(Tag);
    306 }
    307