//===--------------- LLJITWithCustomObjectLinkingLayer.cpp ----------------===//
//
// 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 shows how to switch LLJIT to use a custom object linking layer (we
// use ObjectLinkingLayer, which is backed by JITLink, as an example).
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/StringMap.h"
#include "llvm/ExecutionEngine/JITLink/JITLink.h"
#include "llvm/ExecutionEngine/JITLink/JITLinkMemoryManager.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"

#include "../ExampleModules.h"

using namespace llvm;
using namespace llvm::orc;

ExitOnError ExitOnErr;

const llvm::StringRef TestMod =
    R"(
  define i32 @callee() {
  entry:
    ret i32 7
  }

  define i32 @entry() {
  entry:
    %0 = call i32 @callee()
    ret i32 %0
  }
)";

class MyPlugin : public ObjectLinkingLayer::Plugin {
public:
  // The modifyPassConfig callback gives us a chance to inspect the
  // MaterializationResponsibility and target triple for the object being
  // linked, then add any JITLink passes that we would like to run on the
  // link graph. A pass is just a function object that is callable as
  // Error(jitlink::LinkGraph&). In this case we will add two passes
  // defined as lambdas that call the printLinkerGraph method on our
  // plugin: One to run before the linker applies fixups and another to
  // run afterwards.
  void modifyPassConfig(MaterializationResponsibility &MR, const Triple &TT,
                        jitlink::PassConfiguration &Config) override {
    Config.PostPrunePasses.push_back([this](jitlink::LinkGraph &G) -> Error {
      printLinkGraph(G, "Before fixup:");
      return Error::success();
    });
    Config.PostFixupPasses.push_back([this](jitlink::LinkGraph &G) -> Error {
      printLinkGraph(G, "After fixup:");
      return Error::success();
    });
  }

  void notifyLoaded(MaterializationResponsibility &MR) override {
    dbgs() << "Loading object defining " << MR.getSymbols() << "\n";
  }

  Error notifyEmitted(MaterializationResponsibility &MR) override {
    dbgs() << "Emitted object defining " << MR.getSymbols() << "\n";
    return Error::success();
  }

private:
  void printLinkGraph(jitlink::LinkGraph &G, StringRef Title) {
    constexpr JITTargetAddress LineWidth = 16;

    dbgs() << "--- " << Title << "---\n";
    for (auto &S : G.sections()) {
      dbgs() << "  section: " << S.getName() << "\n";
      for (auto *B : S.blocks()) {
        dbgs() << "    block@" << formatv("{0:x16}", B->getAddress()) << ":\n";

        if (B->isZeroFill())
          continue;

        JITTargetAddress InitAddr = B->getAddress() & ~(LineWidth - 1);
        JITTargetAddress StartAddr = B->getAddress();
        JITTargetAddress EndAddr = B->getAddress() + B->getSize();
        auto *Data = reinterpret_cast<const uint8_t *>(B->getContent().data());

        for (JITTargetAddress CurAddr = InitAddr; CurAddr != EndAddr;
             ++CurAddr) {
          if (CurAddr % LineWidth == 0)
            dbgs() << "    " << formatv("{0:x16}", CurAddr) << ": ";
          if (CurAddr < StartAddr)
            dbgs() << "   ";
          else
            dbgs() << formatv("{0:x-2}", Data[CurAddr - StartAddr]) << " ";
          if (CurAddr % LineWidth == LineWidth - 1)
            dbgs() << "\n";
        }
        if (EndAddr % LineWidth != 0)
          dbgs() << "\n";
        dbgs() << "\n";
      }
    }
  }
};

int main(int argc, char *argv[]) {
  // Initialize LLVM.
  InitLLVM X(argc, argv);

  InitializeNativeTarget();
  InitializeNativeTargetAsmPrinter();

  cl::ParseCommandLineOptions(argc, argv, "LLJITWithObjectLinkingLayerPlugin");
  ExitOnErr.setBanner(std::string(argv[0]) + ": ");

  // Detect the host and set code model to small.
  auto JTMB = ExitOnErr(JITTargetMachineBuilder::detectHost());
  JTMB.setCodeModel(CodeModel::Small);

  // Create an LLJIT instance with an ObjectLinkingLayer as the base layer.
  // We attach our plugin in to the newly created ObjectLinkingLayer before
  // returning it.
  auto J = ExitOnErr(
      LLJITBuilder()
          .setJITTargetMachineBuilder(std::move(JTMB))
          .setObjectLinkingLayerCreator(
              [&](ExecutionSession &ES, const Triple &TT) {
                // Create ObjectLinkingLayer.
                auto ObjLinkingLayer = std::make_unique<ObjectLinkingLayer>(
                    ES, std::make_unique<jitlink::InProcessMemoryManager>());
                // Add an instance of our plugin.
                ObjLinkingLayer->addPlugin(std::make_unique<MyPlugin>());
                return ObjLinkingLayer;
              })
          .create());

  auto M = ExitOnErr(parseExampleModule(TestMod, "test-module"));

  ExitOnErr(J->addIRModule(std::move(M)));

  // Look up the JIT'd function, cast it to a function pointer, then call it.
  auto EntrySym = ExitOnErr(J->lookup("entry"));
  auto *Entry = (int (*)())EntrySym.getAddress();

  int Result = Entry();
  outs() << "---Result---\n"
         << "entry() = " << Result << "\n";

  return 0;
}
