builder.h revision 48c2b03965830c73cdddeae8aea8030f08430137
1/*
2 * Copyright (C) 2014 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_BUILDER_H_
18#define ART_COMPILER_OPTIMIZING_BUILDER_H_
19
20#include "dex_file.h"
21#include "dex_file-inl.h"
22#include "driver/compiler_driver.h"
23#include "driver/dex_compilation_unit.h"
24#include "optimizing_compiler_stats.h"
25#include "primitive.h"
26#include "utils/arena_object.h"
27#include "utils/growable_array.h"
28#include "nodes.h"
29
30namespace art {
31
32class Instruction;
33class SwitchTable;
34
35class HGraphBuilder : public ValueObject {
36 public:
37  HGraphBuilder(ArenaAllocator* arena,
38                DexCompilationUnit* dex_compilation_unit,
39                const DexFile* dex_file,
40                CompilerDriver* driver,
41                OptimizingCompilerStats* compiler_stats)
42      : arena_(arena),
43        branch_targets_(arena, 0),
44        locals_(arena, 0),
45        entry_block_(nullptr),
46        exit_block_(nullptr),
47        current_block_(nullptr),
48        graph_(nullptr),
49        constant0_(nullptr),
50        constant1_(nullptr),
51        dex_file_(dex_file),
52        dex_compilation_unit_(dex_compilation_unit),
53        compiler_driver_(driver),
54        return_type_(Primitive::GetType(dex_compilation_unit_->GetShorty()[0])),
55        code_start_(nullptr),
56        latest_result_(nullptr),
57        compilation_stats_(compiler_stats) {}
58
59  // Only for unit testing.
60  HGraphBuilder(ArenaAllocator* arena, Primitive::Type return_type = Primitive::kPrimInt)
61      : arena_(arena),
62        branch_targets_(arena, 0),
63        locals_(arena, 0),
64        entry_block_(nullptr),
65        exit_block_(nullptr),
66        current_block_(nullptr),
67        graph_(nullptr),
68        constant0_(nullptr),
69        constant1_(nullptr),
70        dex_file_(nullptr),
71        dex_compilation_unit_(nullptr),
72        compiler_driver_(nullptr),
73        return_type_(return_type),
74        code_start_(nullptr),
75        latest_result_(nullptr),
76        compilation_stats_(nullptr) {}
77
78  HGraph* BuildGraph(const DexFile::CodeItem& code);
79
80 private:
81  // Analyzes the dex instruction and adds HInstruction to the graph
82  // to execute that instruction. Returns whether the instruction can
83  // be handled.
84  bool AnalyzeDexInstruction(const Instruction& instruction, uint32_t dex_pc);
85
86  // Finds all instructions that start a new block, and populates branch_targets_ with
87  // the newly created blocks.
88  // As a side effect, also compute the number of dex instructions, blocks, and
89  // branches.
90  void ComputeBranchTargets(const uint16_t* start,
91                            const uint16_t* end,
92                            size_t* number_of_dex_instructions,
93                            size_t* number_of_block,
94                            size_t* number_of_branches);
95  void MaybeUpdateCurrentBlock(size_t index);
96  HBasicBlock* FindBlockStartingAt(int32_t index) const;
97
98  HIntConstant* GetIntConstant0();
99  HIntConstant* GetIntConstant1();
100  HIntConstant* GetIntConstant(int32_t constant);
101  HLongConstant* GetLongConstant(int64_t constant);
102  void InitializeLocals(uint16_t count);
103  HLocal* GetLocalAt(int register_index) const;
104  void UpdateLocal(int register_index, HInstruction* instruction) const;
105  HInstruction* LoadLocal(int register_index, Primitive::Type type) const;
106  void PotentiallyAddSuspendCheck(int32_t target_offset, uint32_t dex_pc);
107  void InitializeParameters(uint16_t number_of_parameters);
108
109  template<typename T>
110  void Unop_12x(const Instruction& instruction, Primitive::Type type);
111
112  template<typename T>
113  void Binop_23x(const Instruction& instruction, Primitive::Type type);
114
115  template<typename T>
116  void Binop_23x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
117
118  template<typename T>
119  void Binop_23x_shift(const Instruction& instruction, Primitive::Type type);
120
121  void Binop_23x_cmp(const Instruction& instruction, Primitive::Type type, HCompare::Bias bias);
122
123  template<typename T>
124  void Binop_12x(const Instruction& instruction, Primitive::Type type);
125
126  template<typename T>
127  void Binop_12x(const Instruction& instruction, Primitive::Type type, uint32_t dex_pc);
128
129  template<typename T>
130  void Binop_12x_shift(const Instruction& instruction, Primitive::Type type);
131
132  template<typename T>
133  void Binop_22b(const Instruction& instruction, bool reverse);
134
135  template<typename T>
136  void Binop_22s(const Instruction& instruction, bool reverse);
137
138  template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc);
139  template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc);
140
141  void Conversion_12x(const Instruction& instruction,
142                      Primitive::Type input_type,
143                      Primitive::Type result_type,
144                      uint32_t dex_pc);
145
146  void BuildCheckedDivRem(uint16_t out_reg,
147                          uint16_t first_reg,
148                          int64_t second_reg_or_constant,
149                          uint32_t dex_pc,
150                          Primitive::Type type,
151                          bool second_is_lit,
152                          bool is_div);
153
154  void BuildReturn(const Instruction& instruction, Primitive::Type type);
155
156  // Builds an instance field access node and returns whether the instruction is supported.
157  bool BuildInstanceFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
158
159  // Builds a static field access node and returns whether the instruction is supported.
160  bool BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put);
161
162  void BuildArrayAccess(const Instruction& instruction,
163                        uint32_t dex_pc,
164                        bool is_get,
165                        Primitive::Type anticipated_type);
166
167  // Builds an invocation node and returns whether the instruction is supported.
168  bool BuildInvoke(const Instruction& instruction,
169                   uint32_t dex_pc,
170                   uint32_t method_idx,
171                   uint32_t number_of_vreg_arguments,
172                   bool is_range,
173                   uint32_t* args,
174                   uint32_t register_index);
175
176  // Builds a new array node and the instructions that fill it.
177  void BuildFilledNewArray(uint32_t dex_pc,
178                           uint32_t type_index,
179                           uint32_t number_of_vreg_arguments,
180                           bool is_range,
181                           uint32_t* args,
182                           uint32_t register_index);
183
184  void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc);
185
186  // Fills the given object with data as specified in the fill-array-data
187  // instruction. Currently only used for non-reference and non-floating point
188  // arrays.
189  template <typename T>
190  void BuildFillArrayData(HInstruction* object,
191                          const T* data,
192                          uint32_t element_count,
193                          Primitive::Type anticipated_type,
194                          uint32_t dex_pc);
195
196  // Fills the given object with data as specified in the fill-array-data
197  // instruction. The data must be for long and double arrays.
198  void BuildFillWideArrayData(HInstruction* object,
199                              const int64_t* data,
200                              uint32_t element_count,
201                              uint32_t dex_pc);
202
203  // Builds a `HInstanceOf`, or a `HCheckCast` instruction.
204  // Returns whether we succeeded in building the instruction.
205  bool BuildTypeCheck(const Instruction& instruction,
206                      uint8_t destination,
207                      uint8_t reference,
208                      uint16_t type_index,
209                      uint32_t dex_pc);
210
211  // Builds an instruction sequence for a packed switch statement.
212  void BuildPackedSwitch(const Instruction& instruction, uint32_t dex_pc);
213
214  // Builds an instruction sequence for a sparse switch statement.
215  void BuildSparseSwitch(const Instruction& instruction, uint32_t dex_pc);
216
217  void BuildSwitchCaseHelper(const Instruction& instruction, size_t index,
218                             bool is_last_case, const SwitchTable& table,
219                             HInstruction* value, int32_t case_value_int,
220                             int32_t target_offset, uint32_t dex_pc);
221
222  bool SkipCompilation(size_t number_of_dex_instructions,
223                       size_t number_of_blocks,
224                       size_t number_of_branches);
225
226  void MaybeRecordStat(MethodCompilationStat compilation_stat);
227
228  ArenaAllocator* const arena_;
229
230  // A list of the size of the dex code holding block information for
231  // the method. If an entry contains a block, then the dex instruction
232  // starting at that entry is the first instruction of a new block.
233  GrowableArray<HBasicBlock*> branch_targets_;
234
235  GrowableArray<HLocal*> locals_;
236
237  HBasicBlock* entry_block_;
238  HBasicBlock* exit_block_;
239  HBasicBlock* current_block_;
240  HGraph* graph_;
241
242  HIntConstant* constant0_;
243  HIntConstant* constant1_;
244
245  const DexFile* const dex_file_;
246  DexCompilationUnit* const dex_compilation_unit_;
247  CompilerDriver* const compiler_driver_;
248  const Primitive::Type return_type_;
249
250  // The pointer in the dex file where the instructions of the code item
251  // being currently compiled start.
252  const uint16_t* code_start_;
253
254  // The last invoke or fill-new-array being built. Only to be
255  // used by move-result instructions.
256  HInstruction* latest_result_;
257
258  OptimizingCompilerStats* compilation_stats_;
259
260  DISALLOW_COPY_AND_ASSIGN(HGraphBuilder);
261};
262
263}  // namespace art
264
265#endif  // ART_COMPILER_OPTIMIZING_BUILDER_H_
266