blob: 49768ded46fcb5bbecf54025f587a94d0009cc53 [file] [log] [blame]
Andreas Gampe53c913b2014-08-12 23:19:23 -07001/*
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#include "quick_compiler.h"
18
19#include <cstdint>
20
Mathieu Chartiere401d142015-04-22 13:56:20 -070021#include "art_method-inl.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080022#include "base/dumpable.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080023#include "base/logging.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080024#include "base/macros.h"
25#include "base/timing_logger.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070026#include "compiler.h"
Elliott Hughes956af0f2014-12-11 14:34:28 -080027#include "dex_file-inl.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080028#include "dex_file_to_method_inliner_map.h"
Andreas Gampe0b9203e2015-01-22 20:39:27 -080029#include "dex/compiler_ir.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080030#include "dex/dex_flags.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070031#include "dex/mir_graph.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080032#include "dex/pass_driver_me_opts.h"
Mathieu Chartier5bdab122015-01-26 18:30:19 -080033#include "dex/pass_driver_me_post_opt.h"
34#include "dex/pass_manager.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070035#include "dex/quick/mir_to_lir.h"
Nicolas Geoffray4824c272015-06-24 15:53:03 +010036#include "dex/verified_method.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070037#include "driver/compiler_driver.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080038#include "driver/compiler_options.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070039#include "elf_writer_quick.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070040#include "experimental_flags.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070041#include "jni/quick/jni_compiler.h"
Andreas Gampe9c462082015-01-27 14:31:40 -080042#include "mir_to_lir.h"
Andreas Gampe0e92f4f2015-01-26 17:37:27 -080043#include "mirror/object.h"
44#include "runtime.h"
Andreas Gampe53c913b2014-08-12 23:19:23 -070045
46// Specific compiler backends.
Alex Light50fa9932015-08-10 15:30:07 -070047#ifdef ART_ENABLE_CODEGEN_arm
Andreas Gampe53c913b2014-08-12 23:19:23 -070048#include "dex/quick/arm/backend_arm.h"
Alex Light50fa9932015-08-10 15:30:07 -070049#endif
50
51#ifdef ART_ENABLE_CODEGEN_arm64
Andreas Gampe53c913b2014-08-12 23:19:23 -070052#include "dex/quick/arm64/backend_arm64.h"
Alex Light50fa9932015-08-10 15:30:07 -070053#endif
54
55#if defined(ART_ENABLE_CODEGEN_mips) || defined(ART_ENABLE_CODEGEN_mips64)
Andreas Gampe53c913b2014-08-12 23:19:23 -070056#include "dex/quick/mips/backend_mips.h"
Alex Light50fa9932015-08-10 15:30:07 -070057#endif
58
59#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
Andreas Gampe53c913b2014-08-12 23:19:23 -070060#include "dex/quick/x86/backend_x86.h"
Alex Light50fa9932015-08-10 15:30:07 -070061#endif
Andreas Gampe53c913b2014-08-12 23:19:23 -070062
63namespace art {
64
Andreas Gampe785d2f22014-11-03 22:57:30 -080065static_assert(0U == static_cast<size_t>(kNone), "kNone not 0");
66static_assert(1U == static_cast<size_t>(kArm), "kArm not 1");
67static_assert(2U == static_cast<size_t>(kArm64), "kArm64 not 2");
68static_assert(3U == static_cast<size_t>(kThumb2), "kThumb2 not 3");
69static_assert(4U == static_cast<size_t>(kX86), "kX86 not 4");
70static_assert(5U == static_cast<size_t>(kX86_64), "kX86_64 not 5");
71static_assert(6U == static_cast<size_t>(kMips), "kMips not 6");
72static_assert(7U == static_cast<size_t>(kMips64), "kMips64 not 7");
Andreas Gampe53c913b2014-08-12 23:19:23 -070073
74// Additional disabled optimizations (over generally disabled) per instruction set.
75static constexpr uint32_t kDisabledOptimizationsPerISA[] = {
76 // 0 = kNone.
77 ~0U,
78 // 1 = kArm, unused (will use kThumb2).
79 ~0U,
80 // 2 = kArm64.
81 0,
82 // 3 = kThumb2.
83 0,
84 // 4 = kX86.
85 (1 << kLoadStoreElimination) |
86 0,
87 // 5 = kX86_64.
88 (1 << kLoadStoreElimination) |
89 0,
90 // 6 = kMips.
91 (1 << kLoadStoreElimination) |
92 (1 << kLoadHoisting) |
93 (1 << kSuppressLoads) |
94 (1 << kNullCheckElimination) |
95 (1 << kPromoteRegs) |
96 (1 << kTrackLiveTemps) |
97 (1 << kSafeOptimizations) |
98 (1 << kBBOpt) |
99 (1 << kMatch) |
100 (1 << kPromoteCompilerTemps) |
101 0,
102 // 7 = kMips64.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100103 (1 << kLoadStoreElimination) |
104 (1 << kLoadHoisting) |
105 (1 << kSuppressLoads) |
106 (1 << kNullCheckElimination) |
107 (1 << kPromoteRegs) |
108 (1 << kTrackLiveTemps) |
109 (1 << kSafeOptimizations) |
110 (1 << kBBOpt) |
111 (1 << kMatch) |
112 (1 << kPromoteCompilerTemps) |
113 0
Andreas Gampe53c913b2014-08-12 23:19:23 -0700114};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800115static_assert(sizeof(kDisabledOptimizationsPerISA) == 8 * sizeof(uint32_t),
116 "kDisabledOpts unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700117
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700118// Supported shorty types per instruction set. null means that all are available.
Andreas Gampe53c913b2014-08-12 23:19:23 -0700119// Z : boolean
120// B : byte
121// S : short
122// C : char
123// I : int
124// J : long
125// F : float
126// D : double
127// L : reference(object, array)
128// V : void
129static const char* kSupportedTypes[] = {
130 // 0 = kNone.
131 "",
132 // 1 = kArm, unused (will use kThumb2).
133 "",
134 // 2 = kArm64.
135 nullptr,
136 // 3 = kThumb2.
137 nullptr,
138 // 4 = kX86.
139 nullptr,
140 // 5 = kX86_64.
141 nullptr,
142 // 6 = kMips.
143 nullptr,
144 // 7 = kMips64.
Maja Gagic6ea651f2015-02-24 16:55:04 +0100145 nullptr
Andreas Gampe53c913b2014-08-12 23:19:23 -0700146};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800147static_assert(sizeof(kSupportedTypes) == 8 * sizeof(char*), "kSupportedTypes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700148
149static int kAllOpcodes[] = {
150 Instruction::NOP,
151 Instruction::MOVE,
152 Instruction::MOVE_FROM16,
153 Instruction::MOVE_16,
154 Instruction::MOVE_WIDE,
155 Instruction::MOVE_WIDE_FROM16,
156 Instruction::MOVE_WIDE_16,
157 Instruction::MOVE_OBJECT,
158 Instruction::MOVE_OBJECT_FROM16,
159 Instruction::MOVE_OBJECT_16,
160 Instruction::MOVE_RESULT,
161 Instruction::MOVE_RESULT_WIDE,
162 Instruction::MOVE_RESULT_OBJECT,
163 Instruction::MOVE_EXCEPTION,
164 Instruction::RETURN_VOID,
165 Instruction::RETURN,
166 Instruction::RETURN_WIDE,
167 Instruction::RETURN_OBJECT,
168 Instruction::CONST_4,
169 Instruction::CONST_16,
170 Instruction::CONST,
171 Instruction::CONST_HIGH16,
172 Instruction::CONST_WIDE_16,
173 Instruction::CONST_WIDE_32,
174 Instruction::CONST_WIDE,
175 Instruction::CONST_WIDE_HIGH16,
176 Instruction::CONST_STRING,
177 Instruction::CONST_STRING_JUMBO,
178 Instruction::CONST_CLASS,
179 Instruction::MONITOR_ENTER,
180 Instruction::MONITOR_EXIT,
181 Instruction::CHECK_CAST,
182 Instruction::INSTANCE_OF,
183 Instruction::ARRAY_LENGTH,
184 Instruction::NEW_INSTANCE,
185 Instruction::NEW_ARRAY,
186 Instruction::FILLED_NEW_ARRAY,
187 Instruction::FILLED_NEW_ARRAY_RANGE,
188 Instruction::FILL_ARRAY_DATA,
189 Instruction::THROW,
190 Instruction::GOTO,
191 Instruction::GOTO_16,
192 Instruction::GOTO_32,
193 Instruction::PACKED_SWITCH,
194 Instruction::SPARSE_SWITCH,
195 Instruction::CMPL_FLOAT,
196 Instruction::CMPG_FLOAT,
197 Instruction::CMPL_DOUBLE,
198 Instruction::CMPG_DOUBLE,
199 Instruction::CMP_LONG,
200 Instruction::IF_EQ,
201 Instruction::IF_NE,
202 Instruction::IF_LT,
203 Instruction::IF_GE,
204 Instruction::IF_GT,
205 Instruction::IF_LE,
206 Instruction::IF_EQZ,
207 Instruction::IF_NEZ,
208 Instruction::IF_LTZ,
209 Instruction::IF_GEZ,
210 Instruction::IF_GTZ,
211 Instruction::IF_LEZ,
212 Instruction::UNUSED_3E,
213 Instruction::UNUSED_3F,
214 Instruction::UNUSED_40,
215 Instruction::UNUSED_41,
216 Instruction::UNUSED_42,
217 Instruction::UNUSED_43,
218 Instruction::AGET,
219 Instruction::AGET_WIDE,
220 Instruction::AGET_OBJECT,
221 Instruction::AGET_BOOLEAN,
222 Instruction::AGET_BYTE,
223 Instruction::AGET_CHAR,
224 Instruction::AGET_SHORT,
225 Instruction::APUT,
226 Instruction::APUT_WIDE,
227 Instruction::APUT_OBJECT,
228 Instruction::APUT_BOOLEAN,
229 Instruction::APUT_BYTE,
230 Instruction::APUT_CHAR,
231 Instruction::APUT_SHORT,
232 Instruction::IGET,
233 Instruction::IGET_WIDE,
234 Instruction::IGET_OBJECT,
235 Instruction::IGET_BOOLEAN,
236 Instruction::IGET_BYTE,
237 Instruction::IGET_CHAR,
238 Instruction::IGET_SHORT,
239 Instruction::IPUT,
240 Instruction::IPUT_WIDE,
241 Instruction::IPUT_OBJECT,
242 Instruction::IPUT_BOOLEAN,
243 Instruction::IPUT_BYTE,
244 Instruction::IPUT_CHAR,
245 Instruction::IPUT_SHORT,
246 Instruction::SGET,
247 Instruction::SGET_WIDE,
248 Instruction::SGET_OBJECT,
249 Instruction::SGET_BOOLEAN,
250 Instruction::SGET_BYTE,
251 Instruction::SGET_CHAR,
252 Instruction::SGET_SHORT,
253 Instruction::SPUT,
254 Instruction::SPUT_WIDE,
255 Instruction::SPUT_OBJECT,
256 Instruction::SPUT_BOOLEAN,
257 Instruction::SPUT_BYTE,
258 Instruction::SPUT_CHAR,
259 Instruction::SPUT_SHORT,
260 Instruction::INVOKE_VIRTUAL,
261 Instruction::INVOKE_SUPER,
262 Instruction::INVOKE_DIRECT,
263 Instruction::INVOKE_STATIC,
264 Instruction::INVOKE_INTERFACE,
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700265 Instruction::RETURN_VOID_NO_BARRIER,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700266 Instruction::INVOKE_VIRTUAL_RANGE,
267 Instruction::INVOKE_SUPER_RANGE,
268 Instruction::INVOKE_DIRECT_RANGE,
269 Instruction::INVOKE_STATIC_RANGE,
270 Instruction::INVOKE_INTERFACE_RANGE,
271 Instruction::UNUSED_79,
272 Instruction::UNUSED_7A,
273 Instruction::NEG_INT,
274 Instruction::NOT_INT,
275 Instruction::NEG_LONG,
276 Instruction::NOT_LONG,
277 Instruction::NEG_FLOAT,
278 Instruction::NEG_DOUBLE,
279 Instruction::INT_TO_LONG,
280 Instruction::INT_TO_FLOAT,
281 Instruction::INT_TO_DOUBLE,
282 Instruction::LONG_TO_INT,
283 Instruction::LONG_TO_FLOAT,
284 Instruction::LONG_TO_DOUBLE,
285 Instruction::FLOAT_TO_INT,
286 Instruction::FLOAT_TO_LONG,
287 Instruction::FLOAT_TO_DOUBLE,
288 Instruction::DOUBLE_TO_INT,
289 Instruction::DOUBLE_TO_LONG,
290 Instruction::DOUBLE_TO_FLOAT,
291 Instruction::INT_TO_BYTE,
292 Instruction::INT_TO_CHAR,
293 Instruction::INT_TO_SHORT,
294 Instruction::ADD_INT,
295 Instruction::SUB_INT,
296 Instruction::MUL_INT,
297 Instruction::DIV_INT,
298 Instruction::REM_INT,
299 Instruction::AND_INT,
300 Instruction::OR_INT,
301 Instruction::XOR_INT,
302 Instruction::SHL_INT,
303 Instruction::SHR_INT,
304 Instruction::USHR_INT,
305 Instruction::ADD_LONG,
306 Instruction::SUB_LONG,
307 Instruction::MUL_LONG,
308 Instruction::DIV_LONG,
309 Instruction::REM_LONG,
310 Instruction::AND_LONG,
311 Instruction::OR_LONG,
312 Instruction::XOR_LONG,
313 Instruction::SHL_LONG,
314 Instruction::SHR_LONG,
315 Instruction::USHR_LONG,
316 Instruction::ADD_FLOAT,
317 Instruction::SUB_FLOAT,
318 Instruction::MUL_FLOAT,
319 Instruction::DIV_FLOAT,
320 Instruction::REM_FLOAT,
321 Instruction::ADD_DOUBLE,
322 Instruction::SUB_DOUBLE,
323 Instruction::MUL_DOUBLE,
324 Instruction::DIV_DOUBLE,
325 Instruction::REM_DOUBLE,
326 Instruction::ADD_INT_2ADDR,
327 Instruction::SUB_INT_2ADDR,
328 Instruction::MUL_INT_2ADDR,
329 Instruction::DIV_INT_2ADDR,
330 Instruction::REM_INT_2ADDR,
331 Instruction::AND_INT_2ADDR,
332 Instruction::OR_INT_2ADDR,
333 Instruction::XOR_INT_2ADDR,
334 Instruction::SHL_INT_2ADDR,
335 Instruction::SHR_INT_2ADDR,
336 Instruction::USHR_INT_2ADDR,
337 Instruction::ADD_LONG_2ADDR,
338 Instruction::SUB_LONG_2ADDR,
339 Instruction::MUL_LONG_2ADDR,
340 Instruction::DIV_LONG_2ADDR,
341 Instruction::REM_LONG_2ADDR,
342 Instruction::AND_LONG_2ADDR,
343 Instruction::OR_LONG_2ADDR,
344 Instruction::XOR_LONG_2ADDR,
345 Instruction::SHL_LONG_2ADDR,
346 Instruction::SHR_LONG_2ADDR,
347 Instruction::USHR_LONG_2ADDR,
348 Instruction::ADD_FLOAT_2ADDR,
349 Instruction::SUB_FLOAT_2ADDR,
350 Instruction::MUL_FLOAT_2ADDR,
351 Instruction::DIV_FLOAT_2ADDR,
352 Instruction::REM_FLOAT_2ADDR,
353 Instruction::ADD_DOUBLE_2ADDR,
354 Instruction::SUB_DOUBLE_2ADDR,
355 Instruction::MUL_DOUBLE_2ADDR,
356 Instruction::DIV_DOUBLE_2ADDR,
357 Instruction::REM_DOUBLE_2ADDR,
358 Instruction::ADD_INT_LIT16,
359 Instruction::RSUB_INT,
360 Instruction::MUL_INT_LIT16,
361 Instruction::DIV_INT_LIT16,
362 Instruction::REM_INT_LIT16,
363 Instruction::AND_INT_LIT16,
364 Instruction::OR_INT_LIT16,
365 Instruction::XOR_INT_LIT16,
366 Instruction::ADD_INT_LIT8,
367 Instruction::RSUB_INT_LIT8,
368 Instruction::MUL_INT_LIT8,
369 Instruction::DIV_INT_LIT8,
370 Instruction::REM_INT_LIT8,
371 Instruction::AND_INT_LIT8,
372 Instruction::OR_INT_LIT8,
373 Instruction::XOR_INT_LIT8,
374 Instruction::SHL_INT_LIT8,
375 Instruction::SHR_INT_LIT8,
376 Instruction::USHR_INT_LIT8,
377 Instruction::IGET_QUICK,
378 Instruction::IGET_WIDE_QUICK,
379 Instruction::IGET_OBJECT_QUICK,
380 Instruction::IPUT_QUICK,
381 Instruction::IPUT_WIDE_QUICK,
382 Instruction::IPUT_OBJECT_QUICK,
383 Instruction::INVOKE_VIRTUAL_QUICK,
384 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
Fred Shih37f05ef2014-07-16 18:38:08 -0700385 Instruction::IPUT_BOOLEAN_QUICK,
386 Instruction::IPUT_BYTE_QUICK,
387 Instruction::IPUT_CHAR_QUICK,
388 Instruction::IPUT_SHORT_QUICK,
Mathieu Chartierffc605c2014-12-10 10:35:44 -0800389 Instruction::IGET_BOOLEAN_QUICK,
390 Instruction::IGET_BYTE_QUICK,
391 Instruction::IGET_CHAR_QUICK,
392 Instruction::IGET_SHORT_QUICK,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700393 Instruction::INVOKE_LAMBDA,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700394 Instruction::UNUSED_F4,
Igor Murashkin6918bf12015-09-27 19:19:06 -0700395 Instruction::CAPTURE_VARIABLE,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700396 Instruction::CREATE_LAMBDA,
Igor Murashkin6918bf12015-09-27 19:19:06 -0700397 Instruction::LIBERATE_VARIABLE,
Igor Murashkin2ee54e22015-06-18 10:05:11 -0700398 Instruction::BOX_LAMBDA,
399 Instruction::UNBOX_LAMBDA,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700400 Instruction::UNUSED_FA,
401 Instruction::UNUSED_FB,
402 Instruction::UNUSED_FC,
403 Instruction::UNUSED_FD,
404 Instruction::UNUSED_FE,
405 Instruction::UNUSED_FF,
406 // ----- ExtendedMIROpcode -----
407 kMirOpPhi,
408 kMirOpCopy,
409 kMirOpFusedCmplFloat,
410 kMirOpFusedCmpgFloat,
411 kMirOpFusedCmplDouble,
412 kMirOpFusedCmpgDouble,
413 kMirOpFusedCmpLong,
414 kMirOpNop,
415 kMirOpNullCheck,
416 kMirOpRangeCheck,
417 kMirOpDivZeroCheck,
418 kMirOpCheck,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700419 kMirOpSelect,
420};
421
Zheng Xu5667fdb2014-10-23 18:29:55 +0800422static int kInvokeOpcodes[] = {
423 Instruction::INVOKE_VIRTUAL,
424 Instruction::INVOKE_SUPER,
425 Instruction::INVOKE_DIRECT,
426 Instruction::INVOKE_STATIC,
427 Instruction::INVOKE_INTERFACE,
428 Instruction::INVOKE_VIRTUAL_RANGE,
429 Instruction::INVOKE_SUPER_RANGE,
430 Instruction::INVOKE_DIRECT_RANGE,
431 Instruction::INVOKE_STATIC_RANGE,
432 Instruction::INVOKE_INTERFACE_RANGE,
433 Instruction::INVOKE_VIRTUAL_QUICK,
434 Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
435};
436
Igor Murashkin158f35c2015-06-10 15:55:30 -0700437// TODO: Add support for lambda opcodes to the quick compiler.
438static const int kUnsupportedLambdaOpcodes[] = {
439 Instruction::INVOKE_LAMBDA,
440 Instruction::CREATE_LAMBDA,
Igor Murashkin2ee54e22015-06-18 10:05:11 -0700441 Instruction::BOX_LAMBDA,
442 Instruction::UNBOX_LAMBDA,
Igor Murashkin158f35c2015-06-10 15:55:30 -0700443};
444
445// Unsupported opcodes. Null can be used when everything is supported. Size of the lists is
Andreas Gampe53c913b2014-08-12 23:19:23 -0700446// recorded below.
447static const int* kUnsupportedOpcodes[] = {
448 // 0 = kNone.
449 kAllOpcodes,
450 // 1 = kArm, unused (will use kThumb2).
451 kAllOpcodes,
452 // 2 = kArm64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700453 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700454 // 3 = kThumb2.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700455 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700456 // 4 = kX86.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700457 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700458 // 5 = kX86_64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700459 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700460 // 6 = kMips.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700461 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700462 // 7 = kMips64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700463 kUnsupportedLambdaOpcodes,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700464};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800465static_assert(sizeof(kUnsupportedOpcodes) == 8 * sizeof(int*), "kUnsupportedOpcodes unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700466
467// Size of the arrays stored above.
468static const size_t kUnsupportedOpcodesSize[] = {
469 // 0 = kNone.
470 arraysize(kAllOpcodes),
471 // 1 = kArm, unused (will use kThumb2).
472 arraysize(kAllOpcodes),
473 // 2 = kArm64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700474 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700475 // 3 = kThumb2.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700476 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700477 // 4 = kX86.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700478 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700479 // 5 = kX86_64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700480 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700481 // 6 = kMips.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700482 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700483 // 7 = kMips64.
Igor Murashkin158f35c2015-06-10 15:55:30 -0700484 arraysize(kUnsupportedLambdaOpcodes),
Andreas Gampe53c913b2014-08-12 23:19:23 -0700485};
Andreas Gampe785d2f22014-11-03 22:57:30 -0800486static_assert(sizeof(kUnsupportedOpcodesSize) == 8 * sizeof(size_t),
487 "kUnsupportedOpcodesSize unexpected");
Andreas Gampe53c913b2014-08-12 23:19:23 -0700488
489// The maximum amount of Dalvik register in a method for which we will start compiling. Tries to
490// avoid an abort when we need to manage more SSA registers than we can.
491static constexpr size_t kMaxAllowedDalvikRegisters = INT16_MAX / 2;
492
493static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) {
494 const char* supported_types = kSupportedTypes[instruction_set];
495 if (supported_types == nullptr) {
496 // Everything available.
497 return true;
498 }
499
500 uint32_t shorty_size = strlen(shorty);
501 CHECK_GE(shorty_size, 1u);
502
503 for (uint32_t i = 0; i < shorty_size; i++) {
504 if (strchr(supported_types, shorty[i]) == nullptr) {
505 return false;
506 }
507 }
508 return true;
Andreas Gampec8ccf682014-09-29 20:07:43 -0700509}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700510
Alex Light705ad492015-09-21 11:36:30 -0700511bool QuickCompiler::CanCompileInstruction(const MIR* mir,
Nicolas Geoffray98e6ce42016-02-16 18:42:15 +0000512 const DexFile& dex_file,
513 CompilationUnit* cu) const {
Alex Light705ad492015-09-21 11:36:30 -0700514 switch (mir->dalvikInsn.opcode) {
515 // Quick compiler won't support new instruction semantics to invoke-super into an interface
516 // method
517 case Instruction::INVOKE_SUPER: // Fall-through
518 case Instruction::INVOKE_SUPER_RANGE: {
519 DCHECK(mir->dalvikInsn.IsInvoke());
520 uint32_t invoke_method_idx = mir->dalvikInsn.vB;
521 const DexFile::MethodId& method_id = dex_file.GetMethodId(invoke_method_idx);
522 const DexFile::ClassDef* class_def = dex_file.FindClassDef(method_id.class_idx_);
523 // False if we are an interface i.e. !(java_access_flags & kAccInterface)
524 return class_def != nullptr && ((class_def->GetJavaAccessFlags() & kAccInterface) == 0);
525 }
Nicolas Geoffray98e6ce42016-02-16 18:42:15 +0000526 case Instruction::NEW_INSTANCE: {
527 uint32_t type_idx = mir->dalvikInsn.vB;
528 if (cu->compiler_driver->IsStringTypeIndex(type_idx, cu->dex_file)) {
529 return false;
530 }
531 return true;
532 }
Alex Light705ad492015-09-21 11:36:30 -0700533 default:
534 return true;
535 }
536}
537
Andreas Gampe53c913b2014-08-12 23:19:23 -0700538// Skip the method that we do not support currently.
Alex Light705ad492015-09-21 11:36:30 -0700539bool QuickCompiler::CanCompileMethod(uint32_t method_idx,
540 const DexFile& dex_file,
Andreas Gampe53c913b2014-08-12 23:19:23 -0700541 CompilationUnit* cu) const {
542 // This is a limitation in mir_graph. See MirGraph::SetNumSSARegs.
Razvan A Lupusoru8d0d03e2014-06-06 17:04:52 -0700543 if (cu->mir_graph->GetNumOfCodeAndTempVRs() > kMaxAllowedDalvikRegisters) {
544 VLOG(compiler) << "Too many dalvik registers : " << cu->mir_graph->GetNumOfCodeAndTempVRs();
Andreas Gampe53c913b2014-08-12 23:19:23 -0700545 return false;
546 }
547
Neil Fuller9724c632016-01-07 15:42:47 +0000548 // Since the quick compiler doesn't (and never will) support default methods we always need to
549 // scan opcodes.
Andreas Gampe53c913b2014-08-12 23:19:23 -0700550
551 // Check if we can compile the prototype.
552 const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
553 if (!CanCompileShorty(shorty, cu->instruction_set)) {
554 VLOG(compiler) << "Unsupported shorty : " << shorty;
555 return false;
556 }
557
558 const int *unsupport_list = kUnsupportedOpcodes[cu->instruction_set];
559 int unsupport_list_size = kUnsupportedOpcodesSize[cu->instruction_set];
560
561 for (unsigned int idx = 0; idx < cu->mir_graph->GetNumBlocks(); idx++) {
562 BasicBlock* bb = cu->mir_graph->GetBasicBlock(idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700563 if (bb == nullptr) continue;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700564 if (bb->block_type == kDead) continue;
565 for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
566 int opcode = mir->dalvikInsn.opcode;
567 // Check if we support the byte code.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800568 if (std::find(unsupport_list, unsupport_list + unsupport_list_size, opcode)
569 != unsupport_list + unsupport_list_size) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700570 if (!MIR::DecodedInstruction::IsPseudoMirOp(opcode)) {
571 VLOG(compiler) << "Unsupported dalvik byte code : "
572 << mir->dalvikInsn.opcode;
573 } else {
574 VLOG(compiler) << "Unsupported extended MIR opcode : "
575 << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst];
576 }
577 return false;
Nicolas Geoffray98e6ce42016-02-16 18:42:15 +0000578 } else if (!CanCompileInstruction(mir, dex_file, cu)) {
Alex Light705ad492015-09-21 11:36:30 -0700579 VLOG(compiler) << "Cannot compile dalvik opcode : " << mir->dalvikInsn.opcode;
580 return false;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700581 }
582 // Check if it invokes a prototype that we cannot support.
Zheng Xu5667fdb2014-10-23 18:29:55 +0800583 if (std::find(kInvokeOpcodes, kInvokeOpcodes + arraysize(kInvokeOpcodes), opcode)
584 != kInvokeOpcodes + arraysize(kInvokeOpcodes)) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700585 uint32_t invoke_method_idx = mir->dalvikInsn.vB;
586 const char* invoke_method_shorty = dex_file.GetMethodShorty(
587 dex_file.GetMethodId(invoke_method_idx));
588 if (!CanCompileShorty(invoke_method_shorty, cu->instruction_set)) {
589 VLOG(compiler) << "Unsupported to invoke '"
590 << PrettyMethod(invoke_method_idx, dex_file)
591 << "' with shorty : " << invoke_method_shorty;
592 return false;
593 }
594 }
595 }
596 }
597 return true;
598}
599
600void QuickCompiler::InitCompilationUnit(CompilationUnit& cu) const {
601 // Disable optimizations according to instruction set.
602 cu.disable_opt |= kDisabledOptimizationsPerISA[cu.instruction_set];
Mathieu Chartiere5f13e52015-02-24 09:37:21 -0800603 if (Runtime::Current()->UseJit()) {
604 // Disable these optimizations for JIT until quickened byte codes are done being implemented.
605 // TODO: Find a cleaner way to do this.
606 cu.disable_opt |= 1u << kLocalValueNumbering;
607 }
Andreas Gampe53c913b2014-08-12 23:19:23 -0700608}
609
David Brazdilee690a32014-12-01 17:04:16 +0000610void QuickCompiler::Init() {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700611 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
612}
613
614void QuickCompiler::UnInit() const {
615 CHECK(GetCompilerDriver()->GetCompilerContext() == nullptr);
616}
617
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800618/* Default optimizer/debug setting for the compiler. */
619static uint32_t kCompilerOptimizerDisableFlags = 0 | // Disable specific optimizations
620 // (1 << kLoadStoreElimination) |
621 // (1 << kLoadHoisting) |
622 // (1 << kSuppressLoads) |
623 // (1 << kNullCheckElimination) |
624 // (1 << kClassInitCheckElimination) |
625 // (1 << kGlobalValueNumbering) |
Vladimir Markoa5e69e82015-04-24 19:03:51 +0100626 // (1 << kGvnDeadCodeElimination) |
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800627 // (1 << kLocalValueNumbering) |
628 // (1 << kPromoteRegs) |
629 // (1 << kTrackLiveTemps) |
630 // (1 << kSafeOptimizations) |
631 // (1 << kBBOpt) |
632 // (1 << kSuspendCheckElimination) |
633 // (1 << kMatch) |
634 // (1 << kPromoteCompilerTemps) |
635 // (1 << kSuppressExceptionEdges) |
636 // (1 << kSuppressMethodInlining) |
637 0;
638
639static uint32_t kCompilerDebugFlags = 0 | // Enable debug/testing modes
640 // (1 << kDebugDisplayMissingTargets) |
641 // (1 << kDebugVerbose) |
642 // (1 << kDebugDumpCFG) |
643 // (1 << kDebugSlowFieldPath) |
644 // (1 << kDebugSlowInvokePath) |
645 // (1 << kDebugSlowStringPath) |
646 // (1 << kDebugSlowestFieldPath) |
647 // (1 << kDebugSlowestStringPath) |
648 // (1 << kDebugExerciseResolveMethod) |
649 // (1 << kDebugVerifyDataflow) |
650 // (1 << kDebugShowMemoryUsage) |
651 // (1 << kDebugShowNops) |
652 // (1 << kDebugCountOpcodes) |
653 // (1 << kDebugDumpCheckStats) |
654 // (1 << kDebugShowSummaryMemoryUsage) |
655 // (1 << kDebugShowFilterStats) |
656 // (1 << kDebugTimings) |
657 // (1 << kDebugCodegenDump) |
658 0;
659
Andreas Gampe53c913b2014-08-12 23:19:23 -0700660CompiledMethod* QuickCompiler::Compile(const DexFile::CodeItem* code_item,
661 uint32_t access_flags,
662 InvokeType invoke_type,
663 uint16_t class_def_idx,
664 uint32_t method_idx,
665 jobject class_loader,
Mathieu Chartier736b5602015-09-02 14:54:11 -0700666 const DexFile& dex_file,
667 Handle<mirror::DexCache> dex_cache) const {
Roland Levillain4d027112015-07-01 15:41:14 +0100668 if (kPoisonHeapReferences) {
669 VLOG(compiler) << "Skipping method : " << PrettyMethod(method_idx, dex_file)
670 << " Reason = Quick does not support heap poisoning.";
671 return nullptr;
672 }
673
Roland Levillain0d5a2812015-11-13 10:07:31 +0000674 if (kEmitCompilerReadBarrier) {
675 VLOG(compiler) << "Skipping method : " << PrettyMethod(method_idx, dex_file)
676 << " Reason = Quick does not support read barrier.";
677 return nullptr;
678 }
679
Andreas Gampe53c913b2014-08-12 23:19:23 -0700680 // TODO: check method fingerprint here to determine appropriate backend type. Until then, use
681 // build default.
682 CompilerDriver* driver = GetCompilerDriver();
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800683
684 VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
685 if (Compiler::IsPathologicalCase(*code_item, method_idx, dex_file)) {
686 return nullptr;
687 }
688
689 DCHECK(driver->GetCompilerOptions().IsCompilationEnabled());
Andreas Gampe0760a812015-08-26 17:12:51 -0700690 DCHECK(!driver->GetVerifiedMethod(&dex_file, method_idx)->HasRuntimeThrow());
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800691
Mathieu Chartier9b34b242015-03-09 11:30:17 -0700692 Runtime* const runtime = Runtime::Current();
693 ClassLinker* const class_linker = runtime->GetClassLinker();
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800694 InstructionSet instruction_set = driver->GetInstructionSet();
695 if (instruction_set == kArm) {
696 instruction_set = kThumb2;
697 }
Mathieu Chartier9b34b242015-03-09 11:30:17 -0700698 CompilationUnit cu(runtime->GetArenaPool(), instruction_set, driver, class_linker);
Vladimir Marko20f85592015-03-19 10:07:02 +0000699 cu.dex_file = &dex_file;
700 cu.class_def_idx = class_def_idx;
701 cu.method_idx = method_idx;
702 cu.access_flags = access_flags;
703 cu.invoke_type = invoke_type;
704 cu.shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800705
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800706 CHECK((cu.instruction_set == kThumb2) ||
707 (cu.instruction_set == kArm64) ||
708 (cu.instruction_set == kX86) ||
709 (cu.instruction_set == kX86_64) ||
Maja Gagic6ea651f2015-02-24 16:55:04 +0100710 (cu.instruction_set == kMips) ||
711 (cu.instruction_set == kMips64));
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800712
713 // TODO: set this from command line
714 constexpr bool compiler_flip_match = false;
715 const std::string compiler_method_match = "";
716
717 bool use_match = !compiler_method_match.empty();
718 bool match = use_match && (compiler_flip_match ^
719 (PrettyMethod(method_idx, dex_file).find(compiler_method_match) != std::string::npos));
720 if (!use_match || match) {
721 cu.disable_opt = kCompilerOptimizerDisableFlags;
722 cu.enable_debug = kCompilerDebugFlags;
723 cu.verbose = VLOG_IS_ON(compiler) ||
724 (cu.enable_debug & (1 << kDebugVerbose));
725 }
726
727 if (driver->GetCompilerOptions().HasVerboseMethods()) {
728 cu.verbose = driver->GetCompilerOptions().IsVerboseMethod(PrettyMethod(method_idx, dex_file));
729 }
730
731 if (cu.verbose) {
732 cu.enable_debug |= (1 << kDebugCodegenDump);
733 }
734
735 /*
736 * TODO: rework handling of optimization and debug flags. Should we split out
737 * MIR and backend flags? Need command-line setting as well.
738 */
739
740 InitCompilationUnit(cu);
741
742 cu.StartTimingSplit("BuildMIRGraph");
743 cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena));
744
745 /*
746 * After creation of the MIR graph, also create the code generator.
747 * The reason we do this is that optimizations on the MIR graph may need to get information
748 * that is only available if a CG exists.
749 */
750 cu.cg.reset(GetCodeGenerator(&cu, nullptr));
751
752 /* Gathering opcode stats? */
753 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
754 cu.mir_graph->EnableOpcodeCounting();
755 }
756
757 /* Build the raw MIR graph */
758 cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
Mathieu Chartier736b5602015-09-02 14:54:11 -0700759 class_loader, dex_file, dex_cache);
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800760
761 if (!CanCompileMethod(method_idx, dex_file, &cu)) {
762 VLOG(compiler) << cu.instruction_set << ": Cannot compile method : "
763 << PrettyMethod(method_idx, dex_file);
764 cu.EndTiming();
765 return nullptr;
766 }
767
768 cu.NewTimingSplit("MIROpt:CheckFilters");
769 std::string skip_message;
770 if (cu.mir_graph->SkipCompilation(&skip_message)) {
771 VLOG(compiler) << cu.instruction_set << ": Skipping method : "
772 << PrettyMethod(method_idx, dex_file) << " Reason = " << skip_message;
773 cu.EndTiming();
774 return nullptr;
775 }
776
777 /* Create the pass driver and launch it */
Nicolas Geoffray216eaa22015-03-17 17:09:30 +0000778 PassDriverMEOpts pass_driver(GetPreOptPassManager(), GetPostOptPassManager(), &cu);
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800779 pass_driver.Launch();
780
Andreas Gampe0e92f4f2015-01-26 17:37:27 -0800781 if (cu.enable_debug & (1 << kDebugDumpCheckStats)) {
782 cu.mir_graph->DumpCheckStats();
783 }
784
785 if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
786 cu.mir_graph->ShowOpcodeStats();
787 }
788
789 /* Reassociate sreg names with original Dalvik vreg names. */
790 cu.mir_graph->RemapRegLocations();
791
792 /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
793 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
794 if (cu.arena_stack.PeakBytesAllocated() > 1 * 1024 * 1024) {
795 MemStats stack_stats(cu.arena_stack.GetPeakStats());
796 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats);
797 }
798 }
799 cu.arena_stack.Reset();
800
801 CompiledMethod* result = nullptr;
802
803 if (cu.mir_graph->PuntToInterpreter()) {
804 VLOG(compiler) << cu.instruction_set << ": Punted method to interpreter: "
805 << PrettyMethod(method_idx, dex_file);
806 cu.EndTiming();
807 return nullptr;
808 }
809
810 cu.cg->Materialize();
811
812 cu.NewTimingSplit("Dedupe"); /* deduping takes up the vast majority of time in GetCompiledMethod(). */
813 result = cu.cg->GetCompiledMethod();
814 cu.NewTimingSplit("Cleanup");
815
816 if (result) {
817 VLOG(compiler) << cu.instruction_set << ": Compiled " << PrettyMethod(method_idx, dex_file);
818 } else {
819 VLOG(compiler) << cu.instruction_set << ": Deferred " << PrettyMethod(method_idx, dex_file);
820 }
821
822 if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
823 if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) {
824 MemStats mem_stats(cu.arena.GetMemStats());
825 LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
826 }
827 }
828
829 if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) {
830 LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks()
831 << " " << PrettyMethod(method_idx, dex_file);
832 }
833
834 cu.EndTiming();
835 driver->GetTimingsLogger()->AddLogger(cu.timings);
836 return result;
Andreas Gampe53c913b2014-08-12 23:19:23 -0700837}
838
839CompiledMethod* QuickCompiler::JniCompile(uint32_t access_flags,
840 uint32_t method_idx,
841 const DexFile& dex_file) const {
842 return ArtQuickJniCompileMethod(GetCompilerDriver(), access_flags, method_idx, dex_file);
843}
844
Mathieu Chartiere401d142015-04-22 13:56:20 -0700845uintptr_t QuickCompiler::GetEntryPointOf(ArtMethod* method) const {
Mathieu Chartier130914e2014-11-18 15:34:09 -0800846 return reinterpret_cast<uintptr_t>(method->GetEntryPointFromQuickCompiledCodePtrSize(
847 InstructionSetPointerSize(GetCompilerDriver()->GetInstructionSet())));
Andreas Gampe53c913b2014-08-12 23:19:23 -0700848}
849
Roland Levillain4b8f1ec2015-08-26 18:34:03 +0100850Mir2Lir* QuickCompiler::GetCodeGenerator(CompilationUnit* cu,
851 void* compilation_unit ATTRIBUTE_UNUSED) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700852 Mir2Lir* mir_to_lir = nullptr;
853 switch (cu->instruction_set) {
Alex Light50fa9932015-08-10 15:30:07 -0700854#ifdef ART_ENABLE_CODEGEN_arm
Andreas Gampe53c913b2014-08-12 23:19:23 -0700855 case kThumb2:
856 mir_to_lir = ArmCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
857 break;
Alex Light50fa9932015-08-10 15:30:07 -0700858#endif // ART_ENABLE_CODEGEN_arm
859#ifdef ART_ENABLE_CODEGEN_arm64
Andreas Gampe53c913b2014-08-12 23:19:23 -0700860 case kArm64:
861 mir_to_lir = Arm64CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
862 break;
Alex Light50fa9932015-08-10 15:30:07 -0700863#endif // ART_ENABLE_CODEGEN_arm64
864#if defined(ART_ENABLE_CODEGEN_mips) || defined(ART_ENABLE_CODEGEN_mips64)
865 // Intentional 2 level ifdef. Want to fail on mips64 if it is not enabled, even if mips is
866 // and vice versa.
867#ifdef ART_ENABLE_CODEGEN_mips
Andreas Gampe53c913b2014-08-12 23:19:23 -0700868 case kMips:
Goran Jakovljevic10957932015-03-24 18:42:56 +0100869 // Fall-through.
Alex Light50fa9932015-08-10 15:30:07 -0700870#endif // ART_ENABLE_CODEGEN_mips
871#ifdef ART_ENABLE_CODEGEN_mips64
Maja Gagic6ea651f2015-02-24 16:55:04 +0100872 case kMips64:
Alex Light50fa9932015-08-10 15:30:07 -0700873#endif // ART_ENABLE_CODEGEN_mips64
Goran Jakovljevic10957932015-03-24 18:42:56 +0100874 mir_to_lir = MipsCodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
Maja Gagic6ea651f2015-02-24 16:55:04 +0100875 break;
Alex Light50fa9932015-08-10 15:30:07 -0700876#endif // ART_ENABLE_CODEGEN_mips || ART_ENABLE_CODEGEN_mips64
877#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
878 // Intentional 2 level ifdef. Want to fail on x86_64 if it is not enabled, even if x86 is
879 // and vice versa.
880#ifdef ART_ENABLE_CODEGEN_x86
Andreas Gampe53c913b2014-08-12 23:19:23 -0700881 case kX86:
882 // Fall-through.
Alex Light50fa9932015-08-10 15:30:07 -0700883#endif // ART_ENABLE_CODEGEN_x86
884#ifdef ART_ENABLE_CODEGEN_x86_64
Andreas Gampe53c913b2014-08-12 23:19:23 -0700885 case kX86_64:
Alex Light50fa9932015-08-10 15:30:07 -0700886#endif // ART_ENABLE_CODEGEN_x86_64
Andreas Gampe53c913b2014-08-12 23:19:23 -0700887 mir_to_lir = X86CodeGenerator(cu, cu->mir_graph.get(), &cu->arena);
888 break;
Alex Light50fa9932015-08-10 15:30:07 -0700889#endif // ART_ENABLE_CODEGEN_x86 || ART_ENABLE_CODEGEN_x86_64
Andreas Gampe53c913b2014-08-12 23:19:23 -0700890 default:
891 LOG(FATAL) << "Unexpected instruction set: " << cu->instruction_set;
892 }
893
894 /* The number of compiler temporaries depends on backend so set it up now if possible */
895 if (mir_to_lir) {
896 size_t max_temps = mir_to_lir->GetMaxPossibleCompilerTemps();
897 bool set_max = cu->mir_graph->SetMaxAvailableNonSpecialCompilerTemps(max_temps);
898 CHECK(set_max);
899 }
900 return mir_to_lir;
901}
902
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800903QuickCompiler::QuickCompiler(CompilerDriver* driver) : Compiler(driver, 100) {
904 const auto& compiler_options = driver->GetCompilerOptions();
905 auto* pass_manager_options = compiler_options.GetPassManagerOptions();
906 pre_opt_pass_manager_.reset(new PassManager(*pass_manager_options));
907 CHECK(pre_opt_pass_manager_.get() != nullptr);
908 PassDriverMEOpts::SetupPasses(pre_opt_pass_manager_.get());
909 pre_opt_pass_manager_->CreateDefaultPassList();
910 if (pass_manager_options->GetPrintPassOptions()) {
911 PassDriverMEOpts::PrintPassOptions(pre_opt_pass_manager_.get());
912 }
913 // TODO: Different options for pre vs post opts?
914 post_opt_pass_manager_.reset(new PassManager(PassManagerOptions()));
915 CHECK(post_opt_pass_manager_.get() != nullptr);
916 PassDriverMEPostOpt::SetupPasses(post_opt_pass_manager_.get());
917 post_opt_pass_manager_->CreateDefaultPassList();
918 if (pass_manager_options->GetPrintPassOptions()) {
919 PassDriverMEPostOpt::PrintPassOptions(post_opt_pass_manager_.get());
920 }
921}
922
923QuickCompiler::~QuickCompiler() {
924}
Andreas Gampe53c913b2014-08-12 23:19:23 -0700925
926Compiler* CreateQuickCompiler(CompilerDriver* driver) {
Mathieu Chartier5bdab122015-01-26 18:30:19 -0800927 return QuickCompiler::Create(driver);
928}
929
930Compiler* QuickCompiler::Create(CompilerDriver* driver) {
Andreas Gampe53c913b2014-08-12 23:19:23 -0700931 return new QuickCompiler(driver);
932}
933
934} // namespace art