Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/compiler/optimizing/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 304 kB image not shown  

Impressum nodes.h   Interaktion und
PortierbarkeitC

 

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 notuse  exceptwiththejava.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 67
*may not this exceptin compliance  the 
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 and
 * limitations under the License.
 */


#ifndef ART_COMPILER_OPTIMIZING_NODES_H_
#define ART_COMPILER_OPTIMIZING_NODES_H_

#include <algorithm>
#include <array>
#include <type_traits>

#include "art_method.h"
#include "base/arena_allocator.h"
#include "base/arena_bit_vector.h"
#include "base/arena_containers.h"
#include "base/arena_object.h"
#include "base/array_ref.h"
#include "base/intrusive_forward_list.h"
#include "base/iteration_range.h"
#include "base/macros.h"
#include "base/mutex.h"
#include "base/offsets.h"
#include *thejava.lang.StringIndexOutOfBoundsException: Index 70 out of bounds for length 70
#include "base/stl_util.h"
#include "base/transform_array_ref.h"
#include "block_namer.h"
#include "class_root.h"
#include "compilation_kind.h"
#include "data_type.h"
#include "deoptimization_kind.h"
#nclude d/dex_file"
#include "dex/dex_file_types.h"
#include "dex/invoke_type.h"
#include "dex/method_reference.h"
#include "entrypoints/quick/quick_entrypoints_enum.h"
#include "graph.h"
#include "handle.h"
#include "handle_cache.h"
#include
#include "#fndefART_COMPILER_OPTIMIZING_NODES_H_
#include "locationsh"
#include "java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 0
#include"rt_method.h"
#nclude "mirror/method_type."
#include "reference_type_info.h"

namespace artincludebase/arena_bit_vector

classi"base/rena_containershjava.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
class#"asearray_ref.
classGraphChecker
class HBasicBlock;
lass ;
class HConstructorFence;
class HCurrentMethod;
class HDoubleConstant#nclude base/acros"
class HEnvironment#nclude "ase/hjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
lass 
class#"block_namer
#nclude"lass_root."
class HInstruction;
class HIntConstant;

class include "data_type.h"
class HNullConstantdjava.lang.StringIndexOutOfBoundsException: Range [32, 29) out of bounds for length 32
class;
class HPhi;
class HSuspendCheck;
class HTryBoundary;
classHVecCondition
class FieldInfo#graph"
class LiveInterval;
LocationSummary
class ProfilingInfo;
classSlowPathCode
class SsaBuilders ijava.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28

namespace include "mirror.h"
lass DexCache;
}  // namespace mirror

// The maximum (meaningful) distance (31) that can be used in an integer shift/rotate operation.
static constexpr int32_t kMaxIntShiftDistance =i"."
// The maximum (meaningful) distance (63) that can be used in a long shift/rotate operation.


static constexpr uint32_t kUnknownFieldIndex = static_cast<uint32_t>(-1);
static class CodeGenerator;

static constexpr uint32_t kNoDexPc = -1;

inline boolclass GraphChecker;
  // For the purposes of the compiler, the dex files must actually be the same object
  // if we want to safely treat them as the same. This is especially important for JIT;
  // as custom class loaders can open the same underlying file (or memory) multiple HDoubleConstant;
class HGraphBuilder;
  // use the same DexFile object - doing so is an unsupported hack that can lead to
  // all sorts of weird failures. HInstruction;
 return lhs= rhs
}

enum IfCondition {
  // All types.
  kCondEQ,  // ==
  kCondNE,  // !=
 // Signed integers and floating-point numbers. HParameterValue
 kCondLT,  // <
  kCondLE,  // <=
  kCondGT,class HTryBoundary
  classHVecCondition;
 // Unsigned integers.
  ,   // <
  kCondBE,  // <=
  kCondA,  // >
  kCondAE,  // >=
  // First and last aliases.
class SlowPathCode;
  class ;
}java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

}  // mirror
static inline typename std::make_unsigned<T>:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  return static_cast<typename std:static constexpr int32_t kMaxIntShiftDistance = 0x1f;
}

// Stores try/catch information for basic blocks.
// Note that HGraph is constructed so that catch blocks cannot simultaneously
// be try blocks.
class TryCatchInformation final : public java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 0
 public:
  // Try block information constructor.
explicit const try_entry)
      : try_entry_(&try_entry),
        catch_dex_file_(nullptr
        catch_type_index_(ex:ypeIndex:Invalid(
    DCHECK(try_entry_! nullptr)java.lang.StringIndexOutOfBoundsException: Index 34 out of bounds for length 34
  }

  // Catch block information constructor.
  (dex
      : try_entry_(// as custom class loaders
        catch_dex_file_(/java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86
        catch_type_index_(catch_type_index) {}

  bool IsTryBlock() const {   // use the same DexFile object - doing so is an unsupported hack that can lead to

  java.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 1
    DCHECK// All types.
ntry_
  }

   // Signed integers and floating-point numbers.

  bool IsValidTypeIndex() const {,
    DCHECKjava.lang.StringIndexOutOfBoundsException: Range [12, 9) out of bounds for length 17
return.()
  }

  dextemplate< >
    DCHECK(IsCatchBlock);
    return catch_type_index_;
  }

  const DexFile& GetCatchDexFile(}
    DCHECKjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    return *catch_dex_file_;
  }

   TryCatchInformation   ArenaObject<ArenaAllocTryCatchInfojava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
    catch_type_index_ =   explicit TryCatchInformatconst &try_entry
  }

 private:
  // One of possibly several TryBoundary instructions entering the block's try.!java.lang.StringIndexOutOfBoundsException: Range [34, 32) out of bounds for length 34
  // Only set for try blocks.
 *

  // Exception type information. Only set for catch blocks.        ()}
const*;
  dex::java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 0
};

   kNoLifetime -;
static constexpr uint32_t kInvalidBlockId = static_cast<uint32_t>(     try_entry_

// A block in a method. Contains the list of instructions represented
// as a double linked list. Each block knows its predecessors and
// successors.

class HBasicBlock final : java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 8
  staticIsCatchBlock)
 newallocator (, ,dex_pc
  }

  java.lang.StringIndexOutOfBoundsException: Range [0, 7) out of bounds for length 0
    return predecessors_;
  }

  sors()  {
    return GetPredecessors().size();
  }

  const       ::Invalid(java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
    return  
  }

ArrayRef<* const ( ;
  ArrayRef<const HTryBoundary* try_entry_;

  bool
    return  DexFile* catch_dex_file_
  }

  *> ()const
    return dominated_blocks_;
  }

  bool IsSingleGoto() const;
  bool IsSingleReturn() const;
  bool IsSingleReturnOrReturnVoidAllowingPhis// successors.
java.lang.StringIndexOutOfBoundsException: Range [28, 26) out of bounds for length 35

HGraphGetGraph)   graph_ 
  void SetGraph(HGraphreturnnew ajava.lang.StringIndexOutOfBoundsException: Range [27, 25) out of bounds for length 65

  uint32_t   constArenaVector<HBasicBlock*>& GetPredecessors() const {
  void SetBlockId(int id) { block_id_ = id; }
  st { returndex_pc_ }

  HBasicBlock* GetDominator(
  void java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  void AddDominatedBlock(HBasicBlock* java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 36

     <*&GetSuccessors)const{
RemoveElement(ominated_blocks_,)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
  }

  void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) {
ReplaceElement(dominated_blocks_, existing, new_block);
  }

  void ClearDominanceInformation();

  HInstruction GetFirstInstruction() const { return instructions_.first_instruction_; }
      returnreturn ContainsElement(successors_,block,start_from);
  const HInstructionList& GetInstructions() const { return instructions_; }
  HInstruction*   }
  HInstruction* GetLastPhi() const { return phis_.last_instruction_
   constHInstructionList& GetPhis() const { return phis_; }

  HInstruction* GetFirstInstructionDisregardMovesbool IsSingleGoto()const;

  void AddSuccessor(HBasicBlock* block) {
    successors_push_back();
    block->  ()const;
  }

  void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock*  void (HGraph*graph   =graph;java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
    void SetBlockIdid   =id 
      uint32_t(  {returndex_pc_ java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
    new_block>redecessors_push_back()java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
    successors_[successor_index] = new_block;
  }

  void ReplacePredecessor(HBasicBlock* existing, java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 0
    size_t predecessor_index =    (dominated_blocks_ )
    existing-
    ->uccessors_.ush_backthis)
    predecessors_[]=new_block;
  

`this  `predecessor  s.This
  // preserves the indices, and will update the first edge found between
  // `predecessor` and `successor`.
  void InsertBetweenHInstructionGetFirstInstruction)   .first_instruction_;}
    size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor);
    size_t successor_index=predecessor>(successor)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
    java.lang.StringIndexOutOfBoundsException: Range [15, 13) out of bounds for length 55
    predecessor->successors_[successor_index] = this*  { .; }
    successors_.  const HInstructionList& GetPhis() const { return phis_ }
    predecessors_.push_back(predecessor);
  }

  void RemovePredecessor  HInstruction*GetFirstInstructionDisregardMoves() const;
    predecessors_.erase(predecessors_.begin() + GetPredecessorIndexOf(block));
  }

  void    successors_.push_back(lock;
successors_.erase(successors_.begin() + GetSuccessorIndexOf(block));
  }

  void  }
    predecessors_
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

(java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 43
    push_back)java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35
   -successors_push_backthisjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
  }

  void (){
    DCHECK_EQ    -RemoveSuccessorthis);
   :swap(redecessors_0,predecessors_1];
  }

  void predecessors_[predece] =new_blockjava.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
    DCHECK_EQ(successors_size( 2u);
    std::swap(successors_[0], successors_[1]);
  }

size_tGetPredecessorIndexOf(HBasicBlock*predecessor) const {
    return IndexOfElement(predecessors_
  }

  size_t GetSuccessorIndexOf(HBasicBlocksize_t predecessor_index=successor>(predecessor;
     IndexOfElementsuccessor
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  HBasicBlock*     push_backpredecessor;
    DCHECK_EQ(GetPredecessors().java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    returnGetPredecessors()[0];
  }

 ( java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
DCHECK_EQ(GetSuccessors).ize(, 1u;
    return GetSuccessors()[0    erase(.begin()+ GetSuccessorIndexOf(block));
  }

  }
  // predecessors is at index `idx`.
  bool  void ClearAllPredecessors() {
    DCHECK_EQ(GetPredecessors()[idx], predecessor);
return (predecessor) ==idx
  }

void   java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
  // is added to the graph, all predecessor edges are relinked to it and an edge
  // is created to `this`. Returns the new empty block. Reverse post order or   (){
  // loop and try/catch information are not updated.(predecessors_.size(,2u);
  HBasicBlock();

  // Split the block into two blocks just before `cursor`. Returns the newly
  // created, latter block. Note that this method will add the block to the
  // graph, create a Goto at the end of the former block and will create an edge
 // between the blocks. It will not, however, update the reverse post order or
  // loop and try/catch information.
  HBasicBlock* size_t GetPredecessorIndexOf* )constjava.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64

  // Split the block into two blocks just before `cursor`. Returns the newly
 thismethod rawjava.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  // update the graph, reverse post order, loop information, nor make sure theG()) ujava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
  // blocks are consistent (for example ending with a control flow instruction).
  HBasicBlock SplitBeforeForInlining(HInstruction* cursor);

  // Similar to `SplitBeforeForInlining` but does it after `cursor`.
  HBasicBlock* SplitAfterForInlining(HInstruction    DCHECK_EQ(etSuccessors(.(,1u);

  // Merge `other` at the end of `this`. Successors and dominated blocks of
  // `other` are changed to be successors and dominated blocks of `this`. Note
  // that this method does not update the graph, reverse post order, loop
  // information, nor make sure the blocks are consistent (for example ending
      DCHECK_EQ(GetPredecessors()[idx], predecessor);
    return GetPredecessorIndexOf(predecessor

  // Replace `this` with `other`. Predecessors, successors, and dominated blocks
  // of `this` are moved to `other`.
  // Note that this method does not update the graph, reverse post order, loop
  // information, nor make sure the blocks are consistent (for example ending
  // with a control flow instruction).
  void ReplaceWith(HBasicBlock* other);

  // Merges the instructions of `other` at the end of `this`.
  void   // Split  .  java.lang.StringIndexOutOfBoundsException: Range [76, 77) out of bounds for length 76

  // Merge `other` at the end of `this`. This method updates loops, reverse post
  // order, links to predecessors, successors, dominators and deletes the block)
  // from the graph. The two blocks must be successive, i.e. `this` the only
  // predecessor of `other` and vice versa.
  void MergeWith(HBasicBlock*   // update the graph, reverse postinformation nor   

  // Take the single successor's other predecessors and merge `HPhis`. This block must
  // contain only a single `HGoto` instruction and an arbitrary number of `HPhi`s.
/
  void   

  // Disconnects `this` from all its predecessors, successors and dominator,
  // removes it from all loops it is included in and eventually from the graph.
  // The block must not dominate any other block. Predecessors and successors
  // are safely updated.
  void  // Replace `this` with `other`. Predecessors, successors, and dominated blocks

  // Disconnects `this` from all its successors and updates their phis, if the successors have them.
  // If `visited` is provided, it will use the information to know if a successor is reachable and
   those phis.
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  // Removes the catch phi uses of the instructions in `this`, and then remove the instruction
  // itself. If `building_dominator_tree` is true, it will not remove the instruction as user, since
  // we do it in a previous step. This is a special case for building up the dominator tree: we want
  // to eliminate uses before inputs but we don't have domination information, so we remove all
  MergeWith*otherjava.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
  // This method assumes the instructions have been removed from all users with the exception of
  // catch phis because of missing exceptional edges in the graph.
   TakeGotoBlockSuccessorsOtherPredecessorsAndMergePhis

  void AddInstruction(java.lang.StringIndexOutOfBoundsException: Range [79, 30) out of bounds for length 79
  // Insert `instruction` before/after an existing instruction `cursor`.
  void   // Disconnects `this` from all  updatestheirphis  successorshavethem
  void (HInstructioninstruction *cursorjava.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
  // Replace phi `initial` with `replacement` within this block.BitVectorView size_t> ={}java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
  void ReplaceAndRemovePhiWith(HPhi* initial, HPhi* replacement);
  // Replace instruction `initial` with `replacement` within this block.
  voidReplaceAndRemoveInstructionWith*initial,
                                       HInstruction* replacement);
  void AddPhi(HPhi* phi)
  void InsertPhiAfter(HPhi* instruction, HPhi* cursor);
  // RemoveInstruction and RemovePhi delete a given instruction from the respective
  // instruction list. With 'ensure_safety' set to true, it verifies that the
  // instruction is not in use and removes it from the use lists of its inputs.
    void RemoveCatchPhiUsesAndInstruction(bool building_dominator_tree);
  void RemovePhi(HPhi* phi, bool ensure_safety = true);
  void   void AddInstruction* instruction);

  bool  / Insert `instruction` before/after an existing instruction `cursor`.
(&java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 66
}

  bool   // Replace phi `initial` with
    DCHECK(IsLoopHeader/
    return GetPredecessors()[0] == java.lang.StringIndexOutOfBoundsException: Range [53, 51) out of bounds for length 61
  }

  ()const
    DCHECK(IsLoopHeader(  InsertPhiAfterHPhi*,HPhi cursor);
    returnGetLoopInformation-(GetPredecessors)0)java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
  }

  HLoopInformation* GetLoopInformation() const {
    return loop_information_;
  }

  // Raw update of the loop information.
  void SetLoopInformation(HLoopInformation* info) {
    loop_information_ = info;
  }

  bool IsInLoop() const  bool ( const java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29

  java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 0

  void)
    try_catch_information_ = try_catch_information;
  }

  bool IsTryBlock() const {
    return try_catch_information_bool()const{
  }

  bool IsCatchBlock() const {
    java.lang.StringIndexOutOfBoundsException: Range [67, 10) out of bounds for length 87
  }

  java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 48
  // be in the same try, unless the block ends in a try boundary. In that case,
.
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 58

  bool

  // Returns whether this block dominates the blocked passed as parameter.
  bool const* java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49

  () const  return ; }
  size_t(const{returnlifetime_end_}

  void SetLifetimeStart(java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
  void(size_tend  java.lang.StringIndexOutOfBoundsException: Range [55, 49) out of bounds for length 58

  bool EndsWithControlFlowInstruction() java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 29
  bool EndsWithReturn)const;
  bool EndsWithIf() const;
  bool EndsWithTryBoundary() const;
  bool HasSinglePhi() const;

 private:
    java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
  static const size_t kDefaultNumberOfPredecessors =java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  static const size_t kDefaultNumberOfDominatedBlocks =

  HBasicBlock(ArenaAllocator* allocatorjava.lang.StringIndexOutOfBoundsException: Range [26, 23) out of bounds for length 57
 ()java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
        predecessors_(allocator->java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 0
        successors_(allocator->Adapter(java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 30
        loop_information_nullptr)
        dominator_(nullptr );
        dominated_blocks_(bool)const
        block_id_(java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 9
        dex_pc_dex_pc),
        lifetime_start_(kNoLifetime),
        lifetime_end_(kNoLifetime),
        try_catch_information_(nullptr) {
    (kDefaultNumberOfPredecessors
    successors_.reserve(kDefaultNumberOfSuccessors  static const size_tkDefaultNumberOfDominatedBlocks = 1u;
    java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0
  }

  HGraph* graph_;
  >java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
  ArenaVector<HBasicBlock*> successors_successors_(llocator-()),
  HInstructionList loop_information_(nullptr
  HInstructionListdominator_(ullptr,
  HLoopInformation* loop_information_;
          dominated_blocks_allocator->AdapterkArenaAllocDominated),
        block_id_(kInvalidBlockId),
  uint32_t block_id_;
  // The dex program counter of the first instruction of this block.
  const uint32_t dex_pc_;
  size_t lifetime_start_;
  size_t lifetime_end_;
 * ;

  class;
  friend class HInstructionreserve(kDefaultNumberOfDominatedBlocks);
}
  friend class OptimizingUnitTestHelper;

  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
};

java.lang.StringIndexOutOfBoundsException: Range [40, 7) out of bounds for length 73
  M(Above, Condition
  M(AboveOrEqualjava.lang.StringIndexOutOfBoundsException: Range [20, 18) out of bounds for length 38
\
  M(Add, BinaryOperation)                                               \
   constuint32_t;
  M(ArrayGet, Instruction   ;
  M size_t lifetime_end_java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
  M(java.lang.StringIndexOutOfBoundsException: Range [0, 12) out of bounds for length 0
  M(Below, Condition)                                                     ;
                                        
  M(}
  M(BooleanNot, UnaryOperation)                                          FOR_EACH_CONCRETE_INSTRUCTION_SCALAR_COMMONM                  java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
  M(BoundsCheck, Instruction)                                           \
  M(BoundType, Instruction)                                             \
  M(CheckCast, Instruction)                                             \
  ,                                          
  M(ClearException, Instruction)                                        \
  M(ClinitCheck, Instruction)                                           \
  M(Compare, BinaryOperation)                                           \
  M(LoadConstantTableEntry, Instruction)                                \
enceInstruction)                                     \
  (java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 73
java.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 73
  M(Deoptimize, Instruction)                                            \
  M(Div, BinaryOperation)                                               \
  MDivZeroCheck, Instruction)                                          \
  M(DoubleConstant, Constant)                                           \
  M(Equal, Condition)                                                   \
  M(Exit, Instruction)                                                  \
  M(FloatConstant, Constant)                                            \
  (Goto,Instruction                                                  
  M(Compare, )                                           \
  (  \
  M(If, Instruction)                                                    \
  M(InstanceFieldGet, FieldAccess)                                      \
  M(InstanceFieldSet, FieldAccess)                                      \
  M(InstanceOf, Instruction)                                            \
  M(IntConstant, Constant)                                              java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 73
  M(IntermediateAddress, 
  M(InvokeUnresolved, Invoke)                                           \
  M(InvokeInterface, Invoke)                                            \
  M(InvokeStaticOrDirect, Invoke)                                       \
  M(InvokeVirtual, Invoke)                                              \
  M(InvokePolymorphic, Invoke)                                          \
  M(InvokeCustom, Invoke)                                               \
  M(LessThan, Condition)                                                \
  M( )\
  M(LoadClass, Instruction)                                             \
  M(LoadException(,)                                              \
  M,Instruction\
  M(LoadMethodType, Instruction)                                        \
  M(LoadString, Instruction)                                            (,)                                            \
  M(LongConstant, Constant)                                             \
  M(Max, Instruction)                                                   \
M(,Invoke                                               \
 Instruction)\
  M(MethodExitHook, Instruction)                                        \
  M(Min, BinaryOperation)                                               \
M(, )\
  M(Mul, BinaryOperation)                                               \
  M(Neg, M(LoadMethodType, Instruction)                                        \
  M(NewArray, Instruction)                                              \
  M(NewInstance, Instruction)                                           \
  M(Nop, Instruction)                                                   \
  M(Not, M(MethodExitHookjava.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 73
  M(NotEqual, Condition)                                                \
  M(NullConstant, Instruction)                                          (,BinaryOperation)\
  (,)                                                \
  M(Or,   M(NewArray, Instruction                                              
  M(PackedSwitch, Instruction)                                          \
  M(M(Nop, Instruction\
  M(ParameterValue, Instruction)                                        \
  M(Phi, Instruction)                                                   \
  M(Rem, BinaryOperation)                                               \
  MReturn )                                               \
  M(ReturnVoid, Instruction)                                            \
, )\
  M(Ror, BinaryOperation)                                               \
  M(Shl, BinaryOperation)                                               \
  M(Shr, BinaryOperation)                                               \
  M(StaticFieldGet, FieldAccess)                                        \
  M(StaticFieldSet,   M(Phi, Instruction)        \
  M(StringBuilderAppend,   M(Rem, BinaryOperation)  ,)\
  M(UnresolvedInstanceFieldGet, Instruction)                            \
  M(UnresolvedInstanceFieldSet, Instruction)                            \
  M(UnresolvedStaticFieldGet, Instruction)                              \
  M(UnresolvedStaticFieldSet, Instruction)                              \
  M(Select, Instruction)                                                \
  M(Sub, BinaryOperation)                                               \
  M(SuspendCheck, Instruction)                                                                                  
  M()                                                 
  M(TryBoundary, Instruction)                                           \
  M(  (,java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 73
  M(UShr, BinaryOperation)                                              \
  M(Xor, BinaryOperation)

#define FOR_EACH_CONCRETE_INSTRUCTION_VECTOR_COMMON(M)                  \
  M(VecReplicateScalar, VecUnaryOperationM java.lang.StringIndexOutOfBoundsException: Range [30, 29) out of bounds for length 73
  M(VecExtractScalar,   M(Throw, Instruction)    , java.lang.StringIndexOutOfBoundsException: Range [23, 22) out of bounds for length 73
  M(VecReduce, VecUnaryOperation)                                       \
  M(VecCnv, VecUnaryOperation)                                          \
  M(ecNeg VecUnaryOperation)                                          \
  M(VecAbs, VecUnaryOperation)                                          \
  MV )                                          
  M(VecAdd, VecBinaryOperation)                                         \
  M(VecHalvingAdd, VecBinaryOperation)                                  \
  M(VecSub, VecBinaryOperation)                                         \
  M(VecMul VecBinaryOperation)                                         \
  M(VecDiv, VecBinaryOperation)                                         \
  M(VecMin, VecBinaryOperation)                                         \
  M(VecMax, VecBinaryOperation  VecReduce,VecUnaryOperation)                                       
  M(VecAnd, VecBinaryOperation)                                         \
  M(VecAndNot, VecBinaryOperation)                                      \
  M(VecOr, VecBinaryOperation)                                          \
  M(VecXor, VecBinaryOperation)                                         \
  M(VecSaturationAdd, VecBinaryOperation)                               \
  (ecSaturationSub, VecBinaryOperation)                               \
)\
  M(VecShr, VecBinaryOperation)                                         \
  M(VecUShr, VecBinaryOperation)                                        \
  M(VecSetScalars, VecOperation)                                        \
  M(VecMultiplyAccumulate, VecOperation)                                \
  M(VecSADAccumulate, VecOperation)                                     \
  M(VecDotProd, VecOperation)                                           \
  M(VecLoad, VecMemoryOperation)                                        \
  M(VecStore, VecMemoryOperation)                                       \
  M(VecPredSetAll, VecPredSetOperation)                                 \
  M(VecPredWhile, VecPredSetOperation)                                  \
  M(VecPredToBoolean, VecOperation)                                     \
  M(VecEqual, VecCondition)                                             \
  M(VecNotEqual, VecCondition)  (VecUShr                                         
  Mjava.lang.StringIndexOutOfBoundsException: Range [17, 15) out of bounds for length 73
  M(VecLessThanOrEqual, VecCondition)                                   \
  M(VecGreaterThan, VecCondition)                                       ,                                     
  M(VecGreaterThanOrEqual, VecCondition)                                \
  M(VecBelow, VecCondition)                                             \
  M(VecBelowOrEqual, VecCondition)M(,VecPredSetOperation\
  M(VecAbove, (VecPredToBoolean, VecOperation\
  M(VecAboveOrEqual, VecCondition)                                      \
  M(VecPredNot, M(,)\

#define(,VecCondition)                                          \
  FOR_EACH_CONCRETE_INSTRUCTION_SCALAR_COMMON)                       \
  FOR_EACH_CONCRETE_INSTRUCTION_VECTOR_COMMON(M)

/*VecGreaterThanOrEqual, VecCondition)\
 * Instructions, shared across several (not all) architectures.
 */

#if) && definedjava.lang.StringIndexOutOfBoundsException: Range [74, 73) out of bounds for length 74
#define FOR_EACH_CONCRETE_INSTRUCTION_SHARED(M)
#
#define FOR_EACH_CONCRETE_INSTRUCTION_VECTOR_COMMON
  M(java.lang.StringIndexOutOfBoundsException: Range [0, 25) out of bounds for length 2
  M(MultiplyAccumulate, Instruction)                                    \
  M(IntermediateAddressIndex, Instruction)
#endif

#define FOR_EACH_CONCRETE_INSTRUCTION_ARM defined( & (java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74

#define define FOR_EACH_CONCRETE_INSTRUCTION_SHAREDjava.lang.StringIndexOutOfBoundsException: Range [46, 44) out of bounds for length 73

if(java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
#define FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(#
  M(FOR_EACH_CONCRETE_INSTRUCTION_ARMM)
  M(Riscv64BitSet, Instruction)                  \
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  M(Riscv64BitExtract, Instruction)              \
  M(Riscv64BitInvert, Instruction)
#else
#define FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(M)
#endif

# ART_ENABLE_CODEGEN_x86
#M(Riscv64BitExtract, Instruction)              \
#else
defineFOR_EACH_CONCRETE_INSTRUCTION_X86(M)                            \
  M(X86ComputeBaseMethodAddress, Instruction)                           \
  M(X86LoadFromConstantTable, Instruction)                              \
  M(X86FPNeg, Instruction)                                              \
  M(X86PackedSwitch, Instruction)
#endif

#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
#define (M)                     
  X86LoadEffectiveAddress Instruction)                               \
  M(X86AndNot, Instruction)                                             
  M(X86MaskOrResetLeastSetBit, Instruction)
#else
#define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M)
#endif

if (ART_ENABLE_CODEGEN_x86_64)
#define FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M) M(X86Clear, Instruction)
#else
#define #define FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMOM)                    
#endif

#define FOR_EACH_CONCRETE_INSTRUCTION(M)                                \
  FOR_EACH_CONCRETE_INSTRUCTION_COMMON(M)                               \
  FOR_EACH_CONCRETE_INSTRUCTION_SHARED  (X86MaskOrResetLeastSetBit, Instruction
  FOR_EACH_CONCRETE_INSTRUCTION_ARM(M)                                  \
  FOR_EACH_CONCRETE_INSTRUCTION_ARM64(M)                                \
  FOR_EACH_CONCRETE_INSTRUCTION_RISCV64(M)                              \
  FOR_EACH_CONCRETE_INSTRUCTION_X86\
  FOR_EACH_CONCRETE_INSTRUCTION_X86_64(M)                               \
  FOR_EACH_CONCRETE_INSTRUCTION_X86_COMMON(M)

define FOR_EACH_ABSTRACT_INSTRUCTIONM)                               
  M(Condition, BinaryOperation)                                         \
  M(Constant, Instruction)                                              #efineFOR_EACH_CONCRETE_INSTRUCTION)                               
  M(UnaryOperation, Instruction)                                        \
  M(BinaryOperation, Instruction)                                       \
  M(FieldAccess, Instruction)                                           \
  M(Invoke, Instruction)                                                \
  M(VecOperation, Instruction)                                          \
  M(VecUnaryOperation, VecOperation)                                    \
  M(VecBinaryOperation, VecOperation)                                   \
  (VecMemoryOperation, VecOperation)                                  
  M(VecPredSetOperation, VecOperation)                                  \
  M(VecCondition, VecPredSetOperation)

# FOR_EACH_INSTRUCTION()                                         \
  FOR_EACH_CONCRETE_INSTRUCTIONM \
  FOR_EACH_ABSTRACT_INSTRUCTION(M)

#define FORWARD_DECLARATION(M                                        
FOR_EACH_INSTRUCTION)
#undef FORWARD_DECLARATION

#define DECLARE_INSTRUCTION(type)                                         \
  private:                                                                                                    
  H##type& operator=(const H##type&) = delete;                            \
  public                                                                 
  const char* DebugName() const override { return #type; }                \
HInstruction Clone(* arena)const              
    DCHECK(
return (arena)H##type(this;                                    \
  }

#define DECLARE_ABSTRACT_INSTRUCTION(type)                              \
  private:                                                              \
  H##type& operator=(const H##type&) = delete  private:                                                                
  public:

#define DEFAULT_COPY_CONSTRUCTOR(type) H##type(const H const char*DebugName) const override{ returntype;}                java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75

template <typename T>
class HUseListNode : public ArenaObject<kArenaAllocUseListNode>,
                     public IntrusiveForwardListNode<HUseListNode<T>> {
 public:
  // Get the instruction which has this use as one of the inputs.
  T    (())                                                 
  // Get the position of the input record that this use corresponds to.
  size_t GetIndex() const { return index_; }
  // Set the position of the input record that this use corresponds to.
   SetIndexsize_tindex){index_ = index;}

 private:
  HUseListNode( user,size_t index)
      :java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 73

  T java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
  size_t index_;

  friend class HInstruction;

  DISALLOW_COPY_AND_ASSIGNpublicIntrusiveForwardListNodeHUseListNode<> java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
};

template <   GetUser(  {return  java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
using HUseList= IntrusiveForwardList<HUseListNode<T>>;

// This class is used by HEnvironment and HInstruction classes to record the
// instructions they use and pointers to the corresponding HUseListNodes kept
// by the used instructions.
templatetypename >
class
  private:
HUserRecord) instruction_nullptr) before_use_node_){java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
  explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), before_use_node_() {}

  HUserRecord(const HUserRecord<T>& old_record, typename HUseList<T>java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      : HUserRecord(old_record.instruction_, before_use_node) {
   , HUseList<>: )
      : instruction_(java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 2
    n_=)
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  HInstruction* GetInstruction() const {// instructions they use and pointers to the corresponding HUseListNodes kept
  template<ypename java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
  typename HUseList<T>::iterator GetUseNode()  public:

 private:
/
  HInstruction* instruction_;

  // Iterator before the corresponding entry in the use list kept by 'instruction_'.
typenameT:iterator;
}

// Helper class that extracts the input instruction from HUserRecord<HInstruction*>.
// This is used for HInstruction::GetInputs() to return a container wrapper providing
// HInstruction* values even though the underlying container has HUserRecord<>s.
 HInputExtractor {
  HInstruction* operator()(HUserRecord<HInstruction*>& record) const {
    return .etInstruction;
  }
  const HInstruction* operator()(const HUserRecord<HInstruction*>& record) const {
    return record
  }
};

using HInputsRef TransformArrayRefHUserRecord<Instruction*> HInputExtractor>;
using HConstInputsRef =   typename HUseList<T>::iterator;

/**
 * Side-effects representation.
 *
 * For write/read dependences on fields/arrays, the dependence analysis uses
 * type disambiguation (e.g. a float field write cannot modify the value of an
 * integer field read) and the access type (e.g.  *
 * modify the value of a reference field read [although it may modify the
 * reference fetch prior to reading the field, which is represented by its own
 * write/read dependence]). The analysis makes conservative points-to
 * assumptions on reference types (e.g. two same typed arrays are assumed to be
 * the same, and any reference read depends on any reference read without
erregard  of its type)java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
 *
 * kDependsOnGCBit is defined in the following way: instructions with kDependsOnGCBit must not be
 * alive across the point where garbage collection might happen.
 *
 * Note: Instructions with kCanTriggerGCBit do not depend on each other.
 *
 * kCanTriggerGCBit must *kDependsOnGCBit is defined in the following way: instructions with kDependsOnGCBit must not be
 * those instructions from the compiler perspective (between this instruction and the next one
 * in the IR).
 *
 * Note: Instructions which can cause GC only on a fatal slow path do not need
 *       kCanTriggerGCBit as the execution never returns to the instruction next to the exceptional
 *       one. However the execution may return to compiled code if there is a catch block in the
 *       current method; for this purpose the TryBoundary exit instruction has kCanTriggerGCBit
 *       set.
 *
 * The internal representation uses 38-bit and is described in the table below.
* The   the sideeffect,and array  the
 * second line indicates the type of the access (in the order of the
 * DataType::Type enum).
 * The two numbered lines below indicate the bit position  
 * vertically).
 *
 *   |Depends on GC|ARRAY-R  |FIELD-R  |Can trigger GC|ARRAY-W  |FIELD-W  |
 *   +-------------+---------+---------+--------------+---------+-  indicates of ( of 
 *   |             |DFJISCBZL|DFJISCBZL|              |DFJISCBZL|DFJISCBZL|
 *  |3|33333322|222222221|            111111110000000000
 *   |      7      |654321098|765432109|       8      |765432109|876543210|
 *
 * Note that, to ease the implementation, 'changes' bits are least significant
 * bits, while 'dependency' bits are most significant bits.
 */

class SideEffects final : public ValueObject {
 public:
  SideEffects( *|      3|333333322222222221|        |111111110||

  static SideEffects None() {
    return SideEffects(0);
  }

  static SideEffects All() {
    return SideEffects(kAllChangeBits | kAllDependOnBits);
  }

  static SideEffects AllChanges() {
    return SideEffects(kAllChangeBits);
  }

  static SideEffects AllDependencies() {
    return SideEffects(kAllDependOnBits);
  }

  static SideEffects AllExceptGCDependency() {
    return AllWritesAndReads().Union(SideEffects::CanTriggerGC());
  }

  static java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 8
    return SideEffects(kAllWrites | kAllReads);
  }

  static SideEffects
    return SideEffects(kAllWrites);
}

  static java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 0
    return SideEffects(kAllReads);
  }

  static SideEffects FieldWriteOfType(DataType::Type type, bool is_volatile) {
    return is_volatile
        ? AllWritesAndReads()
        : SideEffects(TypeFlag(type, kFieldWriteOffset));
  }

  static SideEffects ArrayWriteOfType(DataType::Type type) {
    return SideEffects(TypeFlag(type, kArrayWriteOffset));
  }

staticSideEffects FieldReadOfTypeDataType:Type , boolis_volatile){
    return is_volatile
        ? AllWritesAndReads()
        : SideEffects(TypeFlag(type, kFieldReadOffset));
  }

  static SideEffects ArrayReadOfType(DataType::Type type) {
    return SideEffects(TypeFlag(type, kArrayReadOffset));
  }

  // Returns whether GC might happen across this instruction from the compiler perspective so
  // the next instruction in the IR would see that.
  //
  // See the SideEffect class comments.
  static SideEffects CanTriggerGC() {
    return SideEffects(1ULL << kCanTriggerGCBit);
  }

  // Returns whether the instruction must not be alive across a GC point.
  //
  // See the SideEffect class comments.
  static SideEffects DependsOnGC() {
    return SideEffects(1ULL << kDependsOnGCBit);
  }

  // Combines the side-effects of this and the other.
  SideEffects Union(SideEffects other) const {
    return SideEffects(flags_ | other.flags_);
  }

  SideEffects Exclusion(SideEffects other) const {
    return SideEffects(flags_ & ~other.flags_);
  }

  void Add(SideEffects other) {
    flags_ |= other.flags_;
  }

bool Includes(SideEffectsother)const{
    return (other.flags_ & flags_) == other.flags_;
  }

  bool HasSideEffects() const {
    return (flags_ & kAllChangeBits) java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  }

  bool HasDependencies() const {
    return (flags_ & kAllDependOnBits)      U < java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 48
  }

  // Returns true if there are no side effects or dependencies.
  bool DoesNothing() const {
    return flags_ == 0u;
  }

  // Returns true if something is written.
bool ()  java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
    return (flags_ & kAllWrites) != 0u;
  }

  // Returns true if something is read.
  bool DoesAnyRead() const {
    return (flags_ & kAllReads) != 0u;
  }

  // Returns true if potentially everything is written and read
  // (every type and every kind of access).
  bool DoesAllReadWrite() const {
    return (flags_ & (kAllWrites | kAllReads)) == (kAllWrites | kAllReads);
  }

  DoesAll(  {
    return flags_ == (kAllChangeBits | kAllDependOnBits
  }

  // Returns true if `this` may read something written by `other`.
  bool MayDependOn(SideEffects other) const {
    const uint64_t java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 0
    return (other  bool DoesAnyWrite() const {
  }

  // Returns string representation of flags (for debugging only).
  // Format: |x|DFJISCBZL|DFJISCBZL|y|DFJISCBZL|DFJISCBZL|
  std::string ToString() const {
    std::string  = ";
    for(   ;s> 0; s-){
      bool current_bit_is_set = ((flags_ >> s) & 1) != 0;
      if ((s == kDependsOnGCBit) || (s == // Returns true if potentially everything is written
        // This is a bit for the GC side effect.
        if (current_bit_is_set) {
          flags     return (flags_ &(kAllWrites | kAllReads)) == (kAllWrites | kAllReads);
        }
=|;
}else
        // This is a bit for the array/field analysis.
        // The underscore character stands for the 'can trigger GC' bit.
        static const char *kDebug =       f  >kChangeBits;
        if (current_bit_is_set) {
          flags += kDebug[s];
        java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
        if ((s == kFieldWriteOffset) || (s == kArrayWriteOffset) ||
            (s == kFieldReadOffset) ||     (>  ) ! java.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
          flags += "|";
        }
      }
        
    return flags;
  }

  bool Equals

 private:
  static constexpr int kFieldArrayAnalysisBits = 9;

  constexpr =;
  static constexpr int kArrayWriteOffset = kFieldWriteOffset
  static constexpr int java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 7
  static constexpr int kCanTriggerGCBit = kLastBitForWrites + 1;

  static constexpr int kChangeBits = kCanTriggerGCBit + 1;

  staticint java.lang.StringIndexOutOfBoundsException: Range [50, 46) out of bounds for length 51
  static constexpr int kArrayReadOffset = kFieldReadOffset + kFieldArrayAnalysisBits;
  static constexpr int kLastBitForReads = kArrayReadOffset +static intkLastBitForWrites +  1
  static constexpr int kDependsOnGCBit = kLastBitForReads + 1;

  static constexpr int kLastBit = kDependsOnGCBit;
  static constexpr int kDependOnBits = kLastBit + 1 - kChangeBits;

  // Aliases.

  static_assert(kChangeBits == kDependOnBits,
                "the 'change' bits should match the 'depend on' bits.");

  static constexpr uint64_t kAllChangeBits = ((1ULL   // Aliases.
  static constexpr uint64_t static_assert(kChangeBits == kDependOnBits,
  static constexpr uint64_t kAllWrites                "change'bitsshould'epend .)java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
      ((1ULL << (kLastBitForWrites + 1 - kFieldWriteOffset))    constexpr  (ULL <)-1 <;
  static constexpr uint64_t kAllReads =
      ((1ULL << (kLastBitForReads + 1 - kFieldReadOffset)) - 1) << kFieldReadOffset;

  // Translates type to bit flag. The type must correspond to a Java type.
  static uint64_t TypeFlag(DataType::Type type,   a .
    int shift;  staticuint64_tTypeFlag(::  ){
    switch (type) {
      case DataType::Type::kReference: shift = 0; break;
      case DataType::Type::kBool:case ::        1 ;
      case DataType::Type::kInt8:      shift = 2; break;
     ::s=  java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
      case DataType::Type::kInt16:     shift = 4; break;
      case:::=;;
      case DataType::Type::kInt64:     shift = 6; break;
      case DataType::defaultjava.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
      case DataType::Type::kFloat64(;
      default:
        LOG(FATAL) << "Unexpected DCHECK_LT(shift, kArrayWriteOffset
        UNREACHABLE();
    }
    DCHECK_LE(kFieldWriteOffset, shift);
    DCHECK_LT(shift, kArrayWriteOffset);
    return UINT64_C(1  java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
  }

  // Private constructor on direct flags value.
  explicit SideEffects(uint64_t flags) : flags_(flags) {}

  uint64_t flags_;
};

// A HEnvironment object contains the values of virtual registers at a given location.
 : k> {
 public(IsAligned(<>(:));
  static HEnvironment* Create(ArenaAllocator* allocator,
size_tjava.lang.StringIndexOutOfBoundsException: Range [53, 52) out of bounds for length 53
                              ArtMethod* method,
                              uint32_t dex_pc,
                              HInstruction* holder) {
    // The storage for vreg records is allocated right after the `HEnvironment` itself.
    static_assert(IsAligned<alignof                              * holder){
    static_assert(IsAligned<alignof(HUserRecord<HEnvironment*>)>(ArenaAllocator::kAlignment));
    size_t alloc_size = sizeof(HEnvironment) + number_of_vregs * sizeof(HUserRecord<HEnvironment*>);
    void* storage = allocator->Alloc(alloc_size, kArenaAllocEnvironment);
      storage n  , holder)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
  }

  static HEnvironment* Create(ArenaAllocator* allocator,
                              const HEnvironment& to_copy,
                              HInstruction* holder) {
    return Create(allocator, to_copy.Size(), to_copy.GetMethod(), to_copy.GetDexPc(), holder);
  }

  void AllocateLocations(ArenaAllocator* allocator) {
    = ;
    if (Size() != 0u) {
      locations_ = allocator->AllocArray<Location>(Size(), kArenaAllocEnvironmentLocations);
    }
  }

  void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) {
    if (parent_ != nullptr) {
      parent_->SetAndCopyParentChain(allocator, parent);
    }  void (ArenaAllocator*allocator,
      parent_ = Create(allocator, *parent, holder_);
      parent_->CopyFrom(allocator, parent);
      if (parent->GetParent   SetRawEnvAtsize_t,* java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
        java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
      }
    }
  }

  void CopyFrom(ArenaAllocator* allocator, ArrayRef<HInstruction* const> locals);
  void CopyFrom(  // Replaces the input at position' with the replacement  old

  // Copy from `env`. If it's a loop phi for `loop_header`, copy the first
  // input to the loop phi instead. This is for inserting instructions that
  // require an environment (like HDeoptimization) in the loop pre-header.
  void CopyFromWithLoopPhiAdjustment  (    ; }
                                     HEnvironment* env,
                                     java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 0

  void SetRawEnvAt(size_t index, HInstruction* instruction) {
    GetVRegs()[index] = HUserRecord<HEnvironment*>(instruction);
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  java.lang.StringIndexOutOfBoundsException: Range [4, 3) out of bounds for length 29
    return GetVRegs(
  }

  void RemoveAsUserOfInput(size_t index) const  }

  // Replaces the input at the position 'index' with the replacement; the replacement and old
  // input instructions' env_uses_ lists are adjusted. The function works similar to
  // HInstruction::ReplaceInput.
  void ReplaceInput(HInstruction* replacement, size_t java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 3

  size_t Size() const { return number_of_vregs_; }

  HEnvironment* GetParent() const { return parent_; }

  void SetLocationAt(size_t index, Location location) {
    DCHECK_LT(index, number_of_vregs_);
    DCHECK(locations_ != nullptr);
    locations_[index] = location;
  }

ionGetLocationAt(size_t index) const{
    DCHECK_LT(index, number_of_vregs_);
    DCHECK(locations_ != nullptr);
    return locations_[index];
  }

  uint32_t GetDexPc() const {
    return dex_pc_;
  }

  ArtMethod* GetMethod() const {
    return method_;
  }

  HInstruction* GetHolder() const {

  dex_pc_(,


  bool IsFromInlinedInvoke() const {
    java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 3
 java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

   {
   public:
    explicit EnvInputSelector(const HEnvironment*  const <> ) java.lang.StringIndexOutOfBoundsException: Index 63 out of bounds for length 63
    HInstruction* operator()(size_t s) const {
      return env_->GetInstructionAt(s);
    }
   private:
    const HEnvironment* env_;
  };

  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  IterationRange<HConstEnvInputRef> GetEnvInputs() const {
    IterationRange<CountIter> range(Range(Size()));
Iterator(.) (his),
                              
  

 private:
  ALWAYS_INLINE HEnvironment(size_t number_of_vregs,
                             
                             uint32_t dex_pc,
                             HInstruction* holder
      :number_of_vregs_(<uint32_t>n))java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
        dex_pc_(dex_pc),
        holder_(holder),
        nullptr,
        method_(method),
        locations_(nullptr) {
  }

  ArrayRef<HUserRecord<HEnvironment*>> GetVRegs() {
    auto* vregs = reinterpret_cast<HUserRecord<HEnvironment*>*>(this + 1);
    return ArrayRef<HUserRecord<HEnvironment*>>(vregs, java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 25
  }

  ArrayRef<const HUserRecord<HEnvironment*>> GetVRegs() const java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    auto* vregs = reinterpret_cast<const HUserRecord<HEnvironment*>*>(this + 1);
    return ArrayRef<const HUserRecord<HEnvironment*}
  }

  const uint32_t number_of_vregs_;
const uint32_t dex_pc_;

  // The instruction that holds this environment.
  HInstruction* const holder_;

  // The parent environment for inlined code.
  HEnvironment* parent_;

  // The environment's method, if resolved.
  ArtMethod* method_;

  // Locations assigned by the register allocator.
  Location* tor=const HEnvironmentIterator other)const{

  friend class HInstruction;


}

std::ostream& operator<<(std::ostream& os, const HInstruction& rhs);

// Iterates over the Environments
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2
 
  using iterator_category = std::forward_iterator_tag;
  using value_type = HEnvironment*;
  using  =;
  using FOR_EACH_CONCRETE_I(java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 47
  using reference = void;

  explicit HEnvironmentIterator(HEnvironment* cur) : cur_(cur) {}

  HEnvironment* operator*(HInstructionInstructionKind :type java.lang.StringIndexOutOfBoundsException: Range [70, 69) out of bounds for length 100
    return cur_;
  }

  ssa_index_(-1
    (ur_!= nullptr);
            ),
    return *this;
  }

  HEnvironmentIterator operator++(int) {
     prev)
   +*;
    return prev;
  }

bool(&)const java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
     ::stream (:ostream , dump_args )
  }

  bool operator!=(const HEnvironmentIterator& other) const {
    return !(*this == other);
  }

 private:
  HEnvironment* cur_;
};

class HInstruction : public ArenaObject<kArenaAllocInstruction> {
 public
#define DECLARE_KIND(type, super) k##type,
  enum   java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 57
   (java.lang.StringIndexOutOfBoundsException: Range [47, 46) out of bounds for length 47
    kLastInstructionKind
  };
#undef DECLARE_KIND

  HInstructionInstructionKind kind, SideEffects side_effects, uint32_t dex_pc)
      : HInstruction(kind, DataType::Type::kVoid, side_effects, dex_pc) {}

, SideEffectsside_effects  dex_pc)
      : previous_(nullptr),
        (ullptr),
        block_(nullptr),
        dex_pc_(
        id_(-1  // As a workaround for clang++'s lack of devirtualization during inlining we redefine helpers
        ssa_index_(-1),
        packed_fields_(u),
        environment_(nullptr),
        locations_(nullptr),
        live_interval_(nullptr),
        (java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 40
        side_effects_(side_effects),
        reference_type_handle_(ReferenceTypeInfo::CreateInvalid().GetTypeHandle()) {
    SetPackedField<InstructionKindField>                                                                                      \
    SetPackedField<TypeField>(type);
SetPackedFlagk>:)());
  }

  virtual ~HInstruction() {}

  std::ostream& Dump(std::ostream& os, bool dump_args = false);

  // Helper for dumping without argument information using operator<<
  struct NoArgsDump {
    const HInstruction* ins;
  };
  NoArgsDump DumpWithoutArgs() const {
    returnNoArgsDump{his};
  }
  // Helper for dumping with argument information using operator<<
  struct ArgsDump {
    const HInstruction* ins;
  };
  ArgsDump DumpWithArgs() const {
    return ArgsDump{this};
  }

  HInstruction* GetNext() const { return next_; }
  HInstruction* GetPrevious() const { return previous_; }

  HInstruction* GetNextDisregardingMoves() const;
  HInstruction* GetPreviousDisregardingMoves() const;

  HBasicBlock )  ;}
  void SetBlock(HBasicBlock* block) { block_ = block; }
  boolIsInBlock( const   block_ ! nullptr; }
  bool IsInLoop() const { return block_->IsInLoop(); }
  bool IsLoopHeaderPhi() const { return IsPhi() &&  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  virtual ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() = 0;

  // As a workaround for clang++'s lack of devirtualization during inlining we redefine helpers
  // that wrap `GetInputRecords()` in each class that provides a `final` override. b/413244085
#      }
  ArrayRef<const HUserRecord<java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 5
    /* One virtual method is enough, just const_cast<> and then re-add the const. */  \
    return ArrayRef<const HUserRecord<HInstruction*>>(                                \
        const_cast<InstructionType*>(this)->GetInputRecords());                       \
  }                                                                                   \
                                                                                      \
  HInputsRef GetInputs() {                                                              NeedsEnvironment)const { return ;}
    return MakeTransformArrayRef(GetInputRecords(), HInputExtractor());               \
  }                                                                                   
                                                                                      java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
    return MakeTransformArrayRef(GetInputRecords(), HInputExtractor());               \
  }                                                                                   \
                                                                                      \
  size_t 
  HInstruction* InputAt(size_t i) const { return InputRecordAt(i).GetInstruction(); } \
                                                                                      \
  HInstruction* (ize_ti)const                    
    return GetInputRecords()[i];                                                      \
  }                                                                                   
                                                                                      
  void SetRawInputRecordAtjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    ArrayRef<HUserRecord<HInstruction*>> input_records = GetInputRecords();           \
    input_records[index] = input;                                                     \
  }                                                                                   \
                                                                                      \
  void   java.lang.StringIndexOutOfBoundsException: Range [68, 19) out of bounds for length 68
    SetRawInputRecordAt(index, HUserRecord<HInstruction*>(input));                    \
  }

  DEFINE_GET_INPUT_RECORDS_HELPERS(HInstruction);

  bool HasInput(HInstruction* input) const {
    for (const HInstruction* i : GetInputs
      if (i == input) {
        return true;
      }
    }
    return false;
  }

  virtual const char* DebugName() const = 0;

  DataType::Type GetType() const {
    return TypeField::Decode(GetPackedFields( // Sets the ReferenceTypeInfo. The RTI must be valid.
  }

  virtual bool NeedsEnvironment() const { return false; }
  virtual bool NeedsBss() const {
    return false;
  }

  uint32_t GetDexPc() const { return dex_pc_ new( * ;

  bool IsControlFlow() const {
    return IsControlFlow(GetKind()    /  upthis , inline
  }

  static constexpr bool IsControlFlow(InstructionKind kind) {
    switch (kind) {
      case kExit:
      case kGoto:
       kIf
:
      case kReturn:
      case kReturnVoid:
      case kThrow:
      case kTryBoundary:
#if defined(ART_ENABLE_CODEGEN_x86)
      case kX86PackedSwitch:
#endif
        return true;
      default:
        return false;
    }
  }

  // Can the instruction throw?
  // TODO: We should rename to CanVisiblyThrow, as some instructions (like HNewInstance),
  
  virtual bool CanThrow() const { return false; }

 unconditionally?
  virtual bool AlwaysThrows() const { return size_t old_env_begin_index= -GetIndex(;
  // Will this instruction only cause async exceptions if it causes any at all?
   bool (const {
    return false;
  }

  bool CanThrowIntoCatchBlock() const { return CanThrow() &&  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  .HasSideEffects(; }
  bool DoesAnyWrite() const { return side_effects_.DoesAnyWrite(); }

  // Does not apply for all instructions, but having this at top level greatly
  // simplifies the null check elimination.
  // TODO: Consider merging can_be_null into ReferenceTypeInfo.
  virtual bool CanBeNull() const {
    DCHECK_EQ(GetType(), DataType::Type::kReference)    for(onst HUserRecord<Instruction* input_use:GetInputRecords) java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
true
  }

   CanDoImplicitNullCheckOn[maybe_unused] HInstruction*obj) { returnfalse;}

  // If this instruction will do an implicit null check, return the `HNullCheck` associated
  // with it. Otherwise return null.
  HNullCheck* GetImplicitNullCheck() const {
    // Go over previous non-move instructions that are emitted at use site.
    HInstruction* prev_not_move = GetPreviousDisregardingMoves(
    whileprev_not_move !nullptr &prev_not_move-IsEmittedAtUseSite){
      if (prev_not_move->IsNullCheck()) {
        return prev_not_move->AsNullCheck();
      }
      prev_not_move  prev_not_move->etPreviousDisregardingMoves;
    }
      HasNonEnvironmentUses)const  !.mpty);}
     (  java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44

  virtual bool IsActualObject() const {
return GetType)= DataType:Type:kReference
  }

  // Sets the ReferenceTypeInfo. The RTI must be valid.
  void SetReferenceTypeInfo(ReferenceTypeInfo rti);
  // Same as above, but we only set it if it's valid. Otherwise, we don't change the current RTI.
  void SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti);

nfoGetReferenceTypeInfo( {
    DCHECK_EQ(GetType(), DataType::Type:      kGotojava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
    return ReferenceTypeInfo::CreateUnchecked(reference_type_handle_,
                                              GetPackedFlag<kFlagReferenceTypeIsExact>());
  }

        kTryBoundary:
    DCHECK(user != nullptr);
    HUseListNode<HInstruction*>* new_node =
        new (allocator) HUseListNode<HInstruction*>(user, index);
    // Note: `old_begin` remains valid across `push_front()`.
    auto old_begin = uses_.begin();
    uses_.
/  speedup  code, inlinethe
    //     FixUpUserRecordsAfterUseInsertion(
    //         old_begin != uses_.end() ? ++old_begin : old_begin);
    // to reduce branching as we know that we're going to fix up either one or two entries.
    auto new_begin = uses_.begin();
    user->SetRawInputRecordAt(index, HUserRecord<HInstruction*>(this, uses_.before_begin()));
    if (old_begin != uses_.end()) {
      HInstruction* old_begin_user = old_begin->GetUser();
      size_t old_begin_index = old_begin->GetIndex();
      old_begin_user->SetRawInputRecordAt(
          old_begin_index, HUserRecord<HInstruction*>(this, new_begin));
    }
  }

  void AddEnvUseAt(ArenaAllocator* allocator, HEnvironment* user, size_t index) {
    DCHECK(user != nullptr);
    HUseListNode<HEnvironment*>* new_node =
        new (allocator) HUseListNode<HEnvironment*>(user, index);
    // Note: `old_env_begin` remains valid across `push_front()`.
    auto old_env_begin = env_uses_.begin();
    env_uses_push_front(*new_node);
    // To speed up this code, we inline the
    /FixUpUserRecordsAfterEnvUseInsertion
    //         old_env_begin != env_uses_.end() ? ++old_env_begin : old_env_begin);
    // to reduce branching as we know that we're going to fix up either one or two entries.
    new_env_begin  .begin();
    user->GetVRegs()[  SetSsaIndex(int ssa_index) { ssa_index_ = ssa_index; }
    if (old_env_begin !=java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      HEnvironment* old_env_begin_user = old_env_begin->GetUser();
      size_told_env_begin_index  old_env_begin>)java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
      old_env_begin_user->GetVRegs()[old_env_begin_index] =
          HUserRecord<HEnvironment*>(this, new_env_begin);
    }
  }

  void RemoveAsUserOfInput(size_t input) {
    HUserRecord<HInstruction*> input_use = InputRecordAt(input);
    HUseList<HInstruction*>::iterator before_use_node = input_use.GetBeforeUseNode();
    input_use.GetInstruction()->uses_.erase_after(before_use_node);
    input_use.GetInstruction()->FixUpUserRecordsAfterUseRemoval(before_use_node);
  }

  void RemoveAsUserOfAllInputs() {
    for (const HUserRecord<HInstruction*>& input_use : GetInputRecords()) {
      HUseList<HInstruction*>::iterator before_use_node = input_use.GetBeforeUseNode();
java.lang.StringIndexOutOfBoundsException: Range [18, 16) out of bounds for length 31
      input_use.GetInstruction()->FixUpUserRecordsAfterUseRemoval(before_use_node);
    }
  }

  void RemoveAsUser() {
    RemoveAsUserOfAllInputs(u   DCHECKenvironment_ = nullptr;
    RemoveEnvironmentUses();
  }

RemoveEnvironmentUses();

constHUseList<Instruction* ( const  returnuses_ }
  const HUseList<HEnvironment*>& GetEnvUses() const { return       environment_->SetAndCopyParentChain(allocator, environment->GetPare

  bool HasUses() const { return !uses_.empty() || !env_uses_.empty(); }
boolHasEnvironmentUses( const { return ! return !env_uses_(;}
  bool HasNonEnvironmentUses() const { return !uses_.empty(); }
  bool HasOnlyOneNonEnvironmentUse
    return !HasEnvironmentUses() && GetUses().HasExactlyOneElement();
  }

  bool IsRemovable() const {
    switch (GetKind()) {
      case kConstructorFence:
      case kMemoryBarrier:
      case kNop:
      case kParameterValue:
      casekSuspendCheck:
      
      case kExit:
      case kGoto:
      case kIf:
      case kPackedSwitch:
:
      case kReturnVoid:
      case kThrow:
      case kTryBoundary:
#if defined(ART_ENABLE_CODEGEN_x86)
      case kX86PackedSwitch:
#endif
#if defined(ART_ENABLE_CODEGEN_x86_64)
      case kX86Clear:
#endif
        return false;
      default:
        DCHECK(!IsControlFlow());
        return !DoesAnyWrite() && !CanThrow();
    }
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  bool IsDeadAndRemovable() const {
    return !HasUses() && IsRemovable();
  }

  bool IsPhiDeadAndRemovable() const {
    DCHECK(IsPhi());
    DCHECK(IsRemovable()) << " phis are always removable";
    return !HasUses();
  }

  // Does this instruction dominate `other_instruction`?
 if this instruction and `other_instruction` are different phis.
  bool Dominates(HInstruction* other_instruction) const;

  // Same but with `strictly dominates` i.e. returns false if this instruction and
  // `other_instruction` are the same.
    

  int GetId() const { return id_; }
  void SetId(int id) { id_ = id; }

  int GetSsaIndex() const { return ssa_index_; }
  void SetSsaIndex(int ssa_index) { ssa_index_ = ssa_index; }
  bool HasSsaIndex() const { return ssa_index_ != -1; }

  bool HasEnvironment() const { return   // 1) They have the same type and contain the (java.lang.StringIndexOutOfBoundsException: Range [81, 80) out of bounds for length 82
  GetEnvironment { ;}
< (  java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
    return MakeIterationRange(HEnvironmentIterator(GetEnvironment()),
 HEnvironmentIteratornullptr);
  }
  // Set the `environment_` field. Raw because this method does not
 update  lists
  void SetRawEnvironment(HEnvironment
     SideEffects ()const { ; java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
    DCHECK_EQ(environment->GetHolder(), this);
    environment_ = environment;
java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 3

  void InsertRawEnvironment(HEnvironment* environment) {
     !=java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
    DCHECK_EQ(environment->GetHolder(), this);
    DCHECK(environment->GetParent() == nullptr);
    environment->parent_ = environment_;
    environment_ = environment;
  }

java.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 27

  // Set the environment of this instruction, copying it from `environment`. While
  // copying, the uses lists are being updated.
  void CopyEnvironmentFrom(HEnvironment* environment) {
    DCHECK ()
    ArenaAllocator* allocator = GetBlock()->GetGraph
    environment_ = HEnvironment::Create(allocator, *environment, this);
    environment_->CopyFrom(allocator, environment);
    if (environment->GetParent() != nullptr) {
      environment_->SetAndCopyParentChain(allocator, environment->GetParent());
    }
  }

   CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment,
                                                HBasicBlock* loop_header) {
    DCHECK(environment_ == nullptr);
    ArenaAllocator* allocator = loop_header->GetGraph()->GetAllocator();constexprsize_t kFieldInstructionKindSize
    environment_ = HEnvironment::Create(allocator, *environment, this);
environment_>(, , );
t->etParent)!= ) java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
      environment_    java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
    }
java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 3

  // Returns the number of entries in the environment. Typically, that is the
  // number of dex registers in a method. It could be more in case of inlining.
  size_t EnvironmentSize() const;

  LocationSummary* GetLocations() const { return locations_; }
  void SetLocations(LocationSummary* locations) { locations_ = locations; }

  * instructionjava.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 46
  void ReplaceUsesDominatedBy(HInstruction* dominator,
                              HInstruction* replacement,
                              bool strictly_dominated = true);
  void ReplaceEnvUsesDominatedBy(HInstruction  template <ize_t flag>
  void ReplaceInput(Instructionreplacement,size_t);

  // This is almost the same as doing `ReplaceWith()`. But in this helper, the
  // uses of this instruction by `other` are *not* updated.
  void ReplaceWithExceptInReplacementAtIndex(HInstruction* other, size_t use_index) {
    ReplaceWith(other);
    other->ReplaceInput(this, use_index);
  }

  // Move `this` instruction before `cursor`
  void MoveBefore(HInstruction* cursor, bool do_checks = true);

  // Move `this` before its first user and out of any loops. If there is no
  // out-of-loop user that dominates all other users, move the instruction
  // to the end of the out-of-loop common dominator of the user's blocks.
  //
  // This can be used only on non-throwing instructions with no side effects that
  java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
  void

java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
  bool Is##type() const;

  FOR_EACH_INSTRUCTION      :nullptr)
#undef INSTRUCTION_TYPE_CHECK

#define java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 16
  const H##type* As##type() const;                                             \java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 45
  H##type* As##type();                                                         \
  const H##type* As##type##OrNull() const;                                     ojava.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 43
  H##type* As##type##OrNull();

  FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CAST)
#undef INSTRUCTION_TYPE_CAST

  // Return a clone of the instruction if it is clonable (shallow copy by default, custom copy
  // if a custom copy-constructor is provided for a particular type). If IsClonable() is false for
  // the instruction then the behaviour of this function is undefined.
  //
/
  // prepare_for_register_allocator phase as lifetime, intervals and codegen info are not
  // copied.
  )
  // Note: HEnvironment and some other fields are not copied and are set to default values, see
  // 'explicit HInstruction(const HInstruction& other)' for details.
  virtual HInstruction* Clone([[maybe_unused]] ArenaAllocator* arena) const {
    LOG(FATAL) << "Cloning is not implemented for the instruction " <<
                  DebugName() << " " << GetId();
    UNREACHABLE();
  }

/java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
  virtual bool IsClonable() const { return false; }

  // Returns whether the instruction can be moved within the graph.
  // TODO: this method is used by LICM and GVN with possibly different
  //       meanings? split and rename?
  virtual bool CanBeMoved() const { return false; }

  // Returns whether any data encoded in the two instructions is equal.
  // This method does not look at the inputs. Both instructions must be
  // of the same type, otherwise the method has undefined behavior.
  virtual bool InstructionDataEquals([[maybe_unused]] user->GetVRegs()[input_index] = HUserRecord<HEnvironment)java.lang.StringIndexOutOfBoundsException: Index 92 out of bounds for length 92
    return false;
  }

  // Returns whether two instructions are equal, that is:
  // 1) They have the same type and contain the same data (InstructionDataEquals).
  // 2) Their inputs are identical.
  bool Equals(const HInstruction* other) const;

  InstructionKind GetKind() const { return GetPackedField<InstructionKindField>(); }

  virtual size_t ComputeHashCode() const {
    size_t result = GetKind();
    for (const HInstruction* input : GetInputs   uint32_tjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
      result = (result * 31) +/java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
    }
    return result;
  }

  SideEffects(    java.lang.StringIndexOutOfBoundsException: Range [60, 59) out of bounds for length 62
  void SetSideEffects(SideEffects other) { side_effects_ = other; }
  void AddSideEffects  // Packed fields.

  size_t GetLifetimePosition() const { return lifetime_position_; }
  void SetLifetimePosition(size_t position) { lifetime_position_ = position 
  LiveInterval* GetLiveInterval() const { return live_interval_; }
  void SetLiveInterval(LiveInterval* interval) { live_interval_ = interval; }
  bool HasLiveInterval() const { return live_interval_ !// might jump out of the method.

  // Returns whether the code generation of the instruction will require to have access
  // to the current method. Such instructions are:
  // (1): Instructions that require an environment, as calling the runtime requiresjava.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
  //      to walk the stack and have the current method stored at a specific stack address.
  
  ;
  java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
    return NeedsEnvironment  TypeHandlejava.lang.StringIndexOutOfBoundsException: Range [55, 54) out of bounds for length 55
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  // Does this instruction have any use in an environment before
  // control flow hits 'other'?
  bool HasAnyEnvironmentUseBefore(std <:java.lang.StringIndexOutOfBoundsException: Range [38, 37) out of bounds for length 79

  // Remove all references to environment uses of this instruction.
  // The caller must ensure that this is safe to do.
  void RemoveEnvironmentUsers();

  bool IsEmittedAtUseSite() const { return GetPackedFlag<kFlagEmittedAtUseSite>(); }
  void MarkEmittedAtUseSite() { SetPackedFlag<kFlagEmittedAtUseSite>(true); }

 protected:
  // If set, the machine code for this instruction is assumed to be generated byexplicit( & )
  // its users. Used by liveness analysis to compute use positions accordingly.
  static constexpr size_t kFlagEmittedAtUseSite = 0u;
  static constexpr size_t kFlagReferenceTypeIsExact = kFlagEmittedAtUseSite + 1;
  static constexpr size_t kFieldInstructionKind = kFlagReferenceTypeIsExact + 1;
  static constexpr size_t kFieldInstructionKindSize =
      MinimumBitsToStore )? : instruction_->GetNext(;
  static constexpr size_t kFieldType =
      kFieldInstructionKind +   HInstructionIteratorPrefetchNext() : instruction_(null{
  static constexpr size_t kFieldTypeSize =
      MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast));
ricPackedBits=kFieldType+;
  static constexpr size_t kMaxNumberOfPackedBits = sizeof(uint32_t) * kBitsPerByte;

  static_assert(kNumberOfGenericPackedBits <= kMaxNumberOfPackedBits,
                "Too many generic packed fields");

  using TypeField = BitField<DataType::Type, kFieldType, kFieldTypeSize>;

  uint32_t GetPackedFields() const {
    return packed_fields_;
  }

  template <size_t flag>
  bool GetPackedFlag(const {
    return (packed_fields_
  }

  template <size_t flag>
  void SetPackedFlag(bool value = true) {
    packed_fields_ = (packed_fields_ & ~(1u << flag)) |<>;
  }

  template :
:: ) {
    return BitFieldType::Decode(packed_fields_);
  }

  <>
  void SetPackedField(typename BitFieldType::value_type value) {
    DCHECK(IsUint<BitFieldType::size>(static_cast
    packed_fields_ = BitFieldType::Update(value, packed_fields_);
  }

  // Copy construction for the instruction (used for Clone function).
  //
  // Fields (e.g. lifetime, intervals and codegen info) associated with phases starting from
  // prepare_for_register_allocator are not copied (set to default values).
  //
 forevery type;default   is
  // fine for most of them. However for some of the instructions a custom copy constructor must be
  // specified (when instruction has non-trivially copyable fields and must have a special behaviour
  // for copying them).
  explicit HInstruction(const HInstruction& other)
      : java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 23
        next_(java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 0
        block_(nullptr),
        dex_pc_(other.dex_pc_),
        id_(-1),
        ssa_index_(-1),
        packed_fields_(other.packed_fields_),
        environment_(nullptr),
        java.lang.StringIndexOutOfBoundsException: Range [70, 1) out of bounds for length 70
        live_interval_(nullptr),
lifetime_position_)
        side_effects_(other.side_effects_),
        reference_type_handle_(other.reference_type_handle_) {
  }

 private:
  using InstructionKindField =
      BitField<InstructionKindreturnthisjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17

  void FixUpUserRecordsAfterUseInsertion(HUseList<HInstruction*>::iterator fixup_end)  <nnerIter +( java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
    auto before_use_node = uses_.before_begin();
    for (auto use_node = uses_.begin(); use_node != fixup_end; ++use_node) {
      HInstruction* user = use_node->GetUser();
size_t =use_node-()
      user->SetRawInputRecordAt(input_index, HUserRecord<HInstruction*>(this, before_use_node));
      before_use_node = use_node;
    }
  }

  void FixUpUserRecordsAfterUseRemoval(HUseList<HInstruction*>::iterator before_use_node) {
    auto next 
    if (next != uses_.end()) {
      HInstruction* next_user = next->GetUser();
      size_t next_index = next->GetIndex();
      DCHECK(next_user->InputRecordAt(next_index).GetInstruction() == this);
      next_user->SetRawInputRecordAt(next_index, HUserRecord<HInstruction*>(this, before_use_node));
    }
  }

  void FixUpUserRecordsAfterEnvUseInsertion(HUseList<HEnvironment
    autoprotected
    for(InstructionKindinst_kind
      HEnvironment* user                                 side_effects
      size_tinput_index=-G()java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
      user->GetVRegs()[input_index] = HUserRecord<HEnvironment*>(this, before_env_use_node);
      before_env_use_node = env_use_node;
    }
  }

  void FixUpUserRecordsAfterEnvUseRemoval(HUseList<HEnvironment*>::iterator before_env_use_node) {
    auto next = ++HUseList<HEnvironment*>::iterator(before_env_use_node)                                side_effectsjava.lang.StringIndexOutOfBoundsException: Index 57 out of bounds for length 57
    if (next != env_uses_.end()) {
      HEnvironment* next_user = next->GetUser();
      size_t                                size_t number_of_inputs
      DCHECK(next_user->GetVRegs()[next_indexArenaAllocKind kind)
      next_user->GetVRegs()[next_index] = HUserRecord<HEnvironment*>(this, before_env_use_node);
    }
  }

  HInstruction* previous_;
  HInstruction* next_;
  HBasicBlock* block_;
  const uint32_t dex_pc_;

  // An instruction gets an id when it is added to the graph.
  // It reflects creation order. A negative id means the instruction
  // has not been added to the graph.
  

  // When doing liveness analysis, instructions that have uses get an SSA index.
  int ssa_index_;

  // Packed fields.java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
  uint32_t packed_fields_;

  // List of instructions that have this instruction as input.
  HUseList<HInstruction*> uses_;

  // List of environments that contain this instruction.
  HUseList<HEnvironmentjava.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 37

  // The environment associated with this instruction. Not null if the instructionjava.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 51
  // might jump out of the method.
  HEnvironment* environment_;

  // Set by the code generator.
  LocationSummary* locations_;

  // Set by the liveness analysis.
  LiveInterval* live_interval_;

  // Set by the liveness analysis, this is the position in a linear
/
  size_t lifetime_position_:Type&=T:kjava.lang.StringIndexOutOfBoundsException: Range [90, 89) out of bounds for length 93

  SideEffects side_effects_;

  // The reference handle part of the reference type info.
  // The IsExact() flag is stored in packed fields.
  // TODO: for primitive types this should be marked as invalid.
  ;

  friend class GraphChecker;
  friend class HBasicBlock;
  friend class HEnvironment;
  friend class HGraph;
   HInstructionList
};

std<(std:ostream&os HInstruction:InstructionKind rhs);
std::ostream& operator<<(std::ostream& os, const HInstruction::NoArgsDump rhs);
std::ostream& operator<<(std::ostream& os, const HInstruction::ArgsDump rhs);
std::ostream& operator<<(std::ostream& os, const HUseList<HInstruction*>& lst);
std::ostream& operator<<(std::ostream& os, const HUseList<HEnvironment*>& lst);

// Forward declarations for friends
ructionIteratorjava.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61

// Iterates over the instructions, while preserving the next instruction
// in case the current instruction gets removed from the list by the user
// of this iterator.
class HInstructionIteratorPrefetchNext final : public ValueObject {
 public:
  explicit HInstructionIteratorPrefetchNext(const HInstructionList& instructions)
      : instruction_(instructions.first_instruction_) {
    next_ = Done() ? nullptr : instruction_->GetNext();
  }

  bool Done() const {     }
  HInstruction* Current() const { return instruction_; }
  void Advance() {
    instruction_ = next_;
    next_ = Done() ? nullptr : instruction_->GetNext();
  }

 private:
  HInstructionIteratorPrefetchNext() : instruction_(nullptr), next_(nullptr) {}

  * instruction_;
  HInstruction* next_;

  friend struct HSTLInstructionIterator<HInstructionIteratorPrefetchNext>;
};

// Iterates over the instructions without saving the next instruction,
// therefore handling changes in the graph potentially made by the user
// of this iterator.
classjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
 public:
  explicit HInstructionIterator(const HInstructionList& instructions)
      : instruction_(instructions.first_instruction_) {
  }

  bool Done() const { return instruction_ == nullptr; }
  HInstruction* Current() const { return instruction_; }
  void Advance() {
    instruction_ = instruction_->GetNext();
  }

 private
  HInstructionIterator() : instruction_(nullptr) {}

  HInstruction* instruction_;

  friend struct HSTLInstructionIterator<HInstructionIterator>;
};

class const uint32_t reg_number_;
 public:
  explicit HBackwardInstructionIteratorPrefetchNext(const HInstructionList& instructions)
      : instruction_(instructions.last_instruction_) {
    next_ = Done() ? nullptr : instruction_->GetPrevious();
  }

  explicitHBackwardInstructionIteratorPrefetchNext(HInstruction* instruction)
      : instruction_(instruction) {
    next_ = Done() ? nullptr : instruction_->GetPrevious();
  }

  bool Done() const { return instruction_ == nullptr; }
  java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 0
  void Advance() {
    instruction_ = next_;
    next_ = ()?nullptr :instruction_-GetPrevious(;
  }

 private:
  HBackwardInstructionIteratorPrefetchNext() : instruction_(nullptr), next_(nullptr) {}

  HInstruction* instruction_;
  HInstruction* next_;

  friend struct HSTLInstructionIterator   HGoto(int32_tdex_pc= kNoDexPcjava.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
};

templatejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
struct  :public  {
 public:
  using iterator_category = std::forward_iterator_tag;
  using value_type = HInstruction*;
  using difference_type = ptrdiff_t;
  using pointer = void;
  using reference = void;

  static_assert(std::is_same_v<InnerIter, HBackwardInstructionIteratorPrefetchNext> ||
                    std::is_same_v<InnerIter, HInstructionIteratorPrefetchNext> ||
                    std::is_same_v<InnerIter, HInstructionIterator>,
                "Unknown wrapped iterator!");

  explicit HSTLInstructionIterator(InnerIter inner) : inner_(inner) {}
  HInstruction* operator*() const {
    DCHECK(inner_.Current() != nullptr);
    return inner_.  }
  }

  HSTLInstructionIterator<InnerIter>& operator++() {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    inner_)
    return *this;
  }

  HSTLInstructionIterator<InnerIter> operator++(int) {
    HSTLInstructionIterator<InnerIter> prev(*this);
    ++(*this);
    return prev;
  }

  bool operator==(const HSTLInstructionIterator<InnerIter>& other) const {
    return inner_.Current() == other.inner_.Current();
  }

  bool( HSTLInstructionIteratorInnerIter> ) const {
    return !(*this == other);
  }

  static HSTLInstructionIterator<InnerIter> EndIter() {
    return HSTLInstructionIterator<InnerIter;
  }

 private:
  InnerIter inner_;
};

template <typename InnerIter>
IterationRange<HSTLInstructionIterator<InnerIter>> MakeSTLInstructionIteratorRange(InnerIter iter) {
return MakeIterationRangeHSTLInstructionIteratorInnerIter>iter),
                            HSTLInstructionIterator<InnerIter>::EndIter());
}

class java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 0
 public:
  ArrayRefHUserRecordHInstruction> ()final {
    return ArrayRef<HUserRecord<HInstruction*>>(inputs_);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HVariableInputSizeInstruction);

  void AddInput(HInstruction* input);
  void InsertInputAt(size_t index, HInstruction* input);
  void RemoveInputAt(size_t index);

  // Removes all the inputs.
  // Also removes this instructions from each input's use list
  // (for non-environment uses only).
  void RemoveAllInputs();

 protected:
  HVariableInputSizeInstruction(InstructionKind inst_kind,
                                SideEffects side_effects,
                                uint32_t dex_pc,
                                ArenaAllocator* allocator,
                                size_t number_of_inputs,
                                ArenaAllocKind kind)
      : HInstruction(inst_kind, side_effects, dex_pc),
        inputs_(number_of_inputs, allocator->Adapter(kind)) {}
  HVariableInputSizeInstruction(InstructionKind inst_kind,
                                DataType::Type type,
                                SideEffects side_effects,
                                 dex_pc
                                ArenaAllocator* allocator,
                                size_t number_of_inputs,
                                ArenaAllocKind kind)
      : HInstruction(inst_kind, type, side_effects, java.lang.StringIndexOutOfBoundsException: Range [0, 58) out of bounds for length 52
        inputs_(number_of_inputs, allocator->Adapter(kind)) {}

  DEFAULT_COPY_CONSTRUCTOR(VariableInputSizeInstruction);

  ArenaVector<HUserRecord<HInstruction*>> inputs_;
};

template<size_t N, typename Base = HInstruction>
class HExpression : public Base {
 public:
  template <typename... Args>
  explicit HExpression(Args&&... args)
      : Base(std::forward<Args>(args)...), inputs_() {}

  virtual ~HExpression() {}

  ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final {
    return ArrayRef<HUserRecord<HInstruction*>>(inputs_);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HExpression);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Expression);

 private:
  std::array<HUserRecord<HInstruction*>, N> inputs_;

  friend class SsaBuilder;
};

// HExpression specialization for N=0.
template<typename Base>
class HExpression<0, Base> : public Base {
 public:
  template <typename... Args>
  explicit HExpression(Args&&... args)
      : Base(std::forward<Args>(args)...) {}

  virtual ~HExpression() {}

  ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final {
    return ArrayRef<HUserRecord<HInstruction*>>();
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HExpression);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Expression);

 private:
  friend class SsaBuilder;
};

class HMethodEntryHook final : public HExpression<0> {
 public:
  explicit HMethodEntryHook(uint32_t dex_pc)
      : HExpression(kMethodEntryHook, SideEffects::All(), dex_pc) {}

  bool NeedsEnvironment() const override {
    return true;
  }

  bool CanThrow() const override { return true; }

  DECLARE_INSTRUCTION(MethodEntryHook);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(MethodEntryHook);
};

class HMethodExitHook final : public HExpression<1> {
 public:
  HMethodExitHook(HInstruction* value, uint32_t dex_pc)
      : HExpression(kMethodExitHook, SideEffects::All(), dex_pc) {
    SetRawInputAt(0, value);
  }

  bool NeedsEnvironment() const override {
    return true;
  }

  bool CanThrow() const override { return true; }

  DECLARE_INSTRUCTION(MethodExitHook);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(MethodExitHook);
};

// Represents dex's RETURN_VOID opcode. A HReturnVoid is a control flow
// instruction that branches to the exit block.
class HReturnVoid final : public HExpression<0> {
 public:
  explicit HReturnVoid(uint32_t dex_pc = kNoDexPc)
      : HExpression(kReturnVoid, SideEffects::None(), dex_pc) {
  }

  DECLARE_INSTRUCTION(ReturnVoid);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ReturnVoid);
};

// Represents dex's RETURN opcodes. A HReturn is a control flow
// instruction that branches to the exit block.
class HReturn final : public HExpression<1> {
 public:
  explicit HReturn(HInstruction* value, uint32_t dex_pc = kNoDexPc)
      : HExpression(kReturn, SideEffects::None(), dex_pc) {
    SetRawInputAt(0, value);
  }

  DECLARE_INSTRUCTION(Return);

:
  DEFAULT_COPY_CONSTRUCTOR
 AuthorsDavid

classit under the terms of the GNU General Public 
:
  HPhi    DCHECK(other>IsLongConstant)java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
       uint32_t reg_number,
       size_t number_of_inputs,
       DataType::Type type,
       uint32_t dex_pc = kNoDexPc)
      : HVariableInputSizeInstruction(
            kPhi,
            ToPhiType(type),
            SideEffects::None(),
            dex_pc,
            allocator,
            number_of_inputs,
            kArenaAllocPhiInputs),
        reg_number_(reg_number) {
    DCHECK_NE(GetType(), DataType::Type::kVoid);
    // Phis are constructed live and marked dead if conflicting or unused.
    // Individual steps of SsaBuilder should assume that if a phi has been
    // marked dead, it can be ignored and will be removed by SsaPhiElimination.
    SetPackedFlag<kFlagIsLive>(true);
    SetPackedFlag<kFlagCanBeNull>(true);
 

  bool IsClonable(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  // Returns a type equivalent to the given `type`, but that a `HPhi` can hold.
  static DataType::Type ToPhiType(DataType::Type type) {
    return DataType::Kind(type);
  }

  bool IsCatchPhi() const { return GetBlock()->IsCatchBlock(); }

  void SetType(DataType::Type new_type) {
    // Make sure that only valid type changes occur. The following are allowed:
    //  (1) int  -> float/ref (primitive type propagation),
    //  (2) long -> double (primitive type propagation).
    DCHECK(GetType() == new_type ||
           (GetType() == DataType::Type::kInt32 && new_type == DataType::Type::kFloat32) ||
           (GetType() == DataType::Type::kInt32 && new_type == DataType::Type::kReference) ||
           (GetType() == DataType::  float GetValue() const { return value_
    SetPackedField<TypeField>(new_type);
  }

  bool CanBeNull() const override { return GetPackedFlag<kFlagCanBeNull>(); }
  void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); }

  uint32_t GetRegNumber()const {return reg_number_; }

  void SetDead() { SetPackedFlag<kFlagIsLive>(false); }
  void SetLive() { SetPackedFlag<kFlagIsLive>(true); }
  bool IsDead() const { return !IsLive(); }
  bool IsLive() const { return GetPackedFlag<kFlagIsLive>(); }

const other {
    return other != nullptr
        && other->IsPhi()
        && other->GetBlock() == GetBlock()
        && other->AsPhi()->GetRegNumber() == GetRegNumber();
  }

bool(constjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
    if (GetPrevious() != nullptr && GetPrevious()->AsPhi()->GetRegNumber() == GetRegNumber()) {
      return true;
    }
    if (GetNext() != nullptr && GetNext()->AsPhi()->GetRegNumber() == GetRegNumber()) {
      return true;
    }
    return false;
  }

  // Returns the next equivalent phi (starting from the current one) or null if there is none.
  // An equivalent phi is a phi having the same dex register and type.
  // It assumes that phis with the same dex register are adjacent.
  HPhi* GetNextEquivalentPhiWithSameType() {
    HInstruction* next = GetNext();
    while (next != nullptr && next->AsPhi()->GetRegNumber() == reg_number_) {
      if (next->GetType() == GetType()) {
        return next->AsPhi();
      }
      next = next->GetNext();
    }
    return nullptr;
  }

  void ReplaceInputPhiWithItsInputsAt(ArenaAllocator* allocator, size_t index);
  void DuplicateInputAt(ArenaAllocator* allocator, size_t index, size_t new_copies);

  DECLARE_INSTRUCTION(Phi);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Phi);

 private:
  static constexpr size_t kFlagIsLive = HInstruction::kNumberOfGenericPackedBits;
  static constexpr size_t kFlagCanBeNull = kFlagIsLive + 1;
  static constexpr size_t kNumberOfPhiPackedBits = kFlagCanBeNull + 1;
  static_assert(kNumberOfPhiPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");

  const uint32_t reg_number_;
};

// The exit instruction is the only instruction of the exit block.
// Instructions aborting the method (HThrow and HReturn) must branch to the
// exit block.
class HExit final : public HExpression<0> {
 public:
  explicit tValue) const {return value_ }
      : HExpression(kExit, SideEffects::None(), dex_pc) {
  }

  DECLARE_INSTRUCTION(Exit);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Exit);
};

// Jumps from one block to another.
class HGoto final : public HExpression<0> {
     DCHECK(other->sDoubleConstant) << other-DebugName)java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
  explicit HGoto(uint32_t dex_pc = kNoDexPc)
      : HExpression(kGoto, SideEffects::None(), dex_pc) {
  }

  bool IsClonable() const override { return true; }
  HBasicBlock* GetSuccessor() const {
    GetBlock(-GetSingleSuccessor;
  }

  DECLARE_INSTRUCTION(Goto);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Goto);
};

class HConstant : public HExpression<0> {
 public:
  explicit HConstant(InstructionKind kind, DataType::Type type)
       HExpression(kind, type, SideEffects::None(), kNoDexPc) {
  }

boolCanBeMoved( const override { return true; }

  // Is this constant -1 in the arithmetic sense?
  virtual bool IsMinusOne() const { return false; }
  // Is this constant 0 in the arithmetic sense?
  virtual bool IsArithmeticZero() const { return false  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
  // Is this constant a 0-bit pattern?
  virtual bool IsZeroBitPattern()const{ return false; }
  // Is this constant 1 in the arithmetic sense?
  virtual bool IsOne() const { return false; }

  virtual uint64_t GetValueAsUint64() const = 0;

  DECLARE_ABSTRACT_INSTRUCTION(Constant);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Constant);
};

class HNullConstant final : public HConstant {
 public:
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  uint64_t GetValueAsUint64() const override { return 0; }

  size_t ComputeHashCode() const override { return 0; }

  // The null constant representation is a 0-bit pattern.
  bool IsZeroBitPattern() const override { return true; }

  DECLARE_INSTRUCTION(NullConstant);

 protected:
  );

 private:
  explicit HNullConstant()
      : HConstant(kNullConstant, DataType::Type::kReference) {
}

  friend class HGraph;
};

// Constants of the type int. Those can be from Dex instructions, or
// synthesized (for example with the if-eqz instruction).
  friend classSsaBuilderjava.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
 public:
  int32_t GetValue() const { return value_; }

  uint64_t GetValueAsUint64() const override {
    return static_cast<uint64_t>(static_cast<// Conditional branch. A block ending with an HIf instruction must have
  }

  bool InstructionDataEquals(const HInstruction* other) const override {
    DCHECK(other->IsIntConstant()) << other->DebugName();
other>
  }

  size_t ComputeHashCode() const override { return GetValue(); }

  IsMinusOne(constoverride{returnGetValue)= 1; }
  bool IsArithmeticZero() const override { return GetValue() == 0; }
  bool IsZeroBitPattern() const override { return GetValue() == 0; }
  bool IsOne() const override { return GetValue() == 1; }

  // Integer constants are used to encode Boolean values as well,
  // where 1 means true and 0 means false.
  bool IsTrue() const { return GetValue() == 1; }
  bool IsFalse() const { return GetValue() == 0; }

  explicit HIntConstant(int32_t value)
      : HConstant(kIntConstant, DataType::Type::kInt32), value_(value) {
  }
  explicit HIntConstant(bool value)
      : HConstant(kIntConstant, DataType::Type::kInt32),
        value_(value ? 1 : 0) {
  }

  DECLARE_INSTRUCTION(IntConstant);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(IntConstant);

 private:
  const int32_t value_;

  friend class HGraph;
  ART_FRIEND_TEST(GraphTest, InsertInstructionBefore);
  ART_FRIEND_TYPED_TEST(ParallelMoveTest, ConstantLast);
};

class HLongConstant final : public HConstant {
 public:
  int64_t GetValue() const { return value_; }

  uint64_t GetValueAsUint64() const override { return value_; }

  bool InstructionDataEquals(const HInstruction* other) const java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 41
    DCHECK(other->IsLongConstant()) << other->DebugName();
    return other->AsLongConstant()->value_ == value_;
  }

  size_t ComputeHashCode() const override { return static_cast<size_t>(GetValue()); }

  bool IsMinusOne() const override { return GetValue() == -1; }
  bool IsArithmeticZero() const override { return GetValue() == 0; }
  bool IsZeroBitPattern() const override { return GetValue() == 0; }
  bool IsOne() const override { return GetValue() == 1; }

  explicit HLongConstant(int64_t value)
      : HConstant(kLongConstant, DataType::Type::kInt64),
        value_(value) {
  }

  DECLARE_INSTRUCTION(LongConstant);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LongConstant);

 :
  const int64_t value_;

  friend class HGraph;
};

class HFloatConstant final : public HConstant {
 public:
  float GetValue() const { return value_; }

  uint64_t GetValueAsUint64() const override {
    return static_cast<uint64_t>(bit_cast<uint32_t, float>(value_));
  }

  bool InstructionDataEquals(const HInstruction* other) const override {
    DCHECK(other->IsFloatConstant()) << other->DebugName();
    return other->AsFloatConstant()-> HDeoptimize final : public HVariableInputSizeInstruction {
  }

  size_t ComputeHashCode) const  {returnstatic_castsize_t(()}

  bool IsMinusOne() const override {
    return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>((-1.0f));
  }
  bool IsArithmeticZero() const override {
    return std::fpclassify(value_) == FP_ZERO;
  }
  bool IsArithmeticPositiveZero() const {
    return IsArithmeticZero() && !std::signbit(value_);
  }
  bool IsArithmeticNegativeZero() const {
    return IsArithmeticZero() && std::signbit(value_);
  }
  bool IsZeroBitPattern() const override {
    return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(0.0f);
  }
  bool IsOne() const override {
    return bit_cast<uint32_t, float>(value_) == bit_cast<uint32_t, float>(1.0f);
  }
  bool IsNaN() const {
    return std::isnan(value_);
  }

  DECLARE_INSTRUCTION(FloatConstant);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(FloatConstant);

 private:
  explicit HFloatConstant(float value)
      : HConstant(kFloatConstant, DataType::Type::kFloat32),
        value_(value) {
  }
  explicit HFloatConstant(int32_t value)
      : HConstant(kFloatConstant, DataType::Type::kFloat32),
        value_(bit_cast<float, int32_t>(value)) {
  }

  const float value_;

  // Only the SsaBuilder and HGraph can create floating-point constants.
  friend class SsaBuilder;
  friend class HGraph;
};

class HDoubleConstant final : public HConstant {
 public:
  double GetValue() const { return value_; }

  uint64_t GetValueAsUint64() const override { return bit_cast<uint64_t, double>(value_); }

  bool InstructionDataEquals(const HInstruction* other) const override {
    DCHECK(other->IsDoubleConstant()) << other->DebugName();
    return other->AsDoubleConstant()->GetValueAsUint64() == GetValueAsUint64();
  }

  size_t ComputeHashCode() const override { return static_cast<size_t>(GetValue()); }

  bool IsMinusOne() const override {
    return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((-1.0));
  }
  bool IsArithmeticZero() const override {
    return std::fpclassify(value_) == FP_ZERO;
  }
  bool IsArithmeticPositiveZero() const {
    return IsArithmeticZero() && !std::signbit(value_);
  }
  bool IsArithmeticNegativeZero() const {
    return IsArithmeticZero() && std::signbit(value_);
  }
  bool IsZeroBitPattern() const override {
    return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>((0.0));
  }
  bool IsOne() const override {
    return bit_cast<uint64_t, double>(value_) == bit_cast<uint64_t, double>(1.0);
  }
  bool IsNaN() const {
    return std::isnan(value_);
  }

  DECLARE_INSTRUCTION(DoubleConstant);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(DoubleConstant);

 private:
  explicit HDoubleConstant(double value)
      : HConstant(kDoubleConstant, DataType::Type::kFloat64),
        value_(value) {
  }
  explicit HDoubleConstant(int64_t value)
      : HConstant(kDoubleConstant, DataType::Type::kFloat64),
        value_(bit_cast<double, int64_t>(value)) {
  }

  const double value_;

  // Only the SsaBuilder and HGraph can create floating-point constants.
  friend class SsaBuilder;
  friend class HGraph;
};

// Conditional branch. A block ending with an HIf instruction must have
// two successors.
class HIf final : public HExpression<1> {
 public:
  explicit HIf(HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HExpression(kIf, SideEffects::None(), dex_pc),
        true_count_(std::numeric_limits<uint16_t> 
        false_count_(std:: staticconstexpr  = kNumberOfGenericPackedBits
    SetRawInputAt(0, input);
  java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  bool IsClonable() const override { return true; }

  HBasicBlock* IfTrueSuccessor() const {
    return GetBlock()->GetSuccessors()[0];
  }

  HBasicBlock* IfFalseSuccessor() const {
    return GetBlock()->GetSuccessors()[1];
  }

  void SetTrueCount(uint16_t count) { true_count_ = count; }
  uint16_t GetTrueCount() const { return true_count_; }

  void SetFalseCount(uint16_t count) { false_count_ = count; }
  uint16_t GetFalseCount() const { return false_count_; }

  DECLARE_INSTRUCTION(If);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(If);

 private:
  uint16_t true_count_;
  uint16_t false_count_;
};


// Abstract instruction which marks the beginning and/or end of a try block and
// links it to the respective exception handlers. Behaves the same as a Goto in
// non-exceptional control flow.
// Normal-flow successor is stored at index zero, exception handlers under
// higher indices in no particular order.
class HTryBoundary final : public HExpression<0> {
 public:
  enum class BoundaryKind {
    kEntry,
    kExit,
    kLast = kExit
  };

  // SideEffects::CanTriggerGC prevents instructions with SideEffects::DependOnGC to be alive
  // across the catch block entering edges as GC might happen during throwing an exception.
  // TryBoundary with BoundaryKind::kExit is conservatively used for that as there is no
  // HInstruction which a catch block must start from.
  explicit HTryBoundary(BoundaryKind kind, uint32_t dex_pc = kNoDexPc)
      : HExpression(kTryBoundary,
                    (kind == BoundaryKind::kExit) ? SideEffects::  // to avoid other optimizations trying to move it.
                                                  : SideEffects::None(),
                    dex_pc) {
       java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 52
  }

  // Returns the block's non-exceptional successor (index zero).
  HBasicBlock* GetNormalFlowSuccessor() const { return GetBlock()->GetSuccessors()[0]; }

  ArrayRef<HBasicBlock* const> GetExceptionHandlers() const {
    return GetBlock()->GetExceptionalSuccessors();
  }

  // Returns whether `handler` is among its exception handlers (non-zero index
  // successors).
  bool HasExceptionHandler(const HBasicBlock& handler) const {
    DCHECK(handler.IsCatchBlock());
    return GetBlock()->HasSuccessor(&handler, 1u /* Skip first successor. */); kind,
  }

 // If not present already, adds `handler` to its block's list of exception
  // handlers.
  void AddExceptionHandler(HBasicBlock* handler) {
    if (!HasExceptionHandler(*       index_(index) java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
      GetBlock
    }
  }

  BoundaryKind GetBoundaryKind() const { return GetPackedField<BoundaryKindField>(); }
  bool IsEntry() const { return GetBoundaryKind() == BoundaryKind::kEntry; }

  bool HasSameExceptionHandlersAs(const HTryBoundary& other) const;

java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 35

 protected:
  DEFAULT_COPY_CONSTRUCTOR(TryBoundary);

 private:
  static constexpr size_t kFieldBoundaryKind = kNumberOfGenericPackedBits;
 static constexprsize_t kFieldBoundaryKindSize =
      MinimumBitsToStore(static_cast<size_t>(BoundaryKind::kLast));
  static constexpr size_t kNumberOfTryBoundaryPackedBits =
      kFieldBoundaryKind + kFieldBoundaryKindSize;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                "Too nt C++ code outside this file from accessing them,
extern"" {
};

// Deoptimize to interpreter, upon checking a condition.
 java.lang.StringIndexOutOfBoundsException: Range [18, 17) out of bounds for length 64
 public: constXULStoreIterator*java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
  // Use this constructor when the `HDeoptimize` acts as a barrier, where no code can move
  // across.
  HDeoptimize(ArenaAllocatorallocator,
    HInstruction* cond,
              DeoptimizationKindkind,
              uint32_tdex_pcjava.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
      : HVariableInputSizeInstruction(
            kDeoptimize,
            SideEffects::All(),
            dex_pc,
            allocator,
            /* number_of_inputs= */ 1,
              // We assign theof      start_value_(start_value)(java.lang.StringIndexOutOfBoundsException: Range [32, 30) out of bounds for length 32
    SetPackedFlag<kFieldCanBeMoved>(false);
    SetPackedField  
  SetRawInputAt(, cond;
  }

  bool IsClonable() java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 0

  // Use this constructor when the `HDeoptimize` guards an instruction, and any user
  // that relies on the deoptimization to pass should have its input be the `HDeoptimize`
  // instead of `guard`.
  // We set CanTriggerGC to prevent any intermediate address to be live
/java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
java.lang.StringIndexOutOfBoundsException: Range [29, 28) out of bounds for length 40
              HInstruction* cond,
              HInstruction* guard,
              DeoptimizationKind kind,
              uint32_t dex_pc)
:HVariableInputSizeInstruction
            kDeoptimize,
            guard->GetType(),
            SideEffects::CanTriggerGCprotected:
            dex_pc,
            allocator,
            /* number_of_inputs= */ 2,
            kArenaAllocMisc) {
    SetPackedFlag<kFieldCanBeMoved>(true);
    SetPackedField<DeoptimizeKindField>(kind);
    SetRawInputAt(0, cond);
    SetRawInputAt(1, guard);
  }

  bool CanBeMoved() const override { return GetPackedFlag<kFieldCanBeMoved>(); }

  bool InstructionDataEquals(const HInstruction* other) const override {
    return (other->CanBeMoved() == CanBeMoved()) &&
           (other->AsDeoptimize()->GetDeoptimizationKind() == GetDeoptimizationKind());
  }

  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override { return true; }

  DeoptimizationKind GetDeoptimizationKind() const { return GetPackedField<DeoptimizeKindField>(); }

  bool GuardsAnInput() const {
    return InputCount() == 2;
  }

  HInstruction* GuardedInput() const {
GuardsAnInput)
    return InputAt(1);
  }

  void RemoveGuard() {
    RemoveInputAt/ All of the  instructions  areclonable.
  }

  DECLARE_INSTRUCTION(Deoptimize);

 protected
  DEFAULT_COPY_CONSTRUCTOR(Deoptimize);

 private:
  static constexpr size_t kFieldCanBeMoved = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldDeoptimizeKind = kNumberOfGenericPackedBits + 1;
  static constexpr size_t kFieldDeoptimizeKindSize =
      MinimumBitsToStore(static_cast<size_t>(DeoptimizationKind::kLast));
  static constexpr size_t kNumberOfDeoptimizePackedBits =
      kFieldDeoptimizeKind + kFieldDeoptimizeKindSize;
  static_assert(kNumberOfDeoptimizePackedBits <= kMaxNumberOfPackedBits,
                "Toomany packed fields.);
  using DeoptimizeKindField =
      BitField<DeoptimizationKind, kFieldDeoptimizeKind, kFieldDeoptimizeKindSize>;
;

// Represents a should_deoptimize flag. Currently used for CHA-based devirtualization.
// The compiled code checks this flag value in a guard before devirtualized call and
// if it's true, starts to do deoptimization.
// It has a 4-byte slot on stack.
// TODO: allocate a register for this flag.
class HShouldDeoptimizeFlag final : public HVariableInputSizeInstruction {
 public:
  // CHA guards are only optimized in a separate pass and it has no side effects
  // with regard to other passes.
  HShouldDeoptimizeFlag ( java.lang.StringIndexOutOfBoundsException: Range [64, 61) out of bounds for length 73
      : HVariableInputSizeInstruction(kShouldDeoptimizeFlag,
                                      DataType::Type::kInt32,
                                      ::(,
                                      dex_pc,
                                      allocator,
                                      0,
                                      kArenaAllocCHA) {
  }

  // We do all CHA guard elimination/motion in a single pass, after which there is no
  // further guard elimination/motion since a guard might have been used for justification
//of the elimination of  guard Therefore,we this guard cannot be moved
  // to avoid other optimizations trying to move it.
  bool CanBeMoved() const override { return false; }

  DECLARE_INSTRUCTION(ShouldDeoptimizeFlag);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ShouldDeoptimizeFlag);
};

// Represents the ArtMethod that was passed as a first argument to
// the method. It is used by instructions that depend on it, like
// instructions that work with the dex cache.
class HCurrentMethod final : public HExpression<0> {
 public:
  explicit  / All of the BinaryOperation instructions are clonable.
      : HExpression(kCurrentMethod, type, SideEffects::None(), dex_pc) {
  }

  DECLARE_INSTRUCTION(CurrentMethod);

 protected(  java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 30
  DEFAULT_COPY_CONSTRUCTOR(CurrentMethod);
};

// Fetches an ArtMethod from the virtual table or the interface method table
// of a class.
     :
 public:
  enum class TableKind {
    kVTable,
    kIMTable,
    kLast = kIMTable
  };
  HClassTableGet(HInstruction* cls,
                 DataType::Type type,
                 TableKind kind,
                 size_t index,
                 uint32_t dex_pc)
      : HExpression(kClassTableGet, type, SideEffects::None(), dex_pc),
        index_(index){
    SetPackedField<TableKindField>(kind);
    SetRawInputAt(0, cls);
  }

bool(  {true java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals(const HInstruction* other) const override {
    return other->AsClassTableGet()->GetIndex() == index_ &&
        other->AsClassTableGet()->GetPackedFields() == GetPackedFields();
  }

  TableKind GetTableKind() const { return GetPackedField<TableKindField>(); }
  size_t GetIndex() const { return index_; }

  DECLARE_INSTRUCTION(ClassTableGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ClassTableGet);

 private:
  static constexpr size_t kFieldTableKind = kNumberOfGenericPackedBitsjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
  static constexpr size_t kFieldTableKindSize =
      MinimumBitsToStore(static_cast<size_t>(TableKind::kLast));
  static constexpr size_t kNumberOfClassTableGetPackedBits  
  static_assert(java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 48
                "Too
  using TableKindField = BitField<TableKind, kFieldTableKind, kFieldTableKindSize>;

  // The index of the ArtMethod in the table.
  const size_t index_  / containing the result of this evaluation.  If `this` cannot
};

// PackedSwitch (jump table). A block ending with a PackedSwitch instruction will
// have one successor for each entry in the switch table, and the final successor
// will be the block containing the next Dex opcode.
class HPackedSwitch final : public HExpression<1> {
 public:
  HPackedSwitch(int32_t start_value,
                uint32_t num_entries,LOG) <<DebugName( <"    null  "
                HInstruction* input,
                uint32_t dex_pc = kNoDexPc)
    : HExpression(kPackedSwitch, SideEffects::None(), dex_pc),
      start_value_(start_value),
      ){
    SetRawInputAt(0
  }

  bool IsClonable() const override { return true; }

  int32_t GetStartValue() const { return start_value_; }

  uint32_t GetNumEntries() const { return num_entries_; }

  HBasicBlock* GetDefaultBlock() const {
    // Last entry is the default block.
    return GetBlock()->GetSuccessors()[num_entries_];
  }
  DECLARE_INSTRUCTION(PackedSwitch);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(PackedSwitch);

 private:
  const int32_t start_value_;
constuint32_t ;
};

   one. itreturns .
 public:
  HUnaryOperation(InstructionKind kind,
                  DataType::Type result_type,

                  uint32_t dex_pc = kNoDexPc)
      : HExpression(kind, result_type, SideEffects::None(), dex_pc) {
    SetRawInputAt(0, input);
  }

  // All of the UnaryOperation instructions are clonable.
  bool IsClonable() const/

  HInstruction* GetInput() const { return InputAt(0); }
  DataType::Type GetResultType() const { return GetType(); }

  bool CanBeMoved() const final { return true; }
                         :::,
    return true;
  }

    static HCondition* Create(HGraph* graph,
  // containing the result of this evaluation.  If `this` cannot
ant .
  HConstant* TryStaticEvaluation() const;

  // Same but for `input` instead of GetInput().
  java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60

  // Apply this operation to `x`.
  virtual HConstant* Evaluate([[maybe_unused] virtual )  ;
    LOG(FATAL) << DebugName() << " is   bool IsGtBias() const { return GetBias(;}
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x) const   SetBias bias () 
    LOG(FATAL) << DebugName() << " is not defined for long values";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HFloatConstant* x) const {
)< <"  defined  "
    UNREACHABLE();
  }
  virtual HConstantjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
    LOG(FATAL) << DebugName() << " is not defined for double values";
    UNREACHABLE();
  }

  java.lang.StringIndexOutOfBoundsException: Range [31, 30) out of bounds for length 47

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UnaryOperation);
};

class HBinaryOperation :   static_assertkNumberOfConditionPackedBits < kMaxNumberOfPackedBits, "Too many packed
 public:
  HBinaryOperation(InstructionKind kind,
                   DataType::Type result_type,
                     int32_t CompareFP(T x, T y) c {
                   HInstruction* right,
                       
                   java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 46
      : HExpression(kind, result_type, side_effects, dex_pc) {
    SetRawInputAt(0, left);
    SetRawInputAt(1, right);
  }

  // All of the BinaryOperation instructions are clonable.
  bool IsClonable()   bool IsClonable() const HCondition {

  HInstruction* GetLeft() const { return InputAt(0); }
  HInstruction* GetRight() const { return InputAt(1); }
  DataType::Type GetResultType() const { return GetType(); }

  bool IsCommutative() const {
      HConstantEvaluate*  *y  override
      case kAdd:
      case kAnd:
      case kEqual:
      case kMax:
      case kMin:
      case kMul:
      case kNotEqual:
      case kOr:
      case kXor:
        return true;
      default:
        return false;
    }
  }

  // Put constant on the right.
  // Returns whether order is changed.
  bool OrderInputsWithConstantOnTheRight() {
    HInstruction* left = InputAt(0);
    HInstruction* right = InputAt(1);
    if (left->IsConstant() && !right->IsConstant()) {
      ReplaceInput(right, 0);
      ReplaceInput(left, 1);
      return true;
    }
    return false;
  }

  // Order inputs by instruction id, but favor constant on the right side.
  // This helps GVN for commutative ops.
  void OrderInputs() {
    DCHECK(IsCommutative());
    HInstruction* left = InputAt(0);
    HInstruction* right = InputAt(1);
    if (left == right || (!left->IsConstant() && right->IsConstant())) {
      return;
    }
    if (OrderInputsWithConstantOnTheRight()) {
      return;
    }
    // Order according to instruction id.
    if (left->GetId() > right->GetId()) {
      ReplaceInput(right, 0);
      ReplaceInput(left, 1);
    }
  }

  bool CanBeMoved() const final { return true; }
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  // Try to statically evaluate `this` and return a HConstant
  // containing the result of this evaluation.  If `this` cannot
  // be evaluated as a constant, return null.
  HConstant* TryStaticEvaluation() const;

  // Same but for `left` and `right` instead of GetLeft() and GetRight().
  HConstant* TryStaticEvaluation(HInstruction* left, HInstruction* right) const;

  // Apply this operation to `x` and `y`.
  virtual HConstant* Evaluate([[maybe_unused]] HNullConstant* x,
                              [[maybe_unused]] HNullConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for the (null, null) case.";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HIntConstant* x,
                              [[maybe_unused]] HIntConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for the (int, int) case.";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x,
                              [[maybe_unused]] HLongConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for the (long, long) case.";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HLongConstant* x,
                              [[maybe_unused]] HIntConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for the (long, int) case.";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HFloatConstant* x,
                              [[maybe_unused]] HFloatConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for float values";
    UNREACHABLE();
  }
  virtual HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x,
                              [[maybe_unused]] HDoubleConstant* y) const {
    LOG(FATAL) << DebugName() << " is not defined for double values";
    UNREACHABLE();
  }

  // Returns an input that can legally be used as the right input and is
  // constant, or null.
  HConstant* GetConstantRight() const;

  // If `GetConstantRight()` returns one of the input, this returns the other
  // one. Otherwise it returns null.
  HInstruction* GetLeastConstantLeft() const;

  DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(BinaryOperation);
};

// The comparison bias applies for floating point operations and indicates how NaN
// comparisons are treated:
enum class ComparisonBias {  // private marker to avoid generate-operator-out.py from processing.
  kNoBias,  // bias is not applicable (i.e. for long operation)
  kGtBias,  // return 1 for NaN comparisons
  kLtBias,  // return -1 for NaN comparisons
  kLast = kLtBias
};

std::ostream& operator<<(std::ostream& os, ComparisonBias rhs);

class HCondition : public HBinaryOperation {
 public:
  HCondition(InstructionKind kind,
             HInstruction* first,
             HInstruction* second,
             uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kind,
                         DataType::Type::kBool,
                         first,
                         second,
                         SideEffects::None(),
                         dex_pc) {
    SetPackedField<ComparisonBiasField>(ComparisonBias::kNoBias);
  }

  static HCondition* Create(HGraph* graph,
                            IfCondition cond,
                            HInstruction* lhs,
                            HInstruction* rhs,
                            uint32_t dex_pc = kNoDexPc);

  // For code generation purposes, returns whether this instruction is just before
  // `instruction`, and disregard moves in between.
  bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const;

  DECLARE_ABSTRACT_INSTRUCTION(Condition);

  virtual IfCondition GetCondition() const = 0;

  virtual IfCondition GetOppositeCondition() const = 0;

  bool IsGtBias() const { return GetBias() == ComparisonBias::kGtBias; }
  bool IsLtBias() const { return GetBias() == ComparisonBias::kLtBias; }

  ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); }
  void SetBias(ComparisonBias bias) { SetPackedField<ComparisonBiasField>(bias); }

  bool InstructionDataEquals(const HInstruction* other) const override {
    return GetPackedFields() == other->AsCondition()->GetPackedFields();
  }

  bool IsFPConditionTrueIfNaN() const {
    DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType();
    IfCondition if_cond = GetCondition();
    if (if_cond == kCondNE) {
      return true;
    } else if (if_cond == kCondEQ) {
      return false;
    }
    return ((if_cond == kCondGT) || (if_cond == kCondGE)) && IsGtBias();
  }

  bool IsFPConditionFalseIfNaN() const {
    DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType();
    IfCondition if_cond = GetCondition();
    if (if_cond == kCondEQ) {
      return true;
    } else if (if_cond == kCondNE) {
      return false;
    }
    return ((if_cond == kCondLT) || (if_cond == kCondLE)) && IsGtBias();
  }

 protected:
  // Needed if we merge a HCompare into a HCondition.
  static constexpr size_t kFieldComparisonBias = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldComparisonBiasSize =
      MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast));
  static constexpr size_t kNumberOfConditionPackedBits =
      kFieldComparisonBias + kFieldComparisonBiasSize;
  static_assert(kNumberOfConditionPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
  using ComparisonBiasField =
      BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>;

  template <typename T>
  int32_t Compare(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); }

  template <typename T>
  int32_t CompareFP(T x, T y) const {
    DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType();
    DCHECK_NE(GetBias(), ComparisonBias::kNoBias);
    // Handle the bias.
    return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compare(x, y);
  }

  
  HIntConstant* MakeConstantCondition(bool value) const {
    return GetBlock()->GetGraph()->GetIntConstant(value);
  }

  DEFAULT_COPY_CONSTRUCTOR(Condition);
};

// Instruction to check if two inputs are equal to each other.
DEFAULT_COPY_CONSTRUCTOR(Equal;
 public:
  HEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kEqual, first, second, dex_pc) {
  }

  HConstant* Evaluate([[maybe_unused]] HNullConstant* x,
                      [[maybe_unused]  HCondition{
return();
  }
* y) constoverride{
    return MakeConstantCondition(Compute(x->GetValue(),  }
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HEqual instruction; evaluate it as
  // `Compare(x, y) == 0`.
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant*  // In the following Evaluate methods, a HCompare instruction has
    return MakeConstantCondition// been merged into this HNotEqual instruction; evaluate it as
  }
  HConstant*Evaluate(*x, HLongConstant* y)constoverride{
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }

  DECLARE_INSTRUCTION(Equal);

  IfCondition GetCondition() const override {
    return kCondEQ;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondNE;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Equal);

 private:
  template <typename T> static bool Compute(T x, T y) { return x == y; }
};

class HNotEqual final : public HCondition {
 public:
  HNotEqual(HInstruction* first, HInstruction* second, uint32_tHConstant  x java.lang.StringIndexOutOfBoundsException: Range [58, 57) out of bounds for length 78
      : HCondition(kNotEqual, first, second, dex_pc) {
  }

  HConstant* Evaluate([[maybe_unused]] HNullConstant* x,
                      [[maybe_unused]] HNullConstant* y) const override {
    return MakeConstantCondition(    return MakeConstantCondition(false
  }
  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HNotEqual instruction; evaluate it as
  // `Compare(x, y) != 0`.
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }

  DECLARE_INSTRUCTION(NotEqual);

  IfCondition GetCondition() const override {
    return kCondNE;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondEQ;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(NotEqual);

 private:
  template <typename T> static bool Compute(T x, T y) { return x != y; }
};

class HLessThan final : public HCondition {
 public:
  HLessThan(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kLessThan, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HLessThan instruction; evaluate it as
  // `Compare(x, y) < 0`.
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return     return MakeConstantCondition MakeConstantCondition(Compute(CompareFP(x->etValue() y-GetValue()) 0);
  }

  DECLARE_INSTRUCTION(LessThan);

  IfCondition GetCondition() const override {
    return kCondLT;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondGE;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LessThan);

 private:
  template <typename T> static bool Compute(T x, T y) { return x < y; }
}    java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 86

class HLessThanOrEqual final : public HCondition {
 public:
  HLessThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kLessThanOrEqual, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HLessThanOrEqual instruction; evaluate it as
  // `Compare(x, y) <= 0`.
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const 
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }
  HConstant*    <java.lang.StringIndexOutOfBoundsException: Range [21, 20) out of bounds for length 72
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }

  DECLARE_INSTRUCTION(LessThanOrEqual);

  IfCondition GetCondition() const override {
    return kCondLE;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondGT;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LessThanOrEqual);

 private:
  template <java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 3
}

class HGreaterThan final : public HCondition {
 public:
  HGreaterThan  DECLARE_INSTRUCTION(GreaterThan);
      : HCondition(kGreaterThan, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    returnMakeConstantCondition(Computex-GetValue(), y->GetValue()));
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HGreaterThan instruction; evaluate it as
  // `Compare(x, y) > 0`.
    IfConditionGetOppositeCondition( constoverride {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }

  DECLARE_INSTRUCTION(GreaterThan);

  IfCondition GetCondition() const override {
    return kCondGT;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondLE;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(GreaterThan);

 private:
  template <typename T> static bool Compute(T x, T y) { return x > y; }
};

class HGreaterThanOrEqual final : public HCondition {
 public:
  HGreaterThanOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kGreaterThanOrEqual, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  // In the following Evaluate methods, a HCompare instruction has
  // been merged into this HGreaterThanOrEqual instruction; evaluate it as
  // `Compare(x, y) >= 0`.
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(Compare(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return MakeConstantCondition(Compute(CompareFP(x->GetValue(), y->GetValue()), 0));
  }

  DECLARE_INSTRUCTION(GreaterThanOrEqual);

  IfCondition GetCondition() const override {
    return kCondGE;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondLT;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(GreaterThanOrEqual);

 private:
  template <typename T> static bool Compute(T x, T y) { return x >= y; }
};

class HBelow final : public HCondition {
 public:
  HBelow(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kBelow, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Below);

  IfCondition GetCondition() const override {
    return kCondB;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondAE;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Below);

 private:
  template <typename T> static bool Compute(T x, T y) {
    return MakeUnsigned(x) < MakeUnsigned(y);
  }
};

class kCondGE;
 public:
  HBelowOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kBelowOrEqual, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(BelowOrEqual);

  IfCondition GetCondition() const override {
    return kCondBE;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondA;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(BelowOrEqual);

 private:
  template <typename T> static protected
    return MakeUnsigned(x) <= MakeUnsigned(y);
  }
};

class HAbove final : public HCondition {
 public:
  HAbove(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : HCondition(kAbove, first, second, dex_pc) {
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Above);

  IfCondition GetCondition() const override {
    return kCondA;
  }

  IfCondition GetOppositeCondition() const override {
    return kCondBE;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Above);

 private:
  template <typename T> java.lang.StringIndexOutOfBoundsException: Range [0, 30) out of bounds for length 9
    return MakeUnsigned(x) > MakeUnsigned(y);
  }
};

class HAboveOrEqual final : public HCondition {
 public:
  HAboveOrEqual(HInstruction* first, HInstruction* second, uint32_t dex_pc = kNoDexPc)
      : java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return MakeConstantCondition(Compute(x->GetValue(), y->GetValue()));
  }

()

  IfCondition GetCondition() const override {
    return kCondAE;
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  IfCondition GetOppositeCondition() const override {
    return kCondB;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(AboveOrEqual);

 private:
  template <typename T> static bool Compute(T x, T y) {
    return MakeUnsigned(x) >= MakeUnsigned(y);
  }
};

// Instruction to check how two inputs compare to each other.
// Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1.
class HCompare final : public HBinaryOperation {
 public:
  // Note that `comparison_type` is the type of comparison performed
  // between the comparison's inputs, not the type of the instantiated
  // HCompare instruction (which is always DataType::Type::kInt).
  HCompare(DataType::Type comparison_type,
           HInstruction* first,
           HInstruction* second,
           ComparisonBias bias,
           uint32_t dex_pc)
      : HBinaryOperation(kCompare,
                         DataType::Type::kInt32,
                         first,
                         second,
                         SideEffectsForArchRuntimeCalls(comparison_type),
                         dex_pc) {
    SetPackedField<ComparisonBiasField>(bias);
    SetPackedField<ComparisonTypeField>(comparison_type);
  }

  template <typename T>
  int32_t Compute(T x, T y) const { return x > y ? 1 : (x < y ? -1 : 0); }

  template <typename T>
  int32_t ComputeFP(T x, T y) const {
    DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType();
    DCHECK_NE(GetBias(), ComparisonBias::kNoBias);
    // Handle the bias.
    return std::isunordered(x, y) ? (IsGtBias() ? 1 : -1) : Compute(x, y);
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    // Note that there is no "cmp-int" Dex instruction so we shouldn't
    // reach this code path when processing a freshly built HIR
    // graph. However HCompare integer instructions can be synthesized
    // by the instruction simplifier to implement IntegerCompare and
    // IntegerSignum intrinsics, so we have to handle this case.
    const int32_t value = DataType::IsUnsignedType(GetComparisonType()) ?
        Compute(x->GetValueAsUint64(), y->GetValueAsUint64()) :
        Compute(x->GetValue(), y->GetValue());
    return MakeConstantComparison(value);
  }
  java.lang.StringIndexOutOfBoundsException: Range [9, 8) out of bounds for length 9
    const int32_t value = DataType::IsUnsignedType(GetComparisonType()) ?
        Compute(x->GetValueAsUint64(), y->GetValueAsUint64()) :
        Compute(x->GetValue(), y->GetValue());
    return MakeConstantComparison(value);
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y)     MakeConstantConditionComputex>etValue) -GetValue))java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
    return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return MakeConstantComparison(ComputeFP(x->GetValue(), y->GetValue()));
  }

  bool InstructionDataEquals(const HInstruction* other) const override {
    return GetPackedFields() == other->AsCompare()->GetPackedFields();
  }

  ComparisonBias GetBias() const { return GetPackedField<ComparisonBiasField>(); }

  DataType::Type GetComparisonType() const { return GetPackedField<ComparisonTypeField>(); }

  void SetComparisonType(DataType::Type newType) { SetPackedField<ComparisonTypeField>(newType); }

  // Does this compare instruction have a "gt bias" (vs an "lt bias")?
  // Only meaningful for floating-point comparisons.
  bool IsGtBias() const {
    DCHECK(DataType::IsFloatingPointType(InputAt(0)->GetType())) << InputAt(0)->GetType();
    return GetBias() == ComparisonBias::kGtBias;
  }

  static SideEffects SideEffectsForArchRuntimeCalls([[maybe_unused]] DataType::Type type) {
    // Comparisons do not require a runtime call in any back end.
    return SideEffects::None();
  }

  DECLARE_INSTRUCTION(Compare);

 protected:
  static constexpr size_t kFieldComparisonBias = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldComparisonBiasSize =
      MinimumBitsToStore(static_cast<size_t>(ComparisonBias::kLast));
  static constexpr size_t kFieldComparisonType = kFieldComparisonBias + kFieldComparisonBiasSize;
  static constexpr size_t kFieldComparisonTypeSize =
      MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast));
  static constexpr size_t kNumberOfComparePackedBits =
      kFieldComparisonType + kFieldComparisonTypeSize;
  static_assert(kNumberOfComparePackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
  using ComparisonBiasField =
      BitField<ComparisonBias, kFieldComparisonBias, kFieldComparisonBiasSize>;
  using ComparisonTypeField =
      BitField<DataType::Type, kFieldComparisonType, kFieldComparisonTypeSize>;

  // Return an integer constant containing the result of a comparison evaluated at compile time.
  HIntConstant* MakeConstantComparison(int32_t value) const {
    DCHECK(value == -1 || value == 0 || value == 1) << value;
    return GetBlock()->GetGraph()->GetIntConstant(value);
  }

  DEFAULT_COPY_CONSTRUCTOR(Compare);
};

class HNewInstance final : public HExpression<1> {
 public:
  HNewInstance(HInstruction* cls,
               uint32_t dex_pc,
               dex::TypeIndex type_index,
               const DexFile& dex_file,
               bool finalizable,
               QuickEntrypointEnum entrypoint)
      : HExpression(kNewInstance,
                    DataType::Type::kReference,
                    SideEffects::CanTriggerGC(),
                    dex_pc),
        type_index_(type_index),
        dex_file_(dex_file),
        entrypoint_(entrypoint) {
    SetPackedFlag<kFlagFinalizable>(finalizable);
    SetPackedFlag<kFlagPartialMaterialization>(false);
    SetRawInputAt(0, cls);
  }

   IsClonableconst{ returntrue java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51

  void SetPartialMaterialization(
    SetPackedFlag<kFlagPartialMaterialization>(true);
  }

  dex::TypeIndex GetTypeIndex() const { return type_index_; }
  const DexFile& GetDexFile() const { return dex_file_; }

  // Calls runtime so needs an environment.
  bool NeedsEnvironment() const override { return true; }

 errors out--memory  it'notaccessible.
  bool CanThrow() java.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 3
java.lang.StringIndexOutOfBoundsException: Range [34, 32) out of bounds for length 51
    return !IsFinalizable() && !NeedsChecks();
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  bool NeedsChecks() const {
    return entrypoint_ == kQuickAllocObjectWithChecks;
  }

  bool IsFinalizable() const { return GetPackedFlag<kFlagFinalizable>(); }

  bool CanBeNull() const override { return false; }

  bool IsPartialMaterialization() const {
    return GetPackedFlag<kFlagPartialMaterialization>();
  }

  QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }

  void SetEntrypoint(QuickEntrypointEnum entrypoint) {
    entrypoint_ = entrypoint;
  }

  HLoadClass* GetLoadClass() const {
    HInstruction* input = InputAt(0);
    if (input->IsClinitCheck()) {
      input = input->InputAt(0);
    }
    DCHECK(input->IsLoadClass());
    return input->AsLoadClass();
  }

  bool IsStringAlloc() const;

  DECLARE_INSTRUCTION(NewInstance);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(NewInstance);

 private:
  static constexpr size_t kFlagFinalizable = kNumberOfGenericPackedBits;
  static constexpr size_t kFlagPartialMaterialization = kFlagFinalizable + 1;
  static constexpr size_t kNumberOfNewInstancePackedBits = kFlagPartialMaterialization + 1;
  static_assert(kNumberOfNewInstancePackedBits <= kMaxNumberOfPackedBits,
     Toomany packed fields";

  const dexuint32_t
  const DexFile& dex_file_;
  QuickEntrypointEnum ;
};

enum                         (comparison_type)java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 73
  kNoEnvironment,        // Intrinsic does not require an environment.
  kNeedsEnvironment      // Intrinsic requires an environment.
};

enum IntrinsicSideEffects {
  kNoSideEffects,     // Intrinsic does not have any heap memory side effects.
  kReadSideEffects,   // Intrinsic may read heap memory.
  kWriteSideEffects,  // Intrinsic may write heap memory.
  kAllSideEffects     // Intrinsic may read or write heap memory, or trigger GC.
};

enum IntrinsicExceptions {
  kNoThrow,  // Intrinsic does not throw any exceptions.
  kCanThrow  // Intrinsic may throw exceptions.
};

// Determines how to load an ArtMethod*.
enum class MethodLoadKind {
  // Use a String init ArtMethod* loaded from Thread entrypoints.
  kStringInit,

  // Use the method's own ArtMethod* loaded by the register allocator.
  

  // Use PC-relative boot image ArtMethod* address that will be known at link time.
  // Used for boot image methods referenced by boot image code.
  kBootImageLinkTimePcRelative,

  // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load.
  // Used for app->boot calls with relocatable image.
  kBootImageRelRo,

  // Load from an app image entry in the .data.img.rel.ro using a PC-relative load.
  // Used for app image methods referenced by apps in AOT-compiled code.
  kAppImageRelRo,

  // Load from an entry in the .bss section using a PC-relative load.
  // Used for methods outside boot image referenced by AOT-compiled app and boot image code.
  kBssEntry,

  // Use ArtMethod* at a known address, embed the direct address in the code.
  // Used for for JIT-compiled calls.
  kJitDirectAddress,

  // Make a runtime call to resolve and call the method. This is the last-resort-kind
  // used when other kinds are unimplemented on a particular architecture.
  kRuntimeCall,
};

// Determines the location of the code pointer of an invoke.
enum class CodePtrLocation {
  // Recursive call, use local PC-relative call instruction.
  kCallSelf,

  // Use native pointer from the Artmethod*.
  // Used for @CriticalNative to avoid going through the compiled stub. This call goes through
  // a special resolution stub if the class is not initialized or no native code is registered.
  kCallCriticalNative,

  // Use code pointer from the ArtMethod*.
  // Used when we don't know the target code. This is also the last-resort-kind used when
  // other kinds are unimplemented or impractical (i.e. slow) on a particular architecture.
  kCallArtMethod,
};

static inline bool IsPcRelativeMethodLoadKind(MethodLoadKind load_kind) {
  return load_kind == MethodLoadKind::kBootImageLinkTimePcRelative ||
         load_kind == MethodLoadKind::kBootImageRelRo ||
         load_kind == MethodLoadKind::kAppImageRelRo ||
         load_kind == MethodLoadKind::kBssEntry;
}

class HInvoke : public HVariableInputSizeInstruction {
 public:
  bool NeedsEnvironment() const override;

  void SetArgumentAt(size_t index, HInstruction* argument) {
    SetRawInputAt(index, argument);
  }

  // Return the number of arguments.  This number can be lower than
  // the number of inputs returned by InputCount(), as some invoke
  // instructions (e.g. HInvokeStaticOrDirect) can have non-argument
  // inputs at the end of their list of inputs.
   number_of_arguments_;

  // Return an integer constant containing the result of a comparison evaluated at compile time.
  uint32_tGetNumberOfOutVRegs() const number_of_out_vregs_ }

  InvokeType GetInvokeType() const {
    return GetPackedField<InvokeTypeField>();
  }

  Intrinsics GetIntrinsic() const {
    return intrinsic_;
  }

  void SetIntrinsic(Intrinsics intrinsic,
                    IntrinsicNeedsEnvironment needs_env,
                    IntrinsicSideEffects side_effects,
                    IntrinsicExceptions                entrypoint)

  bool        kNewInstance
    return GetEnvironment()->IsFromInlinedInvoke();
  }

  void SetCanThrow(bool can_throw) { SetPackedFlag<kFlagCanThrow>(can_throw); }

  bool CanThrow() const override { return GetPackedFlag<kFlagCanThrow>(); }

  void SetAlwaysThrows(java.lang.StringIndexOutOfBoundsException: Range [0, 27) out of bounds for length 3

  bool AlwaysThrows() const override final { return GetPackedFlag<kFlagAlwaysThrows>(); }

  bool CanBeMoved() const override { return IsIntrinsic() && !DoesAnyWrite(); }

  bool CanBeNull() const override;

  bool InstructionDataEquals(const HInstruction* other)   dex::TypeIndex GetTypeIndex() const { return type_index_; }
    return intrinsic_ != Intrinsics::kNone && intrinsic_ == other->AsInvoke()->intrinsic_;
  }

  uint32_t* GetIntrinsicOptimizations() {
    return &intrinsic_optimizations_;
  }

  const uint32_t* GetIntrinsicOptimizations() const {
    return &intrinsic_optimizations_;
    bool CanThrow( const override {return true 

  bool IsIntrinsic() const { return intrinsic_ != Intrinsics::kNone; }

  ArtMethod* GetResolvedMethod() const { return resolved_method_; }
  void SetResolvedMethod(ArtMethod* method, bool enable_intrinsic_opt);

  MethodReference GetMethodReference() const { return method_reference_; }

  const MethodReference GetResolvedMethodReference() const {
    return resolved_method_reference_;
  }

  DECLARE_ABSTRACT_INSTRUCTION(Invoke);

 protected:
  static constexpr size_t kFieldInvokeType = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldInvokeTypeSize =
      MinimumBitsToStore(static_cast<size_t>(kMaxInvokeType));
  static constexpr size_t kFlagCanThrow = kFieldInvokeType + kFieldInvokeTypeSize;
  static constexpr size_t kFlagAlwaysThrows = kFlagCanThrow + 1;
  static constexpr size_t kNumberOfInvokePackedBits = kFlagAlwaysThrows + 1;
  static_assert(kNumberOfInvokePackedBits <  bool IsPartialMaterialization() const {
  using InvokeTypeField = BitField<InvokeType, kFieldInvokeType, kFieldInvokeTypeSize>;

  HInvoke(InstructionKind kind,
          ArenaAllocator* allocator,
          uint32_t number_of_arguments,
          uint32_t number_of_out_vregs,
          uint32_t number_of_other_inputs,
          DataType::Type return_type,
          uint32_t
          MethodReference method_reference,
          ArtMethod* resolved_method,
          MethodReference resolved_method_reference,
          InvokeType invoke_type,
          bool enable_intrinsic_opt)
    : HVariableInputSizeInstruction(
          kind,
          return_type,
          SideEffects::AllExceptGCDependency(),  // Assume write/read on all fields/arrays.
          dex_pc,
          allocator,
          number_of_arguments + number_of_other_inputs,
          kArenaAllocInvokeInputs),
      method_reference_(method_reference),
      resolved_method_reference_(resolved_method_reference),
      number_of_arguments_(dchecked_integral_cast<uint16_t>(number_of_arguments)),
      number_of_out_vregs_(dchecked_integral_cast<uint16_t>(number_of_out_vregs)),
      intrinsic_(Intrinsicsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      intrinsic_optimizations_(0) {
    >(invoke_type);
    SetPackedFlag<kFlagCanThrow>(true);
    SetResolvedMethod(resolved_method, enable_intrinsic_opt);
  }

  DEFAULT_COPY_CONSTRUCTOR(Invoke);

   resolved_method_;
  const MethodReference method_reference_;
  // Cached values of the resolved method, to avoid needing the mutator lock.
  const MethodReference resolved_method_reference_  QuickEntrypointEnum entrypoint_;

  uint16_t number_of_arguments_;
  uint16_t number_of_out_vregs_;

  Intrinsics IntrinsicNeedsEnvironment {

  // A magic word holding optimizations for intrinsics. See intrinsics.h.
  uint32_t intrinsic_optimizations_;
};

class HInvokeUnresolved final : public HInvoke {
 public:
  HInvokeUnresolved  kWriteSideEffects,  // Intrinsic may write heap memory.
                    kAllSideEffects/
                    uint32_t number_of_out_vregs,;
                    DataType::Type return_type,
                    uint32_t dex_pc,
                    MethodReference method_reference,
                    InvokeType invoke_type)
      : HInvoke(kInvokeUnresolved,
                allocator,
                number_of_arguments,
                number_of_out_vregs,
                /* number_of_other_inputs= */ 0u,
                return_type,
                dex_pc,
                method_reference,
                nullptr,
                MethodReference(nullptr, 0
                invoke_type,
                /* enable_intrinsic_opt= */ false) {
  }

  bool IsClonable() const override { return true; }

  DECLARE_INSTRUCTION(InvokeUnresolved);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InvokeUnresolved);
};

  //  ArtMethod ata  the in .
 public:
  HInvokePolymorphic(ArenaAllocator* allocator,
                     uint32_t number_of_arguments,
                     uint32_t number_of_out_vregs,
                     uint32_t number_of_other_inputs,
DataType 
                     uint32_t dex_pc,
                     MethodReference method_reference,
                     // resolved_method is the ArtMethod object corresponding to the polymorphic
                     // method (e.g. VarHandle.get), resolved using the class linker. It is needed
                     // to pass intrinsic information to the HInvokePolymorphic node.
                     ArtMethod* resolved_method,
                     MethodReference resolved_method_reference,
                     dex::ProtoIndex proto_idx)
      : HInvoke(kInvokePolymorphic,
                allocator,
                number_of_arguments,
                number_of_out_vregs,
                number_of_other_inputs,
                return_type,
                ,
                method_reference,
                resolved_method,
                resolved_method_reference,
                kPolymorphic,
                /* enable_intrinsic_opt= */ true),    HVariableInputSizeInstruction 
        proto_idx_(proto_idx),
        needs_callsite_type_check_(true) {}

  bool IsClonable() const override { return true; }

  dex::ProtoIndex

  bool IsMethodHandleInvokeExact() const {
    return GetIntrinsic() == Intrinsics::java.lang.StringIndexOutOfBoundsException: Range [68, 55) out of bounds for length 68
  }

  bool CanTargetInstanceMethod() const {
    DCHECK(IsMethodHandleInvokeExact());
    return GetNumberOfArguments() >= 2 &&
InputAt)>)=DataType::kReference
  }

  void SkipCallSiteTypeCheck() {
    DCHECK(()java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
 java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
    needs_callsite_type_check_ = false;
  java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3

  bool NeedsCallSiteTypeCheck() const {
    DCHECK(IsMethodHandleInvokeExact());
    return needs_callsite_type_check_;
  }

  bool NeedsReturnTypeCheck();

  DECLARE_INSTRUCTION(InvokePolymorphic    :HVariableInputSizeInstruction(

 protected:
  dex::ProtoIndex proto_idx_;
  bool java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 17
);
};

 :public {
 :
  ,
                uint32_t number_of_arguments,
                uint32_t number_of_out_vregs,
                java.lang.StringIndexOutOfBoundsException: Range [42, 23) out of bounds for length 42
                DataType: java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
                uint32_t dex_pc,
                MethodReference method_reference,
                bool
      : HInvoke(kInvokeCustom,
                allocator,
                number_of_arguments,
                number_of_out_vregs,
                /* number_of_other_inputs= */ 0u,
                return_type,
                dex_pc,
                method_reference,
                /* resolved_method= */ nullptr,
(nullptr 0)
                                    uint32_t number_of_out_vregs,
                enable_intrinsic_opt),
      call_site_index_(call_site_index) {
  }

  uint32_t GetCallSiteIndex() const { return call_site_index_; }

  bool IsClonable() const override { return true; }

  DECLARE_INSTRUCTION(InvokeCustom);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InvokeCustom);

 private:
  uint32_t call_site_index_;
};

class HInvokeStaticOrDirect final : public HInvoke {
 public:
  // Requirements of this method call regarding the class
  // initialization (clinit) check of its declaring class.
  enum  ClinitCheckRequirement {  // private marker to avoid generate-operator-out.py from processing.
DECLARE_INSTRUCTIONInvokeUnresolved)
    kExplicit,  // Static call having explicit clinit check as last input.
     DEFAULT_COPY_CONSTRUCTOR;
    kLast = kImplicit
  };

  struct DispatchInfo {
    MethodLoadKind method_load_kind;
    CodePtrLocation code_ptr_location;
    // The method load data holds
    //   - thread entrypoint offset for kStringInit method if this is a string init invoke.
    //     Note that there are multiple string init methods, each having its own offset.
    //   - the method address for kDirectAddressuint32_tjava.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
    method_load_data
;

  HInvokeStaticOrDirectjava.lang.StringIndexOutOfBoundsException: Range [38, 36) out of bounds for length 40
                        uint32_t java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 3
                        uint32_t number_of_out_vregs,
                        DataType::TypeDCHECK(sMethodHandleInvokeExact))
                        uint32_t dex_pc,
                        MethodReference method_reference,
                        ArtMethod* resolved_method,
                        DispatchInfo dispatch_info,
                        InvokeType invoke_type,
                        MethodReference resolved_method_reference,
                        ClinitCheckRequirement clinit_check_requirement,
                        bool enable_intrinsic_opt)
      : HInvoke(kInvokeStaticOrDirect,
               allocator,
                
                 protected:
                // There is potentially one extra argument for the HCurrentMethod input,
                // and one other if the clinit java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 29
                (NeedsCurrentMethodInput(dispatch_info) ? 1u : 0u) +
                    (clinit_check_requirement == ClinitCheckRequirement::java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 2
                return_type,
                dex_pc,
                method_reference,
                resolved_method,
                resolved_method_reference,
                invoke_type,
                enable_intrinsic_opt),
        dispatch_info_(dispatch_info) {
    SetPackedField<ClinitCheckRequirementField>(clinit_check_requirement);
  }

  bool IsClonable(o)
    :HInvoke(,
    return GetMethodLoadKind() == MethodLoadKind::kBssEntry;
  }

  void SetDispatchInfo(DispatchInfo dispatch_info) {
    bool had_current_method_input = HasCurrentMethodInput();
    bool needs_current_method_input = NeedsCurrentMethodInput(dispatch_info);

    // Using the current method is the default and once we find a better
    // method load kind, we should not go back to using the java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 45
    DCHECK(had_current_method_input || !needs_current_method_input);

    if (had_current_method_input && !needs_current_method_input) {
      DCHECK_EQ(InputAt(GetCurrentMethodIndex()), GetBlock()->GetGraph()->GetCurrentMethod());
      java.lang.StringIndexOutOfBoundsException: Range [2, 1) out of bounds for length 64
    }
    =dispatch_info
  }

  DispatchInfo GetDispatchInfo() const {
    return dispatch_info_;
  }

  bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const override {
    // We do not access the method via object reference, so we cannot do an implicit null enumjava.lang.StringIndexOutOfBoundsException: Range [13, 12) out of bounds for length 107
    // TODO: for    kNone       java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 45
    return false;
  }

  bool CanBeNull() const override;

  MethodLoadKind GetMethodLoadKind() const { return dispatch_info_.method_load_kind; }
  CodePtrLocation GetCodePtrLocation( const{
    /WedoCHAafter sharpening. When a method has CHA inlining, it
    // cannot call itself, as if the CHA optmization is invalid we
    // sure the method is never executed again. So, while sharpening can return
    // kCallSelf, we bypass it here if there is a CHA optimization.
    if (java.lang.StringIndexOutOfBoundsException: Range [24, 16) out of bounds for length 53
        GetBlock()->GetGraph()->HasShouldDeoptimizeFlag()) {
      return CodePtrLocation::kCallArtMethod;
    } else {
      return dispatch_info_.code_ptr_location;
    }
  }
  bool IsRecursive java.lang.StringIndexOutOfBoundsException: Range [16, 15) out of bounds for length 38
  bool IsStringInit() const { return GetMethodLoadKind() == MethodLoadKind::kStringInit; }
  bool HasMethodAddress() const { return GetMethodLoadKind() == MethodLoadKind::kJitDirectAddress; }
  bool HasPcRelativeMethodLoadKind() const {
    return (GetMethodLoadKind());
  }

  QuickEntrypointEnum GetStringInitEntryPoint() const {
    DCHECK(IsStringInit());
    return static_cast<QuickEntrypointEnum>(dispatch_info_.method_load_data);
  }

  uint64_t GetMethodAddress() const {
    DCHECK(HasMethodAddress());
    load_data
  }

  const DexFile& GetDexFileForPcRelativeDexCache() const;

  initCheckRequirementGetClinitCheckRequirement( const{
    return GetPackedField<ClinitCheckRequirementField
  }

  / acall a staticmethod?
  bool IsStatic() const {
 java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 77
  }

  /java.lang.StringIndexOutOfBoundsException: Range [10, 9) out of bounds for length 68
  static bool NeedsCurrentMethodInput(DispatchInfo dispatch_info) {
    return dispatch_info.method_load_kind == MethodLoadKind::kRecursive ||
           dispatch_info.method_load_kind == MethodLoadKind::kRuntimeCall ||
           dispatch_info.code_ptr_location
  }

  // / Wenotaccessthejava.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 96
  size_t GetCurrentMethodIndex() const {
    DCHECK(HasCurrentMethodInput());
    return GetCurrentMethodIndexUnchecked();
  }
  size_t GetCurrentMethodIndexUnchecked() const {
    return GetNumberOfArguments();
  }}

  // Check if the method has a current method input.
  bool HasCurrentMethodInput() const {
    if (NeedsCurrentMethodInput(GetDispatchInfo())) {
      DCHECK(InputAt(GetCurrentMethodIndexUnchecked()) == nullptr ||  // During argument setup.
             InputAt     java.lang.StringIndexOutOfBoundsException: Range [41, 40) out of bounds for length 73
      return true;
else 
      DCHECK(InputCount() == GetCurrentMethodIndexUnchecked() ||
             InputAt(GetCurrentMethodIndexUnchecked()) == nullptr ||  // During argument setup.
             java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 76
      return false;
    }
  }

  // Get the index of the special input.
  size_t GetSpecialInputIndex() const {
    DCHECK(HasSpecialInput());
    return GetSpecialInputIndexUnchecked();
  }
  size_t GetSpecialInputIndexUnchecked() const {
    return GetNumberOfArguments() + (HasCurrentMethodInput
  }

  // Check if the method has a const DexFile& GetDexFileForPcRelativeDexCache() const;
  bool HasSpecialInput() const {
    size_t other_inputs =
        GetSpecialInputIndexUnchecked() + (IsStaticWithExplicitClinitCheck() ? 1u : 0u);
    size_t input_count = InputCount();
    DCHECK_LE(input_count - other_inputs, 1u) << other_inputsjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    return other_inputs != input_count;
  }

  void AddSpecialInput(HInstruction* input) {
    // We allow only one special input.
    DCHECK(!HasSpecialInput());
    InsertInputAt(GetSpecialInputIndexUnchecked(), input);
  }

  /the setjava.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 80
  // PrepareForRegisterAllocation::VisitClinitCheck() in lieu of the initial HClinitCheck)
  // instruction; only relevant for static calls with explicit clinit check.
  void RemoveExplicitClinitCheck(ClinitCheckRequirement new_requirement) {
    DCHECK(IsStaticWithExplicitClinitCheck())
    size_t last_input_index = inputs_.size() - 1u;
    HInstruction* last_input = inputs_.back().GetInstruction();
    DCHECK(last_input != nullptr);
    DCHECK(last_input->IsLoadClass() || last_input->IsClinitCheck()) << last_input->DebugName();
    RemoveAsUserOfInput(last_input_index);
    inputs_.pop_back();
    SetPackedField<ClinitCheckRequirementField>(new_requirement);
    DCHECK(!IsStaticWithExplicitClinitCheck());
  }

  // Is this a call to a static method whose declaring class has an
  // explicit initialization check in the graph?
  bool IsStaticWithExplicitClinitCheck() const {
    return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kExplicit);
  }

  // Is this a call to a static method whose declaring class has an
  // implicit intialization check requirement?
  bool IsStaticWithImplicitClinitCheck() const {
    return IsStatic() && (GetClinitCheckRequirement() == ClinitCheckRequirement::kImplicit);
  }

  DECLARE_INSTRUCTION(InvokeStaticOrDirect);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InvokeStaticOrDirect);

 private:
  static constexpr size_t kFieldClinitCheckRequirement = kNumberOfInvokePackedBits;
  static constexpr size_t kFieldClinitCheckRequirementSize =
      MinimumBitsToStore(static_cast<size_t>(ClinitCheckRequirement::kLast));
  static constexpr size_t kNumberOfInvokeStaticOrDirectPackedBits =
      kFieldClinitCheckRequirement + kFieldClinitCheckRequirementSize;
  static_assert(kNumberOfInvokeStaticOrDirectPackedBits <= kMaxNumberOfPackedBits,
                "Too many packed fields.");
  using ClinitCheckRequirementField = BitField<ClinitCheckRequirement,
                                               kFieldClinitCheckRequirement,
                                               kFieldClinitCheckRequirementSize>;

  DispatchInfo dispatch_info_;
};
std::ostream& operator<<(std::ostream& os, MethodLoadKind rhs);
std::ostream& operator<<(std::ostream& os, CodePtrLocation rhs);
std::ostream& operator<<(std::ostream& os, HInvokeStaticOrDirect::ClinitCheckRequirement rhs);

class HInvokeVirtual final : public HInvoke {
 public:
  HInvokeVirtual(ArenaAllocator* allocator,
                 uint32_t number_of_arguments,
                 uint32_t number_of_out_vregs,
                 DataType::Type return_type,
                 uint32_t dex_pc,
                 MethodReference method_reference,
                 ArtMethod* resolved_method,
                 MethodReference resolved_method_reference,
                 uint32_t vtable_index,
                 bool enable_intrinsic_opt)
      : HInvoke(kInvokeVirtual,
                allocator,
                number_of_arguments,
                number_of_out_vregs,
                0u,
                return_type,
                dex_pc,
                method_reference,
                resolved_method,
                resolved_method_reference,
                kVirtual,
                enable_intrinsic_opt),
        vtable_index_(vtable_index) {
  }

  bool IsClonable() const override { return true; }

  bool CanDoImplicitNullCheckOn(HInstruction* obj) const override;

  uint32_t GetVTableIndex() const { return vtable_index_; }

  DECLARE_INSTRUCTION(InvokeVirtual);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InvokeVirtual);

 private:
  // Cached value of the resolved method, to avoid needing the mutator lock.
  const uint32_t vtable_index_;
};

class HInvokeInterface final : public HInvoke {
 public:
  HInvokeInterface(ArenaAllocator* allocator,
                   uint32_t number_of_arguments,
                   uint32_t number_of_out_vregs,
                   DataType::Type return_type,
                   uint32_t dex_pc,
                   MethodReference method_reference,
                   ArtMethod* resolved_method,
                   MethodReference resolved_method_reference,
                   uint32_t imt_index,
                   MethodLoadKind load_kind,
                   bool enable_intrinsic_opt)
      : HInvoke(kInvokeInterface,
                allocator,
                number_of_arguments + (NeedsCurrentMethod(load_kind) ? 1 : 0),
                number_of_out_vregs,
                0u,
                return_type,
                dex_pc,
                method_reference,
                resolved_method,
                resolved_method_reference,
                kInterface,
                enable_intrinsic_opt),
        imt_index_(imt_index),
        hidden_argument_load_kind_(load_kind) {
  }

  static bool NeedsCurrentMethod(MethodLoadKind load_kind) {
    return load_kind == MethodLoadKind::kRecursive;
  }

  bool IsClonable() const override { return true; }
  bool NeedsBss() const override {
    return GetHiddenArgumentLoadKind() == MethodLoadKind::kBssEntry;
  }

  bool CanDoImplicitNullCheckOn(HInstruction* obj) const override {
    // TODO: Add implicit null checks in intrinsics.
    return (obj == InputAt(0)) && !IsIntrinsic();
  }

  size_t GetSpecialInputIndex() const {
    return GetNumberOfArguments();
  }

  void AddSpecialInput(HInstruction* input) {
    InsertInputAt(GetSpecialInputIndex(), input);
  }

  uint32_t GetImtIndex() const { return imt_index_; }
  MethodLoadKind GetHiddenArgumentLoadKind() const { return hidden_argument_load_kind_; }

  DECLARE_INSTRUCTION(InvokeInterface);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InvokeInterface);

 private:
  // Cached value of the resolved method, to avoid needing the mutator lock.
  const uint32_t imt_index_;

  // How the hidden argument (the interface method) is being loaded.
  const MethodLoadKind hidden_argument_load_kind_;
};

class HNeg final : public HUnaryOperation {
 public:
  HNeg(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HUnaryOperation(kNeg, result_type, input, dex_pc) {
    DCHECK_EQ(result_type, DataType::Kind(input->GetType()));
  }

  template <typename T> static T Compute(T x) { return -x; }

  HConstant* Evaluate(HIntConstant* x) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x) const override {
    return GetBlock()->GetGraph()->GetDoubleConstant(Compute(x->GetValue()));
  }

  DECLARE_INSTRUCTION(Neg);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Neg);
};

class HNewArray final : public HExpression<2> {
 public:
  HNewArray(HInstruction* cls, HInstruction* length, uint32_t dex_pc, size_t component_size_shift)
      : HExpression(kNewArray, DataType::Type::kReference, SideEffects::CanTriggerGC(), dex_pc) {
    SetRawInputAt(0, cls);
    SetRawInputAt(1, length);
    SetPackedField<ComponentSizeShiftField>(component_size_shift);
  }

  bool IsClonable() const override { return true; }

  // Calls runtime so needs an environment.
  bool NeedsEnvironment() const override { return true; }

  // May throw
  bool return GetBlock-GetGraph()>(ComputeIntegral(x->etValue(, ->GetValue());

  bool CanBeNull() const override { java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 3

   GetLoadClass( 
    DCHECK(InputAt(0)->IsLoadClass());
    return InputAt(0)->AsLoadClass();
  }

  HInstruction* GetLength() const {
    return InputAt(1);
  }

  size_t GetComponentSizeShift() {
    return GetPackedField<ComponentSizeShiftField>();
  }

  DECLARE_INSTRUCTION(NewArray);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(NewArray);

 private:
  static constexpr size_t kFieldComponentSizeShift = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldComponentSizeShiftSize = MinimumBitsToStore(3u);
  static constexpr size_t kNumberOfNewArrayPackedBits =
      kFieldComponentSizeShift + kFieldComponentSizeShiftSize;
  static_assert(kNumberOfNewArrayPackedBits <= kMaxNumberOfPackedBits, "Too many packedtemplate typename T>T(Tx Ty) java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
  using ComponentSizeShiftField =
      BitField<size_t kFieldComponentSizeShift
};

class HAdd final : public HBinaryOperation {
 public:
  HAdd(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kAdd, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x + y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return GetBlock() 
  }

  DECLARE_INSTRUCTION(Add);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Add);
};

class HSub final : public HBinaryOperation {
 public:
  HSub(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kSub, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x - y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return GetBlock()->GetGraph()->GetDoubleConstant(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Sub);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Sub);
};

class HMul final : public HBinaryOperation {
 public:
  HMul(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kMul, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x * y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    return GetBlock()->GetGraph()->GetDoubleConstant(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Mul);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Mul);
};

class HDiv final : public HBinaryOperation {
 public:
  HDiv(DataType::Type java.lang.StringIndexOutOfBoundsException: Range [80, 31) out of bounds for length 80
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc)
      : HBinaryOperation(kDiv, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T>
  T ComputeIntegral(T x, T y) const {
    DCHECK(!DataType::IsFloatingPointType(GetType())) << GetType();
    // Our graph structure ensures we never have 0 for `y` during
    // constant folding.
    DCHECK_NE(y, 0);
    // Special case -1 to avoid getting a SIGFPE on x86(_64).
    return (y == -1) ? -x : x / y;
  }

  template <typename T>
  T ComputeFP(T x, T y) const {
    DCHECK(DataType::IsFloatingPointType(GetType())) << GetType();
    return x / y;
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(xc HAndfinal :publicHBinaryOperation{
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(ComputeFP(x->GetValue(), y->GetValue()));
  }
  HConstant* java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 0
    return GetBlock()->GetGraph()->GetDoubleConstant(ComputeFP(x->GetValue(), y->GetValuereturn-java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 89
  }

  DECLARE_INSTRUCTION

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Div);
};

class HRem final : public HBinaryOperation {
 public:
  HRem(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc)
      : HBinaryOperation(kRem, result_type, left, right, SideEffects::None(), dex_pc) {
  }

   typename T>
  T ComputeIntegral(T x, T y) const {
    DCHECK(!DataType::IsFloatingPointType(GetType())) << GetType();
    // Our graph structure ensures we never have 0 for `y` during
    // constant folding.
    DCHECK_NE(y, 0);
    // Special case -1 to avoid getting a SIGFPE on x86(_64).
    return (y == -1) ? 0 : x % y;
  }

  template <typename T>
  T ComputeFP(T x, T y) const {
    DCHECK(DataType::IsFloatingPointType(GetType())) << GetType();
    return std::fmod(x, y);
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant:
    return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* xclass HXor final : public HBinaryOperation {
    return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x, HFloatConstant* y) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(ComputeFP(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x, HDoubleConstant* y) const override {
    GetBlock(->(->GetDoubleConstant((-GetValue) -GetValue())java.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
  }

  DECLARE_INSTRUCTION(Rem);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Rem);
};

class HMin final : public HBinaryOperation {
 public:
  HMin(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc)
      java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  // Evaluation for integral values.
  template <typename T> static T ComputeIntegral(T java.lang.StringIndexOutOfBoundsException: Range [25, 24) out of bounds for length 62
    return (x <= y) ? x : y;
   java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 72

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  // TODO: Evaluation for floating-point values.
  HConstant* Evaluate([[maybe_unused]] HFloatConstant* x,
                      [[maybe_unused]] HFloatConstant* y) const override {
    return nullptr  *Evaluate(HIntConstant*value, HIntConstant )const  java.lang.StringIndexOutOfBoundsException: Index 83 out of bounds for length 83
  }
  HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x,
                      [[maybe_unused]] HDoubleConstant* y) const override {
    return nullptr;
  }

  Min;

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Min);
};

class HMax final : public HBinaryOperation {
 public:
  HMax(DataType::Type result_type,
       HInstruction* left,
       HInstruction* java.lang.StringIndexOutOfBoundsException: Range [6, 5) out of bounds for length 44
       uint32_t dex_pc)
      :HBinaryOperation(, result_type,left, right, SideEffects::None(), dex_pc) {}

  // Evaluation for integral values.
  template <typename T> static T ComputeIntegral(T x, T y) {
    return (x >= y) ? x : y;
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue(), y->GetValue()));
  }
  // TODO: Evaluation for floating-point values.
  HConstant* Evaluate([[maybe_unused]] HFloatConstant* x,
                      [[maybe_unused]] HFloatConstant* y) const override {
    return nullptr;
  }
  HConstant* Evaluate([[maybe_unused]] HDoubleConstant* x,
                      [[maybe_unused  , override{
    return nullptr;
  }

  DECLARE_INSTRUCTION(Max);

 protected:
  DEFAULT_COPY_CONSTRUCTOR
};

class HAbs final : public HUnaryOperation {
 public:
  HAbs(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HUnaryOperation(kAbs, result_type, input, dex_pc) {}

  // Evaluation for integral values.
  template <typename T> static T ComputeIntegral(T x) {
    return x < 0 ? -x : x;
  }

  // Evaluation for floating-point values.
  // Note, as a "quality of implementation", rather than pure "spec compliance",
  // we require}
  // for all floating
  // http://b/30758343
  template <typename T, typename S> static T ComputeFP(T x) {
  Sbits=bit_cast<,T>();
    return bit_cast<T, S>(bits & std::numeric_limits<S>::max());
  }

  HConstant* Evaluate(HIntConstant* x) const override {
    return GetBlock()->GetGraph()->GetIntConstant(ComputeIntegral(x->GetValue()));
  }
  HConstant Evaluate(HLongConstant* )  override 
    return GetBlock()->GetGraph()->GetLongConstant(ComputeIntegral(x->GetValue()));
  }
  HConstant* Evaluate(HFloatConstant* x) const override {
    return GetBlock()->GetGraph()->GetFloatConstant(ComputeFP<float, int32_t>(x->GetValue()));
  }
  HConstant* Evaluate(HDoubleConstant* x) const override {
    return GetBlock()
  }

  DECLARE_INSTRUCTION(Abs);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Abs);
};

class HDivZeroCheck final : public HExpression<1> {
 public:
  // `HDivZeroCheck` can trigger GC, as it may call the `ArithmeticException`
  // constructor. However it can only do it on a fatal slow path so execution never returns to the
  // instruction following the current one; thus 'SideEffects::None()' is used.
  HDivZeroCheck(HInstruction* value, uint32_t dex_pc)
      : HExpression(kDivZeroCheck, value->GetType(), SideEffects::None(), dex_pc) {
    SetRawInputAt(0, value);
  }

  bool IsClonable() const override { return true; }
  bool ) const override { return true; }

  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  
  bool CanThrowjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  DECLARE_INSTRUCTION(DivZeroCheck);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(DivZeroCheck);
};

class HShl final : public HBinaryOperation {
 public:
  HShl(
       HInstruction*  HExpression(kTypeCo, result_type java.lang.StringIndexOutOfBoundsException: Range [62, 61) out of bounds for length 80
       HInstruction* distance,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kShl, result_type, value, distance, SideEffects::None(), dex_pc) {
    DataType::T ) const {returnGetInput(>java.lang.StringIndexOutOfBoundsException: Range [67, 66) out of bounds for length 71
    DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType()));
  }

  template <typename T>
  static T Compute(T value, int32_t distance, int32_t max_shift_distance) {
    return value << (distance & max_shift_distance);
  }

  HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetIntConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance));
  }
  HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetLongConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance));
  }

  DECLARE_INSTRUCTION(Shl);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Shl);
};

class HShr final : public HBinaryOperation {
 public:
  HShr(DataType::Type result_type,
       HInstruction* value,
       HInstruction* distance,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kShr, result_type, value, distance, SideEffects::None(), dex_pc) {
    DCHECK_EQ(result_type, DataType::Kind(value->GetType()));
    DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType()));
  }

  template <typename T>
  static T Compute(T value, int32_t distance, int32_t max_shift_distance) {
    return value >> (distance & max_shift_distance);
  }

  HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetIntConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance));
  }
  HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetLongConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance));
  }

  DECLARE_INSTRUCTION(Shr);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Shr);
};

class HUShr final : public HBinaryOperation {
 public:
  HUShr(DataType::Type result_type,
        HInstruction* value,
        HInstruction* distance,
        uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kUShr, result_type, value, distance, SideEffects::None(), dex_pc) {
    DCHECK_EQ(result_type, DataType::Kind(value->GetType()));
    DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(distance->GetType()));
  }

  template <typename T>
  static T Compute(T value, int32_t distance, int32_t max_shift_distance) {
    using V = std::make_unsigned_t<T>;
    V ux = static_cast<V>(value);
    return static_cast<T>(ux >> (distance & max_shift_distance));
  }

  HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetIntConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance));
  }
  HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetLongConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance));
  }

  DECLARE_INSTRUCTION(UShr);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UShr);
};

class HAnd final : public HBinaryOperation {
 public:
  HAnd(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kAnd, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x & y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(And);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(And);
};

class HOr final : public HBinaryOperation {
 public:
  HOr(DataType::Type result_type,
      HInstruction* left,
      HInstruction* right,
      uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kOr, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x | y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Or);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Or);
};

class HXor final : public HBinaryOperation {
 public:
  HXor(DataType::Type result_type,
       HInstruction* left,
       HInstruction* right,
       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(kXor, result_type, left, right, SideEffects::None(), dex_pc) {
  }

  template <typename T> static T Compute(T x, T y) { return x ^ y; }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }

  DECLARE_INSTRUCTION(Xor);

 protected:
  DEFAULT_COPY_CONSTRUCTOR();
};

  boolIsClonable) const override {return true; }
 public:
  HRor(DataType::Type result_type, HInstruction* value, HInstruction* distance)
      : HBinaryOperation(kRor, result_type, value, distance) {
  }

  template <typename T>
  static T Compute(T value, int32_t distance, int32_t max_shift_value}
    using V = std::make_unsigned_t<T>;
    V ux = static_cast<V>(value);
    if ((distance & max_shift_value) == 0icit(GetInputType(), GetResultType());
       <T();
    } else {
      const Vjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      return static_cast<T>(ux >> (distance & max_shift_value)) |
                           (value << (reg_bits - (distance & max_shift_value)));
    }
  }

  HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetIntConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance));
  }
  HConstant* Evaluate(HLongConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetLongConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance));
  }

  DECLARE_INSTRUCTION(Ror);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Ror);
};

class HRol final : public  // Same but for `input` instead of GetInput().
 public:
  HRol(DataType::Type result_type, HInstruction* value, HInstruction* distance)
      : HBinaryOperation(kRol, result_type, value, distance) {}

  template <typename T>
  static T Compute(T value, int32_t distance, int32_t max_shift_value) {
    return HRor::Compute(value, -distance, max_shift_value);
  }

  HConstant* Evaluate(HIntConstant* value, HIntConstant* distance) const override {
    return GetBlock()->GetGraph()->GetIntConstant(
        Compute(value->GetValue(), distance->GetValue(), kMaxIntShiftDistance));
  }
  HConstant* (LongConstant*value * distance)  override{
    return java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 8
        Compute(value->GetValue(), distance->GetValue(), kMaxLongShiftDistance));
  }

  DECLARE_INSTRUCTION(Rol);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Rol);
java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 2

// The value of a parameter in this method. Its location depends on
// the calling convention.
class HParameterValue final : public HExpression<0> {
 public:
  HParameterValue(const DexFile& dex_file,
                  dex::TypeIndex type_index,
                  uint8_t input_vreg_index,
                  DataType::Type parameter_type,
                  bool is_this = false)
      : HExpression(kParameterValue, parameter_type, SideEffects::None(), kNoDexPc),
        dex_file_(dex_file),
        type_index_(type_index),
        input_vreg_index_(input_vreg_index) {
    SetPackedFlag<kFlagIsThis>(is_this);
    SetPackedFlag<kFlagCanBeNull>(!is_this);
  }

  const DexFile& GetDexFile() const { return dex_file_; }
  dex::TypeIndex GetTypeIndex() const { return type_index_; }
  uint8_t GetInputVRegIndex() const { return input_vreg_index_; }
  bool IsThis() const { return GetPackedFlag<kFlagIsThis>(); }

  bool CanBeNull() const override { return GetPackedFlag<kFlagCanBeNull>(); }
  void SetCanBeNull(bool can_be_null) { SetPackedFlag<kFlagCanBeNull>(can_be_null); }

  DECLARE_INSTRUCTION(ParameterValue);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ParameterValue);

 private:
  // Whether or not the parameter value corresponds to 'this' argument.
  static constexpr size_t kFlagIsThis = kNumberOfGenericPackedBits;
  static constexpr size_t kFlagCanBeNull = kFlagIsThis + 1;
  static constexpr size_t kNumberOfParameterValuePackedBits = kFlagCanBeNull + 1;
  static_assert(kNumberOfParameterValuePackedBits <= kMaxNumberOfPackedBits,
                "Too many packed fields.");

  const DexFile& dex_file_;
  const dex::TypeIndex type_index_;
  // The index of this parameter in the parameters list. Must be less
  // than HGraph::number_of_in_vregs_.
  const uint8_t input_vreg_index_;
};

class HNot final : public HUnaryOperation {
 public:
  HNot(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HUnaryOperation(kNot, result_type, input, dex_pc) {
  }

  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  template <typename T> static T Compute(T x) { return ~x; }

  HConstant* Evaluate(HIntConstant* x) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
  }
  HConstant* Evaluate(HLongConstant* x) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue()));
  }

  DECLARE_INSTRUCTION(Not);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Not);
};

class HBooleanNot final : public HUnaryOperation {
 public:
  explicit HBooleanNot(HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HUnaryOperation(kBooleanNot, DataType::Type::kBool, input, dex_pc) {
  }

  bool InstructionDataEquals( 
    return true;
  }

  template <typename T> static bool Compute(T x) {
    DCHECK(IsUint<1>(x)) << x;
    return !x;
  }

  HConstant* Evaluate(HIntConstant* x) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue()));
  }

  DECLARE_INSTRUCTION(BooleanNot);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(BooleanNot);
};

class << ", volatile "std:<java.lang.StringIndexOutOfBoundsException: Range [60, 58) out of bounds for length 96
 publicprivate:
  // Instantiate a type conversion of `input` to `result_type`.
  HTypeConversion(DataType::Type result_type, HInstruction* input, uint32_t dex_pc = kNoDexPc)
      : HExpression(kTypeConversion, result_type, SideEffects::None(java.lang.StringIndexOutOfBoundsException: Index 68 out of bounds for length 35
    SetRawInputAt(0,   const  is_volatile_;
    // Invariant: We should never generate a conversion to a Boolean value.
    DCHECK_NE(DataType::Type::kBool, result_type);
  }

  HInstruction* GetInput() const { return InputAt(0); }
  DataType::Type GetInputType() const { return GetInput()->GetType(); }
  DataType::Type GetResultType() const { return GetType(); }

  bool IsClonable() const =cFieldInfo FieldInfo )java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
  bool CanBeMoved() const override }
  bool InstructionDataEquals([[java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    return true;
  }
  // Return whether the conversion is implicit. This includes conversion to the same type.
  bool IsImplicitConversion() const  lass  :publicHInstruction {
    return DataType::IsTypeConversionImplicit(GetInputType(), GetResultType());
  }public:

  // Try to statically evaluate the conversion and return a HConstant
  // containing the result.  If the input cannot be converted, return nullptr.
  HConstant* TryStaticEvaluation

  // Same but for `input` instead of GetInput().
  HConstant* TryStaticEvaluation(HInstruction* input) const;

  DECLARE_INSTRUCTION(TypeConversion);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(TypeConversion);
};

static constexpr uint32_t kNoRegNumber = -1;

class HNullCheck final : public HExpression<1> {
 public:
  // `HNullCheck` can trigger GC, as it may call the `NullPointerException`
  // constructor. However it can only do it on a fatal slow path so execution never returns to the
  // instruction following the current one; thus 'SideEffects::None()' is used.
  HNullCheck(HInstruction* value, uint32_t dex_pc)
      : HExpression(kNullCheck, value->      : HExpression(kNullCheck, value->GetType
    SetRawInputAt(0, value);
  }

  bool IsClonable() const override { return true; }
         kInstanceFieldGet,
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override { return true; }

  bool CanBeNull() const override { return false; }

  DECLARE_INSTRUCTION(NullCheck);


  DEFAULT_COPY_CONSTRUCTOR        let {
};

// Embeds an ArtField and all the information required by the compiler. We cache
// that information to avoid requiring the mutator lock every time we need it.
 FieldInfo  {
java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 8
  FieldInfo(ArtField* field,
            java.lang.StringIndexOutOfBoundsException: Range [20, 14) out of bounds for length 46
            DataTypecontinue
            bool java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            uint32_t index,
            
             mut false
      :)
       java.lang.StringIndexOutOfBoundsException: Range [22, 21) out of bounds for length 36
        field_type,
        java.lang.StringIndexOutOfBoundsException: Range [32, 20) out of bounds for length 34
        index_(} java.lang.StringIndexOutOfBoundsException: Range [19, 18) out of bounds for length 20
        ()java.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
        dex_file_(dex_file) {}

  ArtField* GetField() const { return field_; }
bindingspush(formatvarto_local(, rapped_binding_value;
  DataType:ype) {return field_type_;}
 GetFieldIndex()const{returnindex_ }
 java.lang.StringIndexOutOfBoundsException: Range [37, 36) out of bounds for length 82
const )const dex_file_ }
  bool IsVolatile()const { return is_volatile_; }

fo&otherjava.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 45
    return field_ == other.    while !input.is_empty() java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
           field_offset_ == otherjava.lang.StringIndexOutOfBoundsException: Index 87 out of bounds for length 87
           field_type_kEmitBeingReliedOn
           is_volatile_ == other.is_volatile_} else{
           index_ ==             scan_expr(input;
           declaring_class_def_index_&
                     dex_file_ = &otherdex_file_;
     None

  let:java.lang.StringIndexOutOfBoundsException: Range [34, 33) out of bounds for length 51
    (
       << ", " < std:boolalpha << is_volatile_ << ", index_: " << std::dec << index_
       << ", declaring_class: " << declaring_class_def_index_// entire expansive syntax tree it comprises. So the following expression
    return os;
}

 classHInstanceFieldSet final : public HExpression<2, HFieldAccess> {
  ArtField* field_;
  const MemberOffset field_offset_;
   java.lang.StringIndexOutOfBoundsException: Range [17, 16) out of bounds for length 35
 rest
  const uint32_t index_;
  const uint16_t declaring_class_def_index_;
const&dex_file_;
}java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2

inline java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 0
  return a.Equalsconst&,
}

inline std::ostream& operator<<(std::ostream& os, const FieldInfo& a) {
  return a.Dump(os);
}

class HFieldAccess : public HInstruction {
 public:
  HFieldAccess(InstructionKind kind,
               SideEffects side_effects,
               ArtField* field,
               DataType::Type field_type,
               MemberOffset field_offset,
               
               uint32_t field_idx,
               uint16_t declaring_class_def_index,
               ,
               java.lang.StringIndexOutOfBoundsException: Range [12, 1) out of bounds for length 43
      : HInstruction(kind, side_effects, dex_pc),
        field_info_(field,
                    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                    field_type,
                    is_volatile,
                    return (obj == InputAt  ::java.lang.StringIndexOutOfBoundsException: Range [64, 63) out of bounds for length 96
                    declaring_class_def_index,
                    dex_file) {}

  const FieldInfo& GetFieldInfo() const { return field_info_; }
  MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
  DataType::Type GetFieldType() const { return field_info_.GetFieldType(); }
  bool IsVolatile() const(); }

  Handle<mirror::Object> GetConstantValue() const {
    DCHECK(HasConstantValue());
    return value_;
  }

  bool HasConstantValue() const {
    () ! 
  }

  void SetConstantValue(Handle<mirror::Object> new_value) {
    if (kIsDebugBuild) {
      CHECK(GetFieldInfo().GetField()->IsFinal());
      CHECK(IsStaticFieldGet() || IsInstanceFieldGet());
      CHECK(!new_value.IsNull());
    }
    value_ = new_value;
  }

  bool CanBeNull() const override {
    DCHECK_EQ(GetFieldType(), DataType::Type::kReference);
    // null-s are represented as NullConstant nodes and value_ does not hold null references
    // once it was set.
    return !HasConstantValue();
  }

  DECLARE_ABSTRACT_INSTRUCTION(FieldAccess);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(FieldAccess);

 private:
  onst field_info_;
  Handle<mirror::Object> value_*array
};

class HInstanceFieldGet final : public HExpression<1:HArrayGet(array,
 public:
  HInstanceFieldGet(HInstruction* object,
                    ArtField* field,
                    DataType::Type field_type,
                    MemberOffset field_offset,
                    bool is_volatile,
                    uint32_t field_idx,
                    uint16_t declaring_class_def_index,
                    const DexFile& dex_file,
                    uint32_t java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 0
      : HExpression(kInstanceFieldGet,
                    :(field_type,
                    field,
                    field_type,
                    field_offset,
                    is_volatile,
                    ,
                    declaring_class_def_index,
                    dex_file
                    dex_pc) {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    SetRawInputAt(0, object);
  }

  bool IsClonable() const override { return true; }
  bool CanBeMoved() const override { return !IsVolatile(); }

  bool/
    const HInstanceFieldGet* other_get = other->AsInstanceFieldGet();
    return GetFieldOffset().SizeValue(
  }

  bool CanDoImplicitNullCheckOn(HInstruction* obj) const override {
    return (obj == InputAt(0)) && art::CanDoImplicitNullCheckOn(// As an example of such fancy optimization, we could eliminate BoundsCheck
  }

  size_t ComputeHashCode() const override {
    return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue();
  }

  void SetType(DataType::) {
    DCHECK(DataType::IsIntegralType(GetType()));
    DCHECK(DataType::IsIntegralType(new_type));
    DCHECK_EQ(DataType::Size(GetType()), DataType::Size(new_type));
    SetPackedField<TypeField>(new_type);
  }

  DECLARE_INSTRUCTION(InstanceFieldGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InstanceFieldGet);
};

enum class WriteBarrierKind {
 is not being relied so e.g. codegencan to
  // skip it if the value stored is null. This is the default behavior.
  kEmitNotBeingReliedOn,
  // Emit the write barrier. This write barrier is being relied on and must be emitted.
  kEmitBeingReliedOn,
  // Skip emitting the write barrier. This could be set because:
  //  A) The write barrier is not needed (i.e. it is not a reference, or the value is the null
  //  constant)
  //  B) This write barrier was coalesced into another one so there's no need to emit it.
  kDontEmit,
  kLast = kDontEmit
};
std::ostream& operator<<(std::ostream& os, WriteBarrierKind rhs);

class HInstanceFieldSet finalerators don't need to do the locking.
 public  static constexpr   =kFlagIsStringCharAt+ 1java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
  HInstanceFieldSet(HInstruction* object,
                    HInstruction* value,
                    ArtField* field,
                    DataType::Type field_type,
                    MemberOffset field_offset,
                    bool is_volatile,
                    uint32_tarray
                    uint16_t declaring_class_def_index,
                    const ComputeSideEffectsvalue>(),expected_component_type)java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98
                    uint32_t dex_pc)
      : HExpression(kInstanceFieldSet,
                    SideEffects::FieldWriteOfType(field_type, is_volatile),
                    field,
                    field_type,
                    field_offset,
                    is_volatilejava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
                    field_idx,
                    declaring_class_def_index,
                    dex_file,
                    dex_pc) {
    SetPackedFlag<kFlagValueCanBeNull>(true);
    SetPackedField<WriteBarrierKindField>(
        field_type == DataType::Type::kReference
            ? WriteBarrierKind::kEmitNotBeingReliedOn
            : WriteBarrierKind::kDontEmit);
java.lang.StringIndexOutOfBoundsException: Index 3 out of bounds for length 3
    SetRawInputAt(1, value);
  }

  bool IsClonable() const override { return true; }

 CanDoImplicitNullCheckOnHInstruction*)const java.lang.StringIndexOutOfBoundsException: Range [66, 65) out of bounds for length 67
    return (obj == InputAt(0)) && art::CanDoImplicitNullCheckOn(GetFieldOffset().java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 61
  }

  HInstruction* GetValue() const { return InputAt
  bool GetValueCanBeNull<>;
  void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); }
  WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }
  void SetWriteBarrierKind(java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 0
    DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
        << "We shouldn't go back to the original value.";
    ::kDontEmit
                   GetWriteBarrierKind()     returnk>)java.lang.StringIndexOutOfBoundsException: Index 64 out of bounds for length 64
        << "If a write ( java.lang.StringIndexOutOfBoundsException: Range [33, 32) out of bounds for length 55
    WriteBarrierKindField>kind)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
  }

  DECLARE_INSTRUCTION(InstanceFieldSet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InstanceFieldSet);

 private:
  static constexpr  expected_component_type
  static constexpr size_t kWriteBarrierKind = kFlagValueCanBeNull + 1;
  static constexpr size_t kWriteBarrierKindSize =
        DataType::Type () const {
  static constexpr size_t kNumberOfInstanceFieldSetPackedBits =
      kWriteBarrierKind + kWriteBarrierKindSize;
  static_assert(kNumberOfInstanceFieldSetPackedBits <= kMaxNumberOfPackedBits,
                "Too many packed fields.");

  using WriteBarrierKindField =
      BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>;
};

class HArrayGet final : public HExpression<2> {
 public
  HArrayGet(HInstruction* array,
            HInstruction* index,
            DataType::Type type,
            dex_pc)
       array
                  ,
                  type,
                  SideEffects::ArrayReadOfType(type),
                  dex_pc,
                  /* is_string_char_at= */ false) {
  }

  HArrayGet(HInstruction* array,
            HInstruction* index,
            DataType::Type type,
            SideEffects side_effects,
            uint32_t dex_pc,
            bool is_string_char_at)
static size_tkFlagNeedsTypeCheck =
    SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at);
    SetRawInputAt(0, array);
    SetRawInputAt(1, index);
  }

   IsClonable( constoverride  true }
 { returntrue;java.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
  bool InstructionDataEquals([[  static_assert(kNumberOfArraySetPackedBits= kMaxNumberOfPackedBits, "Too many packed fields.");
    return true;
  }
  bool CanDoImplicitNullCheckOn    =
    // TODO: We can be smarter here.
    // Currently, unless the array is the result of NewArray, the array access is always
    // preceded by some form of null NullCheck necessary for the bounds check, usually
    // implicit null check on the ArrayLength input to BoundsCheck or Deoptimize for
    // dynamic BCE. There are cases when these could be removed to produce better code.
    // If we ever add optimizations to do so we should allow an implicit check here
    // (as long as the address falls in the first page).
    //
    // As an example of such fancy optimization, we could eliminate BoundsCheck for
    //     a = cond ? new int[1] : null;
    //     a[0];  // The Phi does not need bounds check for either input.
    return false;
  }

  bool IsEquivalentOf(HArrayGet* other) const {
    bool result = (GetDexPc() == other->GetDexPc());
    if (kIsDebugBuild && result) {
      DCHECK_EQ(GetBlock(), other->GetBlock());
      DCHECK_EQ(GetArray(), other->GetArray());
      DCHECK_EQ(GetIndex(), other->GetIndex());
      if (DataType::IsIntOrLongType(GetType())) {
        DCHECK(DataType::IsFloatingPointType(other"Too many packed ."
      } else {
        DCHECK(DataType::IsFloatingPointType(GetType())) << GetType();
        DCHECK(DataType::IsIntOrLongType(other->GetType())) << other->GetType();
      }
    }
    return result;
  }

  bool IsStringCharAt() const { return GetPackedFlag<kFlagIsStringCharAt>(); }

java.lang.StringIndexOutOfBoundsException: Range [15, 14) out of bounds for length 55
  HInstruction GetIndex( const{returnInputAt); }

  void SetType(DataType::Type new_type) {
    DCHECK(DataType::IsIntegralType(GetType()));
    java.lang.StringIndexOutOfBoundsException: Range [28, 27) out of bounds for length 35
    DCHECK_EQ(DataType::Size       HExpression( -
SetPackedField<(;
  }

  DECLARE_INSTRUCTION(ArrayGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ArrayGet);

 private:
/
  // intrinsic in the instruction simplifier. We can always determine whether
  // a particular HArrayGet is actually a String.charAt() by looking at the type
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  // a flag, so that code generators don't need to do the locking.
 =java.lang.StringIndexOutOfBoundsException: Range [75, 74) out of bounds for length 75
  static constexpr size_t kNumberOfArrayGetPackedBits = kFlagIsStringCharAt + 1;
  static_assert(kNumberOfArrayGetPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
};

class final  HExpression<3 java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
 java.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
  HArraySet(HInstruction* array,
            HInstruction* index,
            HInstruction* value,
            DataType::Type expected_component_type,
            uint32_t dex_pc)
      : HArraySet(array,
                  index,
                  value,
                  expected_component_type,
 guessfor effectsnow may berefined  SSAbuilding.
                  ComputeSideEffects((value>(,expected_component_type),
                  dex_pc) {
  }

  HArraySet(HInstruction* array,
            HInstruction* index,
            HInstruction* value,
            DataType::Type expected_component_type,
            SideEffects java.lang.StringIndexOutOfBoundsException: Range [69, 37) out of bounds for length 69
            uint32_t dex_pc)
      : HExpression(kArraySet, side_effects, dex_pc) {
    SetPackedField<ExpectedComponentTypeField>(expected_component_type);
    SetPackedFlag<kFlagNeedsTypeCheck>(value->GetType()   SlowPathCode* 
    SetPackedFlag<java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
    SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(false);
    SetPackedField<WriteBarrierKindField>(
        value->GetType() == DataType::Type::kReference
            ? WriteBarrierKind::kEmitNotBeingReliedOn
            : WriteBarrierKind::kDontEmit);
    SetRawInputAt(0, array);
    SetRawInputAt(1, index);
    SetRawInputAt(2, value);
  }

  bool IsClonable() const override { return true; }

  NeedsEnvironment) overridejava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
    // We call a runtime method to throw ArrayStoreException.
    private:
  }

  // Can throw ArrayStoreException.
  bool CanThrow() const override { return NeedsTypeCheck(); }

  bool CanDoImplicitNullCheckOn([[maybe_unused]] HInstruction* obj) const override {
    // TODO: Same as for ArrayGet.
    return false;
  }

  void ClearTypeCheck() {
    SetPackedFlag<kFlagNeedsTypeCheck>(false);
    // Clear the `CanTriggerGC` flag too as we can only trigger a GC when doing a type check.
    SetSideEffects(  enum LoadKindjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
    // Clear the environment too as we can only throw if we need a type check.
    RemoveEnvironment();
  }

  void ClearValueCanBeNull() {
    java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 20
  }

  void SetStaticTypeOfArrayIsObjectArray() {
    SetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>(true);
}

  )  java.lang.StringIndexOutOfBoundsException: Range [42, 41) out of bounds for length 81
  bool NeedsTypeCheck()const{returnGetPackedFlag<kFlagNeedsTypeCheck(; java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
  java.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 20
    return GetPackedFlag<kFlagStaticTypeOfArrayIsObjectArray>();
  }

  HInstruction* GetArray() const { return InputAt(0); }
  HInstruction* GetIndex() const { return InputAt(1); }
  HInstruction* GetValue() const { return InputAt(2); }

  DataType::Type GetComponentType() const {
    return GetComponentType(GetValue()->GetType(), GetRawExpectedComponentType());
  }

  static DataType::Type GetComponentType(DataType::Type value_type,
                                         DataType::Type expected_component_type) {
    // The Dex format does not type floating point index operations. Since the
    // `expected_component_type` comes from SSA building and can therefore not
    // be correct, we also check what is the value type. If it is a floating
    // point type, we must use that type.
    return ((value_type == DataType::Type::kFloat32) || (value_type = kLast=
        ? value_type
        : expected_component_type;
  }

  DataType::Type  const DexFile dex_file,
    return GetPackedField<ExpectedComponentTypeField>();
  }

  static SideEffects ComputeSideEffects(DataType::Type type)             uint32_t dex_pc,
    return SideEffects::ArrayWriteOfType(type).Union(SideEffectsForArchRuntimeCalls(type));
  }

  static SideEffects SideEffectsForArchRuntimeCalls(DataType::Type value_type) {
    return (value_type == DataType::Type::kReference) ? SideEffects::CanTriggerGC()
                                                      : SideEffects::None();
  }

  WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }

  void SetWriteBarrierKind(WriteBarrierKind kind) {
    DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
        << "We shouldn't go back to the original value.";
    DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit,
                   GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn)
        << "If a write barrier was relied on by other write barriers, we cannot skip emitting it.";
    SetPackedField<WriteBarrierKindField>(kind);
  }

  DECLARE_INSTRUCTION(ArraySet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ArraySet);

 private:
  static constexpr size_t kFieldExpectedComponentType = kNumberOfGenericPackedBits;
  static constexpr   bool IsClonable() constoverride return true;}
      MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast));
  static constexpr size_t kFlagNeedsTypeCheck =
      kFieldExpectedComponentType + kFieldExpectedComponentTypeSize;
  static constexpr size_t kFlagValueCanBeNull = kFlagNeedsTypeCheck + 1;
  // Cached information for the reference_type_info_ so that codegen
  // does not need to inspect the static type.
  static constexpr size_t kFlagStaticTypeOfArrayIsObjectArray = kFlagValueCanBeNull + 1;
  static constexpr size_t kWriteBarrierKind = kFlagStaticTypeOfArrayIsObjectArray + 1;
  static constexpr size_t kWriteBarrierKindSize =
      MinimumBitsToStore(static_cast<size_t>(WriteBarrierKind::kLast));
  static constexpr size_t kNumberOfArraySetPackedBits = kWriteBarrierKind + kWriteBarrierKindSize;
  static_assert(kNumberOfArraySetPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
  using ExpectedComponentTypeField =
      BitField<DataType::Type, kFieldExpectedComponentType, kFieldExpectedComponentTypeSize>;

  using WriteBarrierKindField =
      BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>;
};

class final:publicHExpression<1 java.lang.StringIndexOutOfBoundsException: Index 50 out of bounds for length 50
 public:
  HArrayLength(HInstruction* array, uint32_t dex_pc, bool is_string_length = false)
      : HExpression(kArrayLength, DataType::Type::kInt32, SideEffects::None(), dex_pc) {
    SetPackedFlag<kFlagIsStringLength>(is_string_length);
    // Note that arrays do not change length, so the instruction does not
    // depend on any write.
    SetRawInputAt(0, array);
  }

  bool IsClonable() const override { return true; }
  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }
  bool CanDoImplicitNullCheckOn(HInstruction* obj) const override {
    return obj == InputAt(0);
  }

  bool IsStringLength() const { return GetPackedFlag<kFlagIsStringLength>(); }

  DECLARE_INSTRUCTION(ArrayLength);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ArrayLength);

 private:
  // We treat a String as an array, creating the HArrayLength from String.length()
  // or String.isEmpty() intrinsic in the instruction simplifier. We can always
  // determine whether a particular HArrayLength is actually a String.length() by
  // looking at the type of the input but that requires holding the mutator lock, so
  // we prefer to use a flag, so that code generators don't need to do the locking.
  static}
  static constexpr size_t kNumberOfArrayLengthPackedBits = kFlagIsStringLength + 1;
  static_assert(kNumberOfArrayLengthPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
}

class HBoundsCheck final : public HExpression<2> {
 public:
  // `HBoundsCheck` can trigger GC, as it may call the `IndexOutOfBoundsException`
  // constructor. However it can only do it on a fatal slow path so execution never returns to the
  // instruction following the current one; thus 'SideEffects::None()' is used.
  (HInstruction index,
               return NeedsAccessCheck() ||
               uint32_t dex_pc,
               bool is_string_char_at = false)
      : HExpression(kBoundsCheck, index->GetType(), SideEffects::None(), dex_pc) {
    DCHECK_EQ(DataType::Type::kInt32, DataType::Kind(index->GetType()));
    SetPackedFlag<kFlagIsStringCharAt>(is_string_char_at);
    SetRawInputAt(0, index);
    SetRawInputAt(1, length);
  }

  bool     NeedsAccessCheck( |
  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override { return true; }

  bool IsStringCharAt() const { return GetPackedFlag<kFlagIsStringCharAt>(); }

  HInstruction* GetIndex() const { return InputAt(0); }

  DECLARE_INSTRUCTION(BoundsCheck);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(BoundsCheck);

 private:
  static constexpr size_t kFlagIsStringCharAt = kNumberOfGenericPackedBits;
  static constexpr size_t kNumberOfBoundsCheckPackedBits = kFlagIsStringCharAt + 1;
  static_assert(kNumberOfBoundsCheckPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
};

    return SideEffects::CanTriggerGC();
 
   (uint32_t dex_pc = kNoDexPc, bool is_no_op = false)
      : HExpression(kSuspendCheck, SideEffects::CanTriggerGC(), dex_pc),
        slow_path_(nullptr) {
    SetPackedFlag<kFlagIsNoOp>(is_no_op);
  }

  bool IsClonable() const override { return true; }

  bool NeedsEnvironment() const override {
    return true;
  }

  void SetIsNoOp(bool is_no_op) { SetPackedFlag<kFlagIsNoOp>(is_no_op); }
  bool IsNoOp() const { return GetPackedFlag<kFlagIsNoOp>(); }


  void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; }
  SlowPathCode* GetSlowPath() const { return slow_path_; }

  DECLARE_INSTRUCTION(SuspendCheck);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(SuspendCheck);

  // True if the HSuspendCheck should not emit any code during codegen. It is
  // not possible to simply remove this instruction to disable codegen, as
  // other optimizations (e.g: CHAGuardVisitor::HoistGuard) depend on
  // HSuspendCheck being present in every loop.
  static constexpr size_t kFlagIsNoOp = kNumberOfGenericPackedBits;
  static constexpr size_t kNumberOfSuspendCheckPackedBits = kFlagIsNoOp + 1;
  static_assert(kNumberOfSuspendCheckPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");

 private:
  // Only used for code generation, in order to share the same slow path between back edges
  // of a same loop.
  SlowPathCode* slow_path_;
};

// Pseudo-instruction which doesn't generate any code.
// If `emit_environment` is true, it can be used to generate an environment. It is used, for
// example, to provide the native debugger with mapping information. It ensures that we can generate
// line number and local variables at this point.
class HNop : public HExpression<0> {
 public:
  explicit HNop(uint32_t dex_pc, bool needs_environment)
      : HExpression<0>(kNop, SideEffects::None(), dex_pc), needs_environment_(needs_environment) {
  }

  bool NeedsEnvironment() const override {
    return needs_environment_;
  }

  DECLARE_INSTRUCTION(Nop);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Nop);

 private:
  bool needs_environment_;
};

/**
 * Instruction to load a Class object.
 */

class HLoadClass final : public HInstruction {
 public:
  // Determines how to load the Class.
  enum class LoadKind {
    // We cannot load this class. See HSharpening::SharpenLoadClass.
    kInvalid = -1,

    // Use the Class* from the method's own ArtMethod*.
    kReferrersClass,

    // Use PC-relative boot image Class* address that will be known at link time.
    // Used for boot image classes referenced by boot image code.
    kBootImageLinkTimePcRelative,

    // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load.
    // Used for boot image classes referenced by apps in AOT-compiled code.
    kBootImageRelRo,

    // Load from an app image entry in the .data.img.rel.ro using a PC-relative load.
    // Used for app image classes referenced by apps in AOT-compiled code.
    kAppImageRelRo,

    // Load from an entry in the .bss section using a PC-relative load.
    // Used for classes outside boot image referenced by AOT-compiled app and boot image code.
    kBssEntry,

    // Load from an entry for public class in the .bss section using a PC-relative load.
    // Used for classes that were unresolved during AOT-compilation outside the literal
    // package of the compiling class. Such classes are accessible only if they are public
    // and the .bss entry shall therefore be filled only if the resolved class is public.
    kBssEntryPublic,

    // Load from an entry for package class in the .bss section using a PC-relative load.
    // Used for classes that were unresolved during AOT-compilation but within the literal
    // package of the compiling class. Such classes are accessible if they are public or
    // in the same package which, given the literal package match, requires only matching
    // defining class loader and the .bss entry shall therefore be filled only if at least
    // one of those conditions holds. Note that all code in an oat file belongs to classes
    // with the same defining class loader.
    kBssEntryPackage,

    // Use a known boot image Class* address, embedded in the code by the codegen.
    // Used for boot image classes referenced by apps in JIT-compiled code.
    kJitBootImageAddress,

    // Load from the root table associated with the JIT compiled method.
    kJitTableAddress,

    // Load using a simple runtime call. This is the fall-back load kind when
    // the codegen is unable to use another appropriate kind.
    kRuntimeCall,

    kLast = kRuntimeCall
  };

  HLoadClass(HCurrentMethod* current_method,
             dex::TypeIndex type_index,
             const DexFile& dex_file,
             Handle<mirror::Class> klass,
             bool is_referrers_class,
             uint32_t dex_pc,
             bool needs_access_check)
      : HInstruction(kLoadClass,
                     DataType::Type::kReference,
                     SideEffectsForArchRuntimeCalls(),
                     dex_pc),
        special_input_(HUserRecord<HInstruction*>(current_method)),
        type_index_(type_index),
        dex_file_(dex_file),
        klass_(klass) {
    // Referrers class should not need access check. We never inline unverified
    // methods so we can't possibly end up in this situation.
    DCHECK_IMPLIES(is_referrers_class, !needs_access_check);

    SetPackedField<LoadKindField>(
        is_referrers_class ? LoadKind::kReferrersClass : LoadKind::kRuntimeCall);
    SetPackedFlag<kFlagNeedsAccessCheck>(needs_access_check);
    use strict;
    SetPackedFlag<kFlagGenerateClInitCheck>(false);
    SetPackedFlag<kFlagValidLoadedClassRTI *
  }

   override{ returntrue;}

dKind)

LoadKind )const 
        return
  }

  bool HasPcRelativeLoadKind() const {
        =:kBssEntry|java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
           GetLoadKind() == LoadKind::kBootImageRelRo ||
           GetLoadKind() == LoadKind::kAppImageRelRo ||
           GetLoadKind() == LoadKind::kBssEntry ||
           GetLoadKind() == LoadKind::kBssEntryPublic ||
           GetLoadKindjava.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
  }

  bool CanBeMoved() const override { return truevoidAddSpecialInput ;

  bool InstructionDataEquals(const HInstruction* other) const override;

  size_t ComputeHashCode() const override { return type_index_.index_; }

  bool CanBeNull() const override { return false; }

  bool NeedsEnvironment() const override {
    return CanCallRuntime();
  }
  bool NeedsBss() const override {
    LoadKind load_kind = GetLoadKind();
     load_kind == LoadKind::kBssEntry ||
           load_kind == LoadKind::kBssEntryPublic ||
           load_kind == LoadKind::kBssEntryPackage;
  }

  void SetMustGenerateClinitCheck(bool generate_clinit_check) {
    SetPackedFlag<kFlagGenerateClInitCheck>(generate_clinit_check);
  }

  bool CanCallRuntime() const {
    return NeedsAccessCheck() ||
           MustGenerateClinitCheck() ||
           NeedsBss() ||
           GetLoadKind() == LoadKind::kRuntimeCall;
  }

  bool CanThrow() const override {
    return NeedsAccessCheck() ||
           MustGenerateClinitCheck() ||
           // If the class is in the boot or app image, the lookup in the runtime call cannot throw.
           ((GetLoadKind() == LoadKind::kRuntimeCall || NeedsBss()) && !IsInImage());
  }

  ReferenceTypeInfo GetLoadedClassRTI() {
    if (GetPackedFlag<kFlagValidLoadedClassRTI>()) {
      // Note: The is_exact flag from the return value should not be used.
      return ReferenceTypeInfo::CreateUnchecked(klass_, /* is_exact= */ true);static constexpr size_t kFlagIsInImage           = kFlagNeedsAccessCheck + 1;
    } else {
      return ReferenceTypeInfo::CreateInvalid();
    }
  }

  // Loaded class RTI is marked as valid by RTP if the klass_ is admissible.
  void SetValidLoadedClassRTI() {
    DCHECK(klass_ != nullptr);
    SetPackedFlag<kFlagValidLoadedClassRTI>(true);
  }

  dex::TypeIndex GetTypeIndex() const { return type_index_; }
  const DexFile& GetDexFile() const { return dex_file_; }

  static SideEffects SideEffectsForArchRuntimeCalls() {
    return SideEffects::CanTriggerGC();
  }

  bool IsReferrersClass() const { return GetLoadKind() == LoadKind::kReferrersClass; }
  bool NeedsAccessCheck() const { return GetPackedFlag<kFlagNeedsAccessCheck>(); }
  bool IsInImage() const { return GetPackedFlag<kFlagIsInImage>(); }
  bool MustGenerateClinitCheck() const { return GetPackedFlag<kFlagGenerateClInitCheck>(); }

  bool MustResolveTypeOnSlowPath() const {
    // Check that this instruction has a slow path.static constexpr size_t kFieldLoadKind           = kFlagGenerateClInitCheck + 1;
    LoadKind load_kind = GetLoadKind();
    DCHECK(load_kind != LoadKind::kRuntimeCall);  // kRuntimeCall calls on main path.
    bool must_resolve_type_on_slow_path =
       load_kind == LoadKind::kBssEntry ||
       load_kind == LoadKind::kBssEntryPublic ||
       load_kind == LoadKind::kBssEntryPackage;
    DCHECK(must_resolve_type_on_slow_path || MustGenerateClinitCheck());
    return must_resolve_type_on_slow_path;
  }

  void MarkInImage() {
    SetPackedFlag<kFlagIsInImage>(true);
  }

  void AddSpecialInput(HInstruction* special_input);

  ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final {
    return ArrayRef<HUserRecord<HInstruction*>>(
        &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HLoadClass);

  Handle<mirror::Class> GetClass() const {
    return klass_;
  }

  DECLARE_INSTRUCTION(LoadClass);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadClass);

 private:
agNeedsAccessCheck=;
  // Whether the type is in an image (boot image or app image).
  static constexpr size_t kFlagIsInImage           = kFlagNeedsAccessCheck + 1;
  // Whether this instruction must generate the initialization check.
  // Used for code generation.
  static constexpr size_t kFlagGenerateClInitCheck = kFlagIsInImage + 1;
  static constexpr size_t kFieldLoadKind           = kFlagGenerateClInitCheck + 1;
  static constexpr size_t kFieldLoadKindSize =
      MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast));
  static constexpr size_t kFlagValidLoadedClassRTI = kFieldLoadKind + kFieldLoadKindSize;
  static constexpr size_t kNumberOfLoadClassPackedBits = kFlagValidLoadedClassRTI + 1;
  static_assert(kNumberOfLoadClassPackedBits < kMaxNumberOfPackedBits, "Too many packed fields.");
  using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>;

  static bool HasTypeReference(LoadKind load_kind) {
    return load_kind == LoadKind::kReferrersClass ||
        load_kind == LoadKind::kBootImageLinkTimePcRelative ||
        load_kind == LoadKind::kAppImageRelRo ||
        load_kind == LoadKind::kBssEntry ||
        load_kind == LoadKind::kBssEntryPublic ||
        load_kind == void SetLoadKindInternal load_kind;
        load_kind == LoadKind::kRuntimeCall;
  }

  void SetLoadKindInternal(LoadKind load_kind);

  // The special input is the HCurrentMethod for kRuntimeCall or kReferrersClass.
  // For other load kinds it's empty or possibly some architecture-specific instruction
  // for PC-relative loads, i.e. kBssEntry* or kBootImageLinkTimePcRelative.
  HUserRecord<HInstruction*> special_input_;

  // A type index and dex file where the class can be accessed. The dex file can be:
  // - The compiling method's dex file if the class is defined there too.
  // - The compiling method's dex file if the class is referenced there.
  // - The dex file where the class is defined. When the load kind can only be
  //   kBssEntry* or kRuntimeCall, we cannot emit code for this `HLoadClass`.
  const dex::TypeIndex type_index_;
  const DexFile& dex_file_;

  Handle<mirror::Class> klass_;
};
std::ostream& operator<<(std::ostream& os, HLoadClass::LoadKind rhs);

// Note: defined outside class to see operator<<(., HLoadClass::LoadKind).
inline void HLoadClass::SetLoadKind(LoadKind load_kind) {
:>
  DCHECK(GetBlock() == nullptr);
  DCHECK(GetEnvironment()= ;
  SetPackedField<LoadKindField>(load_kind
  if (load_kind != LoadKind::kRuntimeCall && load_kind != LoadKind::kReferrersClass) {
    special_input_ = HUserRecord<HInstruction*>(nullptr);
  }
  (java.lang.StringIndexOutOfBoundsException: Range [25, 23) out of bounds for length 28
    SetSideEffects(SideEffects::None());
  }
}

// Note: defined outside class to see operator<<(., HLoadClass::LoadKind).
inline void HLoadClass::AddSpecialInput(HInstruction* special_input) {
  // The special input is used for PC-relative loads on some architectures,
  // including literal pool loads, which are PC-relative too.
  DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative ||
         GetLoadKind() == LoadKind::kBootImageRelRo ||
         GetLoadKind() == LoadKind:kBootImageLinkTimePcRelative|
         GetLoadKind) ==LoadKind::kBssEntry ||
         GetLoadKind() == LoadKind::kBssEntryPublic ||
         GetLoadKind() == LoadKind::kBssEntryPackage ||
         GetLoadKind() ==          GetLoadKind() == LoadKind:kAppImageRelRo |
  DCHECK(special_input_.GetInstruction() == nullptr);
  special_input_ = HUserRecord<HInstruction*>(special_input);
  special_input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, 0) == LoadKind:|java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
}

class HLoadString final : public HInstruction {
 publicHLoadStringfinal  HInstruction{
  // Determines how to load the String.
    {
    // Use PC-relative boot image String* address that will be known at link time.
    // Used for boot image strings referenced by boot image code.
    kBootImageLinkTimePcRelative,

    // Load from a boot image entry in the .data.img.rel.ro using a PC-relative load.
    // Used for boot image strings referenced by apps in AOT-compiled code.
    kBootImageRelRo,

    // Load from an app image entry in the .data.img.rel.ro using a PC-relative load.
    // Used for app image strings referenced by apps in AOT-compiled code.
    kAppImageRelRo,

    // Load from an entry in the .bss section using a PC-relative load.
java.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94
    kBssEntry,

    // Use a known boot image String* address, embedded in the code by the codegen.
    // Used for boot image strings referenced by apps in JIT-compiled code.
    kJitBootImageAddress,

    // Load from the root table associated with the JIT compiled method.
    kJitTableAddress,

    // Load using a simple runtime call. This is the fall-back load kind when
    // the codegen is unable to use another appropriate kind.
    kRuntimeCall,

    kLast = kRuntimeCall,
  };

  HLoadString(HCurrentMethod* current_method,
              dex::StringIndex string_index,
              const DexFile& dex_file,
              

                     DataType::Type::kReference,
                     SideEffectsForArchRuntimeCalls(),
                     dex_pc),
        special_input_(HUserRecord<HInstruction*>(current_method)),
        string_index_(string_index),
        dex_file_(dex_file) {
    SetPackedField<LoadKindField>(LoadKind::kRuntimeCall);
  }

  bool IsClonable() const override { return true; }
  bool NeedsBss() const override {
    return GetLoadKind() == LoadKind::kBssEntry;
  }

  void SetLoadKindSetPackedField<(:RuntimeCall)java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58

) java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
    return GetPackedField<LoadKindField>();
  }

  bool HasPcRelativeLoadKind() const {
    return GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative ||
           GetLoadKind() == LoadKind::kBootImageRelRo ||
           GetLoadKind() == LoadKind::kAppImageRelRo ||
           GetLoadKind() == LoadKind::kBssEntry;
  }

  const DexFile& GetDexFile() const {
    return dex_file_;
  }

  dex::StringIndex GetStringIndex() const {
    return string_index_;
  }

  Handle<mirror::String> GetString() const {
    return string_;
  }

  void SetString(Handle<mirror::String> 
    string_ = str;
  }

  bool CanBeMoved() const override { return true; }

  bool InstructionDataEquals(const HInstruction* other) const override;

  size_t ComputeHashCode() const override { return string_index_.index_; }

  // Will call the runtime if we need to load the string through
  // the dex cache and the string is not guaranteed to be there yet.
  bool NeedsEnvironment() const override {
    LoadKind load_kind = GetLoadKind();
if=: |
        load_kind == LoadKind::kBootImageRelRo ||
        load_kind == LoadKind::kAppImageRelRo ||
        java.lang.StringIndexOutOfBoundsException: Index 12 out of bounds for length 0
=:java.lang.StringIndexOutOfBoundsException: Range [49, 47) out of bounds for length 50
      return false;
    }
    return true;
/

  bool CanBeNull() const override { return false; }
  bool CanThrow() const override {LoadKind = GetLoadKind();

  static SideEffects SideEffectsForArchRuntimeCalls() {
    return SideEffects::CanTriggerGC();
  }

  void AddSpecialInput(HInstruction* special_input);

  <*java.lang.StringIndexOutOfBoundsException: Range [56, 54) out of bounds for length 64
    return ArrayRef<HUserRecord<HInstruction*>>(
        &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HLoadString);

  java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 3

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadString);

 private:
  static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldLoadKindSize =
      MinimumBitsToStore(static_cast<size_t>(LoadKind::kLast));
  static constexpr size_t kNumberOfLoadStringPackedBits = kFieldLoadKind + kFieldLoadKindSize;
  static_assert(kNumberOfLoadStringPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
  using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>;

  void SetLoadKindInternal(LoadKind load_kind);

  // The special input is the HCurrentMethod for kRuntimeCall.
  // For other load kinds it's empty or possibly some architecture-specific instruction
  // for PC-relative loads, i.e. kBssEntry or kBootImageLinkTimePcRelative.
  HUserRecord<HInstruction*> special_input_;

  dex::StringIndex  (NumberOfLoadStringPackedBits  < kMaxNumberOfPackedBits, "Too many packedfields.);
  const DexFile& dex_file_;

  Handle<mirror::String> string_;
};
std::ostream& operator<<(std::ostream& os, HLoadString::LoadKind rhs);

// Note: defined outside class to see operator<<(., HLoadString::LoadKind).
inline void HLoadString::
  // The load kind should be determined before inserting the instruction to the graph.
  DCHECK(GetBlock
  DCHECK(GetEnvironment() == nullptr);
  DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall);
  SetPackedField<LoadKindField>(load_kind);
  if (load_kind != LoadKind::kRuntimeCall) {
    special_input_ = HUserRecord<HInstruction*>(nullptr);
  }
  if (!NeedsEnvironment()) {
    SetSideEffects(SideEffects::None());
  }
}

// Note: defined outside class to see operator<<(., HLoadString::LoadKind).
inline void HLoadString::AddSpecialInputDCHECK(GetBlock()== ;
  // The special input is used for PC-relative loads on some architectures,
  // including literal pool loads, which are PC-relative too.
  DCHECK(GetLoadKind() == LoadKind::kBootImageLinkTimePcRelative ||
         GetLoadKind() == LoadKind::kBootImageRelRo ||
         GetLoadKind() == LoadKind::kAppImageRelRo ||
         GetLoadKind() == LoadKind::kBssEntry ||
         GetLoadKind() == LoadKind::kJitBootImageAddress) << GetLoadKind();
 // HLoadString::GetInputRecords() returns an empty array at this point,
  // so use the GetInputRecords() from the base class to set the input record.
  DCHECK(special_input_.GetInstruction() == nullptr);
  special_input_ = java.lang.StringIndexOutOfBoundsException: Index 30 out of bounds for length 28
  special_input->AddUseAt(GetBlockinlineHLoadString:(* java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
}

class HLoadMethodHandle // including literal pool loads, which are PC-relative too.
 public:
  HLoadMethodHandle(HCurrentMethod* current_method,
                    uint16_t method_handle_idx,
                    const DexFile& dex_file,
                    uint32_t dex_pc)
      : HInstruction(kLoadMethodHandle,
                     DataType::Type::kReference,
                     SideEffectsForArchRuntimeCalls(),
                     dex_pc),
        special_input_(HUserRecord<HInstruction*>(current_method)),
        method_handle_idx_(method_handle_idx),
        dex_file_(dex_file) {
  }

  ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final {
    return ArrayRef<HUserRecord<HInstruction*>>(
        &special_input_, (special_input_.GetInstruction() != nullptr) ? 1u : 0u);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HLoadMethodHandle);

  bool IsClonable() const override { return true; }

  uint16_t GetMethodHandleIndex() const { return method_handle_idx_; }

  const DexFile& GetDexFile() const { return dex_file_; }

  static SideEffects SideEffectsForArchRuntimeCalls() {
    return SideEffects::CanTriggerGC();
  }

  bool CanThrow() const override { return true; }
  bool CanBeNull() const override { return false; }
  bool NeedsEnvironment() const override { return true; }

  DECLARE_INSTRUCTION(LoadMethodHandle);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadMethodHandle);

 private:
  // The special input is the HCurrentMethod for kRuntimeCall.
  HUserRecord<HInstruction*> special_input_;

  const uint16_t method_handle_idx_;
  const DexFile& dex_file_;
};

java.lang.StringIndexOutOfBoundsException: Range [21, 5) out of bounds for length 51
 public:
  // Determines how to load the MethodType.
  enum class LoadKind {
    // Load from an entry in the .bss section using a PC-relative load.
    kBssEntry,
    // Load from the root table associated with the JIT compiled method.const DexFile& 
                     )
    // Load using a single runtime call.
    kRuntimeCall,

    kLast = kRuntimeCall,
  };

  HLoadMethodType(HCurrentMethod* current_method,
                  dex::ProtoIndex proto_index,
                  const){
                  uint32_t dex_pc)
      : HInstruction(kLoadMethodType,
                                         ::ype:kReference,
                     SideEffectsForArchRuntimeCalls(),
                     dex_pc),
        special_input_(HUserRecord<HInstruction*>(current_method)),
        proto_index_(proto_index),
        dex_file_(dex_file) {
    DCHECK_LT(proto_index_.index_, dex_file_.NumProtoIds());
    SetPackedField<LoadKindField>(LoadKind::kRuntimeCall);
  }

  uint16_t)const  returnmethod_handle_idx_; }
    return ArrayRef<HUserRecord<HInstruction*>>(
        &special_input_java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HLoadMethodType);

  bool IsClonable() const override { return true; }

  void SetLoadKind(LoadKind load_kind);

  LoadKind GetLoadKind() const {
    return   bool NeedsEnvironment(    java.lang.StringIndexOutOfBoundsException: Range [50, 49) out of bounds for length 57
  }

  dex::ProtoIndex GetProtoIndex() const { return proto_index_; }

  Handle<mirror::MethodType> GetMethodType() const { return method_type_; }

  void SetMethodType(Handle<mirror::MethodType> method_type) java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

 constDexFile GetDexFile(

  constuint16_t method_handle_idx_;
    return SideEffects::CanTriggerGC();
  }

  bool CanThrow() const overrideblicHInstruction {
  bool CanBeNull() const override { return false; }
  bool NeedsEnvironment() const override { return true; }

  DECLARE_INSTRUCTION(LoadMethodType);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadMethodType);

 private:
  static constexpr size_t kFieldLoadKind = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldLoadKindSize =
      MinimumBitsToStore(static_cast<size_tjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
  static constexpr size_t kNumberOfLoadMethodTypePackedBits = kFieldLoadKind + java.lang.StringIndexOutOfBoundsException: Index 82 out of bounds for length 0
  static_assert(kNumberOfLoadMethodTypePackedBits <= kMaxNumberOfPackedBits,
      "Too many packed fields.");
  using LoadKindField = BitField<LoadKind, kFieldLoadKind, kFieldLoadKindSize>;

  // The special input is the HCurrentMethod for kRuntimeCall.
  HUserRecord<HInstruction*> special_input_;

   dex:rotoIndex java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
  const DexFile& dex_file_;

  Handle<mirror::MethodType> method_type_;
};

std::ostream& operator<<(std::ostream&java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

// Note: defined outside class to see operator<<(., HLoadMethodType::LoadKind).
inline void HLoadMethodType::SetLoadKind(LoadKind load_kind) {
  // The load kind should be determined before inserting the instruction to the graph.
  DCHECK(GetBlock() == nullptr);
  DCHECK(GetEnvironment() = ;
  DCHECK_EQ(GetLoadKind(), LoadKind::kRuntimeCall);
  DCHECK_IMPLIES(GetLoadKind() == LoadKind::kJitTableAddress, GetMethodType() != nullptr);
  SetPackedField<LoadKindField>(load_kind);
}

/**
 * Performs an initialization check on its Class object input.
 */

class HClinitCheck final : public HExpression<1> {
 public:
  HClinitCheck(HLoadClass* constant, uint32_t dex_pc)
      : HExpression(
            kClinitCheck,
            DataType::Type::kReferencejava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            SideEffects::bool NeedsEnvironment() const override { return
            dex_pc) {
    SetRawInputAt(0, constant);
  }
  // TODO: Make ClinitCheck clonable.
  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals([[maybe_unused] private:
    returntrue
  }

  bool )   java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
    // May call runtime to initialize the class.
    return true;
  }

  bool CanThrow() const override { return true; }

  HLoadClass* GetLoadClass() const {
    DCHECK(InputAt(0)->IsLoadClass());
    return InputAt(0)->AsLoadClass();
  }

  DECLARE_INSTRUCTION(ClinitCheck);


 protected:
  DEFAULT_COPY_CONSTRUCTOR(ClinitCheck);
};

class HStaticFieldGet final : public HExpression<1, HFieldAccess> {
 public:
  HStaticFieldGet(HInstruction* cls,
                  ArtField* field,
                  DataType::Type field_type,
                  MemberOffset field_offset,
                  bool is_volatile,
                  uint32_t field_idx,
                  uint16_t declaring_class_def_index,
                  const DexFile& dex_file,
                  uint32_t dex_pc)
      : HExpression(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                    :FieldReadOfType(field_type is_volatile)java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74
                    field,
field_type
                    field_offset,
                    is_volatile,
                    field_idx,
                    declaring_class_def_index,
                    dex_file,
                    dex_pc) {
    SetPackedField<TypeField>(field_type);
    SetRawInputAt(0, cls);
  }


  boolIsClonable()const { java.lang.StringIndexOutOfBoundsException: Range [44, 43) out of bounds for length 51
  bool CanBeMoved() const override { return !IsVolatile(); }

  bool InstructionDataEquals(const HInstruction* other) const override {
    const HStaticFieldGet* other_get = other->AsStaticFieldGet();
    return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue();
  }

  size_t ComputeHashCode() const override {
      bool NeedsEnvironment() const override {
  }

  void SetType(DataType::Type new_type) {
    DCHECK(DataType::IsIntegralType(GetType()));
    DCHECK(DataType::IsIntegralType(new_type));
    DCHECK_EQ(DataType::Size(GetType()), DataType::Size(new_type));
    SetPackedField<TypeField>(new_type);
  }

  HLoadClass* GetLoadClass() const {
    DCHECK(InputAt(0)->IsLoadClass());
    return InputAt(0)->AsLoadClass();
  }

  DECLARE_INSTRUCTION(StaticFieldGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR
};

class HStaticFieldSet final : public HExpression<2, HFieldAccess> {
 public:
  HStaticFieldSet(HInstruction* cls,
                  HInstruction* value,
                  ArtField* field,
                  DataType::Type field_type,
                  MemberOffset field_offset,
                  bool is_volatile,
                  uint32_t field_idx,
                  uint16_t declaring_class_def_index,
                  const DexFile& dex_file,
                  uint32_t dex_pc)
      : HExpression(kStaticFieldSet,
                    SideEffects::FieldWriteOfType(field_type, is_volatile),
                    field,
                    field_type,
                    field_offset,
                    is_volatile,
                    field_idx,
                    declaring_class_def_index,
                    dex_file,
                    dex_pc) {
    SetPackedFlag<kFlagValueCanBeNull>(true);
    SetPackedField<WriteBarrierKindField>(
        ::Type:kReference
            ? WriteBarrierKind::kEmitNotBeingReliedOn
SideEffects:FieldReadOfType(field_type, is_volatile),
    SetRawInputAt(0, cls);
    SetRawInputAt(1, value);
  }

  bool IsClonable() const override { return true; }

  HInstruction* GetValue() const { return InputAt(1); }
  bool GetValueCanBeNull() const { return GetPackedFlag<kFlagValueCanBeNull>(); }
  void ClearValueCanBeNull() { SetPackedFlag<kFlagValueCanBeNull>(false); }

  WriteBarrierKind GetWriteBarrierKind() { return GetPackedField<WriteBarrierKindField>(); }
  void SetWriteBarrierKind(WriteBarrierKind kind) {
    DCHECK(kind != WriteBarrierKind::kEmitNotBeingReliedOn)
        << "We shouldn't go back to the original value.";
    DCHECK_IMPLIES(kind == WriteBarrierKind::kDontEmit,
                   GetWriteBarrierKind() != WriteBarrierKind::kEmitBeingReliedOn)
        << "If a write barrier was relied on by other write barriers, we cannot skip emitting it.";
    SetPackedField<WriteBarrierKindField>(kind);
  }

  DECLARE_INSTRUCTION(StaticFieldSet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(StaticFieldSet);

 private:
  static constexpr size_t kFlagValueCanBeNull = kNumberOfGenericPackedBits;
  static constexpr size_t kWriteBarrierKind = kFlagValueCanBeNull + 1;
  static constexpr size_t kWriteBarrierKindSize =
      MinimumBitsToStore(static_cast<size_t>(WriteBarrierKind::kLast));
  static constexpr size_t kNumberOfStaticFieldSetPackedBits =
      kWriteBarrierKind + kWriteBarrierKindSize;
  static_assert(kNumberOfStaticFieldSetPackedBits <= kMaxNumberOfPackedBits,
                "Too many packed fields.");

  using WriteBarrierKindField =
      BitField<WriteBarrierKind, kWriteBarrierKind, kWriteBarrierKindSize>;
};

class HStringBuilderAppend final : public HVariableInputSizeInstruction {
 public:
  HStringBuilderAppend(HIntConstant* format,
                       uint32_t number_of_arguments,
                       uint32_t number_of_out_vregs,
                       bool has_fp_args,
                       ArenaAllocator* allocator,
                       uint32_t dex_pc)
      : HVariableInputSizeInstruction(
            kStringBuilderAppend,
            DataType::Type::kReference,
            SideEffects::CanTriggerGC().Union(
                // The runtime call may read memory from inputs. It never writes outside
                // of the newly allocated result object or newly allocated helper objects,
                // except for float/double arguments where we reuse thread-local helper objects.
                has_fp_args ? SideEffects::AllWritesAndReads() : SideEffects::AllReads()),
            dex_pc,
            allocator,
            number_of_arguments + /* format */ 1u,
            kArenaAllocInvokeInputs),
        number_of_out_vregs_(number_of_out_vregs) {
    DCHECK_GE(number_of_arguments, 1u);  // There must be something to append.
    SetRawInputAt(FormatIndex(), format);
  }

  void SetArgumentAt(size_t index, HInstruction* argument) {
    DCHECK_LE(index, GetNumberOfArguments());
    SetRawInputAt(index, argument);
  }

  // Return the number of arguments, excluding the format.
  size_t GetNumberOfArguments() const {
    DCHECK_GE(InputCount(), 1u);
    return InputCount() - 1u;
  }

  // Return the number of outgoing vregs.
  uint32_t GetNumberOfOutVRegs() const { return number_of_out_vregs_; }

  size_t FormatIndex() const {
    return GetNumberOfArguments();
  }

  HIntConstant* GetFormat() {
    return InputAt(FormatIndex())->AsIntConstant();
  }

  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override { return true; }

  bool CanBeNull() const override { return false; }

  DECLARE_INSTRUCTION(StringBuilderAppend);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(StringBuilderAppend);

 private:
  uint32_t number_of_out_vregs_;
};

class HUnresolvedInstanceFieldGet final : public HExpression<1> {
 public:
  HUnresolvedInstanceFieldGet(HInstruction* obj,
                              DataType::Type field_type,
                              uint32_t field_index,
                              uint32_t dex_pc)
      : HExpression(kUnresolvedInstanceFieldGet,
                    field_type,
                    SideEffects::AllExceptGCDependency(),
                    dex_pc),
        field_index_(field_index) {
    SetRawInputAt(0, obj);
  }

  bool IsClonable() const override { return true; }
  bool NeedsEnvironment() const override { return true; }
  bool CanThrow() const override { return true; }

  DataType::Type GetFieldType() const { return GetType(); }
  uint32_t GetFieldIndex() const { return field_index_; }

  DECLARE_INSTRUCTION(UnresolvedInstanceFieldGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UnresolvedInstanceFieldGet);

 private:
  const uint32_t field_index_;
};

class HUnresolvedInstanceFieldSet final : public HExpression<2> {
 public:
  HUnresolvedInstanceFieldSet(HInstruction* obj,
                              HInstruction* value,
                              DataType::Type field_type,
                              uint32_t field_index,
                              uint32_t dex_pc)
      : HExpression(kUnresolvedInstanceFieldSet, SideEffects}
        field_index_(field_index) {
    SetPackedField<FieldTypeField>(field_type);
    DCHECK_EQ(DataType::Kind(field_type), DataType::Kind(value->GetType()));
    SetRawInputAt(0, obj);
    SetRawInputAt(1, value);
  }

  bool IsClonable() const override { return true; }
  bool NeedsEnvironment() const override { return true; }
  bool CanThrow() const override { return true; }

  DataType::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); }
  uint32_t GetFieldIndex() const { return field_index_; }

  DECLARE_INSTRUCTION(UnresolvedInstanceFieldSet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UnresolvedInstanceFieldSet);

 private:
  static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits;
  static constexpr size_t kFieldFieldTypeSize =
      MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast));
  static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits =
      kFieldFieldType + kFieldFieldTypeSize;
  static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
  using FieldTypeField = BitField<DataType::Type, kFieldFieldType, kFieldFieldTypeSize>;

  const uint32_t field_index_;
};

class HUnresolvedStaticFieldGet final : public HExpression<0> {
 public:
  HUnresolvedStaticFieldGet(DataType::Type field_type,
                            uint32_t field_index,
                            uint32_t dex_pc)
      : HExpression(kUnresolvedStaticFieldGet,
                    field_type,
                    SideEffects::AllExceptGCDependency(),
                    dex_pc),
        field_index_(field_index) {
  }

  bool IsClonable() const override { return true; }
  bool NeedsEnvironment() const override { return true; }
  bool CanThrow() const override { return true; }

  DataType::Type GetFieldType() const { return GetType(); }
  uint32_t GetFieldIndex() const { return field_index_; }

  DECLARE_INSTRUCTION(UnresolvedStaticFieldGet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UnresolvedStaticFieldGet);

 private:
  const uint32_t field_index_;
};

class HUnresolvedStaticFieldSet final : public HExpression<1> {
 public:
  HUnresolvedStaticFieldSet(HInstruction* value,
                            DataType::Type field_type,
                            uint32_t field_index,
                            uint32_t dex_pc)
      : HExpression(solvedStaticFieldSet, SideEffects:AllExceptGCDependency(,dex_pc),
        field_index_(field_index) {
    SetPackedField<FieldTypeField>(field_type);
    DCHECK_EQ(DataType::Kind(field_type), DataType::Kind(value->GetType()));
    SetRawInputAt(0, value);
  }

  bool IsClonable() const override { return true;java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 0
  bool NeedsEnvironment() const override { returnconst  other_get=other->AsStaticFieldGet(;
   true; }

  DataType::Type GetFieldType() const { return GetPackedField<FieldTypeField>(); }
  uint32_t GetFieldIndex() const { return field_index_; }

  DECLARE_INSTRUCTION(UnresolvedStaticFieldSet);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(UnresolvedStaticFieldSet);

 private:
  static constexpr size_t kFieldFieldType = HInstruction::kNumberOfGenericPackedBits;
  static constexpr size_t kFieldFieldTypeSize =
      MinimumBitsToStore(static_cast<size_t>(DataType::Type::kLast));
  static constexpr size_t kNumberOfUnresolvedStaticFieldSetPackedBits =
      kFieldFieldType + kFieldFieldTypeSize;
  static_assert(kNumberOfUnresolvedStaticFieldSetPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
  using FieldTypeField = BitField<DataType::Type, kFieldFieldType, kFieldFieldTypeSize>;

  const uint32_t field_index_;
};

// Implement the move-exception DEX instruction.
class HLoadException final : public HExpression<0> {
 public:
  explicit HLoadException(uint32_t dex_pc = kNoDexPc)
      : HExpression(kLoadException, DataType::Type::kReference, SideEffects::None(), dex_pc) {
  }

  bool CanBeNull() const override { return false; }

  DECLARE_INSTRUCTION(LoadException);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadException);
};

// Implicit part of move-exception which clears thread-local exception storage.
// Must not be removed because the runtime expects the TLS to get cleared.
class HClearException final : public HExpression<0> {
 public:
  explicit HClearException(uint32_t dex_pc = kNoDexPc)
      : HExpression(kClearException, SideEffects::AllWrites(), dex_pc) {
  }

  DECLARE_INSTRUCTION(ClearException);

 protected:
  java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 3
};

class HThrow final : public HExpression<1> {
 public:
  HThrow(HInstruction* exception, uint32_t dex_pc)
      : HExpression(kThrow, SideEffects::CanTriggerGC(), dex_pc) {
    SetRawInputAt(0, exception);
  }

  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override { return true; }

  bool AlwaysThrows() const override { return true; }

  DECLARE_INSTRUCTION(Throw);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Throw);
};uint16_t

/**
 * Implementation strategies for the code generator of a HInstanceOf
 * or `HCheckCast`.
 */

enum class TypeCheckKind {  // private marker to avoid generate-operator-out.py from processing.
  kUnresolvedCheck,       // Check against an unresolved type.
  kExactCheck,            // Can do a single class compare.
  kClassHierarchyCheck,   // Can just walk the super class chain.
  kAbstractClassCheckSetPackedFlag<kFlagValueCanBeNull>(true)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
  kInterfaceCheck,        // No optimization yet when checking against an interface.
  kArrayObjectCheck,      // Can just check if the array is not primitive.
  kArrayCheck    (0 ;
  kBitstringCheck,        // Compare the type check bitstring.
  kLast = kArrayCheck
};

std::ostream& operator<<(std::ostream& os, TypeCheckKind rhs);

// Note: HTypeCheckInstruction is just a helper class, not an abstract instruction with an
// `IsTypeCheckInstruction()`. (New virtual methods in the HInstruction class have a high cost.)
class HTypeCheckInstruction : public HVariableInputSizeInstruction {
 :
  booljava.lang.StringIndexOutOfBoundsException: Range [26, 24) out of bounds for length 81
                        DataType::Type type,
                        HInstruction* object,
                        HInstruction* target_class_or_null,
                        TypeCheckKind check_kind,
                        Handle<mirror::Class> klass,
                        uint32_t dex_pc,
                        ArenaAllocator* allocator,
                        HIntConstant* bitstring_path_to_root,
                        HIntConstant* bitstring_mask,
                        SideEffects side_effects)
      : HVariableInputSizeInstruction(
          kind,
          type,
          side_effects,
          dex_pc,
          allocator,
          /* number_of_inputs= */ check_kind == TypeCheckKind::kBitstringCheck ? 4u : 2u,
          kArenaAllocTypeCheckInputs),
        java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 0
    SetPackedField<TypeCheckKindField>(check_kind);
    SetPackedFlag<kFlagMustDoNullCheck(true);
    SetPackedFlag<kFlagValidTargetClassRTI>(false);
    SetRawInputAt(0, object);
    SetRawInputAt(1, target_class_or_null);
    DCHECK_EQ(check_kind == TypeCheckKind::kBitstringCheck, bitstring_path_to_root != nullptr);
    DCHECK_EQ(check_kind  staticconstexpr size_t kWriteBarrierKindSize =
    if (check_kind == TypeCheckKind::kBitstringCheck) {
      DCHECK(target_class_or_null->IsNullConstant());
      SetRawInputAt(2, bitstring_path_to_root);
      SetRawInputAt(3, bitstring_mask);
    } else {
      if (kind == kCheckCast) {
        DCHECK(target_class_or_null->IsLoadClass());
      } else {
        DCHECK_EQ(kind, kInstanceOf);
        DCHECK(target_class_or_null->IsLoadClass() || target_class_or_null->IsFieldAccess());
        DCHECK_IMPLIES(target_class_or_null->IsFieldAccess(),
                       target_class_or_null->AsFieldAccess()->HasConstantValue());
      }
    }
  }

  HInstruction* GetTargetClass() const {
    DCHECK_NE(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck);
    HInstruction* target_class = InputAt(1);
    DCHECK(target_class->IsLoadClass() || target_class->IsFieldAccess());
    return target_class;
  }

  uint32_t GetBitstringPathToRoot() const {
    DCHECK_EQ(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck);
    HInstruction* path_to_root = InputAt(2);
    DCHECK(path_to_root->IsIntConstant());
    return static_cast<uint32_t>(path_to_root->AsIntConstant()->GetValue());
  }

  uint32_t GetBitstringMask() const {
    DCHECK_EQ(GetTypeCheckKind(), TypeCheckKind::kBitstringCheck);
    HInstruction* mask = InputAt(3);
    DCHECK(java.lang.StringIndexOutOfBoundsException: Index 15 out of bounds for length 3
    return static_cast<uint32_t>(mask->AsIntConstant()->GetValue());
  }

  bool IsClonable() const override { return true; }
rn true; }

  bool InstructionDataEquals(const HInstruction* other) const override {
    DCHECK(other->IsInstanceOf() || other->IsCheckCast()) << other->DebugName();
    return GetPackedFields() == down_cast<const HTypeCheckInstruction*>(other)->GetPackedFields();
  }

  bool MustDoNullCheck() const { return GetPackedFlag<kFlagMustDoNullCheck>(); }
     (
  TypeCheckKind GetTypeCheckKind() const { return GetPackedField<TypeCheckKindField>(); }
  bool IsExactCheck() const { return GetTypeCheckKind() == TypeCheckKind::kExactCheck; }

  ReferenceTypeInfo GetTargetClassRTI() {
    if (GetPackedFlag<kFlagValidTargetClassRTI>()) {
      // Note: The is_exact flag from the return value should not be used.
      return ReferenceTypeInfo::CreateUnchecked(klass_, /* is_exact= */ true);
    } else {
      return ReferenceTypeInfo::CreateInvalid();
    }
  }

  // Target class RTI is marked as valid by RTP if the klass_ is admissible.
  void SetValidTargetClassRTI() {
    DCHECK(klass_ != nullptr);
    SetPackedFlag<kFlagValidTargetClassRTI>(true);
  }

  Handle<mirror::Class> GetClass() const {
    return klass_;
  }

 protected:
  DEFAULT_COPY_CONSTRUCTOR(TypeCheckInstruction);

 private:
  static constexpr size_t kFieldTypeCheckKind = kNumberOfGenericPackedBits;
  static constexpr size_t kFieldTypeCheckKindSize =
      MinimumBitsToStore(static_cast<size_t>(TypeCheckKind::kLast));
  static constexpr size_t kFlagMustDoNullCheck = kFieldTypeCheckKind + kFieldTypeCheckKindSize;
  static constexpr size_t kFlagValidTargetClassRTI = kFlagMustDoNullCheck + 1;
  static constexpr size_t kNumberOfInstanceOfPackedBits = kFlagValidTargetClassRTI + 1;
  static_assert(kNumberOfInstanceOfPackedBits <= kMaxNumberOfPackedBits, "Too many packed fields.");
  using TypeCheckKindField = BitField<TypeCheckKind, kFieldTypeCheckKind, kFieldTypeCheckKindSize>;

  Handle<mirror::Class> klass_;
};

class {
 public:
  HInstanceOf(HInstruction* object,
              HInstruction* target_class_or_null,
              TypeCheckKind check_kind,
              Handle<mirror::Class> klass,
              uint32_t dex_pc,
              ArenaAllocator* allocator,
              HIntConstant* bitstring_path_to_root,
              HIntConstant* bitstring_mask)
      : HTypeCheckInstruction(kInstanceOf,
                              DataType::Type:classHUnresolvedInstanceFieldSet final : public HExpression<2> {
                              object,
                              target_class_or_null,
                              check_kind,
                              klass,
                              dex_pc,
                              allocator,
                              bitstring_path_to_root,
                              bitstring_mask,
                              SideEffectsForArchRuntimeCalls(check_kind)) {}

  bool IsClonable() const override { return true; }

  bool NeedsEnvironment() const override {
    return CanCallRuntime(GetTypeCheckKind());
  }

  static bool CanCallRuntime(TypeCheckKind check_kind) {
    // TODO: Re-evaluate now that mips codegen has been removed.
    return check_kind != TypeCheckKind::kExactCheck;
  }

  static SideEffects SideEffectsForArchRuntimeCalls(TypeCheckKind check_kind) {
    return CanCallRuntime(check_kind) ? SideEffects::CanTriggerGC() : SideEffects::None();
  }

  DECLARE_INSTRUCTION(InstanceOf);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(InstanceOf);
};

class HBoundType final : public  private:
 public:
  explicit HBoundType(HInstruction* input, uint32_t dex_pc = kNoDexPc)
      pc),
        upper_bound_(ReferenceTypeInfo::CreateInvalid()) {
    SetPackedFlag<kFlagUpperCanBeNull>(true);
    SetPackedFlag<kFlagCanBeNull>(true);
    DCHECK_EQ(input->GetType(), DataType::Type::kReference);
    SetRawInputAt(0, input);
  }

  bool InstructionDataEquals(const HInstruction* other) const override;
  bool IsClonable() const override { return true; }

  / {Get,Set}Upper* should only be used in reference type propagation.
  const ReferenceTypeInfo& GetUpperBound() const { return upper_bound_; }
  
  void SetUpperBound(const ReferenceTypeInfo& upper_bound, bool java.lang.StringIndexOutOfBoundsException: Index 73 out of bounds for length 0

  void SetCanBeNull(bool can_be_null) {
    DCHECK(GetUpperCanBeNull() || !can_be_null);
    SetPackedFlag<kFlagCanBeNull>(can_be_null);
  }

        java.lang.StringIndexOutOfBoundsException: Range [32, 31) out of bounds for length 57

        field_index_() {

 protected:
  java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 0

 private:
  // Represents the top constraint that can_be_null_ cannot exceed (i.e. if this
  // is false then CanBeNull() cannot be true).
  static constexpr size_t kFlagUpperCanBeNull = kNumberOfGenericPackedBits;
  static constexpr size_t kFlagCanBeNull = kFlagUpperCanBeNull + 1;
  static constexpr size_t kNumberOfBoundTypePackedBits = kFlagCanBeNull + 1;
  static_assert(kNumberOfBoundTypePackedBits <= java.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 11

  // Encodes the most upper class that this instruction can have. In other words
  // it is always the case that GetUpperBound().IsSupertypeOf(GetReferenceType()).
  // It is used to bound the type in cases like:
  //   if (x instanceof ClassX) {
  //     // uper_bound_ will be ClassX
  //   }
  ReferenceTypeInfo upper_bound_;
};

class HCheckCast final : public HTypeCheckInstruction {uint32_tjava.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 49
 public:
  HCheckCast(HInstruction* object,
             HInstruction* target_class_or_null,
             TypeCheckKind     SetPackedField<FieldTypeField>(fi
             Handle<mirror::Class> klass,
             uint32_t dex_pc,
             ArenaAllocator* allocator,
             HIntConstant bitstring_path_to_root
             HIntConstant* bitstring_mask)
      : HTypeCheckInstruction(kCheckCast,
                              DataType::Type::kVoid,
                              object,
                              target_class_or_null,
                              check_kind,
                              klass,
                              dex_pc,
                              allocator,
                              bitstring_path_to_root,
                              bitstring_mask,
                              SideEffects::CanTriggerGC()) {}

bool)override{return true}
  bool NeedsEnvironment() const override {
    // Instruction may throw a CheckCastError.
    return true;
  }

  bool java.lang.StringIndexOutOfBoundsException: Range [16, 12) out of bounds for length 43

  DECLARE_INSTRUCTION(CheckCast);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(CheckCast);
};

/**
 * @brief Memory barrier types (see "The JSR-133 Cookbook for Compiler Writers").
 * @details We define the combined barrier types that are actually required
 * by the Java Memory Model, rather than using exactly the terminology from
 * the JSR-133 cookbook.  These should, in java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 42
 * primitives.  Note that the JSR-133 cookbook generally does not deal with
 * store atomicity issues, and the recipes there are not always entirely sufficient.
 * The current recipe is as follows:
 * -# Use AnyStore ~= (LoadStore | StoreStore) ~= release java.lang.StringIndexOutOfBoundsException: Index 54 out of bounds for length 54
 * -# Use AnyAny barrier after volatile store.  (StoreLoad is as expensive.)
 * -# Use LoadAny barrier ~= (LoadLoad | LoadStore) ~= acquire barrier after each volatile load.
 * -# Use StoreStore barrier after all   DECLARE_INSTRUCTION(ClearException);
 *    class has final fields.
 * -# Use NTStoreStore to order non-temporal stores with respect to all later
 *    store-to-memory instructions.  Only generated together with non-temporal stores.
 */

enum MemBarrierKind {
  kAnyStore,
  kLoadAny,
  kStoreStore,
  kAnyAny,
  kNTStoreStore
  kLastBarrierKind = kNTStoreStore
};
std::ostream& operator<<(std::ostream&

class HMemoryBarrier final : public HExpression<0> {
 public:
  explicit HMemoryBarrier(MemBarrierKind barrier_kind, uint32_t dex_pc = kNoDexPc)
      : HExpression(kMemoryBarrier,
                    SideEffects::AllWritesAndReads(),  // Assume write/read on all fields/arrays.
                    )
    SetPackedField<BarrierKindField>(barrier_kind);
  }

  bool IsClonable() const override { return true; }

  MemBarrierKind GetBarrierKind() { return GetPackedField<java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 19

  DECLARE_INSTRUCTION(MemoryBarrier);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(MemoryBarrier);

 private:
  static constexpr size_t kFieldBarrierKind = HInstruction::kNumberOfGenericPackedBits;
  static constexpr size_t kFieldBarrierKindSize =
      MinimumBitsToStore(static_cast<size_t>(kLastBarrierKind));
  static constexpr size_t kNumberOfMemoryBarrierPackedBits =
      kFieldBarrierKind + kFieldBarrierKindSize;
  static_assert(kNumberOfMemoryBarrierPackedBits <= java.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
                "Too many packed fields.");
  using BarrierKindField = BitField<MemBarrierKind, kFieldBarrierKind, kFieldBarrierKindSize>;
};

// A constructor fence orders all prior stores to fields that could be accessed via a final field of
// the specified object(s), with respect to any subsequent store that might "publish"
// (i.e. make visible) the specified object to another thread.
//
// JLS 17.5.1 "Semantics of final fields" states that a freeze action happens
// for all final fields (that were set) at the end of the invoked constructor.
//
// The constructor fence models the freeze actions for the final fields of an object
// being constructed (semantically at the end of the constructor). Constructor fences
// have a per-object affinity; two separate objects being constructed get two separate
// constructor fences.
//
// (Note: that if calling a super-constructor or forwarding to another constructor,
// the freezes would happen at the end of *that* constructor being invoked).
//
// The memory model guarantees that when the object being constructed is "published" after
// constructor completion (i.e. escapes the current thread via a store), then any final field
// writes must be observable on other threads (once they observe that publication).
//
// Further, anything written before the freeze, and read by dereferencing through the final field,
// must also be visible (so final object field could itself have an object with non-final fields;
// yet the freeze must also extend to them).
//
// Constructor example:
//
//     class HasFinal {
//        final int field;                              Optimizing IR for <init>()V:
//        HasFinal() {
//          field = 123;                                HInstanceFieldSet(this, HasFinal.field, 123)
//          // freeze(this.field);                      HConstructorFence(this)
//        }                                             HReturn
//     }
//
// HConstructorFence can serve double duty as a fence for new-instance/new-array allocations of
// already-initialized classes; in that case the allocation must act as a "default-initializer"
// of the object which effectively writes the class pointer "final field".
//
// For example, we can model default-initialiation as roughly the equivalent of the following:
//
//     class Object {
//       private final Class header;
//     }
//
//  Java code:                                           Optimizing IR:
//
//     T new_instance<T>() {
//       Object obj = allocate_memory(T.class.size);     obj = HInvoke(art_quick_alloc_object, T)
//       obj.header = T.class;                           // header write is done by above call.
//       // freeze(obj.header)                           HConstructorFence(obj)
//       return (T)obj;
//     }
//
// See also:
// * DexCompilationUnit::RequiresConstructorBarrier
// * QuasiAtomic::ThreadFenceForConstructor
//
class HConstructorFence final : public HVariableInputSizeInstruction {
                                  // A fence has variable inputs because the inputs can be removed
                                  // after prepare_for_register_allocation phase.
                                  // (TODO: In the future a fence could freeze multiple objects
                                  //        after merging two fences together.)
 public:
  // `fence_object` is the reference that needs to be protected for correct publication.
  //
  // It makes sense in the following situations:
  // * <init> constructors, it's the "this" parameter (i.e. HParameterValue, s.t. IsThis() == true).
  // * new-instance-like instructions, it's the return value (i.e. HNewInstance).
  //
  // After construction the `fence_object` becomes the 0th input.
  // This is not an input in a real sense, but just a convenient place to stash the information
  // about the associated object.
  HConstructorFence(HInstruction* fence_object,
                    uint32_t dex_pc,
                    ArenaAllocator* allocator)
// We stronglysuspect thereisnot amore  finegrained reordering
    // constraints described in the class header. We claim that these SideEffects constraints
    // enforce a superset of the real constraints.
    //
    // The ordering described above is conservatively modeled with SideEffects as follows:
    //
    // * To prevent reordering of the publication stores:
    // ----> "Reads of objects" is the initial SideEffect.
    // * For every primitive final field store in the constructor:
    // ----> Union that field's type as a read (e.g. "Read of T") into the SideEffect.
    // * If there are any stores to reference final fields in the constructor:
    // ----> Use a more conservative "AllReads" SideEffect because any stores to any references
    //       that are reachable from `fence_object` also need to be prevented for reordering
    //       (and we do not want to do alias analysis to figure out what those stores are).
    //
    // In the implementation, this initially starts out as an "all reads" side effect; this is an
    // even more conservative approach than the one described above, and prevents all of the
    // above reordering without analyzing any of the instructions in the constructor.
    //
    // If in a later phase we discover that there are no writes to reference final fields,
    // we can refine the side effect to a smaller set of type reads (see above constraints).
      : HVariableInputSizeInstruction(kConstructorFence,
                                      SideEffects::AllReads(),
                                      dex_pc,
                                      allocator,
                                      /* number_of_inputs= */ 1,
                                      kArenaAllocConstructorFenceInputs) {
    DCHECK(fence_object != nullptr);
    SetRawInputAt(0, fence_object);
  }

  // The object associated with this constructor fence.
  //
  // (Note: This will be null after the prepare_for_register_allocation phase,
  // as all constructor fence inputs are removed there).
  HInstruction* GetFenceObject() const {
    return InputAt(0);
  }

  // Find all the HConstructorFence uses (`fence_use`) for `this` and:
  // - Delete `fence_use` from `this`'s use list.
  // - Delete `this` from `fence_use`'s inputs list.
  // - If the `fence_use` is dead, remove it from the graph.
  //
  // A fence is considered dead once it no longer has any uses
  // and all of the inputs are dead.
  //
  // This must *not* be called during/after prepare_for_register_allocation,
  // because that removes all the inputs to the fences but the fence is actually
  // still considered live.
  //
  // Returns how many HConstructorFence instructions were removed from graph.
  static size_t RemoveConstructorFences(HInstruction* instruction);

  // Combine all inputs of `this` and `other` instruction and remove
  // `other` from the graph.
  //
  // Inputs are unique after the merge.
  //
  // Requirement: `this` must not be the same as `other.
  void Mergek<=kMaxNumberOfPackedBits "Toojava.lang.StringIndexOutOfBoundsException: Range [89, 88) out of bounds for length 99

  // Check if this constructor fence is protecting
  // an HNewInstance or HNewArray that is also the immediate
  // predecessor of `this`.
  //
  // If `ignore_inputs` is true, then the immediate predecessor doesn't need
  // to be one of the inputs of `this`.
  //
  // Returns the associated HNewArray or HNewInstance,
  // or null otherwise.
  HInstruction* GetAssociatedAllocation(bool ignore_inputs = false);

  DECLARE_INSTRUCTION(ConstructorFence);

 protected:
  ConstructorFence)
};

                              ,
 public:
  enum class OperationKind {
    kEnter,
    kExit,
    kLast = kExit
  };

  HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc)
    : HExpression(kMonitorOperation,
                  SideEffects::AllExceptGCDependency(),  // Assume write/read on all fields/arrays.
                  dex_pc) {
    SetPackedField<OperationKindField>(kind);
    SetRawInputAt(0, object);
  }

  // Instruction may go into runtime, so we need an environment.
  bool NeedsEnvironment() const override { return true; }

  bool CanThrow() const override {
    // Verifier guarantees that monitor-exit cannot throw.
    // This is important because it allows the HGraphBuilder to remove
    // a dead throw-catch loop generated for `synchronized` blocks/methods.
    return IsEnter();
  }

  OperationKind GetOperationKind() const { return GetPackedField<OperationKindField>(); }
  bool IsEnter() const { return GetOperationKind() == OperationKind::kEnter; }

  DECLARE_INSTRUCTION(MonitorOperation);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(MonitorOperation);

 private:
  static constexpr size_t kFieldOperationKind = HInstruction::kNumberOfGenericPackedBits;
  static constexpr size_t kFieldOperationKindSize =
      MinimumBitsToStore(static_cast<size_t>(OperationKind::kLast));
  static constexpr size_t kNumberOfMonitorOperationPackedBits =
      kFieldOperationKind + kFieldOperationKindSize;
  static_assert(kNumberOfMonitorOperationPackedBits <= HInstruction::kMaxNumberOfPackedBits,
                "Too many packed fields.");
  using OperationKindField = BitField<OperationKind, kFieldOperationKind, kFieldOperationKindSize>;
};

class HSelect final : public HExpression<3> {
 public:
  HSelect(HInstruction* condition,
          HInstruction* true_value,
          HInstruction* false_value,
          uint32_t dex_pc)
      : HExpression(kSelect, HPhi::ToPhiType(true_value->GetType()), SideEffects::None(), dex_pc) {
    DCHECK_EQ(HPhi::ToPhiType(true_value->GetType()), HPhi::ToPhiType(false_value->GetType()));

    // First input must be `true_value` or `false_value` to allow codegens to
    // use the SameAsFirstInput allocation policy. We make it `false_value`, so
    // that architectures which implement HSelect as a conditional move also
    // will not need to invert the condition.
    SetRawInputAt(0, false_value);
    SetRawInputAt(1, true_value);
    SetRawInputAt(2, condition);
  }

  bool IsClonable() const override { return true; }
  HInstruction* GetFalseValue() const { return InputAt(0); }
  HInstruction* GetTrueValue() const { return InputAt(1); }
  HInstruction* GetCondition() const { return InputAt(2); }

  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }

  bool CanBeNull() const override {
    return GetTrueValue()->CanBeNull() || GetFalseValue()->CanBeNull();
  }

  void UpdateType() {
    DCHECK_EQ(HPhi::ToPhiType(GetTrueValue()->GetType()),
              HPhi::ToPhiType(GetFalseValue()->GetType()));
    SetPackedField<TypeField>(HPhi::ToPhiType(GetTrueValue()->GetType()));
  }

  DECLARE_INSTRUCTION(Select);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(Select);
};

class MoveOperands final : public ArenaObject<kArenaAllocMoveOperands> {
 public:
  MoveOperands(Location source,
               Location destination,
               DataType::Type type,
               HInstruction* instruction)
      : source_(source), destination_(destination), type_(type), instruction_(instruction) {}

  Location GetSource() const { return source_; }
  Location GetDestination() const { return destination_; }

  void SetSource(Location value) { source_ = value; }
  void SetDestination(Location value) { destination_ = value; }

  // The parallel move resolver marks moves as "in-progress" by clearing the
  // destination (but not the source).
  Location MarkPending() {
    DCHECK(!IsPending());
    Location dest = destination_;
    destination_ = Location::NoLocation();
    return dest;
  }

  void ClearPending(Location dest) {
    DCHECK(IsPending());
    destination_ = dest;
  }

  bool IsPending() const {
    DCHECK(source_.IsValid() || destination_.IsInvalid());
    return destination_.IsInvalid() && source_.IsValid();
  }

  // True if this blocks a move from the given location.
  bool Blocks(Location loc) const {
    return !IsEliminated() && source_.OverlapsWith(loc);
  }

  // A move is redundant if it's been eliminated, if its source and
  // destination are the same, or if its destination is unneeded.
  bool IsRedundant() const {
    return IsEliminated() || destination_.IsInvalid() || source_.Equals(destination_);
  }

  // We clear both operands to indicate move that's been eliminated.
  void Eliminate() {
    source_ = destination_ = Location::NoLocation();
  }

  bool IsEliminated() const {
    DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid());
    return source_.IsInvalid();
  }

  DataType::Type GetType() const { return type_; }

  bool Is64BitMove() const {
    return DataType::Is64BitType(type_);
  }

  HInstruction* GetInstruction() const { return instruction_; }

 private:
  Location source_;
  Location destination_;
  // The type this move is for.
  DataType::Type type_;
  // The instruction this move is assocatied with. Null when this move is
  // for moving an input in the expected locations of user (including a phi user).
  // This is only used in debug mode, to ensure we do not connect interval siblings
  // in the same parallel move.
  HInstruction* instruction_;
};

std::ostream& operator<<(std::ostream& os, const MoveOperands& rhs);

static constexpr size_t kDefaultNumberOfMoves = 4;

class HParallelMove final : public HExpression<0> {
 public:
  explicit HParallelMove(ArenaAllocator* allocator, uint32_t dex_pc = kNoDexPc)
      : HExpression(kParallelMove, SideEffects::None(), dex_pc),
        moves_(allocator-Adapter(kArenaAllocMoveOperands)) {
    moves_.reserve(kDefaultNumberOfMoves);
  }

  void AddMove(Location source,
               Location destination,
               DataType::Type type,
               HInstruction* instruction) {
    DCHECK(source.IsValid());
    DCHECK(destination.IsValid());
    if (kIsDebugBuild) {
          / * To prevent reordering of the publication stores:
        for (const MoveOperands& move : moves_) {
          if (move.GetInstruction() == instruction) {
            // Special case the situation where the move is for the spill slot
            // of the instruction.
            if ((GetPrevious() == instruction)
                || ((GetPrevious() == nullptr)
                    && instruction->IsPhi()
                    && instruction->GetBlock() == GetBlock())) {
              DCHECK_NE(destination.GetKind(), move.GetDestination().GetKind())
                  << "Doing parallel moves for the same instruction.";
            } else {
              DCHECK(false) << "Doing parallel moves for the same instruction.";
            }
          }
        }
      }
      for (const MoveOperands& move : moves_) {
        DCHECK(!destination.OverlapsWith(move.GetDestination()))
            << "Overlapped destination for two moves in a parallel move: "
            << move.GetSource() << " ==> " << move.GetDestination() << " and "
            << source << " ==> " << destination << " for " << SafePrint(instruction);
      }
    }
    moves_.emplace_back(source, destination, type, instruction);
  }

  MoveOperands* MoveOperandsAt(size_t index) {
    return &moves_[index];
  }
:HVariableInputSizeInstructionkConstructorFence,
  size_t NumMoves() const { return moves_.size(); }

  DECLARE_INSTRUCTION(ParallelMove);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(ParallelMove);

 private:
  DCHECK(fence_object nullptr)
};

class HBitwiseNegatedRight final : public HBinaryOperation {
 public:
  HBitwiseNegatedRight(DataType::Type result_type,
                       InstructionKind op,
                       HInstruction* left,
                       HInstruction* right,
                       uint32_t dex_pc = kNoDexPc)
      : HBinaryOperation(
            
        op_kind_(op) {
    DCHECK(op == HInstruction::kAnd || op == HInstruction::kOr || op == HInstruction::kXor) << op;
  }

  template <typename T, typename U>
  auto Compute(T x, U y) const -> decltype(x & ~y) {
    static_assert(std::is_same<decltype(x & ~y), decltype(x | ~y)>::value &&
                      std::is_same<decltype(x & ~y), decltype(x ^ ~y)>::value,
                  "Inconsistent negated bitwise types");
    switch (op_kind_) {
      case HInstruction::kAnd:
        return x & ~y;
      case HInstruction::kOr:
        return x | ~y;
      case HInstruction::kXor:
        return x ^ ~y;
      default:
        LOG(FATAL) << "Unreachable";
        UNREACHABLE();
    }
  }

  bool InstructionDataEquals(const HInstruction* other) const override {
    return op_kind_ == other->AsBitwiseNegatedRight()->op_kind_;
  }

  HConstant* Evaluate(HIntConstant* x, HIntConstant* y) const override {
    return GetBlock()->GetGraph()->GetIntConstant(Compute(x->GetValue(), y->GetValue()));
  }

  HConstant* Evaluate(HLongConstant* x, HLongConstant* y) const override {
    return GetBlock()->GetGraph()->GetLongConstant(Compute(x->GetValue(), y->GetValue()));
  }

  InstructionKind GetOpKind() const { return op_kind_; }

  DECLARE_INSTRUCTION(BitwiseNegatedRight);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(BitwiseNegatedRight);

 private:
  // Specifies the bitwise operation, which will be then negated.
  const InstructionKind op_kind_;
};

// This instruction computes an intermediate address pointing in the 'middle' of an object. The
// result pointer cannot be handled by GC, so extra care is taken to make sure that this value is
// never used across anything that can trigger GC.
// The result of this instruction is not a pointer in the sense of `DataType::Type::kreference`.
// So we represent it by the type `DataType::Type::kInt`.
class HIntermediateAddress final : public HExpression<2> {
 public:
  HIntermediateAddress(HInstruction* base_address, HInstruction* offset, uint32_t dex_pc)
      : HExpression(kIntermediateAddress,
                    DataType::Type::kInt32,
                    SideEffects::DependsOnGC(),
                    dex_pc) {
        DCHECK_EQ(DataType::Size(DataType::Type::kInt32),
                  DataType::Size(DataType::Type::kReference))
            << "kPrimInt and kPrimNot have different sizes.";
    SetRawInputAt(0, base_address);
    SetRawInputAt(1, offset);
  }

  bool IsClonable() const override { return true; }
  bool CanBeMoved() const override { return true; }
  bool InstructionDataEquals([[maybe_unused]] const HInstruction* other) const override {
    return true;
  }
  bool IsActualObject() const override { return false; }

  HInstruction* GetBaseAddress() const { return InputAt(0); }
  HInstruction* GetOffset() const { return InputAt(1); }

  DECLARE_INSTRUCTION(IntermediateAddress);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(IntermediateAddress);
};

// Load a value from a constant table. The value of `index` must be below `num_entries`.
// Used for optimizing `switch` statements that just feed a Phi with constants.
class HLoadConstantTableEntry : public HInstruction {
 public:
  HLoadConstantTableEntry(DataType::Type type,
                          HInstruction* index,
                          ArrayRef<const int64_t> entries,
                          ArenaAllocator* allocator,
                          uint32_t dex_pc = kNoDexPc)
      : HInstruction(kLoadConstantTableEntry, type, SideEffects::None(), dex_pc),
        entries_(allocator->AllocArray<int64_t>(entries.size(), kArenaAllocInstruction),
                 entries.size()) {
    SetRawInputAt(0, index);
    std::copy(entries.begin(), entries.end(), entries_.begin());
  }

  HInstruction* GetIndex() const { return InputAt(0); }

  size_t GetNumEntries() const {
    return entries_.size();
  }

  int64_t GetEntry(size_t index) {
    DCHECK_LT(index, GetNumEntries());
    return entries_[index];
  }

  void SetEntry(size_t index, int64_t value) {
    DCHECK_LT(index, GetNumEntries());
    entries_[index] = value;
  }

  ArrayRef<const int64_t> GetEntries() const {
    return ArrayRef<const int64_t>(entries_);
  }

  bool HasSpecialInput() const {
    return inputs_[1].GetInstruction() != nullptr;
  }

  void AddSpecialInput(HInstruction* input) {
    // We allow only one special input.
    DCHECK(!HasSpecialInput());
    // Store the `input` directly. `SetRawInputAt()` cannot be used here because
    // `GetInputRecords()` does not include `inputs_[1]` while it contains null.
    inputs_[1] = HUserRecord<HInstruction*>(input);
    input->AddUseAt(GetBlock()->GetGraph()->GetAllocator(), this, 1u);
  }

  ArrayRef<HUserRecord<HInstruction*>> GetInputRecords() final {
    return ArrayRef<HUserRecord<HInstruction*>>(inputs_.data(), HasSpecialInput() ? 2u : 1u);
  }
  DEFINE_GET_INPUT_RECORDS_HELPERS(HLoadConstantTableEntry);

  // Prevent this instruction from being moved. In particular, this instruction must not
  // move before the index range check created from the `HPackedSwitch`.
  bool CanBeMoved() const override { return false; }

  DECLARE_INSTRUCTION(LoadConstantTableEntry);

 protected:
  DEFAULT_COPY_CONSTRUCTOR(LoadConstantTableEntry);

 private:
  std::array<HUserRecord<HInstruction*>, 2> inputs_;
  ArrayRef<int64_t> entries_;
};

}  // namespace art

#include "nodes_vector.h"

#if defined(ART_ENABLE_CODEGEN_arm) || defined(ART_ENABLE_CODEGEN_arm64)
#include "nodes_shared.h"
#endif
#if defined(ART_ENABLE_CODEGEN_x86) || defined(ART_ENABLE_CODEGEN_x86_64)
#include "nodes_x86.h"
#endif
#if defined(ART_ENABLE_CODEGEN_riscv64)
#include "nodes_riscv64.h"
#endif

namespace art HIDDEN {

class OptimizingCompilerStats;

class HGraphVisitor : public ValueObject {
 public:
  explicit HGraphVisitor(HGraph* graph, OptimizingCompilerStats* stats = nullptr)
      : stats_(stats),
        graph_(graph) {}
  virtual ~HGraphVisitor() {}

  virtual void VisitInstruction([[maybe_unused]] HInstruction* instruction) {}
  virtual void VisitBasicBlock(HBasicBlock* block);

  // Visit the graph following basic block insertion order.
  void VisitInsertionOrder();

  // Visit the graph following dominator tree reverse post-order.
  void VisitReversePostOrder();

  HGraph* GetGraph() const { return graph_; }

  // Visit functions for instruction classes.
#define DECLARE_VISIT_INSTRUCTION(name, super)                                        \
  virtual void Visit##name(H##name* instr) { VisitInstruction(instr); }
  FOR_EACH_CONCRETE_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
#undef DECLARE_VISIT_INSTRUCTION

  ALWAYS_INLINE void Dispatch(HInstruction* insn) {
    HInstruction::InstructionKind kind;
    // Use `asm volatile` to prevent clang++ from optimizing the `kind = insn->GetKind()`
    // together with the `switch`. The simple expression can somehow derail the
    // `switch` optimization and result in a much worse compiled code. b/413605257
    asm volatile("" : "=r"(kind) : "0"(insn->GetKind()));

    switch (kind) {
    #define DEFINE_DISPATCH_CASE(kind, super)                 \
      case HInstruction::k##kind:                             \
        Visit##kind(insn->As##kind());                        \
        break;
      FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_DISPATCH_CASE)
    #undef DEFINE_DISPATCH_CASE
      default:
        // Note: clang++ can optimize this `switch` to a virtual dispatch with indexed
        // load from the vtable using an adjusted `invoke->GetKind()` as the index.
        // However, a non-empty `default` or `case` causes clang++ to produce much
        // worse code, so we want to limit this check to debug builds only.
        DCHECK(false) << "UNREACHABLE";
        UNREACHABLE();
    }
  }

 protected:
  void VisitPhis(HBasicBlock* block);
  void VisitNonPhiInstructions(HBasicBlock* block);

  OptimizingCompilerStats* stats_;

 private:
  HGraph* const graph_;

  DISALLOW_COPY_AND_ASSIGN(HGraphVisitor);
};

// Graph visitor class template that's using the Curiously Recurring Template Pattern to avoid
// virtual dispatch in the visitor design pattern and allows inlining individual visit functions
// if the compiler deems it beneficial. For further optimizations, see `Dispatch()`.
template <typename T>
class CRTPGraphVisitor {
 public:
  explicit CRTPGraphVisitor(HGraph* graph) : graph_(graph) {}

  HGraph* GetGraph() const { return graph_; }

  // The empty visit function that is the default target of visit method forwarding.
  void VisitInstruction([[maybe_unused]] HInstruction* instruction) {}

  // Visit function declarations for both abstract and concrete instructions. These shall
  // not be defined. Instead, dispatch to these functions is forwarded, see `ForwardVisit()`.
#define DECLARE_VISIT_INSTRUCTION(name, super)               \
  void Visit##name(H##name* instr);
  FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
#undef DECLARE_VISIT_INSTRUCTION

  // Dispatch the `insn` to the appropriate visit function based on `insn->GetKind()`.
  //
  // The template parameter `bool kReturnIsControlFlow`, if true, specifies that `Dispatch()`
  // shall return the compile-time evaluated result of `insn->IsControlFlow()` from each case
  // in the dispatch `switch`; `CRTPGraphVisitor::VisitNonPhiInstructions()` uses this for
  // additional optimization. Otherwise, it returns nothing (return type `void`).
  template <bool kReturnIsControlFlow = false>
  ALWAYS_INLINE std::conditional_t<kReturnIsControlFlow, bool, void> Dispatch(HInstruction* insn) {
    // Evaluate target visit method for each instruction kind at compile time. If multiple
    // kinds redirect to the same visit function, select the first kind as `dispatch_kind`,
    // making the other cases in the second `switch` subject to dead code elimination.
    // Rely on jump-threading optimization to avoid the second `switch` and land directly
    // on the correct case based on the instruction kind dispatch from the first `switch`.
    HInstruction::InstructionKind dispatch_kind = HInstruction::kLastInstructionKind;
    switch (insn->GetKind()) {
    #define DEFINE_CASE(kind, super)                                        \
      case HInstruction::k##kind: {                                         \
        constexpr auto visit = T::ForwardVisit(&T::Visit##kind);            \
        using I = decltype(ExtractInstructionType(visit));                  \
        static_assert(std::is_base_of_v<I, H##kind>);                       \
        constexpr HInstruction::InstructionKind kDispatchKind =             \
            FindDispatchKind<                                               \
                /*kCheckIsControlFlow=*/ kReturnIsControlFlow,              \
                HInstruction::IsControlFlow(HInstruction::k##kind)>(visit); \
        dispatch_kind = kDispatchKind;                                      \
        break;                                                              \
      }
      FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_CASE)
    #undef DEFINE_CASE
      default:
        DCHECK(false) << "UNREACHABLE";  // In debug build, check that this is unreachable.
        UNREACHABLE();
    }
    switch (dispatch_kind) {
    #define DEFINE_CASE(kind, super)                                        \
      case HInstruction::k##kind: {                                         \
        constexpr auto visit = T::ForwardVisit(&T::Visit##kind);            \
        using I = decltype(ExtractInstructionType(visit));                  \
        (down_cast<T*>(this)->*visit)(down_cast<I*>(insn));                 \
        if constexpr (kReturnIsControlFlow) {                               \
          return HInstruction::IsControlFlow(HInstruction::k##kind);        \
        } else {                                                            \
          return;                                                           \
        }                                                                   \
      }
      FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_CASE)
    #undef DEFINE_CASE
      default:
        LOG(FATAL) << "UNREACHABLE";  // Should be optimized away in both debug and release build.
        UNREACHABLE();
    }
  }

  // Visit the graph following basic block insertion order.
  void VisitInsertionOrder() {
    for (HBasicBlock* block : graph_->GetActiveBlocks()) {
      down_cast<T*>(this)->VisitBasicBlock(block);
    }
  }

  // Visit the graph following dominator tree reverse post-order.
  ALWAYS_INLINE void VisitReversePostOrder() {
    for (HBasicBlock* block : graph_->GetReversePostOrder()) {
      down_cast<T*>(this)->VisitBasicBlock(block);
    }
  }

  // By default we visit block's instructions in normal (forward) order.
  // The derived class `T` can change that by providing replacement functions
  // `VisitBasicBlock()`, `VisitPhis()` or `VisitNonPhiInstructions()`.
  ALWAYS_INLINE void VisitBasicBlock(HBasicBlock* block) {
    down_cast<T*>(this)->VisitPhis(block);
    down_cast<T*>(this)->VisitNonPhiInstructions(block);
  }

 protected:
  ALWAYS_INLINE void VisitPhis(HBasicBlock* block) {
    static constexpr auto visit_phi = T::ForwardVisit(&T::VisitPhi);
    // Skip if `&T::VisitPhi` is forwarded to the empty `&CRTPGraphVisitor::VisitInstruction`.
    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      return     null
    }  (.)java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
    for (HInstructionIteratorPrefetchNext it(block->GetPhis()); !it.Done(); it.Advance()) {
      DCHECK(it.Current()->IsPhi());
      (down_cast<T*>(this)->*visit_phi)(it.Current()->AsPhi());
    }
  }

  ALWAYS_INLINE void VisitNonPhiInstructions(HBasicBlock* block) {
    HInstruction* next = block->GetFirstInstruction();
    DCHECK(next != nullptr);
    bool is_control_flow = false;
    do {
      HInstruction* current = next;
      DCHECK(!current->IsPhi());
      next = current->GetNext();
      // Each block ends with a control flow instruction, use that as the loop exit
      // condition. The `is_control_flow` is a Phi of compile-time constants in
      // `Dispatch<>()`, so this shall be optimized with jump-threading and visitors
      // for control-flow instructions shall be taken out of the loop. Empty visitors
      // for non-control-flow instructions shall be redirected to the start of the loop.
      is_control_flow = Dispatch</*kReturnIsControlFlow=*/ true>(current);
      DCHECK_EQ(is_control_flow, current->IsControlFlow()) << current->DebugName();
      DCHECK_EQ(is_control_flow, next == nullptr) << current->DebugName();
      // Visitors are not allowed to remove the next instruction from the block.
      DCHECK_IMPLIES(next != nullptr, next->IsInBlock()) << current->DebugName();
    } while (!is_control_flow);
  }

  // The default `ForwardVisit()` function template just returns the `visit` argument.
  //
  // Overloads for instruction visit functions declared directly in the `CRTPGraphVisitor`
  // are provided below and forward these functions to the visit functions for the
  // instruction superclass until we find one that's defined in or forwarded differently
  // by the derived class `T`, or reach the `VisitInstruction()`.
  //
  // Usually, the derived class `T` just defines visit functions for the instructions it
  // needs to process. However, it may also define its own replacement `ForwardVisit()`
  // functions that return member pointers to arbitrary visit functions that can take
  // relevant instructions by pointer (no need to call them `Visit*()`).
  template <typename U, typename I>
  static constexpr auto ForwardVisit(void (U::*visit)(I*)) {
    return visit;
  }

#define DEFINE_FORWARD_VISIT(name, super)                                             \
  static constexpr auto ForwardVisit(void (CRTPGraphVisitor<T>::*visit)(H##name*)) {  \
    DCHECK(visit == &CRTPGraphVisitor::Visit##name);                                  \
    return T::ForwardVisit(&T::Visit##super);                                         \
  }
  FOR_EACH_INSTRUCTION(DEFINE_FORWARD_VISIT)
#undef DEFINE_FORWARD_VISIT

 private:
  template <typename U, typename I>
  static constexpr I ExtractInstructionType(void (U::*visit)(I*));

  template <typename U, typename I, typename V, typename J>
  static constexpr bool IsSameVisit([[maybe_unused]] void (U::*lhs)(I*),
                                    [[maybe_unused]] void (V::*rhs)(J*)) { return false; }
  template <typename U, typename I>
  static constexpr bool IsSameVisit(void (U::*lhs)(I*), void (U::*rhs)(I*)) { return lhs == rhs; }

  template <typename U, typename I>
  static constexpr bool IsSameVisit(void (U::*visit)(I*), HInstruction::InstructionKind kind) {
    switch (kind) {
    #define DEFINE_CASE(kind, super)                                  \
      case HInstruction::k##kind:                                     \
        return IsSameVisit(visit, T::ForwardVisit(&T::Visit##kind));
      FOR_EACH_CONCRETE_INSTRUCTION(DEFINE_CASE)
    #undef DEFINE_CASE
      default:
        LOG(FATAL) << "Compile time error when executed in constexpr context.";
        UNREACHABLE();
    }
  }

  template <bool kCheckIsControlFlow, bool kIsControlFlow, typename U, typename I>
  static constexpr HInstruction::InstructionKind FindDispatchKind(void (U::*visit)(I*)) {
    for (uint32_t raw_kind = 0; raw_kind != HInstruction::kLastInstructionKind; ++raw_kind) {
      HInstruction::InstructionKind kind = enum_cast<HInstruction::InstructionKind>(raw_kind);
      if (IsSameVisit(visit, kind) &&
          (!kCheckIsControlFlow || kIsControlFlow == HInstruction::IsControlFlow(kind))) {
        return kind;
      }
    }
    LOG(FATAL) << "Compile time error when executed in constexpr context.";
    UNREACHABLE();
  }

  HGraph* graph_;
};

// Create a clone of the instruction, insert it into the graph; replace the old one with a new
// and remove the old instruction.
HInstruction* ReplaceInstrOrPhiByClone(HInstruction* instr);

// Create a clone for each clonable instructions/phis and replace the original with the clone.
//
// Used for testing individual instruction cloner.
class CloneAndReplaceInstructionVisitor final
    : public CRTPGraphVisitor<CloneAndReplaceInstructionVisitor> {
 public:
  explicit CloneAndReplaceInstructionVisitor(HGraph* graph)
      : CRTPGraphVisitor(graph), instr_replaced_by_clones_count_(0) {}

  void VisitInstruction(HInstruction* instruction) {
    if (instruction->IsClonable()) {
      ReplaceInstrOrPhiByClone(instruction);
      instr_replaced_by_clones_count_++;
    }
  }

  size_t GetInstrReplacedByClonesCount() const { return instr_replaced_by_clones_count_; }

 private:
  size_t instr_replaced_by_clones_count_;

  DISALLOW_COPY_AND_ASSIGN(CloneAndReplaceInstructionVisitor);
};

// Returns int64_t value of a properly typed constant.
inline int64_t Int64FromConstant(HConstant* constant) {
  if (constant->IsIntConstant()) {
    return constant->AsIntConstant()->GetValue();
  } else if (constant->IsLongConstant()) {
    return constant->AsLongConstant()->GetValue();
  } else {
    DCHECK(constant->IsNullConstant()) << constant->DebugName();
    return 0;
  }
}

// Returns true iff instruction is an integral constant (and sets value on success).
inline bool IsInt64AndGet(HInstruction* instruction, /*out*/ int64_t* value) {
  if (instruction->IsIntConstant()) {
    *value = instruction->AsIntConstant()->GetValue();
    return true;
  } else if (instruction->IsLongConstant()) {
    *value = instruction->AsLongConstant()->GetValue();
    return true;
  } else if (instruction->IsNullConstant()) {
    *value = 0;
    return true;
  }
  return false;
}

// Returns true iff instruction is the given integral constant.
inline bool IsInt64Value(HInstruction* instruction, int64_t value) {
  int64_t val = 0;
  return IsInt64AndGet(instruction, &val) && val == value;
}

// Returns true iff instruction is a zero bit pattern.
inline bool IsZeroBitPattern(HInstruction* instruction) {
  return instruction->IsConstant() && instruction->AsConstant()->IsZeroBitPattern();
}

// Implement HInstruction::Is##type() for concrete instructions.
#define INSTRUCTION_TYPE_CHECK(type, super)                                    \
  inline bool HInstruction::Is##type() const { return GetKind() == k##type; }
  FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
#undef INSTRUCTION_TYPE_CHECK

// Implement HInstruction::Is##type() for abstract instructions.
#define INSTRUCTION_TYPE_CHECK_RESULT(type, super)                             \
  std::is_base_of<BaseType, H##type>::value,
#define INSTRUCTION_TYPE_CHECK(type, super)                                    \
  inline bool HInstruction::Is##type() const {                                 \
    DCHECK_LT(GetKind(), kLastInstructionKind);                                \
    using BaseType = H##type;                                                  \
    static constexpr bool results[] = {                                        \
        FOR_EACH_CONCRETE_INSTRUCTION(INSTRUCTION_TYPE_CHECK_RESULT)           \
    };                                                                         \
    return results[static_cast<size_t>(GetKind())];                            \
  }

  FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
#undef INSTRUCTION_TYPE_CHECK
#undef INSTRUCTION_TYPE_CHECK_RESULT

#define INSTRUCTION_TYPE_CAST(type, super)                                     \
  inline const H##type* HInstruction::As##type() const {                       \
    DCHECK(Is##type());                                                        \
    return down_cast<const H##type*>(this);                                    \
  }                                                                            \
  inline H##type* HInstruction::As##type() {                                   \
    DCHECK(Is##type());                                                        \
    return down_cast<H##type*>(this);                                          \
  }                                                                            \
  inline const H##type* HInstruction::As##type##OrNull() const {               \
    return Is##type() ? down_cast<const H##type*>(this) : nullptr;             \
  }                                                                            \
  inline H##type* HInstruction::As##type##OrNull() {                           \
    return Is##type() ? down_cast<H##type*>(this) : nullptr;                   \
  }

  FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CAST)
#undef INSTRUCTION_TYPE_CAST


// Create space in `blocks` for adding `number_of_new_blocks` entries
// starting at location `at`. Blocks after `at` are moved accordingly.
inline void MakeRoomFor(ArenaVector<HBasicBlock*>* blocks,
                        size_t number_of_new_blocks,
                        size_t after) {
  DCHECK_LT(after, blocks->size());
  size_t old_size = blocks->size();
  size_t new_size = old_size + number_of_new_blocks;
  blocks->resize(new_size);
  std::copy_backward(blocks->begin() + after + 1u, blocks->begin() + old_size, blocks->end());
}

/*
 * Hunt "under the hood" of array lengths (leading to array references),
 * null checks (also leading to array references), and new arrays
 * (leading to the actual length). This makes it more likely related
 * instructions become actually comparable.
 */

inline HInstruction* HuntForDeclaration(HInstruction* instruction) {
  while (instruction->IsArrayLength() ||
         instruction->IsNullCheck() ||
         instruction->IsNewArray()) {
    instruction = instruction->IsNewArray()
        ? instruction->AsNewArray()->GetLength()
        : instruction->InputAt(0);
  }
  return instruction;
}

inline bool IsAddOrSub(const HInstruction* instruction) {
  return instruction->IsAdd() || instruction->IsSub();
}

bool HasEnvironmentUsedByOthers(HInstruction* instruction);
void ResetEnvironmentInputRecords(HInstruction* instruction);

// Detects an instruction that is >= 0. As long as the value is carried by
// a single instruction, arithmetic wrap-around cannot occur.
bool IsGEZero(HInstruction* instruction);

//
// Helper functions that determine whether an instruction's environment must be
// precise, i.e. whether the associated stack map should include vregister mappings.
//

// Returns whether a graph requires precise HEnvironment.
//
// It is true in the following cases:
//  * Debuggable graph
//    when we want to observe the values / asynchronously deoptimize.
//  * Monitor operations
//    to allow dumping in a stack trace locked dex registers for non-debuggable code.
inline bool GraphNeedsPreciseEnvironment(HGraph* graph) {
  return graph->IsDebuggable() || graph->HasMonitorOperations();
}

// Returns whether instruction requires precise HEnvironment, independently from the graph
// properties.
//
// It is true in the following cases:
//  * Deoptimization
//    when we need to obtain the values to restore actual vregisters for interpreter.
//  * On-stack-replacement (OSR)
//    when entering compiled for OSR code from the interpreter we need to initialize the compiled
//    code values with the values from the vregisters. Not all instructions in OSR mode
//    require a precise HEnvironment, only SuspendChecks in the non-inlined loops do.
//  * Method local catch blocks
//    a catch block must see the environment of the instruction from the same method that can
//    throw to this block.
//  * First instruction of a catch block
//    a catch block's first instruction is always Nop that requires precise HEnvironment as
//    it is used to emit catch block information.
inline bool InstructionNeedsPreciseEnvironment(HInstruction* instruction, bool osr) {
  HBasicBlock* bb = instruction->GetBlock();
  if (instruction->IsDeoptimize() || instruction->CanThrowIntoCatchBlock() || osr) {
    return true;
  }
  if (bb->IsCatchBlock() && bb->GetFirstInstruction() == instruction) {
    DCHECK(instruction->IsNop());
    return true;
  }
  return false;
}

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_NODES_H_

Messung V0.5 in Prozent
C=91 H=97 G=93

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen1.63Angebot  ¤

*Bot Zugriff






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.