blob: b35b191ad5a5c1ac36459a09f0d4016f602895fb [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
2 * Copyright 2010, The Android Open Source Project
3 *
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"
Loganeb3d12b2010-12-16 06:20:18 +080034
Shih-wei Liao320b5492011-06-20 22:53:33 -070035#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080036#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070037#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080038
Logandf23afa2010-11-27 11:04:54 +080039#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080040
Logandf23afa2010-11-27 11:04:54 +080041#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080042
Logan1f028c02010-11-27 01:02:48 +080043#include "llvm/Bitcode/ReaderWriter.h"
44
Logan1f028c02010-11-27 01:02:48 +080045#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080046#include "llvm/CodeGen/RegAllocRegistry.h"
47#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080048
Daniel Malea094881f2011-12-14 17:39:16 -050049#include "llvm/MC/MCContext.h"
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"
57#include "llvm/Target/TargetOptions.h"
Logandf23afa2010-11-27 11:04:54 +080058
59#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070060#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080061#include "llvm/Support/MemoryBuffer.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080062#include "llvm/Support/TargetRegistry.h"
63#include "llvm/Support/TargetSelect.h"
Daniel Malea094881f2011-12-14 17:39:16 -050064#include "llvm/Support/raw_ostream.h"
Logandf23afa2010-11-27 11:04:54 +080065
Daniel Malea094881f2011-12-14 17:39:16 -050066#include "llvm/Constants.h"
Logandf23afa2010-11-27 11:04:54 +080067#include "llvm/GlobalValue.h"
68#include "llvm/Linker.h"
69#include "llvm/LLVMContext.h"
70#include "llvm/Metadata.h"
71#include "llvm/Module.h"
72#include "llvm/PassManager.h"
Daniel Malea094881f2011-12-14 17:39:16 -050073#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080074#include "llvm/Value.h"
75
76#include <errno.h>
77#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080078#include <sys/stat.h>
79#include <sys/types.h>
80#include <unistd.h>
81
Logan75cc8a52011-01-07 06:06:52 +080082#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080083
Logan Chien7890d432011-08-03 14:55:17 +080084#include <algorithm>
85#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080086#include <string>
87#include <vector>
Logan1f028c02010-11-27 01:02:48 +080088
Daniel Malea094881f2011-12-14 17:39:16 -050089extern char* gDebugDumpDirectory;
90
Logan1f028c02010-11-27 01:02:48 +080091namespace bcc {
92
93//////////////////////////////////////////////////////////////////////////////
94// BCC Compiler Static Variables
95//////////////////////////////////////////////////////////////////////////////
96
97bool Compiler::GlobalInitialized = false;
98
Logan1f028c02010-11-27 01:02:48 +080099// Code generation optimization level for the compiler
100llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
101
102std::string Compiler::Triple;
103
104std::string Compiler::CPU;
105
106std::vector<std::string> Compiler::Features;
107
Stephen Hines071288a2011-01-27 14:38:26 -0800108// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800109// slang.cpp)
110const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
111
Stephen Hines071288a2011-01-27 14:38:26 -0800112// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800113// synced with slang_rs_metadata.h)
114const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
115
Stephen Hines071288a2011-01-27 14:38:26 -0800116// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800117// synced with slang_rs_metadata.h)
118const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
119
Stephen Hines071288a2011-01-27 14:38:26 -0800120// Name of metadata node where RS object slot info resides (should be
121// synced with slang_rs_metadata.h)
122const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800123
Daniel Malea094881f2011-12-14 17:39:16 -0500124// Name of metadata node where RS optimization level resides (should be
125// synced with slang_rs_metadata.h)
126const llvm::StringRef OptimizationLevelMetadataName = "#optimization_level";
127
128
129
Logan1f028c02010-11-27 01:02:48 +0800130//////////////////////////////////////////////////////////////////////////////
131// Compiler
132//////////////////////////////////////////////////////////////////////////////
133
134void Compiler::GlobalInitialization() {
135 if (GlobalInitialized)
136 return;
Logan1f028c02010-11-27 01:02:48 +0800137 // if (!llvm::llvm_is_multithreaded())
138 // llvm::llvm_start_multithreaded();
139
140 // Set Triple, CPU and Features here
141 Triple = TARGET_TRIPLE_STRING;
142
Logan Chien3bb77072011-09-17 16:53:53 +0800143#if defined(DEFAULT_ARM_CODEGEN)
144
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700145#if defined(ARCH_ARM_HAVE_VFP)
146 Features.push_back("+vfp3");
147#if !defined(ARCH_ARM_HAVE_VFP_D32)
148 Features.push_back("+d16");
149#endif
150#endif
151
Logan Chien3bb77072011-09-17 16:53:53 +0800152 // NOTE: Currently, we have to turn off the support for NEON explicitly.
153 // Since the ARMCodeEmitter.cpp is not ready for JITing NEON
154 // instructions.
155
156 // FIXME: Re-enable NEON when ARMCodeEmitter supports NEON.
157#define USE_ARM_NEON 0
158#if USE_ARM_NEON
Joseph Wen51001b82011-06-23 18:56:45 -0700159 Features.push_back("+neon");
160 Features.push_back("+neonfp");
161#else
Joseph Wen51001b82011-06-23 18:56:45 -0700162 Features.push_back("-neon");
Logan4fe966f2011-02-27 08:26:40 +0800163 Features.push_back("-neonfp");
Logan Chien3bb77072011-09-17 16:53:53 +0800164#endif // USE_ARM_NEON
165#endif // DEFAULT_ARM_CODEGEN
Joseph Wen51001b82011-06-23 18:56:45 -0700166
Logan Chien3bb77072011-09-17 16:53:53 +0800167#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800168 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800169 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800170 LLVMInitializeARMTargetInfo();
171 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800172#endif
173
Logan Chien3bb77072011-09-17 16:53:53 +0800174#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800175 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800176 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800177 LLVMInitializeX86TargetInfo();
178 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800179#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800180
181#if USE_DISASSEMBLER
182 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800183#endif
Logan1f028c02010-11-27 01:02:48 +0800184 // Below are the global settings to LLVM
185
186 // Disable frame pointer elimination optimization
187 llvm::NoFramePointerElim = false;
188
189 // Use hardfloat ABI
190 //
191 // TODO(all): Need to detect the CPU capability and decide whether to use
192 // softfp. To use softfp, change following 2 lines to
193 //
194 // llvm::FloatABIType = llvm::FloatABI::Soft;
195 // llvm::UseSoftFloat = true;
196 //
Shih-wei Liaoe728cb82010-12-15 15:20:47 -0800197 llvm::FloatABIType = llvm::FloatABI::Soft;
Logan1f028c02010-11-27 01:02:48 +0800198 llvm::UseSoftFloat = false;
199
Logan1f028c02010-11-27 01:02:48 +0800200 // Register the scheduler
201 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
202
Logan35849002011-01-15 07:30:43 +0800203#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700204 // Read in SHA1 checksum of libbcc and libRS.
205 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700206
207 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800208#endif
Logan75cc8a52011-01-07 06:06:52 +0800209
Logan1f028c02010-11-27 01:02:48 +0800210 GlobalInitialized = true;
211}
212
213
214void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
215 std::string *Error = static_cast<std::string*>(UserData);
216 Error->assign(Message);
217 LOGE("%s", Message.c_str());
218 exit(1);
219}
220
221
Logan Chienda5e0c32011-06-13 03:47:21 +0800222#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800223CodeMemoryManager *Compiler::createCodeMemoryManager() {
224 mCodeMemMgr.reset(new CodeMemoryManager());
225 return mCodeMemMgr.get();
226}
Logan Chienda5e0c32011-06-13 03:47:21 +0800227#endif
Logan1f028c02010-11-27 01:02:48 +0800228
229
Logan Chienda5e0c32011-06-13 03:47:21 +0800230#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800231CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800232 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800233 return mCodeEmitter.get();
234}
Logan Chienda5e0c32011-06-13 03:47:21 +0800235#endif
Logan1f028c02010-11-27 01:02:48 +0800236
237
Logan2a6dc822011-01-06 04:05:20 +0800238Compiler::Compiler(ScriptCompiled *result)
239 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800240#if USE_MCJIT
241 mRSExecutable(NULL),
242#endif
Logan1f028c02010-11-27 01:02:48 +0800243 mpSymbolLookupFn(NULL),
244 mpSymbolLookupContext(NULL),
245 mContext(NULL),
246 mModule(NULL),
247 mHasLinked(false) /* Turn off linker */ {
248 llvm::remove_fatal_error_handler();
249 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
250 mContext = new llvm::LLVMContext();
251 return;
252}
253
Logan1f028c02010-11-27 01:02:48 +0800254
Logan474cbd22011-01-31 01:47:44 +0800255llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
256 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800257
Logan474cbd22011-01-31 01:47:44 +0800258 if (!result) {
259 LOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
260 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800261 }
262
Logan474cbd22011-01-31 01:47:44 +0800263 return result;
Logan1f028c02010-11-27 01:02:48 +0800264}
265
266
Logan474cbd22011-01-31 01:47:44 +0800267int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800268 if (llvm::Linker::LinkModules(mModule, moduleWith,
269 llvm::Linker::DestroySource,
270 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800271 return hasError();
272 }
273
Logan1f028c02010-11-27 01:02:48 +0800274 // Everything for linking should be settled down here with no error occurs
275 mHasLinked = true;
276 return hasError();
277}
278
279
Joseph Wen34c600a2011-07-25 17:59:17 -0700280int Compiler::compile(bool compileOnly) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800281 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800282 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800283 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800284
Logan1f028c02010-11-27 01:02:48 +0800285 std::string FeaturesStr;
286
Daniel Malea094881f2011-12-14 17:39:16 -0500287 if (mModule == NULL) // No module was loaded
288 return 0;
289
Logan Chienda5e0c32011-06-13 03:47:21 +0800290 llvm::NamedMDNode const *PragmaMetadata;
291 llvm::NamedMDNode const *ExportVarMetadata;
292 llvm::NamedMDNode const *ExportFuncMetadata;
293 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800294
Daniel Malea094881f2011-12-14 17:39:16 -0500295 llvm::NamedMDNode const *OptimizationLevelMetadata =
296 mModule->getNamedMetadata(OptimizationLevelMetadataName);
297
298 // Default to maximum optimization in the absence of named metadata node
299 int OptimizationLevel = 3;
300 if (OptimizationLevelMetadata) {
301 llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
302 OptimizationLevelMetadata->getOperand(0)->getOperand(0));
303 OptimizationLevel = OL->getZExtValue();
304 }
305
306 if (OptimizationLevel == 0) {
307 CodeGenOptLevel = llvm::CodeGenOpt::None;
308 } else if (OptimizationLevel == 1) {
309 CodeGenOptLevel = llvm::CodeGenOpt::Less;
310 } else if (OptimizationLevel == 2) {
311 CodeGenOptLevel = llvm::CodeGenOpt::Default;
312 } else if (OptimizationLevel == 3) {
313 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
314 }
315
316 // not the best place for this, but we need to set the register allocation
317 // policy after we read the optimization_level metadata from the bitcode
318
319 // Register allocation policy:
320 // createFastRegisterAllocator: fast but bad quality
321 // createLinearScanRegisterAllocator: not so fast but good quality
322 llvm::RegisterRegAlloc::setDefault
323 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
324 llvm::createFastRegisterAllocator :
325 llvm::createLinearScanRegisterAllocator);
326
Logan1f028c02010-11-27 01:02:48 +0800327
328 // Create TargetMachine
329 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
330 if (hasError())
331 goto on_bcc_compile_error;
332
333 if (!CPU.empty() || !Features.empty()) {
334 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800335
336 for (std::vector<std::string>::const_iterator
337 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800338 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800339 }
340
Logan1f028c02010-11-27 01:02:48 +0800341 FeaturesStr = F.getString();
342 }
343
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800344#if defined(DEFAULT_X86_64_CODEGEN)
345 // Data address in X86_64 architecture may reside in a far-away place
Logan Chiend3fe15c2011-07-20 22:08:39 +0800346 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800347 llvm::Reloc::Static,
348 llvm::CodeModel::Medium);
349#else
350 // This is set for the linker (specify how large of the virtual addresses
351 // we can access for all unknown symbols.)
352 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
353 llvm::Reloc::Static,
354 llvm::CodeModel::Small);
355#endif
Logan1f028c02010-11-27 01:02:48 +0800356 if (TM == NULL) {
357 setError("Failed to create target machine implementation for the"
358 " specified triple '" + Triple + "'");
359 goto on_bcc_compile_error;
360 }
361
Logan Chienda5e0c32011-06-13 03:47:21 +0800362 // Get target data from Module
363 TD = new llvm::TargetData(mModule);
364
365 // Load named metadata
366 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
367 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
368 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
369 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
370
371 // Perform link-time optimization if we have multiple modules
372 if (mHasLinked) {
Daniel Malea094881f2011-12-14 17:39:16 -0500373 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
374 CodeGenOptLevel);
Logan Chienda5e0c32011-06-13 03:47:21 +0800375 }
376
377 // Perform code generation
378#if USE_OLD_JIT
379 if (runCodeGen(new llvm::TargetData(*TD), TM,
380 ExportVarMetadata, ExportFuncMetadata) != 0) {
381 goto on_bcc_compile_error;
382 }
383#endif
384
385#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700386 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800387 goto on_bcc_compile_error;
388 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800389
Joseph Wen34c600a2011-07-25 17:59:17 -0700390 if (compileOnly)
391 return 0;
392
393 // Load the ELF Object
394 mRSExecutable =
395 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
396 mEmittedELFExecutable.size(),
397 &resolveSymbolAdapter, this);
398
399 if (!mRSExecutable) {
400 setError("Fail to load emitted ELF relocatable file");
401 goto on_bcc_compile_error;
402 }
403
Daniel Malea094881f2011-12-14 17:39:16 -0500404 rsloaderUpdateSectionHeaders(mRSExecutable,
405 (unsigned char*) mEmittedELFExecutable.begin());
406
Joseph Wen34c600a2011-07-25 17:59:17 -0700407 if (ExportVarMetadata) {
408 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
409 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
410
411 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
412 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
413 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
414 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
415 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
416 llvm::StringRef ExportVarName =
417 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
418
419 varList.push_back(
420 rsloaderGetSymbolAddress(mRSExecutable,
421 ExportVarName.str().c_str()));
422 varNameList.push_back(ExportVarName.str());
423#if DEBUG_MCJIT_REFLECT
424 LOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
425 varList.back());
426#endif
427 continue;
428 }
429 }
430
431 varList.push_back(NULL);
432 }
433 }
434
435 if (ExportFuncMetadata) {
436 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
437 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
438
439 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
440 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
441 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
442 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
443 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
444 llvm::StringRef ExportFuncName =
445 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
446
447 funcList.push_back(
448 rsloaderGetSymbolAddress(mRSExecutable,
449 ExportFuncName.str().c_str()));
450 funcNameList.push_back(ExportFuncName.str());
451#if DEBUG_MCJIT_RELECT
452 LOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
453 funcList.back());
454#endif
455 }
456 }
457 }
458 }
459
Logan Chien4885cf82011-07-20 10:18:05 +0800460#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700461 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700462 // Get MC codegen emitted function name list
463 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
464 std::vector<char const *> func_list(func_list_size, NULL);
465 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700466
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700467 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700468 for (size_t i = 0; i < func_list_size; ++i) {
469 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
470 if (func) {
471 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800472 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
473 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700474 }
475 }
476 }
477#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800478#endif
479
480 // Read pragma information from the metadata node of the module.
481 if (PragmaMetadata) {
482 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
483
484 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
485 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
486 if (Pragma != NULL &&
487 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
488 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
489 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
490
491 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
492 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
493 llvm::StringRef PragmaName =
494 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
495 llvm::StringRef PragmaValue =
496 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
497
498 pragmaList.push_back(
499 std::make_pair(std::string(PragmaName.data(),
500 PragmaName.size()),
501 std::string(PragmaValue.data(),
502 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700503#if DEBUG_BCC_REFLECT
504 LOGD("compile(): Pragma: %s -> %s\n",
505 pragmaList.back().first.c_str(),
506 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700507#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800508 }
509 }
510 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800511 }
512
513 if (ObjectSlotMetadata) {
514 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
515
516 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
517 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
518 if (ObjectSlot != NULL &&
519 ObjectSlot->getNumOperands() == 1) {
520 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
521 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
522 llvm::StringRef Slot =
523 static_cast<llvm::MDString*>(SlotMDS)->getString();
524 uint32_t USlot = 0;
525 if (Slot.getAsInteger(10, USlot)) {
526 setError("Non-integer object slot value '" + Slot.str() + "'");
527 goto on_bcc_compile_error;
528 }
529 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700530#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700531 LOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
532#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800533 }
534 }
535 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800536 }
537
538on_bcc_compile_error:
539 // LOGE("on_bcc_compiler_error");
540 if (TD) {
541 delete TD;
542 }
543
544 if (TM) {
545 delete TM;
546 }
547
548 if (mError.empty()) {
549 return 0;
550 }
551
552 // LOGE(getErrorMessage());
553 return 1;
554}
555
556
557#if USE_OLD_JIT
558int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
559 llvm::NamedMDNode const *ExportVarMetadata,
560 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800561 // Create memory manager for creation of code emitter later.
562 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
563 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800564 return 1;
Logan1f028c02010-11-27 01:02:48 +0800565 }
Logan02286cb2011-01-07 00:30:47 +0800566
567 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800568
569 // Create code emitter
570 if (!mCodeEmitter.get()) {
571 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800572 setError("Failed to create machine code emitter for compilation");
573 return 1;
Logan1f028c02010-11-27 01:02:48 +0800574 }
575 } else {
576 // Reuse the code emitter
577 mCodeEmitter->reset();
578 }
579
580 mCodeEmitter->setTargetMachine(*TM);
581 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
582 mpSymbolLookupContext);
583
Logan1f028c02010-11-27 01:02:48 +0800584 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800585 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
586 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800587
Logan Chienda5e0c32011-06-13 03:47:21 +0800588 // Add TargetData to code generation pass manager
589 CodeGenPasses->add(TD);
590
591 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800592 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
593 *mCodeEmitter,
594 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800595 setError("The machine code emission is not supported on '" + Triple + "'");
596 return 1;
Logan1f028c02010-11-27 01:02:48 +0800597 }
598
Logan Chienda5e0c32011-06-13 03:47:21 +0800599 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800600 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800601 for (llvm::Module::iterator
602 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800603 if (!I->isDeclaration()) {
604 CodeGenPasses->run(*I);
605 }
606 }
607
608 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800609
Logan1f028c02010-11-27 01:02:48 +0800610 // Copy the global address mapping from code emitter and remapping
611 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800612 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
613
Logan1f028c02010-11-27 01:02:48 +0800614 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
615 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
616 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
617 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
618 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
619 llvm::StringRef ExportVarName =
620 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
621
622 CodeEmitter::global_addresses_const_iterator I, E;
623 for (I = mCodeEmitter->global_address_begin(),
624 E = mCodeEmitter->global_address_end();
625 I != E; I++) {
626 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
627 continue;
628 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800629 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700630#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700631 LOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
632#endif
Logan1f028c02010-11-27 01:02:48 +0800633 break;
634 }
635 }
636 if (I != mCodeEmitter->global_address_end())
637 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800638
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700639#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700640 LOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800641 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700642#endif
Logan1f028c02010-11-27 01:02:48 +0800643 }
644 }
645 // if reaching here, we know the global variable record in metadata is
646 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800647 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800648 }
Logan2a6dc822011-01-06 04:05:20 +0800649
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700650 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
651 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800652 }
653
654 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800655 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
656
Logan1f028c02010-11-27 01:02:48 +0800657 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
658 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
659 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
660 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
661 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
662 llvm::StringRef ExportFuncName =
663 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800664 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700665#if DEBUG_BCC_REFLECT
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700666 LOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800667 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700668#endif
Logan1f028c02010-11-27 01:02:48 +0800669 }
670 }
671 }
672 }
673
674 // Tell code emitter now can release the memory using during the JIT since
675 // we have done the code emission
676 mCodeEmitter->releaseUnnecessary();
677
Logan Chienda5e0c32011-06-13 03:47:21 +0800678 return 0;
Logan1f028c02010-11-27 01:02:48 +0800679}
Logan Chienda5e0c32011-06-13 03:47:21 +0800680#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800681
682
Logan Chienda5e0c32011-06-13 03:47:21 +0800683#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700684int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800685 // Decorate mEmittedELFExecutable with formatted ostream
686 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
687
688 // Relax all machine instructions
689 TM->setMCRelaxAll(/* RelaxAll= */ true);
690
691 // Create MC code generation pass manager
692 llvm::PassManager MCCodeGenPasses;
693
694 // Add TargetData to MC code generation pass manager
695 MCCodeGenPasses.add(TD);
696
697 // Add MC code generation passes to pass manager
Daniel Malea094881f2011-12-14 17:39:16 -0500698 llvm::MCContext *Ctx = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800699 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS,
700 CodeGenOptLevel, false)) {
701 setError("Fail to add passes to emit file");
702 return 1;
703 }
704
705 MCCodeGenPasses.run(*mModule);
706 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800707 return 0;
708}
709#endif // USE_MCJIT
710
711
712int Compiler::runLTO(llvm::TargetData *TD,
713 llvm::NamedMDNode const *ExportVarMetadata,
Daniel Malea094881f2011-12-14 17:39:16 -0500714 llvm::NamedMDNode const *ExportFuncMetadata,
715 llvm::CodeGenOpt::Level OptimizationLevel) {
Logan Chien4cc00332011-06-12 14:00:46 +0800716 // Collect All Exported Symbols
717 std::vector<const char*> ExportSymbols;
718
719 // Note: This is a workaround for getting export variable and function name.
720 // We should refine it soon.
721 if (ExportVarMetadata) {
722 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
723 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
724 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
725 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
726 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
727 llvm::StringRef ExportVarName =
728 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
729 ExportSymbols.push_back(ExportVarName.data());
730 }
731 }
732 }
733 }
734
735 if (ExportFuncMetadata) {
736 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
737 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
738 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
739 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
740 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
741 llvm::StringRef ExportFuncName =
742 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
743 ExportSymbols.push_back(ExportFuncName.data());
744 }
745 }
746 }
747 }
748
Logan Chien7890d432011-08-03 14:55:17 +0800749 // TODO(logan): Remove this after we have finished the
750 // bccMarkExternalSymbol API.
751
Stephen Hines64160102011-09-01 17:30:26 -0700752 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800753 ExportSymbols.push_back("root");
754 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700755 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800756
Logan Chien7890d432011-08-03 14:55:17 +0800757 // User-defined exporting symbols
758 std::vector<char const *> const &UserDefinedExternalSymbols =
759 mpResult->getUserDefinedExternalSymbols();
760
761 std::copy(UserDefinedExternalSymbols.begin(),
762 UserDefinedExternalSymbols.end(),
763 std::back_inserter(ExportSymbols));
764
Daniel Malea094881f2011-12-14 17:39:16 -0500765 llvm::PassManager LTOPasses;
766
767 // Add TargetData to LTO passes
768 LTOPasses.add(TD);
769
Logan Chien4cc00332011-06-12 14:00:46 +0800770 // We now create passes list performing LTO. These are copied from
771 // (including comments) llvm::createStandardLTOPasses().
Daniel Malea094881f2011-12-14 17:39:16 -0500772 // Only a subset of these LTO passes are enabled in optimization level 0
773 // as they interfere with interactive debugging.
774 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
Logan Chien4cc00332011-06-12 14:00:46 +0800775
Daniel Malea094881f2011-12-14 17:39:16 -0500776 if (OptimizationLevel != llvm::CodeGenOpt::None) {
777 // Internalize all other symbols not listed in ExportSymbols
778 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Logan Chien4cc00332011-06-12 14:00:46 +0800779
Daniel Malea094881f2011-12-14 17:39:16 -0500780 // Propagate constants at call sites into the functions they call. This
781 // opens opportunities for globalopt (and inlining) by substituting
782 // function pointers passed as arguments to direct uses of functions.
783 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800784
Daniel Malea094881f2011-12-14 17:39:16 -0500785 // Now that we internalized some globals, see if we can hack on them!
786 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800787
Daniel Malea094881f2011-12-14 17:39:16 -0500788 // Linking modules together can lead to duplicated global constants, only
789 // keep one copy of each constant...
790 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800791
Daniel Malea094881f2011-12-14 17:39:16 -0500792 // Remove unused arguments from functions...
793 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800794
Daniel Malea094881f2011-12-14 17:39:16 -0500795 // Reduce the code after globalopt and ipsccp. Both can open up
796 // significant simplification opportunities, and both can propagate
797 // functions through function pointers. When this happens, we often have
798 // to resolve varargs calls, etc, so let instcombine do this.
799 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800800
Daniel Malea094881f2011-12-14 17:39:16 -0500801 // Inline small functions
802 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800803
Daniel Malea094881f2011-12-14 17:39:16 -0500804 // Remove dead EH info.
805 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800806
Daniel Malea094881f2011-12-14 17:39:16 -0500807 // Internalize the globals again after inlining
808 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800809
Daniel Malea094881f2011-12-14 17:39:16 -0500810 // Remove dead functions.
811 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800812
Daniel Malea094881f2011-12-14 17:39:16 -0500813 // If we didn't decide to inline a function, check to see if we can
814 // transform it to pass arguments by value instead of by reference.
815 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800816
Daniel Malea094881f2011-12-14 17:39:16 -0500817 // The IPO passes may leave cruft around. Clean up after them.
818 LTOPasses.add(llvm::createInstructionCombiningPass());
819 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800820
Daniel Malea094881f2011-12-14 17:39:16 -0500821 // Break up allocas
822 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800823
Daniel Malea094881f2011-12-14 17:39:16 -0500824 // Run a few AA driven optimizations here and now, to cleanup the code.
825 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
826 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800827
Daniel Malea094881f2011-12-14 17:39:16 -0500828 // Hoist loop invariants.
829 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800830
Daniel Malea094881f2011-12-14 17:39:16 -0500831 // Remove redundancies.
832 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800833
Daniel Malea094881f2011-12-14 17:39:16 -0500834 // Remove dead memcpys.
835 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800836
Daniel Malea094881f2011-12-14 17:39:16 -0500837 // Nuke dead stores.
838 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800839
Daniel Malea094881f2011-12-14 17:39:16 -0500840 // Cleanup and simplify the code after the scalar optimizations.
841 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800842
Daniel Malea094881f2011-12-14 17:39:16 -0500843 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800844
Daniel Malea094881f2011-12-14 17:39:16 -0500845 // Delete basic blocks, which optimization passes may have killed.
846 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800847
Daniel Malea094881f2011-12-14 17:39:16 -0500848 // Now that we have optimized the program, discard unreachable functions.
849 LTOPasses.add(llvm::createGlobalDCEPass());
850
851 } else {
852 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
853 LTOPasses.add(llvm::createGlobalOptimizerPass());
854 LTOPasses.add(llvm::createConstantMergePass());
855 }
Logan Chien4cc00332011-06-12 14:00:46 +0800856
857 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800858
Daniel Malea094881f2011-12-14 17:39:16 -0500859#if ANDROID_ENGINEERING_BUILD
860 if (0 != gDebugDumpDirectory) {
861 std::string errs;
862 std::string Filename(gDebugDumpDirectory);
863 Filename += "/post-lto-module.ll";
864 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
865 mModule->print(FS, 0);
866 FS.close();
867 }
868#endif
869
Logan Chienda5e0c32011-06-13 03:47:21 +0800870 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800871}
872
873
Logan Chienda5e0c32011-06-13 03:47:21 +0800874#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800875void *Compiler::getSymbolAddress(char const *name) {
876 return rsloaderGetSymbolAddress(mRSExecutable, name);
877}
878#endif
879
880
881#if USE_MCJIT
882void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
883 Compiler *self = reinterpret_cast<Compiler *>(context);
884
885 if (void *Addr = FindRuntimeFunction(name)) {
886 return Addr;
887 }
888
889 if (self->mpSymbolLookupFn) {
890 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
891 return Addr;
892 }
893 }
894
895 LOGE("Unable to resolve symbol: %s\n", name);
896 return NULL;
897}
898#endif
899
900
Logan1f028c02010-11-27 01:02:48 +0800901Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800902 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800903 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800904
Logan Chienda5e0c32011-06-13 03:47:21 +0800905#if USE_MCJIT
906 rsloaderDisposeExec(mRSExecutable);
907#endif
908
Logana4994f52010-11-27 14:06:02 +0800909 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800910}
911
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700912
Logan1f028c02010-11-27 01:02:48 +0800913} // namespace bcc