frontend.cc revision 4439596b00c91f565370bf0813cc2f9165093693
1/*
2 * Copyright (C) 2011 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 "compiler.h"
18#include "compiler_internals.h"
19#include "driver/compiler_driver.h"
20#include "driver/compiler_options.h"
21#include "dataflow_iterator-inl.h"
22#include "leb128.h"
23#include "mirror/object.h"
24#include "pass_driver_me_opts.h"
25#include "runtime.h"
26#include "base/logging.h"
27#include "base/timing_logger.h"
28#include "driver/compiler_options.h"
29#include "dex/quick/dex_file_to_method_inliner_map.h"
30
31namespace art {
32
33extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver* driver) {
34  CHECK(driver->GetCompilerContext() == nullptr);
35}
36
37extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver* driver) {
38  CHECK(driver->GetCompilerContext() == nullptr);
39}
40
41/* Default optimizer/debug setting for the compiler. */
42static uint32_t kCompilerOptimizerDisableFlags = 0 |  // Disable specific optimizations
43  (1 << kLoadStoreElimination) |  // TODO: this pass has been broken for awhile - fix or delete.
44  // (1 << kLoadHoisting) |
45  // (1 << kSuppressLoads) |
46  // (1 << kNullCheckElimination) |
47  // (1 << kClassInitCheckElimination) |
48  // (1 << kPromoteRegs) |
49  // (1 << kTrackLiveTemps) |
50  // (1 << kSafeOptimizations) |
51  // (1 << kBBOpt) |
52  // (1 << kMatch) |
53  // (1 << kPromoteCompilerTemps) |
54  // (1 << kSuppressExceptionEdges) |
55  // (1 << kSuppressMethodInlining) |
56  0;
57
58static uint32_t kCompilerDebugFlags = 0 |     // Enable debug/testing modes
59  // (1 << kDebugDisplayMissingTargets) |
60  // (1 << kDebugVerbose) |
61  // (1 << kDebugDumpCFG) |
62  // (1 << kDebugSlowFieldPath) |
63  // (1 << kDebugSlowInvokePath) |
64  // (1 << kDebugSlowStringPath) |
65  // (1 << kDebugSlowestFieldPath) |
66  // (1 << kDebugSlowestStringPath) |
67  // (1 << kDebugExerciseResolveMethod) |
68  // (1 << kDebugVerifyDataflow) |
69  // (1 << kDebugShowMemoryUsage) |
70  // (1 << kDebugShowNops) |
71  // (1 << kDebugCountOpcodes) |
72  // (1 << kDebugDumpCheckStats) |
73  // (1 << kDebugDumpBitcodeFile) |
74  // (1 << kDebugVerifyBitcode) |
75  // (1 << kDebugShowSummaryMemoryUsage) |
76  // (1 << kDebugShowFilterStats) |
77  // (1 << kDebugTimings) |
78  // (1 << kDebugCodegenDump) |
79  0;
80
81CompilationUnit::CompilationUnit(ArenaPool* pool)
82  : compiler_driver(nullptr),
83    class_linker(nullptr),
84    dex_file(nullptr),
85    class_loader(nullptr),
86    class_def_idx(0),
87    method_idx(0),
88    code_item(nullptr),
89    access_flags(0),
90    invoke_type(kDirect),
91    shorty(nullptr),
92    disable_opt(0),
93    enable_debug(0),
94    verbose(false),
95    compiler(nullptr),
96    instruction_set(kNone),
97    target64(false),
98    num_dalvik_registers(0),
99    insns(nullptr),
100    num_ins(0),
101    num_outs(0),
102    num_regs(0),
103    compiler_flip_match(false),
104    arena(pool),
105    arena_stack(pool),
106    mir_graph(nullptr),
107    cg(nullptr),
108    timings("QuickCompiler", true, false),
109    print_pass(false) {
110}
111
112CompilationUnit::~CompilationUnit() {
113}
114
115void CompilationUnit::StartTimingSplit(const char* label) {
116  if (compiler_driver->GetDumpPasses()) {
117    timings.StartSplit(label);
118  }
119}
120
121void CompilationUnit::NewTimingSplit(const char* label) {
122  if (compiler_driver->GetDumpPasses()) {
123    timings.NewSplit(label);
124  }
125}
126
127void CompilationUnit::EndTiming() {
128  if (compiler_driver->GetDumpPasses()) {
129    timings.EndSplit();
130    if (enable_debug & (1 << kDebugTimings)) {
131      LOG(INFO) << "TIMINGS " << PrettyMethod(method_idx, *dex_file);
132      LOG(INFO) << Dumpable<TimingLogger>(timings);
133    }
134  }
135}
136
137// Enable opcodes that mostly work, but produce assertion errors (thus breaking libartd.so).
138#define ARM64_USE_EXPERIMENTAL_OPCODES 0
139
140// TODO: Remove this when we are able to compile everything.
141int arm64_support_list[] = {
142    Instruction::NOP,
143    Instruction::MOVE,
144    Instruction::MOVE_FROM16,
145    Instruction::MOVE_16,
146    Instruction::MOVE_WIDE,
147    Instruction::MOVE_WIDE_FROM16,
148    Instruction::MOVE_WIDE_16,
149    Instruction::MOVE_OBJECT,
150    Instruction::MOVE_OBJECT_FROM16,
151    Instruction::MOVE_OBJECT_16,
152    Instruction::MOVE_EXCEPTION,
153    Instruction::RETURN_VOID,
154    Instruction::RETURN,
155    Instruction::RETURN_WIDE,
156    Instruction::RETURN_OBJECT,
157    Instruction::CONST_4,
158    Instruction::CONST_16,
159    Instruction::CONST,
160    Instruction::CONST_HIGH16,
161    Instruction::CONST_WIDE_16,
162    Instruction::CONST_WIDE_32,
163    Instruction::CONST_WIDE,
164    Instruction::CONST_WIDE_HIGH16,
165    Instruction::CONST_STRING,
166    Instruction::MONITOR_ENTER,
167    Instruction::MONITOR_EXIT,
168    Instruction::THROW,
169    Instruction::GOTO,
170    Instruction::GOTO_16,
171    Instruction::GOTO_32,
172    Instruction::PACKED_SWITCH,
173    Instruction::SPARSE_SWITCH,
174    Instruction::CMPL_FLOAT,
175    Instruction::CMPG_FLOAT,
176    Instruction::CMPL_DOUBLE,
177    Instruction::CMPG_DOUBLE,
178    Instruction::CMP_LONG,
179    Instruction::IF_EQ,
180    Instruction::IF_NE,
181    Instruction::IF_LT,
182    Instruction::IF_GE,
183    Instruction::IF_GT,
184    Instruction::IF_LE,
185    Instruction::IF_EQZ,
186    Instruction::IF_NEZ,
187    Instruction::IF_LTZ,
188    Instruction::IF_GEZ,
189    Instruction::IF_GTZ,
190    Instruction::IF_LEZ,
191    Instruction::NEG_INT,
192    Instruction::NOT_INT,
193    Instruction::NEG_FLOAT,
194    Instruction::INT_TO_BYTE,
195    Instruction::INT_TO_CHAR,
196    Instruction::INT_TO_SHORT,
197    Instruction::ADD_INT,
198    Instruction::SUB_INT,
199    Instruction::MUL_INT,
200    Instruction::DIV_INT,
201    Instruction::REM_INT,
202    Instruction::AND_INT,
203    Instruction::OR_INT,
204    Instruction::XOR_INT,
205    Instruction::SHL_INT,
206    Instruction::SHR_INT,
207    Instruction::USHR_INT,
208    Instruction::ADD_FLOAT,
209    Instruction::SUB_FLOAT,
210    Instruction::MUL_FLOAT,
211    Instruction::DIV_FLOAT,
212    Instruction::ADD_INT_2ADDR,
213    Instruction::SUB_INT_2ADDR,
214    Instruction::MUL_INT_2ADDR,
215    Instruction::DIV_INT_2ADDR,
216    Instruction::REM_INT_2ADDR,
217    Instruction::AND_INT_2ADDR,
218    Instruction::OR_INT_2ADDR,
219    Instruction::XOR_INT_2ADDR,
220    Instruction::SHL_INT_2ADDR,
221    Instruction::SHR_INT_2ADDR,
222    Instruction::USHR_INT_2ADDR,
223    Instruction::ADD_FLOAT_2ADDR,
224    Instruction::SUB_FLOAT_2ADDR,
225    Instruction::MUL_FLOAT_2ADDR,
226    Instruction::DIV_FLOAT_2ADDR,
227    Instruction::ADD_INT_LIT16,
228    Instruction::RSUB_INT,
229    Instruction::MUL_INT_LIT16,
230    Instruction::DIV_INT_LIT16,
231    Instruction::REM_INT_LIT16,
232    Instruction::AND_INT_LIT16,
233    Instruction::OR_INT_LIT16,
234    Instruction::XOR_INT_LIT16,
235    Instruction::ADD_INT_LIT8,
236    Instruction::RSUB_INT_LIT8,
237    Instruction::MUL_INT_LIT8,
238    Instruction::DIV_INT_LIT8,
239    Instruction::REM_INT_LIT8,
240    Instruction::AND_INT_LIT8,
241    Instruction::OR_INT_LIT8,
242    Instruction::XOR_INT_LIT8,
243    Instruction::SHL_INT_LIT8,
244    Instruction::SHR_INT_LIT8,
245    Instruction::USHR_INT_LIT8,
246    Instruction::SGET,
247    Instruction::SGET_BOOLEAN,
248    Instruction::SGET_BYTE,
249    Instruction::SGET_CHAR,
250    Instruction::SGET_SHORT,
251    Instruction::SGET_OBJECT,
252    Instruction::SPUT,
253    Instruction::SPUT_OBJECT,
254    Instruction::SPUT_BOOLEAN,
255    Instruction::SPUT_BYTE,
256    Instruction::SPUT_CHAR,
257    Instruction::SPUT_SHORT,
258    Instruction::CMPL_FLOAT,
259    Instruction::CMPG_FLOAT,
260    Instruction::IGET,
261    Instruction::IGET_OBJECT,
262    Instruction::IGET_BOOLEAN,
263    Instruction::IGET_BYTE,
264    Instruction::IGET_CHAR,
265    Instruction::IGET_SHORT,
266    Instruction::IPUT,
267    Instruction::IPUT_OBJECT,
268    Instruction::IPUT_BOOLEAN,
269    Instruction::IPUT_BYTE,
270    Instruction::IPUT_CHAR,
271    Instruction::IPUT_SHORT,
272    Instruction::NEG_LONG,
273    Instruction::NOT_LONG,
274    Instruction::NEG_DOUBLE,
275    Instruction::INT_TO_LONG,
276    Instruction::INT_TO_FLOAT,
277    Instruction::INT_TO_DOUBLE,
278    Instruction::LONG_TO_INT,
279    Instruction::LONG_TO_FLOAT,
280    Instruction::LONG_TO_DOUBLE,
281    Instruction::FLOAT_TO_INT,
282    Instruction::FLOAT_TO_LONG,
283    Instruction::FLOAT_TO_DOUBLE,
284    Instruction::DOUBLE_TO_INT,
285    Instruction::DOUBLE_TO_LONG,
286    Instruction::DOUBLE_TO_FLOAT,
287    Instruction::ADD_LONG,
288    Instruction::SUB_LONG,
289    Instruction::MUL_LONG,
290    Instruction::DIV_LONG,
291    Instruction::REM_LONG,
292    Instruction::AND_LONG,
293    Instruction::OR_LONG,
294    Instruction::XOR_LONG,
295    Instruction::SHL_LONG,
296    Instruction::SHR_LONG,
297    Instruction::USHR_LONG,
298    Instruction::REM_FLOAT,
299    Instruction::ADD_DOUBLE,
300    Instruction::SUB_DOUBLE,
301    Instruction::MUL_DOUBLE,
302    Instruction::DIV_DOUBLE,
303    Instruction::REM_DOUBLE,
304    Instruction::ADD_LONG_2ADDR,
305    Instruction::SUB_LONG_2ADDR,
306    Instruction::MUL_LONG_2ADDR,
307    Instruction::DIV_LONG_2ADDR,
308    Instruction::REM_LONG_2ADDR,
309    Instruction::AND_LONG_2ADDR,
310    Instruction::OR_LONG_2ADDR,
311    Instruction::XOR_LONG_2ADDR,
312    Instruction::SHL_LONG_2ADDR,
313    Instruction::SHR_LONG_2ADDR,
314    Instruction::USHR_LONG_2ADDR,
315    Instruction::REM_FLOAT_2ADDR,
316    Instruction::ADD_DOUBLE_2ADDR,
317    Instruction::SUB_DOUBLE_2ADDR,
318    Instruction::MUL_DOUBLE_2ADDR,
319    Instruction::DIV_DOUBLE_2ADDR,
320    Instruction::REM_DOUBLE_2ADDR,
321    // TODO(Arm64): Enable compiler pass
322    // ----- ExtendedMIROpcode -----
323    kMirOpPhi,
324    kMirOpCopy,
325    kMirOpFusedCmplFloat,
326    kMirOpFusedCmpgFloat,
327    kMirOpFusedCmplDouble,
328    kMirOpFusedCmpgDouble,
329    kMirOpFusedCmpLong,
330    kMirOpNop,
331    kMirOpNullCheck,
332    kMirOpRangeCheck,
333    kMirOpDivZeroCheck,
334    kMirOpCheck,
335    kMirOpCheckPart2,
336    kMirOpSelect,
337
338#if ARM64_USE_EXPERIMENTAL_OPCODES
339    // Instruction::MOVE_RESULT,
340    // Instruction::MOVE_RESULT_WIDE,
341    // Instruction::MOVE_RESULT_OBJECT,
342    // Instruction::CONST_STRING_JUMBO,
343    // Instruction::CONST_CLASS,
344    // Instruction::CHECK_CAST,
345    // Instruction::INSTANCE_OF,
346    // Instruction::ARRAY_LENGTH,
347    // Instruction::NEW_INSTANCE,
348    // Instruction::NEW_ARRAY,
349    // Instruction::FILLED_NEW_ARRAY,
350    // Instruction::FILLED_NEW_ARRAY_RANGE,
351    // Instruction::FILL_ARRAY_DATA,
352    // Instruction::UNUSED_3E,
353    // Instruction::UNUSED_3F,
354    // Instruction::UNUSED_40,
355    // Instruction::UNUSED_41,
356    // Instruction::UNUSED_42,
357    // Instruction::UNUSED_43,
358    // Instruction::AGET,
359    // Instruction::AGET_WIDE,
360    // Instruction::AGET_OBJECT,
361    // Instruction::AGET_BOOLEAN,
362    // Instruction::AGET_BYTE,
363    // Instruction::AGET_CHAR,
364    // Instruction::AGET_SHORT,
365    // Instruction::APUT,
366    // Instruction::APUT_WIDE,
367    // Instruction::APUT_OBJECT,
368    // Instruction::APUT_BOOLEAN,
369    // Instruction::APUT_BYTE,
370    // Instruction::APUT_CHAR,
371    // Instruction::APUT_SHORT,
372    // Instruction::IPUT_WIDE,
373    // Instruction::IGET_WIDE,
374    // Instruction::SGET_WIDE,
375    // Instruction::SPUT_WIDE,
376    Instruction::INVOKE_VIRTUAL,
377    Instruction::INVOKE_SUPER,
378    Instruction::INVOKE_DIRECT,
379    Instruction::INVOKE_STATIC,
380    Instruction::INVOKE_INTERFACE,
381    // Instruction::RETURN_VOID_BARRIER,
382    // Instruction::INVOKE_VIRTUAL_RANGE,
383    // Instruction::INVOKE_SUPER_RANGE,
384    // Instruction::INVOKE_DIRECT_RANGE,
385    // Instruction::INVOKE_STATIC_RANGE,
386    // Instruction::INVOKE_INTERFACE_RANGE,
387    // Instruction::UNUSED_79,
388    // Instruction::UNUSED_7A,
389    // Instruction::IGET_QUICK,
390    // Instruction::IGET_WIDE_QUICK,
391    // Instruction::IGET_OBJECT_QUICK,
392    // Instruction::IPUT_QUICK,
393    // Instruction::IPUT_WIDE_QUICK,
394    // Instruction::IPUT_OBJECT_QUICK,
395    // Instruction::INVOKE_VIRTUAL_QUICK,
396    // Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
397    // Instruction::UNUSED_EB,
398    // Instruction::UNUSED_EC,
399    // Instruction::UNUSED_ED,
400    // Instruction::UNUSED_EE,
401    // Instruction::UNUSED_EF,
402    // Instruction::UNUSED_F0,
403    // Instruction::UNUSED_F1,
404    // Instruction::UNUSED_F2,
405    // Instruction::UNUSED_F3,
406    // Instruction::UNUSED_F4,
407    // Instruction::UNUSED_F5,
408    // Instruction::UNUSED_F6,
409    // Instruction::UNUSED_F7,
410    // Instruction::UNUSED_F8,
411    // Instruction::UNUSED_F9,
412    // Instruction::UNUSED_FA,
413    // Instruction::UNUSED_FB,
414    // Instruction::UNUSED_FC,
415    // Instruction::UNUSED_FD,
416    // Instruction::UNUSED_FE,
417    // Instruction::UNUSED_FF,
418#endif /* ARM64_USE_EXPERIMENTAL_OPCODES */
419};
420
421// TODO: Remove this when we are able to compile everything.
422int x86_64_support_list[] = {
423    Instruction::NOP,
424    // Instruction::MOVE,
425    // Instruction::MOVE_FROM16,
426    // Instruction::MOVE_16,
427    // Instruction::MOVE_WIDE,
428    // Instruction::MOVE_WIDE_FROM16,
429    // Instruction::MOVE_WIDE_16,
430    // Instruction::MOVE_OBJECT,
431    // Instruction::MOVE_OBJECT_FROM16,
432    // Instruction::MOVE_OBJECT_16,
433    // Instruction::MOVE_RESULT,
434    // Instruction::MOVE_RESULT_WIDE,
435    // Instruction::MOVE_RESULT_OBJECT,
436    // Instruction::MOVE_EXCEPTION,
437    Instruction::RETURN_VOID,
438    Instruction::RETURN,
439    // Instruction::RETURN_WIDE,
440    Instruction::RETURN_OBJECT,
441    // Instruction::CONST_4,
442    // Instruction::CONST_16,
443    // Instruction::CONST,
444    // Instruction::CONST_HIGH16,
445    // Instruction::CONST_WIDE_16,
446    // Instruction::CONST_WIDE_32,
447    // Instruction::CONST_WIDE,
448    // Instruction::CONST_WIDE_HIGH16,
449    // Instruction::CONST_STRING,
450    // Instruction::CONST_STRING_JUMBO,
451    // Instruction::CONST_CLASS,
452    // Instruction::MONITOR_ENTER,
453    // Instruction::MONITOR_EXIT,
454    // Instruction::CHECK_CAST,
455    // Instruction::INSTANCE_OF,
456    // Instruction::ARRAY_LENGTH,
457    // Instruction::NEW_INSTANCE,
458    // Instruction::NEW_ARRAY,
459    // Instruction::FILLED_NEW_ARRAY,
460    // Instruction::FILLED_NEW_ARRAY_RANGE,
461    // Instruction::FILL_ARRAY_DATA,
462    // Instruction::THROW,
463    // Instruction::GOTO,
464    // Instruction::GOTO_16,
465    // Instruction::GOTO_32,
466    // Instruction::PACKED_SWITCH,
467    // Instruction::SPARSE_SWITCH,
468    // Instruction::CMPL_FLOAT,
469    // Instruction::CMPG_FLOAT,
470    // Instruction::CMPL_DOUBLE,
471    // Instruction::CMPG_DOUBLE,
472    // Instruction::CMP_LONG,
473    // Instruction::IF_EQ,
474    // Instruction::IF_NE,
475    // Instruction::IF_LT,
476    // Instruction::IF_GE,
477    // Instruction::IF_GT,
478    // Instruction::IF_LE,
479    // Instruction::IF_EQZ,
480    // Instruction::IF_NEZ,
481    // Instruction::IF_LTZ,
482    // Instruction::IF_GEZ,
483    // Instruction::IF_GTZ,
484    // Instruction::IF_LEZ,
485    // Instruction::UNUSED_3E,
486    // Instruction::UNUSED_3F,
487    // Instruction::UNUSED_40,
488    // Instruction::UNUSED_41,
489    // Instruction::UNUSED_42,
490    // Instruction::UNUSED_43,
491    // Instruction::AGET,
492    // Instruction::AGET_WIDE,
493    // Instruction::AGET_OBJECT,
494    // Instruction::AGET_BOOLEAN,
495    // Instruction::AGET_BYTE,
496    // Instruction::AGET_CHAR,
497    // Instruction::AGET_SHORT,
498    // Instruction::APUT,
499    // Instruction::APUT_WIDE,
500    // Instruction::APUT_OBJECT,
501    // Instruction::APUT_BOOLEAN,
502    // Instruction::APUT_BYTE,
503    // Instruction::APUT_CHAR,
504    // Instruction::APUT_SHORT,
505    // Instruction::IGET,
506    // Instruction::IGET_WIDE,
507    // Instruction::IGET_OBJECT,
508    // Instruction::IGET_BOOLEAN,
509    // Instruction::IGET_BYTE,
510    // Instruction::IGET_CHAR,
511    // Instruction::IGET_SHORT,
512    // Instruction::IPUT,
513    // Instruction::IPUT_WIDE,
514    // Instruction::IPUT_OBJECT,
515    // Instruction::IPUT_BOOLEAN,
516    // Instruction::IPUT_BYTE,
517    // Instruction::IPUT_CHAR,
518    // Instruction::IPUT_SHORT,
519    Instruction::SGET,
520    // Instruction::SGET_WIDE,
521    Instruction::SGET_OBJECT,
522    Instruction::SGET_BOOLEAN,
523    Instruction::SGET_BYTE,
524    Instruction::SGET_CHAR,
525    Instruction::SGET_SHORT,
526    Instruction::SPUT,
527    // Instruction::SPUT_WIDE,
528    Instruction::SPUT_OBJECT,
529    Instruction::SPUT_BOOLEAN,
530    Instruction::SPUT_BYTE,
531    Instruction::SPUT_CHAR,
532    Instruction::SPUT_SHORT,
533    Instruction::INVOKE_VIRTUAL,
534    Instruction::INVOKE_SUPER,
535    Instruction::INVOKE_DIRECT,
536    Instruction::INVOKE_STATIC,
537    Instruction::INVOKE_INTERFACE,
538    // Instruction::RETURN_VOID_BARRIER,
539    // Instruction::INVOKE_VIRTUAL_RANGE,
540    // Instruction::INVOKE_SUPER_RANGE,
541    // Instruction::INVOKE_DIRECT_RANGE,
542    // Instruction::INVOKE_STATIC_RANGE,
543    // Instruction::INVOKE_INTERFACE_RANGE,
544    // Instruction::UNUSED_79,
545    // Instruction::UNUSED_7A,
546    // Instruction::NEG_INT,
547    // Instruction::NOT_INT,
548    // Instruction::NEG_LONG,
549    // Instruction::NOT_LONG,
550    // Instruction::NEG_FLOAT,
551    // Instruction::NEG_DOUBLE,
552    // Instruction::INT_TO_LONG,
553    // Instruction::INT_TO_FLOAT,
554    // Instruction::INT_TO_DOUBLE,
555    // Instruction::LONG_TO_INT,
556    // Instruction::LONG_TO_FLOAT,
557    // Instruction::LONG_TO_DOUBLE,
558    // Instruction::FLOAT_TO_INT,
559    // Instruction::FLOAT_TO_LONG,
560    // Instruction::FLOAT_TO_DOUBLE,
561    // Instruction::DOUBLE_TO_INT,
562    // Instruction::DOUBLE_TO_LONG,
563    // Instruction::DOUBLE_TO_FLOAT,
564    // Instruction::INT_TO_BYTE,
565    // Instruction::INT_TO_CHAR,
566    // Instruction::INT_TO_SHORT,
567    // Instruction::ADD_INT,
568    // Instruction::SUB_INT,
569    // Instruction::MUL_INT,
570    // Instruction::DIV_INT,
571    // Instruction::REM_INT,
572    // Instruction::AND_INT,
573    // Instruction::OR_INT,
574    // Instruction::XOR_INT,
575    // Instruction::SHL_INT,
576    // Instruction::SHR_INT,
577    // Instruction::USHR_INT,
578    // Instruction::ADD_LONG,
579    // Instruction::SUB_LONG,
580    // Instruction::MUL_LONG,
581    // Instruction::DIV_LONG,
582    // Instruction::REM_LONG,
583    // Instruction::AND_LONG,
584    // Instruction::OR_LONG,
585    // Instruction::XOR_LONG,
586    // Instruction::SHL_LONG,
587    // Instruction::SHR_LONG,
588    // Instruction::USHR_LONG,
589    // Instruction::ADD_FLOAT,
590    // Instruction::SUB_FLOAT,
591    // Instruction::MUL_FLOAT,
592    // Instruction::DIV_FLOAT,
593    // Instruction::REM_FLOAT,
594    // Instruction::ADD_DOUBLE,
595    // Instruction::SUB_DOUBLE,
596    // Instruction::MUL_DOUBLE,
597    // Instruction::DIV_DOUBLE,
598    // Instruction::REM_DOUBLE,
599    // Instruction::ADD_INT_2ADDR,
600    // Instruction::SUB_INT_2ADDR,
601    // Instruction::MUL_INT_2ADDR,
602    // Instruction::DIV_INT_2ADDR,
603    // Instruction::REM_INT_2ADDR,
604    // Instruction::AND_INT_2ADDR,
605    // Instruction::OR_INT_2ADDR,
606    // Instruction::XOR_INT_2ADDR,
607    // Instruction::SHL_INT_2ADDR,
608    // Instruction::SHR_INT_2ADDR,
609    // Instruction::USHR_INT_2ADDR,
610    // Instruction::ADD_LONG_2ADDR,
611    // Instruction::SUB_LONG_2ADDR,
612    // Instruction::MUL_LONG_2ADDR,
613    // Instruction::DIV_LONG_2ADDR,
614    // Instruction::REM_LONG_2ADDR,
615    // Instruction::AND_LONG_2ADDR,
616    // Instruction::OR_LONG_2ADDR,
617    // Instruction::XOR_LONG_2ADDR,
618    // Instruction::SHL_LONG_2ADDR,
619    // Instruction::SHR_LONG_2ADDR,
620    // Instruction::USHR_LONG_2ADDR,
621    // Instruction::ADD_FLOAT_2ADDR,
622    // Instruction::SUB_FLOAT_2ADDR,
623    // Instruction::MUL_FLOAT_2ADDR,
624    // Instruction::DIV_FLOAT_2ADDR,
625    // Instruction::REM_FLOAT_2ADDR,
626    // Instruction::ADD_DOUBLE_2ADDR,
627    // Instruction::SUB_DOUBLE_2ADDR,
628    // Instruction::MUL_DOUBLE_2ADDR,
629    // Instruction::DIV_DOUBLE_2ADDR,
630    // Instruction::REM_DOUBLE_2ADDR,
631    // Instruction::ADD_INT_LIT16,
632    // Instruction::RSUB_INT,
633    // Instruction::MUL_INT_LIT16,
634    // Instruction::DIV_INT_LIT16,
635    // Instruction::REM_INT_LIT16,
636    // Instruction::AND_INT_LIT16,
637    // Instruction::OR_INT_LIT16,
638    // Instruction::XOR_INT_LIT16,
639    // Instruction::ADD_INT_LIT8,
640    // Instruction::RSUB_INT_LIT8,
641    // Instruction::MUL_INT_LIT8,
642    // Instruction::DIV_INT_LIT8,
643    // Instruction::REM_INT_LIT8,
644    // Instruction::AND_INT_LIT8,
645    // Instruction::OR_INT_LIT8,
646    // Instruction::XOR_INT_LIT8,
647    // Instruction::SHL_INT_LIT8,
648    // Instruction::SHR_INT_LIT8,
649    // Instruction::USHR_INT_LIT8,
650    // Instruction::IGET_QUICK,
651    // Instruction::IGET_WIDE_QUICK,
652    // Instruction::IGET_OBJECT_QUICK,
653    // Instruction::IPUT_QUICK,
654    // Instruction::IPUT_WIDE_QUICK,
655    // Instruction::IPUT_OBJECT_QUICK,
656    // Instruction::INVOKE_VIRTUAL_QUICK,
657    // Instruction::INVOKE_VIRTUAL_RANGE_QUICK,
658    // Instruction::UNUSED_EB,
659    // Instruction::UNUSED_EC,
660    // Instruction::UNUSED_ED,
661    // Instruction::UNUSED_EE,
662    // Instruction::UNUSED_EF,
663    // Instruction::UNUSED_F0,
664    // Instruction::UNUSED_F1,
665    // Instruction::UNUSED_F2,
666    // Instruction::UNUSED_F3,
667    // Instruction::UNUSED_F4,
668    // Instruction::UNUSED_F5,
669    // Instruction::UNUSED_F6,
670    // Instruction::UNUSED_F7,
671    // Instruction::UNUSED_F8,
672    // Instruction::UNUSED_F9,
673    // Instruction::UNUSED_FA,
674    // Instruction::UNUSED_FB,
675    // Instruction::UNUSED_FC,
676    // Instruction::UNUSED_FD,
677    // Instruction::UNUSED_FE,
678    // Instruction::UNUSED_FF,
679
680    // ----- ExtendedMIROpcode -----
681    // kMirOpPhi,
682    // kMirOpCopy,
683    // kMirOpFusedCmplFloat,
684    // kMirOpFusedCmpgFloat,
685    // kMirOpFusedCmplDouble,
686    // kMirOpFusedCmpgDouble,
687    // kMirOpFusedCmpLong,
688    // kMirOpNop,
689    // kMirOpNullCheck,
690    // kMirOpRangeCheck,
691    // kMirOpDivZeroCheck,
692    // kMirOpCheck,
693    // kMirOpCheckPart2,
694    // kMirOpSelect,
695    // kMirOpLast,
696};
697
698// Z : boolean
699// B : byte
700// S : short
701// C : char
702// I : int
703// J : long
704// F : float
705// D : double
706// L : reference(object, array)
707// V : void
708// (ARM64) Current calling conversion only support 32bit softfp
709//         which has problems with long, float, double
710constexpr char arm64_supported_types[] = "ZBSCILVJFD";
711// (x84_64) We still have troubles with compiling longs/doubles/floats
712constexpr char x86_64_supported_types[] = "ZBSCILVJFD";
713
714// TODO: Remove this when we are able to compile everything.
715static bool CanCompileShorty(const char* shorty, InstructionSet instruction_set) {
716  uint32_t shorty_size = strlen(shorty);
717  CHECK_GE(shorty_size, 1u);
718  // Set a limitation on maximum number of parameters.
719  // Note : there is an implied "method*" parameter, and probably "this" as well.
720  // 1 is for the return type. Currently, we only accept 2 parameters at the most.
721  // (x86_64): For now we have the same limitation. But we might want to split this
722  //           check in future into two separate cases for arm64 and x86_64.
723  if ((shorty_size > (1 + 2)) && (instruction_set != kX86_64)) {
724    return false;
725  }
726
727  const char* supported_types = arm64_supported_types;
728  if (instruction_set == kX86_64) {
729    supported_types = x86_64_supported_types;
730  }
731  for (uint32_t i = 0; i < shorty_size; i++) {
732    if (strchr(supported_types, shorty[i]) == nullptr) {
733      return false;
734    }
735  }
736  return true;
737};
738
739// TODO: Remove this when we are able to compile everything.
740// Skip the method that we do not support currently.
741static bool CanCompileMethod(uint32_t method_idx, const DexFile& dex_file,
742                             CompilationUnit& cu) {
743  // There is some limitation with current ARM 64 backend.
744  if (cu.instruction_set == kArm64 || cu.instruction_set == kX86_64) {
745    // Check if we can compile the prototype.
746    const char* shorty = dex_file.GetMethodShorty(dex_file.GetMethodId(method_idx));
747    if (!CanCompileShorty(shorty, cu.instruction_set)) {
748      VLOG(compiler) << "Unsupported shorty : " << shorty;
749      return false;
750    }
751
752    const int *support_list = arm64_support_list;
753    int support_list_size = arraysize(arm64_support_list);
754    if (cu.instruction_set == kX86_64) {
755      support_list = x86_64_support_list;
756      support_list_size = arraysize(x86_64_support_list);
757    }
758
759    for (unsigned int idx = 0; idx < cu.mir_graph->GetNumBlocks(); idx++) {
760      BasicBlock* bb = cu.mir_graph->GetBasicBlock(idx);
761      if (bb == NULL) continue;
762      if (bb->block_type == kDead) continue;
763      for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) {
764        int opcode = mir->dalvikInsn.opcode;
765        // Check if we support the byte code.
766        if (std::find(support_list, support_list + support_list_size,
767            opcode) == support_list + support_list_size) {
768          if (!cu.mir_graph->IsPseudoMirOp(opcode)) {
769            VLOG(compiler) << "Unsupported dalvik byte code : "
770                           << mir->dalvikInsn.opcode;
771          } else {
772            VLOG(compiler) << "Unsupported extended MIR opcode : "
773                           << MIRGraph::extended_mir_op_names_[opcode - kMirOpFirst];
774          }
775          return false;
776        }
777        // Check if it invokes a prototype that we cannot support.
778        if (Instruction::INVOKE_VIRTUAL == opcode ||
779            Instruction::INVOKE_SUPER == opcode ||
780            Instruction::INVOKE_DIRECT == opcode ||
781            Instruction::INVOKE_STATIC == opcode ||
782            Instruction::INVOKE_INTERFACE == opcode) {
783          uint32_t invoke_method_idx = mir->dalvikInsn.vB;
784          const char* invoke_method_shorty = dex_file.GetMethodShorty(
785              dex_file.GetMethodId(invoke_method_idx));
786          if (!CanCompileShorty(invoke_method_shorty, cu.instruction_set)) {
787            VLOG(compiler) << "Unsupported to invoke '"
788                           << PrettyMethod(invoke_method_idx, dex_file)
789                           << "' with shorty : " << invoke_method_shorty;
790            return false;
791          }
792        }
793      }
794    }
795
796    LOG(INFO) << "Using experimental instruction set A64 for "
797              << PrettyMethod(method_idx, dex_file);
798  }
799  return true;
800}
801
802static CompiledMethod* CompileMethod(CompilerDriver& driver,
803                                     Compiler* compiler,
804                                     const DexFile::CodeItem* code_item,
805                                     uint32_t access_flags, InvokeType invoke_type,
806                                     uint16_t class_def_idx, uint32_t method_idx,
807                                     jobject class_loader, const DexFile& dex_file,
808                                     void* llvm_compilation_unit) {
809  VLOG(compiler) << "Compiling " << PrettyMethod(method_idx, dex_file) << "...";
810  if (code_item->insns_size_in_code_units_ >= 0x10000) {
811    LOG(INFO) << "Method size exceeds compiler limits: " << code_item->insns_size_in_code_units_
812              << " in " << PrettyMethod(method_idx, dex_file);
813    return NULL;
814  }
815
816  if (!driver.GetCompilerOptions().IsCompilationEnabled()) {
817    return nullptr;
818  }
819
820  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
821  CompilationUnit cu(driver.GetArenaPool());
822
823  cu.compiler_driver = &driver;
824  cu.class_linker = class_linker;
825  cu.instruction_set = driver.GetInstructionSet();
826  if (cu.instruction_set == kArm) {
827    cu.instruction_set = kThumb2;
828  }
829  cu.target64 = Is64BitInstructionSet(cu.instruction_set);
830  cu.compiler = compiler;
831  // TODO: x86_64 & arm64 are not yet implemented.
832  CHECK((cu.instruction_set == kThumb2) ||
833        (cu.instruction_set == kArm64) ||
834        (cu.instruction_set == kX86) ||
835        (cu.instruction_set == kX86_64) ||
836        (cu.instruction_set == kMips));
837
838  /* Adjust this value accordingly once inlining is performed */
839  cu.num_dalvik_registers = code_item->registers_size_;
840  // TODO: set this from command line
841  cu.compiler_flip_match = false;
842  bool use_match = !cu.compiler_method_match.empty();
843  bool match = use_match && (cu.compiler_flip_match ^
844      (PrettyMethod(method_idx, dex_file).find(cu.compiler_method_match) !=
845       std::string::npos));
846  if (!use_match || match) {
847    cu.disable_opt = kCompilerOptimizerDisableFlags;
848    cu.enable_debug = kCompilerDebugFlags;
849    cu.verbose = VLOG_IS_ON(compiler) ||
850        (cu.enable_debug & (1 << kDebugVerbose));
851  }
852
853  if (gVerboseMethods.size() != 0) {
854    cu.verbose = false;
855    for (size_t i = 0; i < gVerboseMethods.size(); ++i) {
856      if (PrettyMethod(method_idx, dex_file).find(gVerboseMethods[i])
857          != std::string::npos) {
858        cu.verbose = true;
859        break;
860      }
861    }
862  }
863
864  if (cu.verbose) {
865    cu.enable_debug |= (1 << kDebugCodegenDump);
866  }
867
868  /*
869   * TODO: rework handling of optimization and debug flags.  Should we split out
870   * MIR and backend flags?  Need command-line setting as well.
871   */
872
873  compiler->InitCompilationUnit(cu);
874
875  if (cu.instruction_set == kMips) {
876    // Disable some optimizations for mips for now
877    cu.disable_opt |= (
878        (1 << kLoadStoreElimination) |
879        (1 << kLoadHoisting) |
880        (1 << kSuppressLoads) |
881        (1 << kNullCheckElimination) |
882        (1 << kPromoteRegs) |
883        (1 << kTrackLiveTemps) |
884        (1 << kSafeOptimizations) |
885        (1 << kBBOpt) |
886        (1 << kMatch) |
887        (1 << kPromoteCompilerTemps));
888  }
889
890  if (cu.instruction_set == kArm64 || cu.instruction_set == kX86_64) {
891    // TODO(Arm64): enable optimizations once backend is mature enough.
892    // TODO(X86_64): enable optimizations once backend is mature enough.
893    cu.disable_opt = ~(uint32_t)0;
894    if (cu.instruction_set == kArm64) {
895      cu.enable_debug |= (1 << kDebugCodegenDump);
896    }
897  }
898
899  cu.StartTimingSplit("BuildMIRGraph");
900  cu.mir_graph.reset(new MIRGraph(&cu, &cu.arena));
901
902  /*
903   * After creation of the MIR graph, also create the code generator.
904   * The reason we do this is that optimizations on the MIR graph may need to get information
905   * that is only available if a CG exists.
906   */
907  cu.cg.reset(compiler->GetCodeGenerator(&cu, llvm_compilation_unit));
908
909  /* Gathering opcode stats? */
910  if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
911    cu.mir_graph->EnableOpcodeCounting();
912  }
913
914  // Check early if we should skip this compilation if the profiler is enabled.
915  if (cu.compiler_driver->ProfilePresent()) {
916    std::string methodname = PrettyMethod(method_idx, dex_file);
917    if (cu.mir_graph->SkipCompilation(methodname)) {
918      return NULL;
919    }
920  }
921
922  /* Build the raw MIR graph */
923  cu.mir_graph->InlineMethod(code_item, access_flags, invoke_type, class_def_idx, method_idx,
924                              class_loader, dex_file);
925
926  // TODO(Arm64): Remove this when we are able to compile everything.
927  if (!CanCompileMethod(method_idx, dex_file, cu)) {
928    VLOG(compiler) << "Cannot compile method : " << PrettyMethod(method_idx, dex_file);
929    return nullptr;
930  }
931
932  cu.NewTimingSplit("MIROpt:CheckFilters");
933  if (cu.mir_graph->SkipCompilation()) {
934    return NULL;
935  }
936
937  /* Create the pass driver and launch it */
938  PassDriverMEOpts pass_driver(&cu);
939  pass_driver.Launch();
940
941  if (cu.enable_debug & (1 << kDebugDumpCheckStats)) {
942    cu.mir_graph->DumpCheckStats();
943  }
944
945  if (kCompilerDebugFlags & (1 << kDebugCountOpcodes)) {
946    cu.mir_graph->ShowOpcodeStats();
947  }
948
949  /* Reassociate sreg names with original Dalvik vreg names. */
950  cu.mir_graph->RemapRegLocations();
951
952  /* Free Arenas from the cu.arena_stack for reuse by the cu.arena in the codegen. */
953  if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
954    if (cu.arena_stack.PeakBytesAllocated() > 256 * 1024) {
955      MemStats stack_stats(cu.arena_stack.GetPeakStats());
956      LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(stack_stats);
957    }
958  }
959  cu.arena_stack.Reset();
960
961  CompiledMethod* result = NULL;
962
963  cu.cg->Materialize();
964
965  cu.NewTimingSplit("Dedupe");  /* deduping takes up the vast majority of time in GetCompiledMethod(). */
966  result = cu.cg->GetCompiledMethod();
967  cu.NewTimingSplit("Cleanup");
968
969  if (result) {
970    VLOG(compiler) << "Compiled " << PrettyMethod(method_idx, dex_file);
971  } else {
972    VLOG(compiler) << "Deferred " << PrettyMethod(method_idx, dex_file);
973  }
974
975  if (cu.enable_debug & (1 << kDebugShowMemoryUsage)) {
976    if (cu.arena.BytesAllocated() > (1 * 1024 *1024)) {
977      MemStats mem_stats(cu.arena.GetMemStats());
978      LOG(INFO) << PrettyMethod(method_idx, dex_file) << " " << Dumpable<MemStats>(mem_stats);
979    }
980  }
981
982  if (cu.enable_debug & (1 << kDebugShowSummaryMemoryUsage)) {
983    LOG(INFO) << "MEMINFO " << cu.arena.BytesAllocated() << " " << cu.mir_graph->GetNumBlocks()
984              << " " << PrettyMethod(method_idx, dex_file);
985  }
986
987  cu.EndTiming();
988  driver.GetTimingsLogger()->AddLogger(cu.timings);
989  return result;
990}
991
992CompiledMethod* CompileOneMethod(CompilerDriver& driver,
993                                 Compiler* compiler,
994                                 const DexFile::CodeItem* code_item,
995                                 uint32_t access_flags,
996                                 InvokeType invoke_type,
997                                 uint16_t class_def_idx,
998                                 uint32_t method_idx,
999                                 jobject class_loader,
1000                                 const DexFile& dex_file,
1001                                 void* compilation_unit) {
1002  return CompileMethod(driver, compiler, code_item, access_flags, invoke_type, class_def_idx,
1003                       method_idx, class_loader, dex_file, compilation_unit);
1004}
1005
1006}  // namespace art
1007
1008extern "C" art::CompiledMethod*
1009    ArtQuickCompileMethod(art::CompilerDriver& driver,
1010                          const art::DexFile::CodeItem* code_item,
1011                          uint32_t access_flags, art::InvokeType invoke_type,
1012                          uint16_t class_def_idx, uint32_t method_idx, jobject class_loader,
1013                          const art::DexFile& dex_file) {
1014  // TODO: check method fingerprint here to determine appropriate backend type.  Until then, use build default
1015  art::Compiler* compiler = driver.GetCompiler();
1016  return art::CompileOneMethod(driver, compiler, code_item, access_flags, invoke_type,
1017                               class_def_idx, method_idx, class_loader, dex_file,
1018                               NULL /* use thread llvm_info */);
1019}
1020