Compiler.cpp revision c0554e25638bec2462daf1a66ed0270a60aec8ea
18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
2dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Copyright 2010-2012, The Android Open Source Project
3dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
4dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Licensed under the Apache License, Version 2.0 (the "License");
5dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * you may not use this file except in compliance with the License.
6dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * You may obtain a copy of the License at
7dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
8dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *     http://www.apache.org/licenses/LICENSE-2.0
9dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch *
10dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * Unless required by applicable law or agreed to in writing, software
11dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * distributed under the License is distributed on an "AS IS" BASIS,
12dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * See the License for the specific language governing permissions and
14dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch * limitations under the License.
15dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch */
16dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
17dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "Compiler.h"
18dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
19dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch#include "Config.h"
20dd8bb3de4f353a81954234999f1fea748aee2ea9Ben Murdoch
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if USE_OLD_JIT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "OldJIT/ContextManager.h"
238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
245f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if USE_DISASSEMBLER
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Disassembler/Disassembler.h"
278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
295abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "DebugHelper.h"
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "FileHandle.h"
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Runtime.h"
32ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "ScriptCompiled.h"
33ca9cb53ed1119a3fd98fafa0972ffeb56dee1c24Steve Block#include "Sha1Helper.h"
34967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
35e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#if USE_MCJIT
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "librsloader.h"
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Transforms/BCCTransforms.h"
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
41f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "llvm/ADT/StringRef.h"
42f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "llvm/ADT/Triple.h"
43f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
44f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch#include "llvm/Analysis/Passes.h"
45f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch
465ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "llvm/Bitcode/ReaderWriter.h"
475ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/CodeGen/Passes.h"
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/CodeGen/RegAllocRegistry.h"
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/CodeGen/SchedulerRegistry.h"
515ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
525ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "llvm/MC/SubtargetFeature.h"
535ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen
545ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "llvm/Transforms/IPO.h"
555ddde30071f639962dd557c453f2ad01f8f0fd00Kristian Monsen#include "llvm/Transforms/Scalar.h"
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/Target/TargetData.h"
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/Target/TargetMachine.h"
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/Target/TargetOptions.h"
608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "llvm/Support/ErrorHandling.h"
62d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Support/FormattedStream.h"
63d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Support/MemoryBuffer.h"
64d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Support/TargetRegistry.h"
65d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Support/TargetSelect.h"
66d0825bca7fe65beaee391d30da42e937db621564Steve Block
67d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Type.h"
68d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/GlobalValue.h"
69d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Linker.h"
70d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/LLVMContext.h"
71d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Metadata.h"
72d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Module.h"
735abb8606fa57c3ebfc8b3c3dbc3fa4a25d2ae306Iain Merrick#include "llvm/PassManager.h"
74d0825bca7fe65beaee391d30da42e937db621564Steve Block#include "llvm/Value.h"
75d0825bca7fe65beaee391d30da42e937db621564Steve Block
76d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <errno.h>
77d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <sys/file.h>
78d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <sys/stat.h>
79e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include <sys/types.h>
808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <unistd.h>
818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
82d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <string.h>
83d0825bca7fe65beaee391d30da42e937db621564Steve Block
84d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <algorithm>
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <iterator>
86d0825bca7fe65beaee391d30da42e937db621564Steve Block#include <string>
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <vector>
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace bcc {
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// BCC Compiler Static Variables
938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project//////////////////////////////////////////////////////////////////////////////
948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Compiler::GlobalInitialized = false;
968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
986b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#if !defined(__HOST__)
996b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner  #define TARGET_TRIPLE_STRING  DEFAULT_TARGET_TRIPLE_STRING
1006b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner#else
1016b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
1026b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner  #if defined(__cplusplus)
1036b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner    extern "C" {
1046b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner  #endif
1056b70adc33054f8aee8c54d0f460458a9df11b8a5Russell Brenner      char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
106d0825bca7fe65beaee391d30da42e937db621564Steve Block  #if defined(__cplusplus)
107d0825bca7fe65beaee391d30da42e937db621564Steve Block    };
108d0825bca7fe65beaee391d30da42e937db621564Steve Block  #endif
109d0825bca7fe65beaee391d30da42e937db621564Steve Block#endif
110d0825bca7fe65beaee391d30da42e937db621564Steve Block
111d0825bca7fe65beaee391d30da42e937db621564Steve Block// Code generation optimization level for the compiler
112d0825bca7fe65beaee391d30da42e937db621564Steve Blockllvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
113d0825bca7fe65beaee391d30da42e937db621564Steve Block
114d0825bca7fe65beaee391d30da42e937db621564Steve Blockstd::string Compiler::Triple;
115d0825bca7fe65beaee391d30da42e937db621564Steve Block
116d0825bca7fe65beaee391d30da42e937db621564Steve Blockstd::string Compiler::CPU;
117d0825bca7fe65beaee391d30da42e937db621564Steve Block
118d0825bca7fe65beaee391d30da42e937db621564Steve Blockstd::vector<std::string> Compiler::Features;
119d0825bca7fe65beaee391d30da42e937db621564Steve Block
120d0825bca7fe65beaee391d30da42e937db621564Steve Block// Name of metadata node where pragma info resides (should be synced with
121d0825bca7fe65beaee391d30da42e937db621564Steve Block// slang.cpp)
122d0825bca7fe65beaee391d30da42e937db621564Steve Blockconst llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
123d0825bca7fe65beaee391d30da42e937db621564Steve Block
124d0825bca7fe65beaee391d30da42e937db621564Steve Block// Name of metadata node where exported variable names reside (should be
1252fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// synced with slang_rs_metadata.h)
1262fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
1272fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1282fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Name of metadata node where exported function names reside (should be
1292fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// synced with slang_rs_metadata.h)
1302fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
1312fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1322fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Name of metadata node where RS object slot info resides (should be
1332fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// synced with slang_rs_metadata.h)
1342fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockconst llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
1352fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1362fc2651226baac27029e38c9d6ef883fa32084dbSteve Block//////////////////////////////////////////////////////////////////////////////
1372fc2651226baac27029e38c9d6ef883fa32084dbSteve Block// Compiler
1382fc2651226baac27029e38c9d6ef883fa32084dbSteve Block//////////////////////////////////////////////////////////////////////////////
1392fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
1405f1ab04193ad0130ca8204aadaceae083aca9881Feng Qianvoid Compiler::GlobalInitialization() {
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  if (GlobalInitialized) {
142967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch    return;
143967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  }
144967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
145967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  // if (!llvm::llvm_is_multithreaded())
146967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  //   llvm::llvm_start_multithreaded();
147967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
148967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  // Set Triple, CPU and Features here
149967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  Triple = TARGET_TRIPLE_STRING;
150967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch
151967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch  // Determine target_archtype
1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if defined(__HOST__)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  std::string Err;
1544576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang  llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  llvm::Triple::ArchType target_archtype;
156d0825bca7fe65beaee391d30da42e937db621564Steve Block  if (Target == 0) {
157d0825bca7fe65beaee391d30da42e937db621564Steve Block    target_archtype = llvm::Triple::UnknownArch;
158d0825bca7fe65beaee391d30da42e937db621564Steve Block  } else {
159dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    const char *target_llvm_name = Target->getName();
160d0825bca7fe65beaee391d30da42e937db621564Steve Block    target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
161d0825bca7fe65beaee391d30da42e937db621564Steve Block  }
162d0825bca7fe65beaee391d30da42e937db621564Steve Block#elif defined(DEFAULT_ARM_CODEGEN)
163dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block  const llvm::Triple::ArchType target_archtype = llvm::Triple::arm;
164d0825bca7fe65beaee391d30da42e937db621564Steve Block#elif defined(DEFAULT_MIPS_CODEGEN)
165d0825bca7fe65beaee391d30da42e937db621564Steve Block  const llvm::Triple::ArchType target_archtype = llvm::Triple::mipsel;
166a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#elif defined(DEFAULT_X86_CODEGEN)
167d0825bca7fe65beaee391d30da42e937db621564Steve Block  const llvm::Triple::ArchType target_archtype = llvm::Triple::x86;
168e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block#elif defined(DEFAULT_X86_64_CODEGEN)
169e8b154fd68f9b33be40a3590e58347f353835f5cSteve Block  const llvm::Triple::ArchType target_archtype = llvm::Triple::x86_64;
170d0825bca7fe65beaee391d30da42e937db621564Steve Block#else
1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  const llvm::Triple::ArchType target_archtype = llvm::Triple::UnknownArch;
1724576aa36e9a9671459299c7963ac95aa94beaea9Shimeng (Simon) Wang#endif
1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project  if (target_archtype == llvm::Triple::arm) {
175635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if defined(ARCH_ARM_HAVE_VFP)
1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Features.push_back("+vfp3");
177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#if !defined(ARCH_ARM_HAVE_VFP_D32)
178635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project    Features.push_back("+d16");
179635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif
1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif
1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#if defined(ARCH_ARM_HAVE_NEON)
1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Features.push_back("+neon");
1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    Features.push_back("+neonfp");
185#else
186    Features.push_back("-neon");
187    Features.push_back("-neonfp");
188#endif
189
190#if defined(DISABLE_ARCH_ARM_HAVE_NEON)
191    Features.push_back("-neon");
192    Features.push_back("-neonfp");
193#endif
194  }
195
196#if defined(PROVIDE_ARM_CODEGEN)
197  LLVMInitializeARMAsmPrinter();
198  LLVMInitializeARMTargetMC();
199  LLVMInitializeARMTargetInfo();
200  LLVMInitializeARMTarget();
201#endif
202
203#if defined(PROVIDE_MIPS_CODEGEN)
204  LLVMInitializeMipsAsmPrinter();
205  LLVMInitializeMipsTargetMC();
206  LLVMInitializeMipsTargetInfo();
207  LLVMInitializeMipsTarget();
208#endif
209
210#if defined(PROVIDE_X86_CODEGEN)
211  LLVMInitializeX86AsmPrinter();
212  LLVMInitializeX86TargetMC();
213  LLVMInitializeX86TargetInfo();
214  LLVMInitializeX86Target();
215#endif
216
217#if USE_DISASSEMBLER
218  InitializeDisassembler();
219#endif
220
221  // -O0: llvm::CodeGenOpt::None
222  // -O1: llvm::CodeGenOpt::Less
223  // -O2: llvm::CodeGenOpt::Default
224  // -O3: llvm::CodeGenOpt::Aggressive
225  CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
226
227  // Register the scheduler
228  llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
229
230  // Register allocation policy:
231  //  createFastRegisterAllocator: fast but bad quality
232  //  createLinearScanRegisterAllocator: not so fast but good quality
233  llvm::RegisterRegAlloc::setDefault
234    ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
235     llvm::createFastRegisterAllocator :
236     llvm::createGreedyRegisterAllocator);
237
238#if USE_CACHE
239  // Read in SHA1 checksum of libbcc and libRS.
240  readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
241
242  calcFileSHA1(sha1LibRS, pathLibRS);
243#endif
244
245  GlobalInitialized = true;
246}
247
248
249void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
250  std::string *Error = static_cast<std::string*>(UserData);
251  Error->assign(Message);
252  ALOGE("%s", Message.c_str());
253  exit(1);
254}
255
256
257#if USE_OLD_JIT
258CodeMemoryManager *Compiler::createCodeMemoryManager() {
259  mCodeMemMgr.reset(new CodeMemoryManager());
260  return mCodeMemMgr.get();
261}
262#endif
263
264
265#if USE_OLD_JIT
266CodeEmitter *Compiler::createCodeEmitter() {
267  mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
268  return mCodeEmitter.get();
269}
270#endif
271
272
273Compiler::Compiler(ScriptCompiled *result)
274  : mpResult(result),
275#if USE_MCJIT
276    mRSExecutable(NULL),
277#endif
278    mpSymbolLookupFn(NULL),
279    mpSymbolLookupContext(NULL),
280    mContext(NULL),
281    mModule(NULL),
282    mHasLinked(false) /* Turn off linker */ {
283  llvm::remove_fatal_error_handler();
284  llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
285  mContext = new llvm::LLVMContext();
286  return;
287}
288
289
290llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
291  llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
292
293  if (!result) {
294    ALOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
295    return NULL;
296  }
297
298  return result;
299}
300
301
302int Compiler::linkModule(llvm::Module *moduleWith) {
303  if (llvm::Linker::LinkModules(mModule, moduleWith,
304                                llvm::Linker::DestroySource,
305                                &mError) != 0) {
306    return hasError();
307  }
308
309  // Everything for linking should be settled down here with no error occurs
310  mHasLinked = true;
311  return hasError();
312}
313
314
315int Compiler::compile(bool compileOnly) {
316  llvm::Target const *Target = NULL;
317  llvm::TargetData *TD = NULL;
318  llvm::TargetMachine *TM = NULL;
319
320  std::string FeaturesStr;
321
322  llvm::NamedMDNode const *PragmaMetadata;
323  llvm::NamedMDNode const *ExportVarMetadata;
324  llvm::NamedMDNode const *ExportFuncMetadata;
325  llvm::NamedMDNode const *ObjectSlotMetadata;
326
327  llvm::TargetOptions Options;
328
329  llvm::CodeModel::Model CM;
330  llvm::Reloc::Model RM;
331
332  if (mModule == NULL)  // No module was loaded
333    return 0;
334
335  // Find LLVM Target
336  Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
337  if (hasError())
338    goto on_bcc_compile_error;
339
340  // Determine code_model_is_medium
341#if defined(__HOST__)
342  bool code_model_is_medium;
343  bool no_frame_pointer_elimination;
344
345  {
346    // open a new scope otherwise compiler complains constructor of the folloinwg two being bypassed by previous 'goto' statement
347    const char *target_llvm_name = Target->getName();
348    const llvm::Triple::ArchType target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
349    // Data address in X86_64 architecture may reside in a far-away place
350    code_model_is_medium = target_archtype == llvm::Triple::x86_64;
351    // Disable frame pointer elimination optimization for X86_64 and X86
352    no_frame_pointer_elimination = (target_archtype == llvm::Triple::x86_64 ||
353                                    target_archtype == llvm::Triple::x86);
354  }
355#elif defined(DEFAULT_X86_64_CODEGEN)
356  #define code_model_is_medium           true
357  #define no_frame_pointer_elimination   true
358#elif defined(DEFAULT_X86_CODEGEN)
359  #define code_model_is_medium           false
360  #define no_frame_pointer_elimination   true
361#else
362  #define code_model_is_medium           false
363  #define no_frame_pointer_elimination   false
364#endif
365
366  if (!CPU.empty() || !Features.empty()) {
367    llvm::SubtargetFeatures F;
368
369    for (std::vector<std::string>::const_iterator
370         I = Features.begin(), E = Features.end(); I != E; I++) {
371      F.AddFeature(*I);
372    }
373
374    FeaturesStr = F.getString();
375  }
376
377  // Setup LLVM Target Machine Options
378  Options.NoFramePointerElim = no_frame_pointer_elimination;
379
380  // Use hardfloat ABI
381  //
382  // TODO(all): Need to detect the CPU capability and decide whether to use
383  // softfp. To use softfp, change following 2 lines to
384  //
385  // options.FloatABIType = llvm::FloatABI::Soft;
386  // options.UseSoftFloat = true;
387  Options.FloatABIType = llvm::FloatABI::Soft;
388  Options.UseSoftFloat = false;
389
390  // This is set for the linker (specify how large of the virtual addresses
391  // we can access for all unknown symbols.)
392  CM = code_model_is_medium? llvm::CodeModel::Medium : llvm::CodeModel::Small;
393
394  RM = llvm::Reloc::Static;
395
396  // Create LLVM Target Machine
397  TM = Target->createTargetMachine(Triple, CPU, FeaturesStr, Options, RM, CM);
398
399  if (TM == NULL) {
400    setError("Failed to create target machine implementation for the"
401             " specified triple '" + Triple + "'");
402    goto on_bcc_compile_error;
403  }
404
405  // Get target data from Module
406  TD = new llvm::TargetData(mModule);
407
408  // Load named metadata
409  ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
410  ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
411  PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
412  ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
413
414  runInternalPasses();
415
416  // Perform link-time optimization if we have multiple modules
417  if (mHasLinked) {
418    runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
419  }
420
421  // Perform code generation
422#if USE_OLD_JIT
423  if (runCodeGen(new llvm::TargetData(*TD), TM,
424                 ExportVarMetadata, ExportFuncMetadata) != 0) {
425    goto on_bcc_compile_error;
426  }
427#endif
428
429#if USE_MCJIT
430  if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
431    goto on_bcc_compile_error;
432  }
433
434  if (compileOnly)
435    return 0;
436
437  // Load the ELF Object
438  mRSExecutable =
439    rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
440                       mEmittedELFExecutable.size(),
441                       &resolveSymbolAdapter, this);
442
443  if (!mRSExecutable) {
444    setError("Fail to load emitted ELF relocatable file");
445    goto on_bcc_compile_error;
446  }
447
448  if (ExportVarMetadata) {
449    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
450    std::vector<std::string> &varNameList = mpResult->mExportVarsName;
451
452    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
453      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
454      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
455        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
456        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
457          llvm::StringRef ExportVarName =
458            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
459
460          varList.push_back(
461            rsloaderGetSymbolAddress(mRSExecutable,
462                                     ExportVarName.str().c_str()));
463          varNameList.push_back(ExportVarName.str());
464#if DEBUG_MCJIT_REFLECT
465          ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
466               varList.back());
467#endif
468          continue;
469        }
470      }
471
472      varList.push_back(NULL);
473    }
474  }
475
476  if (ExportFuncMetadata) {
477    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
478    std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
479
480    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
481      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
482      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
483        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
484        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
485          llvm::StringRef ExportFuncName =
486            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
487
488          funcList.push_back(
489            rsloaderGetSymbolAddress(mRSExecutable,
490                                     ExportFuncName.str().c_str()));
491          funcNameList.push_back(ExportFuncName.str());
492#if DEBUG_MCJIT_RELECT
493          ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
494               funcList.back());
495#endif
496        }
497      }
498    }
499  }
500
501#if DEBUG_MCJIT_DISASSEMBLER
502  {
503    // Get MC codegen emitted function name list
504    size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
505    std::vector<char const *> func_list(func_list_size, NULL);
506    rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
507
508    // Disassemble each function
509    for (size_t i = 0; i < func_list_size; ++i) {
510      void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
511      if (func) {
512        size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
513        Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
514                    Target, TM, func_list[i], (unsigned char const *)func, size);
515      }
516    }
517  }
518#endif
519#endif
520
521  // Read pragma information from the metadata node of the module.
522  if (PragmaMetadata) {
523    ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
524
525    for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
526      llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
527      if (Pragma != NULL &&
528          Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
529        llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
530        llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
531
532        if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
533            (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
534          llvm::StringRef PragmaName =
535            static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
536          llvm::StringRef PragmaValue =
537            static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
538
539          pragmaList.push_back(
540            std::make_pair(std::string(PragmaName.data(),
541                                       PragmaName.size()),
542                           std::string(PragmaValue.data(),
543                                       PragmaValue.size())));
544#if DEBUG_BCC_REFLECT
545          ALOGD("compile(): Pragma: %s -> %s\n",
546               pragmaList.back().first.c_str(),
547               pragmaList.back().second.c_str());
548#endif
549        }
550      }
551    }
552  }
553
554  if (ObjectSlotMetadata) {
555    ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
556
557    for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
558      llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
559      if (ObjectSlot != NULL &&
560          ObjectSlot->getNumOperands() == 1) {
561        llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
562        if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
563          llvm::StringRef Slot =
564              static_cast<llvm::MDString*>(SlotMDS)->getString();
565          uint32_t USlot = 0;
566          if (Slot.getAsInteger(10, USlot)) {
567            setError("Non-integer object slot value '" + Slot.str() + "'");
568            goto on_bcc_compile_error;
569          }
570          objectSlotList.push_back(USlot);
571#if DEBUG_BCC_REFLECT
572          ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
573#endif
574        }
575      }
576    }
577  }
578
579on_bcc_compile_error:
580  // ALOGE("on_bcc_compiler_error");
581  if (TD) {
582    delete TD;
583  }
584
585  if (TM) {
586    delete TM;
587  }
588
589  if (mError.empty()) {
590    return 0;
591  }
592
593  // ALOGE(getErrorMessage());
594  return 1;
595}
596
597
598#if USE_OLD_JIT
599int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
600                         llvm::NamedMDNode const *ExportVarMetadata,
601                         llvm::NamedMDNode const *ExportFuncMetadata) {
602  // Create memory manager for creation of code emitter later.
603  if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
604    setError("Failed to startup memory management for further compilation");
605    return 1;
606  }
607
608  mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
609
610  // Create code emitter
611  if (!mCodeEmitter.get()) {
612    if (!createCodeEmitter()) {
613      setError("Failed to create machine code emitter for compilation");
614      return 1;
615    }
616  } else {
617    // Reuse the code emitter
618    mCodeEmitter->reset();
619  }
620
621  mCodeEmitter->setTargetMachine(*TM);
622  mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
623                                       mpSymbolLookupContext);
624
625  // Create code-gen pass to run the code emitter
626  llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
627    new llvm::FunctionPassManager(mModule));
628
629  // Add TargetData to code generation pass manager
630  CodeGenPasses->add(TD);
631
632  // Add code emit passes
633  if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
634                                     *mCodeEmitter,
635                                     CodeGenOptLevel)) {
636    setError("The machine code emission is not supported on '" + Triple + "'");
637    return 1;
638  }
639
640  // Run the code emitter on every non-declaration function in the module
641  CodeGenPasses->doInitialization();
642  for (llvm::Module::iterator
643       I = mModule->begin(), E = mModule->end(); I != E; I++) {
644    if (!I->isDeclaration()) {
645      CodeGenPasses->run(*I);
646    }
647  }
648
649  CodeGenPasses->doFinalization();
650
651  // Copy the global address mapping from code emitter and remapping
652  if (ExportVarMetadata) {
653    ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
654
655    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
656      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
657      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
658        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
659        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
660          llvm::StringRef ExportVarName =
661            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
662
663          CodeEmitter::global_addresses_const_iterator I, E;
664          for (I = mCodeEmitter->global_address_begin(),
665               E = mCodeEmitter->global_address_end();
666               I != E; I++) {
667            if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
668              continue;
669            if (ExportVarName == I->first->getName()) {
670              varList.push_back(I->second);
671#if DEBUG_BCC_REFLECT
672              ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
673#endif
674              break;
675            }
676          }
677          if (I != mCodeEmitter->global_address_end())
678            continue;  // found
679
680#if DEBUG_BCC_REFLECT
681          ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
682               ExportVarName.str().c_str(), (void *)0);
683#endif
684        }
685      }
686      // if reaching here, we know the global variable record in metadata is
687      // not found. So we make an empty slot
688      varList.push_back(NULL);
689    }
690
691    bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
692              "Number of slots doesn't match the number of export variables!");
693  }
694
695  if (ExportFuncMetadata) {
696    ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
697
698    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
699      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
700      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
701        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
702        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
703          llvm::StringRef ExportFuncName =
704            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
705          funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
706#if DEBUG_BCC_REFLECT
707          ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
708               funcList.back());
709#endif
710        }
711      }
712    }
713  }
714
715  // Tell code emitter now can release the memory using during the JIT since
716  // we have done the code emission
717  mCodeEmitter->releaseUnnecessary();
718
719  return 0;
720}
721#endif // USE_OLD_JIT
722
723
724#if USE_MCJIT
725int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
726  // Decorate mEmittedELFExecutable with formatted ostream
727  llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
728
729  // Relax all machine instructions
730  TM->setMCRelaxAll(/* RelaxAll= */ true);
731
732  // Create MC code generation pass manager
733  llvm::PassManager MCCodeGenPasses;
734
735  // Add TargetData to MC code generation pass manager
736  MCCodeGenPasses.add(TD);
737
738  // Add MC code generation passes to pass manager
739  llvm::MCContext *Ctx;
740  if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
741    setError("Fail to add passes to emit file");
742    return 1;
743  }
744
745  MCCodeGenPasses.run(*mModule);
746  OutSVOS.flush();
747  return 0;
748}
749#endif // USE_MCJIT
750
751int Compiler::runInternalPasses() {
752  llvm::PassManager BCCPasses;
753
754  // Expand ForEach on CPU path to reduce launch overhead.
755  BCCPasses.add(createForEachExpandPass());
756
757  BCCPasses.run(*mModule);
758
759  return 0;
760}
761
762int Compiler::runLTO(llvm::TargetData *TD,
763                     llvm::NamedMDNode const *ExportVarMetadata,
764                     llvm::NamedMDNode const *ExportFuncMetadata) {
765  llvm::PassManager LTOPasses;
766
767  // Add TargetData to LTO passes
768  LTOPasses.add(TD);
769
770  // Collect All Exported Symbols
771  std::vector<const char*> ExportSymbols;
772
773  // Note: This is a workaround for getting export variable and function name.
774  // We should refine it soon.
775  if (ExportVarMetadata) {
776    for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
777      llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
778      if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
779        llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
780        if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
781          llvm::StringRef ExportVarName =
782            static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
783          ExportSymbols.push_back(ExportVarName.data());
784        }
785      }
786    }
787  }
788
789  if (ExportFuncMetadata) {
790    for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
791      llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
792      if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
793        llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
794        if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
795          llvm::StringRef ExportFuncName =
796            static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
797          ExportSymbols.push_back(ExportFuncName.data());
798        }
799      }
800    }
801  }
802
803  // TODO(logan): Remove this after we have finished the
804  // bccMarkExternalSymbol API.
805
806  // root(), init(), and .rs.dtor() are born to be exported
807  ExportSymbols.push_back("root");
808  ExportSymbols.push_back("root.expand");
809  ExportSymbols.push_back("init");
810  ExportSymbols.push_back(".rs.dtor");
811
812  // User-defined exporting symbols
813  std::vector<char const *> const &UserDefinedExternalSymbols =
814    mpResult->getUserDefinedExternalSymbols();
815
816  std::copy(UserDefinedExternalSymbols.begin(),
817            UserDefinedExternalSymbols.end(),
818            std::back_inserter(ExportSymbols));
819
820  // We now create passes list performing LTO. These are copied from
821  // (including comments) llvm::createStandardLTOPasses().
822
823  // Internalize all other symbols not listed in ExportSymbols
824  LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
825
826  // Propagate constants at call sites into the functions they call. This
827  // opens opportunities for globalopt (and inlining) by substituting
828  // function pointers passed as arguments to direct uses of functions.
829  LTOPasses.add(llvm::createIPSCCPPass());
830
831  // Now that we internalized some globals, see if we can hack on them!
832  LTOPasses.add(llvm::createGlobalOptimizerPass());
833
834  // Linking modules together can lead to duplicated global constants, only
835  // keep one copy of each constant...
836  LTOPasses.add(llvm::createConstantMergePass());
837
838  // Remove unused arguments from functions...
839  LTOPasses.add(llvm::createDeadArgEliminationPass());
840
841  // Reduce the code after globalopt and ipsccp. Both can open up
842  // significant simplification opportunities, and both can propagate
843  // functions through function pointers. When this happens, we often have
844  // to resolve varargs calls, etc, so let instcombine do this.
845  LTOPasses.add(llvm::createInstructionCombiningPass());
846
847  // Inline small functions
848  LTOPasses.add(llvm::createFunctionInliningPass());
849
850  // Remove dead EH info.
851  LTOPasses.add(llvm::createPruneEHPass());
852
853  // Internalize the globals again after inlining
854  LTOPasses.add(llvm::createGlobalOptimizerPass());
855
856  // Remove dead functions.
857  LTOPasses.add(llvm::createGlobalDCEPass());
858
859  // If we didn't decide to inline a function, check to see if we can
860  // transform it to pass arguments by value instead of by reference.
861  LTOPasses.add(llvm::createArgumentPromotionPass());
862
863  // The IPO passes may leave cruft around.  Clean up after them.
864  LTOPasses.add(llvm::createInstructionCombiningPass());
865  LTOPasses.add(llvm::createJumpThreadingPass());
866
867  // Break up allocas
868  LTOPasses.add(llvm::createScalarReplAggregatesPass());
869
870  // Run a few AA driven optimizations here and now, to cleanup the code.
871  LTOPasses.add(llvm::createFunctionAttrsPass());  // Add nocapture.
872  LTOPasses.add(llvm::createGlobalsModRefPass());  // IP alias analysis.
873
874  // Hoist loop invariants.
875  LTOPasses.add(llvm::createLICMPass());
876
877  // Remove redundancies.
878  LTOPasses.add(llvm::createGVNPass());
879
880  // Remove dead memcpys.
881  LTOPasses.add(llvm::createMemCpyOptPass());
882
883  // Nuke dead stores.
884  LTOPasses.add(llvm::createDeadStoreEliminationPass());
885
886  // Cleanup and simplify the code after the scalar optimizations.
887  LTOPasses.add(llvm::createInstructionCombiningPass());
888
889  LTOPasses.add(llvm::createJumpThreadingPass());
890
891  // Delete basic blocks, which optimization passes may have killed.
892  LTOPasses.add(llvm::createCFGSimplificationPass());
893
894  // Now that we have optimized the program, discard unreachable functions.
895  LTOPasses.add(llvm::createGlobalDCEPass());
896
897  LTOPasses.run(*mModule);
898
899  return 0;
900}
901
902
903#if USE_MCJIT
904void *Compiler::getSymbolAddress(char const *name) {
905  return rsloaderGetSymbolAddress(mRSExecutable, name);
906}
907#endif
908
909
910#if USE_MCJIT
911void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
912  Compiler *self = reinterpret_cast<Compiler *>(context);
913
914  if (void *Addr = FindRuntimeFunction(name)) {
915    return Addr;
916  }
917
918  if (self->mpSymbolLookupFn) {
919    if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
920      return Addr;
921    }
922  }
923
924  ALOGE("Unable to resolve symbol: %s\n", name);
925  return NULL;
926}
927#endif
928
929
930Compiler::~Compiler() {
931  delete mModule;
932  delete mContext;
933
934#if USE_MCJIT
935  rsloaderDisposeExec(mRSExecutable);
936#endif
937
938  // llvm::llvm_shutdown();
939}
940
941
942}  // namespace bcc
943