1 /* 2 * Copyright (C) 2014 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_NODES_H_ 18 #define ART_COMPILER_OPTIMIZING_NODES_H_ 19 20 #include <algorithm> 21 #include <array> 22 #include <type_traits> 23 24 #include "art_method.h" 25 #include "base/arena_allocator.h" 26 #include "base/arena_bit_vector.h" 27 #include "base/arena_containers.h" 28 #include "base/arena_object.h" 29 #include "base/array_ref.h" 30 #include "base/intrusive_forward_list.h" 31 #include "base/iteration_range.h" 32 #include "base/macros.h" 33 #include "base/mutex.h" 34 #include "base/quasi_atomic.h" 35 #include "base/stl_util.h" 36 #include "base/transform_array_ref.h" 37 #include "block_namer.h" 38 #include "class_root.h" 39 #include "compilation_kind.h" 40 #include "data_type.h" 41 #include "deoptimization_kind.h" 42 #include "dex/dex_file.h" 43 #include "dex/dex_file_types.h" 44 #include "dex/invoke_type.h" 45 #include "dex/method_reference.h" 46 #include "entrypoints/quick/quick_entrypoints_enum.h" 47 #include "handle.h" 48 #include "handle_scope.h" 49 #include "intrinsics_enum.h" 50 #include "locations.h" 51 #include "mirror/class.h" 52 #include "mirror/method_type.h" 53 #include "offsets.h" 54 55 namespace art HIDDEN { 56 57 class ArenaStack; 58 class CodeGenerator; 59 class GraphChecker; 60 class HBasicBlock; 61 class HConstructorFence; 62 class HCurrentMethod; 63 class HDoubleConstant; 64 class HEnvironment; 65 class HFloatConstant; 66 class HGraphBuilder; 67 class HGraphVisitor; 68 class HInstruction; 69 class HIntConstant; 70 class HInvoke; 71 class HLongConstant; 72 class HNullConstant; 73 class HParameterValue; 74 class HPhi; 75 class HSuspendCheck; 76 class HTryBoundary; 77 class FieldInfo; 78 class LiveInterval; 79 class LocationSummary; 80 class ProfilingInfo; 81 class SlowPathCode; 82 class SsaBuilder; 83 84 namespace mirror { 85 class DexCache; 86 } // namespace mirror 87 88 static const int kDefaultNumberOfBlocks = 8; 89 static const int kDefaultNumberOfSuccessors = 2; 90 static const int kDefaultNumberOfPredecessors = 2; 91 static const int kDefaultNumberOfExceptionalPredecessors = 0; 92 static const int kDefaultNumberOfDominatedBlocks = 1; 93 static const int kDefaultNumberOfBackEdges = 1; 94 95 // The maximum (meaningful) distance (31) that can be used in an integer shift/rotate operation. 96 static constexpr int32_t kMaxIntShiftDistance = 0x1f; 97 // The maximum (meaningful) distance (63) that can be used in a long shift/rotate operation. 98 static constexpr int32_t kMaxLongShiftDistance = 0x3f; 99 100 static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1); 101 static constexpr uint16_t kUnknownClassDefIndex = static_cast<uint16_t>(-1); 102 103 static constexpr InvokeType kInvalidInvokeType = static_cast<InvokeType>(-1); 104 105 static constexpr uint32_t kNoDexPc = -1; 106 IsSameDexFile(const DexFile & lhs,const DexFile & rhs)107 inline bool IsSameDexFile(const DexFile& lhs, const DexFile& rhs) { 108 // For the purposes of the compiler, the dex files must actually be the same object 109 // if we want to safely treat them as the same. This is especially important for JIT 110 // as custom class loaders can open the same underlying file (or memory) multiple 111 // times and provide different class resolution but no two class loaders should ever 112 // use the same DexFile object - doing so is an unsupported hack that can lead to 113 // all sorts of weird failures. 114 return &lhs == &rhs; 115 } 116 117 enum IfCondition { 118 // All types. 119 kCondEQ, // == 120 kCondNE, // != 121 // Signed integers and floating-point numbers. 122 kCondLT, // < 123 kCondLE, // <= 124 kCondGT, // > 125 kCondGE, // >= 126 // Unsigned integers. 127 kCondB, // < 128 kCondBE, // <= 129 kCondA, // > 130 kCondAE, // >= 131 // First and last aliases. 132 kCondFirst = kCondEQ, 133 kCondLast = kCondAE, 134 }; 135 136 enum GraphAnalysisResult { 137 kAnalysisSkipped, 138 kAnalysisInvalidBytecode, 139 kAnalysisFailThrowCatchLoop, 140 kAnalysisFailAmbiguousArrayOp, 141 kAnalysisFailIrreducibleLoopAndStringInit, 142 kAnalysisFailPhiEquivalentInOsr, 143 kAnalysisSuccess, 144 }; 145 146 std::ostream& operator<<(std::ostream& os, GraphAnalysisResult ga); 147 148 template <typename T> MakeUnsigned(T x)149 static inline typename std::make_unsigned<T>::type MakeUnsigned(T x) { 150 return static_cast<typename std::make_unsigned<T>::type>(x); 151 } 152 153 class HInstructionList : public ValueObject { 154 public: HInstructionList()155 HInstructionList() : first_instruction_(nullptr), last_instruction_(nullptr) {} 156 157 void AddInstruction(HInstruction* instruction); 158 void RemoveInstruction(HInstruction* instruction); 159 160 // Insert `instruction` before/after an existing instruction `cursor`. 161 void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); 162 void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor); 163 164 // Return true if this list contains `instruction`. 165 bool Contains(HInstruction* instruction) const; 166 167 // Return true if `instruction1` is found before `instruction2` in 168 // this instruction list and false otherwise. Abort if none 169 // of these instructions is found. 170 bool FoundBefore(const HInstruction* instruction1, 171 const HInstruction* instruction2) const; 172 IsEmpty()173 bool IsEmpty() const { return first_instruction_ == nullptr; } Clear()174 void Clear() { first_instruction_ = last_instruction_ = nullptr; } 175 176 // Update the block of all instructions to be `block`. 177 void SetBlockOfInstructions(HBasicBlock* block) const; 178 179 void AddAfter(HInstruction* cursor, const HInstructionList& instruction_list); 180 void AddBefore(HInstruction* cursor, const HInstructionList& instruction_list); 181 void Add(const HInstructionList& instruction_list); 182 183 // Return the number of instructions in the list. This is an expensive operation. 184 size_t CountSize() const; 185 186 private: 187 HInstruction* first_instruction_; 188 HInstruction* last_instruction_; 189 190 friend class HBasicBlock; 191 friend class HGraph; 192 friend class HInstruction; 193 friend class HInstructionIterator; 194 friend class HInstructionIteratorHandleChanges; 195 friend class HBackwardInstructionIterator; 196 197 DISALLOW_COPY_AND_ASSIGN(HInstructionList); 198 }; 199 200 class ReferenceTypeInfo : ValueObject { 201 public: 202 using TypeHandle = Handle<mirror::Class>; 203 204 static ReferenceTypeInfo Create(TypeHandle type_handle, bool is_exact); 205 Create(TypeHandle type_handle)206 static ReferenceTypeInfo Create(TypeHandle type_handle) REQUIRES_SHARED(Locks::mutator_lock_) { 207 return Create(type_handle, type_handle->CannotBeAssignedFromOtherTypes()); 208 } 209 CreateUnchecked(TypeHandle type_handle,bool is_exact)210 static ReferenceTypeInfo CreateUnchecked(TypeHandle type_handle, bool is_exact) { 211 return ReferenceTypeInfo(type_handle, is_exact); 212 } 213 CreateInvalid()214 static ReferenceTypeInfo CreateInvalid() { return ReferenceTypeInfo(); } 215 IsValidHandle(TypeHandle handle)216 static bool IsValidHandle(TypeHandle handle) { 217 return handle.GetReference() != nullptr; 218 } 219 IsValid()220 bool IsValid() const { 221 return IsValidHandle(type_handle_); 222 } 223 IsExact()224 bool IsExact() const { return is_exact_; } 225 IsObjectClass()226 bool IsObjectClass() const REQUIRES_SHARED(Locks::mutator_lock_) { 227 DCHECK(IsValid()); 228 return GetTypeHandle()->IsObjectClass(); 229 } 230 IsStringClass()231 bool IsStringClass() const REQUIRES_SHARED(Locks::mutator_lock_) { 232 DCHECK(IsValid()); 233 return GetTypeHandle()->IsStringClass(); 234 } 235 IsObjectArray()236 bool IsObjectArray() const REQUIRES_SHARED(Locks::mutator_lock_) { 237 DCHECK(IsValid()); 238 return IsArrayClass() && GetTypeHandle()->GetComponentType()->IsObjectClass(); 239 } 240 IsInterface()241 bool IsInterface() const REQUIRES_SHARED(Locks::mutator_lock_) { 242 DCHECK(IsValid()); 243 return GetTypeHandle()->IsInterface(); 244 } 245 IsArrayClass()246 bool IsArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) { 247 DCHECK(IsValid()); 248 return GetTypeHandle()->IsArrayClass(); 249 } 250 IsPrimitiveArrayClass()251 bool IsPrimitiveArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) { 252 DCHECK(IsValid()); 253 return GetTypeHandle()->IsPrimitiveArray(); 254 } 255 IsNonPrimitiveArrayClass()256 bool IsNonPrimitiveArrayClass() const REQUIRES_SHARED(Locks::mutator_lock_) { 257 DCHECK(IsValid()); 258 return IsArrayClass() && !GetTypeHandle()->IsPrimitiveArray(); 259 } 260 CanArrayHold(ReferenceTypeInfo rti)261 bool CanArrayHold(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) { 262 DCHECK(IsValid()); 263 if (!IsExact()) return false; 264 if (!IsArrayClass()) return false; 265 return GetTypeHandle()->GetComponentType()->IsAssignableFrom(rti.GetTypeHandle().Get()); 266 } 267 CanArrayHoldValuesOf(ReferenceTypeInfo rti)268 bool CanArrayHoldValuesOf(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) { 269 DCHECK(IsValid()); 270 if (!IsExact()) return false; 271 if (!IsArrayClass()) return false; 272 if (!rti.IsArrayClass()) return false; 273 return GetTypeHandle()->GetComponentType()->IsAssignableFrom( 274 rti.GetTypeHandle()->GetComponentType()); 275 } 276 GetTypeHandle()277 Handle<mirror::Class> GetTypeHandle() const { return type_handle_; } 278 IsSupertypeOf(ReferenceTypeInfo rti)279 bool IsSupertypeOf(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) { 280 DCHECK(IsValid()); 281 DCHECK(rti.IsValid()); 282 return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get()); 283 } 284 285 // Returns true if the type information provide the same amount of details. 286 // Note that it does not mean that the instructions have the same actual type 287 // (because the type can be the result of a merge). IsEqual(ReferenceTypeInfo rti)288 bool IsEqual(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) { 289 if (!IsValid() && !rti.IsValid()) { 290 // Invalid types are equal. 291 return true; 292 } 293 if (!IsValid() || !rti.IsValid()) { 294 // One is valid, the other not. 295 return false; 296 } 297 return IsExact() == rti.IsExact() 298 && GetTypeHandle().Get() == rti.GetTypeHandle().Get(); 299 } 300 301 private: ReferenceTypeInfo()302 ReferenceTypeInfo() : type_handle_(TypeHandle()), is_exact_(false) {} ReferenceTypeInfo(TypeHandle type_handle,bool is_exact)303 ReferenceTypeInfo(TypeHandle type_handle, bool is_exact) 304 : type_handle_(type_handle), is_exact_(is_exact) { } 305 306 // The class of the object. 307 TypeHandle type_handle_; 308 // Whether or not the type is exact or a superclass of the actual type. 309 // Whether or not we have any information about this type. 310 bool is_exact_; 311 }; 312 313 std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs); 314 315 class HandleCache { 316 public: HandleCache(VariableSizedHandleScope * handles)317 explicit HandleCache(VariableSizedHandleScope* handles) : handles_(handles) { } 318 GetHandles()319 VariableSizedHandleScope* GetHandles() { return handles_; } 320 321 template <typename T> NewHandle(T * object)322 MutableHandle<T> NewHandle(T* object) REQUIRES_SHARED(Locks::mutator_lock_) { 323 return handles_->NewHandle(object); 324 } 325 326 template <typename T> NewHandle(ObjPtr<T> object)327 MutableHandle<T> NewHandle(ObjPtr<T> object) REQUIRES_SHARED(Locks::mutator_lock_) { 328 return handles_->NewHandle(object); 329 } 330 GetObjectClassHandle()331 ReferenceTypeInfo::TypeHandle GetObjectClassHandle() { 332 return GetRootHandle(ClassRoot::kJavaLangObject, &object_class_handle_); 333 } 334 GetClassClassHandle()335 ReferenceTypeInfo::TypeHandle GetClassClassHandle() { 336 return GetRootHandle(ClassRoot::kJavaLangClass, &class_class_handle_); 337 } 338 GetMethodHandleClassHandle()339 ReferenceTypeInfo::TypeHandle GetMethodHandleClassHandle() { 340 return GetRootHandle(ClassRoot::kJavaLangInvokeMethodHandleImpl, &method_handle_class_handle_); 341 } 342 GetMethodTypeClassHandle()343 ReferenceTypeInfo::TypeHandle GetMethodTypeClassHandle() { 344 return GetRootHandle(ClassRoot::kJavaLangInvokeMethodType, &method_type_class_handle_); 345 } 346 GetStringClassHandle()347 ReferenceTypeInfo::TypeHandle GetStringClassHandle() { 348 return GetRootHandle(ClassRoot::kJavaLangString, &string_class_handle_); 349 } 350 GetThrowableClassHandle()351 ReferenceTypeInfo::TypeHandle GetThrowableClassHandle() { 352 return GetRootHandle(ClassRoot::kJavaLangThrowable, &throwable_class_handle_); 353 } 354 355 356 private: GetRootHandle(ClassRoot class_root,ReferenceTypeInfo::TypeHandle * cache)357 inline ReferenceTypeInfo::TypeHandle GetRootHandle(ClassRoot class_root, 358 ReferenceTypeInfo::TypeHandle* cache) { 359 if (UNLIKELY(!ReferenceTypeInfo::IsValidHandle(*cache))) { 360 *cache = CreateRootHandle(handles_, class_root); 361 } 362 return *cache; 363 } 364 365 static ReferenceTypeInfo::TypeHandle CreateRootHandle(VariableSizedHandleScope* handles, 366 ClassRoot class_root); 367 368 VariableSizedHandleScope* handles_; 369 370 ReferenceTypeInfo::TypeHandle object_class_handle_; 371 ReferenceTypeInfo::TypeHandle class_class_handle_; 372 ReferenceTypeInfo::TypeHandle method_handle_class_handle_; 373 ReferenceTypeInfo::TypeHandle method_type_class_handle_; 374 ReferenceTypeInfo::TypeHandle string_class_handle_; 375 ReferenceTypeInfo::TypeHandle throwable_class_handle_; 376 }; 377 378 // Control-flow graph of a method. Contains a list of basic blocks. 379 class HGraph : public ArenaObject<kArenaAllocGraph> { 380 public: 381 HGraph(ArenaAllocator* allocator, 382 ArenaStack* arena_stack, 383 VariableSizedHandleScope* handles, 384 const DexFile& dex_file, 385 uint32_t method_idx, 386 InstructionSet instruction_set, 387 InvokeType invoke_type = kInvalidInvokeType, 388 bool dead_reference_safe = false, 389 bool debuggable = false, 390 CompilationKind compilation_kind = CompilationKind::kOptimized, 391 int start_instruction_id = 0) allocator_(allocator)392 : allocator_(allocator), 393 arena_stack_(arena_stack), 394 handle_cache_(handles), 395 blocks_(allocator->Adapter(kArenaAllocBlockList)), 396 reverse_post_order_(allocator->Adapter(kArenaAllocReversePostOrder)), 397 linear_order_(allocator->Adapter(kArenaAllocLinearOrder)), 398 entry_block_(nullptr), 399 exit_block_(nullptr), 400 maximum_number_of_out_vregs_(0), 401 number_of_vregs_(0), 402 number_of_in_vregs_(0), 403 temporaries_vreg_slots_(0), 404 has_bounds_checks_(false), 405 has_try_catch_(false), 406 has_monitor_operations_(false), 407 has_traditional_simd_(false), 408 has_predicated_simd_(false), 409 has_loops_(false), 410 has_irreducible_loops_(false), 411 has_direct_critical_native_call_(false), 412 has_always_throwing_invokes_(false), 413 dead_reference_safe_(dead_reference_safe), 414 debuggable_(debuggable), 415 current_instruction_id_(start_instruction_id), 416 dex_file_(dex_file), 417 method_idx_(method_idx), 418 invoke_type_(invoke_type), 419 in_ssa_form_(false), 420 number_of_cha_guards_(0), 421 instruction_set_(instruction_set), 422 cached_null_constant_(nullptr), 423 cached_int_constants_(std::less<int32_t>(), allocator->Adapter(kArenaAllocConstantsMap)), 424 cached_float_constants_(std::less<int32_t>(), allocator->Adapter(kArenaAllocConstantsMap)), 425 cached_long_constants_(std::less<int64_t>(), allocator->Adapter(kArenaAllocConstantsMap)), 426 cached_double_constants_(std::less<int64_t>(), allocator->Adapter(kArenaAllocConstantsMap)), 427 cached_current_method_(nullptr), 428 art_method_(nullptr), 429 compilation_kind_(compilation_kind), 430 useful_optimizing_(false), 431 cha_single_implementation_list_(allocator->Adapter(kArenaAllocCHA)) { 432 blocks_.reserve(kDefaultNumberOfBlocks); 433 } 434 435 std::ostream& Dump(std::ostream& os, 436 CodeGenerator* codegen, 437 std::optional<std::reference_wrapper<const BlockNamer>> namer = std::nullopt); 438 GetAllocator()439 ArenaAllocator* GetAllocator() const { return allocator_; } GetArenaStack()440 ArenaStack* GetArenaStack() const { return arena_stack_; } 441 GetHandleCache()442 HandleCache* GetHandleCache() { return &handle_cache_; } 443 GetBlocks()444 const ArenaVector<HBasicBlock*>& GetBlocks() const { return blocks_; } 445 446 // An iterator to only blocks that are still actually in the graph (when 447 // blocks are removed they are replaced with 'nullptr' in GetBlocks to 448 // simplify block-id assignment and avoid memmoves in the block-list). GetActiveBlocks()449 IterationRange<FilterNull<ArenaVector<HBasicBlock*>::const_iterator>> GetActiveBlocks() const { 450 return FilterOutNull(MakeIterationRange(GetBlocks())); 451 } 452 IsInSsaForm()453 bool IsInSsaForm() const { return in_ssa_form_; } SetInSsaForm()454 void SetInSsaForm() { in_ssa_form_ = true; } 455 GetEntryBlock()456 HBasicBlock* GetEntryBlock() const { return entry_block_; } GetExitBlock()457 HBasicBlock* GetExitBlock() const { return exit_block_; } HasExitBlock()458 bool HasExitBlock() const { return exit_block_ != nullptr; } 459 SetEntryBlock(HBasicBlock * block)460 void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; } SetExitBlock(HBasicBlock * block)461 void SetExitBlock(HBasicBlock* block) { exit_block_ = block; } 462 463 void AddBlock(HBasicBlock* block); 464 465 void ComputeDominanceInformation(); 466 void ClearDominanceInformation(); 467 void ClearLoopInformation(); 468 void FindBackEdges(ArenaBitVector* visited); 469 GraphAnalysisResult BuildDominatorTree(); 470 GraphAnalysisResult RecomputeDominatorTree(); 471 void SimplifyCFG(); 472 void SimplifyCatchBlocks(); 473 474 // Analyze all natural loops in this graph. Returns a code specifying that it 475 // was successful or the reason for failure. The method will fail if a loop 476 // is a throw-catch loop, i.e. the header is a catch block. 477 GraphAnalysisResult AnalyzeLoops() const; 478 479 // Iterate over blocks to compute try block membership. Needs reverse post 480 // order and loop information. 481 void ComputeTryBlockInformation(); 482 483 // Inline this graph in `outer_graph`, replacing the given `invoke` instruction. 484 // Returns the instruction to replace the invoke expression or null if the 485 // invoke is for a void method. Note that the caller is responsible for replacing 486 // and removing the invoke instruction. 487 HInstruction* InlineInto(HGraph* outer_graph, HInvoke* invoke); 488 489 // Update the loop and try membership of `block`, which was spawned from `reference`. 490 // In case `reference` is a back edge, `replace_if_back_edge` notifies whether `block` 491 // should be the new back edge. 492 // `has_more_specific_try_catch_info` will be set to true when inlining a try catch. 493 void UpdateLoopAndTryInformationOfNewBlock(HBasicBlock* block, 494 HBasicBlock* reference, 495 bool replace_if_back_edge, 496 bool has_more_specific_try_catch_info = false); 497 498 // Need to add a couple of blocks to test if the loop body is entered and 499 // put deoptimization instructions, etc. 500 void TransformLoopHeaderForBCE(HBasicBlock* header); 501 502 // Adds a new loop directly after the loop with the given header and exit. 503 // Returns the new preheader. 504 HBasicBlock* TransformLoopForVectorization(HBasicBlock* header, 505 HBasicBlock* body, 506 HBasicBlock* exit); 507 508 // Removes `block` from the graph. Assumes `block` has been disconnected from 509 // other blocks and has no instructions or phis. 510 void DeleteDeadEmptyBlock(HBasicBlock* block); 511 512 // Splits the edge between `block` and `successor` while preserving the 513 // indices in the predecessor/successor lists. If there are multiple edges 514 // between the blocks, the lowest indices are used. 515 // Returns the new block which is empty and has the same dex pc as `successor`. 516 HBasicBlock* SplitEdge(HBasicBlock* block, HBasicBlock* successor); 517 518 void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor); 519 520 // Splits the edge between `block` and `successor` and then updates the graph's RPO to keep 521 // consistency without recomputing the whole graph. 522 HBasicBlock* SplitEdgeAndUpdateRPO(HBasicBlock* block, HBasicBlock* successor); 523 524 void OrderLoopHeaderPredecessors(HBasicBlock* header); 525 526 // Transform a loop into a format with a single preheader. 527 // 528 // Each phi in the header should be split: original one in the header should only hold 529 // inputs reachable from the back edges and a single input from the preheader. The newly created 530 // phi in the preheader should collate the inputs from the original multiple incoming blocks. 531 // 532 // Loops in the graph typically have a single preheader, so this method is used to "repair" loops 533 // that no longer have this property. 534 void TransformLoopToSinglePreheaderFormat(HBasicBlock* header); 535 536 void SimplifyLoop(HBasicBlock* header); 537 GetNextInstructionId()538 int32_t GetNextInstructionId() { 539 CHECK_NE(current_instruction_id_, INT32_MAX); 540 return current_instruction_id_++; 541 } 542 GetCurrentInstructionId()543 int32_t GetCurrentInstructionId() const { 544 return current_instruction_id_; 545 } 546 SetCurrentInstructionId(int32_t id)547 void SetCurrentInstructionId(int32_t id) { 548 CHECK_GE(id, current_instruction_id_); 549 current_instruction_id_ = id; 550 } 551 GetMaximumNumberOfOutVRegs()552 uint16_t GetMaximumNumberOfOutVRegs() const { 553 return maximum_number_of_out_vregs_; 554 } 555 SetMaximumNumberOfOutVRegs(uint16_t new_value)556 void SetMaximumNumberOfOutVRegs(uint16_t new_value) { 557 maximum_number_of_out_vregs_ = new_value; 558 } 559 UpdateMaximumNumberOfOutVRegs(uint16_t other_value)560 void UpdateMaximumNumberOfOutVRegs(uint16_t other_value) { 561 maximum_number_of_out_vregs_ = std::max(maximum_number_of_out_vregs_, other_value); 562 } 563 UpdateTemporariesVRegSlots(size_t slots)564 void UpdateTemporariesVRegSlots(size_t slots) { 565 temporaries_vreg_slots_ = std::max(slots, temporaries_vreg_slots_); 566 } 567 GetTemporariesVRegSlots()568 size_t GetTemporariesVRegSlots() const { 569 DCHECK(!in_ssa_form_); 570 return temporaries_vreg_slots_; 571 } 572 SetNumberOfVRegs(uint16_t number_of_vregs)573 void SetNumberOfVRegs(uint16_t number_of_vregs) { 574 number_of_vregs_ = number_of_vregs; 575 } 576 GetNumberOfVRegs()577 uint16_t GetNumberOfVRegs() const { 578 return number_of_vregs_; 579 } 580 SetNumberOfInVRegs(uint16_t value)581 void SetNumberOfInVRegs(uint16_t value) { 582 number_of_in_vregs_ = value; 583 } 584 GetNumberOfInVRegs()585 uint16_t GetNumberOfInVRegs() const { 586 return number_of_in_vregs_; 587 } 588 GetNumberOfLocalVRegs()589 uint16_t GetNumberOfLocalVRegs() const { 590 DCHECK(!in_ssa_form_); 591 return number_of_vregs_ - number_of_in_vregs_; 592 } 593 GetReversePostOrder()594 const ArenaVector<HBasicBlock*>& GetReversePostOrder() const { 595 return reverse_post_order_; 596 } 597 GetReversePostOrderSkipEntryBlock()598 ArrayRef<HBasicBlock* const> GetReversePostOrderSkipEntryBlock() const { 599 DCHECK(GetReversePostOrder()[0] == entry_block_); 600 return ArrayRef<HBasicBlock* const>(GetReversePostOrder()).SubArray(1); 601 } 602 GetPostOrder()603 IterationRange<ArenaVector<HBasicBlock*>::const_reverse_iterator> GetPostOrder() const { 604 return ReverseRange(GetReversePostOrder()); 605 } 606 GetLinearOrder()607 const ArenaVector<HBasicBlock*>& GetLinearOrder() const { 608 return linear_order_; 609 } 610 GetLinearPostOrder()611 IterationRange<ArenaVector<HBasicBlock*>::const_reverse_iterator> GetLinearPostOrder() const { 612 return ReverseRange(GetLinearOrder()); 613 } 614 HasBoundsChecks()615 bool HasBoundsChecks() const { 616 return has_bounds_checks_; 617 } 618 SetHasBoundsChecks(bool value)619 void SetHasBoundsChecks(bool value) { 620 has_bounds_checks_ = value; 621 } 622 623 // Is the code known to be robust against eliminating dead references 624 // and the effects of early finalization? IsDeadReferenceSafe()625 bool IsDeadReferenceSafe() const { return dead_reference_safe_; } 626 MarkDeadReferenceUnsafe()627 void MarkDeadReferenceUnsafe() { dead_reference_safe_ = false; } 628 IsDebuggable()629 bool IsDebuggable() const { return debuggable_; } 630 631 // Returns a constant of the given type and value. If it does not exist 632 // already, it is created and inserted into the graph. This method is only for 633 // integral types. 634 HConstant* GetConstant(DataType::Type type, int64_t value, uint32_t dex_pc = kNoDexPc); 635 636 // TODO: This is problematic for the consistency of reference type propagation 637 // because it can be created anytime after the pass and thus it will be left 638 // with an invalid type. 639 HNullConstant* GetNullConstant(uint32_t dex_pc = kNoDexPc); 640 641 HIntConstant* GetIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) { 642 return CreateConstant(value, &cached_int_constants_, dex_pc); 643 } 644 HLongConstant* GetLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) { 645 return CreateConstant(value, &cached_long_constants_, dex_pc); 646 } 647 HFloatConstant* GetFloatConstant(float value, uint32_t dex_pc = kNoDexPc) { 648 return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_, dex_pc); 649 } 650 HDoubleConstant* GetDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) { 651 return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_, dex_pc); 652 } 653 654 HCurrentMethod* GetCurrentMethod(); 655 GetDexFile()656 const DexFile& GetDexFile() const { 657 return dex_file_; 658 } 659 GetMethodIdx()660 uint32_t GetMethodIdx() const { 661 return method_idx_; 662 } 663 664 // Get the method name (without the signature), e.g. "<init>" 665 const char* GetMethodName() const; 666 667 // Get the pretty method name (class + name + optionally signature). 668 std::string PrettyMethod(bool with_signature = true) const; 669 GetInvokeType()670 InvokeType GetInvokeType() const { 671 return invoke_type_; 672 } 673 GetInstructionSet()674 InstructionSet GetInstructionSet() const { 675 return instruction_set_; 676 } 677 IsCompilingOsr()678 bool IsCompilingOsr() const { return compilation_kind_ == CompilationKind::kOsr; } 679 IsCompilingBaseline()680 bool IsCompilingBaseline() const { return compilation_kind_ == CompilationKind::kBaseline; } 681 GetCompilationKind()682 CompilationKind GetCompilationKind() const { return compilation_kind_; } 683 GetCHASingleImplementationList()684 ArenaSet<ArtMethod*>& GetCHASingleImplementationList() { 685 return cha_single_implementation_list_; 686 } 687 688 // In case of OSR we intend to use SuspendChecks as an entry point to the 689 // function; for debuggable graphs we might deoptimize to interpreter from 690 // SuspendChecks. In these cases we should always generate code for them. SuspendChecksAreAllowedToNoOp()691 bool SuspendChecksAreAllowedToNoOp() const { 692 return !IsDebuggable() && !IsCompilingOsr(); 693 } 694 AddCHASingleImplementationDependency(ArtMethod * method)695 void AddCHASingleImplementationDependency(ArtMethod* method) { 696 cha_single_implementation_list_.insert(method); 697 } 698 HasShouldDeoptimizeFlag()699 bool HasShouldDeoptimizeFlag() const { 700 return number_of_cha_guards_ != 0 || debuggable_; 701 } 702 HasTryCatch()703 bool HasTryCatch() const { return has_try_catch_; } SetHasTryCatch(bool value)704 void SetHasTryCatch(bool value) { has_try_catch_ = value; } 705 HasMonitorOperations()706 bool HasMonitorOperations() const { return has_monitor_operations_; } SetHasMonitorOperations(bool value)707 void SetHasMonitorOperations(bool value) { has_monitor_operations_ = value; } 708 HasTraditionalSIMD()709 bool HasTraditionalSIMD() { return has_traditional_simd_; } SetHasTraditionalSIMD(bool value)710 void SetHasTraditionalSIMD(bool value) { has_traditional_simd_ = value; } 711 HasPredicatedSIMD()712 bool HasPredicatedSIMD() { return has_predicated_simd_; } SetHasPredicatedSIMD(bool value)713 void SetHasPredicatedSIMD(bool value) { has_predicated_simd_ = value; } 714 HasSIMD()715 bool HasSIMD() const { return has_traditional_simd_ || has_predicated_simd_; } 716 HasLoops()717 bool HasLoops() const { return has_loops_; } SetHasLoops(bool value)718 void SetHasLoops(bool value) { has_loops_ = value; } 719 HasIrreducibleLoops()720 bool HasIrreducibleLoops() const { return has_irreducible_loops_; } SetHasIrreducibleLoops(bool value)721 void SetHasIrreducibleLoops(bool value) { has_irreducible_loops_ = value; } 722 HasDirectCriticalNativeCall()723 bool HasDirectCriticalNativeCall() const { return has_direct_critical_native_call_; } SetHasDirectCriticalNativeCall(bool value)724 void SetHasDirectCriticalNativeCall(bool value) { has_direct_critical_native_call_ = value; } 725 HasAlwaysThrowingInvokes()726 bool HasAlwaysThrowingInvokes() const { return has_always_throwing_invokes_; } SetHasAlwaysThrowingInvokes(bool value)727 void SetHasAlwaysThrowingInvokes(bool value) { has_always_throwing_invokes_ = value; } 728 GetArtMethod()729 ArtMethod* GetArtMethod() const { return art_method_; } SetArtMethod(ArtMethod * method)730 void SetArtMethod(ArtMethod* method) { art_method_ = method; } 731 SetProfilingInfo(ProfilingInfo * info)732 void SetProfilingInfo(ProfilingInfo* info) { profiling_info_ = info; } GetProfilingInfo()733 ProfilingInfo* GetProfilingInfo() const { return profiling_info_; } 734 735 // Returns an instruction with the opposite Boolean value from 'cond'. 736 // The instruction has been inserted into the graph, either as a constant, or 737 // before cursor. 738 HInstruction* InsertOppositeCondition(HInstruction* cond, HInstruction* cursor); 739 GetInexactObjectRti()740 ReferenceTypeInfo GetInexactObjectRti() { 741 return ReferenceTypeInfo::Create(handle_cache_.GetObjectClassHandle(), /* is_exact= */ false); 742 } 743 GetNumberOfCHAGuards()744 uint32_t GetNumberOfCHAGuards() const { return number_of_cha_guards_; } SetNumberOfCHAGuards(uint32_t num)745 void SetNumberOfCHAGuards(uint32_t num) { number_of_cha_guards_ = num; } IncrementNumberOfCHAGuards()746 void IncrementNumberOfCHAGuards() { number_of_cha_guards_++; } 747 SetUsefulOptimizing()748 void SetUsefulOptimizing() { useful_optimizing_ = true; } IsUsefulOptimizing()749 bool IsUsefulOptimizing() const { return useful_optimizing_; } 750 751 private: 752 void RemoveDeadBlocksInstructionsAsUsersAndDisconnect(const ArenaBitVector& visited) const; 753 void RemoveDeadBlocks(const ArenaBitVector& visited); 754 755 template <class InstructionType, typename ValueType> 756 InstructionType* CreateConstant(ValueType value, 757 ArenaSafeMap<ValueType, InstructionType*>* cache, 758 uint32_t dex_pc = kNoDexPc) { 759 // Try to find an existing constant of the given value. 760 InstructionType* constant = nullptr; 761 auto cached_constant = cache->find(value); 762 if (cached_constant != cache->end()) { 763 constant = cached_constant->second; 764 } 765 766 // If not found or previously deleted, create and cache a new instruction. 767 // Don't bother reviving a previously deleted instruction, for simplicity. 768 if (constant == nullptr || constant->GetBlock() == nullptr) { 769 constant = new (allocator_) InstructionType(value, dex_pc); 770 cache->Overwrite(value, constant); 771 InsertConstant(constant); 772 } 773 return constant; 774 } 775 776 void InsertConstant(HConstant* instruction); 777 778 // Cache a float constant into the graph. This method should only be 779 // called by the SsaBuilder when creating "equivalent" instructions. 780 void CacheFloatConstant(HFloatConstant* constant); 781 782 // See CacheFloatConstant comment. 783 void CacheDoubleConstant(HDoubleConstant* constant); 784 785 ArenaAllocator* const allocator_; 786 ArenaStack* const arena_stack_; 787 788 HandleCache handle_cache_; 789 790 // List of blocks in insertion order. 791 ArenaVector<HBasicBlock*> blocks_; 792 793 // List of blocks to perform a reverse post order tree traversal. 794 ArenaVector<HBasicBlock*> reverse_post_order_; 795 796 // List of blocks to perform a linear order tree traversal. Unlike the reverse 797 // post order, this order is not incrementally kept up-to-date. 798 ArenaVector<HBasicBlock*> linear_order_; 799 800 HBasicBlock* entry_block_; 801 HBasicBlock* exit_block_; 802 803 // The maximum number of virtual registers arguments passed to a HInvoke in this graph. 804 uint16_t maximum_number_of_out_vregs_; 805 806 // The number of virtual registers in this method. Contains the parameters. 807 uint16_t number_of_vregs_; 808 809 // The number of virtual registers used by parameters of this method. 810 uint16_t number_of_in_vregs_; 811 812 // Number of vreg size slots that the temporaries use (used in baseline compiler). 813 size_t temporaries_vreg_slots_; 814 815 // Flag whether there are bounds checks in the graph. We can skip 816 // BCE if it's false. 817 bool has_bounds_checks_; 818 819 // Flag whether there are try/catch blocks in the graph. We will skip 820 // try/catch-related passes if it's false. 821 bool has_try_catch_; 822 823 // Flag whether there are any HMonitorOperation in the graph. If yes this will mandate 824 // DexRegisterMap to be present to allow deadlock analysis for non-debuggable code. 825 bool has_monitor_operations_; 826 827 // Flags whether SIMD (traditional or predicated) instructions appear in the graph. 828 // If either is true, the code generators may have to be more careful spilling the wider 829 // contents of SIMD registers. 830 bool has_traditional_simd_; 831 bool has_predicated_simd_; 832 833 // Flag whether there are any loops in the graph. We can skip loop 834 // optimization if it's false. 835 bool has_loops_; 836 837 // Flag whether there are any irreducible loops in the graph. 838 bool has_irreducible_loops_; 839 840 // Flag whether there are any direct calls to native code registered 841 // for @CriticalNative methods. 842 bool has_direct_critical_native_call_; 843 844 // Flag whether the graph contains invokes that always throw. 845 bool has_always_throwing_invokes_; 846 847 // Is the code known to be robust against eliminating dead references 848 // and the effects of early finalization? If false, dead reference variables 849 // are kept if they might be visible to the garbage collector. 850 // Currently this means that the class was declared to be dead-reference-safe, 851 // the method accesses no reachability-sensitive fields or data, and the same 852 // is true for any methods that were inlined into the current one. 853 bool dead_reference_safe_; 854 855 // Indicates whether the graph should be compiled in a way that 856 // ensures full debuggability. If false, we can apply more 857 // aggressive optimizations that may limit the level of debugging. 858 const bool debuggable_; 859 860 // The current id to assign to a newly added instruction. See HInstruction.id_. 861 int32_t current_instruction_id_; 862 863 // The dex file from which the method is from. 864 const DexFile& dex_file_; 865 866 // The method index in the dex file. 867 const uint32_t method_idx_; 868 869 // If inlined, this encodes how the callee is being invoked. 870 const InvokeType invoke_type_; 871 872 // Whether the graph has been transformed to SSA form. Only used 873 // in debug mode to ensure we are not using properties only valid 874 // for non-SSA form (like the number of temporaries). 875 bool in_ssa_form_; 876 877 // Number of CHA guards in the graph. Used to short-circuit the 878 // CHA guard optimization pass when there is no CHA guard left. 879 uint32_t number_of_cha_guards_; 880 881 const InstructionSet instruction_set_; 882 883 // Cached constants. 884 HNullConstant* cached_null_constant_; 885 ArenaSafeMap<int32_t, HIntConstant*> cached_int_constants_; 886 ArenaSafeMap<int32_t, HFloatConstant*> cached_float_constants_; 887 ArenaSafeMap<int64_t, HLongConstant*> cached_long_constants_; 888 ArenaSafeMap<int64_t, HDoubleConstant*> cached_double_constants_; 889 890 HCurrentMethod* cached_current_method_; 891 892 // The ArtMethod this graph is for. Note that for AOT, it may be null, 893 // for example for methods whose declaring class could not be resolved 894 // (such as when the superclass could not be found). 895 ArtMethod* art_method_; 896 897 // The `ProfilingInfo` associated with the method being compiled. 898 ProfilingInfo* profiling_info_; 899 900 // How we are compiling the graph: either optimized, osr, or baseline. 901 // For osr, we will make all loops seen as irreducible and emit special 902 // stack maps to mark compiled code entries which the interpreter can 903 // directly jump to. 904 const CompilationKind compilation_kind_; 905 906 // Whether after compiling baseline it is still useful re-optimizing this 907 // method. 908 bool useful_optimizing_; 909 910 // List of methods that are assumed to have single implementation. 911 ArenaSet<ArtMethod*> cha_single_implementation_list_; 912 913 friend class SsaBuilder; // For caching constants. 914 friend class SsaLivenessAnalysis; // For the linear order. 915 friend class HInliner; // For the reverse post order. 916 ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1); 917 DISALLOW_COPY_AND_ASSIGN(HGraph); 918 }; 919 920 class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> { 921 public: HLoopInformation(HBasicBlock * header,HGraph * graph)922 HLoopInformation(HBasicBlock* header, HGraph* graph) 923 : header_(header), 924 suspend_check_(nullptr), 925 irreducible_(false), 926 contains_irreducible_loop_(false), 927 back_edges_(graph->GetAllocator()->Adapter(kArenaAllocLoopInfoBackEdges)), 928 // Make bit vector growable, as the number of blocks may change. 929 blocks_(graph->GetAllocator(), 930 graph->GetBlocks().size(), 931 true, 932 kArenaAllocLoopInfoBackEdges) { 933 back_edges_.reserve(kDefaultNumberOfBackEdges); 934 } 935 IsIrreducible()936 bool IsIrreducible() const { return irreducible_; } ContainsIrreducibleLoop()937 bool ContainsIrreducibleLoop() const { return contains_irreducible_loop_; } 938 939 void Dump(std::ostream& os); 940 GetHeader()941 HBasicBlock* GetHeader() const { 942 return header_; 943 } 944 SetHeader(HBasicBlock * block)945 void SetHeader(HBasicBlock* block) { 946 header_ = block; 947 } 948 GetSuspendCheck()949 HSuspendCheck* GetSuspendCheck() const { return suspend_check_; } SetSuspendCheck(HSuspendCheck * check)950 void SetSuspendCheck(HSuspendCheck* check) { suspend_check_ = check; } HasSuspendCheck()951 bool HasSuspendCheck() const { return suspend_check_ != nullptr; } 952 AddBackEdge(HBasicBlock * back_edge)953 void AddBackEdge(HBasicBlock* back_edge) { 954 back_edges_.push_back(back_edge); 955 } 956 RemoveBackEdge(HBasicBlock * back_edge)957 void RemoveBackEdge(HBasicBlock* back_edge) { 958 RemoveElement(back_edges_, back_edge); 959 } 960 IsBackEdge(const HBasicBlock & block)961 bool IsBackEdge(const HBasicBlock& block) const { 962 return ContainsElement(back_edges_, &block); 963 } 964 NumberOfBackEdges()965 size_t NumberOfBackEdges() const { 966 return back_edges_.size(); 967 } 968 969 HBasicBlock* GetPreHeader() const; 970 GetBackEdges()971 const ArenaVector<HBasicBlock*>& GetBackEdges() const { 972 return back_edges_; 973 } 974 975 // Returns the lifetime position of the back edge that has the 976 // greatest lifetime position. 977 size_t GetLifetimeEnd() const; 978 ReplaceBackEdge(HBasicBlock * existing,HBasicBlock * new_back_edge)979 void ReplaceBackEdge(HBasicBlock* existing, HBasicBlock* new_back_edge) { 980 ReplaceElement(back_edges_, existing, new_back_edge); 981 } 982 983 // Finds blocks that are part of this loop. 984 void Populate(); 985 986 // Updates blocks population of the loop and all of its outer' ones recursively after the 987 // population of the inner loop is updated. 988 void PopulateInnerLoopUpwards(HLoopInformation* inner_loop); 989 990 // Returns whether this loop information contains `block`. 991 // Note that this loop information *must* be populated before entering this function. 992 bool Contains(const HBasicBlock& block) const; 993 994 // Returns whether this loop information is an inner loop of `other`. 995 // Note that `other` *must* be populated before entering this function. 996 bool IsIn(const HLoopInformation& other) const; 997 998 // Returns true if instruction is not defined within this loop. 999 bool IsDefinedOutOfTheLoop(HInstruction* instruction) const; 1000 GetBlocks()1001 const ArenaBitVector& GetBlocks() const { return blocks_; } 1002 1003 void Add(HBasicBlock* block); 1004 void Remove(HBasicBlock* block); 1005 ClearAllBlocks()1006 void ClearAllBlocks() { 1007 blocks_.ClearAllBits(); 1008 } 1009 1010 bool HasBackEdgeNotDominatedByHeader() const; 1011 IsPopulated()1012 bool IsPopulated() const { 1013 return blocks_.GetHighestBitSet() != -1; 1014 } 1015 1016 bool DominatesAllBackEdges(HBasicBlock* block); 1017 1018 bool HasExitEdge() const; 1019 1020 // Resets back edge and blocks-in-loop data. ResetBasicBlockData()1021 void ResetBasicBlockData() { 1022 back_edges_.clear(); 1023 ClearAllBlocks(); 1024 } 1025 1026 private: 1027 // Internal recursive implementation of `Populate`. 1028 void PopulateRecursive(HBasicBlock* block); 1029 void PopulateIrreducibleRecursive(HBasicBlock* block, ArenaBitVector* finalized); 1030 1031 HBasicBlock* header_; 1032 HSuspendCheck* suspend_check_; 1033 bool irreducible_; 1034 bool contains_irreducible_loop_; 1035 ArenaVector<HBasicBlock*> back_edges_; 1036 ArenaBitVector blocks_; 1037 1038 DISALLOW_COPY_AND_ASSIGN(HLoopInformation); 1039 }; 1040 1041 // Stores try/catch information for basic blocks. 1042 // Note that HGraph is constructed so that catch blocks cannot simultaneously 1043 // be try blocks. 1044 class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { 1045 public: 1046 // Try block information constructor. TryCatchInformation(const HTryBoundary & try_entry)1047 explicit TryCatchInformation(const HTryBoundary& try_entry) 1048 : try_entry_(&try_entry), 1049 catch_dex_file_(nullptr), 1050 catch_type_index_(dex::TypeIndex::Invalid()) { 1051 DCHECK(try_entry_ != nullptr); 1052 } 1053 1054 // Catch block information constructor. TryCatchInformation(dex::TypeIndex catch_type_index,const DexFile & dex_file)1055 TryCatchInformation(dex::TypeIndex catch_type_index, const DexFile& dex_file) 1056 : try_entry_(nullptr), 1057 catch_dex_file_(&dex_file), 1058 catch_type_index_(catch_type_index) {} 1059 IsTryBlock()1060 bool IsTryBlock() const { return try_entry_ != nullptr; } 1061 GetTryEntry()1062 const HTryBoundary& GetTryEntry() const { 1063 DCHECK(IsTryBlock()); 1064 return *try_entry_; 1065 } 1066 IsCatchBlock()1067 bool IsCatchBlock() const { return catch_dex_file_ != nullptr; } 1068 IsValidTypeIndex()1069 bool IsValidTypeIndex() const { 1070 DCHECK(IsCatchBlock()); 1071 return catch_type_index_.IsValid(); 1072 } 1073 GetCatchTypeIndex()1074 dex::TypeIndex GetCatchTypeIndex() const { 1075 DCHECK(IsCatchBlock()); 1076 return catch_type_index_; 1077 } 1078 GetCatchDexFile()1079 const DexFile& GetCatchDexFile() const { 1080 DCHECK(IsCatchBlock()); 1081 return *catch_dex_file_; 1082 } 1083 SetInvalidTypeIndex()1084 void SetInvalidTypeIndex() { 1085 catch_type_index_ = dex::TypeIndex::Invalid(); 1086 } 1087 1088 private: 1089 // One of possibly several TryBoundary instructions entering the block's try. 1090 // Only set for try blocks. 1091 const HTryBoundary* try_entry_; 1092 1093 // Exception type information. Only set for catch blocks. 1094 const DexFile* catch_dex_file_; 1095 dex::TypeIndex catch_type_index_; 1096 }; 1097 1098 static constexpr size_t kNoLifetime = -1; 1099 static constexpr uint32_t kInvalidBlockId = static_cast<uint32_t>(-1); 1100 1101 // A block in a method. Contains the list of instructions represented 1102 // as a double linked list. Each block knows its predecessors and 1103 // successors. 1104 1105 class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { 1106 public: 1107 explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc) graph_(graph)1108 : graph_(graph), 1109 predecessors_(graph->GetAllocator()->Adapter(kArenaAllocPredecessors)), 1110 successors_(graph->GetAllocator()->Adapter(kArenaAllocSuccessors)), 1111 loop_information_(nullptr), 1112 dominator_(nullptr), 1113 dominated_blocks_(graph->GetAllocator()->Adapter(kArenaAllocDominated)), 1114 block_id_(kInvalidBlockId), 1115 dex_pc_(dex_pc), 1116 lifetime_start_(kNoLifetime), 1117 lifetime_end_(kNoLifetime), 1118 try_catch_information_(nullptr) { 1119 predecessors_.reserve(kDefaultNumberOfPredecessors); 1120 successors_.reserve(kDefaultNumberOfSuccessors); 1121 dominated_blocks_.reserve(kDefaultNumberOfDominatedBlocks); 1122 } 1123 GetPredecessors()1124 const ArenaVector<HBasicBlock*>& GetPredecessors() const { 1125 return predecessors_; 1126 } 1127 GetNumberOfPredecessors()1128 size_t GetNumberOfPredecessors() const { 1129 return GetPredecessors().size(); 1130 } 1131 GetSuccessors()1132 const ArenaVector<HBasicBlock*>& GetSuccessors() const { 1133 return successors_; 1134 } 1135 1136 ArrayRef<HBasicBlock* const> GetNormalSuccessors() const; 1137 ArrayRef<HBasicBlock* const> GetExceptionalSuccessors() const; 1138 1139 bool HasSuccessor(const HBasicBlock* block, size_t start_from = 0u) { 1140 return ContainsElement(successors_, block, start_from); 1141 } 1142 GetDominatedBlocks()1143 const ArenaVector<HBasicBlock*>& GetDominatedBlocks() const { 1144 return dominated_blocks_; 1145 } 1146 IsEntryBlock()1147 bool IsEntryBlock() const { 1148 return graph_->GetEntryBlock() == this; 1149 } 1150 IsExitBlock()1151 bool IsExitBlock() const { 1152 return graph_->GetExitBlock() == this; 1153 } 1154 1155 bool IsSingleGoto() const; 1156 bool IsSingleReturn() const; 1157 bool IsSingleReturnOrReturnVoidAllowingPhis() const; 1158 bool IsSingleTryBoundary() const; 1159 1160 // Returns true if this block emits nothing but a jump. IsSingleJump()1161 bool IsSingleJump() const { 1162 HLoopInformation* loop_info = GetLoopInformation(); 1163 return (IsSingleGoto() || IsSingleTryBoundary()) 1164 // Back edges generate a suspend check. 1165 && (loop_info == nullptr || !loop_info->IsBackEdge(*this)); 1166 } 1167 AddBackEdge(HBasicBlock * back_edge)1168 void AddBackEdge(HBasicBlock* back_edge) { 1169 if (loop_information_ == nullptr) { 1170 loop_information_ = new (graph_->GetAllocator()) HLoopInformation(this, graph_); 1171 } 1172 DCHECK_EQ(loop_information_->GetHeader(), this); 1173 loop_information_->AddBackEdge(back_edge); 1174 } 1175 1176 // Registers a back edge; if the block was not a loop header before the call associates a newly 1177 // created loop info with it. 1178 // 1179 // Used in SuperblockCloner to preserve LoopInformation object instead of reseting loop 1180 // info for all blocks during back edges recalculation. AddBackEdgeWhileUpdating(HBasicBlock * back_edge)1181 void AddBackEdgeWhileUpdating(HBasicBlock* back_edge) { 1182 if (loop_information_ == nullptr || loop_information_->GetHeader() != this) { 1183 loop_information_ = new (graph_->GetAllocator()) HLoopInformation(this, graph_); 1184 } 1185 loop_information_->AddBackEdge(back_edge); 1186 } 1187 GetGraph()1188 HGraph* GetGraph() const { return graph_; } SetGraph(HGraph * graph)1189 void SetGraph(HGraph* graph) { graph_ = graph; } 1190 GetBlockId()1191 uint32_t GetBlockId() const { return block_id_; } SetBlockId(int id)1192 void SetBlockId(int id) { block_id_ = id; } GetDexPc()1193 uint32_t GetDexPc() const { return dex_pc_; } 1194 GetDominator()1195 HBasicBlock* GetDominator() const { return dominator_; } SetDominator(HBasicBlock * dominator)1196 void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; } AddDominatedBlock(HBasicBlock * block)1197 void AddDominatedBlock(HBasicBlock* block) { dominated_blocks_.push_back(block); } 1198 RemoveDominatedBlock(HBasicBlock * block)1199 void RemoveDominatedBlock(HBasicBlock* block) { 1200 RemoveElement(dominated_blocks_, block); 1201 } 1202 ReplaceDominatedBlock(HBasicBlock * existing,HBasicBlock * new_block)1203 void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) { 1204 ReplaceElement(dominated_blocks_, existing, new_block); 1205 } 1206 1207 void ClearDominanceInformation(); 1208 NumberOfBackEdges()1209 int NumberOfBackEdges() const { 1210 return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0; 1211 } 1212 GetFirstInstruction()1213 HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; } GetLastInstruction()1214 HInstruction* GetLastInstruction() const { return instructions_.last_instruction_; } GetInstructions()1215 const HInstructionList& GetInstructions() const { return instructions_; } GetFirstPhi()1216 HInstruction* GetFirstPhi() const { return phis_.first_instruction_; } GetLastPhi()1217 HInstruction* GetLastPhi() const { return phis_.last_instruction_; } GetPhis()1218 const HInstructionList& GetPhis() const { return phis_; } 1219 1220 HInstruction* GetFirstInstructionDisregardMoves() const; 1221 AddSuccessor(HBasicBlock * block)1222 void AddSuccessor(HBasicBlock* block) { 1223 successors_.push_back(block); 1224 block->predecessors_.push_back(this); 1225 } 1226 ReplaceSuccessor(HBasicBlock * existing,HBasicBlock * new_block)1227 void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock* new_block) { 1228 size_t successor_index = GetSuccessorIndexOf(existing); 1229 existing->RemovePredecessor(this); 1230 new_block->predecessors_.push_back(this); 1231 successors_[successor_index] = new_block; 1232 } 1233 ReplacePredecessor(HBasicBlock * existing,HBasicBlock * new_block)1234 void ReplacePredecessor(HBasicBlock* existing, HBasicBlock* new_block) { 1235 size_t predecessor_index = GetPredecessorIndexOf(existing); 1236 existing->RemoveSuccessor(this); 1237 new_block->successors_.push_back(this); 1238 predecessors_[predecessor_index] = new_block; 1239 } 1240 1241 // Insert `this` between `predecessor` and `successor. This method 1242 // preserves the indices, and will update the first edge found between 1243 // `predecessor` and `successor`. InsertBetween(HBasicBlock * predecessor,HBasicBlock * successor)1244 void InsertBetween(HBasicBlock* predecessor, HBasicBlock* successor) { 1245 size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor); 1246 size_t successor_index = predecessor->GetSuccessorIndexOf(successor); 1247 successor->predecessors_[predecessor_index] = this; 1248 predecessor->successors_[successor_index] = this; 1249 successors_.push_back(successor); 1250 predecessors_.push_back(predecessor); 1251 } 1252 RemovePredecessor(HBasicBlock * block)1253 void RemovePredecessor(HBasicBlock* block) { 1254 predecessors_.erase(predecessors_.begin() + GetPredecessorIndexOf(block)); 1255 } 1256 RemoveSuccessor(HBasicBlock * block)1257 void RemoveSuccessor(HBasicBlock* block) { 1258 successors_.erase(successors_.begin() + GetSuccessorIndexOf(block)); 1259 } 1260 ClearAllPredecessors()1261 void ClearAllPredecessors() { 1262 predecessors_.clear(); 1263 } 1264 AddPredecessor(HBasicBlock * block)1265 void AddPredecessor(HBasicBlock* block) { 1266 predecessors_.push_back(block); 1267 block->successors_.push_back(this); 1268 } 1269 SwapPredecessors()1270 void SwapPredecessors() { 1271 DCHECK_EQ(predecessors_.size(), 2u); 1272 std::swap(predecessors_[0], predecessors_[1]); 1273 } 1274 SwapSuccessors()1275 void SwapSuccessors() { 1276 DCHECK_EQ(successors_.size(), 2u); 1277 std::swap(successors_[0], successors_[1]); 1278 } 1279 GetPredecessorIndexOf(HBasicBlock * predecessor)1280 size_t GetPredecessorIndexOf(HBasicBlock* predecessor) const { 1281 return IndexOfElement(predecessors_, predecessor); 1282 } 1283 GetSuccessorIndexOf(HBasicBlock * successor)1284 size_t GetSuccessorIndexOf(HBasicBlock* successor) const { 1285 return IndexOfElement(successors_, successor); 1286 } 1287 GetSinglePredecessor()1288 HBasicBlock* GetSinglePredecessor() const { 1289 DCHECK_EQ(GetPredecessors().size(), 1u); 1290 return GetPredecessors()[0]; 1291 } 1292 GetSingleSuccessor()1293 HBasicBlock* GetSingleSuccessor() const { 1294 DCHECK_EQ(GetSuccessors().size(), 1u); 1295 return GetSuccessors()[0]; 1296 } 1297 1298 // Returns whether the first occurrence of `predecessor` in the list of 1299 // predecessors is at index `idx`. IsFirstIndexOfPredecessor(HBasicBlock * predecessor,size_t idx)1300 bool IsFirstIndexOfPredecessor(HBasicBlock* predecessor, size_t idx) const { 1301 DCHECK_EQ(GetPredecessors()[idx], predecessor); 1302 return GetPredecessorIndexOf(predecessor) == idx; 1303 } 1304 1305 // Create a new block between this block and its predecessors. The new block 1306 // is added to the graph, all predecessor edges are relinked to it and an edge 1307 // is created to `this`. Returns the new empty block. Reverse post order or 1308 // loop and try/catch information are not updated. 1309 HBasicBlock* CreateImmediateDominator(); 1310 1311 // Split the block into two blocks just before `cursor`. Returns the newly 1312 // created, latter block. Note that this method will add the block to the 1313 // graph, create a Goto at the end of the former block and will create an edge 1314 // between the blocks. It will not, however, update the reverse post order or 1315 // loop and try/catch information. 1316 HBasicBlock* SplitBefore(HInstruction* cursor, bool require_graph_not_in_ssa_form = true); 1317 1318 // Split the block into two blocks just before `cursor`. Returns the newly 1319 // created block. Note that this method just updates raw block information, 1320 // like predecessors, successors, dominators, and instruction list. It does not 1321 // update the graph, reverse post order, loop information, nor make sure the 1322 // blocks are consistent (for example ending with a control flow instruction). 1323 HBasicBlock* SplitBeforeForInlining(HInstruction* cursor); 1324 1325 // Similar to `SplitBeforeForInlining` but does it after `cursor`. 1326 HBasicBlock* SplitAfterForInlining(HInstruction* cursor); 1327 1328 // Merge `other` at the end of `this`. Successors and dominated blocks of 1329 // `other` are changed to be successors and dominated blocks of `this`. Note 1330 // that this method does not update the graph, reverse post order, loop 1331 // information, nor make sure the blocks are consistent (for example ending 1332 // with a control flow instruction). 1333 void MergeWithInlined(HBasicBlock* other); 1334 1335 // Replace `this` with `other`. Predecessors, successors, and dominated blocks 1336 // of `this` are moved to `other`. 1337 // Note that this method does not update the graph, reverse post order, loop 1338 // information, nor make sure the blocks are consistent (for example ending 1339 // with a control flow instruction). 1340 void ReplaceWith(HBasicBlock* other); 1341 1342 // Merges the instructions of `other` at the end of `this`. 1343 void MergeInstructionsWith(HBasicBlock* other); 1344 1345 // Merge `other` at the end of `this`. This method updates loops, reverse post 1346 // order, links to predecessors, successors, dominators and deletes the block 1347 // from the graph. The two blocks must be successive, i.e. `this` the only 1348 // predecessor of `other` and vice versa. 1349 void MergeWith(HBasicBlock* other); 1350 1351 // Disconnects `this` from all its predecessors, successors and dominator, 1352 // removes it from all loops it is included in and eventually from the graph. 1353 // The block must not dominate any other block. Predecessors and successors 1354 // are safely updated. 1355 void DisconnectAndDelete(); 1356 1357 // Disconnects `this` from all its successors and updates their phis, if the successors have them. 1358 // If `visited` is provided, it will use the information to know if a successor is reachable and 1359 // skip updating those phis. 1360 void DisconnectFromSuccessors(const ArenaBitVector* visited = nullptr); 1361 1362 // Removes the catch phi uses of the instructions in `this`, and then remove the instruction 1363 // itself. If `building_dominator_tree` is true, it will not remove the instruction as user, since 1364 // we do it in a previous step. This is a special case for building up the dominator tree: we want 1365 // to eliminate uses before inputs but we don't have domination information, so we remove all 1366 // connections from input/uses first before removing any instruction. 1367 // This method assumes the instructions have been removed from all users with the exception of 1368 // catch phis because of missing exceptional edges in the graph. 1369 void RemoveCatchPhiUsesAndInstruction(bool building_dominator_tree); 1370 1371 void AddInstruction(HInstruction* instruction); 1372 // Insert `instruction` before/after an existing instruction `cursor`. 1373 void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); 1374 void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor); 1375 // Replace phi `initial` with `replacement` within this block. 1376 void ReplaceAndRemovePhiWith(HPhi* initial, HPhi* replacement); 1377 // Replace instruction `initial` with `replacement` within this block. 1378 void ReplaceAndRemoveInstructionWith(HInstruction* initial, 1379 HInstruction* replacement); 1380 void AddPhi(HPhi* phi); 1381 void InsertPhiAfter(HPhi* instruction, HPhi* cursor); 1382 // RemoveInstruction and RemovePhi delete a given instruction from the respective 1383 // instruction list. With 'ensure_safety' set to true, it verifies that the 1384 // instruction is not in use and removes it from the use lists of its inputs. 1385 void RemoveInstruction(HInstruction* instruction, bool ensure_safety = true); 1386 void RemovePhi(HPhi* phi, bool ensure_safety = true); 1387 void RemoveInstructionOrPhi(HInstruction* instruction, bool ensure_safety = true); 1388 IsLoopHeader()1389 bool IsLoopHeader() const { 1390 return IsInLoop() && (loop_information_->GetHeader() == this); 1391 } 1392 IsLoopPreHeaderFirstPredecessor()1393 bool IsLoopPreHeaderFirstPredecessor() const { 1394 DCHECK(IsLoopHeader()); 1395 return GetPredecessors()[0] == GetLoopInformation()->GetPreHeader(); 1396 } 1397 IsFirstPredecessorBackEdge()1398 bool IsFirstPredecessorBackEdge() const { 1399 DCHECK(IsLoopHeader()); 1400 return GetLoopInformation()->IsBackEdge(*GetPredecessors()[0]); 1401 } 1402 GetLoopInformation()1403 HLoopInformation* GetLoopInformation() const { 1404 return loop_information_; 1405 } 1406 1407 // Set the loop_information_ on this block. Overrides the current 1408 // loop_information if it is an outer loop of the passed loop information. 1409 // Note that this method is called while creating the loop information. SetInLoop(HLoopInformation * info)1410 void SetInLoop(HLoopInformation* info) { 1411 if (IsLoopHeader()) { 1412 // Nothing to do. This just means `info` is an outer loop. 1413 } else if (!IsInLoop()) { 1414 loop_information_ = info; 1415 } else if (loop_information_->Contains(*info->GetHeader())) { 1416 // Block is currently part of an outer loop. Make it part of this inner loop. 1417 // Note that a non loop header having a loop information means this loop information 1418 // has already been populated 1419 loop_information_ = info; 1420 } else { 1421 // Block is part of an inner loop. Do not update the loop information. 1422 // Note that we cannot do the check `info->Contains(loop_information_)->GetHeader()` 1423 // at this point, because this method is being called while populating `info`. 1424 } 1425 } 1426 1427 // Raw update of the loop information. SetLoopInformation(HLoopInformation * info)1428 void SetLoopInformation(HLoopInformation* info) { 1429 loop_information_ = info; 1430 } 1431 IsInLoop()1432 bool IsInLoop() const { return loop_information_ != nullptr; } 1433 GetTryCatchInformation()1434 TryCatchInformation* GetTryCatchInformation() const { return try_catch_information_; } 1435 SetTryCatchInformation(TryCatchInformation * try_catch_information)1436 void SetTryCatchInformation(TryCatchInformation* try_catch_information) { 1437 try_catch_information_ = try_catch_information; 1438 } 1439 IsTryBlock()1440 bool IsTryBlock() const { 1441 return try_catch_information_ != nullptr && try_catch_information_->IsTryBlock(); 1442 } 1443 IsCatchBlock()1444 bool IsCatchBlock() const { 1445 return try_catch_information_ != nullptr && try_catch_information_->IsCatchBlock(); 1446 } 1447 1448 // Returns the try entry that this block's successors should have. They will 1449 // be in the same try, unless the block ends in a try boundary. In that case, 1450 // the appropriate try entry will be returned. 1451 const HTryBoundary* ComputeTryEntryOfSuccessors() const; 1452 1453 bool HasThrowingInstructions() const; 1454 1455 // Returns whether this block dominates the blocked passed as parameter. 1456 bool Dominates(const HBasicBlock* block) const; 1457 GetLifetimeStart()1458 size_t GetLifetimeStart() const { return lifetime_start_; } GetLifetimeEnd()1459 size_t GetLifetimeEnd() const { return lifetime_end_; } 1460 SetLifetimeStart(size_t start)1461 void SetLifetimeStart(size_t start) { lifetime_start_ = start; } SetLifetimeEnd(size_t end)1462 void SetLifetimeEnd(size_t end) { lifetime_end_ = end; } 1463 1464 bool EndsWithControlFlowInstruction() const; 1465 bool EndsWithReturn() const; 1466 bool EndsWithIf() const; 1467 bool EndsWithTryBoundary() const; 1468 bool HasSinglePhi() const; 1469 1470 private: 1471 HGraph* graph_; 1472 ArenaVector<HBasicBlock*> predecessors_; 1473 ArenaVector<HBasicBlock*> successors_; 1474 HInstructionList instructions_; 1475 HInstructionList phis_; 1476 HLoopInformation* loop_information_; 1477 HBasicBlock* dominator_; 1478 ArenaVector<HBasicBlock*> dominated_blocks_; 1479 uint32_t block_id_; 1480 // The dex program counter of the first instruction of this block. 1481 const uint32_t dex_pc_; 1482 size_t lifetime_start_; 1483 size_t lifetime_end_; 1484 TryCatchInformation* try_catch_information_; 1485 1486 friend class HGraph; 1487 friend class HInstruction; 1488 // Allow manual control of the ordering of predecessors/successors 1489 friend class OptimizingUnitTestHelper; 1490 1491 DISALLOW_COPY_AND_ASSIGN(HBasicBlock); 1492 }; 1493 1494 // Iterates over the LoopInformation of all loops which contain 'block' 1495 // from the innermost to the outermost. 1496 class HLoopInformationOutwardIterator : public ValueObject { 1497 public: HLoopInformationOutwardIterator(const HBasicBlock & block)1498 explicit HLoopInformationOutwardIterator(const HBasicBlock& block) 1499 : current_(block.GetLoopInformation()) {} 1500 Done()1501 bool Done() const { return current_ == nullptr; } 1502 Advance()1503 void Advance() { 1504 DCHECK(!Done()); 1505 current_ = current_->GetPreHeader()->GetLoopInformation(); 1506 } 1507 Current()1508 HLoopInformation* Current() const { 1509 DCHECK(!Done()); 1510 return current_; 1511 } 1512 1513 private: 1514 HLoopInformation* current_; 1515 1516 DISALLOW_COPY_AND_ASSIGN(HLoopInformationOutwardIterator); 1517 }; 1518 1519 #define FOR_EACH_CONCRETE_INSTRUCTION_SCALAR_COMMON(M) \ 1520 M(Above, Condition) \ 1521 M(AboveOrEqual, Condition) \ 1522 M(Abs, UnaryOperation) \ 1523 M(Add, BinaryOperation) \ 1524 M(And, BinaryOperation) \ 1525 M(ArrayGet, Instruction) \ 1526 M(ArrayLength, Instruction) \ 1527 M(ArraySet, Instruction) \ 1528 M(Below, Condition) \ 1529 M(BelowOrEqual, Condition) \ 1530 M(BitwiseNegatedRight, BinaryOperation) \ 1531 M(BooleanNot, UnaryOperation) \ 1532 M(BoundsCheck, Instruction) \ 1533 M(BoundType, Instruction) \ 1534 M(CheckCast, Instruction) \ 1535 M(ClassTableGet, Instruction) \ 1536 M(ClearException, Instruction) \ 1537 M(ClinitCheck, Instruction) \ 1538 M(Compare, BinaryOperation) \ 1539 M(ConstructorFence, Instruction) \ 1540 M(CurrentMethod, Instruction) \ 1541 M(ShouldDeoptimizeFlag, Instruction) \ 1542 M(Deoptimize, Instruction) \ 1543 M(Div, BinaryOperation) \ 1544 M(DivZeroCheck, Instruction) \ 1545 M(DoubleConstant, Constant) \ 1546 M(Equal, Condition) \ 1547 M(Exit, Instruction) \ 1548 M(FloatConstant, Constant) \ 1549 M(Goto, Instruction) \ 1550 M(GreaterThan, Condition) \ 1551 M(GreaterThanOrEqual, Condition) \ 1552 M(If, Instruction) \ 1553 M(InstanceFieldGet, Instruction) \ 1554 M(InstanceFieldSet, Instruction) \ 1555 M(InstanceOf, Instruction) \ 1556 M(IntConstant, Constant) \ 1557 M(IntermediateAddress, Instruction) \ 1558 M(InvokeUnresolved, Invoke) \ 1559 M(InvokeInterface, Invoke) \ 1560 M(InvokeStaticOrDirect, Invoke) \ 1561 M(InvokeVirtual, Invoke) \ 1562 M(InvokePolymorphic, Invoke) \ 1563 M(InvokeCustom, Invoke) \ 1564 M(LessThan, Condition) \ 1565 M(LessThanOrEqual, Condition) \ 1566 M(LoadClass, Instruction) \ 1567 M(LoadException, Instruction) \ 1568 M(LoadMethodHandle, Instruction) \ 1569 M(LoadMethodType, Instruction) \ 1570 M(LoadString, Instruction) \ 1571 M(LongConstant, Constant) \ 1572 M(Max, Instruction) \ 1573 M(MemoryBarrier, Instruction) \ 1574 M(MethodEntryHook, Instruction) \ 1575 M(MethodExitHook, Instruction) \ 1576 M(Min, BinaryOperation) \ 1577 M(MonitorOperation, Instruction) \ 1578 M(Mul, BinaryOperation) \ 1579 M(Neg, UnaryOperation) \ 1580 M(NewArray, Instruction) \ 1581 M(NewInstance, Instruction) \ 1582 M(Nop, Instruction) \ 1583 M(Not, UnaryOperation) \ 1584 M(NotEqual, Condition) \ 1585 M(NullConstant, Instruction) \ 1586 M(NullCheck, Instruction) \ 1587 M(Or, BinaryOperation) \ 1588 M(PackedSwitch, Instruction) \ 1589 M(ParallelMove, Instruction) \ 1590 M(ParameterValue, Instruction) \ 1591 M(Phi, Instruction) \ 1592 M(Rem, BinaryOperation) \ 1593 M(Return, Instruction) \ 1594 M(ReturnVoid, Instruction) \ 1595 M(Ror, BinaryOperation) \ 1596 M(Shl, BinaryOperation) \ 1597 M(Shr, BinaryOperation) \ 1598 M(StaticFieldGet, Instruction) \ 1599 M(StaticFieldSet, Instruction) \ 1600 M(StringBuilderAppend, Instruction) \ 1601 M(UnresolvedInstanceFieldGet, Instruction) \ 1602 M(UnresolvedInstanceFieldSet, Instruction) \ 1603 M(UnresolvedStaticFieldGet, Instruction) \ 1604 M(UnresolvedStaticFieldSet, Instruction) \ 1605 M(Select, Instruction) \ 1606 M(Sub, BinaryOperation) \ 1607 M(SuspendCheck, Instruction) \ 1608 M(Throw, Instruction) \ 1609 M(TryBoundary, Instruction) \ 1610 M(TypeConversion, Instruction) \ 1611 M(UShr, BinaryOperation) \ 1612 M(Xor, BinaryOperation) 1613 1614 #define FOR_EACH_CONCRETE_INSTRUCTION_VECTOR_COMMON(M) \ 1615 M(VecReplicateScalar, VecUnaryOperation) \ 1616 M(VecExtractScalar, VecUnaryOperation) \ 1617 M(VecReduce, VecUnaryOperation) \ 1618 M(VecCnv, VecUnaryOperation) \ 1619 M(VecNeg, VecUnaryOperation) \ 1620 M(VecAbs, VecUnaryOperation) \ 1621 M(VecNot, VecUnaryOperation) \ 1622 M(VecAdd, VecBinaryOperation) \ 1623 M(VecHalvingAdd, VecBinaryOperation) \ 1624 M(VecSub, VecBinaryOperation) \ 1625 M(VecMul, VecBinaryOperation) \ 1626 M(VecDiv, VecBinaryOperation) \ 1627 M(VecMin, VecBinaryOperation) \ 1628 M(VecMax, VecBinaryOperation) \ 1629 M(VecAnd, VecBinaryOperation) \ 1630 M(VecAndNot, VecBinaryOperation) \ 1631 M(VecOr, VecBinaryOperation) \ 1632 M(VecXor, VecBinaryOperation) \ 1633 M(VecSaturationAdd, VecBinaryOperation) \ 1634 M(VecSaturationSub, VecBinaryOperation) \ 1635 M(VecShl, VecBinaryOperation) \ 1636 M(VecShr, VecBinaryOperation) \ 1637 M(VecUShr, VecBinaryOperation) \ 1638 M(VecSetScalars, VecOperation) \ 1639 M(VecMultiplyAccumulate, VecOperation) \ 1640 M(VecSADAccumulate, VecOperation) \ 1641 M(VecDotProd, VecOperation) \ 1642 M(VecLoad, VecMemoryOperation) \ 1643 M(VecStore, VecMemoryOperation) \ 1644 M(VecPredSetAll, VecPredSetOperation) \ 1645 M(VecPredWhile, VecPredSetOperation) \ 1646 M(VecPredToBoolean, VecOperation) \ 1647 M(VecCondition, VecPredSetOperation) \ 1648 M(VecPredNot, VecPredSetOperation) \ 1649 1650 #define FOR_EACH_CONCRETE_INSTRUCTION_COMMON(M) \ 1651 FOR_EACH_CONCRETE_INSTRUCTION_SCALAR_COMMON(M) \ 1652 FOR_EACH_CONCRETE_INSTRUCTION_VECTOR_COMMON(M) 1653 1654 /* 1655 * Instructions, shared across several (not all) architectures. 1656 */ 1657 #if !defined(ART_ENABLE_CODEGEN_arm) && !defined(ART_ENABLE_CODEGEN_arm64) 1658 #define FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) 1659 #else 1660 #define FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) \ 1661 M(DataProcWithShifterOp, Instruction) \ 1662 M(MultiplyAccumulate, Instruction) \ 1663 M(IntermediateAddressIndex, Instruction) 1664 #endif 1665 1666 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) 1667 1668 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) 1669 1670 #if defined(ART_ENABLE_CODEGEN_riscv64) 1671 #define FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(M) M(Riscv64ShiftAdd, Instruction) 1672 #else 1673 #define FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(M) 1674 #endif 1675 1676 #ifndef ART_ENABLE_CODEGEN_x86 1677 #define FOR_EACH_CONCRETE_INSTRUCTION_X86(M) 1678 #else 1679 #define FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \ 1680 M(X86ComputeBaseMethodAddress, Instruction) \ 1681 M(X86LoadFromConstantTable, Instruction) \ 1682 M(X86FPNeg, Instruction) \ 1683 M(X86PackedSwitch, Instruction) 1684 #endif 1685 1686 #if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64) 1687 #define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) \ 1688 M(X86AndNot, Instruction) \ 1689 M(X86MaskOrResetLeastSetBit, Instruction) 1690 #else 1691 #define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) 1692 #endif 1693 1694 #define FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) 1695 1696 #define FOR_EACH_CONCRETE_INSTRUCTION(M) \ 1697 FOR_EACH_CONCRETE_INSTRUCTION_COMMON(M) \ 1698 FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) \ 1699 FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) \ 1700 FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) \ 1701 FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(M) \ 1702 FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \ 1703 FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) \ 1704 FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M) 1705 1706 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ 1707 M(Condition, BinaryOperation) \ 1708 M(Constant, Instruction) \ 1709 M(UnaryOperation, Instruction) \ 1710 M(BinaryOperation, Instruction) \ 1711 M(Invoke, Instruction) \ 1712 M(VecOperation, Instruction) \ 1713 M(VecUnaryOperation, VecOperation) \ 1714 M(VecBinaryOperation, VecOperation) \ 1715 M(VecMemoryOperation, VecOperation) \ 1716 M(VecPredSetOperation, VecOperation) 1717 1718 #define FOR_EACH_INSTRUCTION(M) \ 1719 FOR_EACH_CONCRETE_INSTRUCTION(M) \ 1720 FOR_EACH_ABSTRACT_INSTRUCTION(M) 1721 1722 #define FORWARD_DECLARATION(type, super) class H##type; FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)1723 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 1724 #undef FORWARD_DECLARATION 1725 1726 #define DECLARE_INSTRUCTION(type) \ 1727 private: \ 1728 H##type& operator=(const H##type&) = delete; \ 1729 public: \ 1730 const char* DebugName() const override { return #type; } \ 1731 HInstruction* Clone(ArenaAllocator* arena) const override { \ 1732 DCHECK(IsClonable()); \ 1733 return new (arena) H##type(*this); \ 1734 } \ 1735 void Accept(HGraphVisitor* visitor) override 1736 1737 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 1738 private: \ 1739 H##type& operator=(const H##type&) = delete; \ 1740 public: 1741 1742 #define DEFAULT_COPY_CONSTRUCTOR(type) H##type(const H##type& other) = default; 1743 1744 template <typename T> 1745 class HUseListNode : public ArenaObject<kArenaAllocUseListNode>, 1746 public IntrusiveForwardListNode<HUseListNode<T>> { 1747 public: 1748 // Get the instruction which has this use as one of the inputs. 1749 T GetUser() const { return user_; } 1750 // Get the position of the input record that this use corresponds to. 1751 size_t GetIndex() const { return index_; } 1752 // Set the position of the input record that this use corresponds to. 1753 void SetIndex(size_t index) { index_ = index; } 1754 1755 private: 1756 HUseListNode(T user, size_t index) 1757 : user_(user), index_(index) {} 1758 1759 T const user_; 1760 size_t index_; 1761 1762 friend class HInstruction; 1763 1764 DISALLOW_COPY_AND_ASSIGN(HUseListNode); 1765 }; 1766 1767 template <typename T> 1768 using HUseList = IntrusiveForwardList<HUseListNode<T>>; 1769 1770 // This class is used by HEnvironment and HInstruction classes to record the 1771 // instructions they use and pointers to the corresponding HUseListNodes kept 1772 // by the used instructions. 1773 template <typename T> 1774 class HUserRecord : public ValueObject { 1775 public: HUserRecord()1776 HUserRecord() : instruction_(nullptr), before_use_node_() {} HUserRecord(HInstruction * instruction)1777 explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), before_use_node_() {} 1778 HUserRecord(const HUserRecord<T> & old_record,typename HUseList<T>::iterator before_use_node)1779 HUserRecord(const HUserRecord<T>& old_record, typename HUseList<T>::iterator before_use_node) 1780 : HUserRecord(old_record.instruction_, before_use_node) {} HUserRecord(HInstruction * instruction,typename HUseList<T>::iterator before_use_node)1781 HUserRecord(HInstruction* instruction, typename HUseList<T>::iterator before_use_node) 1782 : instruction_(instruction), before_use_node_(before_use_node) { 1783 DCHECK(instruction_ != nullptr); 1784 } 1785 GetInstruction()1786 HInstruction* GetInstruction() const { return instruction_; } GetBeforeUseNode()1787 typename HUseList<T>::iterator GetBeforeUseNode() const { return before_use_node_; } GetUseNode()1788 typename HUseList<T>::iterator GetUseNode() const { return ++GetBeforeUseNode(); } 1789 1790 private: 1791 // Instruction used by the user. 1792 HInstruction* instruction_; 1793 1794 // Iterator before the corresponding entry in the use list kept by 'instruction_'. 1795 typename HUseList<T>::iterator before_use_node_; 1796 }; 1797 1798 // Helper class that extracts the input instruction from HUserRecord<HInstruction*>. 1799 // This is used for HInstruction::GetInputs() to return a container wrapper providing 1800 // HInstruction* values even though the underlying container has HUserRecord<>s. 1801 struct HInputExtractor { operatorHInputExtractor1802 HInstruction* operator()(HUserRecord<HInstruction*>& record) const { 1803 return record.GetInstruction(); 1804 } operatorHInputExtractor1805 const HInstruction* operator()(const HUserRecord<HInstruction*>& record) const { 1806 return record.GetInstruction(); 1807 } 1808 }; 1809 1810 using HInputsRef = TransformArrayRef<HUserRecord<HInstruction*>, HInputExtractor>; 1811 using HConstInputsRef = TransformArrayRef<const HUserRecord<HInstruction*>, HInputExtractor>; 1812 1813 /** 1814 * Side-effects representation. 1815 * 1816 * For write/read dependences on fields/arrays, the dependence analysis uses 1817 * type disambiguation (e.g. a float field write cannot modify the value of an 1818 * integer field read) and the access type (e.g. a reference array write cannot 1819 * modify the value of a reference field read [although it may modify the 1820 * reference fetch prior to reading the field, which is represented by its own 1821 * write/read dependence]). The analysis makes conservative points-to 1822 * assumptions on reference types (e.g. two same typed arrays are assumed to be 1823 * the same, and any reference read depends on any reference read without 1824 * further regard of its type). 1825 * 1826 * kDependsOnGCBit is defined in the following way: instructions with kDependsOnGCBit must not be 1827 * alive across the point where garbage collection might happen. 1828 * 1829 * Note: Instructions with kCanTriggerGCBit do not depend on each other. 1830 * 1831 * kCanTriggerGCBit must be used for instructions for which GC might happen on the path across 1832 * those instructions from the compiler perspective (between this instruction and the next one 1833 * in the IR). 1834 * 1835 * Note: Instructions which can cause GC only on a fatal slow path do not need 1836 * kCanTriggerGCBit as the execution never returns to the instruction next to the exceptional 1837 * one. However the execution may return to compiled code if there is a catch block in the 1838 * current method; for this purpose the TryBoundary exit instruction has kCanTriggerGCBit 1839 * set. 1840 * 1841 * The internal representation uses 38-bit and is described in the table below. 1842 * The first line indicates the side effect, and for field/array accesses the 1843 * second line indicates the type of the access (in the order of the 1844 * DataType::Type enum). 1845 * The two numbered lines below indicate the bit position in the bitfield (read 1846 * vertically). 1847 * 1848 * |Depends on GC|ARRAY-R |FIELD-R |Can trigger GC|ARRAY-W |FIELD-W | 1849 * +-------------+---------+---------+--------------+---------+---------+ 1850 * | |DFJISCBZL|DFJISCBZL| |DFJISCBZL|DFJISCBZL| 1851 * | 3 |333333322|222222221| 1 |111111110|000000000| 1852 * | 7 |654321098|765432109| 8 |765432109|876543210| 1853 * 1854 * Note that, to ease the implementation, 'changes' bits are least significant 1855 * bits, while 'dependency' bits are most significant bits. 1856 */ 1857 class SideEffects : public ValueObject { 1858 public: SideEffects()1859 SideEffects() : flags_(0) {} 1860 None()1861 static SideEffects None() { 1862 return SideEffects(0); 1863 } 1864 All()1865 static SideEffects All() { 1866 return SideEffects(kAllChangeBits | kAllDependOnBits); 1867 } 1868 AllChanges()1869 static SideEffects AllChanges() { 1870 return SideEffects(kAllChangeBits); 1871 } 1872 AllDependencies()1873 static SideEffects AllDependencies() { 1874 return SideEffects(kAllDependOnBits); 1875 } 1876 AllExceptGCDependency()1877 static SideEffects AllExceptGCDependency() { 1878 return AllWritesAndReads().Union(SideEffects::CanTriggerGC()); 1879 } 1880 AllWritesAndReads()1881 static SideEffects AllWritesAndReads() { 1882 return SideEffects(kAllWrites | kAllReads); 1883 } 1884 AllWrites()1885 static SideEffects AllWrites() { 1886 return SideEffects(kAllWrites); 1887 } 1888 AllReads()1889 static SideEffects AllReads() { 1890 return SideEffects(kAllReads); 1891 } 1892 FieldWriteOfType(DataType::Type type,bool is_volatile)1893 static SideEffects FieldWriteOfType(DataType::Type type, bool is_volatile) { 1894 return is_volatile 1895 ? AllWritesAndReads() 1896 : SideEffects(TypeFlag(type, kFieldWriteOffset)); 1897 } 1898 ArrayWriteOfType(DataType::Type type)1899 static SideEffects ArrayWriteOfType(DataType::Type type) { 1900 return SideEffects(TypeFlag(type, kArrayWriteOffset)); 1901 } 1902 FieldReadOfType(DataType::Type type,bool is_volatile)1903 static SideEffects FieldReadOfType(DataType::Type type, bool is_volatile) { 1904 return is_volatile 1905 ? AllWritesAndReads() 1906 : SideEffects(TypeFlag(type, kFieldReadOffset)); 1907 } 1908 ArrayReadOfType(DataType::Type type)1909 static SideEffects ArrayReadOfType(DataType::Type type) { 1910 return SideEffects(TypeFlag(type, kArrayReadOffset)); 1911 } 1912 1913 // Returns whether GC might happen across this instruction from the compiler perspective so 1914 // the next instruction in the IR would see that. 1915 // 1916 // See the SideEffect class comments. CanTriggerGC()1917 static SideEffects CanTriggerGC() { 1918 return SideEffects(1ULL << kCanTriggerGCBit); 1919 } 1920 1921 // Returns whether the instruction must not be alive across a GC point. 1922 // 1923 // See the SideEffect class comments. DependsOnGC()1924 static SideEffects DependsOnGC() { 1925 return SideEffects(1ULL << kDependsOnGCBit); 1926 } 1927 1928 // Combines the side-effects of this and the other. Union(SideEffects other)1929 SideEffects Union(SideEffects other) const { 1930 return SideEffects(flags_ | other.flags_); 1931 } 1932 Exclusion(SideEffects other)1933 SideEffects Exclusion(SideEffects other) const { 1934 return SideEffects(flags_ & ~other.flags_); 1935 } 1936 Add(SideEffects other)1937 void Add(SideEffects other) { 1938 flags_ |= other.flags_; 1939 } 1940 Includes(SideEffects other)1941 bool Includes(SideEffects other) const { 1942 return (other.flags_ & flags_) == other.flags_; 1943 } 1944 HasSideEffects()1945 bool HasSideEffects() const { 1946 return (flags_ & kAllChangeBits); 1947 } 1948 HasDependencies()1949 bool HasDependencies() const { 1950 return (flags_ & kAllDependOnBits); 1951 } 1952 1953 // Returns true if there are no side effects or dependencies. DoesNothing()1954 bool DoesNothing() const { 1955 return flags_ == 0; 1956 } 1957 1958 // Returns true if something is written. DoesAnyWrite()1959 bool DoesAnyWrite() const { 1960 return (flags_ & kAllWrites); 1961 } 1962 1963 // Returns true if something is read. DoesAnyRead()1964 bool DoesAnyRead() const { 1965 return (flags_ & kAllReads); 1966 } 1967 1968 // Returns true if potentially everything is written and read 1969 // (every type and every kind of access). DoesAllReadWrite()1970 bool DoesAllReadWrite() const { 1971 return (flags_ & (kAllWrites | kAllReads)) == (kAllWrites | kAllReads); 1972 } 1973 DoesAll()1974 bool DoesAll() const { 1975 return flags_ == (kAllChangeBits | kAllDependOnBits); 1976 } 1977 1978 // Returns true if `this` may read something written by `other`. MayDependOn(SideEffects other)1979 bool MayDependOn(SideEffects other) const { 1980 const uint64_t depends_on_flags = (flags_ & kAllDependOnBits) >> kChangeBits; 1981 return (other.flags_ & depends_on_flags); 1982 } 1983 1984 // Returns string representation of flags (for debugging only). 1985 // Format: |x|DFJISCBZL|DFJISCBZL|y|DFJISCBZL|DFJISCBZL| ToString()1986 std::string ToString() const { 1987 std::string flags = "|"; 1988 for (int s = kLastBit; s >= 0; s--) { 1989 bool current_bit_is_set = ((flags_ >> s) & 1) != 0; 1990 if ((s == kDependsOnGCBit) || (s == kCanTriggerGCBit)) { 1991 // This is a bit for the GC side effect. 1992 if (current_bit_is_set) { 1993 flags += "GC"; 1994 } 1995 flags += "|"; 1996 } else { 1997 // This is a bit for the array/field analysis. 1998 // The underscore character stands for the 'can trigger GC' bit. 1999 static const char *kDebug = "LZBCSIJFDLZBCSIJFD_LZBCSIJFDLZBCSIJFD"; 2000 if (current_bit_is_set) { 2001 flags += kDebug[s]; 2002 } 2003 if ((s == kFieldWriteOffset) || (s == kArrayWriteOffset) || 2004 (s == kFieldReadOffset) || (s == kArrayReadOffset)) { 2005 flags += "|"; 2006 } 2007 } 2008 } 2009 return flags; 2010 } 2011 Equals(const SideEffects & other)2012 bool Equals(const SideEffects& other) const { return flags_ == other.flags_; } 2013 2014 private: 2015 static constexpr int kFieldArrayAnalysisBits = 9; 2016 2017 static constexpr int kFieldWriteOffset = 0; 2018 static constexpr int kArrayWriteOffset = kFieldWriteOffset + kFieldArrayAnalysisBits; 2019 static constexpr int kLastBitForWrites = kArrayWriteOffset + kFieldArrayAnalysisBits - 1; 2020 static constexpr int kCanTriggerGCBit = kLastBitForWrites + 1; 2021 2022 static constexpr int kChangeBits = kCanTriggerGCBit + 1; 2023 2024 static constexpr int kFieldReadOffset = kCanTriggerGCBit + 1; 2025 static constexpr int kArrayReadOffset = kFieldReadOffset + kFieldArrayAnalysisBits; 2026 static constexpr int kLastBitForReads = kArrayReadOffset + kFieldArrayAnalysisBits - 1; 2027 static constexpr int kDependsOnGCBit = kLastBitForReads + 1; 2028 2029 static constexpr int kLastBit = kDependsOnGCBit; 2030 static constexpr int kDependOnBits = kLastBit + 1 - kChangeBits; 2031 2032 // Aliases. 2033 2034 static_assert(kChangeBits == kDependOnBits, 2035 "the 'change' bits should match the 'depend on' bits."); 2036 2037 static constexpr uint64_t kAllChangeBits = ((1ULL << kChangeBits) - 1); 2038 static constexpr uint64_t kAllDependOnBits = ((1ULL << kDependOnBits) - 1) << kChangeBits; 2039 static constexpr uint64_t kAllWrites = 2040 ((1ULL << (kLastBitForWrites + 1 - kFieldWriteOffset)) - 1) << kFieldWriteOffset; 2041 static constexpr uint64_t kAllReads = 2042 ((1ULL << (kLastBitForReads + 1 - kFieldReadOffset)) - 1) << kFieldReadOffset; 2043 2044 // Translates type to bit flag. The type must correspond to a Java type. TypeFlag(DataType::Type type,int offset)2045 static uint64_t TypeFlag(DataType::Type type, int offset) { 2046 int shift; 2047 switch (type) { 2048 case DataType::Type::kReference: shift = 0; break; 2049 case DataType::Type::kBool: shift = 1; break; 2050 case DataType::Type::kInt8: shift = 2; break; 2051 case DataType::Type::kUint16: shift = 3; break; 2052 case DataType::Type::kInt16: shift = 4; break; 2053 case DataType::Type::kInt32: shift = 5; break; 2054 case DataType::Type::kInt64: shift = 6; break; 2055 case DataType::Type::kFloat32: shift = 7; break; 2056 case DataType::Type::kFloat64: shift = 8; break; 2057 default: 2058 LOG(FATAL) << "Unexpected data type " << type; 2059 UNREACHABLE(); 2060 } 2061 DCHECK_LE(kFieldWriteOffset, shift); 2062 DCHECK_LT(shift, kArrayWriteOffset); 2063 return UINT64_C(1) << (shift + offset); 2064 } 2065 2066 // Private constructor on direct flags value. SideEffects(uint64_t flags)2067 explicit SideEffects(uint64_t flags) : flags_(flags) {} 2068 2069 uint64_t flags_; 2070 }; 2071 2072 // A HEnvironment object contains the values of virtual registers at a given location. 2073 class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { 2074 public: HEnvironment(ArenaAllocator * allocator,size_t number_of_vregs,ArtMethod * method,uint32_t dex_pc,HInstruction * holder)2075 ALWAYS_INLINE HEnvironment(ArenaAllocator* allocator, 2076 size_t number_of_vregs, 2077 ArtMethod* method, 2078 uint32_t dex_pc, 2079 HInstruction* holder) 2080 : vregs_(number_of_vregs, allocator->Adapter(kArenaAllocEnvironmentVRegs)), 2081 locations_(allocator->Adapter(kArenaAllocEnvironmentLocations)), 2082 parent_(nullptr), 2083 method_(method), 2084 dex_pc_(dex_pc), 2085 holder_(holder) { 2086 } 2087 HEnvironment(ArenaAllocator * allocator,const HEnvironment & to_copy,HInstruction * holder)2088 ALWAYS_INLINE HEnvironment(ArenaAllocator* allocator, 2089 const HEnvironment& to_copy, 2090 HInstruction* holder) 2091 : HEnvironment(allocator, 2092 to_copy.Size(), 2093 to_copy.GetMethod(), 2094 to_copy.GetDexPc(), 2095 holder) {} 2096 AllocateLocations()2097 void AllocateLocations() { 2098 DCHECK(locations_.empty()); 2099 locations_.resize(vregs_.size()); 2100 } 2101 SetAndCopyParentChain(ArenaAllocator * allocator,HEnvironment * parent)2102 void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) { 2103 if (parent_ != nullptr) { 2104 parent_->SetAndCopyParentChain(allocator, parent); 2105 } else { 2106 parent_ = new (allocator) HEnvironment(allocator, *parent, holder_); 2107 parent_->CopyFrom(parent); 2108 if (parent->GetParent() != nullptr) { 2109 parent_->SetAndCopyParentChain(allocator, parent->GetParent()); 2110 } 2111 } 2112 } 2113 2114 void CopyFrom(ArrayRef<HInstruction* const> locals); 2115 void CopyFrom(HEnvironment* environment); 2116 2117 // Copy from `env`. If it's a loop phi for `loop_header`, copy the first 2118 // input to the loop phi instead. This is for inserting instructions that 2119 // require an environment (like HDeoptimization) in the loop pre-header. 2120 void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header); 2121 SetRawEnvAt(size_t index,HInstruction * instruction)2122 void SetRawEnvAt(size_t index, HInstruction* instruction) { 2123 vregs_[index] = HUserRecord<HEnvironment*>(instruction); 2124 } 2125 GetInstructionAt(size_t index)2126 HInstruction* GetInstructionAt(size_t index) const { 2127 return vregs_[index].GetInstruction(); 2128 } 2129 2130 void RemoveAsUserOfInput(size_t index) const; 2131 2132 // Replaces the input at the position 'index' with the replacement; the replacement and old 2133 // input instructions' env_uses_ lists are adjusted. The function works similar to 2134 // HInstruction::ReplaceInput. 2135 void ReplaceInput(HInstruction* replacement, size_t index); 2136 Size()2137 size_t Size() const { return vregs_.size(); } 2138 GetParent()2139 HEnvironment* GetParent() const { return parent_; } 2140 SetLocationAt(size_t index,Location location)2141 void SetLocationAt(size_t index, Location location) { 2142 locations_[index] = location; 2143 } 2144 GetLocationAt(size_t index)2145 Location GetLocationAt(size_t index) const { 2146 return locations_[index]; 2147 } 2148 GetDexPc()2149 uint32_t GetDexPc() const { 2150 return dex_pc_; 2151 } 2152 GetMethod()2153 ArtMethod* GetMethod() const { 2154 return method_; 2155 } 2156 GetHolder()2157 HInstruction* GetHolder() const { 2158 return holder_; 2159 } 2160 2161 IsFromInlinedInvoke()2162 bool IsFromInlinedInvoke() const { 2163 return GetParent() != nullptr; 2164 } 2165 2166 class EnvInputSelector { 2167 public: EnvInputSelector(const HEnvironment * e)2168 explicit EnvInputSelector(const HEnvironment* e) : env_(e) {} operator()2169 HInstruction* operator()(size_t s) const { 2170 return env_->GetInstructionAt(s); 2171 } 2172 private: 2173 const HEnvironment* env_; 2174 }; 2175 2176 using HConstEnvInputRef = TransformIterator<CountIter, EnvInputSelector>; GetEnvInputs()2177 IterationRange<HConstEnvInputRef> GetEnvInputs() const { 2178 IterationRange<CountIter> range(Range(Size())); 2179 return MakeIterationRange(MakeTransformIterator(range.begin(), EnvInputSelector(this)), 2180 MakeTransformIterator(range.end(), EnvInputSelector(this))); 2181 } 2182 2183 private: 2184 ArenaVector<HUserRecord<HEnvironment*>> vregs_; 2185 ArenaVector<Location> locations_; 2186 HEnvironment* parent_; 2187 ArtMethod* method_; 2188 const uint32_t dex_pc_; 2189 2190 // The instruction that holds this environment. 2191 HInstruction* const holder_; 2192 2193 friend class HInstruction; 2194 2195 DISALLOW_COPY_AND_ASSIGN(HEnvironment); 2196 }; 2197 2198 std::ostream& operator<<(std::ostream& os, const HInstruction& rhs); 2199 2200 // Iterates over the Environments 2201 class HEnvironmentIterator : public ValueObject { 2202 public: 2203 using iterator_category = std::forward_iterator_tag; 2204 using value_type = HEnvironment*; 2205 using difference_type = ptrdiff_t; 2206 using pointer = void; 2207 using reference = void; 2208 HEnvironmentIterator(HEnvironment * cur)2209 explicit HEnvironmentIterator(HEnvironment* cur) : cur_(cur) {} 2210 2211 HEnvironment* operator*() const { 2212 return cur_; 2213 } 2214 2215 HEnvironmentIterator& operator++() { 2216 DCHECK(cur_ != nullptr); 2217 cur_ = cur_->GetParent(); 2218 return *this; 2219 } 2220 2221 HEnvironmentIterator operator++(int) { 2222 HEnvironmentIterator prev(*this); 2223 ++(*this); 2224 return prev; 2225 } 2226 2227 bool operator==(const HEnvironmentIterator& other) const { 2228 return other.cur_ == cur_; 2229 } 2230 2231 bool operator!=(const HEnvironmentIterator& other) const { 2232 return !(*this == other); 2233 } 2234 2235 private: 2236 HEnvironment* cur_; 2237 }; 2238 2239 class HInstruction : public ArenaObject<kArenaAllocInstruction> { 2240 public: 2241 #define DECLARE_KIND(type, super) k##type, 2242 enum InstructionKind { // private marker to avoid generate-operator-out.py from processing. 2243 FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_KIND) 2244 kLastInstructionKind 2245 }; 2246 #undef DECLARE_KIND 2247 HInstruction(InstructionKind kind,SideEffects side_effects,uint32_t dex_pc)2248 HInstruction(InstructionKind kind, SideEffects side_effects, uint32_t dex_pc) 2249 : HInstruction(kind, DataType::Type::kVoid, side_effects, dex_pc) {} 2250 HInstruction(InstructionKind kind,DataType::Type type,SideEffects side_effects,uint32_t dex_pc)2251 HInstruction(InstructionKind kind, DataType::Type type, SideEffects side_effects, uint32_t dex_pc) 2252 : previous_(nullptr), 2253 next_(nullptr), 2254 block_(nullptr), 2255 dex_pc_(dex_pc), 2256 id_(-1), 2257 ssa_index_(-1), 2258 packed_fields_(0u), 2259 environment_(nullptr), 2260 locations_(nullptr), 2261 live_interval_(nullptr), 2262 lifetime_position_(kNoLifetime), 2263 side_effects_(side_effects), 2264 reference_type_handle_(ReferenceTypeInfo::CreateInvalid().GetTypeHandle()) { 2265 SetPackedField<InstructionKindField>(kind); 2266 SetPackedField<TypeField>(type); 2267 SetPackedFlag<kFlagReferenceTypeIsExact>(ReferenceTypeInfo::CreateInvalid().IsExact()); 2268 } 2269 ~HInstruction()2270 virtual ~HInstruction() {} 2271 2272 std::ostream& Dump(std::ostream& os, bool dump_args = false); 2273 2274 // Helper for dumping without argument information using operator<< 2275 struct NoArgsDump { 2276 const HInstruction* ins; 2277 }; DumpWithoutArgs()2278 NoArgsDump DumpWithoutArgs() const { 2279 return NoArgsDump{this}; 2280 } 2281 // Helper for dumping with argument information using operator<< 2282 struct ArgsDump { 2283 const HInstruction* ins; 2284 }; DumpWithArgs()2285 ArgsDump DumpWithArgs() const { 2286 return ArgsDump{this}; 2287 } 2288 GetNext()2289 HInstruction* GetNext() const { return next_; } GetPrevious()2290 HInstruction* GetPrevious() const { return previous_; } 2291 2292 HInstruction* GetNextDisregardingMoves() const; 2293 HInstruction* GetPreviousDisregardingMoves() const; 2294 GetBlock()2295 HBasicBlock* GetBlock() const { return block_; } GetAllocator()2296 ArenaAllocator* GetAllocator() const { return block_->GetGraph()->GetAllocator(); } SetBlock(HBasicBlock * block)2297 void SetBlock(HBasicBlock* block) { block_ = block; } IsInBlock()2298 bool IsInBlock() const { return block_ != nullptr; } IsInLoop()2299 bool IsInLoop() const { return block_->IsInLoop(); } IsLoopHeaderPhi()2300 bool IsLoopHeaderPhi() const { return IsPhi() && block_->IsLoopHeader(); } IsIrreducibleLoopHeaderPhi()2301 bool IsIrreducibleLoopHeaderPhi() const { 2302 return IsLoopHeaderPhi() && GetBlock()->GetLoopInformation()->IsIrreducible(); 2303 } 2304 2305 virtual ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() = 0; 2306 GetInputRecords()2307 ArrayRef<const HUserRecord<HInstruction*>> GetInputRecords() const { 2308 // One virtual method is enough, just const_cast<> and then re-add the const. 2309 return ArrayRef<const HUserRecord<HInstruction*>>( 2310 const_cast<HInstruction*>(this)->GetInputRecords()); 2311 } 2312 GetInputs()2313 HInputsRef GetInputs() { 2314 return MakeTransformArrayRef(GetInputRecords(), HInputExtractor()); 2315 } 2316 GetInputs()2317 HConstInputsRef GetInputs() const { 2318 return MakeTransformArrayRef(GetInputRecords(), HInputExtractor()); 2319 } 2320 InputCount()2321 size_t InputCount() const { return GetInputRecords().size(); } InputAt(size_t i)2322 HInstruction* InputAt(size_t i) const { return InputRecordAt(i).GetInstruction(); } 2323 HasInput(HInstruction * input)2324 bool HasInput(HInstruction* input) const { 2325 for (const HInstruction* i : GetInputs()) { 2326 if (i == input) { 2327 return true; 2328 } 2329 } 2330 return false; 2331 } 2332 SetRawInputAt(size_t index,HInstruction * input)2333 void SetRawInputAt(size_t index, HInstruction* input) { 2334 SetRawInputRecordAt(index, HUserRecord<HInstruction*>(input)); 2335 } 2336 2337 virtual void Accept(HGraphVisitor* visitor) = 0; 2338 virtual const char* DebugName() const = 0; 2339 GetType()2340 DataType::Type GetType() const { 2341 return TypeField::Decode(GetPackedFields()); 2342 } 2343 NeedsEnvironment()2344 virtual bool NeedsEnvironment() const { return false; } NeedsBss()2345 virtual bool NeedsBss() const { 2346 return false; 2347 } 2348 GetDexPc()2349 uint32_t GetDexPc() const { return dex_pc_; } 2350 IsControlFlow()2351 virtual bool IsControlFlow() const { return false; } 2352 2353 // Can the instruction throw? 2354 // TODO: We should rename to CanVisiblyThrow, as some instructions (like HNewInstance), 2355 // could throw OOME, but it is still OK to remove them if they are unused. CanThrow()2356 virtual bool CanThrow() const { return false; } 2357 2358 // Does the instruction always throw an exception unconditionally? AlwaysThrows()2359 virtual bool AlwaysThrows() const { return false; } 2360 // Will this instruction only cause async exceptions if it causes any at all? OnlyThrowsAsyncExceptions()2361 virtual bool OnlyThrowsAsyncExceptions() const { 2362 return false; 2363 } 2364 CanThrowIntoCatchBlock()2365 bool CanThrowIntoCatchBlock() const { return CanThrow() && block_->IsTryBlock(); } 2366 HasSideEffects()2367 bool HasSideEffects() const { return side_effects_.HasSideEffects(); } DoesAnyWrite()2368 bool DoesAnyWrite() const { return side_effects_.DoesAnyWrite(); } 2369 2370 // Does not apply for all instructions, but having this at top level greatly 2371 // simplifies the null check elimination. 2372 // TODO: Consider merging can_be_null into ReferenceTypeInfo. CanBeNull()2373 virtual bool CanBeNull() const { 2374 DCHECK_EQ(GetType(), DataType::Type::kReference) << "CanBeNull only applies to reference types"; 2375 return true; 2376 } 2377 CanDoImplicitNullCheckOn(HInstruction * obj)2378 virtual bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const { return false; } 2379 2380 // If this instruction will do an implicit null check, return the `HNullCheck` associated 2381 // with it. Otherwise return null. GetImplicitNullCheck()2382 HNullCheck* GetImplicitNullCheck() const { 2383 // Go over previous non-move instructions that are emitted at use site. 2384 HInstruction* prev_not_move = GetPreviousDisregardingMoves(); 2385 while (prev_not_move != nullptr && prev_not_move->IsEmittedAtUseSite()) { 2386 if (prev_not_move->IsNullCheck()) { 2387 return prev_not_move->AsNullCheck(); 2388 } 2389 prev_not_move = prev_not_move->GetPreviousDisregardingMoves(); 2390 } 2391 return nullptr; 2392 } 2393 IsActualObject()2394 virtual bool IsActualObject() const { 2395 return GetType() == DataType::Type::kReference; 2396 } 2397 2398 // Sets the ReferenceTypeInfo. The RTI must be valid. 2399 void SetReferenceTypeInfo(ReferenceTypeInfo rti); 2400 // Same as above, but we only set it if it's valid. Otherwise, we don't change the current RTI. 2401 void SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti); 2402 GetReferenceTypeInfo()2403 ReferenceTypeInfo GetReferenceTypeInfo() const { 2404 DCHECK_EQ(GetType(), DataType::Type::kReference); 2405 return ReferenceTypeInfo::CreateUnchecked(reference_type_handle_, 2406 GetPackedFlag<kFlagReferenceTypeIsExact>()); 2407 } 2408 AddUseAt(HInstruction * user,size_t index)2409 void AddUseAt(HInstruction* user, size_t index) { 2410 DCHECK(user != nullptr); 2411 // Note: fixup_end remains valid across push_front(). 2412 auto fixup_end = uses_.empty() ? uses_.begin() : ++uses_.begin(); 2413 ArenaAllocator* allocator = user->GetBlock()->GetGraph()->GetAllocator(); 2414 HUseListNode<HInstruction*>* new_node = 2415 new (allocator) HUseListNode<HInstruction*>(user, index); 2416 uses_.push_front(*new_node); 2417 FixUpUserRecordsAfterUseInsertion(fixup_end); 2418 } 2419 AddEnvUseAt(HEnvironment * user,size_t index)2420 void AddEnvUseAt(HEnvironment* user, size_t index) { 2421 DCHECK(user != nullptr); 2422 // Note: env_fixup_end remains valid across push_front(). 2423 auto env_fixup_end = env_uses_.empty() ? env_uses_.begin() : ++env_uses_.begin(); 2424 HUseListNode<HEnvironment*>* new_node = 2425 new (GetBlock()->GetGraph()->GetAllocator()) HUseListNode<HEnvironment*>(user, index); 2426 env_uses_.push_front(*new_node); 2427 FixUpUserRecordsAfterEnvUseInsertion(env_fixup_end); 2428 } 2429 RemoveAsUserOfInput(size_t input)2430 void RemoveAsUserOfInput(size_t input) { 2431 HUserRecord<HInstruction*> input_use = InputRecordAt(input); 2432 HUseList<HInstruction*>::iterator before_use_node = input_use.GetBeforeUseNode(); 2433 input_use.GetInstruction()->uses_.erase_after(before_use_node); 2434 input_use.GetInstruction()->FixUpUserRecordsAfterUseRemoval(before_use_node); 2435 } 2436 RemoveAsUserOfAllInputs()2437 void RemoveAsUserOfAllInputs() { 2438 for (const HUserRecord<HInstruction*>& input_use : GetInputRecords()) { 2439 HUseList<HInstruction*>::iterator before_use_node = input_use.GetBeforeUseNode(); 2440 input_use.GetInstruction()->uses_.erase_after(before_use_node); 2441 input_use.GetInstruction()->FixUpUserRecordsAfterUseRemoval(before_use_node); 2442 } 2443 } 2444 GetUses()2445 const HUseList<HInstruction*>& GetUses() const { return uses_; } GetEnvUses()2446 const HUseList<HEnvironment*>& GetEnvUses() const { return env_uses_; } 2447 HasUses()2448 bool HasUses() const { return !uses_.empty() || !env_uses_.empty(); } HasEnvironmentUses()2449 bool HasEnvironmentUses() const { return !env_uses_.empty(); } HasNonEnvironmentUses()2450 bool HasNonEnvironmentUses() const { return !uses_.empty(); } HasOnlyOneNonEnvironmentUse()2451 bool HasOnlyOneNonEnvironmentUse() const { 2452 return !HasEnvironmentUses() && GetUses().HasExactlyOneElement(); 2453 } 2454 IsRemovable()2455 bool IsRemovable() const { 2456 return 2457 !DoesAnyWrite() && 2458 // TODO(solanes): Merge calls from IsSuspendCheck to IsControlFlow into one that doesn't 2459 // do virtual dispatching. 2460 !IsSuspendCheck() && 2461 !IsNop() && 2462 !IsParameterValue() && 2463 // If we added an explicit barrier then we should keep it. 2464 !IsMemoryBarrier() && 2465 !IsConstructorFence() && 2466 !IsControlFlow() && 2467 !CanThrow(); 2468 } 2469 IsDeadAndRemovable()2470 bool IsDeadAndRemovable() const { 2471 return !HasUses() && IsRemovable(); 2472 } 2473 IsPhiDeadAndRemovable()2474 bool IsPhiDeadAndRemovable() const { 2475 DCHECK(IsPhi()); 2476 DCHECK(IsRemovable()) << " phis are always removable"; 2477 return !HasUses(); 2478 } 2479 2480 // Does this instruction dominate `other_instruction`? 2481 // Aborts if this instruction and `other_instruction` are different phis. 2482 bool Dominates(HInstruction* other_instruction) const; 2483 2484 // Same but with `strictly dominates` i.e. returns false if this instruction and 2485 // `other_instruction` are the same. 2486 bool StrictlyDominates(HInstruction* other_instruction) const; 2487 GetId()2488 int GetId() const { return id_; } SetId(int id)2489 void SetId(int id) { id_ = id; } 2490 GetSsaIndex()2491 int GetSsaIndex() const { return ssa_index_; } SetSsaIndex(int ssa_index)2492 void SetSsaIndex(int ssa_index) { ssa_index_ = ssa_index; } HasSsaIndex()2493 bool HasSsaIndex() const { return ssa_index_ != -1; } 2494 HasEnvironment()2495 bool HasEnvironment() const { return environment_ != nullptr; } GetEnvironment()2496 HEnvironment* GetEnvironment() const { return environment_; } GetAllEnvironments()2497 IterationRange<HEnvironmentIterator> GetAllEnvironments() const { 2498 return MakeIterationRange(HEnvironmentIterator(GetEnvironment()), 2499 HEnvironmentIterator(nullptr)); 2500 } 2501 // Set the `environment_` field. Raw because this method does not 2502 // update the uses lists. SetRawEnvironment(HEnvironment * environment)2503 void SetRawEnvironment(HEnvironment* environment) { 2504 DCHECK(environment_ == nullptr); 2505 DCHECK_EQ(environment->GetHolder(), this); 2506 environment_ = environment; 2507 } 2508 InsertRawEnvironment(HEnvironment * environment)2509 void InsertRawEnvironment(HEnvironment* environment) { 2510 DCHECK(environment_ != nullptr); 2511 DCHECK_EQ(environment->GetHolder(), this); 2512 DCHECK(environment->GetParent() == nullptr); 2513 environment->parent_ = environment_; 2514 environment_ = environment; 2515 } 2516 2517 void RemoveEnvironment(); 2518 2519 // Set the environment of this instruction, copying it from `environment`. While 2520 // copying, the uses lists are being updated. CopyEnvironmentFrom(HEnvironment * environment)2521 void CopyEnvironmentFrom(HEnvironment* environment) { 2522 DCHECK(environment_ == nullptr); 2523 ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); 2524 environment_ = new (allocator) HEnvironment(allocator, *environment, this); 2525 environment_->CopyFrom(environment); 2526 if (environment->GetParent() != nullptr) { 2527 environment_->SetAndCopyParentChain(allocator, environment->GetParent()); 2528 } 2529 } 2530 CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment * environment,HBasicBlock * block)2531 void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment, 2532 HBasicBlock* block) { 2533 DCHECK(environment_ == nullptr); 2534 ArenaAllocator* allocator = GetBlock()->GetGraph()->GetAllocator(); 2535 environment_ = new (allocator) HEnvironment(allocator, *environment, this); 2536 environment_->CopyFromWithLoopPhiAdjustment(environment, block); 2537 if (environment->GetParent() != nullptr) { 2538 environment_->SetAndCopyParentChain(allocator, environment->GetParent()); 2539 } 2540 } 2541 2542 // Returns the number of entries in the environment. Typically, that is the 2543 // number of dex registers in a method. It could be more in case of inlining. 2544 size_t EnvironmentSize() const; 2545 GetLocations()2546 LocationSummary* GetLocations() const { return locations_; } SetLocations(LocationSummary * locations)2547 void SetLocations(LocationSummary* locations) { locations_ = locations; } 2548 2549 void ReplaceWith(HInstruction* instruction); 2550 void ReplaceUsesDominatedBy(HInstruction* dominator, 2551 HInstruction* replacement, 2552 bool strictly_dominated = true); 2553 void ReplaceEnvUsesDominatedBy(HInstruction* dominator, HInstruction* replacement); 2554 void ReplaceInput(HInstruction* replacement, size_t index); 2555 2556 // This is almost the same as doing `ReplaceWith()`. But in this helper, the 2557 // uses of this instruction by `other` are *not* updated. ReplaceWithExceptInReplacementAtIndex(HInstruction * other,size_t use_index)2558 void ReplaceWithExceptInReplacementAtIndex(HInstruction* other, size_t use_index) { 2559 ReplaceWith(other); 2560 other->ReplaceInput(this, use_index); 2561 } 2562 2563 // Move `this` instruction before `cursor` 2564 void MoveBefore(HInstruction* cursor, bool do_checks = true); 2565 2566 // Move `this` before its first user and out of any loops. If there is no 2567 // out-of-loop user that dominates all other users, move the instruction 2568 // to the end of the out-of-loop common dominator of the user's blocks. 2569 // 2570 // This can be used only on non-throwing instructions with no side effects that 2571 // have at least one use but no environment uses. 2572 void MoveBeforeFirstUserAndOutOfLoops(); 2573 2574 #define INSTRUCTION_TYPE_CHECK(type, super) \ 2575 bool Is##type() const; 2576 2577 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 2578 #undef INSTRUCTION_TYPE_CHECK 2579 2580 #define INSTRUCTION_TYPE_CAST(type, super) \ 2581 const H##type* As##type() const; \ 2582 H##type* As##type(); \ 2583 const H##type* As##type##OrNull() const; \ 2584 H##type* As##type##OrNull(); 2585 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CAST)2586 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CAST) 2587 #undef INSTRUCTION_TYPE_CAST 2588 2589 // Return a clone of the instruction if it is clonable (shallow copy by default, custom copy 2590 // if a custom copy-constructor is provided for a particular type). If IsClonable() is false for 2591 // the instruction then the behaviour of this function is undefined. 2592 // 2593 // Note: It is semantically valid to create a clone of the instruction only until 2594 // prepare_for_register_allocator phase as lifetime, intervals and codegen info are not 2595 // copied. 2596 // 2597 // Note: HEnvironment and some other fields are not copied and are set to default values, see 2598 // 'explicit HInstruction(const HInstruction& other)' for details. 2599 virtual HInstruction* Clone([[maybe_unused]] ArenaAllocator* arena) const { 2600 LOG(FATAL) << "Cloning is not implemented for the instruction " << 2601 DebugName() << " " << GetId(); 2602 UNREACHABLE(); 2603 } 2604 IsFieldAccess()2605 virtual bool IsFieldAccess() const { 2606 return false; 2607 } 2608 GetFieldInfo()2609 virtual const FieldInfo& GetFieldInfo() const { 2610 CHECK(IsFieldAccess()) << "Only callable on field accessors not " << DebugName() << " " 2611 << *this; 2612 LOG(FATAL) << "Must be overridden by field accessors. Not implemented by " << *this; 2613 UNREACHABLE(); 2614 } 2615 2616 // Return whether instruction can be cloned (copied). IsClonable()2617 virtual bool IsClonable() const { return false; } 2618 2619 // Returns whether the instruction can be moved within the graph. 2620 // TODO: this method is used by LICM and GVN with possibly different 2621 // meanings? split and rename? CanBeMoved()2622 virtual bool CanBeMoved() const { return false; } 2623 2624 // Returns whether any data encoded in the two instructions is equal. 2625 // This method does not look at the inputs. Both instructions must be 2626 // of the same type, otherwise the method has undefined behavior. InstructionDataEquals(const HInstruction * other)2627 virtual bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const { 2628 return false; 2629 } 2630 2631 // Returns whether two instructions are equal, that is: 2632 // 1) They have the same type and contain the same data (InstructionDataEquals). 2633 // 2) Their inputs are identical. 2634 bool Equals(const HInstruction* other) const; 2635 GetKind()2636 InstructionKind GetKind() const { return GetPackedField<InstructionKindField>(); } 2637 ComputeHashCode()2638 virtual size_t ComputeHashCode() const { 2639 size_t result = GetKind(); 2640 for (const HInstruction* input : GetInputs()) { 2641 result = (result * 31) + input->GetId(); 2642 } 2643 return result; 2644 } 2645 GetSideEffects()2646 SideEffects GetSideEffects() const { return side_effects_; } SetSideEffects(SideEffects other)2647 void SetSideEffects(SideEffects other) { side_effects_ = other; } AddSideEffects(SideEffects other)2648 void AddSideEffects(SideEffects other) { side_effects_.Add(other); } 2649 GetLifetimePosition()2650 size_t GetLifetimePosition() const { return lifetime_position_; } SetLifetimePosition(size_t position)2651 void SetLifetimePosition(size_t position) { lifetime_position_ = position; } GetLiveInterval()2652 LiveInterval* GetLiveInterval() const { return live_interval_; } SetLiveInterval(LiveInterval * interval)2653 void SetLiveInterval(LiveInterval* interval) { live_interval_ = interval; } HasLiveInterval()2654 bool HasLiveInterval() const { return live_interval_ != nullptr; } 2655 IsSuspendCheckEntry()2656 bool IsSuspendCheckEntry() const { return IsSuspendCheck() && GetBlock()->IsEntryBlock(); } 2657 2658 // Returns whether the code generation of the instruction will require to have access 2659 // to the current method. Such instructions are: 2660 // (1): Instructions that require an environment, as calling the runtime requires 2661 // to walk the stack and have the current method stored at a specific stack address. 2662 // (2): HCurrentMethod, potentially used by HInvokeStaticOrDirect, HLoadString, or HLoadClass 2663 // to access the dex cache. NeedsCurrentMethod()2664 bool NeedsCurrentMethod() const { 2665 return NeedsEnvironment() || IsCurrentMethod(); 2666 } 2667 2668 // Does this instruction have any use in an environment before 2669 // control flow hits 'other'? 2670 bool HasAnyEnvironmentUseBefore(HInstruction* other); 2671 2672 // Remove all references to environment uses of this instruction. 2673 // The caller must ensure that this is safe to do. 2674 void RemoveEnvironmentUsers(); 2675 IsEmittedAtUseSite()2676 bool IsEmittedAtUseSite() const { return GetPackedFlag<kFlagEmittedAtUseSite>(); } MarkEmittedAtUseSite()2677 void MarkEmittedAtUseSite() { SetPackedFlag<kFlagEmittedAtUseSite>(true); } 2678 2679 protected: 2680 // If set, the machine code for this instruction is assumed to be generated by 2681 // its users. Used by liveness analysis to compute use positions accordingly. 2682 static constexpr size_t kFlagEmittedAtUseSite = 0u; 2683 static constexpr size_t kFlagReferenceTypeIsExact = kFlagEmittedAtUseSite + 1; 2684 static constexpr size_t kFieldInstructionKind = kFlagReferenceTypeIsExact + 1; 2685 static constexpr size_t kFieldInstructionKindSize = 2686 MinimumBitsToStore(static_cast<size_t>(InstructionKind::kLastInstructionKind - 1)); 2687 static constexpr size_t kFieldType = 2688 kFieldInstructionKind + kFieldInstructionKindSize; 2689 static constexpr size_t kFieldTypeSize = 2690 MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast)); 2691 static constexpr size_t kNumberOfGenericPackedBits = kFieldType + kFieldTypeSize; 2692 static constexpr size_t kMaxNumberOfPackedBits = sizeof(uint32_t) * kBitsPerByte; 2693 2694 static_assert(kNumberOfGenericPackedBits <= kMaxNumberOfPackedBits, 2695 "Too many generic packed fields"); 2696 2697 using TypeField = BitField<DataType::Type, kFieldType, kFieldTypeSize>; 2698 InputRecordAt(size_t i)2699 const HUserRecord<HInstruction*> InputRecordAt(size_t i) const { 2700 return GetInputRecords()[i]; 2701 } 2702 SetRawInputRecordAt(size_t index,const HUserRecord<HInstruction * > & input)2703 void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) { 2704 ArrayRef<HUserRecord<HInstruction*>> input_records = GetInputRecords(); 2705 input_records[index] = input; 2706 } 2707 GetPackedFields()2708 uint32_t GetPackedFields() const { 2709 return packed_fields_; 2710 } 2711 2712 template <size_t flag> GetPackedFlag()2713 bool GetPackedFlag() const { 2714 return (packed_fields_ & (1u << flag)) != 0u; 2715 } 2716 2717 template <size_t flag> 2718 void SetPackedFlag(bool value = true) { 2719 packed_fields_ = (packed_fields_ & ~(1u << flag)) | ((value ? 1u : 0u) << flag); 2720 } 2721 2722 template <typename BitFieldType> GetPackedField()2723 typename BitFieldType::value_type GetPackedField() const { 2724 return BitFieldType::Decode(packed_fields_); 2725 } 2726 2727 template <typename BitFieldType> SetPackedField(typename BitFieldType::value_type value)2728 void SetPackedField(typename BitFieldType::value_type value) { 2729 DCHECK(IsUint<BitFieldType::size>(static_cast<uintptr_t>(value))); 2730 packed_fields_ = BitFieldType::Update(value, packed_fields_); 2731 } 2732 2733 // Copy construction for the instruction (used for Clone function). 2734 // 2735 // Fields (e.g. lifetime, intervals and codegen info) associated with phases starting from 2736 // prepare_for_register_allocator are not copied (set to default values). 2737 // 2738 // Copy constructors must be provided for every HInstruction type; default copy constructor is 2739 // fine for most of them. However for some of the instructions a custom copy constructor must be 2740 // specified (when instruction has non-trivially copyable fields and must have a special behaviour 2741 // for copying them). HInstruction(const HInstruction & other)2742 explicit HInstruction(const HInstruction& other) 2743 : previous_(nullptr), 2744 next_(nullptr), 2745 block_(nullptr), 2746 dex_pc_(other.dex_pc_), 2747 id_(-1), 2748 ssa_index_(-1), 2749 packed_fields_(other.packed_fields_), 2750 environment_(nullptr), 2751 locations_(nullptr), 2752 live_interval_(nullptr), 2753 lifetime_position_(kNoLifetime), 2754 side_effects_(other.side_effects_), 2755 reference_type_handle_(other.reference_type_handle_) { 2756 } 2757 2758 private: 2759 using InstructionKindField = 2760 BitField<InstructionKind, kFieldInstructionKind, kFieldInstructionKindSize>; 2761 FixUpUserRecordsAfterUseInsertion(HUseList<HInstruction * >::iterator fixup_end)2762 void FixUpUserRecordsAfterUseInsertion(HUseList<HInstruction*>::iterator fixup_end) { 2763 auto before_use_node = uses_.before_begin(); 2764 for (auto use_node = uses_.begin(); use_node != fixup_end; ++use_node) { 2765 HInstruction* user = use_node->GetUser(); 2766 size_t input_index = use_node->GetIndex(); 2767 user->SetRawInputRecordAt(input_index, HUserRecord<HInstruction*>(this, before_use_node)); 2768 before_use_node = use_node; 2769 } 2770 } 2771 FixUpUserRecordsAfterUseRemoval(HUseList<HInstruction * >::iterator before_use_node)2772 void FixUpUserRecordsAfterUseRemoval(HUseList<HInstruction*>::iterator before_use_node) { 2773 auto next = ++HUseList<HInstruction*>::iterator(before_use_node); 2774 if (next != uses_.end()) { 2775 HInstruction* next_user = next->GetUser(); 2776 size_t next_index = next->GetIndex(); 2777 DCHECK(next_user->InputRecordAt(next_index).GetInstruction() == this); 2778 next_user->SetRawInputRecordAt(next_index, HUserRecord<HInstruction*>(this, before_use_node)); 2779 } 2780 } 2781 FixUpUserRecordsAfterEnvUseInsertion(HUseList<HEnvironment * >::iterator env_fixup_end)2782 void FixUpUserRecordsAfterEnvUseInsertion(HUseList<HEnvironment*>::iterator env_fixup_end) { 2783 auto before_env_use_node = env_uses_.before_begin(); 2784 for (auto env_use_node = env_uses_.begin(); env_use_node != env_fixup_end; ++env_use_node) { 2785 HEnvironment* user = env_use_node->GetUser(); 2786 size_t input_index = env_use_node->GetIndex(); 2787 user->vregs_[input_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); 2788 before_env_use_node = env_use_node; 2789 } 2790 } 2791 FixUpUserRecordsAfterEnvUseRemoval(HUseList<HEnvironment * >::iterator before_env_use_node)2792 void FixUpUserRecordsAfterEnvUseRemoval(HUseList<HEnvironment*>::iterator before_env_use_node) { 2793 auto next = ++HUseList<HEnvironment*>::iterator(before_env_use_node); 2794 if (next != env_uses_.end()) { 2795 HEnvironment* next_user = next->GetUser(); 2796 size_t next_index = next->GetIndex(); 2797 DCHECK(next_user->vregs_[next_index].GetInstruction() == this); 2798 next_user->vregs_[next_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); 2799 } 2800 } 2801 2802 HInstruction* previous_; 2803 HInstruction* next_; 2804 HBasicBlock* block_; 2805 const uint32_t dex_pc_; 2806 2807 // An instruction gets an id when it is added to the graph. 2808 // It reflects creation order. A negative id means the instruction 2809 // has not been added to the graph. 2810 int id_; 2811 2812 // When doing liveness analysis, instructions that have uses get an SSA index. 2813 int ssa_index_; 2814 2815 // Packed fields. 2816 uint32_t packed_fields_; 2817 2818 // List of instructions that have this instruction as input. 2819 HUseList<HInstruction*> uses_; 2820 2821 // List of environments that contain this instruction. 2822 HUseList<HEnvironment*> env_uses_; 2823 2824 // The environment associated with this instruction. Not null if the instruction 2825 // might jump out of the method. 2826 HEnvironment* environment_; 2827 2828 // Set by the code generator. 2829 LocationSummary* locations_; 2830 2831 // Set by the liveness analysis. 2832 LiveInterval* live_interval_; 2833 2834 // Set by the liveness analysis, this is the position in a linear 2835 // order of blocks where this instruction's live interval start. 2836 size_t lifetime_position_; 2837 2838 SideEffects side_effects_; 2839 2840 // The reference handle part of the reference type info. 2841 // The IsExact() flag is stored in packed fields. 2842 // TODO: for primitive types this should be marked as invalid. 2843 ReferenceTypeInfo::TypeHandle reference_type_handle_; 2844 2845 friend class GraphChecker; 2846 friend class HBasicBlock; 2847 friend class HEnvironment; 2848 friend class HGraph; 2849 friend class HInstructionList; 2850 }; 2851 2852 std::ostream& operator<<(std::ostream& os, HInstruction::InstructionKind rhs); 2853 std::ostream& operator<<(std::ostream& os, const HInstruction::NoArgsDump rhs); 2854 std::ostream& operator<<(std::ostream& os, const HInstruction::ArgsDump rhs); 2855 std::ostream& operator<<(std::ostream& os, const HUseList<HInstruction*>& lst); 2856 std::ostream& operator<<(std::ostream& os, const HUseList<HEnvironment*>& lst); 2857 2858 // Forward declarations for friends 2859 template <typename InnerIter> struct HSTLInstructionIterator; 2860 2861 // Iterates over the instructions, while preserving the next instruction 2862 // in case the current instruction gets removed from the list by the user 2863 // of this iterator. 2864 class HInstructionIterator : public ValueObject { 2865 public: HInstructionIterator(const HInstructionList & instructions)2866 explicit HInstructionIterator(const HInstructionList& instructions) 2867 : instruction_(instructions.first_instruction_) { 2868 next_ = Done() ? nullptr : instruction_->GetNext(); 2869 } 2870 Done()2871 bool Done() const { return instruction_ == nullptr; } Current()2872 HInstruction* Current() const { return instruction_; } Advance()2873 void Advance() { 2874 instruction_ = next_; 2875 next_ = Done() ? nullptr : instruction_->GetNext(); 2876 } 2877 2878 private: HInstructionIterator()2879 HInstructionIterator() : instruction_(nullptr), next_(nullptr) {} 2880 2881 HInstruction* instruction_; 2882 HInstruction* next_; 2883 2884 friend struct HSTLInstructionIterator<HInstructionIterator>; 2885 }; 2886 2887 // Iterates over the instructions without saving the next instruction, 2888 // therefore handling changes in the graph potentially made by the user 2889 // of this iterator. 2890 class HInstructionIteratorHandleChanges : public ValueObject { 2891 public: 2892 explicit HInstructionIteratorHandleChanges(const HInstructionList& instructions) 2893 : instruction_(instructions.first_instruction_) { 2894 } 2895 2896 bool Done() const { return instruction_ == nullptr; } 2897 HInstruction* Current() const { return instruction_; } 2898 void Advance() { 2899 instruction_ = instruction_->GetNext(); 2900 } 2901 2902 private: 2903 HInstructionIteratorHandleChanges() : instruction_(nullptr) {} 2904 2905 HInstruction* instruction_; 2906 2907 friend struct HSTLInstructionIterator<HInstructionIteratorHandleChanges>; 2908 }; 2909 2910 2911 class HBackwardInstructionIterator : public ValueObject { 2912 public: 2913 explicit HBackwardInstructionIterator(const HInstructionList& instructions) 2914 : instruction_(instructions.last_instruction_) { 2915 next_ = Done() ? nullptr : instruction_->GetPrevious(); 2916 } 2917 2918 explicit HBackwardInstructionIterator(HInstruction* instruction) : instruction_(instruction) { 2919 next_ = Done() ? nullptr : instruction_->GetPrevious(); 2920 } 2921 2922 bool Done() const { return instruction_ == nullptr; } 2923 HInstruction* Current() const { return instruction_; } 2924 void Advance() { 2925 instruction_ = next_; 2926 next_ = Done() ? nullptr : instruction_->GetPrevious(); 2927 } 2928 2929 private: 2930 HBackwardInstructionIterator() : instruction_(nullptr), next_(nullptr) {} 2931 2932 HInstruction* instruction_; 2933 HInstruction* next_; 2934 2935 friend struct HSTLInstructionIterator<HBackwardInstructionIterator>; 2936 }; 2937 2938 template <typename InnerIter> 2939 struct HSTLInstructionIterator : public ValueObject { 2940 public: 2941 using iterator_category = std::forward_iterator_tag; 2942 using value_type = HInstruction*; 2943 using difference_type = ptrdiff_t; 2944 using pointer = void; 2945 using reference = void; 2946 2947 static_assert(std::is_same_v<InnerIter, HBackwardInstructionIterator> || 2948 std::is_same_v<InnerIter, HInstructionIterator> || 2949 std::is_same_v<InnerIter, HInstructionIteratorHandleChanges>, 2950 "Unknown wrapped iterator!"); 2951 2952 explicit HSTLInstructionIterator(InnerIter inner) : inner_(inner) {} 2953 HInstruction* operator*() const { 2954 DCHECK(inner_.Current() != nullptr); 2955 return inner_.Current(); 2956 } 2957 2958 HSTLInstructionIterator<InnerIter>& operator++() { 2959 DCHECK(*this != HSTLInstructionIterator<InnerIter>::EndIter()); 2960 inner_.Advance(); 2961 return *this; 2962 } 2963 2964 HSTLInstructionIterator<InnerIter> operator++(int) { 2965 HSTLInstructionIterator<InnerIter> prev(*this); 2966 ++(*this); 2967 return prev; 2968 } 2969 2970 bool operator==(const HSTLInstructionIterator<InnerIter>& other) const { 2971 return inner_.Current() == other.inner_.Current(); 2972 } 2973 2974 bool operator!=(const HSTLInstructionIterator<InnerIter>& other) const { 2975 return !(*this == other); 2976 } 2977 2978 static HSTLInstructionIterator<InnerIter> EndIter() { 2979 return HSTLInstructionIterator<InnerIter>(InnerIter()); 2980 } 2981 2982 private: 2983 InnerIter inner_; 2984 }; 2985 2986 template <typename InnerIter> 2987 IterationRange<HSTLInstructionIterator<InnerIter>> MakeSTLInstructionIteratorRange(InnerIter iter) { 2988 return MakeIterationRange(HSTLInstructionIterator<InnerIter>(iter), 2989 HSTLInstructionIterator<InnerIter>::EndIter()); 2990 } 2991 2992 class HVariableInputSizeInstruction : public HInstruction { 2993 public: 2994 using HInstruction::GetInputRecords; // Keep the const version visible. 2995 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() override { 2996 return ArrayRef<HUserRecord<HInstruction*>>(inputs_); 2997 } 2998 2999 void AddInput(HInstruction* input); 3000 void InsertInputAt(size_t index, HInstruction* input); 3001 void RemoveInputAt(size_t index); 3002 3003 // Removes all the inputs. 3004 // Also removes this instructions from each input's use list 3005 // (for non-environment uses only). 3006 void RemoveAllInputs(); 3007 3008 protected: 3009 HVariableInputSizeInstruction(InstructionKind inst_kind, 3010 SideEffects side_effects, 3011 uint32_t dex_pc, 3012 ArenaAllocator* allocator, 3013 size_t number_of_inputs, 3014 ArenaAllocKind kind) 3015 : HInstruction(inst_kind, side_effects, dex_pc), 3016 inputs_(number_of_inputs, allocator->Adapter(kind)) {} 3017 HVariableInputSizeInstruction(InstructionKind inst_kind, 3018 DataType::Type type, 3019 SideEffects side_effects, 3020 uint32_t dex_pc, 3021 ArenaAllocator* allocator, 3022 size_t number_of_inputs, 3023 ArenaAllocKind kind) 3024 : HInstruction(inst_kind, type, side_effects, dex_pc), 3025 inputs_(number_of_inputs, allocator->Adapter(kind)) {} 3026 3027 DEFAULT_COPY_CONSTRUCTOR(VariableInputSizeInstruction); 3028 3029 ArenaVector<HUserRecord<HInstruction*>> inputs_; 3030 }; 3031 3032 template<size_t N> 3033 class HExpression : public HInstruction { 3034 public: 3035 HExpression<N>(InstructionKind kind, SideEffects side_effects, uint32_t dex_pc) 3036 : HInstruction(kind, side_effects, dex_pc), inputs_() {} 3037 HExpression<N>(InstructionKind kind, 3038 DataType::Type type, 3039 SideEffects side_effects, 3040 uint32_t dex_pc) 3041 : HInstruction(kind, type, side_effects, dex_pc), inputs_() {} 3042 virtual ~HExpression() {} 3043 3044 using HInstruction::GetInputRecords; // Keep the const version visible. 3045 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 3046 return ArrayRef<HUserRecord<HInstruction*>>(inputs_); 3047 } 3048 3049 protected: 3050 DEFAULT_COPY_CONSTRUCTOR(Expression<N>); 3051 3052 private: 3053 std::array<HUserRecord<HInstruction*>, N> inputs_; 3054 3055 friend class SsaBuilder; 3056 }; 3057 3058 // HExpression specialization for N=0. 3059 template<> 3060 class HExpression<0> : public HInstruction { 3061 public: 3062 using HInstruction::HInstruction; 3063 3064 virtual ~HExpression() {} 3065 3066 using HInstruction::GetInputRecords; // Keep the const version visible. 3067 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 3068 return ArrayRef<HUserRecord<HInstruction*>>(); 3069 } 3070 3071 protected: 3072 DEFAULT_COPY_CONSTRUCTOR(Expression<0>); 3073 3074 private: 3075 friend class SsaBuilder; 3076 }; 3077 3078 class HMethodEntryHook : public HExpression<0> { 3079 public: 3080 explicit HMethodEntryHook(uint32_t dex_pc) 3081 : HExpression(kMethodEntryHook, SideEffects::All(), dex_pc) {} 3082 3083 bool NeedsEnvironment() const override { 3084 return true; 3085 } 3086 3087 bool CanThrow() const override { return true; } 3088 3089 DECLARE_INSTRUCTION(MethodEntryHook); 3090 3091 protected: 3092 DEFAULT_COPY_CONSTRUCTOR(MethodEntryHook); 3093 }; 3094 3095 class HMethodExitHook : public HExpression<1> { 3096 public: 3097 HMethodExitHook(HInstruction* value, uint32_t dex_pc) 3098 : HExpression(kMethodExitHook, SideEffects::All(), dex_pc) { 3099 SetRawInputAt(0, value); 3100 } 3101 3102 bool NeedsEnvironment() const override { 3103 return true; 3104 } 3105 3106 bool CanThrow() const override { return true; } 3107 3108 DECLARE_INSTRUCTION(MethodExitHook); 3109 3110 protected: 3111 DEFAULT_COPY_CONSTRUCTOR(MethodExitHook); 3112 }; 3113 3114 // Represents dex's RETURN_VOID opcode. A HReturnVoid is a control flow 3115 // instruction that branches to the exit block. 3116 class HReturnVoid final : public HExpression<0> { 3117 public: 3118 explicit HReturnVoid(uint32_t dex_pc = kNoDexPc) 3119 : HExpression(kReturnVoid, SideEffects::None(), dex_pc) { 3120 } 3121 3122 bool IsControlFlow() const override { return true; } 3123 3124 DECLARE_INSTRUCTION(ReturnVoid); 3125 3126 protected: 3127 DEFAULT_COPY_CONSTRUCTOR(ReturnVoid); 3128 }; 3129 3130 // Represents dex's RETURN opcodes. A HReturn is a control flow 3131 // instruction that branches to the exit block. 3132 class HReturn final : public HExpression<1> { 3133 public: 3134 explicit HReturn(HInstruction* value, uint32_t dex_pc = kNoDexPc) 3135 : HExpression(kReturn, SideEffects::None(), dex_pc) { 3136 SetRawInputAt(0, value); 3137 } 3138 3139 bool IsControlFlow() const override { return true; } 3140 3141 DECLARE_INSTRUCTION(Return); 3142 3143 protected: 3144 DEFAULT_COPY_CONSTRUCTOR(Return); 3145 }; 3146 3147 class HPhi final : public HVariableInputSizeInstruction { 3148 public: 3149 HPhi(ArenaAllocator* allocator, 3150 uint32_t reg_number, 3151 size_t number_of_inputs, 3152 DataType::Type type, 3153 uint32_t dex_pc = kNoDexPc) 3154 : HVariableInputSizeInstruction( 3155 kPhi, 3156 ToPhiType(type), 3157 SideEffects::None(), 3158 dex_pc, 3159 allocator, 3160 number_of_inputs, 3161 kArenaAllocPhiInputs), 3162 reg_number_(reg_number) { 3163 DCHECK_NE(GetType(), DataType::Type::kVoid); 3164 // Phis are constructed live and marked dead if conflicting or unused. 3165 // Individual steps of SsaBuilder should assume that if a phi has been 3166 // marked dead, it can be ignored and will be removed by SsaPhiElimination. 3167 SetPackedFlag<kFlagIsLive>(true); 3168 SetPackedFlag<kFlagCanBeNull>(true); 3169 } 3170 3171 bool IsClonable() const override { return true; } 3172 3173 // Returns a type equivalent to the given `type`, but that a `HPhi` can hold. 3174 static DataType::Type ToPhiType(DataType::Type type) { 3175 return DataType::Kind(type); 3176 } 3177 3178 bool IsCatchPhi() const { return GetBlock()->IsCatchBlock(); } 3179 3180 void SetType(DataType::Type new_type) { 3181 // Make sure that only valid type changes occur. The following are allowed: 3182 // (1) int -> float/ref (primitive type propagation), 3183 // (2) long -> double (primitive type propagation). 3184 DCHECK(GetType() == new_type || 3185 (GetType() == DataType::Type::kInt32 && new_type == DataType::Type::kFloat32) || 3186 (GetType() == DataType::Type::kInt32 && new_type == DataType::Type::kReference) || 3187 (GetType() == DataType::Type::kInt64 && new_type == DataType::Type::kFloat64)); 3188 SetPackedField<TypeField>(new_type); 3189 } 3190 3191 bool CanBeNull() const override { return GetPackedFlag<kFlagCanBeNull>(); } 3192 void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); } 3193 3194 uint32_t GetRegNumber() const { return reg_number_; } 3195 3196 void SetDead() { SetPackedFlag<kFlagIsLive>(false); } 3197 void SetLive() { SetPackedFlag<kFlagIsLive>(true); } 3198 bool IsDead() const { return !IsLive(); } 3199 bool IsLive() const { return GetPackedFlag<kFlagIsLive>(); } 3200 3201 bool IsVRegEquivalentOf(const HInstruction* other) const { 3202 return other != nullptr 3203 && other->IsPhi() 3204 && other->GetBlock() == GetBlock() 3205 && other->AsPhi()->GetRegNumber() == GetRegNumber(); 3206 } 3207 3208 bool HasEquivalentPhi() const { 3209 if (GetPrevious() != nullptr && GetPrevious()->AsPhi()->GetRegNumber() == GetRegNumber()) { 3210 return true; 3211 } 3212 if (GetNext() != nullptr && GetNext()->AsPhi()->GetRegNumber() == GetRegNumber()) { 3213 return true; 3214 } 3215 return false; 3216 } 3217 3218 // Returns the next equivalent phi (starting from the current one) or null if there is none. 3219 // An equivalent phi is a phi having the same dex register and type. 3220 // It assumes that phis with the same dex register are adjacent. 3221 HPhi* GetNextEquivalentPhiWithSameType() { 3222 HInstruction* next = GetNext(); 3223 while (next != nullptr && next->AsPhi()->GetRegNumber() == reg_number_) { 3224 if (next->GetType() == GetType()) { 3225 return next->AsPhi(); 3226 } 3227 next = next->GetNext(); 3228 } 3229 return nullptr; 3230 } 3231 3232 DECLARE_INSTRUCTION(Phi); 3233 3234 protected: 3235 DEFAULT_COPY_CONSTRUCTOR(Phi); 3236 3237 private: 3238 static constexpr size_t kFlagIsLive = HInstruction::kNumberOfGenericPackedBits; 3239 static constexpr size_t kFlagCanBeNull = kFlagIsLive + 1; 3240 static constexpr size_t kNumberOfPhiPackedBits = kFlagCanBeNull + 1; 3241 static_assert(kNumberOfPhiPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 3242 3243 const uint32_t reg_number_; 3244 }; 3245 3246 // The exit instruction is the only instruction of the exit block. 3247 // Instructions aborting the method (HThrow and HReturn) must branch to the 3248 // exit block. 3249 class HExit final : public HExpression<0> { 3250 public: 3251 explicit HExit(uint32_t dex_pc = kNoDexPc) 3252 : HExpression(kExit, SideEffects::None(), dex_pc) { 3253 } 3254 3255 bool IsControlFlow() const override { return true; } 3256 3257 DECLARE_INSTRUCTION(Exit); 3258 3259 protected: 3260 DEFAULT_COPY_CONSTRUCTOR(Exit); 3261 }; 3262 3263 // Jumps from one block to another. 3264 class HGoto final : public HExpression<0> { 3265 public: 3266 explicit HGoto(uint32_t dex_pc = kNoDexPc) 3267 : HExpression(kGoto, SideEffects::None(), dex_pc) { 3268 } 3269 3270 bool IsClonable() const override { return true; } 3271 bool IsControlFlow() const override { return true; } 3272 3273 HBasicBlock* GetSuccessor() const { 3274 return GetBlock()->GetSingleSuccessor(); 3275 } 3276 3277 DECLARE_INSTRUCTION(Goto); 3278 3279 protected: 3280 DEFAULT_COPY_CONSTRUCTOR(Goto); 3281 }; 3282 3283 class HConstant : public HExpression<0> { 3284 public: 3285 explicit HConstant(InstructionKind kind, DataType::Type type, uint32_t dex_pc = kNoDexPc) 3286 : HExpression(kind, type, SideEffects::None(), dex_pc) { 3287 } 3288 3289 bool CanBeMoved() const override { return true; } 3290 3291 // Is this constant -1 in the arithmetic sense? 3292 virtual bool IsMinusOne() const { return false; } 3293 // Is this constant 0 in the arithmetic sense? 3294 virtual bool IsArithmeticZero() const { return false; } 3295 // Is this constant a 0-bit pattern? 3296 virtual bool IsZeroBitPattern() const { return false; } 3297 // Is this constant 1 in the arithmetic sense? 3298 virtual bool IsOne() const { return false; } 3299 3300 virtual uint64_t GetValueAsUint64() const = 0; 3301 3302 DECLARE_ABSTRACT_INSTRUCTION(Constant); 3303 3304 protected: 3305 DEFAULT_COPY_CONSTRUCTOR(Constant); 3306 }; 3307 3308 class HNullConstant final : public HConstant { 3309 public: 3310 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 3311 return true; 3312 } 3313 3314 uint64_t GetValueAsUint64() const override { return 0; } 3315 3316 size_t ComputeHashCode() const override { return 0; } 3317 3318 // The null constant representation is a 0-bit pattern. 3319 bool IsZeroBitPattern() const override { return true; } 3320 3321 DECLARE_INSTRUCTION(NullConstant); 3322 3323 protected: 3324 DEFAULT_COPY_CONSTRUCTOR(NullConstant); 3325 3326 private: 3327 explicit HNullConstant(uint32_t dex_pc = kNoDexPc) 3328 : HConstant(kNullConstant, DataType::Type::kReference, dex_pc) { 3329 } 3330 3331 friend class HGraph; 3332 }; 3333 3334 // Constants of the type int. Those can be from Dex instructions, or 3335 // synthesized (for example with the if-eqz instruction). 3336 class HIntConstant final : public HConstant { 3337 public: 3338 int32_t GetValue() const { return value_; } 3339 3340 uint64_t GetValueAsUint64() const override { 3341 return static_cast<uint64_t>(static_cast<uint32_t>(value_)); 3342 } 3343 3344 bool InstructionDataEquals(const HInstruction* other) const override { 3345 DCHECK(other->IsIntConstant()) << other->DebugName(); 3346 return other->AsIntConstant()->value_ == value_; 3347 } 3348 3349 size_t ComputeHashCode() const override { return GetValue(); } 3350 3351 bool IsMinusOne() const override { return GetValue() == -1; } 3352 bool IsArithmeticZero() const override { return GetValue() == 0; } 3353 bool IsZeroBitPattern() const override { return GetValue() == 0; } 3354 bool IsOne() const override { return GetValue() == 1; } 3355 3356 // Integer constants are used to encode Boolean values as well, 3357 // where 1 means true and 0 means false. 3358 bool IsTrue() const { return GetValue() == 1; } 3359 bool IsFalse() const { return GetValue() == 0; } 3360 3361 DECLARE_INSTRUCTION(IntConstant); 3362 3363 protected: 3364 DEFAULT_COPY_CONSTRUCTOR(IntConstant); 3365 3366 private: 3367 explicit HIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) 3368 : HConstant(kIntConstant, DataType::Type::kInt32, dex_pc), value_(value) { 3369 } 3370 explicit HIntConstant(bool value, uint32_t dex_pc = kNoDexPc) 3371 : HConstant(kIntConstant, DataType::Type::kInt32, dex_pc), 3372 value_(value ? 1 : 0) { 3373 } 3374 3375 const int32_t value_; 3376 3377 friend class HGraph; 3378 ART_FRIEND_TEST(GraphTest, InsertInstructionBefore); 3379 ART_FRIEND_TYPED_TEST(ParallelMoveTest, ConstantLast); 3380 }; 3381 3382 class HLongConstant final : public HConstant { 3383 public: 3384 int64_t GetValue() const { return value_; } 3385 3386 uint64_t GetValueAsUint64() const override { return value_; } 3387 3388 bool InstructionDataEquals(const HInstruction* other) const override { 3389 DCHECK(other->IsLongConstant()) << other->DebugName(); 3390 return other->AsLongConstant()->value_ == value_; 3391 } 3392 3393 size_t ComputeHashCode() const override { return static_cast<size_t>(GetValue()); } 3394 3395 bool IsMinusOne() const override { return GetValue() == -1; } 3396 bool IsArithmeticZero() const override { return GetValue() == 0; } 3397 bool IsZeroBitPattern() const override { return GetValue() == 0; } 3398 bool IsOne() const override { return GetValue() == 1; } 3399 3400 DECLARE_INSTRUCTION(LongConstant); 3401 3402 protected: 3403 DEFAULT_COPY_CONSTRUCTOR(LongConstant); 3404 3405 private: 3406 explicit HLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) 3407 : HConstant(kLongConstant, DataType::Type::kInt64, dex_pc), 3408 value_(value) { 3409 } 3410 3411 const int64_t value_; 3412 3413 friend class HGraph; 3414 }; 3415 3416 class HFloatConstant final : public HConstant { 3417 public: 3418 float GetValue() const { return value_; } 3419 3420 uint64_t GetValueAsUint64() const override { 3421 return static_cast<uint64_t>(bit_cast<uint32_t, float>(value_)); 3422 } 3423 3424 bool InstructionDataEquals(const HInstruction* other) const override { 3425 DCHECK(other->IsFloatConstant()) << other->DebugName(); 3426 return other->AsFloatConstant()->GetValueAsUint64() == GetValueAsUint64(); 3427 } 3428 3429 size_t ComputeHashCode() const override { return static_cast<size_t>(GetValue()); } 3430 3431 bool IsMinusOne() const override { 3432 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f)); 3433 } 3434 bool IsArithmeticZero() const override { 3435 return std::fpclassify(value_) == FP_ZERO; 3436 } 3437 bool IsArithmeticPositiveZero() const { 3438 return IsArithmeticZero() && !std::signbit(value_); 3439 } 3440 bool IsArithmeticNegativeZero() const { 3441 return IsArithmeticZero() && std::signbit(value_); 3442 } 3443 bool IsZeroBitPattern() const override { 3444 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f); 3445 } 3446 bool IsOne() const override { 3447 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(1.0f); 3448 } 3449 bool IsNaN() const { 3450 return std::isnan(value_); 3451 } 3452 3453 DECLARE_INSTRUCTION(FloatConstant); 3454 3455 protected: 3456 DEFAULT_COPY_CONSTRUCTOR(FloatConstant); 3457 3458 private: 3459 explicit HFloatConstant(float value, uint32_t dex_pc = kNoDexPc) 3460 : HConstant(kFloatConstant, DataType::Type::kFloat32, dex_pc), 3461 value_(value) { 3462 } 3463 explicit HFloatConstant(int32_t value, uint32_t dex_pc = kNoDexPc) 3464 : HConstant(kFloatConstant, DataType::Type::kFloat32, dex_pc), 3465 value_(bit_cast<float, int32_t>(value)) { 3466 } 3467 3468 const float value_; 3469 3470 // Only the SsaBuilder and HGraph can create floating-point constants. 3471 friend class SsaBuilder; 3472 friend class HGraph; 3473 }; 3474 3475 class HDoubleConstant final : public HConstant { 3476 public: 3477 double GetValue() const { return value_; } 3478 3479 uint64_t GetValueAsUint64() const override { return bit_cast<uint64_t, double>(value_); } 3480 3481 bool InstructionDataEquals(const HInstruction* other) const override { 3482 DCHECK(other->IsDoubleConstant()) << other->DebugName(); 3483 return other->AsDoubleConstant()->GetValueAsUint64() == GetValueAsUint64(); 3484 } 3485 3486 size_t ComputeHashCode() const override { return static_cast<size_t>(GetValue()); } 3487 3488 bool IsMinusOne() const override { 3489 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0)); 3490 } 3491 bool IsArithmeticZero() const override { 3492 return std::fpclassify(value_) == FP_ZERO; 3493 } 3494 bool IsArithmeticPositiveZero() const { 3495 return IsArithmeticZero() && !std::signbit(value_); 3496 } 3497 bool IsArithmeticNegativeZero() const { 3498 return IsArithmeticZero() && std::signbit(value_); 3499 } 3500 bool IsZeroBitPattern() const override { 3501 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0)); 3502 } 3503 bool IsOne() const override { 3504 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>(1.0); 3505 } 3506 bool IsNaN() const { 3507 return std::isnan(value_); 3508 } 3509 3510 DECLARE_INSTRUCTION(DoubleConstant); 3511 3512 protected: 3513 DEFAULT_COPY_CONSTRUCTOR(DoubleConstant); 3514 3515 private: 3516 explicit HDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) 3517 : HConstant(kDoubleConstant, DataType::Type::kFloat64, dex_pc), 3518 value_(value) { 3519 } 3520 explicit HDoubleConstant(int64_t value, uint32_t dex_pc = kNoDexPc) 3521 : HConstant(kDoubleConstant, DataType::Type::kFloat64, dex_pc), 3522 value_(bit_cast<double, int64_t>(value)) { 3523 } 3524 3525 const double value_; 3526 3527 // Only the SsaBuilder and HGraph can create floating-point constants. 3528 friend class SsaBuilder; 3529 friend class HGraph; 3530 }; 3531 3532 // Conditional branch. A block ending with an HIf instruction must have 3533 // two successors. 3534 class HIf final : public HExpression<1> { 3535 public: 3536 explicit HIf(HInstruction* input, uint32_t dex_pc = kNoDexPc) 3537 : HExpression(kIf, SideEffects::None(), dex_pc), 3538 true_count_(std::numeric_limits<uint16_t>::max()), 3539 false_count_(std::numeric_limits<uint16_t>::max()) { 3540 SetRawInputAt(0, input); 3541 } 3542 3543 bool IsClonable() const override { return true; } 3544 bool IsControlFlow() const override { return true; } 3545 3546 HBasicBlock* IfTrueSuccessor() const { 3547 return GetBlock()->GetSuccessors()[0]; 3548 } 3549 3550 HBasicBlock* IfFalseSuccessor() const { 3551 return GetBlock()->GetSuccessors()[1]; 3552 } 3553 3554 void SetTrueCount(uint16_t count) { true_count_ = count; } 3555 uint16_t GetTrueCount() const { return true_count_; } 3556 3557 void SetFalseCount(uint16_t count) { false_count_ = count; } 3558 uint16_t GetFalseCount() const { return false_count_; } 3559 3560 DECLARE_INSTRUCTION(If); 3561 3562 protected: 3563 DEFAULT_COPY_CONSTRUCTOR(If); 3564 3565 private: 3566 uint16_t true_count_; 3567 uint16_t false_count_; 3568 }; 3569 3570 3571 // Abstract instruction which marks the beginning and/or end of a try block and 3572 // links it to the respective exception handlers. Behaves the same as a Goto in 3573 // non-exceptional control flow. 3574 // Normal-flow successor is stored at index zero, exception handlers under 3575 // higher indices in no particular order. 3576 class HTryBoundary final : public HExpression<0> { 3577 public: 3578 enum class BoundaryKind { 3579 kEntry, 3580 kExit, 3581 kLast = kExit 3582 }; 3583 3584 // SideEffects::CanTriggerGC prevents instructions with SideEffects::DependOnGC to be alive 3585 // across the catch block entering edges as GC might happen during throwing an exception. 3586 // TryBoundary with BoundaryKind::kExit is conservatively used for that as there is no 3587 // HInstruction which a catch block must start from. 3588 explicit HTryBoundary(BoundaryKind kind, uint32_t dex_pc = kNoDexPc) 3589 : HExpression(kTryBoundary, 3590 (kind == BoundaryKind::kExit) ? SideEffects::CanTriggerGC() 3591 : SideEffects::None(), 3592 dex_pc) { 3593 SetPackedField<BoundaryKindField>(kind); 3594 } 3595 3596 bool IsControlFlow() const override { return true; } 3597 3598 // Returns the block's non-exceptional successor (index zero). 3599 HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors()[0]; } 3600 3601 ArrayRef<HBasicBlock* const> GetExceptionHandlers() const { 3602 return ArrayRef<HBasicBlock* const>(GetBlock()->GetSuccessors()).SubArray(1u); 3603 } 3604 3605 // Returns whether `handler` is among its exception handlers (non-zero index 3606 // successors). 3607 bool HasExceptionHandler(const HBasicBlock& handler) const { 3608 DCHECK(handler.IsCatchBlock()); 3609 return GetBlock()->HasSuccessor(&handler, 1u /* Skip first successor. */); 3610 } 3611 3612 // If not present already, adds `handler` to its block's list of exception 3613 // handlers. 3614 void AddExceptionHandler(HBasicBlock* handler) { 3615 if (!HasExceptionHandler(*handler)) { 3616 GetBlock()->AddSuccessor(handler); 3617 } 3618 } 3619 3620 BoundaryKind GetBoundaryKind() const { return GetPackedField<BoundaryKindField>(); } 3621 bool IsEntry() const { return GetBoundaryKind() == BoundaryKind::kEntry; } 3622 3623 bool HasSameExceptionHandlersAs(const HTryBoundary& other) const; 3624 3625 DECLARE_INSTRUCTION(TryBoundary); 3626 3627 protected: 3628 DEFAULT_COPY_CONSTRUCTOR(TryBoundary); 3629 3630 private: 3631 static constexpr size_t kFieldBoundaryKind = kNumberOfGenericPackedBits; 3632 static constexpr size_t kFieldBoundaryKindSize = 3633 MinimumBitsToStore(static_cast<size_t>(BoundaryKind::kLast)); 3634 static constexpr size_t kNumberOfTryBoundaryPackedBits = 3635 kFieldBoundaryKind + kFieldBoundaryKindSize; 3636 static_assert(kNumberOfTryBoundaryPackedBits <= kMaxNumberOfPackedBits, 3637 "Too many packed fields."); 3638 using BoundaryKindField = BitField<BoundaryKind, kFieldBoundaryKind, kFieldBoundaryKindSize>; 3639 }; 3640 3641 // Deoptimize to interpreter, upon checking a condition. 3642 class HDeoptimize final : public HVariableInputSizeInstruction { 3643 public: 3644 // Use this constructor when the `HDeoptimize` acts as a barrier, where no code can move 3645 // across. 3646 HDeoptimize(ArenaAllocator* allocator, 3647 HInstruction* cond, 3648 DeoptimizationKind kind, 3649 uint32_t dex_pc) 3650 : HVariableInputSizeInstruction( 3651 kDeoptimize, 3652 SideEffects::All(), 3653 dex_pc, 3654 allocator, 3655 /* number_of_inputs= */ 1, 3656 kArenaAllocMisc) { 3657 SetPackedFlag<kFieldCanBeMoved>(false); 3658 SetPackedField<DeoptimizeKindField>(kind); 3659 SetRawInputAt(0, cond); 3660 } 3661 3662 bool IsClonable() const override { return true; } 3663 3664 // Use this constructor when the `HDeoptimize` guards an instruction, and any user 3665 // that relies on the deoptimization to pass should have its input be the `HDeoptimize` 3666 // instead of `guard`. 3667 // We set CanTriggerGC to prevent any intermediate address to be live 3668 // at the point of the `HDeoptimize`. 3669 HDeoptimize(ArenaAllocator* allocator, 3670 HInstruction* cond, 3671 HInstruction* guard, 3672 DeoptimizationKind kind, 3673 uint32_t dex_pc) 3674 : HVariableInputSizeInstruction( 3675 kDeoptimize, 3676 guard->GetType(), 3677 SideEffects::CanTriggerGC(), 3678 dex_pc, 3679 allocator, 3680 /* number_of_inputs= */ 2, 3681 kArenaAllocMisc) { 3682 SetPackedFlag<kFieldCanBeMoved>(true); 3683 SetPackedField<DeoptimizeKindField>(kind); 3684 SetRawInputAt(0, cond); 3685 SetRawInputAt(1, guard); 3686 } 3687 3688 bool CanBeMoved() const override { return GetPackedFlag<kFieldCanBeMoved>(); } 3689 3690 bool InstructionDataEquals(const HInstruction* other) const override { 3691 return (other->CanBeMoved() == CanBeMoved()) && 3692 (other->AsDeoptimize()->GetDeoptimizationKind() == GetDeoptimizationKind()); 3693 } 3694 3695 bool NeedsEnvironment() const override { return true; } 3696 3697 bool CanThrow() const override { return true; } 3698 3699 DeoptimizationKind GetDeoptimizationKind() const { return GetPackedField<DeoptimizeKindField>(); } 3700 3701 bool GuardsAnInput() const { 3702 return InputCount() == 2; 3703 } 3704 3705 HInstruction* GuardedInput() const { 3706 DCHECK(GuardsAnInput()); 3707 return InputAt(1); 3708 } 3709 3710 void RemoveGuard() { 3711 RemoveInputAt(1); 3712 } 3713 3714 DECLARE_INSTRUCTION(Deoptimize); 3715 3716 protected: 3717 DEFAULT_COPY_CONSTRUCTOR(Deoptimize); 3718 3719 private: 3720 static constexpr size_t kFieldCanBeMoved = kNumberOfGenericPackedBits; 3721 static constexpr size_t kFieldDeoptimizeKind = kNumberOfGenericPackedBits + 1; 3722 static constexpr size_t kFieldDeoptimizeKindSize = 3723 MinimumBitsToStore(static_cast<size_t>(DeoptimizationKind::kLast)); 3724 static constexpr size_t kNumberOfDeoptimizePackedBits = 3725 kFieldDeoptimizeKind + kFieldDeoptimizeKindSize; 3726 static_assert(kNumberOfDeoptimizePackedBits <= kMaxNumberOfPackedBits, 3727 "Too many packed fields."); 3728 using DeoptimizeKindField = 3729 BitField<DeoptimizationKind, kFieldDeoptimizeKind, kFieldDeoptimizeKindSize>; 3730 }; 3731 3732 // Represents a should_deoptimize flag. Currently used for CHA-based devirtualization. 3733 // The compiled code checks this flag value in a guard before devirtualized call and 3734 // if it's true, starts to do deoptimization. 3735 // It has a 4-byte slot on stack. 3736 // TODO: allocate a register for this flag. 3737 class HShouldDeoptimizeFlag final : public HVariableInputSizeInstruction { 3738 public: 3739 // CHA guards are only optimized in a separate pass and it has no side effects 3740 // with regard to other passes. 3741 HShouldDeoptimizeFlag(ArenaAllocator* allocator, uint32_t dex_pc) 3742 : HVariableInputSizeInstruction(kShouldDeoptimizeFlag, 3743 DataType::Type::kInt32, 3744 SideEffects::None(), 3745 dex_pc, 3746 allocator, 3747 0, 3748 kArenaAllocCHA) { 3749 } 3750 3751 // We do all CHA guard elimination/motion in a single pass, after which there is no 3752 // further guard elimination/motion since a guard might have been used for justification 3753 // of the elimination of another guard. Therefore, we pretend this guard cannot be moved 3754 // to avoid other optimizations trying to move it. 3755 bool CanBeMoved() const override { return false; } 3756 3757 DECLARE_INSTRUCTION(ShouldDeoptimizeFlag); 3758 3759 protected: 3760 DEFAULT_COPY_CONSTRUCTOR(ShouldDeoptimizeFlag); 3761 }; 3762 3763 // Represents the ArtMethod that was passed as a first argument to 3764 // the method. It is used by instructions that depend on it, like 3765 // instructions that work with the dex cache. 3766 class HCurrentMethod final : public HExpression<0> { 3767 public: 3768 explicit HCurrentMethod(DataType::Type type, uint32_t dex_pc = kNoDexPc) 3769 : HExpression(kCurrentMethod, type, SideEffects::None(), dex_pc) { 3770 } 3771 3772 DECLARE_INSTRUCTION(CurrentMethod); 3773 3774 protected: 3775 DEFAULT_COPY_CONSTRUCTOR(CurrentMethod); 3776 }; 3777 3778 // Fetches an ArtMethod from the virtual table or the interface method table 3779 // of a class. 3780 class HClassTableGet final : public HExpression<1> { 3781 public: 3782 enum class TableKind { 3783 kVTable, 3784 kIMTable, 3785 kLast = kIMTable 3786 }; 3787 HClassTableGet(HInstruction* cls, 3788 DataType::Type type, 3789 TableKind kind, 3790 size_t index, 3791 uint32_t dex_pc) 3792 : HExpression(kClassTableGet, type, SideEffects::None(), dex_pc), 3793 index_(index) { 3794 SetPackedField<TableKindField>(kind); 3795 SetRawInputAt(0, cls); 3796 } 3797 3798 bool IsClonable() const override { return true; } 3799 bool CanBeMoved() const override { return true; } 3800 bool InstructionDataEquals(const HInstruction* other) const override { 3801 return other->AsClassTableGet()->GetIndex() == index_ && 3802 other->AsClassTableGet()->GetPackedFields() == GetPackedFields(); 3803 } 3804 3805 TableKind GetTableKind() const { return GetPackedField<TableKindField>(); } 3806 size_t GetIndex() const { return index_; } 3807 3808 DECLARE_INSTRUCTION(ClassTableGet); 3809 3810 protected: 3811 DEFAULT_COPY_CONSTRUCTOR(ClassTableGet); 3812 3813 private: 3814 static constexpr size_t kFieldTableKind = kNumberOfGenericPackedBits; 3815 static constexpr size_t kFieldTableKindSize = 3816 MinimumBitsToStore(static_cast<size_t>(TableKind::kLast)); 3817 static constexpr size_t kNumberOfClassTableGetPackedBits = kFieldTableKind + kFieldTableKindSize; 3818 static_assert(kNumberOfClassTableGetPackedBits <= kMaxNumberOfPackedBits, 3819 "Too many packed fields."); 3820 using TableKindField = BitField<TableKind, kFieldTableKind, kFieldTableKindSize>; 3821 3822 // The index of the ArtMethod in the table. 3823 const size_t index_; 3824 }; 3825 3826 // PackedSwitch (jump table). A block ending with a PackedSwitch instruction will 3827 // have one successor for each entry in the switch table, and the final successor 3828 // will be the block containing the next Dex opcode. 3829 class HPackedSwitch final : public HExpression<1> { 3830 public: 3831 HPackedSwitch(int32_t start_value, 3832 uint32_t num_entries, 3833 HInstruction* input, 3834 uint32_t dex_pc = kNoDexPc) 3835 : HExpression(kPackedSwitch, SideEffects::None(), dex_pc), 3836 start_value_(start_value), 3837 num_entries_(num_entries) { 3838 SetRawInputAt(0, input); 3839 } 3840 3841 bool IsClonable() const override { return true; } 3842 3843 bool IsControlFlow() const override { return true; } 3844 3845 int32_t GetStartValue() const { return start_value_; } 3846 3847 uint32_t GetNumEntries() const { return num_entries_; } 3848 3849 HBasicBlock* GetDefaultBlock() const { 3850 // Last entry is the default block. 3851 return GetBlock()->GetSuccessors()[num_entries_]; 3852 } 3853 DECLARE_INSTRUCTION(PackedSwitch); 3854 3855 protected: 3856 DEFAULT_COPY_CONSTRUCTOR(PackedSwitch); 3857 3858 private: 3859 const int32_t start_value_; 3860 const uint32_t num_entries_; 3861 }; 3862 3863 class HUnaryOperation : public HExpression<1> { 3864 public: 3865 HUnaryOperation(InstructionKind kind, 3866 DataType::Type result_type, 3867 HInstruction* input, 3868 uint32_t dex_pc = kNoDexPc) 3869 : HExpression(kind, result_type, SideEffects::None(), dex_pc) { 3870 SetRawInputAt(0, input); 3871 } 3872 3873 // All of the UnaryOperation instructions are clonable. 3874 bool IsClonable() const override { return true; } 3875 3876 HInstruction* GetInput() const { return InputAt(0); } 3877 DataType::Type GetResultType() const { return GetType(); } 3878 3879 bool CanBeMoved() const override { return true; } 3880 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 3881 return true; 3882 } 3883 3884 // Try to statically evaluate `this` and return a HConstant 3885 // containing the result of this evaluation. If `this` cannot 3886 // be evaluated as a constant, return null. 3887 HConstant* TryStaticEvaluation() const; 3888 3889 // Same but for `input` instead of GetInput(). 3890 HConstant* TryStaticEvaluation(HInstruction* input) const; 3891 3892 // Apply this operation to `x`. 3893 virtual HConstant* Evaluate([[maybe_unused]] HIntConstant* x) const { 3894 LOG(FATAL) << DebugName() << " is not defined for int values"; 3895 UNREACHABLE(); 3896 } 3897 virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x) const { 3898 LOG(FATAL) << DebugName() << " is not defined for long values"; 3899 UNREACHABLE(); 3900 } 3901 virtual HConstant* Evaluate([[maybe_unused]] HFloatConstant* x) const { 3902 LOG(FATAL) << DebugName() << " is not defined for float values"; 3903 UNREACHABLE(); 3904 } 3905 virtual HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x) const { 3906 LOG(FATAL) << DebugName() << " is not defined for double values"; 3907 UNREACHABLE(); 3908 } 3909 3910 DECLARE_ABSTRACT_INSTRUCTION(UnaryOperation); 3911 3912 protected: 3913 DEFAULT_COPY_CONSTRUCTOR(UnaryOperation); 3914 }; 3915 3916 class HBinaryOperation : public HExpression<2> { 3917 public: 3918 HBinaryOperation(InstructionKind kind, 3919 DataType::Type result_type, 3920 HInstruction* left, 3921 HInstruction* right, 3922 SideEffects side_effects = SideEffects::None(), 3923 uint32_t dex_pc = kNoDexPc) 3924 : HExpression(kind, result_type, side_effects, dex_pc) { 3925 SetRawInputAt(0, left); 3926 SetRawInputAt(1, right); 3927 } 3928 3929 // All of the BinaryOperation instructions are clonable. 3930 bool IsClonable() const override { return true; } 3931 3932 HInstruction* GetLeft() const { return InputAt(0); } 3933 HInstruction* GetRight() const { return InputAt(1); } 3934 DataType::Type GetResultType() const { return GetType(); } 3935 3936 virtual bool IsCommutative() const { return false; } 3937 3938 // Put constant on the right. 3939 // Returns whether order is changed. 3940 bool OrderInputsWithConstantOnTheRight() { 3941 HInstruction* left = InputAt(0); 3942 HInstruction* right = InputAt(1); 3943 if (left->IsConstant() && !right->IsConstant()) { 3944 ReplaceInput(right, 0); 3945 ReplaceInput(left, 1); 3946 return true; 3947 } 3948 return false; 3949 } 3950 3951 // Order inputs by instruction id, but favor constant on the right side. 3952 // This helps GVN for commutative ops. 3953 void OrderInputs() { 3954 DCHECK(IsCommutative()); 3955 HInstruction* left = InputAt(0); 3956 HInstruction* right = InputAt(1); 3957 if (left == right || (!left->IsConstant() && right->IsConstant())) { 3958 return; 3959 } 3960 if (OrderInputsWithConstantOnTheRight()) { 3961 return; 3962 } 3963 // Order according to instruction id. 3964 if (left->GetId() > right->GetId()) { 3965 ReplaceInput(right, 0); 3966 ReplaceInput(left, 1); 3967 } 3968 } 3969 3970 bool CanBeMoved() const override { return true; } 3971 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 3972 return true; 3973 } 3974 3975 // Try to statically evaluate `this` and return a HConstant 3976 // containing the result of this evaluation. If `this` cannot 3977 // be evaluated as a constant, return null. 3978 HConstant* TryStaticEvaluation() const; 3979 3980 // Same but for `left` and `right` instead of GetLeft() and GetRight(). 3981 HConstant* TryStaticEvaluation(HInstruction* left, HInstruction* right) const; 3982 3983 // Apply this operation to `x` and `y`. 3984 virtual HConstant* Evaluate([[maybe_unused]] HNullConstant* x, 3985 [[maybe_unused]] HNullConstant* y) const { 3986 LOG(FATAL) << DebugName() << " is not defined for the (null, null) case."; 3987 UNREACHABLE(); 3988 } 3989 virtual HConstant* Evaluate([[maybe_unused]] HIntConstant* x, 3990 [[maybe_unused]] HIntConstant* y) const { 3991 LOG(FATAL) << DebugName() << " is not defined for the (int, int) case."; 3992 UNREACHABLE(); 3993 } 3994 virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x, 3995 [[maybe_unused]] HLongConstant* y) const { 3996 LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; 3997 UNREACHABLE(); 3998 } 3999 virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x, 4000 [[maybe_unused]] HIntConstant* y) const { 4001 LOG(FATAL) << DebugName() << " is not defined for the (long, int) case."; 4002 UNREACHABLE(); 4003 } 4004 virtual HConstant* Evaluate([[maybe_unused]] HFloatConstant* x, 4005 [[maybe_unused]] HFloatConstant* y) const { 4006 LOG(FATAL) << DebugName() << " is not defined for float values"; 4007 UNREACHABLE(); 4008 } 4009 virtual HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x, 4010 [[maybe_unused]] HDoubleConstant* y) const { 4011 LOG(FATAL) << DebugName() << " is not defined for double values"; 4012 UNREACHABLE(); 4013 } 4014 4015 // Returns an input that can legally be used as the right input and is 4016 // constant, or null. 4017 HConstant* GetConstantRight() const; 4018 4019 // If `GetConstantRight()` returns one of the input, this returns the other 4020 // one. Otherwise it returns null. 4021 HInstruction* GetLeastConstantLeft() const; 4022 4023 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation); 4024 4025 protected: 4026 DEFAULT_COPY_CONSTRUCTOR(BinaryOperation); 4027 }; 4028 4029 // The comparison bias applies for floating point operations and indicates how NaN 4030 // comparisons are treated: 4031 enum class ComparisonBias { // private marker to avoid generate-operator-out.py from processing. 4032 kNoBias, // bias is not applicable (i.e. for long operation) 4033 kGtBias, // return 1 for NaN comparisons 4034 kLtBias, // return -1 for NaN comparisons 4035 kLast = kLtBias 4036 }; 4037 4038 std::ostream& operator<<(std::ostream& os, ComparisonBias rhs); 4039 4040 class HCondition : public HBinaryOperation { 4041 public: 4042 HCondition(InstructionKind kind, 4043 HInstruction* first, 4044 HInstruction* second, 4045 uint32_t dex_pc = kNoDexPc) 4046 : HBinaryOperation(kind, 4047 DataType::Type::kBool, 4048 first, 4049 second, 4050 SideEffects::None(), 4051 dex_pc) { 4052 SetPackedField<ComparisonBiasField>(ComparisonBias::kNoBias); 4053 } 4054 4055 // For code generation purposes, returns whether this instruction is just before 4056 // `instruction`, and disregard moves in between. 4057 bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const; 4058 4059 DECLARE_ABSTRACT_INSTRUCTION(Condition); 4060 4061 virtual IfCondition GetCondition() const = 0; 4062 4063 virtual IfCondition GetOppositeCondition() const = 0; 4064 4065 bool IsGtBias() const { return GetBias() == ComparisonBias::kGtBias; } 4066 bool IsLtBias() const { return GetBias() == ComparisonBias::kLtBias; } 4067 4068 ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); } 4069 void SetBias(ComparisonBias bias) { SetPackedField<ComparisonBiasField>(bias); } 4070 4071 bool InstructionDataEquals(const HInstruction* other) const override { 4072 return GetPackedFields() == other->AsCondition()->GetPackedFields(); 4073 } 4074 4075 bool IsFPConditionTrueIfNaN() const { 4076 DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 4077 IfCondition if_cond = GetCondition(); 4078 if (if_cond == kCondNE) { 4079 return true; 4080 } else if (if_cond == kCondEQ) { 4081 return false; 4082 } 4083 return ((if_cond == kCondGT) || (if_cond == kCondGE)) && IsGtBias(); 4084 } 4085 4086 bool IsFPConditionFalseIfNaN() const { 4087 DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 4088 IfCondition if_cond = GetCondition(); 4089 if (if_cond == kCondEQ) { 4090 return true; 4091 } else if (if_cond == kCondNE) { 4092 return false; 4093 } 4094 return ((if_cond == kCondLT) || (if_cond == kCondLE)) && IsGtBias(); 4095 } 4096 4097 protected: 4098 // Needed if we merge a HCompare into a HCondition. 4099 static constexpr size_t kFieldComparisonBias = kNumberOfGenericPackedBits; 4100 static constexpr size_t kFieldComparisonBiasSize = 4101 MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast)); 4102 static constexpr size_t kNumberOfConditionPackedBits = 4103 kFieldComparisonBias + kFieldComparisonBiasSize; 4104 static_assert(kNumberOfConditionPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 4105 using ComparisonBiasField = 4106 BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>; 4107 4108 template <typename T> 4109 int32_t Compare(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); } 4110 4111 template <typename T> 4112 int32_t CompareFP(T x, T y) const { 4113 DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 4114 DCHECK_NE(GetBias(), ComparisonBias::kNoBias); 4115 // Handle the bias. 4116 return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compare(x, y); 4117 } 4118 4119 // Return an integer constant containing the result of a condition evaluated at compile time. 4120 HIntConstant* MakeConstantCondition(bool value, uint32_t dex_pc) const { 4121 return GetBlock()->GetGraph()->GetIntConstant(value, dex_pc); 4122 } 4123 4124 DEFAULT_COPY_CONSTRUCTOR(Condition); 4125 }; 4126 4127 // Instruction to check if two inputs are equal to each other. 4128 class HEqual final : public HCondition { 4129 public: 4130 HEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4131 : HCondition(kEqual, first, second, dex_pc) { 4132 } 4133 4134 bool IsCommutative() const override { return true; } 4135 4136 HConstant* Evaluate([[maybe_unused]] HNullConstant* x, 4137 [[maybe_unused]] HNullConstant* y) const override { 4138 return MakeConstantCondition(true, GetDexPc()); 4139 } 4140 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4141 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4142 } 4143 // In the following Evaluate methods, a HCompare instruction has 4144 // been merged into this HEqual instruction; evaluate it as 4145 // `Compare(x, y) == 0`. 4146 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4147 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), 4148 GetDexPc()); 4149 } 4150 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4151 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4152 } 4153 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4154 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4155 } 4156 4157 DECLARE_INSTRUCTION(Equal); 4158 4159 IfCondition GetCondition() const override { 4160 return kCondEQ; 4161 } 4162 4163 IfCondition GetOppositeCondition() const override { 4164 return kCondNE; 4165 } 4166 4167 protected: 4168 DEFAULT_COPY_CONSTRUCTOR(Equal); 4169 4170 private: 4171 template <typename T> static bool Compute(T x, T y) { return x == y; } 4172 }; 4173 4174 class HNotEqual final : public HCondition { 4175 public: 4176 HNotEqual(HInstruction* first, HInstruction* second, 4177 uint32_t dex_pc = kNoDexPc) 4178 : HCondition(kNotEqual, first, second, dex_pc) { 4179 } 4180 4181 bool IsCommutative() const override { return true; } 4182 4183 HConstant* Evaluate([[maybe_unused]] HNullConstant* x, 4184 [[maybe_unused]] HNullConstant* y) const override { 4185 return MakeConstantCondition(false, GetDexPc()); 4186 } 4187 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4188 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4189 } 4190 // In the following Evaluate methods, a HCompare instruction has 4191 // been merged into this HNotEqual instruction; evaluate it as 4192 // `Compare(x, y) != 0`. 4193 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4194 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4195 } 4196 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4197 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4198 } 4199 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4200 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4201 } 4202 4203 DECLARE_INSTRUCTION(NotEqual); 4204 4205 IfCondition GetCondition() const override { 4206 return kCondNE; 4207 } 4208 4209 IfCondition GetOppositeCondition() const override { 4210 return kCondEQ; 4211 } 4212 4213 protected: 4214 DEFAULT_COPY_CONSTRUCTOR(NotEqual); 4215 4216 private: 4217 template <typename T> static bool Compute(T x, T y) { return x != y; } 4218 }; 4219 4220 class HLessThan final : public HCondition { 4221 public: 4222 HLessThan(HInstruction* first, HInstruction* second, 4223 uint32_t dex_pc = kNoDexPc) 4224 : HCondition(kLessThan, first, second, dex_pc) { 4225 } 4226 4227 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4228 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4229 } 4230 // In the following Evaluate methods, a HCompare instruction has 4231 // been merged into this HLessThan instruction; evaluate it as 4232 // `Compare(x, y) < 0`. 4233 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4234 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4235 } 4236 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4237 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4238 } 4239 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4240 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4241 } 4242 4243 DECLARE_INSTRUCTION(LessThan); 4244 4245 IfCondition GetCondition() const override { 4246 return kCondLT; 4247 } 4248 4249 IfCondition GetOppositeCondition() const override { 4250 return kCondGE; 4251 } 4252 4253 protected: 4254 DEFAULT_COPY_CONSTRUCTOR(LessThan); 4255 4256 private: 4257 template <typename T> static bool Compute(T x, T y) { return x < y; } 4258 }; 4259 4260 class HLessThanOrEqual final : public HCondition { 4261 public: 4262 HLessThanOrEqual(HInstruction* first, HInstruction* second, 4263 uint32_t dex_pc = kNoDexPc) 4264 : HCondition(kLessThanOrEqual, first, second, dex_pc) { 4265 } 4266 4267 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4268 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4269 } 4270 // In the following Evaluate methods, a HCompare instruction has 4271 // been merged into this HLessThanOrEqual instruction; evaluate it as 4272 // `Compare(x, y) <= 0`. 4273 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4274 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4275 } 4276 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4277 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4278 } 4279 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4280 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4281 } 4282 4283 DECLARE_INSTRUCTION(LessThanOrEqual); 4284 4285 IfCondition GetCondition() const override { 4286 return kCondLE; 4287 } 4288 4289 IfCondition GetOppositeCondition() const override { 4290 return kCondGT; 4291 } 4292 4293 protected: 4294 DEFAULT_COPY_CONSTRUCTOR(LessThanOrEqual); 4295 4296 private: 4297 template <typename T> static bool Compute(T x, T y) { return x <= y; } 4298 }; 4299 4300 class HGreaterThan final : public HCondition { 4301 public: 4302 HGreaterThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4303 : HCondition(kGreaterThan, first, second, dex_pc) { 4304 } 4305 4306 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4307 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4308 } 4309 // In the following Evaluate methods, a HCompare instruction has 4310 // been merged into this HGreaterThan instruction; evaluate it as 4311 // `Compare(x, y) > 0`. 4312 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4313 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4314 } 4315 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4316 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4317 } 4318 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4319 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4320 } 4321 4322 DECLARE_INSTRUCTION(GreaterThan); 4323 4324 IfCondition GetCondition() const override { 4325 return kCondGT; 4326 } 4327 4328 IfCondition GetOppositeCondition() const override { 4329 return kCondLE; 4330 } 4331 4332 protected: 4333 DEFAULT_COPY_CONSTRUCTOR(GreaterThan); 4334 4335 private: 4336 template <typename T> static bool Compute(T x, T y) { return x > y; } 4337 }; 4338 4339 class HGreaterThanOrEqual final : public HCondition { 4340 public: 4341 HGreaterThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4342 : HCondition(kGreaterThanOrEqual, first, second, dex_pc) { 4343 } 4344 4345 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4346 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4347 } 4348 // In the following Evaluate methods, a HCompare instruction has 4349 // been merged into this HGreaterThanOrEqual instruction; evaluate it as 4350 // `Compare(x, y) >= 0`. 4351 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4352 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4353 } 4354 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4355 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4356 } 4357 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4358 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 4359 } 4360 4361 DECLARE_INSTRUCTION(GreaterThanOrEqual); 4362 4363 IfCondition GetCondition() const override { 4364 return kCondGE; 4365 } 4366 4367 IfCondition GetOppositeCondition() const override { 4368 return kCondLT; 4369 } 4370 4371 protected: 4372 DEFAULT_COPY_CONSTRUCTOR(GreaterThanOrEqual); 4373 4374 private: 4375 template <typename T> static bool Compute(T x, T y) { return x >= y; } 4376 }; 4377 4378 class HBelow final : public HCondition { 4379 public: 4380 HBelow(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4381 : HCondition(kBelow, first, second, dex_pc) { 4382 } 4383 4384 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4385 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4386 } 4387 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4388 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4389 } 4390 4391 DECLARE_INSTRUCTION(Below); 4392 4393 IfCondition GetCondition() const override { 4394 return kCondB; 4395 } 4396 4397 IfCondition GetOppositeCondition() const override { 4398 return kCondAE; 4399 } 4400 4401 protected: 4402 DEFAULT_COPY_CONSTRUCTOR(Below); 4403 4404 private: 4405 template <typename T> static bool Compute(T x, T y) { 4406 return MakeUnsigned(x) < MakeUnsigned(y); 4407 } 4408 }; 4409 4410 class HBelowOrEqual final : public HCondition { 4411 public: 4412 HBelowOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4413 : HCondition(kBelowOrEqual, first, second, dex_pc) { 4414 } 4415 4416 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4417 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4418 } 4419 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4420 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4421 } 4422 4423 DECLARE_INSTRUCTION(BelowOrEqual); 4424 4425 IfCondition GetCondition() const override { 4426 return kCondBE; 4427 } 4428 4429 IfCondition GetOppositeCondition() const override { 4430 return kCondA; 4431 } 4432 4433 protected: 4434 DEFAULT_COPY_CONSTRUCTOR(BelowOrEqual); 4435 4436 private: 4437 template <typename T> static bool Compute(T x, T y) { 4438 return MakeUnsigned(x) <= MakeUnsigned(y); 4439 } 4440 }; 4441 4442 class HAbove final : public HCondition { 4443 public: 4444 HAbove(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4445 : HCondition(kAbove, first, second, dex_pc) { 4446 } 4447 4448 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4449 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4450 } 4451 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4452 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4453 } 4454 4455 DECLARE_INSTRUCTION(Above); 4456 4457 IfCondition GetCondition() const override { 4458 return kCondA; 4459 } 4460 4461 IfCondition GetOppositeCondition() const override { 4462 return kCondBE; 4463 } 4464 4465 protected: 4466 DEFAULT_COPY_CONSTRUCTOR(Above); 4467 4468 private: 4469 template <typename T> static bool Compute(T x, T y) { 4470 return MakeUnsigned(x) > MakeUnsigned(y); 4471 } 4472 }; 4473 4474 class HAboveOrEqual final : public HCondition { 4475 public: 4476 HAboveOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 4477 : HCondition(kAboveOrEqual, first, second, dex_pc) { 4478 } 4479 4480 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4481 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4482 } 4483 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4484 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4485 } 4486 4487 DECLARE_INSTRUCTION(AboveOrEqual); 4488 4489 IfCondition GetCondition() const override { 4490 return kCondAE; 4491 } 4492 4493 IfCondition GetOppositeCondition() const override { 4494 return kCondB; 4495 } 4496 4497 protected: 4498 DEFAULT_COPY_CONSTRUCTOR(AboveOrEqual); 4499 4500 private: 4501 template <typename T> static bool Compute(T x, T y) { 4502 return MakeUnsigned(x) >= MakeUnsigned(y); 4503 } 4504 }; 4505 4506 // Instruction to check how two inputs compare to each other. 4507 // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1. 4508 class HCompare final : public HBinaryOperation { 4509 public: 4510 // Note that `comparison_type` is the type of comparison performed 4511 // between the comparison's inputs, not the type of the instantiated 4512 // HCompare instruction (which is always DataType::Type::kInt). 4513 HCompare(DataType::Type comparison_type, 4514 HInstruction* first, 4515 HInstruction* second, 4516 ComparisonBias bias, 4517 uint32_t dex_pc) 4518 : HBinaryOperation(kCompare, 4519 DataType::Type::kInt32, 4520 first, 4521 second, 4522 SideEffectsForArchRuntimeCalls(comparison_type), 4523 dex_pc) { 4524 SetPackedField<ComparisonBiasField>(bias); 4525 } 4526 4527 template <typename T> 4528 int32_t Compute(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); } 4529 4530 template <typename T> 4531 int32_t ComputeFP(T x, T y) const { 4532 DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 4533 DCHECK_NE(GetBias(), ComparisonBias::kNoBias); 4534 // Handle the bias. 4535 return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compute(x, y); 4536 } 4537 4538 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 4539 // Note that there is no "cmp-int" Dex instruction so we shouldn't 4540 // reach this code path when processing a freshly built HIR 4541 // graph. However HCompare integer instructions can be synthesized 4542 // by the instruction simplifier to implement IntegerCompare and 4543 // IntegerSignum intrinsics, so we have to handle this case. 4544 return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4545 } 4546 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 4547 return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4548 } 4549 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 4550 return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4551 } 4552 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 4553 return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4554 } 4555 4556 bool InstructionDataEquals(const HInstruction* other) const override { 4557 return GetPackedFields() == other->AsCompare()->GetPackedFields(); 4558 } 4559 4560 ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); } 4561 4562 // Does this compare instruction have a "gt bias" (vs an "lt bias")? 4563 // Only meaningful for floating-point comparisons. 4564 bool IsGtBias() const { 4565 DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 4566 return GetBias() == ComparisonBias::kGtBias; 4567 } 4568 4569 static SideEffects SideEffectsForArchRuntimeCalls([[maybe_unused]] DataType::Type type) { 4570 // Comparisons do not require a runtime call in any back end. 4571 return SideEffects::None(); 4572 } 4573 4574 DECLARE_INSTRUCTION(Compare); 4575 4576 protected: 4577 static constexpr size_t kFieldComparisonBias = kNumberOfGenericPackedBits; 4578 static constexpr size_t kFieldComparisonBiasSize = 4579 MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast)); 4580 static constexpr size_t kNumberOfComparePackedBits = 4581 kFieldComparisonBias + kFieldComparisonBiasSize; 4582 static_assert(kNumberOfComparePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 4583 using ComparisonBiasField = 4584 BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>; 4585 4586 // Return an integer constant containing the result of a comparison evaluated at compile time. 4587 HIntConstant* MakeConstantComparison(int32_t value, uint32_t dex_pc) const { 4588 DCHECK(value == -1 || value == 0 || value == 1) << value; 4589 return GetBlock()->GetGraph()->GetIntConstant(value, dex_pc); 4590 } 4591 4592 DEFAULT_COPY_CONSTRUCTOR(Compare); 4593 }; 4594 4595 class HNewInstance final : public HExpression<1> { 4596 public: 4597 HNewInstance(HInstruction* cls, 4598 uint32_t dex_pc, 4599 dex::TypeIndex type_index, 4600 const DexFile& dex_file, 4601 bool finalizable, 4602 QuickEntrypointEnum entrypoint) 4603 : HExpression(kNewInstance, 4604 DataType::Type::kReference, 4605 SideEffects::CanTriggerGC(), 4606 dex_pc), 4607 type_index_(type_index), 4608 dex_file_(dex_file), 4609 entrypoint_(entrypoint) { 4610 SetPackedFlag<kFlagFinalizable>(finalizable); 4611 SetPackedFlag<kFlagPartialMaterialization>(false); 4612 SetRawInputAt(0, cls); 4613 } 4614 4615 bool IsClonable() const override { return true; } 4616 4617 void SetPartialMaterialization() { 4618 SetPackedFlag<kFlagPartialMaterialization>(true); 4619 } 4620 4621 dex::TypeIndex GetTypeIndex() const { return type_index_; } 4622 const DexFile& GetDexFile() const { return dex_file_; } 4623 4624 // Calls runtime so needs an environment. 4625 bool NeedsEnvironment() const override { return true; } 4626 4627 // Can throw errors when out-of-memory or if it's not instantiable/accessible. 4628 bool CanThrow() const override { return true; } 4629 bool OnlyThrowsAsyncExceptions() const override { 4630 return !IsFinalizable() && !NeedsChecks(); 4631 } 4632 4633 bool NeedsChecks() const { 4634 return entrypoint_ == kQuickAllocObjectWithChecks; 4635 } 4636 4637 bool IsFinalizable() const { return GetPackedFlag<kFlagFinalizable>(); } 4638 4639 bool CanBeNull() const override { return false; } 4640 4641 bool IsPartialMaterialization() const { 4642 return GetPackedFlag<kFlagPartialMaterialization>(); 4643 } 4644 4645 QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } 4646 4647 void SetEntrypoint(QuickEntrypointEnum entrypoint) { 4648 entrypoint_ = entrypoint; 4649 } 4650 4651 HLoadClass* GetLoadClass() const { 4652 HInstruction* input = InputAt(0); 4653 if (input->IsClinitCheck()) { 4654 input = input->InputAt(0); 4655 } 4656 DCHECK(input->IsLoadClass()); 4657 return input->AsLoadClass(); 4658 } 4659 4660 bool IsStringAlloc() const; 4661 4662 DECLARE_INSTRUCTION(NewInstance); 4663 4664 protected: 4665 DEFAULT_COPY_CONSTRUCTOR(NewInstance); 4666 4667 private: 4668 static constexpr size_t kFlagFinalizable = kNumberOfGenericPackedBits; 4669 static constexpr size_t kFlagPartialMaterialization = kFlagFinalizable + 1; 4670 static constexpr size_t kNumberOfNewInstancePackedBits = kFlagPartialMaterialization + 1; 4671 static_assert(kNumberOfNewInstancePackedBits <= kMaxNumberOfPackedBits, 4672 "Too many packed fields."); 4673 4674 const dex::TypeIndex type_index_; 4675 const DexFile& dex_file_; 4676 QuickEntrypointEnum entrypoint_; 4677 }; 4678 4679 enum IntrinsicNeedsEnvironment { 4680 kNoEnvironment, // Intrinsic does not require an environment. 4681 kNeedsEnvironment // Intrinsic requires an environment. 4682 }; 4683 4684 enum IntrinsicSideEffects { 4685 kNoSideEffects, // Intrinsic does not have any heap memory side effects. 4686 kReadSideEffects, // Intrinsic may read heap memory. 4687 kWriteSideEffects, // Intrinsic may write heap memory. 4688 kAllSideEffects // Intrinsic may read or write heap memory, or trigger GC. 4689 }; 4690 4691 enum IntrinsicExceptions { 4692 kNoThrow, // Intrinsic does not throw any exceptions. 4693 kCanThrow // Intrinsic may throw exceptions. 4694 }; 4695 4696 // Determines how to load an ArtMethod*. 4697 enum class MethodLoadKind { 4698 // Use a String init ArtMethod* loaded from Thread entrypoints. 4699 kStringInit, 4700 4701 // Use the method's own ArtMethod* loaded by the register allocator. 4702 kRecursive, 4703 4704 // Use PC-relative boot image ArtMethod* address that will be known at link time. 4705 // Used for boot image methods referenced by boot image code. 4706 kBootImageLinkTimePcRelative, 4707 4708 // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load. 4709 // Used for app->boot calls with relocatable image. 4710 kBootImageRelRo, 4711 4712 // Load from an entry in the .bss section using a PC-relative load. 4713 // Used for methods outside boot image referenced by AOT-compiled app and boot image code. 4714 kBssEntry, 4715 4716 // Use ArtMethod* at a known address, embed the direct address in the code. 4717 // Used for for JIT-compiled calls. 4718 kJitDirectAddress, 4719 4720 // Make a runtime call to resolve and call the method. This is the last-resort-kind 4721 // used when other kinds are unimplemented on a particular architecture. 4722 kRuntimeCall, 4723 }; 4724 4725 // Determines the location of the code pointer of an invoke. 4726 enum class CodePtrLocation { 4727 // Recursive call, use local PC-relative call instruction. 4728 kCallSelf, 4729 4730 // Use native pointer from the Artmethod*. 4731 // Used for @CriticalNative to avoid going through the compiled stub. This call goes through 4732 // a special resolution stub if the class is not initialized or no native code is registered. 4733 kCallCriticalNative, 4734 4735 // Use code pointer from the ArtMethod*. 4736 // Used when we don't know the target code. This is also the last-resort-kind used when 4737 // other kinds are unimplemented or impractical (i.e. slow) on a particular architecture. 4738 kCallArtMethod, 4739 }; 4740 4741 static inline bool IsPcRelativeMethodLoadKind(MethodLoadKind load_kind) { 4742 return load_kind == MethodLoadKind::kBootImageLinkTimePcRelative || 4743 load_kind == MethodLoadKind::kBootImageRelRo || 4744 load_kind == MethodLoadKind::kBssEntry; 4745 } 4746 4747 class HInvoke : public HVariableInputSizeInstruction { 4748 public: 4749 bool NeedsEnvironment() const override; 4750 4751 void SetArgumentAt(size_t index, HInstruction* argument) { 4752 SetRawInputAt(index, argument); 4753 } 4754 4755 // Return the number of arguments. This number can be lower than 4756 // the number of inputs returned by InputCount(), as some invoke 4757 // instructions (e.g. HInvokeStaticOrDirect) can have non-argument 4758 // inputs at the end of their list of inputs. 4759 uint32_t GetNumberOfArguments() const { return number_of_arguments_; } 4760 4761 InvokeType GetInvokeType() const { 4762 return GetPackedField<InvokeTypeField>(); 4763 } 4764 4765 Intrinsics GetIntrinsic() const { 4766 return intrinsic_; 4767 } 4768 4769 void SetIntrinsic(Intrinsics intrinsic, 4770 IntrinsicNeedsEnvironment needs_env, 4771 IntrinsicSideEffects side_effects, 4772 IntrinsicExceptions exceptions); 4773 4774 bool IsFromInlinedInvoke() const { 4775 return GetEnvironment()->IsFromInlinedInvoke(); 4776 } 4777 4778 void SetCanThrow(bool can_throw) { SetPackedFlag<kFlagCanThrow>(can_throw); } 4779 4780 bool CanThrow() const override { return GetPackedFlag<kFlagCanThrow>(); } 4781 4782 void SetAlwaysThrows(bool always_throws) { SetPackedFlag<kFlagAlwaysThrows>(always_throws); } 4783 4784 bool AlwaysThrows() const override final { return GetPackedFlag<kFlagAlwaysThrows>(); } 4785 4786 bool CanBeMoved() const override { return IsIntrinsic() && !DoesAnyWrite(); } 4787 4788 bool InstructionDataEquals(const HInstruction* other) const override { 4789 return intrinsic_ != Intrinsics::kNone && intrinsic_ == other->AsInvoke()->intrinsic_; 4790 } 4791 4792 uint32_t* GetIntrinsicOptimizations() { 4793 return &intrinsic_optimizations_; 4794 } 4795 4796 const uint32_t* GetIntrinsicOptimizations() const { 4797 return &intrinsic_optimizations_; 4798 } 4799 4800 bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; } 4801 4802 ArtMethod* GetResolvedMethod() const { return resolved_method_; } 4803 void SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt); 4804 4805 MethodReference GetMethodReference() const { return method_reference_; } 4806 4807 const MethodReference GetResolvedMethodReference() const { 4808 return resolved_method_reference_; 4809 } 4810 4811 DECLARE_ABSTRACT_INSTRUCTION(Invoke); 4812 4813 protected: 4814 static constexpr size_t kFieldInvokeType = kNumberOfGenericPackedBits; 4815 static constexpr size_t kFieldInvokeTypeSize = 4816 MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType)); 4817 static constexpr size_t kFlagCanThrow = kFieldInvokeType + kFieldInvokeTypeSize; 4818 static constexpr size_t kFlagAlwaysThrows = kFlagCanThrow + 1; 4819 static constexpr size_t kNumberOfInvokePackedBits = kFlagAlwaysThrows + 1; 4820 static_assert(kNumberOfInvokePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 4821 using InvokeTypeField = BitField<InvokeType, kFieldInvokeType, kFieldInvokeTypeSize>; 4822 4823 HInvoke(InstructionKind kind, 4824 ArenaAllocator* allocator, 4825 uint32_t number_of_arguments, 4826 uint32_t number_of_other_inputs, 4827 DataType::Type return_type, 4828 uint32_t dex_pc, 4829 MethodReference method_reference, 4830 ArtMethod* resolved_method, 4831 MethodReference resolved_method_reference, 4832 InvokeType invoke_type, 4833 bool enable_intrinsic_opt) 4834 : HVariableInputSizeInstruction( 4835 kind, 4836 return_type, 4837 SideEffects::AllExceptGCDependency(), // Assume write/read on all fields/arrays. 4838 dex_pc, 4839 allocator, 4840 number_of_arguments + number_of_other_inputs, 4841 kArenaAllocInvokeInputs), 4842 number_of_arguments_(number_of_arguments), 4843 method_reference_(method_reference), 4844 resolved_method_reference_(resolved_method_reference), 4845 intrinsic_(Intrinsics::kNone), 4846 intrinsic_optimizations_(0) { 4847 SetPackedField<InvokeTypeField>(invoke_type); 4848 SetPackedFlag<kFlagCanThrow>(true); 4849 SetResolvedMethod(resolved_method, enable_intrinsic_opt); 4850 } 4851 4852 DEFAULT_COPY_CONSTRUCTOR(Invoke); 4853 4854 uint32_t number_of_arguments_; 4855 ArtMethod* resolved_method_; 4856 const MethodReference method_reference_; 4857 // Cached values of the resolved method, to avoid needing the mutator lock. 4858 const MethodReference resolved_method_reference_; 4859 Intrinsics intrinsic_; 4860 4861 // A magic word holding optimizations for intrinsics. See intrinsics.h. 4862 uint32_t intrinsic_optimizations_; 4863 }; 4864 4865 class HInvokeUnresolved final : public HInvoke { 4866 public: 4867 HInvokeUnresolved(ArenaAllocator* allocator, 4868 uint32_t number_of_arguments, 4869 DataType::Type return_type, 4870 uint32_t dex_pc, 4871 MethodReference method_reference, 4872 InvokeType invoke_type) 4873 : HInvoke(kInvokeUnresolved, 4874 allocator, 4875 number_of_arguments, 4876 /* number_of_other_inputs= */ 0u, 4877 return_type, 4878 dex_pc, 4879 method_reference, 4880 nullptr, 4881 MethodReference(nullptr, 0u), 4882 invoke_type, 4883 /* enable_intrinsic_opt= */ false) { 4884 } 4885 4886 bool IsClonable() const override { return true; } 4887 4888 DECLARE_INSTRUCTION(InvokeUnresolved); 4889 4890 protected: 4891 DEFAULT_COPY_CONSTRUCTOR(InvokeUnresolved); 4892 }; 4893 4894 class HInvokePolymorphic final : public HInvoke { 4895 public: 4896 HInvokePolymorphic(ArenaAllocator* allocator, 4897 uint32_t number_of_arguments, 4898 DataType::Type return_type, 4899 uint32_t dex_pc, 4900 MethodReference method_reference, 4901 // resolved_method is the ArtMethod object corresponding to the polymorphic 4902 // method (e.g. VarHandle.get), resolved using the class linker. It is needed 4903 // to pass intrinsic information to the HInvokePolymorphic node. 4904 ArtMethod* resolved_method, 4905 MethodReference resolved_method_reference, 4906 dex::ProtoIndex proto_idx) 4907 : HInvoke(kInvokePolymorphic, 4908 allocator, 4909 number_of_arguments, 4910 /* number_of_other_inputs= */ 0u, 4911 return_type, 4912 dex_pc, 4913 method_reference, 4914 resolved_method, 4915 resolved_method_reference, 4916 kPolymorphic, 4917 /* enable_intrinsic_opt= */ true), 4918 proto_idx_(proto_idx) {} 4919 4920 bool IsClonable() const override { return true; } 4921 4922 dex::ProtoIndex GetProtoIndex() { return proto_idx_; } 4923 4924 DECLARE_INSTRUCTION(InvokePolymorphic); 4925 4926 protected: 4927 dex::ProtoIndex proto_idx_; 4928 DEFAULT_COPY_CONSTRUCTOR(InvokePolymorphic); 4929 }; 4930 4931 class HInvokeCustom final : public HInvoke { 4932 public: 4933 HInvokeCustom(ArenaAllocator* allocator, 4934 uint32_t number_of_arguments, 4935 uint32_t call_site_index, 4936 DataType::Type return_type, 4937 uint32_t dex_pc, 4938 MethodReference method_reference, 4939 bool enable_intrinsic_opt) 4940 : HInvoke(kInvokeCustom, 4941 allocator, 4942 number_of_arguments, 4943 /* number_of_other_inputs= */ 0u, 4944 return_type, 4945 dex_pc, 4946 method_reference, 4947 /* resolved_method= */ nullptr, 4948 MethodReference(nullptr, 0u), 4949 kStatic, 4950 enable_intrinsic_opt), 4951 call_site_index_(call_site_index) { 4952 } 4953 4954 uint32_t GetCallSiteIndex() const { return call_site_index_; } 4955 4956 bool IsClonable() const override { return true; } 4957 4958 DECLARE_INSTRUCTION(InvokeCustom); 4959 4960 protected: 4961 DEFAULT_COPY_CONSTRUCTOR(InvokeCustom); 4962 4963 private: 4964 uint32_t call_site_index_; 4965 }; 4966 4967 class HInvokeStaticOrDirect final : public HInvoke { 4968 public: 4969 // Requirements of this method call regarding the class 4970 // initialization (clinit) check of its declaring class. 4971 enum class ClinitCheckRequirement { // private marker to avoid generate-operator-out.py from processing. 4972 kNone, // Class already initialized. 4973 kExplicit, // Static call having explicit clinit check as last input. 4974 kImplicit, // Static call implicitly requiring a clinit check. 4975 kLast = kImplicit 4976 }; 4977 4978 struct DispatchInfo { 4979 MethodLoadKind method_load_kind; 4980 CodePtrLocation code_ptr_location; 4981 // The method load data holds 4982 // - thread entrypoint offset for kStringInit method if this is a string init invoke. 4983 // Note that there are multiple string init methods, each having its own offset. 4984 // - the method address for kDirectAddress 4985 uint64_t method_load_data; 4986 }; 4987 4988 HInvokeStaticOrDirect(ArenaAllocator* allocator, 4989 uint32_t number_of_arguments, 4990 DataType::Type return_type, 4991 uint32_t dex_pc, 4992 MethodReference method_reference, 4993 ArtMethod* resolved_method, 4994 DispatchInfo dispatch_info, 4995 InvokeType invoke_type, 4996 MethodReference resolved_method_reference, 4997 ClinitCheckRequirement clinit_check_requirement, 4998 bool enable_intrinsic_opt) 4999 : HInvoke(kInvokeStaticOrDirect, 5000 allocator, 5001 number_of_arguments, 5002 // There is potentially one extra argument for the HCurrentMethod input, 5003 // and one other if the clinit check is explicit. These can be removed later. 5004 (NeedsCurrentMethodInput(dispatch_info) ? 1u : 0u) + 5005 (clinit_check_requirement == ClinitCheckRequirement::kExplicit ? 1u : 0u), 5006 return_type, 5007 dex_pc, 5008 method_reference, 5009 resolved_method, 5010 resolved_method_reference, 5011 invoke_type, 5012 enable_intrinsic_opt), 5013 dispatch_info_(dispatch_info) { 5014 SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement); 5015 } 5016 5017 bool IsClonable() const override { return true; } 5018 bool NeedsBss() const override { 5019 return GetMethodLoadKind() == MethodLoadKind::kBssEntry; 5020 } 5021 5022 void SetDispatchInfo(DispatchInfo dispatch_info) { 5023 bool had_current_method_input = HasCurrentMethodInput(); 5024 bool needs_current_method_input = NeedsCurrentMethodInput(dispatch_info); 5025 5026 // Using the current method is the default and once we find a better 5027 // method load kind, we should not go back to using the current method. 5028 DCHECK(had_current_method_input || !needs_current_method_input); 5029 5030 if (had_current_method_input && !needs_current_method_input) { 5031 DCHECK_EQ(InputAt(GetCurrentMethodIndex()), GetBlock()->GetGraph()->GetCurrentMethod()); 5032 RemoveInputAt(GetCurrentMethodIndex()); 5033 } 5034 dispatch_info_ = dispatch_info; 5035 } 5036 5037 DispatchInfo GetDispatchInfo() const { 5038 return dispatch_info_; 5039 } 5040 5041 using HInstruction::GetInputRecords; // Keep the const version visible. 5042 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() override { 5043 ArrayRef<HUserRecord<HInstruction*>> input_records = HInvoke::GetInputRecords(); 5044 if (kIsDebugBuild && IsStaticWithExplicitClinitCheck()) { 5045 DCHECK(!input_records.empty()); 5046 DCHECK_GT(input_records.size(), GetNumberOfArguments()); 5047 HInstruction* last_input = input_records.back().GetInstruction(); 5048 // Note: `last_input` may be null during arguments setup. 5049 if (last_input != nullptr) { 5050 // `last_input` is the last input of a static invoke marked as having 5051 // an explicit clinit check. It must either be: 5052 // - an art::HClinitCheck instruction, set by art::HGraphBuilder; or 5053 // - an art::HLoadClass instruction, set by art::PrepareForRegisterAllocation. 5054 DCHECK(last_input->IsClinitCheck() || last_input->IsLoadClass()) << last_input->DebugName(); 5055 } 5056 } 5057 return input_records; 5058 } 5059 5060 bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const override { 5061 // We do not access the method via object reference, so we cannot do an implicit null check. 5062 // TODO: for intrinsics we can generate implicit null checks. 5063 return false; 5064 } 5065 5066 bool CanBeNull() const override; 5067 5068 MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; } 5069 CodePtrLocation GetCodePtrLocation() const { 5070 // We do CHA analysis after sharpening. When a method has CHA inlining, it 5071 // cannot call itself, as if the CHA optmization is invalid we want to make 5072 // sure the method is never executed again. So, while sharpening can return 5073 // kCallSelf, we bypass it here if there is a CHA optimization. 5074 if (dispatch_info_.code_ptr_location == CodePtrLocation::kCallSelf && 5075 GetBlock()->GetGraph()->HasShouldDeoptimizeFlag()) { 5076 return CodePtrLocation::kCallArtMethod; 5077 } else { 5078 return dispatch_info_.code_ptr_location; 5079 } 5080 } 5081 bool IsRecursive() const { return GetMethodLoadKind() == MethodLoadKind::kRecursive; } 5082 bool IsStringInit() const { return GetMethodLoadKind() == MethodLoadKind::kStringInit; } 5083 bool HasMethodAddress() const { return GetMethodLoadKind() == MethodLoadKind::kJitDirectAddress; } 5084 bool HasPcRelativeMethodLoadKind() const { 5085 return IsPcRelativeMethodLoadKind(GetMethodLoadKind()); 5086 } 5087 5088 QuickEntrypointEnum GetStringInitEntryPoint() const { 5089 DCHECK(IsStringInit()); 5090 return static_cast<QuickEntrypointEnum>(dispatch_info_.method_load_data); 5091 } 5092 5093 uint64_t GetMethodAddress() const { 5094 DCHECK(HasMethodAddress()); 5095 return dispatch_info_.method_load_data; 5096 } 5097 5098 const DexFile& GetDexFileForPcRelativeDexCache() const; 5099 5100 ClinitCheckRequirement GetClinitCheckRequirement() const { 5101 return GetPackedField<ClinitCheckRequirementField>(); 5102 } 5103 5104 // Is this instruction a call to a static method? 5105 bool IsStatic() const { 5106 return GetInvokeType() == kStatic; 5107 } 5108 5109 // Does this method load kind need the current method as an input? 5110 static bool NeedsCurrentMethodInput(DispatchInfo dispatch_info) { 5111 return dispatch_info.method_load_kind == MethodLoadKind::kRecursive || 5112 dispatch_info.method_load_kind == MethodLoadKind::kRuntimeCall || 5113 dispatch_info.code_ptr_location == CodePtrLocation::kCallCriticalNative; 5114 } 5115 5116 // Get the index of the current method input. 5117 size_t GetCurrentMethodIndex() const { 5118 DCHECK(HasCurrentMethodInput()); 5119 return GetCurrentMethodIndexUnchecked(); 5120 } 5121 size_t GetCurrentMethodIndexUnchecked() const { 5122 return GetNumberOfArguments(); 5123 } 5124 5125 // Check if the method has a current method input. 5126 bool HasCurrentMethodInput() const { 5127 if (NeedsCurrentMethodInput(GetDispatchInfo())) { 5128 DCHECK(InputAt(GetCurrentMethodIndexUnchecked()) == nullptr || // During argument setup. 5129 InputAt(GetCurrentMethodIndexUnchecked())->IsCurrentMethod()); 5130 return true; 5131 } else { 5132 DCHECK(InputCount() == GetCurrentMethodIndexUnchecked() || 5133 InputAt(GetCurrentMethodIndexUnchecked()) == nullptr || // During argument setup. 5134 !InputAt(GetCurrentMethodIndexUnchecked())->IsCurrentMethod()); 5135 return false; 5136 } 5137 } 5138 5139 // Get the index of the special input. 5140 size_t GetSpecialInputIndex() const { 5141 DCHECK(HasSpecialInput()); 5142 return GetSpecialInputIndexUnchecked(); 5143 } 5144 size_t GetSpecialInputIndexUnchecked() const { 5145 return GetNumberOfArguments() + (HasCurrentMethodInput() ? 1u : 0u); 5146 } 5147 5148 // Check if the method has a special input. 5149 bool HasSpecialInput() const { 5150 size_t other_inputs = 5151 GetSpecialInputIndexUnchecked() + (IsStaticWithExplicitClinitCheck() ? 1u : 0u); 5152 size_t input_count = InputCount(); 5153 DCHECK_LE(input_count - other_inputs, 1u) << other_inputs << " " << input_count; 5154 return other_inputs != input_count; 5155 } 5156 5157 void AddSpecialInput(HInstruction* input) { 5158 // We allow only one special input. 5159 DCHECK(!HasSpecialInput()); 5160 InsertInputAt(GetSpecialInputIndexUnchecked(), input); 5161 } 5162 5163 // Remove the HClinitCheck or the replacement HLoadClass (set as last input by 5164 // PrepareForRegisterAllocation::VisitClinitCheck() in lieu of the initial HClinitCheck) 5165 // instruction; only relevant for static calls with explicit clinit check. 5166 void RemoveExplicitClinitCheck(ClinitCheckRequirement new_requirement) { 5167 DCHECK(IsStaticWithExplicitClinitCheck()); 5168 size_t last_input_index = inputs_.size() - 1u; 5169 HInstruction* last_input = inputs_.back().GetInstruction(); 5170 DCHECK(last_input != nullptr); 5171 DCHECK(last_input->IsLoadClass() || last_input->IsClinitCheck()) << last_input->DebugName(); 5172 RemoveAsUserOfInput(last_input_index); 5173 inputs_.pop_back(); 5174 SetPackedField<ClinitCheckRequirementField>(new_requirement); 5175 DCHECK(!IsStaticWithExplicitClinitCheck()); 5176 } 5177 5178 // Is this a call to a static method whose declaring class has an 5179 // explicit initialization check in the graph? 5180 bool IsStaticWithExplicitClinitCheck() const { 5181 return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kExplicit); 5182 } 5183 5184 // Is this a call to a static method whose declaring class has an 5185 // implicit intialization check requirement? 5186 bool IsStaticWithImplicitClinitCheck() const { 5187 return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kImplicit); 5188 } 5189 5190 DECLARE_INSTRUCTION(InvokeStaticOrDirect); 5191 5192 protected: 5193 DEFAULT_COPY_CONSTRUCTOR(InvokeStaticOrDirect); 5194 5195 private: 5196 static constexpr size_t kFieldClinitCheckRequirement = kNumberOfInvokePackedBits; 5197 static constexpr size_t kFieldClinitCheckRequirementSize = 5198 MinimumBitsToStore(static_cast<size_t>(ClinitCheckRequirement::kLast)); 5199 static constexpr size_t kNumberOfInvokeStaticOrDirectPackedBits = 5200 kFieldClinitCheckRequirement + kFieldClinitCheckRequirementSize; 5201 static_assert(kNumberOfInvokeStaticOrDirectPackedBits <= kMaxNumberOfPackedBits, 5202 "Too many packed fields."); 5203 using ClinitCheckRequirementField = BitField<ClinitCheckRequirement, 5204 kFieldClinitCheckRequirement, 5205 kFieldClinitCheckRequirementSize>; 5206 5207 DispatchInfo dispatch_info_; 5208 }; 5209 std::ostream& operator<<(std::ostream& os, MethodLoadKind rhs); 5210 std::ostream& operator<<(std::ostream& os, CodePtrLocation rhs); 5211 std::ostream& operator<<(std::ostream& os, HInvokeStaticOrDirect::ClinitCheckRequirement rhs); 5212 5213 class HInvokeVirtual final : public HInvoke { 5214 public: 5215 HInvokeVirtual(ArenaAllocator* allocator, 5216 uint32_t number_of_arguments, 5217 DataType::Type return_type, 5218 uint32_t dex_pc, 5219 MethodReference method_reference, 5220 ArtMethod* resolved_method, 5221 MethodReference resolved_method_reference, 5222 uint32_t vtable_index, 5223 bool enable_intrinsic_opt) 5224 : HInvoke(kInvokeVirtual, 5225 allocator, 5226 number_of_arguments, 5227 0u, 5228 return_type, 5229 dex_pc, 5230 method_reference, 5231 resolved_method, 5232 resolved_method_reference, 5233 kVirtual, 5234 enable_intrinsic_opt), 5235 vtable_index_(vtable_index) { 5236 } 5237 5238 bool IsClonable() const override { return true; } 5239 5240 bool CanBeNull() const override { 5241 switch (GetIntrinsic()) { 5242 case Intrinsics::kThreadCurrentThread: 5243 case Intrinsics::kStringBufferAppend: 5244 case Intrinsics::kStringBufferToString: 5245 case Intrinsics::kStringBuilderAppendObject: 5246 case Intrinsics::kStringBuilderAppendString: 5247 case Intrinsics::kStringBuilderAppendCharSequence: 5248 case Intrinsics::kStringBuilderAppendCharArray: 5249 case Intrinsics::kStringBuilderAppendBoolean: 5250 case Intrinsics::kStringBuilderAppendChar: 5251 case Intrinsics::kStringBuilderAppendInt: 5252 case Intrinsics::kStringBuilderAppendLong: 5253 case Intrinsics::kStringBuilderAppendFloat: 5254 case Intrinsics::kStringBuilderAppendDouble: 5255 case Intrinsics::kStringBuilderToString: 5256 return false; 5257 default: 5258 return HInvoke::CanBeNull(); 5259 } 5260 } 5261 5262 bool CanDoImplicitNullCheckOn(HInstruction* obj) const override; 5263 5264 uint32_t GetVTableIndex() const { return vtable_index_; } 5265 5266 DECLARE_INSTRUCTION(InvokeVirtual); 5267 5268 protected: 5269 DEFAULT_COPY_CONSTRUCTOR(InvokeVirtual); 5270 5271 private: 5272 // Cached value of the resolved method, to avoid needing the mutator lock. 5273 const uint32_t vtable_index_; 5274 }; 5275 5276 class HInvokeInterface final : public HInvoke { 5277 public: 5278 HInvokeInterface(ArenaAllocator* allocator, 5279 uint32_t number_of_arguments, 5280 DataType::Type return_type, 5281 uint32_t dex_pc, 5282 MethodReference method_reference, 5283 ArtMethod* resolved_method, 5284 MethodReference resolved_method_reference, 5285 uint32_t imt_index, 5286 MethodLoadKind load_kind, 5287 bool enable_intrinsic_opt) 5288 : HInvoke(kInvokeInterface, 5289 allocator, 5290 number_of_arguments + (NeedsCurrentMethod(load_kind) ? 1 : 0), 5291 0u, 5292 return_type, 5293 dex_pc, 5294 method_reference, 5295 resolved_method, 5296 resolved_method_reference, 5297 kInterface, 5298 enable_intrinsic_opt), 5299 imt_index_(imt_index), 5300 hidden_argument_load_kind_(load_kind) { 5301 } 5302 5303 static bool NeedsCurrentMethod(MethodLoadKind load_kind) { 5304 return load_kind == MethodLoadKind::kRecursive; 5305 } 5306 5307 bool IsClonable() const override { return true; } 5308 bool NeedsBss() const override { 5309 return GetHiddenArgumentLoadKind() == MethodLoadKind::kBssEntry; 5310 } 5311 5312 bool CanDoImplicitNullCheckOn(HInstruction* obj) const override { 5313 // TODO: Add implicit null checks in intrinsics. 5314 return (obj == InputAt(0)) && !IsIntrinsic(); 5315 } 5316 5317 size_t GetSpecialInputIndex() const { 5318 return GetNumberOfArguments(); 5319 } 5320 5321 void AddSpecialInput(HInstruction* input) { 5322 InsertInputAt(GetSpecialInputIndex(), input); 5323 } 5324 5325 uint32_t GetImtIndex() const { return imt_index_; } 5326 MethodLoadKind GetHiddenArgumentLoadKind() const { return hidden_argument_load_kind_; } 5327 5328 DECLARE_INSTRUCTION(InvokeInterface); 5329 5330 protected: 5331 DEFAULT_COPY_CONSTRUCTOR(InvokeInterface); 5332 5333 private: 5334 // Cached value of the resolved method, to avoid needing the mutator lock. 5335 const uint32_t imt_index_; 5336 5337 // How the hidden argument (the interface method) is being loaded. 5338 const MethodLoadKind hidden_argument_load_kind_; 5339 }; 5340 5341 class HNeg final : public HUnaryOperation { 5342 public: 5343 HNeg(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 5344 : HUnaryOperation(kNeg, result_type, input, dex_pc) { 5345 DCHECK_EQ(result_type, DataType::Kind(input->GetType())); 5346 } 5347 5348 template <typename T> static T Compute(T x) { return -x; } 5349 5350 HConstant* Evaluate(HIntConstant* x) const override { 5351 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 5352 } 5353 HConstant* Evaluate(HLongConstant* x) const override { 5354 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); 5355 } 5356 HConstant* Evaluate(HFloatConstant* x) const override { 5357 return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue()), GetDexPc()); 5358 } 5359 HConstant* Evaluate(HDoubleConstant* x) const override { 5360 return GetBlock()->GetGraph()->GetDoubleConstant(Compute(x->GetValue()), GetDexPc()); 5361 } 5362 5363 DECLARE_INSTRUCTION(Neg); 5364 5365 protected: 5366 DEFAULT_COPY_CONSTRUCTOR(Neg); 5367 }; 5368 5369 class HNewArray final : public HExpression<2> { 5370 public: 5371 HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc, size_t component_size_shift) 5372 : HExpression(kNewArray, DataType::Type::kReference, SideEffects::CanTriggerGC(), dex_pc) { 5373 SetRawInputAt(0, cls); 5374 SetRawInputAt(1, length); 5375 SetPackedField<ComponentSizeShiftField>(component_size_shift); 5376 } 5377 5378 bool IsClonable() const override { return true; } 5379 5380 // Calls runtime so needs an environment. 5381 bool NeedsEnvironment() const override { return true; } 5382 5383 // May throw NegativeArraySizeException, OutOfMemoryError, etc. 5384 bool CanThrow() const override { return true; } 5385 5386 bool CanBeNull() const override { return false; } 5387 5388 HLoadClass* GetLoadClass() const { 5389 DCHECK(InputAt(0)->IsLoadClass()); 5390 return InputAt(0)->AsLoadClass(); 5391 } 5392 5393 HInstruction* GetLength() const { 5394 return InputAt(1); 5395 } 5396 5397 size_t GetComponentSizeShift() { 5398 return GetPackedField<ComponentSizeShiftField>(); 5399 } 5400 5401 DECLARE_INSTRUCTION(NewArray); 5402 5403 protected: 5404 DEFAULT_COPY_CONSTRUCTOR(NewArray); 5405 5406 private: 5407 static constexpr size_t kFieldComponentSizeShift = kNumberOfGenericPackedBits; 5408 static constexpr size_t kFieldComponentSizeShiftSize = MinimumBitsToStore(3u); 5409 static constexpr size_t kNumberOfNewArrayPackedBits = 5410 kFieldComponentSizeShift + kFieldComponentSizeShiftSize; 5411 static_assert(kNumberOfNewArrayPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 5412 using ComponentSizeShiftField = 5413 BitField<size_t, kFieldComponentSizeShift, kFieldComponentSizeShiftSize>; 5414 }; 5415 5416 class HAdd final : public HBinaryOperation { 5417 public: 5418 HAdd(DataType::Type result_type, 5419 HInstruction* left, 5420 HInstruction* right, 5421 uint32_t dex_pc = kNoDexPc) 5422 : HBinaryOperation(kAdd, result_type, left, right, SideEffects::None(), dex_pc) { 5423 } 5424 5425 bool IsCommutative() const override { return true; } 5426 5427 template <typename T> static T Compute(T x, T y) { return x + y; } 5428 5429 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5430 return GetBlock()->GetGraph()->GetIntConstant( 5431 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5432 } 5433 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5434 return GetBlock()->GetGraph()->GetLongConstant( 5435 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5436 } 5437 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 5438 return GetBlock()->GetGraph()->GetFloatConstant( 5439 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5440 } 5441 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 5442 return GetBlock()->GetGraph()->GetDoubleConstant( 5443 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5444 } 5445 5446 DECLARE_INSTRUCTION(Add); 5447 5448 protected: 5449 DEFAULT_COPY_CONSTRUCTOR(Add); 5450 }; 5451 5452 class HSub final : public HBinaryOperation { 5453 public: 5454 HSub(DataType::Type result_type, 5455 HInstruction* left, 5456 HInstruction* right, 5457 uint32_t dex_pc = kNoDexPc) 5458 : HBinaryOperation(kSub, result_type, left, right, SideEffects::None(), dex_pc) { 5459 } 5460 5461 template <typename T> static T Compute(T x, T y) { return x - y; } 5462 5463 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5464 return GetBlock()->GetGraph()->GetIntConstant( 5465 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5466 } 5467 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5468 return GetBlock()->GetGraph()->GetLongConstant( 5469 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5470 } 5471 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 5472 return GetBlock()->GetGraph()->GetFloatConstant( 5473 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5474 } 5475 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 5476 return GetBlock()->GetGraph()->GetDoubleConstant( 5477 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5478 } 5479 5480 DECLARE_INSTRUCTION(Sub); 5481 5482 protected: 5483 DEFAULT_COPY_CONSTRUCTOR(Sub); 5484 }; 5485 5486 class HMul final : public HBinaryOperation { 5487 public: 5488 HMul(DataType::Type result_type, 5489 HInstruction* left, 5490 HInstruction* right, 5491 uint32_t dex_pc = kNoDexPc) 5492 : HBinaryOperation(kMul, result_type, left, right, SideEffects::None(), dex_pc) { 5493 } 5494 5495 bool IsCommutative() const override { return true; } 5496 5497 template <typename T> static T Compute(T x, T y) { return x * y; } 5498 5499 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5500 return GetBlock()->GetGraph()->GetIntConstant( 5501 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5502 } 5503 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5504 return GetBlock()->GetGraph()->GetLongConstant( 5505 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5506 } 5507 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 5508 return GetBlock()->GetGraph()->GetFloatConstant( 5509 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5510 } 5511 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 5512 return GetBlock()->GetGraph()->GetDoubleConstant( 5513 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5514 } 5515 5516 DECLARE_INSTRUCTION(Mul); 5517 5518 protected: 5519 DEFAULT_COPY_CONSTRUCTOR(Mul); 5520 }; 5521 5522 class HDiv final : public HBinaryOperation { 5523 public: 5524 HDiv(DataType::Type result_type, 5525 HInstruction* left, 5526 HInstruction* right, 5527 uint32_t dex_pc) 5528 : HBinaryOperation(kDiv, result_type, left, right, SideEffects::None(), dex_pc) { 5529 } 5530 5531 template <typename T> 5532 T ComputeIntegral(T x, T y) const { 5533 DCHECK(!DataType::IsFloatingPointType(GetType())) << GetType(); 5534 // Our graph structure ensures we never have 0 for `y` during 5535 // constant folding. 5536 DCHECK_NE(y, 0); 5537 // Special case -1 to avoid getting a SIGFPE on x86(_64). 5538 return (y == -1) ? -x : x / y; 5539 } 5540 5541 template <typename T> 5542 T ComputeFP(T x, T y) const { 5543 DCHECK(DataType::IsFloatingPointType(GetType())) << GetType(); 5544 return x / y; 5545 } 5546 5547 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5548 return GetBlock()->GetGraph()->GetIntConstant( 5549 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5550 } 5551 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5552 return GetBlock()->GetGraph()->GetLongConstant( 5553 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5554 } 5555 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 5556 return GetBlock()->GetGraph()->GetFloatConstant( 5557 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 5558 } 5559 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 5560 return GetBlock()->GetGraph()->GetDoubleConstant( 5561 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 5562 } 5563 5564 DECLARE_INSTRUCTION(Div); 5565 5566 protected: 5567 DEFAULT_COPY_CONSTRUCTOR(Div); 5568 }; 5569 5570 class HRem final : public HBinaryOperation { 5571 public: 5572 HRem(DataType::Type result_type, 5573 HInstruction* left, 5574 HInstruction* right, 5575 uint32_t dex_pc) 5576 : HBinaryOperation(kRem, result_type, left, right, SideEffects::None(), dex_pc) { 5577 } 5578 5579 template <typename T> 5580 T ComputeIntegral(T x, T y) const { 5581 DCHECK(!DataType::IsFloatingPointType(GetType())) << GetType(); 5582 // Our graph structure ensures we never have 0 for `y` during 5583 // constant folding. 5584 DCHECK_NE(y, 0); 5585 // Special case -1 to avoid getting a SIGFPE on x86(_64). 5586 return (y == -1) ? 0 : x % y; 5587 } 5588 5589 template <typename T> 5590 T ComputeFP(T x, T y) const { 5591 DCHECK(DataType::IsFloatingPointType(GetType())) << GetType(); 5592 return std::fmod(x, y); 5593 } 5594 5595 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5596 return GetBlock()->GetGraph()->GetIntConstant( 5597 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5598 } 5599 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5600 return GetBlock()->GetGraph()->GetLongConstant( 5601 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5602 } 5603 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override { 5604 return GetBlock()->GetGraph()->GetFloatConstant( 5605 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 5606 } 5607 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override { 5608 return GetBlock()->GetGraph()->GetDoubleConstant( 5609 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 5610 } 5611 5612 DECLARE_INSTRUCTION(Rem); 5613 5614 protected: 5615 DEFAULT_COPY_CONSTRUCTOR(Rem); 5616 }; 5617 5618 class HMin final : public HBinaryOperation { 5619 public: 5620 HMin(DataType::Type result_type, 5621 HInstruction* left, 5622 HInstruction* right, 5623 uint32_t dex_pc) 5624 : HBinaryOperation(kMin, result_type, left, right, SideEffects::None(), dex_pc) {} 5625 5626 bool IsCommutative() const override { return true; } 5627 5628 // Evaluation for integral values. 5629 template <typename T> static T ComputeIntegral(T x, T y) { 5630 return (x <= y) ? x : y; 5631 } 5632 5633 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5634 return GetBlock()->GetGraph()->GetIntConstant( 5635 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5636 } 5637 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5638 return GetBlock()->GetGraph()->GetLongConstant( 5639 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5640 } 5641 // TODO: Evaluation for floating-point values. 5642 HConstant* Evaluate([[maybe_unused]] HFloatConstant* x, 5643 [[maybe_unused]] HFloatConstant* y) const override { 5644 return nullptr; 5645 } 5646 HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x, 5647 [[maybe_unused]] HDoubleConstant* y) const override { 5648 return nullptr; 5649 } 5650 5651 DECLARE_INSTRUCTION(Min); 5652 5653 protected: 5654 DEFAULT_COPY_CONSTRUCTOR(Min); 5655 }; 5656 5657 class HMax final : public HBinaryOperation { 5658 public: 5659 HMax(DataType::Type result_type, 5660 HInstruction* left, 5661 HInstruction* right, 5662 uint32_t dex_pc) 5663 : HBinaryOperation(kMax, result_type, left, right, SideEffects::None(), dex_pc) {} 5664 5665 bool IsCommutative() const override { return true; } 5666 5667 // Evaluation for integral values. 5668 template <typename T> static T ComputeIntegral(T x, T y) { 5669 return (x >= y) ? x : y; 5670 } 5671 5672 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5673 return GetBlock()->GetGraph()->GetIntConstant( 5674 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5675 } 5676 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5677 return GetBlock()->GetGraph()->GetLongConstant( 5678 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 5679 } 5680 // TODO: Evaluation for floating-point values. 5681 HConstant* Evaluate([[maybe_unused]] HFloatConstant* x, 5682 [[maybe_unused]] HFloatConstant* y) const override { 5683 return nullptr; 5684 } 5685 HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x, 5686 [[maybe_unused]] HDoubleConstant* y) const override { 5687 return nullptr; 5688 } 5689 5690 DECLARE_INSTRUCTION(Max); 5691 5692 protected: 5693 DEFAULT_COPY_CONSTRUCTOR(Max); 5694 }; 5695 5696 class HAbs final : public HUnaryOperation { 5697 public: 5698 HAbs(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 5699 : HUnaryOperation(kAbs, result_type, input, dex_pc) {} 5700 5701 // Evaluation for integral values. 5702 template <typename T> static T ComputeIntegral(T x) { 5703 return x < 0 ? -x : x; 5704 } 5705 5706 // Evaluation for floating-point values. 5707 // Note, as a "quality of implementation", rather than pure "spec compliance", 5708 // we require that Math.abs() clears the sign bit (but changes nothing else) 5709 // for all floating-point numbers, including NaN (signaling NaN may become quiet though). 5710 // http://b/30758343 5711 template <typename T, typename S> static T ComputeFP(T x) { 5712 S bits = bit_cast<S, T>(x); 5713 return bit_cast<T, S>(bits & std::numeric_limits<S>::max()); 5714 } 5715 5716 HConstant* Evaluate(HIntConstant* x) const override { 5717 return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(x->GetValue()), GetDexPc()); 5718 } 5719 HConstant* Evaluate(HLongConstant* x) const override { 5720 return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue()), GetDexPc()); 5721 } 5722 HConstant* Evaluate(HFloatConstant* x) const override { 5723 return GetBlock()->GetGraph()->GetFloatConstant( 5724 ComputeFP<float, int32_t>(x->GetValue()), GetDexPc()); 5725 } 5726 HConstant* Evaluate(HDoubleConstant* x) const override { 5727 return GetBlock()->GetGraph()->GetDoubleConstant( 5728 ComputeFP<double, int64_t>(x->GetValue()), GetDexPc()); 5729 } 5730 5731 DECLARE_INSTRUCTION(Abs); 5732 5733 protected: 5734 DEFAULT_COPY_CONSTRUCTOR(Abs); 5735 }; 5736 5737 class HDivZeroCheck final : public HExpression<1> { 5738 public: 5739 // `HDivZeroCheck` can trigger GC, as it may call the `ArithmeticException` 5740 // constructor. However it can only do it on a fatal slow path so execution never returns to the 5741 // instruction following the current one; thus 'SideEffects::None()' is used. 5742 HDivZeroCheck(HInstruction* value, uint32_t dex_pc) 5743 : HExpression(kDivZeroCheck, value->GetType(), SideEffects::None(), dex_pc) { 5744 SetRawInputAt(0, value); 5745 } 5746 5747 bool IsClonable() const override { return true; } 5748 bool CanBeMoved() const override { return true; } 5749 5750 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 5751 return true; 5752 } 5753 5754 bool NeedsEnvironment() const override { return true; } 5755 bool CanThrow() const override { return true; } 5756 5757 DECLARE_INSTRUCTION(DivZeroCheck); 5758 5759 protected: 5760 DEFAULT_COPY_CONSTRUCTOR(DivZeroCheck); 5761 }; 5762 5763 class HShl final : public HBinaryOperation { 5764 public: 5765 HShl(DataType::Type result_type, 5766 HInstruction* value, 5767 HInstruction* distance, 5768 uint32_t dex_pc = kNoDexPc) 5769 : HBinaryOperation(kShl, result_type, value, distance, SideEffects::None(), dex_pc) { 5770 DCHECK_EQ(result_type, DataType::Kind(value->GetType())); 5771 DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType())); 5772 } 5773 5774 template <typename T> 5775 static T Compute(T value, int32_t distance, int32_t max_shift_distance) { 5776 return value << (distance & max_shift_distance); 5777 } 5778 5779 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override { 5780 return GetBlock()->GetGraph()->GetIntConstant( 5781 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 5782 } 5783 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override { 5784 return GetBlock()->GetGraph()->GetLongConstant( 5785 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 5786 } 5787 5788 DECLARE_INSTRUCTION(Shl); 5789 5790 protected: 5791 DEFAULT_COPY_CONSTRUCTOR(Shl); 5792 }; 5793 5794 class HShr final : public HBinaryOperation { 5795 public: 5796 HShr(DataType::Type result_type, 5797 HInstruction* value, 5798 HInstruction* distance, 5799 uint32_t dex_pc = kNoDexPc) 5800 : HBinaryOperation(kShr, result_type, value, distance, SideEffects::None(), dex_pc) { 5801 DCHECK_EQ(result_type, DataType::Kind(value->GetType())); 5802 DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType())); 5803 } 5804 5805 template <typename T> 5806 static T Compute(T value, int32_t distance, int32_t max_shift_distance) { 5807 return value >> (distance & max_shift_distance); 5808 } 5809 5810 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override { 5811 return GetBlock()->GetGraph()->GetIntConstant( 5812 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 5813 } 5814 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override { 5815 return GetBlock()->GetGraph()->GetLongConstant( 5816 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 5817 } 5818 5819 DECLARE_INSTRUCTION(Shr); 5820 5821 protected: 5822 DEFAULT_COPY_CONSTRUCTOR(Shr); 5823 }; 5824 5825 class HUShr final : public HBinaryOperation { 5826 public: 5827 HUShr(DataType::Type result_type, 5828 HInstruction* value, 5829 HInstruction* distance, 5830 uint32_t dex_pc = kNoDexPc) 5831 : HBinaryOperation(kUShr, result_type, value, distance, SideEffects::None(), dex_pc) { 5832 DCHECK_EQ(result_type, DataType::Kind(value->GetType())); 5833 DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType())); 5834 } 5835 5836 template <typename T> 5837 static T Compute(T value, int32_t distance, int32_t max_shift_distance) { 5838 using V = std::make_unsigned_t<T>; 5839 V ux = static_cast<V>(value); 5840 return static_cast<T>(ux >> (distance & max_shift_distance)); 5841 } 5842 5843 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override { 5844 return GetBlock()->GetGraph()->GetIntConstant( 5845 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 5846 } 5847 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override { 5848 return GetBlock()->GetGraph()->GetLongConstant( 5849 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 5850 } 5851 5852 DECLARE_INSTRUCTION(UShr); 5853 5854 protected: 5855 DEFAULT_COPY_CONSTRUCTOR(UShr); 5856 }; 5857 5858 class HAnd final : public HBinaryOperation { 5859 public: 5860 HAnd(DataType::Type result_type, 5861 HInstruction* left, 5862 HInstruction* right, 5863 uint32_t dex_pc = kNoDexPc) 5864 : HBinaryOperation(kAnd, result_type, left, right, SideEffects::None(), dex_pc) { 5865 } 5866 5867 bool IsCommutative() const override { return true; } 5868 5869 template <typename T> static T Compute(T x, T y) { return x & y; } 5870 5871 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5872 return GetBlock()->GetGraph()->GetIntConstant( 5873 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5874 } 5875 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5876 return GetBlock()->GetGraph()->GetLongConstant( 5877 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5878 } 5879 5880 DECLARE_INSTRUCTION(And); 5881 5882 protected: 5883 DEFAULT_COPY_CONSTRUCTOR(And); 5884 }; 5885 5886 class HOr final : public HBinaryOperation { 5887 public: 5888 HOr(DataType::Type result_type, 5889 HInstruction* left, 5890 HInstruction* right, 5891 uint32_t dex_pc = kNoDexPc) 5892 : HBinaryOperation(kOr, result_type, left, right, SideEffects::None(), dex_pc) { 5893 } 5894 5895 bool IsCommutative() const override { return true; } 5896 5897 template <typename T> static T Compute(T x, T y) { return x | y; } 5898 5899 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5900 return GetBlock()->GetGraph()->GetIntConstant( 5901 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5902 } 5903 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5904 return GetBlock()->GetGraph()->GetLongConstant( 5905 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5906 } 5907 5908 DECLARE_INSTRUCTION(Or); 5909 5910 protected: 5911 DEFAULT_COPY_CONSTRUCTOR(Or); 5912 }; 5913 5914 class HXor final : public HBinaryOperation { 5915 public: 5916 HXor(DataType::Type result_type, 5917 HInstruction* left, 5918 HInstruction* right, 5919 uint32_t dex_pc = kNoDexPc) 5920 : HBinaryOperation(kXor, result_type, left, right, SideEffects::None(), dex_pc) { 5921 } 5922 5923 bool IsCommutative() const override { return true; } 5924 5925 template <typename T> static T Compute(T x, T y) { return x ^ y; } 5926 5927 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 5928 return GetBlock()->GetGraph()->GetIntConstant( 5929 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5930 } 5931 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 5932 return GetBlock()->GetGraph()->GetLongConstant( 5933 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 5934 } 5935 5936 DECLARE_INSTRUCTION(Xor); 5937 5938 protected: 5939 DEFAULT_COPY_CONSTRUCTOR(Xor); 5940 }; 5941 5942 class HRor final : public HBinaryOperation { 5943 public: 5944 HRor(DataType::Type result_type, HInstruction* value, HInstruction* distance) 5945 : HBinaryOperation(kRor, result_type, value, distance) { 5946 } 5947 5948 template <typename T> 5949 static T Compute(T value, int32_t distance, int32_t max_shift_value) { 5950 using V = std::make_unsigned_t<T>; 5951 V ux = static_cast<V>(value); 5952 if ((distance & max_shift_value) == 0) { 5953 return static_cast<T>(ux); 5954 } else { 5955 const V reg_bits = sizeof(T) * 8; 5956 return static_cast<T>(ux >> (distance & max_shift_value)) | 5957 (value << (reg_bits - (distance & max_shift_value))); 5958 } 5959 } 5960 5961 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override { 5962 return GetBlock()->GetGraph()->GetIntConstant( 5963 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 5964 } 5965 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override { 5966 return GetBlock()->GetGraph()->GetLongConstant( 5967 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 5968 } 5969 5970 DECLARE_INSTRUCTION(Ror); 5971 5972 protected: 5973 DEFAULT_COPY_CONSTRUCTOR(Ror); 5974 }; 5975 5976 // The value of a parameter in this method. Its location depends on 5977 // the calling convention. 5978 class HParameterValue final : public HExpression<0> { 5979 public: 5980 HParameterValue(const DexFile& dex_file, 5981 dex::TypeIndex type_index, 5982 uint8_t index, 5983 DataType::Type parameter_type, 5984 bool is_this = false) 5985 : HExpression(kParameterValue, parameter_type, SideEffects::None(), kNoDexPc), 5986 dex_file_(dex_file), 5987 type_index_(type_index), 5988 index_(index) { 5989 SetPackedFlag<kFlagIsThis>(is_this); 5990 SetPackedFlag<kFlagCanBeNull>(!is_this); 5991 } 5992 5993 const DexFile& GetDexFile() const { return dex_file_; } 5994 dex::TypeIndex GetTypeIndex() const { return type_index_; } 5995 uint8_t GetIndex() const { return index_; } 5996 bool IsThis() const { return GetPackedFlag<kFlagIsThis>(); } 5997 5998 bool CanBeNull() const override { return GetPackedFlag<kFlagCanBeNull>(); } 5999 void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); } 6000 6001 DECLARE_INSTRUCTION(ParameterValue); 6002 6003 protected: 6004 DEFAULT_COPY_CONSTRUCTOR(ParameterValue); 6005 6006 private: 6007 // Whether or not the parameter value corresponds to 'this' argument. 6008 static constexpr size_t kFlagIsThis = kNumberOfGenericPackedBits; 6009 static constexpr size_t kFlagCanBeNull = kFlagIsThis + 1; 6010 static constexpr size_t kNumberOfParameterValuePackedBits = kFlagCanBeNull + 1; 6011 static_assert(kNumberOfParameterValuePackedBits <= kMaxNumberOfPackedBits, 6012 "Too many packed fields."); 6013 6014 const DexFile& dex_file_; 6015 const dex::TypeIndex type_index_; 6016 // The index of this parameter in the parameters list. Must be less 6017 // than HGraph::number_of_in_vregs_. 6018 const uint8_t index_; 6019 }; 6020 6021 class HNot final : public HUnaryOperation { 6022 public: 6023 HNot(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 6024 : HUnaryOperation(kNot, result_type, input, dex_pc) { 6025 } 6026 6027 bool CanBeMoved() const override { return true; } 6028 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6029 return true; 6030 } 6031 6032 template <typename T> static T Compute(T x) { return ~x; } 6033 6034 HConstant* Evaluate(HIntConstant* x) const override { 6035 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 6036 } 6037 HConstant* Evaluate(HLongConstant* x) const override { 6038 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); 6039 } 6040 6041 DECLARE_INSTRUCTION(Not); 6042 6043 protected: 6044 DEFAULT_COPY_CONSTRUCTOR(Not); 6045 }; 6046 6047 class HBooleanNot final : public HUnaryOperation { 6048 public: 6049 explicit HBooleanNot(HInstruction* input, uint32_t dex_pc = kNoDexPc) 6050 : HUnaryOperation(kBooleanNot, DataType::Type::kBool, input, dex_pc) { 6051 } 6052 6053 bool CanBeMoved() const override { return true; } 6054 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6055 return true; 6056 } 6057 6058 template <typename T> static bool Compute(T x) { 6059 DCHECK(IsUint<1>(x)) << x; 6060 return !x; 6061 } 6062 6063 HConstant* Evaluate(HIntConstant* x) const override { 6064 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 6065 } 6066 6067 DECLARE_INSTRUCTION(BooleanNot); 6068 6069 protected: 6070 DEFAULT_COPY_CONSTRUCTOR(BooleanNot); 6071 }; 6072 6073 class HTypeConversion final : public HExpression<1> { 6074 public: 6075 // Instantiate a type conversion of `input` to `result_type`. 6076 HTypeConversion(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 6077 : HExpression(kTypeConversion, result_type, SideEffects::None(), dex_pc) { 6078 SetRawInputAt(0, input); 6079 // Invariant: We should never generate a conversion to a Boolean value. 6080 DCHECK_NE(DataType::Type::kBool, result_type); 6081 } 6082 6083 HInstruction* GetInput() const { return InputAt(0); } 6084 DataType::Type GetInputType() const { return GetInput()->GetType(); } 6085 DataType::Type GetResultType() const { return GetType(); } 6086 6087 bool IsClonable() const override { return true; } 6088 bool CanBeMoved() const override { return true; } 6089 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6090 return true; 6091 } 6092 // Return whether the conversion is implicit. This includes conversion to the same type. 6093 bool IsImplicitConversion() const { 6094 return DataType::IsTypeConversionImplicit(GetInputType(), GetResultType()); 6095 } 6096 6097 // Try to statically evaluate the conversion and return a HConstant 6098 // containing the result. If the input cannot be converted, return nullptr. 6099 HConstant* TryStaticEvaluation() const; 6100 6101 // Same but for `input` instead of GetInput(). 6102 HConstant* TryStaticEvaluation(HInstruction* input) const; 6103 6104 DECLARE_INSTRUCTION(TypeConversion); 6105 6106 protected: 6107 DEFAULT_COPY_CONSTRUCTOR(TypeConversion); 6108 }; 6109 6110 static constexpr uint32_t kNoRegNumber = -1; 6111 6112 class HNullCheck final : public HExpression<1> { 6113 public: 6114 // `HNullCheck` can trigger GC, as it may call the `NullPointerException` 6115 // constructor. However it can only do it on a fatal slow path so execution never returns to the 6116 // instruction following the current one; thus 'SideEffects::None()' is used. 6117 HNullCheck(HInstruction* value, uint32_t dex_pc) 6118 : HExpression(kNullCheck, value->GetType(), SideEffects::None(), dex_pc) { 6119 SetRawInputAt(0, value); 6120 } 6121 6122 bool IsClonable() const override { return true; } 6123 bool CanBeMoved() const override { return true; } 6124 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6125 return true; 6126 } 6127 6128 bool NeedsEnvironment() const override { return true; } 6129 6130 bool CanThrow() const override { return true; } 6131 6132 bool CanBeNull() const override { return false; } 6133 6134 DECLARE_INSTRUCTION(NullCheck); 6135 6136 protected: 6137 DEFAULT_COPY_CONSTRUCTOR(NullCheck); 6138 }; 6139 6140 // Embeds an ArtField and all the information required by the compiler. We cache 6141 // that information to avoid requiring the mutator lock every time we need it. 6142 class FieldInfo : public ValueObject { 6143 public: 6144 FieldInfo(ArtField* field, 6145 MemberOffset field_offset, 6146 DataType::Type field_type, 6147 bool is_volatile, 6148 uint32_t index, 6149 uint16_t declaring_class_def_index, 6150 const DexFile& dex_file) 6151 : field_(field), 6152 field_offset_(field_offset), 6153 field_type_(field_type), 6154 is_volatile_(is_volatile), 6155 index_(index), 6156 declaring_class_def_index_(declaring_class_def_index), 6157 dex_file_(dex_file) {} 6158 6159 ArtField* GetField() const { return field_; } 6160 MemberOffset GetFieldOffset() const { return field_offset_; } 6161 DataType::Type GetFieldType() const { return field_type_; } 6162 uint32_t GetFieldIndex() const { return index_; } 6163 uint16_t GetDeclaringClassDefIndex() const { return declaring_class_def_index_;} 6164 const DexFile& GetDexFile() const { return dex_file_; } 6165 bool IsVolatile() const { return is_volatile_; } 6166 6167 bool Equals(const FieldInfo& other) const { 6168 return field_ == other.field_ && 6169 field_offset_ == other.field_offset_ && 6170 field_type_ == other.field_type_ && 6171 is_volatile_ == other.is_volatile_ && 6172 index_ == other.index_ && 6173 declaring_class_def_index_ == other.declaring_class_def_index_ && 6174 &dex_file_ == &other.dex_file_; 6175 } 6176 6177 std::ostream& Dump(std::ostream& os) const { 6178 os << field_ << ", off: " << field_offset_ << ", type: " << field_type_ 6179 << ", volatile: " << std::boolalpha << is_volatile_ << ", index_: " << std::dec << index_ 6180 << ", declaring_class: " << declaring_class_def_index_ << ", dex: " << dex_file_; 6181 return os; 6182 } 6183 6184 private: 6185 ArtField* const field_; 6186 const MemberOffset field_offset_; 6187 const DataType::Type field_type_; 6188 const bool is_volatile_; 6189 const uint32_t index_; 6190 const uint16_t declaring_class_def_index_; 6191 const DexFile& dex_file_; 6192 }; 6193 6194 inline bool operator==(const FieldInfo& a, const FieldInfo& b) { 6195 return a.Equals(b); 6196 } 6197 6198 inline std::ostream& operator<<(std::ostream& os, const FieldInfo& a) { 6199 return a.Dump(os); 6200 } 6201 6202 class HInstanceFieldGet final : public HExpression<1> { 6203 public: 6204 HInstanceFieldGet(HInstruction* value, 6205 ArtField* field, 6206 DataType::Type field_type, 6207 MemberOffset field_offset, 6208 bool is_volatile, 6209 uint32_t field_idx, 6210 uint16_t declaring_class_def_index, 6211 const DexFile& dex_file, 6212 uint32_t dex_pc) 6213 : HExpression(kInstanceFieldGet, 6214 field_type, 6215 SideEffects::FieldReadOfType(field_type, is_volatile), 6216 dex_pc), 6217 field_info_(field, 6218 field_offset, 6219 field_type, 6220 is_volatile, 6221 field_idx, 6222 declaring_class_def_index, 6223 dex_file) { 6224 SetRawInputAt(0, value); 6225 } 6226 6227 bool IsClonable() const override { return true; } 6228 bool CanBeMoved() const override { return !IsVolatile(); } 6229 6230 bool InstructionDataEquals(const HInstruction* other) const override { 6231 const HInstanceFieldGet* other_get = other->AsInstanceFieldGet(); 6232 return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue(); 6233 } 6234 6235 bool CanDoImplicitNullCheckOn(HInstruction* obj) const override { 6236 return (obj == InputAt(0)) && art::CanDoImplicitNullCheckOn(GetFieldOffset().Uint32Value()); 6237 } 6238 6239 size_t ComputeHashCode() const override { 6240 return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue(); 6241 } 6242 6243 bool IsFieldAccess() const override { return true; } 6244 const FieldInfo& GetFieldInfo() const override { return field_info_; } 6245 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 6246 DataType::Type GetFieldType() const { return field_info_.GetFieldType(); } 6247 bool IsVolatile() const { return field_info_.IsVolatile(); } 6248 6249 void SetType(DataType::Type new_type) { 6250 DCHECK(DataType::IsIntegralType(GetType())); 6251 DCHECK(DataType::IsIntegralType(new_type)); 6252 DCHECK_EQ(DataType::Size(GetType()), DataType::Size(new_type)); 6253 SetPackedField<TypeField>(new_type); 6254 } 6255 6256 DECLARE_INSTRUCTION(InstanceFieldGet); 6257 6258 protected: 6259 DEFAULT_COPY_CONSTRUCTOR(InstanceFieldGet); 6260 6261 private: 6262 const FieldInfo field_info_; 6263 }; 6264 6265 enum class WriteBarrierKind { 6266 // Emit the write barrier. This write barrier is not being relied on so e.g. codegen can decide to 6267 // skip it if the value stored is null. This is the default behavior. 6268 kEmitNotBeingReliedOn, 6269 // Emit the write barrier. This write barrier is being relied on and must be emitted. 6270 kEmitBeingReliedOn, 6271 // Skip emitting the write barrier. This could be set because: 6272 // A) The write barrier is not needed (i.e. it is not a reference, or the value is the null 6273 // constant) 6274 // B) This write barrier was coalesced into another one so there's no need to emit it. 6275 kDontEmit, 6276 kLast = kDontEmit 6277 }; 6278 std::ostream& operator<<(std::ostream& os, WriteBarrierKind rhs); 6279 6280 class HInstanceFieldSet final : public HExpression<2> { 6281 public: 6282 HInstanceFieldSet(HInstruction* object, 6283 HInstruction* value, 6284 ArtField* field, 6285 DataType::Type field_type, 6286 MemberOffset field_offset, 6287 bool is_volatile, 6288 uint32_t field_idx, 6289 uint16_t declaring_class_def_index, 6290 const DexFile& dex_file, 6291 uint32_t dex_pc) 6292 : HExpression(kInstanceFieldSet, 6293 SideEffects::FieldWriteOfType(field_type, is_volatile), 6294 dex_pc), 6295 field_info_(field, 6296 field_offset, 6297 field_type, 6298 is_volatile, 6299 field_idx, 6300 declaring_class_def_index, 6301 dex_file) { 6302 SetPackedFlag<kFlagValueCanBeNull>(true); 6303 SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn); 6304 SetRawInputAt(0, object); 6305 SetRawInputAt(1, value); 6306 } 6307 6308 bool IsClonable() const override { return true; } 6309 6310 bool CanDoImplicitNullCheckOn(HInstruction* obj) const override { 6311 return (obj == InputAt(0)) && art::CanDoImplicitNullCheckOn(GetFieldOffset().Uint32Value()); 6312 } 6313 6314 bool IsFieldAccess() const override { return true; } 6315 const FieldInfo& GetFieldInfo() const override { return field_info_; } 6316 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 6317 DataType::Type GetFieldType() const { return field_info_.GetFieldType(); } 6318 bool IsVolatile() const { return field_info_.IsVolatile(); } 6319 HInstruction* GetValue() const { return InputAt(1); } 6320 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 6321 void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } 6322 WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); } 6323 void SetWriteBarrierKind(WriteBarrierKind kind) { 6324 DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn) 6325 << "We shouldn't go back to the original value."; 6326 DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit, 6327 GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn) 6328 << "If a write barrier was relied on by other write barriers, we cannot skip emitting it."; 6329 SetPackedField<WriteBarrierKindField>(kind); 6330 } 6331 6332 DECLARE_INSTRUCTION(InstanceFieldSet); 6333 6334 protected: 6335 DEFAULT_COPY_CONSTRUCTOR(InstanceFieldSet); 6336 6337 private: 6338 static constexpr size_t kFlagValueCanBeNull = kNumberOfGenericPackedBits; 6339 static constexpr size_t kWriteBarrierKind = kFlagValueCanBeNull + 1; 6340 static constexpr size_t kWriteBarrierKindSize = 6341 MinimumBitsToStore(static_cast<size_t>(WriteBarrierKind::kLast)); 6342 static constexpr size_t kNumberOfInstanceFieldSetPackedBits = 6343 kWriteBarrierKind + kWriteBarrierKindSize; 6344 static_assert(kNumberOfInstanceFieldSetPackedBits <= kMaxNumberOfPackedBits, 6345 "Too many packed fields."); 6346 6347 const FieldInfo field_info_; 6348 using WriteBarrierKindField = 6349 BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>; 6350 }; 6351 6352 class HArrayGet final : public HExpression<2> { 6353 public: 6354 HArrayGet(HInstruction* array, 6355 HInstruction* index, 6356 DataType::Type type, 6357 uint32_t dex_pc) 6358 : HArrayGet(array, 6359 index, 6360 type, 6361 SideEffects::ArrayReadOfType(type), 6362 dex_pc, 6363 /* is_string_char_at= */ false) { 6364 } 6365 6366 HArrayGet(HInstruction* array, 6367 HInstruction* index, 6368 DataType::Type type, 6369 SideEffects side_effects, 6370 uint32_t dex_pc, 6371 bool is_string_char_at) 6372 : HExpression(kArrayGet, type, side_effects, dex_pc) { 6373 SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at); 6374 SetRawInputAt(0, array); 6375 SetRawInputAt(1, index); 6376 } 6377 6378 bool IsClonable() const override { return true; } 6379 bool CanBeMoved() const override { return true; } 6380 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6381 return true; 6382 } 6383 bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const override { 6384 // TODO: We can be smarter here. 6385 // Currently, unless the array is the result of NewArray, the array access is always 6386 // preceded by some form of null NullCheck necessary for the bounds check, usually 6387 // implicit null check on the ArrayLength input to BoundsCheck or Deoptimize for 6388 // dynamic BCE. There are cases when these could be removed to produce better code. 6389 // If we ever add optimizations to do so we should allow an implicit check here 6390 // (as long as the address falls in the first page). 6391 // 6392 // As an example of such fancy optimization, we could eliminate BoundsCheck for 6393 // a = cond ? new int[1] : null; 6394 // a[0]; // The Phi does not need bounds check for either input. 6395 return false; 6396 } 6397 6398 bool IsEquivalentOf(HArrayGet* other) const { 6399 bool result = (GetDexPc() == other->GetDexPc()); 6400 if (kIsDebugBuild && result) { 6401 DCHECK_EQ(GetBlock(), other->GetBlock()); 6402 DCHECK_EQ(GetArray(), other->GetArray()); 6403 DCHECK_EQ(GetIndex(), other->GetIndex()); 6404 if (DataType::IsIntOrLongType(GetType())) { 6405 DCHECK(DataType::IsFloatingPointType(other->GetType())) << other->GetType(); 6406 } else { 6407 DCHECK(DataType::IsFloatingPointType(GetType())) << GetType(); 6408 DCHECK(DataType::IsIntOrLongType(other->GetType())) << other->GetType(); 6409 } 6410 } 6411 return result; 6412 } 6413 6414 bool IsStringCharAt() const { return GetPackedFlag<kFlagIsStringCharAt>(); } 6415 6416 HInstruction* GetArray() const { return InputAt(0); } 6417 HInstruction* GetIndex() const { return InputAt(1); } 6418 6419 void SetType(DataType::Type new_type) { 6420 DCHECK(DataType::IsIntegralType(GetType())); 6421 DCHECK(DataType::IsIntegralType(new_type)); 6422 DCHECK_EQ(DataType::Size(GetType()), DataType::Size(new_type)); 6423 SetPackedField<TypeField>(new_type); 6424 } 6425 6426 DECLARE_INSTRUCTION(ArrayGet); 6427 6428 protected: 6429 DEFAULT_COPY_CONSTRUCTOR(ArrayGet); 6430 6431 private: 6432 // We treat a String as an array, creating the HArrayGet from String.charAt() 6433 // intrinsic in the instruction simplifier. We can always determine whether 6434 // a particular HArrayGet is actually a String.charAt() by looking at the type 6435 // of the input but that requires holding the mutator lock, so we prefer to use 6436 // a flag, so that code generators don't need to do the locking. 6437 static constexpr size_t kFlagIsStringCharAt = kNumberOfGenericPackedBits; 6438 static constexpr size_t kNumberOfArrayGetPackedBits = kFlagIsStringCharAt + 1; 6439 static_assert(kNumberOfArrayGetPackedBits <= HInstruction::kMaxNumberOfPackedBits, 6440 "Too many packed fields."); 6441 }; 6442 6443 class HArraySet final : public HExpression<3> { 6444 public: 6445 HArraySet(HInstruction* array, 6446 HInstruction* index, 6447 HInstruction* value, 6448 DataType::Type expected_component_type, 6449 uint32_t dex_pc) 6450 : HArraySet(array, 6451 index, 6452 value, 6453 expected_component_type, 6454 // Make a best guess for side effects now, may be refined during SSA building. 6455 ComputeSideEffects(GetComponentType(value->GetType(), expected_component_type)), 6456 dex_pc) { 6457 } 6458 6459 HArraySet(HInstruction* array, 6460 HInstruction* index, 6461 HInstruction* value, 6462 DataType::Type expected_component_type, 6463 SideEffects side_effects, 6464 uint32_t dex_pc) 6465 : HExpression(kArraySet, side_effects, dex_pc) { 6466 SetPackedField<ExpectedComponentTypeField>(expected_component_type); 6467 SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType() == DataType::Type::kReference); 6468 SetPackedFlag<kFlagValueCanBeNull>(true); 6469 SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(false); 6470 SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn); 6471 SetRawInputAt(0, array); 6472 SetRawInputAt(1, index); 6473 SetRawInputAt(2, value); 6474 } 6475 6476 bool IsClonable() const override { return true; } 6477 6478 bool NeedsEnvironment() const override { 6479 // We call a runtime method to throw ArrayStoreException. 6480 return NeedsTypeCheck(); 6481 } 6482 6483 // Can throw ArrayStoreException. 6484 bool CanThrow() const override { return NeedsTypeCheck(); } 6485 6486 bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const override { 6487 // TODO: Same as for ArrayGet. 6488 return false; 6489 } 6490 6491 void ClearTypeCheck() { 6492 SetPackedFlag<kFlagNeedsTypeCheck>(false); 6493 // Clear the `CanTriggerGC` flag too as we can only trigger a GC when doing a type check. 6494 SetSideEffects(GetSideEffects().Exclusion(SideEffects::CanTriggerGC())); 6495 // Clear the environment too as we can only throw if we need a type check. 6496 RemoveEnvironment(); 6497 } 6498 6499 void ClearValueCanBeNull() { 6500 SetPackedFlag<kFlagValueCanBeNull>(false); 6501 } 6502 6503 void SetStaticTypeOfArrayIsObjectArray() { 6504 SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(true); 6505 } 6506 6507 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 6508 bool NeedsTypeCheck() const { return GetPackedFlag<kFlagNeedsTypeCheck>(); } 6509 bool StaticTypeOfArrayIsObjectArray() const { 6510 return GetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(); 6511 } 6512 6513 HInstruction* GetArray() const { return InputAt(0); } 6514 HInstruction* GetIndex() const { return InputAt(1); } 6515 HInstruction* GetValue() const { return InputAt(2); } 6516 6517 DataType::Type GetComponentType() const { 6518 return GetComponentType(GetValue()->GetType(), GetRawExpectedComponentType()); 6519 } 6520 6521 static DataType::Type GetComponentType(DataType::Type value_type, 6522 DataType::Type expected_component_type) { 6523 // The Dex format does not type floating point index operations. Since the 6524 // `expected_component_type` comes from SSA building and can therefore not 6525 // be correct, we also check what is the value type. If it is a floating 6526 // point type, we must use that type. 6527 return ((value_type == DataType::Type::kFloat32) || (value_type == DataType::Type::kFloat64)) 6528 ? value_type 6529 : expected_component_type; 6530 } 6531 6532 DataType::Type GetRawExpectedComponentType() const { 6533 return GetPackedField<ExpectedComponentTypeField>(); 6534 } 6535 6536 static SideEffects ComputeSideEffects(DataType::Type type) { 6537 return SideEffects::ArrayWriteOfType(type).Union(SideEffectsForArchRuntimeCalls(type)); 6538 } 6539 6540 static SideEffects SideEffectsForArchRuntimeCalls(DataType::Type value_type) { 6541 return (value_type == DataType::Type::kReference) ? SideEffects::CanTriggerGC() 6542 : SideEffects::None(); 6543 } 6544 6545 WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); } 6546 6547 void SetWriteBarrierKind(WriteBarrierKind kind) { 6548 DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn) 6549 << "We shouldn't go back to the original value."; 6550 DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit, 6551 GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn) 6552 << "If a write barrier was relied on by other write barriers, we cannot skip emitting it."; 6553 SetPackedField<WriteBarrierKindField>(kind); 6554 } 6555 6556 DECLARE_INSTRUCTION(ArraySet); 6557 6558 protected: 6559 DEFAULT_COPY_CONSTRUCTOR(ArraySet); 6560 6561 private: 6562 static constexpr size_t kFieldExpectedComponentType = kNumberOfGenericPackedBits; 6563 static constexpr size_t kFieldExpectedComponentTypeSize = 6564 MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast)); 6565 static constexpr size_t kFlagNeedsTypeCheck = 6566 kFieldExpectedComponentType + kFieldExpectedComponentTypeSize; 6567 static constexpr size_t kFlagValueCanBeNull = kFlagNeedsTypeCheck + 1; 6568 // Cached information for the reference_type_info_ so that codegen 6569 // does not need to inspect the static type. 6570 static constexpr size_t kFlagStaticTypeOfArrayIsObjectArray = kFlagValueCanBeNull + 1; 6571 static constexpr size_t kWriteBarrierKind = kFlagStaticTypeOfArrayIsObjectArray + 1; 6572 static constexpr size_t kWriteBarrierKindSize = 6573 MinimumBitsToStore(static_cast<size_t>(WriteBarrierKind::kLast)); 6574 static constexpr size_t kNumberOfArraySetPackedBits = kWriteBarrierKind + kWriteBarrierKindSize; 6575 static_assert(kNumberOfArraySetPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 6576 using ExpectedComponentTypeField = 6577 BitField<DataType::Type, kFieldExpectedComponentType, kFieldExpectedComponentTypeSize>; 6578 6579 using WriteBarrierKindField = 6580 BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>; 6581 }; 6582 6583 class HArrayLength final : public HExpression<1> { 6584 public: 6585 HArrayLength(HInstruction* array, uint32_t dex_pc, bool is_string_length = false) 6586 : HExpression(kArrayLength, DataType::Type::kInt32, SideEffects::None(), dex_pc) { 6587 SetPackedFlag<kFlagIsStringLength>(is_string_length); 6588 // Note that arrays do not change length, so the instruction does not 6589 // depend on any write. 6590 SetRawInputAt(0, array); 6591 } 6592 6593 bool IsClonable() const override { return true; } 6594 bool CanBeMoved() const override { return true; } 6595 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6596 return true; 6597 } 6598 bool CanDoImplicitNullCheckOn(HInstruction* obj) const override { 6599 return obj == InputAt(0); 6600 } 6601 6602 bool IsStringLength() const { return GetPackedFlag<kFlagIsStringLength>(); } 6603 6604 DECLARE_INSTRUCTION(ArrayLength); 6605 6606 protected: 6607 DEFAULT_COPY_CONSTRUCTOR(ArrayLength); 6608 6609 private: 6610 // We treat a String as an array, creating the HArrayLength from String.length() 6611 // or String.isEmpty() intrinsic in the instruction simplifier. We can always 6612 // determine whether a particular HArrayLength is actually a String.length() by 6613 // looking at the type of the input but that requires holding the mutator lock, so 6614 // we prefer to use a flag, so that code generators don't need to do the locking. 6615 static constexpr size_t kFlagIsStringLength = kNumberOfGenericPackedBits; 6616 static constexpr size_t kNumberOfArrayLengthPackedBits = kFlagIsStringLength + 1; 6617 static_assert(kNumberOfArrayLengthPackedBits <= HInstruction::kMaxNumberOfPackedBits, 6618 "Too many packed fields."); 6619 }; 6620 6621 class HBoundsCheck final : public HExpression<2> { 6622 public: 6623 // `HBoundsCheck` can trigger GC, as it may call the `IndexOutOfBoundsException` 6624 // constructor. However it can only do it on a fatal slow path so execution never returns to the 6625 // instruction following the current one; thus 'SideEffects::None()' is used. 6626 HBoundsCheck(HInstruction* index, 6627 HInstruction* length, 6628 uint32_t dex_pc, 6629 bool is_string_char_at = false) 6630 : HExpression(kBoundsCheck, index->GetType(), SideEffects::None(), dex_pc) { 6631 DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(index->GetType())); 6632 SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at); 6633 SetRawInputAt(0, index); 6634 SetRawInputAt(1, length); 6635 } 6636 6637 bool IsClonable() const override { return true; } 6638 bool CanBeMoved() const override { return true; } 6639 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 6640 return true; 6641 } 6642 6643 bool NeedsEnvironment() const override { return true; } 6644 6645 bool CanThrow() const override { return true; } 6646 6647 bool IsStringCharAt() const { return GetPackedFlag<kFlagIsStringCharAt>(); } 6648 6649 HInstruction* GetIndex() const { return InputAt(0); } 6650 6651 DECLARE_INSTRUCTION(BoundsCheck); 6652 6653 protected: 6654 DEFAULT_COPY_CONSTRUCTOR(BoundsCheck); 6655 6656 private: 6657 static constexpr size_t kFlagIsStringCharAt = kNumberOfGenericPackedBits; 6658 static constexpr size_t kNumberOfBoundsCheckPackedBits = kFlagIsStringCharAt + 1; 6659 static_assert(kNumberOfBoundsCheckPackedBits <= HInstruction::kMaxNumberOfPackedBits, 6660 "Too many packed fields."); 6661 }; 6662 6663 class HSuspendCheck final : public HExpression<0> { 6664 public: 6665 explicit HSuspendCheck(uint32_t dex_pc = kNoDexPc, bool is_no_op = false) 6666 : HExpression(kSuspendCheck, SideEffects::CanTriggerGC(), dex_pc), 6667 slow_path_(nullptr) { 6668 SetPackedFlag<kFlagIsNoOp>(is_no_op); 6669 } 6670 6671 bool IsClonable() const override { return true; } 6672 6673 bool NeedsEnvironment() const override { 6674 return true; 6675 } 6676 6677 void SetIsNoOp(bool is_no_op) { SetPackedFlag<kFlagIsNoOp>(is_no_op); } 6678 bool IsNoOp() const { return GetPackedFlag<kFlagIsNoOp>(); } 6679 6680 6681 void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; } 6682 SlowPathCode* GetSlowPath() const { return slow_path_; } 6683 6684 DECLARE_INSTRUCTION(SuspendCheck); 6685 6686 protected: 6687 DEFAULT_COPY_CONSTRUCTOR(SuspendCheck); 6688 6689 // True if the HSuspendCheck should not emit any code during codegen. It is 6690 // not possible to simply remove this instruction to disable codegen, as 6691 // other optimizations (e.g: CHAGuardVisitor::HoistGuard) depend on 6692 // HSuspendCheck being present in every loop. 6693 static constexpr size_t kFlagIsNoOp = kNumberOfGenericPackedBits; 6694 static constexpr size_t kNumberOfSuspendCheckPackedBits = kFlagIsNoOp + 1; 6695 static_assert(kNumberOfSuspendCheckPackedBits <= HInstruction::kMaxNumberOfPackedBits, 6696 "Too many packed fields."); 6697 6698 private: 6699 // Only used for code generation, in order to share the same slow path between back edges 6700 // of a same loop. 6701 SlowPathCode* slow_path_; 6702 }; 6703 6704 // Pseudo-instruction which doesn't generate any code. 6705 // If `emit_environment` is true, it can be used to generate an environment. It is used, for 6706 // example, to provide the native debugger with mapping information. It ensures that we can generate 6707 // line number and local variables at this point. 6708 class HNop : public HExpression<0> { 6709 public: 6710 explicit HNop(uint32_t dex_pc, bool needs_environment) 6711 : HExpression<0>(kNop, SideEffects::None(), dex_pc), needs_environment_(needs_environment) { 6712 } 6713 6714 bool NeedsEnvironment() const override { 6715 return needs_environment_; 6716 } 6717 6718 DECLARE_INSTRUCTION(Nop); 6719 6720 protected: 6721 DEFAULT_COPY_CONSTRUCTOR(Nop); 6722 6723 private: 6724 bool needs_environment_; 6725 }; 6726 6727 /** 6728 * Instruction to load a Class object. 6729 */ 6730 class HLoadClass final : public HInstruction { 6731 public: 6732 // Determines how to load the Class. 6733 enum class LoadKind { 6734 // We cannot load this class. See HSharpening::SharpenLoadClass. 6735 kInvalid = -1, 6736 6737 // Use the Class* from the method's own ArtMethod*. 6738 kReferrersClass, 6739 6740 // Use PC-relative boot image Class* address that will be known at link time. 6741 // Used for boot image classes referenced by boot image code. 6742 kBootImageLinkTimePcRelative, 6743 6744 // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load. 6745 // Used for boot image classes referenced by apps in AOT-compiled code. 6746 kBootImageRelRo, 6747 6748 // Load from an app image entry in the .data.img.rel.ro using a PC-relative load. 6749 // Used for app image classes referenced by apps in AOT-compiled code. 6750 kAppImageRelRo, 6751 6752 // Load from an entry in the .bss section using a PC-relative load. 6753 // Used for classes outside boot image referenced by AOT-compiled app and boot image code. 6754 kBssEntry, 6755 6756 // Load from an entry for public class in the .bss section using a PC-relative load. 6757 // Used for classes that were unresolved during AOT-compilation outside the literal 6758 // package of the compiling class. Such classes are accessible only if they are public 6759 // and the .bss entry shall therefore be filled only if the resolved class is public. 6760 kBssEntryPublic, 6761 6762 // Load from an entry for package class in the .bss section using a PC-relative load. 6763 // Used for classes that were unresolved during AOT-compilation but within the literal 6764 // package of the compiling class. Such classes are accessible if they are public or 6765 // in the same package which, given the literal package match, requires only matching 6766 // defining class loader and the .bss entry shall therefore be filled only if at least 6767 // one of those conditions holds. Note that all code in an oat file belongs to classes 6768 // with the same defining class loader. 6769 kBssEntryPackage, 6770 6771 // Use a known boot image Class* address, embedded in the code by the codegen. 6772 // Used for boot image classes referenced by apps in JIT-compiled code. 6773 kJitBootImageAddress, 6774 6775 // Load from the root table associated with the JIT compiled method. 6776 kJitTableAddress, 6777 6778 // Load using a simple runtime call. This is the fall-back load kind when 6779 // the codegen is unable to use another appropriate kind. 6780 kRuntimeCall, 6781 6782 kLast = kRuntimeCall 6783 }; 6784 6785 HLoadClass(HCurrentMethod* current_method, 6786 dex::TypeIndex type_index, 6787 const DexFile& dex_file, 6788 Handle<mirror::Class> klass, 6789 bool is_referrers_class, 6790 uint32_t dex_pc, 6791 bool needs_access_check) 6792 : HInstruction(kLoadClass, 6793 DataType::Type::kReference, 6794 SideEffectsForArchRuntimeCalls(), 6795 dex_pc), 6796 special_input_(HUserRecord<HInstruction*>(current_method)), 6797 type_index_(type_index), 6798 dex_file_(dex_file), 6799 klass_(klass) { 6800 // Referrers class should not need access check. We never inline unverified 6801 // methods so we can't possibly end up in this situation. 6802 DCHECK_IMPLIES(is_referrers_class, !needs_access_check); 6803 6804 SetPackedField<LoadKindField>( 6805 is_referrers_class ? LoadKind::kReferrersClass : LoadKind::kRuntimeCall); 6806 SetPackedFlag<kFlagNeedsAccessCheck>(needs_access_check); 6807 SetPackedFlag<kFlagIsInImage>(false); 6808 SetPackedFlag<kFlagGenerateClInitCheck>(false); 6809 SetPackedFlag<kFlagValidLoadedClassRTI>(false); 6810 } 6811 6812 bool IsClonable() const override { return true; } 6813 6814 void SetLoadKind(LoadKind load_kind); 6815 6816 LoadKind GetLoadKind() const { 6817 return GetPackedField<LoadKindField>(); 6818 } 6819 6820 bool HasPcRelativeLoadKind() const { 6821 return GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative || 6822 GetLoadKind() == LoadKind::kBootImageRelRo || 6823 GetLoadKind() == LoadKind::kAppImageRelRo || 6824 GetLoadKind() == LoadKind::kBssEntry || 6825 GetLoadKind() == LoadKind::kBssEntryPublic || 6826 GetLoadKind() == LoadKind::kBssEntryPackage; 6827 } 6828 6829 bool CanBeMoved() const override { return true; } 6830 6831 bool InstructionDataEquals(const HInstruction* other) const override; 6832 6833 size_t ComputeHashCode() const override { return type_index_.index_; } 6834 6835 bool CanBeNull() const override { return false; } 6836 6837 bool NeedsEnvironment() const override { 6838 return CanCallRuntime(); 6839 } 6840 bool NeedsBss() const override { 6841 LoadKind load_kind = GetLoadKind(); 6842 return load_kind == LoadKind::kBssEntry || 6843 load_kind == LoadKind::kBssEntryPublic || 6844 load_kind == LoadKind::kBssEntryPackage; 6845 } 6846 6847 void SetMustGenerateClinitCheck(bool generate_clinit_check) { 6848 SetPackedFlag<kFlagGenerateClInitCheck>(generate_clinit_check); 6849 } 6850 6851 bool CanCallRuntime() const { 6852 return NeedsAccessCheck() || 6853 MustGenerateClinitCheck() || 6854 NeedsBss() || 6855 GetLoadKind() == LoadKind::kRuntimeCall; 6856 } 6857 6858 bool CanThrow() const override { 6859 return NeedsAccessCheck() || 6860 MustGenerateClinitCheck() || 6861 // If the class is in the boot or app image, the lookup in the runtime call cannot throw. 6862 ((GetLoadKind() == LoadKind::kRuntimeCall || NeedsBss()) && !IsInImage()); 6863 } 6864 6865 ReferenceTypeInfo GetLoadedClassRTI() { 6866 if (GetPackedFlag<kFlagValidLoadedClassRTI>()) { 6867 // Note: The is_exact flag from the return value should not be used. 6868 return ReferenceTypeInfo::CreateUnchecked(klass_, /* is_exact= */ true); 6869 } else { 6870 return ReferenceTypeInfo::CreateInvalid(); 6871 } 6872 } 6873 6874 // Loaded class RTI is marked as valid by RTP if the klass_ is admissible. 6875 void SetValidLoadedClassRTI() { 6876 DCHECK(klass_ != nullptr); 6877 SetPackedFlag<kFlagValidLoadedClassRTI>(true); 6878 } 6879 6880 dex::TypeIndex GetTypeIndex() const { return type_index_; } 6881 const DexFile& GetDexFile() const { return dex_file_; } 6882 6883 static SideEffects SideEffectsForArchRuntimeCalls() { 6884 return SideEffects::CanTriggerGC(); 6885 } 6886 6887 bool IsReferrersClass() const { return GetLoadKind() == LoadKind::kReferrersClass; } 6888 bool NeedsAccessCheck() const { return GetPackedFlag<kFlagNeedsAccessCheck>(); } 6889 bool IsInImage() const { return GetPackedFlag<kFlagIsInImage>(); } 6890 bool MustGenerateClinitCheck() const { return GetPackedFlag<kFlagGenerateClInitCheck>(); } 6891 6892 bool MustResolveTypeOnSlowPath() const { 6893 // Check that this instruction has a slow path. 6894 LoadKind load_kind = GetLoadKind(); 6895 DCHECK(load_kind != LoadKind::kRuntimeCall); // kRuntimeCall calls on main path. 6896 bool must_resolve_type_on_slow_path = 6897 load_kind == LoadKind::kBssEntry || 6898 load_kind == LoadKind::kBssEntryPublic || 6899 load_kind == LoadKind::kBssEntryPackage; 6900 DCHECK(must_resolve_type_on_slow_path || MustGenerateClinitCheck()); 6901 return must_resolve_type_on_slow_path; 6902 } 6903 6904 void MarkInImage() { 6905 SetPackedFlag<kFlagIsInImage>(true); 6906 } 6907 6908 void AddSpecialInput(HInstruction* special_input); 6909 6910 using HInstruction::GetInputRecords; // Keep the const version visible. 6911 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 6912 return ArrayRef<HUserRecord<HInstruction*>>( 6913 &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u); 6914 } 6915 6916 Handle<mirror::Class> GetClass() const { 6917 return klass_; 6918 } 6919 6920 DECLARE_INSTRUCTION(LoadClass); 6921 6922 protected: 6923 DEFAULT_COPY_CONSTRUCTOR(LoadClass); 6924 6925 private: 6926 static constexpr size_t kFlagNeedsAccessCheck = kNumberOfGenericPackedBits; 6927 // Whether the type is in an image (boot image or app image). 6928 static constexpr size_t kFlagIsInImage = kFlagNeedsAccessCheck + 1; 6929 // Whether this instruction must generate the initialization check. 6930 // Used for code generation. 6931 static constexpr size_t kFlagGenerateClInitCheck = kFlagIsInImage + 1; 6932 static constexpr size_t kFieldLoadKind = kFlagGenerateClInitCheck + 1; 6933 static constexpr size_t kFieldLoadKindSize = 6934 MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast)); 6935 static constexpr size_t kFlagValidLoadedClassRTI = kFieldLoadKind + kFieldLoadKindSize; 6936 static constexpr size_t kNumberOfLoadClassPackedBits = kFlagValidLoadedClassRTI + 1; 6937 static_assert(kNumberOfLoadClassPackedBits < kMaxNumberOfPackedBits, "Too many packed fields."); 6938 using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>; 6939 6940 static bool HasTypeReference(LoadKind load_kind) { 6941 return load_kind == LoadKind::kReferrersClass || 6942 load_kind == LoadKind::kBootImageLinkTimePcRelative || 6943 load_kind == LoadKind::kAppImageRelRo || 6944 load_kind == LoadKind::kBssEntry || 6945 load_kind == LoadKind::kBssEntryPublic || 6946 load_kind == LoadKind::kBssEntryPackage || 6947 load_kind == LoadKind::kRuntimeCall; 6948 } 6949 6950 void SetLoadKindInternal(LoadKind load_kind); 6951 6952 // The special input is the HCurrentMethod for kRuntimeCall or kReferrersClass. 6953 // For other load kinds it's empty or possibly some architecture-specific instruction 6954 // for PC-relative loads, i.e. kBssEntry* or kBootImageLinkTimePcRelative. 6955 HUserRecord<HInstruction*> special_input_; 6956 6957 // A type index and dex file where the class can be accessed. The dex file can be: 6958 // - The compiling method's dex file if the class is defined there too. 6959 // - The compiling method's dex file if the class is referenced there. 6960 // - The dex file where the class is defined. When the load kind can only be 6961 // kBssEntry* or kRuntimeCall, we cannot emit code for this `HLoadClass`. 6962 const dex::TypeIndex type_index_; 6963 const DexFile& dex_file_; 6964 6965 Handle<mirror::Class> klass_; 6966 }; 6967 std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs); 6968 6969 // Note: defined outside class to see operator<<(., HLoadClass::LoadKind). 6970 inline void HLoadClass::SetLoadKind(LoadKind load_kind) { 6971 // The load kind should be determined before inserting the instruction to the graph. 6972 DCHECK(GetBlock() == nullptr); 6973 DCHECK(GetEnvironment() == nullptr); 6974 SetPackedField<LoadKindField>(load_kind); 6975 if (load_kind != LoadKind::kRuntimeCall && load_kind != LoadKind::kReferrersClass) { 6976 special_input_ = HUserRecord<HInstruction*>(nullptr); 6977 } 6978 if (!NeedsEnvironment()) { 6979 SetSideEffects(SideEffects::None()); 6980 } 6981 } 6982 6983 // Note: defined outside class to see operator<<(., HLoadClass::LoadKind). 6984 inline void HLoadClass::AddSpecialInput(HInstruction* special_input) { 6985 // The special input is used for PC-relative loads on some architectures, 6986 // including literal pool loads, which are PC-relative too. 6987 DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative || 6988 GetLoadKind() == LoadKind::kBootImageRelRo || 6989 GetLoadKind() == LoadKind::kAppImageRelRo || 6990 GetLoadKind() == LoadKind::kBssEntry || 6991 GetLoadKind() == LoadKind::kBssEntryPublic || 6992 GetLoadKind() == LoadKind::kBssEntryPackage || 6993 GetLoadKind() == LoadKind::kJitBootImageAddress) << GetLoadKind(); 6994 DCHECK(special_input_.GetInstruction() == nullptr); 6995 special_input_ = HUserRecord<HInstruction*>(special_input); 6996 special_input->AddUseAt(this, 0); 6997 } 6998 6999 class HLoadString final : public HInstruction { 7000 public: 7001 // Determines how to load the String. 7002 enum class LoadKind { 7003 // Use PC-relative boot image String* address that will be known at link time. 7004 // Used for boot image strings referenced by boot image code. 7005 kBootImageLinkTimePcRelative, 7006 7007 // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load. 7008 // Used for boot image strings referenced by apps in AOT-compiled code. 7009 kBootImageRelRo, 7010 7011 // Load from an entry in the .bss section using a PC-relative load. 7012 // Used for strings outside boot image referenced by AOT-compiled app and boot image code. 7013 kBssEntry, 7014 7015 // Use a known boot image String* address, embedded in the code by the codegen. 7016 // Used for boot image strings referenced by apps in JIT-compiled code. 7017 kJitBootImageAddress, 7018 7019 // Load from the root table associated with the JIT compiled method. 7020 kJitTableAddress, 7021 7022 // Load using a simple runtime call. This is the fall-back load kind when 7023 // the codegen is unable to use another appropriate kind. 7024 kRuntimeCall, 7025 7026 kLast = kRuntimeCall, 7027 }; 7028 7029 HLoadString(HCurrentMethod* current_method, 7030 dex::StringIndex string_index, 7031 const DexFile& dex_file, 7032 uint32_t dex_pc) 7033 : HInstruction(kLoadString, 7034 DataType::Type::kReference, 7035 SideEffectsForArchRuntimeCalls(), 7036 dex_pc), 7037 special_input_(HUserRecord<HInstruction*>(current_method)), 7038 string_index_(string_index), 7039 dex_file_(dex_file) { 7040 SetPackedField<LoadKindField>(LoadKind::kRuntimeCall); 7041 } 7042 7043 bool IsClonable() const override { return true; } 7044 bool NeedsBss() const override { 7045 return GetLoadKind() == LoadKind::kBssEntry; 7046 } 7047 7048 void SetLoadKind(LoadKind load_kind); 7049 7050 LoadKind GetLoadKind() const { 7051 return GetPackedField<LoadKindField>(); 7052 } 7053 7054 bool HasPcRelativeLoadKind() const { 7055 return GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative || 7056 GetLoadKind() == LoadKind::kBootImageRelRo || 7057 GetLoadKind() == LoadKind::kBssEntry; 7058 } 7059 7060 const DexFile& GetDexFile() const { 7061 return dex_file_; 7062 } 7063 7064 dex::StringIndex GetStringIndex() const { 7065 return string_index_; 7066 } 7067 7068 Handle<mirror::String> GetString() const { 7069 return string_; 7070 } 7071 7072 void SetString(Handle<mirror::String> str) { 7073 string_ = str; 7074 } 7075 7076 bool CanBeMoved() const override { return true; } 7077 7078 bool InstructionDataEquals(const HInstruction* other) const override; 7079 7080 size_t ComputeHashCode() const override { return string_index_.index_; } 7081 7082 // Will call the runtime if we need to load the string through 7083 // the dex cache and the string is not guaranteed to be there yet. 7084 bool NeedsEnvironment() const override { 7085 LoadKind load_kind = GetLoadKind(); 7086 if (load_kind == LoadKind::kBootImageLinkTimePcRelative || 7087 load_kind == LoadKind::kBootImageRelRo || 7088 load_kind == LoadKind::kJitBootImageAddress || 7089 load_kind == LoadKind::kJitTableAddress) { 7090 return false; 7091 } 7092 return true; 7093 } 7094 7095 bool CanBeNull() const override { return false; } 7096 bool CanThrow() const override { return NeedsEnvironment(); } 7097 7098 static SideEffects SideEffectsForArchRuntimeCalls() { 7099 return SideEffects::CanTriggerGC(); 7100 } 7101 7102 void AddSpecialInput(HInstruction* special_input); 7103 7104 using HInstruction::GetInputRecords; // Keep the const version visible. 7105 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 7106 return ArrayRef<HUserRecord<HInstruction*>>( 7107 &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u); 7108 } 7109 7110 DECLARE_INSTRUCTION(LoadString); 7111 7112 protected: 7113 DEFAULT_COPY_CONSTRUCTOR(LoadString); 7114 7115 private: 7116 static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits; 7117 static constexpr size_t kFieldLoadKindSize = 7118 MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast)); 7119 static constexpr size_t kNumberOfLoadStringPackedBits = kFieldLoadKind + kFieldLoadKindSize; 7120 static_assert(kNumberOfLoadStringPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 7121 using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>; 7122 7123 void SetLoadKindInternal(LoadKind load_kind); 7124 7125 // The special input is the HCurrentMethod for kRuntimeCall. 7126 // For other load kinds it's empty or possibly some architecture-specific instruction 7127 // for PC-relative loads, i.e. kBssEntry or kBootImageLinkTimePcRelative. 7128 HUserRecord<HInstruction*> special_input_; 7129 7130 dex::StringIndex string_index_; 7131 const DexFile& dex_file_; 7132 7133 Handle<mirror::String> string_; 7134 }; 7135 std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); 7136 7137 // Note: defined outside class to see operator<<(., HLoadString::LoadKind). 7138 inline void HLoadString::SetLoadKind(LoadKind load_kind) { 7139 // The load kind should be determined before inserting the instruction to the graph. 7140 DCHECK(GetBlock() == nullptr); 7141 DCHECK(GetEnvironment() == nullptr); 7142 DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); 7143 SetPackedField<LoadKindField>(load_kind); 7144 if (load_kind != LoadKind::kRuntimeCall) { 7145 special_input_ = HUserRecord<HInstruction*>(nullptr); 7146 } 7147 if (!NeedsEnvironment()) { 7148 SetSideEffects(SideEffects::None()); 7149 } 7150 } 7151 7152 // Note: defined outside class to see operator<<(., HLoadString::LoadKind). 7153 inline void HLoadString::AddSpecialInput(HInstruction* special_input) { 7154 // The special input is used for PC-relative loads on some architectures, 7155 // including literal pool loads, which are PC-relative too. 7156 DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative || 7157 GetLoadKind() == LoadKind::kBootImageRelRo || 7158 GetLoadKind() == LoadKind::kBssEntry || 7159 GetLoadKind() == LoadKind::kJitBootImageAddress) << GetLoadKind(); 7160 // HLoadString::GetInputRecords() returns an empty array at this point, 7161 // so use the GetInputRecords() from the base class to set the input record. 7162 DCHECK(special_input_.GetInstruction() == nullptr); 7163 special_input_ = HUserRecord<HInstruction*>(special_input); 7164 special_input->AddUseAt(this, 0); 7165 } 7166 7167 class HLoadMethodHandle final : public HInstruction { 7168 public: 7169 HLoadMethodHandle(HCurrentMethod* current_method, 7170 uint16_t method_handle_idx, 7171 const DexFile& dex_file, 7172 uint32_t dex_pc) 7173 : HInstruction(kLoadMethodHandle, 7174 DataType::Type::kReference, 7175 SideEffectsForArchRuntimeCalls(), 7176 dex_pc), 7177 special_input_(HUserRecord<HInstruction*>(current_method)), 7178 method_handle_idx_(method_handle_idx), 7179 dex_file_(dex_file) { 7180 } 7181 7182 using HInstruction::GetInputRecords; // Keep the const version visible. 7183 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 7184 return ArrayRef<HUserRecord<HInstruction*>>( 7185 &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u); 7186 } 7187 7188 bool IsClonable() const override { return true; } 7189 7190 uint16_t GetMethodHandleIndex() const { return method_handle_idx_; } 7191 7192 const DexFile& GetDexFile() const { return dex_file_; } 7193 7194 static SideEffects SideEffectsForArchRuntimeCalls() { 7195 return SideEffects::CanTriggerGC(); 7196 } 7197 7198 bool CanThrow() const override { return true; } 7199 7200 bool NeedsEnvironment() const override { return true; } 7201 7202 DECLARE_INSTRUCTION(LoadMethodHandle); 7203 7204 protected: 7205 DEFAULT_COPY_CONSTRUCTOR(LoadMethodHandle); 7206 7207 private: 7208 // The special input is the HCurrentMethod for kRuntimeCall. 7209 HUserRecord<HInstruction*> special_input_; 7210 7211 const uint16_t method_handle_idx_; 7212 const DexFile& dex_file_; 7213 }; 7214 7215 class HLoadMethodType final : public HInstruction { 7216 public: 7217 // Determines how to load the MethodType. 7218 enum class LoadKind { 7219 // Load from an entry in the .bss section using a PC-relative load. 7220 kBssEntry, 7221 // Load using a single runtime call. 7222 kRuntimeCall, 7223 7224 kLast = kRuntimeCall, 7225 }; 7226 7227 HLoadMethodType(HCurrentMethod* current_method, 7228 dex::ProtoIndex proto_index, 7229 const DexFile& dex_file, 7230 uint32_t dex_pc) 7231 : HInstruction(kLoadMethodType, 7232 DataType::Type::kReference, 7233 SideEffectsForArchRuntimeCalls(), 7234 dex_pc), 7235 special_input_(HUserRecord<HInstruction*>(current_method)), 7236 proto_index_(proto_index), 7237 dex_file_(dex_file) { 7238 SetPackedField<LoadKindField>(LoadKind::kRuntimeCall); 7239 } 7240 7241 using HInstruction::GetInputRecords; // Keep the const version visible. 7242 ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final { 7243 return ArrayRef<HUserRecord<HInstruction*>>( 7244 &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u); 7245 } 7246 7247 bool IsClonable() const override { return true; } 7248 7249 void SetLoadKind(LoadKind load_kind); 7250 7251 LoadKind GetLoadKind() const { 7252 return GetPackedField<LoadKindField>(); 7253 } 7254 7255 dex::ProtoIndex GetProtoIndex() const { return proto_index_; } 7256 7257 const DexFile& GetDexFile() const { return dex_file_; } 7258 7259 static SideEffects SideEffectsForArchRuntimeCalls() { 7260 return SideEffects::CanTriggerGC(); 7261 } 7262 7263 bool CanThrow() const override { return true; } 7264 7265 bool NeedsEnvironment() const override { return true; } 7266 7267 DECLARE_INSTRUCTION(LoadMethodType); 7268 7269 protected: 7270 DEFAULT_COPY_CONSTRUCTOR(LoadMethodType); 7271 7272 private: 7273 static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits; 7274 static constexpr size_t kFieldLoadKindSize = 7275 MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast)); 7276 static constexpr size_t kNumberOfLoadMethodTypePackedBits = kFieldLoadKind + kFieldLoadKindSize; 7277 static_assert(kNumberOfLoadMethodTypePackedBits <= kMaxNumberOfPackedBits, 7278 "Too many packed fields."); 7279 using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>; 7280 7281 // The special input is the HCurrentMethod for kRuntimeCall. 7282 HUserRecord<HInstruction*> special_input_; 7283 7284 const dex::ProtoIndex proto_index_; 7285 const DexFile& dex_file_; 7286 }; 7287 7288 std::ostream& operator<<(std::ostream& os, HLoadMethodType::LoadKind rhs); 7289 7290 // Note: defined outside class to see operator<<(., HLoadMethodType::LoadKind). 7291 inline void HLoadMethodType::SetLoadKind(LoadKind load_kind) { 7292 // The load kind should be determined before inserting the instruction to the graph. 7293 DCHECK(GetBlock() == nullptr); 7294 DCHECK(GetEnvironment() == nullptr); 7295 DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall); 7296 SetPackedField<LoadKindField>(load_kind); 7297 } 7298 7299 /** 7300 * Performs an initialization check on its Class object input. 7301 */ 7302 class HClinitCheck final : public HExpression<1> { 7303 public: 7304 HClinitCheck(HLoadClass* constant, uint32_t dex_pc) 7305 : HExpression( 7306 kClinitCheck, 7307 DataType::Type::kReference, 7308 SideEffects::AllExceptGCDependency(), // Assume write/read on all fields/arrays. 7309 dex_pc) { 7310 SetRawInputAt(0, constant); 7311 } 7312 // TODO: Make ClinitCheck clonable. 7313 bool CanBeMoved() const override { return true; } 7314 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 7315 return true; 7316 } 7317 7318 bool NeedsEnvironment() const override { 7319 // May call runtime to initialize the class. 7320 return true; 7321 } 7322 7323 bool CanThrow() const override { return true; } 7324 7325 HLoadClass* GetLoadClass() const { 7326 DCHECK(InputAt(0)->IsLoadClass()); 7327 return InputAt(0)->AsLoadClass(); 7328 } 7329 7330 DECLARE_INSTRUCTION(ClinitCheck); 7331 7332 7333 protected: 7334 DEFAULT_COPY_CONSTRUCTOR(ClinitCheck); 7335 }; 7336 7337 class HStaticFieldGet final : public HExpression<1> { 7338 public: 7339 HStaticFieldGet(HInstruction* cls, 7340 ArtField* field, 7341 DataType::Type field_type, 7342 MemberOffset field_offset, 7343 bool is_volatile, 7344 uint32_t field_idx, 7345 uint16_t declaring_class_def_index, 7346 const DexFile& dex_file, 7347 uint32_t dex_pc) 7348 : HExpression(kStaticFieldGet, 7349 field_type, 7350 SideEffects::FieldReadOfType(field_type, is_volatile), 7351 dex_pc), 7352 field_info_(field, 7353 field_offset, 7354 field_type, 7355 is_volatile, 7356 field_idx, 7357 declaring_class_def_index, 7358 dex_file) { 7359 SetRawInputAt(0, cls); 7360 } 7361 7362 7363 bool IsClonable() const override { return true; } 7364 bool CanBeMoved() const override { return !IsVolatile(); } 7365 7366 bool InstructionDataEquals(const HInstruction* other) const override { 7367 const HStaticFieldGet* other_get = other->AsStaticFieldGet(); 7368 return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue(); 7369 } 7370 7371 size_t ComputeHashCode() const override { 7372 return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue(); 7373 } 7374 7375 bool IsFieldAccess() const override { return true; } 7376 const FieldInfo& GetFieldInfo() const override { return field_info_; } 7377 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 7378 DataType::Type GetFieldType() const { return field_info_.GetFieldType(); } 7379 bool IsVolatile() const { return field_info_.IsVolatile(); } 7380 7381 void SetType(DataType::Type new_type) { 7382 DCHECK(DataType::IsIntegralType(GetType())); 7383 DCHECK(DataType::IsIntegralType(new_type)); 7384 DCHECK_EQ(DataType::Size(GetType()), DataType::Size(new_type)); 7385 SetPackedField<TypeField>(new_type); 7386 } 7387 7388 DECLARE_INSTRUCTION(StaticFieldGet); 7389 7390 protected: 7391 DEFAULT_COPY_CONSTRUCTOR(StaticFieldGet); 7392 7393 private: 7394 const FieldInfo field_info_; 7395 }; 7396 7397 class HStaticFieldSet final : public HExpression<2> { 7398 public: 7399 HStaticFieldSet(HInstruction* cls, 7400 HInstruction* value, 7401 ArtField* field, 7402 DataType::Type field_type, 7403 MemberOffset field_offset, 7404 bool is_volatile, 7405 uint32_t field_idx, 7406 uint16_t declaring_class_def_index, 7407 const DexFile& dex_file, 7408 uint32_t dex_pc) 7409 : HExpression(kStaticFieldSet, 7410 SideEffects::FieldWriteOfType(field_type, is_volatile), 7411 dex_pc), 7412 field_info_(field, 7413 field_offset, 7414 field_type, 7415 is_volatile, 7416 field_idx, 7417 declaring_class_def_index, 7418 dex_file) { 7419 SetPackedFlag<kFlagValueCanBeNull>(true); 7420 SetPackedField<WriteBarrierKindField>(WriteBarrierKind::kEmitNotBeingReliedOn); 7421 SetRawInputAt(0, cls); 7422 SetRawInputAt(1, value); 7423 } 7424 7425 bool IsClonable() const override { return true; } 7426 bool IsFieldAccess() const override { return true; } 7427 const FieldInfo& GetFieldInfo() const override { return field_info_; } 7428 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 7429 DataType::Type GetFieldType() const { return field_info_.GetFieldType(); } 7430 bool IsVolatile() const { return field_info_.IsVolatile(); } 7431 7432 HInstruction* GetValue() const { return InputAt(1); } 7433 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 7434 void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } 7435 7436 WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); } 7437 void SetWriteBarrierKind(WriteBarrierKind kind) { 7438 DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn) 7439 << "We shouldn't go back to the original value."; 7440 DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit, 7441 GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn) 7442 << "If a write barrier was relied on by other write barriers, we cannot skip emitting it."; 7443 SetPackedField<WriteBarrierKindField>(kind); 7444 } 7445 7446 DECLARE_INSTRUCTION(StaticFieldSet); 7447 7448 protected: 7449 DEFAULT_COPY_CONSTRUCTOR(StaticFieldSet); 7450 7451 private: 7452 static constexpr size_t kFlagValueCanBeNull = kNumberOfGenericPackedBits; 7453 static constexpr size_t kWriteBarrierKind = kFlagValueCanBeNull + 1; 7454 static constexpr size_t kWriteBarrierKindSize = 7455 MinimumBitsToStore(static_cast<size_t>(WriteBarrierKind::kLast)); 7456 static constexpr size_t kNumberOfStaticFieldSetPackedBits = 7457 kWriteBarrierKind + kWriteBarrierKindSize; 7458 static_assert(kNumberOfStaticFieldSetPackedBits <= kMaxNumberOfPackedBits, 7459 "Too many packed fields."); 7460 7461 const FieldInfo field_info_; 7462 using WriteBarrierKindField = 7463 BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>; 7464 }; 7465 7466 class HStringBuilderAppend final : public HVariableInputSizeInstruction { 7467 public: 7468 HStringBuilderAppend(HIntConstant* format, 7469 uint32_t number_of_arguments, 7470 bool has_fp_args, 7471 ArenaAllocator* allocator, 7472 uint32_t dex_pc) 7473 : HVariableInputSizeInstruction( 7474 kStringBuilderAppend, 7475 DataType::Type::kReference, 7476 SideEffects::CanTriggerGC().Union( 7477 // The runtime call may read memory from inputs. It never writes outside 7478 // of the newly allocated result object or newly allocated helper objects, 7479 // except for float/double arguments where we reuse thread-local helper objects. 7480 has_fp_args ? SideEffects::AllWritesAndReads() : SideEffects::AllReads()), 7481 dex_pc, 7482 allocator, 7483 number_of_arguments + /* format */ 1u, 7484 kArenaAllocInvokeInputs) { 7485 DCHECK_GE(number_of_arguments, 1u); // There must be something to append. 7486 SetRawInputAt(FormatIndex(), format); 7487 } 7488 7489 void SetArgumentAt(size_t index, HInstruction* argument) { 7490 DCHECK_LE(index, GetNumberOfArguments()); 7491 SetRawInputAt(index, argument); 7492 } 7493 7494 // Return the number of arguments, excluding the format. 7495 size_t GetNumberOfArguments() const { 7496 DCHECK_GE(InputCount(), 1u); 7497 return InputCount() - 1u; 7498 } 7499 7500 size_t FormatIndex() const { 7501 return GetNumberOfArguments(); 7502 } 7503 7504 HIntConstant* GetFormat() { 7505 return InputAt(FormatIndex())->AsIntConstant(); 7506 } 7507 7508 bool NeedsEnvironment() const override { return true; } 7509 7510 bool CanThrow() const override { return true; } 7511 7512 bool CanBeNull() const override { return false; } 7513 7514 DECLARE_INSTRUCTION(StringBuilderAppend); 7515 7516 protected: 7517 DEFAULT_COPY_CONSTRUCTOR(StringBuilderAppend); 7518 }; 7519 7520 class HUnresolvedInstanceFieldGet final : public HExpression<1> { 7521 public: 7522 HUnresolvedInstanceFieldGet(HInstruction* obj, 7523 DataType::Type field_type, 7524 uint32_t field_index, 7525 uint32_t dex_pc) 7526 : HExpression(kUnresolvedInstanceFieldGet, 7527 field_type, 7528 SideEffects::AllExceptGCDependency(), 7529 dex_pc), 7530 field_index_(field_index) { 7531 SetRawInputAt(0, obj); 7532 } 7533 7534 bool IsClonable() const override { return true; } 7535 bool NeedsEnvironment() const override { return true; } 7536 bool CanThrow() const override { return true; } 7537 7538 DataType::Type GetFieldType() const { return GetType(); } 7539 uint32_t GetFieldIndex() const { return field_index_; } 7540 7541 DECLARE_INSTRUCTION(UnresolvedInstanceFieldGet); 7542 7543 protected: 7544 DEFAULT_COPY_CONSTRUCTOR(UnresolvedInstanceFieldGet); 7545 7546 private: 7547 const uint32_t field_index_; 7548 }; 7549 7550 class HUnresolvedInstanceFieldSet final : public HExpression<2> { 7551 public: 7552 HUnresolvedInstanceFieldSet(HInstruction* obj, 7553 HInstruction* value, 7554 DataType::Type field_type, 7555 uint32_t field_index, 7556 uint32_t dex_pc) 7557 : HExpression(kUnresolvedInstanceFieldSet, SideEffects::AllExceptGCDependency(), dex_pc), 7558 field_index_(field_index) { 7559 SetPackedField<FieldTypeField>(field_type); 7560 DCHECK_EQ(DataType::Kind(field_type), DataType::Kind(value->GetType())); 7561 SetRawInputAt(0, obj); 7562 SetRawInputAt(1, value); 7563 } 7564 7565 bool IsClonable() const override { return true; } 7566 bool NeedsEnvironment() const override { return true; } 7567 bool CanThrow() const override { return true; } 7568 7569 DataType::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); } 7570 uint32_t GetFieldIndex() const { return field_index_; } 7571 7572 DECLARE_INSTRUCTION(UnresolvedInstanceFieldSet); 7573 7574 protected: 7575 DEFAULT_COPY_CONSTRUCTOR(UnresolvedInstanceFieldSet); 7576 7577 private: 7578 static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits; 7579 static constexpr size_t kFieldFieldTypeSize = 7580 MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast)); 7581 static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits = 7582 kFieldFieldType + kFieldFieldTypeSize; 7583 static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits, 7584 "Too many packed fields."); 7585 using FieldTypeField = BitField<DataType::Type, kFieldFieldType, kFieldFieldTypeSize>; 7586 7587 const uint32_t field_index_; 7588 }; 7589 7590 class HUnresolvedStaticFieldGet final : public HExpression<0> { 7591 public: 7592 HUnresolvedStaticFieldGet(DataType::Type field_type, 7593 uint32_t field_index, 7594 uint32_t dex_pc) 7595 : HExpression(kUnresolvedStaticFieldGet, 7596 field_type, 7597 SideEffects::AllExceptGCDependency(), 7598 dex_pc), 7599 field_index_(field_index) { 7600 } 7601 7602 bool IsClonable() const override { return true; } 7603 bool NeedsEnvironment() const override { return true; } 7604 bool CanThrow() const override { return true; } 7605 7606 DataType::Type GetFieldType() const { return GetType(); } 7607 uint32_t GetFieldIndex() const { return field_index_; } 7608 7609 DECLARE_INSTRUCTION(UnresolvedStaticFieldGet); 7610 7611 protected: 7612 DEFAULT_COPY_CONSTRUCTOR(UnresolvedStaticFieldGet); 7613 7614 private: 7615 const uint32_t field_index_; 7616 }; 7617 7618 class HUnresolvedStaticFieldSet final : public HExpression<1> { 7619 public: 7620 HUnresolvedStaticFieldSet(HInstruction* value, 7621 DataType::Type field_type, 7622 uint32_t field_index, 7623 uint32_t dex_pc) 7624 : HExpression(kUnresolvedStaticFieldSet, SideEffects::AllExceptGCDependency(), dex_pc), 7625 field_index_(field_index) { 7626 SetPackedField<FieldTypeField>(field_type); 7627 DCHECK_EQ(DataType::Kind(field_type), DataType::Kind(value->GetType())); 7628 SetRawInputAt(0, value); 7629 } 7630 7631 bool IsClonable() const override { return true; } 7632 bool NeedsEnvironment() const override { return true; } 7633 bool CanThrow() const override { return true; } 7634 7635 DataType::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); } 7636 uint32_t GetFieldIndex() const { return field_index_; } 7637 7638 DECLARE_INSTRUCTION(UnresolvedStaticFieldSet); 7639 7640 protected: 7641 DEFAULT_COPY_CONSTRUCTOR(UnresolvedStaticFieldSet); 7642 7643 private: 7644 static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits; 7645 static constexpr size_t kFieldFieldTypeSize = 7646 MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast)); 7647 static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits = 7648 kFieldFieldType + kFieldFieldTypeSize; 7649 static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits, 7650 "Too many packed fields."); 7651 using FieldTypeField = BitField<DataType::Type, kFieldFieldType, kFieldFieldTypeSize>; 7652 7653 const uint32_t field_index_; 7654 }; 7655 7656 // Implement the move-exception DEX instruction. 7657 class HLoadException final : public HExpression<0> { 7658 public: 7659 explicit HLoadException(uint32_t dex_pc = kNoDexPc) 7660 : HExpression(kLoadException, DataType::Type::kReference, SideEffects::None(), dex_pc) { 7661 } 7662 7663 bool CanBeNull() const override { return false; } 7664 7665 DECLARE_INSTRUCTION(LoadException); 7666 7667 protected: 7668 DEFAULT_COPY_CONSTRUCTOR(LoadException); 7669 }; 7670 7671 // Implicit part of move-exception which clears thread-local exception storage. 7672 // Must not be removed because the runtime expects the TLS to get cleared. 7673 class HClearException final : public HExpression<0> { 7674 public: 7675 explicit HClearException(uint32_t dex_pc = kNoDexPc) 7676 : HExpression(kClearException, SideEffects::AllWrites(), dex_pc) { 7677 } 7678 7679 DECLARE_INSTRUCTION(ClearException); 7680 7681 protected: 7682 DEFAULT_COPY_CONSTRUCTOR(ClearException); 7683 }; 7684 7685 class HThrow final : public HExpression<1> { 7686 public: 7687 HThrow(HInstruction* exception, uint32_t dex_pc) 7688 : HExpression(kThrow, SideEffects::CanTriggerGC(), dex_pc) { 7689 SetRawInputAt(0, exception); 7690 } 7691 7692 bool IsControlFlow() const override { return true; } 7693 7694 bool NeedsEnvironment() const override { return true; } 7695 7696 bool CanThrow() const override { return true; } 7697 7698 bool AlwaysThrows() const override { return true; } 7699 7700 DECLARE_INSTRUCTION(Throw); 7701 7702 protected: 7703 DEFAULT_COPY_CONSTRUCTOR(Throw); 7704 }; 7705 7706 /** 7707 * Implementation strategies for the code generator of a HInstanceOf 7708 * or `HCheckCast`. 7709 */ 7710 enum class TypeCheckKind { // private marker to avoid generate-operator-out.py from processing. 7711 kUnresolvedCheck, // Check against an unresolved type. 7712 kExactCheck, // Can do a single class compare. 7713 kClassHierarchyCheck, // Can just walk the super class chain. 7714 kAbstractClassCheck, // Can just walk the super class chain, starting one up. 7715 kInterfaceCheck, // No optimization yet when checking against an interface. 7716 kArrayObjectCheck, // Can just check if the array is not primitive. 7717 kArrayCheck, // No optimization yet when checking against a generic array. 7718 kBitstringCheck, // Compare the type check bitstring. 7719 kLast = kArrayCheck 7720 }; 7721 7722 std::ostream& operator<<(std::ostream& os, TypeCheckKind rhs); 7723 7724 // Note: HTypeCheckInstruction is just a helper class, not an abstract instruction with an 7725 // `IsTypeCheckInstruction()`. (New virtual methods in the HInstruction class have a high cost.) 7726 class HTypeCheckInstruction : public HVariableInputSizeInstruction { 7727 public: 7728 HTypeCheckInstruction(InstructionKind kind, 7729 DataType::Type type, 7730 HInstruction* object, 7731 HInstruction* target_class_or_null, 7732 TypeCheckKind check_kind, 7733 Handle<mirror::Class> klass, 7734 uint32_t dex_pc, 7735 ArenaAllocator* allocator, 7736 HIntConstant* bitstring_path_to_root, 7737 HIntConstant* bitstring_mask, 7738 SideEffects side_effects) 7739 : HVariableInputSizeInstruction( 7740 kind, 7741 type, 7742 side_effects, 7743 dex_pc, 7744 allocator, 7745 /* number_of_inputs= */ check_kind == TypeCheckKind::kBitstringCheck ? 4u : 2u, 7746 kArenaAllocTypeCheckInputs), 7747 klass_(klass) { 7748 SetPackedField<TypeCheckKindField>(check_kind); 7749 SetPackedFlag<kFlagMustDoNullCheck>(true); 7750 SetPackedFlag<kFlagValidTargetClassRTI>(false); 7751 SetRawInputAt(0, object); 7752 SetRawInputAt(1, target_class_or_null); 7753 DCHECK_EQ(check_kind == TypeCheckKind::kBitstringCheck, bitstring_path_to_root != nullptr); 7754 DCHECK_EQ(check_kind == TypeCheckKind::kBitstringCheck, bitstring_mask != nullptr); 7755 if (check_kind == TypeCheckKind::kBitstringCheck) { 7756 DCHECK(target_class_or_null->IsNullConstant()); 7757 SetRawInputAt(2, bitstring_path_to_root); 7758 SetRawInputAt(3, bitstring_mask); 7759 } else { 7760 DCHECK(target_class_or_null->IsLoadClass()); 7761 } 7762 } 7763 7764 HLoadClass* GetTargetClass() const { 7765 DCHECK_NE(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck); 7766 HInstruction* load_class = InputAt(1); 7767 DCHECK(load_class->IsLoadClass()); 7768 return load_class->AsLoadClass(); 7769 } 7770 7771 uint32_t GetBitstringPathToRoot() const { 7772 DCHECK_EQ(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck); 7773 HInstruction* path_to_root = InputAt(2); 7774 DCHECK(path_to_root->IsIntConstant()); 7775 return static_cast<uint32_t>(path_to_root->AsIntConstant()->GetValue()); 7776 } 7777 7778 uint32_t GetBitstringMask() const { 7779 DCHECK_EQ(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck); 7780 HInstruction* mask = InputAt(3); 7781 DCHECK(mask->IsIntConstant()); 7782 return static_cast<uint32_t>(mask->AsIntConstant()->GetValue()); 7783 } 7784 7785 bool IsClonable() const override { return true; } 7786 bool CanBeMoved() const override { return true; } 7787 7788 bool InstructionDataEquals(const HInstruction* other) const override { 7789 DCHECK(other->IsInstanceOf() || other->IsCheckCast()) << other->DebugName(); 7790 return GetPackedFields() == down_cast<const HTypeCheckInstruction*>(other)->GetPackedFields(); 7791 } 7792 7793 bool MustDoNullCheck() const { return GetPackedFlag<kFlagMustDoNullCheck>(); } 7794 void ClearMustDoNullCheck() { SetPackedFlag<kFlagMustDoNullCheck>(false); } 7795 TypeCheckKind GetTypeCheckKind() const { return GetPackedField<TypeCheckKindField>(); } 7796 bool IsExactCheck() const { return GetTypeCheckKind() == TypeCheckKind::kExactCheck; } 7797 7798 ReferenceTypeInfo GetTargetClassRTI() { 7799 if (GetPackedFlag<kFlagValidTargetClassRTI>()) { 7800 // Note: The is_exact flag from the return value should not be used. 7801 return ReferenceTypeInfo::CreateUnchecked(klass_, /* is_exact= */ true); 7802 } else { 7803 return ReferenceTypeInfo::CreateInvalid(); 7804 } 7805 } 7806 7807 // Target class RTI is marked as valid by RTP if the klass_ is admissible. 7808 void SetValidTargetClassRTI() { 7809 DCHECK(klass_ != nullptr); 7810 SetPackedFlag<kFlagValidTargetClassRTI>(true); 7811 } 7812 7813 Handle<mirror::Class> GetClass() const { 7814 return klass_; 7815 } 7816 7817 protected: 7818 DEFAULT_COPY_CONSTRUCTOR(TypeCheckInstruction); 7819 7820 private: 7821 static constexpr size_t kFieldTypeCheckKind = kNumberOfGenericPackedBits; 7822 static constexpr size_t kFieldTypeCheckKindSize = 7823 MinimumBitsToStore(static_cast<size_t>(TypeCheckKind::kLast)); 7824 static constexpr size_t kFlagMustDoNullCheck = kFieldTypeCheckKind + kFieldTypeCheckKindSize; 7825 static constexpr size_t kFlagValidTargetClassRTI = kFlagMustDoNullCheck + 1; 7826 static constexpr size_t kNumberOfInstanceOfPackedBits = kFlagValidTargetClassRTI + 1; 7827 static_assert(kNumberOfInstanceOfPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 7828 using TypeCheckKindField = BitField<TypeCheckKind, kFieldTypeCheckKind, kFieldTypeCheckKindSize>; 7829 7830 Handle<mirror::Class> klass_; 7831 }; 7832 7833 class HInstanceOf final : public HTypeCheckInstruction { 7834 public: 7835 HInstanceOf(HInstruction* object, 7836 HInstruction* target_class_or_null, 7837 TypeCheckKind check_kind, 7838 Handle<mirror::Class> klass, 7839 uint32_t dex_pc, 7840 ArenaAllocator* allocator, 7841 HIntConstant* bitstring_path_to_root, 7842 HIntConstant* bitstring_mask) 7843 : HTypeCheckInstruction(kInstanceOf, 7844 DataType::Type::kBool, 7845 object, 7846 target_class_or_null, 7847 check_kind, 7848 klass, 7849 dex_pc, 7850 allocator, 7851 bitstring_path_to_root, 7852 bitstring_mask, 7853 SideEffectsForArchRuntimeCalls(check_kind)) {} 7854 7855 bool IsClonable() const override { return true; } 7856 7857 bool NeedsEnvironment() const override { 7858 return CanCallRuntime(GetTypeCheckKind()); 7859 } 7860 7861 static bool CanCallRuntime(TypeCheckKind check_kind) { 7862 // TODO: Re-evaluate now that mips codegen has been removed. 7863 return check_kind != TypeCheckKind::kExactCheck; 7864 } 7865 7866 static SideEffects SideEffectsForArchRuntimeCalls(TypeCheckKind check_kind) { 7867 return CanCallRuntime(check_kind) ? SideEffects::CanTriggerGC() : SideEffects::None(); 7868 } 7869 7870 DECLARE_INSTRUCTION(InstanceOf); 7871 7872 protected: 7873 DEFAULT_COPY_CONSTRUCTOR(InstanceOf); 7874 }; 7875 7876 class HBoundType final : public HExpression<1> { 7877 public: 7878 explicit HBoundType(HInstruction* input, uint32_t dex_pc = kNoDexPc) 7879 : HExpression(kBoundType, DataType::Type::kReference, SideEffects::None(), dex_pc), 7880 upper_bound_(ReferenceTypeInfo::CreateInvalid()) { 7881 SetPackedFlag<kFlagUpperCanBeNull>(true); 7882 SetPackedFlag<kFlagCanBeNull>(true); 7883 DCHECK_EQ(input->GetType(), DataType::Type::kReference); 7884 SetRawInputAt(0, input); 7885 } 7886 7887 bool InstructionDataEquals(const HInstruction* other) const override; 7888 bool IsClonable() const override { return true; } 7889 7890 // {Get,Set}Upper* should only be used in reference type propagation. 7891 const ReferenceTypeInfo& GetUpperBound() const { return upper_bound_; } 7892 bool GetUpperCanBeNull() const { return GetPackedFlag<kFlagUpperCanBeNull>(); } 7893 void SetUpperBound(const ReferenceTypeInfo& upper_bound, bool can_be_null); 7894 7895 void SetCanBeNull(bool can_be_null) { 7896 DCHECK(GetUpperCanBeNull() || !can_be_null); 7897 SetPackedFlag<kFlagCanBeNull>(can_be_null); 7898 } 7899 7900 bool CanBeNull() const override { return GetPackedFlag<kFlagCanBeNull>(); } 7901 7902 DECLARE_INSTRUCTION(BoundType); 7903 7904 protected: 7905 DEFAULT_COPY_CONSTRUCTOR(BoundType); 7906 7907 private: 7908 // Represents the top constraint that can_be_null_ cannot exceed (i.e. if this 7909 // is false then CanBeNull() cannot be true). 7910 static constexpr size_t kFlagUpperCanBeNull = kNumberOfGenericPackedBits; 7911 static constexpr size_t kFlagCanBeNull = kFlagUpperCanBeNull + 1; 7912 static constexpr size_t kNumberOfBoundTypePackedBits = kFlagCanBeNull + 1; 7913 static_assert(kNumberOfBoundTypePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 7914 7915 // Encodes the most upper class that this instruction can have. In other words 7916 // it is always the case that GetUpperBound().IsSupertypeOf(GetReferenceType()). 7917 // It is used to bound the type in cases like: 7918 // if (x instanceof ClassX) { 7919 // // uper_bound_ will be ClassX 7920 // } 7921 ReferenceTypeInfo upper_bound_; 7922 }; 7923 7924 class HCheckCast final : public HTypeCheckInstruction { 7925 public: 7926 HCheckCast(HInstruction* object, 7927 HInstruction* target_class_or_null, 7928 TypeCheckKind check_kind, 7929 Handle<mirror::Class> klass, 7930 uint32_t dex_pc, 7931 ArenaAllocator* allocator, 7932 HIntConstant* bitstring_path_to_root, 7933 HIntConstant* bitstring_mask) 7934 : HTypeCheckInstruction(kCheckCast, 7935 DataType::Type::kVoid, 7936 object, 7937 target_class_or_null, 7938 check_kind, 7939 klass, 7940 dex_pc, 7941 allocator, 7942 bitstring_path_to_root, 7943 bitstring_mask, 7944 SideEffects::CanTriggerGC()) {} 7945 7946 bool IsClonable() const override { return true; } 7947 bool NeedsEnvironment() const override { 7948 // Instruction may throw a CheckCastError. 7949 return true; 7950 } 7951 7952 bool CanThrow() const override { return true; } 7953 7954 DECLARE_INSTRUCTION(CheckCast); 7955 7956 protected: 7957 DEFAULT_COPY_CONSTRUCTOR(CheckCast); 7958 }; 7959 7960 /** 7961 * @brief Memory barrier types (see "The JSR-133 Cookbook for Compiler Writers"). 7962 * @details We define the combined barrier types that are actually required 7963 * by the Java Memory Model, rather than using exactly the terminology from 7964 * the JSR-133 cookbook. These should, in many cases, be replaced by acquire/release 7965 * primitives. Note that the JSR-133 cookbook generally does not deal with 7966 * store atomicity issues, and the recipes there are not always entirely sufficient. 7967 * The current recipe is as follows: 7968 * -# Use AnyStore ~= (LoadStore | StoreStore) ~= release barrier before volatile store. 7969 * -# Use AnyAny barrier after volatile store. (StoreLoad is as expensive.) 7970 * -# Use LoadAny barrier ~= (LoadLoad | LoadStore) ~= acquire barrier after each volatile load. 7971 * -# Use StoreStore barrier after all stores but before return from any constructor whose 7972 * class has final fields. 7973 * -# Use NTStoreStore to order non-temporal stores with respect to all later 7974 * store-to-memory instructions. Only generated together with non-temporal stores. 7975 */ 7976 enum MemBarrierKind { 7977 kAnyStore, 7978 kLoadAny, 7979 kStoreStore, 7980 kAnyAny, 7981 kNTStoreStore, 7982 kLastBarrierKind = kNTStoreStore 7983 }; 7984 std::ostream& operator<<(std::ostream& os, MemBarrierKind kind); 7985 7986 class HMemoryBarrier final : public HExpression<0> { 7987 public: 7988 explicit HMemoryBarrier(MemBarrierKind barrier_kind, uint32_t dex_pc = kNoDexPc) 7989 : HExpression(kMemoryBarrier, 7990 SideEffects::AllWritesAndReads(), // Assume write/read on all fields/arrays. 7991 dex_pc) { 7992 SetPackedField<BarrierKindField>(barrier_kind); 7993 } 7994 7995 bool IsClonable() const override { return true; } 7996 7997 MemBarrierKind GetBarrierKind() { return GetPackedField<BarrierKindField>(); } 7998 7999 DECLARE_INSTRUCTION(MemoryBarrier); 8000 8001 protected: 8002 DEFAULT_COPY_CONSTRUCTOR(MemoryBarrier); 8003 8004 private: 8005 static constexpr size_t kFieldBarrierKind = HInstruction::kNumberOfGenericPackedBits; 8006 static constexpr size_t kFieldBarrierKindSize = 8007 MinimumBitsToStore(static_cast<size_t>(kLastBarrierKind)); 8008 static constexpr size_t kNumberOfMemoryBarrierPackedBits = 8009 kFieldBarrierKind + kFieldBarrierKindSize; 8010 static_assert(kNumberOfMemoryBarrierPackedBits <= kMaxNumberOfPackedBits, 8011 "Too many packed fields."); 8012 using BarrierKindField = BitField<MemBarrierKind, kFieldBarrierKind, kFieldBarrierKindSize>; 8013 }; 8014 8015 // A constructor fence orders all prior stores to fields that could be accessed via a final field of 8016 // the specified object(s), with respect to any subsequent store that might "publish" 8017 // (i.e. make visible) the specified object to another thread. 8018 // 8019 // JLS 17.5.1 "Semantics of final fields" states that a freeze action happens 8020 // for all final fields (that were set) at the end of the invoked constructor. 8021 // 8022 // The constructor fence models the freeze actions for the final fields of an object 8023 // being constructed (semantically at the end of the constructor). Constructor fences 8024 // have a per-object affinity; two separate objects being constructed get two separate 8025 // constructor fences. 8026 // 8027 // (Note: that if calling a super-constructor or forwarding to another constructor, 8028 // the freezes would happen at the end of *that* constructor being invoked). 8029 // 8030 // The memory model guarantees that when the object being constructed is "published" after 8031 // constructor completion (i.e. escapes the current thread via a store), then any final field 8032 // writes must be observable on other threads (once they observe that publication). 8033 // 8034 // Further, anything written before the freeze, and read by dereferencing through the final field, 8035 // must also be visible (so final object field could itself have an object with non-final fields; 8036 // yet the freeze must also extend to them). 8037 // 8038 // Constructor example: 8039 // 8040 // class HasFinal { 8041 // final int field; Optimizing IR for <init>()V: 8042 // HasFinal() { 8043 // field = 123; HInstanceFieldSet(this, HasFinal.field, 123) 8044 // // freeze(this.field); HConstructorFence(this) 8045 // } HReturn 8046 // } 8047 // 8048 // HConstructorFence can serve double duty as a fence for new-instance/new-array allocations of 8049 // already-initialized classes; in that case the allocation must act as a "default-initializer" 8050 // of the object which effectively writes the class pointer "final field". 8051 // 8052 // For example, we can model default-initialiation as roughly the equivalent of the following: 8053 // 8054 // class Object { 8055 // private final Class header; 8056 // } 8057 // 8058 // Java code: Optimizing IR: 8059 // 8060 // T new_instance<T>() { 8061 // Object obj = allocate_memory(T.class.size); obj = HInvoke(art_quick_alloc_object, T) 8062 // obj.header = T.class; // header write is done by above call. 8063 // // freeze(obj.header) HConstructorFence(obj) 8064 // return (T)obj; 8065 // } 8066 // 8067 // See also: 8068 // * DexCompilationUnit::RequiresConstructorBarrier 8069 // * QuasiAtomic::ThreadFenceForConstructor 8070 // 8071 class HConstructorFence final : public HVariableInputSizeInstruction { 8072 // A fence has variable inputs because the inputs can be removed 8073 // after prepare_for_register_allocation phase. 8074 // (TODO: In the future a fence could freeze multiple objects 8075 // after merging two fences together.) 8076 public: 8077 // `fence_object` is the reference that needs to be protected for correct publication. 8078 // 8079 // It makes sense in the following situations: 8080 // * <init> constructors, it's the "this" parameter (i.e. HParameterValue, s.t. IsThis() == true). 8081 // * new-instance-like instructions, it's the return value (i.e. HNewInstance). 8082 // 8083 // After construction the `fence_object` becomes the 0th input. 8084 // This is not an input in a real sense, but just a convenient place to stash the information 8085 // about the associated object. 8086 HConstructorFence(HInstruction* fence_object, 8087 uint32_t dex_pc, 8088 ArenaAllocator* allocator) 8089 // We strongly suspect there is not a more accurate way to describe the fine-grained reordering 8090 // constraints described in the class header. We claim that these SideEffects constraints 8091 // enforce a superset of the real constraints. 8092 // 8093 // The ordering described above is conservatively modeled with SideEffects as follows: 8094 // 8095 // * To prevent reordering of the publication stores: 8096 // ----> "Reads of objects" is the initial SideEffect. 8097 // * For every primitive final field store in the constructor: 8098 // ----> Union that field's type as a read (e.g. "Read of T") into the SideEffect. 8099 // * If there are any stores to reference final fields in the constructor: 8100 // ----> Use a more conservative "AllReads" SideEffect because any stores to any references 8101 // that are reachable from `fence_object` also need to be prevented for reordering 8102 // (and we do not want to do alias analysis to figure out what those stores are). 8103 // 8104 // In the implementation, this initially starts out as an "all reads" side effect; this is an 8105 // even more conservative approach than the one described above, and prevents all of the 8106 // above reordering without analyzing any of the instructions in the constructor. 8107 // 8108 // If in a later phase we discover that there are no writes to reference final fields, 8109 // we can refine the side effect to a smaller set of type reads (see above constraints). 8110 : HVariableInputSizeInstruction(kConstructorFence, 8111 SideEffects::AllReads(), 8112 dex_pc, 8113 allocator, 8114 /* number_of_inputs= */ 1, 8115 kArenaAllocConstructorFenceInputs) { 8116 DCHECK(fence_object != nullptr); 8117 SetRawInputAt(0, fence_object); 8118 } 8119 8120 // The object associated with this constructor fence. 8121 // 8122 // (Note: This will be null after the prepare_for_register_allocation phase, 8123 // as all constructor fence inputs are removed there). 8124 HInstruction* GetFenceObject() const { 8125 return InputAt(0); 8126 } 8127 8128 // Find all the HConstructorFence uses (`fence_use`) for `this` and: 8129 // - Delete `fence_use` from `this`'s use list. 8130 // - Delete `this` from `fence_use`'s inputs list. 8131 // - If the `fence_use` is dead, remove it from the graph. 8132 // 8133 // A fence is considered dead once it no longer has any uses 8134 // and all of the inputs are dead. 8135 // 8136 // This must *not* be called during/after prepare_for_register_allocation, 8137 // because that removes all the inputs to the fences but the fence is actually 8138 // still considered live. 8139 // 8140 // Returns how many HConstructorFence instructions were removed from graph. 8141 static size_t RemoveConstructorFences(HInstruction* instruction); 8142 8143 // Combine all inputs of `this` and `other` instruction and remove 8144 // `other` from the graph. 8145 // 8146 // Inputs are unique after the merge. 8147 // 8148 // Requirement: `this` must not be the same as `other. 8149 void Merge(HConstructorFence* other); 8150 8151 // Check if this constructor fence is protecting 8152 // an HNewInstance or HNewArray that is also the immediate 8153 // predecessor of `this`. 8154 // 8155 // If `ignore_inputs` is true, then the immediate predecessor doesn't need 8156 // to be one of the inputs of `this`. 8157 // 8158 // Returns the associated HNewArray or HNewInstance, 8159 // or null otherwise. 8160 HInstruction* GetAssociatedAllocation(bool ignore_inputs = false); 8161 8162 DECLARE_INSTRUCTION(ConstructorFence); 8163 8164 protected: 8165 DEFAULT_COPY_CONSTRUCTOR(ConstructorFence); 8166 }; 8167 8168 class HMonitorOperation final : public HExpression<1> { 8169 public: 8170 enum class OperationKind { 8171 kEnter, 8172 kExit, 8173 kLast = kExit 8174 }; 8175 8176 HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc) 8177 : HExpression(kMonitorOperation, 8178 SideEffects::AllExceptGCDependency(), // Assume write/read on all fields/arrays. 8179 dex_pc) { 8180 SetPackedField<OperationKindField>(kind); 8181 SetRawInputAt(0, object); 8182 } 8183 8184 // Instruction may go into runtime, so we need an environment. 8185 bool NeedsEnvironment() const override { return true; } 8186 8187 bool CanThrow() const override { 8188 // Verifier guarantees that monitor-exit cannot throw. 8189 // This is important because it allows the HGraphBuilder to remove 8190 // a dead throw-catch loop generated for `synchronized` blocks/methods. 8191 return IsEnter(); 8192 } 8193 8194 OperationKind GetOperationKind() const { return GetPackedField<OperationKindField>(); } 8195 bool IsEnter() const { return GetOperationKind() == OperationKind::kEnter; } 8196 8197 DECLARE_INSTRUCTION(MonitorOperation); 8198 8199 protected: 8200 DEFAULT_COPY_CONSTRUCTOR(MonitorOperation); 8201 8202 private: 8203 static constexpr size_t kFieldOperationKind = HInstruction::kNumberOfGenericPackedBits; 8204 static constexpr size_t kFieldOperationKindSize = 8205 MinimumBitsToStore(static_cast<size_t>(OperationKind::kLast)); 8206 static constexpr size_t kNumberOfMonitorOperationPackedBits = 8207 kFieldOperationKind + kFieldOperationKindSize; 8208 static_assert(kNumberOfMonitorOperationPackedBits <= HInstruction::kMaxNumberOfPackedBits, 8209 "Too many packed fields."); 8210 using OperationKindField = BitField<OperationKind, kFieldOperationKind, kFieldOperationKindSize>; 8211 }; 8212 8213 class HSelect final : public HExpression<3> { 8214 public: 8215 HSelect(HInstruction* condition, 8216 HInstruction* true_value, 8217 HInstruction* false_value, 8218 uint32_t dex_pc) 8219 : HExpression(kSelect, HPhi::ToPhiType(true_value->GetType()), SideEffects::None(), dex_pc) { 8220 DCHECK_EQ(HPhi::ToPhiType(true_value->GetType()), HPhi::ToPhiType(false_value->GetType())); 8221 8222 // First input must be `true_value` or `false_value` to allow codegens to 8223 // use the SameAsFirstInput allocation policy. We make it `false_value`, so 8224 // that architectures which implement HSelect as a conditional move also 8225 // will not need to invert the condition. 8226 SetRawInputAt(0, false_value); 8227 SetRawInputAt(1, true_value); 8228 SetRawInputAt(2, condition); 8229 } 8230 8231 bool IsClonable() const override { return true; } 8232 HInstruction* GetFalseValue() const { return InputAt(0); } 8233 HInstruction* GetTrueValue() const { return InputAt(1); } 8234 HInstruction* GetCondition() const { return InputAt(2); } 8235 8236 bool CanBeMoved() const override { return true; } 8237 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 8238 return true; 8239 } 8240 8241 bool CanBeNull() const override { 8242 return GetTrueValue()->CanBeNull() || GetFalseValue()->CanBeNull(); 8243 } 8244 8245 void UpdateType() { 8246 DCHECK_EQ(HPhi::ToPhiType(GetTrueValue()->GetType()), 8247 HPhi::ToPhiType(GetFalseValue()->GetType())); 8248 SetPackedField<TypeField>(HPhi::ToPhiType(GetTrueValue()->GetType())); 8249 } 8250 8251 DECLARE_INSTRUCTION(Select); 8252 8253 protected: 8254 DEFAULT_COPY_CONSTRUCTOR(Select); 8255 }; 8256 8257 class MoveOperands : public ArenaObject<kArenaAllocMoveOperands> { 8258 public: 8259 MoveOperands(Location source, 8260 Location destination, 8261 DataType::Type type, 8262 HInstruction* instruction) 8263 : source_(source), destination_(destination), type_(type), instruction_(instruction) {} 8264 8265 Location GetSource() const { return source_; } 8266 Location GetDestination() const { return destination_; } 8267 8268 void SetSource(Location value) { source_ = value; } 8269 void SetDestination(Location value) { destination_ = value; } 8270 8271 // The parallel move resolver marks moves as "in-progress" by clearing the 8272 // destination (but not the source). 8273 Location MarkPending() { 8274 DCHECK(!IsPending()); 8275 Location dest = destination_; 8276 destination_ = Location::NoLocation(); 8277 return dest; 8278 } 8279 8280 void ClearPending(Location dest) { 8281 DCHECK(IsPending()); 8282 destination_ = dest; 8283 } 8284 8285 bool IsPending() const { 8286 DCHECK(source_.IsValid() || destination_.IsInvalid()); 8287 return destination_.IsInvalid() && source_.IsValid(); 8288 } 8289 8290 // True if this blocks a move from the given location. 8291 bool Blocks(Location loc) const { 8292 return !IsEliminated() && source_.OverlapsWith(loc); 8293 } 8294 8295 // A move is redundant if it's been eliminated, if its source and 8296 // destination are the same, or if its destination is unneeded. 8297 bool IsRedundant() const { 8298 return IsEliminated() || destination_.IsInvalid() || source_.Equals(destination_); 8299 } 8300 8301 // We clear both operands to indicate move that's been eliminated. 8302 void Eliminate() { 8303 source_ = destination_ = Location::NoLocation(); 8304 } 8305 8306 bool IsEliminated() const { 8307 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); 8308 return source_.IsInvalid(); 8309 } 8310 8311 DataType::Type GetType() const { return type_; } 8312 8313 bool Is64BitMove() const { 8314 return DataType::Is64BitType(type_); 8315 } 8316 8317 HInstruction* GetInstruction() const { return instruction_; } 8318 8319 private: 8320 Location source_; 8321 Location destination_; 8322 // The type this move is for. 8323 DataType::Type type_; 8324 // The instruction this move is assocatied with. Null when this move is 8325 // for moving an input in the expected locations of user (including a phi user). 8326 // This is only used in debug mode, to ensure we do not connect interval siblings 8327 // in the same parallel move. 8328 HInstruction* instruction_; 8329 }; 8330 8331 std::ostream& operator<<(std::ostream& os, const MoveOperands& rhs); 8332 8333 static constexpr size_t kDefaultNumberOfMoves = 4; 8334 8335 class HParallelMove final : public HExpression<0> { 8336 public: 8337 explicit HParallelMove(ArenaAllocator* allocator, uint32_t dex_pc = kNoDexPc) 8338 : HExpression(kParallelMove, SideEffects::None(), dex_pc), 8339 moves_(allocator->Adapter(kArenaAllocMoveOperands)) { 8340 moves_.reserve(kDefaultNumberOfMoves); 8341 } 8342 8343 void AddMove(Location source, 8344 Location destination, 8345 DataType::Type type, 8346 HInstruction* instruction) { 8347 DCHECK(source.IsValid()); 8348 DCHECK(destination.IsValid()); 8349 if (kIsDebugBuild) { 8350 if (instruction != nullptr) { 8351 for (const MoveOperands& move : moves_) { 8352 if (move.GetInstruction() == instruction) { 8353 // Special case the situation where the move is for the spill slot 8354 // of the instruction. 8355 if ((GetPrevious() == instruction) 8356 || ((GetPrevious() == nullptr) 8357 && instruction->IsPhi() 8358 && instruction->GetBlock() == GetBlock())) { 8359 DCHECK_NE(destination.GetKind(), move.GetDestination().GetKind()) 8360 << "Doing parallel moves for the same instruction."; 8361 } else { 8362 DCHECK(false) << "Doing parallel moves for the same instruction."; 8363 } 8364 } 8365 } 8366 } 8367 for (const MoveOperands& move : moves_) { 8368 DCHECK(!destination.OverlapsWith(move.GetDestination())) 8369 << "Overlapped destination for two moves in a parallel move: " 8370 << move.GetSource() << " ==> " << move.GetDestination() << " and " 8371 << source << " ==> " << destination << " for " << SafePrint(instruction); 8372 } 8373 } 8374 moves_.emplace_back(source, destination, type, instruction); 8375 } 8376 8377 MoveOperands* MoveOperandsAt(size_t index) { 8378 return &moves_[index]; 8379 } 8380 8381 size_t NumMoves() const { return moves_.size(); } 8382 8383 DECLARE_INSTRUCTION(ParallelMove); 8384 8385 protected: 8386 DEFAULT_COPY_CONSTRUCTOR(ParallelMove); 8387 8388 private: 8389 ArenaVector<MoveOperands> moves_; 8390 }; 8391 8392 class HBitwiseNegatedRight final : public HBinaryOperation { 8393 public: 8394 HBitwiseNegatedRight(DataType::Type result_type, 8395 InstructionKind op, 8396 HInstruction* left, 8397 HInstruction* right, 8398 uint32_t dex_pc = kNoDexPc) 8399 : HBinaryOperation( 8400 kBitwiseNegatedRight, result_type, left, right, SideEffects::None(), dex_pc), 8401 op_kind_(op) { 8402 DCHECK(op == HInstruction::kAnd || op == HInstruction::kOr || op == HInstruction::kXor) << op; 8403 } 8404 8405 template <typename T, typename U> 8406 auto Compute(T x, U y) const -> decltype(x & ~y) { 8407 static_assert(std::is_same<decltype(x & ~y), decltype(x | ~y)>::value && 8408 std::is_same<decltype(x & ~y), decltype(x ^ ~y)>::value, 8409 "Inconsistent negated bitwise types"); 8410 switch (op_kind_) { 8411 case HInstruction::kAnd: 8412 return x & ~y; 8413 case HInstruction::kOr: 8414 return x | ~y; 8415 case HInstruction::kXor: 8416 return x ^ ~y; 8417 default: 8418 LOG(FATAL) << "Unreachable"; 8419 UNREACHABLE(); 8420 } 8421 } 8422 8423 bool InstructionDataEquals(const HInstruction* other) const override { 8424 return op_kind_ == other->AsBitwiseNegatedRight()->op_kind_; 8425 } 8426 8427 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override { 8428 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()), 8429 GetDexPc()); 8430 } 8431 8432 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override { 8433 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()), 8434 GetDexPc()); 8435 } 8436 8437 InstructionKind GetOpKind() const { return op_kind_; } 8438 8439 DECLARE_INSTRUCTION(BitwiseNegatedRight); 8440 8441 protected: 8442 DEFAULT_COPY_CONSTRUCTOR(BitwiseNegatedRight); 8443 8444 private: 8445 // Specifies the bitwise operation, which will be then negated. 8446 const InstructionKind op_kind_; 8447 }; 8448 8449 // This instruction computes an intermediate address pointing in the 'middle' of an object. The 8450 // result pointer cannot be handled by GC, so extra care is taken to make sure that this value is 8451 // never used across anything that can trigger GC. 8452 // The result of this instruction is not a pointer in the sense of `DataType::Type::kreference`. 8453 // So we represent it by the type `DataType::Type::kInt`. 8454 class HIntermediateAddress final : public HExpression<2> { 8455 public: 8456 HIntermediateAddress(HInstruction* base_address, HInstruction* offset, uint32_t dex_pc) 8457 : HExpression(kIntermediateAddress, 8458 DataType::Type::kInt32, 8459 SideEffects::DependsOnGC(), 8460 dex_pc) { 8461 DCHECK_EQ(DataType::Size(DataType::Type::kInt32), 8462 DataType::Size(DataType::Type::kReference)) 8463 << "kPrimInt and kPrimNot have different sizes."; 8464 SetRawInputAt(0, base_address); 8465 SetRawInputAt(1, offset); 8466 } 8467 8468 bool IsClonable() const override { return true; } 8469 bool CanBeMoved() const override { return true; } 8470 bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override { 8471 return true; 8472 } 8473 bool IsActualObject() const override { return false; } 8474 8475 HInstruction* GetBaseAddress() const { return InputAt(0); } 8476 HInstruction* GetOffset() const { return InputAt(1); } 8477 8478 DECLARE_INSTRUCTION(IntermediateAddress); 8479 8480 protected: 8481 DEFAULT_COPY_CONSTRUCTOR(IntermediateAddress); 8482 }; 8483 8484 8485 } // namespace art 8486 8487 #include "nodes_vector.h" 8488 8489 #if defined(ART_ENABLE_CODEGEN_arm) || defined(ART_ENABLE_CODEGEN_arm64) 8490 #include "nodes_shared.h" 8491 #endif 8492 #if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64) 8493 #include "nodes_x86.h" 8494 #endif 8495 #if defined(ART_ENABLE_CODEGEN_riscv64) 8496 #include "nodes_riscv64.h" 8497 #endif 8498 8499 namespace art HIDDEN { 8500 8501 class OptimizingCompilerStats; 8502 8503 class HGraphVisitor : public ValueObject { 8504 public: 8505 explicit HGraphVisitor(HGraph* graph, OptimizingCompilerStats* stats = nullptr) 8506 : stats_(stats), 8507 graph_(graph) {} 8508 virtual ~HGraphVisitor() {} 8509 8510 virtual void VisitInstruction([[maybe_unused]] HInstruction* instruction) {} 8511 virtual void VisitBasicBlock(HBasicBlock* block); 8512 8513 // Visit the graph following basic block insertion order. 8514 void VisitInsertionOrder(); 8515 8516 // Visit the graph following dominator tree reverse post-order. 8517 void VisitReversePostOrder(); 8518 8519 HGraph* GetGraph() const { return graph_; } 8520 8521 // Visit functions for instruction classes. 8522 #define DECLARE_VISIT_INSTRUCTION(name, super) \ 8523 virtual void Visit##name(H##name* instr) { VisitInstruction(instr); } 8524 8525 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 8526 8527 #undef DECLARE_VISIT_INSTRUCTION 8528 8529 protected: 8530 void VisitPhis(HBasicBlock* block); 8531 void VisitNonPhiInstructions(HBasicBlock* block); 8532 8533 OptimizingCompilerStats* stats_; 8534 8535 private: 8536 HGraph* const graph_; 8537 8538 DISALLOW_COPY_AND_ASSIGN(HGraphVisitor); 8539 }; 8540 8541 class HGraphDelegateVisitor : public HGraphVisitor { 8542 public: 8543 explicit HGraphDelegateVisitor(HGraph* graph, OptimizingCompilerStats* stats = nullptr) 8544 : HGraphVisitor(graph, stats) {} 8545 virtual ~HGraphDelegateVisitor() {} 8546 8547 // Visit functions that delegate to to super class. 8548 #define DECLARE_VISIT_INSTRUCTION(name, super) \ 8549 void Visit##name(H##name* instr) override { Visit##super(instr); } 8550 8551 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 8552 8553 #undef DECLARE_VISIT_INSTRUCTION 8554 8555 private: 8556 DISALLOW_COPY_AND_ASSIGN(HGraphDelegateVisitor); 8557 }; 8558 8559 // Create a clone of the instruction, insert it into the graph; replace the old one with a new 8560 // and remove the old instruction. 8561 HInstruction* ReplaceInstrOrPhiByClone(HInstruction* instr); 8562 8563 // Create a clone for each clonable instructions/phis and replace the original with the clone. 8564 // 8565 // Used for testing individual instruction cloner. 8566 class CloneAndReplaceInstructionVisitor final : public HGraphDelegateVisitor { 8567 public: 8568 explicit CloneAndReplaceInstructionVisitor(HGraph* graph) 8569 : HGraphDelegateVisitor(graph), instr_replaced_by_clones_count_(0) {} 8570 8571 void VisitInstruction(HInstruction* instruction) override { 8572 if (instruction->IsClonable()) { 8573 ReplaceInstrOrPhiByClone(instruction); 8574 instr_replaced_by_clones_count_++; 8575 } 8576 } 8577 8578 size_t GetInstrReplacedByClonesCount() const { return instr_replaced_by_clones_count_; } 8579 8580 private: 8581 size_t instr_replaced_by_clones_count_; 8582 8583 DISALLOW_COPY_AND_ASSIGN(CloneAndReplaceInstructionVisitor); 8584 }; 8585 8586 // Iterator over the blocks that are part of the loop; includes blocks which are part 8587 // of an inner loop. The order in which the blocks are iterated is on their 8588 // block id. 8589 class HBlocksInLoopIterator : public ValueObject { 8590 public: 8591 explicit HBlocksInLoopIterator(const HLoopInformation& info) 8592 : blocks_in_loop_(info.GetBlocks()), 8593 blocks_(info.GetHeader()->GetGraph()->GetBlocks()), 8594 index_(0) { 8595 if (!blocks_in_loop_.IsBitSet(index_)) { 8596 Advance(); 8597 } 8598 } 8599 8600 bool Done() const { return index_ == blocks_.size(); } 8601 HBasicBlock* Current() const { return blocks_[index_]; } 8602 void Advance() { 8603 ++index_; 8604 for (size_t e = blocks_.size(); index_ < e; ++index_) { 8605 if (blocks_in_loop_.IsBitSet(index_)) { 8606 break; 8607 } 8608 } 8609 } 8610 8611 private: 8612 const BitVector& blocks_in_loop_; 8613 const ArenaVector<HBasicBlock*>& blocks_; 8614 size_t index_; 8615 8616 DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator); 8617 }; 8618 8619 // Iterator over the blocks that are part of the loop; includes blocks which are part 8620 // of an inner loop. The order in which the blocks are iterated is reverse 8621 // post order. 8622 class HBlocksInLoopReversePostOrderIterator : public ValueObject { 8623 public: 8624 explicit HBlocksInLoopReversePostOrderIterator(const HLoopInformation& info) 8625 : blocks_in_loop_(info.GetBlocks()), 8626 blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()), 8627 index_(0) { 8628 if (!blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 8629 Advance(); 8630 } 8631 } 8632 8633 bool Done() const { return index_ == blocks_.size(); } 8634 HBasicBlock* Current() const { return blocks_[index_]; } 8635 void Advance() { 8636 ++index_; 8637 for (size_t e = blocks_.size(); index_ < e; ++index_) { 8638 if (blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 8639 break; 8640 } 8641 } 8642 } 8643 8644 private: 8645 const BitVector& blocks_in_loop_; 8646 const ArenaVector<HBasicBlock*>& blocks_; 8647 size_t index_; 8648 8649 DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopReversePostOrderIterator); 8650 }; 8651 8652 // Iterator over the blocks that are part of the loop; includes blocks which are part 8653 // of an inner loop. The order in which the blocks are iterated is post order. 8654 class HBlocksInLoopPostOrderIterator : public ValueObject { 8655 public: 8656 explicit HBlocksInLoopPostOrderIterator(const HLoopInformation& info) 8657 : blocks_in_loop_(info.GetBlocks()), 8658 blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()), 8659 index_(blocks_.size() - 1) { 8660 if (!blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 8661 Advance(); 8662 } 8663 } 8664 8665 bool Done() const { return index_ < 0; } 8666 HBasicBlock* Current() const { return blocks_[index_]; } 8667 void Advance() { 8668 --index_; 8669 for (; index_ >= 0; --index_) { 8670 if (blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 8671 break; 8672 } 8673 } 8674 } 8675 8676 private: 8677 const BitVector& blocks_in_loop_; 8678 const ArenaVector<HBasicBlock*>& blocks_; 8679 8680 int32_t index_; 8681 8682 DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopPostOrderIterator); 8683 }; 8684 8685 // Returns int64_t value of a properly typed constant. 8686 inline int64_t Int64FromConstant(HConstant* constant) { 8687 if (constant->IsIntConstant()) { 8688 return constant->AsIntConstant()->GetValue(); 8689 } else if (constant->IsLongConstant()) { 8690 return constant->AsLongConstant()->GetValue(); 8691 } else { 8692 DCHECK(constant->IsNullConstant()) << constant->DebugName(); 8693 return 0; 8694 } 8695 } 8696 8697 // Returns true iff instruction is an integral constant (and sets value on success). 8698 inline bool IsInt64AndGet(HInstruction* instruction, /*out*/ int64_t* value) { 8699 if (instruction->IsIntConstant()) { 8700 *value = instruction->AsIntConstant()->GetValue(); 8701 return true; 8702 } else if (instruction->IsLongConstant()) { 8703 *value = instruction->AsLongConstant()->GetValue(); 8704 return true; 8705 } else if (instruction->IsNullConstant()) { 8706 *value = 0; 8707 return true; 8708 } 8709 return false; 8710 } 8711 8712 // Returns true iff instruction is the given integral constant. 8713 inline bool IsInt64Value(HInstruction* instruction, int64_t value) { 8714 int64_t val = 0; 8715 return IsInt64AndGet(instruction, &val) && val == value; 8716 } 8717 8718 // Returns true iff instruction is a zero bit pattern. 8719 inline bool IsZeroBitPattern(HInstruction* instruction) { 8720 return instruction->IsConstant() && instruction->AsConstant()->IsZeroBitPattern(); 8721 } 8722 8723 // Implement HInstruction::Is##type() for concrete instructions. 8724 #define INSTRUCTION_TYPE_CHECK(type, super) \ 8725 inline bool HInstruction::Is##type() const { return GetKind() == k##type; } 8726 FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 8727 #undef INSTRUCTION_TYPE_CHECK 8728 8729 // Implement HInstruction::Is##type() for abstract instructions. 8730 #define INSTRUCTION_TYPE_CHECK_RESULT(type, super) \ 8731 std::is_base_of<BaseType, H##type>::value, 8732 #define INSTRUCTION_TYPE_CHECK(type, super) \ 8733 inline bool HInstruction::Is##type() const { \ 8734 DCHECK_LT(GetKind(), kLastInstructionKind); \ 8735 using BaseType = H##type; \ 8736 static constexpr bool results[] = { \ 8737 FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK_RESULT) \ 8738 }; \ 8739 return results[static_cast<size_t>(GetKind())]; \ 8740 } 8741 8742 FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 8743 #undef INSTRUCTION_TYPE_CHECK 8744 #undef INSTRUCTION_TYPE_CHECK_RESULT 8745 8746 #define INSTRUCTION_TYPE_CAST(type, super) \ 8747 inline const H##type* HInstruction::As##type() const { \ 8748 DCHECK(Is##type()); \ 8749 return down_cast<const H##type*>(this); \ 8750 } \ 8751 inline H##type* HInstruction::As##type() { \ 8752 DCHECK(Is##type()); \ 8753 return down_cast<H##type*>(this); \ 8754 } \ 8755 inline const H##type* HInstruction::As##type##OrNull() const { \ 8756 return Is##type() ? down_cast<const H##type*>(this) : nullptr; \ 8757 } \ 8758 inline H##type* HInstruction::As##type##OrNull() { \ 8759 return Is##type() ? down_cast<H##type*>(this) : nullptr; \ 8760 } 8761 8762 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CAST) 8763 #undef INSTRUCTION_TYPE_CAST 8764 8765 8766 // Create space in `blocks` for adding `number_of_new_blocks` entries 8767 // starting at location `at`. Blocks after `at` are moved accordingly. 8768 inline void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks, 8769 size_t number_of_new_blocks, 8770 size_t after) { 8771 DCHECK_LT(after, blocks->size()); 8772 size_t old_size = blocks->size(); 8773 size_t new_size = old_size + number_of_new_blocks; 8774 blocks->resize(new_size); 8775 std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end()); 8776 } 8777 8778 /* 8779 * Hunt "under the hood" of array lengths (leading to array references), 8780 * null checks (also leading to array references), and new arrays 8781 * (leading to the actual length). This makes it more likely related 8782 * instructions become actually comparable. 8783 */ 8784 inline HInstruction* HuntForDeclaration(HInstruction* instruction) { 8785 while (instruction->IsArrayLength() || 8786 instruction->IsNullCheck() || 8787 instruction->IsNewArray()) { 8788 instruction = instruction->IsNewArray() 8789 ? instruction->AsNewArray()->GetLength() 8790 : instruction->InputAt(0); 8791 } 8792 return instruction; 8793 } 8794 8795 inline bool IsAddOrSub(const HInstruction* instruction) { 8796 return instruction->IsAdd() || instruction->IsSub(); 8797 } 8798 8799 void RemoveEnvironmentUses(HInstruction* instruction); 8800 bool HasEnvironmentUsedByOthers(HInstruction* instruction); 8801 void ResetEnvironmentInputRecords(HInstruction* instruction); 8802 8803 // Detects an instruction that is >= 0. As long as the value is carried by 8804 // a single instruction, arithmetic wrap-around cannot occur. 8805 bool IsGEZero(HInstruction* instruction); 8806 8807 } // namespace art 8808 8809 #endif // ART_COMPILER_OPTIMIZING_NODES_H_ 8810