• 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 "driver/compiler_driver.h"
24 #include "driver/compiler_driver-inl.h"
25 #include "driver/dex_compilation_unit.h"
26 #include "mirror/dex_cache.h"
27 #include "nodes.h"
28 #include "optimizing_compiler_stats.h"
29 #include "ssa_builder.h"
30 
31 namespace art {
32 
33 class HInstructionBuilder : public ValueObject {
34  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,const uint8_t * interpreter_metadata,OptimizingCompilerStats * compiler_stats,Handle<mirror::DexCache> dex_cache)35   HInstructionBuilder(HGraph* graph,
36                       HBasicBlockBuilder* block_builder,
37                       SsaBuilder* ssa_builder,
38                       const DexFile* dex_file,
39                       const DexFile::CodeItem& code_item,
40                       Primitive::Type return_type,
41                       DexCompilationUnit* dex_compilation_unit,
42                       const DexCompilationUnit* const outer_compilation_unit,
43                       CompilerDriver* driver,
44                       const uint8_t* interpreter_metadata,
45                       OptimizingCompilerStats* compiler_stats,
46                       Handle<mirror::DexCache> dex_cache)
47       : arena_(graph->GetArena()),
48         graph_(graph),
49         dex_file_(dex_file),
50         code_item_(code_item),
51         return_type_(return_type),
52         block_builder_(block_builder),
53         ssa_builder_(ssa_builder),
54         locals_for_(arena_->Adapter(kArenaAllocGraphBuilder)),
55         current_block_(nullptr),
56         current_locals_(nullptr),
57         latest_result_(nullptr),
58         compiler_driver_(driver),
59         dex_compilation_unit_(dex_compilation_unit),
60         outer_compilation_unit_(outer_compilation_unit),
61         interpreter_metadata_(interpreter_metadata),
62         skipped_interpreter_metadata_(std::less<uint32_t>(),
63                                       arena_->Adapter(kArenaAllocGraphBuilder)),
64         compilation_stats_(compiler_stats),
65         dex_cache_(dex_cache),
66         loop_headers_(graph->GetArena()->Adapter(kArenaAllocGraphBuilder)) {
67     loop_headers_.reserve(kDefaultNumberOfLoops);
68   }
69 
70   bool Build();
71 
72  private:
73   void MaybeRecordStat(MethodCompilationStat compilation_stat);
74 
75   void InitializeBlockLocals();
76   void PropagateLocalsToCatchBlocks();
77   void SetLoopHeaderPhiInputs();
78 
79   bool ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc);
80   void FindNativeDebugInfoLocations(ArenaBitVector* locations);
81 
82   bool CanDecodeQuickenedInfo() const;
83   uint16_t LookupQuickenedInfo(uint32_t dex_pc);
84 
85   HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const;
86 
87   ArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block);
88   HInstruction* ValueOfLocalAt(HBasicBlock* block, size_t local);
89   HInstruction* LoadLocal(uint32_t register_index, Primitive::Type type) const;
90   HInstruction* LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc);
91   void UpdateLocal(uint32_t register_index, HInstruction* instruction);
92 
93   void AppendInstruction(HInstruction* instruction);
94   void InsertInstructionAtTop(HInstruction* instruction);
95   void InitializeInstruction(HInstruction* instruction);
96 
97   void InitializeParameters();
98 
99   // Returns whether the current method needs access check for the type.
100   // Output parameter finalizable is set to whether the type is finalizable.
101   bool NeedsAccessCheck(uint32_t type_index,
102                         Handle<mirror::DexCache> dex_cache,
103                         /*out*/bool* finalizable) const
104       SHARED_REQUIRES(Locks::mutator_lock_);
105   bool NeedsAccessCheck(uint32_t type_index, /*out*/bool* finalizable) const;
106 
107   template<typename T>
108   void Unop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
109 
110   template<typename T>
111   void Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
112 
113   template<typename T>
114   void Binop_23x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
115 
116   void Binop_23x_cmp(const Instruction& instruction,
117                      Primitive::Type type,
118                      ComparisonBias bias,
119                      uint32_t dex_pc);
120 
121   template<typename T>
122   void Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
123 
124   template<typename T>
125   void Binop_12x_shift(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
126 
127   template<typename T>
128   void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc);
129 
130   template<typename T>
131   void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc);
132 
133   template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
134   template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
135 
136   void Conversion_12x(const Instruction& instruction,
137                       Primitive::Type input_type,
138                       Primitive::Type result_type,
139                       uint32_t dex_pc);
140 
141   void BuildCheckedDivRem(uint16_t out_reg,
142                           uint16_t first_reg,
143                           int64_t second_reg_or_constant,
144                           uint32_t dex_pc,
145                           Primitive::Type type,
146                           bool second_is_lit,
147                           bool is_div);
148 
149   void BuildReturn(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
150 
151   // Builds an instance field access node and returns whether the instruction is supported.
152   bool BuildInstanceFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
153 
154   void BuildUnresolvedStaticFieldAccess(const Instruction& instruction,
155                                         uint32_t dex_pc,
156                                         bool is_put,
157                                         Primitive::Type field_type);
158   // Builds a static field access node and returns whether the instruction is supported.
159   bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
160 
161   void BuildArrayAccess(const Instruction& instruction,
162                         uint32_t dex_pc,
163                         bool is_get,
164                         Primitive::Type anticipated_type);
165 
166   // Builds an invocation node and returns whether the instruction is supported.
167   bool BuildInvoke(const Instruction& instruction,
168                    uint32_t dex_pc,
169                    uint32_t method_idx,
170                    uint32_t number_of_vreg_arguments,
171                    bool is_range,
172                    uint32_t* args,
173                    uint32_t register_index);
174 
175   // Builds a new array node and the instructions that fill it.
176   void BuildFilledNewArray(uint32_t dex_pc,
177                            uint32_t type_index,
178                            uint32_t number_of_vreg_arguments,
179                            bool is_range,
180                            uint32_t* args,
181                            uint32_t register_index);
182 
183   void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
184 
185   // Fills the given object with data as specified in the fill-array-data
186   // instruction. Currently only used for non-reference and non-floating point
187   // arrays.
188   template <typename T>
189   void BuildFillArrayData(HInstruction* object,
190                           const T* data,
191                           uint32_t element_count,
192                           Primitive::Type anticipated_type,
193                           uint32_t dex_pc);
194 
195   // Fills the given object with data as specified in the fill-array-data
196   // instruction. The data must be for long and double arrays.
197   void BuildFillWideArrayData(HInstruction* object,
198                               const int64_t* data,
199                               uint32_t element_count,
200                               uint32_t dex_pc);
201 
202   // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
203   void BuildTypeCheck(const Instruction& instruction,
204                       uint8_t destination,
205                       uint8_t reference,
206                       uint16_t type_index,
207                       uint32_t dex_pc);
208 
209   // Builds an instruction sequence for a switch statement.
210   void BuildSwitch(const Instruction& instruction, uint32_t dex_pc);
211 
212   // Returns the outer-most compiling method's class.
213   mirror::Class* GetOutermostCompilingClass() const;
214 
215   // Returns the class whose method is being compiled.
216   mirror::Class* GetCompilingClass() const;
217 
218   // Returns whether `type_index` points to the outer-most compiling method's class.
219   bool IsOutermostCompilingClass(uint16_t type_index) const;
220 
221   void PotentiallySimplifyFakeString(uint16_t original_dex_register,
222                                      uint32_t dex_pc,
223                                      HInvoke* invoke);
224 
225   bool SetupInvokeArguments(HInvoke* invoke,
226                             uint32_t number_of_vreg_arguments,
227                             uint32_t* args,
228                             uint32_t register_index,
229                             bool is_range,
230                             const char* descriptor,
231                             size_t start_index,
232                             size_t* argument_index);
233 
234   bool HandleInvoke(HInvoke* invoke,
235                     uint32_t number_of_vreg_arguments,
236                     uint32_t* args,
237                     uint32_t register_index,
238                     bool is_range,
239                     const char* descriptor,
240                     HClinitCheck* clinit_check);
241 
242   bool HandleStringInit(HInvoke* invoke,
243                         uint32_t number_of_vreg_arguments,
244                         uint32_t* args,
245                         uint32_t register_index,
246                         bool is_range,
247                         const char* descriptor);
248   void HandleStringInitResult(HInvokeStaticOrDirect* invoke);
249 
250   HClinitCheck* ProcessClinitCheckForInvoke(
251       uint32_t dex_pc,
252       ArtMethod* method,
253       uint32_t method_idx,
254       HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement)
255       SHARED_REQUIRES(Locks::mutator_lock_);
256 
257   // Build a HNewInstance instruction.
258   bool BuildNewInstance(uint16_t type_index, uint32_t dex_pc);
259 
260   // Return whether the compiler can assume `cls` is initialized.
261   bool IsInitialized(Handle<mirror::Class> cls) const
262       SHARED_REQUIRES(Locks::mutator_lock_);
263 
264   // Try to resolve a method using the class linker. Return null if a method could
265   // not be resolved.
266   ArtMethod* ResolveMethod(uint16_t method_idx, InvokeType invoke_type);
267 
268   ArenaAllocator* const arena_;
269   HGraph* const graph_;
270 
271   // The dex file where the method being compiled is, and the bytecode data.
272   const DexFile* const dex_file_;
273   const DexFile::CodeItem& code_item_;
274 
275   // The return type of the method being compiled.
276   const Primitive::Type return_type_;
277 
278   HBasicBlockBuilder* block_builder_;
279   SsaBuilder* ssa_builder_;
280 
281   ArenaVector<ArenaVector<HInstruction*>> locals_for_;
282   HBasicBlock* current_block_;
283   ArenaVector<HInstruction*>* current_locals_;
284   HInstruction* latest_result_;
285 
286   CompilerDriver* const compiler_driver_;
287 
288   // The compilation unit of the current method being compiled. Note that
289   // it can be an inlined method.
290   DexCompilationUnit* const dex_compilation_unit_;
291 
292   // The compilation unit of the outermost method being compiled. That is the
293   // method being compiled (and not inlined), and potentially inlining other
294   // methods.
295   const DexCompilationUnit* const outer_compilation_unit_;
296 
297   // Original values kept after instruction quickening. This is a data buffer
298   // of Leb128-encoded (dex_pc, value) pairs sorted by dex_pc.
299   const uint8_t* interpreter_metadata_;
300 
301   // InstructionBuilder does not parse instructions in dex_pc order. Quickening
302   // info for out-of-order dex_pcs is stored in a map until the positions
303   // are eventually visited.
304   ArenaSafeMap<uint32_t, uint16_t> skipped_interpreter_metadata_;
305 
306   OptimizingCompilerStats* compilation_stats_;
307   Handle<mirror::DexCache> dex_cache_;
308 
309   ArenaVector<HBasicBlock*> loop_headers_;
310 
311   static constexpr int kDefaultNumberOfLoops = 2;
312 
313   DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder);
314 };
315 
316 }  // namespace art
317 
318 #endif  // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_
319