llvm.org GIT mirror llvm / release_70 lib / IR / LLVMContext.cpp
release_70

Tree @release_70 (Download .tar.gz)

LLVMContext.cpp @release_70

dbf5081
2bc29dc
 
 
 
 
 
 
5217007
 
12ddd40
5217007
 
2bc29dc
0b8c9a8
e3e43d9
aaf3f04
 
 
 
de262fe
 
0b8c9a8
aaf3f04
 
 
 
 
 
 
 
 
2bc29dc
 
ec39f09
b2143b6
 
2af93f1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b29976c
df808fe
9f219e8
dd33e17
2af93f1
 
 
 
 
 
 
977fc82
b4b58ba
 
 
 
b46bb54
 
 
 
 
e6a9ed7
 
 
 
 
8f85685
 
 
 
 
4cdc883
8f85685
 
 
 
 
4cdc883
ec39f09
aaf3f04
2bc29dc
48b2f3e
30268be
 
 
 
 
 
 
 
38686bd
 
 
 
f64c889
 
 
 
 
42a4ee0
 
f64c889
 
 
 
 
42a4ee0
 
f64c889
 
 
 
42a4ee0
04e3b1e
18b4c37
 
 
 
 
 
 
 
 
 
 
04d2186
de262fe
 
8e8ec78
 
 
 
 
f8cec99
 
e330528
 
 
 
 
 
 
47c0d49
 
 
 
1bb4b12
 
47c0d49
 
18b4c37
 
 
de262fe
 
 
18b4c37
de262fe
 
9bc1b73
 
 
 
 
 
 
 
 
 
 
3a4c60c
341149a
38686bd
 
5844691
341149a
 
38686bd
 
04d2186
d16404a
 
 
 
138faec
 
 
5fe8a3c
138faec
 
5fe8a3c
04d2186
 
 
3b0d377
 
a15d888
 
 
 
 
 
 
 
 
 
db8ece3
a15d888
 
04d2186
c5599f6
 
 
 
 
 
 
 
04d2186
18b4c37
 
 
04d2186
 
 
 
b902acb
de262fe
a15d888
 
de262fe
a15d888
 
de262fe
 
 
3a4c60c
341149a
38686bd
 
 
 
 
 
581e255
04e3b1e
 
581e255
 
 
1d4f28c
48b2f3e
9d3627e
002f836
04e3b1e
 
19538d1
04e3b1e
 
 
 
5b674c0
 
 
 
 
 
 
 
3569d3c
8f85685
 
 
 
 
 
 
 
3569d3c
 
 
 
 
 
 
 
 
aaf3f04
3569d3c
 
 
aaf3f04
3569d3c
 
 
2de9927
b3cb9bc
 
 
2de9927
2663f35
9bb5d5d
2663f35
9bb5d5d
 
 
75cc051
9bb5d5d
 
2663f35
9bb5d5d
2de9927
 
 
1e455c5
46d5e2b
558f76f
1e455c5
18b4c37
46d5e2b
 
 
 
18b4c37
 
 
 
 
 
 
//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file implements LLVMContext, as a wrapper around the opaque
//  class LLVMContextImpl.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/LLVMContext.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdlib>
#include <string>
#include <utility>

using namespace llvm;

LLVMContext::LLVMContext() : pImpl(new LLVMContextImpl(*this)) {
  // Create the fixed metadata kinds. This is done in the same order as the
  // MD_* enum values so that they correspond.
  std::pair<unsigned, StringRef> MDKinds[] = {
    {MD_dbg, "dbg"},
    {MD_tbaa, "tbaa"},
    {MD_prof, "prof"},
    {MD_fpmath, "fpmath"},
    {MD_range, "range"},
    {MD_tbaa_struct, "tbaa.struct"},
    {MD_invariant_load, "invariant.load"},
    {MD_alias_scope, "alias.scope"},
    {MD_noalias, "noalias"},
    {MD_nontemporal, "nontemporal"},
    {MD_mem_parallel_loop_access, "llvm.mem.parallel_loop_access"},
    {MD_nonnull, "nonnull"},
    {MD_dereferenceable, "dereferenceable"},
    {MD_dereferenceable_or_null, "dereferenceable_or_null"},
    {MD_make_implicit, "make.implicit"},
    {MD_unpredictable, "unpredictable"},
    {MD_invariant_group, "invariant.group"},
    {MD_align, "align"},
    {MD_loop, "llvm.loop"},
    {MD_type, "type"},
    {MD_section_prefix, "section_prefix"},
    {MD_absolute_symbol, "absolute_symbol"},
    {MD_associated, "associated"},
    {MD_callees, "callees"},
    {MD_irr_loop, "irr_loop"},
  };

  for (auto &MDKind : MDKinds) {
    unsigned ID = getMDKindID(MDKind.second);
    assert(ID == MDKind.first && "metadata kind id drifted");
    (void)ID;
  }

  auto *DeoptEntry = pImpl->getOrInsertBundleTag("deopt");
  assert(DeoptEntry->second == LLVMContext::OB_deopt &&
         "deopt operand bundle id drifted!");
  (void)DeoptEntry;

  auto *FuncletEntry = pImpl->getOrInsertBundleTag("funclet");
  assert(FuncletEntry->second == LLVMContext::OB_funclet &&
         "funclet operand bundle id drifted!");
  (void)FuncletEntry;

  auto *GCTransitionEntry = pImpl->getOrInsertBundleTag("gc-transition");
  assert(GCTransitionEntry->second == LLVMContext::OB_gc_transition &&
         "gc-transition operand bundle id drifted!");
  (void)GCTransitionEntry;

  SyncScope::ID SingleThreadSSID =
      pImpl->getOrInsertSyncScopeID("singlethread");
  assert(SingleThreadSSID == SyncScope::SingleThread &&
         "singlethread synchronization scope ID drifted!");
  (void)SingleThreadSSID;

  SyncScope::ID SystemSSID =
      pImpl->getOrInsertSyncScopeID("");
  assert(SystemSSID == SyncScope::System &&
         "system synchronization scope ID drifted!");
  (void)SystemSSID;
}

LLVMContext::~LLVMContext() { delete pImpl; }

void LLVMContext::addModule(Module *M) {
  pImpl->OwnedModules.insert(M);
}

void LLVMContext::removeModule(Module *M) {
  pImpl->OwnedModules.erase(M);
}

//===----------------------------------------------------------------------===//
// Recoverable Backend Errors
//===----------------------------------------------------------------------===//

void LLVMContext::
setInlineAsmDiagnosticHandler(InlineAsmDiagHandlerTy DiagHandler,
                              void *DiagContext) {
  pImpl->InlineAsmDiagHandler = DiagHandler;
  pImpl->InlineAsmDiagContext = DiagContext;
}

/// getInlineAsmDiagnosticHandler - Return the diagnostic handler set by
/// setInlineAsmDiagnosticHandler.
LLVMContext::InlineAsmDiagHandlerTy
LLVMContext::getInlineAsmDiagnosticHandler() const {
  return pImpl->InlineAsmDiagHandler;
}

/// getInlineAsmDiagnosticContext - Return the diagnostic context set by
/// setInlineAsmDiagnosticHandler.
void *LLVMContext::getInlineAsmDiagnosticContext() const {
  return pImpl->InlineAsmDiagContext;
}

void LLVMContext::setDiagnosticHandlerCallBack(
    DiagnosticHandler::DiagnosticHandlerTy DiagnosticHandler,
    void *DiagnosticContext, bool RespectFilters) {
  pImpl->DiagHandler->DiagHandlerCallback = DiagnosticHandler;
  pImpl->DiagHandler->DiagnosticContext = DiagnosticContext;
  pImpl->RespectDiagnosticFilters = RespectFilters;
}

void LLVMContext::setDiagnosticHandler(std::unique_ptr<DiagnosticHandler> &&DH,
                                      bool RespectFilters) {
  pImpl->DiagHandler = std::move(DH);
  pImpl->RespectDiagnosticFilters = RespectFilters;
}

void LLVMContext::setDiagnosticsHotnessRequested(bool Requested) {
  pImpl->DiagnosticsHotnessRequested = Requested;
}
bool LLVMContext::getDiagnosticsHotnessRequested() const {
  return pImpl->DiagnosticsHotnessRequested;
}

void LLVMContext::setDiagnosticsHotnessThreshold(uint64_t Threshold) {
  pImpl->DiagnosticsHotnessThreshold = Threshold;
}
uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
  return pImpl->DiagnosticsHotnessThreshold;
}

yaml::Output *LLVMContext::getDiagnosticsOutputFile() {
  return pImpl->DiagnosticsOutputFile.get();
}

void LLVMContext::setDiagnosticsOutputFile(std::unique_ptr<yaml::Output> F) {
  pImpl->DiagnosticsOutputFile = std::move(F);
}

DiagnosticHandler::DiagnosticHandlerTy
LLVMContext::getDiagnosticHandlerCallBack() const {
  return pImpl->DiagHandler->DiagHandlerCallback;
}

void *LLVMContext::getDiagnosticContext() const {
  return pImpl->DiagHandler->DiagnosticContext;
}

void LLVMContext::setYieldCallback(YieldCallbackTy Callback, void *OpaqueHandle)
{
  pImpl->YieldCallback = Callback;
  pImpl->YieldOpaqueHandle = OpaqueHandle;
}

void LLVMContext::yield() {
  if (pImpl->YieldCallback)
    pImpl->YieldCallback(this, pImpl->YieldOpaqueHandle);
}

void LLVMContext::emitError(const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(ErrorStr));
}

void LLVMContext::emitError(const Instruction *I, const Twine &ErrorStr) {
  assert (I && "Invalid instruction");
  diagnose(DiagnosticInfoInlineAsm(*I, ErrorStr));
}

static bool isDiagnosticEnabled(const DiagnosticInfo &DI) {
  // Optimization remarks are selective. They need to check whether the regexp
  // pattern, passed via one of the -pass-remarks* flags, matches the name of
  // the pass that is emitting the diagnostic. If there is no match, ignore the
  // diagnostic and return.
  //
  // Also noisy remarks are only enabled if we have hotness information to sort
  // them.
  if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
    return Remark->isEnabled() &&
           (!Remark->isVerbose() || Remark->getHotness());

  return true;
}

const char *
LLVMContext::getDiagnosticMessagePrefix(DiagnosticSeverity Severity) {
  switch (Severity) {
  case DS_Error:
    return "error";
  case DS_Warning:
    return "warning";
  case DS_Remark:
    return "remark";
  case DS_Note:
    return "note";
  }
  llvm_unreachable("Unknown DiagnosticSeverity");
}

void LLVMContext::diagnose(const DiagnosticInfo &DI) {
  if (auto *OptDiagBase = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) {
    yaml::Output *Out = getDiagnosticsOutputFile();
    if (Out) {
      // For remarks the << operator takes a reference to a pointer.
      auto *P = const_cast<DiagnosticInfoOptimizationBase *>(OptDiagBase);
      *Out << P;
    }
  }
  // If there is a report handler, use it.
  if (pImpl->DiagHandler &&
      (!pImpl->RespectDiagnosticFilters || isDiagnosticEnabled(DI)) &&
      pImpl->DiagHandler->handleDiagnostics(DI))
    return;

  if (!isDiagnosticEnabled(DI))
    return;

  // Otherwise, print the message with a prefix based on the severity.
  DiagnosticPrinterRawOStream DP(errs());
  errs() << getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
  DI.print(DP);
  errs() << "\n";
  if (DI.getSeverity() == DS_Error)
    exit(1);
}

void LLVMContext::emitError(unsigned LocCookie, const Twine &ErrorStr) {
  diagnose(DiagnosticInfoInlineAsm(LocCookie, ErrorStr));
}

//===----------------------------------------------------------------------===//
// Metadata Kind Uniquing
//===----------------------------------------------------------------------===//

/// Return a unique non-zero ID for the specified metadata kind.
unsigned LLVMContext::getMDKindID(StringRef Name) const {
  // If this is new, assign it its ID.
  return pImpl->CustomMDKindNames.insert(
                                     std::make_pair(
                                         Name, pImpl->CustomMDKindNames.size()))
      .first->second;
}

/// getHandlerNames - Populate client-supplied smallvector using custom
/// metadata name and ID.
void LLVMContext::getMDKindNames(SmallVectorImpl<StringRef> &Names) const {
  Names.resize(pImpl->CustomMDKindNames.size());
  for (StringMap<unsigned>::const_iterator I = pImpl->CustomMDKindNames.begin(),
       E = pImpl->CustomMDKindNames.end(); I != E; ++I)
    Names[I->second] = I->first();
}

void LLVMContext::getOperandBundleTags(SmallVectorImpl<StringRef> &Tags) const {
  pImpl->getOperandBundleTags(Tags);
}

uint32_t LLVMContext::getOperandBundleTagID(StringRef Tag) const {
  return pImpl->getOperandBundleTagID(Tag);
}

SyncScope::ID LLVMContext::getOrInsertSyncScopeID(StringRef SSN) {
  return pImpl->getOrInsertSyncScopeID(SSN);
}

void LLVMContext::getSyncScopeNames(SmallVectorImpl<StringRef> &SSNs) const {
  pImpl->getSyncScopeNames(SSNs);
}

void LLVMContext::setGC(const Function &Fn, std::string GCName) {
  auto It = pImpl->GCNames.find(&Fn);

  if (It == pImpl->GCNames.end()) {
    pImpl->GCNames.insert(std::make_pair(&Fn, std::move(GCName)));
    return;
  }
  It->second = std::move(GCName);
}

const std::string &LLVMContext::getGC(const Function &Fn) {
  return pImpl->GCNames[&Fn];
}

void LLVMContext::deleteGC(const Function &Fn) {
  pImpl->GCNames.erase(&Fn);
}

bool LLVMContext::shouldDiscardValueNames() const {
  return pImpl->DiscardValueNames;
}

bool LLVMContext::isODRUniquingDebugTypes() const { return !!pImpl->DITypeMap; }

void LLVMContext::enableDebugTypeODRUniquing() {
  if (pImpl->DITypeMap)
    return;

  pImpl->DITypeMap.emplace();
}

void LLVMContext::disableDebugTypeODRUniquing() { pImpl->DITypeMap.reset(); }

void LLVMContext::setDiscardValueNames(bool Discard) {
  pImpl->DiscardValueNames = Discard;
}

OptPassGate &LLVMContext::getOptPassGate() const {
  return pImpl->getOptPassGate();
}

void LLVMContext::setOptPassGate(OptPassGate& OPG) {
  pImpl->setOptPassGate(OPG);
}

const DiagnosticHandler *LLVMContext::getDiagHandlerPtr() const {
  return pImpl->DiagHandler.get();
}

std::unique_ptr<DiagnosticHandler> LLVMContext::getDiagnosticHandler() {
  return std::move(pImpl->DiagHandler);
}