10fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang/*
20fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Copyright 2012, The Android Open Source Project
30fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
40fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Licensed under the Apache License, Version 2.0 (the "License");
50fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * you may not use this file except in compliance with the License.
60fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * You may obtain a copy of the License at
70fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
80fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *     http://www.apache.org/licenses/LICENSE-2.0
90fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang *
100fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * Unless required by applicable law or agreed to in writing, software
110fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * distributed under the License is distributed on an "AS IS" BASIS,
120fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * See the License for the specific language governing permissions and
140fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang * limitations under the License.
150fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang */
160fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
17e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSCompilerDriver.h"
18c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang
197b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser#include <llvm/IR/Module.h>
20ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hines#include <llvm/Support/CommandLine.h>
21b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines#include <llvm/Support/Path.h>
227b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser#include <llvm/Support/raw_ostream.h>
237bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
247bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao#include "bcinfo/BitcodeWrapper.h"
257bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
2647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines#include "bcc/Compiler.h"
27bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines#include "bcc/Config/Config.h"
28e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSExecutable.h"
29f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet#include "bcc/Renderscript/RSInfo.h"
30e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines#include "bcc/Renderscript/RSScript.h"
31c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/CompilerConfig.h"
327bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao#include "bcc/Source.h"
33c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/FileMutex.h"
34ef73a242762bcd8113b9b65ceccbe7d909b5acbcZonr Chang#include "bcc/Support/Log.h"
35c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/InputFile.h"
36c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/Initialization.h"
377bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao#include "bcc/Support/Sha1Util.h"
38c72c4ddfcd79c74f70713da91a69569451b5c19eZonr Chang#include "bcc/Support/OutputFile.h"
390fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
40b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#ifdef HAVE_ANDROID_OS
410fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang#include <cutils/properties.h>
42b81d697ec617be24494b622a3532f1c465264415Nick Kralevich#endif
430fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang#include <utils/String8.h>
447bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao#include <utils/StopWatch.h>
450fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
460fffa7e4adc90079dc0f252359050fe872b360ddZonr Changusing namespace bcc;
470fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
48f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet// Get the build fingerprint of the Android device we are running on.
49f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouilletstatic std::string getBuildFingerPrint() {
50f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet#ifdef HAVE_ANDROID_OS
51f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    char fingerprint[PROPERTY_VALUE_MAX];
52f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    property_get("ro.build.fingerprint", fingerprint, "");
53f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    return fingerprint;
54f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet#else
55f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet    return "HostBuild";
56f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet#endif
57f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet}
58f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
593ab9da1e1b3d7794994393af086d096397fb84dbStephen HinesRSCompilerDriver::RSCompilerDriver(bool pUseCompilerRT) :
60b39557ea3f72e1854581aa1f859b2323499389b1Stephen Hines    mConfig(NULL), mCompiler(), mDebugContext(false),
61c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    mLinkRuntimeCallback(NULL), mEnableGlobalMerge(true) {
620fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  init::Initialize();
630fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
640fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
650fffa7e4adc90079dc0f252359050fe872b360ddZonr ChangRSCompilerDriver::~RSCompilerDriver() {
660fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  delete mConfig;
670fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
680fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
69f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc BrouilletRSExecutable* RSCompilerDriver::loadScript(const char* pCacheDir, const char* pResName,
70f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                           const char* pBitcode, size_t pBitcodeSize,
71f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                           const char* expectedCompileCommandLine,
72f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                           SymbolResolverProxy& pResolver) {
73f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // android::StopWatch load_time("bcc: RSCompilerDriver::loadScript time");
7447f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  if ((pCacheDir == NULL) || (pResName == NULL)) {
7547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    ALOGE("Missing pCacheDir and/or pResName");
7647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return NULL;
7747f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  }
7847f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines
7947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
8047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %zu)",
8147f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines          pBitcode, pBitcodeSize);
8247f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return NULL;
8347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  }
8447f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines
8547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  // {pCacheDir}/{pResName}.o
86b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::SmallString<80> output_path(pCacheDir);
87b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::sys::path::append(output_path, pResName);
88b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::sys::path::replace_extension(output_path, ".o");
890fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
900fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
9101f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  // Acquire the read lock for reading the Script object file.
920fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
9347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  FileMutex<FileBase::kReadLock> read_output_mutex(output_path.c_str());
940fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
950fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  if (read_output_mutex.hasError() || !read_output_mutex.lock()) {
9647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    ALOGE("Unable to acquire the read lock for %s! (%s)", output_path.c_str(),
970fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang          read_output_mutex.getErrorMessage().c_str());
980fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    return NULL;
990fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
1000fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
1010fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
1020fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Read the output object file.
1030fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
10447f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  InputFile *object_file = new (std::nothrow) InputFile(output_path.c_str());
1050fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
10601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  if ((object_file == NULL) || object_file->hasError()) {
10747f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      //      ALOGE("Unable to open the %s for read! (%s)", output_path.c_str(),
10801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      //            object_file->getErrorMessage().c_str());
10901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    delete object_file;
1100fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    return NULL;
1110fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
1120fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
1130fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
11401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  // Acquire the read lock on object_file for reading its RS info file.
1150fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
11647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  android::String8 info_path = RSInfo::GetPath(output_path.c_str());
1170fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
11801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  if (!object_file->lock()) {
1190fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    ALOGE("Unable to acquire the read lock on %s for reading %s! (%s)",
12047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines          output_path.c_str(), info_path.string(),
12101f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines          object_file->getErrorMessage().c_str());
12201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    delete object_file;
1230fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    return NULL;
1240fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
1250fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
126f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  //===---------------------------------------------------------------------===//
1270fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Open and load the RS info file.
1280fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
1290fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  InputFile info_file(info_path.string());
130c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  RSInfo *info = RSInfo::ReadFromFile(info_file);
1310fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
13201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  // Release the lock on object_file.
13301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  object_file->unlock();
1340fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
1350fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  if (info == NULL) {
13601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    delete object_file;
1370fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    return NULL;
1380fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
1390fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
140f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  //===---------------------------------------------------------------------===//
141f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // Check that the info in the RS info file is consistent we what we want.
142f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  //===--------------------------------------------------------------------===//
143f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
144f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  uint8_t expectedSourceHash[SHA1_DIGEST_LENGTH];
145f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  Sha1Util::GetSHA1DigestFromBuffer(expectedSourceHash, pBitcode, pBitcodeSize);
146f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
147f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  std::string expectedBuildFingerprint = getBuildFingerPrint();
148f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
149f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // If the info file contains different hash for the source than what we are
150f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // looking for, bail.  Do the same if the command line used when compiling or the
151f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // build fingerprint of Android has changed.  The compiled code found on disk is
152f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // out of date and needs to be recompiled first.
153f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  if (!info->IsConsistent(output_path.c_str(), expectedSourceHash, expectedCompileCommandLine,
154f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                          expectedBuildFingerprint.c_str())) {
155f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet      delete object_file;
156f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet      delete info;
157f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet      return NULL;
158c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  }
159c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet
1600fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
1610fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Create the RSExecutable.
1620fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
163f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  RSExecutable *executable = RSExecutable::Create(*info, *object_file, pResolver);
164f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  if (executable == NULL) {
16501f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    delete object_file;
1660fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    delete info;
1670fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    return NULL;
1680fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
1690fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
170f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  return executable;
1710fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
1720fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
173bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines#if defined(PROVIDE_ARM_CODEGEN)
174ad69476ec040ba9ee07176ccb758aabb5ff6d51cStephen Hinesextern llvm::cl::opt<bool> EnableGlobalMerge;
175c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines#endif
176c06cd06078a8c866d5cecbf897326092b55a8955Stephen Hines
1770fffa7e4adc90079dc0f252359050fe872b360ddZonr Changbool RSCompilerDriver::setupConfig(const RSScript &pScript) {
1780fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  bool changed = false;
1790fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
1800fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  const llvm::CodeGenOpt::Level script_opt_level =
1810fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang      static_cast<llvm::CodeGenOpt::Level>(pScript.getOptimizationLevel());
1820fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
183bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines#if defined(PROVIDE_ARM_CODEGEN)
184045558bd401d0af58a0b57594d75d45ff3035dc9Stephen Hines  EnableGlobalMerge = mEnableGlobalMerge;
185045558bd401d0af58a0b57594d75d45ff3035dc9Stephen Hines#endif
186045558bd401d0af58a0b57594d75d45ff3035dc9Stephen Hines
1870fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  if (mConfig != NULL) {
1880fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    // Renderscript bitcode may have their optimization flag configuration
1890fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    // different than the previous run of RS compilation.
1900fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    if (mConfig->getOptimizationLevel() != script_opt_level) {
1910fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang      mConfig->setOptimizationLevel(script_opt_level);
1920fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang      changed = true;
1930fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    }
1940fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  } else {
1950fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    // Haven't run the compiler ever.
196bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines    mConfig = new (std::nothrow) CompilerConfig(DEFAULT_TARGET_TRIPLE_STRING);
1970fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    if (mConfig == NULL) {
1980fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang      // Return false since mConfig remains NULL and out-of-memory.
1990fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang      return false;
2000fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    }
2010fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    mConfig->setOptimizationLevel(script_opt_level);
2020fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    changed = true;
2030fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
2040fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
205bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines#if defined(PROVIDE_ARM_CODEGEN)
2060fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  assert((pScript.getInfo() != NULL) && "NULL RS info!");
207bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines  bool script_full_prec = (pScript.getInfo()->getFloatPrecisionRequirement() ==
208bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines                           RSInfo::FP_Full);
209bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines  if (mConfig->getFullPrecision() != script_full_prec) {
210bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines    mConfig->setFullPrecision(script_full_prec);
211bde1a2599780d6eaebbc284976ceb690492f6abdStephen Hines    changed = true;
2120fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
2130fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang#endif
2140fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
2150fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  return changed;
2160fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
2170fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
218f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc BrouilletCompiler::ErrorCode RSCompilerDriver::compileScript(RSScript& pScript, const char* pScriptName,
219f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                                    const char* pOutputPath,
220f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                                    const char* pRuntimePath,
221f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                                    const RSInfo::DependencyHashTy& pSourceHash,
222f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                                    const char* compileCommandLineToEmbed,
223f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                                    bool saveInfoFile, bool pDumpIR) {
224f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
2250fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  RSInfo *info = NULL;
2260fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
2270fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
2280fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Extract RS-specific information from source bitcode.
2290fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
2300fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // RS info may contains configuration (such as #optimization_level) to the
2310fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // compiler therefore it should be extracted before compilation.
232f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  info = RSInfo::ExtractFromSource(pScript.getSource(), pSourceHash, compileCommandLineToEmbed,
233f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                   getBuildFingerPrint().c_str());
2340fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  if (info == NULL) {
23547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return Compiler::kErrInvalidSource;
2360fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
2370fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
2380fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
2390fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // Associate script with its info
2400fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
2410fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // This is required since RS compiler may need information in the info file
2420fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  // to do some transformation (e.g., expand foreach-able function.)
2430fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  pScript.setInfo(info);
2440fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
2450fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  //===--------------------------------------------------------------------===//
246e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines  // Link RS script with Renderscript runtime.
247ba4206445e192f4c0fa519eae55c4b84cfb0efeeShih-wei Liao  //===--------------------------------------------------------------------===//
248331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (!RSScript::LinkRuntime(pScript, pRuntimePath)) {
249e198abec6c5e3eab380ccf6897b0a0b9c2dd92ddStephen Hines    ALOGE("Failed to link script '%s' with Renderscript runtime!", pScriptName);
25047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return Compiler::kErrInvalidSource;
251ba4206445e192f4c0fa519eae55c4b84cfb0efeeShih-wei Liao  }
252ba4206445e192f4c0fa519eae55c4b84cfb0efeeShih-wei Liao
25301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines  {
2540784365a38fd5a9c08dd484f9ba549328d4dff97Stephen Hines    // FIXME(srhines): Windows compilation can't use locking like this, but
2550784365a38fd5a9c08dd484f9ba549328d4dff97Stephen Hines    // we also don't need to worry about concurrent writers of the same file.
256d7a95265621a788a6de8c0c3a27a588d7c466f79Stephen Hines#ifndef USE_MINGW
2570784365a38fd5a9c08dd484f9ba549328d4dff97Stephen Hines    //===------------------------------------------------------------------===//
25801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    // Acquire the write lock for writing output object file.
2590784365a38fd5a9c08dd484f9ba549328d4dff97Stephen Hines    //===------------------------------------------------------------------===//
26001f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    FileMutex<FileBase::kWriteLock> write_output_mutex(pOutputPath);
2610fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
26201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (write_output_mutex.hasError() || !write_output_mutex.lock()) {
26301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Unable to acquire the lock for writing %s! (%s)",
26401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines            pOutputPath, write_output_mutex.getErrorMessage().c_str());
26547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
26601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
267d7a95265621a788a6de8c0c3a27a588d7c466f79Stephen Hines#endif
2680fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
26901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    // Open the output file for write.
270acf9c9eeb5a07535dbed5b272c7f22cc1b050a40Stephen Hines    OutputFile output_file(pOutputPath,
271acf9c9eeb5a07535dbed5b272c7f22cc1b050a40Stephen Hines                           FileBase::kTruncate | FileBase::kBinary);
2720fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
27301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (output_file.hasError()) {
27401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines        ALOGE("Unable to open %s for write! (%s)", pOutputPath,
27501f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines              output_file.getErrorMessage().c_str());
27647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
27701f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
2780fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
27901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    // Setup the config to the compiler.
28001f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    bool compiler_need_reconfigure = setupConfig(pScript);
2810fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
28201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (mConfig == NULL) {
28301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Failed to setup config for RS compiler to compile %s!",
28401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines            pOutputPath);
28547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
2860fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang    }
2870fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
28801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (compiler_need_reconfigure) {
28901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      Compiler::ErrorCode err = mCompiler.config(*mConfig);
29001f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      if (err != Compiler::kSuccess) {
29101f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines        ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath,
29201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines              Compiler::GetErrorString(err));
29347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines        return Compiler::kErrInvalidSource;
29401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      }
29501f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
29601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines
29727fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    OutputFile *ir_file = NULL;
29827fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    llvm::raw_fd_ostream *IRStream = NULL;
29927fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    if (pDumpIR) {
30027fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      android::String8 path(pOutputPath);
30127fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      path.append(".ll");
30227fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      ir_file = new OutputFile(path.string(), FileBase::kTruncate);
30327fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      IRStream = ir_file->dup();
30427fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    }
30527fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser
30601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    // Run the compiler.
30727fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    Compiler::ErrorCode compile_result = mCompiler.compile(pScript,
30827fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser                                                           output_file, IRStream);
30927fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser
31027fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    if (ir_file) {
31127fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      ir_file->close();
31227fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser      delete ir_file;
31327fb7edfd3f53f52fba6ee81267c02f7896198a3Tobias Grosser    }
31401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines
31501f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (compile_result != Compiler::kSuccess) {
31601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath,
31701f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines            Compiler::GetErrorString(compile_result));
31847f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
31901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
3200fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
3210fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
322f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  if (saveInfoFile) {
32301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    android::String8 info_path = RSInfo::GetPath(pOutputPath);
32401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    OutputFile info_file(info_path.string(), FileBase::kTruncate);
3250fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
32601f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (info_file.hasError()) {
32701f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Failed to open the info file %s for write! (%s)",
32801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines            info_path.string(), info_file.getErrorMessage().c_str());
32947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
33001f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
3316d01af642a7cacdbd483f0c57e9f17cdeaaa98d6Shih-wei Liao
33201f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    FileMutex<FileBase::kWriteLock> write_info_mutex(info_path.string());
33301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (write_info_mutex.hasError() || !write_info_mutex.lock()) {
33401f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Unable to acquire the lock for writing %s! (%s)",
33501f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines            info_path.string(), write_info_mutex.getErrorMessage().c_str());
33647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
33701f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
33801f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines
33901f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    // Perform the write.
34001f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    if (!info->write(info_file)) {
34101f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines      ALOGE("Failed to sync the RS info file %s!", info_path.string());
34247f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines      return Compiler::kErrInvalidSource;
34301f05d4b45cbde1e07d4707152908c1d843f1328Stephen Hines    }
3440fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang  }
3450fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
34647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  return Compiler::kSuccess;
3470fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
3480fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang
34947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hinesbool RSCompilerDriver::build(BCCContext &pContext,
35047f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                             const char *pCacheDir,
35147f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                             const char *pResName,
35247f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                             const char *pBitcode,
35347f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                             size_t pBitcodeSize,
354f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                             const char *commandLine,
35547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                             const char *pRuntimePath,
3567b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser                             RSLinkRuntimeCallback pLinkRuntimeCallback,
3577b980e1717f3cf418f7bc4e40597004bc1139b8bTobias Grosser                             bool pDumpIR) {
358c89f78b40e7823eb2d08e7129794c9f6f1992c08Tim Murray    //  android::StopWatch build_time("bcc: RSCompilerDriver::build time");
3597bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3607bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Check parameters.
3617bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3627bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  if ((pCacheDir == NULL) || (pResName == NULL)) {
3637bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao    ALOGE("Invalid parameter passed to RSCompilerDriver::build()! (cache dir: "
3647bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao          "%s, resource name: %s)", ((pCacheDir) ? pCacheDir : "(null)"),
3657bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao                                    ((pResName) ? pResName : "(null)"));
36647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return false;
3677bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  }
3687bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
3697bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
3707bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao    ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %u)",
3717bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao          pBitcode, static_cast<unsigned>(pBitcodeSize));
37247f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return false;
3737bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  }
3747bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
3757bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3767bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Prepare dependency information.
3777bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
378c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet  uint8_t bitcode_sha1[SHA1_DIGEST_LENGTH];
3797bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
3807bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
3817bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3827bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Construct output path.
3837bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // {pCacheDir}/{pResName}.o
384b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  //===--------------------------------------------------------------------===//
385b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::SmallString<80> output_path(pCacheDir);
386b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::sys::path::append(output_path, pResName);
387b10c3a7d91556ef31ce91ef018fee4722b783960Stephen Hines  llvm::sys::path::replace_extension(output_path, ".o");
3887bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
3897bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3907bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Load the bitcode and create script.
3917bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
3927bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  Source *source = Source::CreateFromBuffer(pContext, pResName,
3937bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao                                            pBitcode, pBitcodeSize);
3947bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  if (source == NULL) {
39547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return false;
3967bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  }
3977bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
398f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  RSScript script(*source);
399c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  if (pLinkRuntimeCallback) {
400c3437f05c638f8befda59170ae788873db24dc1cStephen Hines    setLinkRuntimeCallback(pLinkRuntimeCallback);
401c3437f05c638f8befda59170ae788873db24dc1cStephen Hines  }
4027bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
403f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  script.setLinkRuntimeCallback(getLinkRuntimeCallback());
40406731a6150ae8014d37258d5f32ef8bc14a3db63Stephen Hines
4057bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Read information from bitcode wrapper.
4067bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
407f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  script.setCompilerVersion(wrapper.getCompilerVersion());
408f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  script.setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
409f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                              wrapper.getOptimizationLevel()));
4107bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
4117bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
4127bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  // Compile the script
4137bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao  //===--------------------------------------------------------------------===//
414f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  Compiler::ErrorCode status = compileScript(script, pResName,
41547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines                                             output_path.c_str(),
416f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                             pRuntimePath, bitcode_sha1, commandLine,
417f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                             true, pDumpIR);
4187bcec85228c1eceade6efc9cd7d02ef81c8d55e9Shih-wei Liao
419f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  return status == Compiler::kSuccess;
4200fffa7e4adc90079dc0f252359050fe872b360ddZonr Chang}
421331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
422331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
423c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouilletbool RSCompilerDriver::buildForCompatLib(RSScript &pScript, const char *pOut,
424c5e607adff80a66bc5420baffd299862abdf368dJean-Luc Brouillet                                         const char *pRuntimePath) {
425f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // For compat lib, we don't check the RS info file so we don't need the source hash,
426f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // compile command, and build fingerprint.
427f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  // TODO We may want to make them optional or embed real values.
428f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  uint8_t bitcode_sha1[SHA1_DIGEST_LENGTH] = {0};
429f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  const char* compileCommandLineToEmbed = "";
430f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  const char* buildFingerprintToEmbed = "";
431f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet
432f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  RSInfo* info = RSInfo::ExtractFromSource(pScript.getSource(), bitcode_sha1,
433f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                           compileCommandLineToEmbed, buildFingerprintToEmbed);
434331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  if (info == NULL) {
43547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return false;
436331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  }
437331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines  pScript.setInfo(info);
438331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
43986a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  // Embed the info string directly in the ELF, since this path is for an
44086a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  // offline (host) compilation.
44186a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines  pScript.setEmbedInfo(true);
44286a0b797c221d4c3373dc10c8229b75b6747f6e7Stephen Hines
443f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet  Compiler::ErrorCode status = compileScript(pScript, pOut, pOut, pRuntimePath, bitcode_sha1,
444f2ac3176c351cd80bce77fe1488f3de2d0789c1bJean-Luc Brouillet                                             compileCommandLineToEmbed, false, false);
44547f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  if (status != Compiler::kSuccess) {
44647f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines    return false;
44747f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  }
44847f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines
44947f0d5a8d9ed629a6d58d3e69891f2c7fdee44d9Stephen Hines  return true;
450331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines}
451331310e1f3f86a795f78e42b3f03558a43829f09Stephen Hines
452