blob: 058b71168714bf7b319693a6a0c73353da84a747 [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,
53 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();
88
89 private:
David Brazdildee58d62016-04-07 09:54:26 +000090 void InitializeBlockLocals();
91 void PropagateLocalsToCatchBlocks();
92 void SetLoopHeaderPhiInputs();
93
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070094 bool ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc, size_t quicken_index);
Vladimir Marko69d310e2017-10-09 14:12:23 +010095 ArenaBitVector* FindNativeDebugInfoLocations();
David Brazdildee58d62016-04-07 09:54:26 +000096
97 bool CanDecodeQuickenedInfo() const;
Mathieu Chartierde4b08f2017-07-10 14:13:41 -070098 uint16_t LookupQuickenedInfo(uint32_t quicken_index);
David Brazdildee58d62016-04-07 09:54:26 +000099
100 HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const;
101
Vladimir Marko69d310e2017-10-09 14:12:23 +0100102 ScopedArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
Mingyao Yang01b47b02017-02-03 12:09:57 -0800103 // Out of line version of GetLocalsFor(), which has a fast path that is
104 // beneficial to get inlined by callers.
Vladimir Marko69d310e2017-10-09 14:12:23 +0100105 ScopedArenaVector<HInstruction*>* GetLocalsForWithAllocation(
106 HBasicBlock* block, ScopedArenaVector<HInstruction*>* locals, const size_t vregs);
David Brazdildee58d62016-04-07 09:54:26 +0000107 HInstruction* ValueOfLocalAt(HBasicBlock* block, size_t local);
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100108 HInstruction* LoadLocal(uint32_t register_index, DataType::Type type) const;
David Brazdilc120bbe2016-04-22 16:57:00 +0100109 HInstruction* LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000110 void UpdateLocal(uint32_t register_index, HInstruction* instruction);
111
112 void AppendInstruction(HInstruction* instruction);
113 void InsertInstructionAtTop(HInstruction* instruction);
114 void InitializeInstruction(HInstruction* instruction);
115
116 void InitializeParameters();
117
118 // Returns whether the current method needs access check for the type.
119 // Output parameter finalizable is set to whether the type is finalizable.
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000120 bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700121 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000122
123 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100124 void Unop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000125
126 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100127 void Binop_23x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000128
129 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100130 void Binop_23x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000131
132 void Binop_23x_cmp(const Instruction& instruction,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100133 DataType::Type type,
David Brazdildee58d62016-04-07 09:54:26 +0000134 ComparisonBias bias,
135 uint32_t dex_pc);
136
137 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100138 void Binop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000139
140 template<typename T>
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100141 void Binop_12x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000142
143 template<typename T>
144 void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc);
145
146 template<typename T>
147 void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc);
148
149 template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
150 template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
151
152 void Conversion_12x(const Instruction& instruction,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100153 DataType::Type input_type,
154 DataType::Type result_type,
David Brazdildee58d62016-04-07 09:54:26 +0000155 uint32_t dex_pc);
156
157 void BuildCheckedDivRem(uint16_t out_reg,
158 uint16_t first_reg,
159 int64_t second_reg_or_constant,
160 uint32_t dex_pc,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100161 DataType::Type type,
David Brazdildee58d62016-04-07 09:54:26 +0000162 bool second_is_lit,
163 bool is_div);
164
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100165 void BuildReturn(const Instruction& instruction, DataType::Type type, uint32_t dex_pc);
David Brazdildee58d62016-04-07 09:54:26 +0000166
167 // Builds an instance field access node and returns whether the instruction is supported.
Mathieu Chartierde4b08f2017-07-10 14:13:41 -0700168 bool BuildInstanceFieldAccess(const Instruction& instruction,
169 uint32_t dex_pc,
170 bool is_put,
171 size_t quicken_index);
David Brazdildee58d62016-04-07 09:54:26 +0000172
173 void BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
174 uint32_t dex_pc,
175 bool is_put,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100176 DataType::Type field_type);
David Brazdildee58d62016-04-07 09:54:26 +0000177 // Builds a static field access node and returns whether the instruction is supported.
178 bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
179
180 void BuildArrayAccess(const Instruction& instruction,
181 uint32_t dex_pc,
182 bool is_get,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100183 DataType::Type anticipated_type);
David Brazdildee58d62016-04-07 09:54:26 +0000184
185 // Builds an invocation node and returns whether the instruction is supported.
186 bool BuildInvoke(const Instruction& instruction,
187 uint32_t dex_pc,
188 uint32_t method_idx,
189 uint32_t number_of_vreg_arguments,
190 bool is_range,
191 uint32_t* args,
192 uint32_t register_index);
193
Orion Hodsonac141392017-01-13 11:53:47 +0000194 // Builds an invocation node for invoke-polymorphic and returns whether the
195 // instruction is supported.
196 bool BuildInvokePolymorphic(const Instruction& instruction,
197 uint32_t dex_pc,
198 uint32_t method_idx,
199 uint32_t proto_idx,
200 uint32_t number_of_vreg_arguments,
201 bool is_range,
202 uint32_t* args,
203 uint32_t register_index);
204
David Brazdildee58d62016-04-07 09:54:26 +0000205 // Builds a new array node and the instructions that fill it.
Igor Murashkin79d8fa72017-04-18 09:37:23 -0700206 HNewArray* BuildFilledNewArray(uint32_t dex_pc,
207 dex::TypeIndex type_index,
208 uint32_t number_of_vreg_arguments,
209 bool is_range,
210 uint32_t* args,
211 uint32_t register_index);
David Brazdildee58d62016-04-07 09:54:26 +0000212
213 void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
214
215 // Fills the given object with data as specified in the fill-array-data
216 // instruction. Currently only used for non-reference and non-floating point
217 // arrays.
218 template <typename T>
219 void BuildFillArrayData(HInstruction* object,
220 const T* data,
221 uint32_t element_count,
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100222 DataType::Type anticipated_type,
David Brazdildee58d62016-04-07 09:54:26 +0000223 uint32_t dex_pc);
224
225 // Fills the given object with data as specified in the fill-array-data
226 // instruction. The data must be for long and double arrays.
227 void BuildFillWideArrayData(HInstruction* object,
228 const int64_t* data,
229 uint32_t element_count,
230 uint32_t dex_pc);
231
232 // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
233 void BuildTypeCheck(const Instruction& instruction,
234 uint8_t destination,
235 uint8_t reference,
Andreas Gampea5b09a62016-11-17 15:21:22 -0800236 dex::TypeIndex type_index,
David Brazdildee58d62016-04-07 09:54:26 +0000237 uint32_t dex_pc);
238
239 // Builds an instruction sequence for a switch statement.
240 void BuildSwitch(const Instruction& instruction, uint32_t dex_pc);
241
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000242 // Builds a `HLoadClass` loading the given `type_index`. If `outer` is true,
243 // this method will use the outer class's dex file to lookup the type at
244 // `type_index`.
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000245 HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc);
246
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000247 HLoadClass* BuildLoadClass(dex::TypeIndex type_index,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000248 const DexFile& dex_file,
249 Handle<mirror::Class> klass,
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000250 uint32_t dex_pc,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000251 bool needs_access_check)
252 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000253
David Brazdildee58d62016-04-07 09:54:26 +0000254 // Returns the outer-most compiling method's class.
255 mirror::Class* GetOutermostCompilingClass() const;
256
257 // Returns the class whose method is being compiled.
258 mirror::Class* GetCompilingClass() const;
259
260 // Returns whether `type_index` points to the outer-most compiling method's class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800261 bool IsOutermostCompilingClass(dex::TypeIndex type_index) const;
David Brazdildee58d62016-04-07 09:54:26 +0000262
263 void PotentiallySimplifyFakeString(uint16_t original_dex_register,
264 uint32_t dex_pc,
265 HInvoke* invoke);
266
267 bool SetupInvokeArguments(HInvoke* invoke,
268 uint32_t number_of_vreg_arguments,
269 uint32_t* args,
270 uint32_t register_index,
271 bool is_range,
272 const char* descriptor,
273 size_t start_index,
274 size_t* argument_index);
275
276 bool HandleInvoke(HInvoke* invoke,
277 uint32_t number_of_vreg_arguments,
278 uint32_t* args,
279 uint32_t register_index,
280 bool is_range,
281 const char* descriptor,
Aart Bik296fbb42016-06-07 13:49:12 -0700282 HClinitCheck* clinit_check,
283 bool is_unresolved);
David Brazdildee58d62016-04-07 09:54:26 +0000284
285 bool HandleStringInit(HInvoke* invoke,
286 uint32_t number_of_vreg_arguments,
287 uint32_t* args,
288 uint32_t register_index,
289 bool is_range,
290 const char* descriptor);
291 void HandleStringInitResult(HInvokeStaticOrDirect* invoke);
292
293 HClinitCheck* ProcessClinitCheckForInvoke(
294 uint32_t dex_pc,
295 ArtMethod* method,
David Brazdildee58d62016-04-07 09:54:26 +0000296 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700297 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000298
299 // Build a HNewInstance instruction.
Igor Murashkin79d8fa72017-04-18 09:37:23 -0700300 HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc);
301
302 // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the
303 // happens-before ordering for default-initialization of the object referred to by new_instance.
304 void BuildConstructorFenceForAllocation(HInstruction* allocation);
David Brazdildee58d62016-04-07 09:54:26 +0000305
306 // Return whether the compiler can assume `cls` is initialized.
307 bool IsInitialized(Handle<mirror::Class> cls) const
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700308 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000309
310 // Try to resolve a method using the class linker. Return null if a method could
311 // not be resolved.
312 ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
313
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000314 // Try to resolve a field using the class linker. Return null if it could not
315 // be found.
316 ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put);
317
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000318 ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index,
319 const DexCompilationUnit& compilation_unit) const
320 REQUIRES_SHARED(Locks::mutator_lock_);
321
322 ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_);
323
Vladimir Markoca6fff82017-10-03 14:49:14 +0100324 ArenaAllocator* const allocator_;
David Brazdildee58d62016-04-07 09:54:26 +0000325 HGraph* const graph_;
Vladimir Marko69d310e2017-10-09 14:12:23 +0100326 VariableSizedHandleScope* const handles_;
David Brazdildee58d62016-04-07 09:54:26 +0000327
328 // The dex file where the method being compiled is, and the bytecode data.
329 const DexFile* const dex_file_;
330 const DexFile::CodeItem& code_item_;
331
332 // The return type of the method being compiled.
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100333 const DataType::Type return_type_;
David Brazdildee58d62016-04-07 09:54:26 +0000334
Vladimir Marko69d310e2017-10-09 14:12:23 +0100335 HBasicBlockBuilder* const block_builder_;
336 SsaBuilder* const ssa_builder_;
David Brazdildee58d62016-04-07 09:54:26 +0000337
338 CompilerDriver* const compiler_driver_;
339
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000340 CodeGenerator* const code_generator_;
341
David Brazdildee58d62016-04-07 09:54:26 +0000342 // The compilation unit of the current method being compiled. Note that
343 // it can be an inlined method.
Vladimir Markoca6fff82017-10-03 14:49:14 +0100344 const DexCompilationUnit* const dex_compilation_unit_;
David Brazdildee58d62016-04-07 09:54:26 +0000345
346 // The compilation unit of the outermost method being compiled. That is the
347 // method being compiled (and not inlined), and potentially inlining other
348 // methods.
349 const DexCompilationUnit* const outer_compilation_unit_;
350
Mathieu Chartierde4b08f2017-07-10 14:13:41 -0700351 // Original values kept after instruction quickening.
352 QuickenInfoTable quicken_info_;
David Brazdildee58d62016-04-07 09:54:26 +0000353
Vladimir Marko69d310e2017-10-09 14:12:23 +0100354 OptimizingCompilerStats* const compilation_stats_;
David Brazdildee58d62016-04-07 09:54:26 +0000355
Vladimir Marko69d310e2017-10-09 14:12:23 +0100356 ScopedArenaAllocator* const local_allocator_;
357 ScopedArenaVector<ScopedArenaVector<HInstruction*>> locals_for_;
358 HBasicBlock* current_block_;
359 ScopedArenaVector<HInstruction*>* current_locals_;
360 HInstruction* latest_result_;
361 // Current "this" parameter.
362 // Valid only after InitializeParameters() finishes.
363 // * Null for static methods.
364 // * Non-null for instance methods.
365 HParameterValue* current_this_parameter_;
366
367 ScopedArenaVector<HBasicBlock*> loop_headers_;
David Brazdildee58d62016-04-07 09:54:26 +0000368
369 static constexpr int kDefaultNumberOfLoops = 2;
370
371 DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder);
372};
373
374} // namespace art
375
376#endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_