blob: c4a08704a7da073561419c6d4aa065d6a89b8d8e [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
Stephen Hines2f6a4932012-05-03 12:27:13 -070017#include "Compiler.h"
Logan1f028c02010-11-27 01:02:48 +080018
Stephen Hines4a68b1c2012-05-03 12:28:14 -070019#include "Config.h"
20#include <bcinfo/MetadataExtractor.h>
Logan35849002011-01-15 07:30:43 +080021
Stephen Hines4a68b1c2012-05-03 12:28:14 -070022#if USE_DISASSEMBLER
23#include "Disassembler/Disassembler.h"
24#endif
25
26#include "BCCRuntimeSymbolResolver.h"
Stephen Hines2f6a4932012-05-03 12:27:13 -070027#include "DebugHelper.h"
Stephen Hines4a68b1c2012-05-03 12:28:14 -070028#include "ScriptCompiled.h"
29#include "Sha1Helper.h"
30#include "CompilerOption.h"
31#include "SymbolResolverProxy.h"
32#include "SymbolResolvers.h"
Loganeb3d12b2010-12-16 06:20:18 +080033
Stephen Hines4a68b1c2012-05-03 12:28:14 -070034#include "librsloader.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080035
Stephen Hines09ebd172012-05-03 12:28:26 -070036#include "Transforms/BCCTransforms.h"
Stephen Hinesdb169182012-01-05 18:46:36 -080037
Stephen Hines4a68b1c2012-05-03 12:28:14 -070038#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080039
Stephen Hines4a68b1c2012-05-03 12:28:14 -070040#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080041
Stephen Hines4a68b1c2012-05-03 12:28:14 -070042#include "llvm/CodeGen/Passes.h"
43#include "llvm/CodeGen/RegAllocRegistry.h"
44#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080045
Stephen Hines4a68b1c2012-05-03 12:28:14 -070046#include "llvm/MC/MCContext.h"
47#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao40bcd662011-10-22 17:51:01 -070048
Stephen Hines4a68b1c2012-05-03 12:28:14 -070049#include "llvm/Transforms/IPO.h"
50#include "llvm/Transforms/Scalar.h"
Logan1f028c02010-11-27 01:02:48 +080051
Stephen Hines4a68b1c2012-05-03 12:28:14 -070052#include "llvm/Target/TargetData.h"
53#include "llvm/Target/TargetMachine.h"
Logan1f028c02010-11-27 01:02:48 +080054
Stephen Hines4a68b1c2012-05-03 12:28:14 -070055#include "llvm/Support/ErrorHandling.h"
56#include "llvm/Support/FormattedStream.h"
57#include "llvm/Support/TargetRegistry.h"
58#include "llvm/Support/TargetSelect.h"
59#include "llvm/Support/raw_ostream.h"
Zonr Changfef9a1b2012-04-13 15:58:24 +080060
Stephen Hines4a68b1c2012-05-03 12:28:14 -070061#include "llvm/Constants.h"
62#include "llvm/GlobalValue.h"
63#include "llvm/Linker.h"
64#include "llvm/LLVMContext.h"
65#include "llvm/Module.h"
66#include "llvm/PassManager.h"
67#include "llvm/Type.h"
68#include "llvm/Value.h"
69
70#include <errno.h>
71#include <sys/file.h>
72#include <sys/stat.h>
73#include <sys/types.h>
74#include <unistd.h>
75
76#include <string.h>
77
78#include <algorithm>
79#include <iterator>
80#include <string>
81#include <vector>
82
83extern char* gDebugDumpDirectory;
84
85namespace bcc {
86
87//////////////////////////////////////////////////////////////////////////////
88// BCC Compiler Static Variables
89//////////////////////////////////////////////////////////////////////////////
90
91bool Compiler::GlobalInitialized = false;
92
93
94#if !defined(__HOST__)
95 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
96#else
97// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
98 #if defined(__cplusplus)
99 extern "C" {
100 #endif
101 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
102 #if defined(__cplusplus)
103 };
104 #endif
105#endif
106
107// Code generation optimization level for the compiler
108llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
109
110std::string Compiler::Triple;
111llvm::Triple::ArchType Compiler::ArchType;
112
113std::string Compiler::CPU;
114
115std::vector<std::string> Compiler::Features;
116
117
118//////////////////////////////////////////////////////////////////////////////
119// Compiler
120//////////////////////////////////////////////////////////////////////////////
121
122void Compiler::GlobalInitialization() {
123 if (GlobalInitialized) {
Zonr Changfef9a1b2012-04-13 15:58:24 +0800124 return;
Logan1f028c02010-11-27 01:02:48 +0800125 }
Zonr Changfef9a1b2012-04-13 15:58:24 +0800126
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700127#if defined(PROVIDE_ARM_CODEGEN)
128 LLVMInitializeARMAsmPrinter();
129 LLVMInitializeARMTargetMC();
130 LLVMInitializeARMTargetInfo();
131 LLVMInitializeARMTarget();
132#endif
133
134#if defined(PROVIDE_MIPS_CODEGEN)
135 LLVMInitializeMipsAsmPrinter();
136 LLVMInitializeMipsTargetMC();
137 LLVMInitializeMipsTargetInfo();
138 LLVMInitializeMipsTarget();
139#endif
140
141#if defined(PROVIDE_X86_CODEGEN)
142 LLVMInitializeX86AsmPrinter();
143 LLVMInitializeX86TargetMC();
144 LLVMInitializeX86TargetInfo();
145 LLVMInitializeX86Target();
146#endif
147
148#if USE_DISASSEMBLER
149 InitializeDisassembler();
150#endif
151
152 // if (!llvm::llvm_is_multithreaded())
153 // llvm::llvm_start_multithreaded();
154
155 // Set Triple, CPU and Features here
156 Triple = TARGET_TRIPLE_STRING;
157
158 // Determine ArchType
159#if defined(__HOST__)
160 {
161 std::string Err;
162 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
163 if (Target != NULL) {
164 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
165 } else {
166 ArchType = llvm::Triple::UnknownArch;
167 ALOGE("%s", Err.c_str());
168 }
169 }
170#elif defined(DEFAULT_ARM_CODEGEN)
171 ArchType = llvm::Triple::arm;
172#elif defined(DEFAULT_MIPS_CODEGEN)
173 ArchType = llvm::Triple::mipsel;
174#elif defined(DEFAULT_X86_CODEGEN)
175 ArchType = llvm::Triple::x86;
176#elif defined(DEFAULT_X86_64_CODEGEN)
177 ArchType = llvm::Triple::x86_64;
178#else
179 ArchType = llvm::Triple::UnknownArch;
180#endif
181
182 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
183# if defined(ARCH_ARM_HAVE_VFP)
184 Features.push_back("+vfp3");
185# if !defined(ARCH_ARM_HAVE_VFP_D32)
186 Features.push_back("+d16");
187# endif
188# endif
189
190# if defined(ARCH_ARM_HAVE_NEON)
191 Features.push_back("+neon");
192 Features.push_back("+neonfp");
193# else
194 Features.push_back("-neon");
195 Features.push_back("-neonfp");
196# endif
197
198// FIXME(all): Turn NEON back on after debugging the rebase.
199# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
200 Features.push_back("-neon");
201 Features.push_back("-neonfp");
202# endif
203 }
204
205 // Register the scheduler
206 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
207
208 // Read in SHA1 checksum of libbcc and libRS.
209 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
210
211 calcFileSHA1(sha1LibRS, pathLibRS);
212
213 GlobalInitialized = true;
214}
215
216
217void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
218 std::string *Error = static_cast<std::string*>(UserData);
219 Error->assign(Message);
220 ALOGE("%s", Message.c_str());
221 exit(1);
222}
223
224
225Compiler::Compiler(ScriptCompiled *result)
226 : mpResult(result),
227 mRSExecutable(NULL),
228 mpSymbolLookupFn(NULL),
229 mpSymbolLookupContext(NULL),
230 mModule(NULL) {
231 llvm::remove_fatal_error_handler();
232 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Zonr Changfef9a1b2012-04-13 15:58:24 +0800233 return;
Logan1f028c02010-11-27 01:02:48 +0800234}
235
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700236int Compiler::readModule(llvm::Module &pModule) {
237 mModule = &pModule;
238 if (pModule.getMaterializer() != NULL) {
239 // A module with non-null materializer means that it is a lazy-load module.
240 // Materialize it now via invoking MaterializeAllPermanently(). This
241 // function returns false when the materialization is successful.
242 if (pModule.MaterializeAllPermanently(&mError)) {
243 setError("Failed to materialize the module `" +
244 pModule.getModuleIdentifier() + "'! (" + mError + ")");
245 mModule = NULL;
246 }
247 }
248 return hasError();
249}
250
251int Compiler::compile(const CompilerOption &option) {
252 llvm::Target const *Target = NULL;
253 llvm::TargetData *TD = NULL;
254 llvm::TargetMachine *TM = NULL;
255
256 std::string FeaturesStr;
257
258 if (mModule == NULL) // No module was loaded
259 return 0;
260
261 bcinfo::MetadataExtractor ME(mModule);
262 ME.extract();
263
264 size_t VarCount = ME.getExportVarCount();
265 size_t FuncCount = ME.getExportFuncCount();
266 size_t ForEachSigCount = ME.getExportForEachSignatureCount();
267 size_t ObjectSlotCount = ME.getObjectSlotCount();
268 size_t PragmaCount = ME.getPragmaCount();
269
270 std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
271 std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
272 std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
Stephen Hines09ebd172012-05-03 12:28:26 -0700273 std::vector<std::string> ForEachNameList;
274 std::vector<uint32_t> ForEachSigList;
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700275 std::vector<const char*> ExportSymbols;
276
277 // Defaults to maximum optimization level from MetadataExtractor.
278 uint32_t OptimizationLevel = ME.getOptimizationLevel();
279
280 if (OptimizationLevel == 0) {
281 CodeGenOptLevel = llvm::CodeGenOpt::None;
282 } else if (OptimizationLevel == 1) {
283 CodeGenOptLevel = llvm::CodeGenOpt::Less;
284 } else if (OptimizationLevel == 2) {
285 CodeGenOptLevel = llvm::CodeGenOpt::Default;
286 } else if (OptimizationLevel == 3) {
287 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Daniel Malea094881f2011-12-14 17:39:16 -0500288 }
289
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700290 // not the best place for this, but we need to set the register allocation
291 // policy after we read the optimization_level metadata from the bitcode
Daniel Malea094881f2011-12-14 17:39:16 -0500292
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700293 // Register allocation policy:
Daniel Malea094881f2011-12-14 17:39:16 -0500294 // createFastRegisterAllocator: fast but bad quality
295 // createLinearScanRegisterAllocator: not so fast but good quality
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700296 llvm::RegisterRegAlloc::setDefault
297 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
298 llvm::createFastRegisterAllocator :
299 llvm::createGreedyRegisterAllocator);
300
301 // Find LLVM Target
302 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
303 if (hasError())
304 goto on_bcc_compile_error;
305
306#if defined(ARCH_ARM_HAVE_NEON)
307 // Full-precision means we have to disable NEON
308 if (ME.getRSFloatPrecision() == bcinfo::RS_FP_Full) {
309 Features.push_back("-neon");
310 Features.push_back("-neonfp");
311 }
312#endif
313
314 if (!CPU.empty() || !Features.empty()) {
315 llvm::SubtargetFeatures F;
316
317 for (std::vector<std::string>::const_iterator
318 I = Features.begin(), E = Features.end(); I != E; I++) {
319 F.AddFeature(*I);
320 }
321
322 FeaturesStr = F.getString();
Logan1f028c02010-11-27 01:02:48 +0800323 }
324
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700325 // Create LLVM Target Machine
326 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
327 option.TargetOpt,
328 option.RelocModelOpt,
329 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800330
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700331 if (TM == NULL) {
332 setError("Failed to create target machine implementation for the"
333 " specified triple '" + Triple + "'");
334 goto on_bcc_compile_error;
335 }
336
337 // Get target data from Module
338 TD = new llvm::TargetData(mModule);
339
340 // Read pragma information from MetadataExtractor
341 if (PragmaCount) {
342 ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
343 const char **PragmaKeys = ME.getPragmaKeyList();
344 const char **PragmaValues = ME.getPragmaValueList();
345 for (size_t i = 0; i < PragmaCount; i++) {
346 PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
347 }
348 }
349
350 if (VarCount) {
351 const char **VarNames = ME.getExportVarNameList();
352 for (size_t i = 0; i < VarCount; i++) {
353 VarNameList.push_back(VarNames[i]);
354 ExportSymbols.push_back(VarNames[i]);
355 }
356 }
357
358 if (FuncCount) {
359 const char **FuncNames = ME.getExportFuncNameList();
360 for (size_t i = 0; i < FuncCount; i++) {
361 FuncNameList.push_back(FuncNames[i]);
362 ExportSymbols.push_back(FuncNames[i]);
363 }
364 }
365
366 if (ForEachSigCount) {
367 const char **ForEachNames = ME.getExportForEachNameList();
368 const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
369 for (size_t i = 0; i < ForEachSigCount; i++) {
Stephen Hines09ebd172012-05-03 12:28:26 -0700370 std::string Name(ForEachNames[i]);
371 ForEachNameList.push_back(Name);
372 ForEachExpandList.push_back(Name + ".expand");
373 ForEachSigList.push_back(ForEachSigs[i]);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700374 }
375
376 // Need to wait until ForEachExpandList is fully populated to fill in
377 // exported symbols.
378 for (size_t i = 0; i < ForEachSigCount; i++) {
379 ExportSymbols.push_back(ForEachExpandList[i].c_str());
380 }
381 }
382
383 if (ObjectSlotCount) {
384 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
385 const uint32_t *ObjectSlots = ME.getObjectSlotList();
386 for (size_t i = 0; i < ObjectSlotCount; i++) {
387 objectSlotList.push_back(ObjectSlots[i]);
388 }
389 }
390
Stephen Hines09ebd172012-05-03 12:28:26 -0700391 runInternalPasses(ForEachNameList, ForEachSigList);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700392
393 // Perform link-time optimization if we have multiple modules
394 if (option.RunLTO) {
395 runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
396 }
397
398 // Perform code generation
399 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
400 goto on_bcc_compile_error;
401 }
402
403 if (!option.LoadAfterCompile)
404 return 0;
405
406 // Load the ELF Object
407 {
408 BCCRuntimeSymbolResolver BCCRuntimesResolver;
409 LookupFunctionSymbolResolver<void*> RSSymbolResolver(mpSymbolLookupFn,
410 mpSymbolLookupContext);
411
412 SymbolResolverProxy Resolver;
413 Resolver.chainResolver(BCCRuntimesResolver);
414 Resolver.chainResolver(RSSymbolResolver);
415
416 mRSExecutable =
417 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
418 mEmittedELFExecutable.size(),
419 SymbolResolverProxy::LookupFunction, &Resolver);
420 }
421
422 if (!mRSExecutable) {
423 setError("Fail to load emitted ELF relocatable file");
424 goto on_bcc_compile_error;
425 }
426
427 rsloaderUpdateSectionHeaders(mRSExecutable,
428 (unsigned char*) mEmittedELFExecutable.begin());
429
430 // Once the ELF object has been loaded, populate the various slots for RS
431 // with the appropriate relocated addresses.
432 if (VarCount) {
433 ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
434 for (size_t i = 0; i < VarCount; i++) {
435 VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
436 VarNameList[i].c_str()));
437 }
438 }
439
440 if (FuncCount) {
441 ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
442 for (size_t i = 0; i < FuncCount; i++) {
443 FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
444 FuncNameList[i].c_str()));
445 }
446 }
447
448 if (ForEachSigCount) {
449 ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
450 for (size_t i = 0; i < ForEachSigCount; i++) {
451 ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
452 ForEachExpandList[i].c_str()));
453 }
454 }
455
456#if DEBUG_MC_DISASSEMBLER
457 {
458 // Get MC codegen emitted function name list
459 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
460 std::vector<char const *> func_list(func_list_size, NULL);
461 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
462
463 // Disassemble each function
464 for (size_t i = 0; i < func_list_size; ++i) {
465 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
466 if (func) {
467 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
468 Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
469 Target, TM, func_list[i], (unsigned char const *)func, size);
470 }
471 }
472 }
473#endif
474
475on_bcc_compile_error:
476 // ALOGE("on_bcc_compiler_error");
477 if (TD) {
478 delete TD;
479 }
480
481 if (TM) {
482 delete TM;
483 }
484
485 if (mError.empty()) {
486 return 0;
487 }
488
489 // ALOGE(getErrorMessage());
490 return 1;
Logan Chienda5e0c32011-06-13 03:47:21 +0800491}
492
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700493
494int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
495 // Decorate mEmittedELFExecutable with formatted ostream
496 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
497
498 // Relax all machine instructions
499 TM->setMCRelaxAll(/* RelaxAll= */ true);
500
501 // Create MC code generation pass manager
502 llvm::PassManager MCCodeGenPasses;
503
504 // Add TargetData to MC code generation pass manager
505 MCCodeGenPasses.add(TD);
506
507 // Add MC code generation passes to pass manager
508 llvm::MCContext *Ctx = NULL;
509 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
510 setError("Fail to add passes to emit file");
511 return 1;
512 }
513
514 MCCodeGenPasses.run(*mModule);
515 OutSVOS.flush();
516 return 0;
Zonr Changfef9a1b2012-04-13 15:58:24 +0800517}
Logan Chienda5e0c32011-06-13 03:47:21 +0800518
Stephen Hines09ebd172012-05-03 12:28:26 -0700519int Compiler::runInternalPasses(std::vector<std::string>& Names,
520 std::vector<uint32_t>& Signatures) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700521 llvm::PassManager BCCPasses;
Logan Chienda5e0c32011-06-13 03:47:21 +0800522
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700523 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hines09ebd172012-05-03 12:28:26 -0700524 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Logan Chienda5e0c32011-06-13 03:47:21 +0800525
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700526 BCCPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800527
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700528 return 0;
529}
Logan Chienda5e0c32011-06-13 03:47:21 +0800530
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700531int Compiler::runLTO(llvm::TargetData *TD,
532 std::vector<const char*>& ExportSymbols,
533 llvm::CodeGenOpt::Level OptimizationLevel) {
534 // Note: ExportSymbols is a workaround for getting all exported variable,
535 // function, and kernel names.
536 // We should refine it soon.
537
538 // TODO(logan): Remove this after we have finished the
539 // bccMarkExternalSymbol API.
540
541 // root(), init(), and .rs.dtor() are born to be exported
542 ExportSymbols.push_back("root");
543 ExportSymbols.push_back("init");
544 ExportSymbols.push_back(".rs.dtor");
545
546 // User-defined exporting symbols
547 std::vector<char const *> const &UserDefinedExternalSymbols =
548 mpResult->getUserDefinedExternalSymbols();
549
550 std::copy(UserDefinedExternalSymbols.begin(),
551 UserDefinedExternalSymbols.end(),
552 std::back_inserter(ExportSymbols));
553
554 llvm::PassManager LTOPasses;
555
556 // Add TargetData to LTO passes
557 LTOPasses.add(TD);
Daniel Malea094881f2011-12-14 17:39:16 -0500558
Logan Chien4cc00332011-06-12 14:00:46 +0800559 // We now create passes list performing LTO. These are copied from
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700560 // (including comments) llvm::createStandardLTOPasses().
561 // Only a subset of these LTO passes are enabled in optimization level 0
562 // as they interfere with interactive debugging.
563 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
564
565 if (OptimizationLevel != llvm::CodeGenOpt::None) {
566 // Internalize all other symbols not listed in ExportSymbols
567 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
568
Daniel Malea094881f2011-12-14 17:39:16 -0500569 // Propagate constants at call sites into the functions they call. This
570 // opens opportunities for globalopt (and inlining) by substituting
571 // function pointers passed as arguments to direct uses of functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700572 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800573
Daniel Malea094881f2011-12-14 17:39:16 -0500574 // Now that we internalized some globals, see if we can hack on them!
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700575 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800576
Daniel Malea094881f2011-12-14 17:39:16 -0500577 // Linking modules together can lead to duplicated global constants, only
578 // keep one copy of each constant...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700579 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800580
Daniel Malea094881f2011-12-14 17:39:16 -0500581 // Remove unused arguments from functions...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700582 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800583
Daniel Malea094881f2011-12-14 17:39:16 -0500584 // Reduce the code after globalopt and ipsccp. Both can open up
585 // significant simplification opportunities, and both can propagate
586 // functions through function pointers. When this happens, we often have
587 // to resolve varargs calls, etc, so let instcombine do this.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700588 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800589
Daniel Malea094881f2011-12-14 17:39:16 -0500590 // Inline small functions
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700591 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800592
Daniel Malea094881f2011-12-14 17:39:16 -0500593 // Remove dead EH info.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700594 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800595
Daniel Malea094881f2011-12-14 17:39:16 -0500596 // Internalize the globals again after inlining
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700597 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800598
Daniel Malea094881f2011-12-14 17:39:16 -0500599 // Remove dead functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700600 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800601
Daniel Malea094881f2011-12-14 17:39:16 -0500602 // If we didn't decide to inline a function, check to see if we can
603 // transform it to pass arguments by value instead of by reference.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700604 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800605
Daniel Malea094881f2011-12-14 17:39:16 -0500606 // The IPO passes may leave cruft around. Clean up after them.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700607 LTOPasses.add(llvm::createInstructionCombiningPass());
608 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800609
Daniel Malea094881f2011-12-14 17:39:16 -0500610 // Break up allocas
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700611 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800612
Daniel Malea094881f2011-12-14 17:39:16 -0500613 // Run a few AA driven optimizations here and now, to cleanup the code.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700614 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
615 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800616
Daniel Malea094881f2011-12-14 17:39:16 -0500617 // Hoist loop invariants.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700618 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800619
Daniel Malea094881f2011-12-14 17:39:16 -0500620 // Remove redundancies.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700621 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800622
Daniel Malea094881f2011-12-14 17:39:16 -0500623 // Remove dead memcpys.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700624 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800625
Daniel Malea094881f2011-12-14 17:39:16 -0500626 // Nuke dead stores.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700627 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800628
Daniel Malea094881f2011-12-14 17:39:16 -0500629 // Cleanup and simplify the code after the scalar optimizations.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700630 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800631
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700632 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800633
Daniel Malea094881f2011-12-14 17:39:16 -0500634 // Delete basic blocks, which optimization passes may have killed.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700635 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800636
Daniel Malea094881f2011-12-14 17:39:16 -0500637 // Now that we have optimized the program, discard unreachable functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700638 LTOPasses.add(llvm::createGlobalDCEPass());
639
640 } else {
641 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
642 LTOPasses.add(llvm::createGlobalOptimizerPass());
643 LTOPasses.add(llvm::createConstantMergePass());
Daniel Malea094881f2011-12-14 17:39:16 -0500644 }
Logan Chien4cc00332011-06-12 14:00:46 +0800645
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700646 LTOPasses.run(*mModule);
647
648#if ANDROID_ENGINEERING_BUILD
649 if (0 != gDebugDumpDirectory) {
650 std::string errs;
651 std::string Filename(gDebugDumpDirectory);
652 Filename += "/post-lto-module.ll";
653 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
654 mModule->print(FS, 0);
655 FS.close();
Daniel Malea094881f2011-12-14 17:39:16 -0500656 }
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700657#endif
Daniel Malea094881f2011-12-14 17:39:16 -0500658
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700659 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800660}
661
662
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700663void *Compiler::getSymbolAddress(char const *name) {
664 return rsloaderGetSymbolAddress(mRSExecutable, name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800665}
Logan Chienda5e0c32011-06-13 03:47:21 +0800666
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700667Compiler::~Compiler() {
668 rsloaderDisposeExec(mRSExecutable);
Logan Chienda5e0c32011-06-13 03:47:21 +0800669
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700670 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800671}
672
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700673
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700674} // namespace bcc