• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
20 #include "base/arena_containers.h"
21 #include "base/arena_object.h"
22 #include "block_builder.h"
23 #include "dex_file_types.h"
24 #include "driver/compiler_driver.h"
25 #include "driver/compiler_driver-inl.h"
26 #include "driver/dex_compilation_unit.h"
27 #include "mirror/dex_cache.h"
28 #include "nodes.h"
29 #include "optimizing_compiler_stats.h"
30 #include "quicken_info.h"
31 #include "ssa_builder.h"
32 
33 namespace art {
34 
35 class CodeGenerator;
36 class Instruction;
37 
38 class HInstructionBuilder : public ValueObject {
39  public:
HInstructionBuilder(HGraph * graph,HBasicBlockBuilder * block_builder,SsaBuilder * ssa_builder,const DexFile * dex_file,const DexFile::CodeItem & code_item,Primitive::Type return_type,DexCompilationUnit * dex_compilation_unit,const DexCompilationUnit * const outer_compilation_unit,CompilerDriver * driver,CodeGenerator * code_generator,const uint8_t * interpreter_metadata,OptimizingCompilerStats * compiler_stats,Handle<mirror::DexCache> dex_cache,VariableSizedHandleScope * handles)40   HInstructionBuilder(HGraph* graph,
41                       HBasicBlockBuilder* block_builder,
42                       SsaBuilder* ssa_builder,
43                       const DexFile* dex_file,
44                       const DexFile::CodeItem& code_item,
45                       Primitive::Type return_type,
46                       DexCompilationUnit* dex_compilation_unit,
47                       const DexCompilationUnit* const outer_compilation_unit,
48                       CompilerDriver* driver,
49                       CodeGenerator* code_generator,
50                       const uint8_t* interpreter_metadata,
51                       OptimizingCompilerStats* compiler_stats,
52                       Handle<mirror::DexCache> dex_cache,
53                       VariableSizedHandleScope* handles)
54       : arena_(graph->GetArena()),
55         graph_(graph),
56         handles_(handles),
57         dex_file_(dex_file),
58         code_item_(code_item),
59         return_type_(return_type),
60         block_builder_(block_builder),
61         ssa_builder_(ssa_builder),
62         locals_for_(arena_->Adapter(kArenaAllocGraphBuilder)),
63         current_block_(nullptr),
64         current_locals_(nullptr),
65         latest_result_(nullptr),
66         current_this_parameter_(nullptr),
67         compiler_driver_(driver),
68         code_generator_(code_generator),
69         dex_compilation_unit_(dex_compilation_unit),
70         outer_compilation_unit_(outer_compilation_unit),
71         quicken_info_(interpreter_metadata),
72         compilation_stats_(compiler_stats),
73         dex_cache_(dex_cache),
74         loop_headers_(graph->GetArena()->Adapter(kArenaAllocGraphBuilder)) {
75     loop_headers_.reserve(kDefaultNumberOfLoops);
76   }
77 
78   bool Build();
79 
80  private:
81   void MaybeRecordStat(MethodCompilationStat compilation_stat);
82 
83   void InitializeBlockLocals();
84   void PropagateLocalsToCatchBlocks();
85   void SetLoopHeaderPhiInputs();
86 
87   bool ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc, size_t quicken_index);
88   void FindNativeDebugInfoLocations(ArenaBitVector* locations);
89 
90   bool CanDecodeQuickenedInfo() const;
91   uint16_t LookupQuickenedInfo(uint32_t quicken_index);
92 
93   HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const;
94 
95   ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
96   // Out of line version of GetLocalsFor(), which has a fast path that is
97   // beneficial to get inlined by callers.
98   ArenaVector<HInstruction*>* GetLocalsForWithAllocation(
99       HBasicBlock* block, ArenaVector<HInstruction*>* locals, const size_t vregs);
100   HInstruction* ValueOfLocalAt(HBasicBlock* block, size_t local);
101   HInstruction* LoadLocal(uint32_t register_index, Primitive::Type type) const;
102   HInstruction* LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc);
103   void UpdateLocal(uint32_t register_index, HInstruction* instruction);
104 
105   void AppendInstruction(HInstruction* instruction);
106   void InsertInstructionAtTop(HInstruction* instruction);
107   void InitializeInstruction(HInstruction* instruction);
108 
109   void InitializeParameters();
110 
111   // Returns whether the current method needs access check for the type.
112   // Output parameter finalizable is set to whether the type is finalizable.
113   bool NeedsAccessCheck(dex::TypeIndex type_index, /*out*/bool* finalizable) const
114       REQUIRES_SHARED(Locks::mutator_lock_);
115 
116   template<typename T>
117   void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
118 
119   template<typename T>
120   void Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
121 
122   template<typename T>
123   void Binop_23x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
124 
125   void Binop_23x_cmp(const Instruction& instruction,
126                      Primitive::Type type,
127                      ComparisonBias bias,
128                      uint32_t dex_pc);
129 
130   template<typename T>
131   void Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
132 
133   template<typename T>
134   void Binop_12x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
135 
136   template<typename T>
137   void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc);
138 
139   template<typename T>
140   void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc);
141 
142   template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
143   template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
144 
145   void Conversion_12x(const Instruction& instruction,
146                       Primitive::Type input_type,
147                       Primitive::Type result_type,
148                       uint32_t dex_pc);
149 
150   void BuildCheckedDivRem(uint16_t out_reg,
151                           uint16_t first_reg,
152                           int64_t second_reg_or_constant,
153                           uint32_t dex_pc,
154                           Primitive::Type type,
155                           bool second_is_lit,
156                           bool is_div);
157 
158   void BuildReturn(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
159 
160   // Builds an instance field access node and returns whether the instruction is supported.
161   bool BuildInstanceFieldAccess(const Instruction& instruction,
162                                 uint32_t dex_pc,
163                                 bool is_put,
164                                 size_t quicken_index);
165 
166   void BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
167                                         uint32_t dex_pc,
168                                         bool is_put,
169                                         Primitive::Type field_type);
170   // Builds a static field access node and returns whether the instruction is supported.
171   bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
172 
173   void BuildArrayAccess(const Instruction& instruction,
174                         uint32_t dex_pc,
175                         bool is_get,
176                         Primitive::Type anticipated_type);
177 
178   // Builds an invocation node and returns whether the instruction is supported.
179   bool BuildInvoke(const Instruction& instruction,
180                    uint32_t dex_pc,
181                    uint32_t method_idx,
182                    uint32_t number_of_vreg_arguments,
183                    bool is_range,
184                    uint32_t* args,
185                    uint32_t register_index);
186 
187   // Builds an invocation node for invoke-polymorphic and returns whether the
188   // instruction is supported.
189   bool BuildInvokePolymorphic(const Instruction& instruction,
190                               uint32_t dex_pc,
191                               uint32_t method_idx,
192                               uint32_t proto_idx,
193                               uint32_t number_of_vreg_arguments,
194                               bool is_range,
195                               uint32_t* args,
196                               uint32_t register_index);
197 
198   // Builds a new array node and the instructions that fill it.
199   HNewArray* BuildFilledNewArray(uint32_t dex_pc,
200                                  dex::TypeIndex type_index,
201                                  uint32_t number_of_vreg_arguments,
202                                  bool is_range,
203                                  uint32_t* args,
204                                  uint32_t register_index);
205 
206   void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
207 
208   // Fills the given object with data as specified in the fill-array-data
209   // instruction. Currently only used for non-reference and non-floating point
210   // arrays.
211   template <typename T>
212   void BuildFillArrayData(HInstruction* object,
213                           const T* data,
214                           uint32_t element_count,
215                           Primitive::Type anticipated_type,
216                           uint32_t dex_pc);
217 
218   // Fills the given object with data as specified in the fill-array-data
219   // instruction. The data must be for long and double arrays.
220   void BuildFillWideArrayData(HInstruction* object,
221                               const int64_t* data,
222                               uint32_t element_count,
223                               uint32_t dex_pc);
224 
225   // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
226   void BuildTypeCheck(const Instruction& instruction,
227                       uint8_t destination,
228                       uint8_t reference,
229                       dex::TypeIndex type_index,
230                       uint32_t dex_pc);
231 
232   // Builds an instruction sequence for a switch statement.
233   void BuildSwitch(const Instruction& instruction, uint32_t dex_pc);
234 
235   // Builds a `HLoadClass` loading the given `type_index`. If `outer` is true,
236   // this method will use the outer class's dex file to lookup the type at
237   // `type_index`.
238   HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc);
239 
240   HLoadClass* BuildLoadClass(dex::TypeIndex type_index,
241                              const DexFile& dex_file,
242                              Handle<mirror::Class> klass,
243                              uint32_t dex_pc,
244                              bool needs_access_check)
245       REQUIRES_SHARED(Locks::mutator_lock_);
246 
247   // Returns the outer-most compiling method's class.
248   mirror::Class* GetOutermostCompilingClass() const;
249 
250   // Returns the class whose method is being compiled.
251   mirror::Class* GetCompilingClass() const;
252 
253   // Returns whether `type_index` points to the outer-most compiling method's class.
254   bool IsOutermostCompilingClass(dex::TypeIndex type_index) const;
255 
256   void PotentiallySimplifyFakeString(uint16_t original_dex_register,
257                                      uint32_t dex_pc,
258                                      HInvoke* invoke);
259 
260   bool SetupInvokeArguments(HInvoke* invoke,
261                             uint32_t number_of_vreg_arguments,
262                             uint32_t* args,
263                             uint32_t register_index,
264                             bool is_range,
265                             const char* descriptor,
266                             size_t start_index,
267                             size_t* argument_index);
268 
269   bool HandleInvoke(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                     HClinitCheck* clinit_check,
276                     bool is_unresolved);
277 
278   bool HandleStringInit(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);
284   void HandleStringInitResult(HInvokeStaticOrDirect* invoke);
285 
286   HClinitCheck* ProcessClinitCheckForInvoke(
287       uint32_t dex_pc,
288       ArtMethod* method,
289       HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
290       REQUIRES_SHARED(Locks::mutator_lock_);
291 
292   // Build a HNewInstance instruction.
293   HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc);
294 
295   // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the
296   // happens-before ordering for default-initialization of the object referred to by new_instance.
297   void BuildConstructorFenceForAllocation(HInstruction* allocation);
298 
299   // Return whether the compiler can assume `cls` is initialized.
300   bool IsInitialized(Handle<mirror::Class> cls) const
301       REQUIRES_SHARED(Locks::mutator_lock_);
302 
303   // Try to resolve a method using the class linker. Return null if a method could
304   // not be resolved.
305   ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
306 
307   // Try to resolve a field using the class linker. Return null if it could not
308   // be found.
309   ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put);
310 
311   ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index,
312                                            const DexCompilationUnit& compilation_unit) const
313       REQUIRES_SHARED(Locks::mutator_lock_);
314 
315   ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_);
316 
317   ArenaAllocator* const arena_;
318   HGraph* const graph_;
319   VariableSizedHandleScope* handles_;
320 
321   // The dex file where the method being compiled is, and the bytecode data.
322   const DexFile* const dex_file_;
323   const DexFile::CodeItem& code_item_;
324 
325   // The return type of the method being compiled.
326   const Primitive::Type return_type_;
327 
328   HBasicBlockBuilder* block_builder_;
329   SsaBuilder* ssa_builder_;
330 
331   ArenaVector<ArenaVector<HInstruction*>> locals_for_;
332   HBasicBlock* current_block_;
333   ArenaVector<HInstruction*>* current_locals_;
334   HInstruction* latest_result_;
335   // Current "this" parameter.
336   // Valid only after InitializeParameters() finishes.
337   // * Null for static methods.
338   // * Non-null for instance methods.
339   HParameterValue* current_this_parameter_;
340 
341   CompilerDriver* const compiler_driver_;
342 
343   CodeGenerator* const code_generator_;
344 
345   // The compilation unit of the current method being compiled. Note that
346   // it can be an inlined method.
347   DexCompilationUnit* const dex_compilation_unit_;
348 
349   // The compilation unit of the outermost method being compiled. That is the
350   // method being compiled (and not inlined), and potentially inlining other
351   // methods.
352   const DexCompilationUnit* const outer_compilation_unit_;
353 
354   // Original values kept after instruction quickening.
355   QuickenInfoTable quicken_info_;
356 
357   OptimizingCompilerStats* compilation_stats_;
358   Handle<mirror::DexCache> dex_cache_;
359 
360   ArenaVector<HBasicBlock*> loop_headers_;
361 
362   static constexpr int kDefaultNumberOfLoops = 2;
363 
364   DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder);
365 };
366 
367 }  // namespace art
368 
369 #endif  // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_
370