resolved conflicts for merge of 7c75d915 to master
Change-Id: I25c1dc90af679e2463abffd33ee8838b4727396f
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index cee5daa..4199fb2 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -47,6 +47,7 @@
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/Transforms/IPO.h"
@@ -59,14 +60,16 @@
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
-#include "llvm/Type.h"
+#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/Linker.h"
#include "llvm/LLVMContext.h"
#include "llvm/Metadata.h"
#include "llvm/Module.h"
#include "llvm/PassManager.h"
+#include "llvm/Type.h"
#include "llvm/Value.h"
#include <errno.h>
@@ -82,6 +85,8 @@
#include <string>
#include <vector>
+extern char* gDebugDumpDirectory;
+
namespace bcc {
//////////////////////////////////////////////////////////////////////////////
@@ -140,6 +145,12 @@
// synced with slang_rs_metadata.h)
const llvm::StringRef Compiler::ObjectSlotMetadataName = "#rs_object_slots";
+// Name of metadata node where RS optimization level resides (should be
+// synced with slang_rs_metadata.h)
+const llvm::StringRef OptimizationLevelMetadataName = "#optimization_level";
+
+
+
//////////////////////////////////////////////////////////////////////////////
// Compiler
//////////////////////////////////////////////////////////////////////////////
@@ -226,23 +237,9 @@
InitializeDisassembler();
#endif
- // -O0: llvm::CodeGenOpt::None
- // -O1: llvm::CodeGenOpt::Less
- // -O2: llvm::CodeGenOpt::Default
- // -O3: llvm::CodeGenOpt::Aggressive
- CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
-
// Register the scheduler
llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
- // Register allocation policy:
- // createFastRegisterAllocator: fast but bad quality
- // createLinearScanRegisterAllocator: not so fast but good quality
- llvm::RegisterRegAlloc::setDefault
- ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
- llvm::createFastRegisterAllocator :
- llvm::createGreedyRegisterAllocator);
-
#if USE_CACHE
// Read in SHA1 checksum of libbcc and libRS.
readSHA1(sha1LibBCC_SHA1, sizeof(sha1LibBCC_SHA1), pathLibBCC_SHA1);
@@ -313,6 +310,9 @@
std::string FeaturesStr;
+ if (mModule == NULL) // No module was loaded
+ return 0;
+
llvm::NamedMDNode const *PragmaMetadata;
llvm::NamedMDNode const *ExportVarMetadata;
llvm::NamedMDNode const *ExportFuncMetadata;
@@ -324,8 +324,37 @@
std::vector<std::string> ForEachExpandList;
std::vector<uint32_t> forEachSigList;
- if (mModule == NULL) // No module was loaded
- return 0;
+ llvm::NamedMDNode const *OptimizationLevelMetadata =
+ mModule->getNamedMetadata(OptimizationLevelMetadataName);
+
+ // Default to maximum optimization in the absence of named metadata node
+ int OptimizationLevel = 3;
+ if (OptimizationLevelMetadata) {
+ llvm::ConstantInt* OL = llvm::dyn_cast<llvm::ConstantInt>(
+ OptimizationLevelMetadata->getOperand(0)->getOperand(0));
+ OptimizationLevel = OL->getZExtValue();
+ }
+
+ if (OptimizationLevel == 0) {
+ CodeGenOptLevel = llvm::CodeGenOpt::None;
+ } else if (OptimizationLevel == 1) {
+ CodeGenOptLevel = llvm::CodeGenOpt::Less;
+ } else if (OptimizationLevel == 2) {
+ CodeGenOptLevel = llvm::CodeGenOpt::Default;
+ } else if (OptimizationLevel == 3) {
+ CodeGenOptLevel = llvm::CodeGenOpt::Aggressive;
+ }
+
+ // not the best place for this, but we need to set the register allocation
+ // policy after we read the optimization_level metadata from the bitcode
+
+ // Register allocation policy:
+ // createFastRegisterAllocator: fast but bad quality
+ // createLinearScanRegisterAllocator: not so fast but good quality
+ llvm::RegisterRegAlloc::setDefault
+ ((CodeGenOptLevel == llvm::CodeGenOpt::None) ?
+ llvm::createFastRegisterAllocator :
+ llvm::createGreedyRegisterAllocator);
// Find LLVM Target
Target = llvm::TargetRegistry::lookupTarget(Triple, mError);
@@ -410,7 +439,7 @@
// Perform link-time optimization if we have multiple modules
if (mHasLinked) {
runLTO(new llvm::TargetData(*TD), ExportVarMetadata, ExportFuncMetadata,
- ForEachExpandList);
+ ForEachExpandList, CodeGenOptLevel);
}
// Perform code generation
@@ -440,6 +469,9 @@
goto on_bcc_compile_error;
}
+ rsloaderUpdateSectionHeaders(mRSExecutable,
+ (unsigned char*) mEmittedELFExecutable.begin());
+
if (ExportVarMetadata) {
ScriptCompiled::ExportVarList &varList = mpResult->mExportVars;
std::vector<std::string> &varNameList = mpResult->mExportVarsName;
@@ -754,7 +786,7 @@
MCCodeGenPasses.add(TD);
// Add MC code generation passes to pass manager
- llvm::MCContext *Ctx;
+ llvm::MCContext *Ctx = NULL;
if (TM->addPassesToEmitMC(MCCodeGenPasses, Ctx, OutSVOS, false)) {
setError("Fail to add passes to emit file");
return 1;
@@ -781,12 +813,8 @@
int Compiler::runLTO(llvm::TargetData *TD,
llvm::NamedMDNode const *ExportVarMetadata,
llvm::NamedMDNode const *ExportFuncMetadata,
- std::vector<std::string>& ForEachExpandList) {
- llvm::PassManager LTOPasses;
-
- // Add TargetData to LTO passes
- LTOPasses.add(TD);
-
+ std::vector<std::string>& ForEachExpandList,
+ llvm::CodeGenOpt::Level OptimizationLevel) {
// Collect All Exported Symbols
std::vector<const char*> ExportSymbols;
@@ -840,85 +868,111 @@
UserDefinedExternalSymbols.end(),
std::back_inserter(ExportSymbols));
+ llvm::PassManager LTOPasses;
+
+ // Add TargetData to LTO passes
+ LTOPasses.add(TD);
+
// We now create passes list performing LTO. These are copied from
// (including comments) llvm::createStandardLTOPasses().
+ // Only a subset of these LTO passes are enabled in optimization level 0
+ // as they interfere with interactive debugging.
+ // FIXME: figure out which passes (if any) makes sense for levels 1 and 2
- // Internalize all other symbols not listed in ExportSymbols
- LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
+ if (OptimizationLevel != llvm::CodeGenOpt::None) {
+ // Internalize all other symbols not listed in ExportSymbols
+ LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
- // Propagate constants at call sites into the functions they call. This
- // opens opportunities for globalopt (and inlining) by substituting
- // function pointers passed as arguments to direct uses of functions.
- LTOPasses.add(llvm::createIPSCCPPass());
+ // Propagate constants at call sites into the functions they call. This
+ // opens opportunities for globalopt (and inlining) by substituting
+ // function pointers passed as arguments to direct uses of functions.
+ LTOPasses.add(llvm::createIPSCCPPass());
- // Now that we internalized some globals, see if we can hack on them!
- LTOPasses.add(llvm::createGlobalOptimizerPass());
+ // Now that we internalized some globals, see if we can hack on them!
+ LTOPasses.add(llvm::createGlobalOptimizerPass());
- // Linking modules together can lead to duplicated global constants, only
- // keep one copy of each constant...
- LTOPasses.add(llvm::createConstantMergePass());
+ // Linking modules together can lead to duplicated global constants, only
+ // keep one copy of each constant...
+ LTOPasses.add(llvm::createConstantMergePass());
- // Remove unused arguments from functions...
- LTOPasses.add(llvm::createDeadArgEliminationPass());
+ // Remove unused arguments from functions...
+ LTOPasses.add(llvm::createDeadArgEliminationPass());
- // Reduce the code after globalopt and ipsccp. Both can open up
- // significant simplification opportunities, and both can propagate
- // functions through function pointers. When this happens, we often have
- // to resolve varargs calls, etc, so let instcombine do this.
- LTOPasses.add(llvm::createInstructionCombiningPass());
+ // Reduce the code after globalopt and ipsccp. Both can open up
+ // significant simplification opportunities, and both can propagate
+ // functions through function pointers. When this happens, we often have
+ // to resolve varargs calls, etc, so let instcombine do this.
+ LTOPasses.add(llvm::createInstructionCombiningPass());
- // Inline small functions
- LTOPasses.add(llvm::createFunctionInliningPass());
+ // Inline small functions
+ LTOPasses.add(llvm::createFunctionInliningPass());
- // Remove dead EH info.
- LTOPasses.add(llvm::createPruneEHPass());
+ // Remove dead EH info.
+ LTOPasses.add(llvm::createPruneEHPass());
- // Internalize the globals again after inlining
- LTOPasses.add(llvm::createGlobalOptimizerPass());
+ // Internalize the globals again after inlining
+ LTOPasses.add(llvm::createGlobalOptimizerPass());
- // Remove dead functions.
- LTOPasses.add(llvm::createGlobalDCEPass());
+ // Remove dead functions.
+ LTOPasses.add(llvm::createGlobalDCEPass());
- // If we didn't decide to inline a function, check to see if we can
- // transform it to pass arguments by value instead of by reference.
- LTOPasses.add(llvm::createArgumentPromotionPass());
+ // If we didn't decide to inline a function, check to see if we can
+ // transform it to pass arguments by value instead of by reference.
+ LTOPasses.add(llvm::createArgumentPromotionPass());
- // The IPO passes may leave cruft around. Clean up after them.
- LTOPasses.add(llvm::createInstructionCombiningPass());
- LTOPasses.add(llvm::createJumpThreadingPass());
+ // The IPO passes may leave cruft around. Clean up after them.
+ LTOPasses.add(llvm::createInstructionCombiningPass());
+ LTOPasses.add(llvm::createJumpThreadingPass());
- // Break up allocas
- LTOPasses.add(llvm::createScalarReplAggregatesPass());
+ // Break up allocas
+ LTOPasses.add(llvm::createScalarReplAggregatesPass());
- // Run a few AA driven optimizations here and now, to cleanup the code.
- LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
- LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
+ // Run a few AA driven optimizations here and now, to cleanup the code.
+ LTOPasses.add(llvm::createFunctionAttrsPass()); // Add nocapture.
+ LTOPasses.add(llvm::createGlobalsModRefPass()); // IP alias analysis.
- // Hoist loop invariants.
- LTOPasses.add(llvm::createLICMPass());
+ // Hoist loop invariants.
+ LTOPasses.add(llvm::createLICMPass());
- // Remove redundancies.
- LTOPasses.add(llvm::createGVNPass());
+ // Remove redundancies.
+ LTOPasses.add(llvm::createGVNPass());
- // Remove dead memcpys.
- LTOPasses.add(llvm::createMemCpyOptPass());
+ // Remove dead memcpys.
+ LTOPasses.add(llvm::createMemCpyOptPass());
- // Nuke dead stores.
- LTOPasses.add(llvm::createDeadStoreEliminationPass());
+ // Nuke dead stores.
+ LTOPasses.add(llvm::createDeadStoreEliminationPass());
- // Cleanup and simplify the code after the scalar optimizations.
- LTOPasses.add(llvm::createInstructionCombiningPass());
+ // Cleanup and simplify the code after the scalar optimizations.
+ LTOPasses.add(llvm::createInstructionCombiningPass());
- LTOPasses.add(llvm::createJumpThreadingPass());
+ LTOPasses.add(llvm::createJumpThreadingPass());
- // Delete basic blocks, which optimization passes may have killed.
- LTOPasses.add(llvm::createCFGSimplificationPass());
+ // Delete basic blocks, which optimization passes may have killed.
+ LTOPasses.add(llvm::createCFGSimplificationPass());
- // Now that we have optimized the program, discard unreachable functions.
- LTOPasses.add(llvm::createGlobalDCEPass());
+ // Now that we have optimized the program, discard unreachable functions.
+ LTOPasses.add(llvm::createGlobalDCEPass());
+
+ } else {
+ LTOPasses.add(llvm::createInternalizePass(ExportSymbols));
+ LTOPasses.add(llvm::createGlobalOptimizerPass());
+ LTOPasses.add(llvm::createConstantMergePass());
+ }
LTOPasses.run(*mModule);
+#if ANDROID_ENGINEERING_BUILD
+ if (0 != gDebugDumpDirectory) {
+ std::string errs;
+ std::string Filename(gDebugDumpDirectory);
+ Filename += "/post-lto-module.ll";
+ llvm::raw_fd_ostream FS(Filename.c_str(), errs);
+ mModule->print(FS, 0);
+ FS.close();
+ }
+#endif
+
return 0;
}