1/* 2 * Copyright 2012, The Android Open Source Project 3 * 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 17#include "bcc/Support/CompilerConfig.h" 18#include "bcc/Config/Config.h" 19#include "bcc/Support/Properties.h" 20 21#include <llvm/CodeGen/SchedulerRegistry.h> 22#include <llvm/MC/SubtargetFeature.h> 23#include <llvm/Support/Host.h> 24#include <llvm/Support/TargetRegistry.h> 25 26#include "bcc/Support/Log.h" 27 28using namespace bcc; 29 30CompilerConfig::CompilerConfig(const std::string &pTriple) 31 : mTriple(pTriple), mFullPrecision(true), mTarget(NULL) { 32 //===--------------------------------------------------------------------===// 33 // Default setting of register sheduler 34 //===--------------------------------------------------------------------===// 35 llvm::RegisterScheduler::setDefault(llvm::createDefaultScheduler); 36 37 //===--------------------------------------------------------------------===// 38 // Default setting of target options 39 //===--------------------------------------------------------------------===// 40 // Use hardfloat ABI by default. 41 // 42 // TODO(all): Need to detect the CPU capability and decide whether to use 43 // softfp. To use softfp, change the following 2 lines to 44 // 45 // options.FloatABIType = llvm::FloatABI::Soft; 46 // options.UseSoftFloat = true; 47 mTargetOpts.FloatABIType = llvm::FloatABI::Soft; 48 mTargetOpts.UseSoftFloat = false; 49 50 // Enable frame pointer elimination optimization by default. 51 mTargetOpts.NoFramePointerElim = false; 52 53 //===--------------------------------------------------------------------===// 54 // Default setting for code model 55 //===--------------------------------------------------------------------===// 56 mCodeModel = llvm::CodeModel::Small; 57 58 //===--------------------------------------------------------------------===// 59 // Default setting for relocation model 60 //===--------------------------------------------------------------------===// 61 mRelocModel = llvm::Reloc::Default; 62 63 //===--------------------------------------------------------------------===// 64 // Default setting for optimization level (-O2) 65 //===--------------------------------------------------------------------===// 66 mOptLevel = llvm::CodeGenOpt::Default; 67 68 //===--------------------------------------------------------------------===// 69 // Default setting for architecture type 70 //===--------------------------------------------------------------------===// 71 mArchType = llvm::Triple::UnknownArch; 72 73 initializeTarget(); 74 initializeArch(); 75 76 return; 77} 78 79bool CompilerConfig::initializeTarget() { 80 std::string error; 81 mTarget = llvm::TargetRegistry::lookupTarget(mTriple, error); 82 if (mTarget != NULL) { 83 return true; 84 } else { 85 ALOGE("Cannot initialize llvm::Target for given triple '%s'! (%s)", 86 mTriple.c_str(), error.c_str()); 87 return false; 88 } 89} 90 91bool CompilerConfig::initializeArch() { 92 if (mTarget != NULL) { 93 mArchType = llvm::Triple::getArchTypeForLLVMName(mTarget->getName()); 94 } else { 95 mArchType = llvm::Triple::UnknownArch; 96 return false; 97 } 98 99 // Configure each architecture for any necessary additional flags. 100 switch (mArchType) { 101#if defined(PROVIDE_ARM_CODEGEN) 102 case llvm::Triple::arm: { 103 llvm::StringMap<bool> features; 104 llvm::sys::getHostCPUFeatures(features); 105 std::vector<std::string> attributes; 106 107#if defined(__HOST__) || defined(ARCH_ARM_HAVE_VFP) 108 attributes.push_back("+vfp3"); 109#if !defined(__HOST__) && !defined(ARCH_ARM_HAVE_VFP_D32) 110 attributes.push_back("+d16"); 111#endif // !__HOST__ && !ARCH_ARM_HAVE_VFP_D32 112#endif // __HOST__ || ARCH_ARM_HAVE_VFP 113 114#if defined(__HOST__) || defined(ARCH_ARM_HAVE_NEON) 115 // Only enable NEON on ARM if we have relaxed precision floats. 116 if (!mFullPrecision) { 117 attributes.push_back("+neon"); 118 } else { 119#endif // __HOST__ || ARCH_ARM_HAVE_NEON 120 attributes.push_back("-neon"); 121 attributes.push_back("-neonfp"); 122#if defined(__HOST__) || defined(ARCH_ARM_HAVE_NEON) 123 } 124#endif // __HOST__ || ARCH_ARM_HAVE_NEON 125 126 if (!getProperty("debug.rs.arm-no-hwdiv")) { 127 if (features.count("hwdiv-arm") && features["hwdiv-arm"]) 128 attributes.push_back("+hwdiv-arm"); 129 130 if (features.count("hwdiv") && features["hwdiv"]) 131 attributes.push_back("+hwdiv"); 132 } 133 134 setFeatureString(attributes); 135 136#if defined(TARGET_BUILD) 137 if (!getProperty("debug.rs.arm-no-tune-for-cpu")) { 138#ifndef FORCE_CPU_VARIANT_32 139 setCPU(llvm::sys::getHostCPUName()); 140#else 141#define XSTR(S) #S 142#define STR(S) XSTR(S) 143 setCPU(STR(FORCE_CPU_VARIANT_32)); 144#undef STR 145#undef XSTR 146#endif 147 } 148#endif // TARGET_BUILD 149 150 break; 151 } 152#endif // PROVIDE_ARM_CODEGEN 153 154#if defined(PROVIDE_ARM64_CODEGEN) 155 case llvm::Triple::aarch64: 156#if defined(TARGET_BUILD) 157 if (!getProperty("debug.rs.arm-no-tune-for-cpu")) { 158#ifndef FORCE_CPU_VARIANT_64 159 setCPU(llvm::sys::getHostCPUName()); 160#else 161#define XSTR(S) #S 162#define STR(S) XSTR(S) 163 setCPU(STR(FORCE_CPU_VARIANT_64)); 164#undef STR 165#undef XSTR 166#endif 167 168 } 169#endif // TARGET_BUILD 170 break; 171#endif // PROVIDE_ARM64_CODEGEN 172 173#if defined (PROVIDE_MIPS_CODEGEN) 174 case llvm::Triple::mips: 175 case llvm::Triple::mipsel: 176 case llvm::Triple::mips64: 177 case llvm::Triple::mips64el: 178 if (getRelocationModel() == llvm::Reloc::Default) { 179 setRelocationModel(llvm::Reloc::Static); 180 } 181 break; 182#endif // PROVIDE_MIPS_CODEGEN 183 184#if defined (PROVIDE_X86_CODEGEN) 185 case llvm::Triple::x86: 186 // Disable frame pointer elimination optimization on x86 family. 187 getTargetOptions().NoFramePointerElim = true; 188 getTargetOptions().UseInitArray = true; 189 break; 190#endif // PROVIDE_X86_CODEGEN 191 192#if defined (PROVIDE_X86_CODEGEN) 193 case llvm::Triple::x86_64: 194 setCodeModel(llvm::CodeModel::Medium); 195 // Disable frame pointer elimination optimization on x86 family. 196 getTargetOptions().NoFramePointerElim = true; 197 getTargetOptions().UseInitArray = true; 198 break; 199#endif // PROVIDE_X86_CODEGEN 200 201 default: 202 ALOGE("Unsupported architecture type: %s", mTarget->getName()); 203 return false; 204 } 205 206 return true; 207} 208 209void CompilerConfig::setFeatureString(const std::vector<std::string> &pAttrs) { 210 llvm::SubtargetFeatures f; 211 212 for (std::vector<std::string>::const_iterator attr_iter = pAttrs.begin(), 213 attr_end = pAttrs.end(); 214 attr_iter != attr_end; attr_iter++) { 215 f.AddFeature(*attr_iter); 216 } 217 218 mFeatureString = f.getString(); 219 return; 220} 221