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