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 "base/arena_bit_vector.h" 25 #include "base/arena_containers.h" 26 #include "base/arena_object.h" 27 #include "base/stl_util.h" 28 #include "dex/compiler_enums.h" 29 #include "entrypoints/quick/quick_entrypoints_enum.h" 30 #include "handle.h" 31 #include "handle_scope.h" 32 #include "invoke_type.h" 33 #include "locations.h" 34 #include "method_reference.h" 35 #include "mirror/class.h" 36 #include "offsets.h" 37 #include "primitive.h" 38 #include "utils/array_ref.h" 39 #include "utils/intrusive_forward_list.h" 40 41 namespace art { 42 43 class GraphChecker; 44 class HBasicBlock; 45 class HCurrentMethod; 46 class HDoubleConstant; 47 class HEnvironment; 48 class HFloatConstant; 49 class HGraphBuilder; 50 class HGraphVisitor; 51 class HInstruction; 52 class HIntConstant; 53 class HInvoke; 54 class HLongConstant; 55 class HNullConstant; 56 class HPhi; 57 class HSuspendCheck; 58 class HTryBoundary; 59 class LiveInterval; 60 class LocationSummary; 61 class SlowPathCode; 62 class SsaBuilder; 63 64 namespace mirror { 65 class DexCache; 66 } // namespace mirror 67 68 static const int kDefaultNumberOfBlocks = 8; 69 static const int kDefaultNumberOfSuccessors = 2; 70 static const int kDefaultNumberOfPredecessors = 2; 71 static const int kDefaultNumberOfExceptionalPredecessors = 0; 72 static const int kDefaultNumberOfDominatedBlocks = 1; 73 static const int kDefaultNumberOfBackEdges = 1; 74 75 // The maximum (meaningful) distance (31) that can be used in an integer shift/rotate operation. 76 static constexpr int32_t kMaxIntShiftDistance = 0x1f; 77 // The maximum (meaningful) distance (63) that can be used in a long shift/rotate operation. 78 static constexpr int32_t kMaxLongShiftDistance = 0x3f; 79 80 static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1); 81 static constexpr uint16_t kUnknownClassDefIndex = static_cast<uint16_t>(-1); 82 83 static constexpr InvokeType kInvalidInvokeType = static_cast<InvokeType>(-1); 84 85 static constexpr uint32_t kNoDexPc = -1; 86 87 enum IfCondition { 88 // All types. 89 kCondEQ, // == 90 kCondNE, // != 91 // Signed integers and floating-point numbers. 92 kCondLT, // < 93 kCondLE, // <= 94 kCondGT, // > 95 kCondGE, // >= 96 // Unsigned integers. 97 kCondB, // < 98 kCondBE, // <= 99 kCondA, // > 100 kCondAE, // >= 101 }; 102 103 enum GraphAnalysisResult { 104 kAnalysisSkipped, 105 kAnalysisInvalidBytecode, 106 kAnalysisFailThrowCatchLoop, 107 kAnalysisFailAmbiguousArrayOp, 108 kAnalysisSuccess, 109 }; 110 111 class HInstructionList : public ValueObject { 112 public: 113 HInstructionList() : first_instruction_(nullptr), last_instruction_(nullptr) {} 114 115 void AddInstruction(HInstruction* instruction); 116 void RemoveInstruction(HInstruction* instruction); 117 118 // Insert `instruction` before/after an existing instruction `cursor`. 119 void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); 120 void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor); 121 122 // Return true if this list contains `instruction`. 123 bool Contains(HInstruction* instruction) const; 124 125 // Return true if `instruction1` is found before `instruction2` in 126 // this instruction list and false otherwise. Abort if none 127 // of these instructions is found. 128 bool FoundBefore(const HInstruction* instruction1, 129 const HInstruction* instruction2) const; 130 131 bool IsEmpty() const { return first_instruction_ == nullptr; } 132 void Clear() { first_instruction_ = last_instruction_ = nullptr; } 133 134 // Update the block of all instructions to be `block`. 135 void SetBlockOfInstructions(HBasicBlock* block) const; 136 137 void AddAfter(HInstruction* cursor, const HInstructionList& instruction_list); 138 void AddBefore(HInstruction* cursor, const HInstructionList& instruction_list); 139 void Add(const HInstructionList& instruction_list); 140 141 // Return the number of instructions in the list. This is an expensive operation. 142 size_t CountSize() const; 143 144 private: 145 HInstruction* first_instruction_; 146 HInstruction* last_instruction_; 147 148 friend class HBasicBlock; 149 friend class HGraph; 150 friend class HInstruction; 151 friend class HInstructionIterator; 152 friend class HBackwardInstructionIterator; 153 154 DISALLOW_COPY_AND_ASSIGN(HInstructionList); 155 }; 156 157 class ReferenceTypeInfo : ValueObject { 158 public: 159 typedef Handle<mirror::Class> TypeHandle; 160 161 static ReferenceTypeInfo Create(TypeHandle type_handle, bool is_exact); 162 163 static ReferenceTypeInfo CreateUnchecked(TypeHandle type_handle, bool is_exact) { 164 return ReferenceTypeInfo(type_handle, is_exact); 165 } 166 167 static ReferenceTypeInfo CreateInvalid() { return ReferenceTypeInfo(); } 168 169 static bool IsValidHandle(TypeHandle handle) { 170 return handle.GetReference() != nullptr; 171 } 172 173 bool IsValid() const { 174 return IsValidHandle(type_handle_); 175 } 176 177 bool IsExact() const { return is_exact_; } 178 179 bool IsObjectClass() const SHARED_REQUIRES(Locks::mutator_lock_) { 180 DCHECK(IsValid()); 181 return GetTypeHandle()->IsObjectClass(); 182 } 183 184 bool IsStringClass() const SHARED_REQUIRES(Locks::mutator_lock_) { 185 DCHECK(IsValid()); 186 return GetTypeHandle()->IsStringClass(); 187 } 188 189 bool IsObjectArray() const SHARED_REQUIRES(Locks::mutator_lock_) { 190 DCHECK(IsValid()); 191 return IsArrayClass() && GetTypeHandle()->GetComponentType()->IsObjectClass(); 192 } 193 194 bool IsInterface() const SHARED_REQUIRES(Locks::mutator_lock_) { 195 DCHECK(IsValid()); 196 return GetTypeHandle()->IsInterface(); 197 } 198 199 bool IsArrayClass() const SHARED_REQUIRES(Locks::mutator_lock_) { 200 DCHECK(IsValid()); 201 return GetTypeHandle()->IsArrayClass(); 202 } 203 204 bool IsPrimitiveArrayClass() const SHARED_REQUIRES(Locks::mutator_lock_) { 205 DCHECK(IsValid()); 206 return GetTypeHandle()->IsPrimitiveArray(); 207 } 208 209 bool IsNonPrimitiveArrayClass() const SHARED_REQUIRES(Locks::mutator_lock_) { 210 DCHECK(IsValid()); 211 return GetTypeHandle()->IsArrayClass() && !GetTypeHandle()->IsPrimitiveArray(); 212 } 213 214 bool CanArrayHold(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { 215 DCHECK(IsValid()); 216 if (!IsExact()) return false; 217 if (!IsArrayClass()) return false; 218 return GetTypeHandle()->GetComponentType()->IsAssignableFrom(rti.GetTypeHandle().Get()); 219 } 220 221 bool CanArrayHoldValuesOf(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { 222 DCHECK(IsValid()); 223 if (!IsExact()) return false; 224 if (!IsArrayClass()) return false; 225 if (!rti.IsArrayClass()) return false; 226 return GetTypeHandle()->GetComponentType()->IsAssignableFrom( 227 rti.GetTypeHandle()->GetComponentType()); 228 } 229 230 Handle<mirror::Class> GetTypeHandle() const { return type_handle_; } 231 232 bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { 233 DCHECK(IsValid()); 234 DCHECK(rti.IsValid()); 235 return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get()); 236 } 237 238 bool IsStrictSupertypeOf(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { 239 DCHECK(IsValid()); 240 DCHECK(rti.IsValid()); 241 return GetTypeHandle().Get() != rti.GetTypeHandle().Get() && 242 GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get()); 243 } 244 245 // Returns true if the type information provide the same amount of details. 246 // Note that it does not mean that the instructions have the same actual type 247 // (because the type can be the result of a merge). 248 bool IsEqual(ReferenceTypeInfo rti) const SHARED_REQUIRES(Locks::mutator_lock_) { 249 if (!IsValid() && !rti.IsValid()) { 250 // Invalid types are equal. 251 return true; 252 } 253 if (!IsValid() || !rti.IsValid()) { 254 // One is valid, the other not. 255 return false; 256 } 257 return IsExact() == rti.IsExact() 258 && GetTypeHandle().Get() == rti.GetTypeHandle().Get(); 259 } 260 261 private: 262 ReferenceTypeInfo() : type_handle_(TypeHandle()), is_exact_(false) {} 263 ReferenceTypeInfo(TypeHandle type_handle, bool is_exact) 264 : type_handle_(type_handle), is_exact_(is_exact) { } 265 266 // The class of the object. 267 TypeHandle type_handle_; 268 // Whether or not the type is exact or a superclass of the actual type. 269 // Whether or not we have any information about this type. 270 bool is_exact_; 271 }; 272 273 std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs); 274 275 // Control-flow graph of a method. Contains a list of basic blocks. 276 class HGraph : public ArenaObject<kArenaAllocGraph> { 277 public: 278 HGraph(ArenaAllocator* arena, 279 const DexFile& dex_file, 280 uint32_t method_idx, 281 bool should_generate_constructor_barrier, 282 InstructionSet instruction_set, 283 InvokeType invoke_type = kInvalidInvokeType, 284 bool debuggable = false, 285 bool osr = false, 286 int start_instruction_id = 0) 287 : arena_(arena), 288 blocks_(arena->Adapter(kArenaAllocBlockList)), 289 reverse_post_order_(arena->Adapter(kArenaAllocReversePostOrder)), 290 linear_order_(arena->Adapter(kArenaAllocLinearOrder)), 291 entry_block_(nullptr), 292 exit_block_(nullptr), 293 maximum_number_of_out_vregs_(0), 294 number_of_vregs_(0), 295 number_of_in_vregs_(0), 296 temporaries_vreg_slots_(0), 297 has_bounds_checks_(false), 298 has_try_catch_(false), 299 has_irreducible_loops_(false), 300 debuggable_(debuggable), 301 current_instruction_id_(start_instruction_id), 302 dex_file_(dex_file), 303 method_idx_(method_idx), 304 invoke_type_(invoke_type), 305 in_ssa_form_(false), 306 should_generate_constructor_barrier_(should_generate_constructor_barrier), 307 instruction_set_(instruction_set), 308 cached_null_constant_(nullptr), 309 cached_int_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)), 310 cached_float_constants_(std::less<int32_t>(), arena->Adapter(kArenaAllocConstantsMap)), 311 cached_long_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)), 312 cached_double_constants_(std::less<int64_t>(), arena->Adapter(kArenaAllocConstantsMap)), 313 cached_current_method_(nullptr), 314 inexact_object_rti_(ReferenceTypeInfo::CreateInvalid()), 315 osr_(osr) { 316 blocks_.reserve(kDefaultNumberOfBlocks); 317 } 318 319 // Acquires and stores RTI of inexact Object to be used when creating HNullConstant. 320 void InitializeInexactObjectRTI(StackHandleScopeCollection* handles); 321 322 ArenaAllocator* GetArena() const { return arena_; } 323 const ArenaVector<HBasicBlock*>& GetBlocks() const { return blocks_; } 324 325 bool IsInSsaForm() const { return in_ssa_form_; } 326 void SetInSsaForm() { in_ssa_form_ = true; } 327 328 HBasicBlock* GetEntryBlock() const { return entry_block_; } 329 HBasicBlock* GetExitBlock() const { return exit_block_; } 330 bool HasExitBlock() const { return exit_block_ != nullptr; } 331 332 void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; } 333 void SetExitBlock(HBasicBlock* block) { exit_block_ = block; } 334 335 void AddBlock(HBasicBlock* block); 336 337 void ComputeDominanceInformation(); 338 void ClearDominanceInformation(); 339 void ClearLoopInformation(); 340 void FindBackEdges(ArenaBitVector* visited); 341 GraphAnalysisResult BuildDominatorTree(); 342 void SimplifyCFG(); 343 void SimplifyCatchBlocks(); 344 345 // Analyze all natural loops in this graph. Returns a code specifying that it 346 // was successful or the reason for failure. The method will fail if a loop 347 // is a throw-catch loop, i.e. the header is a catch block. 348 GraphAnalysisResult AnalyzeLoops() const; 349 350 // Iterate over blocks to compute try block membership. Needs reverse post 351 // order and loop information. 352 void ComputeTryBlockInformation(); 353 354 // Inline this graph in `outer_graph`, replacing the given `invoke` instruction. 355 // Returns the instruction to replace the invoke expression or null if the 356 // invoke is for a void method. Note that the caller is responsible for replacing 357 // and removing the invoke instruction. 358 HInstruction* InlineInto(HGraph* outer_graph, HInvoke* invoke); 359 360 // Update the loop and try membership of `block`, which was spawned from `reference`. 361 // In case `reference` is a back edge, `replace_if_back_edge` notifies whether `block` 362 // should be the new back edge. 363 void UpdateLoopAndTryInformationOfNewBlock(HBasicBlock* block, 364 HBasicBlock* reference, 365 bool replace_if_back_edge); 366 367 // Need to add a couple of blocks to test if the loop body is entered and 368 // put deoptimization instructions, etc. 369 void TransformLoopHeaderForBCE(HBasicBlock* header); 370 371 // Removes `block` from the graph. Assumes `block` has been disconnected from 372 // other blocks and has no instructions or phis. 373 void DeleteDeadEmptyBlock(HBasicBlock* block); 374 375 // Splits the edge between `block` and `successor` while preserving the 376 // indices in the predecessor/successor lists. If there are multiple edges 377 // between the blocks, the lowest indices are used. 378 // Returns the new block which is empty and has the same dex pc as `successor`. 379 HBasicBlock* SplitEdge(HBasicBlock* block, HBasicBlock* successor); 380 381 void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor); 382 void SimplifyLoop(HBasicBlock* header); 383 384 int32_t GetNextInstructionId() { 385 DCHECK_NE(current_instruction_id_, INT32_MAX); 386 return current_instruction_id_++; 387 } 388 389 int32_t GetCurrentInstructionId() const { 390 return current_instruction_id_; 391 } 392 393 void SetCurrentInstructionId(int32_t id) { 394 DCHECK_GE(id, current_instruction_id_); 395 current_instruction_id_ = id; 396 } 397 398 uint16_t GetMaximumNumberOfOutVRegs() const { 399 return maximum_number_of_out_vregs_; 400 } 401 402 void SetMaximumNumberOfOutVRegs(uint16_t new_value) { 403 maximum_number_of_out_vregs_ = new_value; 404 } 405 406 void UpdateMaximumNumberOfOutVRegs(uint16_t other_value) { 407 maximum_number_of_out_vregs_ = std::max(maximum_number_of_out_vregs_, other_value); 408 } 409 410 void UpdateTemporariesVRegSlots(size_t slots) { 411 temporaries_vreg_slots_ = std::max(slots, temporaries_vreg_slots_); 412 } 413 414 size_t GetTemporariesVRegSlots() const { 415 DCHECK(!in_ssa_form_); 416 return temporaries_vreg_slots_; 417 } 418 419 void SetNumberOfVRegs(uint16_t number_of_vregs) { 420 number_of_vregs_ = number_of_vregs; 421 } 422 423 uint16_t GetNumberOfVRegs() const { 424 return number_of_vregs_; 425 } 426 427 void SetNumberOfInVRegs(uint16_t value) { 428 number_of_in_vregs_ = value; 429 } 430 431 uint16_t GetNumberOfInVRegs() const { 432 return number_of_in_vregs_; 433 } 434 435 uint16_t GetNumberOfLocalVRegs() const { 436 DCHECK(!in_ssa_form_); 437 return number_of_vregs_ - number_of_in_vregs_; 438 } 439 440 const ArenaVector<HBasicBlock*>& GetReversePostOrder() const { 441 return reverse_post_order_; 442 } 443 444 const ArenaVector<HBasicBlock*>& GetLinearOrder() const { 445 return linear_order_; 446 } 447 448 bool HasBoundsChecks() const { 449 return has_bounds_checks_; 450 } 451 452 void SetHasBoundsChecks(bool value) { 453 has_bounds_checks_ = value; 454 } 455 456 bool ShouldGenerateConstructorBarrier() const { 457 return should_generate_constructor_barrier_; 458 } 459 460 bool IsDebuggable() const { return debuggable_; } 461 462 // Returns a constant of the given type and value. If it does not exist 463 // already, it is created and inserted into the graph. This method is only for 464 // integral types. 465 HConstant* GetConstant(Primitive::Type type, int64_t value, uint32_t dex_pc = kNoDexPc); 466 467 // TODO: This is problematic for the consistency of reference type propagation 468 // because it can be created anytime after the pass and thus it will be left 469 // with an invalid type. 470 HNullConstant* GetNullConstant(uint32_t dex_pc = kNoDexPc); 471 472 HIntConstant* GetIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) { 473 return CreateConstant(value, &cached_int_constants_, dex_pc); 474 } 475 HLongConstant* GetLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) { 476 return CreateConstant(value, &cached_long_constants_, dex_pc); 477 } 478 HFloatConstant* GetFloatConstant(float value, uint32_t dex_pc = kNoDexPc) { 479 return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_, dex_pc); 480 } 481 HDoubleConstant* GetDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) { 482 return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_, dex_pc); 483 } 484 485 HCurrentMethod* GetCurrentMethod(); 486 487 const DexFile& GetDexFile() const { 488 return dex_file_; 489 } 490 491 uint32_t GetMethodIdx() const { 492 return method_idx_; 493 } 494 495 InvokeType GetInvokeType() const { 496 return invoke_type_; 497 } 498 499 InstructionSet GetInstructionSet() const { 500 return instruction_set_; 501 } 502 503 bool IsCompilingOsr() const { return osr_; } 504 505 bool HasTryCatch() const { return has_try_catch_; } 506 void SetHasTryCatch(bool value) { has_try_catch_ = value; } 507 508 bool HasIrreducibleLoops() const { return has_irreducible_loops_; } 509 void SetHasIrreducibleLoops(bool value) { has_irreducible_loops_ = value; } 510 511 ArtMethod* GetArtMethod() const { return art_method_; } 512 void SetArtMethod(ArtMethod* method) { art_method_ = method; } 513 514 // Returns an instruction with the opposite boolean value from 'cond'. 515 // The instruction has been inserted into the graph, either as a constant, or 516 // before cursor. 517 HInstruction* InsertOppositeCondition(HInstruction* cond, HInstruction* cursor); 518 519 ReferenceTypeInfo GetInexactObjectRti() const { return inexact_object_rti_; } 520 521 private: 522 void RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visited) const; 523 void RemoveDeadBlocks(const ArenaBitVector& visited); 524 525 template <class InstructionType, typename ValueType> 526 InstructionType* CreateConstant(ValueType value, 527 ArenaSafeMap<ValueType, InstructionType*>* cache, 528 uint32_t dex_pc = kNoDexPc) { 529 // Try to find an existing constant of the given value. 530 InstructionType* constant = nullptr; 531 auto cached_constant = cache->find(value); 532 if (cached_constant != cache->end()) { 533 constant = cached_constant->second; 534 } 535 536 // If not found or previously deleted, create and cache a new instruction. 537 // Don't bother reviving a previously deleted instruction, for simplicity. 538 if (constant == nullptr || constant->GetBlock() == nullptr) { 539 constant = new (arena_) InstructionType(value, dex_pc); 540 cache->Overwrite(value, constant); 541 InsertConstant(constant); 542 } 543 return constant; 544 } 545 546 void InsertConstant(HConstant* instruction); 547 548 // Cache a float constant into the graph. This method should only be 549 // called by the SsaBuilder when creating "equivalent" instructions. 550 void CacheFloatConstant(HFloatConstant* constant); 551 552 // See CacheFloatConstant comment. 553 void CacheDoubleConstant(HDoubleConstant* constant); 554 555 ArenaAllocator* const arena_; 556 557 // List of blocks in insertion order. 558 ArenaVector<HBasicBlock*> blocks_; 559 560 // List of blocks to perform a reverse post order tree traversal. 561 ArenaVector<HBasicBlock*> reverse_post_order_; 562 563 // List of blocks to perform a linear order tree traversal. 564 ArenaVector<HBasicBlock*> linear_order_; 565 566 HBasicBlock* entry_block_; 567 HBasicBlock* exit_block_; 568 569 // The maximum number of virtual registers arguments passed to a HInvoke in this graph. 570 uint16_t maximum_number_of_out_vregs_; 571 572 // The number of virtual registers in this method. Contains the parameters. 573 uint16_t number_of_vregs_; 574 575 // The number of virtual registers used by parameters of this method. 576 uint16_t number_of_in_vregs_; 577 578 // Number of vreg size slots that the temporaries use (used in baseline compiler). 579 size_t temporaries_vreg_slots_; 580 581 // Has bounds checks. We can totally skip BCE if it's false. 582 bool has_bounds_checks_; 583 584 // Flag whether there are any try/catch blocks in the graph. We will skip 585 // try/catch-related passes if false. 586 bool has_try_catch_; 587 588 // Flag whether there are any irreducible loops in the graph. 589 bool has_irreducible_loops_; 590 591 // Indicates whether the graph should be compiled in a way that 592 // ensures full debuggability. If false, we can apply more 593 // aggressive optimizations that may limit the level of debugging. 594 const bool debuggable_; 595 596 // The current id to assign to a newly added instruction. See HInstruction.id_. 597 int32_t current_instruction_id_; 598 599 // The dex file from which the method is from. 600 const DexFile& dex_file_; 601 602 // The method index in the dex file. 603 const uint32_t method_idx_; 604 605 // If inlined, this encodes how the callee is being invoked. 606 const InvokeType invoke_type_; 607 608 // Whether the graph has been transformed to SSA form. Only used 609 // in debug mode to ensure we are not using properties only valid 610 // for non-SSA form (like the number of temporaries). 611 bool in_ssa_form_; 612 613 const bool should_generate_constructor_barrier_; 614 615 const InstructionSet instruction_set_; 616 617 // Cached constants. 618 HNullConstant* cached_null_constant_; 619 ArenaSafeMap<int32_t, HIntConstant*> cached_int_constants_; 620 ArenaSafeMap<int32_t, HFloatConstant*> cached_float_constants_; 621 ArenaSafeMap<int64_t, HLongConstant*> cached_long_constants_; 622 ArenaSafeMap<int64_t, HDoubleConstant*> cached_double_constants_; 623 624 HCurrentMethod* cached_current_method_; 625 626 // The ArtMethod this graph is for. Note that for AOT, it may be null, 627 // for example for methods whose declaring class could not be resolved 628 // (such as when the superclass could not be found). 629 ArtMethod* art_method_; 630 631 // Keep the RTI of inexact Object to avoid having to pass stack handle 632 // collection pointer to passes which may create NullConstant. 633 ReferenceTypeInfo inexact_object_rti_; 634 635 // Whether we are compiling this graph for on stack replacement: this will 636 // make all loops seen as irreducible and emit special stack maps to mark 637 // compiled code entries which the interpreter can directly jump to. 638 const bool osr_; 639 640 friend class SsaBuilder; // For caching constants. 641 friend class SsaLivenessAnalysis; // For the linear order. 642 friend class HInliner; // For the reverse post order. 643 ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1); 644 DISALLOW_COPY_AND_ASSIGN(HGraph); 645 }; 646 647 class HLoopInformation : public ArenaObject<kArenaAllocLoopInfo> { 648 public: 649 HLoopInformation(HBasicBlock* header, HGraph* graph) 650 : header_(header), 651 suspend_check_(nullptr), 652 irreducible_(false), 653 contains_irreducible_loop_(false), 654 back_edges_(graph->GetArena()->Adapter(kArenaAllocLoopInfoBackEdges)), 655 // Make bit vector growable, as the number of blocks may change. 656 blocks_(graph->GetArena(), graph->GetBlocks().size(), true, kArenaAllocLoopInfoBackEdges) { 657 back_edges_.reserve(kDefaultNumberOfBackEdges); 658 } 659 660 bool IsIrreducible() const { return irreducible_; } 661 bool ContainsIrreducibleLoop() const { return contains_irreducible_loop_; } 662 663 void Dump(std::ostream& os); 664 665 HBasicBlock* GetHeader() const { 666 return header_; 667 } 668 669 void SetHeader(HBasicBlock* block) { 670 header_ = block; 671 } 672 673 HSuspendCheck* GetSuspendCheck() const { return suspend_check_; } 674 void SetSuspendCheck(HSuspendCheck* check) { suspend_check_ = check; } 675 bool HasSuspendCheck() const { return suspend_check_ != nullptr; } 676 677 void AddBackEdge(HBasicBlock* back_edge) { 678 back_edges_.push_back(back_edge); 679 } 680 681 void RemoveBackEdge(HBasicBlock* back_edge) { 682 RemoveElement(back_edges_, back_edge); 683 } 684 685 bool IsBackEdge(const HBasicBlock& block) const { 686 return ContainsElement(back_edges_, &block); 687 } 688 689 size_t NumberOfBackEdges() const { 690 return back_edges_.size(); 691 } 692 693 HBasicBlock* GetPreHeader() const; 694 695 const ArenaVector<HBasicBlock*>& GetBackEdges() const { 696 return back_edges_; 697 } 698 699 // Returns the lifetime position of the back edge that has the 700 // greatest lifetime position. 701 size_t GetLifetimeEnd() const; 702 703 void ReplaceBackEdge(HBasicBlock* existing, HBasicBlock* new_back_edge) { 704 ReplaceElement(back_edges_, existing, new_back_edge); 705 } 706 707 // Finds blocks that are part of this loop. 708 void Populate(); 709 710 // Returns whether this loop information contains `block`. 711 // Note that this loop information *must* be populated before entering this function. 712 bool Contains(const HBasicBlock& block) const; 713 714 // Returns whether this loop information is an inner loop of `other`. 715 // Note that `other` *must* be populated before entering this function. 716 bool IsIn(const HLoopInformation& other) const; 717 718 // Returns true if instruction is not defined within this loop. 719 bool IsDefinedOutOfTheLoop(HInstruction* instruction) const; 720 721 const ArenaBitVector& GetBlocks() const { return blocks_; } 722 723 void Add(HBasicBlock* block); 724 void Remove(HBasicBlock* block); 725 726 void ClearAllBlocks() { 727 blocks_.ClearAllBits(); 728 } 729 730 bool HasBackEdgeNotDominatedByHeader() const; 731 732 bool IsPopulated() const { 733 return blocks_.GetHighestBitSet() != -1; 734 } 735 736 bool DominatesAllBackEdges(HBasicBlock* block); 737 738 private: 739 // Internal recursive implementation of `Populate`. 740 void PopulateRecursive(HBasicBlock* block); 741 void PopulateIrreducibleRecursive(HBasicBlock* block, ArenaBitVector* finalized); 742 743 HBasicBlock* header_; 744 HSuspendCheck* suspend_check_; 745 bool irreducible_; 746 bool contains_irreducible_loop_; 747 ArenaVector<HBasicBlock*> back_edges_; 748 ArenaBitVector blocks_; 749 750 DISALLOW_COPY_AND_ASSIGN(HLoopInformation); 751 }; 752 753 // Stores try/catch information for basic blocks. 754 // Note that HGraph is constructed so that catch blocks cannot simultaneously 755 // be try blocks. 756 class TryCatchInformation : public ArenaObject<kArenaAllocTryCatchInfo> { 757 public: 758 // Try block information constructor. 759 explicit TryCatchInformation(const HTryBoundary& try_entry) 760 : try_entry_(&try_entry), 761 catch_dex_file_(nullptr), 762 catch_type_index_(DexFile::kDexNoIndex16) { 763 DCHECK(try_entry_ != nullptr); 764 } 765 766 // Catch block information constructor. 767 TryCatchInformation(uint16_t catch_type_index, const DexFile& dex_file) 768 : try_entry_(nullptr), 769 catch_dex_file_(&dex_file), 770 catch_type_index_(catch_type_index) {} 771 772 bool IsTryBlock() const { return try_entry_ != nullptr; } 773 774 const HTryBoundary& GetTryEntry() const { 775 DCHECK(IsTryBlock()); 776 return *try_entry_; 777 } 778 779 bool IsCatchBlock() const { return catch_dex_file_ != nullptr; } 780 781 bool IsCatchAllTypeIndex() const { 782 DCHECK(IsCatchBlock()); 783 return catch_type_index_ == DexFile::kDexNoIndex16; 784 } 785 786 uint16_t GetCatchTypeIndex() const { 787 DCHECK(IsCatchBlock()); 788 return catch_type_index_; 789 } 790 791 const DexFile& GetCatchDexFile() const { 792 DCHECK(IsCatchBlock()); 793 return *catch_dex_file_; 794 } 795 796 private: 797 // One of possibly several TryBoundary instructions entering the block's try. 798 // Only set for try blocks. 799 const HTryBoundary* try_entry_; 800 801 // Exception type information. Only set for catch blocks. 802 const DexFile* catch_dex_file_; 803 const uint16_t catch_type_index_; 804 }; 805 806 static constexpr size_t kNoLifetime = -1; 807 static constexpr uint32_t kInvalidBlockId = static_cast<uint32_t>(-1); 808 809 // A block in a method. Contains the list of instructions represented 810 // as a double linked list. Each block knows its predecessors and 811 // successors. 812 813 class HBasicBlock : public ArenaObject<kArenaAllocBasicBlock> { 814 public: 815 HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc) 816 : graph_(graph), 817 predecessors_(graph->GetArena()->Adapter(kArenaAllocPredecessors)), 818 successors_(graph->GetArena()->Adapter(kArenaAllocSuccessors)), 819 loop_information_(nullptr), 820 dominator_(nullptr), 821 dominated_blocks_(graph->GetArena()->Adapter(kArenaAllocDominated)), 822 block_id_(kInvalidBlockId), 823 dex_pc_(dex_pc), 824 lifetime_start_(kNoLifetime), 825 lifetime_end_(kNoLifetime), 826 try_catch_information_(nullptr) { 827 predecessors_.reserve(kDefaultNumberOfPredecessors); 828 successors_.reserve(kDefaultNumberOfSuccessors); 829 dominated_blocks_.reserve(kDefaultNumberOfDominatedBlocks); 830 } 831 832 const ArenaVector<HBasicBlock*>& GetPredecessors() const { 833 return predecessors_; 834 } 835 836 const ArenaVector<HBasicBlock*>& GetSuccessors() const { 837 return successors_; 838 } 839 840 ArrayRef<HBasicBlock* const> GetNormalSuccessors() const; 841 ArrayRef<HBasicBlock* const> GetExceptionalSuccessors() const; 842 843 bool HasSuccessor(const HBasicBlock* block, size_t start_from = 0u) { 844 return ContainsElement(successors_, block, start_from); 845 } 846 847 const ArenaVector<HBasicBlock*>& GetDominatedBlocks() const { 848 return dominated_blocks_; 849 } 850 851 bool IsEntryBlock() const { 852 return graph_->GetEntryBlock() == this; 853 } 854 855 bool IsExitBlock() const { 856 return graph_->GetExitBlock() == this; 857 } 858 859 bool IsSingleGoto() const; 860 bool IsSingleTryBoundary() const; 861 862 // Returns true if this block emits nothing but a jump. 863 bool IsSingleJump() const { 864 HLoopInformation* loop_info = GetLoopInformation(); 865 return (IsSingleGoto() || IsSingleTryBoundary()) 866 // Back edges generate a suspend check. 867 && (loop_info == nullptr || !loop_info->IsBackEdge(*this)); 868 } 869 870 void AddBackEdge(HBasicBlock* back_edge) { 871 if (loop_information_ == nullptr) { 872 loop_information_ = new (graph_->GetArena()) HLoopInformation(this, graph_); 873 } 874 DCHECK_EQ(loop_information_->GetHeader(), this); 875 loop_information_->AddBackEdge(back_edge); 876 } 877 878 HGraph* GetGraph() const { return graph_; } 879 void SetGraph(HGraph* graph) { graph_ = graph; } 880 881 uint32_t GetBlockId() const { return block_id_; } 882 void SetBlockId(int id) { block_id_ = id; } 883 uint32_t GetDexPc() const { return dex_pc_; } 884 885 HBasicBlock* GetDominator() const { return dominator_; } 886 void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; } 887 void AddDominatedBlock(HBasicBlock* block) { dominated_blocks_.push_back(block); } 888 889 void RemoveDominatedBlock(HBasicBlock* block) { 890 RemoveElement(dominated_blocks_, block); 891 } 892 893 void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) { 894 ReplaceElement(dominated_blocks_, existing, new_block); 895 } 896 897 void ClearDominanceInformation(); 898 899 int NumberOfBackEdges() const { 900 return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0; 901 } 902 903 HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; } 904 HInstruction* GetLastInstruction() const { return instructions_.last_instruction_; } 905 const HInstructionList& GetInstructions() const { return instructions_; } 906 HInstruction* GetFirstPhi() const { return phis_.first_instruction_; } 907 HInstruction* GetLastPhi() const { return phis_.last_instruction_; } 908 const HInstructionList& GetPhis() const { return phis_; } 909 910 HInstruction* GetFirstInstructionDisregardMoves() const; 911 912 void AddSuccessor(HBasicBlock* block) { 913 successors_.push_back(block); 914 block->predecessors_.push_back(this); 915 } 916 917 void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock* new_block) { 918 size_t successor_index = GetSuccessorIndexOf(existing); 919 existing->RemovePredecessor(this); 920 new_block->predecessors_.push_back(this); 921 successors_[successor_index] = new_block; 922 } 923 924 void ReplacePredecessor(HBasicBlock* existing, HBasicBlock* new_block) { 925 size_t predecessor_index = GetPredecessorIndexOf(existing); 926 existing->RemoveSuccessor(this); 927 new_block->successors_.push_back(this); 928 predecessors_[predecessor_index] = new_block; 929 } 930 931 // Insert `this` between `predecessor` and `successor. This method 932 // preserves the indicies, and will update the first edge found between 933 // `predecessor` and `successor`. 934 void InsertBetween(HBasicBlock* predecessor, HBasicBlock* successor) { 935 size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor); 936 size_t successor_index = predecessor->GetSuccessorIndexOf(successor); 937 successor->predecessors_[predecessor_index] = this; 938 predecessor->successors_[successor_index] = this; 939 successors_.push_back(successor); 940 predecessors_.push_back(predecessor); 941 } 942 943 void RemovePredecessor(HBasicBlock* block) { 944 predecessors_.erase(predecessors_.begin() + GetPredecessorIndexOf(block)); 945 } 946 947 void RemoveSuccessor(HBasicBlock* block) { 948 successors_.erase(successors_.begin() + GetSuccessorIndexOf(block)); 949 } 950 951 void ClearAllPredecessors() { 952 predecessors_.clear(); 953 } 954 955 void AddPredecessor(HBasicBlock* block) { 956 predecessors_.push_back(block); 957 block->successors_.push_back(this); 958 } 959 960 void SwapPredecessors() { 961 DCHECK_EQ(predecessors_.size(), 2u); 962 std::swap(predecessors_[0], predecessors_[1]); 963 } 964 965 void SwapSuccessors() { 966 DCHECK_EQ(successors_.size(), 2u); 967 std::swap(successors_[0], successors_[1]); 968 } 969 970 size_t GetPredecessorIndexOf(HBasicBlock* predecessor) const { 971 return IndexOfElement(predecessors_, predecessor); 972 } 973 974 size_t GetSuccessorIndexOf(HBasicBlock* successor) const { 975 return IndexOfElement(successors_, successor); 976 } 977 978 HBasicBlock* GetSinglePredecessor() const { 979 DCHECK_EQ(GetPredecessors().size(), 1u); 980 return GetPredecessors()[0]; 981 } 982 983 HBasicBlock* GetSingleSuccessor() const { 984 DCHECK_EQ(GetSuccessors().size(), 1u); 985 return GetSuccessors()[0]; 986 } 987 988 // Returns whether the first occurrence of `predecessor` in the list of 989 // predecessors is at index `idx`. 990 bool IsFirstIndexOfPredecessor(HBasicBlock* predecessor, size_t idx) const { 991 DCHECK_EQ(GetPredecessors()[idx], predecessor); 992 return GetPredecessorIndexOf(predecessor) == idx; 993 } 994 995 // Create a new block between this block and its predecessors. The new block 996 // is added to the graph, all predecessor edges are relinked to it and an edge 997 // is created to `this`. Returns the new empty block. Reverse post order or 998 // loop and try/catch information are not updated. 999 HBasicBlock* CreateImmediateDominator(); 1000 1001 // Split the block into two blocks just before `cursor`. Returns the newly 1002 // created, latter block. Note that this method will add the block to the 1003 // graph, create a Goto at the end of the former block and will create an edge 1004 // between the blocks. It will not, however, update the reverse post order or 1005 // loop and try/catch information. 1006 HBasicBlock* SplitBefore(HInstruction* cursor); 1007 1008 // Split the block into two blocks just before `cursor`. Returns the newly 1009 // created block. Note that this method just updates raw block information, 1010 // like predecessors, successors, dominators, and instruction list. It does not 1011 // update the graph, reverse post order, loop information, nor make sure the 1012 // blocks are consistent (for example ending with a control flow instruction). 1013 HBasicBlock* SplitBeforeForInlining(HInstruction* cursor); 1014 1015 // Similar to `SplitBeforeForInlining` but does it after `cursor`. 1016 HBasicBlock* SplitAfterForInlining(HInstruction* cursor); 1017 1018 // Merge `other` at the end of `this`. Successors and dominated blocks of 1019 // `other` are changed to be successors and dominated blocks of `this`. Note 1020 // that this method does not update the graph, reverse post order, loop 1021 // information, nor make sure the blocks are consistent (for example ending 1022 // with a control flow instruction). 1023 void MergeWithInlined(HBasicBlock* other); 1024 1025 // Replace `this` with `other`. Predecessors, successors, and dominated blocks 1026 // of `this` are moved to `other`. 1027 // Note that this method does not update the graph, reverse post order, loop 1028 // information, nor make sure the blocks are consistent (for example ending 1029 // with a control flow instruction). 1030 void ReplaceWith(HBasicBlock* other); 1031 1032 // Merge `other` at the end of `this`. This method updates loops, reverse post 1033 // order, links to predecessors, successors, dominators and deletes the block 1034 // from the graph. The two blocks must be successive, i.e. `this` the only 1035 // predecessor of `other` and vice versa. 1036 void MergeWith(HBasicBlock* other); 1037 1038 // Disconnects `this` from all its predecessors, successors and dominator, 1039 // removes it from all loops it is included in and eventually from the graph. 1040 // The block must not dominate any other block. Predecessors and successors 1041 // are safely updated. 1042 void DisconnectAndDelete(); 1043 1044 void AddInstruction(HInstruction* instruction); 1045 // Insert `instruction` before/after an existing instruction `cursor`. 1046 void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor); 1047 void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor); 1048 // Replace instruction `initial` with `replacement` within this block. 1049 void ReplaceAndRemoveInstructionWith(HInstruction* initial, 1050 HInstruction* replacement); 1051 void MoveInstructionBefore(HInstruction* insn, HInstruction* cursor); 1052 void AddPhi(HPhi* phi); 1053 void InsertPhiAfter(HPhi* instruction, HPhi* cursor); 1054 // RemoveInstruction and RemovePhi delete a given instruction from the respective 1055 // instruction list. With 'ensure_safety' set to true, it verifies that the 1056 // instruction is not in use and removes it from the use lists of its inputs. 1057 void RemoveInstruction(HInstruction* instruction, bool ensure_safety = true); 1058 void RemovePhi(HPhi* phi, bool ensure_safety = true); 1059 void RemoveInstructionOrPhi(HInstruction* instruction, bool ensure_safety = true); 1060 1061 bool IsLoopHeader() const { 1062 return IsInLoop() && (loop_information_->GetHeader() == this); 1063 } 1064 1065 bool IsLoopPreHeaderFirstPredecessor() const { 1066 DCHECK(IsLoopHeader()); 1067 return GetPredecessors()[0] == GetLoopInformation()->GetPreHeader(); 1068 } 1069 1070 bool IsFirstPredecessorBackEdge() const { 1071 DCHECK(IsLoopHeader()); 1072 return GetLoopInformation()->IsBackEdge(*GetPredecessors()[0]); 1073 } 1074 1075 HLoopInformation* GetLoopInformation() const { 1076 return loop_information_; 1077 } 1078 1079 // Set the loop_information_ on this block. Overrides the current 1080 // loop_information if it is an outer loop of the passed loop information. 1081 // Note that this method is called while creating the loop information. 1082 void SetInLoop(HLoopInformation* info) { 1083 if (IsLoopHeader()) { 1084 // Nothing to do. This just means `info` is an outer loop. 1085 } else if (!IsInLoop()) { 1086 loop_information_ = info; 1087 } else if (loop_information_->Contains(*info->GetHeader())) { 1088 // Block is currently part of an outer loop. Make it part of this inner loop. 1089 // Note that a non loop header having a loop information means this loop information 1090 // has already been populated 1091 loop_information_ = info; 1092 } else { 1093 // Block is part of an inner loop. Do not update the loop information. 1094 // Note that we cannot do the check `info->Contains(loop_information_)->GetHeader()` 1095 // at this point, because this method is being called while populating `info`. 1096 } 1097 } 1098 1099 // Raw update of the loop information. 1100 void SetLoopInformation(HLoopInformation* info) { 1101 loop_information_ = info; 1102 } 1103 1104 bool IsInLoop() const { return loop_information_ != nullptr; } 1105 1106 TryCatchInformation* GetTryCatchInformation() const { return try_catch_information_; } 1107 1108 void SetTryCatchInformation(TryCatchInformation* try_catch_information) { 1109 try_catch_information_ = try_catch_information; 1110 } 1111 1112 bool IsTryBlock() const { 1113 return try_catch_information_ != nullptr && try_catch_information_->IsTryBlock(); 1114 } 1115 1116 bool IsCatchBlock() const { 1117 return try_catch_information_ != nullptr && try_catch_information_->IsCatchBlock(); 1118 } 1119 1120 // Returns the try entry that this block's successors should have. They will 1121 // be in the same try, unless the block ends in a try boundary. In that case, 1122 // the appropriate try entry will be returned. 1123 const HTryBoundary* ComputeTryEntryOfSuccessors() const; 1124 1125 bool HasThrowingInstructions() const; 1126 1127 // Returns whether this block dominates the blocked passed as parameter. 1128 bool Dominates(HBasicBlock* block) const; 1129 1130 size_t GetLifetimeStart() const { return lifetime_start_; } 1131 size_t GetLifetimeEnd() const { return lifetime_end_; } 1132 1133 void SetLifetimeStart(size_t start) { lifetime_start_ = start; } 1134 void SetLifetimeEnd(size_t end) { lifetime_end_ = end; } 1135 1136 bool EndsWithControlFlowInstruction() const; 1137 bool EndsWithIf() const; 1138 bool EndsWithTryBoundary() const; 1139 bool HasSinglePhi() const; 1140 1141 private: 1142 HGraph* graph_; 1143 ArenaVector<HBasicBlock*> predecessors_; 1144 ArenaVector<HBasicBlock*> successors_; 1145 HInstructionList instructions_; 1146 HInstructionList phis_; 1147 HLoopInformation* loop_information_; 1148 HBasicBlock* dominator_; 1149 ArenaVector<HBasicBlock*> dominated_blocks_; 1150 uint32_t block_id_; 1151 // The dex program counter of the first instruction of this block. 1152 const uint32_t dex_pc_; 1153 size_t lifetime_start_; 1154 size_t lifetime_end_; 1155 TryCatchInformation* try_catch_information_; 1156 1157 friend class HGraph; 1158 friend class HInstruction; 1159 1160 DISALLOW_COPY_AND_ASSIGN(HBasicBlock); 1161 }; 1162 1163 // Iterates over the LoopInformation of all loops which contain 'block' 1164 // from the innermost to the outermost. 1165 class HLoopInformationOutwardIterator : public ValueObject { 1166 public: 1167 explicit HLoopInformationOutwardIterator(const HBasicBlock& block) 1168 : current_(block.GetLoopInformation()) {} 1169 1170 bool Done() const { return current_ == nullptr; } 1171 1172 void Advance() { 1173 DCHECK(!Done()); 1174 current_ = current_->GetPreHeader()->GetLoopInformation(); 1175 } 1176 1177 HLoopInformation* Current() const { 1178 DCHECK(!Done()); 1179 return current_; 1180 } 1181 1182 private: 1183 HLoopInformation* current_; 1184 1185 DISALLOW_COPY_AND_ASSIGN(HLoopInformationOutwardIterator); 1186 }; 1187 1188 #define FOR_EACH_CONCRETE_INSTRUCTION_COMMON(M) \ 1189 M(Above, Condition) \ 1190 M(AboveOrEqual, Condition) \ 1191 M(Add, BinaryOperation) \ 1192 M(And, BinaryOperation) \ 1193 M(ArrayGet, Instruction) \ 1194 M(ArrayLength, Instruction) \ 1195 M(ArraySet, Instruction) \ 1196 M(Below, Condition) \ 1197 M(BelowOrEqual, Condition) \ 1198 M(BooleanNot, UnaryOperation) \ 1199 M(BoundsCheck, Instruction) \ 1200 M(BoundType, Instruction) \ 1201 M(CheckCast, Instruction) \ 1202 M(ClassTableGet, Instruction) \ 1203 M(ClearException, Instruction) \ 1204 M(ClinitCheck, Instruction) \ 1205 M(Compare, BinaryOperation) \ 1206 M(CurrentMethod, Instruction) \ 1207 M(Deoptimize, Instruction) \ 1208 M(Div, BinaryOperation) \ 1209 M(DivZeroCheck, Instruction) \ 1210 M(DoubleConstant, Constant) \ 1211 M(Equal, Condition) \ 1212 M(Exit, Instruction) \ 1213 M(FloatConstant, Constant) \ 1214 M(Goto, Instruction) \ 1215 M(GreaterThan, Condition) \ 1216 M(GreaterThanOrEqual, Condition) \ 1217 M(If, Instruction) \ 1218 M(InstanceFieldGet, Instruction) \ 1219 M(InstanceFieldSet, Instruction) \ 1220 M(InstanceOf, Instruction) \ 1221 M(IntConstant, Constant) \ 1222 M(InvokeUnresolved, Invoke) \ 1223 M(InvokeInterface, Invoke) \ 1224 M(InvokeStaticOrDirect, Invoke) \ 1225 M(InvokeVirtual, Invoke) \ 1226 M(LessThan, Condition) \ 1227 M(LessThanOrEqual, Condition) \ 1228 M(LoadClass, Instruction) \ 1229 M(LoadException, Instruction) \ 1230 M(LoadString, Instruction) \ 1231 M(LongConstant, Constant) \ 1232 M(MemoryBarrier, Instruction) \ 1233 M(MonitorOperation, Instruction) \ 1234 M(Mul, BinaryOperation) \ 1235 M(NativeDebugInfo, Instruction) \ 1236 M(Neg, UnaryOperation) \ 1237 M(NewArray, Instruction) \ 1238 M(NewInstance, Instruction) \ 1239 M(Not, UnaryOperation) \ 1240 M(NotEqual, Condition) \ 1241 M(NullConstant, Instruction) \ 1242 M(NullCheck, Instruction) \ 1243 M(Or, BinaryOperation) \ 1244 M(PackedSwitch, Instruction) \ 1245 M(ParallelMove, Instruction) \ 1246 M(ParameterValue, Instruction) \ 1247 M(Phi, Instruction) \ 1248 M(Rem, BinaryOperation) \ 1249 M(Return, Instruction) \ 1250 M(ReturnVoid, Instruction) \ 1251 M(Ror, BinaryOperation) \ 1252 M(Shl, BinaryOperation) \ 1253 M(Shr, BinaryOperation) \ 1254 M(StaticFieldGet, Instruction) \ 1255 M(StaticFieldSet, Instruction) \ 1256 M(UnresolvedInstanceFieldGet, Instruction) \ 1257 M(UnresolvedInstanceFieldSet, Instruction) \ 1258 M(UnresolvedStaticFieldGet, Instruction) \ 1259 M(UnresolvedStaticFieldSet, Instruction) \ 1260 M(Select, Instruction) \ 1261 M(Sub, BinaryOperation) \ 1262 M(SuspendCheck, Instruction) \ 1263 M(Throw, Instruction) \ 1264 M(TryBoundary, Instruction) \ 1265 M(TypeConversion, Instruction) \ 1266 M(UShr, BinaryOperation) \ 1267 M(Xor, BinaryOperation) \ 1268 1269 /* 1270 * Instructions, shared across several (not all) architectures. 1271 */ 1272 #if !defined(ART_ENABLE_CODEGEN_arm) && !defined(ART_ENABLE_CODEGEN_arm64) 1273 #define FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) 1274 #else 1275 #define FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) \ 1276 M(BitwiseNegatedRight, Instruction) \ 1277 M(MultiplyAccumulate, Instruction) 1278 #endif 1279 1280 #ifndef ART_ENABLE_CODEGEN_arm 1281 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) 1282 #else 1283 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) \ 1284 M(ArmDexCacheArraysBase, Instruction) 1285 #endif 1286 1287 #ifndef ART_ENABLE_CODEGEN_arm64 1288 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) 1289 #else 1290 #define FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) \ 1291 M(Arm64DataProcWithShifterOp, Instruction) \ 1292 M(Arm64IntermediateAddress, Instruction) 1293 #endif 1294 1295 #define FOR_EACH_CONCRETE_INSTRUCTION_MIPS(M) 1296 1297 #define FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(M) 1298 1299 #ifndef ART_ENABLE_CODEGEN_x86 1300 #define FOR_EACH_CONCRETE_INSTRUCTION_X86(M) 1301 #else 1302 #define FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \ 1303 M(X86ComputeBaseMethodAddress, Instruction) \ 1304 M(X86LoadFromConstantTable, Instruction) \ 1305 M(X86FPNeg, Instruction) \ 1306 M(X86PackedSwitch, Instruction) 1307 #endif 1308 1309 #define FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) 1310 1311 #define FOR_EACH_CONCRETE_INSTRUCTION(M) \ 1312 FOR_EACH_CONCRETE_INSTRUCTION_COMMON(M) \ 1313 FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M) \ 1314 FOR_EACH_CONCRETE_INSTRUCTION_ARM(M) \ 1315 FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M) \ 1316 FOR_EACH_CONCRETE_INSTRUCTION_MIPS(M) \ 1317 FOR_EACH_CONCRETE_INSTRUCTION_MIPS64(M) \ 1318 FOR_EACH_CONCRETE_INSTRUCTION_X86(M) \ 1319 FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) 1320 1321 #define FOR_EACH_ABSTRACT_INSTRUCTION(M) \ 1322 M(Condition, BinaryOperation) \ 1323 M(Constant, Instruction) \ 1324 M(UnaryOperation, Instruction) \ 1325 M(BinaryOperation, Instruction) \ 1326 M(Invoke, Instruction) 1327 1328 #define FOR_EACH_INSTRUCTION(M) \ 1329 FOR_EACH_CONCRETE_INSTRUCTION(M) \ 1330 FOR_EACH_ABSTRACT_INSTRUCTION(M) 1331 1332 #define FORWARD_DECLARATION(type, super) class H##type; 1333 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 1334 #undef FORWARD_DECLARATION 1335 1336 #define DECLARE_INSTRUCTION(type) \ 1337 InstructionKind GetKindInternal() const OVERRIDE { return k##type; } \ 1338 const char* DebugName() const OVERRIDE { return #type; } \ 1339 bool InstructionTypeEquals(HInstruction* other) const OVERRIDE { \ 1340 return other->Is##type(); \ 1341 } \ 1342 void Accept(HGraphVisitor* visitor) OVERRIDE 1343 1344 #define DECLARE_ABSTRACT_INSTRUCTION(type) \ 1345 bool Is##type() const { return As##type() != nullptr; } \ 1346 const H##type* As##type() const { return this; } \ 1347 H##type* As##type() { return this; } 1348 1349 template <typename T> 1350 class HUseListNode : public ArenaObject<kArenaAllocUseListNode> { 1351 public: 1352 T GetUser() const { return user_; } 1353 size_t GetIndex() const { return index_; } 1354 void SetIndex(size_t index) { index_ = index; } 1355 1356 // Hook for the IntrusiveForwardList<>. 1357 // TODO: Hide this better. 1358 IntrusiveForwardListHook hook; 1359 1360 private: 1361 HUseListNode(T user, size_t index) 1362 : user_(user), index_(index) {} 1363 1364 T const user_; 1365 size_t index_; 1366 1367 friend class HInstruction; 1368 1369 DISALLOW_COPY_AND_ASSIGN(HUseListNode); 1370 }; 1371 1372 template <typename T> 1373 using HUseList = IntrusiveForwardList<HUseListNode<T>>; 1374 1375 // This class is used by HEnvironment and HInstruction classes to record the 1376 // instructions they use and pointers to the corresponding HUseListNodes kept 1377 // by the used instructions. 1378 template <typename T> 1379 class HUserRecord : public ValueObject { 1380 public: 1381 HUserRecord() : instruction_(nullptr), before_use_node_() {} 1382 explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), before_use_node_() {} 1383 1384 HUserRecord(const HUserRecord<T>& old_record, typename HUseList<T>::iterator before_use_node) 1385 : HUserRecord(old_record.instruction_, before_use_node) {} 1386 HUserRecord(HInstruction* instruction, typename HUseList<T>::iterator before_use_node) 1387 : instruction_(instruction), before_use_node_(before_use_node) { 1388 DCHECK(instruction_ != nullptr); 1389 } 1390 1391 HInstruction* GetInstruction() const { return instruction_; } 1392 typename HUseList<T>::iterator GetBeforeUseNode() const { return before_use_node_; } 1393 typename HUseList<T>::iterator GetUseNode() const { return ++GetBeforeUseNode(); } 1394 1395 private: 1396 // Instruction used by the user. 1397 HInstruction* instruction_; 1398 1399 // Iterator before the corresponding entry in the use list kept by 'instruction_'. 1400 typename HUseList<T>::iterator before_use_node_; 1401 }; 1402 1403 /** 1404 * Side-effects representation. 1405 * 1406 * For write/read dependences on fields/arrays, the dependence analysis uses 1407 * type disambiguation (e.g. a float field write cannot modify the value of an 1408 * integer field read) and the access type (e.g. a reference array write cannot 1409 * modify the value of a reference field read [although it may modify the 1410 * reference fetch prior to reading the field, which is represented by its own 1411 * write/read dependence]). The analysis makes conservative points-to 1412 * assumptions on reference types (e.g. two same typed arrays are assumed to be 1413 * the same, and any reference read depends on any reference read without 1414 * further regard of its type). 1415 * 1416 * The internal representation uses 38-bit and is described in the table below. 1417 * The first line indicates the side effect, and for field/array accesses the 1418 * second line indicates the type of the access (in the order of the 1419 * Primitive::Type enum). 1420 * The two numbered lines below indicate the bit position in the bitfield (read 1421 * vertically). 1422 * 1423 * |Depends on GC|ARRAY-R |FIELD-R |Can trigger GC|ARRAY-W |FIELD-W | 1424 * +-------------+---------+---------+--------------+---------+---------+ 1425 * | |DFJISCBZL|DFJISCBZL| |DFJISCBZL|DFJISCBZL| 1426 * | 3 |333333322|222222221| 1 |111111110|000000000| 1427 * | 7 |654321098|765432109| 8 |765432109|876543210| 1428 * 1429 * Note that, to ease the implementation, 'changes' bits are least significant 1430 * bits, while 'dependency' bits are most significant bits. 1431 */ 1432 class SideEffects : public ValueObject { 1433 public: 1434 SideEffects() : flags_(0) {} 1435 1436 static SideEffects None() { 1437 return SideEffects(0); 1438 } 1439 1440 static SideEffects All() { 1441 return SideEffects(kAllChangeBits | kAllDependOnBits); 1442 } 1443 1444 static SideEffects AllChanges() { 1445 return SideEffects(kAllChangeBits); 1446 } 1447 1448 static SideEffects AllDependencies() { 1449 return SideEffects(kAllDependOnBits); 1450 } 1451 1452 static SideEffects AllExceptGCDependency() { 1453 return AllWritesAndReads().Union(SideEffects::CanTriggerGC()); 1454 } 1455 1456 static SideEffects AllWritesAndReads() { 1457 return SideEffects(kAllWrites | kAllReads); 1458 } 1459 1460 static SideEffects AllWrites() { 1461 return SideEffects(kAllWrites); 1462 } 1463 1464 static SideEffects AllReads() { 1465 return SideEffects(kAllReads); 1466 } 1467 1468 static SideEffects FieldWriteOfType(Primitive::Type type, bool is_volatile) { 1469 return is_volatile 1470 ? AllWritesAndReads() 1471 : SideEffects(TypeFlagWithAlias(type, kFieldWriteOffset)); 1472 } 1473 1474 static SideEffects ArrayWriteOfType(Primitive::Type type) { 1475 return SideEffects(TypeFlagWithAlias(type, kArrayWriteOffset)); 1476 } 1477 1478 static SideEffects FieldReadOfType(Primitive::Type type, bool is_volatile) { 1479 return is_volatile 1480 ? AllWritesAndReads() 1481 : SideEffects(TypeFlagWithAlias(type, kFieldReadOffset)); 1482 } 1483 1484 static SideEffects ArrayReadOfType(Primitive::Type type) { 1485 return SideEffects(TypeFlagWithAlias(type, kArrayReadOffset)); 1486 } 1487 1488 static SideEffects CanTriggerGC() { 1489 return SideEffects(1ULL << kCanTriggerGCBit); 1490 } 1491 1492 static SideEffects DependsOnGC() { 1493 return SideEffects(1ULL << kDependsOnGCBit); 1494 } 1495 1496 // Combines the side-effects of this and the other. 1497 SideEffects Union(SideEffects other) const { 1498 return SideEffects(flags_ | other.flags_); 1499 } 1500 1501 SideEffects Exclusion(SideEffects other) const { 1502 return SideEffects(flags_ & ~other.flags_); 1503 } 1504 1505 void Add(SideEffects other) { 1506 flags_ |= other.flags_; 1507 } 1508 1509 bool Includes(SideEffects other) const { 1510 return (other.flags_ & flags_) == other.flags_; 1511 } 1512 1513 bool HasSideEffects() const { 1514 return (flags_ & kAllChangeBits); 1515 } 1516 1517 bool HasDependencies() const { 1518 return (flags_ & kAllDependOnBits); 1519 } 1520 1521 // Returns true if there are no side effects or dependencies. 1522 bool DoesNothing() const { 1523 return flags_ == 0; 1524 } 1525 1526 // Returns true if something is written. 1527 bool DoesAnyWrite() const { 1528 return (flags_ & kAllWrites); 1529 } 1530 1531 // Returns true if something is read. 1532 bool DoesAnyRead() const { 1533 return (flags_ & kAllReads); 1534 } 1535 1536 // Returns true if potentially everything is written and read 1537 // (every type and every kind of access). 1538 bool DoesAllReadWrite() const { 1539 return (flags_ & (kAllWrites | kAllReads)) == (kAllWrites | kAllReads); 1540 } 1541 1542 bool DoesAll() const { 1543 return flags_ == (kAllChangeBits | kAllDependOnBits); 1544 } 1545 1546 // Returns true if `this` may read something written by `other`. 1547 bool MayDependOn(SideEffects other) const { 1548 const uint64_t depends_on_flags = (flags_ & kAllDependOnBits) >> kChangeBits; 1549 return (other.flags_ & depends_on_flags); 1550 } 1551 1552 // Returns string representation of flags (for debugging only). 1553 // Format: |x|DFJISCBZL|DFJISCBZL|y|DFJISCBZL|DFJISCBZL| 1554 std::string ToString() const { 1555 std::string flags = "|"; 1556 for (int s = kLastBit; s >= 0; s--) { 1557 bool current_bit_is_set = ((flags_ >> s) & 1) != 0; 1558 if ((s == kDependsOnGCBit) || (s == kCanTriggerGCBit)) { 1559 // This is a bit for the GC side effect. 1560 if (current_bit_is_set) { 1561 flags += "GC"; 1562 } 1563 flags += "|"; 1564 } else { 1565 // This is a bit for the array/field analysis. 1566 // The underscore character stands for the 'can trigger GC' bit. 1567 static const char *kDebug = "LZBCSIJFDLZBCSIJFD_LZBCSIJFDLZBCSIJFD"; 1568 if (current_bit_is_set) { 1569 flags += kDebug[s]; 1570 } 1571 if ((s == kFieldWriteOffset) || (s == kArrayWriteOffset) || 1572 (s == kFieldReadOffset) || (s == kArrayReadOffset)) { 1573 flags += "|"; 1574 } 1575 } 1576 } 1577 return flags; 1578 } 1579 1580 bool Equals(const SideEffects& other) const { return flags_ == other.flags_; } 1581 1582 private: 1583 static constexpr int kFieldArrayAnalysisBits = 9; 1584 1585 static constexpr int kFieldWriteOffset = 0; 1586 static constexpr int kArrayWriteOffset = kFieldWriteOffset + kFieldArrayAnalysisBits; 1587 static constexpr int kLastBitForWrites = kArrayWriteOffset + kFieldArrayAnalysisBits - 1; 1588 static constexpr int kCanTriggerGCBit = kLastBitForWrites + 1; 1589 1590 static constexpr int kChangeBits = kCanTriggerGCBit + 1; 1591 1592 static constexpr int kFieldReadOffset = kCanTriggerGCBit + 1; 1593 static constexpr int kArrayReadOffset = kFieldReadOffset + kFieldArrayAnalysisBits; 1594 static constexpr int kLastBitForReads = kArrayReadOffset + kFieldArrayAnalysisBits - 1; 1595 static constexpr int kDependsOnGCBit = kLastBitForReads + 1; 1596 1597 static constexpr int kLastBit = kDependsOnGCBit; 1598 static constexpr int kDependOnBits = kLastBit + 1 - kChangeBits; 1599 1600 // Aliases. 1601 1602 static_assert(kChangeBits == kDependOnBits, 1603 "the 'change' bits should match the 'depend on' bits."); 1604 1605 static constexpr uint64_t kAllChangeBits = ((1ULL << kChangeBits) - 1); 1606 static constexpr uint64_t kAllDependOnBits = ((1ULL << kDependOnBits) - 1) << kChangeBits; 1607 static constexpr uint64_t kAllWrites = 1608 ((1ULL << (kLastBitForWrites + 1 - kFieldWriteOffset)) - 1) << kFieldWriteOffset; 1609 static constexpr uint64_t kAllReads = 1610 ((1ULL << (kLastBitForReads + 1 - kFieldReadOffset)) - 1) << kFieldReadOffset; 1611 1612 // Work around the fact that HIR aliases I/F and J/D. 1613 // TODO: remove this interceptor once HIR types are clean 1614 static uint64_t TypeFlagWithAlias(Primitive::Type type, int offset) { 1615 switch (type) { 1616 case Primitive::kPrimInt: 1617 case Primitive::kPrimFloat: 1618 return TypeFlag(Primitive::kPrimInt, offset) | 1619 TypeFlag(Primitive::kPrimFloat, offset); 1620 case Primitive::kPrimLong: 1621 case Primitive::kPrimDouble: 1622 return TypeFlag(Primitive::kPrimLong, offset) | 1623 TypeFlag(Primitive::kPrimDouble, offset); 1624 default: 1625 return TypeFlag(type, offset); 1626 } 1627 } 1628 1629 // Translates type to bit flag. 1630 static uint64_t TypeFlag(Primitive::Type type, int offset) { 1631 CHECK_NE(type, Primitive::kPrimVoid); 1632 const uint64_t one = 1; 1633 const int shift = type; // 0-based consecutive enum 1634 DCHECK_LE(kFieldWriteOffset, shift); 1635 DCHECK_LT(shift, kArrayWriteOffset); 1636 return one << (type + offset); 1637 } 1638 1639 // Private constructor on direct flags value. 1640 explicit SideEffects(uint64_t flags) : flags_(flags) {} 1641 1642 uint64_t flags_; 1643 }; 1644 1645 // A HEnvironment object contains the values of virtual registers at a given location. 1646 class HEnvironment : public ArenaObject<kArenaAllocEnvironment> { 1647 public: 1648 HEnvironment(ArenaAllocator* arena, 1649 size_t number_of_vregs, 1650 const DexFile& dex_file, 1651 uint32_t method_idx, 1652 uint32_t dex_pc, 1653 InvokeType invoke_type, 1654 HInstruction* holder) 1655 : vregs_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentVRegs)), 1656 locations_(number_of_vregs, arena->Adapter(kArenaAllocEnvironmentLocations)), 1657 parent_(nullptr), 1658 dex_file_(dex_file), 1659 method_idx_(method_idx), 1660 dex_pc_(dex_pc), 1661 invoke_type_(invoke_type), 1662 holder_(holder) { 1663 } 1664 1665 HEnvironment(ArenaAllocator* arena, const HEnvironment& to_copy, HInstruction* holder) 1666 : HEnvironment(arena, 1667 to_copy.Size(), 1668 to_copy.GetDexFile(), 1669 to_copy.GetMethodIdx(), 1670 to_copy.GetDexPc(), 1671 to_copy.GetInvokeType(), 1672 holder) {} 1673 1674 void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) { 1675 if (parent_ != nullptr) { 1676 parent_->SetAndCopyParentChain(allocator, parent); 1677 } else { 1678 parent_ = new (allocator) HEnvironment(allocator, *parent, holder_); 1679 parent_->CopyFrom(parent); 1680 if (parent->GetParent() != nullptr) { 1681 parent_->SetAndCopyParentChain(allocator, parent->GetParent()); 1682 } 1683 } 1684 } 1685 1686 void CopyFrom(const ArenaVector<HInstruction*>& locals); 1687 void CopyFrom(HEnvironment* environment); 1688 1689 // Copy from `env`. If it's a loop phi for `loop_header`, copy the first 1690 // input to the loop phi instead. This is for inserting instructions that 1691 // require an environment (like HDeoptimization) in the loop pre-header. 1692 void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header); 1693 1694 void SetRawEnvAt(size_t index, HInstruction* instruction) { 1695 vregs_[index] = HUserRecord<HEnvironment*>(instruction); 1696 } 1697 1698 HInstruction* GetInstructionAt(size_t index) const { 1699 return vregs_[index].GetInstruction(); 1700 } 1701 1702 void RemoveAsUserOfInput(size_t index) const; 1703 1704 size_t Size() const { return vregs_.size(); } 1705 1706 HEnvironment* GetParent() const { return parent_; } 1707 1708 void SetLocationAt(size_t index, Location location) { 1709 locations_[index] = location; 1710 } 1711 1712 Location GetLocationAt(size_t index) const { 1713 return locations_[index]; 1714 } 1715 1716 uint32_t GetDexPc() const { 1717 return dex_pc_; 1718 } 1719 1720 uint32_t GetMethodIdx() const { 1721 return method_idx_; 1722 } 1723 1724 InvokeType GetInvokeType() const { 1725 return invoke_type_; 1726 } 1727 1728 const DexFile& GetDexFile() const { 1729 return dex_file_; 1730 } 1731 1732 HInstruction* GetHolder() const { 1733 return holder_; 1734 } 1735 1736 1737 bool IsFromInlinedInvoke() const { 1738 return GetParent() != nullptr; 1739 } 1740 1741 private: 1742 ArenaVector<HUserRecord<HEnvironment*>> vregs_; 1743 ArenaVector<Location> locations_; 1744 HEnvironment* parent_; 1745 const DexFile& dex_file_; 1746 const uint32_t method_idx_; 1747 const uint32_t dex_pc_; 1748 const InvokeType invoke_type_; 1749 1750 // The instruction that holds this environment. 1751 HInstruction* const holder_; 1752 1753 friend class HInstruction; 1754 1755 DISALLOW_COPY_AND_ASSIGN(HEnvironment); 1756 }; 1757 1758 class HInstruction : public ArenaObject<kArenaAllocInstruction> { 1759 public: 1760 HInstruction(SideEffects side_effects, uint32_t dex_pc) 1761 : previous_(nullptr), 1762 next_(nullptr), 1763 block_(nullptr), 1764 dex_pc_(dex_pc), 1765 id_(-1), 1766 ssa_index_(-1), 1767 packed_fields_(0u), 1768 environment_(nullptr), 1769 locations_(nullptr), 1770 live_interval_(nullptr), 1771 lifetime_position_(kNoLifetime), 1772 side_effects_(side_effects), 1773 reference_type_handle_(ReferenceTypeInfo::CreateInvalid().GetTypeHandle()) { 1774 SetPackedFlag<kFlagReferenceTypeIsExact>(ReferenceTypeInfo::CreateInvalid().IsExact()); 1775 } 1776 1777 virtual ~HInstruction() {} 1778 1779 #define DECLARE_KIND(type, super) k##type, 1780 enum InstructionKind { 1781 FOR_EACH_INSTRUCTION(DECLARE_KIND) 1782 }; 1783 #undef DECLARE_KIND 1784 1785 HInstruction* GetNext() const { return next_; } 1786 HInstruction* GetPrevious() const { return previous_; } 1787 1788 HInstruction* GetNextDisregardingMoves() const; 1789 HInstruction* GetPreviousDisregardingMoves() const; 1790 1791 HBasicBlock* GetBlock() const { return block_; } 1792 ArenaAllocator* GetArena() const { return block_->GetGraph()->GetArena(); } 1793 void SetBlock(HBasicBlock* block) { block_ = block; } 1794 bool IsInBlock() const { return block_ != nullptr; } 1795 bool IsInLoop() const { return block_->IsInLoop(); } 1796 bool IsLoopHeaderPhi() const { return IsPhi() && block_->IsLoopHeader(); } 1797 bool IsIrreducibleLoopHeaderPhi() const { 1798 return IsLoopHeaderPhi() && GetBlock()->GetLoopInformation()->IsIrreducible(); 1799 } 1800 1801 virtual size_t InputCount() const = 0; 1802 HInstruction* InputAt(size_t i) const { return InputRecordAt(i).GetInstruction(); } 1803 1804 virtual void Accept(HGraphVisitor* visitor) = 0; 1805 virtual const char* DebugName() const = 0; 1806 1807 virtual Primitive::Type GetType() const { return Primitive::kPrimVoid; } 1808 void SetRawInputAt(size_t index, HInstruction* input) { 1809 SetRawInputRecordAt(index, HUserRecord<HInstruction*>(input)); 1810 } 1811 1812 virtual bool NeedsEnvironment() const { return false; } 1813 1814 uint32_t GetDexPc() const { return dex_pc_; } 1815 1816 virtual bool IsControlFlow() const { return false; } 1817 1818 virtual bool CanThrow() const { return false; } 1819 bool CanThrowIntoCatchBlock() const { return CanThrow() && block_->IsTryBlock(); } 1820 1821 bool HasSideEffects() const { return side_effects_.HasSideEffects(); } 1822 bool DoesAnyWrite() const { return side_effects_.DoesAnyWrite(); } 1823 1824 // Does not apply for all instructions, but having this at top level greatly 1825 // simplifies the null check elimination. 1826 // TODO: Consider merging can_be_null into ReferenceTypeInfo. 1827 virtual bool CanBeNull() const { 1828 DCHECK_EQ(GetType(), Primitive::kPrimNot) << "CanBeNull only applies to reference types"; 1829 return true; 1830 } 1831 1832 virtual bool CanDoImplicitNullCheckOn(HInstruction* obj ATTRIBUTE_UNUSED) const { 1833 return false; 1834 } 1835 1836 virtual bool IsActualObject() const { 1837 return GetType() == Primitive::kPrimNot; 1838 } 1839 1840 void SetReferenceTypeInfo(ReferenceTypeInfo rti); 1841 1842 ReferenceTypeInfo GetReferenceTypeInfo() const { 1843 DCHECK_EQ(GetType(), Primitive::kPrimNot); 1844 return ReferenceTypeInfo::CreateUnchecked(reference_type_handle_, 1845 GetPackedFlag<kFlagReferenceTypeIsExact>()); 1846 } 1847 1848 void AddUseAt(HInstruction* user, size_t index) { 1849 DCHECK(user != nullptr); 1850 // Note: fixup_end remains valid across push_front(). 1851 auto fixup_end = uses_.empty() ? uses_.begin() : ++uses_.begin(); 1852 HUseListNode<HInstruction*>* new_node = 1853 new (GetBlock()->GetGraph()->GetArena()) HUseListNode<HInstruction*>(user, index); 1854 uses_.push_front(*new_node); 1855 FixUpUserRecordsAfterUseInsertion(fixup_end); 1856 } 1857 1858 void AddEnvUseAt(HEnvironment* user, size_t index) { 1859 DCHECK(user != nullptr); 1860 // Note: env_fixup_end remains valid across push_front(). 1861 auto env_fixup_end = env_uses_.empty() ? env_uses_.begin() : ++env_uses_.begin(); 1862 HUseListNode<HEnvironment*>* new_node = 1863 new (GetBlock()->GetGraph()->GetArena()) HUseListNode<HEnvironment*>(user, index); 1864 env_uses_.push_front(*new_node); 1865 FixUpUserRecordsAfterEnvUseInsertion(env_fixup_end); 1866 } 1867 1868 void RemoveAsUserOfInput(size_t input) { 1869 HUserRecord<HInstruction*> input_use = InputRecordAt(input); 1870 HUseList<HInstruction*>::iterator before_use_node = input_use.GetBeforeUseNode(); 1871 input_use.GetInstruction()->uses_.erase_after(before_use_node); 1872 input_use.GetInstruction()->FixUpUserRecordsAfterUseRemoval(before_use_node); 1873 } 1874 1875 const HUseList<HInstruction*>& GetUses() const { return uses_; } 1876 const HUseList<HEnvironment*>& GetEnvUses() const { return env_uses_; } 1877 1878 bool HasUses() const { return !uses_.empty() || !env_uses_.empty(); } 1879 bool HasEnvironmentUses() const { return !env_uses_.empty(); } 1880 bool HasNonEnvironmentUses() const { return !uses_.empty(); } 1881 bool HasOnlyOneNonEnvironmentUse() const { 1882 return !HasEnvironmentUses() && GetUses().HasExactlyOneElement(); 1883 } 1884 1885 // Does this instruction strictly dominate `other_instruction`? 1886 // Returns false if this instruction and `other_instruction` are the same. 1887 // Aborts if this instruction and `other_instruction` are both phis. 1888 bool StrictlyDominates(HInstruction* other_instruction) const; 1889 1890 int GetId() const { return id_; } 1891 void SetId(int id) { id_ = id; } 1892 1893 int GetSsaIndex() const { return ssa_index_; } 1894 void SetSsaIndex(int ssa_index) { ssa_index_ = ssa_index; } 1895 bool HasSsaIndex() const { return ssa_index_ != -1; } 1896 1897 bool HasEnvironment() const { return environment_ != nullptr; } 1898 HEnvironment* GetEnvironment() const { return environment_; } 1899 // Set the `environment_` field. Raw because this method does not 1900 // update the uses lists. 1901 void SetRawEnvironment(HEnvironment* environment) { 1902 DCHECK(environment_ == nullptr); 1903 DCHECK_EQ(environment->GetHolder(), this); 1904 environment_ = environment; 1905 } 1906 1907 void RemoveEnvironment(); 1908 1909 // Set the environment of this instruction, copying it from `environment`. While 1910 // copying, the uses lists are being updated. 1911 void CopyEnvironmentFrom(HEnvironment* environment) { 1912 DCHECK(environment_ == nullptr); 1913 ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena(); 1914 environment_ = new (allocator) HEnvironment(allocator, *environment, this); 1915 environment_->CopyFrom(environment); 1916 if (environment->GetParent() != nullptr) { 1917 environment_->SetAndCopyParentChain(allocator, environment->GetParent()); 1918 } 1919 } 1920 1921 void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment, 1922 HBasicBlock* block) { 1923 DCHECK(environment_ == nullptr); 1924 ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena(); 1925 environment_ = new (allocator) HEnvironment(allocator, *environment, this); 1926 environment_->CopyFromWithLoopPhiAdjustment(environment, block); 1927 if (environment->GetParent() != nullptr) { 1928 environment_->SetAndCopyParentChain(allocator, environment->GetParent()); 1929 } 1930 } 1931 1932 // Returns the number of entries in the environment. Typically, that is the 1933 // number of dex registers in a method. It could be more in case of inlining. 1934 size_t EnvironmentSize() const; 1935 1936 LocationSummary* GetLocations() const { return locations_; } 1937 void SetLocations(LocationSummary* locations) { locations_ = locations; } 1938 1939 void ReplaceWith(HInstruction* instruction); 1940 void ReplaceInput(HInstruction* replacement, size_t index); 1941 1942 // This is almost the same as doing `ReplaceWith()`. But in this helper, the 1943 // uses of this instruction by `other` are *not* updated. 1944 void ReplaceWithExceptInReplacementAtIndex(HInstruction* other, size_t use_index) { 1945 ReplaceWith(other); 1946 other->ReplaceInput(this, use_index); 1947 } 1948 1949 // Move `this` instruction before `cursor`. 1950 void MoveBefore(HInstruction* cursor); 1951 1952 // Move `this` before its first user and out of any loops. If there is no 1953 // out-of-loop user that dominates all other users, move the instruction 1954 // to the end of the out-of-loop common dominator of the user's blocks. 1955 // 1956 // This can be used only on non-throwing instructions with no side effects that 1957 // have at least one use but no environment uses. 1958 void MoveBeforeFirstUserAndOutOfLoops(); 1959 1960 #define INSTRUCTION_TYPE_CHECK(type, super) \ 1961 bool Is##type() const; \ 1962 const H##type* As##type() const; \ 1963 H##type* As##type(); 1964 1965 FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 1966 #undef INSTRUCTION_TYPE_CHECK 1967 1968 #define INSTRUCTION_TYPE_CHECK(type, super) \ 1969 bool Is##type() const { return (As##type() != nullptr); } \ 1970 virtual const H##type* As##type() const { return nullptr; } \ 1971 virtual H##type* As##type() { return nullptr; } 1972 FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 1973 #undef INSTRUCTION_TYPE_CHECK 1974 1975 // Returns whether the instruction can be moved within the graph. 1976 virtual bool CanBeMoved() const { return false; } 1977 1978 // Returns whether the two instructions are of the same kind. 1979 virtual bool InstructionTypeEquals(HInstruction* other ATTRIBUTE_UNUSED) const { 1980 return false; 1981 } 1982 1983 // Returns whether any data encoded in the two instructions is equal. 1984 // This method does not look at the inputs. Both instructions must be 1985 // of the same type, otherwise the method has undefined behavior. 1986 virtual bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const { 1987 return false; 1988 } 1989 1990 // Returns whether two instructions are equal, that is: 1991 // 1) They have the same type and contain the same data (InstructionDataEquals). 1992 // 2) Their inputs are identical. 1993 bool Equals(HInstruction* other) const; 1994 1995 // TODO: Remove this indirection when the [[pure]] attribute proposal (n3744) 1996 // is adopted and implemented by our C++ compiler(s). Fow now, we need to hide 1997 // the virtual function because the __attribute__((__pure__)) doesn't really 1998 // apply the strong requirement for virtual functions, preventing optimizations. 1999 InstructionKind GetKind() const PURE; 2000 virtual InstructionKind GetKindInternal() const = 0; 2001 2002 virtual size_t ComputeHashCode() const { 2003 size_t result = GetKind(); 2004 for (size_t i = 0, e = InputCount(); i < e; ++i) { 2005 result = (result * 31) + InputAt(i)->GetId(); 2006 } 2007 return result; 2008 } 2009 2010 SideEffects GetSideEffects() const { return side_effects_; } 2011 void SetSideEffects(SideEffects other) { side_effects_ = other; } 2012 void AddSideEffects(SideEffects other) { side_effects_.Add(other); } 2013 2014 size_t GetLifetimePosition() const { return lifetime_position_; } 2015 void SetLifetimePosition(size_t position) { lifetime_position_ = position; } 2016 LiveInterval* GetLiveInterval() const { return live_interval_; } 2017 void SetLiveInterval(LiveInterval* interval) { live_interval_ = interval; } 2018 bool HasLiveInterval() const { return live_interval_ != nullptr; } 2019 2020 bool IsSuspendCheckEntry() const { return IsSuspendCheck() && GetBlock()->IsEntryBlock(); } 2021 2022 // Returns whether the code generation of the instruction will require to have access 2023 // to the current method. Such instructions are: 2024 // (1): Instructions that require an environment, as calling the runtime requires 2025 // to walk the stack and have the current method stored at a specific stack address. 2026 // (2): Object literals like classes and strings, that are loaded from the dex cache 2027 // fields of the current method. 2028 bool NeedsCurrentMethod() const { 2029 return NeedsEnvironment() || IsLoadClass() || IsLoadString(); 2030 } 2031 2032 // Returns whether the code generation of the instruction will require to have access 2033 // to the dex cache of the current method's declaring class via the current method. 2034 virtual bool NeedsDexCacheOfDeclaringClass() const { return false; } 2035 2036 // Does this instruction have any use in an environment before 2037 // control flow hits 'other'? 2038 bool HasAnyEnvironmentUseBefore(HInstruction* other); 2039 2040 // Remove all references to environment uses of this instruction. 2041 // The caller must ensure that this is safe to do. 2042 void RemoveEnvironmentUsers(); 2043 2044 bool IsEmittedAtUseSite() const { return GetPackedFlag<kFlagEmittedAtUseSite>(); } 2045 void MarkEmittedAtUseSite() { SetPackedFlag<kFlagEmittedAtUseSite>(true); } 2046 2047 protected: 2048 // If set, the machine code for this instruction is assumed to be generated by 2049 // its users. Used by liveness analysis to compute use positions accordingly. 2050 static constexpr size_t kFlagEmittedAtUseSite = 0u; 2051 static constexpr size_t kFlagReferenceTypeIsExact = kFlagEmittedAtUseSite + 1; 2052 static constexpr size_t kNumberOfGenericPackedBits = kFlagReferenceTypeIsExact + 1; 2053 static constexpr size_t kMaxNumberOfPackedBits = sizeof(uint32_t) * kBitsPerByte; 2054 2055 virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0; 2056 virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0; 2057 2058 uint32_t GetPackedFields() const { 2059 return packed_fields_; 2060 } 2061 2062 template <size_t flag> 2063 bool GetPackedFlag() const { 2064 return (packed_fields_ & (1u << flag)) != 0u; 2065 } 2066 2067 template <size_t flag> 2068 void SetPackedFlag(bool value = true) { 2069 packed_fields_ = (packed_fields_ & ~(1u << flag)) | ((value ? 1u : 0u) << flag); 2070 } 2071 2072 template <typename BitFieldType> 2073 typename BitFieldType::value_type GetPackedField() const { 2074 return BitFieldType::Decode(packed_fields_); 2075 } 2076 2077 template <typename BitFieldType> 2078 void SetPackedField(typename BitFieldType::value_type value) { 2079 DCHECK(IsUint<BitFieldType::size>(static_cast<uintptr_t>(value))); 2080 packed_fields_ = BitFieldType::Update(value, packed_fields_); 2081 } 2082 2083 private: 2084 void FixUpUserRecordsAfterUseInsertion(HUseList<HInstruction*>::iterator fixup_end) { 2085 auto before_use_node = uses_.before_begin(); 2086 for (auto use_node = uses_.begin(); use_node != fixup_end; ++use_node) { 2087 HInstruction* user = use_node->GetUser(); 2088 size_t input_index = use_node->GetIndex(); 2089 user->SetRawInputRecordAt(input_index, HUserRecord<HInstruction*>(this, before_use_node)); 2090 before_use_node = use_node; 2091 } 2092 } 2093 2094 void FixUpUserRecordsAfterUseRemoval(HUseList<HInstruction*>::iterator before_use_node) { 2095 auto next = ++HUseList<HInstruction*>::iterator(before_use_node); 2096 if (next != uses_.end()) { 2097 HInstruction* next_user = next->GetUser(); 2098 size_t next_index = next->GetIndex(); 2099 DCHECK(next_user->InputRecordAt(next_index).GetInstruction() == this); 2100 next_user->SetRawInputRecordAt(next_index, HUserRecord<HInstruction*>(this, before_use_node)); 2101 } 2102 } 2103 2104 void FixUpUserRecordsAfterEnvUseInsertion(HUseList<HEnvironment*>::iterator env_fixup_end) { 2105 auto before_env_use_node = env_uses_.before_begin(); 2106 for (auto env_use_node = env_uses_.begin(); env_use_node != env_fixup_end; ++env_use_node) { 2107 HEnvironment* user = env_use_node->GetUser(); 2108 size_t input_index = env_use_node->GetIndex(); 2109 user->vregs_[input_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); 2110 before_env_use_node = env_use_node; 2111 } 2112 } 2113 2114 void FixUpUserRecordsAfterEnvUseRemoval(HUseList<HEnvironment*>::iterator before_env_use_node) { 2115 auto next = ++HUseList<HEnvironment*>::iterator(before_env_use_node); 2116 if (next != env_uses_.end()) { 2117 HEnvironment* next_user = next->GetUser(); 2118 size_t next_index = next->GetIndex(); 2119 DCHECK(next_user->vregs_[next_index].GetInstruction() == this); 2120 next_user->vregs_[next_index] = HUserRecord<HEnvironment*>(this, before_env_use_node); 2121 } 2122 } 2123 2124 HInstruction* previous_; 2125 HInstruction* next_; 2126 HBasicBlock* block_; 2127 const uint32_t dex_pc_; 2128 2129 // An instruction gets an id when it is added to the graph. 2130 // It reflects creation order. A negative id means the instruction 2131 // has not been added to the graph. 2132 int id_; 2133 2134 // When doing liveness analysis, instructions that have uses get an SSA index. 2135 int ssa_index_; 2136 2137 // Packed fields. 2138 uint32_t packed_fields_; 2139 2140 // List of instructions that have this instruction as input. 2141 HUseList<HInstruction*> uses_; 2142 2143 // List of environments that contain this instruction. 2144 HUseList<HEnvironment*> env_uses_; 2145 2146 // The environment associated with this instruction. Not null if the instruction 2147 // might jump out of the method. 2148 HEnvironment* environment_; 2149 2150 // Set by the code generator. 2151 LocationSummary* locations_; 2152 2153 // Set by the liveness analysis. 2154 LiveInterval* live_interval_; 2155 2156 // Set by the liveness analysis, this is the position in a linear 2157 // order of blocks where this instruction's live interval start. 2158 size_t lifetime_position_; 2159 2160 SideEffects side_effects_; 2161 2162 // The reference handle part of the reference type info. 2163 // The IsExact() flag is stored in packed fields. 2164 // TODO: for primitive types this should be marked as invalid. 2165 ReferenceTypeInfo::TypeHandle reference_type_handle_; 2166 2167 friend class GraphChecker; 2168 friend class HBasicBlock; 2169 friend class HEnvironment; 2170 friend class HGraph; 2171 friend class HInstructionList; 2172 2173 DISALLOW_COPY_AND_ASSIGN(HInstruction); 2174 }; 2175 std::ostream& operator<<(std::ostream& os, const HInstruction::InstructionKind& rhs); 2176 2177 class HInputIterator : public ValueObject { 2178 public: 2179 explicit HInputIterator(HInstruction* instruction) : instruction_(instruction), index_(0) {} 2180 2181 bool Done() const { return index_ == instruction_->InputCount(); } 2182 HInstruction* Current() const { return instruction_->InputAt(index_); } 2183 void Advance() { index_++; } 2184 2185 private: 2186 HInstruction* instruction_; 2187 size_t index_; 2188 2189 DISALLOW_COPY_AND_ASSIGN(HInputIterator); 2190 }; 2191 2192 class HInstructionIterator : public ValueObject { 2193 public: 2194 explicit HInstructionIterator(const HInstructionList& instructions) 2195 : instruction_(instructions.first_instruction_) { 2196 next_ = Done() ? nullptr : instruction_->GetNext(); 2197 } 2198 2199 bool Done() const { return instruction_ == nullptr; } 2200 HInstruction* Current() const { return instruction_; } 2201 void Advance() { 2202 instruction_ = next_; 2203 next_ = Done() ? nullptr : instruction_->GetNext(); 2204 } 2205 2206 private: 2207 HInstruction* instruction_; 2208 HInstruction* next_; 2209 2210 DISALLOW_COPY_AND_ASSIGN(HInstructionIterator); 2211 }; 2212 2213 class HBackwardInstructionIterator : public ValueObject { 2214 public: 2215 explicit HBackwardInstructionIterator(const HInstructionList& instructions) 2216 : instruction_(instructions.last_instruction_) { 2217 next_ = Done() ? nullptr : instruction_->GetPrevious(); 2218 } 2219 2220 bool Done() const { return instruction_ == nullptr; } 2221 HInstruction* Current() const { return instruction_; } 2222 void Advance() { 2223 instruction_ = next_; 2224 next_ = Done() ? nullptr : instruction_->GetPrevious(); 2225 } 2226 2227 private: 2228 HInstruction* instruction_; 2229 HInstruction* next_; 2230 2231 DISALLOW_COPY_AND_ASSIGN(HBackwardInstructionIterator); 2232 }; 2233 2234 template<size_t N> 2235 class HTemplateInstruction: public HInstruction { 2236 public: 2237 HTemplateInstruction<N>(SideEffects side_effects, uint32_t dex_pc) 2238 : HInstruction(side_effects, dex_pc), inputs_() {} 2239 virtual ~HTemplateInstruction() {} 2240 2241 size_t InputCount() const OVERRIDE { return N; } 2242 2243 protected: 2244 const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { 2245 DCHECK_LT(i, N); 2246 return inputs_[i]; 2247 } 2248 2249 void SetRawInputRecordAt(size_t i, const HUserRecord<HInstruction*>& input) OVERRIDE { 2250 DCHECK_LT(i, N); 2251 inputs_[i] = input; 2252 } 2253 2254 private: 2255 std::array<HUserRecord<HInstruction*>, N> inputs_; 2256 2257 friend class SsaBuilder; 2258 }; 2259 2260 // HTemplateInstruction specialization for N=0. 2261 template<> 2262 class HTemplateInstruction<0>: public HInstruction { 2263 public: 2264 explicit HTemplateInstruction<0>(SideEffects side_effects, uint32_t dex_pc) 2265 : HInstruction(side_effects, dex_pc) {} 2266 2267 virtual ~HTemplateInstruction() {} 2268 2269 size_t InputCount() const OVERRIDE { return 0; } 2270 2271 protected: 2272 const HUserRecord<HInstruction*> InputRecordAt(size_t i ATTRIBUTE_UNUSED) const OVERRIDE { 2273 LOG(FATAL) << "Unreachable"; 2274 UNREACHABLE(); 2275 } 2276 2277 void SetRawInputRecordAt(size_t i ATTRIBUTE_UNUSED, 2278 const HUserRecord<HInstruction*>& input ATTRIBUTE_UNUSED) OVERRIDE { 2279 LOG(FATAL) << "Unreachable"; 2280 UNREACHABLE(); 2281 } 2282 2283 private: 2284 friend class SsaBuilder; 2285 }; 2286 2287 template<intptr_t N> 2288 class HExpression : public HTemplateInstruction<N> { 2289 public: 2290 HExpression<N>(Primitive::Type type, SideEffects side_effects, uint32_t dex_pc) 2291 : HTemplateInstruction<N>(side_effects, dex_pc) { 2292 this->template SetPackedField<TypeField>(type); 2293 } 2294 virtual ~HExpression() {} 2295 2296 Primitive::Type GetType() const OVERRIDE { 2297 return TypeField::Decode(this->GetPackedFields()); 2298 } 2299 2300 protected: 2301 static constexpr size_t kFieldType = HInstruction::kNumberOfGenericPackedBits; 2302 static constexpr size_t kFieldTypeSize = 2303 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 2304 static constexpr size_t kNumberOfExpressionPackedBits = kFieldType + kFieldTypeSize; 2305 static_assert(kNumberOfExpressionPackedBits <= HInstruction::kMaxNumberOfPackedBits, 2306 "Too many packed fields."); 2307 using TypeField = BitField<Primitive::Type, kFieldType, kFieldTypeSize>; 2308 }; 2309 2310 // Represents dex's RETURN_VOID opcode. A HReturnVoid is a control flow 2311 // instruction that branches to the exit block. 2312 class HReturnVoid : public HTemplateInstruction<0> { 2313 public: 2314 explicit HReturnVoid(uint32_t dex_pc = kNoDexPc) 2315 : HTemplateInstruction(SideEffects::None(), dex_pc) {} 2316 2317 bool IsControlFlow() const OVERRIDE { return true; } 2318 2319 DECLARE_INSTRUCTION(ReturnVoid); 2320 2321 private: 2322 DISALLOW_COPY_AND_ASSIGN(HReturnVoid); 2323 }; 2324 2325 // Represents dex's RETURN opcodes. A HReturn is a control flow 2326 // instruction that branches to the exit block. 2327 class HReturn : public HTemplateInstruction<1> { 2328 public: 2329 explicit HReturn(HInstruction* value, uint32_t dex_pc = kNoDexPc) 2330 : HTemplateInstruction(SideEffects::None(), dex_pc) { 2331 SetRawInputAt(0, value); 2332 } 2333 2334 bool IsControlFlow() const OVERRIDE { return true; } 2335 2336 DECLARE_INSTRUCTION(Return); 2337 2338 private: 2339 DISALLOW_COPY_AND_ASSIGN(HReturn); 2340 }; 2341 2342 class HPhi : public HInstruction { 2343 public: 2344 HPhi(ArenaAllocator* arena, 2345 uint32_t reg_number, 2346 size_t number_of_inputs, 2347 Primitive::Type type, 2348 uint32_t dex_pc = kNoDexPc) 2349 : HInstruction(SideEffects::None(), dex_pc), 2350 inputs_(number_of_inputs, arena->Adapter(kArenaAllocPhiInputs)), 2351 reg_number_(reg_number) { 2352 SetPackedField<TypeField>(ToPhiType(type)); 2353 DCHECK_NE(GetType(), Primitive::kPrimVoid); 2354 // Phis are constructed live and marked dead if conflicting or unused. 2355 // Individual steps of SsaBuilder should assume that if a phi has been 2356 // marked dead, it can be ignored and will be removed by SsaPhiElimination. 2357 SetPackedFlag<kFlagIsLive>(true); 2358 SetPackedFlag<kFlagCanBeNull>(true); 2359 } 2360 2361 // Returns a type equivalent to the given `type`, but that a `HPhi` can hold. 2362 static Primitive::Type ToPhiType(Primitive::Type type) { 2363 return Primitive::PrimitiveKind(type); 2364 } 2365 2366 bool IsCatchPhi() const { return GetBlock()->IsCatchBlock(); } 2367 2368 size_t InputCount() const OVERRIDE { return inputs_.size(); } 2369 2370 void AddInput(HInstruction* input); 2371 void RemoveInputAt(size_t index); 2372 2373 Primitive::Type GetType() const OVERRIDE { return GetPackedField<TypeField>(); } 2374 void SetType(Primitive::Type new_type) { 2375 // Make sure that only valid type changes occur. The following are allowed: 2376 // (1) int -> float/ref (primitive type propagation), 2377 // (2) long -> double (primitive type propagation). 2378 DCHECK(GetType() == new_type || 2379 (GetType() == Primitive::kPrimInt && new_type == Primitive::kPrimFloat) || 2380 (GetType() == Primitive::kPrimInt && new_type == Primitive::kPrimNot) || 2381 (GetType() == Primitive::kPrimLong && new_type == Primitive::kPrimDouble)); 2382 SetPackedField<TypeField>(new_type); 2383 } 2384 2385 bool CanBeNull() const OVERRIDE { return GetPackedFlag<kFlagCanBeNull>(); } 2386 void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); } 2387 2388 uint32_t GetRegNumber() const { return reg_number_; } 2389 2390 void SetDead() { SetPackedFlag<kFlagIsLive>(false); } 2391 void SetLive() { SetPackedFlag<kFlagIsLive>(true); } 2392 bool IsDead() const { return !IsLive(); } 2393 bool IsLive() const { return GetPackedFlag<kFlagIsLive>(); } 2394 2395 bool IsVRegEquivalentOf(HInstruction* other) const { 2396 return other != nullptr 2397 && other->IsPhi() 2398 && other->AsPhi()->GetBlock() == GetBlock() 2399 && other->AsPhi()->GetRegNumber() == GetRegNumber(); 2400 } 2401 2402 // Returns the next equivalent phi (starting from the current one) or null if there is none. 2403 // An equivalent phi is a phi having the same dex register and type. 2404 // It assumes that phis with the same dex register are adjacent. 2405 HPhi* GetNextEquivalentPhiWithSameType() { 2406 HInstruction* next = GetNext(); 2407 while (next != nullptr && next->AsPhi()->GetRegNumber() == reg_number_) { 2408 if (next->GetType() == GetType()) { 2409 return next->AsPhi(); 2410 } 2411 next = next->GetNext(); 2412 } 2413 return nullptr; 2414 } 2415 2416 DECLARE_INSTRUCTION(Phi); 2417 2418 protected: 2419 const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE { 2420 return inputs_[index]; 2421 } 2422 2423 void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE { 2424 inputs_[index] = input; 2425 } 2426 2427 private: 2428 static constexpr size_t kFieldType = HInstruction::kNumberOfGenericPackedBits; 2429 static constexpr size_t kFieldTypeSize = 2430 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 2431 static constexpr size_t kFlagIsLive = kFieldType + kFieldTypeSize; 2432 static constexpr size_t kFlagCanBeNull = kFlagIsLive + 1; 2433 static constexpr size_t kNumberOfPhiPackedBits = kFlagCanBeNull + 1; 2434 static_assert(kNumberOfPhiPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 2435 using TypeField = BitField<Primitive::Type, kFieldType, kFieldTypeSize>; 2436 2437 ArenaVector<HUserRecord<HInstruction*> > inputs_; 2438 const uint32_t reg_number_; 2439 2440 DISALLOW_COPY_AND_ASSIGN(HPhi); 2441 }; 2442 2443 // The exit instruction is the only instruction of the exit block. 2444 // Instructions aborting the method (HThrow and HReturn) must branch to the 2445 // exit block. 2446 class HExit : public HTemplateInstruction<0> { 2447 public: 2448 explicit HExit(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {} 2449 2450 bool IsControlFlow() const OVERRIDE { return true; } 2451 2452 DECLARE_INSTRUCTION(Exit); 2453 2454 private: 2455 DISALLOW_COPY_AND_ASSIGN(HExit); 2456 }; 2457 2458 // Jumps from one block to another. 2459 class HGoto : public HTemplateInstruction<0> { 2460 public: 2461 explicit HGoto(uint32_t dex_pc = kNoDexPc) : HTemplateInstruction(SideEffects::None(), dex_pc) {} 2462 2463 bool IsControlFlow() const OVERRIDE { return true; } 2464 2465 HBasicBlock* GetSuccessor() const { 2466 return GetBlock()->GetSingleSuccessor(); 2467 } 2468 2469 DECLARE_INSTRUCTION(Goto); 2470 2471 private: 2472 DISALLOW_COPY_AND_ASSIGN(HGoto); 2473 }; 2474 2475 class HConstant : public HExpression<0> { 2476 public: 2477 explicit HConstant(Primitive::Type type, uint32_t dex_pc = kNoDexPc) 2478 : HExpression(type, SideEffects::None(), dex_pc) {} 2479 2480 bool CanBeMoved() const OVERRIDE { return true; } 2481 2482 // Is this constant -1 in the arithmetic sense? 2483 virtual bool IsMinusOne() const { return false; } 2484 // Is this constant 0 in the arithmetic sense? 2485 virtual bool IsArithmeticZero() const { return false; } 2486 // Is this constant a 0-bit pattern? 2487 virtual bool IsZeroBitPattern() const { return false; } 2488 // Is this constant 1 in the arithmetic sense? 2489 virtual bool IsOne() const { return false; } 2490 2491 virtual uint64_t GetValueAsUint64() const = 0; 2492 2493 DECLARE_ABSTRACT_INSTRUCTION(Constant); 2494 2495 private: 2496 DISALLOW_COPY_AND_ASSIGN(HConstant); 2497 }; 2498 2499 class HNullConstant : public HConstant { 2500 public: 2501 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 2502 return true; 2503 } 2504 2505 uint64_t GetValueAsUint64() const OVERRIDE { return 0; } 2506 2507 size_t ComputeHashCode() const OVERRIDE { return 0; } 2508 2509 // The null constant representation is a 0-bit pattern. 2510 virtual bool IsZeroBitPattern() const { return true; } 2511 2512 DECLARE_INSTRUCTION(NullConstant); 2513 2514 private: 2515 explicit HNullConstant(uint32_t dex_pc = kNoDexPc) : HConstant(Primitive::kPrimNot, dex_pc) {} 2516 2517 friend class HGraph; 2518 DISALLOW_COPY_AND_ASSIGN(HNullConstant); 2519 }; 2520 2521 // Constants of the type int. Those can be from Dex instructions, or 2522 // synthesized (for example with the if-eqz instruction). 2523 class HIntConstant : public HConstant { 2524 public: 2525 int32_t GetValue() const { return value_; } 2526 2527 uint64_t GetValueAsUint64() const OVERRIDE { 2528 return static_cast<uint64_t>(static_cast<uint32_t>(value_)); 2529 } 2530 2531 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 2532 DCHECK(other->IsIntConstant()) << other->DebugName(); 2533 return other->AsIntConstant()->value_ == value_; 2534 } 2535 2536 size_t ComputeHashCode() const OVERRIDE { return GetValue(); } 2537 2538 bool IsMinusOne() const OVERRIDE { return GetValue() == -1; } 2539 bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; } 2540 bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; } 2541 bool IsOne() const OVERRIDE { return GetValue() == 1; } 2542 2543 // Integer constants are used to encode Boolean values as well, 2544 // where 1 means true and 0 means false. 2545 bool IsTrue() const { return GetValue() == 1; } 2546 bool IsFalse() const { return GetValue() == 0; } 2547 2548 DECLARE_INSTRUCTION(IntConstant); 2549 2550 private: 2551 explicit HIntConstant(int32_t value, uint32_t dex_pc = kNoDexPc) 2552 : HConstant(Primitive::kPrimInt, dex_pc), value_(value) {} 2553 explicit HIntConstant(bool value, uint32_t dex_pc = kNoDexPc) 2554 : HConstant(Primitive::kPrimInt, dex_pc), value_(value ? 1 : 0) {} 2555 2556 const int32_t value_; 2557 2558 friend class HGraph; 2559 ART_FRIEND_TEST(GraphTest, InsertInstructionBefore); 2560 ART_FRIEND_TYPED_TEST(ParallelMoveTest, ConstantLast); 2561 DISALLOW_COPY_AND_ASSIGN(HIntConstant); 2562 }; 2563 2564 class HLongConstant : public HConstant { 2565 public: 2566 int64_t GetValue() const { return value_; } 2567 2568 uint64_t GetValueAsUint64() const OVERRIDE { return value_; } 2569 2570 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 2571 DCHECK(other->IsLongConstant()) << other->DebugName(); 2572 return other->AsLongConstant()->value_ == value_; 2573 } 2574 2575 size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } 2576 2577 bool IsMinusOne() const OVERRIDE { return GetValue() == -1; } 2578 bool IsArithmeticZero() const OVERRIDE { return GetValue() == 0; } 2579 bool IsZeroBitPattern() const OVERRIDE { return GetValue() == 0; } 2580 bool IsOne() const OVERRIDE { return GetValue() == 1; } 2581 2582 DECLARE_INSTRUCTION(LongConstant); 2583 2584 private: 2585 explicit HLongConstant(int64_t value, uint32_t dex_pc = kNoDexPc) 2586 : HConstant(Primitive::kPrimLong, dex_pc), value_(value) {} 2587 2588 const int64_t value_; 2589 2590 friend class HGraph; 2591 DISALLOW_COPY_AND_ASSIGN(HLongConstant); 2592 }; 2593 2594 class HFloatConstant : public HConstant { 2595 public: 2596 float GetValue() const { return value_; } 2597 2598 uint64_t GetValueAsUint64() const OVERRIDE { 2599 return static_cast<uint64_t>(bit_cast<uint32_t, float>(value_)); 2600 } 2601 2602 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 2603 DCHECK(other->IsFloatConstant()) << other->DebugName(); 2604 return other->AsFloatConstant()->GetValueAsUint64() == GetValueAsUint64(); 2605 } 2606 2607 size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } 2608 2609 bool IsMinusOne() const OVERRIDE { 2610 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f)); 2611 } 2612 bool IsArithmeticZero() const OVERRIDE { 2613 return std::fpclassify(value_) == FP_ZERO; 2614 } 2615 bool IsArithmeticPositiveZero() const { 2616 return IsArithmeticZero() && !std::signbit(value_); 2617 } 2618 bool IsArithmeticNegativeZero() const { 2619 return IsArithmeticZero() && std::signbit(value_); 2620 } 2621 bool IsZeroBitPattern() const OVERRIDE { 2622 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f); 2623 } 2624 bool IsOne() const OVERRIDE { 2625 return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(1.0f); 2626 } 2627 bool IsNaN() const { 2628 return std::isnan(value_); 2629 } 2630 2631 DECLARE_INSTRUCTION(FloatConstant); 2632 2633 private: 2634 explicit HFloatConstant(float value, uint32_t dex_pc = kNoDexPc) 2635 : HConstant(Primitive::kPrimFloat, dex_pc), value_(value) {} 2636 explicit HFloatConstant(int32_t value, uint32_t dex_pc = kNoDexPc) 2637 : HConstant(Primitive::kPrimFloat, dex_pc), value_(bit_cast<float, int32_t>(value)) {} 2638 2639 const float value_; 2640 2641 // Only the SsaBuilder and HGraph can create floating-point constants. 2642 friend class SsaBuilder; 2643 friend class HGraph; 2644 DISALLOW_COPY_AND_ASSIGN(HFloatConstant); 2645 }; 2646 2647 class HDoubleConstant : public HConstant { 2648 public: 2649 double GetValue() const { return value_; } 2650 2651 uint64_t GetValueAsUint64() const OVERRIDE { return bit_cast<uint64_t, double>(value_); } 2652 2653 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 2654 DCHECK(other->IsDoubleConstant()) << other->DebugName(); 2655 return other->AsDoubleConstant()->GetValueAsUint64() == GetValueAsUint64(); 2656 } 2657 2658 size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); } 2659 2660 bool IsMinusOne() const OVERRIDE { 2661 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0)); 2662 } 2663 bool IsArithmeticZero() const OVERRIDE { 2664 return std::fpclassify(value_) == FP_ZERO; 2665 } 2666 bool IsArithmeticPositiveZero() const { 2667 return IsArithmeticZero() && !std::signbit(value_); 2668 } 2669 bool IsArithmeticNegativeZero() const { 2670 return IsArithmeticZero() && std::signbit(value_); 2671 } 2672 bool IsZeroBitPattern() const OVERRIDE { 2673 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0)); 2674 } 2675 bool IsOne() const OVERRIDE { 2676 return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>(1.0); 2677 } 2678 bool IsNaN() const { 2679 return std::isnan(value_); 2680 } 2681 2682 DECLARE_INSTRUCTION(DoubleConstant); 2683 2684 private: 2685 explicit HDoubleConstant(double value, uint32_t dex_pc = kNoDexPc) 2686 : HConstant(Primitive::kPrimDouble, dex_pc), value_(value) {} 2687 explicit HDoubleConstant(int64_t value, uint32_t dex_pc = kNoDexPc) 2688 : HConstant(Primitive::kPrimDouble, dex_pc), value_(bit_cast<double, int64_t>(value)) {} 2689 2690 const double value_; 2691 2692 // Only the SsaBuilder and HGraph can create floating-point constants. 2693 friend class SsaBuilder; 2694 friend class HGraph; 2695 DISALLOW_COPY_AND_ASSIGN(HDoubleConstant); 2696 }; 2697 2698 // Conditional branch. A block ending with an HIf instruction must have 2699 // two successors. 2700 class HIf : public HTemplateInstruction<1> { 2701 public: 2702 explicit HIf(HInstruction* input, uint32_t dex_pc = kNoDexPc) 2703 : HTemplateInstruction(SideEffects::None(), dex_pc) { 2704 SetRawInputAt(0, input); 2705 } 2706 2707 bool IsControlFlow() const OVERRIDE { return true; } 2708 2709 HBasicBlock* IfTrueSuccessor() const { 2710 return GetBlock()->GetSuccessors()[0]; 2711 } 2712 2713 HBasicBlock* IfFalseSuccessor() const { 2714 return GetBlock()->GetSuccessors()[1]; 2715 } 2716 2717 DECLARE_INSTRUCTION(If); 2718 2719 private: 2720 DISALLOW_COPY_AND_ASSIGN(HIf); 2721 }; 2722 2723 2724 // Abstract instruction which marks the beginning and/or end of a try block and 2725 // links it to the respective exception handlers. Behaves the same as a Goto in 2726 // non-exceptional control flow. 2727 // Normal-flow successor is stored at index zero, exception handlers under 2728 // higher indices in no particular order. 2729 class HTryBoundary : public HTemplateInstruction<0> { 2730 public: 2731 enum class BoundaryKind { 2732 kEntry, 2733 kExit, 2734 kLast = kExit 2735 }; 2736 2737 explicit HTryBoundary(BoundaryKind kind, uint32_t dex_pc = kNoDexPc) 2738 : HTemplateInstruction(SideEffects::None(), dex_pc) { 2739 SetPackedField<BoundaryKindField>(kind); 2740 } 2741 2742 bool IsControlFlow() const OVERRIDE { return true; } 2743 2744 // Returns the block's non-exceptional successor (index zero). 2745 HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors()[0]; } 2746 2747 ArrayRef<HBasicBlock* const> GetExceptionHandlers() const { 2748 return ArrayRef<HBasicBlock* const>(GetBlock()->GetSuccessors()).SubArray(1u); 2749 } 2750 2751 // Returns whether `handler` is among its exception handlers (non-zero index 2752 // successors). 2753 bool HasExceptionHandler(const HBasicBlock& handler) const { 2754 DCHECK(handler.IsCatchBlock()); 2755 return GetBlock()->HasSuccessor(&handler, 1u /* Skip first successor. */); 2756 } 2757 2758 // If not present already, adds `handler` to its block's list of exception 2759 // handlers. 2760 void AddExceptionHandler(HBasicBlock* handler) { 2761 if (!HasExceptionHandler(*handler)) { 2762 GetBlock()->AddSuccessor(handler); 2763 } 2764 } 2765 2766 BoundaryKind GetBoundaryKind() const { return GetPackedField<BoundaryKindField>(); } 2767 bool IsEntry() const { return GetBoundaryKind() == BoundaryKind::kEntry; } 2768 2769 bool HasSameExceptionHandlersAs(const HTryBoundary& other) const; 2770 2771 DECLARE_INSTRUCTION(TryBoundary); 2772 2773 private: 2774 static constexpr size_t kFieldBoundaryKind = kNumberOfGenericPackedBits; 2775 static constexpr size_t kFieldBoundaryKindSize = 2776 MinimumBitsToStore(static_cast<size_t>(BoundaryKind::kLast)); 2777 static constexpr size_t kNumberOfTryBoundaryPackedBits = 2778 kFieldBoundaryKind + kFieldBoundaryKindSize; 2779 static_assert(kNumberOfTryBoundaryPackedBits <= kMaxNumberOfPackedBits, 2780 "Too many packed fields."); 2781 using BoundaryKindField = BitField<BoundaryKind, kFieldBoundaryKind, kFieldBoundaryKindSize>; 2782 2783 DISALLOW_COPY_AND_ASSIGN(HTryBoundary); 2784 }; 2785 2786 // Deoptimize to interpreter, upon checking a condition. 2787 class HDeoptimize : public HTemplateInstruction<1> { 2788 public: 2789 // We set CanTriggerGC to prevent any intermediate address to be live 2790 // at the point of the `HDeoptimize`. 2791 HDeoptimize(HInstruction* cond, uint32_t dex_pc) 2792 : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) { 2793 SetRawInputAt(0, cond); 2794 } 2795 2796 bool CanBeMoved() const OVERRIDE { return true; } 2797 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 2798 return true; 2799 } 2800 bool NeedsEnvironment() const OVERRIDE { return true; } 2801 bool CanThrow() const OVERRIDE { return true; } 2802 2803 DECLARE_INSTRUCTION(Deoptimize); 2804 2805 private: 2806 DISALLOW_COPY_AND_ASSIGN(HDeoptimize); 2807 }; 2808 2809 // Represents the ArtMethod that was passed as a first argument to 2810 // the method. It is used by instructions that depend on it, like 2811 // instructions that work with the dex cache. 2812 class HCurrentMethod : public HExpression<0> { 2813 public: 2814 explicit HCurrentMethod(Primitive::Type type, uint32_t dex_pc = kNoDexPc) 2815 : HExpression(type, SideEffects::None(), dex_pc) {} 2816 2817 DECLARE_INSTRUCTION(CurrentMethod); 2818 2819 private: 2820 DISALLOW_COPY_AND_ASSIGN(HCurrentMethod); 2821 }; 2822 2823 // Fetches an ArtMethod from the virtual table or the interface method table 2824 // of a class. 2825 class HClassTableGet : public HExpression<1> { 2826 public: 2827 enum class TableKind { 2828 kVTable, 2829 kIMTable, 2830 kLast = kIMTable 2831 }; 2832 HClassTableGet(HInstruction* cls, 2833 Primitive::Type type, 2834 TableKind kind, 2835 size_t index, 2836 uint32_t dex_pc) 2837 : HExpression(type, SideEffects::None(), dex_pc), 2838 index_(index) { 2839 SetPackedField<TableKindField>(kind); 2840 SetRawInputAt(0, cls); 2841 } 2842 2843 bool CanBeMoved() const OVERRIDE { return true; } 2844 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 2845 return other->AsClassTableGet()->GetIndex() == index_ && 2846 other->AsClassTableGet()->GetPackedFields() == GetPackedFields(); 2847 } 2848 2849 TableKind GetTableKind() const { return GetPackedField<TableKindField>(); } 2850 size_t GetIndex() const { return index_; } 2851 2852 DECLARE_INSTRUCTION(ClassTableGet); 2853 2854 private: 2855 static constexpr size_t kFieldTableKind = kNumberOfExpressionPackedBits; 2856 static constexpr size_t kFieldTableKindSize = 2857 MinimumBitsToStore(static_cast<size_t>(TableKind::kLast)); 2858 static constexpr size_t kNumberOfClassTableGetPackedBits = kFieldTableKind + kFieldTableKindSize; 2859 static_assert(kNumberOfClassTableGetPackedBits <= kMaxNumberOfPackedBits, 2860 "Too many packed fields."); 2861 using TableKindField = BitField<TableKind, kFieldTableKind, kFieldTableKind>; 2862 2863 // The index of the ArtMethod in the table. 2864 const size_t index_; 2865 2866 DISALLOW_COPY_AND_ASSIGN(HClassTableGet); 2867 }; 2868 2869 // PackedSwitch (jump table). A block ending with a PackedSwitch instruction will 2870 // have one successor for each entry in the switch table, and the final successor 2871 // will be the block containing the next Dex opcode. 2872 class HPackedSwitch : public HTemplateInstruction<1> { 2873 public: 2874 HPackedSwitch(int32_t start_value, 2875 uint32_t num_entries, 2876 HInstruction* input, 2877 uint32_t dex_pc = kNoDexPc) 2878 : HTemplateInstruction(SideEffects::None(), dex_pc), 2879 start_value_(start_value), 2880 num_entries_(num_entries) { 2881 SetRawInputAt(0, input); 2882 } 2883 2884 bool IsControlFlow() const OVERRIDE { return true; } 2885 2886 int32_t GetStartValue() const { return start_value_; } 2887 2888 uint32_t GetNumEntries() const { return num_entries_; } 2889 2890 HBasicBlock* GetDefaultBlock() const { 2891 // Last entry is the default block. 2892 return GetBlock()->GetSuccessors()[num_entries_]; 2893 } 2894 DECLARE_INSTRUCTION(PackedSwitch); 2895 2896 private: 2897 const int32_t start_value_; 2898 const uint32_t num_entries_; 2899 2900 DISALLOW_COPY_AND_ASSIGN(HPackedSwitch); 2901 }; 2902 2903 class HUnaryOperation : public HExpression<1> { 2904 public: 2905 HUnaryOperation(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 2906 : HExpression(result_type, SideEffects::None(), dex_pc) { 2907 SetRawInputAt(0, input); 2908 } 2909 2910 HInstruction* GetInput() const { return InputAt(0); } 2911 Primitive::Type GetResultType() const { return GetType(); } 2912 2913 bool CanBeMoved() const OVERRIDE { return true; } 2914 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 2915 return true; 2916 } 2917 2918 // Try to statically evaluate `this` and return a HConstant 2919 // containing the result of this evaluation. If `this` cannot 2920 // be evaluated as a constant, return null. 2921 HConstant* TryStaticEvaluation() const; 2922 2923 // Apply this operation to `x`. 2924 virtual HConstant* Evaluate(HIntConstant* x) const = 0; 2925 virtual HConstant* Evaluate(HLongConstant* x) const = 0; 2926 virtual HConstant* Evaluate(HFloatConstant* x) const = 0; 2927 virtual HConstant* Evaluate(HDoubleConstant* x) const = 0; 2928 2929 DECLARE_ABSTRACT_INSTRUCTION(UnaryOperation); 2930 2931 private: 2932 DISALLOW_COPY_AND_ASSIGN(HUnaryOperation); 2933 }; 2934 2935 class HBinaryOperation : public HExpression<2> { 2936 public: 2937 HBinaryOperation(Primitive::Type result_type, 2938 HInstruction* left, 2939 HInstruction* right, 2940 SideEffects side_effects = SideEffects::None(), 2941 uint32_t dex_pc = kNoDexPc) 2942 : HExpression(result_type, side_effects, dex_pc) { 2943 SetRawInputAt(0, left); 2944 SetRawInputAt(1, right); 2945 } 2946 2947 HInstruction* GetLeft() const { return InputAt(0); } 2948 HInstruction* GetRight() const { return InputAt(1); } 2949 Primitive::Type GetResultType() const { return GetType(); } 2950 2951 virtual bool IsCommutative() const { return false; } 2952 2953 // Put constant on the right. 2954 // Returns whether order is changed. 2955 bool OrderInputsWithConstantOnTheRight() { 2956 HInstruction* left = InputAt(0); 2957 HInstruction* right = InputAt(1); 2958 if (left->IsConstant() && !right->IsConstant()) { 2959 ReplaceInput(right, 0); 2960 ReplaceInput(left, 1); 2961 return true; 2962 } 2963 return false; 2964 } 2965 2966 // Order inputs by instruction id, but favor constant on the right side. 2967 // This helps GVN for commutative ops. 2968 void OrderInputs() { 2969 DCHECK(IsCommutative()); 2970 HInstruction* left = InputAt(0); 2971 HInstruction* right = InputAt(1); 2972 if (left == right || (!left->IsConstant() && right->IsConstant())) { 2973 return; 2974 } 2975 if (OrderInputsWithConstantOnTheRight()) { 2976 return; 2977 } 2978 // Order according to instruction id. 2979 if (left->GetId() > right->GetId()) { 2980 ReplaceInput(right, 0); 2981 ReplaceInput(left, 1); 2982 } 2983 } 2984 2985 bool CanBeMoved() const OVERRIDE { return true; } 2986 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 2987 return true; 2988 } 2989 2990 // Try to statically evaluate `this` and return a HConstant 2991 // containing the result of this evaluation. If `this` cannot 2992 // be evaluated as a constant, return null. 2993 HConstant* TryStaticEvaluation() const; 2994 2995 // Apply this operation to `x` and `y`. 2996 virtual HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, 2997 HNullConstant* y ATTRIBUTE_UNUSED) const { 2998 LOG(FATAL) << DebugName() << " is not defined for the (null, null) case."; 2999 UNREACHABLE(); 3000 } 3001 virtual HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const = 0; 3002 virtual HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const = 0; 3003 virtual HConstant* Evaluate(HLongConstant* x ATTRIBUTE_UNUSED, 3004 HIntConstant* y ATTRIBUTE_UNUSED) const { 3005 LOG(FATAL) << DebugName() << " is not defined for the (long, int) case."; 3006 UNREACHABLE(); 3007 } 3008 virtual HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const = 0; 3009 virtual HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const = 0; 3010 3011 // Returns an input that can legally be used as the right input and is 3012 // constant, or null. 3013 HConstant* GetConstantRight() const; 3014 3015 // If `GetConstantRight()` returns one of the input, this returns the other 3016 // one. Otherwise it returns null. 3017 HInstruction* GetLeastConstantLeft() const; 3018 3019 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation); 3020 3021 private: 3022 DISALLOW_COPY_AND_ASSIGN(HBinaryOperation); 3023 }; 3024 3025 // The comparison bias applies for floating point operations and indicates how NaN 3026 // comparisons are treated: 3027 enum class ComparisonBias { 3028 kNoBias, // bias is not applicable (i.e. for long operation) 3029 kGtBias, // return 1 for NaN comparisons 3030 kLtBias, // return -1 for NaN comparisons 3031 kLast = kLtBias 3032 }; 3033 3034 std::ostream& operator<<(std::ostream& os, const ComparisonBias& rhs); 3035 3036 class HCondition : public HBinaryOperation { 3037 public: 3038 HCondition(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3039 : HBinaryOperation(Primitive::kPrimBoolean, first, second, SideEffects::None(), dex_pc) { 3040 SetPackedField<ComparisonBiasField>(ComparisonBias::kNoBias); 3041 } 3042 3043 // For code generation purposes, returns whether this instruction is just before 3044 // `instruction`, and disregard moves in between. 3045 bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const; 3046 3047 DECLARE_ABSTRACT_INSTRUCTION(Condition); 3048 3049 virtual IfCondition GetCondition() const = 0; 3050 3051 virtual IfCondition GetOppositeCondition() const = 0; 3052 3053 bool IsGtBias() const { return GetBias() == ComparisonBias::kGtBias; } 3054 bool IsLtBias() const { return GetBias() == ComparisonBias::kLtBias; } 3055 3056 ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); } 3057 void SetBias(ComparisonBias bias) { SetPackedField<ComparisonBiasField>(bias); } 3058 3059 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 3060 return GetPackedFields() == other->AsCondition()->GetPackedFields(); 3061 } 3062 3063 bool IsFPConditionTrueIfNaN() const { 3064 DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 3065 IfCondition if_cond = GetCondition(); 3066 if (if_cond == kCondNE) { 3067 return true; 3068 } else if (if_cond == kCondEQ) { 3069 return false; 3070 } 3071 return ((if_cond == kCondGT) || (if_cond == kCondGE)) && IsGtBias(); 3072 } 3073 3074 bool IsFPConditionFalseIfNaN() const { 3075 DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 3076 IfCondition if_cond = GetCondition(); 3077 if (if_cond == kCondEQ) { 3078 return true; 3079 } else if (if_cond == kCondNE) { 3080 return false; 3081 } 3082 return ((if_cond == kCondLT) || (if_cond == kCondLE)) && IsGtBias(); 3083 } 3084 3085 protected: 3086 // Needed if we merge a HCompare into a HCondition. 3087 static constexpr size_t kFieldComparisonBias = kNumberOfExpressionPackedBits; 3088 static constexpr size_t kFieldComparisonBiasSize = 3089 MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast)); 3090 static constexpr size_t kNumberOfConditionPackedBits = 3091 kFieldComparisonBias + kFieldComparisonBiasSize; 3092 static_assert(kNumberOfConditionPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 3093 using ComparisonBiasField = 3094 BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>; 3095 3096 template <typename T> 3097 int32_t Compare(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); } 3098 3099 template <typename T> 3100 int32_t CompareFP(T x, T y) const { 3101 DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 3102 DCHECK_NE(GetBias(), ComparisonBias::kNoBias); 3103 // Handle the bias. 3104 return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compare(x, y); 3105 } 3106 3107 // Return an integer constant containing the result of a condition evaluated at compile time. 3108 HIntConstant* MakeConstantCondition(bool value, uint32_t dex_pc) const { 3109 return GetBlock()->GetGraph()->GetIntConstant(value, dex_pc); 3110 } 3111 3112 private: 3113 DISALLOW_COPY_AND_ASSIGN(HCondition); 3114 }; 3115 3116 // Instruction to check if two inputs are equal to each other. 3117 class HEqual : public HCondition { 3118 public: 3119 HEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3120 : HCondition(first, second, dex_pc) {} 3121 3122 bool IsCommutative() const OVERRIDE { return true; } 3123 3124 HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, 3125 HNullConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3126 return MakeConstantCondition(true, GetDexPc()); 3127 } 3128 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3129 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3130 } 3131 // In the following Evaluate methods, a HCompare instruction has 3132 // been merged into this HEqual instruction; evaluate it as 3133 // `Compare(x, y) == 0`. 3134 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3135 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), 3136 GetDexPc()); 3137 } 3138 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3139 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3140 } 3141 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3142 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3143 } 3144 3145 DECLARE_INSTRUCTION(Equal); 3146 3147 IfCondition GetCondition() const OVERRIDE { 3148 return kCondEQ; 3149 } 3150 3151 IfCondition GetOppositeCondition() const OVERRIDE { 3152 return kCondNE; 3153 } 3154 3155 private: 3156 template <typename T> bool Compute(T x, T y) const { return x == y; } 3157 3158 DISALLOW_COPY_AND_ASSIGN(HEqual); 3159 }; 3160 3161 class HNotEqual : public HCondition { 3162 public: 3163 HNotEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3164 : HCondition(first, second, dex_pc) {} 3165 3166 bool IsCommutative() const OVERRIDE { return true; } 3167 3168 HConstant* Evaluate(HNullConstant* x ATTRIBUTE_UNUSED, 3169 HNullConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3170 return MakeConstantCondition(false, GetDexPc()); 3171 } 3172 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3173 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3174 } 3175 // In the following Evaluate methods, a HCompare instruction has 3176 // been merged into this HNotEqual instruction; evaluate it as 3177 // `Compare(x, y) != 0`. 3178 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3179 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3180 } 3181 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3182 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3183 } 3184 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3185 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3186 } 3187 3188 DECLARE_INSTRUCTION(NotEqual); 3189 3190 IfCondition GetCondition() const OVERRIDE { 3191 return kCondNE; 3192 } 3193 3194 IfCondition GetOppositeCondition() const OVERRIDE { 3195 return kCondEQ; 3196 } 3197 3198 private: 3199 template <typename T> bool Compute(T x, T y) const { return x != y; } 3200 3201 DISALLOW_COPY_AND_ASSIGN(HNotEqual); 3202 }; 3203 3204 class HLessThan : public HCondition { 3205 public: 3206 HLessThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3207 : HCondition(first, second, dex_pc) {} 3208 3209 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3210 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3211 } 3212 // In the following Evaluate methods, a HCompare instruction has 3213 // been merged into this HLessThan instruction; evaluate it as 3214 // `Compare(x, y) < 0`. 3215 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3216 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3217 } 3218 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3219 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3220 } 3221 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3222 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3223 } 3224 3225 DECLARE_INSTRUCTION(LessThan); 3226 3227 IfCondition GetCondition() const OVERRIDE { 3228 return kCondLT; 3229 } 3230 3231 IfCondition GetOppositeCondition() const OVERRIDE { 3232 return kCondGE; 3233 } 3234 3235 private: 3236 template <typename T> bool Compute(T x, T y) const { return x < y; } 3237 3238 DISALLOW_COPY_AND_ASSIGN(HLessThan); 3239 }; 3240 3241 class HLessThanOrEqual : public HCondition { 3242 public: 3243 HLessThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3244 : HCondition(first, second, dex_pc) {} 3245 3246 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3247 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3248 } 3249 // In the following Evaluate methods, a HCompare instruction has 3250 // been merged into this HLessThanOrEqual instruction; evaluate it as 3251 // `Compare(x, y) <= 0`. 3252 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3253 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3254 } 3255 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3256 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3257 } 3258 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3259 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3260 } 3261 3262 DECLARE_INSTRUCTION(LessThanOrEqual); 3263 3264 IfCondition GetCondition() const OVERRIDE { 3265 return kCondLE; 3266 } 3267 3268 IfCondition GetOppositeCondition() const OVERRIDE { 3269 return kCondGT; 3270 } 3271 3272 private: 3273 template <typename T> bool Compute(T x, T y) const { return x <= y; } 3274 3275 DISALLOW_COPY_AND_ASSIGN(HLessThanOrEqual); 3276 }; 3277 3278 class HGreaterThan : public HCondition { 3279 public: 3280 HGreaterThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3281 : HCondition(first, second, dex_pc) {} 3282 3283 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3284 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3285 } 3286 // In the following Evaluate methods, a HCompare instruction has 3287 // been merged into this HGreaterThan instruction; evaluate it as 3288 // `Compare(x, y) > 0`. 3289 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3290 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3291 } 3292 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3293 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3294 } 3295 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3296 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3297 } 3298 3299 DECLARE_INSTRUCTION(GreaterThan); 3300 3301 IfCondition GetCondition() const OVERRIDE { 3302 return kCondGT; 3303 } 3304 3305 IfCondition GetOppositeCondition() const OVERRIDE { 3306 return kCondLE; 3307 } 3308 3309 private: 3310 template <typename T> bool Compute(T x, T y) const { return x > y; } 3311 3312 DISALLOW_COPY_AND_ASSIGN(HGreaterThan); 3313 }; 3314 3315 class HGreaterThanOrEqual : public HCondition { 3316 public: 3317 HGreaterThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3318 : HCondition(first, second, dex_pc) {} 3319 3320 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3321 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3322 } 3323 // In the following Evaluate methods, a HCompare instruction has 3324 // been merged into this HGreaterThanOrEqual instruction; evaluate it as 3325 // `Compare(x, y) >= 0`. 3326 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3327 return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3328 } 3329 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3330 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3331 } 3332 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3333 return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0), GetDexPc()); 3334 } 3335 3336 DECLARE_INSTRUCTION(GreaterThanOrEqual); 3337 3338 IfCondition GetCondition() const OVERRIDE { 3339 return kCondGE; 3340 } 3341 3342 IfCondition GetOppositeCondition() const OVERRIDE { 3343 return kCondLT; 3344 } 3345 3346 private: 3347 template <typename T> bool Compute(T x, T y) const { return x >= y; } 3348 3349 DISALLOW_COPY_AND_ASSIGN(HGreaterThanOrEqual); 3350 }; 3351 3352 class HBelow : public HCondition { 3353 public: 3354 HBelow(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3355 : HCondition(first, second, dex_pc) {} 3356 3357 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3358 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3359 } 3360 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3361 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3362 } 3363 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 3364 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3365 LOG(FATAL) << DebugName() << " is not defined for float values"; 3366 UNREACHABLE(); 3367 } 3368 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 3369 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3370 LOG(FATAL) << DebugName() << " is not defined for double values"; 3371 UNREACHABLE(); 3372 } 3373 3374 DECLARE_INSTRUCTION(Below); 3375 3376 IfCondition GetCondition() const OVERRIDE { 3377 return kCondB; 3378 } 3379 3380 IfCondition GetOppositeCondition() const OVERRIDE { 3381 return kCondAE; 3382 } 3383 3384 private: 3385 template <typename T> bool Compute(T x, T y) const { 3386 return MakeUnsigned(x) < MakeUnsigned(y); 3387 } 3388 3389 DISALLOW_COPY_AND_ASSIGN(HBelow); 3390 }; 3391 3392 class HBelowOrEqual : public HCondition { 3393 public: 3394 HBelowOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3395 : HCondition(first, second, dex_pc) {} 3396 3397 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3398 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3399 } 3400 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3401 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3402 } 3403 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 3404 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3405 LOG(FATAL) << DebugName() << " is not defined for float values"; 3406 UNREACHABLE(); 3407 } 3408 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 3409 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3410 LOG(FATAL) << DebugName() << " is not defined for double values"; 3411 UNREACHABLE(); 3412 } 3413 3414 DECLARE_INSTRUCTION(BelowOrEqual); 3415 3416 IfCondition GetCondition() const OVERRIDE { 3417 return kCondBE; 3418 } 3419 3420 IfCondition GetOppositeCondition() const OVERRIDE { 3421 return kCondA; 3422 } 3423 3424 private: 3425 template <typename T> bool Compute(T x, T y) const { 3426 return MakeUnsigned(x) <= MakeUnsigned(y); 3427 } 3428 3429 DISALLOW_COPY_AND_ASSIGN(HBelowOrEqual); 3430 }; 3431 3432 class HAbove : public HCondition { 3433 public: 3434 HAbove(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3435 : HCondition(first, second, dex_pc) {} 3436 3437 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3438 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3439 } 3440 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3441 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3442 } 3443 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 3444 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3445 LOG(FATAL) << DebugName() << " is not defined for float values"; 3446 UNREACHABLE(); 3447 } 3448 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 3449 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3450 LOG(FATAL) << DebugName() << " is not defined for double values"; 3451 UNREACHABLE(); 3452 } 3453 3454 DECLARE_INSTRUCTION(Above); 3455 3456 IfCondition GetCondition() const OVERRIDE { 3457 return kCondA; 3458 } 3459 3460 IfCondition GetOppositeCondition() const OVERRIDE { 3461 return kCondBE; 3462 } 3463 3464 private: 3465 template <typename T> bool Compute(T x, T y) const { 3466 return MakeUnsigned(x) > MakeUnsigned(y); 3467 } 3468 3469 DISALLOW_COPY_AND_ASSIGN(HAbove); 3470 }; 3471 3472 class HAboveOrEqual : public HCondition { 3473 public: 3474 HAboveOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc) 3475 : HCondition(first, second, dex_pc) {} 3476 3477 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3478 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3479 } 3480 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3481 return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3482 } 3483 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 3484 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3485 LOG(FATAL) << DebugName() << " is not defined for float values"; 3486 UNREACHABLE(); 3487 } 3488 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 3489 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 3490 LOG(FATAL) << DebugName() << " is not defined for double values"; 3491 UNREACHABLE(); 3492 } 3493 3494 DECLARE_INSTRUCTION(AboveOrEqual); 3495 3496 IfCondition GetCondition() const OVERRIDE { 3497 return kCondAE; 3498 } 3499 3500 IfCondition GetOppositeCondition() const OVERRIDE { 3501 return kCondB; 3502 } 3503 3504 private: 3505 template <typename T> bool Compute(T x, T y) const { 3506 return MakeUnsigned(x) >= MakeUnsigned(y); 3507 } 3508 3509 DISALLOW_COPY_AND_ASSIGN(HAboveOrEqual); 3510 }; 3511 3512 // Instruction to check how two inputs compare to each other. 3513 // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1. 3514 class HCompare : public HBinaryOperation { 3515 public: 3516 // Note that `comparison_type` is the type of comparison performed 3517 // between the comparison's inputs, not the type of the instantiated 3518 // HCompare instruction (which is always Primitive::kPrimInt). 3519 HCompare(Primitive::Type comparison_type, 3520 HInstruction* first, 3521 HInstruction* second, 3522 ComparisonBias bias, 3523 uint32_t dex_pc) 3524 : HBinaryOperation(Primitive::kPrimInt, 3525 first, 3526 second, 3527 SideEffectsForArchRuntimeCalls(comparison_type), 3528 dex_pc) { 3529 SetPackedField<ComparisonBiasField>(bias); 3530 DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(first->GetType())); 3531 DCHECK_EQ(comparison_type, Primitive::PrimitiveKind(second->GetType())); 3532 } 3533 3534 template <typename T> 3535 int32_t Compute(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); } 3536 3537 template <typename T> 3538 int32_t ComputeFP(T x, T y) const { 3539 DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 3540 DCHECK_NE(GetBias(), ComparisonBias::kNoBias); 3541 // Handle the bias. 3542 return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compute(x, y); 3543 } 3544 3545 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 3546 // Note that there is no "cmp-int" Dex instruction so we shouldn't 3547 // reach this code path when processing a freshly built HIR 3548 // graph. However HCompare integer instructions can be synthesized 3549 // by the instruction simplifier to implement IntegerCompare and 3550 // IntegerSignum intrinsics, so we have to handle this case. 3551 return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3552 } 3553 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 3554 return MakeConstantComparison(Compute(x->GetValue(), y->GetValue()), GetDexPc()); 3555 } 3556 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 3557 return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 3558 } 3559 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 3560 return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 3561 } 3562 3563 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 3564 return GetPackedFields() == other->AsCompare()->GetPackedFields(); 3565 } 3566 3567 ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); } 3568 3569 // Does this compare instruction have a "gt bias" (vs an "lt bias")? 3570 // Only meaningful for floating-point comparisons. 3571 bool IsGtBias() const { 3572 DCHECK(Primitive::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType(); 3573 return GetBias() == ComparisonBias::kGtBias; 3574 } 3575 3576 static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type type ATTRIBUTE_UNUSED) { 3577 // Comparisons do not require a runtime call in any back end. 3578 return SideEffects::None(); 3579 } 3580 3581 DECLARE_INSTRUCTION(Compare); 3582 3583 protected: 3584 static constexpr size_t kFieldComparisonBias = kNumberOfExpressionPackedBits; 3585 static constexpr size_t kFieldComparisonBiasSize = 3586 MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast)); 3587 static constexpr size_t kNumberOfComparePackedBits = 3588 kFieldComparisonBias + kFieldComparisonBiasSize; 3589 static_assert(kNumberOfComparePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 3590 using ComparisonBiasField = 3591 BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>; 3592 3593 // Return an integer constant containing the result of a comparison evaluated at compile time. 3594 HIntConstant* MakeConstantComparison(int32_t value, uint32_t dex_pc) const { 3595 DCHECK(value == -1 || value == 0 || value == 1) << value; 3596 return GetBlock()->GetGraph()->GetIntConstant(value, dex_pc); 3597 } 3598 3599 private: 3600 DISALLOW_COPY_AND_ASSIGN(HCompare); 3601 }; 3602 3603 class HNewInstance : public HExpression<2> { 3604 public: 3605 HNewInstance(HInstruction* cls, 3606 HCurrentMethod* current_method, 3607 uint32_t dex_pc, 3608 uint16_t type_index, 3609 const DexFile& dex_file, 3610 bool can_throw, 3611 bool finalizable, 3612 QuickEntrypointEnum entrypoint) 3613 : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), 3614 type_index_(type_index), 3615 dex_file_(dex_file), 3616 entrypoint_(entrypoint) { 3617 SetPackedFlag<kFlagCanThrow>(can_throw); 3618 SetPackedFlag<kFlagFinalizable>(finalizable); 3619 SetRawInputAt(0, cls); 3620 SetRawInputAt(1, current_method); 3621 } 3622 3623 uint16_t GetTypeIndex() const { return type_index_; } 3624 const DexFile& GetDexFile() const { return dex_file_; } 3625 3626 // Calls runtime so needs an environment. 3627 bool NeedsEnvironment() const OVERRIDE { return true; } 3628 3629 // It may throw when called on type that's not instantiable/accessible. 3630 // It can throw OOME. 3631 // TODO: distinguish between the two cases so we can for example allow allocation elimination. 3632 bool CanThrow() const OVERRIDE { return GetPackedFlag<kFlagCanThrow>() || true; } 3633 3634 bool IsFinalizable() const { return GetPackedFlag<kFlagFinalizable>(); } 3635 3636 bool CanBeNull() const OVERRIDE { return false; } 3637 3638 QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } 3639 3640 void SetEntrypoint(QuickEntrypointEnum entrypoint) { 3641 entrypoint_ = entrypoint; 3642 } 3643 3644 bool IsStringAlloc() const; 3645 3646 DECLARE_INSTRUCTION(NewInstance); 3647 3648 private: 3649 static constexpr size_t kFlagCanThrow = kNumberOfExpressionPackedBits; 3650 static constexpr size_t kFlagFinalizable = kFlagCanThrow + 1; 3651 static constexpr size_t kNumberOfNewInstancePackedBits = kFlagFinalizable + 1; 3652 static_assert(kNumberOfNewInstancePackedBits <= kMaxNumberOfPackedBits, 3653 "Too many packed fields."); 3654 3655 const uint16_t type_index_; 3656 const DexFile& dex_file_; 3657 QuickEntrypointEnum entrypoint_; 3658 3659 DISALLOW_COPY_AND_ASSIGN(HNewInstance); 3660 }; 3661 3662 enum class Intrinsics { 3663 #define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 3664 k ## Name, 3665 #include "intrinsics_list.h" 3666 kNone, 3667 INTRINSICS_LIST(OPTIMIZING_INTRINSICS) 3668 #undef INTRINSICS_LIST 3669 #undef OPTIMIZING_INTRINSICS 3670 }; 3671 std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); 3672 3673 enum IntrinsicNeedsEnvironmentOrCache { 3674 kNoEnvironmentOrCache, // Intrinsic does not require an environment or dex cache. 3675 kNeedsEnvironmentOrCache // Intrinsic requires an environment or requires a dex cache. 3676 }; 3677 3678 enum IntrinsicSideEffects { 3679 kNoSideEffects, // Intrinsic does not have any heap memory side effects. 3680 kReadSideEffects, // Intrinsic may read heap memory. 3681 kWriteSideEffects, // Intrinsic may write heap memory. 3682 kAllSideEffects // Intrinsic may read or write heap memory, or trigger GC. 3683 }; 3684 3685 enum IntrinsicExceptions { 3686 kNoThrow, // Intrinsic does not throw any exceptions. 3687 kCanThrow // Intrinsic may throw exceptions. 3688 }; 3689 3690 class HInvoke : public HInstruction { 3691 public: 3692 size_t InputCount() const OVERRIDE { return inputs_.size(); } 3693 3694 bool NeedsEnvironment() const OVERRIDE; 3695 3696 void SetArgumentAt(size_t index, HInstruction* argument) { 3697 SetRawInputAt(index, argument); 3698 } 3699 3700 // Return the number of arguments. This number can be lower than 3701 // the number of inputs returned by InputCount(), as some invoke 3702 // instructions (e.g. HInvokeStaticOrDirect) can have non-argument 3703 // inputs at the end of their list of inputs. 3704 uint32_t GetNumberOfArguments() const { return number_of_arguments_; } 3705 3706 Primitive::Type GetType() const OVERRIDE { return GetPackedField<ReturnTypeField>(); } 3707 3708 uint32_t GetDexMethodIndex() const { return dex_method_index_; } 3709 const DexFile& GetDexFile() const { return GetEnvironment()->GetDexFile(); } 3710 3711 InvokeType GetOriginalInvokeType() const { 3712 return GetPackedField<OriginalInvokeTypeField>(); 3713 } 3714 3715 Intrinsics GetIntrinsic() const { 3716 return intrinsic_; 3717 } 3718 3719 void SetIntrinsic(Intrinsics intrinsic, 3720 IntrinsicNeedsEnvironmentOrCache needs_env_or_cache, 3721 IntrinsicSideEffects side_effects, 3722 IntrinsicExceptions exceptions); 3723 3724 bool IsFromInlinedInvoke() const { 3725 return GetEnvironment()->IsFromInlinedInvoke(); 3726 } 3727 3728 bool CanThrow() const OVERRIDE { return GetPackedFlag<kFlagCanThrow>(); } 3729 3730 bool CanBeMoved() const OVERRIDE { return IsIntrinsic(); } 3731 3732 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 3733 return intrinsic_ != Intrinsics::kNone && intrinsic_ == other->AsInvoke()->intrinsic_; 3734 } 3735 3736 uint32_t* GetIntrinsicOptimizations() { 3737 return &intrinsic_optimizations_; 3738 } 3739 3740 const uint32_t* GetIntrinsicOptimizations() const { 3741 return &intrinsic_optimizations_; 3742 } 3743 3744 bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; } 3745 3746 DECLARE_ABSTRACT_INSTRUCTION(Invoke); 3747 3748 protected: 3749 static constexpr size_t kFieldOriginalInvokeType = kNumberOfGenericPackedBits; 3750 static constexpr size_t kFieldOriginalInvokeTypeSize = 3751 MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType)); 3752 static constexpr size_t kFieldReturnType = 3753 kFieldOriginalInvokeType + kFieldOriginalInvokeTypeSize; 3754 static constexpr size_t kFieldReturnTypeSize = 3755 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 3756 static constexpr size_t kFlagCanThrow = kFieldReturnType + kFieldReturnTypeSize; 3757 static constexpr size_t kNumberOfInvokePackedBits = kFlagCanThrow + 1; 3758 static_assert(kNumberOfInvokePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 3759 using OriginalInvokeTypeField = 3760 BitField<InvokeType, kFieldOriginalInvokeType, kFieldOriginalInvokeTypeSize>; 3761 using ReturnTypeField = BitField<Primitive::Type, kFieldReturnType, kFieldReturnTypeSize>; 3762 3763 HInvoke(ArenaAllocator* arena, 3764 uint32_t number_of_arguments, 3765 uint32_t number_of_other_inputs, 3766 Primitive::Type return_type, 3767 uint32_t dex_pc, 3768 uint32_t dex_method_index, 3769 InvokeType original_invoke_type) 3770 : HInstruction( 3771 SideEffects::AllExceptGCDependency(), dex_pc), // Assume write/read on all fields/arrays. 3772 number_of_arguments_(number_of_arguments), 3773 inputs_(number_of_arguments + number_of_other_inputs, 3774 arena->Adapter(kArenaAllocInvokeInputs)), 3775 dex_method_index_(dex_method_index), 3776 intrinsic_(Intrinsics::kNone), 3777 intrinsic_optimizations_(0) { 3778 SetPackedField<ReturnTypeField>(return_type); 3779 SetPackedField<OriginalInvokeTypeField>(original_invoke_type); 3780 SetPackedFlag<kFlagCanThrow>(true); 3781 } 3782 3783 const HUserRecord<HInstruction*> InputRecordAt(size_t index) const OVERRIDE { 3784 return inputs_[index]; 3785 } 3786 3787 void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE { 3788 inputs_[index] = input; 3789 } 3790 3791 void SetCanThrow(bool can_throw) { SetPackedFlag<kFlagCanThrow>(can_throw); } 3792 3793 uint32_t number_of_arguments_; 3794 ArenaVector<HUserRecord<HInstruction*>> inputs_; 3795 const uint32_t dex_method_index_; 3796 Intrinsics intrinsic_; 3797 3798 // A magic word holding optimizations for intrinsics. See intrinsics.h. 3799 uint32_t intrinsic_optimizations_; 3800 3801 private: 3802 DISALLOW_COPY_AND_ASSIGN(HInvoke); 3803 }; 3804 3805 class HInvokeUnresolved : public HInvoke { 3806 public: 3807 HInvokeUnresolved(ArenaAllocator* arena, 3808 uint32_t number_of_arguments, 3809 Primitive::Type return_type, 3810 uint32_t dex_pc, 3811 uint32_t dex_method_index, 3812 InvokeType invoke_type) 3813 : HInvoke(arena, 3814 number_of_arguments, 3815 0u /* number_of_other_inputs */, 3816 return_type, 3817 dex_pc, 3818 dex_method_index, 3819 invoke_type) { 3820 } 3821 3822 DECLARE_INSTRUCTION(InvokeUnresolved); 3823 3824 private: 3825 DISALLOW_COPY_AND_ASSIGN(HInvokeUnresolved); 3826 }; 3827 3828 class HInvokeStaticOrDirect : public HInvoke { 3829 public: 3830 // Requirements of this method call regarding the class 3831 // initialization (clinit) check of its declaring class. 3832 enum class ClinitCheckRequirement { 3833 kNone, // Class already initialized. 3834 kExplicit, // Static call having explicit clinit check as last input. 3835 kImplicit, // Static call implicitly requiring a clinit check. 3836 kLast = kImplicit 3837 }; 3838 3839 // Determines how to load the target ArtMethod*. 3840 enum class MethodLoadKind { 3841 // Use a String init ArtMethod* loaded from Thread entrypoints. 3842 kStringInit, 3843 3844 // Use the method's own ArtMethod* loaded by the register allocator. 3845 kRecursive, 3846 3847 // Use ArtMethod* at a known address, embed the direct address in the code. 3848 // Used for app->boot calls with non-relocatable image and for JIT-compiled calls. 3849 kDirectAddress, 3850 3851 // Use ArtMethod* at an address that will be known at link time, embed the direct 3852 // address in the code. If the image is relocatable, emit .patch_oat entry. 3853 // Used for app->boot calls with relocatable image and boot->boot calls, whether 3854 // the image relocatable or not. 3855 kDirectAddressWithFixup, 3856 3857 // Load from resolved methods array in the dex cache using a PC-relative load. 3858 // Used when we need to use the dex cache, for example for invoke-static that 3859 // may cause class initialization (the entry may point to a resolution method), 3860 // and we know that we can access the dex cache arrays using a PC-relative load. 3861 kDexCachePcRelative, 3862 3863 // Use ArtMethod* from the resolved methods of the compiled method's own ArtMethod*. 3864 // Used for JIT when we need to use the dex cache. This is also the last-resort-kind 3865 // used when other kinds are unavailable (say, dex cache arrays are not PC-relative) 3866 // or unimplemented or impractical (i.e. slow) on a particular architecture. 3867 kDexCacheViaMethod, 3868 }; 3869 3870 // Determines the location of the code pointer. 3871 enum class CodePtrLocation { 3872 // Recursive call, use local PC-relative call instruction. 3873 kCallSelf, 3874 3875 // Use PC-relative call instruction patched at link time. 3876 // Used for calls within an oat file, boot->boot or app->app. 3877 kCallPCRelative, 3878 3879 // Call to a known target address, embed the direct address in code. 3880 // Used for app->boot call with non-relocatable image and for JIT-compiled calls. 3881 kCallDirect, 3882 3883 // Call to a target address that will be known at link time, embed the direct 3884 // address in code. If the image is relocatable, emit .patch_oat entry. 3885 // Used for app->boot calls with relocatable image and boot->boot calls, whether 3886 // the image relocatable or not. 3887 kCallDirectWithFixup, 3888 3889 // Use code pointer from the ArtMethod*. 3890 // Used when we don't know the target code. This is also the last-resort-kind used when 3891 // other kinds are unimplemented or impractical (i.e. slow) on a particular architecture. 3892 kCallArtMethod, 3893 }; 3894 3895 struct DispatchInfo { 3896 MethodLoadKind method_load_kind; 3897 CodePtrLocation code_ptr_location; 3898 // The method load data holds 3899 // - thread entrypoint offset for kStringInit method if this is a string init invoke. 3900 // Note that there are multiple string init methods, each having its own offset. 3901 // - the method address for kDirectAddress 3902 // - the dex cache arrays offset for kDexCachePcRel. 3903 uint64_t method_load_data; 3904 uint64_t direct_code_ptr; 3905 }; 3906 3907 HInvokeStaticOrDirect(ArenaAllocator* arena, 3908 uint32_t number_of_arguments, 3909 Primitive::Type return_type, 3910 uint32_t dex_pc, 3911 uint32_t method_index, 3912 MethodReference target_method, 3913 DispatchInfo dispatch_info, 3914 InvokeType original_invoke_type, 3915 InvokeType optimized_invoke_type, 3916 ClinitCheckRequirement clinit_check_requirement) 3917 : HInvoke(arena, 3918 number_of_arguments, 3919 // There is potentially one extra argument for the HCurrentMethod node, and 3920 // potentially one other if the clinit check is explicit, and potentially 3921 // one other if the method is a string factory. 3922 (NeedsCurrentMethodInput(dispatch_info.method_load_kind) ? 1u : 0u) + 3923 (clinit_check_requirement == ClinitCheckRequirement::kExplicit ? 1u : 0u), 3924 return_type, 3925 dex_pc, 3926 method_index, 3927 original_invoke_type), 3928 target_method_(target_method), 3929 dispatch_info_(dispatch_info) { 3930 SetPackedField<OptimizedInvokeTypeField>(optimized_invoke_type); 3931 SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement); 3932 } 3933 3934 void SetDispatchInfo(const DispatchInfo& dispatch_info) { 3935 bool had_current_method_input = HasCurrentMethodInput(); 3936 bool needs_current_method_input = NeedsCurrentMethodInput(dispatch_info.method_load_kind); 3937 3938 // Using the current method is the default and once we find a better 3939 // method load kind, we should not go back to using the current method. 3940 DCHECK(had_current_method_input || !needs_current_method_input); 3941 3942 if (had_current_method_input && !needs_current_method_input) { 3943 DCHECK_EQ(InputAt(GetSpecialInputIndex()), GetBlock()->GetGraph()->GetCurrentMethod()); 3944 RemoveInputAt(GetSpecialInputIndex()); 3945 } 3946 dispatch_info_ = dispatch_info; 3947 } 3948 3949 void AddSpecialInput(HInstruction* input) { 3950 // We allow only one special input. 3951 DCHECK(!IsStringInit() && !HasCurrentMethodInput()); 3952 DCHECK(InputCount() == GetSpecialInputIndex() || 3953 (InputCount() == GetSpecialInputIndex() + 1 && IsStaticWithExplicitClinitCheck())); 3954 InsertInputAt(GetSpecialInputIndex(), input); 3955 } 3956 3957 bool CanDoImplicitNullCheckOn(HInstruction* obj ATTRIBUTE_UNUSED) const OVERRIDE { 3958 // We access the method via the dex cache so we can't do an implicit null check. 3959 // TODO: for intrinsics we can generate implicit null checks. 3960 return false; 3961 } 3962 3963 bool CanBeNull() const OVERRIDE { 3964 return GetPackedField<ReturnTypeField>() == Primitive::kPrimNot && !IsStringInit(); 3965 } 3966 3967 // Get the index of the special input, if any. 3968 // 3969 // If the invoke HasCurrentMethodInput(), the "special input" is the current 3970 // method pointer; otherwise there may be one platform-specific special input, 3971 // such as PC-relative addressing base. 3972 uint32_t GetSpecialInputIndex() const { return GetNumberOfArguments(); } 3973 bool HasSpecialInput() const { return GetNumberOfArguments() != InputCount(); } 3974 3975 InvokeType GetOptimizedInvokeType() const { 3976 return GetPackedField<OptimizedInvokeTypeField>(); 3977 } 3978 3979 void SetOptimizedInvokeType(InvokeType invoke_type) { 3980 SetPackedField<OptimizedInvokeTypeField>(invoke_type); 3981 } 3982 3983 MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; } 3984 CodePtrLocation GetCodePtrLocation() const { return dispatch_info_.code_ptr_location; } 3985 bool IsRecursive() const { return GetMethodLoadKind() == MethodLoadKind::kRecursive; } 3986 bool NeedsDexCacheOfDeclaringClass() const OVERRIDE; 3987 bool IsStringInit() const { return GetMethodLoadKind() == MethodLoadKind::kStringInit; } 3988 bool HasMethodAddress() const { return GetMethodLoadKind() == MethodLoadKind::kDirectAddress; } 3989 bool HasPcRelativeDexCache() const { 3990 return GetMethodLoadKind() == MethodLoadKind::kDexCachePcRelative; 3991 } 3992 bool HasCurrentMethodInput() const { 3993 // This function can be called only after the invoke has been fully initialized by the builder. 3994 if (NeedsCurrentMethodInput(GetMethodLoadKind())) { 3995 DCHECK(InputAt(GetSpecialInputIndex())->IsCurrentMethod()); 3996 return true; 3997 } else { 3998 DCHECK(InputCount() == GetSpecialInputIndex() || 3999 !InputAt(GetSpecialInputIndex())->IsCurrentMethod()); 4000 return false; 4001 } 4002 } 4003 bool HasDirectCodePtr() const { return GetCodePtrLocation() == CodePtrLocation::kCallDirect; } 4004 MethodReference GetTargetMethod() const { return target_method_; } 4005 void SetTargetMethod(MethodReference method) { target_method_ = method; } 4006 4007 int32_t GetStringInitOffset() const { 4008 DCHECK(IsStringInit()); 4009 return dispatch_info_.method_load_data; 4010 } 4011 4012 uint64_t GetMethodAddress() const { 4013 DCHECK(HasMethodAddress()); 4014 return dispatch_info_.method_load_data; 4015 } 4016 4017 uint32_t GetDexCacheArrayOffset() const { 4018 DCHECK(HasPcRelativeDexCache()); 4019 return dispatch_info_.method_load_data; 4020 } 4021 4022 uint64_t GetDirectCodePtr() const { 4023 DCHECK(HasDirectCodePtr()); 4024 return dispatch_info_.direct_code_ptr; 4025 } 4026 4027 ClinitCheckRequirement GetClinitCheckRequirement() const { 4028 return GetPackedField<ClinitCheckRequirementField>(); 4029 } 4030 4031 // Is this instruction a call to a static method? 4032 bool IsStatic() const { 4033 return GetOriginalInvokeType() == kStatic; 4034 } 4035 4036 // Remove the HClinitCheck or the replacement HLoadClass (set as last input by 4037 // PrepareForRegisterAllocation::VisitClinitCheck() in lieu of the initial HClinitCheck) 4038 // instruction; only relevant for static calls with explicit clinit check. 4039 void RemoveExplicitClinitCheck(ClinitCheckRequirement new_requirement) { 4040 DCHECK(IsStaticWithExplicitClinitCheck()); 4041 size_t last_input_index = InputCount() - 1; 4042 HInstruction* last_input = InputAt(last_input_index); 4043 DCHECK(last_input != nullptr); 4044 DCHECK(last_input->IsLoadClass() || last_input->IsClinitCheck()) << last_input->DebugName(); 4045 RemoveAsUserOfInput(last_input_index); 4046 inputs_.pop_back(); 4047 SetPackedField<ClinitCheckRequirementField>(new_requirement); 4048 DCHECK(!IsStaticWithExplicitClinitCheck()); 4049 } 4050 4051 // Is this a call to a static method whose declaring class has an 4052 // explicit initialization check in the graph? 4053 bool IsStaticWithExplicitClinitCheck() const { 4054 return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kExplicit); 4055 } 4056 4057 // Is this a call to a static method whose declaring class has an 4058 // implicit intialization check requirement? 4059 bool IsStaticWithImplicitClinitCheck() const { 4060 return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kImplicit); 4061 } 4062 4063 // Does this method load kind need the current method as an input? 4064 static bool NeedsCurrentMethodInput(MethodLoadKind kind) { 4065 return kind == MethodLoadKind::kRecursive || kind == MethodLoadKind::kDexCacheViaMethod; 4066 } 4067 4068 DECLARE_INSTRUCTION(InvokeStaticOrDirect); 4069 4070 protected: 4071 const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { 4072 const HUserRecord<HInstruction*> input_record = HInvoke::InputRecordAt(i); 4073 if (kIsDebugBuild && IsStaticWithExplicitClinitCheck() && (i == InputCount() - 1)) { 4074 HInstruction* input = input_record.GetInstruction(); 4075 // `input` is the last input of a static invoke marked as having 4076 // an explicit clinit check. It must either be: 4077 // - an art::HClinitCheck instruction, set by art::HGraphBuilder; or 4078 // - an art::HLoadClass instruction, set by art::PrepareForRegisterAllocation. 4079 DCHECK(input != nullptr); 4080 DCHECK(input->IsClinitCheck() || input->IsLoadClass()) << input->DebugName(); 4081 } 4082 return input_record; 4083 } 4084 4085 void InsertInputAt(size_t index, HInstruction* input); 4086 void RemoveInputAt(size_t index); 4087 4088 private: 4089 static constexpr size_t kFieldOptimizedInvokeType = kNumberOfInvokePackedBits; 4090 static constexpr size_t kFieldOptimizedInvokeTypeSize = 4091 MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType)); 4092 static constexpr size_t kFieldClinitCheckRequirement = 4093 kFieldOptimizedInvokeType + kFieldOptimizedInvokeTypeSize; 4094 static constexpr size_t kFieldClinitCheckRequirementSize = 4095 MinimumBitsToStore(static_cast<size_t>(ClinitCheckRequirement::kLast)); 4096 static constexpr size_t kNumberOfInvokeStaticOrDirectPackedBits = 4097 kFieldClinitCheckRequirement + kFieldClinitCheckRequirementSize; 4098 static_assert(kNumberOfInvokeStaticOrDirectPackedBits <= kMaxNumberOfPackedBits, 4099 "Too many packed fields."); 4100 using OptimizedInvokeTypeField = 4101 BitField<InvokeType, kFieldOptimizedInvokeType, kFieldOptimizedInvokeTypeSize>; 4102 using ClinitCheckRequirementField = BitField<ClinitCheckRequirement, 4103 kFieldClinitCheckRequirement, 4104 kFieldClinitCheckRequirementSize>; 4105 4106 // The target method may refer to different dex file or method index than the original 4107 // invoke. This happens for sharpened calls and for calls where a method was redeclared 4108 // in derived class to increase visibility. 4109 MethodReference target_method_; 4110 DispatchInfo dispatch_info_; 4111 4112 DISALLOW_COPY_AND_ASSIGN(HInvokeStaticOrDirect); 4113 }; 4114 std::ostream& operator<<(std::ostream& os, HInvokeStaticOrDirect::MethodLoadKind rhs); 4115 std::ostream& operator<<(std::ostream& os, HInvokeStaticOrDirect::ClinitCheckRequirement rhs); 4116 4117 class HInvokeVirtual : public HInvoke { 4118 public: 4119 HInvokeVirtual(ArenaAllocator* arena, 4120 uint32_t number_of_arguments, 4121 Primitive::Type return_type, 4122 uint32_t dex_pc, 4123 uint32_t dex_method_index, 4124 uint32_t vtable_index) 4125 : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kVirtual), 4126 vtable_index_(vtable_index) {} 4127 4128 bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { 4129 // TODO: Add implicit null checks in intrinsics. 4130 return (obj == InputAt(0)) && !GetLocations()->Intrinsified(); 4131 } 4132 4133 uint32_t GetVTableIndex() const { return vtable_index_; } 4134 4135 DECLARE_INSTRUCTION(InvokeVirtual); 4136 4137 private: 4138 const uint32_t vtable_index_; 4139 4140 DISALLOW_COPY_AND_ASSIGN(HInvokeVirtual); 4141 }; 4142 4143 class HInvokeInterface : public HInvoke { 4144 public: 4145 HInvokeInterface(ArenaAllocator* arena, 4146 uint32_t number_of_arguments, 4147 Primitive::Type return_type, 4148 uint32_t dex_pc, 4149 uint32_t dex_method_index, 4150 uint32_t imt_index) 4151 : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index, kInterface), 4152 imt_index_(imt_index) {} 4153 4154 bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { 4155 // TODO: Add implicit null checks in intrinsics. 4156 return (obj == InputAt(0)) && !GetLocations()->Intrinsified(); 4157 } 4158 4159 uint32_t GetImtIndex() const { return imt_index_; } 4160 uint32_t GetDexMethodIndex() const { return dex_method_index_; } 4161 4162 DECLARE_INSTRUCTION(InvokeInterface); 4163 4164 private: 4165 const uint32_t imt_index_; 4166 4167 DISALLOW_COPY_AND_ASSIGN(HInvokeInterface); 4168 }; 4169 4170 class HNeg : public HUnaryOperation { 4171 public: 4172 HNeg(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 4173 : HUnaryOperation(result_type, input, dex_pc) { 4174 DCHECK_EQ(result_type, Primitive::PrimitiveKind(input->GetType())); 4175 } 4176 4177 template <typename T> T Compute(T x) const { return -x; } 4178 4179 HConstant* Evaluate(HIntConstant* x) const OVERRIDE { 4180 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 4181 } 4182 HConstant* Evaluate(HLongConstant* x) const OVERRIDE { 4183 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); 4184 } 4185 HConstant* Evaluate(HFloatConstant* x) const OVERRIDE { 4186 return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue()), GetDexPc()); 4187 } 4188 HConstant* Evaluate(HDoubleConstant* x) const OVERRIDE { 4189 return GetBlock()->GetGraph()->GetDoubleConstant(Compute(x->GetValue()), GetDexPc()); 4190 } 4191 4192 DECLARE_INSTRUCTION(Neg); 4193 4194 private: 4195 DISALLOW_COPY_AND_ASSIGN(HNeg); 4196 }; 4197 4198 class HNewArray : public HExpression<2> { 4199 public: 4200 HNewArray(HInstruction* length, 4201 HCurrentMethod* current_method, 4202 uint32_t dex_pc, 4203 uint16_t type_index, 4204 const DexFile& dex_file, 4205 QuickEntrypointEnum entrypoint) 4206 : HExpression(Primitive::kPrimNot, SideEffects::CanTriggerGC(), dex_pc), 4207 type_index_(type_index), 4208 dex_file_(dex_file), 4209 entrypoint_(entrypoint) { 4210 SetRawInputAt(0, length); 4211 SetRawInputAt(1, current_method); 4212 } 4213 4214 uint16_t GetTypeIndex() const { return type_index_; } 4215 const DexFile& GetDexFile() const { return dex_file_; } 4216 4217 // Calls runtime so needs an environment. 4218 bool NeedsEnvironment() const OVERRIDE { return true; } 4219 4220 // May throw NegativeArraySizeException, OutOfMemoryError, etc. 4221 bool CanThrow() const OVERRIDE { return true; } 4222 4223 bool CanBeNull() const OVERRIDE { return false; } 4224 4225 QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; } 4226 4227 DECLARE_INSTRUCTION(NewArray); 4228 4229 private: 4230 const uint16_t type_index_; 4231 const DexFile& dex_file_; 4232 const QuickEntrypointEnum entrypoint_; 4233 4234 DISALLOW_COPY_AND_ASSIGN(HNewArray); 4235 }; 4236 4237 class HAdd : public HBinaryOperation { 4238 public: 4239 HAdd(Primitive::Type result_type, 4240 HInstruction* left, 4241 HInstruction* right, 4242 uint32_t dex_pc = kNoDexPc) 4243 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4244 4245 bool IsCommutative() const OVERRIDE { return true; } 4246 4247 template <typename T> T Compute(T x, T y) const { return x + y; } 4248 4249 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4250 return GetBlock()->GetGraph()->GetIntConstant( 4251 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4252 } 4253 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4254 return GetBlock()->GetGraph()->GetLongConstant( 4255 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4256 } 4257 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 4258 return GetBlock()->GetGraph()->GetFloatConstant( 4259 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4260 } 4261 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 4262 return GetBlock()->GetGraph()->GetDoubleConstant( 4263 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4264 } 4265 4266 DECLARE_INSTRUCTION(Add); 4267 4268 private: 4269 DISALLOW_COPY_AND_ASSIGN(HAdd); 4270 }; 4271 4272 class HSub : public HBinaryOperation { 4273 public: 4274 HSub(Primitive::Type result_type, 4275 HInstruction* left, 4276 HInstruction* right, 4277 uint32_t dex_pc = kNoDexPc) 4278 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4279 4280 template <typename T> T Compute(T x, T y) const { return x - y; } 4281 4282 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4283 return GetBlock()->GetGraph()->GetIntConstant( 4284 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4285 } 4286 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4287 return GetBlock()->GetGraph()->GetLongConstant( 4288 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4289 } 4290 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 4291 return GetBlock()->GetGraph()->GetFloatConstant( 4292 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4293 } 4294 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 4295 return GetBlock()->GetGraph()->GetDoubleConstant( 4296 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4297 } 4298 4299 DECLARE_INSTRUCTION(Sub); 4300 4301 private: 4302 DISALLOW_COPY_AND_ASSIGN(HSub); 4303 }; 4304 4305 class HMul : public HBinaryOperation { 4306 public: 4307 HMul(Primitive::Type result_type, 4308 HInstruction* left, 4309 HInstruction* right, 4310 uint32_t dex_pc = kNoDexPc) 4311 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4312 4313 bool IsCommutative() const OVERRIDE { return true; } 4314 4315 template <typename T> T Compute(T x, T y) const { return x * y; } 4316 4317 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4318 return GetBlock()->GetGraph()->GetIntConstant( 4319 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4320 } 4321 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4322 return GetBlock()->GetGraph()->GetLongConstant( 4323 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4324 } 4325 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 4326 return GetBlock()->GetGraph()->GetFloatConstant( 4327 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4328 } 4329 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 4330 return GetBlock()->GetGraph()->GetDoubleConstant( 4331 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4332 } 4333 4334 DECLARE_INSTRUCTION(Mul); 4335 4336 private: 4337 DISALLOW_COPY_AND_ASSIGN(HMul); 4338 }; 4339 4340 class HDiv : public HBinaryOperation { 4341 public: 4342 HDiv(Primitive::Type result_type, 4343 HInstruction* left, 4344 HInstruction* right, 4345 uint32_t dex_pc) 4346 : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {} 4347 4348 template <typename T> 4349 T ComputeIntegral(T x, T y) const { 4350 DCHECK(!Primitive::IsFloatingPointType(GetType())) << GetType(); 4351 // Our graph structure ensures we never have 0 for `y` during 4352 // constant folding. 4353 DCHECK_NE(y, 0); 4354 // Special case -1 to avoid getting a SIGFPE on x86(_64). 4355 return (y == -1) ? -x : x / y; 4356 } 4357 4358 template <typename T> 4359 T ComputeFP(T x, T y) const { 4360 DCHECK(Primitive::IsFloatingPointType(GetType())) << GetType(); 4361 return x / y; 4362 } 4363 4364 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4365 return GetBlock()->GetGraph()->GetIntConstant( 4366 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 4367 } 4368 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4369 return GetBlock()->GetGraph()->GetLongConstant( 4370 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 4371 } 4372 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 4373 return GetBlock()->GetGraph()->GetFloatConstant( 4374 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4375 } 4376 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 4377 return GetBlock()->GetGraph()->GetDoubleConstant( 4378 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4379 } 4380 4381 static SideEffects SideEffectsForArchRuntimeCalls() { 4382 // The generated code can use a runtime call. 4383 return SideEffects::CanTriggerGC(); 4384 } 4385 4386 DECLARE_INSTRUCTION(Div); 4387 4388 private: 4389 DISALLOW_COPY_AND_ASSIGN(HDiv); 4390 }; 4391 4392 class HRem : public HBinaryOperation { 4393 public: 4394 HRem(Primitive::Type result_type, 4395 HInstruction* left, 4396 HInstruction* right, 4397 uint32_t dex_pc) 4398 : HBinaryOperation(result_type, left, right, SideEffectsForArchRuntimeCalls(), dex_pc) {} 4399 4400 template <typename T> 4401 T ComputeIntegral(T x, T y) const { 4402 DCHECK(!Primitive::IsFloatingPointType(GetType())) << GetType(); 4403 // Our graph structure ensures we never have 0 for `y` during 4404 // constant folding. 4405 DCHECK_NE(y, 0); 4406 // Special case -1 to avoid getting a SIGFPE on x86(_64). 4407 return (y == -1) ? 0 : x % y; 4408 } 4409 4410 template <typename T> 4411 T ComputeFP(T x, T y) const { 4412 DCHECK(Primitive::IsFloatingPointType(GetType())) << GetType(); 4413 return std::fmod(x, y); 4414 } 4415 4416 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4417 return GetBlock()->GetGraph()->GetIntConstant( 4418 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 4419 } 4420 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4421 return GetBlock()->GetGraph()->GetLongConstant( 4422 ComputeIntegral(x->GetValue(), y->GetValue()), GetDexPc()); 4423 } 4424 HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const OVERRIDE { 4425 return GetBlock()->GetGraph()->GetFloatConstant( 4426 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4427 } 4428 HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const OVERRIDE { 4429 return GetBlock()->GetGraph()->GetDoubleConstant( 4430 ComputeFP(x->GetValue(), y->GetValue()), GetDexPc()); 4431 } 4432 4433 static SideEffects SideEffectsForArchRuntimeCalls() { 4434 return SideEffects::CanTriggerGC(); 4435 } 4436 4437 DECLARE_INSTRUCTION(Rem); 4438 4439 private: 4440 DISALLOW_COPY_AND_ASSIGN(HRem); 4441 }; 4442 4443 class HDivZeroCheck : public HExpression<1> { 4444 public: 4445 // `HDivZeroCheck` can trigger GC, as it may call the `ArithmeticException` 4446 // constructor. 4447 HDivZeroCheck(HInstruction* value, uint32_t dex_pc) 4448 : HExpression(value->GetType(), SideEffects::CanTriggerGC(), dex_pc) { 4449 SetRawInputAt(0, value); 4450 } 4451 4452 Primitive::Type GetType() const OVERRIDE { return InputAt(0)->GetType(); } 4453 4454 bool CanBeMoved() const OVERRIDE { return true; } 4455 4456 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 4457 return true; 4458 } 4459 4460 bool NeedsEnvironment() const OVERRIDE { return true; } 4461 bool CanThrow() const OVERRIDE { return true; } 4462 4463 DECLARE_INSTRUCTION(DivZeroCheck); 4464 4465 private: 4466 DISALLOW_COPY_AND_ASSIGN(HDivZeroCheck); 4467 }; 4468 4469 class HShl : public HBinaryOperation { 4470 public: 4471 HShl(Primitive::Type result_type, 4472 HInstruction* value, 4473 HInstruction* distance, 4474 uint32_t dex_pc = kNoDexPc) 4475 : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { 4476 DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); 4477 DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); 4478 } 4479 4480 template <typename T> 4481 T Compute(T value, int32_t distance, int32_t max_shift_distance) const { 4482 return value << (distance & max_shift_distance); 4483 } 4484 4485 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { 4486 return GetBlock()->GetGraph()->GetIntConstant( 4487 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 4488 } 4489 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { 4490 return GetBlock()->GetGraph()->GetLongConstant( 4491 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 4492 } 4493 HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, 4494 HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4495 LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; 4496 UNREACHABLE(); 4497 } 4498 HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, 4499 HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4500 LOG(FATAL) << DebugName() << " is not defined for float values"; 4501 UNREACHABLE(); 4502 } 4503 HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, 4504 HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4505 LOG(FATAL) << DebugName() << " is not defined for double values"; 4506 UNREACHABLE(); 4507 } 4508 4509 DECLARE_INSTRUCTION(Shl); 4510 4511 private: 4512 DISALLOW_COPY_AND_ASSIGN(HShl); 4513 }; 4514 4515 class HShr : public HBinaryOperation { 4516 public: 4517 HShr(Primitive::Type result_type, 4518 HInstruction* value, 4519 HInstruction* distance, 4520 uint32_t dex_pc = kNoDexPc) 4521 : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { 4522 DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); 4523 DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); 4524 } 4525 4526 template <typename T> 4527 T Compute(T value, int32_t distance, int32_t max_shift_distance) const { 4528 return value >> (distance & max_shift_distance); 4529 } 4530 4531 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { 4532 return GetBlock()->GetGraph()->GetIntConstant( 4533 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 4534 } 4535 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { 4536 return GetBlock()->GetGraph()->GetLongConstant( 4537 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 4538 } 4539 HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, 4540 HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4541 LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; 4542 UNREACHABLE(); 4543 } 4544 HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, 4545 HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4546 LOG(FATAL) << DebugName() << " is not defined for float values"; 4547 UNREACHABLE(); 4548 } 4549 HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, 4550 HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4551 LOG(FATAL) << DebugName() << " is not defined for double values"; 4552 UNREACHABLE(); 4553 } 4554 4555 DECLARE_INSTRUCTION(Shr); 4556 4557 private: 4558 DISALLOW_COPY_AND_ASSIGN(HShr); 4559 }; 4560 4561 class HUShr : public HBinaryOperation { 4562 public: 4563 HUShr(Primitive::Type result_type, 4564 HInstruction* value, 4565 HInstruction* distance, 4566 uint32_t dex_pc = kNoDexPc) 4567 : HBinaryOperation(result_type, value, distance, SideEffects::None(), dex_pc) { 4568 DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); 4569 DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); 4570 } 4571 4572 template <typename T> 4573 T Compute(T value, int32_t distance, int32_t max_shift_distance) const { 4574 typedef typename std::make_unsigned<T>::type V; 4575 V ux = static_cast<V>(value); 4576 return static_cast<T>(ux >> (distance & max_shift_distance)); 4577 } 4578 4579 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { 4580 return GetBlock()->GetGraph()->GetIntConstant( 4581 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 4582 } 4583 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { 4584 return GetBlock()->GetGraph()->GetLongConstant( 4585 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 4586 } 4587 HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, 4588 HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4589 LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; 4590 UNREACHABLE(); 4591 } 4592 HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, 4593 HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4594 LOG(FATAL) << DebugName() << " is not defined for float values"; 4595 UNREACHABLE(); 4596 } 4597 HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, 4598 HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4599 LOG(FATAL) << DebugName() << " is not defined for double values"; 4600 UNREACHABLE(); 4601 } 4602 4603 DECLARE_INSTRUCTION(UShr); 4604 4605 private: 4606 DISALLOW_COPY_AND_ASSIGN(HUShr); 4607 }; 4608 4609 class HAnd : public HBinaryOperation { 4610 public: 4611 HAnd(Primitive::Type result_type, 4612 HInstruction* left, 4613 HInstruction* right, 4614 uint32_t dex_pc = kNoDexPc) 4615 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4616 4617 bool IsCommutative() const OVERRIDE { return true; } 4618 4619 template <typename T> T Compute(T x, T y) const { return x & y; } 4620 4621 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4622 return GetBlock()->GetGraph()->GetIntConstant( 4623 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4624 } 4625 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4626 return GetBlock()->GetGraph()->GetLongConstant( 4627 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4628 } 4629 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 4630 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4631 LOG(FATAL) << DebugName() << " is not defined for float values"; 4632 UNREACHABLE(); 4633 } 4634 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 4635 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4636 LOG(FATAL) << DebugName() << " is not defined for double values"; 4637 UNREACHABLE(); 4638 } 4639 4640 DECLARE_INSTRUCTION(And); 4641 4642 private: 4643 DISALLOW_COPY_AND_ASSIGN(HAnd); 4644 }; 4645 4646 class HOr : public HBinaryOperation { 4647 public: 4648 HOr(Primitive::Type result_type, 4649 HInstruction* left, 4650 HInstruction* right, 4651 uint32_t dex_pc = kNoDexPc) 4652 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4653 4654 bool IsCommutative() const OVERRIDE { return true; } 4655 4656 template <typename T> T Compute(T x, T y) const { return x | y; } 4657 4658 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4659 return GetBlock()->GetGraph()->GetIntConstant( 4660 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4661 } 4662 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4663 return GetBlock()->GetGraph()->GetLongConstant( 4664 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4665 } 4666 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 4667 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4668 LOG(FATAL) << DebugName() << " is not defined for float values"; 4669 UNREACHABLE(); 4670 } 4671 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 4672 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4673 LOG(FATAL) << DebugName() << " is not defined for double values"; 4674 UNREACHABLE(); 4675 } 4676 4677 DECLARE_INSTRUCTION(Or); 4678 4679 private: 4680 DISALLOW_COPY_AND_ASSIGN(HOr); 4681 }; 4682 4683 class HXor : public HBinaryOperation { 4684 public: 4685 HXor(Primitive::Type result_type, 4686 HInstruction* left, 4687 HInstruction* right, 4688 uint32_t dex_pc = kNoDexPc) 4689 : HBinaryOperation(result_type, left, right, SideEffects::None(), dex_pc) {} 4690 4691 bool IsCommutative() const OVERRIDE { return true; } 4692 4693 template <typename T> T Compute(T x, T y) const { return x ^ y; } 4694 4695 HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const OVERRIDE { 4696 return GetBlock()->GetGraph()->GetIntConstant( 4697 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4698 } 4699 HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const OVERRIDE { 4700 return GetBlock()->GetGraph()->GetLongConstant( 4701 Compute(x->GetValue(), y->GetValue()), GetDexPc()); 4702 } 4703 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED, 4704 HFloatConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4705 LOG(FATAL) << DebugName() << " is not defined for float values"; 4706 UNREACHABLE(); 4707 } 4708 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED, 4709 HDoubleConstant* y ATTRIBUTE_UNUSED) const OVERRIDE { 4710 LOG(FATAL) << DebugName() << " is not defined for double values"; 4711 UNREACHABLE(); 4712 } 4713 4714 DECLARE_INSTRUCTION(Xor); 4715 4716 private: 4717 DISALLOW_COPY_AND_ASSIGN(HXor); 4718 }; 4719 4720 class HRor : public HBinaryOperation { 4721 public: 4722 HRor(Primitive::Type result_type, HInstruction* value, HInstruction* distance) 4723 : HBinaryOperation(result_type, value, distance) { 4724 DCHECK_EQ(result_type, Primitive::PrimitiveKind(value->GetType())); 4725 DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(distance->GetType())); 4726 } 4727 4728 template <typename T> 4729 T Compute(T value, int32_t distance, int32_t max_shift_value) const { 4730 typedef typename std::make_unsigned<T>::type V; 4731 V ux = static_cast<V>(value); 4732 if ((distance & max_shift_value) == 0) { 4733 return static_cast<T>(ux); 4734 } else { 4735 const V reg_bits = sizeof(T) * 8; 4736 return static_cast<T>(ux >> (distance & max_shift_value)) | 4737 (value << (reg_bits - (distance & max_shift_value))); 4738 } 4739 } 4740 4741 HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const OVERRIDE { 4742 return GetBlock()->GetGraph()->GetIntConstant( 4743 Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance), GetDexPc()); 4744 } 4745 HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const OVERRIDE { 4746 return GetBlock()->GetGraph()->GetLongConstant( 4747 Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance), GetDexPc()); 4748 } 4749 HConstant* Evaluate(HLongConstant* value ATTRIBUTE_UNUSED, 4750 HLongConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4751 LOG(FATAL) << DebugName() << " is not defined for the (long, long) case."; 4752 UNREACHABLE(); 4753 } 4754 HConstant* Evaluate(HFloatConstant* value ATTRIBUTE_UNUSED, 4755 HFloatConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4756 LOG(FATAL) << DebugName() << " is not defined for float values"; 4757 UNREACHABLE(); 4758 } 4759 HConstant* Evaluate(HDoubleConstant* value ATTRIBUTE_UNUSED, 4760 HDoubleConstant* distance ATTRIBUTE_UNUSED) const OVERRIDE { 4761 LOG(FATAL) << DebugName() << " is not defined for double values"; 4762 UNREACHABLE(); 4763 } 4764 4765 DECLARE_INSTRUCTION(Ror); 4766 4767 private: 4768 DISALLOW_COPY_AND_ASSIGN(HRor); 4769 }; 4770 4771 // The value of a parameter in this method. Its location depends on 4772 // the calling convention. 4773 class HParameterValue : public HExpression<0> { 4774 public: 4775 HParameterValue(const DexFile& dex_file, 4776 uint16_t type_index, 4777 uint8_t index, 4778 Primitive::Type parameter_type, 4779 bool is_this = false) 4780 : HExpression(parameter_type, SideEffects::None(), kNoDexPc), 4781 dex_file_(dex_file), 4782 type_index_(type_index), 4783 index_(index) { 4784 SetPackedFlag<kFlagIsThis>(is_this); 4785 SetPackedFlag<kFlagCanBeNull>(!is_this); 4786 } 4787 4788 const DexFile& GetDexFile() const { return dex_file_; } 4789 uint16_t GetTypeIndex() const { return type_index_; } 4790 uint8_t GetIndex() const { return index_; } 4791 bool IsThis() const { return GetPackedFlag<kFlagIsThis>(); } 4792 4793 bool CanBeNull() const OVERRIDE { return GetPackedFlag<kFlagCanBeNull>(); } 4794 void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); } 4795 4796 DECLARE_INSTRUCTION(ParameterValue); 4797 4798 private: 4799 // Whether or not the parameter value corresponds to 'this' argument. 4800 static constexpr size_t kFlagIsThis = kNumberOfExpressionPackedBits; 4801 static constexpr size_t kFlagCanBeNull = kFlagIsThis + 1; 4802 static constexpr size_t kNumberOfParameterValuePackedBits = kFlagCanBeNull + 1; 4803 static_assert(kNumberOfParameterValuePackedBits <= kMaxNumberOfPackedBits, 4804 "Too many packed fields."); 4805 4806 const DexFile& dex_file_; 4807 const uint16_t type_index_; 4808 // The index of this parameter in the parameters list. Must be less 4809 // than HGraph::number_of_in_vregs_. 4810 const uint8_t index_; 4811 4812 DISALLOW_COPY_AND_ASSIGN(HParameterValue); 4813 }; 4814 4815 class HNot : public HUnaryOperation { 4816 public: 4817 HNot(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc) 4818 : HUnaryOperation(result_type, input, dex_pc) {} 4819 4820 bool CanBeMoved() const OVERRIDE { return true; } 4821 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 4822 return true; 4823 } 4824 4825 template <typename T> T Compute(T x) const { return ~x; } 4826 4827 HConstant* Evaluate(HIntConstant* x) const OVERRIDE { 4828 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 4829 } 4830 HConstant* Evaluate(HLongConstant* x) const OVERRIDE { 4831 return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()), GetDexPc()); 4832 } 4833 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { 4834 LOG(FATAL) << DebugName() << " is not defined for float values"; 4835 UNREACHABLE(); 4836 } 4837 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { 4838 LOG(FATAL) << DebugName() << " is not defined for double values"; 4839 UNREACHABLE(); 4840 } 4841 4842 DECLARE_INSTRUCTION(Not); 4843 4844 private: 4845 DISALLOW_COPY_AND_ASSIGN(HNot); 4846 }; 4847 4848 class HBooleanNot : public HUnaryOperation { 4849 public: 4850 explicit HBooleanNot(HInstruction* input, uint32_t dex_pc = kNoDexPc) 4851 : HUnaryOperation(Primitive::Type::kPrimBoolean, input, dex_pc) {} 4852 4853 bool CanBeMoved() const OVERRIDE { return true; } 4854 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 4855 return true; 4856 } 4857 4858 template <typename T> bool Compute(T x) const { 4859 DCHECK(IsUint<1>(x)) << x; 4860 return !x; 4861 } 4862 4863 HConstant* Evaluate(HIntConstant* x) const OVERRIDE { 4864 return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()), GetDexPc()); 4865 } 4866 HConstant* Evaluate(HLongConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { 4867 LOG(FATAL) << DebugName() << " is not defined for long values"; 4868 UNREACHABLE(); 4869 } 4870 HConstant* Evaluate(HFloatConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { 4871 LOG(FATAL) << DebugName() << " is not defined for float values"; 4872 UNREACHABLE(); 4873 } 4874 HConstant* Evaluate(HDoubleConstant* x ATTRIBUTE_UNUSED) const OVERRIDE { 4875 LOG(FATAL) << DebugName() << " is not defined for double values"; 4876 UNREACHABLE(); 4877 } 4878 4879 DECLARE_INSTRUCTION(BooleanNot); 4880 4881 private: 4882 DISALLOW_COPY_AND_ASSIGN(HBooleanNot); 4883 }; 4884 4885 class HTypeConversion : public HExpression<1> { 4886 public: 4887 // Instantiate a type conversion of `input` to `result_type`. 4888 HTypeConversion(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc) 4889 : HExpression(result_type, 4890 SideEffectsForArchRuntimeCalls(input->GetType(), result_type), 4891 dex_pc) { 4892 SetRawInputAt(0, input); 4893 // Invariant: We should never generate a conversion to a Boolean value. 4894 DCHECK_NE(Primitive::kPrimBoolean, result_type); 4895 } 4896 4897 HInstruction* GetInput() const { return InputAt(0); } 4898 Primitive::Type GetInputType() const { return GetInput()->GetType(); } 4899 Primitive::Type GetResultType() const { return GetType(); } 4900 4901 bool CanBeMoved() const OVERRIDE { return true; } 4902 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } 4903 4904 // Try to statically evaluate the conversion and return a HConstant 4905 // containing the result. If the input cannot be converted, return nullptr. 4906 HConstant* TryStaticEvaluation() const; 4907 4908 static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type input_type, 4909 Primitive::Type result_type) { 4910 // Some architectures may not require the 'GC' side effects, but at this point 4911 // in the compilation process we do not know what architecture we will 4912 // generate code for, so we must be conservative. 4913 if ((Primitive::IsFloatingPointType(input_type) && Primitive::IsIntegralType(result_type)) 4914 || (input_type == Primitive::kPrimLong && Primitive::IsFloatingPointType(result_type))) { 4915 return SideEffects::CanTriggerGC(); 4916 } 4917 return SideEffects::None(); 4918 } 4919 4920 DECLARE_INSTRUCTION(TypeConversion); 4921 4922 private: 4923 DISALLOW_COPY_AND_ASSIGN(HTypeConversion); 4924 }; 4925 4926 static constexpr uint32_t kNoRegNumber = -1; 4927 4928 class HNullCheck : public HExpression<1> { 4929 public: 4930 // `HNullCheck` can trigger GC, as it may call the `NullPointerException` 4931 // constructor. 4932 HNullCheck(HInstruction* value, uint32_t dex_pc) 4933 : HExpression(value->GetType(), SideEffects::CanTriggerGC(), dex_pc) { 4934 SetRawInputAt(0, value); 4935 } 4936 4937 bool CanBeMoved() const OVERRIDE { return true; } 4938 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 4939 return true; 4940 } 4941 4942 bool NeedsEnvironment() const OVERRIDE { return true; } 4943 4944 bool CanThrow() const OVERRIDE { return true; } 4945 4946 bool CanBeNull() const OVERRIDE { return false; } 4947 4948 4949 DECLARE_INSTRUCTION(NullCheck); 4950 4951 private: 4952 DISALLOW_COPY_AND_ASSIGN(HNullCheck); 4953 }; 4954 4955 class FieldInfo : public ValueObject { 4956 public: 4957 FieldInfo(MemberOffset field_offset, 4958 Primitive::Type field_type, 4959 bool is_volatile, 4960 uint32_t index, 4961 uint16_t declaring_class_def_index, 4962 const DexFile& dex_file, 4963 Handle<mirror::DexCache> dex_cache) 4964 : field_offset_(field_offset), 4965 field_type_(field_type), 4966 is_volatile_(is_volatile), 4967 index_(index), 4968 declaring_class_def_index_(declaring_class_def_index), 4969 dex_file_(dex_file), 4970 dex_cache_(dex_cache) {} 4971 4972 MemberOffset GetFieldOffset() const { return field_offset_; } 4973 Primitive::Type GetFieldType() const { return field_type_; } 4974 uint32_t GetFieldIndex() const { return index_; } 4975 uint16_t GetDeclaringClassDefIndex() const { return declaring_class_def_index_;} 4976 const DexFile& GetDexFile() const { return dex_file_; } 4977 bool IsVolatile() const { return is_volatile_; } 4978 Handle<mirror::DexCache> GetDexCache() const { return dex_cache_; } 4979 4980 private: 4981 const MemberOffset field_offset_; 4982 const Primitive::Type field_type_; 4983 const bool is_volatile_; 4984 const uint32_t index_; 4985 const uint16_t declaring_class_def_index_; 4986 const DexFile& dex_file_; 4987 const Handle<mirror::DexCache> dex_cache_; 4988 }; 4989 4990 class HInstanceFieldGet : public HExpression<1> { 4991 public: 4992 HInstanceFieldGet(HInstruction* value, 4993 Primitive::Type field_type, 4994 MemberOffset field_offset, 4995 bool is_volatile, 4996 uint32_t field_idx, 4997 uint16_t declaring_class_def_index, 4998 const DexFile& dex_file, 4999 Handle<mirror::DexCache> dex_cache, 5000 uint32_t dex_pc) 5001 : HExpression(field_type, 5002 SideEffects::FieldReadOfType(field_type, is_volatile), 5003 dex_pc), 5004 field_info_(field_offset, 5005 field_type, 5006 is_volatile, 5007 field_idx, 5008 declaring_class_def_index, 5009 dex_file, 5010 dex_cache) { 5011 SetRawInputAt(0, value); 5012 } 5013 5014 bool CanBeMoved() const OVERRIDE { return !IsVolatile(); } 5015 5016 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 5017 HInstanceFieldGet* other_get = other->AsInstanceFieldGet(); 5018 return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue(); 5019 } 5020 5021 bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { 5022 return (obj == InputAt(0)) && GetFieldOffset().Uint32Value() < kPageSize; 5023 } 5024 5025 size_t ComputeHashCode() const OVERRIDE { 5026 return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue(); 5027 } 5028 5029 const FieldInfo& GetFieldInfo() const { return field_info_; } 5030 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 5031 Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } 5032 bool IsVolatile() const { return field_info_.IsVolatile(); } 5033 5034 DECLARE_INSTRUCTION(InstanceFieldGet); 5035 5036 private: 5037 const FieldInfo field_info_; 5038 5039 DISALLOW_COPY_AND_ASSIGN(HInstanceFieldGet); 5040 }; 5041 5042 class HInstanceFieldSet : public HTemplateInstruction<2> { 5043 public: 5044 HInstanceFieldSet(HInstruction* object, 5045 HInstruction* value, 5046 Primitive::Type field_type, 5047 MemberOffset field_offset, 5048 bool is_volatile, 5049 uint32_t field_idx, 5050 uint16_t declaring_class_def_index, 5051 const DexFile& dex_file, 5052 Handle<mirror::DexCache> dex_cache, 5053 uint32_t dex_pc) 5054 : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile), 5055 dex_pc), 5056 field_info_(field_offset, 5057 field_type, 5058 is_volatile, 5059 field_idx, 5060 declaring_class_def_index, 5061 dex_file, 5062 dex_cache) { 5063 SetPackedFlag<kFlagValueCanBeNull>(true); 5064 SetRawInputAt(0, object); 5065 SetRawInputAt(1, value); 5066 } 5067 5068 bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { 5069 return (obj == InputAt(0)) && GetFieldOffset().Uint32Value() < kPageSize; 5070 } 5071 5072 const FieldInfo& GetFieldInfo() const { return field_info_; } 5073 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 5074 Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } 5075 bool IsVolatile() const { return field_info_.IsVolatile(); } 5076 HInstruction* GetValue() const { return InputAt(1); } 5077 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 5078 void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } 5079 5080 DECLARE_INSTRUCTION(InstanceFieldSet); 5081 5082 private: 5083 static constexpr size_t kFlagValueCanBeNull = kNumberOfGenericPackedBits; 5084 static constexpr size_t kNumberOfInstanceFieldSetPackedBits = kFlagValueCanBeNull + 1; 5085 static_assert(kNumberOfInstanceFieldSetPackedBits <= kMaxNumberOfPackedBits, 5086 "Too many packed fields."); 5087 5088 const FieldInfo field_info_; 5089 5090 DISALLOW_COPY_AND_ASSIGN(HInstanceFieldSet); 5091 }; 5092 5093 class HArrayGet : public HExpression<2> { 5094 public: 5095 HArrayGet(HInstruction* array, 5096 HInstruction* index, 5097 Primitive::Type type, 5098 uint32_t dex_pc, 5099 SideEffects additional_side_effects = SideEffects::None()) 5100 : HExpression(type, 5101 SideEffects::ArrayReadOfType(type).Union(additional_side_effects), 5102 dex_pc) { 5103 SetRawInputAt(0, array); 5104 SetRawInputAt(1, index); 5105 } 5106 5107 bool CanBeMoved() const OVERRIDE { return true; } 5108 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 5109 return true; 5110 } 5111 bool CanDoImplicitNullCheckOn(HInstruction* obj ATTRIBUTE_UNUSED) const OVERRIDE { 5112 // TODO: We can be smarter here. 5113 // Currently, the array access is always preceded by an ArrayLength or a NullCheck 5114 // which generates the implicit null check. There are cases when these can be removed 5115 // to produce better code. If we ever add optimizations to do so we should allow an 5116 // implicit check here (as long as the address falls in the first page). 5117 return false; 5118 } 5119 5120 bool IsEquivalentOf(HArrayGet* other) const { 5121 bool result = (GetDexPc() == other->GetDexPc()); 5122 if (kIsDebugBuild && result) { 5123 DCHECK_EQ(GetBlock(), other->GetBlock()); 5124 DCHECK_EQ(GetArray(), other->GetArray()); 5125 DCHECK_EQ(GetIndex(), other->GetIndex()); 5126 if (Primitive::IsIntOrLongType(GetType())) { 5127 DCHECK(Primitive::IsFloatingPointType(other->GetType())) << other->GetType(); 5128 } else { 5129 DCHECK(Primitive::IsFloatingPointType(GetType())) << GetType(); 5130 DCHECK(Primitive::IsIntOrLongType(other->GetType())) << other->GetType(); 5131 } 5132 } 5133 return result; 5134 } 5135 5136 HInstruction* GetArray() const { return InputAt(0); } 5137 HInstruction* GetIndex() const { return InputAt(1); } 5138 5139 DECLARE_INSTRUCTION(ArrayGet); 5140 5141 private: 5142 DISALLOW_COPY_AND_ASSIGN(HArrayGet); 5143 }; 5144 5145 class HArraySet : public HTemplateInstruction<3> { 5146 public: 5147 HArraySet(HInstruction* array, 5148 HInstruction* index, 5149 HInstruction* value, 5150 Primitive::Type expected_component_type, 5151 uint32_t dex_pc, 5152 SideEffects additional_side_effects = SideEffects::None()) 5153 : HTemplateInstruction( 5154 SideEffects::ArrayWriteOfType(expected_component_type).Union( 5155 SideEffectsForArchRuntimeCalls(value->GetType())).Union( 5156 additional_side_effects), 5157 dex_pc) { 5158 SetPackedField<ExpectedComponentTypeField>(expected_component_type); 5159 SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType() == Primitive::kPrimNot); 5160 SetPackedFlag<kFlagValueCanBeNull>(true); 5161 SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(false); 5162 SetRawInputAt(0, array); 5163 SetRawInputAt(1, index); 5164 SetRawInputAt(2, value); 5165 } 5166 5167 bool NeedsEnvironment() const OVERRIDE { 5168 // We call a runtime method to throw ArrayStoreException. 5169 return NeedsTypeCheck(); 5170 } 5171 5172 // Can throw ArrayStoreException. 5173 bool CanThrow() const OVERRIDE { return NeedsTypeCheck(); } 5174 5175 bool CanDoImplicitNullCheckOn(HInstruction* obj ATTRIBUTE_UNUSED) const OVERRIDE { 5176 // TODO: Same as for ArrayGet. 5177 return false; 5178 } 5179 5180 void ClearNeedsTypeCheck() { 5181 SetPackedFlag<kFlagNeedsTypeCheck>(false); 5182 } 5183 5184 void ClearValueCanBeNull() { 5185 SetPackedFlag<kFlagValueCanBeNull>(false); 5186 } 5187 5188 void SetStaticTypeOfArrayIsObjectArray() { 5189 SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(true); 5190 } 5191 5192 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 5193 bool NeedsTypeCheck() const { return GetPackedFlag<kFlagNeedsTypeCheck>(); } 5194 bool StaticTypeOfArrayIsObjectArray() const { 5195 return GetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(); 5196 } 5197 5198 HInstruction* GetArray() const { return InputAt(0); } 5199 HInstruction* GetIndex() const { return InputAt(1); } 5200 HInstruction* GetValue() const { return InputAt(2); } 5201 5202 Primitive::Type GetComponentType() const { 5203 // The Dex format does not type floating point index operations. Since the 5204 // `expected_component_type_` is set during building and can therefore not 5205 // be correct, we also check what is the value type. If it is a floating 5206 // point type, we must use that type. 5207 Primitive::Type value_type = GetValue()->GetType(); 5208 return ((value_type == Primitive::kPrimFloat) || (value_type == Primitive::kPrimDouble)) 5209 ? value_type 5210 : GetRawExpectedComponentType(); 5211 } 5212 5213 Primitive::Type GetRawExpectedComponentType() const { 5214 return GetPackedField<ExpectedComponentTypeField>(); 5215 } 5216 5217 static SideEffects SideEffectsForArchRuntimeCalls(Primitive::Type value_type) { 5218 return (value_type == Primitive::kPrimNot) ? SideEffects::CanTriggerGC() : SideEffects::None(); 5219 } 5220 5221 DECLARE_INSTRUCTION(ArraySet); 5222 5223 private: 5224 static constexpr size_t kFieldExpectedComponentType = kNumberOfGenericPackedBits; 5225 static constexpr size_t kFieldExpectedComponentTypeSize = 5226 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 5227 static constexpr size_t kFlagNeedsTypeCheck = 5228 kFieldExpectedComponentType + kFieldExpectedComponentTypeSize; 5229 static constexpr size_t kFlagValueCanBeNull = kFlagNeedsTypeCheck + 1; 5230 // Cached information for the reference_type_info_ so that codegen 5231 // does not need to inspect the static type. 5232 static constexpr size_t kFlagStaticTypeOfArrayIsObjectArray = kFlagValueCanBeNull + 1; 5233 static constexpr size_t kNumberOfArraySetPackedBits = 5234 kFlagStaticTypeOfArrayIsObjectArray + 1; 5235 static_assert(kNumberOfArraySetPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 5236 using ExpectedComponentTypeField = 5237 BitField<Primitive::Type, kFieldExpectedComponentType, kFieldExpectedComponentTypeSize>; 5238 5239 DISALLOW_COPY_AND_ASSIGN(HArraySet); 5240 }; 5241 5242 class HArrayLength : public HExpression<1> { 5243 public: 5244 HArrayLength(HInstruction* array, uint32_t dex_pc) 5245 : HExpression(Primitive::kPrimInt, SideEffects::None(), dex_pc) { 5246 // Note that arrays do not change length, so the instruction does not 5247 // depend on any write. 5248 SetRawInputAt(0, array); 5249 } 5250 5251 bool CanBeMoved() const OVERRIDE { return true; } 5252 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 5253 return true; 5254 } 5255 bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { 5256 return obj == InputAt(0); 5257 } 5258 5259 DECLARE_INSTRUCTION(ArrayLength); 5260 5261 private: 5262 DISALLOW_COPY_AND_ASSIGN(HArrayLength); 5263 }; 5264 5265 class HBoundsCheck : public HExpression<2> { 5266 public: 5267 // `HBoundsCheck` can trigger GC, as it may call the `IndexOutOfBoundsException` 5268 // constructor. 5269 HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc) 5270 : HExpression(index->GetType(), SideEffects::CanTriggerGC(), dex_pc) { 5271 DCHECK_EQ(Primitive::kPrimInt, Primitive::PrimitiveKind(index->GetType())); 5272 SetRawInputAt(0, index); 5273 SetRawInputAt(1, length); 5274 } 5275 5276 bool CanBeMoved() const OVERRIDE { return true; } 5277 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 5278 return true; 5279 } 5280 5281 bool NeedsEnvironment() const OVERRIDE { return true; } 5282 5283 bool CanThrow() const OVERRIDE { return true; } 5284 5285 HInstruction* GetIndex() const { return InputAt(0); } 5286 5287 DECLARE_INSTRUCTION(BoundsCheck); 5288 5289 private: 5290 DISALLOW_COPY_AND_ASSIGN(HBoundsCheck); 5291 }; 5292 5293 class HSuspendCheck : public HTemplateInstruction<0> { 5294 public: 5295 explicit HSuspendCheck(uint32_t dex_pc = kNoDexPc) 5296 : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc), slow_path_(nullptr) {} 5297 5298 bool NeedsEnvironment() const OVERRIDE { 5299 return true; 5300 } 5301 5302 void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; } 5303 SlowPathCode* GetSlowPath() const { return slow_path_; } 5304 5305 DECLARE_INSTRUCTION(SuspendCheck); 5306 5307 private: 5308 // Only used for code generation, in order to share the same slow path between back edges 5309 // of a same loop. 5310 SlowPathCode* slow_path_; 5311 5312 DISALLOW_COPY_AND_ASSIGN(HSuspendCheck); 5313 }; 5314 5315 // Pseudo-instruction which provides the native debugger with mapping information. 5316 // It ensures that we can generate line number and local variables at this point. 5317 class HNativeDebugInfo : public HTemplateInstruction<0> { 5318 public: 5319 explicit HNativeDebugInfo(uint32_t dex_pc) 5320 : HTemplateInstruction<0>(SideEffects::None(), dex_pc) {} 5321 5322 bool NeedsEnvironment() const OVERRIDE { 5323 return true; 5324 } 5325 5326 DECLARE_INSTRUCTION(NativeDebugInfo); 5327 5328 private: 5329 DISALLOW_COPY_AND_ASSIGN(HNativeDebugInfo); 5330 }; 5331 5332 /** 5333 * Instruction to load a Class object. 5334 */ 5335 class HLoadClass : public HExpression<1> { 5336 public: 5337 HLoadClass(HCurrentMethod* current_method, 5338 uint16_t type_index, 5339 const DexFile& dex_file, 5340 bool is_referrers_class, 5341 uint32_t dex_pc, 5342 bool needs_access_check, 5343 bool is_in_dex_cache) 5344 : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc), 5345 type_index_(type_index), 5346 dex_file_(dex_file), 5347 loaded_class_rti_(ReferenceTypeInfo::CreateInvalid()) { 5348 // Referrers class should not need access check. We never inline unverified 5349 // methods so we can't possibly end up in this situation. 5350 DCHECK(!is_referrers_class || !needs_access_check); 5351 5352 SetPackedFlag<kFlagIsReferrersClass>(is_referrers_class); 5353 SetPackedFlag<kFlagNeedsAccessCheck>(needs_access_check); 5354 SetPackedFlag<kFlagIsInDexCache>(is_in_dex_cache); 5355 SetPackedFlag<kFlagGenerateClInitCheck>(false); 5356 SetRawInputAt(0, current_method); 5357 } 5358 5359 bool CanBeMoved() const OVERRIDE { return true; } 5360 5361 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 5362 // Note that we don't need to test for generate_clinit_check_. 5363 // Whether or not we need to generate the clinit check is processed in 5364 // prepare_for_register_allocator based on existing HInvokes and HClinitChecks. 5365 return other->AsLoadClass()->type_index_ == type_index_ && 5366 other->AsLoadClass()->GetPackedFields() == GetPackedFields(); 5367 } 5368 5369 size_t ComputeHashCode() const OVERRIDE { return type_index_; } 5370 5371 uint16_t GetTypeIndex() const { return type_index_; } 5372 bool CanBeNull() const OVERRIDE { return false; } 5373 5374 bool NeedsEnvironment() const OVERRIDE { 5375 return CanCallRuntime(); 5376 } 5377 5378 void SetMustGenerateClinitCheck(bool generate_clinit_check) { 5379 // The entrypoint the code generator is going to call does not do 5380 // clinit of the class. 5381 DCHECK(!NeedsAccessCheck()); 5382 SetPackedFlag<kFlagGenerateClInitCheck>(generate_clinit_check); 5383 } 5384 5385 bool CanCallRuntime() const { 5386 return MustGenerateClinitCheck() || 5387 (!IsReferrersClass() && !IsInDexCache()) || 5388 NeedsAccessCheck(); 5389 } 5390 5391 5392 bool CanThrow() const OVERRIDE { 5393 return CanCallRuntime(); 5394 } 5395 5396 ReferenceTypeInfo GetLoadedClassRTI() { 5397 return loaded_class_rti_; 5398 } 5399 5400 void SetLoadedClassRTI(ReferenceTypeInfo rti) { 5401 // Make sure we only set exact types (the loaded class should never be merged). 5402 DCHECK(rti.IsExact()); 5403 loaded_class_rti_ = rti; 5404 } 5405 5406 const DexFile& GetDexFile() { return dex_file_; } 5407 5408 bool NeedsDexCacheOfDeclaringClass() const OVERRIDE { return !IsReferrersClass(); } 5409 5410 static SideEffects SideEffectsForArchRuntimeCalls() { 5411 return SideEffects::CanTriggerGC(); 5412 } 5413 5414 bool IsReferrersClass() const { return GetPackedFlag<kFlagIsReferrersClass>(); } 5415 bool NeedsAccessCheck() const { return GetPackedFlag<kFlagNeedsAccessCheck>(); } 5416 bool IsInDexCache() const { return GetPackedFlag<kFlagIsInDexCache>(); } 5417 bool MustGenerateClinitCheck() const { return GetPackedFlag<kFlagGenerateClInitCheck>(); } 5418 5419 DECLARE_INSTRUCTION(LoadClass); 5420 5421 private: 5422 static constexpr size_t kFlagIsReferrersClass = kNumberOfExpressionPackedBits; 5423 static constexpr size_t kFlagNeedsAccessCheck = kFlagIsReferrersClass + 1; 5424 static constexpr size_t kFlagIsInDexCache = kFlagNeedsAccessCheck + 1; 5425 // Whether this instruction must generate the initialization check. 5426 // Used for code generation. 5427 static constexpr size_t kFlagGenerateClInitCheck = kFlagIsInDexCache + 1; 5428 static constexpr size_t kNumberOfLoadClassPackedBits = kFlagGenerateClInitCheck + 1; 5429 static_assert(kNumberOfLoadClassPackedBits < kMaxNumberOfPackedBits, "Too many packed fields."); 5430 5431 const uint16_t type_index_; 5432 const DexFile& dex_file_; 5433 5434 ReferenceTypeInfo loaded_class_rti_; 5435 5436 DISALLOW_COPY_AND_ASSIGN(HLoadClass); 5437 }; 5438 5439 class HLoadString : public HExpression<1> { 5440 public: 5441 // Determines how to load the String. 5442 enum class LoadKind { 5443 // Use boot image String* address that will be known at link time. 5444 // Used for boot image strings referenced by boot image code in non-PIC mode. 5445 kBootImageLinkTimeAddress, 5446 5447 // Use PC-relative boot image String* address that will be known at link time. 5448 // Used for boot image strings referenced by boot image code in PIC mode. 5449 kBootImageLinkTimePcRelative, 5450 5451 // Use a known boot image String* address, embedded in the code by the codegen. 5452 // Used for boot image strings referenced by apps in AOT- and JIT-compiled code. 5453 // Note: codegen needs to emit a linker patch if indicated by compiler options' 5454 // GetIncludePatchInformation(). 5455 kBootImageAddress, 5456 5457 // Load from the resolved strings array at an absolute address. 5458 // Used for strings outside the boot image referenced by JIT-compiled code. 5459 kDexCacheAddress, 5460 5461 // Load from resolved strings array in the dex cache using a PC-relative load. 5462 // Used for strings outside boot image when we know that we can access 5463 // the dex cache arrays using a PC-relative load. 5464 kDexCachePcRelative, 5465 5466 // Load from resolved strings array accessed through the class loaded from 5467 // the compiled method's own ArtMethod*. This is the default access type when 5468 // all other types are unavailable. 5469 kDexCacheViaMethod, 5470 5471 kLast = kDexCacheViaMethod 5472 }; 5473 5474 HLoadString(HCurrentMethod* current_method, 5475 uint32_t string_index, 5476 const DexFile& dex_file, 5477 uint32_t dex_pc) 5478 : HExpression(Primitive::kPrimNot, SideEffectsForArchRuntimeCalls(), dex_pc), 5479 string_index_(string_index) { 5480 SetPackedFlag<kFlagIsInDexCache>(false); 5481 SetPackedField<LoadKindField>(LoadKind::kDexCacheViaMethod); 5482 load_data_.ref.dex_file = &dex_file; 5483 SetRawInputAt(0, current_method); 5484 } 5485 5486 void SetLoadKindWithAddress(LoadKind load_kind, uint64_t address) { 5487 DCHECK(HasAddress(load_kind)); 5488 load_data_.address = address; 5489 SetLoadKindInternal(load_kind); 5490 } 5491 5492 void SetLoadKindWithStringReference(LoadKind load_kind, 5493 const DexFile& dex_file, 5494 uint32_t string_index) { 5495 DCHECK(HasStringReference(load_kind)); 5496 load_data_.ref.dex_file = &dex_file; 5497 string_index_ = string_index; 5498 SetLoadKindInternal(load_kind); 5499 } 5500 5501 void SetLoadKindWithDexCacheReference(LoadKind load_kind, 5502 const DexFile& dex_file, 5503 uint32_t element_index) { 5504 DCHECK(HasDexCacheReference(load_kind)); 5505 load_data_.ref.dex_file = &dex_file; 5506 load_data_.ref.dex_cache_element_index = element_index; 5507 SetLoadKindInternal(load_kind); 5508 } 5509 5510 LoadKind GetLoadKind() const { 5511 return GetPackedField<LoadKindField>(); 5512 } 5513 5514 const DexFile& GetDexFile() const; 5515 5516 uint32_t GetStringIndex() const { 5517 DCHECK(HasStringReference(GetLoadKind()) || /* For slow paths. */ !IsInDexCache()); 5518 return string_index_; 5519 } 5520 5521 uint32_t GetDexCacheElementOffset() const; 5522 5523 uint64_t GetAddress() const { 5524 DCHECK(HasAddress(GetLoadKind())); 5525 return load_data_.address; 5526 } 5527 5528 bool CanBeMoved() const OVERRIDE { return true; } 5529 5530 bool InstructionDataEquals(HInstruction* other) const OVERRIDE; 5531 5532 size_t ComputeHashCode() const OVERRIDE { return string_index_; } 5533 5534 // Will call the runtime if we need to load the string through 5535 // the dex cache and the string is not guaranteed to be there yet. 5536 bool NeedsEnvironment() const OVERRIDE { 5537 LoadKind load_kind = GetLoadKind(); 5538 if (load_kind == LoadKind::kBootImageLinkTimeAddress || 5539 load_kind == LoadKind::kBootImageLinkTimePcRelative || 5540 load_kind == LoadKind::kBootImageAddress) { 5541 return false; 5542 } 5543 return !IsInDexCache(); 5544 } 5545 5546 bool NeedsDexCacheOfDeclaringClass() const OVERRIDE { 5547 return GetLoadKind() == LoadKind::kDexCacheViaMethod; 5548 } 5549 5550 bool CanBeNull() const OVERRIDE { return false; } 5551 bool CanThrow() const OVERRIDE { return NeedsEnvironment(); } 5552 5553 static SideEffects SideEffectsForArchRuntimeCalls() { 5554 return SideEffects::CanTriggerGC(); 5555 } 5556 5557 bool IsInDexCache() const { return GetPackedFlag<kFlagIsInDexCache>(); } 5558 5559 void MarkInDexCache() { 5560 SetPackedFlag<kFlagIsInDexCache>(true); 5561 DCHECK(!NeedsEnvironment()); 5562 RemoveEnvironment(); 5563 SetSideEffects(SideEffects::None()); 5564 } 5565 5566 size_t InputCount() const OVERRIDE { 5567 return (InputAt(0) != nullptr) ? 1u : 0u; 5568 } 5569 5570 void AddSpecialInput(HInstruction* special_input); 5571 5572 DECLARE_INSTRUCTION(LoadString); 5573 5574 private: 5575 static constexpr size_t kFlagIsInDexCache = kNumberOfExpressionPackedBits; 5576 static constexpr size_t kFieldLoadKind = kFlagIsInDexCache + 1; 5577 static constexpr size_t kFieldLoadKindSize = 5578 MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast)); 5579 static constexpr size_t kNumberOfLoadStringPackedBits = kFieldLoadKind + kFieldLoadKindSize; 5580 static_assert(kNumberOfLoadStringPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 5581 using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>; 5582 5583 static bool HasStringReference(LoadKind load_kind) { 5584 return load_kind == LoadKind::kBootImageLinkTimeAddress || 5585 load_kind == LoadKind::kBootImageLinkTimePcRelative || 5586 load_kind == LoadKind::kDexCacheViaMethod; 5587 } 5588 5589 static bool HasAddress(LoadKind load_kind) { 5590 return load_kind == LoadKind::kBootImageAddress || load_kind == LoadKind::kDexCacheAddress; 5591 } 5592 5593 static bool HasDexCacheReference(LoadKind load_kind) { 5594 return load_kind == LoadKind::kDexCachePcRelative; 5595 } 5596 5597 void SetLoadKindInternal(LoadKind load_kind); 5598 5599 // String index serves also as the hash code and it's also needed for slow-paths, 5600 // so it must not be overwritten with other load data. 5601 uint32_t string_index_; 5602 5603 union { 5604 struct { 5605 const DexFile* dex_file; // For string reference and dex cache reference. 5606 uint32_t dex_cache_element_index; // Only for dex cache reference. 5607 } ref; 5608 uint64_t address; // Up to 64-bit, needed for kDexCacheAddress on 64-bit targets. 5609 } load_data_; 5610 5611 DISALLOW_COPY_AND_ASSIGN(HLoadString); 5612 }; 5613 std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs); 5614 5615 // Note: defined outside class to see operator<<(., HLoadString::LoadKind). 5616 inline const DexFile& HLoadString::GetDexFile() const { 5617 DCHECK(HasStringReference(GetLoadKind()) || HasDexCacheReference(GetLoadKind())) 5618 << GetLoadKind(); 5619 return *load_data_.ref.dex_file; 5620 } 5621 5622 // Note: defined outside class to see operator<<(., HLoadString::LoadKind). 5623 inline uint32_t HLoadString::GetDexCacheElementOffset() const { 5624 DCHECK(HasDexCacheReference(GetLoadKind())) << GetLoadKind(); 5625 return load_data_.ref.dex_cache_element_index; 5626 } 5627 5628 // Note: defined outside class to see operator<<(., HLoadString::LoadKind). 5629 inline void HLoadString::AddSpecialInput(HInstruction* special_input) { 5630 // The special input is used for PC-relative loads on some architectures. 5631 DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative || 5632 GetLoadKind() == LoadKind::kDexCachePcRelative) << GetLoadKind(); 5633 DCHECK(InputAt(0) == nullptr); 5634 SetRawInputAt(0u, special_input); 5635 special_input->AddUseAt(this, 0); 5636 } 5637 5638 /** 5639 * Performs an initialization check on its Class object input. 5640 */ 5641 class HClinitCheck : public HExpression<1> { 5642 public: 5643 HClinitCheck(HLoadClass* constant, uint32_t dex_pc) 5644 : HExpression( 5645 Primitive::kPrimNot, 5646 SideEffects::AllChanges(), // Assume write/read on all fields/arrays. 5647 dex_pc) { 5648 SetRawInputAt(0, constant); 5649 } 5650 5651 bool CanBeMoved() const OVERRIDE { return true; } 5652 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 5653 return true; 5654 } 5655 5656 bool NeedsEnvironment() const OVERRIDE { 5657 // May call runtime to initialize the class. 5658 return true; 5659 } 5660 5661 bool CanThrow() const OVERRIDE { return true; } 5662 5663 HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); } 5664 5665 DECLARE_INSTRUCTION(ClinitCheck); 5666 5667 private: 5668 DISALLOW_COPY_AND_ASSIGN(HClinitCheck); 5669 }; 5670 5671 class HStaticFieldGet : public HExpression<1> { 5672 public: 5673 HStaticFieldGet(HInstruction* cls, 5674 Primitive::Type field_type, 5675 MemberOffset field_offset, 5676 bool is_volatile, 5677 uint32_t field_idx, 5678 uint16_t declaring_class_def_index, 5679 const DexFile& dex_file, 5680 Handle<mirror::DexCache> dex_cache, 5681 uint32_t dex_pc) 5682 : HExpression(field_type, 5683 SideEffects::FieldReadOfType(field_type, is_volatile), 5684 dex_pc), 5685 field_info_(field_offset, 5686 field_type, 5687 is_volatile, 5688 field_idx, 5689 declaring_class_def_index, 5690 dex_file, 5691 dex_cache) { 5692 SetRawInputAt(0, cls); 5693 } 5694 5695 5696 bool CanBeMoved() const OVERRIDE { return !IsVolatile(); } 5697 5698 bool InstructionDataEquals(HInstruction* other) const OVERRIDE { 5699 HStaticFieldGet* other_get = other->AsStaticFieldGet(); 5700 return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue(); 5701 } 5702 5703 size_t ComputeHashCode() const OVERRIDE { 5704 return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue(); 5705 } 5706 5707 const FieldInfo& GetFieldInfo() const { return field_info_; } 5708 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 5709 Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } 5710 bool IsVolatile() const { return field_info_.IsVolatile(); } 5711 5712 DECLARE_INSTRUCTION(StaticFieldGet); 5713 5714 private: 5715 const FieldInfo field_info_; 5716 5717 DISALLOW_COPY_AND_ASSIGN(HStaticFieldGet); 5718 }; 5719 5720 class HStaticFieldSet : public HTemplateInstruction<2> { 5721 public: 5722 HStaticFieldSet(HInstruction* cls, 5723 HInstruction* value, 5724 Primitive::Type field_type, 5725 MemberOffset field_offset, 5726 bool is_volatile, 5727 uint32_t field_idx, 5728 uint16_t declaring_class_def_index, 5729 const DexFile& dex_file, 5730 Handle<mirror::DexCache> dex_cache, 5731 uint32_t dex_pc) 5732 : HTemplateInstruction(SideEffects::FieldWriteOfType(field_type, is_volatile), 5733 dex_pc), 5734 field_info_(field_offset, 5735 field_type, 5736 is_volatile, 5737 field_idx, 5738 declaring_class_def_index, 5739 dex_file, 5740 dex_cache) { 5741 SetPackedFlag<kFlagValueCanBeNull>(true); 5742 SetRawInputAt(0, cls); 5743 SetRawInputAt(1, value); 5744 } 5745 5746 const FieldInfo& GetFieldInfo() const { return field_info_; } 5747 MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); } 5748 Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); } 5749 bool IsVolatile() const { return field_info_.IsVolatile(); } 5750 5751 HInstruction* GetValue() const { return InputAt(1); } 5752 bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); } 5753 void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); } 5754 5755 DECLARE_INSTRUCTION(StaticFieldSet); 5756 5757 private: 5758 static constexpr size_t kFlagValueCanBeNull = kNumberOfGenericPackedBits; 5759 static constexpr size_t kNumberOfStaticFieldSetPackedBits = kFlagValueCanBeNull + 1; 5760 static_assert(kNumberOfStaticFieldSetPackedBits <= kMaxNumberOfPackedBits, 5761 "Too many packed fields."); 5762 5763 const FieldInfo field_info_; 5764 5765 DISALLOW_COPY_AND_ASSIGN(HStaticFieldSet); 5766 }; 5767 5768 class HUnresolvedInstanceFieldGet : public HExpression<1> { 5769 public: 5770 HUnresolvedInstanceFieldGet(HInstruction* obj, 5771 Primitive::Type field_type, 5772 uint32_t field_index, 5773 uint32_t dex_pc) 5774 : HExpression(field_type, SideEffects::AllExceptGCDependency(), dex_pc), 5775 field_index_(field_index) { 5776 SetRawInputAt(0, obj); 5777 } 5778 5779 bool NeedsEnvironment() const OVERRIDE { return true; } 5780 bool CanThrow() const OVERRIDE { return true; } 5781 5782 Primitive::Type GetFieldType() const { return GetType(); } 5783 uint32_t GetFieldIndex() const { return field_index_; } 5784 5785 DECLARE_INSTRUCTION(UnresolvedInstanceFieldGet); 5786 5787 private: 5788 const uint32_t field_index_; 5789 5790 DISALLOW_COPY_AND_ASSIGN(HUnresolvedInstanceFieldGet); 5791 }; 5792 5793 class HUnresolvedInstanceFieldSet : public HTemplateInstruction<2> { 5794 public: 5795 HUnresolvedInstanceFieldSet(HInstruction* obj, 5796 HInstruction* value, 5797 Primitive::Type field_type, 5798 uint32_t field_index, 5799 uint32_t dex_pc) 5800 : HTemplateInstruction(SideEffects::AllExceptGCDependency(), dex_pc), 5801 field_index_(field_index) { 5802 SetPackedField<FieldTypeField>(field_type); 5803 DCHECK_EQ(Primitive::PrimitiveKind(field_type), Primitive::PrimitiveKind(value->GetType())); 5804 SetRawInputAt(0, obj); 5805 SetRawInputAt(1, value); 5806 } 5807 5808 bool NeedsEnvironment() const OVERRIDE { return true; } 5809 bool CanThrow() const OVERRIDE { return true; } 5810 5811 Primitive::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); } 5812 uint32_t GetFieldIndex() const { return field_index_; } 5813 5814 DECLARE_INSTRUCTION(UnresolvedInstanceFieldSet); 5815 5816 private: 5817 static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits; 5818 static constexpr size_t kFieldFieldTypeSize = 5819 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 5820 static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits = 5821 kFieldFieldType + kFieldFieldTypeSize; 5822 static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits, 5823 "Too many packed fields."); 5824 using FieldTypeField = BitField<Primitive::Type, kFieldFieldType, kFieldFieldTypeSize>; 5825 5826 const uint32_t field_index_; 5827 5828 DISALLOW_COPY_AND_ASSIGN(HUnresolvedInstanceFieldSet); 5829 }; 5830 5831 class HUnresolvedStaticFieldGet : public HExpression<0> { 5832 public: 5833 HUnresolvedStaticFieldGet(Primitive::Type field_type, 5834 uint32_t field_index, 5835 uint32_t dex_pc) 5836 : HExpression(field_type, SideEffects::AllExceptGCDependency(), dex_pc), 5837 field_index_(field_index) { 5838 } 5839 5840 bool NeedsEnvironment() const OVERRIDE { return true; } 5841 bool CanThrow() const OVERRIDE { return true; } 5842 5843 Primitive::Type GetFieldType() const { return GetType(); } 5844 uint32_t GetFieldIndex() const { return field_index_; } 5845 5846 DECLARE_INSTRUCTION(UnresolvedStaticFieldGet); 5847 5848 private: 5849 const uint32_t field_index_; 5850 5851 DISALLOW_COPY_AND_ASSIGN(HUnresolvedStaticFieldGet); 5852 }; 5853 5854 class HUnresolvedStaticFieldSet : public HTemplateInstruction<1> { 5855 public: 5856 HUnresolvedStaticFieldSet(HInstruction* value, 5857 Primitive::Type field_type, 5858 uint32_t field_index, 5859 uint32_t dex_pc) 5860 : HTemplateInstruction(SideEffects::AllExceptGCDependency(), dex_pc), 5861 field_index_(field_index) { 5862 SetPackedField<FieldTypeField>(field_type); 5863 DCHECK_EQ(Primitive::PrimitiveKind(field_type), Primitive::PrimitiveKind(value->GetType())); 5864 SetRawInputAt(0, value); 5865 } 5866 5867 bool NeedsEnvironment() const OVERRIDE { return true; } 5868 bool CanThrow() const OVERRIDE { return true; } 5869 5870 Primitive::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); } 5871 uint32_t GetFieldIndex() const { return field_index_; } 5872 5873 DECLARE_INSTRUCTION(UnresolvedStaticFieldSet); 5874 5875 private: 5876 static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits; 5877 static constexpr size_t kFieldFieldTypeSize = 5878 MinimumBitsToStore(static_cast<size_t>(Primitive::kPrimLast)); 5879 static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits = 5880 kFieldFieldType + kFieldFieldTypeSize; 5881 static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits, 5882 "Too many packed fields."); 5883 using FieldTypeField = BitField<Primitive::Type, kFieldFieldType, kFieldFieldTypeSize>; 5884 5885 const uint32_t field_index_; 5886 5887 DISALLOW_COPY_AND_ASSIGN(HUnresolvedStaticFieldSet); 5888 }; 5889 5890 // Implement the move-exception DEX instruction. 5891 class HLoadException : public HExpression<0> { 5892 public: 5893 explicit HLoadException(uint32_t dex_pc = kNoDexPc) 5894 : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc) {} 5895 5896 bool CanBeNull() const OVERRIDE { return false; } 5897 5898 DECLARE_INSTRUCTION(LoadException); 5899 5900 private: 5901 DISALLOW_COPY_AND_ASSIGN(HLoadException); 5902 }; 5903 5904 // Implicit part of move-exception which clears thread-local exception storage. 5905 // Must not be removed because the runtime expects the TLS to get cleared. 5906 class HClearException : public HTemplateInstruction<0> { 5907 public: 5908 explicit HClearException(uint32_t dex_pc = kNoDexPc) 5909 : HTemplateInstruction(SideEffects::AllWrites(), dex_pc) {} 5910 5911 DECLARE_INSTRUCTION(ClearException); 5912 5913 private: 5914 DISALLOW_COPY_AND_ASSIGN(HClearException); 5915 }; 5916 5917 class HThrow : public HTemplateInstruction<1> { 5918 public: 5919 HThrow(HInstruction* exception, uint32_t dex_pc) 5920 : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) { 5921 SetRawInputAt(0, exception); 5922 } 5923 5924 bool IsControlFlow() const OVERRIDE { return true; } 5925 5926 bool NeedsEnvironment() const OVERRIDE { return true; } 5927 5928 bool CanThrow() const OVERRIDE { return true; } 5929 5930 5931 DECLARE_INSTRUCTION(Throw); 5932 5933 private: 5934 DISALLOW_COPY_AND_ASSIGN(HThrow); 5935 }; 5936 5937 /** 5938 * Implementation strategies for the code generator of a HInstanceOf 5939 * or `HCheckCast`. 5940 */ 5941 enum class TypeCheckKind { 5942 kUnresolvedCheck, // Check against an unresolved type. 5943 kExactCheck, // Can do a single class compare. 5944 kClassHierarchyCheck, // Can just walk the super class chain. 5945 kAbstractClassCheck, // Can just walk the super class chain, starting one up. 5946 kInterfaceCheck, // No optimization yet when checking against an interface. 5947 kArrayObjectCheck, // Can just check if the array is not primitive. 5948 kArrayCheck, // No optimization yet when checking against a generic array. 5949 kLast = kArrayCheck 5950 }; 5951 5952 std::ostream& operator<<(std::ostream& os, TypeCheckKind rhs); 5953 5954 class HInstanceOf : public HExpression<2> { 5955 public: 5956 HInstanceOf(HInstruction* object, 5957 HLoadClass* constant, 5958 TypeCheckKind check_kind, 5959 uint32_t dex_pc) 5960 : HExpression(Primitive::kPrimBoolean, 5961 SideEffectsForArchRuntimeCalls(check_kind), 5962 dex_pc) { 5963 SetPackedField<TypeCheckKindField>(check_kind); 5964 SetPackedFlag<kFlagMustDoNullCheck>(true); 5965 SetRawInputAt(0, object); 5966 SetRawInputAt(1, constant); 5967 } 5968 5969 bool CanBeMoved() const OVERRIDE { return true; } 5970 5971 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 5972 return true; 5973 } 5974 5975 bool NeedsEnvironment() const OVERRIDE { 5976 return CanCallRuntime(GetTypeCheckKind()); 5977 } 5978 5979 // Used only in code generation. 5980 bool MustDoNullCheck() const { return GetPackedFlag<kFlagMustDoNullCheck>(); } 5981 void ClearMustDoNullCheck() { SetPackedFlag<kFlagMustDoNullCheck>(false); } 5982 TypeCheckKind GetTypeCheckKind() const { return GetPackedField<TypeCheckKindField>(); } 5983 bool IsExactCheck() const { return GetTypeCheckKind() == TypeCheckKind::kExactCheck; } 5984 5985 static bool CanCallRuntime(TypeCheckKind check_kind) { 5986 // Mips currently does runtime calls for any other checks. 5987 return check_kind != TypeCheckKind::kExactCheck; 5988 } 5989 5990 static SideEffects SideEffectsForArchRuntimeCalls(TypeCheckKind check_kind) { 5991 return CanCallRuntime(check_kind) ? SideEffects::CanTriggerGC() : SideEffects::None(); 5992 } 5993 5994 DECLARE_INSTRUCTION(InstanceOf); 5995 5996 private: 5997 static constexpr size_t kFieldTypeCheckKind = kNumberOfExpressionPackedBits; 5998 static constexpr size_t kFieldTypeCheckKindSize = 5999 MinimumBitsToStore(static_cast<size_t>(TypeCheckKind::kLast)); 6000 static constexpr size_t kFlagMustDoNullCheck = kFieldTypeCheckKind + kFieldTypeCheckKindSize; 6001 static constexpr size_t kNumberOfInstanceOfPackedBits = kFlagMustDoNullCheck + 1; 6002 static_assert(kNumberOfInstanceOfPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 6003 using TypeCheckKindField = BitField<TypeCheckKind, kFieldTypeCheckKind, kFieldTypeCheckKindSize>; 6004 6005 DISALLOW_COPY_AND_ASSIGN(HInstanceOf); 6006 }; 6007 6008 class HBoundType : public HExpression<1> { 6009 public: 6010 HBoundType(HInstruction* input, uint32_t dex_pc = kNoDexPc) 6011 : HExpression(Primitive::kPrimNot, SideEffects::None(), dex_pc), 6012 upper_bound_(ReferenceTypeInfo::CreateInvalid()) { 6013 SetPackedFlag<kFlagUpperCanBeNull>(true); 6014 SetPackedFlag<kFlagCanBeNull>(true); 6015 DCHECK_EQ(input->GetType(), Primitive::kPrimNot); 6016 SetRawInputAt(0, input); 6017 } 6018 6019 // {Get,Set}Upper* should only be used in reference type propagation. 6020 const ReferenceTypeInfo& GetUpperBound() const { return upper_bound_; } 6021 bool GetUpperCanBeNull() const { return GetPackedFlag<kFlagUpperCanBeNull>(); } 6022 void SetUpperBound(const ReferenceTypeInfo& upper_bound, bool can_be_null); 6023 6024 void SetCanBeNull(bool can_be_null) { 6025 DCHECK(GetUpperCanBeNull() || !can_be_null); 6026 SetPackedFlag<kFlagCanBeNull>(can_be_null); 6027 } 6028 6029 bool CanBeNull() const OVERRIDE { return GetPackedFlag<kFlagCanBeNull>(); } 6030 6031 DECLARE_INSTRUCTION(BoundType); 6032 6033 private: 6034 // Represents the top constraint that can_be_null_ cannot exceed (i.e. if this 6035 // is false then CanBeNull() cannot be true). 6036 static constexpr size_t kFlagUpperCanBeNull = kNumberOfExpressionPackedBits; 6037 static constexpr size_t kFlagCanBeNull = kFlagUpperCanBeNull + 1; 6038 static constexpr size_t kNumberOfBoundTypePackedBits = kFlagCanBeNull + 1; 6039 static_assert(kNumberOfBoundTypePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 6040 6041 // Encodes the most upper class that this instruction can have. In other words 6042 // it is always the case that GetUpperBound().IsSupertypeOf(GetReferenceType()). 6043 // It is used to bound the type in cases like: 6044 // if (x instanceof ClassX) { 6045 // // uper_bound_ will be ClassX 6046 // } 6047 ReferenceTypeInfo upper_bound_; 6048 6049 DISALLOW_COPY_AND_ASSIGN(HBoundType); 6050 }; 6051 6052 class HCheckCast : public HTemplateInstruction<2> { 6053 public: 6054 HCheckCast(HInstruction* object, 6055 HLoadClass* constant, 6056 TypeCheckKind check_kind, 6057 uint32_t dex_pc) 6058 : HTemplateInstruction(SideEffects::CanTriggerGC(), dex_pc) { 6059 SetPackedField<TypeCheckKindField>(check_kind); 6060 SetPackedFlag<kFlagMustDoNullCheck>(true); 6061 SetRawInputAt(0, object); 6062 SetRawInputAt(1, constant); 6063 } 6064 6065 bool CanBeMoved() const OVERRIDE { return true; } 6066 6067 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { 6068 return true; 6069 } 6070 6071 bool NeedsEnvironment() const OVERRIDE { 6072 // Instruction may throw a CheckCastError. 6073 return true; 6074 } 6075 6076 bool CanThrow() const OVERRIDE { return true; } 6077 6078 bool MustDoNullCheck() const { return GetPackedFlag<kFlagMustDoNullCheck>(); } 6079 void ClearMustDoNullCheck() { SetPackedFlag<kFlagMustDoNullCheck>(false); } 6080 TypeCheckKind GetTypeCheckKind() const { return GetPackedField<TypeCheckKindField>(); } 6081 bool IsExactCheck() const { return GetTypeCheckKind() == TypeCheckKind::kExactCheck; } 6082 6083 DECLARE_INSTRUCTION(CheckCast); 6084 6085 private: 6086 static constexpr size_t kFieldTypeCheckKind = kNumberOfGenericPackedBits; 6087 static constexpr size_t kFieldTypeCheckKindSize = 6088 MinimumBitsToStore(static_cast<size_t>(TypeCheckKind::kLast)); 6089 static constexpr size_t kFlagMustDoNullCheck = kFieldTypeCheckKind + kFieldTypeCheckKindSize; 6090 static constexpr size_t kNumberOfCheckCastPackedBits = kFlagMustDoNullCheck + 1; 6091 static_assert(kNumberOfCheckCastPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields."); 6092 using TypeCheckKindField = BitField<TypeCheckKind, kFieldTypeCheckKind, kFieldTypeCheckKindSize>; 6093 6094 DISALLOW_COPY_AND_ASSIGN(HCheckCast); 6095 }; 6096 6097 class HMemoryBarrier : public HTemplateInstruction<0> { 6098 public: 6099 explicit HMemoryBarrier(MemBarrierKind barrier_kind, uint32_t dex_pc = kNoDexPc) 6100 : HTemplateInstruction( 6101 SideEffects::AllWritesAndReads(), dex_pc) { // Assume write/read on all fields/arrays. 6102 SetPackedField<BarrierKindField>(barrier_kind); 6103 } 6104 6105 MemBarrierKind GetBarrierKind() { return GetPackedField<BarrierKindField>(); } 6106 6107 DECLARE_INSTRUCTION(MemoryBarrier); 6108 6109 private: 6110 static constexpr size_t kFieldBarrierKind = HInstruction::kNumberOfGenericPackedBits; 6111 static constexpr size_t kFieldBarrierKindSize = 6112 MinimumBitsToStore(static_cast<size_t>(kLastBarrierKind)); 6113 static constexpr size_t kNumberOfMemoryBarrierPackedBits = 6114 kFieldBarrierKind + kFieldBarrierKindSize; 6115 static_assert(kNumberOfMemoryBarrierPackedBits <= kMaxNumberOfPackedBits, 6116 "Too many packed fields."); 6117 using BarrierKindField = BitField<MemBarrierKind, kFieldBarrierKind, kFieldBarrierKindSize>; 6118 6119 DISALLOW_COPY_AND_ASSIGN(HMemoryBarrier); 6120 }; 6121 6122 class HMonitorOperation : public HTemplateInstruction<1> { 6123 public: 6124 enum class OperationKind { 6125 kEnter, 6126 kExit, 6127 kLast = kExit 6128 }; 6129 6130 HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc) 6131 : HTemplateInstruction( 6132 SideEffects::AllExceptGCDependency(), // Assume write/read on all fields/arrays. 6133 dex_pc) { 6134 SetPackedField<OperationKindField>(kind); 6135 SetRawInputAt(0, object); 6136 } 6137 6138 // Instruction may go into runtime, so we need an environment. 6139 bool NeedsEnvironment() const OVERRIDE { return true; } 6140 6141 bool CanThrow() const OVERRIDE { 6142 // Verifier guarantees that monitor-exit cannot throw. 6143 // This is important because it allows the HGraphBuilder to remove 6144 // a dead throw-catch loop generated for `synchronized` blocks/methods. 6145 return IsEnter(); 6146 } 6147 6148 OperationKind GetOperationKind() const { return GetPackedField<OperationKindField>(); } 6149 bool IsEnter() const { return GetOperationKind() == OperationKind::kEnter; } 6150 6151 DECLARE_INSTRUCTION(MonitorOperation); 6152 6153 private: 6154 static constexpr size_t kFieldOperationKind = HInstruction::kNumberOfGenericPackedBits; 6155 static constexpr size_t kFieldOperationKindSize = 6156 MinimumBitsToStore(static_cast<size_t>(OperationKind::kLast)); 6157 static constexpr size_t kNumberOfMonitorOperationPackedBits = 6158 kFieldOperationKind + kFieldOperationKindSize; 6159 static_assert(kNumberOfMonitorOperationPackedBits <= HInstruction::kMaxNumberOfPackedBits, 6160 "Too many packed fields."); 6161 using OperationKindField = BitField<OperationKind, kFieldOperationKind, kFieldOperationKindSize>; 6162 6163 private: 6164 DISALLOW_COPY_AND_ASSIGN(HMonitorOperation); 6165 }; 6166 6167 class HSelect : public HExpression<3> { 6168 public: 6169 HSelect(HInstruction* condition, 6170 HInstruction* true_value, 6171 HInstruction* false_value, 6172 uint32_t dex_pc) 6173 : HExpression(HPhi::ToPhiType(true_value->GetType()), SideEffects::None(), dex_pc) { 6174 DCHECK_EQ(HPhi::ToPhiType(true_value->GetType()), HPhi::ToPhiType(false_value->GetType())); 6175 6176 // First input must be `true_value` or `false_value` to allow codegens to 6177 // use the SameAsFirstInput allocation policy. We make it `false_value`, so 6178 // that architectures which implement HSelect as a conditional move also 6179 // will not need to invert the condition. 6180 SetRawInputAt(0, false_value); 6181 SetRawInputAt(1, true_value); 6182 SetRawInputAt(2, condition); 6183 } 6184 6185 HInstruction* GetFalseValue() const { return InputAt(0); } 6186 HInstruction* GetTrueValue() const { return InputAt(1); } 6187 HInstruction* GetCondition() const { return InputAt(2); } 6188 6189 bool CanBeMoved() const OVERRIDE { return true; } 6190 bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; } 6191 6192 bool CanBeNull() const OVERRIDE { 6193 return GetTrueValue()->CanBeNull() || GetFalseValue()->CanBeNull(); 6194 } 6195 6196 DECLARE_INSTRUCTION(Select); 6197 6198 private: 6199 DISALLOW_COPY_AND_ASSIGN(HSelect); 6200 }; 6201 6202 class MoveOperands : public ArenaObject<kArenaAllocMoveOperands> { 6203 public: 6204 MoveOperands(Location source, 6205 Location destination, 6206 Primitive::Type type, 6207 HInstruction* instruction) 6208 : source_(source), destination_(destination), type_(type), instruction_(instruction) {} 6209 6210 Location GetSource() const { return source_; } 6211 Location GetDestination() const { return destination_; } 6212 6213 void SetSource(Location value) { source_ = value; } 6214 void SetDestination(Location value) { destination_ = value; } 6215 6216 // The parallel move resolver marks moves as "in-progress" by clearing the 6217 // destination (but not the source). 6218 Location MarkPending() { 6219 DCHECK(!IsPending()); 6220 Location dest = destination_; 6221 destination_ = Location::NoLocation(); 6222 return dest; 6223 } 6224 6225 void ClearPending(Location dest) { 6226 DCHECK(IsPending()); 6227 destination_ = dest; 6228 } 6229 6230 bool IsPending() const { 6231 DCHECK(source_.IsValid() || destination_.IsInvalid()); 6232 return destination_.IsInvalid() && source_.IsValid(); 6233 } 6234 6235 // True if this blocks a move from the given location. 6236 bool Blocks(Location loc) const { 6237 return !IsEliminated() && source_.OverlapsWith(loc); 6238 } 6239 6240 // A move is redundant if it's been eliminated, if its source and 6241 // destination are the same, or if its destination is unneeded. 6242 bool IsRedundant() const { 6243 return IsEliminated() || destination_.IsInvalid() || source_.Equals(destination_); 6244 } 6245 6246 // We clear both operands to indicate move that's been eliminated. 6247 void Eliminate() { 6248 source_ = destination_ = Location::NoLocation(); 6249 } 6250 6251 bool IsEliminated() const { 6252 DCHECK(!source_.IsInvalid() || destination_.IsInvalid()); 6253 return source_.IsInvalid(); 6254 } 6255 6256 Primitive::Type GetType() const { return type_; } 6257 6258 bool Is64BitMove() const { 6259 return Primitive::Is64BitType(type_); 6260 } 6261 6262 HInstruction* GetInstruction() const { return instruction_; } 6263 6264 private: 6265 Location source_; 6266 Location destination_; 6267 // The type this move is for. 6268 Primitive::Type type_; 6269 // The instruction this move is assocatied with. Null when this move is 6270 // for moving an input in the expected locations of user (including a phi user). 6271 // This is only used in debug mode, to ensure we do not connect interval siblings 6272 // in the same parallel move. 6273 HInstruction* instruction_; 6274 }; 6275 6276 std::ostream& operator<<(std::ostream& os, const MoveOperands& rhs); 6277 6278 static constexpr size_t kDefaultNumberOfMoves = 4; 6279 6280 class HParallelMove : public HTemplateInstruction<0> { 6281 public: 6282 explicit HParallelMove(ArenaAllocator* arena, uint32_t dex_pc = kNoDexPc) 6283 : HTemplateInstruction(SideEffects::None(), dex_pc), 6284 moves_(arena->Adapter(kArenaAllocMoveOperands)) { 6285 moves_.reserve(kDefaultNumberOfMoves); 6286 } 6287 6288 void AddMove(Location source, 6289 Location destination, 6290 Primitive::Type type, 6291 HInstruction* instruction) { 6292 DCHECK(source.IsValid()); 6293 DCHECK(destination.IsValid()); 6294 if (kIsDebugBuild) { 6295 if (instruction != nullptr) { 6296 for (const MoveOperands& move : moves_) { 6297 if (move.GetInstruction() == instruction) { 6298 // Special case the situation where the move is for the spill slot 6299 // of the instruction. 6300 if ((GetPrevious() == instruction) 6301 || ((GetPrevious() == nullptr) 6302 && instruction->IsPhi() 6303 && instruction->GetBlock() == GetBlock())) { 6304 DCHECK_NE(destination.GetKind(), move.GetDestination().GetKind()) 6305 << "Doing parallel moves for the same instruction."; 6306 } else { 6307 DCHECK(false) << "Doing parallel moves for the same instruction."; 6308 } 6309 } 6310 } 6311 } 6312 for (const MoveOperands& move : moves_) { 6313 DCHECK(!destination.OverlapsWith(move.GetDestination())) 6314 << "Overlapped destination for two moves in a parallel move: " 6315 << move.GetSource() << " ==> " << move.GetDestination() << " and " 6316 << source << " ==> " << destination; 6317 } 6318 } 6319 moves_.emplace_back(source, destination, type, instruction); 6320 } 6321 6322 MoveOperands* MoveOperandsAt(size_t index) { 6323 return &moves_[index]; 6324 } 6325 6326 size_t NumMoves() const { return moves_.size(); } 6327 6328 DECLARE_INSTRUCTION(ParallelMove); 6329 6330 private: 6331 ArenaVector<MoveOperands> moves_; 6332 6333 DISALLOW_COPY_AND_ASSIGN(HParallelMove); 6334 }; 6335 6336 } // namespace art 6337 6338 #if defined(ART_ENABLE_CODEGEN_arm) || defined(ART_ENABLE_CODEGEN_arm64) 6339 #include "nodes_shared.h" 6340 #endif 6341 #ifdef ART_ENABLE_CODEGEN_arm 6342 #include "nodes_arm.h" 6343 #endif 6344 #ifdef ART_ENABLE_CODEGEN_arm64 6345 #include "nodes_arm64.h" 6346 #endif 6347 #ifdef ART_ENABLE_CODEGEN_x86 6348 #include "nodes_x86.h" 6349 #endif 6350 6351 namespace art { 6352 6353 class HGraphVisitor : public ValueObject { 6354 public: 6355 explicit HGraphVisitor(HGraph* graph) : graph_(graph) {} 6356 virtual ~HGraphVisitor() {} 6357 6358 virtual void VisitInstruction(HInstruction* instruction ATTRIBUTE_UNUSED) {} 6359 virtual void VisitBasicBlock(HBasicBlock* block); 6360 6361 // Visit the graph following basic block insertion order. 6362 void VisitInsertionOrder(); 6363 6364 // Visit the graph following dominator tree reverse post-order. 6365 void VisitReversePostOrder(); 6366 6367 HGraph* GetGraph() const { return graph_; } 6368 6369 // Visit functions for instruction classes. 6370 #define DECLARE_VISIT_INSTRUCTION(name, super) \ 6371 virtual void Visit##name(H##name* instr) { VisitInstruction(instr); } 6372 6373 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 6374 6375 #undef DECLARE_VISIT_INSTRUCTION 6376 6377 private: 6378 HGraph* const graph_; 6379 6380 DISALLOW_COPY_AND_ASSIGN(HGraphVisitor); 6381 }; 6382 6383 class HGraphDelegateVisitor : public HGraphVisitor { 6384 public: 6385 explicit HGraphDelegateVisitor(HGraph* graph) : HGraphVisitor(graph) {} 6386 virtual ~HGraphDelegateVisitor() {} 6387 6388 // Visit functions that delegate to to super class. 6389 #define DECLARE_VISIT_INSTRUCTION(name, super) \ 6390 void Visit##name(H##name* instr) OVERRIDE { Visit##super(instr); } 6391 6392 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 6393 6394 #undef DECLARE_VISIT_INSTRUCTION 6395 6396 private: 6397 DISALLOW_COPY_AND_ASSIGN(HGraphDelegateVisitor); 6398 }; 6399 6400 class HInsertionOrderIterator : public ValueObject { 6401 public: 6402 explicit HInsertionOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {} 6403 6404 bool Done() const { return index_ == graph_.GetBlocks().size(); } 6405 HBasicBlock* Current() const { return graph_.GetBlocks()[index_]; } 6406 void Advance() { ++index_; } 6407 6408 private: 6409 const HGraph& graph_; 6410 size_t index_; 6411 6412 DISALLOW_COPY_AND_ASSIGN(HInsertionOrderIterator); 6413 }; 6414 6415 class HReversePostOrderIterator : public ValueObject { 6416 public: 6417 explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) { 6418 // Check that reverse post order of the graph has been built. 6419 DCHECK(!graph.GetReversePostOrder().empty()); 6420 } 6421 6422 bool Done() const { return index_ == graph_.GetReversePostOrder().size(); } 6423 HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_]; } 6424 void Advance() { ++index_; } 6425 6426 private: 6427 const HGraph& graph_; 6428 size_t index_; 6429 6430 DISALLOW_COPY_AND_ASSIGN(HReversePostOrderIterator); 6431 }; 6432 6433 class HPostOrderIterator : public ValueObject { 6434 public: 6435 explicit HPostOrderIterator(const HGraph& graph) 6436 : graph_(graph), index_(graph_.GetReversePostOrder().size()) { 6437 // Check that reverse post order of the graph has been built. 6438 DCHECK(!graph.GetReversePostOrder().empty()); 6439 } 6440 6441 bool Done() const { return index_ == 0; } 6442 HBasicBlock* Current() const { return graph_.GetReversePostOrder()[index_ - 1u]; } 6443 void Advance() { --index_; } 6444 6445 private: 6446 const HGraph& graph_; 6447 size_t index_; 6448 6449 DISALLOW_COPY_AND_ASSIGN(HPostOrderIterator); 6450 }; 6451 6452 class HLinearPostOrderIterator : public ValueObject { 6453 public: 6454 explicit HLinearPostOrderIterator(const HGraph& graph) 6455 : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().size()) {} 6456 6457 bool Done() const { return index_ == 0; } 6458 6459 HBasicBlock* Current() const { return order_[index_ - 1u]; } 6460 6461 void Advance() { 6462 --index_; 6463 DCHECK_GE(index_, 0U); 6464 } 6465 6466 private: 6467 const ArenaVector<HBasicBlock*>& order_; 6468 size_t index_; 6469 6470 DISALLOW_COPY_AND_ASSIGN(HLinearPostOrderIterator); 6471 }; 6472 6473 class HLinearOrderIterator : public ValueObject { 6474 public: 6475 explicit HLinearOrderIterator(const HGraph& graph) 6476 : order_(graph.GetLinearOrder()), index_(0) {} 6477 6478 bool Done() const { return index_ == order_.size(); } 6479 HBasicBlock* Current() const { return order_[index_]; } 6480 void Advance() { ++index_; } 6481 6482 private: 6483 const ArenaVector<HBasicBlock*>& order_; 6484 size_t index_; 6485 6486 DISALLOW_COPY_AND_ASSIGN(HLinearOrderIterator); 6487 }; 6488 6489 // Iterator over the blocks that art part of the loop. Includes blocks part 6490 // of an inner loop. The order in which the blocks are iterated is on their 6491 // block id. 6492 class HBlocksInLoopIterator : public ValueObject { 6493 public: 6494 explicit HBlocksInLoopIterator(const HLoopInformation& info) 6495 : blocks_in_loop_(info.GetBlocks()), 6496 blocks_(info.GetHeader()->GetGraph()->GetBlocks()), 6497 index_(0) { 6498 if (!blocks_in_loop_.IsBitSet(index_)) { 6499 Advance(); 6500 } 6501 } 6502 6503 bool Done() const { return index_ == blocks_.size(); } 6504 HBasicBlock* Current() const { return blocks_[index_]; } 6505 void Advance() { 6506 ++index_; 6507 for (size_t e = blocks_.size(); index_ < e; ++index_) { 6508 if (blocks_in_loop_.IsBitSet(index_)) { 6509 break; 6510 } 6511 } 6512 } 6513 6514 private: 6515 const BitVector& blocks_in_loop_; 6516 const ArenaVector<HBasicBlock*>& blocks_; 6517 size_t index_; 6518 6519 DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator); 6520 }; 6521 6522 // Iterator over the blocks that art part of the loop. Includes blocks part 6523 // of an inner loop. The order in which the blocks are iterated is reverse 6524 // post order. 6525 class HBlocksInLoopReversePostOrderIterator : public ValueObject { 6526 public: 6527 explicit HBlocksInLoopReversePostOrderIterator(const HLoopInformation& info) 6528 : blocks_in_loop_(info.GetBlocks()), 6529 blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()), 6530 index_(0) { 6531 if (!blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 6532 Advance(); 6533 } 6534 } 6535 6536 bool Done() const { return index_ == blocks_.size(); } 6537 HBasicBlock* Current() const { return blocks_[index_]; } 6538 void Advance() { 6539 ++index_; 6540 for (size_t e = blocks_.size(); index_ < e; ++index_) { 6541 if (blocks_in_loop_.IsBitSet(blocks_[index_]->GetBlockId())) { 6542 break; 6543 } 6544 } 6545 } 6546 6547 private: 6548 const BitVector& blocks_in_loop_; 6549 const ArenaVector<HBasicBlock*>& blocks_; 6550 size_t index_; 6551 6552 DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopReversePostOrderIterator); 6553 }; 6554 6555 inline int64_t Int64FromConstant(HConstant* constant) { 6556 if (constant->IsIntConstant()) { 6557 return constant->AsIntConstant()->GetValue(); 6558 } else if (constant->IsLongConstant()) { 6559 return constant->AsLongConstant()->GetValue(); 6560 } else { 6561 DCHECK(constant->IsNullConstant()) << constant->DebugName(); 6562 return 0; 6563 } 6564 } 6565 6566 inline bool IsSameDexFile(const DexFile& lhs, const DexFile& rhs) { 6567 // For the purposes of the compiler, the dex files must actually be the same object 6568 // if we want to safely treat them as the same. This is especially important for JIT 6569 // as custom class loaders can open the same underlying file (or memory) multiple 6570 // times and provide different class resolution but no two class loaders should ever 6571 // use the same DexFile object - doing so is an unsupported hack that can lead to 6572 // all sorts of weird failures. 6573 return &lhs == &rhs; 6574 } 6575 6576 #define INSTRUCTION_TYPE_CHECK(type, super) \ 6577 inline bool HInstruction::Is##type() const { return GetKind() == k##type; } \ 6578 inline const H##type* HInstruction::As##type() const { \ 6579 return Is##type() ? down_cast<const H##type*>(this) : nullptr; \ 6580 } \ 6581 inline H##type* HInstruction::As##type() { \ 6582 return Is##type() ? static_cast<H##type*>(this) : nullptr; \ 6583 } 6584 6585 FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK) 6586 #undef INSTRUCTION_TYPE_CHECK 6587 6588 // Create space in `blocks` for adding `number_of_new_blocks` entries 6589 // starting at location `at`. Blocks after `at` are moved accordingly. 6590 inline void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks, 6591 size_t number_of_new_blocks, 6592 size_t after) { 6593 DCHECK_LT(after, blocks->size()); 6594 size_t old_size = blocks->size(); 6595 size_t new_size = old_size + number_of_new_blocks; 6596 blocks->resize(new_size); 6597 std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end()); 6598 } 6599 6600 } // namespace art 6601 6602 #endif // ART_COMPILER_OPTIMIZING_NODES_H_ 6603