//===-- llvm-jitlistener.cpp - Utility for testing MCJIT event listener ---===//
//
// 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 program is a used by lit tests to verify the MCJIT JITEventListener
// interface.  It registers a mock JIT event listener, generates a module from
// an input IR file and dumps the reported event information to stdout.
//
//===----------------------------------------------------------------------===//

#include "../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include <string>

using namespace llvm;

namespace {

typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
typedef std::map<uint64_t, SourceLocations> NativeCodeMap;

NativeCodeMap  ReportedDebugFuncs;

int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
  switch (EventType) {
    case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
      if (!EventSpecificData) {
        errs() <<
          "Error: The JIT event listener did not provide a event data.";
        return -1;
      }
      iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);

      ReportedDebugFuncs[msg->method_id];

      outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
             << ", Size = " << msg->method_size << "\n";

      for(unsigned int i = 0; i < msg->line_number_size; ++i) {
        if (!msg->line_number_table) {
          errs() << "A function with a non-zero line count had no line table.";
          return -1;
        }
        std::pair<std::string, unsigned int> loc(
          std::string(msg->source_file_name),
          msg->line_number_table[i].LineNumber);
        ReportedDebugFuncs[msg->method_id].push_back(loc);
        outs() << "  Line info @ " << msg->line_number_table[i].Offset
               << ": " << msg->source_file_name
               << ", line " << msg->line_number_table[i].LineNumber << "\n";
      }
      outs() << "\n";
    }
    break;
    case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
      if (!EventSpecificData) {
        errs() <<
          "Error: The JIT event listener did not provide a event data.";
        return -1;
      }
      unsigned int UnloadId
        = *reinterpret_cast<unsigned int*>(EventSpecificData);
      assert(1 == ReportedDebugFuncs.erase(UnloadId));
      outs() << "Method unload [" << UnloadId << "]\n";
    }
    break;
    default:
      break;
  }
  return 0;
}

iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
  // for testing, pretend we have an Intel Parallel Amplifier XE 2011
  // instance attached
  return iJIT_SAMPLING_ON;
}

unsigned int GetNewMethodID(void) {
  static unsigned int id = 0;
  return ++id;
}

class JitEventListenerTest {
protected:
  void InitEE(const std::string &IRFile) {
    // If we have a native target, initialize it to ensure it is linked in and
    // usable by the JIT.
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();

    // Parse the bitcode...
    SMDiagnostic Err;
    std::unique_ptr<Module> TheModule(parseIRFile(IRFile, Err, Context));
    if (!TheModule) {
      errs() << Err.getMessage();
      return;
    }

    RTDyldMemoryManager *MemMgr = new SectionMemoryManager();
    if (!MemMgr) {
      errs() << "Unable to create memory manager.";
      return;
    }

    // Override the triple to generate ELF on Windows since that's supported
    Triple Tuple(TheModule->getTargetTriple());
    if (Tuple.getTriple().empty())
      Tuple.setTriple(sys::getProcessTriple());

    if (Tuple.isOSWindows() && !Tuple.isOSBinFormatELF()) {
      Tuple.setObjectFormat(Triple::ELF);
      TheModule->setTargetTriple(Tuple.getTriple());
    }

    // Compile the IR
    std::string Error;
    TheJIT.reset(EngineBuilder(std::move(TheModule))
      .setEngineKind(EngineKind::JIT)
      .setErrorStr(&Error)
      .setMCJITMemoryManager(std::unique_ptr<RTDyldMemoryManager>(MemMgr))
      .create());
    if (Error.empty() == false)
      errs() << Error;
  }

  void DestroyEE() {
    TheJIT.reset();
  }

  LLVMContext Context; // Global ownership
  std::unique_ptr<ExecutionEngine> TheJIT;

public:
  void ProcessInput(const std::string &Filename) {
    InitEE(Filename);

    std::unique_ptr<llvm::JITEventListener> Listener(
        JITEventListener::createIntelJITEventListener(new IntelJITEventsWrapper(
            NotifyEvent, 0, IsProfilingActive, 0, 0, GetNewMethodID)));

    TheJIT->RegisterJITEventListener(Listener.get());

    TheJIT->finalizeObject();

    // Destroy the JIT engine instead of unregistering to get unload events.
    DestroyEE();
  }
};



} // end anonymous namespace

static cl::opt<std::string>
InputFilename(cl::Positional, cl::desc("<input IR file>"),
               cl::Required);

int main(int argc, char **argv) {
  InitLLVM X(argc, argv);
  cl::ParseCommandLineOptions(argc, argv, "llvm jit event listener test utility\n");

  JitEventListenerTest Test;
  Test.ProcessInput(InputFilename);
  return 0;
}
