blob: e7bdd5266c1420035b5176af72f6e0a77f1988ea [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
Stephen Hinesdb169182012-01-05 18:46:36 -08002 * Copyright 2010-2012, The Android Open Source Project
Logan1f028c02010-11-27 01:02:48 +08003 *
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
Loganc4395232010-11-27 18:54:17 +080017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
Stephen Hines569986d2012-03-09 19:58:45 -080020#include <bcinfo/MetadataExtractor.h>
Logan35849002011-01-15 07:30:43 +080021
Logan Chiend2a5f302011-07-19 20:32:25 +080022#if USE_OLD_JIT
23#include "OldJIT/ContextManager.h"
24#endif
25
Logan Chien4885cf82011-07-20 10:18:05 +080026#if USE_DISASSEMBLER
27#include "Disassembler/Disassembler.h"
28#endif
29
Logan4dcd6792011-02-28 05:12:00 +080030#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070031#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080032#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080033#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080034#include "Sha1Helper.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080035#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080036
Shih-wei Liao320b5492011-06-20 22:53:33 -070037#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080038#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070039#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080040
Stephen Hinesdb169182012-01-05 18:46:36 -080041#include "Transforms/BCCTransforms.h"
42
Logandf23afa2010-11-27 11:04:54 +080043#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080044
Logandf23afa2010-11-27 11:04:54 +080045#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080046
Logan1f028c02010-11-27 01:02:48 +080047#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080048#include "llvm/CodeGen/RegAllocRegistry.h"
49#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080050
Daniel Malea094881f2011-12-14 17:39:16 -050051#include "llvm/MC/MCContext.h"
Logan Chien9347e0b2011-07-07 19:51:47 +080052#include "llvm/MC/SubtargetFeature.h"
53
Logandf23afa2010-11-27 11:04:54 +080054#include "llvm/Transforms/IPO.h"
55#include "llvm/Transforms/Scalar.h"
56
Logandf23afa2010-11-27 11:04:54 +080057#include "llvm/Target/TargetData.h"
58#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080059
60#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070061#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080062#include "llvm/Support/TargetRegistry.h"
63#include "llvm/Support/TargetSelect.h"
Daniel Malea094881f2011-12-14 17:39:16 -050064#include "llvm/Support/raw_ostream.h"
Logandf23afa2010-11-27 11:04:54 +080065
Daniel Malea094881f2011-12-14 17:39:16 -050066#include "llvm/Constants.h"
Logandf23afa2010-11-27 11:04:54 +080067#include "llvm/GlobalValue.h"
68#include "llvm/Linker.h"
69#include "llvm/LLVMContext.h"
Logandf23afa2010-11-27 11:04:54 +080070#include "llvm/Module.h"
71#include "llvm/PassManager.h"
Daniel Malea094881f2011-12-14 17:39:16 -050072#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080073#include "llvm/Value.h"
74
75#include <errno.h>
76#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080077#include <sys/stat.h>
78#include <sys/types.h>
79#include <unistd.h>
80
Logan75cc8a52011-01-07 06:06:52 +080081#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080082
Logan Chien7890d432011-08-03 14:55:17 +080083#include <algorithm>
84#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080085#include <string>
86#include <vector>
Logan1f028c02010-11-27 01:02:48 +080087
Daniel Malea094881f2011-12-14 17:39:16 -050088extern char* gDebugDumpDirectory;
89
Logan1f028c02010-11-27 01:02:48 +080090namespace bcc {
91
92//////////////////////////////////////////////////////////////////////////////
93// BCC Compiler Static Variables
94//////////////////////////////////////////////////////////////////////////////
95
96bool Compiler::GlobalInitialized = false;
97
Andrew Hsieh998ec832011-11-21 02:36:11 -080098
99#if !defined(__HOST__)
100 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
101#else
102// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
103 #if defined(__cplusplus)
104 extern "C" {
105 #endif
106 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
107 #if defined(__cplusplus)
108 };
109 #endif
110#endif
111
Logan1f028c02010-11-27 01:02:48 +0800112// Code generation optimization level for the compiler
113llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
114
115std::string Compiler::Triple;
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800116llvm::Triple::ArchType Compiler::ArchType;
Logan1f028c02010-11-27 01:02:48 +0800117
118std::string Compiler::CPU;
119
120std::vector<std::string> Compiler::Features;
121
Daniel Malea094881f2011-12-14 17:39:16 -0500122
Logan1f028c02010-11-27 01:02:48 +0800123//////////////////////////////////////////////////////////////////////////////
124// Compiler
125//////////////////////////////////////////////////////////////////////////////
126
127void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700128 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800129 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700130 }
131
Shih-wei Liao22705912012-03-06 19:13:26 -0800132#if defined(PROVIDE_ARM_CODEGEN)
133 LLVMInitializeARMAsmPrinter();
134 LLVMInitializeARMTargetMC();
135 LLVMInitializeARMTargetInfo();
136 LLVMInitializeARMTarget();
137#endif
138
139#if defined(PROVIDE_MIPS_CODEGEN)
140 LLVMInitializeMipsAsmPrinter();
141 LLVMInitializeMipsTargetMC();
142 LLVMInitializeMipsTargetInfo();
143 LLVMInitializeMipsTarget();
144#endif
145
146#if defined(PROVIDE_X86_CODEGEN)
147 LLVMInitializeX86AsmPrinter();
148 LLVMInitializeX86TargetMC();
149 LLVMInitializeX86TargetInfo();
150 LLVMInitializeX86Target();
151#endif
152
153#if USE_DISASSEMBLER
154 InitializeDisassembler();
155#endif
156
Logan1f028c02010-11-27 01:02:48 +0800157 // if (!llvm::llvm_is_multithreaded())
158 // llvm::llvm_start_multithreaded();
159
160 // Set Triple, CPU and Features here
161 Triple = TARGET_TRIPLE_STRING;
162
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800163 // Determine ArchType
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800164#if defined(__HOST__)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800165 {
166 std::string Err;
167 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
Stephen Hinescc366e52012-02-21 17:22:04 -0800168 if (Target != NULL) {
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800169 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
170 } else {
171 ArchType = llvm::Triple::UnknownArch;
172 ALOGE("%s", Err.c_str());
173 }
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800174 }
175#elif defined(DEFAULT_ARM_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800176 ArchType = llvm::Triple::arm;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800177#elif defined(DEFAULT_MIPS_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800178 ArchType = llvm::Triple::mipsel;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800179#elif defined(DEFAULT_X86_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800180 ArchType = llvm::Triple::x86;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800181#elif defined(DEFAULT_X86_64_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800182 ArchType = llvm::Triple::x86_64;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800183#else
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800184 ArchType = llvm::Triple::UnknownArch;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800185#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800186
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800187 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800188# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800189 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800190# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800191 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800192# endif
193# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700194
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800195# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800196 Features.push_back("+neon");
197 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800198# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800199 Features.push_back("-neon");
200 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800201# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700202
Stephen Hinesf6b202b2012-03-06 17:45:41 -0800203// FIXME(all): Turn NEON back on after debugging the rebase.
204# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800205 Features.push_back("-neon");
206 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800207# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800208 }
Joseph Wen51001b82011-06-23 18:56:45 -0700209
Logan1f028c02010-11-27 01:02:48 +0800210 // Register the scheduler
211 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
212
Logan35849002011-01-15 07:30:43 +0800213#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700214 // Read in SHA1 checksum of libbcc and libRS.
215 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700216
217 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800218#endif
Logan75cc8a52011-01-07 06:06:52 +0800219
Logan1f028c02010-11-27 01:02:48 +0800220 GlobalInitialized = true;
221}
222
223
224void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
225 std::string *Error = static_cast<std::string*>(UserData);
226 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000227 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800228 exit(1);
229}
230
231
Logan Chienda5e0c32011-06-13 03:47:21 +0800232#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800233CodeMemoryManager *Compiler::createCodeMemoryManager() {
234 mCodeMemMgr.reset(new CodeMemoryManager());
235 return mCodeMemMgr.get();
236}
Logan Chienda5e0c32011-06-13 03:47:21 +0800237#endif
Logan1f028c02010-11-27 01:02:48 +0800238
239
Logan Chienda5e0c32011-06-13 03:47:21 +0800240#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800241CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800242 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800243 return mCodeEmitter.get();
244}
Logan Chienda5e0c32011-06-13 03:47:21 +0800245#endif
Logan1f028c02010-11-27 01:02:48 +0800246
247
Logan2a6dc822011-01-06 04:05:20 +0800248Compiler::Compiler(ScriptCompiled *result)
249 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800250#if USE_MCJIT
251 mRSExecutable(NULL),
252#endif
Logan1f028c02010-11-27 01:02:48 +0800253 mpSymbolLookupFn(NULL),
254 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800255 mModule(NULL),
256 mHasLinked(false) /* Turn off linker */ {
257 llvm::remove_fatal_error_handler();
258 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800259 return;
260}
261
Logan1f028c02010-11-27 01:02:48 +0800262
Logan474cbd22011-01-31 01:47:44 +0800263int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800264 if (llvm::Linker::LinkModules(mModule, moduleWith,
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800265 llvm::Linker::PreserveSource,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800266 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800267 return hasError();
268 }
269
Logan1f028c02010-11-27 01:02:48 +0800270 // Everything for linking should be settled down here with no error occurs
271 mHasLinked = true;
272 return hasError();
273}
274
275
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800276int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800277 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800278 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800279 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800280
Logan1f028c02010-11-27 01:02:48 +0800281 std::string FeaturesStr;
282
Daniel Malea094881f2011-12-14 17:39:16 -0500283 if (mModule == NULL) // No module was loaded
284 return 0;
285
Stephen Hines569986d2012-03-09 19:58:45 -0800286 bcinfo::MetadataExtractor ME(mModule);
287 ME.extract();
Logan1f028c02010-11-27 01:02:48 +0800288
Stephen Hines569986d2012-03-09 19:58:45 -0800289 size_t VarCount = ME.getExportVarCount();
290 size_t FuncCount = ME.getExportFuncCount();
291 size_t ForEachSigCount = ME.getExportForEachSignatureCount();
292 size_t ObjectSlotCount = ME.getObjectSlotCount();
293 size_t PragmaCount = ME.getPragmaCount();
294
295 std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
296 std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
297 std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
Stephen Hinescc366e52012-02-21 17:22:04 -0800298 std::vector<std::string> ForEachNameList;
Stephen Hines569986d2012-03-09 19:58:45 -0800299 std::vector<uint32_t> ForEachSigList;
300 std::vector<const char*> ExportSymbols;
Stephen Hinescc366e52012-02-21 17:22:04 -0800301
Stephen Hines569986d2012-03-09 19:58:45 -0800302 // Defaults to maximum optimization level from MetadataExtractor.
303 int OptimizationLevel = ME.getOptimizationLevel();
Daniel Malea094881f2011-12-14 17:39:16 -0500304
305 if (OptimizationLevel == 0) {
306 CodeGenOptLevel = llvm::CodeGenOpt::None;
307 } else if (OptimizationLevel == 1) {
308 CodeGenOptLevel = llvm::CodeGenOpt::Less;
309 } else if (OptimizationLevel == 2) {
310 CodeGenOptLevel = llvm::CodeGenOpt::Default;
311 } else if (OptimizationLevel == 3) {
312 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
313 }
314
315 // not the best place for this, but we need to set the register allocation
316 // policy after we read the optimization_level metadata from the bitcode
317
318 // Register allocation policy:
319 // createFastRegisterAllocator: fast but bad quality
320 // createLinearScanRegisterAllocator: not so fast but good quality
321 llvm::RegisterRegAlloc::setDefault
322 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
323 llvm::createFastRegisterAllocator :
Stephen Hinese0918ac2012-03-01 23:28:09 -0800324 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800325
Logan Chienbe81e102011-12-16 13:31:39 +0800326 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800327 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
328 if (hasError())
329 goto on_bcc_compile_error;
330
331 if (!CPU.empty() || !Features.empty()) {
332 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800333
334 for (std::vector<std::string>::const_iterator
335 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800336 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800337 }
338
Logan1f028c02010-11-27 01:02:48 +0800339 FeaturesStr = F.getString();
340 }
341
Logan Chienbe81e102011-12-16 13:31:39 +0800342 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800343 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
344 option.TargetOpt,
345 option.RelocModelOpt,
346 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800347
Logan1f028c02010-11-27 01:02:48 +0800348 if (TM == NULL) {
349 setError("Failed to create target machine implementation for the"
350 " specified triple '" + Triple + "'");
351 goto on_bcc_compile_error;
352 }
353
Logan Chienda5e0c32011-06-13 03:47:21 +0800354 // Get target data from Module
355 TD = new llvm::TargetData(mModule);
356
Stephen Hines569986d2012-03-09 19:58:45 -0800357 // Read pragma information from MetadataExtractor
358 if (PragmaCount) {
359 ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
360 const char **PragmaKeys = ME.getPragmaKeyList();
361 const char **PragmaValues = ME.getPragmaValueList();
362 for (size_t i = 0; i < PragmaCount; i++) {
363 PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
Stephen Hinescc366e52012-02-21 17:22:04 -0800364 }
365 }
366
Stephen Hines569986d2012-03-09 19:58:45 -0800367 if (VarCount) {
368 const char **VarNames = ME.getExportVarNameList();
369 for (size_t i = 0; i < VarCount; i++) {
370 VarNameList.push_back(VarNames[i]);
371 ExportSymbols.push_back(VarNames[i]);
Stephen Hinescc366e52012-02-21 17:22:04 -0800372 }
373 }
374
Stephen Hines569986d2012-03-09 19:58:45 -0800375 if (FuncCount) {
376 const char **FuncNames = ME.getExportFuncNameList();
377 for (size_t i = 0; i < FuncCount; i++) {
378 FuncNameList.push_back(FuncNames[i]);
379 ExportSymbols.push_back(FuncNames[i]);
380 }
381 }
382
383 if (ForEachSigCount) {
384 const char **ForEachNames = ME.getExportForEachNameList();
385 const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
386 for (size_t i = 0; i < ForEachSigCount; i++) {
387 std::string Name(ForEachNames[i]);
388 ForEachNameList.push_back(Name);
389 ForEachExpandList.push_back(Name + ".expand");
390 ForEachSigList.push_back(ForEachSigs[i]);
391 }
392
393 // Need to wait until ForEachExpandList is fully populated to fill in
394 // exported symbols.
395 for (size_t i = 0; i < ForEachSigCount; i++) {
396 ExportSymbols.push_back(ForEachExpandList[i].c_str());
397 }
398 }
399
400 if (ObjectSlotCount) {
401 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
402 const uint32_t *ObjectSlots = ME.getObjectSlotList();
403 for (size_t i = 0; i < ObjectSlotCount; i++) {
404 objectSlotList.push_back(ObjectSlots[i]);
405 }
406 }
407
408 runInternalPasses(ForEachNameList, ForEachSigList);
Stephen Hinesdb169182012-01-05 18:46:36 -0800409
Logan Chienda5e0c32011-06-13 03:47:21 +0800410 // Perform link-time optimization if we have multiple modules
411 if (mHasLinked) {
Stephen Hines569986d2012-03-09 19:58:45 -0800412 runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
Logan Chienda5e0c32011-06-13 03:47:21 +0800413 }
414
415 // Perform code generation
416#if USE_OLD_JIT
417 if (runCodeGen(new llvm::TargetData(*TD), TM,
418 ExportVarMetadata, ExportFuncMetadata) != 0) {
419 goto on_bcc_compile_error;
420 }
421#endif
422
423#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700424 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800425 goto on_bcc_compile_error;
426 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800427
Zonr Chang2fcbd022012-01-06 21:04:31 +0800428 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700429 return 0;
430
431 // Load the ELF Object
432 mRSExecutable =
Stephen Hines569986d2012-03-09 19:58:45 -0800433 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
434 mEmittedELFExecutable.size(),
435 &resolveSymbolAdapter, this);
Joseph Wen34c600a2011-07-25 17:59:17 -0700436
437 if (!mRSExecutable) {
438 setError("Fail to load emitted ELF relocatable file");
439 goto on_bcc_compile_error;
440 }
441
Daniel Malea094881f2011-12-14 17:39:16 -0500442 rsloaderUpdateSectionHeaders(mRSExecutable,
Stephen Hines569986d2012-03-09 19:58:45 -0800443 (unsigned char*) mEmittedELFExecutable.begin());
Daniel Malea094881f2011-12-14 17:39:16 -0500444
Stephen Hines569986d2012-03-09 19:58:45 -0800445 // Once the ELF object has been loaded, populate the various slots for RS
446 // with the appropriate relocated addresses.
447 if (VarCount) {
448 ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
449 for (size_t i = 0; i < VarCount; i++) {
450 VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
451 VarNameList[i].c_str()));
Joseph Wen34c600a2011-07-25 17:59:17 -0700452 }
453 }
454
Stephen Hines569986d2012-03-09 19:58:45 -0800455 if (FuncCount) {
456 ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
457 for (size_t i = 0; i < FuncCount; i++) {
458 FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
459 FuncNameList[i].c_str()));
Joseph Wen34c600a2011-07-25 17:59:17 -0700460 }
461 }
462
Stephen Hines569986d2012-03-09 19:58:45 -0800463 if (ForEachSigCount) {
464 ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
465 for (size_t i = 0; i < ForEachSigCount; i++) {
466 ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
467 ForEachExpandList[i].c_str()));
Stephen Hinescc366e52012-02-21 17:22:04 -0800468 }
469 }
470
Logan Chien4885cf82011-07-20 10:18:05 +0800471#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700472 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700473 // Get MC codegen emitted function name list
474 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
475 std::vector<char const *> func_list(func_list_size, NULL);
476 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700477
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700478 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700479 for (size_t i = 0; i < func_list_size; ++i) {
480 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
481 if (func) {
482 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800483 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
484 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700485 }
486 }
487 }
488#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800489#endif
490
Logan Chienda5e0c32011-06-13 03:47:21 +0800491on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000492 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800493 if (TD) {
494 delete TD;
495 }
496
497 if (TM) {
498 delete TM;
499 }
500
501 if (mError.empty()) {
502 return 0;
503 }
504
Steve Block10c14122012-01-08 10:15:06 +0000505 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800506 return 1;
507}
508
509
510#if USE_OLD_JIT
511int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
512 llvm::NamedMDNode const *ExportVarMetadata,
513 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800514 // Create memory manager for creation of code emitter later.
515 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
516 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800517 return 1;
Logan1f028c02010-11-27 01:02:48 +0800518 }
Logan02286cb2011-01-07 00:30:47 +0800519
520 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800521
522 // Create code emitter
523 if (!mCodeEmitter.get()) {
524 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800525 setError("Failed to create machine code emitter for compilation");
526 return 1;
Logan1f028c02010-11-27 01:02:48 +0800527 }
528 } else {
529 // Reuse the code emitter
530 mCodeEmitter->reset();
531 }
532
533 mCodeEmitter->setTargetMachine(*TM);
534 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
535 mpSymbolLookupContext);
536
Logan1f028c02010-11-27 01:02:48 +0800537 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800538 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
539 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800540
Logan Chienda5e0c32011-06-13 03:47:21 +0800541 // Add TargetData to code generation pass manager
542 CodeGenPasses->add(TD);
543
544 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800545 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
546 *mCodeEmitter,
547 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800548 setError("The machine code emission is not supported on '" + Triple + "'");
549 return 1;
Logan1f028c02010-11-27 01:02:48 +0800550 }
551
Logan Chienda5e0c32011-06-13 03:47:21 +0800552 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800553 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800554 for (llvm::Module::iterator
555 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800556 if (!I->isDeclaration()) {
557 CodeGenPasses->run(*I);
558 }
559 }
560
561 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800562
Logan1f028c02010-11-27 01:02:48 +0800563 // Copy the global address mapping from code emitter and remapping
564 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800565 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
566
Logan1f028c02010-11-27 01:02:48 +0800567 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
568 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
569 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
570 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
571 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
572 llvm::StringRef ExportVarName =
573 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
574
575 CodeEmitter::global_addresses_const_iterator I, E;
576 for (I = mCodeEmitter->global_address_begin(),
577 E = mCodeEmitter->global_address_end();
578 I != E; I++) {
579 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
580 continue;
581 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800582 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700583#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000584 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700585#endif
Logan1f028c02010-11-27 01:02:48 +0800586 break;
587 }
588 }
589 if (I != mCodeEmitter->global_address_end())
590 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800591
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700592#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000593 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800594 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700595#endif
Logan1f028c02010-11-27 01:02:48 +0800596 }
597 }
598 // if reaching here, we know the global variable record in metadata is
599 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800600 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800601 }
Logan2a6dc822011-01-06 04:05:20 +0800602
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700603 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
604 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800605 }
606
607 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800608 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
609
Logan1f028c02010-11-27 01:02:48 +0800610 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
611 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
612 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
613 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
614 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
615 llvm::StringRef ExportFuncName =
616 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800617 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700618#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000619 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800620 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700621#endif
Logan1f028c02010-11-27 01:02:48 +0800622 }
623 }
624 }
625 }
626
627 // Tell code emitter now can release the memory using during the JIT since
628 // we have done the code emission
629 mCodeEmitter->releaseUnnecessary();
630
Logan Chienda5e0c32011-06-13 03:47:21 +0800631 return 0;
Logan1f028c02010-11-27 01:02:48 +0800632}
Logan Chienda5e0c32011-06-13 03:47:21 +0800633#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800634
635
Logan Chienda5e0c32011-06-13 03:47:21 +0800636#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700637int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800638 // Decorate mEmittedELFExecutable with formatted ostream
639 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
640
641 // Relax all machine instructions
642 TM->setMCRelaxAll(/* RelaxAll= */ true);
643
644 // Create MC code generation pass manager
645 llvm::PassManager MCCodeGenPasses;
646
647 // Add TargetData to MC code generation pass manager
648 MCCodeGenPasses.add(TD);
649
650 // Add MC code generation passes to pass manager
Daniel Malea094881f2011-12-14 17:39:16 -0500651 llvm::MCContext *Ctx = NULL;
Logan Chien4e4485d2011-11-25 18:12:33 +0800652 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800653 setError("Fail to add passes to emit file");
654 return 1;
655 }
656
657 MCCodeGenPasses.run(*mModule);
658 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800659 return 0;
660}
661#endif // USE_MCJIT
662
Stephen Hinescc366e52012-02-21 17:22:04 -0800663int Compiler::runInternalPasses(std::vector<std::string>& Names,
664 std::vector<uint32_t>& Signatures) {
Stephen Hinesdb169182012-01-05 18:46:36 -0800665 llvm::PassManager BCCPasses;
666
667 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hinescc366e52012-02-21 17:22:04 -0800668 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Stephen Hinesdb169182012-01-05 18:46:36 -0800669
670 BCCPasses.run(*mModule);
671
672 return 0;
673}
Logan Chienda5e0c32011-06-13 03:47:21 +0800674
675int Compiler::runLTO(llvm::TargetData *TD,
Stephen Hines569986d2012-03-09 19:58:45 -0800676 std::vector<const char*>& ExportSymbols,
Daniel Malea094881f2011-12-14 17:39:16 -0500677 llvm::CodeGenOpt::Level OptimizationLevel) {
Stephen Hines569986d2012-03-09 19:58:45 -0800678 // Note: ExportSymbols is a workaround for getting all exported variable,
679 // function, and kernel names.
Logan Chien4cc00332011-06-12 14:00:46 +0800680 // We should refine it soon.
Stephen Hinescc366e52012-02-21 17:22:04 -0800681
Logan Chien7890d432011-08-03 14:55:17 +0800682 // TODO(logan): Remove this after we have finished the
683 // bccMarkExternalSymbol API.
684
Stephen Hines64160102011-09-01 17:30:26 -0700685 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800686 ExportSymbols.push_back("root");
687 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700688 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800689
Logan Chien7890d432011-08-03 14:55:17 +0800690 // User-defined exporting symbols
691 std::vector<char const *> const &UserDefinedExternalSymbols =
692 mpResult->getUserDefinedExternalSymbols();
693
694 std::copy(UserDefinedExternalSymbols.begin(),
695 UserDefinedExternalSymbols.end(),
696 std::back_inserter(ExportSymbols));
697
Daniel Malea094881f2011-12-14 17:39:16 -0500698 llvm::PassManager LTOPasses;
699
700 // Add TargetData to LTO passes
701 LTOPasses.add(TD);
702
Logan Chien4cc00332011-06-12 14:00:46 +0800703 // We now create passes list performing LTO. These are copied from
704 // (including comments) llvm::createStandardLTOPasses().
Daniel Malea094881f2011-12-14 17:39:16 -0500705 // Only a subset of these LTO passes are enabled in optimization level 0
706 // as they interfere with interactive debugging.
707 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
Logan Chien4cc00332011-06-12 14:00:46 +0800708
Daniel Malea094881f2011-12-14 17:39:16 -0500709 if (OptimizationLevel != llvm::CodeGenOpt::None) {
710 // Internalize all other symbols not listed in ExportSymbols
711 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Logan Chien4cc00332011-06-12 14:00:46 +0800712
Daniel Malea094881f2011-12-14 17:39:16 -0500713 // Propagate constants at call sites into the functions they call. This
714 // opens opportunities for globalopt (and inlining) by substituting
715 // function pointers passed as arguments to direct uses of functions.
716 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800717
Daniel Malea094881f2011-12-14 17:39:16 -0500718 // Now that we internalized some globals, see if we can hack on them!
719 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800720
Daniel Malea094881f2011-12-14 17:39:16 -0500721 // Linking modules together can lead to duplicated global constants, only
722 // keep one copy of each constant...
723 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800724
Daniel Malea094881f2011-12-14 17:39:16 -0500725 // Remove unused arguments from functions...
726 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800727
Daniel Malea094881f2011-12-14 17:39:16 -0500728 // Reduce the code after globalopt and ipsccp. Both can open up
729 // significant simplification opportunities, and both can propagate
730 // functions through function pointers. When this happens, we often have
731 // to resolve varargs calls, etc, so let instcombine do this.
732 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800733
Daniel Malea094881f2011-12-14 17:39:16 -0500734 // Inline small functions
735 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800736
Daniel Malea094881f2011-12-14 17:39:16 -0500737 // Remove dead EH info.
738 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800739
Daniel Malea094881f2011-12-14 17:39:16 -0500740 // Internalize the globals again after inlining
741 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800742
Daniel Malea094881f2011-12-14 17:39:16 -0500743 // Remove dead functions.
744 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800745
Daniel Malea094881f2011-12-14 17:39:16 -0500746 // If we didn't decide to inline a function, check to see if we can
747 // transform it to pass arguments by value instead of by reference.
748 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800749
Daniel Malea094881f2011-12-14 17:39:16 -0500750 // The IPO passes may leave cruft around. Clean up after them.
751 LTOPasses.add(llvm::createInstructionCombiningPass());
752 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800753
Daniel Malea094881f2011-12-14 17:39:16 -0500754 // Break up allocas
755 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800756
Daniel Malea094881f2011-12-14 17:39:16 -0500757 // Run a few AA driven optimizations here and now, to cleanup the code.
758 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
759 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800760
Daniel Malea094881f2011-12-14 17:39:16 -0500761 // Hoist loop invariants.
762 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800763
Daniel Malea094881f2011-12-14 17:39:16 -0500764 // Remove redundancies.
765 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800766
Daniel Malea094881f2011-12-14 17:39:16 -0500767 // Remove dead memcpys.
768 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800769
Daniel Malea094881f2011-12-14 17:39:16 -0500770 // Nuke dead stores.
771 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800772
Daniel Malea094881f2011-12-14 17:39:16 -0500773 // Cleanup and simplify the code after the scalar optimizations.
774 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800775
Daniel Malea094881f2011-12-14 17:39:16 -0500776 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800777
Daniel Malea094881f2011-12-14 17:39:16 -0500778 // Delete basic blocks, which optimization passes may have killed.
779 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800780
Daniel Malea094881f2011-12-14 17:39:16 -0500781 // Now that we have optimized the program, discard unreachable functions.
782 LTOPasses.add(llvm::createGlobalDCEPass());
783
784 } else {
785 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
786 LTOPasses.add(llvm::createGlobalOptimizerPass());
787 LTOPasses.add(llvm::createConstantMergePass());
788 }
Logan Chien4cc00332011-06-12 14:00:46 +0800789
790 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800791
Daniel Malea094881f2011-12-14 17:39:16 -0500792#if ANDROID_ENGINEERING_BUILD
793 if (0 != gDebugDumpDirectory) {
794 std::string errs;
795 std::string Filename(gDebugDumpDirectory);
796 Filename += "/post-lto-module.ll";
797 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
798 mModule->print(FS, 0);
799 FS.close();
800 }
801#endif
802
Logan Chienda5e0c32011-06-13 03:47:21 +0800803 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800804}
805
806
Logan Chienda5e0c32011-06-13 03:47:21 +0800807#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800808void *Compiler::getSymbolAddress(char const *name) {
809 return rsloaderGetSymbolAddress(mRSExecutable, name);
810}
811#endif
812
813
814#if USE_MCJIT
815void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
816 Compiler *self = reinterpret_cast<Compiler *>(context);
817
818 if (void *Addr = FindRuntimeFunction(name)) {
819 return Addr;
820 }
821
822 if (self->mpSymbolLookupFn) {
823 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
824 return Addr;
825 }
826 }
827
Steve Block10c14122012-01-08 10:15:06 +0000828 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800829 return NULL;
830}
831#endif
832
833
Logan1f028c02010-11-27 01:02:48 +0800834Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800835#if USE_MCJIT
836 rsloaderDisposeExec(mRSExecutable);
837#endif
838
Logana4994f52010-11-27 14:06:02 +0800839 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800840}
841
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700842
Logan1f028c02010-11-27 01:02:48 +0800843} // namespace bcc