//===-- RenderScriptExpressionOpts.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
//
//===----------------------------------------------------------------------===//

#include <string>

#include "llvm/ADT/None.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"

#include "clang/Basic/TargetOptions.h"

#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/Log.h"

#include "RenderScriptExpressionOpts.h"
#include "RenderScriptRuntime.h"
#include "RenderScriptx86ABIFixups.h"

using namespace lldb_private;
using namespace lldb_renderscript;

// [``slang``](https://android.googlesource.com/platform/frameworks/compile/slang),
// the compiler frontend for RenderScript embeds an ARM specific triple in IR
// that is shipped in the app, after generating IR that has some assumptions
// that an ARM device is the target. As the IR is then compiled on a device of
// unknown (at time the IR was generated at least) architecture, when calling
// RenderScript API function as part of debugger expressions, we have to
// perform a fixup pass that removes those assumptions right before the module
// is sent to be generated by the llvm backend.

namespace {
bool registerRSDefaultTargetOpts(clang::TargetOptions &proto,
                                 const llvm::Triple::ArchType &arch) {
  switch (arch) {
  case llvm::Triple::ArchType::x86:
    proto.Triple = "i686--linux-android";
    proto.CPU = "atom";
    proto.Features.push_back("+long64");
    // Fallthrough for common x86 family features
    LLVM_FALLTHROUGH;
  case llvm::Triple::ArchType::x86_64:
    proto.Features.push_back("+mmx");
    proto.Features.push_back("+sse");
    proto.Features.push_back("+sse2");
    proto.Features.push_back("+sse3");
    proto.Features.push_back("+ssse3");
    proto.Features.push_back("+sse4.1");
    proto.Features.push_back("+sse4.2");
    break;
  case llvm::Triple::ArchType::mipsel:
    // pretend this is `arm' for the front-end
    proto.Triple = "armv7-none-linux-android";
    proto.CPU = "";
    proto.Features.push_back("+long64");
    break;
  case llvm::Triple::ArchType::mips64el:
    // pretend this is `aarch64' for the front-end
    proto.Triple = "aarch64-none-linux-android";
    proto.CPU = "";
    break;
  default:
    return false;
  }
  return true;
}
} // end anonymous namespace

bool RenderScriptRuntimeModulePass::runOnModule(llvm::Module &module) {
  bool changed_module = false;
  Log *log(
      GetLogIfAllCategoriesSet(LIBLLDB_LOG_LANGUAGE | LIBLLDB_LOG_EXPRESSIONS));

  std::string err;
  llvm::StringRef real_triple =
      m_process_ptr->GetTarget().GetArchitecture().GetTriple().getTriple();
  const llvm::Target *target_info =
      llvm::TargetRegistry::lookupTarget(std::string(real_triple), err);
  if (!target_info) {
    if (log)
      log->Warning("couldn't determine real target architecture: '%s'",
                   err.c_str());
    return false;
  }

  llvm::Optional<llvm::Reloc::Model> reloc_model = llvm::None;
  assert(m_process_ptr && "no available lldb process");
  switch (m_process_ptr->GetTarget().GetArchitecture().GetMachine()) {
  case llvm::Triple::ArchType::x86:
    changed_module |= fixupX86FunctionCalls(module);
    // For some reason this triple gets totally missed by the backend, and must
    // be set manually. There a reference in bcc/Main.cpp about auto feature-
    // detection being removed from LLVM3.5, but I can't see that discussion
    // anywhere public.
    real_triple = "i686--linux-android";
    break;
  case llvm::Triple::ArchType::x86_64:
    changed_module |= fixupX86_64FunctionCalls(module);
    break;
  case llvm::Triple::ArchType::mipsel:
  case llvm::Triple::ArchType::mips64el:
    // No actual IR fixup pass is needed on MIPS, but the datalayout and
    // targetmachine do need to be explicitly set.

    // bcc explicitly compiles MIPS code to use the static relocation model due
    // to an issue with relocations in mclinker. see
    // libbcc/support/CompilerConfig.cpp for details
    reloc_model = llvm::Reloc::Static;
    changed_module = true;
    break;
  case llvm::Triple::ArchType::arm:
  case llvm::Triple::ArchType::aarch64:
    // ARM subtargets need no fixup passes as they are the initial target as
    // generated by the
    // slang compiler frontend.
    break;
  default:
    if (log)
      log->Warning("Ignoring unknown renderscript target");
    return false;
  }

  if (changed_module) {
    llvm::TargetOptions options;
    llvm::TargetMachine *target_machine = target_info->createTargetMachine(
        real_triple, "", "", options, reloc_model);
    assert(target_machine &&
           "failed to identify RenderScriptRuntime target machine");
    // We've been using a triple and datalayout of some ARM variant all along,
    // so we need to let the backend know that this is no longer the case.
    if (log) {
      LLDB_LOGF(log, "%s - Changing RS target triple to '%s'", __FUNCTION__,
                real_triple.str().c_str());
      LLDB_LOGF(
          log, "%s - Changing RS datalayout to '%s'", __FUNCTION__,
          target_machine->createDataLayout().getStringRepresentation().c_str());
    }
    module.setTargetTriple(real_triple);
    module.setDataLayout(target_machine->createDataLayout());
  }
  return changed_module;
}

char RenderScriptRuntimeModulePass::ID = 0;

namespace lldb_private {

bool RenderScriptRuntime::GetOverrideExprOptions(clang::TargetOptions &proto) {
  auto *process = GetProcess();
  assert(process);
  return registerRSDefaultTargetOpts(
      proto, process->GetTarget().GetArchitecture().GetMachine());
}

bool RenderScriptRuntime::GetIRPasses(LLVMUserExpression::IRPasses &passes) {
  if (!m_ir_passes)
    m_ir_passes = new RSIRPasses(GetProcess());
  assert(m_ir_passes);

  passes.EarlyPasses = m_ir_passes->EarlyPasses;
  passes.LatePasses = m_ir_passes->LatePasses;

  return true;
}

namespace lldb_renderscript {

RSIRPasses::RSIRPasses(Process *process) {
  IRPasses();
  assert(process);

  EarlyPasses = std::make_shared<llvm::legacy::PassManager>();
  assert(EarlyPasses);
  EarlyPasses->add(new RenderScriptRuntimeModulePass(process));
}

RSIRPasses::~RSIRPasses() {}

} // namespace lldb_renderscript
} // namespace lldb_private
