blob: a56c11c96b402c854f8fc064a96b7b711d6afdb1 [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
Stephen Hines2f6a4932012-05-03 12:27:13 -070026#include "DebugHelper.h"
Stephen Hines5fb14742012-05-03 12:29:50 -070027#include "Runtime.h"
Stephen Hines4a68b1c2012-05-03 12:28:14 -070028#include "ScriptCompiled.h"
29#include "Sha1Helper.h"
30#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080031
Stephen Hines4a68b1c2012-05-03 12:28:14 -070032#include "librsloader.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080033
Stephen Hines09ebd172012-05-03 12:28:26 -070034#include "Transforms/BCCTransforms.h"
Stephen Hinesdb169182012-01-05 18:46:36 -080035
Stephen Hines4a68b1c2012-05-03 12:28:14 -070036#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080037
Stephen Hines4a68b1c2012-05-03 12:28:14 -070038#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080039
Stephen Hines4a68b1c2012-05-03 12:28:14 -070040#include "llvm/CodeGen/Passes.h"
41#include "llvm/CodeGen/RegAllocRegistry.h"
42#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080043
Stephen Hines4a68b1c2012-05-03 12:28:14 -070044#include "llvm/MC/MCContext.h"
45#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao40bcd662011-10-22 17:51:01 -070046
Stephen Hines4a68b1c2012-05-03 12:28:14 -070047#include "llvm/Transforms/IPO.h"
48#include "llvm/Transforms/Scalar.h"
Logan1f028c02010-11-27 01:02:48 +080049
Stephen Hines4a68b1c2012-05-03 12:28:14 -070050#include "llvm/Target/TargetData.h"
51#include "llvm/Target/TargetMachine.h"
Logan1f028c02010-11-27 01:02:48 +080052
Stephen Hines4a68b1c2012-05-03 12:28:14 -070053#include "llvm/Support/ErrorHandling.h"
54#include "llvm/Support/FormattedStream.h"
55#include "llvm/Support/TargetRegistry.h"
56#include "llvm/Support/TargetSelect.h"
57#include "llvm/Support/raw_ostream.h"
Zonr Changfef9a1b2012-04-13 15:58:24 +080058
Stephen Hines4a68b1c2012-05-03 12:28:14 -070059#include "llvm/Constants.h"
60#include "llvm/GlobalValue.h"
61#include "llvm/Linker.h"
62#include "llvm/LLVMContext.h"
63#include "llvm/Module.h"
64#include "llvm/PassManager.h"
65#include "llvm/Type.h"
66#include "llvm/Value.h"
67
68#include <errno.h>
69#include <sys/file.h>
70#include <sys/stat.h>
71#include <sys/types.h>
72#include <unistd.h>
73
74#include <string.h>
75
76#include <algorithm>
77#include <iterator>
78#include <string>
79#include <vector>
80
81extern char* gDebugDumpDirectory;
82
83namespace bcc {
84
85//////////////////////////////////////////////////////////////////////////////
86// BCC Compiler Static Variables
87//////////////////////////////////////////////////////////////////////////////
88
89bool Compiler::GlobalInitialized = false;
90
91
92#if !defined(__HOST__)
93 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
94#else
95// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
96 #if defined(__cplusplus)
97 extern "C" {
98 #endif
99 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
100 #if defined(__cplusplus)
101 };
102 #endif
103#endif
104
105// Code generation optimization level for the compiler
106llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
107
108std::string Compiler::Triple;
109llvm::Triple::ArchType Compiler::ArchType;
110
111std::string Compiler::CPU;
112
113std::vector<std::string> Compiler::Features;
114
115
116//////////////////////////////////////////////////////////////////////////////
117// Compiler
118//////////////////////////////////////////////////////////////////////////////
119
120void Compiler::GlobalInitialization() {
121 if (GlobalInitialized) {
Zonr Changfef9a1b2012-04-13 15:58:24 +0800122 return;
Logan1f028c02010-11-27 01:02:48 +0800123 }
Zonr Changfef9a1b2012-04-13 15:58:24 +0800124
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700125#if defined(PROVIDE_ARM_CODEGEN)
126 LLVMInitializeARMAsmPrinter();
127 LLVMInitializeARMTargetMC();
128 LLVMInitializeARMTargetInfo();
129 LLVMInitializeARMTarget();
130#endif
131
132#if defined(PROVIDE_MIPS_CODEGEN)
133 LLVMInitializeMipsAsmPrinter();
134 LLVMInitializeMipsTargetMC();
135 LLVMInitializeMipsTargetInfo();
136 LLVMInitializeMipsTarget();
137#endif
138
139#if defined(PROVIDE_X86_CODEGEN)
140 LLVMInitializeX86AsmPrinter();
141 LLVMInitializeX86TargetMC();
142 LLVMInitializeX86TargetInfo();
143 LLVMInitializeX86Target();
144#endif
145
146#if USE_DISASSEMBLER
147 InitializeDisassembler();
148#endif
149
150 // if (!llvm::llvm_is_multithreaded())
151 // llvm::llvm_start_multithreaded();
152
153 // Set Triple, CPU and Features here
154 Triple = TARGET_TRIPLE_STRING;
155
156 // Determine ArchType
157#if defined(__HOST__)
158 {
159 std::string Err;
160 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
161 if (Target != NULL) {
162 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
163 } else {
164 ArchType = llvm::Triple::UnknownArch;
165 ALOGE("%s", Err.c_str());
166 }
167 }
168#elif defined(DEFAULT_ARM_CODEGEN)
169 ArchType = llvm::Triple::arm;
170#elif defined(DEFAULT_MIPS_CODEGEN)
171 ArchType = llvm::Triple::mipsel;
172#elif defined(DEFAULT_X86_CODEGEN)
173 ArchType = llvm::Triple::x86;
174#elif defined(DEFAULT_X86_64_CODEGEN)
175 ArchType = llvm::Triple::x86_64;
176#else
177 ArchType = llvm::Triple::UnknownArch;
178#endif
179
180 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
181# if defined(ARCH_ARM_HAVE_VFP)
182 Features.push_back("+vfp3");
183# if !defined(ARCH_ARM_HAVE_VFP_D32)
184 Features.push_back("+d16");
185# endif
186# endif
187
188# if defined(ARCH_ARM_HAVE_NEON)
189 Features.push_back("+neon");
190 Features.push_back("+neonfp");
191# else
192 Features.push_back("-neon");
193 Features.push_back("-neonfp");
194# endif
195
196// FIXME(all): Turn NEON back on after debugging the rebase.
197# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
198 Features.push_back("-neon");
199 Features.push_back("-neonfp");
200# endif
201 }
202
203 // Register the scheduler
204 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
205
206 // Read in SHA1 checksum of libbcc and libRS.
207 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
208
209 calcFileSHA1(sha1LibRS, pathLibRS);
210
211 GlobalInitialized = true;
212}
213
214
215void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
216 std::string *Error = static_cast<std::string*>(UserData);
217 Error->assign(Message);
218 ALOGE("%s", Message.c_str());
219 exit(1);
220}
221
222
223Compiler::Compiler(ScriptCompiled *result)
224 : mpResult(result),
225 mRSExecutable(NULL),
226 mpSymbolLookupFn(NULL),
227 mpSymbolLookupContext(NULL),
228 mModule(NULL) {
229 llvm::remove_fatal_error_handler();
230 llvm::install_fatal_error_handler(LLVMErrorHandler, &mError);
Zonr Changfef9a1b2012-04-13 15:58:24 +0800231 return;
Logan1f028c02010-11-27 01:02:48 +0800232}
233
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700234int Compiler::readModule(llvm::Module &pModule) {
235 mModule = &pModule;
236 if (pModule.getMaterializer() != NULL) {
237 // A module with non-null materializer means that it is a lazy-load module.
238 // Materialize it now via invoking MaterializeAllPermanently(). This
239 // function returns false when the materialization is successful.
240 if (pModule.MaterializeAllPermanently(&mError)) {
241 setError("Failed to materialize the module `" +
242 pModule.getModuleIdentifier() + "'! (" + mError + ")");
243 mModule = NULL;
244 }
245 }
246 return hasError();
247}
248
249int Compiler::compile(const CompilerOption &option) {
250 llvm::Target const *Target = NULL;
251 llvm::TargetData *TD = NULL;
252 llvm::TargetMachine *TM = NULL;
253
254 std::string FeaturesStr;
255
256 if (mModule == NULL) // No module was loaded
257 return 0;
258
259 bcinfo::MetadataExtractor ME(mModule);
260 ME.extract();
261
262 size_t VarCount = ME.getExportVarCount();
263 size_t FuncCount = ME.getExportFuncCount();
264 size_t ForEachSigCount = ME.getExportForEachSignatureCount();
265 size_t ObjectSlotCount = ME.getObjectSlotCount();
266 size_t PragmaCount = ME.getPragmaCount();
267
268 std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
269 std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
270 std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
Stephen Hines09ebd172012-05-03 12:28:26 -0700271 std::vector<std::string> ForEachNameList;
272 std::vector<uint32_t> ForEachSigList;
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700273 std::vector<const char*> ExportSymbols;
274
275 // Defaults to maximum optimization level from MetadataExtractor.
276 uint32_t OptimizationLevel = ME.getOptimizationLevel();
277
278 if (OptimizationLevel == 0) {
279 CodeGenOptLevel = llvm::CodeGenOpt::None;
280 } else if (OptimizationLevel == 1) {
281 CodeGenOptLevel = llvm::CodeGenOpt::Less;
282 } else if (OptimizationLevel == 2) {
283 CodeGenOptLevel = llvm::CodeGenOpt::Default;
284 } else if (OptimizationLevel == 3) {
285 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Daniel Malea094881f2011-12-14 17:39:16 -0500286 }
287
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700288 // not the best place for this, but we need to set the register allocation
289 // policy after we read the optimization_level metadata from the bitcode
Daniel Malea094881f2011-12-14 17:39:16 -0500290
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700291 // Register allocation policy:
Daniel Malea094881f2011-12-14 17:39:16 -0500292 // createFastRegisterAllocator: fast but bad quality
293 // createLinearScanRegisterAllocator: not so fast but good quality
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700294 llvm::RegisterRegAlloc::setDefault
295 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
296 llvm::createFastRegisterAllocator :
297 llvm::createGreedyRegisterAllocator);
298
299 // Find LLVM Target
300 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
301 if (hasError())
302 goto on_bcc_compile_error;
303
304#if defined(ARCH_ARM_HAVE_NEON)
305 // Full-precision means we have to disable NEON
306 if (ME.getRSFloatPrecision() == bcinfo::RS_FP_Full) {
307 Features.push_back("-neon");
308 Features.push_back("-neonfp");
309 }
310#endif
311
312 if (!CPU.empty() || !Features.empty()) {
313 llvm::SubtargetFeatures F;
314
315 for (std::vector<std::string>::const_iterator
316 I = Features.begin(), E = Features.end(); I != E; I++) {
317 F.AddFeature(*I);
318 }
319
320 FeaturesStr = F.getString();
Logan1f028c02010-11-27 01:02:48 +0800321 }
322
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700323 // Create LLVM Target Machine
324 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
325 option.TargetOpt,
326 option.RelocModelOpt,
327 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800328
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700329 if (TM == NULL) {
330 setError("Failed to create target machine implementation for the"
331 " specified triple '" + Triple + "'");
332 goto on_bcc_compile_error;
333 }
334
335 // Get target data from Module
336 TD = new llvm::TargetData(mModule);
337
338 // Read pragma information from MetadataExtractor
339 if (PragmaCount) {
340 ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
341 const char **PragmaKeys = ME.getPragmaKeyList();
342 const char **PragmaValues = ME.getPragmaValueList();
343 for (size_t i = 0; i < PragmaCount; i++) {
344 PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
345 }
346 }
347
348 if (VarCount) {
349 const char **VarNames = ME.getExportVarNameList();
350 for (size_t i = 0; i < VarCount; i++) {
351 VarNameList.push_back(VarNames[i]);
352 ExportSymbols.push_back(VarNames[i]);
353 }
354 }
355
356 if (FuncCount) {
357 const char **FuncNames = ME.getExportFuncNameList();
358 for (size_t i = 0; i < FuncCount; i++) {
359 FuncNameList.push_back(FuncNames[i]);
360 ExportSymbols.push_back(FuncNames[i]);
361 }
362 }
363
364 if (ForEachSigCount) {
365 const char **ForEachNames = ME.getExportForEachNameList();
366 const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
367 for (size_t i = 0; i < ForEachSigCount; i++) {
Stephen Hines09ebd172012-05-03 12:28:26 -0700368 std::string Name(ForEachNames[i]);
369 ForEachNameList.push_back(Name);
370 ForEachExpandList.push_back(Name + ".expand");
371 ForEachSigList.push_back(ForEachSigs[i]);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700372 }
373
374 // Need to wait until ForEachExpandList is fully populated to fill in
375 // exported symbols.
376 for (size_t i = 0; i < ForEachSigCount; i++) {
377 ExportSymbols.push_back(ForEachExpandList[i].c_str());
378 }
379 }
380
381 if (ObjectSlotCount) {
382 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
383 const uint32_t *ObjectSlots = ME.getObjectSlotList();
384 for (size_t i = 0; i < ObjectSlotCount; i++) {
385 objectSlotList.push_back(ObjectSlots[i]);
386 }
387 }
388
Stephen Hines09ebd172012-05-03 12:28:26 -0700389 runInternalPasses(ForEachNameList, ForEachSigList);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700390
391 // Perform link-time optimization if we have multiple modules
392 if (option.RunLTO) {
393 runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
394 }
395
396 // Perform code generation
397 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
398 goto on_bcc_compile_error;
399 }
400
401 if (!option.LoadAfterCompile)
402 return 0;
403
404 // Load the ELF Object
Stephen Hines5fb14742012-05-03 12:29:50 -0700405 mRSExecutable =
406 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
407 mEmittedELFExecutable.size(),
408 &resolveSymbolAdapter, this);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700409
410 if (!mRSExecutable) {
411 setError("Fail to load emitted ELF relocatable file");
412 goto on_bcc_compile_error;
413 }
414
415 rsloaderUpdateSectionHeaders(mRSExecutable,
416 (unsigned char*) mEmittedELFExecutable.begin());
417
418 // Once the ELF object has been loaded, populate the various slots for RS
419 // with the appropriate relocated addresses.
420 if (VarCount) {
421 ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
422 for (size_t i = 0; i < VarCount; i++) {
423 VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
424 VarNameList[i].c_str()));
425 }
426 }
427
428 if (FuncCount) {
429 ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
430 for (size_t i = 0; i < FuncCount; i++) {
431 FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
432 FuncNameList[i].c_str()));
433 }
434 }
435
436 if (ForEachSigCount) {
437 ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
438 for (size_t i = 0; i < ForEachSigCount; i++) {
439 ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
440 ForEachExpandList[i].c_str()));
441 }
442 }
443
444#if DEBUG_MC_DISASSEMBLER
445 {
446 // Get MC codegen emitted function name list
447 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
448 std::vector<char const *> func_list(func_list_size, NULL);
449 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
450
451 // Disassemble each function
452 for (size_t i = 0; i < func_list_size; ++i) {
453 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
454 if (func) {
455 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
456 Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
457 Target, TM, func_list[i], (unsigned char const *)func, size);
458 }
459 }
460 }
461#endif
462
463on_bcc_compile_error:
464 // ALOGE("on_bcc_compiler_error");
465 if (TD) {
466 delete TD;
467 }
468
469 if (TM) {
470 delete TM;
471 }
472
473 if (mError.empty()) {
474 return 0;
475 }
476
477 // ALOGE(getErrorMessage());
478 return 1;
Logan Chienda5e0c32011-06-13 03:47:21 +0800479}
480
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700481
482int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
483 // Decorate mEmittedELFExecutable with formatted ostream
484 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
485
486 // Relax all machine instructions
487 TM->setMCRelaxAll(/* RelaxAll= */ true);
488
489 // Create MC code generation pass manager
490 llvm::PassManager MCCodeGenPasses;
491
492 // Add TargetData to MC code generation pass manager
493 MCCodeGenPasses.add(TD);
494
495 // Add MC code generation passes to pass manager
496 llvm::MCContext *Ctx = NULL;
497 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
498 setError("Fail to add passes to emit file");
499 return 1;
500 }
501
502 MCCodeGenPasses.run(*mModule);
503 OutSVOS.flush();
504 return 0;
Zonr Changfef9a1b2012-04-13 15:58:24 +0800505}
Logan Chienda5e0c32011-06-13 03:47:21 +0800506
Stephen Hines09ebd172012-05-03 12:28:26 -0700507int Compiler::runInternalPasses(std::vector<std::string>& Names,
508 std::vector<uint32_t>& Signatures) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700509 llvm::PassManager BCCPasses;
Logan Chienda5e0c32011-06-13 03:47:21 +0800510
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700511 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hines09ebd172012-05-03 12:28:26 -0700512 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Logan Chienda5e0c32011-06-13 03:47:21 +0800513
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700514 BCCPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800515
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700516 return 0;
517}
Logan Chienda5e0c32011-06-13 03:47:21 +0800518
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700519int Compiler::runLTO(llvm::TargetData *TD,
520 std::vector<const char*>& ExportSymbols,
521 llvm::CodeGenOpt::Level OptimizationLevel) {
522 // Note: ExportSymbols is a workaround for getting all exported variable,
523 // function, and kernel names.
524 // We should refine it soon.
525
526 // TODO(logan): Remove this after we have finished the
527 // bccMarkExternalSymbol API.
528
529 // root(), init(), and .rs.dtor() are born to be exported
530 ExportSymbols.push_back("root");
531 ExportSymbols.push_back("init");
532 ExportSymbols.push_back(".rs.dtor");
533
534 // User-defined exporting symbols
535 std::vector<char const *> const &UserDefinedExternalSymbols =
536 mpResult->getUserDefinedExternalSymbols();
537
538 std::copy(UserDefinedExternalSymbols.begin(),
539 UserDefinedExternalSymbols.end(),
540 std::back_inserter(ExportSymbols));
541
542 llvm::PassManager LTOPasses;
543
544 // Add TargetData to LTO passes
545 LTOPasses.add(TD);
Daniel Malea094881f2011-12-14 17:39:16 -0500546
Logan Chien4cc00332011-06-12 14:00:46 +0800547 // We now create passes list performing LTO. These are copied from
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700548 // (including comments) llvm::createStandardLTOPasses().
549 // Only a subset of these LTO passes are enabled in optimization level 0
550 // as they interfere with interactive debugging.
551 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
552
553 if (OptimizationLevel != llvm::CodeGenOpt::None) {
554 // Internalize all other symbols not listed in ExportSymbols
555 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
556
Daniel Malea094881f2011-12-14 17:39:16 -0500557 // Propagate constants at call sites into the functions they call. This
558 // opens opportunities for globalopt (and inlining) by substituting
559 // function pointers passed as arguments to direct uses of functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700560 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800561
Daniel Malea094881f2011-12-14 17:39:16 -0500562 // Now that we internalized some globals, see if we can hack on them!
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700563 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800564
Daniel Malea094881f2011-12-14 17:39:16 -0500565 // Linking modules together can lead to duplicated global constants, only
566 // keep one copy of each constant...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700567 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800568
Daniel Malea094881f2011-12-14 17:39:16 -0500569 // Remove unused arguments from functions...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700570 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800571
Daniel Malea094881f2011-12-14 17:39:16 -0500572 // Reduce the code after globalopt and ipsccp. Both can open up
573 // significant simplification opportunities, and both can propagate
574 // functions through function pointers. When this happens, we often have
575 // to resolve varargs calls, etc, so let instcombine do this.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700576 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800577
Daniel Malea094881f2011-12-14 17:39:16 -0500578 // Inline small functions
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700579 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800580
Daniel Malea094881f2011-12-14 17:39:16 -0500581 // Remove dead EH info.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700582 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800583
Daniel Malea094881f2011-12-14 17:39:16 -0500584 // Internalize the globals again after inlining
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700585 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800586
Daniel Malea094881f2011-12-14 17:39:16 -0500587 // Remove dead functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700588 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800589
Daniel Malea094881f2011-12-14 17:39:16 -0500590 // If we didn't decide to inline a function, check to see if we can
591 // transform it to pass arguments by value instead of by reference.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700592 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800593
Daniel Malea094881f2011-12-14 17:39:16 -0500594 // The IPO passes may leave cruft around. Clean up after them.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700595 LTOPasses.add(llvm::createInstructionCombiningPass());
596 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800597
Daniel Malea094881f2011-12-14 17:39:16 -0500598 // Break up allocas
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700599 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800600
Daniel Malea094881f2011-12-14 17:39:16 -0500601 // Run a few AA driven optimizations here and now, to cleanup the code.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700602 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
603 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800604
Daniel Malea094881f2011-12-14 17:39:16 -0500605 // Hoist loop invariants.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700606 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800607
Daniel Malea094881f2011-12-14 17:39:16 -0500608 // Remove redundancies.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700609 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800610
Daniel Malea094881f2011-12-14 17:39:16 -0500611 // Remove dead memcpys.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700612 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800613
Daniel Malea094881f2011-12-14 17:39:16 -0500614 // Nuke dead stores.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700615 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800616
Daniel Malea094881f2011-12-14 17:39:16 -0500617 // Cleanup and simplify the code after the scalar optimizations.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700618 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800619
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700620 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800621
Daniel Malea094881f2011-12-14 17:39:16 -0500622 // Delete basic blocks, which optimization passes may have killed.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700623 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800624
Daniel Malea094881f2011-12-14 17:39:16 -0500625 // Now that we have optimized the program, discard unreachable functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700626 LTOPasses.add(llvm::createGlobalDCEPass());
627
628 } else {
629 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
630 LTOPasses.add(llvm::createGlobalOptimizerPass());
631 LTOPasses.add(llvm::createConstantMergePass());
Daniel Malea094881f2011-12-14 17:39:16 -0500632 }
Logan Chien4cc00332011-06-12 14:00:46 +0800633
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700634 LTOPasses.run(*mModule);
635
636#if ANDROID_ENGINEERING_BUILD
637 if (0 != gDebugDumpDirectory) {
638 std::string errs;
639 std::string Filename(gDebugDumpDirectory);
640 Filename += "/post-lto-module.ll";
641 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
642 mModule->print(FS, 0);
643 FS.close();
Daniel Malea094881f2011-12-14 17:39:16 -0500644 }
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700645#endif
Daniel Malea094881f2011-12-14 17:39:16 -0500646
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700647 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800648}
649
650
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700651void *Compiler::getSymbolAddress(char const *name) {
652 return rsloaderGetSymbolAddress(mRSExecutable, name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800653}
Logan Chienda5e0c32011-06-13 03:47:21 +0800654
Stephen Hines5fb14742012-05-03 12:29:50 -0700655
656void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
657 Compiler *self = reinterpret_cast<Compiler *>(context);
658
659 if (void *Addr = FindRuntimeFunction(name)) {
660 return Addr;
661 }
662
663 if (self->mpSymbolLookupFn) {
664 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
665 return Addr;
666 }
667 }
668
669 ALOGE("Unable to resolve symbol: %s\n", name);
670 return NULL;
671}
672
673
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700674Compiler::~Compiler() {
675 rsloaderDisposeExec(mRSExecutable);
Logan Chienda5e0c32011-06-13 03:47:21 +0800676
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700677 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800678}
679
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700680
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700681} // namespace bcc