blob: 58a49c5dc93834e8c27b09e9e920d0b6a8c591e6 [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 Hines758d00c2012-05-03 12:30:15 -070027#include "FileHandle.h"
Stephen Hines5fb14742012-05-03 12:29:50 -070028#include "Runtime.h"
Stephen Hines4a68b1c2012-05-03 12:28:14 -070029#include "ScriptCompiled.h"
30#include "Sha1Helper.h"
31#include "CompilerOption.h"
Loganeb3d12b2010-12-16 06:20:18 +080032
Stephen Hines4a68b1c2012-05-03 12:28:14 -070033#include "librsloader.h"
Logan Chienda5e0c32011-06-13 03:47:21 +080034
Stephen Hines09ebd172012-05-03 12:28:26 -070035#include "Transforms/BCCTransforms.h"
Stephen Hinesdb169182012-01-05 18:46:36 -080036
Stephen Hines4a68b1c2012-05-03 12:28:14 -070037#include "llvm/ADT/StringRef.h"
Logan1f028c02010-11-27 01:02:48 +080038
Stephen Hines4a68b1c2012-05-03 12:28:14 -070039#include "llvm/Analysis/Passes.h"
Logan1f028c02010-11-27 01:02:48 +080040
Stephen Hines4a68b1c2012-05-03 12:28:14 -070041#include "llvm/CodeGen/Passes.h"
42#include "llvm/CodeGen/RegAllocRegistry.h"
43#include "llvm/CodeGen/SchedulerRegistry.h"
Logan1f028c02010-11-27 01:02:48 +080044
Stephen Hines4a68b1c2012-05-03 12:28:14 -070045#include "llvm/MC/MCContext.h"
46#include "llvm/MC/SubtargetFeature.h"
Shih-wei Liao40bcd662011-10-22 17:51:01 -070047
Stephen Hines4a68b1c2012-05-03 12:28:14 -070048#include "llvm/Transforms/IPO.h"
49#include "llvm/Transforms/Scalar.h"
Logan1f028c02010-11-27 01:02:48 +080050
Stephen Hines4a68b1c2012-05-03 12:28:14 -070051#include "llvm/Target/TargetData.h"
52#include "llvm/Target/TargetMachine.h"
Logan1f028c02010-11-27 01:02:48 +080053
Stephen Hines4a68b1c2012-05-03 12:28:14 -070054#include "llvm/Support/ErrorHandling.h"
55#include "llvm/Support/FormattedStream.h"
56#include "llvm/Support/TargetRegistry.h"
57#include "llvm/Support/TargetSelect.h"
58#include "llvm/Support/raw_ostream.h"
Zonr Changfef9a1b2012-04-13 15:58:24 +080059
Stephen Hines4a68b1c2012-05-03 12:28:14 -070060#include "llvm/Constants.h"
61#include "llvm/GlobalValue.h"
62#include "llvm/Linker.h"
63#include "llvm/LLVMContext.h"
64#include "llvm/Module.h"
65#include "llvm/PassManager.h"
66#include "llvm/Type.h"
67#include "llvm/Value.h"
68
69#include <errno.h>
70#include <sys/file.h>
71#include <sys/stat.h>
72#include <sys/types.h>
73#include <unistd.h>
74
75#include <string.h>
76
77#include <algorithm>
78#include <iterator>
79#include <string>
80#include <vector>
81
82extern char* gDebugDumpDirectory;
83
84namespace bcc {
85
86//////////////////////////////////////////////////////////////////////////////
87// BCC Compiler Static Variables
88//////////////////////////////////////////////////////////////////////////////
89
90bool Compiler::GlobalInitialized = false;
91
92
93#if !defined(__HOST__)
94 #define TARGET_TRIPLE_STRING DEFAULT_TARGET_TRIPLE_STRING
95#else
96// In host TARGET_TRIPLE_STRING is a variable to allow cross-compilation.
97 #if defined(__cplusplus)
98 extern "C" {
99 #endif
100 char *TARGET_TRIPLE_STRING = (char*)DEFAULT_TARGET_TRIPLE_STRING;
101 #if defined(__cplusplus)
102 };
103 #endif
104#endif
105
106// Code generation optimization level for the compiler
107llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
108
109std::string Compiler::Triple;
110llvm::Triple::ArchType Compiler::ArchType;
111
112std::string Compiler::CPU;
113
114std::vector<std::string> Compiler::Features;
115
116
117//////////////////////////////////////////////////////////////////////////////
118// Compiler
119//////////////////////////////////////////////////////////////////////////////
120
121void Compiler::GlobalInitialization() {
122 if (GlobalInitialized) {
Zonr Changfef9a1b2012-04-13 15:58:24 +0800123 return;
Logan1f028c02010-11-27 01:02:48 +0800124 }
Zonr Changfef9a1b2012-04-13 15:58:24 +0800125
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700126#if defined(PROVIDE_ARM_CODEGEN)
127 LLVMInitializeARMAsmPrinter();
128 LLVMInitializeARMTargetMC();
129 LLVMInitializeARMTargetInfo();
130 LLVMInitializeARMTarget();
131#endif
132
133#if defined(PROVIDE_MIPS_CODEGEN)
134 LLVMInitializeMipsAsmPrinter();
135 LLVMInitializeMipsTargetMC();
136 LLVMInitializeMipsTargetInfo();
137 LLVMInitializeMipsTarget();
138#endif
139
140#if defined(PROVIDE_X86_CODEGEN)
141 LLVMInitializeX86AsmPrinter();
142 LLVMInitializeX86TargetMC();
143 LLVMInitializeX86TargetInfo();
144 LLVMInitializeX86Target();
145#endif
146
147#if USE_DISASSEMBLER
148 InitializeDisassembler();
149#endif
150
151 // if (!llvm::llvm_is_multithreaded())
152 // llvm::llvm_start_multithreaded();
153
154 // Set Triple, CPU and Features here
155 Triple = TARGET_TRIPLE_STRING;
156
157 // Determine ArchType
158#if defined(__HOST__)
159 {
160 std::string Err;
161 llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
162 if (Target != NULL) {
163 ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
164 } else {
165 ArchType = llvm::Triple::UnknownArch;
166 ALOGE("%s", Err.c_str());
167 }
168 }
169#elif defined(DEFAULT_ARM_CODEGEN)
170 ArchType = llvm::Triple::arm;
171#elif defined(DEFAULT_MIPS_CODEGEN)
172 ArchType = llvm::Triple::mipsel;
173#elif defined(DEFAULT_X86_CODEGEN)
174 ArchType = llvm::Triple::x86;
175#elif defined(DEFAULT_X86_64_CODEGEN)
176 ArchType = llvm::Triple::x86_64;
177#else
178 ArchType = llvm::Triple::UnknownArch;
179#endif
180
181 if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
182# if defined(ARCH_ARM_HAVE_VFP)
183 Features.push_back("+vfp3");
184# if !defined(ARCH_ARM_HAVE_VFP_D32)
185 Features.push_back("+d16");
186# endif
187# endif
188
189# if defined(ARCH_ARM_HAVE_NEON)
190 Features.push_back("+neon");
191 Features.push_back("+neonfp");
192# else
193 Features.push_back("-neon");
194 Features.push_back("-neonfp");
195# endif
196
197// FIXME(all): Turn NEON back on after debugging the rebase.
198# if 1 || defined(DISABLE_ARCH_ARM_HAVE_NEON)
199 Features.push_back("-neon");
200 Features.push_back("-neonfp");
201# endif
202 }
203
204 // Register the scheduler
205 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
206
207 // Read in SHA1 checksum of libbcc and libRS.
208 readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
209
210 calcFileSHA1(sha1LibRS, pathLibRS);
211
212 GlobalInitialized = true;
213}
214
215
216void Compiler::LLVMErrorHandler(void *UserData, const std::string &Message) {
217 std::string *Error = static_cast<std::string*>(UserData);
218 Error->assign(Message);
219 ALOGE("%s", Message.c_str());
220 exit(1);
221}
222
223
224Compiler::Compiler(ScriptCompiled *result)
225 : mpResult(result),
226 mRSExecutable(NULL),
227 mpSymbolLookupFn(NULL),
228 mpSymbolLookupContext(NULL),
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700229 mModule(NULL),
230 mHasLinked(false) /* Turn off linker */ {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700231 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 Hinesead5ccb2012-05-03 12:30:38 -0700236
237int Compiler::linkModule(llvm::Module *moduleWith) {
238 if (llvm::Linker::LinkModules(mModule, moduleWith,
239 llvm::Linker::PreserveSource,
240 &mError) != 0) {
241 return hasError();
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700242 }
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700243
244 // Everything for linking should be settled down here with no error occurs
245 mHasLinked = true;
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700246 return hasError();
247}
248
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700249
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700250int Compiler::compile(const CompilerOption &option) {
251 llvm::Target const *Target = NULL;
252 llvm::TargetData *TD = NULL;
253 llvm::TargetMachine *TM = NULL;
254
255 std::string FeaturesStr;
256
257 if (mModule == NULL) // No module was loaded
258 return 0;
259
260 bcinfo::MetadataExtractor ME(mModule);
261 ME.extract();
262
263 size_t VarCount = ME.getExportVarCount();
264 size_t FuncCount = ME.getExportFuncCount();
265 size_t ForEachSigCount = ME.getExportForEachSignatureCount();
266 size_t ObjectSlotCount = ME.getObjectSlotCount();
267 size_t PragmaCount = ME.getPragmaCount();
268
269 std::vector<std::string> &VarNameList = mpResult->mExportVarsName;
270 std::vector<std::string> &FuncNameList = mpResult->mExportFuncsName;
271 std::vector<std::string> &ForEachExpandList = mpResult->mExportForEachName;
Stephen Hines09ebd172012-05-03 12:28:26 -0700272 std::vector<std::string> ForEachNameList;
273 std::vector<uint32_t> ForEachSigList;
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700274 std::vector<const char*> ExportSymbols;
275
276 // Defaults to maximum optimization level from MetadataExtractor.
277 uint32_t OptimizationLevel = ME.getOptimizationLevel();
278
279 if (OptimizationLevel == 0) {
280 CodeGenOptLevel = llvm::CodeGenOpt::None;
281 } else if (OptimizationLevel == 1) {
282 CodeGenOptLevel = llvm::CodeGenOpt::Less;
283 } else if (OptimizationLevel == 2) {
284 CodeGenOptLevel = llvm::CodeGenOpt::Default;
285 } else if (OptimizationLevel == 3) {
286 CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
Daniel Malea094881f2011-12-14 17:39:16 -0500287 }
288
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700289 // not the best place for this, but we need to set the register allocation
290 // policy after we read the optimization_level metadata from the bitcode
Daniel Malea094881f2011-12-14 17:39:16 -0500291
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700292 // Register allocation policy:
Daniel Malea094881f2011-12-14 17:39:16 -0500293 // createFastRegisterAllocator: fast but bad quality
294 // createLinearScanRegisterAllocator: not so fast but good quality
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700295 llvm::RegisterRegAlloc::setDefault
296 ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
297 llvm::createFastRegisterAllocator :
298 llvm::createGreedyRegisterAllocator);
299
300 // Find LLVM Target
301 Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
302 if (hasError())
303 goto on_bcc_compile_error;
304
305#if defined(ARCH_ARM_HAVE_NEON)
306 // Full-precision means we have to disable NEON
307 if (ME.getRSFloatPrecision() == bcinfo::RS_FP_Full) {
308 Features.push_back("-neon");
309 Features.push_back("-neonfp");
310 }
311#endif
312
313 if (!CPU.empty() || !Features.empty()) {
314 llvm::SubtargetFeatures F;
315
316 for (std::vector<std::string>::const_iterator
317 I = Features.begin(), E = Features.end(); I != E; I++) {
318 F.AddFeature(*I);
319 }
320
321 FeaturesStr = F.getString();
Logan1f028c02010-11-27 01:02:48 +0800322 }
323
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700324 // Create LLVM Target Machine
325 TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
326 option.TargetOpt,
327 option.RelocModelOpt,
328 option.CodeModelOpt);
Logan Chienbe81e102011-12-16 13:31:39 +0800329
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700330 if (TM == NULL) {
331 setError("Failed to create target machine implementation for the"
332 " specified triple '" + Triple + "'");
333 goto on_bcc_compile_error;
334 }
335
336 // Get target data from Module
337 TD = new llvm::TargetData(mModule);
338
339 // Read pragma information from MetadataExtractor
340 if (PragmaCount) {
341 ScriptCompiled::PragmaList &PragmaPairs = mpResult->mPragmas;
342 const char **PragmaKeys = ME.getPragmaKeyList();
343 const char **PragmaValues = ME.getPragmaValueList();
344 for (size_t i = 0; i < PragmaCount; i++) {
345 PragmaPairs.push_back(std::make_pair(PragmaKeys[i], PragmaValues[i]));
346 }
347 }
348
349 if (VarCount) {
350 const char **VarNames = ME.getExportVarNameList();
351 for (size_t i = 0; i < VarCount; i++) {
352 VarNameList.push_back(VarNames[i]);
353 ExportSymbols.push_back(VarNames[i]);
354 }
355 }
356
357 if (FuncCount) {
358 const char **FuncNames = ME.getExportFuncNameList();
359 for (size_t i = 0; i < FuncCount; i++) {
360 FuncNameList.push_back(FuncNames[i]);
361 ExportSymbols.push_back(FuncNames[i]);
362 }
363 }
364
365 if (ForEachSigCount) {
366 const char **ForEachNames = ME.getExportForEachNameList();
367 const uint32_t *ForEachSigs = ME.getExportForEachSignatureList();
368 for (size_t i = 0; i < ForEachSigCount; i++) {
Stephen Hines09ebd172012-05-03 12:28:26 -0700369 std::string Name(ForEachNames[i]);
370 ForEachNameList.push_back(Name);
371 ForEachExpandList.push_back(Name + ".expand");
372 ForEachSigList.push_back(ForEachSigs[i]);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700373 }
374
375 // Need to wait until ForEachExpandList is fully populated to fill in
376 // exported symbols.
377 for (size_t i = 0; i < ForEachSigCount; i++) {
378 ExportSymbols.push_back(ForEachExpandList[i].c_str());
379 }
380 }
381
382 if (ObjectSlotCount) {
383 ScriptCompiled::ObjectSlotList &objectSlotList = mpResult->mObjectSlots;
384 const uint32_t *ObjectSlots = ME.getObjectSlotList();
385 for (size_t i = 0; i < ObjectSlotCount; i++) {
386 objectSlotList.push_back(ObjectSlots[i]);
387 }
388 }
389
Stephen Hines09ebd172012-05-03 12:28:26 -0700390 runInternalPasses(ForEachNameList, ForEachSigList);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700391
392 // Perform link-time optimization if we have multiple modules
Stephen Hinesead5ccb2012-05-03 12:30:38 -0700393 if (mHasLinked) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700394 runLTO(new llvm::TargetData(*TD), ExportSymbols, CodeGenOptLevel);
395 }
396
397 // Perform code generation
398 if (runMCCodeGen(new llvm::TargetData(*TD), TM) != 0) {
399 goto on_bcc_compile_error;
400 }
401
402 if (!option.LoadAfterCompile)
403 return 0;
404
405 // Load the ELF Object
Stephen Hines5fb14742012-05-03 12:29:50 -0700406 mRSExecutable =
407 rsloaderCreateExec((unsigned char *)&*mEmittedELFExecutable.begin(),
408 mEmittedELFExecutable.size(),
409 &resolveSymbolAdapter, this);
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700410
411 if (!mRSExecutable) {
412 setError("Fail to load emitted ELF relocatable file");
413 goto on_bcc_compile_error;
414 }
415
416 rsloaderUpdateSectionHeaders(mRSExecutable,
417 (unsigned char*) mEmittedELFExecutable.begin());
418
419 // Once the ELF object has been loaded, populate the various slots for RS
420 // with the appropriate relocated addresses.
421 if (VarCount) {
422 ScriptCompiled::ExportVarList &VarList = mpResult->mExportVars;
423 for (size_t i = 0; i < VarCount; i++) {
424 VarList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
425 VarNameList[i].c_str()));
426 }
427 }
428
429 if (FuncCount) {
430 ScriptCompiled::ExportFuncList &FuncList = mpResult->mExportFuncs;
431 for (size_t i = 0; i < FuncCount; i++) {
432 FuncList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
433 FuncNameList[i].c_str()));
434 }
435 }
436
437 if (ForEachSigCount) {
438 ScriptCompiled::ExportForEachList &ForEachList = mpResult->mExportForEach;
439 for (size_t i = 0; i < ForEachSigCount; i++) {
440 ForEachList.push_back(rsloaderGetSymbolAddress(mRSExecutable,
441 ForEachExpandList[i].c_str()));
442 }
443 }
444
445#if DEBUG_MC_DISASSEMBLER
446 {
447 // Get MC codegen emitted function name list
448 size_t func_list_size = rsloaderGetFuncCount(mRSExecutable);
449 std::vector<char const *> func_list(func_list_size, NULL);
450 rsloaderGetFuncNameList(mRSExecutable, func_list_size, &*func_list.begin());
451
452 // Disassemble each function
453 for (size_t i = 0; i < func_list_size; ++i) {
454 void *func = rsloaderGetSymbolAddress(mRSExecutable, func_list[i]);
455 if (func) {
456 size_t size = rsloaderGetSymbolSize(mRSExecutable, func_list[i]);
457 Disassemble(DEBUG_MC_DISASSEMBLER_FILE,
458 Target, TM, func_list[i], (unsigned char const *)func, size);
459 }
460 }
461 }
462#endif
463
464on_bcc_compile_error:
465 // ALOGE("on_bcc_compiler_error");
466 if (TD) {
467 delete TD;
468 }
469
470 if (TM) {
471 delete TM;
472 }
473
474 if (mError.empty()) {
475 return 0;
476 }
477
478 // ALOGE(getErrorMessage());
479 return 1;
Logan Chienda5e0c32011-06-13 03:47:21 +0800480}
481
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700482
483int Compiler::runMCCodeGen(llvm::TargetData *TD, llvm::TargetMachine *TM) {
484 // Decorate mEmittedELFExecutable with formatted ostream
485 llvm::raw_svector_ostream OutSVOS(mEmittedELFExecutable);
486
487 // Relax all machine instructions
488 TM->setMCRelaxAll(/* RelaxAll= */ true);
489
490 // Create MC code generation pass manager
491 llvm::PassManager MCCodeGenPasses;
492
493 // Add TargetData to MC code generation pass manager
494 MCCodeGenPasses.add(TD);
495
496 // Add MC code generation passes to pass manager
497 llvm::MCContext *Ctx = NULL;
498 if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
499 setError("Fail to add passes to emit file");
500 return 1;
501 }
502
503 MCCodeGenPasses.run(*mModule);
504 OutSVOS.flush();
505 return 0;
Zonr Changfef9a1b2012-04-13 15:58:24 +0800506}
Logan Chienda5e0c32011-06-13 03:47:21 +0800507
Stephen Hines09ebd172012-05-03 12:28:26 -0700508int Compiler::runInternalPasses(std::vector<std::string>& Names,
509 std::vector<uint32_t>& Signatures) {
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700510 llvm::PassManager BCCPasses;
Logan Chienda5e0c32011-06-13 03:47:21 +0800511
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700512 // Expand ForEach on CPU path to reduce launch overhead.
Stephen Hines09ebd172012-05-03 12:28:26 -0700513 BCCPasses.add(createForEachExpandPass(Names, Signatures));
Logan Chienda5e0c32011-06-13 03:47:21 +0800514
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700515 BCCPasses.run(*mModule);
Logan Chienda5e0c32011-06-13 03:47:21 +0800516
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700517 return 0;
518}
Logan Chienda5e0c32011-06-13 03:47:21 +0800519
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700520int Compiler::runLTO(llvm::TargetData *TD,
521 std::vector<const char*>& ExportSymbols,
522 llvm::CodeGenOpt::Level OptimizationLevel) {
523 // Note: ExportSymbols is a workaround for getting all exported variable,
524 // function, and kernel names.
525 // We should refine it soon.
526
527 // TODO(logan): Remove this after we have finished the
528 // bccMarkExternalSymbol API.
529
530 // root(), init(), and .rs.dtor() are born to be exported
531 ExportSymbols.push_back("root");
532 ExportSymbols.push_back("init");
533 ExportSymbols.push_back(".rs.dtor");
534
535 // User-defined exporting symbols
536 std::vector<char const *> const &UserDefinedExternalSymbols =
537 mpResult->getUserDefinedExternalSymbols();
538
539 std::copy(UserDefinedExternalSymbols.begin(),
540 UserDefinedExternalSymbols.end(),
541 std::back_inserter(ExportSymbols));
542
543 llvm::PassManager LTOPasses;
544
545 // Add TargetData to LTO passes
546 LTOPasses.add(TD);
Daniel Malea094881f2011-12-14 17:39:16 -0500547
Logan Chien4cc00332011-06-12 14:00:46 +0800548 // We now create passes list performing LTO. These are copied from
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700549 // (including comments) llvm::createStandardLTOPasses().
550 // Only a subset of these LTO passes are enabled in optimization level 0
551 // as they interfere with interactive debugging.
552 // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
553
554 if (OptimizationLevel != llvm::CodeGenOpt::None) {
555 // Internalize all other symbols not listed in ExportSymbols
556 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
557
Daniel Malea094881f2011-12-14 17:39:16 -0500558 // Propagate constants at call sites into the functions they call. This
559 // opens opportunities for globalopt (and inlining) by substituting
560 // function pointers passed as arguments to direct uses of functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700561 LTOPasses.add(llvm::createIPSCCPPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800562
Daniel Malea094881f2011-12-14 17:39:16 -0500563 // Now that we internalized some globals, see if we can hack on them!
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700564 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800565
Daniel Malea094881f2011-12-14 17:39:16 -0500566 // Linking modules together can lead to duplicated global constants, only
567 // keep one copy of each constant...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700568 LTOPasses.add(llvm::createConstantMergePass());
Logan Chien4cc00332011-06-12 14:00:46 +0800569
Daniel Malea094881f2011-12-14 17:39:16 -0500570 // Remove unused arguments from functions...
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700571 LTOPasses.add(llvm::createDeadArgEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800572
Daniel Malea094881f2011-12-14 17:39:16 -0500573 // Reduce the code after globalopt and ipsccp. Both can open up
574 // significant simplification opportunities, and both can propagate
575 // functions through function pointers. When this happens, we often have
576 // to resolve varargs calls, etc, so let instcombine do this.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700577 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800578
Daniel Malea094881f2011-12-14 17:39:16 -0500579 // Inline small functions
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700580 LTOPasses.add(llvm::createFunctionInliningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800581
Daniel Malea094881f2011-12-14 17:39:16 -0500582 // Remove dead EH info.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700583 LTOPasses.add(llvm::createPruneEHPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800584
Daniel Malea094881f2011-12-14 17:39:16 -0500585 // Internalize the globals again after inlining
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700586 LTOPasses.add(llvm::createGlobalOptimizerPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800587
Daniel Malea094881f2011-12-14 17:39:16 -0500588 // Remove dead functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700589 LTOPasses.add(llvm::createGlobalDCEPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800590
Daniel Malea094881f2011-12-14 17:39:16 -0500591 // If we didn't decide to inline a function, check to see if we can
592 // transform it to pass arguments by value instead of by reference.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700593 LTOPasses.add(llvm::createArgumentPromotionPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800594
Daniel Malea094881f2011-12-14 17:39:16 -0500595 // The IPO passes may leave cruft around. Clean up after them.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700596 LTOPasses.add(llvm::createInstructionCombiningPass());
597 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800598
Daniel Malea094881f2011-12-14 17:39:16 -0500599 // Break up allocas
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700600 LTOPasses.add(llvm::createScalarReplAggregatesPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800601
Daniel Malea094881f2011-12-14 17:39:16 -0500602 // Run a few AA driven optimizations here and now, to cleanup the code.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700603 LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
604 LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
Logan Chien4cc00332011-06-12 14:00:46 +0800605
Daniel Malea094881f2011-12-14 17:39:16 -0500606 // Hoist loop invariants.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700607 LTOPasses.add(llvm::createLICMPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800608
Daniel Malea094881f2011-12-14 17:39:16 -0500609 // Remove redundancies.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700610 LTOPasses.add(llvm::createGVNPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800611
Daniel Malea094881f2011-12-14 17:39:16 -0500612 // Remove dead memcpys.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700613 LTOPasses.add(llvm::createMemCpyOptPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800614
Daniel Malea094881f2011-12-14 17:39:16 -0500615 // Nuke dead stores.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700616 LTOPasses.add(llvm::createDeadStoreEliminationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800617
Daniel Malea094881f2011-12-14 17:39:16 -0500618 // Cleanup and simplify the code after the scalar optimizations.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700619 LTOPasses.add(llvm::createInstructionCombiningPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800620
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700621 LTOPasses.add(llvm::createJumpThreadingPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800622
Daniel Malea094881f2011-12-14 17:39:16 -0500623 // Delete basic blocks, which optimization passes may have killed.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700624 LTOPasses.add(llvm::createCFGSimplificationPass());
Logan Chien4cc00332011-06-12 14:00:46 +0800625
Daniel Malea094881f2011-12-14 17:39:16 -0500626 // Now that we have optimized the program, discard unreachable functions.
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700627 LTOPasses.add(llvm::createGlobalDCEPass());
628
629 } else {
630 LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
631 LTOPasses.add(llvm::createGlobalOptimizerPass());
632 LTOPasses.add(llvm::createConstantMergePass());
Daniel Malea094881f2011-12-14 17:39:16 -0500633 }
Logan Chien4cc00332011-06-12 14:00:46 +0800634
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700635 LTOPasses.run(*mModule);
636
637#if ANDROID_ENGINEERING_BUILD
638 if (0 != gDebugDumpDirectory) {
639 std::string errs;
640 std::string Filename(gDebugDumpDirectory);
641 Filename += "/post-lto-module.ll";
642 llvm::raw_fd_ostream FS(Filename.c_str(), errs);
643 mModule->print(FS, 0);
644 FS.close();
Daniel Malea094881f2011-12-14 17:39:16 -0500645 }
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700646#endif
Daniel Malea094881f2011-12-14 17:39:16 -0500647
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700648 return 0;
Logan Chien4cc00332011-06-12 14:00:46 +0800649}
650
651
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700652void *Compiler::getSymbolAddress(char const *name) {
653 return rsloaderGetSymbolAddress(mRSExecutable, name);
Logan Chienda5e0c32011-06-13 03:47:21 +0800654}
Logan Chienda5e0c32011-06-13 03:47:21 +0800655
Stephen Hines5fb14742012-05-03 12:29:50 -0700656
657void *Compiler::resolveSymbolAdapter(void *context, char const *name) {
658 Compiler *self = reinterpret_cast<Compiler *>(context);
659
660 if (void *Addr = FindRuntimeFunction(name)) {
661 return Addr;
662 }
663
664 if (self->mpSymbolLookupFn) {
665 if (void *Addr = self->mpSymbolLookupFn(self->mpSymbolLookupContext, name)) {
666 return Addr;
667 }
668 }
669
670 ALOGE("Unable to resolve symbol: %s\n", name);
671 return NULL;
672}
673
674
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700675Compiler::~Compiler() {
676 rsloaderDisposeExec(mRSExecutable);
Logan Chienda5e0c32011-06-13 03:47:21 +0800677
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700678 // llvm::llvm_shutdown();
Logan1f028c02010-11-27 01:02:48 +0800679}
680
Shih-wei Liao90cd3d12011-06-20 15:43:34 -0700681
Stephen Hines4a68b1c2012-05-03 12:28:14 -0700682} // namespace bcc