blob: cee5daa8af4a4af0d604f7e7155606fa982cec5f [file] [log] [blame]
Logan1f028c02010-11-27 01:02:48 +08001/*
Stephen Hinesdb169182012-01-05 18:46:36 -08002 * Copyright 2010-2012, The Android Open Source Project
Logan1f028c02010-11-27 01:02:48 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Loganc4395232010-11-27 18:54:17 +080017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Logan35849002011-01-15 07:30:43 +080019#include "Config.h"
20
Logan Chiend2a5f302011-07-19 20:32:25 +080021#if USE_OLD_JIT
22#include "OldJIT/ContextManager.h"
23#endif
24
Logan Chien4885cf82011-07-20 10:18:05 +080025#if USE_DISASSEMBLER
26#include "Disassembler/Disassembler.h"
27#endif
28
Logan4dcd6792011-02-28 05:12:00 +080029#include "DebugHelper.h"
Shih-wei Liao6c0c7b02011-05-21 21:47:14 -070030#include "FileHandle.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080031#include "Runtime.h"
Logan2a6dc822011-01-06 04:05:20 +080032#include "ScriptCompiled.h"
Logan75cc8a52011-01-07 06:06:52 +080033#include "Sha1Helper.h"
Zonr Chang2fcbd022012-01-06 21:04:31 +080034#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080035
Shih-wei Liao320b5492011-06-20 22:53:33 -070036#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +080037#include "librsloader.h"
Shih-wei Liao320b5492011-06-20 22:53:33 -070038#endif
Logan Chienda5e0c32011-06-13 03:47:21 +080039
Stephen Hinesdb169182012-01-05 18:46:36 -080040#include "Transforms/BCCTransforms.h"
41
Logandf23afa2010-11-27 11:04:54 +080042#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080043
Logandf23afa2010-11-27 11:04:54 +080044#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080045
Logan1f028c02010-11-27 01:02:48 +080046#include "llvm/CodeGen/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080047#include "llvm/CodeGen/RegAllocRegistry.h"
48#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080049
Logan Chien9347e0b2011-07-07 19:51:47 +080050#include "llvm/MC/SubtargetFeature.h"
51
Logandf23afa2010-11-27 11:04:54 +080052#include "llvm/Transforms/IPO.h"
53#include "llvm/Transforms/Scalar.h"
54
Logandf23afa2010-11-27 11:04:54 +080055#include "llvm/Target/TargetData.h"
56#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080057
58#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070059#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080060#include "llvm/Support/TargetRegistry.h"
61#include "llvm/Support/TargetSelect.h"
Logandf23afa2010-11-27 11:04:54 +080062
Shih-wei Liao90cd3d12011-06-20 15:43:34 -070063#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080064#include "llvm/GlobalValue.h"
65#include "llvm/Linker.h"
66#include "llvm/LLVMContext.h"
67#include "llvm/Metadata.h"
68#include "llvm/Module.h"
69#include "llvm/PassManager.h"
70#include "llvm/Value.h"
71
72#include <errno.h>
73#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080074#include <sys/stat.h>
75#include <sys/types.h>
76#include <unistd.h>
77
Logan75cc8a52011-01-07 06:06:52 +080078#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080079
Logan Chien7890d432011-08-03 14:55:17 +080080#include <algorithm>
81#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080082#include <string>
83#include <vector>
Logan1f028c02010-11-27 01:02:48 +080084
Logan1f028c02010-11-27 01:02:48 +080085namespace bcc {
86
87//////////////////////////////////////////////////////////////////////////////
88// BCC Compiler Static Variables
89//////////////////////////////////////////////////////////////////////////////
90
91bool Compiler::GlobalInitialized = false;
92
Andrew Hsieh998ec832011-11-21 02:36:11 -080093
94#if !defined(__HOST__)
95 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
96#else
97// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
98 #if defined(__cplusplus)
99 extern "C" {
100 #endif
101 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
102 #if defined(__cplusplus)
103 };
104 #endif
105#endif
106
Logan1f028c02010-11-27 01:02:48 +0800107// Code generation optimization level for the compiler
108llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
109
110std::string Compiler::Triple;
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800111llvm::Triple::ArchType Compiler::ArchType;
Logan1f028c02010-11-27 01:02:48 +0800112
113std::string Compiler::CPU;
114
115std::vector<std::string> Compiler::Features;
116
Stephen Hines071288a2011-01-27 14:38:26 -0800117// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800118// slang.cpp)
119const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
120
Stephen Hines071288a2011-01-27 14:38:26 -0800121// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800122// synced with slang_rs_metadata.h)
123const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
124
Stephen Hines071288a2011-01-27 14:38:26 -0800125// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800126// synced with slang_rs_metadata.h)
127const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
128
Stephen Hinescc366e52012-02-21 17:22:04 -0800129// Name of metadata node where exported ForEach name information resides
130// (should be synced with slang_rs_metadata.h)
131const llvm::StringRef Compiler::ExportForEachNameMetadataName =
132 "#rs_export_foreach_name";
133
134// Name of metadata node where exported ForEach signature information resides
135// (should be synced with slang_rs_metadata.h)
136const llvm::StringRef Compiler::ExportForEachMetadataName =
137 "#rs_export_foreach";
138
Stephen Hines071288a2011-01-27 14:38:26 -0800139// Name of metadata node where RS object slot info resides (should be
140// synced with slang_rs_metadata.h)
141const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800142
143//////////////////////////////////////////////////////////////////////////////
144// Compiler
145//////////////////////////////////////////////////////////////////////////////
146
147void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700148 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800149 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700150 }
151
Logan1f028c02010-11-27 01:02:48 +0800152 // if (!llvm::llvm_is_multithreaded())
153 // llvm::llvm_start_multithreaded();
154
155 // Set Triple, CPU and Features here
156 Triple = TARGET_TRIPLE_STRING;
157
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800158 // Determine ArchType
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800159#if defined(__HOST__)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800160 {
161 std::string Err;
162 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
Stephen Hinescc366e52012-02-21 17:22:04 -0800163 if (Target != NULL) {
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800164 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
165 } else {
166 ArchType = llvm::Triple::UnknownArch;
167 ALOGE("%s", Err.c_str());
168 }
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800169 }
170#elif defined(DEFAULT_ARM_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800171 ArchType = llvm::Triple::arm;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800172#elif defined(DEFAULT_MIPS_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800173 ArchType = llvm::Triple::mipsel;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800174#elif defined(DEFAULT_X86_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800175 ArchType = llvm::Triple::x86;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800176#elif defined(DEFAULT_X86_64_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800177 ArchType = llvm::Triple::x86_64;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800178#else
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800179 ArchType = llvm::Triple::UnknownArch;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800180#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800181
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800182 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800183# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800184 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800185# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800186 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800187# endif
188# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700189
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800190# if defined(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# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800194 Features.push_back("-neon");
195 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800196# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700197
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800198# if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800199 Features.push_back("-neon");
200 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800201# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800202 }
Joseph Wen51001b82011-06-23 18:56:45 -0700203
Logan Chien3bb77072011-09-17 16:53:53 +0800204#if defined(PROVIDE_ARM_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800205 LLVMInitializeARMAsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800206 LLVMInitializeARMTargetMC();
Logan1f028c02010-11-27 01:02:48 +0800207 LLVMInitializeARMTargetInfo();
208 LLVMInitializeARMTarget();
Logan1f028c02010-11-27 01:02:48 +0800209#endif
210
Logan Chien21392f02011-11-26 20:32:01 +0800211#if defined(PROVIDE_MIPS_CODEGEN)
212 LLVMInitializeMipsAsmPrinter();
213 LLVMInitializeMipsTargetMC();
214 LLVMInitializeMipsTargetInfo();
215 LLVMInitializeMipsTarget();
216#endif
217
Logan Chien3bb77072011-09-17 16:53:53 +0800218#if defined(PROVIDE_X86_CODEGEN)
Logan Chienb9ef9ab2011-07-20 11:11:06 +0800219 LLVMInitializeX86AsmPrinter();
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800220 LLVMInitializeX86TargetMC();
Logan1f028c02010-11-27 01:02:48 +0800221 LLVMInitializeX86TargetInfo();
222 LLVMInitializeX86Target();
Logan1f028c02010-11-27 01:02:48 +0800223#endif
Logan Chien9347e0b2011-07-07 19:51:47 +0800224
225#if USE_DISASSEMBLER
226 InitializeDisassembler();
Logan1f028c02010-11-27 01:02:48 +0800227#endif
228
229 // -O0: llvm::CodeGenOpt::None
230 // -O1: llvm::CodeGenOpt::Less
231 // -O2: llvm::CodeGenOpt::Default
232 // -O3: llvm::CodeGenOpt::Aggressive
Shih-wei Liao72f67a62010-12-14 13:36:15 -0800233 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Logan1f028c02010-11-27 01:02:48 +0800234
Logan1f028c02010-11-27 01:02:48 +0800235 // Register the scheduler
236 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
237
238 // Register allocation policy:
239 // createFastRegisterAllocator: fast but bad quality
240 // createLinearScanRegisterAllocator: not so fast but good quality
241 llvm::RegisterRegAlloc::setDefault
242 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
243 llvm::createFastRegisterAllocator :
Logan Chiene1bff142011-11-15 15:55:41 +0800244 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800245
Logan35849002011-01-15 07:30:43 +0800246#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700247 // Read in SHA1 checksum of libbcc and libRS.
248 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700249
250 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800251#endif
Logan75cc8a52011-01-07 06:06:52 +0800252
Logan1f028c02010-11-27 01:02:48 +0800253 GlobalInitialized = true;
254}
255
256
257void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
258 std::string *Error = static_cast<std::string*>(UserData);
259 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000260 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800261 exit(1);
262}
263
264
Logan Chienda5e0c32011-06-13 03:47:21 +0800265#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800266CodeMemoryManager *Compiler::createCodeMemoryManager() {
267 mCodeMemMgr.reset(new CodeMemoryManager());
268 return mCodeMemMgr.get();
269}
Logan Chienda5e0c32011-06-13 03:47:21 +0800270#endif
Logan1f028c02010-11-27 01:02:48 +0800271
272
Logan Chienda5e0c32011-06-13 03:47:21 +0800273#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800274CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800275 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800276 return mCodeEmitter.get();
277}
Logan Chienda5e0c32011-06-13 03:47:21 +0800278#endif
Logan1f028c02010-11-27 01:02:48 +0800279
280
Logan2a6dc822011-01-06 04:05:20 +0800281Compiler::Compiler(ScriptCompiled *result)
282 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800283#if USE_MCJIT
284 mRSExecutable(NULL),
285#endif
Logan1f028c02010-11-27 01:02:48 +0800286 mpSymbolLookupFn(NULL),
287 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800288 mModule(NULL),
289 mHasLinked(false) /* Turn off linker */ {
290 llvm::remove_fatal_error_handler();
291 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800292 return;
293}
294
Logan1f028c02010-11-27 01:02:48 +0800295
Logan474cbd22011-01-31 01:47:44 +0800296int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800297 if (llvm::Linker::LinkModules(mModule, moduleWith,
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800298 llvm::Linker::PreserveSource,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800299 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800300 return hasError();
301 }
302
Logan1f028c02010-11-27 01:02:48 +0800303 // Everything for linking should be settled down here with no error occurs
304 mHasLinked = true;
305 return hasError();
306}
307
308
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800309int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800310 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800311 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800312 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800313
Logan1f028c02010-11-27 01:02:48 +0800314 std::string FeaturesStr;
315
Logan Chienda5e0c32011-06-13 03:47:21 +0800316 llvm::NamedMDNode const *PragmaMetadata;
317 llvm::NamedMDNode const *ExportVarMetadata;
318 llvm::NamedMDNode const *ExportFuncMetadata;
Stephen Hinescc366e52012-02-21 17:22:04 -0800319 llvm::NamedMDNode const *ExportForEachNameMetadata;
320 llvm::NamedMDNode const *ExportForEachMetadata;
Logan Chienda5e0c32011-06-13 03:47:21 +0800321 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800322
Stephen Hinescc366e52012-02-21 17:22:04 -0800323 std::vector<std::string> ForEachNameList;
324 std::vector<std::string> ForEachExpandList;
325 std::vector<uint32_t> forEachSigList;
326
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
Logan Chienbe81e102011-12-16 13:31:39 +0800346 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800347 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
348 option.TargetOpt,
349 option.RelocModelOpt,
350 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800351
Logan1f028c02010-11-27 01:02:48 +0800352 if (TM == NULL) {
353 setError("Failed to create target machine implementation for the"
354 " specified triple '" + Triple + "'");
355 goto on_bcc_compile_error;
356 }
357
Logan Chienda5e0c32011-06-13 03:47:21 +0800358 // Get target data from Module
359 TD = new llvm::TargetData(mModule);
360
361 // Load named metadata
362 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
363 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
Stephen Hinescc366e52012-02-21 17:22:04 -0800364 ExportForEachNameMetadata =
365 mModule->getNamedMetadata(ExportForEachNameMetadataName);
366 ExportForEachMetadata =
367 mModule->getNamedMetadata(ExportForEachMetadataName);
Logan Chienda5e0c32011-06-13 03:47:21 +0800368 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
369 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
370
Stephen Hinescc366e52012-02-21 17:22:04 -0800371 if (ExportForEachNameMetadata) {
372 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
373 i != e;
374 i++) {
375 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
376 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
377 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
378 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
379 llvm::StringRef ExportForEachName =
380 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
381 ForEachNameList.push_back(ExportForEachName.str());
382 std::string ExpandName = ExportForEachName.str() + ".expand";
383 ForEachExpandList.push_back(ExpandName);
384 }
385 }
386 }
387 }
388
389 if (ExportForEachMetadata) {
390 for (int i = 0, e = ExportForEachMetadata->getNumOperands(); i != e; i++) {
391 llvm::MDNode *SigNode = ExportForEachMetadata->getOperand(i);
392 if (SigNode != NULL && SigNode->getNumOperands() == 1) {
393 llvm::Value *SigVal = SigNode->getOperand(0);
394 if (SigVal->getValueID() == llvm::Value::MDStringVal) {
395 llvm::StringRef SigString =
396 static_cast<llvm::MDString*>(SigVal)->getString();
397 uint32_t Signature = 0;
398 if (SigString.getAsInteger(10, Signature)) {
399 ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
400 goto on_bcc_compile_error;
401 }
402 forEachSigList.push_back(Signature);
403 }
404 }
405 }
406 }
407
408 runInternalPasses(ForEachNameList, forEachSigList);
Stephen Hinesdb169182012-01-05 18:46:36 -0800409
Logan Chienda5e0c32011-06-13 03:47:21 +0800410 // Perform link-time optimization if we have multiple modules
411 if (mHasLinked) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800412 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
413 ForEachExpandList);
Logan Chienda5e0c32011-06-13 03:47:21 +0800414 }
415
416 // Perform code generation
417#if USE_OLD_JIT
418 if (runCodeGen(new llvm::TargetData(*TD), TM,
419 ExportVarMetadata, ExportFuncMetadata) != 0) {
420 goto on_bcc_compile_error;
421 }
422#endif
423
424#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700425 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800426 goto on_bcc_compile_error;
427 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800428
Zonr Chang2fcbd022012-01-06 21:04:31 +0800429 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700430 return 0;
431
432 // Load the ELF Object
433 mRSExecutable =
434 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
435 mEmittedELFExecutable.size(),
436 &resolveSymbolAdapter, this);
437
438 if (!mRSExecutable) {
439 setError("Fail to load emitted ELF relocatable file");
440 goto on_bcc_compile_error;
441 }
442
443 if (ExportVarMetadata) {
444 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
445 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
446
447 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
448 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
449 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
450 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
451 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
452 llvm::StringRef ExportVarName =
453 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
454
455 varList.push_back(
456 rsloaderGetSymbolAddress(mRSExecutable,
457 ExportVarName.str().c_str()));
458 varNameList.push_back(ExportVarName.str());
459#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000460 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700461 varList.back());
462#endif
463 continue;
464 }
465 }
466
467 varList.push_back(NULL);
468 }
469 }
470
471 if (ExportFuncMetadata) {
472 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
473 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
474
475 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
476 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
477 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
478 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
479 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
480 llvm::StringRef ExportFuncName =
481 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
482
483 funcList.push_back(
484 rsloaderGetSymbolAddress(mRSExecutable,
485 ExportFuncName.str().c_str()));
486 funcNameList.push_back(ExportFuncName.str());
487#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000488 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700489 funcList.back());
490#endif
491 }
492 }
493 }
494 }
495
Stephen Hinescc366e52012-02-21 17:22:04 -0800496 if (ExportForEachNameMetadata) {
497 ScriptCompiled::ExportForEachList &forEachList = mpResult->mExportForEach;
498 std::vector<std::string> &ForEachNameList = mpResult->mExportForEachName;
499
500 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
501 i != e;
502 i++) {
503 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
504 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
505 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
506 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
507 llvm::StringRef ExportForEachName =
508 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
509 std::string Name = ExportForEachName.str() + ".expand";
510
511 forEachList.push_back(
512 rsloaderGetSymbolAddress(mRSExecutable, Name.c_str()));
513 ForEachNameList.push_back(Name);
514 }
515 }
516 }
517 }
518
Logan Chien4885cf82011-07-20 10:18:05 +0800519#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700520 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700521 // Get MC codegen emitted function name list
522 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
523 std::vector<char const *> func_list(func_list_size, NULL);
524 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700525
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700526 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700527 for (size_t i = 0; i < func_list_size; ++i) {
528 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
529 if (func) {
530 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800531 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
532 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700533 }
534 }
535 }
536#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800537#endif
538
539 // Read pragma information from the metadata node of the module.
540 if (PragmaMetadata) {
541 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
542
543 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
544 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
545 if (Pragma != NULL &&
546 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
547 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
548 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
549
550 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
551 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
552 llvm::StringRef PragmaName =
553 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
554 llvm::StringRef PragmaValue =
555 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
556
557 pragmaList.push_back(
558 std::make_pair(std::string(PragmaName.data(),
559 PragmaName.size()),
560 std::string(PragmaValue.data(),
561 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700562#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000563 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700564 pragmaList.back().first.c_str(),
565 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700566#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800567 }
568 }
569 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800570 }
571
572 if (ObjectSlotMetadata) {
573 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
574
575 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
576 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
577 if (ObjectSlot != NULL &&
578 ObjectSlot->getNumOperands() == 1) {
579 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
580 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
581 llvm::StringRef Slot =
582 static_cast<llvm::MDString*>(SlotMDS)->getString();
583 uint32_t USlot = 0;
584 if (Slot.getAsInteger(10, USlot)) {
585 setError("Non-integer object slot value '" + Slot.str() + "'");
586 goto on_bcc_compile_error;
587 }
588 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700589#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000590 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700591#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800592 }
593 }
594 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800595 }
596
597on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000598 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800599 if (TD) {
600 delete TD;
601 }
602
603 if (TM) {
604 delete TM;
605 }
606
607 if (mError.empty()) {
608 return 0;
609 }
610
Steve Block10c14122012-01-08 10:15:06 +0000611 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800612 return 1;
613}
614
615
616#if USE_OLD_JIT
617int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
618 llvm::NamedMDNode const *ExportVarMetadata,
619 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800620 // Create memory manager for creation of code emitter later.
621 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
622 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800623 return 1;
Logan1f028c02010-11-27 01:02:48 +0800624 }
Logan02286cb2011-01-07 00:30:47 +0800625
626 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800627
628 // Create code emitter
629 if (!mCodeEmitter.get()) {
630 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800631 setError("Failed to create machine code emitter for compilation");
632 return 1;
Logan1f028c02010-11-27 01:02:48 +0800633 }
634 } else {
635 // Reuse the code emitter
636 mCodeEmitter->reset();
637 }
638
639 mCodeEmitter->setTargetMachine(*TM);
640 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
641 mpSymbolLookupContext);
642
Logan1f028c02010-11-27 01:02:48 +0800643 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800644 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
645 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800646
Logan Chienda5e0c32011-06-13 03:47:21 +0800647 // Add TargetData to code generation pass manager
648 CodeGenPasses->add(TD);
649
650 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800651 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
652 *mCodeEmitter,
653 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800654 setError("The machine code emission is not supported on '" + Triple + "'");
655 return 1;
Logan1f028c02010-11-27 01:02:48 +0800656 }
657
Logan Chienda5e0c32011-06-13 03:47:21 +0800658 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800659 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800660 for (llvm::Module::iterator
661 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800662 if (!I->isDeclaration()) {
663 CodeGenPasses->run(*I);
664 }
665 }
666
667 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800668
Logan1f028c02010-11-27 01:02:48 +0800669 // Copy the global address mapping from code emitter and remapping
670 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800671 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
672
Logan1f028c02010-11-27 01:02:48 +0800673 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
674 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
675 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
676 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
677 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
678 llvm::StringRef ExportVarName =
679 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
680
681 CodeEmitter::global_addresses_const_iterator I, E;
682 for (I = mCodeEmitter->global_address_begin(),
683 E = mCodeEmitter->global_address_end();
684 I != E; I++) {
685 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
686 continue;
687 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800688 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700689#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000690 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700691#endif
Logan1f028c02010-11-27 01:02:48 +0800692 break;
693 }
694 }
695 if (I != mCodeEmitter->global_address_end())
696 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800697
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700698#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000699 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800700 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700701#endif
Logan1f028c02010-11-27 01:02:48 +0800702 }
703 }
704 // if reaching here, we know the global variable record in metadata is
705 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800706 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800707 }
Logan2a6dc822011-01-06 04:05:20 +0800708
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700709 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
710 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800711 }
712
713 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800714 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
715
Logan1f028c02010-11-27 01:02:48 +0800716 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
717 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
718 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
719 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
720 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
721 llvm::StringRef ExportFuncName =
722 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800723 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700724#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000725 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800726 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700727#endif
Logan1f028c02010-11-27 01:02:48 +0800728 }
729 }
730 }
731 }
732
733 // Tell code emitter now can release the memory using during the JIT since
734 // we have done the code emission
735 mCodeEmitter->releaseUnnecessary();
736
Logan Chienda5e0c32011-06-13 03:47:21 +0800737 return 0;
Logan1f028c02010-11-27 01:02:48 +0800738}
Logan Chienda5e0c32011-06-13 03:47:21 +0800739#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800740
741
Logan Chienda5e0c32011-06-13 03:47:21 +0800742#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700743int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800744 // Decorate mEmittedELFExecutable with formatted ostream
745 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
746
747 // Relax all machine instructions
748 TM->setMCRelaxAll(/* RelaxAll= */ true);
749
750 // Create MC code generation pass manager
751 llvm::PassManager MCCodeGenPasses;
752
753 // Add TargetData to MC code generation pass manager
754 MCCodeGenPasses.add(TD);
755
756 // Add MC code generation passes to pass manager
757 llvm::MCContext *Ctx;
Logan Chien4e4485d2011-11-25 18:12:33 +0800758 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800759 setError("Fail to add passes to emit file");
760 return 1;
761 }
762
763 MCCodeGenPasses.run(*mModule);
764 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800765 return 0;
766}
767#endif // USE_MCJIT
768
Stephen Hinescc366e52012-02-21 17:22:04 -0800769int Compiler::runInternalPasses(std::vector<std::string>& Names,
770 std::vector<uint32_t>& Signatures) {
Stephen Hinesdb169182012-01-05 18:46:36 -0800771 llvm::PassManager BCCPasses;
772
773 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hinescc366e52012-02-21 17:22:04 -0800774 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Stephen Hinesdb169182012-01-05 18:46:36 -0800775
776 BCCPasses.run(*mModule);
777
778 return 0;
779}
Logan Chienda5e0c32011-06-13 03:47:21 +0800780
781int Compiler::runLTO(llvm::TargetData *TD,
782 llvm::NamedMDNode const *ExportVarMetadata,
Stephen Hinescc366e52012-02-21 17:22:04 -0800783 llvm::NamedMDNode const *ExportFuncMetadata,
784 std::vector<std::string>& ForEachExpandList) {
Logan Chien4cc00332011-06-12 14:00:46 +0800785 llvm::PassManager LTOPasses;
786
787 // Add TargetData to LTO passes
788 LTOPasses.add(TD);
789
790 // Collect All Exported Symbols
791 std::vector<const char*> ExportSymbols;
792
793 // Note: This is a workaround for getting export variable and function name.
794 // We should refine it soon.
795 if (ExportVarMetadata) {
796 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
797 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
798 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
799 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
800 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
801 llvm::StringRef ExportVarName =
802 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
803 ExportSymbols.push_back(ExportVarName.data());
804 }
805 }
806 }
807 }
808
809 if (ExportFuncMetadata) {
810 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
811 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
812 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
813 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
814 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
815 llvm::StringRef ExportFuncName =
816 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
817 ExportSymbols.push_back(ExportFuncName.data());
818 }
819 }
820 }
821 }
822
Stephen Hinescc366e52012-02-21 17:22:04 -0800823 for (int i = 0, e = ForEachExpandList.size(); i != e; i++) {
824 ExportSymbols.push_back(ForEachExpandList[i].c_str());
825 }
826
Logan Chien7890d432011-08-03 14:55:17 +0800827 // TODO(logan): Remove this after we have finished the
828 // bccMarkExternalSymbol API.
829
Stephen Hines64160102011-09-01 17:30:26 -0700830 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800831 ExportSymbols.push_back("root");
832 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700833 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800834
Logan Chien7890d432011-08-03 14:55:17 +0800835 // User-defined exporting symbols
836 std::vector<char const *> const &UserDefinedExternalSymbols =
837 mpResult->getUserDefinedExternalSymbols();
838
839 std::copy(UserDefinedExternalSymbols.begin(),
840 UserDefinedExternalSymbols.end(),
841 std::back_inserter(ExportSymbols));
842
Logan Chien4cc00332011-06-12 14:00:46 +0800843 // We now create passes list performing LTO. These are copied from
844 // (including comments) llvm::createStandardLTOPasses().
845
846 // Internalize all other symbols not listed in ExportSymbols
847 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
848
849 // Propagate constants at call sites into the functions they call. This
850 // opens opportunities for globalopt (and inlining) by substituting
851 // function pointers passed as arguments to direct uses of functions.
852 LTOPasses.add(llvm::createIPSCCPPass());
853
854 // Now that we internalized some globals, see if we can hack on them!
855 LTOPasses.add(llvm::createGlobalOptimizerPass());
856
857 // Linking modules together can lead to duplicated global constants, only
858 // keep one copy of each constant...
859 LTOPasses.add(llvm::createConstantMergePass());
860
861 // Remove unused arguments from functions...
862 LTOPasses.add(llvm::createDeadArgEliminationPass());
863
864 // Reduce the code after globalopt and ipsccp. Both can open up
865 // significant simplification opportunities, and both can propagate
866 // functions through function pointers. When this happens, we often have
867 // to resolve varargs calls, etc, so let instcombine do this.
868 LTOPasses.add(llvm::createInstructionCombiningPass());
869
870 // Inline small functions
871 LTOPasses.add(llvm::createFunctionInliningPass());
872
873 // Remove dead EH info.
874 LTOPasses.add(llvm::createPruneEHPass());
875
876 // Internalize the globals again after inlining
877 LTOPasses.add(llvm::createGlobalOptimizerPass());
878
879 // Remove dead functions.
880 LTOPasses.add(llvm::createGlobalDCEPass());
881
882 // If we didn't decide to inline a function, check to see if we can
883 // transform it to pass arguments by value instead of by reference.
884 LTOPasses.add(llvm::createArgumentPromotionPass());
885
886 // The IPO passes may leave cruft around. Clean up after them.
887 LTOPasses.add(llvm::createInstructionCombiningPass());
888 LTOPasses.add(llvm::createJumpThreadingPass());
889
890 // Break up allocas
891 LTOPasses.add(llvm::createScalarReplAggregatesPass());
892
893 // Run a few AA driven optimizations here and now, to cleanup the code.
894 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
895 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
896
897 // Hoist loop invariants.
898 LTOPasses.add(llvm::createLICMPass());
899
900 // Remove redundancies.
901 LTOPasses.add(llvm::createGVNPass());
902
903 // Remove dead memcpys.
904 LTOPasses.add(llvm::createMemCpyOptPass());
905
906 // Nuke dead stores.
907 LTOPasses.add(llvm::createDeadStoreEliminationPass());
908
909 // Cleanup and simplify the code after the scalar optimizations.
910 LTOPasses.add(llvm::createInstructionCombiningPass());
911
912 LTOPasses.add(llvm::createJumpThreadingPass());
913
914 // Delete basic blocks, which optimization passes may have killed.
915 LTOPasses.add(llvm::createCFGSimplificationPass());
916
917 // Now that we have optimized the program, discard unreachable functions.
918 LTOPasses.add(llvm::createGlobalDCEPass());
919
920 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800921
922 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800923}
924
925
Logan Chienda5e0c32011-06-13 03:47:21 +0800926#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800927void *Compiler::getSymbolAddress(char const *name) {
928 return rsloaderGetSymbolAddress(mRSExecutable, name);
929}
930#endif
931
932
933#if USE_MCJIT
934void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
935 Compiler *self = reinterpret_cast<Compiler *>(context);
936
937 if (void *Addr = FindRuntimeFunction(name)) {
938 return Addr;
939 }
940
941 if (self->mpSymbolLookupFn) {
942 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
943 return Addr;
944 }
945 }
946
Steve Block10c14122012-01-08 10:15:06 +0000947 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800948 return NULL;
949}
950#endif
951
952
Logan1f028c02010-11-27 01:02:48 +0800953Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +0800954#if USE_MCJIT
955 rsloaderDisposeExec(mRSExecutable);
956#endif
957
Logana4994f52010-11-27 14:06:02 +0800958 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800959}
960
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700961
Logan1f028c02010-11-27 01:02:48 +0800962} // namespace bcc