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