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 template <DataType::Type type> 136 void BuildMove(uint32_t dest_reg, uint32_t src_reg); 137 138 void BuildReturn(const Instruction& instruction, DataType::Type type, uint32_t dex_pc); 139 140 // Builds an instance field access node and returns whether the instruction is supported. 141 bool BuildInstanceFieldAccess(const Instruction& instruction, 142 uint32_t dex_pc, 143 bool is_put); 144 145 void BuildUnresolvedStaticFieldAccess(const Instruction& instruction, 146 uint32_t dex_pc, 147 bool is_put, 148 DataType::Type field_type); 149 // Builds a static field access node. 150 void BuildStaticFieldAccess(const Instruction& instruction, uint32_t dex_pc, bool is_put); 151 152 void BuildArrayAccess(const Instruction& instruction, 153 uint32_t dex_pc, 154 bool is_get, 155 DataType::Type anticipated_type); 156 157 // Builds an invocation node and returns whether the instruction is supported. 158 bool BuildInvoke(const Instruction& instruction, 159 uint32_t dex_pc, 160 uint32_t method_idx, 161 const InstructionOperands& operands); 162 163 // Builds an invocation node for invoke-polymorphic and returns whether the 164 // instruction is supported. 165 bool BuildInvokePolymorphic(uint32_t dex_pc, 166 uint32_t method_idx, 167 dex::ProtoIndex proto_idx, 168 const InstructionOperands& operands); 169 170 // Builds an invocation node for invoke-custom and returns whether the 171 // instruction is supported. 172 bool BuildInvokeCustom(uint32_t dex_pc, 173 uint32_t call_site_idx, 174 const InstructionOperands& operands); 175 176 // Builds a new array node. 177 HNewArray* BuildNewArray(uint32_t dex_pc, dex::TypeIndex type_index, HInstruction* length); 178 179 // Builds a new array node and the instructions that fill it. 180 HNewArray* BuildFilledNewArray(uint32_t dex_pc, 181 dex::TypeIndex type_index, 182 const InstructionOperands& operands); 183 184 void BuildFillArrayData(const Instruction& instruction, uint32_t dex_pc); 185 186 // Fills the given object with data as specified in the fill-array-data 187 // instruction. Currently only used for non-reference and non-floating point 188 // arrays. 189 template <typename T> 190 void BuildFillArrayData(HInstruction* object, 191 const T* data, 192 uint32_t element_count, 193 DataType::Type anticipated_type, 194 uint32_t dex_pc); 195 196 // Fills the given object with data as specified in the fill-array-data 197 // instruction. The data must be for long and double arrays. 198 void BuildFillWideArrayData(HInstruction* object, 199 const int64_t* data, 200 uint32_t element_count, 201 uint32_t dex_pc); 202 203 // Builds a `HInstanceOf`, or a `HCheckCast` instruction. 204 void BuildTypeCheck(bool is_instance_of, 205 HInstruction* object, 206 dex::TypeIndex type_index, 207 uint32_t dex_pc); 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(dex::TypeIndex type_index, ObjPtr<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 enum class ReceiverArg { 247 kNone, // No receiver, static method. 248 kNullCheckedArg, // Normal instance invoke, null check and pass the argument. 249 kNullCheckedOnly, // Null check but do not use the arg, used for intrinsic replacements. 250 kPlainArg, // Do not null check but pass the argument, used for unresolved methods. 251 kIgnored, // No receiver despite allocated vreg, used for String.<init>. 252 }; 253 bool SetupInvokeArguments(HInstruction* invoke, 254 const InstructionOperands& operands, 255 const char* shorty, 256 ReceiverArg receiver_arg); 257 258 bool HandleInvoke(HInvoke* invoke, 259 const InstructionOperands& operands, 260 const char* shorty, 261 bool is_unresolved); 262 263 bool HandleStringInit(HInvoke* invoke, 264 const InstructionOperands& operands, 265 const char* shorty); 266 void HandleStringInitResult(HInvokeStaticOrDirect* invoke); 267 268 HClinitCheck* ProcessClinitCheckForInvoke( 269 uint32_t dex_pc, 270 ArtMethod* method, 271 HInvokeStaticOrDirect::ClinitCheckRequirement* clinit_check_requirement); 272 273 // Try to build a replacement for an intrinsic invoke. Returns true on success, 274 // false on failure. Failure can be either lack of replacement HIR classes, or 275 // input register mismatch. 276 bool BuildSimpleIntrinsic(ArtMethod* method, 277 uint32_t dex_pc, 278 const InstructionOperands& operands, 279 const char* shorty); 280 281 // Build a HNewInstance instruction. 282 HNewInstance* BuildNewInstance(dex::TypeIndex type_index, uint32_t dex_pc); 283 284 // Build a HConstructorFence for HNewInstance and HNewArray instructions. This ensures the 285 // happens-before ordering for default-initialization of the object referred to by new_instance. 286 void BuildConstructorFenceForAllocation(HInstruction* allocation); 287 288 // Return whether the compiler can assume `cls` is initialized. 289 bool IsInitialized(ObjPtr<mirror::Class> cls) const 290 REQUIRES_SHARED(Locks::mutator_lock_); 291 292 // Try to resolve a field using the class linker. Return null if it could not 293 // be found. 294 ArtField* ResolveField(uint16_t field_idx, bool is_static, bool is_put); 295 296 ObjPtr<mirror::Class> LookupResolvedType(dex::TypeIndex type_index, 297 const DexCompilationUnit& compilation_unit) const 298 REQUIRES_SHARED(Locks::mutator_lock_); 299 300 ObjPtr<mirror::Class> LookupReferrerClass() const REQUIRES_SHARED(Locks::mutator_lock_); 301 302 ArenaAllocator* const allocator_; 303 HGraph* const graph_; 304 305 // The dex file where the method being compiled is, and the bytecode data. 306 const DexFile* const dex_file_; 307 const CodeItemDebugInfoAccessor code_item_accessor_; // null for intrinsic graph. 308 309 // The return type of the method being compiled. 310 const DataType::Type return_type_; 311 312 HBasicBlockBuilder* const block_builder_; 313 SsaBuilder* const ssa_builder_; 314 315 CodeGenerator* const code_generator_; 316 317 // The compilation unit of the current method being compiled. Note that 318 // it can be an inlined method. 319 const DexCompilationUnit* const dex_compilation_unit_; 320 321 // The compilation unit of the outermost method being compiled. That is the 322 // method being compiled (and not inlined), and potentially inlining other 323 // methods. 324 const DexCompilationUnit* const outer_compilation_unit_; 325 326 OptimizingCompilerStats* const compilation_stats_; 327 328 ScopedArenaAllocator* const local_allocator_; 329 ScopedArenaVector<ScopedArenaVector<HInstruction*>> locals_for_; 330 HBasicBlock* current_block_; 331 ScopedArenaVector<HInstruction*>* current_locals_; 332 HInstruction* latest_result_; 333 // Current "this" parameter. 334 // Valid only after InitializeParameters() finishes. 335 // * Null for static methods. 336 // * Non-null for instance methods. 337 HParameterValue* current_this_parameter_; 338 339 ScopedArenaVector<HBasicBlock*> loop_headers_; 340 341 // Cached resolved types for the current compilation unit's DexFile. 342 // Handle<>s reference entries in the `graph_->GetHandleCache()`. 343 ScopedArenaSafeMap<dex::TypeIndex, Handle<mirror::Class>> class_cache_; 344 345 static constexpr int kDefaultNumberOfLoops = 2; 346 347 DISALLOW_COPY_AND_ASSIGN(HInstructionBuilder); 348 }; 349 350 } // namespace art 351 352 #endif // ART_COMPILER_OPTIMIZING_INSTRUCTION_BUILDER_H_ 353