//===---------- speculation.cpp - Utilities for Speculation ----------===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "llvm/ExecutionEngine/Orc/Speculation.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Verifier.h"

namespace llvm {

namespace orc {

// ImplSymbolMap methods
void ImplSymbolMap::trackImpls(SymbolAliasMap ImplMaps, JITDylib *SrcJD) {
  assert(SrcJD && "Tracking on Null Source .impl dylib");
  std::lock_guard<std::mutex> Lockit(ConcurrentAccess);
  for (auto &I : ImplMaps) {
    auto It = Maps.insert({I.first, {I.second.Aliasee, SrcJD}});
    // check rationale when independent dylibs have same symbol name?
    assert(It.second && "ImplSymbols are already tracked for this Symbol?");
    (void)(It);
  }
}

// Trigger Speculative Compiles.
void Speculator::speculateForEntryPoint(Speculator *Ptr, uint64_t StubId) {
  assert(Ptr && " Null Address Received in orc_speculate_for ");
  Ptr->speculateFor(StubId);
}

Error Speculator::addSpeculationRuntime(JITDylib &JD,
                                        MangleAndInterner &Mangle) {
  JITEvaluatedSymbol ThisPtr(pointerToJITTargetAddress(this),
                             JITSymbolFlags::Exported);
  JITEvaluatedSymbol SpeculateForEntryPtr(
      pointerToJITTargetAddress(&speculateForEntryPoint),
      JITSymbolFlags::Exported);
  return JD.define(absoluteSymbols({
      {Mangle("__orc_speculator"), ThisPtr},                // Data Symbol
      {Mangle("__orc_speculate_for"), SpeculateForEntryPtr} // Callable Symbol
  }));
}

// If two modules, share the same LLVMContext, different threads must
// not access them concurrently without locking the associated LLVMContext
// this implementation follows this contract.
void IRSpeculationLayer::emit(std::unique_ptr<MaterializationResponsibility> R,
                              ThreadSafeModule TSM) {

  assert(TSM && "Speculation Layer received Null Module ?");
  assert(TSM.getContext().getContext() != nullptr &&
         "Module with null LLVMContext?");

  // Instrumentation of runtime calls, lock the Module
  TSM.withModuleDo([this, &R](Module &M) {
    auto &MContext = M.getContext();
    auto SpeculatorVTy = StructType::create(MContext, "Class.Speculator");
    auto RuntimeCallTy = FunctionType::get(
        Type::getVoidTy(MContext),
        {SpeculatorVTy->getPointerTo(), Type::getInt64Ty(MContext)}, false);
    auto RuntimeCall =
        Function::Create(RuntimeCallTy, Function::LinkageTypes::ExternalLinkage,
                         "__orc_speculate_for", &M);
    auto SpeclAddr = new GlobalVariable(
        M, SpeculatorVTy, false, GlobalValue::LinkageTypes::ExternalLinkage,
        nullptr, "__orc_speculator");

    IRBuilder<> Mutator(MContext);

    // QueryAnalysis allowed to transform the IR source, one such example is
    // Simplify CFG helps the static branch prediction heuristics!
    for (auto &Fn : M.getFunctionList()) {
      if (!Fn.isDeclaration()) {

        auto IRNames = QueryAnalysis(Fn);
        // Instrument and register if Query has result
        if (IRNames.hasValue()) {

          // Emit globals for each function.
          auto LoadValueTy = Type::getInt8Ty(MContext);
          auto SpeculatorGuard = new GlobalVariable(
              M, LoadValueTy, false, GlobalValue::LinkageTypes::InternalLinkage,
              ConstantInt::get(LoadValueTy, 0),
              "__orc_speculate.guard.for." + Fn.getName());
          SpeculatorGuard->setAlignment(Align(1));
          SpeculatorGuard->setUnnamedAddr(GlobalValue::UnnamedAddr::Local);

          BasicBlock &ProgramEntry = Fn.getEntryBlock();
          // Create BasicBlocks before the program's entry basicblock
          BasicBlock *SpeculateBlock = BasicBlock::Create(
              MContext, "__orc_speculate.block", &Fn, &ProgramEntry);
          BasicBlock *SpeculateDecisionBlock = BasicBlock::Create(
              MContext, "__orc_speculate.decision.block", &Fn, SpeculateBlock);

          assert(SpeculateDecisionBlock == &Fn.getEntryBlock() &&
                 "SpeculateDecisionBlock not updated?");
          Mutator.SetInsertPoint(SpeculateDecisionBlock);

          auto LoadGuard =
              Mutator.CreateLoad(LoadValueTy, SpeculatorGuard, "guard.value");
          // if just loaded value equal to 0,return true.
          auto CanSpeculate =
              Mutator.CreateICmpEQ(LoadGuard, ConstantInt::get(LoadValueTy, 0),
                                   "compare.to.speculate");
          Mutator.CreateCondBr(CanSpeculate, SpeculateBlock, &ProgramEntry);

          Mutator.SetInsertPoint(SpeculateBlock);
          auto ImplAddrToUint =
              Mutator.CreatePtrToInt(&Fn, Type::getInt64Ty(MContext));
          Mutator.CreateCall(RuntimeCallTy, RuntimeCall,
                             {SpeclAddr, ImplAddrToUint});
          Mutator.CreateStore(ConstantInt::get(LoadValueTy, 1),
                              SpeculatorGuard);
          Mutator.CreateBr(&ProgramEntry);

          assert(Mutator.GetInsertBlock()->getParent() == &Fn &&
                 "IR builder association mismatch?");
          S.registerSymbols(internToJITSymbols(IRNames.getValue()),
                            &R->getTargetJITDylib());
        }
      }
    }
  });

  assert(!TSM.withModuleDo([](const Module &M) { return verifyModule(M); }) &&
         "Speculation Instrumentation breaks IR?");

  NextLayer.emit(std::move(R), std::move(TSM));
}

} // namespace orc
} // namespace llvm
