//===- MCJITTestBase.h - Common base class for MCJIT Unit tests -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This class implements common functionality required by the MCJIT unit tests,
// as well as logic to skip tests on unsupported architectures and operating
// systems.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
#define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H

#include "MCJITTestAPICommon.h"
#include "llvm/Config/config.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CodeGen.h"

namespace llvm {

/// Helper class that can build very simple Modules
class TrivialModuleBuilder {
protected:
  LLVMContext Context;
  IRBuilder<> Builder;
  std::string BuilderTriple;

  TrivialModuleBuilder(const std::string &Triple)
    : Builder(Context), BuilderTriple(Triple) {}

  Module *createEmptyModule(StringRef Name = StringRef()) {
    Module * M = new Module(Name, Context);
    M->setTargetTriple(Triple::normalize(BuilderTriple));
    return M;
  }

  Function *startFunction(Module *M, FunctionType *FT, StringRef Name) {
    Function *Result =
        Function::Create(FT, GlobalValue::ExternalLinkage, Name, M);

    BasicBlock *BB = BasicBlock::Create(Context, Name, Result);
    Builder.SetInsertPoint(BB);

    return Result;
  }

  void endFunctionWithRet(Function *Func, Value *RetValue) {
    Builder.CreateRet(RetValue);
  }

  // Inserts a simple function that invokes Callee and takes the same arguments:
  //    int Caller(...) { return Callee(...); }
  Function *insertSimpleCallFunction(Module *M, Function *Callee) {
    Function *Result = startFunction(M, Callee->getFunctionType(), "caller");

    SmallVector<Value*, 1> CallArgs;

    for (Argument &A : Result->args())
      CallArgs.push_back(&A);

    Value *ReturnCode = Builder.CreateCall(Callee, CallArgs);
    Builder.CreateRet(ReturnCode);
    return Result;
  }

  // Inserts a function named 'main' that returns a uint32_t:
  //    int32_t main() { return X; }
  // where X is given by returnCode
  Function *insertMainFunction(Module *M, uint32_t returnCode) {
    Function *Result = startFunction(
        M, FunctionType::get(Type::getInt32Ty(Context), {}, false), "main");

    Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode));
    endFunctionWithRet(Result, ReturnVal);

    return Result;
  }

  // Inserts a function
  //    int32_t add(int32_t a, int32_t b) { return a + b; }
  // in the current module and returns a pointer to it.
  Function *insertAddFunction(Module *M, StringRef Name = "add") {
    Function *Result = startFunction(
        M,
        FunctionType::get(
            Type::getInt32Ty(Context),
            {Type::getInt32Ty(Context), Type::getInt32Ty(Context)}, false),
        Name);

    Function::arg_iterator args = Result->arg_begin();
    Value *Arg1 = &*args;
    Value *Arg2 = &*++args;
    Value *AddResult = Builder.CreateAdd(Arg1, Arg2);

    endFunctionWithRet(Result, AddResult);

    return Result;
  }

  // Inserts a declaration to a function defined elsewhere
  Function *insertExternalReferenceToFunction(Module *M, FunctionType *FTy,
                                              StringRef Name) {
    Function *Result =
        Function::Create(FTy, GlobalValue::ExternalLinkage, Name, M);
    return Result;
  }

  // Inserts an declaration to a function defined elsewhere
  Function *insertExternalReferenceToFunction(Module *M, Function *Func) {
    Function *Result = Function::Create(Func->getFunctionType(),
                                        GlobalValue::ExternalLinkage,
                                        Func->getName(), M);
    return Result;
  }

  // Inserts a global variable of type int32
  // FIXME: make this a template function to support any type
  GlobalVariable *insertGlobalInt32(Module *M,
                                    StringRef name,
                                    int32_t InitialValue) {
    Type *GlobalTy = Type::getInt32Ty(Context);
    Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue));
    GlobalVariable *Global = new GlobalVariable(*M,
                                                GlobalTy,
                                                false,
                                                GlobalValue::ExternalLinkage,
                                                IV,
                                                name);
    return Global;
  }

  // Inserts a function
  //   int32_t recursive_add(int32_t num) {
  //     if (num == 0) {
  //       return num;
  //     } else {
  //       int32_t recursive_param = num - 1;
  //       return num + Helper(recursive_param);
  //     }
  //   }
  // NOTE: if Helper is left as the default parameter, Helper == recursive_add.
  Function *insertAccumulateFunction(Module *M,
                                     Function *Helper = nullptr,
                                     StringRef Name = "accumulate") {
    Function *Result =
        startFunction(M,
                      FunctionType::get(Type::getInt32Ty(Context),
                                        {Type::getInt32Ty(Context)}, false),
                      Name);
    if (!Helper)
      Helper = Result;

    BasicBlock *BaseCase = BasicBlock::Create(Context, "", Result);
    BasicBlock *RecursiveCase = BasicBlock::Create(Context, "", Result);

    // if (num == 0)
    Value *Param = &*Result->arg_begin();
    Value *Zero = ConstantInt::get(Context, APInt(32, 0));
    Builder.CreateCondBr(Builder.CreateICmpEQ(Param, Zero),
                         BaseCase, RecursiveCase);

    //   return num;
    Builder.SetInsertPoint(BaseCase);
    Builder.CreateRet(Param);

    //   int32_t recursive_param = num - 1;
    //   return Helper(recursive_param);
    Builder.SetInsertPoint(RecursiveCase);
    Value *One = ConstantInt::get(Context, APInt(32, 1));
    Value *RecursiveParam = Builder.CreateSub(Param, One);
    Value *RecursiveReturn = Builder.CreateCall(Helper, RecursiveParam);
    Value *Accumulator = Builder.CreateAdd(Param, RecursiveReturn);
    Builder.CreateRet(Accumulator);

    return Result;
  }

  // Populates Modules A and B:
  // Module A { Extern FB1, Function FA which calls FB1 },
  // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
  void createCrossModuleRecursiveCase(std::unique_ptr<Module> &A, Function *&FA,
                                      std::unique_ptr<Module> &B,
                                      Function *&FB1, Function *&FB2) {
    // Define FB1 in B.
    B.reset(createEmptyModule("B"));
    FB1 = insertAccumulateFunction(B.get(), nullptr, "FB1");

    // Declare FB1 in A (as an external).
    A.reset(createEmptyModule("A"));
    Function *FB1Extern = insertExternalReferenceToFunction(A.get(), FB1);

    // Define FA in A (with a call to FB1).
    FA = insertAccumulateFunction(A.get(), FB1Extern, "FA");

    // Declare FA in B (as an external)
    Function *FAExtern = insertExternalReferenceToFunction(B.get(), FA);

    // Define FB2 in B (with a call to FA)
    FB2 = insertAccumulateFunction(B.get(), FAExtern, "FB2");
  }

  // Module A { Function FA },
  // Module B { Extern FA, Function FB which calls FA },
  // Module C { Extern FB, Function FC which calls FB },
  void
  createThreeModuleChainedCallsCase(std::unique_ptr<Module> &A, Function *&FA,
                                    std::unique_ptr<Module> &B, Function *&FB,
                                    std::unique_ptr<Module> &C, Function *&FC) {
    A.reset(createEmptyModule("A"));
    FA = insertAddFunction(A.get());

    B.reset(createEmptyModule("B"));
    Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
    FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);

    C.reset(createEmptyModule("C"));
    Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB);
    FC = insertSimpleCallFunction(C.get(), FBExtern_in_C);
  }

  // Module A { Function FA },
  // Populates Modules A and B:
  // Module B { Function FB }
  void createTwoModuleCase(std::unique_ptr<Module> &A, Function *&FA,
                           std::unique_ptr<Module> &B, Function *&FB) {
    A.reset(createEmptyModule("A"));
    FA = insertAddFunction(A.get());

    B.reset(createEmptyModule("B"));
    FB = insertAddFunction(B.get());
  }

  // Module A { Function FA },
  // Module B { Extern FA, Function FB which calls FA }
  void createTwoModuleExternCase(std::unique_ptr<Module> &A, Function *&FA,
                                 std::unique_ptr<Module> &B, Function *&FB) {
    A.reset(createEmptyModule("A"));
    FA = insertAddFunction(A.get());

    B.reset(createEmptyModule("B"));
    Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
    FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);
  }

  // Module A { Function FA },
  // Module B { Extern FA, Function FB which calls FA },
  // Module C { Extern FB, Function FC which calls FA },
  void createThreeModuleCase(std::unique_ptr<Module> &A, Function *&FA,
                             std::unique_ptr<Module> &B, Function *&FB,
                             std::unique_ptr<Module> &C, Function *&FC) {
    A.reset(createEmptyModule("A"));
    FA = insertAddFunction(A.get());

    B.reset(createEmptyModule("B"));
    Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
    FB = insertSimpleCallFunction(B.get(), FAExtern_in_B);

    C.reset(createEmptyModule("C"));
    Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA);
    FC = insertSimpleCallFunction(C.get(), FAExtern_in_C);
  }
};

class MCJITTestBase : public MCJITTestAPICommon, public TrivialModuleBuilder {
protected:
  MCJITTestBase()
      : TrivialModuleBuilder(HostTriple), OptLevel(CodeGenOpt::None),
        CodeModel(CodeModel::Small), MArch(""), MM(new SectionMemoryManager) {
    // The architectures below are known to be compatible with MCJIT as they
    // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
    // kept in sync.
    SupportedArchs.push_back(Triple::aarch64);
    SupportedArchs.push_back(Triple::arm);
    SupportedArchs.push_back(Triple::mips);
    SupportedArchs.push_back(Triple::mipsel);
    SupportedArchs.push_back(Triple::mips64);
    SupportedArchs.push_back(Triple::mips64el);
    SupportedArchs.push_back(Triple::x86);
    SupportedArchs.push_back(Triple::x86_64);

    // Some architectures have sub-architectures in which tests will fail, like
    // ARM. These two vectors will define if they do have sub-archs (to avoid
    // extra work for those who don't), and if so, if they are listed to work
    HasSubArchs.push_back(Triple::arm);
    SupportedSubArchs.push_back("armv6");
    SupportedSubArchs.push_back("armv7");

    UnsupportedEnvironments.push_back(Triple::Cygnus);
  }

  void createJIT(std::unique_ptr<Module> M) {

    // Due to the EngineBuilder constructor, it is required to have a Module
    // in order to construct an ExecutionEngine (i.e. MCJIT)
    assert(M != 0 && "a non-null Module must be provided to create MCJIT");

    EngineBuilder EB(std::move(M));
    std::string Error;
    TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
                 .setMCJITMemoryManager(std::move(MM))
                 .setErrorStr(&Error)
                 .setOptLevel(CodeGenOpt::None)
                 .setMArch(MArch)
                 .setMCPU(sys::getHostCPUName())
                 //.setMAttrs(MAttrs)
                 .create());
    // At this point, we cannot modify the module any more.
    assert(TheJIT.get() != NULL && "error creating MCJIT with EngineBuilder");
  }

  CodeGenOpt::Level OptLevel;
  CodeModel::Model CodeModel;
  StringRef MArch;
  SmallVector<std::string, 1> MAttrs;
  std::unique_ptr<ExecutionEngine> TheJIT;
  std::unique_ptr<RTDyldMemoryManager> MM;

  std::unique_ptr<Module> M;
};

} // namespace llvm

#endif // LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
