blob: f551ac428002d3a2c60b5ad6b79df45573f65de0 [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);
David Brazdildee58d62016-04-07 09:54:26 +0000178 // Builds a static field access node and returns whether the instruction is supported.
179 bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
180
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
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000243 // Builds a `HLoadClass` loading the given `type_index`. If `outer` is true,
244 // this method will use the outer class's dex file to lookup the type at
245 // `type_index`.
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000246 HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc);
247
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000248 HLoadClass* BuildLoadClass(dex::TypeIndex type_index,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000249 const DexFile& dex_file,
250 Handle<mirror::Class> klass,
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000251 uint32_t dex_pc,
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000252 bool needs_access_check)
253 REQUIRES_SHARED(Locks::mutator_lock_);
Nicolas Geoffray5247c082017-01-13 14:17:29 +0000254
David Brazdildee58d62016-04-07 09:54:26 +0000255 // Returns the outer-most compiling method's class.
256 mirror::Class* GetOutermostCompilingClass() const;
257
258 // Returns the class whose method is being compiled.
259 mirror::Class* GetCompilingClass() const;
260
261 // Returns whether `type_index` points to the outer-most compiling method's class.
Andreas Gampea5b09a62016-11-17 15:21:22 -0800262 bool IsOutermostCompilingClass(dex::TypeIndex type_index) const;
David Brazdildee58d62016-04-07 09:54:26 +0000263
264 void PotentiallySimplifyFakeString(uint16_t original_dex_register,
265 uint32_t dex_pc,
266 HInvoke* invoke);
267
268 bool SetupInvokeArguments(HInvoke* invoke,
269 uint32_t number_of_vreg_arguments,
270 uint32_t* args,
271 uint32_t register_index,
272 bool is_range,
273 const char* descriptor,
274 size_t start_index,
275 size_t* argument_index);
276
277 bool HandleInvoke(HInvoke* invoke,
278 uint32_t number_of_vreg_arguments,
279 uint32_t* args,
280 uint32_t register_index,
281 bool is_range,
282 const char* descriptor,
Aart Bik296fbb42016-06-07 13:49:12 -0700283 HClinitCheck* clinit_check,
284 bool is_unresolved);
David Brazdildee58d62016-04-07 09:54:26 +0000285
286 bool HandleStringInit(HInvoke* invoke,
287 uint32_t number_of_vreg_arguments,
288 uint32_t* args,
289 uint32_t register_index,
290 bool is_range,
291 const char* descriptor);
292 void HandleStringInitResult(HInvokeStaticOrDirect* invoke);
293
294 HClinitCheck* ProcessClinitCheckForInvoke(
295 uint32_t dex_pc,
296 ArtMethod* method,
David Brazdildee58d62016-04-07 09:54:26 +0000297 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700298 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000299
300 // Build a HNewInstance instruction.
Igor Murashkin79d8fa72017-04-18 09:37:23 -0700301 HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc);
302
303 // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the
304 // happens-before ordering for default-initialization of the object referred to by new_instance.
305 void BuildConstructorFenceForAllocation(HInstruction* allocation);
David Brazdildee58d62016-04-07 09:54:26 +0000306
307 // Return whether the compiler can assume `cls` is initialized.
308 bool IsInitialized(Handle<mirror::Class> cls) const
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700309 REQUIRES_SHARED(Locks::mutator_lock_);
David Brazdildee58d62016-04-07 09:54:26 +0000310
311 // Try to resolve a method using the class linker. Return null if a method could
312 // not be resolved.
313 ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
314
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000315 // Try to resolve a field using the class linker. Return null if it could not
316 // be found.
317 ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put);
318
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000319 ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index,
320 const DexCompilationUnit& compilation_unit) const
321 REQUIRES_SHARED(Locks::mutator_lock_);
322
323 ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_);
324
Vladimir Markoca6fff82017-10-03 14:49:14 +0100325 ArenaAllocator* const allocator_;
David Brazdildee58d62016-04-07 09:54:26 +0000326 HGraph* const graph_;
Vladimir Marko69d310e2017-10-09 14:12:23 +0100327 VariableSizedHandleScope* const handles_;
David Brazdildee58d62016-04-07 09:54:26 +0000328
329 // The dex file where the method being compiled is, and the bytecode data.
330 const DexFile* const dex_file_;
Vladimir Marko92f7f3c2017-10-31 11:38:30 +0000331 const DexFile::CodeItem* const code_item_; // null for intrinsic graph.
David Brazdildee58d62016-04-07 09:54:26 +0000332
333 // The return type of the method being compiled.
Vladimir Marko0ebe0d82017-09-21 22:50:39 +0100334 const DataType::Type return_type_;
David Brazdildee58d62016-04-07 09:54:26 +0000335
Vladimir Marko69d310e2017-10-09 14:12:23 +0100336 HBasicBlockBuilder* const block_builder_;
337 SsaBuilder* const ssa_builder_;
David Brazdildee58d62016-04-07 09:54:26 +0000338
339 CompilerDriver* const compiler_driver_;
340
Nicolas Geoffray83c8e272017-01-31 14:36:37 +0000341 CodeGenerator* const code_generator_;
342
David Brazdildee58d62016-04-07 09:54:26 +0000343 // The compilation unit of the current method being compiled. Note that
344 // it can be an inlined method.
Vladimir Markoca6fff82017-10-03 14:49:14 +0100345 const DexCompilationUnit* const dex_compilation_unit_;
David Brazdildee58d62016-04-07 09:54:26 +0000346
347 // The compilation unit of the outermost method being compiled. That is the
348 // method being compiled (and not inlined), and potentially inlining other
349 // methods.
350 const DexCompilationUnit* const outer_compilation_unit_;
351
Mathieu Chartierde4b08f2017-07-10 14:13:41 -0700352 // Original values kept after instruction quickening.
353 QuickenInfoTable quicken_info_;
David Brazdildee58d62016-04-07 09:54:26 +0000354
Vladimir Marko69d310e2017-10-09 14:12:23 +0100355 OptimizingCompilerStats* const compilation_stats_;
David Brazdildee58d62016-04-07 09:54:26 +0000356
Vladimir Marko69d310e2017-10-09 14:12:23 +0100357 ScopedArenaAllocator* const local_allocator_;
358 ScopedArenaVector<ScopedArenaVector<HInstruction*>> locals_for_;
359 HBasicBlock* current_block_;
360 ScopedArenaVector<HInstruction*>* current_locals_;
361 HInstruction* latest_result_;
362 // Current "this" parameter.
363 // Valid only after InitializeParameters() finishes.
364 // * Null for static methods.
365 // * Non-null for instance methods.
366 HParameterValue* current_this_parameter_;
367
368 ScopedArenaVector<HBasicBlock*> loop_headers_;
David Brazdildee58d62016-04-07 09:54:26 +0000369
370 static constexpr int kDefaultNumberOfLoops = 2;
371
372 DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder);
373};
374
375} // namespace art
376
377#endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_