• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
28 using namespace bcc;
29 
CompilerConfig(const std::string & pTriple)30 CompilerConfig::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 
initializeTarget()79 bool 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 
initializeArch()91 bool 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 
setFeatureString(const std::vector<std::string> & pAttrs)209 void 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