blob: ebdfb0f5823737e8e96e911afe7cf0fd9a5e8de8 [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
Daniel Malea094881f2011-12-14 17:39:16 -050050#include "llvm/MC/MCContext.h"
Logan Chien9347e0b2011-07-07 19:51:47 +080051#include "llvm/MC/SubtargetFeature.h"
52
Logandf23afa2010-11-27 11:04:54 +080053#include "llvm/Transforms/IPO.h"
54#include "llvm/Transforms/Scalar.h"
55
Logandf23afa2010-11-27 11:04:54 +080056#include "llvm/Target/TargetData.h"
57#include "llvm/Target/TargetMachine.h"
Logandf23afa2010-11-27 11:04:54 +080058
59#include "llvm/Support/ErrorHandling.h"
Shih-wei Liao898c5a92011-05-18 07:02:39 -070060#include "llvm/Support/FormattedStream.h"
Logan Chienbc9eb8f2011-10-21 15:17:45 +080061#include "llvm/Support/TargetRegistry.h"
62#include "llvm/Support/TargetSelect.h"
Daniel Malea094881f2011-12-14 17:39:16 -050063#include "llvm/Support/raw_ostream.h"
Logandf23afa2010-11-27 11:04:54 +080064
Daniel Malea094881f2011-12-14 17:39:16 -050065#include "llvm/Constants.h"
Logandf23afa2010-11-27 11:04:54 +080066#include "llvm/GlobalValue.h"
67#include "llvm/Linker.h"
68#include "llvm/LLVMContext.h"
69#include "llvm/Metadata.h"
70#include "llvm/Module.h"
71#include "llvm/PassManager.h"
Daniel Malea094881f2011-12-14 17:39:16 -050072#include "llvm/Type.h"
Logandf23afa2010-11-27 11:04:54 +080073#include "llvm/Value.h"
74
75#include <errno.h>
76#include <sys/file.h>
Logandf23afa2010-11-27 11:04:54 +080077#include <sys/stat.h>
78#include <sys/types.h>
79#include <unistd.h>
80
Logan75cc8a52011-01-07 06:06:52 +080081#include <string.h>
Logan8b77a772010-12-21 09:11:01 +080082
Logan Chien7890d432011-08-03 14:55:17 +080083#include <algorithm>
84#include <iterator>
Logandf23afa2010-11-27 11:04:54 +080085#include <string>
86#include <vector>
Logan1f028c02010-11-27 01:02:48 +080087
Daniel Malea094881f2011-12-14 17:39:16 -050088extern char* gDebugDumpDirectory;
89
Logan1f028c02010-11-27 01:02:48 +080090namespace bcc {
91
92//////////////////////////////////////////////////////////////////////////////
93// BCC Compiler Static Variables
94//////////////////////////////////////////////////////////////////////////////
95
96bool Compiler::GlobalInitialized = false;
97
Andrew Hsieh998ec832011-11-21 02:36:11 -080098
99#if !defined(__HOST__)
100 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
101#else
102// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
103 #if defined(__cplusplus)
104 extern "C" {
105 #endif
106 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
107 #if defined(__cplusplus)
108 };
109 #endif
110#endif
111
Logan1f028c02010-11-27 01:02:48 +0800112// Code generation optimization level for the compiler
113llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
114
115std::string Compiler::Triple;
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800116llvm::Triple::ArchType Compiler::ArchType;
Logan1f028c02010-11-27 01:02:48 +0800117
118std::string Compiler::CPU;
119
120std::vector<std::string> Compiler::Features;
121
Stephen Hines071288a2011-01-27 14:38:26 -0800122// Name of metadata node where pragma info resides (should be synced with
Logan1f028c02010-11-27 01:02:48 +0800123// slang.cpp)
124const llvm::StringRef Compiler::PragmaMetadataName = "#pragma";
125
Stephen Hines071288a2011-01-27 14:38:26 -0800126// Name of metadata node where exported variable names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800127// synced with slang_rs_metadata.h)
128const llvm::StringRef Compiler::ExportVarMetadataName = "#rs_export_var";
129
Stephen Hines071288a2011-01-27 14:38:26 -0800130// Name of metadata node where exported function names reside (should be
Logan1f028c02010-11-27 01:02:48 +0800131// synced with slang_rs_metadata.h)
132const llvm::StringRef Compiler::ExportFuncMetadataName = "#rs_export_func";
133
Stephen Hinescc366e52012-02-21 17:22:04 -0800134// Name of metadata node where exported ForEach name information resides
135// (should be synced with slang_rs_metadata.h)
136const llvm::StringRef Compiler::ExportForEachNameMetadataName =
137 "#rs_export_foreach_name";
138
139// Name of metadata node where exported ForEach signature information resides
140// (should be synced with slang_rs_metadata.h)
141const llvm::StringRef Compiler::ExportForEachMetadataName =
142 "#rs_export_foreach";
143
Stephen Hines071288a2011-01-27 14:38:26 -0800144// Name of metadata node where RS object slot info resides (should be
145// synced with slang_rs_metadata.h)
146const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
Logan1f028c02010-11-27 01:02:48 +0800147
Daniel Malea094881f2011-12-14 17:39:16 -0500148// Name of metadata node where RS optimization level resides (should be
149// synced with slang_rs_metadata.h)
150const llvm::StringRef OptimizationLevelMetadataName = "#optimization_level";
151
152
153
Logan1f028c02010-11-27 01:02:48 +0800154//////////////////////////////////////////////////////////////////////////////
155// Compiler
156//////////////////////////////////////////////////////////////////////////////
157
158void Compiler::GlobalInitialization() {
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700159 if (GlobalInitialized) {
Logan1f028c02010-11-27 01:02:48 +0800160 return;
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700161 }
162
Shih-wei Liao22705912012-03-06 19:13:26 -0800163#if defined(PROVIDE_ARM_CODEGEN)
164 LLVMInitializeARMAsmPrinter();
165 LLVMInitializeARMTargetMC();
166 LLVMInitializeARMTargetInfo();
167 LLVMInitializeARMTarget();
168#endif
169
170#if defined(PROVIDE_MIPS_CODEGEN)
171 LLVMInitializeMipsAsmPrinter();
172 LLVMInitializeMipsTargetMC();
173 LLVMInitializeMipsTargetInfo();
174 LLVMInitializeMipsTarget();
175#endif
176
177#if defined(PROVIDE_X86_CODEGEN)
178 LLVMInitializeX86AsmPrinter();
179 LLVMInitializeX86TargetMC();
180 LLVMInitializeX86TargetInfo();
181 LLVMInitializeX86Target();
182#endif
183
184#if USE_DISASSEMBLER
185 InitializeDisassembler();
186#endif
187
Logan1f028c02010-11-27 01:02:48 +0800188 // if (!llvm::llvm_is_multithreaded())
189 // llvm::llvm_start_multithreaded();
190
191 // Set Triple, CPU and Features here
192 Triple = TARGET_TRIPLE_STRING;
193
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800194 // Determine ArchType
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800195#if defined(__HOST__)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800196 {
197 std::string Err;
198 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
Stephen Hinescc366e52012-02-21 17:22:04 -0800199 if (Target != NULL) {
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800200 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
201 } else {
202 ArchType = llvm::Triple::UnknownArch;
203 ALOGE("%s", Err.c_str());
204 }
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800205 }
206#elif defined(DEFAULT_ARM_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800207 ArchType = llvm::Triple::arm;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800208#elif defined(DEFAULT_MIPS_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800209 ArchType = llvm::Triple::mipsel;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800210#elif defined(DEFAULT_X86_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800211 ArchType = llvm::Triple::x86;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800212#elif defined(DEFAULT_X86_64_CODEGEN)
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800213 ArchType = llvm::Triple::x86_64;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800214#else
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800215 ArchType = llvm::Triple::UnknownArch;
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800216#endif
Logan Chien3bb77072011-09-17 16:53:53 +0800217
Shih-wei Liao4deffde2012-01-17 20:38:17 +0800218 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800219# if defined(ARCH_ARM_HAVE_VFP)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800220 Features.push_back("+vfp3");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800221# if !defined(ARCH_ARM_HAVE_VFP_D32)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800222 Features.push_back("+d16");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800223# endif
224# endif
Stephen Hinesa12d2f32011-09-07 15:30:06 -0700225
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800226# if defined(ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800227 Features.push_back("+neon");
228 Features.push_back("+neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800229# else
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800230 Features.push_back("-neon");
231 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800232# endif
Shih-wei Liao40bcd662011-10-22 17:51:01 -0700233
Stephen Hinesf6b202b2012-03-06 17:45:41 -0800234// FIXME(all): Turn NEON back on after debugging the rebase.
235# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800236 Features.push_back("-neon");
237 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800238# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800239 }
Joseph Wen51001b82011-06-23 18:56:45 -0700240
Logan1f028c02010-11-27 01:02:48 +0800241 // Register the scheduler
242 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
243
Logan35849002011-01-15 07:30:43 +0800244#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700245 // Read in SHA1 checksum of libbcc and libRS.
246 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700247
248 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800249#endif
Logan75cc8a52011-01-07 06:06:52 +0800250
Logan1f028c02010-11-27 01:02:48 +0800251 GlobalInitialized = true;
252}
253
254
255void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
256 std::string *Error = static_cast<std::string*>(UserData);
257 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000258 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800259 exit(1);
260}
261
262
Logan Chienda5e0c32011-06-13 03:47:21 +0800263#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800264CodeMemoryManager *Compiler::createCodeMemoryManager() {
265 mCodeMemMgr.reset(new CodeMemoryManager());
266 return mCodeMemMgr.get();
267}
Logan Chienda5e0c32011-06-13 03:47:21 +0800268#endif
Logan1f028c02010-11-27 01:02:48 +0800269
270
Logan Chienda5e0c32011-06-13 03:47:21 +0800271#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800272CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800273 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800274 return mCodeEmitter.get();
275}
Logan Chienda5e0c32011-06-13 03:47:21 +0800276#endif
Logan1f028c02010-11-27 01:02:48 +0800277
278
Logan2a6dc822011-01-06 04:05:20 +0800279Compiler::Compiler(ScriptCompiled *result)
280 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800281#if USE_MCJIT
282 mRSExecutable(NULL),
283#endif
Logan1f028c02010-11-27 01:02:48 +0800284 mpSymbolLookupFn(NULL),
285 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800286 mModule(NULL),
287 mHasLinked(false) /* Turn off linker */ {
288 llvm::remove_fatal_error_handler();
289 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800290 return;
291}
292
Logan1f028c02010-11-27 01:02:48 +0800293
Logan474cbd22011-01-31 01:47:44 +0800294int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800295 if (llvm::Linker::LinkModules(mModule, moduleWith,
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800296 llvm::Linker::PreserveSource,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800297 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800298 return hasError();
299 }
300
Logan1f028c02010-11-27 01:02:48 +0800301 // Everything for linking should be settled down here with no error occurs
302 mHasLinked = true;
303 return hasError();
304}
305
306
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800307int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800308 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800309 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800310 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800311
Logan1f028c02010-11-27 01:02:48 +0800312 std::string FeaturesStr;
313
Daniel Malea094881f2011-12-14 17:39:16 -0500314 if (mModule == NULL) // No module was loaded
315 return 0;
316
Logan Chienda5e0c32011-06-13 03:47:21 +0800317 llvm::NamedMDNode const *PragmaMetadata;
318 llvm::NamedMDNode const *ExportVarMetadata;
319 llvm::NamedMDNode const *ExportFuncMetadata;
Stephen Hinescc366e52012-02-21 17:22:04 -0800320 llvm::NamedMDNode const *ExportForEachNameMetadata;
321 llvm::NamedMDNode const *ExportForEachMetadata;
Logan Chienda5e0c32011-06-13 03:47:21 +0800322 llvm::NamedMDNode const *ObjectSlotMetadata;
Logan1f028c02010-11-27 01:02:48 +0800323
Stephen Hinescc366e52012-02-21 17:22:04 -0800324 std::vector<std::string> ForEachNameList;
325 std::vector<std::string> ForEachExpandList;
326 std::vector<uint32_t> forEachSigList;
327
Daniel Malea094881f2011-12-14 17:39:16 -0500328 llvm::NamedMDNode const *OptimizationLevelMetadata =
329 mModule->getNamedMetadata(OptimizationLevelMetadataName);
330
331 // Default to maximum optimization in the absence of named metadata node
332 int OptimizationLevel = 3;
333 if (OptimizationLevelMetadata) {
334 llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
335 OptimizationLevelMetadata->getOperand(0)->getOperand(0));
336 OptimizationLevel = OL->getZExtValue();
337 }
338
339 if (OptimizationLevel == 0) {
340 CodeGenOptLevel = llvm::CodeGenOpt::None;
341 } else if (OptimizationLevel == 1) {
342 CodeGenOptLevel = llvm::CodeGenOpt::Less;
343 } else if (OptimizationLevel == 2) {
344 CodeGenOptLevel = llvm::CodeGenOpt::Default;
345 } else if (OptimizationLevel == 3) {
346 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
347 }
348
349 // not the best place for this, but we need to set the register allocation
350 // policy after we read the optimization_level metadata from the bitcode
351
352 // Register allocation policy:
353 // createFastRegisterAllocator: fast but bad quality
354 // createLinearScanRegisterAllocator: not so fast but good quality
355 llvm::RegisterRegAlloc::setDefault
356 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
357 llvm::createFastRegisterAllocator :
Stephen Hinese0918ac2012-03-01 23:28:09 -0800358 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800359
Logan Chienbe81e102011-12-16 13:31:39 +0800360 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800361 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
362 if (hasError())
363 goto on_bcc_compile_error;
364
365 if (!CPU.empty() || !Features.empty()) {
366 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800367
368 for (std::vector<std::string>::const_iterator
369 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800370 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800371 }
372
Logan1f028c02010-11-27 01:02:48 +0800373 FeaturesStr = F.getString();
374 }
375
Logan Chienbe81e102011-12-16 13:31:39 +0800376 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800377 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
378 option.TargetOpt,
379 option.RelocModelOpt,
380 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800381
Logan1f028c02010-11-27 01:02:48 +0800382 if (TM == NULL) {
383 setError("Failed to create target machine implementation for the"
384 " specified triple '" + Triple + "'");
385 goto on_bcc_compile_error;
386 }
387
Logan Chienda5e0c32011-06-13 03:47:21 +0800388 // Get target data from Module
389 TD = new llvm::TargetData(mModule);
390
391 // Load named metadata
392 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
393 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
Stephen Hinescc366e52012-02-21 17:22:04 -0800394 ExportForEachNameMetadata =
395 mModule->getNamedMetadata(ExportForEachNameMetadataName);
396 ExportForEachMetadata =
397 mModule->getNamedMetadata(ExportForEachMetadataName);
Logan Chienda5e0c32011-06-13 03:47:21 +0800398 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
399 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
400
Stephen Hinescc366e52012-02-21 17:22:04 -0800401 if (ExportForEachNameMetadata) {
402 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
403 i != e;
404 i++) {
405 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
406 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
407 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
408 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
409 llvm::StringRef ExportForEachName =
410 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
411 ForEachNameList.push_back(ExportForEachName.str());
412 std::string ExpandName = ExportForEachName.str() + ".expand";
413 ForEachExpandList.push_back(ExpandName);
414 }
415 }
416 }
417 }
418
419 if (ExportForEachMetadata) {
420 for (int i = 0, e = ExportForEachMetadata->getNumOperands(); i != e; i++) {
421 llvm::MDNode *SigNode = ExportForEachMetadata->getOperand(i);
422 if (SigNode != NULL && SigNode->getNumOperands() == 1) {
423 llvm::Value *SigVal = SigNode->getOperand(0);
424 if (SigVal->getValueID() == llvm::Value::MDStringVal) {
425 llvm::StringRef SigString =
426 static_cast<llvm::MDString*>(SigVal)->getString();
427 uint32_t Signature = 0;
428 if (SigString.getAsInteger(10, Signature)) {
429 ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
430 goto on_bcc_compile_error;
431 }
432 forEachSigList.push_back(Signature);
433 }
434 }
435 }
436 }
437
438 runInternalPasses(ForEachNameList, forEachSigList);
Stephen Hinesdb169182012-01-05 18:46:36 -0800439
Logan Chienda5e0c32011-06-13 03:47:21 +0800440 // Perform link-time optimization if we have multiple modules
441 if (mHasLinked) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800442 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
Stephen Hinese0918ac2012-03-01 23:28:09 -0800443 ForEachExpandList, CodeGenOptLevel);
Logan Chienda5e0c32011-06-13 03:47:21 +0800444 }
445
446 // Perform code generation
447#if USE_OLD_JIT
448 if (runCodeGen(new llvm::TargetData(*TD), TM,
449 ExportVarMetadata, ExportFuncMetadata) != 0) {
450 goto on_bcc_compile_error;
451 }
452#endif
453
454#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700455 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800456 goto on_bcc_compile_error;
457 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800458
Zonr Chang2fcbd022012-01-06 21:04:31 +0800459 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700460 return 0;
461
462 // Load the ELF Object
463 mRSExecutable =
464 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
465 mEmittedELFExecutable.size(),
466 &resolveSymbolAdapter, this);
467
468 if (!mRSExecutable) {
469 setError("Fail to load emitted ELF relocatable file");
470 goto on_bcc_compile_error;
471 }
472
Daniel Malea094881f2011-12-14 17:39:16 -0500473 rsloaderUpdateSectionHeaders(mRSExecutable,
474 (unsigned char*) mEmittedELFExecutable.begin());
475
Joseph Wen34c600a2011-07-25 17:59:17 -0700476 if (ExportVarMetadata) {
477 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
478 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
479
480 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
481 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
482 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
483 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
484 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
485 llvm::StringRef ExportVarName =
486 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
487
488 varList.push_back(
489 rsloaderGetSymbolAddress(mRSExecutable,
490 ExportVarName.str().c_str()));
491 varNameList.push_back(ExportVarName.str());
492#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000493 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700494 varList.back());
495#endif
496 continue;
497 }
498 }
499
500 varList.push_back(NULL);
501 }
502 }
503
504 if (ExportFuncMetadata) {
505 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
506 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
507
508 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
509 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
510 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
511 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
512 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
513 llvm::StringRef ExportFuncName =
514 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
515
516 funcList.push_back(
517 rsloaderGetSymbolAddress(mRSExecutable,
518 ExportFuncName.str().c_str()));
519 funcNameList.push_back(ExportFuncName.str());
520#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000521 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700522 funcList.back());
523#endif
524 }
525 }
526 }
527 }
528
Stephen Hinescc366e52012-02-21 17:22:04 -0800529 if (ExportForEachNameMetadata) {
530 ScriptCompiled::ExportForEachList &forEachList = mpResult->mExportForEach;
531 std::vector<std::string> &ForEachNameList = mpResult->mExportForEachName;
532
533 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
534 i != e;
535 i++) {
536 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
537 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
538 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
539 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
540 llvm::StringRef ExportForEachName =
541 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
542 std::string Name = ExportForEachName.str() + ".expand";
543
544 forEachList.push_back(
545 rsloaderGetSymbolAddress(mRSExecutable, Name.c_str()));
546 ForEachNameList.push_back(Name);
547 }
548 }
549 }
550 }
551
Logan Chien4885cf82011-07-20 10:18:05 +0800552#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700553 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700554 // Get MC codegen emitted function name list
555 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
556 std::vector<char const *> func_list(func_list_size, NULL);
557 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700558
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700559 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700560 for (size_t i = 0; i < func_list_size; ++i) {
561 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
562 if (func) {
563 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800564 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
565 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700566 }
567 }
568 }
569#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800570#endif
571
572 // Read pragma information from the metadata node of the module.
573 if (PragmaMetadata) {
574 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
575
576 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
577 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
578 if (Pragma != NULL &&
579 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
580 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
581 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
582
583 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
584 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
585 llvm::StringRef PragmaName =
586 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
587 llvm::StringRef PragmaValue =
588 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
589
590 pragmaList.push_back(
591 std::make_pair(std::string(PragmaName.data(),
592 PragmaName.size()),
593 std::string(PragmaValue.data(),
594 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700595#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000596 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700597 pragmaList.back().first.c_str(),
598 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700599#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800600 }
601 }
602 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800603 }
604
605 if (ObjectSlotMetadata) {
606 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
607
608 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
609 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
610 if (ObjectSlot != NULL &&
611 ObjectSlot->getNumOperands() == 1) {
612 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
613 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
614 llvm::StringRef Slot =
615 static_cast<llvm::MDString*>(SlotMDS)->getString();
616 uint32_t USlot = 0;
617 if (Slot.getAsInteger(10, USlot)) {
618 setError("Non-integer object slot value '" + Slot.str() + "'");
619 goto on_bcc_compile_error;
620 }
621 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700622#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000623 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700624#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800625 }
626 }
627 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800628 }
629
630on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000631 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800632 if (TD) {
633 delete TD;
634 }
635
636 if (TM) {
637 delete TM;
638 }
639
640 if (mError.empty()) {
641 return 0;
642 }
643
Steve Block10c14122012-01-08 10:15:06 +0000644 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800645 return 1;
646}
647
648
649#if USE_OLD_JIT
650int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
651 llvm::NamedMDNode const *ExportVarMetadata,
652 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800653 // Create memory manager for creation of code emitter later.
654 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
655 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800656 return 1;
Logan1f028c02010-11-27 01:02:48 +0800657 }
Logan02286cb2011-01-07 00:30:47 +0800658
659 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800660
661 // Create code emitter
662 if (!mCodeEmitter.get()) {
663 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800664 setError("Failed to create machine code emitter for compilation");
665 return 1;
Logan1f028c02010-11-27 01:02:48 +0800666 }
667 } else {
668 // Reuse the code emitter
669 mCodeEmitter->reset();
670 }
671
672 mCodeEmitter->setTargetMachine(*TM);
673 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
674 mpSymbolLookupContext);
675
Logan1f028c02010-11-27 01:02:48 +0800676 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800677 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
678 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800679
Logan Chienda5e0c32011-06-13 03:47:21 +0800680 // Add TargetData to code generation pass manager
681 CodeGenPasses->add(TD);
682
683 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800684 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
685 *mCodeEmitter,
686 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800687 setError("The machine code emission is not supported on '" + Triple + "'");
688 return 1;
Logan1f028c02010-11-27 01:02:48 +0800689 }
690
Logan Chienda5e0c32011-06-13 03:47:21 +0800691 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800692 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800693 for (llvm::Module::iterator
694 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800695 if (!I->isDeclaration()) {
696 CodeGenPasses->run(*I);
697 }
698 }
699
700 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800701
Logan1f028c02010-11-27 01:02:48 +0800702 // Copy the global address mapping from code emitter and remapping
703 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800704 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
705
Logan1f028c02010-11-27 01:02:48 +0800706 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
707 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
708 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
709 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
710 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
711 llvm::StringRef ExportVarName =
712 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
713
714 CodeEmitter::global_addresses_const_iterator I, E;
715 for (I = mCodeEmitter->global_address_begin(),
716 E = mCodeEmitter->global_address_end();
717 I != E; I++) {
718 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
719 continue;
720 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800721 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700722#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000723 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700724#endif
Logan1f028c02010-11-27 01:02:48 +0800725 break;
726 }
727 }
728 if (I != mCodeEmitter->global_address_end())
729 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800730
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700731#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000732 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800733 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700734#endif
Logan1f028c02010-11-27 01:02:48 +0800735 }
736 }
737 // if reaching here, we know the global variable record in metadata is
738 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800739 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800740 }
Logan2a6dc822011-01-06 04:05:20 +0800741
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700742 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
743 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800744 }
745
746 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800747 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
748
Logan1f028c02010-11-27 01:02:48 +0800749 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
750 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
751 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
752 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
753 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
754 llvm::StringRef ExportFuncName =
755 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800756 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700757#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000758 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800759 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700760#endif
Logan1f028c02010-11-27 01:02:48 +0800761 }
762 }
763 }
764 }
765
766 // Tell code emitter now can release the memory using during the JIT since
767 // we have done the code emission
768 mCodeEmitter->releaseUnnecessary();
769
Logan Chienda5e0c32011-06-13 03:47:21 +0800770 return 0;
Logan1f028c02010-11-27 01:02:48 +0800771}
Logan Chienda5e0c32011-06-13 03:47:21 +0800772#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800773
774
Logan Chienda5e0c32011-06-13 03:47:21 +0800775#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700776int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800777 // Decorate mEmittedELFExecutable with formatted ostream
778 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
779
780 // Relax all machine instructions
781 TM->setMCRelaxAll(/* RelaxAll= */ true);
782
783 // Create MC code generation pass manager
784 llvm::PassManager MCCodeGenPasses;
785
786 // Add TargetData to MC code generation pass manager
787 MCCodeGenPasses.add(TD);
788
789 // Add MC code generation passes to pass manager
Daniel Malea094881f2011-12-14 17:39:16 -0500790 llvm::MCContext *Ctx = NULL;
Logan Chien4e4485d2011-11-25 18:12:33 +0800791 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800792 setError("Fail to add passes to emit file");
793 return 1;
794 }
795
796 MCCodeGenPasses.run(*mModule);
797 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800798 return 0;
799}
800#endif // USE_MCJIT
801
Stephen Hinescc366e52012-02-21 17:22:04 -0800802int Compiler::runInternalPasses(std::vector<std::string>& Names,
803 std::vector<uint32_t>& Signatures) {
Stephen Hinesdb169182012-01-05 18:46:36 -0800804 llvm::PassManager BCCPasses;
805
806 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hinescc366e52012-02-21 17:22:04 -0800807 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Stephen Hinesdb169182012-01-05 18:46:36 -0800808
809 BCCPasses.run(*mModule);
810
811 return 0;
812}
Logan Chienda5e0c32011-06-13 03:47:21 +0800813
814int Compiler::runLTO(llvm::TargetData *TD,
815 llvm::NamedMDNode const *ExportVarMetadata,
Stephen Hinescc366e52012-02-21 17:22:04 -0800816 llvm::NamedMDNode const *ExportFuncMetadata,
Stephen Hinese0918ac2012-03-01 23:28:09 -0800817 std::vector<std::string>& ForEachExpandList,
Daniel Malea094881f2011-12-14 17:39:16 -0500818 llvm::CodeGenOpt::Level OptimizationLevel) {
Logan Chien4cc00332011-06-12 14:00:46 +0800819 // Collect All Exported Symbols
820 std::vector<const char*> ExportSymbols;
821
822 // Note: This is a workaround for getting export variable and function name.
823 // We should refine it soon.
824 if (ExportVarMetadata) {
825 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
826 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
827 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
828 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
829 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
830 llvm::StringRef ExportVarName =
831 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
832 ExportSymbols.push_back(ExportVarName.data());
833 }
834 }
835 }
836 }
837
838 if (ExportFuncMetadata) {
839 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
840 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
841 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
842 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
843 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
844 llvm::StringRef ExportFuncName =
845 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
846 ExportSymbols.push_back(ExportFuncName.data());
847 }
848 }
849 }
850 }
851
Stephen Hinescc366e52012-02-21 17:22:04 -0800852 for (int i = 0, e = ForEachExpandList.size(); i != e; i++) {
853 ExportSymbols.push_back(ForEachExpandList[i].c_str());
854 }
855
Logan Chien7890d432011-08-03 14:55:17 +0800856 // TODO(logan): Remove this after we have finished the
857 // bccMarkExternalSymbol API.
858
Stephen Hines64160102011-09-01 17:30:26 -0700859 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800860 ExportSymbols.push_back("root");
861 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700862 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800863
Logan Chien7890d432011-08-03 14:55:17 +0800864 // User-defined exporting symbols
865 std::vector<char const *> const &UserDefinedExternalSymbols =
866 mpResult->getUserDefinedExternalSymbols();
867
868 std::copy(UserDefinedExternalSymbols.begin(),
869 UserDefinedExternalSymbols.end(),
870 std::back_inserter(ExportSymbols));
871
Daniel Malea094881f2011-12-14 17:39:16 -0500872 llvm::PassManager LTOPasses;
873
874 // Add TargetData to LTO passes
875 LTOPasses.add(TD);
876
Logan Chien4cc00332011-06-12 14:00:46 +0800877 // We now create passes list performing LTO. These are copied from
878 // (including comments) llvm::createStandardLTOPasses().
Daniel Malea094881f2011-12-14 17:39:16 -0500879 // Only a subset of these LTO passes are enabled in optimization level 0
880 // as they interfere with interactive debugging.
881 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
Logan Chien4cc00332011-06-12 14:00:46 +0800882
Daniel Malea094881f2011-12-14 17:39:16 -0500883 if (OptimizationLevel != llvm::CodeGenOpt::None) {
884 // Internalize all other symbols not listed in ExportSymbols
885 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Logan Chien4cc00332011-06-12 14:00:46 +0800886
Daniel Malea094881f2011-12-14 17:39:16 -0500887 // Propagate constants at call sites into the functions they call. This
888 // opens opportunities for globalopt (and inlining) by substituting
889 // function pointers passed as arguments to direct uses of functions.
890 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800891
Daniel Malea094881f2011-12-14 17:39:16 -0500892 // Now that we internalized some globals, see if we can hack on them!
893 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800894
Daniel Malea094881f2011-12-14 17:39:16 -0500895 // Linking modules together can lead to duplicated global constants, only
896 // keep one copy of each constant...
897 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800898
Daniel Malea094881f2011-12-14 17:39:16 -0500899 // Remove unused arguments from functions...
900 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800901
Daniel Malea094881f2011-12-14 17:39:16 -0500902 // Reduce the code after globalopt and ipsccp. Both can open up
903 // significant simplification opportunities, and both can propagate
904 // functions through function pointers. When this happens, we often have
905 // to resolve varargs calls, etc, so let instcombine do this.
906 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800907
Daniel Malea094881f2011-12-14 17:39:16 -0500908 // Inline small functions
909 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800910
Daniel Malea094881f2011-12-14 17:39:16 -0500911 // Remove dead EH info.
912 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800913
Daniel Malea094881f2011-12-14 17:39:16 -0500914 // Internalize the globals again after inlining
915 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800916
Daniel Malea094881f2011-12-14 17:39:16 -0500917 // Remove dead functions.
918 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800919
Daniel Malea094881f2011-12-14 17:39:16 -0500920 // If we didn't decide to inline a function, check to see if we can
921 // transform it to pass arguments by value instead of by reference.
922 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800923
Daniel Malea094881f2011-12-14 17:39:16 -0500924 // The IPO passes may leave cruft around. Clean up after them.
925 LTOPasses.add(llvm::createInstructionCombiningPass());
926 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800927
Daniel Malea094881f2011-12-14 17:39:16 -0500928 // Break up allocas
929 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800930
Daniel Malea094881f2011-12-14 17:39:16 -0500931 // Run a few AA driven optimizations here and now, to cleanup the code.
932 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
933 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800934
Daniel Malea094881f2011-12-14 17:39:16 -0500935 // Hoist loop invariants.
936 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800937
Daniel Malea094881f2011-12-14 17:39:16 -0500938 // Remove redundancies.
939 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800940
Daniel Malea094881f2011-12-14 17:39:16 -0500941 // Remove dead memcpys.
942 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800943
Daniel Malea094881f2011-12-14 17:39:16 -0500944 // Nuke dead stores.
945 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800946
Daniel Malea094881f2011-12-14 17:39:16 -0500947 // Cleanup and simplify the code after the scalar optimizations.
948 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800949
Daniel Malea094881f2011-12-14 17:39:16 -0500950 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800951
Daniel Malea094881f2011-12-14 17:39:16 -0500952 // Delete basic blocks, which optimization passes may have killed.
953 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800954
Daniel Malea094881f2011-12-14 17:39:16 -0500955 // Now that we have optimized the program, discard unreachable functions.
956 LTOPasses.add(llvm::createGlobalDCEPass());
957
958 } else {
959 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
960 LTOPasses.add(llvm::createGlobalOptimizerPass());
961 LTOPasses.add(llvm::createConstantMergePass());
962 }
Logan Chien4cc00332011-06-12 14:00:46 +0800963
964 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800965
Daniel Malea094881f2011-12-14 17:39:16 -0500966#if ANDROID_ENGINEERING_BUILD
967 if (0 != gDebugDumpDirectory) {
968 std::string errs;
969 std::string Filename(gDebugDumpDirectory);
970 Filename += "/post-lto-module.ll";
971 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
972 mModule->print(FS, 0);
973 FS.close();
974 }
975#endif
976
Logan Chienda5e0c32011-06-13 03:47:21 +0800977 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800978}
979
980
Logan Chienda5e0c32011-06-13 03:47:21 +0800981#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800982void *Compiler::getSymbolAddress(char const *name) {
983 return rsloaderGetSymbolAddress(mRSExecutable, name);
984}
985#endif
986
987
988#if USE_MCJIT
989void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
990 Compiler *self = reinterpret_cast<Compiler *>(context);
991
992 if (void *Addr = FindRuntimeFunction(name)) {
993 return Addr;
994 }
995
996 if (self->mpSymbolLookupFn) {
997 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
998 return Addr;
999 }
1000 }
1001
Steve Block10c14122012-01-08 10:15:06 +00001002 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +08001003 return NULL;
1004}
1005#endif
1006
1007
Logan1f028c02010-11-27 01:02:48 +08001008Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +08001009#if USE_MCJIT
1010 rsloaderDisposeExec(mRSExecutable);
1011#endif
1012
Logana4994f52010-11-27 14:06:02 +08001013 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +08001014}
1015
Shih-wei Liao90cd3d12011-06-20 15:43:34 -07001016
Logan1f028c02010-11-27 01:02:48 +08001017} // namespace bcc