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 30 namespace art { 31 32 class ArenaBitVector; 33 class ArtField; 34 class ArtMethod; 35 class CodeGenerator; 36 class DexCompilationUnit; 37 class HBasicBlockBuilder; 38 class Instruction; 39 class InstructionOperands; 40 class OptimizingCompilerStats; 41 class ScopedObjectAccess; 42 class SsaBuilder; 43 44 namespace mirror { 45 class Class; 46 class MethodType; 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 CodeGenerator* code_generator, 60 OptimizingCompilerStats* compiler_stats, 61 ScopedArenaAllocator* local_allocator); 62 63 bool Build(); 64 void BuildIntrinsic(ArtMethod* method); 65 66 private: 67 void InitializeBlockLocals(); 68 void PropagateLocalsToCatchBlocks(); 69 void SetLoopHeaderPhiInputs(); 70 71 bool ProcessDexInstruction(const Instruction& instruction, uint32_t dex_pc); 72 ArenaBitVector* FindNativeDebugInfoLocations(); 73 74 HBasicBlock* FindBlockStartingAt(uint32_t dex_pc) const; 75 76 ScopedArenaVector<HInstruction*>* GetLocalsFor(HBasicBlock* block); 77 // Out of line version of GetLocalsFor(), which has a fast path that is 78 // beneficial to get inlined by callers. 79 ScopedArenaVector<HInstruction*>* GetLocalsForWithAllocation( 80 HBasicBlock* block, ScopedArenaVector<HInstruction*>* locals, const size_t vregs); 81 HInstruction* ValueOfLocalAt(HBasicBlock* block, size_t local); 82 HInstruction* LoadLocal(uint32_t register_index, DataType::Type type) const; 83 HInstruction* LoadNullCheckedLocal(uint32_t register_index, uint32_t dex_pc); 84 void UpdateLocal(uint32_t register_index, HInstruction* instruction); 85 86 void AppendInstruction(HInstruction* instruction); 87 void InsertInstructionAtTop(HInstruction* instruction); 88 void InitializeInstruction(HInstruction* instruction); 89 90 void InitializeParameters(); 91 92 template<typename T> 93 void Unop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 94 95 template<typename T> 96 void Binop_23x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 97 98 template<typename T> 99 void Binop_23x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 100 101 void Binop_23x_cmp(const Instruction& instruction, 102 DataType::Type type, 103 ComparisonBias bias, 104 uint32_t dex_pc); 105 106 template<typename T> 107 void Binop_12x(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 108 109 template<typename T> 110 void Binop_12x_shift(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 111 112 template<typename T> 113 void Binop_22b(const Instruction& instruction, bool reverse, uint32_t dex_pc); 114 115 template<typename T> 116 void Binop_22s(const Instruction& instruction, bool reverse, uint32_t dex_pc); 117 118 template<typename T> void If_21t(const Instruction& instruction, uint32_t dex_pc); 119 template<typename T> void If_22t(const Instruction& instruction, uint32_t dex_pc); 120 121 void Conversion_12x(const Instruction& instruction, 122 DataType::Type input_type, 123 DataType::Type result_type, 124 uint32_t dex_pc); 125 126 void BuildCheckedDivRem(uint16_t out_reg, 127 uint16_t first_reg, 128 int64_t second_reg_or_constant, 129 uint32_t dex_pc, 130 DataType::Type type, 131 bool second_is_lit, 132 bool is_div); 133 134 void BuildReturn(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 135 136 // Builds an instance field access node and returns whether the instruction is supported. 137 bool BuildInstanceFieldAccess(const Instruction& instruction, 138 uint32_t dex_pc, 139 bool is_put); 140 141 void BuildUnresolvedStaticFieldAccess(const Instruction& instruction, 142 uint32_t dex_pc, 143 bool is_put, 144 DataType::Type field_type); 145 // Builds a static field access node. 146 void BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put); 147 148 void BuildArrayAccess(const Instruction& instruction, 149 uint32_t dex_pc, 150 bool is_get, 151 DataType::Type anticipated_type); 152 153 // Builds an invocation node and returns whether the instruction is supported. 154 bool BuildInvoke(const Instruction& instruction, 155 uint32_t dex_pc, 156 uint32_t method_idx, 157 const InstructionOperands& operands); 158 159 // Builds an invocation node for invoke-polymorphic and returns whether the 160 // instruction is supported. 161 bool BuildInvokePolymorphic(uint32_t dex_pc, 162 uint32_t method_idx, 163 dex::ProtoIndex proto_idx, 164 const InstructionOperands& operands); 165 166 // Builds an invocation node for invoke-custom and returns whether the 167 // instruction is supported. 168 bool BuildInvokeCustom(uint32_t dex_pc, 169 uint32_t call_site_idx, 170 const InstructionOperands& operands); 171 172 // Builds a new array node. 173 HNewArray* BuildNewArray(uint32_t dex_pc, dex::TypeIndex type_index, HInstruction* length); 174 175 // Builds a new array node and the instructions that fill it. 176 HNewArray* BuildFilledNewArray(uint32_t dex_pc, 177 dex::TypeIndex type_index, 178 const InstructionOperands& operands); 179 180 void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc); 181 182 // Fills the given object with data as specified in the fill-array-data 183 // instruction. Currently only used for non-reference and non-floating point 184 // arrays. 185 template <typename T> 186 void BuildFillArrayData(HInstruction* object, 187 const T* data, 188 uint32_t element_count, 189 DataType::Type anticipated_type, 190 uint32_t dex_pc); 191 192 // Fills the given object with data as specified in the fill-array-data 193 // instruction. The data must be for long and double arrays. 194 void BuildFillWideArrayData(HInstruction* object, 195 const int64_t* data, 196 uint32_t element_count, 197 uint32_t dex_pc); 198 199 // Builds a `HInstanceOf`, or a `HCheckCast` instruction. 200 void BuildTypeCheck(bool is_instance_of, 201 HInstruction* object, 202 dex::TypeIndex type_index, 203 uint32_t dex_pc); 204 void BuildTypeCheck(const Instruction& instruction, 205 uint8_t destination, 206 uint8_t reference, 207 dex::TypeIndex type_index, 208 uint32_t dex_pc); 209 210 // Builds an instruction sequence for a switch statement. 211 void BuildSwitch(const Instruction& instruction, uint32_t dex_pc); 212 213 // Builds a `HLoadString` loading the given `string_index`. 214 void BuildLoadString(dex::StringIndex string_index, uint32_t dex_pc); 215 216 // Builds a `HLoadClass` loading the given `type_index`. 217 HLoadClass* BuildLoadClass(dex::TypeIndex type_index, uint32_t dex_pc); 218 219 HLoadClass* BuildLoadClass(dex::TypeIndex type_index, 220 const DexFile& dex_file, 221 Handle<mirror::Class> klass, 222 uint32_t dex_pc, 223 bool needs_access_check) 224 REQUIRES_SHARED(Locks::mutator_lock_); 225 226 Handle<mirror::Class> ResolveClass(ScopedObjectAccess& soa, dex::TypeIndex type_index) 227 REQUIRES_SHARED(Locks::mutator_lock_); 228 229 bool LoadClassNeedsAccessCheck(dex::TypeIndex type_index, ObjPtr<mirror::Class> klass) 230 REQUIRES_SHARED(Locks::mutator_lock_); 231 232 // Builds a `HLoadMethodHandle` loading the given `method_handle_index`. 233 void BuildLoadMethodHandle(uint16_t method_handle_idx, uint32_t dex_pc); 234 235 // Builds a `HLoadMethodType` loading the given `proto_index`. 236 void BuildLoadMethodType(dex::ProtoIndex proto_index, uint32_t dex_pc); 237 238 void PotentiallySimplifyFakeString(uint16_t original_dex_register, 239 uint32_t dex_pc, 240 HInvoke* invoke); 241 242 enum class ReceiverArg { 243 kNone, // No receiver, static method. 244 kNullCheckedArg, // Normal instance invoke, null check and pass the argument. 245 kNullCheckedOnly, // Null check but do not use the arg, used for intrinsic replacements. 246 kPlainArg, // Do not null check but pass the argument, used for unresolved methods. 247 kIgnored, // No receiver despite allocated vreg, used for String.<init>. 248 }; 249 bool SetupInvokeArguments(HInstruction* invoke, 250 const InstructionOperands& operands, 251 const char* shorty, 252 ReceiverArg receiver_arg); 253 254 bool HandleInvoke(HInvoke* invoke, 255 const InstructionOperands& operands, 256 const char* shorty, 257 bool is_unresolved); 258 259 bool HandleStringInit(HInvoke* invoke, 260 const InstructionOperands& operands, 261 const char* shorty); 262 void HandleStringInitResult(HInvokeStaticOrDirect* invoke); 263 264 HClinitCheck* ProcessClinitCheckForInvoke( 265 uint32_t dex_pc, 266 ArtMethod* method, 267 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement); 268 269 // Try to build a replacement for an intrinsic invoke. Returns true on success, 270 // false on failure. Failure can be either lack of replacement HIR classes, or 271 // input register mismatch. 272 bool BuildSimpleIntrinsic(ArtMethod* method, 273 uint32_t dex_pc, 274 const InstructionOperands& operands, 275 const char* shorty); 276 277 // Build a HNewInstance instruction. 278 HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc); 279 280 // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the 281 // happens-before ordering for default-initialization of the object referred to by new_instance. 282 void BuildConstructorFenceForAllocation(HInstruction* allocation); 283 284 // Return whether the compiler can assume `cls` is initialized. 285 bool IsInitialized(ObjPtr<mirror::Class> cls) const 286 REQUIRES_SHARED(Locks::mutator_lock_); 287 288 // Try to resolve a field using the class linker. Return null if it could not 289 // be found. 290 ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put); 291 292 ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index, 293 const DexCompilationUnit& compilation_unit) const 294 REQUIRES_SHARED(Locks::mutator_lock_); 295 296 ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_); 297 298 ArenaAllocator* const allocator_; 299 HGraph* const graph_; 300 301 // The dex file where the method being compiled is, and the bytecode data. 302 const DexFile* const dex_file_; 303 const CodeItemDebugInfoAccessor code_item_accessor_; // null for intrinsic graph. 304 305 // The return type of the method being compiled. 306 const DataType::Type return_type_; 307 308 HBasicBlockBuilder* const block_builder_; 309 SsaBuilder* const ssa_builder_; 310 311 CodeGenerator* const code_generator_; 312 313 // The compilation unit of the current method being compiled. Note that 314 // it can be an inlined method. 315 const DexCompilationUnit* const dex_compilation_unit_; 316 317 // The compilation unit of the outermost method being compiled. That is the 318 // method being compiled (and not inlined), and potentially inlining other 319 // methods. 320 const DexCompilationUnit* const outer_compilation_unit_; 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 `graph_->GetHandleCache()`. 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