/*
 * 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) {
  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;
  }

  // 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;
}

