blob: 0f845bdbcfb27929810deffc68e786efaa6773a6 [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
Stephen Hinese198abe2012-07-27 18:05:41 -070017#include "bcc/Renderscript/RSCompilerDriver.h"
Zonr Chang0fffa7e2012-04-12 19:43:53 +080018
Tobias Grosser7b980e12013-06-20 10:12:13 -070019#include <llvm/IR/Module.h>
Stephen Hinesad694762013-04-29 18:59:47 -070020#include <llvm/Support/CommandLine.h>
Stephen Hinesb10c3a72013-08-07 23:15:22 -070021#include <llvm/Support/Path.h>
Tobias Grosser7b980e12013-06-20 10:12:13 -070022#include <llvm/Support/raw_ostream.h>
Shih-wei Liao7bcec852012-04-25 04:07:09 -070023
24#include "bcinfo/BitcodeWrapper.h"
25
Stephen Hines47f0d5a2013-06-05 00:27:38 -070026#include "bcc/Compiler.h"
Stephen Hinesbde1a252014-05-15 18:02:33 -070027#include "bcc/Config/Config.h"
Stephen Hinese198abe2012-07-27 18:05:41 -070028#include "bcc/Renderscript/RSExecutable.h"
29#include "bcc/Renderscript/RSScript.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080030#include "bcc/Support/CompilerConfig.h"
Shih-wei Liao7bcec852012-04-25 04:07:09 -070031#include "bcc/Source.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080032#include "bcc/Support/FileMutex.h"
Zonr Changef73a242012-04-12 16:44:01 +080033#include "bcc/Support/Log.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080034#include "bcc/Support/InputFile.h"
35#include "bcc/Support/Initialization.h"
Shih-wei Liao7bcec852012-04-25 04:07:09 -070036#include "bcc/Support/Sha1Util.h"
Zonr Changc72c4dd2012-04-12 15:38:53 +080037#include "bcc/Support/OutputFile.h"
Zonr Chang0fffa7e2012-04-12 19:43:53 +080038
Nick Kralevichb81d6972013-05-21 16:52:35 -070039#ifdef HAVE_ANDROID_OS
Zonr Chang0fffa7e2012-04-12 19:43:53 +080040#include <cutils/properties.h>
Nick Kralevichb81d6972013-05-21 16:52:35 -070041#endif
Zonr Chang0fffa7e2012-04-12 19:43:53 +080042#include <utils/String8.h>
Shih-wei Liao7bcec852012-04-25 04:07:09 -070043#include <utils/StopWatch.h>
Zonr Chang0fffa7e2012-04-12 19:43:53 +080044
45using namespace bcc;
46
Stephen Hines3ab9da12013-02-01 18:39:15 -080047RSCompilerDriver::RSCompilerDriver(bool pUseCompilerRT) :
Stephen Hinesb39557e2014-05-21 21:14:46 -070048 mConfig(NULL), mCompiler(), mDebugContext(false),
Stephen Hinesc3437f02014-01-30 17:57:21 -080049 mLinkRuntimeCallback(NULL), mEnableGlobalMerge(true) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +080050 init::Initialize();
Zonr Chang0fffa7e2012-04-12 19:43:53 +080051}
52
53RSCompilerDriver::~RSCompilerDriver() {
54 delete mConfig;
55}
56
Shih-wei Liao7bcec852012-04-25 04:07:09 -070057RSExecutable *
Stephen Hines47f0d5a2013-06-05 00:27:38 -070058RSCompilerDriver::loadScript(const char *pCacheDir, const char *pResName,
Stephen Hinesb39557e2014-05-21 21:14:46 -070059 const char *pBitcode, size_t pBitcodeSize,
60 SymbolResolverProxy &pResolver) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -070061 //android::StopWatch load_time("bcc: RSCompilerDriver::loadScript time");
62 if ((pCacheDir == NULL) || (pResName == NULL)) {
63 ALOGE("Missing pCacheDir and/or pResName");
64 return NULL;
65 }
66
67 if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
68 ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %zu)",
69 pBitcode, pBitcodeSize);
70 return NULL;
71 }
72
73 RSInfo::DependencyTableTy dep_info;
74 uint8_t bitcode_sha1[20];
75 Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
Stephen Hines47f0d5a2013-06-05 00:27:38 -070076
Stephen Hines47f0d5a2013-06-05 00:27:38 -070077 // {pCacheDir}/{pResName}.o
Stephen Hinesb10c3a72013-08-07 23:15:22 -070078 llvm::SmallString<80> output_path(pCacheDir);
79 llvm::sys::path::append(output_path, pResName);
80 llvm::sys::path::replace_extension(output_path, ".o");
Zonr Chang0fffa7e2012-04-12 19:43:53 +080081
Stephen Hines5eea9732013-06-19 19:09:32 -070082 dep_info.push(std::make_pair(output_path.c_str(), bitcode_sha1));
83
Zonr Chang0fffa7e2012-04-12 19:43:53 +080084 //===--------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -070085 // Acquire the read lock for reading the Script object file.
Zonr Chang0fffa7e2012-04-12 19:43:53 +080086 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -070087 FileMutex<FileBase::kReadLock> read_output_mutex(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +080088
89 if (read_output_mutex.hasError() || !read_output_mutex.lock()) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -070090 ALOGE("Unable to acquire the read lock for %s! (%s)", output_path.c_str(),
Zonr Chang0fffa7e2012-04-12 19:43:53 +080091 read_output_mutex.getErrorMessage().c_str());
92 return NULL;
93 }
94
95 //===--------------------------------------------------------------------===//
96 // Read the output object file.
97 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -070098 InputFile *object_file = new (std::nothrow) InputFile(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +080099
Stephen Hines01f05d42013-05-31 20:51:27 -0700100 if ((object_file == NULL) || object_file->hasError()) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700101 // ALOGE("Unable to open the %s for read! (%s)", output_path.c_str(),
Stephen Hines01f05d42013-05-31 20:51:27 -0700102 // object_file->getErrorMessage().c_str());
103 delete object_file;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800104 return NULL;
105 }
106
107 //===--------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700108 // Acquire the read lock on object_file for reading its RS info file.
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800109 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700110 android::String8 info_path = RSInfo::GetPath(output_path.c_str());
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800111
Stephen Hines01f05d42013-05-31 20:51:27 -0700112 if (!object_file->lock()) {
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800113 ALOGE("Unable to acquire the read lock on %s for reading %s! (%s)",
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700114 output_path.c_str(), info_path.string(),
Stephen Hines01f05d42013-05-31 20:51:27 -0700115 object_file->getErrorMessage().c_str());
116 delete object_file;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800117 return NULL;
118 }
119
120 //===---------------------------------------------------------------------===//
121 // Open and load the RS info file.
122 //===--------------------------------------------------------------------===//
123 InputFile info_file(info_path.string());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700124 RSInfo *info = RSInfo::ReadFromFile(info_file, dep_info);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800125
Stephen Hines01f05d42013-05-31 20:51:27 -0700126 // Release the lock on object_file.
127 object_file->unlock();
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800128
129 if (info == NULL) {
Stephen Hines01f05d42013-05-31 20:51:27 -0700130 delete object_file;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800131 return NULL;
132 }
133
134 //===--------------------------------------------------------------------===//
135 // Create the RSExecutable.
136 //===--------------------------------------------------------------------===//
Stephen Hinesb39557e2014-05-21 21:14:46 -0700137 RSExecutable *result = RSExecutable::Create(*info, *object_file, pResolver);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800138 if (result == NULL) {
Stephen Hines01f05d42013-05-31 20:51:27 -0700139 delete object_file;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800140 delete info;
141 return NULL;
142 }
143
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800144 return result;
145}
146
Stephen Hinesbde1a252014-05-15 18:02:33 -0700147#if defined(PROVIDE_ARM_CODEGEN)
Stephen Hinesad694762013-04-29 18:59:47 -0700148extern llvm::cl::opt<bool> EnableGlobalMerge;
Stephen Hinesc06cd062013-07-12 10:51:29 -0700149#endif
150
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800151bool RSCompilerDriver::setupConfig(const RSScript &pScript) {
152 bool changed = false;
153
154 const llvm::CodeGenOpt::Level script_opt_level =
155 static_cast<llvm::CodeGenOpt::Level>(pScript.getOptimizationLevel());
156
Stephen Hinesbde1a252014-05-15 18:02:33 -0700157#if defined(PROVIDE_ARM_CODEGEN)
Stephen Hines045558b2014-02-18 14:07:15 -0800158 EnableGlobalMerge = mEnableGlobalMerge;
159#endif
160
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800161 if (mConfig != NULL) {
162 // Renderscript bitcode may have their optimization flag configuration
163 // different than the previous run of RS compilation.
164 if (mConfig->getOptimizationLevel() != script_opt_level) {
165 mConfig->setOptimizationLevel(script_opt_level);
166 changed = true;
167 }
168 } else {
169 // Haven't run the compiler ever.
Stephen Hinesbde1a252014-05-15 18:02:33 -0700170 mConfig = new (std::nothrow) CompilerConfig(DEFAULT_TARGET_TRIPLE_STRING);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800171 if (mConfig == NULL) {
172 // Return false since mConfig remains NULL and out-of-memory.
173 return false;
174 }
175 mConfig->setOptimizationLevel(script_opt_level);
176 changed = true;
177 }
178
Stephen Hinesbde1a252014-05-15 18:02:33 -0700179#if defined(PROVIDE_ARM_CODEGEN)
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800180 assert((pScript.getInfo() != NULL) && "NULL RS info!");
Stephen Hinesbde1a252014-05-15 18:02:33 -0700181 bool script_full_prec = (pScript.getInfo()->getFloatPrecisionRequirement() ==
182 RSInfo::FP_Full);
183 if (mConfig->getFullPrecision() != script_full_prec) {
184 mConfig->setFullPrecision(script_full_prec);
185 changed = true;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800186 }
187#endif
188
189 return changed;
190}
191
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700192Compiler::ErrorCode
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700193RSCompilerDriver::compileScript(RSScript &pScript,
Shih-wei Liaoba420642012-06-30 11:27:37 -0700194 const char* pScriptName,
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700195 const char *pOutputPath,
Stephen Hines331310e2012-10-26 19:27:55 -0700196 const char *pRuntimePath,
197 const RSInfo::DependencyTableTy &pDeps,
Tobias Grosser7b980e12013-06-20 10:12:13 -0700198 bool pSkipLoad, bool pDumpIR) {
Tim Murrayc89f78b2013-05-09 11:57:12 -0700199 //android::StopWatch compile_time("bcc: RSCompilerDriver::compileScript time");
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800200 RSInfo *info = NULL;
201
202 //===--------------------------------------------------------------------===//
203 // Extract RS-specific information from source bitcode.
204 //===--------------------------------------------------------------------===//
205 // RS info may contains configuration (such as #optimization_level) to the
206 // compiler therefore it should be extracted before compilation.
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700207 info = RSInfo::ExtractFromSource(pScript.getSource(), pDeps);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800208 if (info == NULL) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700209 return Compiler::kErrInvalidSource;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800210 }
211
212 //===--------------------------------------------------------------------===//
213 // Associate script with its info
214 //===--------------------------------------------------------------------===//
215 // This is required since RS compiler may need information in the info file
216 // to do some transformation (e.g., expand foreach-able function.)
217 pScript.setInfo(info);
218
219 //===--------------------------------------------------------------------===//
Stephen Hinese198abe2012-07-27 18:05:41 -0700220 // Link RS script with Renderscript runtime.
Shih-wei Liaoba420642012-06-30 11:27:37 -0700221 //===--------------------------------------------------------------------===//
Stephen Hines331310e2012-10-26 19:27:55 -0700222 if (!RSScript::LinkRuntime(pScript, pRuntimePath)) {
Stephen Hinese198abe2012-07-27 18:05:41 -0700223 ALOGE("Failed to link script '%s' with Renderscript runtime!", pScriptName);
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700224 return Compiler::kErrInvalidSource;
Shih-wei Liaoba420642012-06-30 11:27:37 -0700225 }
226
Stephen Hines01f05d42013-05-31 20:51:27 -0700227 {
Stephen Hines07843652013-08-15 15:41:47 -0700228 // FIXME(srhines): Windows compilation can't use locking like this, but
229 // we also don't need to worry about concurrent writers of the same file.
Stephen Hinesd7a95262013-08-08 16:03:19 -0700230#ifndef USE_MINGW
Stephen Hines07843652013-08-15 15:41:47 -0700231 //===------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700232 // Acquire the write lock for writing output object file.
Stephen Hines07843652013-08-15 15:41:47 -0700233 //===------------------------------------------------------------------===//
Stephen Hines01f05d42013-05-31 20:51:27 -0700234 FileMutex<FileBase::kWriteLock> write_output_mutex(pOutputPath);
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800235
Stephen Hines01f05d42013-05-31 20:51:27 -0700236 if (write_output_mutex.hasError() || !write_output_mutex.lock()) {
237 ALOGE("Unable to acquire the lock for writing %s! (%s)",
238 pOutputPath, write_output_mutex.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700239 return Compiler::kErrInvalidSource;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800240 }
Stephen Hinesd7a95262013-08-08 16:03:19 -0700241#endif
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800242
Stephen Hines01f05d42013-05-31 20:51:27 -0700243 // Open the output file for write.
Stephen Hinesacf9c9e2013-09-26 16:32:31 -0700244 OutputFile output_file(pOutputPath,
245 FileBase::kTruncate | FileBase::kBinary);
Stephen Hines01f05d42013-05-31 20:51:27 -0700246
247 if (output_file.hasError()) {
248 ALOGE("Unable to open %s for write! (%s)", pOutputPath,
249 output_file.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700250 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700251 }
252
253 // Setup the config to the compiler.
254 bool compiler_need_reconfigure = setupConfig(pScript);
255
256 if (mConfig == NULL) {
257 ALOGE("Failed to setup config for RS compiler to compile %s!",
258 pOutputPath);
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700259 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700260 }
261
262 if (compiler_need_reconfigure) {
263 Compiler::ErrorCode err = mCompiler.config(*mConfig);
264 if (err != Compiler::kSuccess) {
265 ALOGE("Failed to config the RS compiler for %s! (%s)",pOutputPath,
266 Compiler::GetErrorString(err));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700267 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700268 }
269 }
270
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700271 OutputFile *ir_file = NULL;
272 llvm::raw_fd_ostream *IRStream = NULL;
273 if (pDumpIR) {
274 android::String8 path(pOutputPath);
275 path.append(".ll");
276 ir_file = new OutputFile(path.string(), FileBase::kTruncate);
277 IRStream = ir_file->dup();
278 }
279
Stephen Hines01f05d42013-05-31 20:51:27 -0700280 // Run the compiler.
Tobias Grosser27fb7ed2013-06-21 18:34:56 -0700281 Compiler::ErrorCode compile_result = mCompiler.compile(pScript,
282 output_file, IRStream);
283
284 if (ir_file) {
285 ir_file->close();
286 delete ir_file;
287 }
Stephen Hines01f05d42013-05-31 20:51:27 -0700288
289 if (compile_result != Compiler::kSuccess) {
290 ALOGE("Unable to compile the source to file %s! (%s)", pOutputPath,
291 Compiler::GetErrorString(compile_result));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700292 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700293 }
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800294 }
295
Stephen Hines331310e2012-10-26 19:27:55 -0700296 // No need to produce an RSExecutable in this case.
297 // TODO: Error handling in this case is nonexistent.
298 if (pSkipLoad) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700299 return Compiler::kSuccess;
Stephen Hines331310e2012-10-26 19:27:55 -0700300 }
301
Stephen Hines01f05d42013-05-31 20:51:27 -0700302 {
303 android::String8 info_path = RSInfo::GetPath(pOutputPath);
304 OutputFile info_file(info_path.string(), FileBase::kTruncate);
305
306 if (info_file.hasError()) {
307 ALOGE("Failed to open the info file %s for write! (%s)",
308 info_path.string(), info_file.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700309 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700310 }
311
312 FileMutex<FileBase::kWriteLock> write_info_mutex(info_path.string());
313 if (write_info_mutex.hasError() || !write_info_mutex.lock()) {
314 ALOGE("Unable to acquire the lock for writing %s! (%s)",
315 info_path.string(), write_info_mutex.getErrorMessage().c_str());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700316 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700317 }
318
319 // Perform the write.
320 if (!info->write(info_file)) {
321 ALOGE("Failed to sync the RS info file %s!", info_path.string());
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700322 return Compiler::kErrInvalidSource;
Stephen Hines01f05d42013-05-31 20:51:27 -0700323 }
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800324 }
325
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700326 return Compiler::kSuccess;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800327}
328
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700329bool RSCompilerDriver::build(BCCContext &pContext,
330 const char *pCacheDir,
331 const char *pResName,
332 const char *pBitcode,
333 size_t pBitcodeSize,
334 const char *pRuntimePath,
Tobias Grosser7b980e12013-06-20 10:12:13 -0700335 RSLinkRuntimeCallback pLinkRuntimeCallback,
336 bool pDumpIR) {
Tim Murrayc89f78b2013-05-09 11:57:12 -0700337 // android::StopWatch build_time("bcc: RSCompilerDriver::build time");
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700338 //===--------------------------------------------------------------------===//
339 // Check parameters.
340 //===--------------------------------------------------------------------===//
341 if ((pCacheDir == NULL) || (pResName == NULL)) {
342 ALOGE("Invalid parameter passed to RSCompilerDriver::build()! (cache dir: "
343 "%s, resource name: %s)", ((pCacheDir) ? pCacheDir : "(null)"),
344 ((pResName) ? pResName : "(null)"));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700345 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700346 }
347
348 if ((pBitcode == NULL) || (pBitcodeSize <= 0)) {
349 ALOGE("No bitcode supplied! (bitcode: %p, size of bitcode: %u)",
350 pBitcode, static_cast<unsigned>(pBitcodeSize));
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700351 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700352 }
353
354 //===--------------------------------------------------------------------===//
355 // Prepare dependency information.
356 //===--------------------------------------------------------------------===//
357 RSInfo::DependencyTableTy dep_info;
358 uint8_t bitcode_sha1[20];
359 Sha1Util::GetSHA1DigestFromBuffer(bitcode_sha1, pBitcode, pBitcodeSize);
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700360
361 //===--------------------------------------------------------------------===//
362 // Construct output path.
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700363 // {pCacheDir}/{pResName}.o
Stephen Hinesb10c3a72013-08-07 23:15:22 -0700364 //===--------------------------------------------------------------------===//
365 llvm::SmallString<80> output_path(pCacheDir);
366 llvm::sys::path::append(output_path, pResName);
367 llvm::sys::path::replace_extension(output_path, ".o");
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700368
Stephen Hines5eea9732013-06-19 19:09:32 -0700369 dep_info.push(std::make_pair(output_path.c_str(), bitcode_sha1));
370
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700371 //===--------------------------------------------------------------------===//
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700372 // Load the bitcode and create script.
373 //===--------------------------------------------------------------------===//
374 Source *source = Source::CreateFromBuffer(pContext, pResName,
375 pBitcode, pBitcodeSize);
376 if (source == NULL) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700377 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700378 }
379
380 RSScript *script = new (std::nothrow) RSScript(*source);
381 if (script == NULL) {
382 ALOGE("Out of memory when create Script object for '%s'! (output: %s)",
383 pResName, output_path.c_str());
384 delete source;
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700385 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700386 }
Stephen Hinesc3437f02014-01-30 17:57:21 -0800387 if (pLinkRuntimeCallback) {
388 setLinkRuntimeCallback(pLinkRuntimeCallback);
389 }
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700390
Stephen Hinesc3437f02014-01-30 17:57:21 -0800391 script->setLinkRuntimeCallback(getLinkRuntimeCallback());
Stephen Hines06731a62013-02-12 19:29:42 -0800392
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700393 // Read information from bitcode wrapper.
394 bcinfo::BitcodeWrapper wrapper(pBitcode, pBitcodeSize);
395 script->setCompilerVersion(wrapper.getCompilerVersion());
396 script->setOptimizationLevel(static_cast<RSScript::OptimizationLevel>(
397 wrapper.getOptimizationLevel()));
398
399 //===--------------------------------------------------------------------===//
400 // Compile the script
401 //===--------------------------------------------------------------------===//
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700402 Compiler::ErrorCode status = compileScript(*script, pResName,
403 output_path.c_str(),
Tobias Grosser7b980e12013-06-20 10:12:13 -0700404 pRuntimePath, dep_info, false,
405 pDumpIR);
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700406
407 // Script is no longer used. Free it to get more memory.
408 delete script;
409
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700410 if (status != Compiler::kSuccess) {
411 return false;
Shih-wei Liao7bcec852012-04-25 04:07:09 -0700412 }
413
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700414 return true;
Zonr Chang0fffa7e2012-04-12 19:43:53 +0800415}
Stephen Hines331310e2012-10-26 19:27:55 -0700416
417
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700418bool RSCompilerDriver::build(RSScript &pScript, const char *pOut,
419 const char *pRuntimePath) {
Stephen Hines331310e2012-10-26 19:27:55 -0700420 RSInfo::DependencyTableTy dep_info;
421 RSInfo *info = RSInfo::ExtractFromSource(pScript.getSource(), dep_info);
422 if (info == NULL) {
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700423 return false;
Stephen Hines331310e2012-10-26 19:27:55 -0700424 }
425 pScript.setInfo(info);
426
Stephen Hines86a0b792012-11-06 20:04:47 -0800427 // Embed the info string directly in the ELF, since this path is for an
428 // offline (host) compilation.
429 pScript.setEmbedInfo(true);
430
Stephen Hines47f0d5a2013-06-05 00:27:38 -0700431 Compiler::ErrorCode status = compileScript(pScript, pOut, pOut, pRuntimePath,
432 dep_info, true);
433 if (status != Compiler::kSuccess) {
434 return false;
435 }
436
437 return true;
Stephen Hines331310e2012-10-26 19:27:55 -0700438}
439