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