//===-- AVRInstrumentFunctions.cpp - Insert instrumentation for testing ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass takes a function and inserts calls to hook functions which are
// told the name, arguments, and results of function calls.
//
// The hooks can do anything with the information given. It is possible to
// send the data through a serial connection in order to runs tests on
// bare metal.
//
//===----------------------------------------------------------------------===//

#include "AVR.h"

#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>

using namespace llvm;

#define AVR_INSTRUMENT_FUNCTIONS_NAME "AVR function instrumentation pass"

namespace {

// External symbols that we emit calls to.
namespace symbols {

#define SYMBOL_PREFIX "avr_instrumentation"

  const StringRef PREFIX = SYMBOL_PREFIX;

  // void (i16 argCount);
  const StringRef BEGIN_FUNCTION_SIGNATURE = SYMBOL_PREFIX "_begin_signature";
  // void(i16 argCount);
  const StringRef END_FUNCTION_SIGNATURE = SYMBOL_PREFIX "_end_signature";

#undef SYMBOL_PREFIX
}

class AVRInstrumentFunctions : public FunctionPass {
public:
  static char ID;

  AVRInstrumentFunctions() : FunctionPass(ID) {
    initializeAVRInstrumentFunctionsPass(*PassRegistry::getPassRegistry());
  }

  bool runOnFunction(Function &F) override;

  StringRef getPassName() const override { return AVR_INSTRUMENT_FUNCTIONS_NAME; }
};

char AVRInstrumentFunctions::ID = 0;

/// Creates a pointer to a string.
static Value *CreateStringPtr(BasicBlock &BB, StringRef Str) {
  LLVMContext &Ctx = BB.getContext();
  IntegerType *I8 = Type::getInt8Ty(Ctx);

  Constant *ConstantStr = ConstantDataArray::getString(Ctx, Str);
  GlobalVariable *GlobalStr = new GlobalVariable(*BB.getParent()->getParent(),
                                                 ConstantStr->getType(),
                                                 true, /* is a constant */
                                                 GlobalValue::PrivateLinkage,
                                                 ConstantStr);
  return GetElementPtrInst::CreateInBounds(GlobalStr,
    {ConstantInt::get(I8, 0), ConstantInt::get(I8, 0)}, "", &BB);
}

static std::string GetTypeName(Type &Ty) {
  if (auto *IntTy = dyn_cast<IntegerType>(&Ty)) {
    return std::string("i") + std::to_string(IntTy->getBitWidth());
  }

  if (Ty.isFloatingPointTy()) {
    return std::string("f") + std::to_string(Ty.getPrimitiveSizeInBits());
  }

  llvm_unreachable("unknown return type");
}

/// Builds a call to one of the signature begin/end hooks.
static void BuildSignatureCall(StringRef SymName, BasicBlock &BB, Function &F) {
  LLVMContext &Ctx = F.getContext();
  IntegerType *I16 = Type::getInt16Ty(Ctx);

  FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx),
    {Type::getInt8PtrTy(Ctx), I16}, false);

  Constant *Fn = F.getParent()->getOrInsertFunction(SymName, FnType);
  Value *FunctionName = CreateStringPtr(BB, F.getName());

  Value *Args[] = {FunctionName,
                   ConstantInt::get(I16, F.arg_size())};
  CallInst::Create(Fn, Args, "", &BB);
}

/// Builds instructions to call into an external function to
/// notify about a function signature beginning.
static void BuildBeginSignature(BasicBlock &BB, Function &F) {
  return BuildSignatureCall(symbols::BEGIN_FUNCTION_SIGNATURE, BB, F);
}

/// Builds instructions to call into an external function to
/// notify about a function signature ending.
static void BuildEndSignature(BasicBlock &BB, Function &F) {
  return BuildSignatureCall(symbols::END_FUNCTION_SIGNATURE, BB, F);
}

/// Get the name of the external symbol that we need to call
/// to notify about this argument.
static std::string GetArgumentSymbolName(Argument &Arg) {
  return (symbols::PREFIX + "_argument_" + GetTypeName(*Arg.getType())).str();
}

/// Builds a call to one of the argument hooks.
static void BuildArgument(BasicBlock &BB, Argument &Arg) {
  Function &F = *Arg.getParent();
  LLVMContext &Ctx = F.getContext();

  Type *I8 = Type::getInt8Ty(Ctx);

  FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx),
    {Type::getInt8PtrTy(Ctx), I8, Arg.getType()}, false);

  Constant *Fn = F.getParent()->getOrInsertFunction(
    GetArgumentSymbolName(Arg), FnType);
  Value *ArgName = CreateStringPtr(BB, Arg.getName());

  Value *Args[] = {ArgName, ConstantInt::get(I8, Arg.getArgNo()), &Arg};
  CallInst::Create(Fn, Args, "", &BB);
}

/// Builds a call to all of the function signature hooks.
static void BuildSignature(BasicBlock &BB, Function &F) {
  BuildBeginSignature(BB, F);
  for (Argument &Arg : F.args()) { BuildArgument(BB, Arg); }
  BuildEndSignature(BB, F);
}

/// Builds the instrumentation entry block.
static void BuildEntryBlock(Function &F) {
  BasicBlock &EntryBlock = F.getEntryBlock();

  // Create a new basic block at the start of the existing entry block.
  BasicBlock *BB = BasicBlock::Create(F.getContext(),
                                      "instrumentation_entry",
                                      &F, &EntryBlock);

  BuildSignature(*BB, F);

  // Jump to the actual entry block.
  BranchInst::Create(&EntryBlock, BB);
}

static std::string GetReturnSymbolName(Value &Val) {
  return (symbols::PREFIX + "_result_" + GetTypeName(*Val.getType())).str();
}

static void BuildExitHook(Instruction &I) {
  Function &F = *I.getParent()->getParent();
  LLVMContext &Ctx = F.getContext();

  if (auto *Ret = dyn_cast<ReturnInst>(&I)) {
    Value *RetVal = Ret->getReturnValue();
    assert(RetVal && "should only be instrumenting functions with return values");

    FunctionType *FnType = FunctionType::get(Type::getVoidTy(Ctx),
      {RetVal->getType()}, false);

    Constant *Fn = F.getParent()->getOrInsertFunction(
      GetReturnSymbolName(*RetVal), FnType);

    // Call the result hook just before the return.
    CallInst::Create(Fn, {RetVal}, "", &I);
  }
}

/// Runs return hooks before all returns in a function.
static void BuildExitHooks(Function &F) {
  for (BasicBlock &BB : F) {
    auto BBI = BB.begin(), E = BB.end();
    while (BBI != E) {
      auto NBBI = std::next(BBI);

      BuildExitHook(*BBI);

      // Modified |= expandMI(BB, MBBI);
      BBI = NBBI;
    }
  }
}

static bool ShouldInstrument(Function &F) {
  // No point reporting results if there are none.
  return !F.getReturnType()->isVoidTy();
}

bool AVRInstrumentFunctions::runOnFunction(Function &F) {
  if (ShouldInstrument(F)) {
    BuildEntryBlock(F);
    BuildExitHooks(F);
  }

  return true;
}

} // end of anonymous namespace

INITIALIZE_PASS(AVRInstrumentFunctions, "avr-instrument-functions",
                AVR_INSTRUMENT_FUNCTIONS_NAME, false, false)

namespace llvm {

FunctionPass *createAVRInstrumentFunctionsPass() { return new AVRInstrumentFunctions(); }

} // end of namespace llvm
