blob: 9ae2e036627850348f8934ff6c9245edc13380d5 [file] [log] [blame]
Zonr Chang0fffa7e2012-04-12 19:43:53 +08001/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Chris Wailes35978e72014-08-11 14:01:47 -070017#include <string>
18
Stephen Hinese198abe2012-07-27 18:05:41 -070019#include "bcc/Renderscript/RSCompilerDriver.h"
Zonr Chang0fffa7e2012-04-12 19:43:53 +080020
Tobias Grosser7b980e12013-06-20 10:12:13 -070021#include <llvm/IR/Module.h>
Stephen Hinesad694762013-04-29 18:59:47 -070022#include <llvm/Support/CommandLine.h>
Stephen Hinesb10c3a72013-08-07 23:15:22 -070023#include <llvm/Support/Path.h>
Tobias Grosser7b980e12013-06-20 10:12:13 -070024#include <llvm/Support/raw_ostream.h>
Shih-wei Liao7bcec852012-04-25 04:07:09 -070025
26#include "bcinfo/BitcodeWrapper.h"
27
Stephen Hines47f0d5a2013-06-05 00:27:38 -070028#include "bcc/Compiler.h"
Stephen Hinesbde1a252014-05-15 18:02:33 -070029#include "bcc/Config/Config.h"
Stephen Hinese198abe2012-07-27 18:05:41 -070030#include "bcc/Renderscript/RSExecutable.h"
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -070031#include "bcc/Renderscript/RSInfo.h"
Stephen Hinese198abe2012-07-27 18:05:41 -070032#include "bcc/Renderscript/RSScript.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080033#include "bcc/Support/CompilerConfig.h"
Shih-wei Liao7bcec852012-04-25 04:07:09 -070034#include "bcc/Source.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080035#include "bcc/Support/FileMutex.h"
Zonr Changef73a242012-04-12 16:44:01 +080036#include "bcc/Support/Log.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080037#include "bcc/Support/InputFile.h"
38#include "bcc/Support/Initialization.h"
Shih-wei Liao7bcec852012-04-25 04:07:09 -070039#include "bcc/Support/Sha1Util.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080040#include "bcc/Support/OutputFile.h"
Zonr Chang0fffa7e2012-04-12 19:43:53 +080041
Nick Kralevichb81d6972013-05-21 16:52:35 -070042#ifdef HAVE_ANDROID_OS
Zonr Chang0fffa7e2012-04-12 19:43:53 +080043#include <cutils/properties.h>
Nick Kralevichb81d6972013-05-21 16:52:35 -070044#endif
Shih-wei Liao7bcec852012-04-25 04:07:09 -070045#include <utils/StopWatch.h>
Zonr Chang0fffa7e2012-04-12 19:43:53 +080046
47using namespace bcc;
48
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -070049// Get the build fingerprint of the Android device we are running on.
50static std::string getBuildFingerPrint() {
51#ifdef HAVE_ANDROID_OS
52 char fingerprint[PROPERTY_VALUE_MAX];
53 property_get("ro.build.fingerprint", fingerprint, "");
54 return fingerprint;
55#else
56 return "HostBuild";
57#endif
58}
59
Stephen Hines3ab9da12013-02-01 18:39:15 -080060RSCompilerDriver::RSCompilerDriver(bool pUseCompilerRT) :
Chris Wailes900c6c12014-08-13 15:40:00 -070061 mConfig(nullptr), mCompiler(), mDebugContext(false),
62 mLinkRuntimeCallback(nullptr), mEnableGlobalMerge(true) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +080063 init::Initialize();
Zonr Chang0fffa7e2012-04-12 19:43:53 +080064}
65
66RSCompilerDriver::~RSCompilerDriver() {
67 delete mConfig;
68}
69
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -070070RSExecutable* RSCompilerDriver::loadScript(const char* pCacheDir, const char* pResName,
71 const char* pBitcode, size_t pBitcodeSize,
72 const char* expectedCompileCommandLine,
73 SymbolResolverProxy& pResolver) {
74 // android::StopWatch load_time("bcc: RSCompilerDriver::loadScript time");
Chris Wailes900c6c12014-08-13 15:40:00 -070075 if ((pCacheDir == nullptr) || (pResName == nullptr)) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -070076 ALOGE("Missing pCacheDir and/or pResName");
Chris Wailes900c6c12014-08-13 15:40:00 -070077 return nullptr;
Stephen Hines47f0d5a2013-06-05 00:27:38 -070078 }
79
Chris Wailes900c6c12014-08-13 15:40:00 -070080 if ((pBitcode == nullptr) || (pBitcodeSize <= 0)) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -070081 ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %zu)",
82 pBitcode, pBitcodeSize);
Chris Wailes900c6c12014-08-13 15:40:00 -070083 return nullptr;
Stephen Hines47f0d5a2013-06-05 00:27:38 -070084 }
85
Stephen Hines47f0d5a2013-06-05 00:27:38 -070086 // {pCacheDir}/{pResName}.o
Stephen Hinesb10c3a72013-08-07 23:15:22 -070087 llvm::SmallString<80> output_path(pCacheDir);
88 llvm::sys::path::append(output_path, pResName);
89 llvm::sys::path::replace_extension(output_path, ".o");
Zonr Chang0fffa7e2012-04-12 19:43:53 +080090
Zonr Chang0fffa7e2012-04-12 19:43:53 +080091 //===--------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -070092 // Acquire the read lock for reading the Script object file.
Zonr Chang0fffa7e2012-04-12 19:43:53 +080093 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -070094 FileMutex<FileBase::kReadLock> read_output_mutex(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +080095
96 if (read_output_mutex.hasError() || !read_output_mutex.lock()) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -070097 ALOGE("Unable to acquire the read lock for %s! (%s)", output_path.c_str(),
Zonr Chang0fffa7e2012-04-12 19:43:53 +080098 read_output_mutex.getErrorMessage().c_str());
Chris Wailes900c6c12014-08-13 15:40:00 -070099 return nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800100 }
101
102 //===--------------------------------------------------------------------===//
103 // Read the output object file.
104 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700105 InputFile *object_file = new (std::nothrow) InputFile(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800106
Chris Wailes900c6c12014-08-13 15:40:00 -0700107 if ((object_file == nullptr) || object_file->hasError()) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700108 // ALOGE("Unable to open the %s for read! (%s)", output_path.c_str(),
Stephen Hines01f05d42013-05-31 20:51:27 -0700109 // object_file->getErrorMessage().c_str());
110 delete object_file;
Chris Wailes900c6c12014-08-13 15:40:00 -0700111 return nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800112 }
113
114 //===--------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700115 // Acquire the read lock on object_file for reading its RS info file.
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800116 //===--------------------------------------------------------------------===//
Chris Wailes35978e72014-08-11 14:01:47 -0700117 std::string info_path = RSInfo::GetPath(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800118
Stephen Hines01f05d42013-05-31 20:51:27 -0700119 if (!object_file->lock()) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800120 ALOGE("Unable to acquire the read lock on %s for reading %s! (%s)",
Chris Wailes35978e72014-08-11 14:01:47 -0700121 output_path.c_str(), info_path.c_str(),
Stephen Hines01f05d42013-05-31 20:51:27 -0700122 object_file->getErrorMessage().c_str());
123 delete object_file;
Chris Wailes900c6c12014-08-13 15:40:00 -0700124 return nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800125 }
126
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700127 //===---------------------------------------------------------------------===//
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800128 // Open and load the RS info file.
129 //===--------------------------------------------------------------------===//
Chris Wailes35978e72014-08-11 14:01:47 -0700130 InputFile info_file(info_path.c_str());
Jean-Luc Brouilletc5e607a2014-06-18 18:14:02 -0700131 RSInfo *info = RSInfo::ReadFromFile(info_file);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800132
Stephen Hines01f05d42013-05-31 20:51:27 -0700133 // Release the lock on object_file.
134 object_file->unlock();
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800135
Chris Wailes900c6c12014-08-13 15:40:00 -0700136 if (info == nullptr) {
Stephen Hines01f05d42013-05-31 20:51:27 -0700137 delete object_file;
Chris Wailes900c6c12014-08-13 15:40:00 -0700138 return nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800139 }
140
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700141 //===---------------------------------------------------------------------===//
142 // Check that the info in the RS info file is consistent we what we want.
143 //===--------------------------------------------------------------------===//
144
145 uint8_t expectedSourceHash[SHA1_DIGEST_LENGTH];
146 Sha1Util::GetSHA1DigestFromBuffer(expectedSourceHash, pBitcode, pBitcodeSize);
147
148 std::string expectedBuildFingerprint = getBuildFingerPrint();
149
150 // If the info file contains different hash for the source than what we are
151 // looking for, bail. Do the same if the command line used when compiling or the
152 // build fingerprint of Android has changed. The compiled code found on disk is
153 // out of date and needs to be recompiled first.
154 if (!info->IsConsistent(output_path.c_str(), expectedSourceHash, expectedCompileCommandLine,
155 expectedBuildFingerprint.c_str())) {
156 delete object_file;
157 delete info;
Chris Wailes900c6c12014-08-13 15:40:00 -0700158 return nullptr;
Jean-Luc Brouilletc5e607a2014-06-18 18:14:02 -0700159 }
160
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800161 //===--------------------------------------------------------------------===//
162 // Create the RSExecutable.
163 //===--------------------------------------------------------------------===//
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700164 RSExecutable *executable = RSExecutable::Create(*info, *object_file, pResolver);
Chris Wailes900c6c12014-08-13 15:40:00 -0700165 if (executable == nullptr) {
Stephen Hines01f05d42013-05-31 20:51:27 -0700166 delete object_file;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800167 delete info;
Chris Wailes900c6c12014-08-13 15:40:00 -0700168 return nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800169 }
170
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700171 return executable;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800172}
173
Stephen Hinesbde1a252014-05-15 18:02:33 -0700174#if defined(PROVIDE_ARM_CODEGEN)
Stephen Hinesad694762013-04-29 18:59:47 -0700175extern llvm::cl::opt<bool> EnableGlobalMerge;
Stephen Hinesc06cd062013-07-12 10:51:29 -0700176#endif
177
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800178bool RSCompilerDriver::setupConfig(const RSScript &pScript) {
179 bool changed = false;
180
181 const llvm::CodeGenOpt::Level script_opt_level =
182 static_cast<llvm::CodeGenOpt::Level>(pScript.getOptimizationLevel());
183
Stephen Hinesbde1a252014-05-15 18:02:33 -0700184#if defined(PROVIDE_ARM_CODEGEN)
Stephen Hines045558b2014-02-18 14:07:15 -0800185 EnableGlobalMerge = mEnableGlobalMerge;
186#endif
187
Chris Wailes900c6c12014-08-13 15:40:00 -0700188 if (mConfig != nullptr) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800189 // Renderscript bitcode may have their optimization flag configuration
190 // different than the previous run of RS compilation.
191 if (mConfig->getOptimizationLevel() != script_opt_level) {
192 mConfig->setOptimizationLevel(script_opt_level);
193 changed = true;
194 }
195 } else {
196 // Haven't run the compiler ever.
Stephen Hinesbde1a252014-05-15 18:02:33 -0700197 mConfig = new (std::nothrow) CompilerConfig(DEFAULT_TARGET_TRIPLE_STRING);
Chris Wailes900c6c12014-08-13 15:40:00 -0700198 if (mConfig == nullptr) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800199 // Return false since mConfig remains NULL and out-of-memory.
200 return false;
201 }
202 mConfig->setOptimizationLevel(script_opt_level);
203 changed = true;
204 }
205
Stephen Hinesbde1a252014-05-15 18:02:33 -0700206#if defined(PROVIDE_ARM_CODEGEN)
Chris Wailes900c6c12014-08-13 15:40:00 -0700207 assert((pScript.getInfo() != nullptr) && "NULL RS info!");
Stephen Hinesbde1a252014-05-15 18:02:33 -0700208 bool script_full_prec = (pScript.getInfo()->getFloatPrecisionRequirement() ==
209 RSInfo::FP_Full);
210 if (mConfig->getFullPrecision() != script_full_prec) {
211 mConfig->setFullPrecision(script_full_prec);
212 changed = true;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800213 }
214#endif
215
216 return changed;
217}
218
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700219Compiler::ErrorCode RSCompilerDriver::compileScript(RSScript& pScript, const char* pScriptName,
220 const char* pOutputPath,
221 const char* pRuntimePath,
222 const RSInfo::DependencyHashTy& pSourceHash,
223 const char* compileCommandLineToEmbed,
224 bool saveInfoFile, bool pDumpIR) {
225 // android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
Chris Wailes900c6c12014-08-13 15:40:00 -0700226 RSInfo *info = nullptr;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800227
228 //===--------------------------------------------------------------------===//
229 // Extract RS-specific information from source bitcode.
230 //===--------------------------------------------------------------------===//
231 // RS info may contains configuration (such as #optimization_level) to the
232 // compiler therefore it should be extracted before compilation.
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700233 info = RSInfo::ExtractFromSource(pScript.getSource(), pSourceHash, compileCommandLineToEmbed,
234 getBuildFingerPrint().c_str());
Chris Wailes900c6c12014-08-13 15:40:00 -0700235 if (info == nullptr) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700236 return Compiler::kErrInvalidSource;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800237 }
238
239 //===--------------------------------------------------------------------===//
240 // Associate script with its info
241 //===--------------------------------------------------------------------===//
242 // This is required since RS compiler may need information in the info file
243 // to do some transformation (e.g., expand foreach-able function.)
244 pScript.setInfo(info);
245
246 //===--------------------------------------------------------------------===//
Stephen Hinese198abe2012-07-27 18:05:41 -0700247 // Link RS script with Renderscript runtime.
Shih-wei Liaoba420642012-06-30 11:27:37 -0700248 //===--------------------------------------------------------------------===//
Stephen Hines331310e2012-10-26 19:27:55 -0700249 if (!RSScript::LinkRuntime(pScript, pRuntimePath)) {
Stephen Hinese198abe2012-07-27 18:05:41 -0700250 ALOGE("Failed to link script '%s' with Renderscript runtime!", pScriptName);
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700251 return Compiler::kErrInvalidSource;
Shih-wei Liaoba420642012-06-30 11:27:37 -0700252 }
253
Stephen Hines01f05d42013-05-31 20:51:27 -0700254 {
Stephen Hines07843652013-08-15 15:41:47 -0700255 // FIXME(srhines): Windows compilation can't use locking like this, but
256 // we also don't need to worry about concurrent writers of the same file.
Stephen Hinesd7a95262013-08-08 16:03:19 -0700257#ifndef USE_MINGW
Stephen Hines07843652013-08-15 15:41:47 -0700258 //===------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700259 // Acquire the write lock for writing output object file.
Stephen Hines07843652013-08-15 15:41:47 -0700260 //===------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700261 FileMutex<FileBase::kWriteLock> write_output_mutex(pOutputPath);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800262
Stephen Hines01f05d42013-05-31 20:51:27 -0700263 if (write_output_mutex.hasError() || !write_output_mutex.lock()) {
264 ALOGE("Unable to acquire the lock for writing %s! (%s)",
265 pOutputPath, write_output_mutex.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700266 return Compiler::kErrInvalidSource;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800267 }
Stephen Hinesd7a95262013-08-08 16:03:19 -0700268#endif
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800269
Stephen Hines01f05d42013-05-31 20:51:27 -0700270 // Open the output file for write.
Stephen Hinesacf9c9e2013-09-26 16:32:31 -0700271 OutputFile output_file(pOutputPath,
272 FileBase::kTruncate | FileBase::kBinary);
Stephen Hines01f05d42013-05-31 20:51:27 -0700273
274 if (output_file.hasError()) {
275 ALOGE("Unable to open %s for write! (%s)", pOutputPath,
276 output_file.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700277 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700278 }
279
280 // Setup the config to the compiler.
281 bool compiler_need_reconfigure = setupConfig(pScript);
282
Chris Wailes900c6c12014-08-13 15:40:00 -0700283 if (mConfig == nullptr) {
Stephen Hines01f05d42013-05-31 20:51:27 -0700284 ALOGE("Failed to setup config for RS compiler to compile %s!",
285 pOutputPath);
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700286 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700287 }
288
289 if (compiler_need_reconfigure) {
290 Compiler::ErrorCode err = mCompiler.config(*mConfig);
291 if (err != Compiler::kSuccess) {
292 ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath,
293 Compiler::GetErrorString(err));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700294 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700295 }
296 }
297
Chris Wailes900c6c12014-08-13 15:40:00 -0700298 OutputFile *ir_file = nullptr;
299 llvm::raw_fd_ostream *IRStream = nullptr;
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700300 if (pDumpIR) {
Chris Wailes35978e72014-08-11 14:01:47 -0700301 std::string path(pOutputPath);
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700302 path.append(".ll");
Chris Wailes35978e72014-08-11 14:01:47 -0700303 ir_file = new OutputFile(path.c_str(), FileBase::kTruncate);
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700304 IRStream = ir_file->dup();
305 }
306
Stephen Hines01f05d42013-05-31 20:51:27 -0700307 // Run the compiler.
Chris Wailes35978e72014-08-11 14:01:47 -0700308 Compiler::ErrorCode compile_result =
309 mCompiler.compile(pScript, output_file, IRStream);
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700310
311 if (ir_file) {
312 ir_file->close();
313 delete ir_file;
314 }
Stephen Hines01f05d42013-05-31 20:51:27 -0700315
316 if (compile_result != Compiler::kSuccess) {
317 ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath,
318 Compiler::GetErrorString(compile_result));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700319 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700320 }
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800321 }
322
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700323 if (saveInfoFile) {
Chris Wailes35978e72014-08-11 14:01:47 -0700324 std::string info_path = RSInfo::GetPath(pOutputPath);
325 OutputFile info_file(info_path.c_str(), FileBase::kTruncate);
Stephen Hines01f05d42013-05-31 20:51:27 -0700326
327 if (info_file.hasError()) {
328 ALOGE("Failed to open the info file %s for write! (%s)",
Chris Wailes35978e72014-08-11 14:01:47 -0700329 info_path.c_str(), info_file.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700330 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700331 }
332
Chris Wailes35978e72014-08-11 14:01:47 -0700333 FileMutex<FileBase::kWriteLock> write_info_mutex(info_path.c_str());
Stephen Hines01f05d42013-05-31 20:51:27 -0700334 if (write_info_mutex.hasError() || !write_info_mutex.lock()) {
335 ALOGE("Unable to acquire the lock for writing %s! (%s)",
Chris Wailes35978e72014-08-11 14:01:47 -0700336 info_path.c_str(), write_info_mutex.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700337 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700338 }
339
340 // Perform the write.
341 if (!info->write(info_file)) {
Chris Wailes35978e72014-08-11 14:01:47 -0700342 ALOGE("Failed to sync the RS info file %s!", info_path.c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700343 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700344 }
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800345 }
346
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700347 return Compiler::kSuccess;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800348}
349
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700350bool RSCompilerDriver::build(BCCContext &pContext,
351 const char *pCacheDir,
352 const char *pResName,
353 const char *pBitcode,
354 size_t pBitcodeSize,
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700355 const char *commandLine,
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700356 const char *pRuntimePath,
Tobias Grosser7b980e12013-06-20 10:12:13 -0700357 RSLinkRuntimeCallback pLinkRuntimeCallback,
358 bool pDumpIR) {
Tim Murrayc89f78b2013-05-09 11:57:12 -0700359 // android::StopWatch build_time("bcc: RSCompilerDriver::build time");
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700360 //===--------------------------------------------------------------------===//
361 // Check parameters.
362 //===--------------------------------------------------------------------===//
Chris Wailes900c6c12014-08-13 15:40:00 -0700363 if ((pCacheDir == nullptr) || (pResName == nullptr)) {
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700364 ALOGE("Invalid parameter passed to RSCompilerDriver::build()! (cache dir: "
365 "%s, resource name: %s)", ((pCacheDir) ? pCacheDir : "(null)"),
366 ((pResName) ? pResName : "(null)"));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700367 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700368 }
369
Chris Wailes900c6c12014-08-13 15:40:00 -0700370 if ((pBitcode == nullptr) || (pBitcodeSize <= 0)) {
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700371 ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %u)",
372 pBitcode, static_cast<unsigned>(pBitcodeSize));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700373 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700374 }
375
376 //===--------------------------------------------------------------------===//
377 // Prepare dependency information.
378 //===--------------------------------------------------------------------===//
Jean-Luc Brouilletc5e607a2014-06-18 18:14:02 -0700379 uint8_t bitcode_sha1[SHA1_DIGEST_LENGTH];
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700380 Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700381
382 //===--------------------------------------------------------------------===//
383 // Construct output path.
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700384 // {pCacheDir}/{pResName}.o
Stephen Hinesb10c3a72013-08-07 23:15:22 -0700385 //===--------------------------------------------------------------------===//
386 llvm::SmallString<80> output_path(pCacheDir);
387 llvm::sys::path::append(output_path, pResName);
388 llvm::sys::path::replace_extension(output_path, ".o");
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700389
390 //===--------------------------------------------------------------------===//
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700391 // Load the bitcode and create script.
392 //===--------------------------------------------------------------------===//
393 Source *source = Source::CreateFromBuffer(pContext, pResName,
394 pBitcode, pBitcodeSize);
Chris Wailes900c6c12014-08-13 15:40:00 -0700395 if (source == nullptr) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700396 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700397 }
398
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700399 RSScript script(*source);
Stephen Hinesc3437f02014-01-30 17:57:21 -0800400 if (pLinkRuntimeCallback) {
401 setLinkRuntimeCallback(pLinkRuntimeCallback);
402 }
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700403
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700404 script.setLinkRuntimeCallback(getLinkRuntimeCallback());
Stephen Hines06731a62013-02-12 19:29:42 -0800405
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700406 // Read information from bitcode wrapper.
407 bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700408 script.setCompilerVersion(wrapper.getCompilerVersion());
409 script.setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
410 wrapper.getOptimizationLevel()));
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700411
412 //===--------------------------------------------------------------------===//
413 // Compile the script
414 //===--------------------------------------------------------------------===//
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700415 Compiler::ErrorCode status = compileScript(script, pResName,
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700416 output_path.c_str(),
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700417 pRuntimePath, bitcode_sha1, commandLine,
418 true, pDumpIR);
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700419
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700420 return status == Compiler::kSuccess;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800421}
Stephen Hines331310e2012-10-26 19:27:55 -0700422
423
Jean-Luc Brouilletc5e607a2014-06-18 18:14:02 -0700424bool RSCompilerDriver::buildForCompatLib(RSScript &pScript, const char *pOut,
425 const char *pRuntimePath) {
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700426 // For compat lib, we don't check the RS info file so we don't need the source hash,
427 // compile command, and build fingerprint.
428 // TODO We may want to make them optional or embed real values.
429 uint8_t bitcode_sha1[SHA1_DIGEST_LENGTH] = {0};
430 const char* compileCommandLineToEmbed = "";
431 const char* buildFingerprintToEmbed = "";
432
433 RSInfo* info = RSInfo::ExtractFromSource(pScript.getSource(), bitcode_sha1,
434 compileCommandLineToEmbed, buildFingerprintToEmbed);
Chris Wailes900c6c12014-08-13 15:40:00 -0700435 if (info == nullptr) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700436 return false;
Stephen Hines331310e2012-10-26 19:27:55 -0700437 }
438 pScript.setInfo(info);
439
Stephen Hines86a0b792012-11-06 20:04:47 -0800440 // Embed the info string directly in the ELF, since this path is for an
441 // offline (host) compilation.
442 pScript.setEmbedInfo(true);
443
Jean-Luc Brouilletf2ac3172014-06-25 18:21:36 -0700444 Compiler::ErrorCode status = compileScript(pScript, pOut, pOut, pRuntimePath, bitcode_sha1,
445 compileCommandLineToEmbed, false, false);
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700446 if (status != Compiler::kSuccess) {
447 return false;
448 }
449
450 return true;
Stephen Hines331310e2012-10-26 19:27:55 -0700451}