blob: 45958dc9b2157277fca296507a2fd9b14d9446a5 [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"
Logan1f028c02010-11-27 01:02:48 +080043
Logandf23afa2010-11-27 11:04:54 +080044#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080045
Logan1f028c02010-11-27 01:02:48 +080046#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080047#include "llvm/CodeGen/RegAllocRegistry.h"
48#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080049
Logan Chien9347e0b2011-07-07 19:51:47 +080050#include "llvm/MC/SubtargetFeature.h"
51
Logandf23afa2010-11-27 11:04:54 +080052#include "llvm/Transforms/IPO.h"
53#include "llvm/Transforms/Scalar.h"
54
Logandf23afa2010-11-27 11:04:54 +080055#include "llvm/Target/TargetData.h"
56#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080057
58#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070059#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080060#include "llvm/Support/TargetRegistry.h"
61#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080062
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070063#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080064#include "llvm/GlobalValue.h"
65#include "llvm/Linker.h"
66#include "llvm/LLVMContext.h"
67#include "llvm/Metadata.h"
68#include "llvm/Module.h"
69#include "llvm/PassManager.h"
70#include "llvm/Value.h"
71
72#include <errno.h>
73#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080074#include <sys/stat.h>
75#include <sys/types.h>
76#include <unistd.h>
77
Logan75cc8a52011-01-07 06:06:52 +080078#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080079
Logan Chien7890d432011-08-03 14:55:17 +080080#include <algorithm>
81#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080082#include <string>
83#include <vector>
Logan1f028c02010-11-27 01:02:48 +080084
Logan1f028c02010-11-27 01:02:48 +080085namespace bcc {
86
87//////////////////////////////////////////////////////////////////////////////
88// BCC Compiler Static Variables
89//////////////////////////////////////////////////////////////////////////////
90
91bool Compiler::GlobalInitialized = false;
92
Andrew Hsieh998ec832011-11-21 02:36:11 -080093
94#if !defined(__HOST__)
95 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
96#else
97// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
98 #if defined(__cplusplus)
99 extern "C" {
100 #endif
101 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
102 #if defined(__cplusplus)
103 };
104 #endif
105#endif
106
Logan1f028c02010-11-27 01:02:48 +0800107// Code generation optimization level for the compiler
108llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
109
110std::string Compiler::Triple;
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800111llvm::Triple::ArchType Compiler::ArchType;
Logan1f028c02010-11-27 01:02:48 +0800112
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
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800148 // Determine ArchType
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800149#if defined(__HOST__)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800150 {
151 std::string Err;
152 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
153 if (Target == NULL) {
154 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
155 } else {
156 ArchType = llvm::Triple::UnknownArch;
157 ALOGE("%s", Err.c_str());
158 }
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800159 }
160#elif defined(DEFAULT_ARM_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800161 ArchType = llvm::Triple::arm;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800162#elif defined(DEFAULT_MIPS_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800163 ArchType = llvm::Triple::mipsel;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800164#elif defined(DEFAULT_X86_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800165 ArchType = llvm::Triple::x86;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800166#elif defined(DEFAULT_X86_64_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800167 ArchType = llvm::Triple::x86_64;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800168#else
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800169 ArchType = llvm::Triple::UnknownArch;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800170#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800171
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800172 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800173# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800174 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800175# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800176 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800177# endif
178# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700179
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800180# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800181 Features.push_back("+neon");
182 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800183# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800184 Features.push_back("-neon");
185 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800186# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700187
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800188# if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800189 Features.push_back("-neon");
190 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800191# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800192 }
Joseph Wen51001b82011-06-23 18:56:45 -0700193
Logan Chien3bb77072011-09-17 16:53:53 +0800194#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800195 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800196 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800197 LLVMInitializeARMTargetInfo();
198 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800199#endif
200
Logan Chien21392f02011-11-26 20:32:01 +0800201#if defined(PROVIDE_MIPS_CODEGEN)
202 LLVMInitializeMipsAsmPrinter();
203 LLVMInitializeMipsTargetMC();
204 LLVMInitializeMipsTargetInfo();
205 LLVMInitializeMipsTarget();
206#endif
207
Logan Chien3bb77072011-09-17 16:53:53 +0800208#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800209 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800210 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800211 LLVMInitializeX86TargetInfo();
212 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800213#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800214
215#if USE_DISASSEMBLER
216 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800217#endif
218
219 // -O0: llvm::CodeGenOpt::None
220 // -O1: llvm::CodeGenOpt::Less
221 // -O2: llvm::CodeGenOpt::Default
222 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800223 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800224
Logan1f028c02010-11-27 01:02:48 +0800225 // Register the scheduler
226 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
227
228 // Register allocation policy:
229 // createFastRegisterAllocator: fast but bad quality
230 // createLinearScanRegisterAllocator: not so fast but good quality
231 llvm::RegisterRegAlloc::setDefault
232 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
233 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800234 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800235
Logan35849002011-01-15 07:30:43 +0800236#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700237 // Read in SHA1 checksum of libbcc and libRS.
238 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700239
240 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800241#endif
Logan75cc8a52011-01-07 06:06:52 +0800242
Logan1f028c02010-11-27 01:02:48 +0800243 GlobalInitialized = true;
244}
245
246
247void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
248 std::string *Error = static_cast<std::string*>(UserData);
249 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000250 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800251 exit(1);
252}
253
254
Logan Chienda5e0c32011-06-13 03:47:21 +0800255#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800256CodeMemoryManager *Compiler::createCodeMemoryManager() {
257 mCodeMemMgr.reset(new CodeMemoryManager());
258 return mCodeMemMgr.get();
259}
Logan Chienda5e0c32011-06-13 03:47:21 +0800260#endif
Logan1f028c02010-11-27 01:02:48 +0800261
262
Logan Chienda5e0c32011-06-13 03:47:21 +0800263#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800264CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800265 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800266 return mCodeEmitter.get();
267}
Logan Chienda5e0c32011-06-13 03:47:21 +0800268#endif
Logan1f028c02010-11-27 01:02:48 +0800269
270
Logan2a6dc822011-01-06 04:05:20 +0800271Compiler::Compiler(ScriptCompiled *result)
272 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800273#if USE_MCJIT
274 mRSExecutable(NULL),
275#endif
Logan1f028c02010-11-27 01:02:48 +0800276 mpSymbolLookupFn(NULL),
277 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800278 mModule(NULL),
279 mHasLinked(false) /* Turn off linker */ {
280 llvm::remove_fatal_error_handler();
281 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800282 return;
283}
284
Logan1f028c02010-11-27 01:02:48 +0800285
Logan474cbd22011-01-31 01:47:44 +0800286int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800287 if (llvm::Linker::LinkModules(mModule, moduleWith,
288 llvm::Linker::DestroySource,
289 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800290 return hasError();
291 }
292
Logan1f028c02010-11-27 01:02:48 +0800293 // Everything for linking should be settled down here with no error occurs
294 mHasLinked = true;
295 return hasError();
296}
297
298
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800299int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800300 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800301 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800302 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800303
Logan1f028c02010-11-27 01:02:48 +0800304 std::string FeaturesStr;
305
Logan Chienda5e0c32011-06-13 03:47:21 +0800306 llvm::NamedMDNode const *PragmaMetadata;
307 llvm::NamedMDNode const *ExportVarMetadata;
308 llvm::NamedMDNode const *ExportFuncMetadata;
309 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800310
Logan1f028c02010-11-27 01:02:48 +0800311 if (mModule == NULL) // No module was loaded
312 return 0;
313
Logan Chienbe81e102011-12-16 13:31:39 +0800314 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800315 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
316 if (hasError())
317 goto on_bcc_compile_error;
318
319 if (!CPU.empty() || !Features.empty()) {
320 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800321
322 for (std::vector<std::string>::const_iterator
323 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800324 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800325 }
326
Logan1f028c02010-11-27 01:02:48 +0800327 FeaturesStr = F.getString();
328 }
329
Logan Chienbe81e102011-12-16 13:31:39 +0800330 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800331 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
332 option.TargetOpt,
333 option.RelocModelOpt,
334 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800335
Logan1f028c02010-11-27 01:02:48 +0800336 if (TM == NULL) {
337 setError("Failed to create target machine implementation for the"
338 " specified triple '" + Triple + "'");
339 goto on_bcc_compile_error;
340 }
341
Logan Chienda5e0c32011-06-13 03:47:21 +0800342 // Get target data from Module
343 TD = new llvm::TargetData(mModule);
344
345 // Load named metadata
346 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
347 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
348 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
349 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
350
Stephen Hinesdb169182012-01-05 18:46:36 -0800351 runInternalPasses();
352
Logan Chienda5e0c32011-06-13 03:47:21 +0800353 // Perform link-time optimization if we have multiple modules
354 if (mHasLinked) {
355 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
356 }
357
358 // Perform code generation
359#if USE_OLD_JIT
360 if (runCodeGen(new llvm::TargetData(*TD), TM,
361 ExportVarMetadata, ExportFuncMetadata) != 0) {
362 goto on_bcc_compile_error;
363 }
364#endif
365
366#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700367 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800368 goto on_bcc_compile_error;
369 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800370
Zonr Chang2fcbd022012-01-06 21:04:31 +0800371 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700372 return 0;
373
374 // Load the ELF Object
375 mRSExecutable =
376 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
377 mEmittedELFExecutable.size(),
378 &resolveSymbolAdapter, this);
379
380 if (!mRSExecutable) {
381 setError("Fail to load emitted ELF relocatable file");
382 goto on_bcc_compile_error;
383 }
384
385 if (ExportVarMetadata) {
386 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
387 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
388
389 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
390 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
391 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
392 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
393 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
394 llvm::StringRef ExportVarName =
395 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
396
397 varList.push_back(
398 rsloaderGetSymbolAddress(mRSExecutable,
399 ExportVarName.str().c_str()));
400 varNameList.push_back(ExportVarName.str());
401#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000402 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700403 varList.back());
404#endif
405 continue;
406 }
407 }
408
409 varList.push_back(NULL);
410 }
411 }
412
413 if (ExportFuncMetadata) {
414 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
415 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
416
417 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
418 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
419 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
420 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
421 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
422 llvm::StringRef ExportFuncName =
423 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
424
425 funcList.push_back(
426 rsloaderGetSymbolAddress(mRSExecutable,
427 ExportFuncName.str().c_str()));
428 funcNameList.push_back(ExportFuncName.str());
429#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000430 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700431 funcList.back());
432#endif
433 }
434 }
435 }
436 }
437
Logan Chien4885cf82011-07-20 10:18:05 +0800438#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700439 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700440 // Get MC codegen emitted function name list
441 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
442 std::vector<char const *> func_list(func_list_size, NULL);
443 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700444
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700445 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700446 for (size_t i = 0; i < func_list_size; ++i) {
447 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
448 if (func) {
449 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800450 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
451 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700452 }
453 }
454 }
455#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800456#endif
457
458 // Read pragma information from the metadata node of the module.
459 if (PragmaMetadata) {
460 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
461
462 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
463 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
464 if (Pragma != NULL &&
465 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
466 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
467 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
468
469 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
470 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
471 llvm::StringRef PragmaName =
472 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
473 llvm::StringRef PragmaValue =
474 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
475
476 pragmaList.push_back(
477 std::make_pair(std::string(PragmaName.data(),
478 PragmaName.size()),
479 std::string(PragmaValue.data(),
480 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700481#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000482 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700483 pragmaList.back().first.c_str(),
484 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700485#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800486 }
487 }
488 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800489 }
490
491 if (ObjectSlotMetadata) {
492 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
493
494 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
495 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
496 if (ObjectSlot != NULL &&
497 ObjectSlot->getNumOperands() == 1) {
498 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
499 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
500 llvm::StringRef Slot =
501 static_cast<llvm::MDString*>(SlotMDS)->getString();
502 uint32_t USlot = 0;
503 if (Slot.getAsInteger(10, USlot)) {
504 setError("Non-integer object slot value '" + Slot.str() + "'");
505 goto on_bcc_compile_error;
506 }
507 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700508#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000509 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700510#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800511 }
512 }
513 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800514 }
515
516on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000517 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800518 if (TD) {
519 delete TD;
520 }
521
522 if (TM) {
523 delete TM;
524 }
525
526 if (mError.empty()) {
527 return 0;
528 }
529
Steve Block10c14122012-01-08 10:15:06 +0000530 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800531 return 1;
532}
533
534
535#if USE_OLD_JIT
536int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
537 llvm::NamedMDNode const *ExportVarMetadata,
538 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800539 // Create memory manager for creation of code emitter later.
540 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
541 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800542 return 1;
Logan1f028c02010-11-27 01:02:48 +0800543 }
Logan02286cb2011-01-07 00:30:47 +0800544
545 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800546
547 // Create code emitter
548 if (!mCodeEmitter.get()) {
549 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800550 setError("Failed to create machine code emitter for compilation");
551 return 1;
Logan1f028c02010-11-27 01:02:48 +0800552 }
553 } else {
554 // Reuse the code emitter
555 mCodeEmitter->reset();
556 }
557
558 mCodeEmitter->setTargetMachine(*TM);
559 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
560 mpSymbolLookupContext);
561
Logan1f028c02010-11-27 01:02:48 +0800562 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800563 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
564 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800565
Logan Chienda5e0c32011-06-13 03:47:21 +0800566 // Add TargetData to code generation pass manager
567 CodeGenPasses->add(TD);
568
569 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800570 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
571 *mCodeEmitter,
572 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800573 setError("The machine code emission is not supported on '" + Triple + "'");
574 return 1;
Logan1f028c02010-11-27 01:02:48 +0800575 }
576
Logan Chienda5e0c32011-06-13 03:47:21 +0800577 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800578 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800579 for (llvm::Module::iterator
580 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800581 if (!I->isDeclaration()) {
582 CodeGenPasses->run(*I);
583 }
584 }
585
586 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800587
Logan1f028c02010-11-27 01:02:48 +0800588 // Copy the global address mapping from code emitter and remapping
589 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800590 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
591
Logan1f028c02010-11-27 01:02:48 +0800592 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
593 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
594 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
595 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
596 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
597 llvm::StringRef ExportVarName =
598 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
599
600 CodeEmitter::global_addresses_const_iterator I, E;
601 for (I = mCodeEmitter->global_address_begin(),
602 E = mCodeEmitter->global_address_end();
603 I != E; I++) {
604 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
605 continue;
606 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800607 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700608#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000609 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700610#endif
Logan1f028c02010-11-27 01:02:48 +0800611 break;
612 }
613 }
614 if (I != mCodeEmitter->global_address_end())
615 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800616
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700617#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000618 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800619 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700620#endif
Logan1f028c02010-11-27 01:02:48 +0800621 }
622 }
623 // if reaching here, we know the global variable record in metadata is
624 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800625 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800626 }
Logan2a6dc822011-01-06 04:05:20 +0800627
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700628 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
629 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800630 }
631
632 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800633 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
634
Logan1f028c02010-11-27 01:02:48 +0800635 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
636 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
637 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
638 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
639 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
640 llvm::StringRef ExportFuncName =
641 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800642 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700643#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000644 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800645 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700646#endif
Logan1f028c02010-11-27 01:02:48 +0800647 }
648 }
649 }
650 }
651
652 // Tell code emitter now can release the memory using during the JIT since
653 // we have done the code emission
654 mCodeEmitter->releaseUnnecessary();
655
Logan Chienda5e0c32011-06-13 03:47:21 +0800656 return 0;
Logan1f028c02010-11-27 01:02:48 +0800657}
Logan Chienda5e0c32011-06-13 03:47:21 +0800658#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800659
660
Logan Chienda5e0c32011-06-13 03:47:21 +0800661#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700662int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800663 // Decorate mEmittedELFExecutable with formatted ostream
664 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
665
666 // Relax all machine instructions
667 TM->setMCRelaxAll(/* RelaxAll= */ true);
668
669 // Create MC code generation pass manager
670 llvm::PassManager MCCodeGenPasses;
671
672 // Add TargetData to MC code generation pass manager
673 MCCodeGenPasses.add(TD);
674
675 // Add MC code generation passes to pass manager
676 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800677 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800678 setError("Fail to add passes to emit file");
679 return 1;
680 }
681
682 MCCodeGenPasses.run(*mModule);
683 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800684 return 0;
685}
686#endif // USE_MCJIT
687
Stephen Hinesdb169182012-01-05 18:46:36 -0800688int Compiler::runInternalPasses() {
689 llvm::PassManager BCCPasses;
690
691 // Expand ForEach on CPU path to reduce launch overhead.
692 BCCPasses.add(createForEachExpandPass());
693
694 BCCPasses.run(*mModule);
695
696 return 0;
697}
Logan Chienda5e0c32011-06-13 03:47:21 +0800698
699int Compiler::runLTO(llvm::TargetData *TD,
700 llvm::NamedMDNode const *ExportVarMetadata,
701 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800702 llvm::PassManager LTOPasses;
703
704 // Add TargetData to LTO passes
705 LTOPasses.add(TD);
706
707 // Collect All Exported Symbols
708 std::vector<const char*> ExportSymbols;
709
710 // Note: This is a workaround for getting export variable and function name.
711 // We should refine it soon.
712 if (ExportVarMetadata) {
713 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
714 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
715 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
716 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
717 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
718 llvm::StringRef ExportVarName =
719 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
720 ExportSymbols.push_back(ExportVarName.data());
721 }
722 }
723 }
724 }
725
726 if (ExportFuncMetadata) {
727 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
728 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
729 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
730 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
731 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
732 llvm::StringRef ExportFuncName =
733 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
734 ExportSymbols.push_back(ExportFuncName.data());
735 }
736 }
737 }
738 }
739
Logan Chien7890d432011-08-03 14:55:17 +0800740 // TODO(logan): Remove this after we have finished the
741 // bccMarkExternalSymbol API.
742
Stephen Hines64160102011-09-01 17:30:26 -0700743 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800744 ExportSymbols.push_back("root");
Stephen Hinesdb169182012-01-05 18:46:36 -0800745 ExportSymbols.push_back("root.expand");
Logan Chien4cc00332011-06-12 14:00:46 +0800746 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700747 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800748
Logan Chien7890d432011-08-03 14:55:17 +0800749 // User-defined exporting symbols
750 std::vector<char const *> const &UserDefinedExternalSymbols =
751 mpResult->getUserDefinedExternalSymbols();
752
753 std::copy(UserDefinedExternalSymbols.begin(),
754 UserDefinedExternalSymbols.end(),
755 std::back_inserter(ExportSymbols));
756
Logan Chien4cc00332011-06-12 14:00:46 +0800757 // We now create passes list performing LTO. These are copied from
758 // (including comments) llvm::createStandardLTOPasses().
759
760 // Internalize all other symbols not listed in ExportSymbols
761 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
762
763 // Propagate constants at call sites into the functions they call. This
764 // opens opportunities for globalopt (and inlining) by substituting
765 // function pointers passed as arguments to direct uses of functions.
766 LTOPasses.add(llvm::createIPSCCPPass());
767
768 // Now that we internalized some globals, see if we can hack on them!
769 LTOPasses.add(llvm::createGlobalOptimizerPass());
770
771 // Linking modules together can lead to duplicated global constants, only
772 // keep one copy of each constant...
773 LTOPasses.add(llvm::createConstantMergePass());
774
775 // Remove unused arguments from functions...
776 LTOPasses.add(llvm::createDeadArgEliminationPass());
777
778 // Reduce the code after globalopt and ipsccp. Both can open up
779 // significant simplification opportunities, and both can propagate
780 // functions through function pointers. When this happens, we often have
781 // to resolve varargs calls, etc, so let instcombine do this.
782 LTOPasses.add(llvm::createInstructionCombiningPass());
783
784 // Inline small functions
785 LTOPasses.add(llvm::createFunctionInliningPass());
786
787 // Remove dead EH info.
788 LTOPasses.add(llvm::createPruneEHPass());
789
790 // Internalize the globals again after inlining
791 LTOPasses.add(llvm::createGlobalOptimizerPass());
792
793 // Remove dead functions.
794 LTOPasses.add(llvm::createGlobalDCEPass());
795
796 // If we didn't decide to inline a function, check to see if we can
797 // transform it to pass arguments by value instead of by reference.
798 LTOPasses.add(llvm::createArgumentPromotionPass());
799
800 // The IPO passes may leave cruft around. Clean up after them.
801 LTOPasses.add(llvm::createInstructionCombiningPass());
802 LTOPasses.add(llvm::createJumpThreadingPass());
803
804 // Break up allocas
805 LTOPasses.add(llvm::createScalarReplAggregatesPass());
806
807 // Run a few AA driven optimizations here and now, to cleanup the code.
808 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
809 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
810
811 // Hoist loop invariants.
812 LTOPasses.add(llvm::createLICMPass());
813
814 // Remove redundancies.
815 LTOPasses.add(llvm::createGVNPass());
816
817 // Remove dead memcpys.
818 LTOPasses.add(llvm::createMemCpyOptPass());
819
820 // Nuke dead stores.
821 LTOPasses.add(llvm::createDeadStoreEliminationPass());
822
823 // Cleanup and simplify the code after the scalar optimizations.
824 LTOPasses.add(llvm::createInstructionCombiningPass());
825
826 LTOPasses.add(llvm::createJumpThreadingPass());
827
828 // Delete basic blocks, which optimization passes may have killed.
829 LTOPasses.add(llvm::createCFGSimplificationPass());
830
831 // Now that we have optimized the program, discard unreachable functions.
832 LTOPasses.add(llvm::createGlobalDCEPass());
833
834 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800835
836 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800837}
838
839
Logan Chienda5e0c32011-06-13 03:47:21 +0800840#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800841void *Compiler::getSymbolAddress(char const *name) {
842 return rsloaderGetSymbolAddress(mRSExecutable, name);
843}
844#endif
845
846
847#if USE_MCJIT
848void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
849 Compiler *self = reinterpret_cast<Compiler *>(context);
850
851 if (void *Addr = FindRuntimeFunction(name)) {
852 return Addr;
853 }
854
855 if (self->mpSymbolLookupFn) {
856 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
857 return Addr;
858 }
859 }
860
Steve Block10c14122012-01-08 10:15:06 +0000861 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800862 return NULL;
863}
864#endif
865
866
Logan1f028c02010-11-27 01:02:48 +0800867Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800868#if USE_MCJIT
869 rsloaderDisposeExec(mRSExecutable);
870#endif
871
Logana4994f52010-11-27 14:06:02 +0800872 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800873}
874
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700875
Logan1f028c02010-11-27 01:02:48 +0800876} // namespace bcc