blob: 0500d40cd30f06786e4e42760547a357fc1b94ea [file] [log] [blame]
David Brazdildee58d62016-04-07 09:54:26 +00001/*
2 * Copyright (C) 2016 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_OPTIMIZING_INSTRUCTION_BUILDER_H_
18#define ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_
19
Vladimir Marko69d310e2017-10-09 14:12:23 +010020#include "base/scoped_arena_allocator.h"
21#include "base/scoped_arena_containers.h"
22#include "data_type.h"
23#include "dex_file.h"
Andreas Gampea5b09a62016-11-17 15:21:22 -080024#include "dex_file_types.h"
Vladimir Marko69d310e2017-10-09 14:12:23 +010025#include "handle.h"
David Brazdildee58d62016-04-07 09:54:26 +000026#include "nodes.h"
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070027#include "quicken_info.h"
David Brazdildee58d62016-04-07 09:54:26 +000028
29namespace art {
30
Vladimir Marko69d310e2017-10-09 14:12:23 +010031class ArenaBitVector;
32class ArtField;
33class ArtMethod;
Nicolas Geoffray83c8e272017-01-31 14:36:37 +000034class CodeGenerator;
Vladimir Marko69d310e2017-10-09 14:12:23 +010035class CompilerDriver;
36class DexCompilationUnit;
37class HBasicBlockBuilder;
Andreas Gampe26de38b2016-07-27 17:53:11 -070038class Instruction;
Vladimir Marko69d310e2017-10-09 14:12:23 +010039class OptimizingCompilerStats;
40class SsaBuilder;
41class VariableSizedHandleScope;
42
43namespace mirror {
44class Class;
45} // namespace mirror
Andreas Gampe26de38b2016-07-27 17:53:11 -070046
David Brazdildee58d62016-04-07 09:54:26 +000047class HInstructionBuilder : public ValueObject {
48 public:
49 HInstructionBuilder(HGraph* graph,
50 HBasicBlockBuilder* block_builder,
51 SsaBuilder* ssa_builder,
52 const DexFile* dex_file,
Vladimir Marko92f7f3c2017-10-31 11:38:30 +000053 const DexFile::CodeItem* code_item,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +010054 DataType::Type return_type,
Vladimir Markoca6fff82017-10-03 14:49:14 +010055 const DexCompilationUnit* dex_compilation_unit,
56 const DexCompilationUnit* outer_compilation_unit,
Vladimir Marko69d310e2017-10-09 14:12:23 +010057 CompilerDriver* compiler_driver,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +000058 CodeGenerator* code_generator,
David Brazdildee58d62016-04-07 09:54:26 +000059 const uint8_t* interpreter_metadata,
60 OptimizingCompilerStats* compiler_stats,
Vladimir Marko69d310e2017-10-09 14:12:23 +010061 VariableSizedHandleScope* handles,
62 ScopedArenaAllocator* local_allocator)
Vladimir Markoca6fff82017-10-03 14:49:14 +010063 : allocator_(graph->GetAllocator()),
David Brazdildee58d62016-04-07 09:54:26 +000064 graph_(graph),
Nicolas Geoffray5247c082017-01-13 14:17:29 +000065 handles_(handles),
David Brazdildee58d62016-04-07 09:54:26 +000066 dex_file_(dex_file),
67 code_item_(code_item),
68 return_type_(return_type),
69 block_builder_(block_builder),
70 ssa_builder_(ssa_builder),
Vladimir Marko69d310e2017-10-09 14:12:23 +010071 compiler_driver_(compiler_driver),
Nicolas Geoffray83c8e272017-01-31 14:36:37 +000072 code_generator_(code_generator),
David Brazdildee58d62016-04-07 09:54:26 +000073 dex_compilation_unit_(dex_compilation_unit),
74 outer_compilation_unit_(outer_compilation_unit),
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070075 quicken_info_(interpreter_metadata),
David Brazdildee58d62016-04-07 09:54:26 +000076 compilation_stats_(compiler_stats),
Vladimir Marko69d310e2017-10-09 14:12:23 +010077 local_allocator_(local_allocator),
78 locals_for_(local_allocator->Adapter(kArenaAllocGraphBuilder)),
79 current_block_(nullptr),
80 current_locals_(nullptr),
81 latest_result_(nullptr),
82 current_this_parameter_(nullptr),
83 loop_headers_(local_allocator->Adapter(kArenaAllocGraphBuilder)) {
David Brazdildee58d62016-04-07 09:54:26 +000084 loop_headers_.reserve(kDefaultNumberOfLoops);
85 }
86
87 bool Build();
Vladimir Marko92f7f3c2017-10-31 11:38:30 +000088 void BuildIntrinsic(ArtMethod* method);
David Brazdildee58d62016-04-07 09:54:26 +000089
90 private:
David Brazdildee58d62016-04-07 09:54:26 +000091 void InitializeBlockLocals();
92 void PropagateLocalsToCatchBlocks();
93 void SetLoopHeaderPhiInputs();
94
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070095 bool ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc, size_t quicken_index);
Vladimir Marko69d310e2017-10-09 14:12:23 +010096 ArenaBitVector* FindNativeDebugInfoLocations();
David Brazdildee58d62016-04-07 09:54:26 +000097
98 bool CanDecodeQuickenedInfo() const;
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070099 uint16_t LookupQuickenedInfo(uint32_t quicken_index);
David Brazdildee58d62016-04-07 09:54:26 +0000100
101 HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const;
102
Vladimir Marko69d310e2017-10-09 14:12:23 +0100103 ScopedArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
Mingyao Yang01b47b02017-02-03 12:09:57 -0800104 // Out of line version of GetLocalsFor(), which has a fast path that is
105 // beneficial to get inlined by callers.
Vladimir Marko69d310e2017-10-09 14:12:23 +0100106 ScopedArenaVector<HInstruction*>* GetLocalsForWithAllocation(
107 HBasicBlock* block, ScopedArenaVector<HInstruction*>* locals, const size_t vregs);
David Brazdildee58d62016-04-07 09:54:26 +0000108 HInstruction* ValueOfLocalAt(HBasicBlock* block, size_t local);
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100109 HInstruction* LoadLocal(uint32_t register_index, DataType::Type type) const;
David Brazdilc120bbe2016-04-22 16:57:00 +0100110 HInstruction* LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000111 void UpdateLocal(uint32_t register_index, HInstruction* instruction);
112
113 void AppendInstruction(HInstruction* instruction);
114 void InsertInstructionAtTop(HInstruction* instruction);
115 void InitializeInstruction(HInstruction* instruction);
116
117 void InitializeParameters();
118
119 // Returns whether the current method needs access check for the type.
120 // Output parameter finalizable is set to whether the type is finalizable.
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000121 bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700122 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000123
124 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100125 void Unop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000126
127 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100128 void Binop_23x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000129
130 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100131 void Binop_23x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000132
133 void Binop_23x_cmp(const Instruction& instruction,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100134 DataType::Type type,
David Brazdildee58d62016-04-07 09:54:26 +0000135 ComparisonBias bias,
136 uint32_t dex_pc);
137
138 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100139 void Binop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000140
141 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100142 void Binop_12x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000143
144 template<typename T>
145 void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc);
146
147 template<typename T>
148 void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc);
149
150 template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
151 template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
152
153 void Conversion_12x(const Instruction& instruction,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100154 DataType::Type input_type,
155 DataType::Type result_type,
David Brazdildee58d62016-04-07 09:54:26 +0000156 uint32_t dex_pc);
157
158 void BuildCheckedDivRem(uint16_t out_reg,
159 uint16_t first_reg,
160 int64_t second_reg_or_constant,
161 uint32_t dex_pc,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100162 DataType::Type type,
David Brazdildee58d62016-04-07 09:54:26 +0000163 bool second_is_lit,
164 bool is_div);
165
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100166 void BuildReturn(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000167
168 // Builds an instance field access node and returns whether the instruction is supported.
Mathieu Chartierde4b08f2017-07-10 14:13:41 -0700169 bool BuildInstanceFieldAccess(const Instruction& instruction,
170 uint32_t dex_pc,
171 bool is_put,
172 size_t quicken_index);
David Brazdildee58d62016-04-07 09:54:26 +0000173
174 void BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
175 uint32_t dex_pc,
176 bool is_put,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100177 DataType::Type field_type);
Nicolas Geoffraydbb9aef2017-11-23 10:44:11 +0000178 // Builds a static field access node.
179 void BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
David Brazdildee58d62016-04-07 09:54:26 +0000180
181 void BuildArrayAccess(const Instruction& instruction,
182 uint32_t dex_pc,
183 bool is_get,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100184 DataType::Type anticipated_type);
David Brazdildee58d62016-04-07 09:54:26 +0000185
186 // Builds an invocation node and returns whether the instruction is supported.
187 bool BuildInvoke(const Instruction& instruction,
188 uint32_t dex_pc,
189 uint32_t method_idx,
190 uint32_t number_of_vreg_arguments,
191 bool is_range,
192 uint32_t* args,
193 uint32_t register_index);
194
Orion Hodsonac141392017-01-13 11:53:47 +0000195 // Builds an invocation node for invoke-polymorphic and returns whether the
196 // instruction is supported.
197 bool BuildInvokePolymorphic(const Instruction& instruction,
198 uint32_t dex_pc,
199 uint32_t method_idx,
200 uint32_t proto_idx,
201 uint32_t number_of_vreg_arguments,
202 bool is_range,
203 uint32_t* args,
204 uint32_t register_index);
205
David Brazdildee58d62016-04-07 09:54:26 +0000206 // Builds a new array node and the instructions that fill it.
Igor Murashkin79d8fa72017-04-18 09:37:23 -0700207 HNewArray* BuildFilledNewArray(uint32_t dex_pc,
208 dex::TypeIndex type_index,
209 uint32_t number_of_vreg_arguments,
210 bool is_range,
211 uint32_t* args,
212 uint32_t register_index);
David Brazdildee58d62016-04-07 09:54:26 +0000213
214 void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
215
216 // Fills the given object with data as specified in the fill-array-data
217 // instruction. Currently only used for non-reference and non-floating point
218 // arrays.
219 template <typename T>
220 void BuildFillArrayData(HInstruction* object,
221 const T* data,
222 uint32_t element_count,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100223 DataType::Type anticipated_type,
David Brazdildee58d62016-04-07 09:54:26 +0000224 uint32_t dex_pc);
225
226 // Fills the given object with data as specified in the fill-array-data
227 // instruction. The data must be for long and double arrays.
228 void BuildFillWideArrayData(HInstruction* object,
229 const int64_t* data,
230 uint32_t element_count,
231 uint32_t dex_pc);
232
233 // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
234 void BuildTypeCheck(const Instruction& instruction,
235 uint8_t destination,
236 uint8_t reference,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800237 dex::TypeIndex type_index,
David Brazdildee58d62016-04-07 09:54:26 +0000238 uint32_t dex_pc);
239
240 // Builds an instruction sequence for a switch statement.
241 void BuildSwitch(const Instruction& instruction, uint32_t dex_pc);
242
Vladimir Marko28e012a2017-12-07 11:22:59 +0000243 // Builds a `HLoadString` loading the given `string_index`.
244 void BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc);
245
246 // Builds a `HLoadClass` loading the given `type_index`.
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000247 HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc);
248
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000249 HLoadClass* BuildLoadClass(dex::TypeIndex type_index,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000250 const DexFile& dex_file,
251 Handle<mirror::Class> klass,
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000252 uint32_t dex_pc,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000253 bool needs_access_check)
254 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000255
David Brazdildee58d62016-04-07 09:54:26 +0000256 // Returns the outer-most compiling method's class.
Vladimir Marko28e012a2017-12-07 11:22:59 +0000257 ObjPtr<mirror::Class> GetOutermostCompilingClass() const;
David Brazdildee58d62016-04-07 09:54:26 +0000258
259 // Returns the class whose method is being compiled.
Vladimir Marko28e012a2017-12-07 11:22:59 +0000260 ObjPtr<mirror::Class> GetCompilingClass() const;
David Brazdildee58d62016-04-07 09:54:26 +0000261
262 // Returns whether `type_index` points to the outer-most compiling method's class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800263 bool IsOutermostCompilingClass(dex::TypeIndex type_index) const;
David Brazdildee58d62016-04-07 09:54:26 +0000264
265 void PotentiallySimplifyFakeString(uint16_t original_dex_register,
266 uint32_t dex_pc,
267 HInvoke* invoke);
268
269 bool SetupInvokeArguments(HInvoke* invoke,
270 uint32_t number_of_vreg_arguments,
271 uint32_t* args,
272 uint32_t register_index,
273 bool is_range,
274 const char* descriptor,
275 size_t start_index,
276 size_t* argument_index);
277
278 bool HandleInvoke(HInvoke* invoke,
279 uint32_t number_of_vreg_arguments,
280 uint32_t* args,
281 uint32_t register_index,
282 bool is_range,
283 const char* descriptor,
Aart Bik296fbb42016-06-07 13:49:12 -0700284 HClinitCheck* clinit_check,
285 bool is_unresolved);
David Brazdildee58d62016-04-07 09:54:26 +0000286
287 bool HandleStringInit(HInvoke* invoke,
288 uint32_t number_of_vreg_arguments,
289 uint32_t* args,
290 uint32_t register_index,
291 bool is_range,
292 const char* descriptor);
293 void HandleStringInitResult(HInvokeStaticOrDirect* invoke);
294
295 HClinitCheck* ProcessClinitCheckForInvoke(
296 uint32_t dex_pc,
297 ArtMethod* method,
David Brazdildee58d62016-04-07 09:54:26 +0000298 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700299 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000300
301 // Build a HNewInstance instruction.
Igor Murashkin79d8fa72017-04-18 09:37:23 -0700302 HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc);
303
304 // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the
305 // happens-before ordering for default-initialization of the object referred to by new_instance.
306 void BuildConstructorFenceForAllocation(HInstruction* allocation);
David Brazdildee58d62016-04-07 09:54:26 +0000307
308 // Return whether the compiler can assume `cls` is initialized.
309 bool IsInitialized(Handle<mirror::Class> cls) const
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700310 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000311
312 // Try to resolve a method using the class linker. Return null if a method could
313 // not be resolved.
314 ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
315
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000316 // Try to resolve a field using the class linker. Return null if it could not
317 // be found.
318 ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put);
319
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000320 ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index,
321 const DexCompilationUnit& compilation_unit) const
322 REQUIRES_SHARED(Locks::mutator_lock_);
323
324 ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_);
325
Vladimir Markoca6fff82017-10-03 14:49:14 +0100326 ArenaAllocator* const allocator_;
David Brazdildee58d62016-04-07 09:54:26 +0000327 HGraph* const graph_;
Vladimir Marko69d310e2017-10-09 14:12:23 +0100328 VariableSizedHandleScope* const handles_;
David Brazdildee58d62016-04-07 09:54:26 +0000329
330 // The dex file where the method being compiled is, and the bytecode data.
331 const DexFile* const dex_file_;
Vladimir Marko92f7f3c2017-10-31 11:38:30 +0000332 const DexFile::CodeItem* const code_item_; // null for intrinsic graph.
David Brazdildee58d62016-04-07 09:54:26 +0000333
334 // The return type of the method being compiled.
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100335 const DataType::Type return_type_;
David Brazdildee58d62016-04-07 09:54:26 +0000336
Vladimir Marko69d310e2017-10-09 14:12:23 +0100337 HBasicBlockBuilder* const block_builder_;
338 SsaBuilder* const ssa_builder_;
David Brazdildee58d62016-04-07 09:54:26 +0000339
340 CompilerDriver* const compiler_driver_;
341
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000342 CodeGenerator* const code_generator_;
343
David Brazdildee58d62016-04-07 09:54:26 +0000344 // The compilation unit of the current method being compiled. Note that
345 // it can be an inlined method.
Vladimir Markoca6fff82017-10-03 14:49:14 +0100346 const DexCompilationUnit* const dex_compilation_unit_;
David Brazdildee58d62016-04-07 09:54:26 +0000347
348 // The compilation unit of the outermost method being compiled. That is the
349 // method being compiled (and not inlined), and potentially inlining other
350 // methods.
351 const DexCompilationUnit* const outer_compilation_unit_;
352
Mathieu Chartierde4b08f2017-07-10 14:13:41 -0700353 // Original values kept after instruction quickening.
354 QuickenInfoTable quicken_info_;
David Brazdildee58d62016-04-07 09:54:26 +0000355
Vladimir Marko69d310e2017-10-09 14:12:23 +0100356 OptimizingCompilerStats* const compilation_stats_;
David Brazdildee58d62016-04-07 09:54:26 +0000357
Vladimir Marko69d310e2017-10-09 14:12:23 +0100358 ScopedArenaAllocator* const local_allocator_;
359 ScopedArenaVector<ScopedArenaVector<HInstruction*>> locals_for_;
360 HBasicBlock* current_block_;
361 ScopedArenaVector<HInstruction*>* current_locals_;
362 HInstruction* latest_result_;
363 // Current "this" parameter.
364 // Valid only after InitializeParameters() finishes.
365 // * Null for static methods.
366 // * Non-null for instance methods.
367 HParameterValue* current_this_parameter_;
368
369 ScopedArenaVector<HBasicBlock*> loop_headers_;
David Brazdildee58d62016-04-07 09:54:26 +0000370
371 static constexpr int kDefaultNumberOfLoops = 2;
372
373 DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder);
374};
375
376} // namespace art
377
378#endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_