//===-- LLVMContext.cpp - Implement LLVMContext ---------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
//  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/LLVMRemarkStreamer.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Remarks/RemarkStreamer.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[] = {
#define LLVM_FIXED_MD_KIND(EnumID, Name, Value) {EnumID, Name},
#include "llvm/IR/FixedMetadataKinds.def"
#undef LLVM_FIXED_MD_KIND
  };

  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;

  auto *CFGuardTargetEntry = pImpl->getOrInsertBundleTag("cfguardtarget");
  assert(CFGuardTargetEntry->second == LLVMContext::OB_cfguardtarget &&
         "cfguardtarget operand bundle id drifted!");
  (void)CFGuardTargetEntry;

  auto *PreallocatedEntry = pImpl->getOrInsertBundleTag("preallocated");
  assert(PreallocatedEntry->second == LLVMContext::OB_preallocated &&
         "preallocated operand bundle id drifted!");
  (void)PreallocatedEntry;

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

  auto *ClangAttachedCall =
      pImpl->getOrInsertBundleTag("clang.arc.attachedcall");
  assert(ClangAttachedCall->second == LLVMContext::OB_clang_arc_attachedcall &&
         "clang.arc.attachedcall operand bundle id drifted!");
  (void)ClangAttachedCall;

  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::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(Optional<uint64_t> Threshold) {
  pImpl->DiagnosticsHotnessThreshold = Threshold;
}

uint64_t LLVMContext::getDiagnosticsHotnessThreshold() const {
  return pImpl->DiagnosticsHotnessThreshold.getValueOr(UINT64_MAX);
}

bool LLVMContext::isDiagnosticsHotnessThresholdSetFromPSI() const {
  return !pImpl->DiagnosticsHotnessThreshold.hasValue();
}

remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() {
  return pImpl->MainRemarkStreamer.get();
}
const remarks::RemarkStreamer *LLVMContext::getMainRemarkStreamer() const {
  return const_cast<LLVMContext *>(this)->getMainRemarkStreamer();
}
void LLVMContext::setMainRemarkStreamer(
    std::unique_ptr<remarks::RemarkStreamer> RemarkStreamer) {
  pImpl->MainRemarkStreamer = std::move(RemarkStreamer);
}

LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() {
  return pImpl->LLVMRS.get();
}
const LLVMRemarkStreamer *LLVMContext::getLLVMRemarkStreamer() const {
  return const_cast<LLVMContext *>(this)->getLLVMRemarkStreamer();
}
void LLVMContext::setLLVMRemarkStreamer(
    std::unique_ptr<LLVMRemarkStreamer> RemarkStreamer) {
  pImpl->LLVMRS = std::move(RemarkStreamer);
}

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))
    if (LLVMRemarkStreamer *RS = getLLVMRemarkStreamer())
      RS->emit(*OptDiagBase);

  // 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);
}

StringMapEntry<uint32_t> *
LLVMContext::getOrInsertBundleTag(StringRef TagName) const {
  return pImpl->getOrInsertBundleTag(TagName);
}

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);
}
