/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "bcc/Renderscript/RSCompilerDriver.h"

#include <llvm/Support/Path.h>

#include "bcinfo/BitcodeWrapper.h"

#include "bcc/Renderscript/RSExecutable.h"
#include "bcc/Renderscript/RSScript.h"
#include "bcc/Support/CompilerConfig.h"
#include "bcc/Support/TargetCompilerConfigs.h"
#include "bcc/Source.h"
#include "bcc/Support/FileMutex.h"
#include "bcc/Support/Log.h"
#include "bcc/Support/InputFile.h"
#include "bcc/Support/Initialization.h"
#include "bcc/Support/Sha1Util.h"
#include "bcc/Support/OutputFile.h"

#include <cutils/properties.h>
#include <utils/String8.h>
#include <utils/StopWatch.h>

using namespace bcc;

namespace {

bool is_force_recompile() {
  char buf[PROPERTY_VALUE_MAX];

  // Re-compile if floating point precision has been overridden.
  property_get("debug.rs.precision", buf, "");
  if (buf[0] != '\0') {
    return true;
  }

  // Re-compile if debug.rs.forcerecompile is set.
  property_get("debug.rs.forcerecompile", buf, "0");
  if ((::strcmp(buf, "1") == 0) || (::strcmp(buf, "true") == 0)) {
    return true;
  } else {
    return false;
  }
}

} // end anonymous namespace

RSCompilerDriver::RSCompilerDriver(bool pUseCompilerRT) :
    mConfig(NULL), mCompiler(), mCompilerRuntime(NULL) {
  init::Initialize();
  // Chain the symbol resolvers for compiler_rt and RS runtimes.
  if (pUseCompilerRT) {
    mCompilerRuntime = new CompilerRTSymbolResolver();
    mResolver.chainResolver(*mCompilerRuntime);
  }
  mResolver.chainResolver(mRSRuntime);
}

RSCompilerDriver::~RSCompilerDriver() {
  delete mCompilerRuntime;
  delete mConfig;
}

RSExecutable *
RSCompilerDriver::loadScriptCache(const char *pOutputPath,
                                  const RSInfo::DependencyTableTy &pDeps) {
  android::StopWatch load_time("bcc: RSCompilerDriver::loadScriptCache time");
  RSExecutable *result = NULL;

  if (is_force_recompile())
    return NULL;

  //===--------------------------------------------------------------------===//
  // Acquire the read lock for reading output object file.
  //===--------------------------------------------------------------------===//
  FileMutex<FileBase::kReadLock> read_output_mutex(pOutputPath);

  if (read_output_mutex.hasError() || !read_output_mutex.lock()) {
    ALOGE("Unable to acquire the read lock for %s! (%s)", pOutputPath,
          read_output_mutex.getErrorMessage().c_str());
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Read the output object file.
  //===--------------------------------------------------------------------===//
  InputFile *output_file = new (std::nothrow) InputFile(pOutputPath);

  if ((output_file == NULL) || output_file->hasError()) {
    ALOGE("Unable to open the %s for read! (%s)", pOutputPath,
          output_file->getErrorMessage().c_str());
    delete output_file;
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Acquire the read lock on output_file for reading its RS info file.
  //===--------------------------------------------------------------------===//
  android::String8 info_path = RSInfo::GetPath(*output_file);

  if (!output_file->lock()) {
    ALOGE("Unable to acquire the read lock on %s for reading %s! (%s)",
          pOutputPath, info_path.string(),
          output_file->getErrorMessage().c_str());
    delete output_file;
    return NULL;
  }

 //===---------------------------------------------------------------------===//
  // Open and load the RS info file.
  //===--------------------------------------------------------------------===//
  InputFile info_file(info_path.string());
  RSInfo *info = RSInfo::ReadFromFile(info_file, pDeps);

  // Release the lock on output_file.
  output_file->unlock();

  if (info == NULL) {
    delete output_file;
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Create the RSExecutable.
  //===--------------------------------------------------------------------===//
  result = RSExecutable::Create(*info, *output_file, mResolver);
  if (result == NULL) {
    delete output_file;
    delete info;
    return NULL;
  }

  return result;
}

bool RSCompilerDriver::setupConfig(const RSScript &pScript) {
  bool changed = false;

  const llvm::CodeGenOpt::Level script_opt_level =
      static_cast<llvm::CodeGenOpt::Level>(pScript.getOptimizationLevel());

  if (mConfig != NULL) {
    // Renderscript bitcode may have their optimization flag configuration
    // different than the previous run of RS compilation.
    if (mConfig->getOptimizationLevel() != script_opt_level) {
      mConfig->setOptimizationLevel(script_opt_level);
      changed = true;
    }
  } else {
    // Haven't run the compiler ever.
    mConfig = new (std::nothrow) DefaultCompilerConfig();
    if (mConfig == NULL) {
      // Return false since mConfig remains NULL and out-of-memory.
      return false;
    }
    mConfig->setOptimizationLevel(script_opt_level);
    changed = true;
  }

#if defined(DEFAULT_ARM_CODEGEN)
  // NEON should be disable when full-precision floating point is required.
  assert((pScript.getInfo() != NULL) && "NULL RS info!");
  if (pScript.getInfo()->getFloatPrecisionRequirement() == RSInfo::FP_Full) {
    // Must be ARMCompilerConfig.
    ARMCompilerConfig *arm_config = static_cast<ARMCompilerConfig *>(mConfig);
    changed |= arm_config->enableNEON(/* pEnable */false);
  }
#endif

  return changed;
}

RSExecutable *
RSCompilerDriver::compileScript(RSScript &pScript,
                                const char* pScriptName,
                                const char *pOutputPath,
                                const char *pRuntimePath,
                                const RSInfo::DependencyTableTy &pDeps,
                                bool pSkipLoad) {
  android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
  RSExecutable *result = NULL;
  RSInfo *info = NULL;

  //===--------------------------------------------------------------------===//
  // Extract RS-specific information from source bitcode.
  //===--------------------------------------------------------------------===//
  // RS info may contains configuration (such as #optimization_level) to the
  // compiler therefore it should be extracted before compilation.
  info = RSInfo::ExtractFromSource(pScript.getSource(), pDeps);
  if (info == NULL) {
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Associate script with its info
  //===--------------------------------------------------------------------===//
  // This is required since RS compiler may need information in the info file
  // to do some transformation (e.g., expand foreach-able function.)
  pScript.setInfo(info);

  //===--------------------------------------------------------------------===//
  // Link RS script with Renderscript runtime.
  //===--------------------------------------------------------------------===//
  if (!RSScript::LinkRuntime(pScript, pRuntimePath)) {
    ALOGE("Failed to link script '%s' with Renderscript runtime!", pScriptName);
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Acquire the write lock for writing output object file.
  //===--------------------------------------------------------------------===//
  FileMutex<FileBase::kWriteLock> write_output_mutex(pOutputPath);

  if (write_output_mutex.hasError() || !write_output_mutex.lock()) {
    ALOGE("Unable to acquire the lock for writing %s! (%s)",
          pOutputPath, write_output_mutex.getErrorMessage().c_str());
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Open the output file for write.
  //===--------------------------------------------------------------------===//
  OutputFile *output_file =
      new (std::nothrow) OutputFile(pOutputPath, FileBase::kTruncate);

  if ((output_file == NULL) || output_file->hasError()) {
    ALOGE("Unable to open the %s for write! (%s)", pOutputPath,
          output_file->getErrorMessage().c_str());
    delete info;
    delete output_file;
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Setup the config to the compiler.
  //===--------------------------------------------------------------------===//
  bool compiler_need_reconfigure = setupConfig(pScript);

  if (mConfig == NULL) {
    ALOGE("Failed to setup config for RS compiler to compile %s!", pOutputPath);
    delete info;
    delete output_file;
    return NULL;
  }

  // Compiler need to re-config if it's haven't run the config() yet or the
  // configuration it referenced is changed.
  if (compiler_need_reconfigure) {
    Compiler::ErrorCode err = mCompiler.config(*mConfig);
    if (err != Compiler::kSuccess) {
      ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath,
            Compiler::GetErrorString(err));
      delete info;
      delete output_file;
      return NULL;
    }
  }

  //===--------------------------------------------------------------------===//
  // Run the compiler.
  //===--------------------------------------------------------------------===//
  Compiler::ErrorCode compile_result = mCompiler.compile(pScript, *output_file);
  if (compile_result != Compiler::kSuccess) {
    ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath,
          Compiler::GetErrorString(compile_result));
    delete info;
    delete output_file;
    return NULL;
  }

  // No need to produce an RSExecutable in this case.
  // TODO: Error handling in this case is nonexistent.
  if (pSkipLoad) {
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Create the RSExecutable.
  //===--------------------------------------------------------------------===//
  result = RSExecutable::Create(*info, *output_file, mResolver);
  if (result == NULL) {
    delete info;
    delete output_file;
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Dump the disassembly for debug when possible.
  //===--------------------------------------------------------------------===//
#if USE_DISASSEMBLER
  OutputFile *disassembly_output =
      new (std::nothrow) OutputFile(DEBUG_DISASSEMBLER_FILE,
                                    FileBase::kAppend);

  if (disassembly_output != NULL) {
    result->dumpDisassembly(*disassembly_output);
    delete disassembly_output;
  }
#endif

  //===--------------------------------------------------------------------===//
  // Write out the RS info file.
  //===--------------------------------------------------------------------===//
  // Note that write failure only results in a warning since the source is
  // successfully compiled and loaded.
  if (!result->syncInfo(/* pForce */true)) {
    ALOGW("%s was successfully compiled and loaded but its RS info file failed "
          "to write out!", pOutputPath);
  }

  return result;
}

RSExecutable *RSCompilerDriver::build(BCCContext &pContext,
                                      const char *pCacheDir,
                                      const char *pResName,
                                      const char *pBitcode,
                                      size_t pBitcodeSize,
                                      const char *pRuntimePath,
                                      RSLinkRuntimeCallback pLinkRuntimeCallback) {
  android::StopWatch build_time("bcc: RSCompilerDriver::build time");
  //===--------------------------------------------------------------------===//
  // Check parameters.
  //===--------------------------------------------------------------------===//
  if ((pCacheDir == NULL) || (pResName == NULL)) {
    ALOGE("Invalid parameter passed to RSCompilerDriver::build()! (cache dir: "
          "%s, resource name: %s)", ((pCacheDir) ? pCacheDir : "(null)"),
                                    ((pResName) ? pResName : "(null)"));
    return NULL;
  }

  if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
    ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %u)",
          pBitcode, static_cast<unsigned>(pBitcodeSize));
    return NULL;
  }

  //===--------------------------------------------------------------------===//
  // Prepare dependency information.
  //===--------------------------------------------------------------------===//
  RSInfo::DependencyTableTy dep_info;
  uint8_t bitcode_sha1[20];
  Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
  dep_info.push(std::make_pair(pResName, bitcode_sha1));

  //===--------------------------------------------------------------------===//
  // Construct output path.
  //===--------------------------------------------------------------------===//
  llvm::sys::Path output_path(pCacheDir);

  // {pCacheDir}/{pResName}
  if (!output_path.appendComponent(pResName)) {
    ALOGE("Failed to construct output path %s/%s!", pCacheDir, pResName);
    return NULL;
  }

  // {pCacheDir}/{pResName}.o
  output_path.appendSuffix("o");

  //===--------------------------------------------------------------------===//
  // Load cache.
  //===--------------------------------------------------------------------===//
  RSExecutable *result = loadScriptCache(output_path.c_str(), dep_info);

  if (result != NULL) {
    // Cache hit
    return result;
  }

  //===--------------------------------------------------------------------===//
  // Load the bitcode and create script.
  //===--------------------------------------------------------------------===//
  Source *source = Source::CreateFromBuffer(pContext, pResName,
                                            pBitcode, pBitcodeSize);
  if (source == NULL) {
    return NULL;
  }

  RSScript *script = new (std::nothrow) RSScript(*source);
  if (script == NULL) {
    ALOGE("Out of memory when create Script object for '%s'! (output: %s)",
          pResName, output_path.c_str());
    delete source;
    return NULL;
  }

  script->setLinkRuntimeCallback(pLinkRuntimeCallback);

  // Read information from bitcode wrapper.
  bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
  script->setCompilerVersion(wrapper.getCompilerVersion());
  script->setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
                                   wrapper.getOptimizationLevel()));

  //===--------------------------------------------------------------------===//
  // Compile the script
  //===--------------------------------------------------------------------===//
  result = compileScript(*script, pResName, output_path.c_str(), pRuntimePath,
                         dep_info, false);

  // Script is no longer used. Free it to get more memory.
  delete script;

  if (result == NULL) {
    return NULL;
  }

  return result;
}


RSExecutable *RSCompilerDriver::build(RSScript &pScript, const char *pOut,
                                      const char *pRuntimePath) {
  RSInfo::DependencyTableTy dep_info;
  RSInfo *info = RSInfo::ExtractFromSource(pScript.getSource(), dep_info);
  if (info == NULL) {
    return NULL;
  }
  pScript.setInfo(info);

  // Embed the info string directly in the ELF, since this path is for an
  // offline (host) compilation.
  pScript.setEmbedInfo(true);

  RSExecutable *result = compileScript(pScript, pOut, pOut, pRuntimePath,
                                       dep_info, true);
  return result;
}

