Merge "De-cruft the libbcc compiler infrastructure."
diff --git a/include/bcc/Compiler.h b/include/bcc/Compiler.h
index 630be08..fabbadc 100644
--- a/include/bcc/Compiler.h
+++ b/include/bcc/Compiler.h
@@ -64,14 +64,7 @@
kErrPrepareOutput,
kPrepareCodeGenPass,
- kErrHookBeforeAddLTOPasses,
- kErrHookAfterAddLTOPasses,
- kErrHookAfterExecuteLTOPasses,
-
- kErrHookBeforeAddCodeGenPasses,
- kErrHookAfterAddCodeGenPasses,
- kErrHookBeforeExecuteCodeGenPasses,
- kErrHookAfterExecuteCodeGenPasses,
+ kErrCustomPasses,
kErrInvalidSource
};
@@ -80,11 +73,14 @@
private:
llvm::TargetMachine *mTarget;
- // LTO is enabled by default.
- bool mEnableLTO;
+ // Optimization is enabled by default.
+ bool mEnableOpt;
- enum ErrorCode runLTO(Script &pScript);
- enum ErrorCode runCodeGen(Script &pScript, llvm::raw_ostream &pResult);
+ enum ErrorCode runPasses(Script &pScript, llvm::raw_ostream &pResult);
+
+ bool addCustomPasses(Script &pScript, llvm::PassManager &pPM);
+ bool addInternalizeSymbolsPass(Script &pScript, llvm::PassManager &pPM);
+ bool addExpandForEachPass(Script &pScript, llvm::PassManager &pPM);
public:
Compiler();
@@ -106,48 +102,10 @@
const llvm::TargetMachine& getTargetMachine() const
{ return *mTarget; }
- void enableLTO(bool pEnable = true)
- { mEnableLTO = pEnable; }
+ void enableOpt(bool pEnable = true)
+ { mEnableOpt = pEnable; }
- virtual ~Compiler();
-
-protected:
- //===--------------------------------------------------------------------===//
- // Plugin callbacks for sub-class.
- //===--------------------------------------------------------------------===//
- // Called before adding first pass to code-generation passes.
- virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
- { return true; }
-
- // Called after adding last pass to code-generation passes.
- virtual bool afterAddLTOPasses(Script &pScript, llvm::PassManager &pPM)
- { return true; }
-
- // Called before executing code-generation passes.
- virtual bool beforeExecuteLTOPasses(Script &pScript,
- llvm::PassManager &pPM)
- { return true; }
-
- // Called after executing code-generation passes.
- virtual bool afterExecuteLTOPasses(Script &pScript)
- { return true; }
-
- // Called before adding first pass to code-generation passes.
- virtual bool beforeAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
- { return true; }
-
- // Called after adding last pass to code-generation passes.
- virtual bool afterAddCodeGenPasses(Script &pScript, llvm::PassManager &pPM)
- { return true; }
-
- // Called before executing code-generation passes.
- virtual bool beforeExecuteCodeGenPasses(Script &pScript,
- llvm::PassManager &pPM)
- { return true; }
-
- // Called after executing code-generation passes.
- virtual bool afterExecuteCodeGenPasses(Script &pScript)
- { return true; }
+ ~Compiler();
};
} // end namespace bcc
diff --git a/include/bcc/Renderscript/RSCompiler.h b/include/bcc/Renderscript/RSCompiler.h
deleted file mode 100644
index a46d558..0000000
--- a/include/bcc/Renderscript/RSCompiler.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef BCC_RS_COMPILER_H
-#define BCC_RS_COMPILER_H
-
-#include "bcc/Compiler.h"
-
-namespace bcc {
-
-class RSCompiler : public Compiler {
-private:
- virtual bool beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM);
- bool addInternalizeSymbolsPass(Script &pScript, llvm::PassManager &pPM);
- bool addExpandForEachPass(Script &pScript, llvm::PassManager &pPM);
-};
-
-} // end namespace bcc
-
-#endif // BCC_RS_COMPILER_H
diff --git a/include/bcc/Renderscript/RSCompilerDriver.h b/include/bcc/Renderscript/RSCompilerDriver.h
index a2a68d1..3ad9e01 100644
--- a/include/bcc/Renderscript/RSCompilerDriver.h
+++ b/include/bcc/Renderscript/RSCompilerDriver.h
@@ -17,11 +17,11 @@
#ifndef BCC_RS_COMPILER_DRIVER_H
#define BCC_RS_COMPILER_DRIVER_H
+#include "bcc/Compiler.h"
#include "bcc/ExecutionEngine/CompilerRTSymbolResolver.h"
#include "bcc/ExecutionEngine/SymbolResolvers.h"
#include "bcc/ExecutionEngine/SymbolResolverProxy.h"
#include "bcc/Renderscript/RSInfo.h"
-#include "bcc/Renderscript/RSCompiler.h"
#include "bcc/Renderscript/RSScript.h"
namespace bcc {
@@ -39,7 +39,7 @@
class RSCompilerDriver {
private:
CompilerConfig *mConfig;
- RSCompiler mCompiler;
+ Compiler mCompiler;
// Are we compiling under an RS debug context with additional checks?
bool mDebugContext;
@@ -73,7 +73,7 @@
RSCompilerDriver(bool pUseCompilerRT = true);
~RSCompilerDriver();
- RSCompiler *getCompiler() {
+ Compiler *getCompiler() {
return &mCompiler;
}
diff --git a/lib/Core/Compiler.cpp b/lib/Core/Compiler.cpp
index c5890e2..4b4b4b7 100644
--- a/lib/Core/Compiler.cpp
+++ b/lib/Core/Compiler.cpp
@@ -28,11 +28,16 @@
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
#include <llvm/Transforms/Scalar.h>
+#include "bcc/Assert.h"
+#include "bcc/Renderscript/RSExecutable.h"
+#include "bcc/Renderscript/RSScript.h"
+#include "bcc/Renderscript/RSTransforms.h"
#include "bcc/Script.h"
#include "bcc/Source.h"
#include "bcc/Support/CompilerConfig.h"
#include "bcc/Support/Log.h"
#include "bcc/Support/OutputFile.h"
+#include "bcinfo/MetadataExtractor.h"
#include <string>
@@ -62,20 +67,8 @@
return "Failed to prepare file for output.";
case kPrepareCodeGenPass:
return "Failed to construct pass list for code-generation.";
- case kErrHookBeforeAddLTOPasses:
- return "Error occurred during beforeAddLTOPasses() in subclass.";
- case kErrHookAfterAddLTOPasses:
- return "Error occurred during afterAddLTOPasses() in subclass.";
- case kErrHookAfterExecuteLTOPasses:
- return "Error occurred during afterExecuteLTOPasses() in subclass.";
- case kErrHookBeforeAddCodeGenPasses:
- return "Error occurred during beforeAddCodeGenPasses() in subclass.";
- case kErrHookAfterAddCodeGenPasses:
- return "Error occurred during afterAddCodeGenPasses() in subclass.";
- case kErrHookBeforeExecuteCodeGenPasses:
- return "Error occurred during beforeExecuteCodeGenPasses() in subclass.";
- case kErrHookAfterExecuteCodeGenPasses:
- return "Error occurred during afterExecuteCodeGenPasses() in subclass.";
+ case kErrCustomPasses:
+ return "Error occurred while adding custom passes.";
case kErrInvalidSource:
return "Error loading input bitcode";
}
@@ -89,12 +82,12 @@
//===----------------------------------------------------------------------===//
// Instance Methods
//===----------------------------------------------------------------------===//
-Compiler::Compiler() : mTarget(nullptr), mEnableLTO(true) {
+Compiler::Compiler() : mTarget(nullptr), mEnableOpt(true) {
return;
}
Compiler::Compiler(const CompilerConfig &pConfig) : mTarget(nullptr),
- mEnableLTO(true) {
+ mEnableOpt(true) {
const std::string &triple = pConfig.getTriple();
enum ErrorCode err = config(pConfig);
@@ -123,7 +116,7 @@
if (new_target == nullptr) {
return ((mTarget != nullptr) ? kErrSwitchTargetMachine :
- kErrCreateTargetMachine);
+ kErrCreateTargetMachine);
}
// Replace the old TargetMachine.
@@ -146,98 +139,50 @@
delete mTarget;
}
-enum Compiler::ErrorCode Compiler::runLTO(Script &pScript) {
- llvm::DataLayoutPass *data_layout_pass = nullptr;
-
+enum Compiler::ErrorCode Compiler::runPasses(Script &pScript,
+ llvm::raw_ostream &pResult) {
// Pass manager for link-time optimization
- llvm::PassManager lto_passes;
+ llvm::PassManager passes;
+
+ // Empty MCContext.
+ llvm::MCContext *mc_context = nullptr;
// Prepare DataLayout target data from Module
- data_layout_pass = new (std::nothrow) llvm::DataLayoutPass(*mTarget->getDataLayout());
+ llvm::DataLayoutPass *data_layout_pass =
+ new (std::nothrow) llvm::DataLayoutPass(*mTarget->getDataLayout());
+
if (data_layout_pass == nullptr) {
return kErrDataLayoutNoMemory;
}
// Add DataLayout to the pass manager.
- lto_passes.add(data_layout_pass);
+ passes.add(data_layout_pass);
- // Invoke "beforeAddLTOPasses" before adding the first pass.
- if (!beforeAddLTOPasses(pScript, lto_passes)) {
- return kErrHookBeforeAddLTOPasses;
+ // Add our custom passes.
+ if (!addCustomPasses(pScript, passes)) {
+ return kErrCustomPasses;
}
if (mTarget->getOptLevel() == llvm::CodeGenOpt::None) {
- lto_passes.add(llvm::createGlobalOptimizerPass());
- lto_passes.add(llvm::createConstantMergePass());
+ passes.add(llvm::createGlobalOptimizerPass());
+ passes.add(llvm::createConstantMergePass());
+
} else {
// FIXME: Figure out which passes should be executed.
llvm::PassManagerBuilder Builder;
- Builder.populateLTOPassManager(lto_passes, /*Internalize*/false,
- /*RunInliner*/true);
- }
-
- // Invoke "afterAddLTOPasses" after pass manager finished its
- // construction.
- if (!afterAddLTOPasses(pScript, lto_passes)) {
- return kErrHookAfterAddLTOPasses;
- }
-
- lto_passes.run(pScript.getSource().getModule());
-
- // Invoke "afterExecuteLTOPasses" before returning.
- if (!afterExecuteLTOPasses(pScript)) {
- return kErrHookAfterExecuteLTOPasses;
- }
-
- return kSuccess;
-}
-
-enum Compiler::ErrorCode Compiler::runCodeGen(Script &pScript,
- llvm::raw_ostream &pResult) {
- llvm::DataLayoutPass *data_layout_pass;
- llvm::MCContext *mc_context = nullptr;
-
- // Create pass manager for MC code generation.
- llvm::PassManager codegen_passes;
-
- // Prepare DataLayout target data from Module
- data_layout_pass = new (std::nothrow) llvm::DataLayoutPass(*mTarget->getDataLayout());
- if (data_layout_pass == nullptr) {
- return kErrDataLayoutNoMemory;
- }
-
- // Add DataLayout to the pass manager.
- codegen_passes.add(data_layout_pass);
-
- // Invokde "beforeAddCodeGenPasses" before adding the first pass.
- if (!beforeAddCodeGenPasses(pScript, codegen_passes)) {
- return kErrHookBeforeAddCodeGenPasses;
+ Builder.populateLTOPassManager(passes,
+ /*Internalize*/ false,
+ /*RunInliner*/ true);
}
// Add passes to the pass manager to emit machine code through MC layer.
- if (mTarget->addPassesToEmitMC(codegen_passes, mc_context, pResult,
+ if (mTarget->addPassesToEmitMC(passes, mc_context, pResult,
/* DisableVerify */false)) {
return kPrepareCodeGenPass;
}
- // Invokde "afterAddCodeGenPasses" after pass manager finished its
- // construction.
- if (!afterAddCodeGenPasses(pScript, codegen_passes)) {
- return kErrHookAfterAddCodeGenPasses;
- }
-
- // Invokde "beforeExecuteCodeGenPasses" before executing the passes.
- if (!beforeExecuteCodeGenPasses(pScript, codegen_passes)) {
- return kErrHookBeforeExecuteCodeGenPasses;
- }
-
- // Execute the pass.
- codegen_passes.run(pScript.getSource().getModule());
-
- // Invokde "afterExecuteCodeGenPasses" before returning.
- if (!afterExecuteCodeGenPasses(pScript)) {
- return kErrHookAfterExecuteCodeGenPasses;
- }
+ // Execute the passes.
+ passes.run(pScript.getSource().getModule());
return kSuccess;
}
@@ -280,15 +225,12 @@
}
}
- if (mEnableLTO && ((err = runLTO(pScript)) != kSuccess)) {
+ if ((err = runPasses(pScript, pResult)) != kSuccess) {
return err;
}
- if (IRStream)
+ if (IRStream) {
*IRStream << module;
-
- if ((err = runCodeGen(pScript, pResult)) != kSuccess) {
- return err;
}
return kSuccess;
@@ -316,3 +258,84 @@
return err;
}
+
+bool Compiler::addInternalizeSymbolsPass(Script &pScript, llvm::PassManager &pPM) {
+ // Add a pass to internalize the symbols that don't need to have global
+ // visibility.
+ RSScript &script = static_cast<RSScript &>(pScript);
+ llvm::Module &module = script.getSource().getModule();
+ bcinfo::MetadataExtractor me(&module);
+ if (!me.extract()) {
+ bccAssert(false && "Could not extract metadata for module!");
+ return false;
+ }
+
+ // The vector contains the symbols that should not be internalized.
+ std::vector<const char *> export_symbols;
+
+ // Special RS functions should always be global symbols.
+ const char **special_functions = RSExecutable::SpecialFunctionNames;
+ while (*special_functions != nullptr) {
+ export_symbols.push_back(*special_functions);
+ special_functions++;
+ }
+
+ // Visibility of symbols appeared in rs_export_var and rs_export_func should
+ // also be preserved.
+ size_t exportVarCount = me.getExportVarCount();
+ size_t exportFuncCount = me.getExportFuncCount();
+ size_t exportForEachCount = me.getExportForEachSignatureCount();
+ const char **exportVarNameList = me.getExportVarNameList();
+ const char **exportFuncNameList = me.getExportFuncNameList();
+ const char **exportForEachNameList = me.getExportForEachNameList();
+ size_t i;
+
+ for (i = 0; i < exportVarCount; ++i) {
+ export_symbols.push_back(exportVarNameList[i]);
+ }
+
+ for (i = 0; i < exportFuncCount; ++i) {
+ export_symbols.push_back(exportFuncNameList[i]);
+ }
+
+ // Expanded foreach functions should not be internalized, too.
+ // expanded_foreach_funcs keeps the .expand version of the kernel names
+ // around until createInternalizePass() is finished making its own
+ // copy of the visible symbols.
+ std::vector<std::string> expanded_foreach_funcs;
+ for (i = 0; i < exportForEachCount; ++i) {
+ expanded_foreach_funcs.push_back(
+ std::string(exportForEachNameList[i]) + ".expand");
+ }
+
+ for (i = 0; i < exportForEachCount; i++) {
+ export_symbols.push_back(expanded_foreach_funcs[i].c_str());
+ }
+
+ pPM.add(llvm::createInternalizePass(export_symbols));
+
+ return true;
+}
+
+bool Compiler::addExpandForEachPass(Script &pScript, llvm::PassManager &pPM) {
+ // Script passed to RSCompiler must be a RSScript.
+ RSScript &script = static_cast<RSScript &>(pScript);
+
+ // Expand ForEach on CPU path to reduce launch overhead.
+ bool pEnableStepOpt = true;
+ pPM.add(createRSForEachExpandPass(pEnableStepOpt));
+ if (script.getEmbedInfo())
+ pPM.add(createRSEmbedInfoPass());
+
+ return true;
+}
+
+bool Compiler::addCustomPasses(Script &pScript, llvm::PassManager &pPM) {
+ if (!addExpandForEachPass(pScript, pPM))
+ return false;
+
+ if (!addInternalizeSymbolsPass(pScript, pPM))
+ return false;
+
+ return true;
+}
diff --git a/lib/Renderscript/Android.mk b/lib/Renderscript/Android.mk
index cac894a..133966e 100644
--- a/lib/Renderscript/Android.mk
+++ b/lib/Renderscript/Android.mk
@@ -22,7 +22,6 @@
#=====================================================================
libbcc_renderscript_SRC_FILES := \
- RSCompiler.cpp \
RSCompilerDriver.cpp \
RSEmbedInfo.cpp \
RSExecutable.cpp \
diff --git a/lib/Renderscript/RSCompiler.cpp b/lib/Renderscript/RSCompiler.cpp
deleted file mode 100644
index dc5ba6a..0000000
--- a/lib/Renderscript/RSCompiler.cpp
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "bcc/Renderscript/RSCompiler.h"
-
-#include <llvm/IR/Module.h>
-#include <llvm/PassManager.h>
-#include <llvm/Transforms/IPO.h>
-
-#include "bcc/Assert.h"
-#include "bcc/Renderscript/RSExecutable.h"
-#include "bcc/Renderscript/RSScript.h"
-#include "bcc/Renderscript/RSTransforms.h"
-#include "bcc/Source.h"
-#include "bcc/Support/Log.h"
-#include "bcinfo/MetadataExtractor.h"
-
-using namespace bcc;
-
-bool RSCompiler::addInternalizeSymbolsPass(Script &pScript, llvm::PassManager &pPM) {
- // Add a pass to internalize the symbols that don't need to have global
- // visibility.
- RSScript &script = static_cast<RSScript &>(pScript);
- llvm::Module &module = script.getSource().getModule();
- bcinfo::MetadataExtractor me(&module);
- if (!me.extract()) {
- bccAssert(false && "Could not extract metadata for module!");
- return false;
- }
-
- // The vector contains the symbols that should not be internalized.
- std::vector<const char *> export_symbols;
-
- // Special RS functions should always be global symbols.
- const char **special_functions = RSExecutable::SpecialFunctionNames;
- while (*special_functions != nullptr) {
- export_symbols.push_back(*special_functions);
- special_functions++;
- }
-
- // Visibility of symbols appeared in rs_export_var and rs_export_func should
- // also be preserved.
- size_t exportVarCount = me.getExportVarCount();
- size_t exportFuncCount = me.getExportFuncCount();
- size_t exportForEachCount = me.getExportForEachSignatureCount();
- const char **exportVarNameList = me.getExportVarNameList();
- const char **exportFuncNameList = me.getExportFuncNameList();
- const char **exportForEachNameList = me.getExportForEachNameList();
- size_t i;
-
- for (i = 0; i < exportVarCount; ++i) {
- export_symbols.push_back(exportVarNameList[i]);
- }
-
- for (i = 0; i < exportFuncCount; ++i) {
- export_symbols.push_back(exportFuncNameList[i]);
- }
-
- // Expanded foreach functions should not be internalized, too.
- // expanded_foreach_funcs keeps the .expand version of the kernel names
- // around until createInternalizePass() is finished making its own
- // copy of the visible symbols.
- std::vector<std::string> expanded_foreach_funcs;
- for (i = 0; i < exportForEachCount; ++i) {
- expanded_foreach_funcs.push_back(
- std::string(exportForEachNameList[i]) + ".expand");
- }
-
- for (i = 0; i < exportForEachCount; i++) {
- export_symbols.push_back(expanded_foreach_funcs[i].c_str());
- }
-
- pPM.add(llvm::createInternalizePass(export_symbols));
-
- return true;
-}
-
-bool RSCompiler::addExpandForEachPass(Script &pScript, llvm::PassManager &pPM) {
- // Script passed to RSCompiler must be a RSScript.
- RSScript &script = static_cast<RSScript &>(pScript);
-
- // Expand ForEach on CPU path to reduce launch overhead.
- bool pEnableStepOpt = true;
- pPM.add(createRSForEachExpandPass(pEnableStepOpt));
- if (script.getEmbedInfo())
- pPM.add(createRSEmbedInfoPass());
-
- return true;
-}
-
-bool RSCompiler::beforeAddLTOPasses(Script &pScript, llvm::PassManager &pPM) {
- if (!addExpandForEachPass(pScript, pPM))
- return false;
-
- if (!addInternalizeSymbolsPass(pScript, pPM))
- return false;
-
- return true;
-}
diff --git a/tools/bcc/Main.cpp b/tools/bcc/Main.cpp
index 6b9b13d..9c6ed45 100644
--- a/tools/bcc/Main.cpp
+++ b/tools/bcc/Main.cpp
@@ -116,7 +116,7 @@
static inline
bool ConfigCompiler(RSCompilerDriver &pRSCD) {
- RSCompiler *RSC = pRSCD.getCompiler();
+ Compiler *RSC = pRSCD.getCompiler();
CompilerConfig *config = nullptr;
config = new (std::nothrow) CompilerConfig(OptTargetTriple);
diff --git a/tools/bcc_compat/Main.cpp b/tools/bcc_compat/Main.cpp
index f7875e8..6593d9a 100644
--- a/tools/bcc_compat/Main.cpp
+++ b/tools/bcc_compat/Main.cpp
@@ -151,7 +151,7 @@
static inline
bool ConfigCompiler(RSCompilerDriver &pCompilerDriver) {
- RSCompiler *compiler = pCompilerDriver.getCompiler();
+ Compiler *compiler = pCompilerDriver.getCompiler();
CompilerConfig *config = nullptr;
config = new (std::nothrow) CompilerConfig(OptTargetTriple);