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