Introduce CompilerConfig.
CompilerConfig defines the "attributes" of a Compiler. It contains
target information, configuration, etc. to setup an instance of
Compiler (more specifically, a instance of LLVM TargetMachine used by
the compiler.)
CompilerConfig together with bcc::init::Initialize() will replace
current Compiler::GlobalInitialization().
diff --git a/Config.h b/Config.h
index c1f4133..3c29c60 100644
--- a/Config.h
+++ b/Config.h
@@ -58,14 +58,19 @@
#endif
#endif
+#define DEFAULT_ARM_TRIPLE_STRING "armv7-none-linux-gnueabi"
+#define DEFAULT_MIPS_TRIPLE_STRING "mipsel-none-linux-gnueabi"
+#define DEFAULT_X86_TRIPLE_STRING "i686-unknown-linux"
+#define DEFAULT_X86_64_TRIPLE_STRING "x86_64-unknown-linux"
+
#if defined(DEFAULT_ARM_CODEGEN)
- #define DEFAULT_TARGET_TRIPLE_STRING "armv7-none-linux-gnueabi"
+ #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_ARM_TRIPLE_STRING
#elif defined(DEFAULT_MIPS_CODEGEN)
- #define DEFAULT_TARGET_TRIPLE_STRING "mipsel-none-linux-gnueabi"
+ #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_MIPS_TRIPLE_STRING
#elif defined(DEFAULT_X86_CODEGEN)
- #define DEFAULT_TARGET_TRIPLE_STRING "i686-unknown-linux"
+ #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_X86_TRIPLE_STRING
#elif defined(DEFAULT_X86_64_CODEGEN)
- #define DEFAULT_TARGET_TRIPLE_STRING "x86_64-unknown-linux"
+ #define DEFAULT_TARGET_TRIPLE_STRING DEFAULT_X86_64_TRIPLE_STRING
#endif
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
diff --git a/lib/ExecutionEngine/Android.mk b/lib/ExecutionEngine/Android.mk
index 02088cb..d101107 100644
--- a/lib/ExecutionEngine/Android.mk
+++ b/lib/ExecutionEngine/Android.mk
@@ -27,10 +27,12 @@
BCCContextImpl.cpp \
BCCRuntimeSymbolResolver.cpp \
Compiler.cpp \
+ CompilerConfig.cpp \
ELFObjectLoaderImpl.cpp \
FileBase.cpp \
GDBJIT.cpp \
GDBJITRegistrar.cpp \
+ Initialization.cpp \
InputFile.cpp \
MCCacheWriter.cpp \
MCCacheReader.cpp \
@@ -49,7 +51,8 @@
Sha1Helper.cpp \
Source.cpp \
SymbolResolverProxy.cpp \
- SymbolResolvers.cpp
+ SymbolResolvers.cpp \
+ TargetCompilerConfigs.cpp
#=====================================================================
diff --git a/lib/ExecutionEngine/CompilerConfig.cpp b/lib/ExecutionEngine/CompilerConfig.cpp
new file mode 100644
index 0000000..faaaa97
--- /dev/null
+++ b/lib/ExecutionEngine/CompilerConfig.cpp
@@ -0,0 +1,109 @@
+/*
+ * 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 "CompilerConfig.h"
+
+#include <llvm/CodeGen/SchedulerRegistry.h>
+#include <llvm/MC/SubtargetFeature.h>
+#include <llvm/Support/TargetRegistry.h>
+
+#include "DebugHelper.h"
+#include "TargetCompilerConfigs.h"
+
+using namespace bcc;
+
+CompilerConfig::CompilerConfig(const std::string &pTriple)
+ : mTriple(pTriple), mTarget(NULL) {
+ //===--------------------------------------------------------------------===//
+ // Default setting of register sheduler
+ //===--------------------------------------------------------------------===//
+ llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler);
+
+ //===--------------------------------------------------------------------===//
+ // Default setting of target options
+ //===--------------------------------------------------------------------===//
+ // Use hardfloat ABI by default.
+ //
+ // TODO(all): Need to detect the CPU capability and decide whether to use
+ // softfp. To use softfp, change the following 2 lines to
+ //
+ // options.FloatABIType = llvm::FloatABI::Soft;
+ // options.UseSoftFloat = true;
+ mTargetOpts.FloatABIType = llvm::FloatABI::Soft;
+ mTargetOpts.UseSoftFloat = false;
+
+ // Enable frame pointer elimination optimization by default.
+ mTargetOpts.NoFramePointerElim = false;
+
+ //===--------------------------------------------------------------------===//
+ // Default setting for code model
+ //===--------------------------------------------------------------------===//
+ mCodeModel = llvm::CodeModel::Small;
+
+ //===--------------------------------------------------------------------===//
+ // Default setting for relocation model
+ //===--------------------------------------------------------------------===//
+ mRelocModel = llvm::Reloc::Default;
+
+ //===--------------------------------------------------------------------===//
+ // Default setting for optimization level (-O2)
+ //===--------------------------------------------------------------------===//
+ mOptLevel = llvm::CodeGenOpt::Default;
+
+ //===--------------------------------------------------------------------===//
+ // Default setting for architecture type
+ //===--------------------------------------------------------------------===//
+ mArchType = llvm::Triple::UnknownArch;
+
+ initializeTarget();
+ initializeArch();
+
+ return;
+}
+
+bool CompilerConfig::initializeTarget() {
+ std::string error;
+ mTarget = llvm::TargetRegistry::lookupTarget(mTriple, error);
+ if (mTarget != NULL) {
+ return true;
+ } else {
+ ALOGE("Cannot initialize llvm::Target for given triple '%s'! (%s)",
+ mTriple.c_str(), error.c_str());
+ return false;
+ }
+}
+
+void CompilerConfig::initializeArch() {
+ if (mTarget != NULL) {
+ mArchType = llvm::Triple::getArchTypeForLLVMName(mTarget->getName());
+ } else {
+ mArchType = llvm::Triple::UnknownArch;
+ }
+ return;
+}
+
+void CompilerConfig::setFeatureString(const std::vector<std::string> &pAttrs) {
+ llvm::SubtargetFeatures f;
+
+ for (std::vector<std::string>::const_iterator attr_iter = pAttrs.begin(),
+ attr_end = pAttrs.end();
+ attr_iter != attr_end; attr_iter++) {
+ f.AddFeature(*attr_iter);
+ }
+
+ mFeatureString = f.getString();
+ return;
+}
diff --git a/lib/ExecutionEngine/CompilerConfig.h b/lib/ExecutionEngine/CompilerConfig.h
new file mode 100644
index 0000000..d83086a
--- /dev/null
+++ b/lib/ExecutionEngine/CompilerConfig.h
@@ -0,0 +1,117 @@
+/*
+ * 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_EXECUTION_ENGINE_COMPILER_CONFIG_H
+#define BCC_EXECUTION_ENGINE_COMPILER_CONFIG_H
+
+#include <string>
+#include <vector>
+
+#include <llvm/ADT/Triple.h>
+#include <llvm/Support/CodeGen.h>
+#include <llvm/Target/TargetOptions.h>
+
+namespace llvm {
+
+class Target;
+
+} // end namespace llvm
+
+namespace bcc {
+
+class CompilerConfig {
+private:
+ //===--------------------------------------------------------------------===//
+ // Available Configurations
+ //===--------------------------------------------------------------------===//
+ std::string mTriple;
+
+ // Optional. If given, the name of the target CPU to generate code for.
+ std::string mCPU;
+
+ llvm::TargetOptions mTargetOpts;
+
+ llvm::CodeModel::Model mCodeModel;
+
+ llvm::CodeGenOpt::Level mOptLevel;
+
+ llvm::Reloc::Model mRelocModel;
+
+ // The list of target specific features to enable or disable -- this should
+ // be a list of strings starting with '+' (enable) or '-' (disable).
+ std::string mFeatureString;
+
+private:
+ //===--------------------------------------------------------------------===//
+ // These are generated by CompilerConfig during initialize().
+ //===--------------------------------------------------------------------===//
+ const llvm::Target *mTarget;
+ bool initializeTarget();
+
+ llvm::Triple::ArchType mArchType;
+ void initializeArch();
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Getters
+ //===--------------------------------------------------------------------===//
+ inline const std::string &getTriple() const
+ { return mTriple; }
+
+ inline const std::string &getCPU() const
+ { return mCPU; }
+ inline void setCPU(const std::string &pCPU)
+ { mCPU = pCPU; }
+
+ inline const llvm::TargetOptions &getTargetOptions() const
+ { return mTargetOpts; }
+ inline llvm::TargetOptions &getTargetOptions()
+ { return mTargetOpts; }
+
+ inline llvm::CodeModel::Model getCodeModel() const
+ { return mCodeModel; }
+ inline void setCodeModel(llvm::CodeModel::Model pCodeMode)
+ { mCodeModel = pCodeMode; }
+
+ inline llvm::CodeGenOpt::Level getOptimizationLevel() const
+ { return mOptLevel; }
+ inline void setOptimizationLevel(llvm::CodeGenOpt::Level pOptLvl)
+ { mOptLevel = pOptLvl; }
+
+ inline llvm::Reloc::Model getRelocationModel() const
+ { return mRelocModel; }
+ inline void setRelocationModel(llvm::Reloc::Model pRelocModel)
+ { mRelocModel = pRelocModel; }
+
+ inline const llvm::Target *getTarget() const
+ { return mTarget; }
+
+ inline llvm::Triple::ArchType getArchType() const
+ { return mArchType; }
+
+ inline const std::string &getFeatureString() const
+ { return mFeatureString; }
+ void setFeatureString(const std::vector<std::string> &pAttrs);
+
+public:
+ CompilerConfig(const std::string &pTriple);
+
+ virtual ~CompilerConfig() { }
+};
+
+} // end namespace bcc
+
+#endif // BCC_EXECUTION_ENGINE_COMPILER_CONFIG_H
diff --git a/lib/ExecutionEngine/Initialization.cpp b/lib/ExecutionEngine/Initialization.cpp
new file mode 100644
index 0000000..7cdb938
--- /dev/null
+++ b/lib/ExecutionEngine/Initialization.cpp
@@ -0,0 +1,75 @@
+/*
+ * 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 "Initialization.h"
+
+#include <cstdlib>
+
+#include <llvm/Support/ErrorHandling.h>
+#include <llvm/Support/TargetSelect.h>
+
+#include "Config.h"
+#include "DebugHelper.h"
+
+namespace {
+
+void llvm_error_handler(void *pUserData, const std::string &pMessage) {
+ ALOGE("%s", pMessage.c_str());
+ ::exit(1);
+}
+
+} // end anonymous namespace
+
+void bcc::init::Initialize() {
+ static bool is_initialized = false;
+
+ if (is_initialized) {
+ return;
+ }
+
+ // Setup error handler for LLVM.
+ llvm::remove_fatal_error_handler();
+ llvm::install_fatal_error_handler(llvm_error_handler, NULL);
+
+#if defined(PROVIDE_ARM_CODEGEN)
+ LLVMInitializeARMAsmPrinter();
+ LLVMInitializeARMTargetMC();
+ LLVMInitializeARMTargetInfo();
+ LLVMInitializeARMTarget();
+#endif
+
+#if defined(PROVIDE_MIPS_CODEGEN)
+ LLVMInitializeMipsAsmPrinter();
+ LLVMInitializeMipsTargetMC();
+ LLVMInitializeMipsTargetInfo();
+ LLVMInitializeMipsTarget();
+#endif
+
+#if defined(PROVIDE_X86_CODEGEN)
+ LLVMInitializeX86AsmPrinter();
+ LLVMInitializeX86TargetMC();
+ LLVMInitializeX86TargetInfo();
+ LLVMInitializeX86Target();
+#endif
+
+#if USE_DISASSEMBLER
+ InitializeDisassembler();
+#endif
+
+ is_initialized = true;
+
+ return;
+}
diff --git a/lib/ExecutionEngine/Initialization.h b/lib/ExecutionEngine/Initialization.h
new file mode 100644
index 0000000..9a357bc
--- /dev/null
+++ b/lib/ExecutionEngine/Initialization.h
@@ -0,0 +1,30 @@
+/*
+ * 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_EXECUTION_ENGINE_INITIALIZATION_H
+#define BCC_EXECUTION_ENGINE_INITIALIZATION_H
+
+namespace bcc {
+
+namespace init {
+
+void Initialize();
+
+} // end namespace init
+
+} // end namespace bcc
+
+#endif // BCC_EXECUTION_ENGINE_INITIALIZATION_H
diff --git a/lib/ExecutionEngine/TargetCompilerConfigs.cpp b/lib/ExecutionEngine/TargetCompilerConfigs.cpp
new file mode 100644
index 0000000..2e2f5da
--- /dev/null
+++ b/lib/ExecutionEngine/TargetCompilerConfigs.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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 "TargetCompilerConfigs.h"
+
+using namespace bcc;
+
+//===----------------------------------------------------------------------===//
+// ARM
+//===----------------------------------------------------------------------===//
+#if defined(PROVIDE_ARM_CODEGEN)
+
+void ARMCompilerConfig::GetFeatureVector(std::vector<std::string> &pAttributes,
+ bool pEnableNEON) {
+#if defined(ARCH_ARM_HAVE_VFP)
+ pAttributes.push_back("+vfp3");
+# if !defined(ARCH_ARM_HAVE_VFP_D32)
+ pAttributes.push_back("+d16");
+# endif
+#endif
+
+#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
+ if (pEnableNEON) {
+ // FIXME(all): Turn NEON back on after debugging the rebase.
+ //attributes.push_back("+neon");
+ //attributes.push_back("+neonfp");
+ pAttributes.push_back("-neon");
+ pAttributes.push_back("-neonfp");
+ } else {
+ pAttributes.push_back("-neon");
+ pAttributes.push_back("-neonfp");
+ }
+#else
+ pAttributes.push_back("-neon");
+ pAttributes.push_back("-neonfp");
+#endif
+
+ return;
+}
+
+ARMCompilerConfig::ARMCompilerConfig()
+ : CompilerConfig(DEFAULT_ARM_TRIPLE_STRING) {
+
+ // Enable NEON by default.
+ mEnableNEON = true;
+
+ std::vector<std::string> attributes;
+ GetFeatureVector(attributes, /* pEnableNEON */mEnableNEON);
+ setFeatureString(attributes);
+
+ return;
+}
+
+bool ARMCompilerConfig::enableNEON(bool pEnable) {
+#if defined(ARCH_ARM_HAVE_NEON) && !defined(DISABLE_ARCH_ARM_HAVE_NEON)
+ if (mEnableNEON != pEnable) {
+ std::vector<std::string> attributes;
+ GetFeatureVector(attributes, pEnable);
+ setFeatureString(attributes);
+ mEnableNEON = pEnable;
+ return true;
+ }
+ // Fall-through
+#endif
+ return false;
+}
+#endif // defined(PROVIDE_ARM_CODEGEN)
diff --git a/lib/ExecutionEngine/TargetCompilerConfigs.h b/lib/ExecutionEngine/TargetCompilerConfigs.h
new file mode 100644
index 0000000..bf10a7a
--- /dev/null
+++ b/lib/ExecutionEngine/TargetCompilerConfigs.h
@@ -0,0 +1,102 @@
+/*
+ * 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_EXECUTION_ENGINE_TARGET_COMPILER_CONFIGS_H
+#define BCC_EXECUTION_ENGINE_TARGET_COMPILER_CONFIGS_H
+
+#include "CompilerConfig.h"
+#include "Config.h"
+
+namespace bcc {
+
+//===----------------------------------------------------------------------===//
+// ARM
+//===----------------------------------------------------------------------===//
+#if defined(PROVIDE_ARM_CODEGEN)
+class ARMCompilerConfig : public CompilerConfig {
+private:
+ bool mEnableNEON;
+
+ static void GetFeatureVector(std::vector<std::string> &pAttributes,
+ bool pEnableNEON);
+
+public:
+ ARMCompilerConfig();
+
+ // Return true if config has been changed after returning from this function.
+ bool enableNEON(bool pEnable = true);
+};
+#endif // defined(PROVIDE_ARM_CODEGEN)
+
+//===----------------------------------------------------------------------===//
+// MIPS
+//===----------------------------------------------------------------------===//
+#if defined(PROVIDE_MIPS_CODEGEN)
+class MipsCompilerConfig : public CompilerConfig {
+public:
+ MipsCompilerConfig() : CompilerConfig(DEFAULT_MIPS_TRIPLE_STRING) {}
+};
+#endif // defined(PROVIDE_MIPS_CODEGEN)
+
+//===----------------------------------------------------------------------===//
+// X86 and X86_64
+//===----------------------------------------------------------------------===//
+#if defined(PROVIDE_X86_CODEGEN)
+class X86FamilyCompilerConfigBase : public CompilerConfig {
+protected:
+ X86FamilyCompilerConfigBase(const std::string &pTriple)
+ : CompilerConfig(pTriple) {
+ // Disable frame pointer elimination optimization on x86 family.
+ getTargetOptions().NoFramePointerElim = true;
+ return;
+ }
+};
+
+class X86_32CompilerConfig : public X86FamilyCompilerConfigBase {
+public:
+ X86_32CompilerConfig() :
+ X86FamilyCompilerConfigBase(DEFAULT_X86_TRIPLE_STRING) { }
+};
+
+class X86_64CompilerConfig : public X86FamilyCompilerConfigBase {
+public:
+ X86_64CompilerConfig() :
+ X86FamilyCompilerConfigBase(DEFAULT_X86_64_TRIPLE_STRING) {
+ setCodeModel(llvm::CodeModel::Medium);
+ }
+};
+#endif // defined(PROVIDE_X86_CODEGEN)
+
+//===----------------------------------------------------------------------===//
+// Default target
+//===----------------------------------------------------------------------===//
+class DefaultCompilerConfig : public
+#if defined(DEFAULT_ARM_CODEGEN)
+ ARMCompilerConfig
+#elif defined(DEFAULT_MIPS_CODEGEN)
+ MipsCompilerConfig
+#elif defined(DEFAULT_X86_CODEGEN)
+ X86_32CompilerConfig
+#elif defined(DEFAULT_X86_64_CODEGEN)
+ X86_64CompilerConfig
+#else
+# error "Unsupported Default Target!"
+#endif
+{ };
+
+} // end namespace bcc
+
+#endif // BCC_EXECUTION_ENGINE_TARGET_COMPILER_CONFIGS_H