blob: a29980653d95786ec7d7c9dedbdb480754f33842 [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
Stephen Hinesdb169182012-01-05 18:46:36 -08002 * Copyright 2010-2012, The Android Open Source Project
Logan1f028c02010-11-27 01:02:48 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Loganc4395232010-11-27 18:54:17 +080017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/ContextManager.h"
23#endif
24
Logan Chien4885cf82011-07-20 10:18:05 +080025#if USE_DISASSEMBLER
26#include "Disassembler/Disassembler.h"
27#endif
28
Logan4dcd6792011-02-28 05:12:00 +080029#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070030#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080031#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080032#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080033#include "Sha1Helper.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080034#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080035
Shih-wei Liao320b5492011-06-20 22:53:33 -070036#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080037#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070038#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080039
Stephen Hinesdb169182012-01-05 18:46:36 -080040#include "Transforms/BCCTransforms.h"
41
Logandf23afa2010-11-27 11:04:54 +080042#include "llvm/ADT/StringRef.h"
Andrew Hsiehc0554e22012-01-13 22:34:34 -080043#include "llvm/ADT/Triple.h"
Logan1f028c02010-11-27 01:02:48 +080044
Logandf23afa2010-11-27 11:04:54 +080045#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080046
Logan1f028c02010-11-27 01:02:48 +080047#include "llvm/Bitcode/ReaderWriter.h"
48
Logan1f028c02010-11-27 01:02:48 +080049#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080050#include "llvm/CodeGen/RegAllocRegistry.h"
51#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080052
Logan Chien9347e0b2011-07-07 19:51:47 +080053#include "llvm/MC/SubtargetFeature.h"
54
Logandf23afa2010-11-27 11:04:54 +080055#include "llvm/Transforms/IPO.h"
56#include "llvm/Transforms/Scalar.h"
57
Logandf23afa2010-11-27 11:04:54 +080058#include "llvm/Target/TargetData.h"
59#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080060
61#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070062#include "llvm/Support/FormattedStream.h"
Logandf23afa2010-11-27 11:04:54 +080063#include "llvm/Support/MemoryBuffer.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080064#include "llvm/Support/TargetRegistry.h"
65#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080066
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070067#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080068#include "llvm/GlobalValue.h"
69#include "llvm/Linker.h"
70#include "llvm/LLVMContext.h"
71#include "llvm/Metadata.h"
72#include "llvm/Module.h"
73#include "llvm/PassManager.h"
74#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
Logan1f028c02010-11-27 01:02:48 +080089namespace bcc {
90
91//////////////////////////////////////////////////////////////////////////////
92// BCC Compiler Static Variables
93//////////////////////////////////////////////////////////////////////////////
94
95bool Compiler::GlobalInitialized = false;
96
Andrew Hsieh998ec832011-11-21 02:36:11 -080097
98#if !defined(__HOST__)
99 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
100#else
101// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
102 #if defined(__cplusplus)
103 extern "C" {
104 #endif
105 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
106 #if defined(__cplusplus)
107 };
108 #endif
109#endif
110
Logan1f028c02010-11-27 01:02:48 +0800111// Code generation optimization level for the compiler
112llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
113
114std::string Compiler::Triple;
115
116std::string Compiler::CPU;
117
118std::vector<std::string> Compiler::Features;
119
Stephen Hines071288a2011-01-27 14:38:26 -0800120// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800121// slang.cpp)
122const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
123
Stephen Hines071288a2011-01-27 14:38:26 -0800124// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800125// synced with slang_rs_metadata.h)
126const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
127
Stephen Hines071288a2011-01-27 14:38:26 -0800128// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800129// synced with slang_rs_metadata.h)
130const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
131
Stephen Hines071288a2011-01-27 14:38:26 -0800132// Name of metadata node where RS object slot info resides (should be
133// synced with slang_rs_metadata.h)
134const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800135
136//////////////////////////////////////////////////////////////////////////////
137// Compiler
138//////////////////////////////////////////////////////////////////////////////
139
140void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700141 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800142 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700143 }
144
Logan1f028c02010-11-27 01:02:48 +0800145 // if (!llvm::llvm_is_multithreaded())
146 // llvm::llvm_start_multithreaded();
147
148 // Set Triple, CPU and Features here
149 Triple = TARGET_TRIPLE_STRING;
150
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800151 // Determine target_archtype
152#if defined(__HOST__)
153 std::string Err;
154 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
155 llvm::Triple::ArchType target_archtype;
156 if (Target == 0) {
157 target_archtype = llvm::Triple::UnknownArch;
158 } else {
159 const char *target_llvm_name = Target->getName();
160 target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
161 }
162#elif defined(DEFAULT_ARM_CODEGEN)
163 const llvm::Triple::ArchType target_archtype = llvm::Triple::arm;
164#elif defined(DEFAULT_MIPS_CODEGEN)
165 const llvm::Triple::ArchType target_archtype = llvm::Triple::mipsel;
166#elif defined(DEFAULT_X86_CODEGEN)
167 const llvm::Triple::ArchType target_archtype = llvm::Triple::x86;
168#elif defined(DEFAULT_X86_64_CODEGEN)
169 const llvm::Triple::ArchType target_archtype = llvm::Triple::x86_64;
170#else
171 const llvm::Triple::ArchType target_archtype = llvm::Triple::UnknownArch;
172#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800173
Andrew Hsiehe7371e12012-01-14 21:36:49 -0800174 if (target_archtype == llvm::Triple::arm || target_archtype == llvm::Triple::thumb) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800175# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800176 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800177# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800178 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800179# endif
180# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700181
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800182# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800183 Features.push_back("+neon");
184 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800185# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800186 Features.push_back("-neon");
187 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800188# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700189
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800190# if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800191 Features.push_back("-neon");
192 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800193# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800194 }
Joseph Wen51001b82011-06-23 18:56:45 -0700195
Logan Chien3bb77072011-09-17 16:53:53 +0800196#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800197 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800198 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800199 LLVMInitializeARMTargetInfo();
200 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800201#endif
202
Logan Chien21392f02011-11-26 20:32:01 +0800203#if defined(PROVIDE_MIPS_CODEGEN)
204 LLVMInitializeMipsAsmPrinter();
205 LLVMInitializeMipsTargetMC();
206 LLVMInitializeMipsTargetInfo();
207 LLVMInitializeMipsTarget();
208#endif
209
Logan Chien3bb77072011-09-17 16:53:53 +0800210#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800211 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800212 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800213 LLVMInitializeX86TargetInfo();
214 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800215#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800216
217#if USE_DISASSEMBLER
218 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800219#endif
220
221 // -O0: llvm::CodeGenOpt::None
222 // -O1: llvm::CodeGenOpt::Less
223 // -O2: llvm::CodeGenOpt::Default
224 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800225 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800226
Logan1f028c02010-11-27 01:02:48 +0800227 // 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 :
Logan Chiene1bff142011-11-15 15:55:41 +0800236 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800237
Logan35849002011-01-15 07:30:43 +0800238#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700239 // Read in SHA1 checksum of libbcc and libRS.
240 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700241
242 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800243#endif
Logan75cc8a52011-01-07 06:06:52 +0800244
Logan1f028c02010-11-27 01:02:48 +0800245 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);
Steve Block10c14122012-01-08 10:15:06 +0000252 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800253 exit(1);
254}
255
256
Logan Chienda5e0c32011-06-13 03:47:21 +0800257#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800258CodeMemoryManager *Compiler::createCodeMemoryManager() {
259 mCodeMemMgr.reset(new CodeMemoryManager());
260 return mCodeMemMgr.get();
261}
Logan Chienda5e0c32011-06-13 03:47:21 +0800262#endif
Logan1f028c02010-11-27 01:02:48 +0800263
264
Logan Chienda5e0c32011-06-13 03:47:21 +0800265#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800266CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800267 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800268 return mCodeEmitter.get();
269}
Logan Chienda5e0c32011-06-13 03:47:21 +0800270#endif
Logan1f028c02010-11-27 01:02:48 +0800271
272
Logan2a6dc822011-01-06 04:05:20 +0800273Compiler::Compiler(ScriptCompiled *result)
274 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800275#if USE_MCJIT
276 mRSExecutable(NULL),
277#endif
Logan1f028c02010-11-27 01:02:48 +0800278 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
Logan1f028c02010-11-27 01:02:48 +0800289
Logan474cbd22011-01-31 01:47:44 +0800290llvm::Module *Compiler::parseBitcodeFile(llvm::MemoryBuffer *MEM) {
291 llvm::Module *result = llvm::ParseBitcodeFile(MEM, *mContext, &mError);
Logan1f028c02010-11-27 01:02:48 +0800292
Logan474cbd22011-01-31 01:47:44 +0800293 if (!result) {
Steve Block10c14122012-01-08 10:15:06 +0000294 ALOGE("Unable to ParseBitcodeFile: %s\n", mError.c_str());
Logan474cbd22011-01-31 01:47:44 +0800295 return NULL;
Logan1f028c02010-11-27 01:02:48 +0800296 }
297
Logan474cbd22011-01-31 01:47:44 +0800298 return result;
Logan1f028c02010-11-27 01:02:48 +0800299}
300
301
Logan474cbd22011-01-31 01:47:44 +0800302int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800303 if (llvm::Linker::LinkModules(mModule, moduleWith,
304 llvm::Linker::DestroySource,
305 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800306 return hasError();
307 }
308
Logan1f028c02010-11-27 01:02:48 +0800309 // Everything for linking should be settled down here with no error occurs
310 mHasLinked = true;
311 return hasError();
312}
313
314
Zonr Chang2fcbd022012-01-06 21:04:31 +0800315int Compiler::compile(CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800316 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800317 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800318 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800319
Logan1f028c02010-11-27 01:02:48 +0800320 std::string FeaturesStr;
321
Logan Chienda5e0c32011-06-13 03:47:21 +0800322 llvm::NamedMDNode const *PragmaMetadata;
323 llvm::NamedMDNode const *ExportVarMetadata;
324 llvm::NamedMDNode const *ExportFuncMetadata;
325 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800326
Logan1f028c02010-11-27 01:02:48 +0800327 if (mModule == NULL) // No module was loaded
328 return 0;
329
Logan Chienbe81e102011-12-16 13:31:39 +0800330 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800331 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
332 if (hasError())
333 goto on_bcc_compile_error;
334
335 if (!CPU.empty() || !Features.empty()) {
336 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800337
338 for (std::vector<std::string>::const_iterator
339 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800340 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800341 }
342
Logan1f028c02010-11-27 01:02:48 +0800343 FeaturesStr = F.getString();
344 }
345
Zonr Chang2fcbd022012-01-06 21:04:31 +0800346 // Determine if code_model_is_medium
347 // And determine if no_frame_pointer_elimination
348#if defined(__HOST__)
349 bool code_model_is_medium;
350 bool no_frame_pointer_elimination;
Logan Chienbe81e102011-12-16 13:31:39 +0800351
Zonr Chang2fcbd022012-01-06 21:04:31 +0800352 {
353 // open a new scope otherwise compiler complains constructor of the
354 // folloinwg two being bypassed by previous 'goto' statement
355 const char *target_llvm_name = Target->getName();
356 const llvm::Triple::ArchType target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
357 // Data address in X86_64 architecture may reside in a far-away place
358 code_model_is_medium = target_archtype == llvm::Triple::x86_64;
359 // Disable frame pointer elimination optimization for X86_64 and X86
360 no_frame_pointer_elimination = (target_archtype == llvm::Triple::x86_64 ||
361 target_archtype == llvm::Triple::x86);
362 }
363#elif defined(DEFAULT_X86_64_CODEGEN)
364# define code_model_is_medium true
365# define no_frame_pointer_elimination true
366#elif defined(DEFAULT_X86_CODEGEN)
367# define code_model_is_medium false
368# define no_frame_pointer_elimination true
369#else
370# define code_model_is_medium false
371# define no_frame_pointer_elimination false
372#endif
373
374 // Setup LLVM Target Machine Options
375 option.TargetOpt.NoFramePointerElim = no_frame_pointer_elimination;
Logan Chienbe81e102011-12-16 13:31:39 +0800376
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800377 // This is set for the linker (specify how large of the virtual addresses
378 // we can access for all unknown symbols.)
Zonr Chang2fcbd022012-01-06 21:04:31 +0800379 option.CodeModelOpt = code_model_is_medium ? llvm::CodeModel::Medium : llvm::CodeModel::Small;
Logan Chienbe81e102011-12-16 13:31:39 +0800380
381 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800382 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
383 option.TargetOpt,
384 option.RelocModelOpt,
385 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800386
Logan1f028c02010-11-27 01:02:48 +0800387 if (TM == NULL) {
388 setError("Failed to create target machine implementation for the"
389 " specified triple '" + Triple + "'");
390 goto on_bcc_compile_error;
391 }
392
Logan Chienda5e0c32011-06-13 03:47:21 +0800393 // Get target data from Module
394 TD = new llvm::TargetData(mModule);
395
396 // Load named metadata
397 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
398 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
399 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
400 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
401
Stephen Hinesdb169182012-01-05 18:46:36 -0800402 runInternalPasses();
403
Logan Chienda5e0c32011-06-13 03:47:21 +0800404 // Perform link-time optimization if we have multiple modules
405 if (mHasLinked) {
406 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
407 }
408
409 // Perform code generation
410#if USE_OLD_JIT
411 if (runCodeGen(new llvm::TargetData(*TD), TM,
412 ExportVarMetadata, ExportFuncMetadata) != 0) {
413 goto on_bcc_compile_error;
414 }
415#endif
416
417#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700418 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800419 goto on_bcc_compile_error;
420 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800421
Zonr Chang2fcbd022012-01-06 21:04:31 +0800422 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700423 return 0;
424
425 // Load the ELF Object
426 mRSExecutable =
427 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
428 mEmittedELFExecutable.size(),
429 &resolveSymbolAdapter, this);
430
431 if (!mRSExecutable) {
432 setError("Fail to load emitted ELF relocatable file");
433 goto on_bcc_compile_error;
434 }
435
436 if (ExportVarMetadata) {
437 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
438 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
439
440 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
441 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
442 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
443 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
444 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
445 llvm::StringRef ExportVarName =
446 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
447
448 varList.push_back(
449 rsloaderGetSymbolAddress(mRSExecutable,
450 ExportVarName.str().c_str()));
451 varNameList.push_back(ExportVarName.str());
452#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000453 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700454 varList.back());
455#endif
456 continue;
457 }
458 }
459
460 varList.push_back(NULL);
461 }
462 }
463
464 if (ExportFuncMetadata) {
465 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
466 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
467
468 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
469 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
470 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
471 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
472 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
473 llvm::StringRef ExportFuncName =
474 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
475
476 funcList.push_back(
477 rsloaderGetSymbolAddress(mRSExecutable,
478 ExportFuncName.str().c_str()));
479 funcNameList.push_back(ExportFuncName.str());
480#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000481 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700482 funcList.back());
483#endif
484 }
485 }
486 }
487 }
488
Logan Chien4885cf82011-07-20 10:18:05 +0800489#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700490 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700491 // Get MC codegen emitted function name list
492 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
493 std::vector<char const *> func_list(func_list_size, NULL);
494 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700495
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700496 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700497 for (size_t i = 0; i < func_list_size; ++i) {
498 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
499 if (func) {
500 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800501 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
502 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700503 }
504 }
505 }
506#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800507#endif
508
509 // Read pragma information from the metadata node of the module.
510 if (PragmaMetadata) {
511 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
512
513 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
514 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
515 if (Pragma != NULL &&
516 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
517 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
518 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
519
520 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
521 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
522 llvm::StringRef PragmaName =
523 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
524 llvm::StringRef PragmaValue =
525 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
526
527 pragmaList.push_back(
528 std::make_pair(std::string(PragmaName.data(),
529 PragmaName.size()),
530 std::string(PragmaValue.data(),
531 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700532#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000533 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700534 pragmaList.back().first.c_str(),
535 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700536#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800537 }
538 }
539 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800540 }
541
542 if (ObjectSlotMetadata) {
543 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
544
545 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
546 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
547 if (ObjectSlot != NULL &&
548 ObjectSlot->getNumOperands() == 1) {
549 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
550 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
551 llvm::StringRef Slot =
552 static_cast<llvm::MDString*>(SlotMDS)->getString();
553 uint32_t USlot = 0;
554 if (Slot.getAsInteger(10, USlot)) {
555 setError("Non-integer object slot value '" + Slot.str() + "'");
556 goto on_bcc_compile_error;
557 }
558 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700559#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000560 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700561#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800562 }
563 }
564 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800565 }
566
567on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000568 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800569 if (TD) {
570 delete TD;
571 }
572
573 if (TM) {
574 delete TM;
575 }
576
577 if (mError.empty()) {
578 return 0;
579 }
580
Steve Block10c14122012-01-08 10:15:06 +0000581 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800582 return 1;
583}
584
585
586#if USE_OLD_JIT
587int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
588 llvm::NamedMDNode const *ExportVarMetadata,
589 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800590 // Create memory manager for creation of code emitter later.
591 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
592 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800593 return 1;
Logan1f028c02010-11-27 01:02:48 +0800594 }
Logan02286cb2011-01-07 00:30:47 +0800595
596 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800597
598 // Create code emitter
599 if (!mCodeEmitter.get()) {
600 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800601 setError("Failed to create machine code emitter for compilation");
602 return 1;
Logan1f028c02010-11-27 01:02:48 +0800603 }
604 } else {
605 // Reuse the code emitter
606 mCodeEmitter->reset();
607 }
608
609 mCodeEmitter->setTargetMachine(*TM);
610 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
611 mpSymbolLookupContext);
612
Logan1f028c02010-11-27 01:02:48 +0800613 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800614 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
615 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800616
Logan Chienda5e0c32011-06-13 03:47:21 +0800617 // Add TargetData to code generation pass manager
618 CodeGenPasses->add(TD);
619
620 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800621 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
622 *mCodeEmitter,
623 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800624 setError("The machine code emission is not supported on '" + Triple + "'");
625 return 1;
Logan1f028c02010-11-27 01:02:48 +0800626 }
627
Logan Chienda5e0c32011-06-13 03:47:21 +0800628 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800629 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800630 for (llvm::Module::iterator
631 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800632 if (!I->isDeclaration()) {
633 CodeGenPasses->run(*I);
634 }
635 }
636
637 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800638
Logan1f028c02010-11-27 01:02:48 +0800639 // Copy the global address mapping from code emitter and remapping
640 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800641 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
642
Logan1f028c02010-11-27 01:02:48 +0800643 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
644 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
645 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
646 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
647 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
648 llvm::StringRef ExportVarName =
649 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
650
651 CodeEmitter::global_addresses_const_iterator I, E;
652 for (I = mCodeEmitter->global_address_begin(),
653 E = mCodeEmitter->global_address_end();
654 I != E; I++) {
655 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
656 continue;
657 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800658 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700659#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000660 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700661#endif
Logan1f028c02010-11-27 01:02:48 +0800662 break;
663 }
664 }
665 if (I != mCodeEmitter->global_address_end())
666 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800667
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700668#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000669 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800670 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700671#endif
Logan1f028c02010-11-27 01:02:48 +0800672 }
673 }
674 // if reaching here, we know the global variable record in metadata is
675 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800676 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800677 }
Logan2a6dc822011-01-06 04:05:20 +0800678
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700679 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
680 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800681 }
682
683 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800684 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
685
Logan1f028c02010-11-27 01:02:48 +0800686 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
687 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
688 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
689 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
690 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
691 llvm::StringRef ExportFuncName =
692 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800693 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700694#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000695 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800696 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700697#endif
Logan1f028c02010-11-27 01:02:48 +0800698 }
699 }
700 }
701 }
702
703 // Tell code emitter now can release the memory using during the JIT since
704 // we have done the code emission
705 mCodeEmitter->releaseUnnecessary();
706
Logan Chienda5e0c32011-06-13 03:47:21 +0800707 return 0;
Logan1f028c02010-11-27 01:02:48 +0800708}
Logan Chienda5e0c32011-06-13 03:47:21 +0800709#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800710
711
Logan Chienda5e0c32011-06-13 03:47:21 +0800712#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700713int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800714 // Decorate mEmittedELFExecutable with formatted ostream
715 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
716
717 // Relax all machine instructions
718 TM->setMCRelaxAll(/* RelaxAll= */ true);
719
720 // Create MC code generation pass manager
721 llvm::PassManager MCCodeGenPasses;
722
723 // Add TargetData to MC code generation pass manager
724 MCCodeGenPasses.add(TD);
725
726 // Add MC code generation passes to pass manager
727 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800728 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800729 setError("Fail to add passes to emit file");
730 return 1;
731 }
732
733 MCCodeGenPasses.run(*mModule);
734 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800735 return 0;
736}
737#endif // USE_MCJIT
738
Stephen Hinesdb169182012-01-05 18:46:36 -0800739int Compiler::runInternalPasses() {
740 llvm::PassManager BCCPasses;
741
742 // Expand ForEach on CPU path to reduce launch overhead.
743 BCCPasses.add(createForEachExpandPass());
744
745 BCCPasses.run(*mModule);
746
747 return 0;
748}
Logan Chienda5e0c32011-06-13 03:47:21 +0800749
750int Compiler::runLTO(llvm::TargetData *TD,
751 llvm::NamedMDNode const *ExportVarMetadata,
752 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800753 llvm::PassManager LTOPasses;
754
755 // Add TargetData to LTO passes
756 LTOPasses.add(TD);
757
758 // Collect All Exported Symbols
759 std::vector<const char*> ExportSymbols;
760
761 // Note: This is a workaround for getting export variable and function name.
762 // We should refine it soon.
763 if (ExportVarMetadata) {
764 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
765 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
766 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
767 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
768 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
769 llvm::StringRef ExportVarName =
770 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
771 ExportSymbols.push_back(ExportVarName.data());
772 }
773 }
774 }
775 }
776
777 if (ExportFuncMetadata) {
778 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
779 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
780 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
781 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
782 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
783 llvm::StringRef ExportFuncName =
784 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
785 ExportSymbols.push_back(ExportFuncName.data());
786 }
787 }
788 }
789 }
790
Logan Chien7890d432011-08-03 14:55:17 +0800791 // TODO(logan): Remove this after we have finished the
792 // bccMarkExternalSymbol API.
793
Stephen Hines64160102011-09-01 17:30:26 -0700794 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800795 ExportSymbols.push_back("root");
Stephen Hinesdb169182012-01-05 18:46:36 -0800796 ExportSymbols.push_back("root.expand");
Logan Chien4cc00332011-06-12 14:00:46 +0800797 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700798 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800799
Logan Chien7890d432011-08-03 14:55:17 +0800800 // User-defined exporting symbols
801 std::vector<char const *> const &UserDefinedExternalSymbols =
802 mpResult->getUserDefinedExternalSymbols();
803
804 std::copy(UserDefinedExternalSymbols.begin(),
805 UserDefinedExternalSymbols.end(),
806 std::back_inserter(ExportSymbols));
807
Logan Chien4cc00332011-06-12 14:00:46 +0800808 // We now create passes list performing LTO. These are copied from
809 // (including comments) llvm::createStandardLTOPasses().
810
811 // Internalize all other symbols not listed in ExportSymbols
812 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
813
814 // Propagate constants at call sites into the functions they call. This
815 // opens opportunities for globalopt (and inlining) by substituting
816 // function pointers passed as arguments to direct uses of functions.
817 LTOPasses.add(llvm::createIPSCCPPass());
818
819 // Now that we internalized some globals, see if we can hack on them!
820 LTOPasses.add(llvm::createGlobalOptimizerPass());
821
822 // Linking modules together can lead to duplicated global constants, only
823 // keep one copy of each constant...
824 LTOPasses.add(llvm::createConstantMergePass());
825
826 // Remove unused arguments from functions...
827 LTOPasses.add(llvm::createDeadArgEliminationPass());
828
829 // Reduce the code after globalopt and ipsccp. Both can open up
830 // significant simplification opportunities, and both can propagate
831 // functions through function pointers. When this happens, we often have
832 // to resolve varargs calls, etc, so let instcombine do this.
833 LTOPasses.add(llvm::createInstructionCombiningPass());
834
835 // Inline small functions
836 LTOPasses.add(llvm::createFunctionInliningPass());
837
838 // Remove dead EH info.
839 LTOPasses.add(llvm::createPruneEHPass());
840
841 // Internalize the globals again after inlining
842 LTOPasses.add(llvm::createGlobalOptimizerPass());
843
844 // Remove dead functions.
845 LTOPasses.add(llvm::createGlobalDCEPass());
846
847 // If we didn't decide to inline a function, check to see if we can
848 // transform it to pass arguments by value instead of by reference.
849 LTOPasses.add(llvm::createArgumentPromotionPass());
850
851 // The IPO passes may leave cruft around. Clean up after them.
852 LTOPasses.add(llvm::createInstructionCombiningPass());
853 LTOPasses.add(llvm::createJumpThreadingPass());
854
855 // Break up allocas
856 LTOPasses.add(llvm::createScalarReplAggregatesPass());
857
858 // Run a few AA driven optimizations here and now, to cleanup the code.
859 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
860 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
861
862 // Hoist loop invariants.
863 LTOPasses.add(llvm::createLICMPass());
864
865 // Remove redundancies.
866 LTOPasses.add(llvm::createGVNPass());
867
868 // Remove dead memcpys.
869 LTOPasses.add(llvm::createMemCpyOptPass());
870
871 // Nuke dead stores.
872 LTOPasses.add(llvm::createDeadStoreEliminationPass());
873
874 // Cleanup and simplify the code after the scalar optimizations.
875 LTOPasses.add(llvm::createInstructionCombiningPass());
876
877 LTOPasses.add(llvm::createJumpThreadingPass());
878
879 // Delete basic blocks, which optimization passes may have killed.
880 LTOPasses.add(llvm::createCFGSimplificationPass());
881
882 // Now that we have optimized the program, discard unreachable functions.
883 LTOPasses.add(llvm::createGlobalDCEPass());
884
885 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800886
887 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800888}
889
890
Logan Chienda5e0c32011-06-13 03:47:21 +0800891#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800892void *Compiler::getSymbolAddress(char const *name) {
893 return rsloaderGetSymbolAddress(mRSExecutable, name);
894}
895#endif
896
897
898#if USE_MCJIT
899void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
900 Compiler *self = reinterpret_cast<Compiler *>(context);
901
902 if (void *Addr = FindRuntimeFunction(name)) {
903 return Addr;
904 }
905
906 if (self->mpSymbolLookupFn) {
907 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
908 return Addr;
909 }
910 }
911
Steve Block10c14122012-01-08 10:15:06 +0000912 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800913 return NULL;
914}
915#endif
916
917
Logan1f028c02010-11-27 01:02:48 +0800918Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800919 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800920 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800921
Logan Chienda5e0c32011-06-13 03:47:21 +0800922#if USE_MCJIT
923 rsloaderDisposeExec(mRSExecutable);
924#endif
925
Logana4994f52010-11-27 14:06:02 +0800926 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800927}
928
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700929
Logan1f028c02010-11-27 01:02:48 +0800930} // namespace bcc