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