blob: 4545c0ed072f54f99259a11ffd2afa816a64e938 [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"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/ContextManager.h"
23#endif
24
Logan Chien4885cf82011-07-20 10:18:05 +080025#if USE_DISASSEMBLER
26#include "Disassembler/Disassembler.h"
27#endif
28
Logan4dcd6792011-02-28 05:12:00 +080029#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070030#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080031#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080032#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080033#include "Sha1Helper.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080034#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080035
Shih-wei Liao320b5492011-06-20 22:53:33 -070036#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080037#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070038#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080039
Stephen Hinesdb169182012-01-05 18:46:36 -080040#include "Transforms/BCCTransforms.h"
41
Logandf23afa2010-11-27 11:04:54 +080042#include "llvm/ADT/StringRef.h"
Andrew Hsiehc0554e22012-01-13 22:34:34 -080043#include "llvm/ADT/Triple.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
Logan Chien9347e0b2011-07-07 19:51:47 +080051#include "llvm/MC/SubtargetFeature.h"
52
Logandf23afa2010-11-27 11:04:54 +080053#include "llvm/Transforms/IPO.h"
54#include "llvm/Transforms/Scalar.h"
55
Logandf23afa2010-11-27 11:04:54 +080056#include "llvm/Target/TargetData.h"
57#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080058
59#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070060#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080061#include "llvm/Support/TargetRegistry.h"
62#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080063
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070064#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080065#include "llvm/GlobalValue.h"
66#include "llvm/Linker.h"
67#include "llvm/LLVMContext.h"
68#include "llvm/Metadata.h"
69#include "llvm/Module.h"
70#include "llvm/PassManager.h"
71#include "llvm/Value.h"
72
73#include <errno.h>
74#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080075#include <sys/stat.h>
76#include <sys/types.h>
77#include <unistd.h>
78
Logan75cc8a52011-01-07 06:06:52 +080079#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080080
Logan Chien7890d432011-08-03 14:55:17 +080081#include <algorithm>
82#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080083#include <string>
84#include <vector>
Logan1f028c02010-11-27 01:02:48 +080085
Logan1f028c02010-11-27 01:02:48 +080086namespace bcc {
87
88//////////////////////////////////////////////////////////////////////////////
89// BCC Compiler Static Variables
90//////////////////////////////////////////////////////////////////////////////
91
92bool Compiler::GlobalInitialized = false;
93
Andrew Hsieh998ec832011-11-21 02:36:11 -080094
95#if !defined(__HOST__)
96 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
97#else
98// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
99 #if defined(__cplusplus)
100 extern "C" {
101 #endif
102 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
103 #if defined(__cplusplus)
104 };
105 #endif
106#endif
107
Logan1f028c02010-11-27 01:02:48 +0800108// Code generation optimization level for the compiler
109llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
110
111std::string Compiler::Triple;
112
113std::string Compiler::CPU;
114
115std::vector<std::string> Compiler::Features;
116
Stephen Hines071288a2011-01-27 14:38:26 -0800117// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800118// slang.cpp)
119const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
120
Stephen Hines071288a2011-01-27 14:38:26 -0800121// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800122// synced with slang_rs_metadata.h)
123const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
124
Stephen Hines071288a2011-01-27 14:38:26 -0800125// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800126// synced with slang_rs_metadata.h)
127const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
128
Stephen Hines071288a2011-01-27 14:38:26 -0800129// Name of metadata node where RS object slot info resides (should be
130// synced with slang_rs_metadata.h)
131const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800132
133//////////////////////////////////////////////////////////////////////////////
134// Compiler
135//////////////////////////////////////////////////////////////////////////////
136
137void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700138 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800139 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700140 }
141
Logan1f028c02010-11-27 01:02:48 +0800142 // if (!llvm::llvm_is_multithreaded())
143 // llvm::llvm_start_multithreaded();
144
145 // Set Triple, CPU and Features here
146 Triple = TARGET_TRIPLE_STRING;
147
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800148 // Determine target_archtype
149#if defined(__HOST__)
150 std::string Err;
151 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
152 llvm::Triple::ArchType target_archtype;
153 if (Target == 0) {
154 target_archtype = llvm::Triple::UnknownArch;
155 } else {
156 const char *target_llvm_name = Target->getName();
157 target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
158 }
159#elif defined(DEFAULT_ARM_CODEGEN)
160 const llvm::Triple::ArchType target_archtype = llvm::Triple::arm;
161#elif defined(DEFAULT_MIPS_CODEGEN)
162 const llvm::Triple::ArchType target_archtype = llvm::Triple::mipsel;
163#elif defined(DEFAULT_X86_CODEGEN)
164 const llvm::Triple::ArchType target_archtype = llvm::Triple::x86;
165#elif defined(DEFAULT_X86_64_CODEGEN)
166 const llvm::Triple::ArchType target_archtype = llvm::Triple::x86_64;
167#else
168 const llvm::Triple::ArchType target_archtype = llvm::Triple::UnknownArch;
169#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800170
Andrew Hsiehe7371e12012-01-14 21:36:49 -0800171 if (target_archtype == llvm::Triple::arm || target_archtype == llvm::Triple::thumb) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800172# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800173 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800174# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800175 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800176# endif
177# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700178
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800179# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800180 Features.push_back("+neon");
181 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800182# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800183 Features.push_back("-neon");
184 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800185# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700186
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800187# if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800188 Features.push_back("-neon");
189 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800190# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800191 }
Joseph Wen51001b82011-06-23 18:56:45 -0700192
Logan Chien3bb77072011-09-17 16:53:53 +0800193#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800194 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800195 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800196 LLVMInitializeARMTargetInfo();
197 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800198#endif
199
Logan Chien21392f02011-11-26 20:32:01 +0800200#if defined(PROVIDE_MIPS_CODEGEN)
201 LLVMInitializeMipsAsmPrinter();
202 LLVMInitializeMipsTargetMC();
203 LLVMInitializeMipsTargetInfo();
204 LLVMInitializeMipsTarget();
205#endif
206
Logan Chien3bb77072011-09-17 16:53:53 +0800207#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800208 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800209 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800210 LLVMInitializeX86TargetInfo();
211 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800212#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800213
214#if USE_DISASSEMBLER
215 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800216#endif
217
218 // -O0: llvm::CodeGenOpt::None
219 // -O1: llvm::CodeGenOpt::Less
220 // -O2: llvm::CodeGenOpt::Default
221 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800222 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800223
Logan1f028c02010-11-27 01:02:48 +0800224 // Register the scheduler
225 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
226
227 // Register allocation policy:
228 // createFastRegisterAllocator: fast but bad quality
229 // createLinearScanRegisterAllocator: not so fast but good quality
230 llvm::RegisterRegAlloc::setDefault
231 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
232 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800233 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800234
Logan35849002011-01-15 07:30:43 +0800235#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700236 // Read in SHA1 checksum of libbcc and libRS.
237 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700238
239 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800240#endif
Logan75cc8a52011-01-07 06:06:52 +0800241
Logan1f028c02010-11-27 01:02:48 +0800242 GlobalInitialized = true;
243}
244
245
246void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
247 std::string *Error = static_cast<std::string*>(UserData);
248 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000249 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800250 exit(1);
251}
252
253
Logan Chienda5e0c32011-06-13 03:47:21 +0800254#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800255CodeMemoryManager *Compiler::createCodeMemoryManager() {
256 mCodeMemMgr.reset(new CodeMemoryManager());
257 return mCodeMemMgr.get();
258}
Logan Chienda5e0c32011-06-13 03:47:21 +0800259#endif
Logan1f028c02010-11-27 01:02:48 +0800260
261
Logan Chienda5e0c32011-06-13 03:47:21 +0800262#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800263CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800264 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800265 return mCodeEmitter.get();
266}
Logan Chienda5e0c32011-06-13 03:47:21 +0800267#endif
Logan1f028c02010-11-27 01:02:48 +0800268
269
Logan2a6dc822011-01-06 04:05:20 +0800270Compiler::Compiler(ScriptCompiled *result)
271 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800272#if USE_MCJIT
273 mRSExecutable(NULL),
274#endif
Logan1f028c02010-11-27 01:02:48 +0800275 mpSymbolLookupFn(NULL),
276 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800277 mModule(NULL),
278 mHasLinked(false) /* Turn off linker */ {
279 llvm::remove_fatal_error_handler();
280 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800281 return;
282}
283
Logan1f028c02010-11-27 01:02:48 +0800284
Logan474cbd22011-01-31 01:47:44 +0800285int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800286 if (llvm::Linker::LinkModules(mModule, moduleWith,
287 llvm::Linker::DestroySource,
288 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800289 return hasError();
290 }
291
Logan1f028c02010-11-27 01:02:48 +0800292 // Everything for linking should be settled down here with no error occurs
293 mHasLinked = true;
294 return hasError();
295}
296
297
Zonr Chang2fcbd022012-01-06 21:04:31 +0800298int Compiler::compile(CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800299 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800300 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800301 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800302
Logan1f028c02010-11-27 01:02:48 +0800303 std::string FeaturesStr;
304
Logan Chienda5e0c32011-06-13 03:47:21 +0800305 llvm::NamedMDNode const *PragmaMetadata;
306 llvm::NamedMDNode const *ExportVarMetadata;
307 llvm::NamedMDNode const *ExportFuncMetadata;
308 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800309
Logan1f028c02010-11-27 01:02:48 +0800310 if (mModule == NULL) // No module was loaded
311 return 0;
312
Logan Chienbe81e102011-12-16 13:31:39 +0800313 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800314 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
315 if (hasError())
316 goto on_bcc_compile_error;
317
318 if (!CPU.empty() || !Features.empty()) {
319 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800320
321 for (std::vector<std::string>::const_iterator
322 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800323 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800324 }
325
Logan1f028c02010-11-27 01:02:48 +0800326 FeaturesStr = F.getString();
327 }
328
Zonr Chang2fcbd022012-01-06 21:04:31 +0800329 // Determine if code_model_is_medium
330 // And determine if no_frame_pointer_elimination
331#if defined(__HOST__)
332 bool code_model_is_medium;
333 bool no_frame_pointer_elimination;
Logan Chienbe81e102011-12-16 13:31:39 +0800334
Zonr Chang2fcbd022012-01-06 21:04:31 +0800335 {
336 // open a new scope otherwise compiler complains constructor of the
337 // folloinwg two being bypassed by previous 'goto' statement
338 const char *target_llvm_name = Target->getName();
339 const llvm::Triple::ArchType target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
340 // Data address in X86_64 architecture may reside in a far-away place
341 code_model_is_medium = target_archtype == llvm::Triple::x86_64;
342 // Disable frame pointer elimination optimization for X86_64 and X86
343 no_frame_pointer_elimination = (target_archtype == llvm::Triple::x86_64 ||
344 target_archtype == llvm::Triple::x86);
345 }
346#elif defined(DEFAULT_X86_64_CODEGEN)
347# define code_model_is_medium true
348# define no_frame_pointer_elimination true
349#elif defined(DEFAULT_X86_CODEGEN)
350# define code_model_is_medium false
351# define no_frame_pointer_elimination true
352#else
353# define code_model_is_medium false
354# define no_frame_pointer_elimination false
355#endif
356
357 // Setup LLVM Target Machine Options
358 option.TargetOpt.NoFramePointerElim = no_frame_pointer_elimination;
Logan Chienbe81e102011-12-16 13:31:39 +0800359
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800360 // This is set for the linker (specify how large of the virtual addresses
361 // we can access for all unknown symbols.)
Zonr Chang2fcbd022012-01-06 21:04:31 +0800362 option.CodeModelOpt = code_model_is_medium ? llvm::CodeModel::Medium : llvm::CodeModel::Small;
Logan Chienbe81e102011-12-16 13:31:39 +0800363
364 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800365 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
366 option.TargetOpt,
367 option.RelocModelOpt,
368 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800369
Logan1f028c02010-11-27 01:02:48 +0800370 if (TM == NULL) {
371 setError("Failed to create target machine implementation for the"
372 " specified triple '" + Triple + "'");
373 goto on_bcc_compile_error;
374 }
375
Logan Chienda5e0c32011-06-13 03:47:21 +0800376 // Get target data from Module
377 TD = new llvm::TargetData(mModule);
378
379 // Load named metadata
380 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
381 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
382 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
383 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
384
Stephen Hinesdb169182012-01-05 18:46:36 -0800385 runInternalPasses();
386
Logan Chienda5e0c32011-06-13 03:47:21 +0800387 // Perform link-time optimization if we have multiple modules
388 if (mHasLinked) {
389 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
390 }
391
392 // Perform code generation
393#if USE_OLD_JIT
394 if (runCodeGen(new llvm::TargetData(*TD), TM,
395 ExportVarMetadata, ExportFuncMetadata) != 0) {
396 goto on_bcc_compile_error;
397 }
398#endif
399
400#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700401 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800402 goto on_bcc_compile_error;
403 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800404
Zonr Chang2fcbd022012-01-06 21:04:31 +0800405 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700406 return 0;
407
408 // Load the ELF Object
409 mRSExecutable =
410 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
411 mEmittedELFExecutable.size(),
412 &resolveSymbolAdapter, this);
413
414 if (!mRSExecutable) {
415 setError("Fail to load emitted ELF relocatable file");
416 goto on_bcc_compile_error;
417 }
418
419 if (ExportVarMetadata) {
420 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
421 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
422
423 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
424 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
425 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
426 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
427 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
428 llvm::StringRef ExportVarName =
429 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
430
431 varList.push_back(
432 rsloaderGetSymbolAddress(mRSExecutable,
433 ExportVarName.str().c_str()));
434 varNameList.push_back(ExportVarName.str());
435#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000436 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700437 varList.back());
438#endif
439 continue;
440 }
441 }
442
443 varList.push_back(NULL);
444 }
445 }
446
447 if (ExportFuncMetadata) {
448 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
449 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
450
451 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
452 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
453 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
454 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
455 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
456 llvm::StringRef ExportFuncName =
457 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
458
459 funcList.push_back(
460 rsloaderGetSymbolAddress(mRSExecutable,
461 ExportFuncName.str().c_str()));
462 funcNameList.push_back(ExportFuncName.str());
463#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000464 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700465 funcList.back());
466#endif
467 }
468 }
469 }
470 }
471
Logan Chien4885cf82011-07-20 10:18:05 +0800472#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700473 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700474 // Get MC codegen emitted function name list
475 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
476 std::vector<char const *> func_list(func_list_size, NULL);
477 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700478
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700479 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700480 for (size_t i = 0; i < func_list_size; ++i) {
481 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
482 if (func) {
483 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800484 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
485 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700486 }
487 }
488 }
489#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800490#endif
491
492 // Read pragma information from the metadata node of the module.
493 if (PragmaMetadata) {
494 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
495
496 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
497 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
498 if (Pragma != NULL &&
499 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
500 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
501 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
502
503 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
504 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
505 llvm::StringRef PragmaName =
506 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
507 llvm::StringRef PragmaValue =
508 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
509
510 pragmaList.push_back(
511 std::make_pair(std::string(PragmaName.data(),
512 PragmaName.size()),
513 std::string(PragmaValue.data(),
514 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700515#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000516 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700517 pragmaList.back().first.c_str(),
518 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700519#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800520 }
521 }
522 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800523 }
524
525 if (ObjectSlotMetadata) {
526 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
527
528 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
529 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
530 if (ObjectSlot != NULL &&
531 ObjectSlot->getNumOperands() == 1) {
532 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
533 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
534 llvm::StringRef Slot =
535 static_cast<llvm::MDString*>(SlotMDS)->getString();
536 uint32_t USlot = 0;
537 if (Slot.getAsInteger(10, USlot)) {
538 setError("Non-integer object slot value '" + Slot.str() + "'");
539 goto on_bcc_compile_error;
540 }
541 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700542#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000543 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700544#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800545 }
546 }
547 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800548 }
549
550on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000551 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800552 if (TD) {
553 delete TD;
554 }
555
556 if (TM) {
557 delete TM;
558 }
559
560 if (mError.empty()) {
561 return 0;
562 }
563
Steve Block10c14122012-01-08 10:15:06 +0000564 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800565 return 1;
566}
567
568
569#if USE_OLD_JIT
570int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
571 llvm::NamedMDNode const *ExportVarMetadata,
572 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800573 // Create memory manager for creation of code emitter later.
574 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
575 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800576 return 1;
Logan1f028c02010-11-27 01:02:48 +0800577 }
Logan02286cb2011-01-07 00:30:47 +0800578
579 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800580
581 // Create code emitter
582 if (!mCodeEmitter.get()) {
583 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800584 setError("Failed to create machine code emitter for compilation");
585 return 1;
Logan1f028c02010-11-27 01:02:48 +0800586 }
587 } else {
588 // Reuse the code emitter
589 mCodeEmitter->reset();
590 }
591
592 mCodeEmitter->setTargetMachine(*TM);
593 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
594 mpSymbolLookupContext);
595
Logan1f028c02010-11-27 01:02:48 +0800596 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800597 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
598 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800599
Logan Chienda5e0c32011-06-13 03:47:21 +0800600 // Add TargetData to code generation pass manager
601 CodeGenPasses->add(TD);
602
603 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800604 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
605 *mCodeEmitter,
606 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800607 setError("The machine code emission is not supported on '" + Triple + "'");
608 return 1;
Logan1f028c02010-11-27 01:02:48 +0800609 }
610
Logan Chienda5e0c32011-06-13 03:47:21 +0800611 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800612 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800613 for (llvm::Module::iterator
614 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800615 if (!I->isDeclaration()) {
616 CodeGenPasses->run(*I);
617 }
618 }
619
620 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800621
Logan1f028c02010-11-27 01:02:48 +0800622 // Copy the global address mapping from code emitter and remapping
623 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800624 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
625
Logan1f028c02010-11-27 01:02:48 +0800626 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
627 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
628 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
629 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
630 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
631 llvm::StringRef ExportVarName =
632 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
633
634 CodeEmitter::global_addresses_const_iterator I, E;
635 for (I = mCodeEmitter->global_address_begin(),
636 E = mCodeEmitter->global_address_end();
637 I != E; I++) {
638 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
639 continue;
640 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800641 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700642#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000643 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700644#endif
Logan1f028c02010-11-27 01:02:48 +0800645 break;
646 }
647 }
648 if (I != mCodeEmitter->global_address_end())
649 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800650
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700651#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000652 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800653 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700654#endif
Logan1f028c02010-11-27 01:02:48 +0800655 }
656 }
657 // if reaching here, we know the global variable record in metadata is
658 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800659 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800660 }
Logan2a6dc822011-01-06 04:05:20 +0800661
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700662 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
663 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800664 }
665
666 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800667 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
668
Logan1f028c02010-11-27 01:02:48 +0800669 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
670 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
671 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
672 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
673 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
674 llvm::StringRef ExportFuncName =
675 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800676 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700677#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000678 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800679 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700680#endif
Logan1f028c02010-11-27 01:02:48 +0800681 }
682 }
683 }
684 }
685
686 // Tell code emitter now can release the memory using during the JIT since
687 // we have done the code emission
688 mCodeEmitter->releaseUnnecessary();
689
Logan Chienda5e0c32011-06-13 03:47:21 +0800690 return 0;
Logan1f028c02010-11-27 01:02:48 +0800691}
Logan Chienda5e0c32011-06-13 03:47:21 +0800692#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800693
694
Logan Chienda5e0c32011-06-13 03:47:21 +0800695#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700696int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800697 // Decorate mEmittedELFExecutable with formatted ostream
698 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
699
700 // Relax all machine instructions
701 TM->setMCRelaxAll(/* RelaxAll= */ true);
702
703 // Create MC code generation pass manager
704 llvm::PassManager MCCodeGenPasses;
705
706 // Add TargetData to MC code generation pass manager
707 MCCodeGenPasses.add(TD);
708
709 // Add MC code generation passes to pass manager
710 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800711 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800712 setError("Fail to add passes to emit file");
713 return 1;
714 }
715
716 MCCodeGenPasses.run(*mModule);
717 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800718 return 0;
719}
720#endif // USE_MCJIT
721
Stephen Hinesdb169182012-01-05 18:46:36 -0800722int Compiler::runInternalPasses() {
723 llvm::PassManager BCCPasses;
724
725 // Expand ForEach on CPU path to reduce launch overhead.
726 BCCPasses.add(createForEachExpandPass());
727
728 BCCPasses.run(*mModule);
729
730 return 0;
731}
Logan Chienda5e0c32011-06-13 03:47:21 +0800732
733int Compiler::runLTO(llvm::TargetData *TD,
734 llvm::NamedMDNode const *ExportVarMetadata,
735 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800736 llvm::PassManager LTOPasses;
737
738 // Add TargetData to LTO passes
739 LTOPasses.add(TD);
740
741 // Collect All Exported Symbols
742 std::vector<const char*> ExportSymbols;
743
744 // Note: This is a workaround for getting export variable and function name.
745 // We should refine it soon.
746 if (ExportVarMetadata) {
747 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
748 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
749 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
750 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
751 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
752 llvm::StringRef ExportVarName =
753 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
754 ExportSymbols.push_back(ExportVarName.data());
755 }
756 }
757 }
758 }
759
760 if (ExportFuncMetadata) {
761 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
762 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
763 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
764 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
765 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
766 llvm::StringRef ExportFuncName =
767 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
768 ExportSymbols.push_back(ExportFuncName.data());
769 }
770 }
771 }
772 }
773
Logan Chien7890d432011-08-03 14:55:17 +0800774 // TODO(logan): Remove this after we have finished the
775 // bccMarkExternalSymbol API.
776
Stephen Hines64160102011-09-01 17:30:26 -0700777 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800778 ExportSymbols.push_back("root");
Stephen Hinesdb169182012-01-05 18:46:36 -0800779 ExportSymbols.push_back("root.expand");
Logan Chien4cc00332011-06-12 14:00:46 +0800780 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700781 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800782
Logan Chien7890d432011-08-03 14:55:17 +0800783 // User-defined exporting symbols
784 std::vector<char const *> const &UserDefinedExternalSymbols =
785 mpResult->getUserDefinedExternalSymbols();
786
787 std::copy(UserDefinedExternalSymbols.begin(),
788 UserDefinedExternalSymbols.end(),
789 std::back_inserter(ExportSymbols));
790
Logan Chien4cc00332011-06-12 14:00:46 +0800791 // We now create passes list performing LTO. These are copied from
792 // (including comments) llvm::createStandardLTOPasses().
793
794 // Internalize all other symbols not listed in ExportSymbols
795 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
796
797 // Propagate constants at call sites into the functions they call. This
798 // opens opportunities for globalopt (and inlining) by substituting
799 // function pointers passed as arguments to direct uses of functions.
800 LTOPasses.add(llvm::createIPSCCPPass());
801
802 // Now that we internalized some globals, see if we can hack on them!
803 LTOPasses.add(llvm::createGlobalOptimizerPass());
804
805 // Linking modules together can lead to duplicated global constants, only
806 // keep one copy of each constant...
807 LTOPasses.add(llvm::createConstantMergePass());
808
809 // Remove unused arguments from functions...
810 LTOPasses.add(llvm::createDeadArgEliminationPass());
811
812 // Reduce the code after globalopt and ipsccp. Both can open up
813 // significant simplification opportunities, and both can propagate
814 // functions through function pointers. When this happens, we often have
815 // to resolve varargs calls, etc, so let instcombine do this.
816 LTOPasses.add(llvm::createInstructionCombiningPass());
817
818 // Inline small functions
819 LTOPasses.add(llvm::createFunctionInliningPass());
820
821 // Remove dead EH info.
822 LTOPasses.add(llvm::createPruneEHPass());
823
824 // Internalize the globals again after inlining
825 LTOPasses.add(llvm::createGlobalOptimizerPass());
826
827 // Remove dead functions.
828 LTOPasses.add(llvm::createGlobalDCEPass());
829
830 // If we didn't decide to inline a function, check to see if we can
831 // transform it to pass arguments by value instead of by reference.
832 LTOPasses.add(llvm::createArgumentPromotionPass());
833
834 // The IPO passes may leave cruft around. Clean up after them.
835 LTOPasses.add(llvm::createInstructionCombiningPass());
836 LTOPasses.add(llvm::createJumpThreadingPass());
837
838 // Break up allocas
839 LTOPasses.add(llvm::createScalarReplAggregatesPass());
840
841 // Run a few AA driven optimizations here and now, to cleanup the code.
842 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
843 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
844
845 // Hoist loop invariants.
846 LTOPasses.add(llvm::createLICMPass());
847
848 // Remove redundancies.
849 LTOPasses.add(llvm::createGVNPass());
850
851 // Remove dead memcpys.
852 LTOPasses.add(llvm::createMemCpyOptPass());
853
854 // Nuke dead stores.
855 LTOPasses.add(llvm::createDeadStoreEliminationPass());
856
857 // Cleanup and simplify the code after the scalar optimizations.
858 LTOPasses.add(llvm::createInstructionCombiningPass());
859
860 LTOPasses.add(llvm::createJumpThreadingPass());
861
862 // Delete basic blocks, which optimization passes may have killed.
863 LTOPasses.add(llvm::createCFGSimplificationPass());
864
865 // Now that we have optimized the program, discard unreachable functions.
866 LTOPasses.add(llvm::createGlobalDCEPass());
867
868 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800869
870 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800871}
872
873
Logan Chienda5e0c32011-06-13 03:47:21 +0800874#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800875void *Compiler::getSymbolAddress(char const *name) {
876 return rsloaderGetSymbolAddress(mRSExecutable, name);
877}
878#endif
879
880
881#if USE_MCJIT
882void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
883 Compiler *self = reinterpret_cast<Compiler *>(context);
884
885 if (void *Addr = FindRuntimeFunction(name)) {
886 return Addr;
887 }
888
889 if (self->mpSymbolLookupFn) {
890 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
891 return Addr;
892 }
893 }
894
Steve Block10c14122012-01-08 10:15:06 +0000895 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800896 return NULL;
897}
898#endif
899
900
Logan1f028c02010-11-27 01:02:48 +0800901Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800902#if USE_MCJIT
903 rsloaderDisposeExec(mRSExecutable);
904#endif
905
Logana4994f52010-11-27 14:06:02 +0800906 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800907}
908
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700909
Logan1f028c02010-11-27 01:02:48 +0800910} // namespace bcc