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