blob: e25036edf8eb62d7f860f0eb256d6297f155ebdd [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
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800234# if defined(DISABLE_ARCH_ARM_HAVE_NEON)
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800235 Features.push_back("-neon");
236 Features.push_back("-neonfp");
Shih-wei Liaofbeb9b62012-01-14 02:14:31 -0800237# endif
Andrew Hsiehc0554e22012-01-13 22:34:34 -0800238 }
Joseph Wen51001b82011-06-23 18:56:45 -0700239
Logan1f028c02010-11-27 01:02:48 +0800240 // Register the scheduler
241 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
242
Logan35849002011-01-15 07:30:43 +0800243#if USE_CACHE
Ying Wang26fea102011-07-05 15:12:25 -0700244 // Read in SHA1 checksum of libbcc and libRS.
245 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
Joseph Wen76919072011-07-07 23:06:15 -0700246
247 calcFileSHA1(sha1LibRS, pathLibRS);
Logan35849002011-01-15 07:30:43 +0800248#endif
Logan75cc8a52011-01-07 06:06:52 +0800249
Logan1f028c02010-11-27 01:02:48 +0800250 GlobalInitialized = true;
251}
252
253
254void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
255 std::string *Error = static_cast<std::string*>(UserData);
256 Error->assign(Message);
Steve Block10c14122012-01-08 10:15:06 +0000257 ALOGE("%s", Message.c_str());
Logan1f028c02010-11-27 01:02:48 +0800258 exit(1);
259}
260
261
Logan Chienda5e0c32011-06-13 03:47:21 +0800262#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800263CodeMemoryManager *Compiler::createCodeMemoryManager() {
264 mCodeMemMgr.reset(new CodeMemoryManager());
265 return mCodeMemMgr.get();
266}
Logan Chienda5e0c32011-06-13 03:47:21 +0800267#endif
Logan1f028c02010-11-27 01:02:48 +0800268
269
Logan Chienda5e0c32011-06-13 03:47:21 +0800270#if USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800271CodeEmitter *Compiler::createCodeEmitter() {
Logan7dcaac92011-01-06 04:26:23 +0800272 mCodeEmitter.reset(new CodeEmitter(mpResult, mCodeMemMgr.get()));
Logan1f028c02010-11-27 01:02:48 +0800273 return mCodeEmitter.get();
274}
Logan Chienda5e0c32011-06-13 03:47:21 +0800275#endif
Logan1f028c02010-11-27 01:02:48 +0800276
277
Logan2a6dc822011-01-06 04:05:20 +0800278Compiler::Compiler(ScriptCompiled *result)
279 : mpResult(result),
Logan Chienda5e0c32011-06-13 03:47:21 +0800280#if USE_MCJIT
281 mRSExecutable(NULL),
282#endif
Logan1f028c02010-11-27 01:02:48 +0800283 mpSymbolLookupFn(NULL),
284 mpSymbolLookupContext(NULL),
Logan1f028c02010-11-27 01:02:48 +0800285 mModule(NULL),
286 mHasLinked(false) /* Turn off linker */ {
287 llvm::remove_fatal_error_handler();
288 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Logan1f028c02010-11-27 01:02:48 +0800289 return;
290}
291
Logan1f028c02010-11-27 01:02:48 +0800292
Logan474cbd22011-01-31 01:47:44 +0800293int Compiler::linkModule(llvm::Module *moduleWith) {
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800294 if (llvm::Linker::LinkModules(mModule, moduleWith,
Shih-wei Liaod88c0d12012-01-17 20:32:58 -0800295 llvm::Linker::PreserveSource,
Logan Chienbc9eb8f2011-10-21 15:17:45 +0800296 &mError) != 0) {
Logan1f028c02010-11-27 01:02:48 +0800297 return hasError();
298 }
299
Logan1f028c02010-11-27 01:02:48 +0800300 // Everything for linking should be settled down here with no error occurs
301 mHasLinked = true;
302 return hasError();
303}
304
305
Shih-wei Liao9e81e372012-01-17 16:38:40 -0800306int Compiler::compile(const CompilerOption &option) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800307 llvm::Target const *Target = NULL;
Logan1f028c02010-11-27 01:02:48 +0800308 llvm::TargetData *TD = NULL;
Logan1f028c02010-11-27 01:02:48 +0800309 llvm::TargetMachine *TM = NULL;
Logan Chienda5e0c32011-06-13 03:47:21 +0800310
Logan1f028c02010-11-27 01:02:48 +0800311 std::string FeaturesStr;
312
Daniel Malea094881f2011-12-14 17:39:16 -0500313 if (mModule == NULL) // No module was loaded
314 return 0;
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
Daniel Malea094881f2011-12-14 17:39:16 -0500327 llvm::NamedMDNode const *OptimizationLevelMetadata =
328 mModule->getNamedMetadata(OptimizationLevelMetadataName);
329
330 // Default to maximum optimization in the absence of named metadata node
331 int OptimizationLevel = 3;
332 if (OptimizationLevelMetadata) {
333 llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
334 OptimizationLevelMetadata->getOperand(0)->getOperand(0));
335 OptimizationLevel = OL->getZExtValue();
336 }
337
338 if (OptimizationLevel == 0) {
339 CodeGenOptLevel = llvm::CodeGenOpt::None;
340 } else if (OptimizationLevel == 1) {
341 CodeGenOptLevel = llvm::CodeGenOpt::Less;
342 } else if (OptimizationLevel == 2) {
343 CodeGenOptLevel = llvm::CodeGenOpt::Default;
344 } else if (OptimizationLevel == 3) {
345 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
346 }
347
348 // not the best place for this, but we need to set the register allocation
349 // policy after we read the optimization_level metadata from the bitcode
350
351 // Register allocation policy:
352 // createFastRegisterAllocator: fast but bad quality
353 // createLinearScanRegisterAllocator: not so fast but good quality
354 llvm::RegisterRegAlloc::setDefault
355 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
356 llvm::createFastRegisterAllocator :
Stephen Hinese0918ac2012-03-01 23:28:09 -0800357 llvm::createGreedyRegisterAllocator);
Logan1f028c02010-11-27 01:02:48 +0800358
Logan Chienbe81e102011-12-16 13:31:39 +0800359 // Find LLVM Target
Logan1f028c02010-11-27 01:02:48 +0800360 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
361 if (hasError())
362 goto on_bcc_compile_error;
363
364 if (!CPU.empty() || !Features.empty()) {
365 llvm::SubtargetFeatures F;
Logana4994f52010-11-27 14:06:02 +0800366
367 for (std::vector<std::string>::const_iterator
368 I = Features.begin(), E = Features.end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800369 F.AddFeature(*I);
Logana4994f52010-11-27 14:06:02 +0800370 }
371
Logan1f028c02010-11-27 01:02:48 +0800372 FeaturesStr = F.getString();
373 }
374
Logan Chienbe81e102011-12-16 13:31:39 +0800375 // Create LLVM Target Machine
Zonr Chang2fcbd022012-01-06 21:04:31 +0800376 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
377 option.TargetOpt,
378 option.RelocModelOpt,
379 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800380
Logan1f028c02010-11-27 01:02:48 +0800381 if (TM == NULL) {
382 setError("Failed to create target machine implementation for the"
383 " specified triple '" + Triple + "'");
384 goto on_bcc_compile_error;
385 }
386
Logan Chienda5e0c32011-06-13 03:47:21 +0800387 // Get target data from Module
388 TD = new llvm::TargetData(mModule);
389
390 // Load named metadata
391 ExportVarMetadata = mModule->getNamedMetadata(ExportVarMetadataName);
392 ExportFuncMetadata = mModule->getNamedMetadata(ExportFuncMetadataName);
Stephen Hinescc366e52012-02-21 17:22:04 -0800393 ExportForEachNameMetadata =
394 mModule->getNamedMetadata(ExportForEachNameMetadataName);
395 ExportForEachMetadata =
396 mModule->getNamedMetadata(ExportForEachMetadataName);
Logan Chienda5e0c32011-06-13 03:47:21 +0800397 PragmaMetadata = mModule->getNamedMetadata(PragmaMetadataName);
398 ObjectSlotMetadata = mModule->getNamedMetadata(ObjectSlotMetadataName);
399
Stephen Hinescc366e52012-02-21 17:22:04 -0800400 if (ExportForEachNameMetadata) {
401 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
402 i != e;
403 i++) {
404 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
405 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
406 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
407 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
408 llvm::StringRef ExportForEachName =
409 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
410 ForEachNameList.push_back(ExportForEachName.str());
411 std::string ExpandName = ExportForEachName.str() + ".expand";
412 ForEachExpandList.push_back(ExpandName);
413 }
414 }
415 }
416 }
417
418 if (ExportForEachMetadata) {
419 for (int i = 0, e = ExportForEachMetadata->getNumOperands(); i != e; i++) {
420 llvm::MDNode *SigNode = ExportForEachMetadata->getOperand(i);
421 if (SigNode != NULL && SigNode->getNumOperands() == 1) {
422 llvm::Value *SigVal = SigNode->getOperand(0);
423 if (SigVal->getValueID() == llvm::Value::MDStringVal) {
424 llvm::StringRef SigString =
425 static_cast<llvm::MDString*>(SigVal)->getString();
426 uint32_t Signature = 0;
427 if (SigString.getAsInteger(10, Signature)) {
428 ALOGE("Non-integer signature value '%s'", SigString.str().c_str());
429 goto on_bcc_compile_error;
430 }
431 forEachSigList.push_back(Signature);
432 }
433 }
434 }
435 }
436
437 runInternalPasses(ForEachNameList, forEachSigList);
Stephen Hinesdb169182012-01-05 18:46:36 -0800438
Logan Chienda5e0c32011-06-13 03:47:21 +0800439 // Perform link-time optimization if we have multiple modules
440 if (mHasLinked) {
Stephen Hinescc366e52012-02-21 17:22:04 -0800441 runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
Stephen Hinese0918ac2012-03-01 23:28:09 -0800442 ForEachExpandList, CodeGenOptLevel);
Logan Chienda5e0c32011-06-13 03:47:21 +0800443 }
444
445 // Perform code generation
446#if USE_OLD_JIT
447 if (runCodeGen(new llvm::TargetData(*TD), TM,
448 ExportVarMetadata, ExportFuncMetadata) != 0) {
449 goto on_bcc_compile_error;
450 }
451#endif
452
453#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700454 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800455 goto on_bcc_compile_error;
456 }
Logan Chien9347e0b2011-07-07 19:51:47 +0800457
Zonr Chang2fcbd022012-01-06 21:04:31 +0800458 if (!option.LoadAfterCompile)
Joseph Wen34c600a2011-07-25 17:59:17 -0700459 return 0;
460
461 // Load the ELF Object
462 mRSExecutable =
463 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
464 mEmittedELFExecutable.size(),
465 &resolveSymbolAdapter, this);
466
467 if (!mRSExecutable) {
468 setError("Fail to load emitted ELF relocatable file");
469 goto on_bcc_compile_error;
470 }
471
Daniel Malea094881f2011-12-14 17:39:16 -0500472 rsloaderUpdateSectionHeaders(mRSExecutable,
473 (unsigned char*) mEmittedELFExecutable.begin());
474
Joseph Wen34c600a2011-07-25 17:59:17 -0700475 if (ExportVarMetadata) {
476 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
477 std::vector<std::string> &varNameList = mpResult->mExportVarsName;
478
479 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
480 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
481 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
482 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
483 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
484 llvm::StringRef ExportVarName =
485 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
486
487 varList.push_back(
488 rsloaderGetSymbolAddress(mRSExecutable,
489 ExportVarName.str().c_str()));
490 varNameList.push_back(ExportVarName.str());
491#if DEBUG_MCJIT_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000492 ALOGD("runMCCodeGen(): Exported Var: %s @ %p\n", ExportVarName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700493 varList.back());
494#endif
495 continue;
496 }
497 }
498
499 varList.push_back(NULL);
500 }
501 }
502
503 if (ExportFuncMetadata) {
504 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
505 std::vector<std::string> &funcNameList = mpResult->mExportFuncsName;
506
507 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
508 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
509 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
510 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
511 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
512 llvm::StringRef ExportFuncName =
513 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
514
515 funcList.push_back(
516 rsloaderGetSymbolAddress(mRSExecutable,
517 ExportFuncName.str().c_str()));
518 funcNameList.push_back(ExportFuncName.str());
519#if DEBUG_MCJIT_RELECT
Steve Blockb20498e2011-12-20 16:24:20 +0000520 ALOGD("runMCCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Joseph Wen34c600a2011-07-25 17:59:17 -0700521 funcList.back());
522#endif
523 }
524 }
525 }
526 }
527
Stephen Hinescc366e52012-02-21 17:22:04 -0800528 if (ExportForEachNameMetadata) {
529 ScriptCompiled::ExportForEachList &forEachList = mpResult->mExportForEach;
530 std::vector<std::string> &ForEachNameList = mpResult->mExportForEachName;
531
532 for (int i = 0, e = ExportForEachNameMetadata->getNumOperands();
533 i != e;
534 i++) {
535 llvm::MDNode *ExportForEach = ExportForEachNameMetadata->getOperand(i);
536 if (ExportForEach != NULL && ExportForEach->getNumOperands() > 0) {
537 llvm::Value *ExportForEachNameMDS = ExportForEach->getOperand(0);
538 if (ExportForEachNameMDS->getValueID() == llvm::Value::MDStringVal) {
539 llvm::StringRef ExportForEachName =
540 static_cast<llvm::MDString*>(ExportForEachNameMDS)->getString();
541 std::string Name = ExportForEachName.str() + ".expand";
542
543 forEachList.push_back(
544 rsloaderGetSymbolAddress(mRSExecutable, Name.c_str()));
545 ForEachNameList.push_back(Name);
546 }
547 }
548 }
549 }
550
Logan Chien4885cf82011-07-20 10:18:05 +0800551#if DEBUG_MCJIT_DISASSEMBLER
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700552 {
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700553 // Get MC codegen emitted function name list
554 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
555 std::vector<char const *> func_list(func_list_size, NULL);
556 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
Shih-wei Liao320b5492011-06-20 22:53:33 -0700557
Shih-wei Liaod3c551f2011-07-01 04:28:27 -0700558 // Disassemble each function
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700559 for (size_t i = 0; i < func_list_size; ++i) {
560 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
561 if (func) {
562 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
Logan Chien9347e0b2011-07-07 19:51:47 +0800563 Disassemble(DEBUG_MCJIT_DISASSEMBLER_FILE,
564 Target, TM, func_list[i], (unsigned char const *)func, size);
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700565 }
566 }
567 }
568#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800569#endif
570
571 // Read pragma information from the metadata node of the module.
572 if (PragmaMetadata) {
573 ScriptCompiled::PragmaList &pragmaList = mpResult->mPragmas;
574
575 for (int i = 0, e = PragmaMetadata->getNumOperands(); i != e; i++) {
576 llvm::MDNode *Pragma = PragmaMetadata->getOperand(i);
577 if (Pragma != NULL &&
578 Pragma->getNumOperands() == 2 /* should have exactly 2 operands */) {
579 llvm::Value *PragmaNameMDS = Pragma->getOperand(0);
580 llvm::Value *PragmaValueMDS = Pragma->getOperand(1);
581
582 if ((PragmaNameMDS->getValueID() == llvm::Value::MDStringVal) &&
583 (PragmaValueMDS->getValueID() == llvm::Value::MDStringVal)) {
584 llvm::StringRef PragmaName =
585 static_cast<llvm::MDString*>(PragmaNameMDS)->getString();
586 llvm::StringRef PragmaValue =
587 static_cast<llvm::MDString*>(PragmaValueMDS)->getString();
588
589 pragmaList.push_back(
590 std::make_pair(std::string(PragmaName.data(),
591 PragmaName.size()),
592 std::string(PragmaValue.data(),
593 PragmaValue.size())));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700594#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000595 ALOGD("compile(): Pragma: %s -> %s\n",
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700596 pragmaList.back().first.c_str(),
597 pragmaList.back().second.c_str());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700598#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800599 }
600 }
601 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800602 }
603
604 if (ObjectSlotMetadata) {
605 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
606
607 for (int i = 0, e = ObjectSlotMetadata->getNumOperands(); i != e; i++) {
608 llvm::MDNode *ObjectSlot = ObjectSlotMetadata->getOperand(i);
609 if (ObjectSlot != NULL &&
610 ObjectSlot->getNumOperands() == 1) {
611 llvm::Value *SlotMDS = ObjectSlot->getOperand(0);
612 if (SlotMDS->getValueID() == llvm::Value::MDStringVal) {
613 llvm::StringRef Slot =
614 static_cast<llvm::MDString*>(SlotMDS)->getString();
615 uint32_t USlot = 0;
616 if (Slot.getAsInteger(10, USlot)) {
617 setError("Non-integer object slot value '" + Slot.str() + "'");
618 goto on_bcc_compile_error;
619 }
620 objectSlotList.push_back(USlot);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700621#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000622 ALOGD("compile(): RefCount Slot: %s @ %u\n", Slot.str().c_str(), USlot);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700623#endif
Logan Chienda5e0c32011-06-13 03:47:21 +0800624 }
625 }
626 }
Logan Chienda5e0c32011-06-13 03:47:21 +0800627 }
628
629on_bcc_compile_error:
Steve Block10c14122012-01-08 10:15:06 +0000630 // ALOGE("on_bcc_compiler_error");
Logan Chienda5e0c32011-06-13 03:47:21 +0800631 if (TD) {
632 delete TD;
633 }
634
635 if (TM) {
636 delete TM;
637 }
638
639 if (mError.empty()) {
640 return 0;
641 }
642
Steve Block10c14122012-01-08 10:15:06 +0000643 // ALOGE(getErrorMessage());
Logan Chienda5e0c32011-06-13 03:47:21 +0800644 return 1;
645}
646
647
648#if USE_OLD_JIT
649int Compiler::runCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM,
650 llvm::NamedMDNode const *ExportVarMetadata,
651 llvm::NamedMDNode const *ExportFuncMetadata) {
Logan1f028c02010-11-27 01:02:48 +0800652 // Create memory manager for creation of code emitter later.
653 if (!mCodeMemMgr.get() && !createCodeMemoryManager()) {
654 setError("Failed to startup memory management for further compilation");
Logan Chienda5e0c32011-06-13 03:47:21 +0800655 return 1;
Logan1f028c02010-11-27 01:02:48 +0800656 }
Logan02286cb2011-01-07 00:30:47 +0800657
658 mpResult->mContext = (char *) (mCodeMemMgr.get()->getCodeMemBase());
Logan1f028c02010-11-27 01:02:48 +0800659
660 // Create code emitter
661 if (!mCodeEmitter.get()) {
662 if (!createCodeEmitter()) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800663 setError("Failed to create machine code emitter for compilation");
664 return 1;
Logan1f028c02010-11-27 01:02:48 +0800665 }
666 } else {
667 // Reuse the code emitter
668 mCodeEmitter->reset();
669 }
670
671 mCodeEmitter->setTargetMachine(*TM);
672 mCodeEmitter->registerSymbolCallback(mpSymbolLookupFn,
673 mpSymbolLookupContext);
674
Logan1f028c02010-11-27 01:02:48 +0800675 // Create code-gen pass to run the code emitter
Logan Chienda5e0c32011-06-13 03:47:21 +0800676 llvm::OwningPtr<llvm::FunctionPassManager> CodeGenPasses(
677 new llvm::FunctionPassManager(mModule));
Logan1f028c02010-11-27 01:02:48 +0800678
Logan Chienda5e0c32011-06-13 03:47:21 +0800679 // Add TargetData to code generation pass manager
680 CodeGenPasses->add(TD);
681
682 // Add code emit passes
Logan1f028c02010-11-27 01:02:48 +0800683 if (TM->addPassesToEmitMachineCode(*CodeGenPasses,
684 *mCodeEmitter,
685 CodeGenOptLevel)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800686 setError("The machine code emission is not supported on '" + Triple + "'");
687 return 1;
Logan1f028c02010-11-27 01:02:48 +0800688 }
689
Logan Chienda5e0c32011-06-13 03:47:21 +0800690 // Run the code emitter on every non-declaration function in the module
Logan1f028c02010-11-27 01:02:48 +0800691 CodeGenPasses->doInitialization();
Logan Chienda5e0c32011-06-13 03:47:21 +0800692 for (llvm::Module::iterator
693 I = mModule->begin(), E = mModule->end(); I != E; I++) {
Logan1f028c02010-11-27 01:02:48 +0800694 if (!I->isDeclaration()) {
695 CodeGenPasses->run(*I);
696 }
697 }
698
699 CodeGenPasses->doFinalization();
Logan Chienb0ceca22011-06-12 13:34:49 +0800700
Logan1f028c02010-11-27 01:02:48 +0800701 // Copy the global address mapping from code emitter and remapping
702 if (ExportVarMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800703 ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
704
Logan1f028c02010-11-27 01:02:48 +0800705 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
706 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
707 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
708 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
709 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
710 llvm::StringRef ExportVarName =
711 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
712
713 CodeEmitter::global_addresses_const_iterator I, E;
714 for (I = mCodeEmitter->global_address_begin(),
715 E = mCodeEmitter->global_address_end();
716 I != E; I++) {
717 if (I->first->getValueID() != llvm::Value::GlobalVariableVal)
718 continue;
719 if (ExportVarName == I->first->getName()) {
Logan2a6dc822011-01-06 04:05:20 +0800720 varList.push_back(I->second);
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700721#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000722 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n", ExportVarName.str().c_str(), I->second);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700723#endif
Logan1f028c02010-11-27 01:02:48 +0800724 break;
725 }
726 }
727 if (I != mCodeEmitter->global_address_end())
728 continue; // found
Logan Chien7d1bf582011-06-13 23:22:40 +0800729
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700730#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000731 ALOGD("runCodeGen(): Exported VAR: %s @ %p\n",
Logan Chien7d1bf582011-06-13 23:22:40 +0800732 ExportVarName.str().c_str(), (void *)0);
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700733#endif
Logan1f028c02010-11-27 01:02:48 +0800734 }
735 }
736 // if reaching here, we know the global variable record in metadata is
737 // not found. So we make an empty slot
Logan2a6dc822011-01-06 04:05:20 +0800738 varList.push_back(NULL);
Logan1f028c02010-11-27 01:02:48 +0800739 }
Logan2a6dc822011-01-06 04:05:20 +0800740
Stephen Hinesbbcef8a2011-05-04 19:40:10 -0700741 bccAssert((varList.size() == ExportVarMetadata->getNumOperands()) &&
742 "Number of slots doesn't match the number of export variables!");
Logan1f028c02010-11-27 01:02:48 +0800743 }
744
745 if (ExportFuncMetadata) {
Logan2a6dc822011-01-06 04:05:20 +0800746 ScriptCompiled::ExportFuncList &funcList = mpResult->mExportFuncs;
747
Logan1f028c02010-11-27 01:02:48 +0800748 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
749 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
750 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
751 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
752 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
753 llvm::StringRef ExportFuncName =
754 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
Logan7dcaac92011-01-06 04:26:23 +0800755 funcList.push_back(mpResult->lookup(ExportFuncName.str().c_str()));
Shih-wei Liao9f73de02011-07-01 04:40:24 -0700756#if DEBUG_BCC_REFLECT
Steve Blockb20498e2011-12-20 16:24:20 +0000757 ALOGD("runCodeGen(): Exported Func: %s @ %p\n", ExportFuncName.str().c_str(),
Logan Chien7d1bf582011-06-13 23:22:40 +0800758 funcList.back());
Shih-wei Liao749a51c2011-06-17 16:02:18 -0700759#endif
Logan1f028c02010-11-27 01:02:48 +0800760 }
761 }
762 }
763 }
764
765 // Tell code emitter now can release the memory using during the JIT since
766 // we have done the code emission
767 mCodeEmitter->releaseUnnecessary();
768
Logan Chienda5e0c32011-06-13 03:47:21 +0800769 return 0;
Logan1f028c02010-11-27 01:02:48 +0800770}
Logan Chienda5e0c32011-06-13 03:47:21 +0800771#endif // USE_OLD_JIT
Logan1f028c02010-11-27 01:02:48 +0800772
773
Logan Chienda5e0c32011-06-13 03:47:21 +0800774#if USE_MCJIT
Joseph Wen34c600a2011-07-25 17:59:17 -0700775int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800776 // Decorate mEmittedELFExecutable with formatted ostream
777 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
778
779 // Relax all machine instructions
780 TM->setMCRelaxAll(/* RelaxAll= */ true);
781
782 // Create MC code generation pass manager
783 llvm::PassManager MCCodeGenPasses;
784
785 // Add TargetData to MC code generation pass manager
786 MCCodeGenPasses.add(TD);
787
788 // Add MC code generation passes to pass manager
Daniel Malea094881f2011-12-14 17:39:16 -0500789 llvm::MCContext *Ctx = NULL;
Logan Chien4e4485d2011-11-25 18:12:33 +0800790 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
Logan Chienda5e0c32011-06-13 03:47:21 +0800791 setError("Fail to add passes to emit file");
792 return 1;
793 }
794
795 MCCodeGenPasses.run(*mModule);
796 OutSVOS.flush();
Logan Chienda5e0c32011-06-13 03:47:21 +0800797 return 0;
798}
799#endif // USE_MCJIT
800
Stephen Hinescc366e52012-02-21 17:22:04 -0800801int Compiler::runInternalPasses(std::vector<std::string>& Names,
802 std::vector<uint32_t>& Signatures) {
Stephen Hinesdb169182012-01-05 18:46:36 -0800803 llvm::PassManager BCCPasses;
804
805 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hinescc366e52012-02-21 17:22:04 -0800806 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Stephen Hinesdb169182012-01-05 18:46:36 -0800807
808 BCCPasses.run(*mModule);
809
810 return 0;
811}
Logan Chienda5e0c32011-06-13 03:47:21 +0800812
813int Compiler::runLTO(llvm::TargetData *TD,
814 llvm::NamedMDNode const *ExportVarMetadata,
Stephen Hinescc366e52012-02-21 17:22:04 -0800815 llvm::NamedMDNode const *ExportFuncMetadata,
Stephen Hinese0918ac2012-03-01 23:28:09 -0800816 std::vector<std::string>& ForEachExpandList,
Daniel Malea094881f2011-12-14 17:39:16 -0500817 llvm::CodeGenOpt::Level OptimizationLevel) {
Logan Chien4cc00332011-06-12 14:00:46 +0800818 // Collect All Exported Symbols
819 std::vector<const char*> ExportSymbols;
820
821 // Note: This is a workaround for getting export variable and function name.
822 // We should refine it soon.
823 if (ExportVarMetadata) {
824 for (int i = 0, e = ExportVarMetadata->getNumOperands(); i != e; i++) {
825 llvm::MDNode *ExportVar = ExportVarMetadata->getOperand(i);
826 if (ExportVar != NULL && ExportVar->getNumOperands() > 1) {
827 llvm::Value *ExportVarNameMDS = ExportVar->getOperand(0);
828 if (ExportVarNameMDS->getValueID() == llvm::Value::MDStringVal) {
829 llvm::StringRef ExportVarName =
830 static_cast<llvm::MDString*>(ExportVarNameMDS)->getString();
831 ExportSymbols.push_back(ExportVarName.data());
832 }
833 }
834 }
835 }
836
837 if (ExportFuncMetadata) {
838 for (int i = 0, e = ExportFuncMetadata->getNumOperands(); i != e; i++) {
839 llvm::MDNode *ExportFunc = ExportFuncMetadata->getOperand(i);
840 if (ExportFunc != NULL && ExportFunc->getNumOperands() > 0) {
841 llvm::Value *ExportFuncNameMDS = ExportFunc->getOperand(0);
842 if (ExportFuncNameMDS->getValueID() == llvm::Value::MDStringVal) {
843 llvm::StringRef ExportFuncName =
844 static_cast<llvm::MDString*>(ExportFuncNameMDS)->getString();
845 ExportSymbols.push_back(ExportFuncName.data());
846 }
847 }
848 }
849 }
850
Stephen Hinescc366e52012-02-21 17:22:04 -0800851 for (int i = 0, e = ForEachExpandList.size(); i != e; i++) {
852 ExportSymbols.push_back(ForEachExpandList[i].c_str());
853 }
854
Logan Chien7890d432011-08-03 14:55:17 +0800855 // TODO(logan): Remove this after we have finished the
856 // bccMarkExternalSymbol API.
857
Stephen Hines64160102011-09-01 17:30:26 -0700858 // root(), init(), and .rs.dtor() are born to be exported
Logan Chien4cc00332011-06-12 14:00:46 +0800859 ExportSymbols.push_back("root");
860 ExportSymbols.push_back("init");
Stephen Hines64160102011-09-01 17:30:26 -0700861 ExportSymbols.push_back(".rs.dtor");
Logan Chien4cc00332011-06-12 14:00:46 +0800862
Logan Chien7890d432011-08-03 14:55:17 +0800863 // User-defined exporting symbols
864 std::vector<char const *> const &UserDefinedExternalSymbols =
865 mpResult->getUserDefinedExternalSymbols();
866
867 std::copy(UserDefinedExternalSymbols.begin(),
868 UserDefinedExternalSymbols.end(),
869 std::back_inserter(ExportSymbols));
870
Daniel Malea094881f2011-12-14 17:39:16 -0500871 llvm::PassManager LTOPasses;
872
873 // Add TargetData to LTO passes
874 LTOPasses.add(TD);
875
Logan Chien4cc00332011-06-12 14:00:46 +0800876 // We now create passes list performing LTO. These are copied from
877 // (including comments) llvm::createStandardLTOPasses().
Daniel Malea094881f2011-12-14 17:39:16 -0500878 // Only a subset of these LTO passes are enabled in optimization level 0
879 // as they interfere with interactive debugging.
880 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
Logan Chien4cc00332011-06-12 14:00:46 +0800881
Daniel Malea094881f2011-12-14 17:39:16 -0500882 if (OptimizationLevel != llvm::CodeGenOpt::None) {
883 // Internalize all other symbols not listed in ExportSymbols
884 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
Logan Chien4cc00332011-06-12 14:00:46 +0800885
Daniel Malea094881f2011-12-14 17:39:16 -0500886 // Propagate constants at call sites into the functions they call. This
887 // opens opportunities for globalopt (and inlining) by substituting
888 // function pointers passed as arguments to direct uses of functions.
889 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800890
Daniel Malea094881f2011-12-14 17:39:16 -0500891 // Now that we internalized some globals, see if we can hack on them!
892 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800893
Daniel Malea094881f2011-12-14 17:39:16 -0500894 // Linking modules together can lead to duplicated global constants, only
895 // keep one copy of each constant...
896 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800897
Daniel Malea094881f2011-12-14 17:39:16 -0500898 // Remove unused arguments from functions...
899 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800900
Daniel Malea094881f2011-12-14 17:39:16 -0500901 // Reduce the code after globalopt and ipsccp. Both can open up
902 // significant simplification opportunities, and both can propagate
903 // functions through function pointers. When this happens, we often have
904 // to resolve varargs calls, etc, so let instcombine do this.
905 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800906
Daniel Malea094881f2011-12-14 17:39:16 -0500907 // Inline small functions
908 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800909
Daniel Malea094881f2011-12-14 17:39:16 -0500910 // Remove dead EH info.
911 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800912
Daniel Malea094881f2011-12-14 17:39:16 -0500913 // Internalize the globals again after inlining
914 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800915
Daniel Malea094881f2011-12-14 17:39:16 -0500916 // Remove dead functions.
917 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800918
Daniel Malea094881f2011-12-14 17:39:16 -0500919 // If we didn't decide to inline a function, check to see if we can
920 // transform it to pass arguments by value instead of by reference.
921 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800922
Daniel Malea094881f2011-12-14 17:39:16 -0500923 // The IPO passes may leave cruft around. Clean up after them.
924 LTOPasses.add(llvm::createInstructionCombiningPass());
925 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800926
Daniel Malea094881f2011-12-14 17:39:16 -0500927 // Break up allocas
928 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800929
Daniel Malea094881f2011-12-14 17:39:16 -0500930 // Run a few AA driven optimizations here and now, to cleanup the code.
931 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
932 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800933
Daniel Malea094881f2011-12-14 17:39:16 -0500934 // Hoist loop invariants.
935 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800936
Daniel Malea094881f2011-12-14 17:39:16 -0500937 // Remove redundancies.
938 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800939
Daniel Malea094881f2011-12-14 17:39:16 -0500940 // Remove dead memcpys.
941 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800942
Daniel Malea094881f2011-12-14 17:39:16 -0500943 // Nuke dead stores.
944 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800945
Daniel Malea094881f2011-12-14 17:39:16 -0500946 // Cleanup and simplify the code after the scalar optimizations.
947 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800948
Daniel Malea094881f2011-12-14 17:39:16 -0500949 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800950
Daniel Malea094881f2011-12-14 17:39:16 -0500951 // Delete basic blocks, which optimization passes may have killed.
952 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800953
Daniel Malea094881f2011-12-14 17:39:16 -0500954 // Now that we have optimized the program, discard unreachable functions.
955 LTOPasses.add(llvm::createGlobalDCEPass());
956
957 } else {
958 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
959 LTOPasses.add(llvm::createGlobalOptimizerPass());
960 LTOPasses.add(llvm::createConstantMergePass());
961 }
Logan Chien4cc00332011-06-12 14:00:46 +0800962
963 LTOPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800964
Daniel Malea094881f2011-12-14 17:39:16 -0500965#if ANDROID_ENGINEERING_BUILD
966 if (0 != gDebugDumpDirectory) {
967 std::string errs;
968 std::string Filename(gDebugDumpDirectory);
969 Filename += "/post-lto-module.ll";
970 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
971 mModule->print(FS, 0);
972 FS.close();
973 }
974#endif
975
Logan Chienda5e0c32011-06-13 03:47:21 +0800976 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800977}
978
979
Logan Chienda5e0c32011-06-13 03:47:21 +0800980#if USE_MCJIT
Logan Chienda5e0c32011-06-13 03:47:21 +0800981void *Compiler::getSymbolAddress(char const *name) {
982 return rsloaderGetSymbolAddress(mRSExecutable, name);
983}
984#endif
985
986
987#if USE_MCJIT
988void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
989 Compiler *self = reinterpret_cast<Compiler *>(context);
990
991 if (void *Addr = FindRuntimeFunction(name)) {
992 return Addr;
993 }
994
995 if (self->mpSymbolLookupFn) {
996 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
997 return Addr;
998 }
999 }
1000
Steve Block10c14122012-01-08 10:15:06 +00001001 ALOGE("Unable to resolve symbol: %s\n", name);
Logan Chienda5e0c32011-06-13 03:47:21 +08001002 return NULL;
1003}
1004#endif
1005
1006
Logan1f028c02010-11-27 01:02:48 +08001007Compiler::~Compiler() {
Logan Chienda5e0c32011-06-13 03:47:21 +08001008#if USE_MCJIT
1009 rsloaderDisposeExec(mRSExecutable);
1010#endif
1011
Logana4994f52010-11-27 14:06:02 +08001012 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +08001013}
1014
Shih-wei Liao90cd3d12011-06-20 15:43:34 -07001015
Logan1f028c02010-11-27 01:02:48 +08001016} // namespace bcc