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