compiler_options.h revision 0802518a6a5af8182131eb3fe66bf58dd77f9fe2
1/*
2 * Copyright (C) 2014 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#ifndef ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
18#define ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
19
20#include <ostream>
21#include <string>
22#include <vector>
23
24#include "base/macros.h"
25#include "compiler_filter.h"
26#include "globals.h"
27#include "optimizing/register_allocator.h"
28#include "utils.h"
29
30namespace art {
31
32namespace verifier {
33  class VerifierDepsTest;
34}
35
36class DexFile;
37
38class CompilerOptions FINAL {
39 public:
40  // Guide heuristics to determine whether to compile method if profile data not available.
41  static const size_t kDefaultHugeMethodThreshold = 10000;
42  static const size_t kDefaultLargeMethodThreshold = 600;
43  static const size_t kDefaultSmallMethodThreshold = 60;
44  static const size_t kDefaultTinyMethodThreshold = 20;
45  static const size_t kDefaultNumDexMethodsThreshold = 900;
46  static constexpr double kDefaultTopKProfileThreshold = 90.0;
47  static const bool kDefaultGenerateDebugInfo = false;
48  static const bool kDefaultGenerateMiniDebugInfo = false;
49  static const bool kDefaultIncludePatchInformation = false;
50  static const size_t kDefaultInlineDepthLimit = 3;
51  static const size_t kDefaultInlineMaxCodeUnits = 32;
52  static constexpr size_t kUnsetInlineDepthLimit = -1;
53  static constexpr size_t kUnsetInlineMaxCodeUnits = -1;
54
55  // Default inlining settings when the space filter is used.
56  static constexpr size_t kSpaceFilterInlineDepthLimit = 3;
57  static constexpr size_t kSpaceFilterInlineMaxCodeUnits = 10;
58
59  CompilerOptions();
60  ~CompilerOptions();
61
62  CompilerOptions(CompilerFilter::Filter compiler_filter,
63                  size_t huge_method_threshold,
64                  size_t large_method_threshold,
65                  size_t small_method_threshold,
66                  size_t tiny_method_threshold,
67                  size_t num_dex_methods_threshold,
68                  size_t inline_depth_limit,
69                  size_t inline_max_code_units,
70                  const std::vector<const DexFile*>* no_inline_from,
71                  bool include_patch_information,
72                  double top_k_profile_threshold,
73                  bool debuggable,
74                  bool generate_debug_info,
75                  bool implicit_null_checks,
76                  bool implicit_so_checks,
77                  bool implicit_suspend_checks,
78                  bool compile_pic,
79                  const std::vector<std::string>* verbose_methods,
80                  std::ostream* init_failure_output,
81                  bool abort_on_hard_verifier_failure,
82                  const std::string& dump_cfg_file_name,
83                  bool dump_cfg_append,
84                  bool force_determinism,
85                  RegisterAllocator::Strategy regalloc_strategy,
86                  const std::vector<std::string>* passes_to_run);
87
88  CompilerFilter::Filter GetCompilerFilter() const {
89    return compiler_filter_;
90  }
91
92  void SetCompilerFilter(CompilerFilter::Filter compiler_filter) {
93    compiler_filter_ = compiler_filter;
94  }
95
96  bool VerifyAtRuntime() const {
97    return compiler_filter_ == CompilerFilter::kVerifyAtRuntime;
98  }
99
100  bool IsBytecodeCompilationEnabled() const {
101    return CompilerFilter::IsBytecodeCompilationEnabled(compiler_filter_);
102  }
103
104  bool IsJniCompilationEnabled() const {
105    return CompilerFilter::IsJniCompilationEnabled(compiler_filter_);
106  }
107
108  bool IsVerificationEnabled() const {
109    return CompilerFilter::IsVerificationEnabled(compiler_filter_);
110  }
111
112  bool NeverVerify() const {
113    return compiler_filter_ == CompilerFilter::kVerifyNone;
114  }
115
116  bool VerifyOnlyProfile() const {
117    return compiler_filter_ == CompilerFilter::kVerifyProfile;
118  }
119
120  size_t GetHugeMethodThreshold() const {
121    return huge_method_threshold_;
122  }
123
124  size_t GetLargeMethodThreshold() const {
125    return large_method_threshold_;
126  }
127
128  size_t GetSmallMethodThreshold() const {
129    return small_method_threshold_;
130  }
131
132  size_t GetTinyMethodThreshold() const {
133    return tiny_method_threshold_;
134  }
135
136  bool IsHugeMethod(size_t num_dalvik_instructions) const {
137    return num_dalvik_instructions > huge_method_threshold_;
138  }
139
140  bool IsLargeMethod(size_t num_dalvik_instructions) const {
141    return num_dalvik_instructions > large_method_threshold_;
142  }
143
144  bool IsSmallMethod(size_t num_dalvik_instructions) const {
145    return num_dalvik_instructions > small_method_threshold_;
146  }
147
148  bool IsTinyMethod(size_t num_dalvik_instructions) const {
149    return num_dalvik_instructions > tiny_method_threshold_;
150  }
151
152  size_t GetNumDexMethodsThreshold() const {
153    return num_dex_methods_threshold_;
154  }
155
156  size_t GetInlineDepthLimit() const {
157    return inline_depth_limit_;
158  }
159  void SetInlineDepthLimit(size_t limit) {
160    inline_depth_limit_ = limit;
161  }
162
163  size_t GetInlineMaxCodeUnits() const {
164    return inline_max_code_units_;
165  }
166  void SetInlineMaxCodeUnits(size_t units) {
167    inline_max_code_units_ = units;
168  }
169
170  double GetTopKProfileThreshold() const {
171    return top_k_profile_threshold_;
172  }
173
174  bool GetDebuggable() const {
175    return debuggable_;
176  }
177
178  bool GetNativeDebuggable() const {
179    return GetDebuggable() && GetGenerateDebugInfo();
180  }
181
182  // This flag controls whether the compiler collects debugging information.
183  // The other flags control how the information is written to disk.
184  bool GenerateAnyDebugInfo() const {
185    return GetGenerateDebugInfo() || GetGenerateMiniDebugInfo();
186  }
187
188  bool GetGenerateDebugInfo() const {
189    return generate_debug_info_;
190  }
191
192  bool GetGenerateMiniDebugInfo() const {
193    return generate_mini_debug_info_;
194  }
195
196  bool GetGenerateBuildId() const {
197    return generate_build_id_;
198  }
199
200  bool GetImplicitNullChecks() const {
201    return implicit_null_checks_;
202  }
203
204  bool GetImplicitStackOverflowChecks() const {
205    return implicit_so_checks_;
206  }
207
208  bool GetImplicitSuspendChecks() const {
209    return implicit_suspend_checks_;
210  }
211
212  bool GetIncludePatchInformation() const {
213    return include_patch_information_;
214  }
215
216  bool IsBootImage() const {
217    return boot_image_;
218  }
219
220  bool IsAppImage() const {
221    return app_image_;
222  }
223
224  // Should the code be compiled as position independent?
225  bool GetCompilePic() const {
226    return compile_pic_;
227  }
228
229  bool HasVerboseMethods() const {
230    return verbose_methods_ != nullptr && !verbose_methods_->empty();
231  }
232
233  bool IsVerboseMethod(const std::string& pretty_method) const {
234    for (const std::string& cur_method : *verbose_methods_) {
235      if (pretty_method.find(cur_method) != std::string::npos) {
236        return true;
237      }
238    }
239    return false;
240  }
241
242  std::ostream* GetInitFailureOutput() const {
243    return init_failure_output_.get();
244  }
245
246  bool AbortOnHardVerifierFailure() const {
247    return abort_on_hard_verifier_failure_;
248  }
249
250  const std::vector<const DexFile*>* GetNoInlineFromDexFile() const {
251    return no_inline_from_;
252  }
253
254  bool ParseCompilerOption(const StringPiece& option, UsageFn Usage);
255
256  const std::string& GetDumpCfgFileName() const {
257    return dump_cfg_file_name_;
258  }
259
260  bool GetDumpCfgAppend() const {
261    return dump_cfg_append_;
262  }
263
264  bool IsForceDeterminism() const {
265    return force_determinism_;
266  }
267
268  RegisterAllocator::Strategy GetRegisterAllocationStrategy() const {
269    return register_allocation_strategy_;
270  }
271
272  const std::vector<std::string>* GetPassesToRun() const {
273    return passes_to_run_;
274  }
275
276 private:
277  void ParseDumpInitFailures(const StringPiece& option, UsageFn Usage);
278  void ParseDumpCfgPasses(const StringPiece& option, UsageFn Usage);
279  void ParseInlineMaxCodeUnits(const StringPiece& option, UsageFn Usage);
280  void ParseInlineDepthLimit(const StringPiece& option, UsageFn Usage);
281  void ParseNumDexMethods(const StringPiece& option, UsageFn Usage);
282  void ParseTinyMethodMax(const StringPiece& option, UsageFn Usage);
283  void ParseSmallMethodMax(const StringPiece& option, UsageFn Usage);
284  void ParseLargeMethodMax(const StringPiece& option, UsageFn Usage);
285  void ParseHugeMethodMax(const StringPiece& option, UsageFn Usage);
286  void ParseRegisterAllocationStrategy(const StringPiece& option, UsageFn Usage);
287
288  CompilerFilter::Filter compiler_filter_;
289  size_t huge_method_threshold_;
290  size_t large_method_threshold_;
291  size_t small_method_threshold_;
292  size_t tiny_method_threshold_;
293  size_t num_dex_methods_threshold_;
294  size_t inline_depth_limit_;
295  size_t inline_max_code_units_;
296
297  // Dex files from which we should not inline code.
298  // This is usually a very short list (i.e. a single dex file), so we
299  // prefer vector<> over a lookup-oriented container, such as set<>.
300  const std::vector<const DexFile*>* no_inline_from_;
301
302  bool boot_image_;
303  bool app_image_;
304  bool include_patch_information_;
305  // When using a profile file only the top K% of the profiled samples will be compiled.
306  double top_k_profile_threshold_;
307  bool debuggable_;
308  bool generate_debug_info_;
309  bool generate_mini_debug_info_;
310  bool generate_build_id_;
311  bool implicit_null_checks_;
312  bool implicit_so_checks_;
313  bool implicit_suspend_checks_;
314  bool compile_pic_;
315
316  // Vector of methods to have verbose output enabled for.
317  const std::vector<std::string>* verbose_methods_;
318
319  // Abort compilation with an error if we find a class that fails verification with a hard
320  // failure.
321  bool abort_on_hard_verifier_failure_;
322
323  // Log initialization of initialization failures to this stream if not null.
324  std::unique_ptr<std::ostream> init_failure_output_;
325
326  std::string dump_cfg_file_name_;
327  bool dump_cfg_append_;
328
329  // Whether the compiler should trade performance for determinism to guarantee exactly reproducible
330  // outcomes.
331  bool force_determinism_;
332
333  RegisterAllocator::Strategy register_allocation_strategy_;
334
335  // If not null, specifies optimization passes which will be run instead of defaults.
336  // Note that passes_to_run_ is not checked for correctness and providing an incorrect
337  // list of passes can lead to unexpected compiler behaviour. This is caused by dependencies
338  // between passes. Failing to satisfy them can for example lead to compiler crashes.
339  // Passing pass names which are not recognized by the compiler will result in
340  // compiler-dependant behavior.
341  const std::vector<std::string>* passes_to_run_;
342
343  friend class Dex2Oat;
344  friend class CommonCompilerTest;
345  friend class verifier::VerifierDepsTest;
346
347  DISALLOW_COPY_AND_ASSIGN(CompilerOptions);
348};
349
350}  // namespace art
351
352#endif  // ART_COMPILER_DRIVER_COMPILER_OPTIONS_H_
353