blob: 77f5f51ceb6a03c9142d1eb3ce72b7884f2e8e86 [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"
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
Stephen Hinesdb169182012-01-05 18:46:36 -080039#include "Transforms/BCCTransforms.h"
40
Logandf23afa2010-11-27 11:04:54 +080041#include "llvm/ADT/StringRef.h"
Andrew Hsiehc0554e22012-01-13 22:34:34 -080042#include "llvm/ADT/Triple.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/Bitcode/ReaderWriter.h"
47
Logan1f028c02010-11-27 01:02:48 +080048#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080049#include "llvm/CodeGen/RegAllocRegistry.h"
50#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080051
Logan Chien9347e0b2011-07-07 19:51:47 +080052#include "llvm/MC/SubtargetFeature.h"
53
Logandf23afa2010-11-27 11:04:54 +080054#include "llvm/Transforms/IPO.h"
55#include "llvm/Transforms/Scalar.h"
56
Logandf23afa2010-11-27 11:04:54 +080057#include "llvm/Target/TargetData.h"
58#include "llvm/Target/TargetMachine.h"
59#include "llvm/Target/TargetOptions.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 Hsiehc0554e22012-01-13 22:34:34 -0800174 if (target_archtype == llvm::Triple::arm) {
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700175#if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800176 Features.push_back("+vfp3");
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700177#if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800178 Features.push_back("+d16");
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700179#endif
180#endif
181
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700182#if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800183 Features.push_back("+neon");
184 Features.push_back("+neonfp");
Stephen Hines7f079eb2011-11-09 15:19:03 -0800185#else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800186 Features.push_back("-neon");
187 Features.push_back("-neonfp");
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700188#endif
189
190#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 Liao40bcd662011-10-22 17:51:01 -0700193#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
Joseph Wen34c600a2011-07-25 17:59:17 -0700315int Compiler::compile(bool compileOnly) {
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
Logan Chienbe81e102011-12-16 13:31:39 +0800327 llvm::TargetOptions Options;
328
329 llvm::CodeModel::Model CM;
330 llvm::Reloc::Model RM;
331
Logan1f028c02010-11-27 01:02:48 +0800332 if (mModule == NULL) // No module was loaded
333 return 0;
334
Logan Chienbe81e102011-12-16 13:31:39 +0800335 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800336 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
337 if (hasError())
338 goto on_bcc_compile_error;
339
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800340 // Determine code_model_is_medium
341#if defined(__HOST__)
342 bool code_model_is_medium;
343 bool no_frame_pointer_elimination;
344
345 {
346 // open a new scope otherwise compiler complains constructor of the folloinwg two being bypassed by previous 'goto' statement
347 const char *target_llvm_name = Target->getName();
348 const llvm::Triple::ArchType target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
349 // Data address in X86_64 architecture may reside in a far-away place
350 code_model_is_medium = target_archtype == llvm::Triple::x86_64;
351 // Disable frame pointer elimination optimization for X86_64 and X86
352 no_frame_pointer_elimination = (target_archtype == llvm::Triple::x86_64 ||
353 target_archtype == llvm::Triple::x86);
354 }
355#elif defined(DEFAULT_X86_64_CODEGEN)
356 #define code_model_is_medium true
357 #define no_frame_pointer_elimination true
358#elif defined(DEFAULT_X86_CODEGEN)
359 #define code_model_is_medium false
360 #define no_frame_pointer_elimination true
361#else
362 #define code_model_is_medium false
363 #define no_frame_pointer_elimination false
364#endif
365
Logan1f028c02010-11-27 01:02:48 +0800366 if (!CPU.empty() || !Features.empty()) {
367 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800368
369 for (std::vector<std::string>::const_iterator
370 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800371 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800372 }
373
Logan1f028c02010-11-27 01:02:48 +0800374 FeaturesStr = F.getString();
375 }
376
Logan Chienbe81e102011-12-16 13:31:39 +0800377 // Setup LLVM Target Machine Options
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800378 Options.NoFramePointerElim = no_frame_pointer_elimination;
Logan Chienbe81e102011-12-16 13:31:39 +0800379
380 // Use hardfloat ABI
381 //
382 // TODO(all): Need to detect the CPU capability and decide whether to use
383 // softfp. To use softfp, change following 2 lines to
384 //
385 // options.FloatABIType = llvm::FloatABI::Soft;
386 // options.UseSoftFloat = true;
387 Options.FloatABIType = llvm::FloatABI::Soft;
388 Options.UseSoftFloat = false;
389
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800390 // This is set for the linker (specify how large of the virtual addresses
391 // we can access for all unknown symbols.)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800392 CM = code_model_is_medium? llvm::CodeModel::Medium : llvm::CodeModel::Small;
Logan Chienbe81e102011-12-16 13:31:39 +0800393
394 RM = llvm::Reloc::Static;
395
396 // Create LLVM Target Machine
397 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr, Options, RM, CM);
398
Logan1f028c02010-11-27 01:02:48 +0800399 if (TM == NULL) {
400 setError("Failed to create target machine implementation for the"
401 " specified triple '" + Triple + "'");
402 goto on_bcc_compile_error;
403 }
404
Logan Chienda5e0c32011-06-13 03:47:21 +0800405 // Get target data from Module
406 TD = new llvm::TargetData(mModule);
407
408 // Load named metadata
409 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
410 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
411 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
412 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
413
Stephen Hinesdb169182012-01-05 18:46:36 -0800414 runInternalPasses();
415
Logan Chienda5e0c32011-06-13 03:47:21 +0800416 // Perform link-time optimization if we have multiple modules
417 if (mHasLinked) {
418 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata);
419 }
420
421 // Perform code generation
422#if USE_OLD_JIT
423 if (runCodeGen(new llvm::TargetData(*TD), TM,
424 ExportVarMetadata, ExportFuncMetadata) != 0) {
425 goto on_bcc_compile_error;
426 }
427#endif
428
429#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700430 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800431 goto on_bcc_compile_error;
432 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800433
Joseph Wen34c600a2011-07-25 17:59:17 -0700434 if (compileOnly)
435 return 0;
436
437 // Load the ELF Object
438 mRSExecutable =
439 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
440 mEmittedELFExecutable.size(),
441 &resolveSymbolAdapter, this);
442
443 if (!mRSExecutable) {
444 setError("Fail to load emitted ELF relocatable file");
445 goto on_bcc_compile_error;
446 }
447
448 if (ExportVarMetadata) {
449 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
450 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
451
452 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
453 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
454 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
455 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
456 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
457 llvm::StringRef ExportVarName =
458 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
459
460 varList.push_back(
461 rsloaderGetSymbolAddress(mRSExecutable,
462 ExportVarName.str().c_str()));
463 varNameList.push_back(ExportVarName.str());
464#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000465 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700466 varList.back());
467#endif
468 continue;
469 }
470 }
471
472 varList.push_back(NULL);
473 }
474 }
475
476 if (ExportFuncMetadata) {
477 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
478 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
479
480 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
481 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
482 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
483 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
484 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
485 llvm::StringRef ExportFuncName =
486 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
487
488 funcList.push_back(
489 rsloaderGetSymbolAddress(mRSExecutable,
490 ExportFuncName.str().c_str()));
491 funcNameList.push_back(ExportFuncName.str());
492#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000493 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700494 funcList.back());
495#endif
496 }
497 }
498 }
499 }
500
Logan Chien4885cf82011-07-20 10:18:05 +0800501#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700502 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700503 // Get MC codegen emitted function name list
504 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
505 std::vector<char const *> func_list(func_list_size, NULL);
506 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700507
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700508 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700509 for (size_t i = 0; i < func_list_size; ++i) {
510 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
511 if (func) {
512 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800513 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
514 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700515 }
516 }
517 }
518#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800519#endif
520
521 // Read pragma information from the metadata node of the module.
522 if (PragmaMetadata) {
523 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
524
525 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
526 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
527 if (Pragma != NULL &&
528 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
529 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
530 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
531
532 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
533 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
534 llvm::StringRef PragmaName =
535 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
536 llvm::StringRef PragmaValue =
537 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
538
539 pragmaList.push_back(
540 std::make_pair(std::string(PragmaName.data(),
541 PragmaName.size()),
542 std::string(PragmaValue.data(),
543 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700544#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000545 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700546 pragmaList.back().first.c_str(),
547 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700548#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800549 }
550 }
551 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800552 }
553
554 if (ObjectSlotMetadata) {
555 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
556
557 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
558 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
559 if (ObjectSlot != NULL &&
560 ObjectSlot->getNumOperands() == 1) {
561 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
562 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
563 llvm::StringRef Slot =
564 static_cast<llvm::MDString*>(SlotMDS)->getString();
565 uint32_t USlot = 0;
566 if (Slot.getAsInteger(10, USlot)) {
567 setError("Non-integer object slot value '" + Slot.str() + "'");
568 goto on_bcc_compile_error;
569 }
570 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700571#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000572 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700573#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800574 }
575 }
576 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800577 }
578
579on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000580 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800581 if (TD) {
582 delete TD;
583 }
584
585 if (TM) {
586 delete TM;
587 }
588
589 if (mError.empty()) {
590 return 0;
591 }
592
Steve Block10c14122012-01-08 10:15:06 +0000593 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800594 return 1;
595}
596
597
598#if USE_OLD_JIT
599int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
600 llvm::NamedMDNode const *ExportVarMetadata,
601 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800602 // Create memory manager for creation of code emitter later.
603 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
604 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800605 return 1;
Logan1f028c02010-11-27 01:02:48 +0800606 }
Logan02286cb2011-01-07 00:30:47 +0800607
608 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800609
610 // Create code emitter
611 if (!mCodeEmitter.get()) {
612 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800613 setError("Failed to create machine code emitter for compilation");
614 return 1;
Logan1f028c02010-11-27 01:02:48 +0800615 }
616 } else {
617 // Reuse the code emitter
618 mCodeEmitter->reset();
619 }
620
621 mCodeEmitter->setTargetMachine(*TM);
622 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
623 mpSymbolLookupContext);
624
Logan1f028c02010-11-27 01:02:48 +0800625 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800626 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
627 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800628
Logan Chienda5e0c32011-06-13 03:47:21 +0800629 // Add TargetData to code generation pass manager
630 CodeGenPasses->add(TD);
631
632 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800633 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
634 *mCodeEmitter,
635 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800636 setError("The machine code emission is not supported on '" + Triple + "'");
637 return 1;
Logan1f028c02010-11-27 01:02:48 +0800638 }
639
Logan Chienda5e0c32011-06-13 03:47:21 +0800640 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800641 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800642 for (llvm::Module::iterator
643 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800644 if (!I->isDeclaration()) {
645 CodeGenPasses->run(*I);
646 }
647 }
648
649 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800650
Logan1f028c02010-11-27 01:02:48 +0800651 // Copy the global address mapping from code emitter and remapping
652 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800653 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
654
Logan1f028c02010-11-27 01:02:48 +0800655 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
656 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
657 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
658 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
659 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
660 llvm::StringRef ExportVarName =
661 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
662
663 CodeEmitter::global_addresses_const_iterator I, E;
664 for (I = mCodeEmitter->global_address_begin(),
665 E = mCodeEmitter->global_address_end();
666 I != E; I++) {
667 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
668 continue;
669 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800670 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700671#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000672 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700673#endif
Logan1f028c02010-11-27 01:02:48 +0800674 break;
675 }
676 }
677 if (I != mCodeEmitter->global_address_end())
678 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800679
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700680#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000681 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800682 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700683#endif
Logan1f028c02010-11-27 01:02:48 +0800684 }
685 }
686 // if reaching here, we know the global variable record in metadata is
687 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800688 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800689 }
Logan2a6dc822011-01-06 04:05:20 +0800690
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700691 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
692 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800693 }
694
695 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800696 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
697
Logan1f028c02010-11-27 01:02:48 +0800698 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
699 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
700 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
701 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
702 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
703 llvm::StringRef ExportFuncName =
704 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800705 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700706#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000707 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800708 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700709#endif
Logan1f028c02010-11-27 01:02:48 +0800710 }
711 }
712 }
713 }
714
715 // Tell code emitter now can release the memory using during the JIT since
716 // we have done the code emission
717 mCodeEmitter->releaseUnnecessary();
718
Logan Chienda5e0c32011-06-13 03:47:21 +0800719 return 0;
Logan1f028c02010-11-27 01:02:48 +0800720}
Logan Chienda5e0c32011-06-13 03:47:21 +0800721#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800722
723
Logan Chienda5e0c32011-06-13 03:47:21 +0800724#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700725int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800726 // Decorate mEmittedELFExecutable with formatted ostream
727 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
728
729 // Relax all machine instructions
730 TM->setMCRelaxAll(/* RelaxAll= */ true);
731
732 // Create MC code generation pass manager
733 llvm::PassManager MCCodeGenPasses;
734
735 // Add TargetData to MC code generation pass manager
736 MCCodeGenPasses.add(TD);
737
738 // Add MC code generation passes to pass manager
739 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800740 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800741 setError("Fail to add passes to emit file");
742 return 1;
743 }
744
745 MCCodeGenPasses.run(*mModule);
746 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800747 return 0;
748}
749#endif // USE_MCJIT
750
Stephen Hinesdb169182012-01-05 18:46:36 -0800751int Compiler::runInternalPasses() {
752 llvm::PassManager BCCPasses;
753
754 // Expand ForEach on CPU path to reduce launch overhead.
755 BCCPasses.add(createForEachExpandPass());
756
757 BCCPasses.run(*mModule);
758
759 return 0;
760}
Logan Chienda5e0c32011-06-13 03:47:21 +0800761
762int Compiler::runLTO(llvm::TargetData *TD,
763 llvm::NamedMDNode const *ExportVarMetadata,
764 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan Chien4cc00332011-06-12 14:00:46 +0800765 llvm::PassManager LTOPasses;
766
767 // Add TargetData to LTO passes
768 LTOPasses.add(TD);
769
770 // Collect All Exported Symbols
771 std::vector<const char*> ExportSymbols;
772
773 // Note: This is a workaround for getting export variable and function name.
774 // We should refine it soon.
775 if (ExportVarMetadata) {
776 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
777 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
778 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
779 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
780 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
781 llvm::StringRef ExportVarName =
782 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
783 ExportSymbols.push_back(ExportVarName.data());
784 }
785 }
786 }
787 }
788
789 if (ExportFuncMetadata) {
790 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
791 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
792 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
793 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
794 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
795 llvm::StringRef ExportFuncName =
796 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
797 ExportSymbols.push_back(ExportFuncName.data());
798 }
799 }
800 }
801 }
802
Logan Chien7890d432011-08-03 14:55:17 +0800803 // TODO(logan): Remove this after we have finished the
804 // bccMarkExternalSymbol API.
805
Stephen Hines64160102011-09-01 17:30:26 -0700806 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800807 ExportSymbols.push_back("root");
Stephen Hinesdb169182012-01-05 18:46:36 -0800808 ExportSymbols.push_back("root.expand");
Logan Chien4cc00332011-06-12 14:00:46 +0800809 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700810 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800811
Logan Chien7890d432011-08-03 14:55:17 +0800812 // User-defined exporting symbols
813 std::vector<char const *> const &UserDefinedExternalSymbols =
814 mpResult->getUserDefinedExternalSymbols();
815
816 std::copy(UserDefinedExternalSymbols.begin(),
817 UserDefinedExternalSymbols.end(),
818 std::back_inserter(ExportSymbols));
819
Logan Chien4cc00332011-06-12 14:00:46 +0800820 // We now create passes list performing LTO. These are copied from
821 // (including comments) llvm::createStandardLTOPasses().
822
823 // Internalize all other symbols not listed in ExportSymbols
824 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
825
826 // Propagate constants at call sites into the functions they call. This
827 // opens opportunities for globalopt (and inlining) by substituting
828 // function pointers passed as arguments to direct uses of functions.
829 LTOPasses.add(llvm::createIPSCCPPass());
830
831 // Now that we internalized some globals, see if we can hack on them!
832 LTOPasses.add(llvm::createGlobalOptimizerPass());
833
834 // Linking modules together can lead to duplicated global constants, only
835 // keep one copy of each constant...
836 LTOPasses.add(llvm::createConstantMergePass());
837
838 // Remove unused arguments from functions...
839 LTOPasses.add(llvm::createDeadArgEliminationPass());
840
841 // Reduce the code after globalopt and ipsccp. Both can open up
842 // significant simplification opportunities, and both can propagate
843 // functions through function pointers. When this happens, we often have
844 // to resolve varargs calls, etc, so let instcombine do this.
845 LTOPasses.add(llvm::createInstructionCombiningPass());
846
847 // Inline small functions
848 LTOPasses.add(llvm::createFunctionInliningPass());
849
850 // Remove dead EH info.
851 LTOPasses.add(llvm::createPruneEHPass());
852
853 // Internalize the globals again after inlining
854 LTOPasses.add(llvm::createGlobalOptimizerPass());
855
856 // Remove dead functions.
857 LTOPasses.add(llvm::createGlobalDCEPass());
858
859 // If we didn't decide to inline a function, check to see if we can
860 // transform it to pass arguments by value instead of by reference.
861 LTOPasses.add(llvm::createArgumentPromotionPass());
862
863 // The IPO passes may leave cruft around. Clean up after them.
864 LTOPasses.add(llvm::createInstructionCombiningPass());
865 LTOPasses.add(llvm::createJumpThreadingPass());
866
867 // Break up allocas
868 LTOPasses.add(llvm::createScalarReplAggregatesPass());
869
870 // Run a few AA driven optimizations here and now, to cleanup the code.
871 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
872 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
873
874 // Hoist loop invariants.
875 LTOPasses.add(llvm::createLICMPass());
876
877 // Remove redundancies.
878 LTOPasses.add(llvm::createGVNPass());
879
880 // Remove dead memcpys.
881 LTOPasses.add(llvm::createMemCpyOptPass());
882
883 // Nuke dead stores.
884 LTOPasses.add(llvm::createDeadStoreEliminationPass());
885
886 // Cleanup and simplify the code after the scalar optimizations.
887 LTOPasses.add(llvm::createInstructionCombiningPass());
888
889 LTOPasses.add(llvm::createJumpThreadingPass());
890
891 // Delete basic blocks, which optimization passes may have killed.
892 LTOPasses.add(llvm::createCFGSimplificationPass());
893
894 // Now that we have optimized the program, discard unreachable functions.
895 LTOPasses.add(llvm::createGlobalDCEPass());
896
897 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800898
899 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800900}
901
902
Logan Chienda5e0c32011-06-13 03:47:21 +0800903#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800904void *Compiler::getSymbolAddress(char const *name) {
905 return rsloaderGetSymbolAddress(mRSExecutable, name);
906}
907#endif
908
909
910#if USE_MCJIT
911void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
912 Compiler *self = reinterpret_cast<Compiler *>(context);
913
914 if (void *Addr = FindRuntimeFunction(name)) {
915 return Addr;
916 }
917
918 if (self->mpSymbolLookupFn) {
919 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
920 return Addr;
921 }
922 }
923
Steve Block10c14122012-01-08 10:15:06 +0000924 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800925 return NULL;
926}
927#endif
928
929
Logan1f028c02010-11-27 01:02:48 +0800930Compiler::~Compiler() {
Logan1f028c02010-11-27 01:02:48 +0800931 delete mModule;
Logan1f028c02010-11-27 01:02:48 +0800932 delete mContext;
Logana4994f52010-11-27 14:06:02 +0800933
Logan Chienda5e0c32011-06-13 03:47:21 +0800934#if USE_MCJIT
935 rsloaderDisposeExec(mRSExecutable);
936#endif
937
Logana4994f52010-11-27 14:06:02 +0800938 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800939}
940
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700941
Logan1f028c02010-11-27 01:02:48 +0800942} // namespace bcc