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