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