Home | History | Annotate | Download | only in optimizing
      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 "base/arena_containers.h"
     21 #include "base/arena_object.h"
     22 #include "dex/compiler_enums.h"
     23 #include "entrypoints/quick/quick_entrypoints_enum.h"
     24 #include "handle.h"
     25 #include "handle_scope.h"
     26 #include "invoke_type.h"
     27 #include "locations.h"
     28 #include "mirror/class.h"
     29 #include "offsets.h"
     30 #include "primitive.h"
     31 #include "utils/arena_bit_vector.h"
     32 #include "utils/growable_array.h"
     33 
     34 namespace art {
     35 
     36 class GraphChecker;
     37 class HBasicBlock;
     38 class HDoubleConstant;
     39 class HEnvironment;
     40 class HFloatConstant;
     41 class HGraphVisitor;
     42 class HInstruction;
     43 class HIntConstant;
     44 class HInvoke;
     45 class HLongConstant;
     46 class HNullConstant;
     47 class HPhi;
     48 class HSuspendCheck;
     49 class LiveInterval;
     50 class LocationSummary;
     51 class SlowPathCode;
     52 class SsaBuilder;
     53 
     54 static const int kDefaultNumberOfBlocks = 8;
     55 static const int kDefaultNumberOfSuccessors = 2;
     56 static const int kDefaultNumberOfPredecessors = 2;
     57 static const int kDefaultNumberOfDominatedBlocks = 1;
     58 static const int kDefaultNumberOfBackEdges = 1;
     59 
     60 static constexpr uint32_t kMaxIntShiftValue = 0x1f;
     61 static constexpr uint64_t kMaxLongShiftValue = 0x3f;
     62 
     63 enum IfCondition {
     64   kCondEQ,
     65   kCondNE,
     66   kCondLT,
     67   kCondLE,
     68   kCondGT,
     69   kCondGE,
     70 };
     71 
     72 class HInstructionList {
     73  public:
     74   HInstructionList() : first_instruction_(nullptr), last_instruction_(nullptr) {}
     75 
     76   void AddInstruction(HInstruction* instruction);
     77   void RemoveInstruction(HInstruction* instruction);
     78 
     79   // Insert `instruction` before/after an existing instruction `cursor`.
     80   void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor);
     81   void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor);
     82 
     83   // Return true if this list contains `instruction`.
     84   bool Contains(HInstruction* instruction) const;
     85 
     86   // Return true if `instruction1` is found before `instruction2` in
     87   // this instruction list and false otherwise.  Abort if none
     88   // of these instructions is found.
     89   bool FoundBefore(const HInstruction* instruction1,
     90                    const HInstruction* instruction2) const;
     91 
     92   bool IsEmpty() const { return first_instruction_ == nullptr; }
     93   void Clear() { first_instruction_ = last_instruction_ = nullptr; }
     94 
     95   // Update the block of all instructions to be `block`.
     96   void SetBlockOfInstructions(HBasicBlock* block) const;
     97 
     98   void AddAfter(HInstruction* cursor, const HInstructionList& instruction_list);
     99   void Add(const HInstructionList& instruction_list);
    100 
    101   // Return the number of instructions in the list. This is an expensive operation.
    102   size_t CountSize() const;
    103 
    104  private:
    105   HInstruction* first_instruction_;
    106   HInstruction* last_instruction_;
    107 
    108   friend class HBasicBlock;
    109   friend class HGraph;
    110   friend class HInstruction;
    111   friend class HInstructionIterator;
    112   friend class HBackwardInstructionIterator;
    113 
    114   DISALLOW_COPY_AND_ASSIGN(HInstructionList);
    115 };
    116 
    117 // Control-flow graph of a method. Contains a list of basic blocks.
    118 class HGraph : public ArenaObject<kArenaAllocMisc> {
    119  public:
    120   HGraph(ArenaAllocator* arena,
    121          const DexFile& dex_file,
    122          uint32_t method_idx,
    123          InstructionSet instruction_set,
    124          bool debuggable = false,
    125          int start_instruction_id = 0)
    126       : arena_(arena),
    127         blocks_(arena, kDefaultNumberOfBlocks),
    128         reverse_post_order_(arena, kDefaultNumberOfBlocks),
    129         linear_order_(arena, kDefaultNumberOfBlocks),
    130         entry_block_(nullptr),
    131         exit_block_(nullptr),
    132         maximum_number_of_out_vregs_(0),
    133         number_of_vregs_(0),
    134         number_of_in_vregs_(0),
    135         temporaries_vreg_slots_(0),
    136         has_bounds_checks_(false),
    137         debuggable_(debuggable),
    138         current_instruction_id_(start_instruction_id),
    139         dex_file_(dex_file),
    140         method_idx_(method_idx),
    141         instruction_set_(instruction_set),
    142         cached_null_constant_(nullptr),
    143         cached_int_constants_(std::less<int32_t>(), arena->Adapter()),
    144         cached_float_constants_(std::less<int32_t>(), arena->Adapter()),
    145         cached_long_constants_(std::less<int64_t>(), arena->Adapter()),
    146         cached_double_constants_(std::less<int64_t>(), arena->Adapter()) {}
    147 
    148   ArenaAllocator* GetArena() const { return arena_; }
    149   const GrowableArray<HBasicBlock*>& GetBlocks() const { return blocks_; }
    150   HBasicBlock* GetBlock(size_t id) const { return blocks_.Get(id); }
    151 
    152   HBasicBlock* GetEntryBlock() const { return entry_block_; }
    153   HBasicBlock* GetExitBlock() const { return exit_block_; }
    154 
    155   void SetEntryBlock(HBasicBlock* block) { entry_block_ = block; }
    156   void SetExitBlock(HBasicBlock* block) { exit_block_ = block; }
    157 
    158   void AddBlock(HBasicBlock* block);
    159 
    160   // Try building the SSA form of this graph, with dominance computation and loop
    161   // recognition. Returns whether it was successful in doing all these steps.
    162   bool TryBuildingSsa() {
    163     BuildDominatorTree();
    164     // The SSA builder requires loops to all be natural. Specifically, the dead phi
    165     // elimination phase checks the consistency of the graph when doing a post-order
    166     // visit for eliminating dead phis: a dead phi can only have loop header phi
    167     // users remaining when being visited.
    168     if (!AnalyzeNaturalLoops()) return false;
    169     TransformToSsa();
    170     return true;
    171   }
    172 
    173   void ComputeDominanceInformation();
    174   void ClearDominanceInformation();
    175 
    176   void BuildDominatorTree();
    177   void TransformToSsa();
    178   void SimplifyCFG();
    179 
    180   // Analyze all natural loops in this graph. Returns false if one
    181   // loop is not natural, that is the header does not dominate the
    182   // back edge.
    183   bool AnalyzeNaturalLoops() const;
    184 
    185   // Inline this graph in `outer_graph`, replacing the given `invoke` instruction.
    186   void InlineInto(HGraph* outer_graph, HInvoke* invoke);
    187 
    188   // Need to add a couple of blocks to test if the loop body is entered and
    189   // put deoptimization instructions, etc.
    190   void TransformLoopHeaderForBCE(HBasicBlock* header);
    191 
    192   // Removes `block` from the graph.
    193   void DeleteDeadBlock(HBasicBlock* block);
    194 
    195   void SplitCriticalEdge(HBasicBlock* block, HBasicBlock* successor);
    196   void SimplifyLoop(HBasicBlock* header);
    197 
    198   int32_t GetNextInstructionId() {
    199     DCHECK_NE(current_instruction_id_, INT32_MAX);
    200     return current_instruction_id_++;
    201   }
    202 
    203   int32_t GetCurrentInstructionId() const {
    204     return current_instruction_id_;
    205   }
    206 
    207   void SetCurrentInstructionId(int32_t id) {
    208     current_instruction_id_ = id;
    209   }
    210 
    211   uint16_t GetMaximumNumberOfOutVRegs() const {
    212     return maximum_number_of_out_vregs_;
    213   }
    214 
    215   void SetMaximumNumberOfOutVRegs(uint16_t new_value) {
    216     maximum_number_of_out_vregs_ = new_value;
    217   }
    218 
    219   void UpdateTemporariesVRegSlots(size_t slots) {
    220     temporaries_vreg_slots_ = std::max(slots, temporaries_vreg_slots_);
    221   }
    222 
    223   size_t GetTemporariesVRegSlots() const {
    224     return temporaries_vreg_slots_;
    225   }
    226 
    227   void SetNumberOfVRegs(uint16_t number_of_vregs) {
    228     number_of_vregs_ = number_of_vregs;
    229   }
    230 
    231   uint16_t GetNumberOfVRegs() const {
    232     return number_of_vregs_;
    233   }
    234 
    235   void SetNumberOfInVRegs(uint16_t value) {
    236     number_of_in_vregs_ = value;
    237   }
    238 
    239   uint16_t GetNumberOfLocalVRegs() const {
    240     return number_of_vregs_ - number_of_in_vregs_;
    241   }
    242 
    243   const GrowableArray<HBasicBlock*>& GetReversePostOrder() const {
    244     return reverse_post_order_;
    245   }
    246 
    247   const GrowableArray<HBasicBlock*>& GetLinearOrder() const {
    248     return linear_order_;
    249   }
    250 
    251   bool HasBoundsChecks() const {
    252     return has_bounds_checks_;
    253   }
    254 
    255   void SetHasBoundsChecks(bool value) {
    256     has_bounds_checks_ = value;
    257   }
    258 
    259   bool IsDebuggable() const { return debuggable_; }
    260 
    261   // Returns a constant of the given type and value. If it does not exist
    262   // already, it is created and inserted into the graph. This method is only for
    263   // integral types.
    264   HConstant* GetConstant(Primitive::Type type, int64_t value);
    265   HNullConstant* GetNullConstant();
    266   HIntConstant* GetIntConstant(int32_t value) {
    267     return CreateConstant(value, &cached_int_constants_);
    268   }
    269   HLongConstant* GetLongConstant(int64_t value) {
    270     return CreateConstant(value, &cached_long_constants_);
    271   }
    272   HFloatConstant* GetFloatConstant(float value) {
    273     return CreateConstant(bit_cast<int32_t, float>(value), &cached_float_constants_);
    274   }
    275   HDoubleConstant* GetDoubleConstant(double value) {
    276     return CreateConstant(bit_cast<int64_t, double>(value), &cached_double_constants_);
    277   }
    278 
    279   HBasicBlock* FindCommonDominator(HBasicBlock* first, HBasicBlock* second) const;
    280 
    281   const DexFile& GetDexFile() const {
    282     return dex_file_;
    283   }
    284 
    285   uint32_t GetMethodIdx() const {
    286     return method_idx_;
    287   }
    288 
    289  private:
    290   void VisitBlockForDominatorTree(HBasicBlock* block,
    291                                   HBasicBlock* predecessor,
    292                                   GrowableArray<size_t>* visits);
    293   void FindBackEdges(ArenaBitVector* visited);
    294   void VisitBlockForBackEdges(HBasicBlock* block,
    295                               ArenaBitVector* visited,
    296                               ArenaBitVector* visiting);
    297   void RemoveInstructionsAsUsersFromDeadBlocks(const ArenaBitVector& visited) const;
    298   void RemoveDeadBlocks(const ArenaBitVector& visited);
    299 
    300   template <class InstructionType, typename ValueType>
    301   InstructionType* CreateConstant(ValueType value,
    302                                   ArenaSafeMap<ValueType, InstructionType*>* cache) {
    303     // Try to find an existing constant of the given value.
    304     InstructionType* constant = nullptr;
    305     auto cached_constant = cache->find(value);
    306     if (cached_constant != cache->end()) {
    307       constant = cached_constant->second;
    308     }
    309 
    310     // If not found or previously deleted, create and cache a new instruction.
    311     if (constant == nullptr || constant->GetBlock() == nullptr) {
    312       constant = new (arena_) InstructionType(value);
    313       cache->Overwrite(value, constant);
    314       InsertConstant(constant);
    315     }
    316     return constant;
    317   }
    318 
    319   void InsertConstant(HConstant* instruction);
    320 
    321   // Cache a float constant into the graph. This method should only be
    322   // called by the SsaBuilder when creating "equivalent" instructions.
    323   void CacheFloatConstant(HFloatConstant* constant);
    324 
    325   // See CacheFloatConstant comment.
    326   void CacheDoubleConstant(HDoubleConstant* constant);
    327 
    328   ArenaAllocator* const arena_;
    329 
    330   // List of blocks in insertion order.
    331   GrowableArray<HBasicBlock*> blocks_;
    332 
    333   // List of blocks to perform a reverse post order tree traversal.
    334   GrowableArray<HBasicBlock*> reverse_post_order_;
    335 
    336   // List of blocks to perform a linear order tree traversal.
    337   GrowableArray<HBasicBlock*> linear_order_;
    338 
    339   HBasicBlock* entry_block_;
    340   HBasicBlock* exit_block_;
    341 
    342   // The maximum number of virtual registers arguments passed to a HInvoke in this graph.
    343   uint16_t maximum_number_of_out_vregs_;
    344 
    345   // The number of virtual registers in this method. Contains the parameters.
    346   uint16_t number_of_vregs_;
    347 
    348   // The number of virtual registers used by parameters of this method.
    349   uint16_t number_of_in_vregs_;
    350 
    351   // Number of vreg size slots that the temporaries use (used in baseline compiler).
    352   size_t temporaries_vreg_slots_;
    353 
    354   // Has bounds checks. We can totally skip BCE if it's false.
    355   bool has_bounds_checks_;
    356 
    357   // Indicates whether the graph should be compiled in a way that
    358   // ensures full debuggability. If false, we can apply more
    359   // aggressive optimizations that may limit the level of debugging.
    360   const bool debuggable_;
    361 
    362   // The current id to assign to a newly added instruction. See HInstruction.id_.
    363   int32_t current_instruction_id_;
    364 
    365   // The dex file from which the method is from.
    366   const DexFile& dex_file_;
    367 
    368   // The method index in the dex file.
    369   const uint32_t method_idx_;
    370 
    371   const InstructionSet instruction_set_;
    372 
    373   // Cached constants.
    374   HNullConstant* cached_null_constant_;
    375   ArenaSafeMap<int32_t, HIntConstant*> cached_int_constants_;
    376   ArenaSafeMap<int32_t, HFloatConstant*> cached_float_constants_;
    377   ArenaSafeMap<int64_t, HLongConstant*> cached_long_constants_;
    378   ArenaSafeMap<int64_t, HDoubleConstant*> cached_double_constants_;
    379 
    380   friend class SsaBuilder;           // For caching constants.
    381   friend class SsaLivenessAnalysis;  // For the linear order.
    382   ART_FRIEND_TEST(GraphTest, IfSuccessorSimpleJoinBlock1);
    383   DISALLOW_COPY_AND_ASSIGN(HGraph);
    384 };
    385 
    386 class HLoopInformation : public ArenaObject<kArenaAllocMisc> {
    387  public:
    388   HLoopInformation(HBasicBlock* header, HGraph* graph)
    389       : header_(header),
    390         suspend_check_(nullptr),
    391         back_edges_(graph->GetArena(), kDefaultNumberOfBackEdges),
    392         // Make bit vector growable, as the number of blocks may change.
    393         blocks_(graph->GetArena(), graph->GetBlocks().Size(), true) {}
    394 
    395   HBasicBlock* GetHeader() const {
    396     return header_;
    397   }
    398 
    399   void SetHeader(HBasicBlock* block) {
    400     header_ = block;
    401   }
    402 
    403   HSuspendCheck* GetSuspendCheck() const { return suspend_check_; }
    404   void SetSuspendCheck(HSuspendCheck* check) { suspend_check_ = check; }
    405   bool HasSuspendCheck() const { return suspend_check_ != nullptr; }
    406 
    407   void AddBackEdge(HBasicBlock* back_edge) {
    408     back_edges_.Add(back_edge);
    409   }
    410 
    411   void RemoveBackEdge(HBasicBlock* back_edge) {
    412     back_edges_.Delete(back_edge);
    413   }
    414 
    415   bool IsBackEdge(const HBasicBlock& block) const {
    416     for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
    417       if (back_edges_.Get(i) == &block) return true;
    418     }
    419     return false;
    420   }
    421 
    422   size_t NumberOfBackEdges() const {
    423     return back_edges_.Size();
    424   }
    425 
    426   HBasicBlock* GetPreHeader() const;
    427 
    428   const GrowableArray<HBasicBlock*>& GetBackEdges() const {
    429     return back_edges_;
    430   }
    431 
    432   // Returns the lifetime position of the back edge that has the
    433   // greatest lifetime position.
    434   size_t GetLifetimeEnd() const;
    435 
    436   void ReplaceBackEdge(HBasicBlock* existing, HBasicBlock* new_back_edge) {
    437     for (size_t i = 0, e = back_edges_.Size(); i < e; ++i) {
    438       if (back_edges_.Get(i) == existing) {
    439         back_edges_.Put(i, new_back_edge);
    440         return;
    441       }
    442     }
    443     UNREACHABLE();
    444   }
    445 
    446   // Finds blocks that are part of this loop. Returns whether the loop is a natural loop,
    447   // that is the header dominates the back edge.
    448   bool Populate();
    449 
    450   // Reanalyzes the loop by removing loop info from its blocks and re-running
    451   // Populate(). If there are no back edges left, the loop info is completely
    452   // removed as well as its SuspendCheck instruction. It must be run on nested
    453   // inner loops first.
    454   void Update();
    455 
    456   // Returns whether this loop information contains `block`.
    457   // Note that this loop information *must* be populated before entering this function.
    458   bool Contains(const HBasicBlock& block) const;
    459 
    460   // Returns whether this loop information is an inner loop of `other`.
    461   // Note that `other` *must* be populated before entering this function.
    462   bool IsIn(const HLoopInformation& other) const;
    463 
    464   const ArenaBitVector& GetBlocks() const { return blocks_; }
    465 
    466   void Add(HBasicBlock* block);
    467   void Remove(HBasicBlock* block);
    468 
    469  private:
    470   // Internal recursive implementation of `Populate`.
    471   void PopulateRecursive(HBasicBlock* block);
    472 
    473   HBasicBlock* header_;
    474   HSuspendCheck* suspend_check_;
    475   GrowableArray<HBasicBlock*> back_edges_;
    476   ArenaBitVector blocks_;
    477 
    478   DISALLOW_COPY_AND_ASSIGN(HLoopInformation);
    479 };
    480 
    481 static constexpr size_t kNoLifetime = -1;
    482 static constexpr uint32_t kNoDexPc = -1;
    483 
    484 // A block in a method. Contains the list of instructions represented
    485 // as a double linked list. Each block knows its predecessors and
    486 // successors.
    487 
    488 class HBasicBlock : public ArenaObject<kArenaAllocMisc> {
    489  public:
    490   explicit HBasicBlock(HGraph* graph, uint32_t dex_pc = kNoDexPc)
    491       : graph_(graph),
    492         predecessors_(graph->GetArena(), kDefaultNumberOfPredecessors),
    493         successors_(graph->GetArena(), kDefaultNumberOfSuccessors),
    494         loop_information_(nullptr),
    495         dominator_(nullptr),
    496         dominated_blocks_(graph->GetArena(), kDefaultNumberOfDominatedBlocks),
    497         block_id_(-1),
    498         dex_pc_(dex_pc),
    499         lifetime_start_(kNoLifetime),
    500         lifetime_end_(kNoLifetime),
    501         is_catch_block_(false) {}
    502 
    503   const GrowableArray<HBasicBlock*>& GetPredecessors() const {
    504     return predecessors_;
    505   }
    506 
    507   const GrowableArray<HBasicBlock*>& GetSuccessors() const {
    508     return successors_;
    509   }
    510 
    511   const GrowableArray<HBasicBlock*>& GetDominatedBlocks() const {
    512     return dominated_blocks_;
    513   }
    514 
    515   bool IsEntryBlock() const {
    516     return graph_->GetEntryBlock() == this;
    517   }
    518 
    519   bool IsExitBlock() const {
    520     return graph_->GetExitBlock() == this;
    521   }
    522 
    523   bool IsSingleGoto() const;
    524 
    525   void AddBackEdge(HBasicBlock* back_edge) {
    526     if (loop_information_ == nullptr) {
    527       loop_information_ = new (graph_->GetArena()) HLoopInformation(this, graph_);
    528     }
    529     DCHECK_EQ(loop_information_->GetHeader(), this);
    530     loop_information_->AddBackEdge(back_edge);
    531   }
    532 
    533   HGraph* GetGraph() const { return graph_; }
    534   void SetGraph(HGraph* graph) { graph_ = graph; }
    535 
    536   int GetBlockId() const { return block_id_; }
    537   void SetBlockId(int id) { block_id_ = id; }
    538 
    539   HBasicBlock* GetDominator() const { return dominator_; }
    540   void SetDominator(HBasicBlock* dominator) { dominator_ = dominator; }
    541   void AddDominatedBlock(HBasicBlock* block) { dominated_blocks_.Add(block); }
    542   void RemoveDominatedBlock(HBasicBlock* block) { dominated_blocks_.Delete(block); }
    543   void ReplaceDominatedBlock(HBasicBlock* existing, HBasicBlock* new_block) {
    544     for (size_t i = 0, e = dominated_blocks_.Size(); i < e; ++i) {
    545       if (dominated_blocks_.Get(i) == existing) {
    546         dominated_blocks_.Put(i, new_block);
    547         return;
    548       }
    549     }
    550     LOG(FATAL) << "Unreachable";
    551     UNREACHABLE();
    552   }
    553   void ClearDominanceInformation();
    554 
    555   int NumberOfBackEdges() const {
    556     return IsLoopHeader() ? loop_information_->NumberOfBackEdges() : 0;
    557   }
    558 
    559   HInstruction* GetFirstInstruction() const { return instructions_.first_instruction_; }
    560   HInstruction* GetLastInstruction() const { return instructions_.last_instruction_; }
    561   const HInstructionList& GetInstructions() const { return instructions_; }
    562   HInstruction* GetFirstPhi() const { return phis_.first_instruction_; }
    563   HInstruction* GetLastPhi() const { return phis_.last_instruction_; }
    564   const HInstructionList& GetPhis() const { return phis_; }
    565 
    566   void AddSuccessor(HBasicBlock* block) {
    567     successors_.Add(block);
    568     block->predecessors_.Add(this);
    569   }
    570 
    571   void ReplaceSuccessor(HBasicBlock* existing, HBasicBlock* new_block) {
    572     size_t successor_index = GetSuccessorIndexOf(existing);
    573     DCHECK_NE(successor_index, static_cast<size_t>(-1));
    574     existing->RemovePredecessor(this);
    575     new_block->predecessors_.Add(this);
    576     successors_.Put(successor_index, new_block);
    577   }
    578 
    579   void ReplacePredecessor(HBasicBlock* existing, HBasicBlock* new_block) {
    580     size_t predecessor_index = GetPredecessorIndexOf(existing);
    581     DCHECK_NE(predecessor_index, static_cast<size_t>(-1));
    582     existing->RemoveSuccessor(this);
    583     new_block->successors_.Add(this);
    584     predecessors_.Put(predecessor_index, new_block);
    585   }
    586 
    587   // Insert `this` between `predecessor` and `successor. This method
    588   // preserves the indicies, and will update the first edge found between
    589   // `predecessor` and `successor`.
    590   void InsertBetween(HBasicBlock* predecessor, HBasicBlock* successor) {
    591     size_t predecessor_index = successor->GetPredecessorIndexOf(predecessor);
    592     DCHECK_NE(predecessor_index, static_cast<size_t>(-1));
    593     size_t successor_index = predecessor->GetSuccessorIndexOf(successor);
    594     DCHECK_NE(successor_index, static_cast<size_t>(-1));
    595     successor->predecessors_.Put(predecessor_index, this);
    596     predecessor->successors_.Put(successor_index, this);
    597     successors_.Add(successor);
    598     predecessors_.Add(predecessor);
    599   }
    600 
    601   void RemovePredecessor(HBasicBlock* block) {
    602     predecessors_.Delete(block);
    603   }
    604 
    605   void RemoveSuccessor(HBasicBlock* block) {
    606     successors_.Delete(block);
    607   }
    608 
    609   void ClearAllPredecessors() {
    610     predecessors_.Reset();
    611   }
    612 
    613   void AddPredecessor(HBasicBlock* block) {
    614     predecessors_.Add(block);
    615     block->successors_.Add(this);
    616   }
    617 
    618   void SwapPredecessors() {
    619     DCHECK_EQ(predecessors_.Size(), 2u);
    620     HBasicBlock* temp = predecessors_.Get(0);
    621     predecessors_.Put(0, predecessors_.Get(1));
    622     predecessors_.Put(1, temp);
    623   }
    624 
    625   void SwapSuccessors() {
    626     DCHECK_EQ(successors_.Size(), 2u);
    627     HBasicBlock* temp = successors_.Get(0);
    628     successors_.Put(0, successors_.Get(1));
    629     successors_.Put(1, temp);
    630   }
    631 
    632   size_t GetPredecessorIndexOf(HBasicBlock* predecessor) {
    633     for (size_t i = 0, e = predecessors_.Size(); i < e; ++i) {
    634       if (predecessors_.Get(i) == predecessor) {
    635         return i;
    636       }
    637     }
    638     return -1;
    639   }
    640 
    641   size_t GetSuccessorIndexOf(HBasicBlock* successor) {
    642     for (size_t i = 0, e = successors_.Size(); i < e; ++i) {
    643       if (successors_.Get(i) == successor) {
    644         return i;
    645       }
    646     }
    647     return -1;
    648   }
    649 
    650   // Split the block into two blocks just after `cursor`. Returns the newly
    651   // created block. Note that this method just updates raw block information,
    652   // like predecessors, successors, dominators, and instruction list. It does not
    653   // update the graph, reverse post order, loop information, nor make sure the
    654   // blocks are consistent (for example ending with a control flow instruction).
    655   HBasicBlock* SplitAfter(HInstruction* cursor);
    656 
    657   // Merge `other` at the end of `this`. Successors and dominated blocks of
    658   // `other` are changed to be successors and dominated blocks of `this`. Note
    659   // that this method does not update the graph, reverse post order, loop
    660   // information, nor make sure the blocks are consistent (for example ending
    661   // with a control flow instruction).
    662   void MergeWithInlined(HBasicBlock* other);
    663 
    664   // Replace `this` with `other`. Predecessors, successors, and dominated blocks
    665   // of `this` are moved to `other`.
    666   // Note that this method does not update the graph, reverse post order, loop
    667   // information, nor make sure the blocks are consistent (for example ending
    668   // with a control flow instruction).
    669   void ReplaceWith(HBasicBlock* other);
    670 
    671   // Merge `other` at the end of `this`. This method updates loops, reverse post
    672   // order, links to predecessors, successors, dominators and deletes the block
    673   // from the graph. The two blocks must be successive, i.e. `this` the only
    674   // predecessor of `other` and vice versa.
    675   void MergeWith(HBasicBlock* other);
    676 
    677   // Disconnects `this` from all its predecessors, successors and dominator,
    678   // removes it from all loops it is included in and eventually from the graph.
    679   // The block must not dominate any other block. Predecessors and successors
    680   // are safely updated.
    681   void DisconnectAndDelete();
    682 
    683   void AddInstruction(HInstruction* instruction);
    684   // Insert `instruction` before/after an existing instruction `cursor`.
    685   void InsertInstructionBefore(HInstruction* instruction, HInstruction* cursor);
    686   void InsertInstructionAfter(HInstruction* instruction, HInstruction* cursor);
    687   // Replace instruction `initial` with `replacement` within this block.
    688   void ReplaceAndRemoveInstructionWith(HInstruction* initial,
    689                                        HInstruction* replacement);
    690   void AddPhi(HPhi* phi);
    691   void InsertPhiAfter(HPhi* instruction, HPhi* cursor);
    692   // RemoveInstruction and RemovePhi delete a given instruction from the respective
    693   // instruction list. With 'ensure_safety' set to true, it verifies that the
    694   // instruction is not in use and removes it from the use lists of its inputs.
    695   void RemoveInstruction(HInstruction* instruction, bool ensure_safety = true);
    696   void RemovePhi(HPhi* phi, bool ensure_safety = true);
    697   void RemoveInstructionOrPhi(HInstruction* instruction, bool ensure_safety = true);
    698 
    699   bool IsLoopHeader() const {
    700     return IsInLoop() && (loop_information_->GetHeader() == this);
    701   }
    702 
    703   bool IsLoopPreHeaderFirstPredecessor() const {
    704     DCHECK(IsLoopHeader());
    705     DCHECK(!GetPredecessors().IsEmpty());
    706     return GetPredecessors().Get(0) == GetLoopInformation()->GetPreHeader();
    707   }
    708 
    709   HLoopInformation* GetLoopInformation() const {
    710     return loop_information_;
    711   }
    712 
    713   // Set the loop_information_ on this block. Overrides the current
    714   // loop_information if it is an outer loop of the passed loop information.
    715   // Note that this method is called while creating the loop information.
    716   void SetInLoop(HLoopInformation* info) {
    717     if (IsLoopHeader()) {
    718       // Nothing to do. This just means `info` is an outer loop.
    719     } else if (!IsInLoop()) {
    720       loop_information_ = info;
    721     } else if (loop_information_->Contains(*info->GetHeader())) {
    722       // Block is currently part of an outer loop. Make it part of this inner loop.
    723       // Note that a non loop header having a loop information means this loop information
    724       // has already been populated
    725       loop_information_ = info;
    726     } else {
    727       // Block is part of an inner loop. Do not update the loop information.
    728       // Note that we cannot do the check `info->Contains(loop_information_)->GetHeader()`
    729       // at this point, because this method is being called while populating `info`.
    730     }
    731   }
    732 
    733   // Raw update of the loop information.
    734   void SetLoopInformation(HLoopInformation* info) {
    735     loop_information_ = info;
    736   }
    737 
    738   bool IsInLoop() const { return loop_information_ != nullptr; }
    739 
    740   // Returns whether this block dominates the blocked passed as parameter.
    741   bool Dominates(HBasicBlock* block) const;
    742 
    743   size_t GetLifetimeStart() const { return lifetime_start_; }
    744   size_t GetLifetimeEnd() const { return lifetime_end_; }
    745 
    746   void SetLifetimeStart(size_t start) { lifetime_start_ = start; }
    747   void SetLifetimeEnd(size_t end) { lifetime_end_ = end; }
    748 
    749   uint32_t GetDexPc() const { return dex_pc_; }
    750 
    751   bool IsCatchBlock() const { return is_catch_block_; }
    752   void SetIsCatchBlock() { is_catch_block_ = true; }
    753 
    754   bool EndsWithControlFlowInstruction() const;
    755   bool EndsWithIf() const;
    756   bool HasSinglePhi() const;
    757 
    758  private:
    759   HGraph* graph_;
    760   GrowableArray<HBasicBlock*> predecessors_;
    761   GrowableArray<HBasicBlock*> successors_;
    762   HInstructionList instructions_;
    763   HInstructionList phis_;
    764   HLoopInformation* loop_information_;
    765   HBasicBlock* dominator_;
    766   GrowableArray<HBasicBlock*> dominated_blocks_;
    767   int block_id_;
    768   // The dex program counter of the first instruction of this block.
    769   const uint32_t dex_pc_;
    770   size_t lifetime_start_;
    771   size_t lifetime_end_;
    772   bool is_catch_block_;
    773 
    774   friend class HGraph;
    775   friend class HInstruction;
    776 
    777   DISALLOW_COPY_AND_ASSIGN(HBasicBlock);
    778 };
    779 
    780 // Iterates over the LoopInformation of all loops which contain 'block'
    781 // from the innermost to the outermost.
    782 class HLoopInformationOutwardIterator : public ValueObject {
    783  public:
    784   explicit HLoopInformationOutwardIterator(const HBasicBlock& block)
    785       : current_(block.GetLoopInformation()) {}
    786 
    787   bool Done() const { return current_ == nullptr; }
    788 
    789   void Advance() {
    790     DCHECK(!Done());
    791     current_ = current_->GetPreHeader()->GetLoopInformation();
    792   }
    793 
    794   HLoopInformation* Current() const {
    795     DCHECK(!Done());
    796     return current_;
    797   }
    798 
    799  private:
    800   HLoopInformation* current_;
    801 
    802   DISALLOW_COPY_AND_ASSIGN(HLoopInformationOutwardIterator);
    803 };
    804 
    805 #define FOR_EACH_CONCRETE_INSTRUCTION(M)                                \
    806   M(Add, BinaryOperation)                                               \
    807   M(And, BinaryOperation)                                               \
    808   M(ArrayGet, Instruction)                                              \
    809   M(ArrayLength, Instruction)                                           \
    810   M(ArraySet, Instruction)                                              \
    811   M(BooleanNot, UnaryOperation)                                         \
    812   M(BoundsCheck, Instruction)                                           \
    813   M(BoundType, Instruction)                                             \
    814   M(CheckCast, Instruction)                                             \
    815   M(ClinitCheck, Instruction)                                           \
    816   M(Compare, BinaryOperation)                                           \
    817   M(Condition, BinaryOperation)                                         \
    818   M(Deoptimize, Instruction)                                            \
    819   M(Div, BinaryOperation)                                               \
    820   M(DivZeroCheck, Instruction)                                          \
    821   M(DoubleConstant, Constant)                                           \
    822   M(Equal, Condition)                                                   \
    823   M(Exit, Instruction)                                                  \
    824   M(FloatConstant, Constant)                                            \
    825   M(Goto, Instruction)                                                  \
    826   M(GreaterThan, Condition)                                             \
    827   M(GreaterThanOrEqual, Condition)                                      \
    828   M(If, Instruction)                                                    \
    829   M(InstanceFieldGet, Instruction)                                      \
    830   M(InstanceFieldSet, Instruction)                                      \
    831   M(InstanceOf, Instruction)                                            \
    832   M(IntConstant, Constant)                                              \
    833   M(InvokeInterface, Invoke)                                            \
    834   M(InvokeStaticOrDirect, Invoke)                                       \
    835   M(InvokeVirtual, Invoke)                                              \
    836   M(LessThan, Condition)                                                \
    837   M(LessThanOrEqual, Condition)                                         \
    838   M(LoadClass, Instruction)                                             \
    839   M(LoadException, Instruction)                                         \
    840   M(LoadLocal, Instruction)                                             \
    841   M(LoadString, Instruction)                                            \
    842   M(Local, Instruction)                                                 \
    843   M(LongConstant, Constant)                                             \
    844   M(MemoryBarrier, Instruction)                                         \
    845   M(MonitorOperation, Instruction)                                      \
    846   M(Mul, BinaryOperation)                                               \
    847   M(Neg, UnaryOperation)                                                \
    848   M(NewArray, Instruction)                                              \
    849   M(NewInstance, Instruction)                                           \
    850   M(Not, UnaryOperation)                                                \
    851   M(NotEqual, Condition)                                                \
    852   M(NullConstant, Instruction)                                          \
    853   M(NullCheck, Instruction)                                             \
    854   M(Or, BinaryOperation)                                                \
    855   M(ParallelMove, Instruction)                                          \
    856   M(ParameterValue, Instruction)                                        \
    857   M(Phi, Instruction)                                                   \
    858   M(Rem, BinaryOperation)                                               \
    859   M(Return, Instruction)                                                \
    860   M(ReturnVoid, Instruction)                                            \
    861   M(Shl, BinaryOperation)                                               \
    862   M(Shr, BinaryOperation)                                               \
    863   M(StaticFieldGet, Instruction)                                        \
    864   M(StaticFieldSet, Instruction)                                        \
    865   M(StoreLocal, Instruction)                                            \
    866   M(Sub, BinaryOperation)                                               \
    867   M(SuspendCheck, Instruction)                                          \
    868   M(Temporary, Instruction)                                             \
    869   M(Throw, Instruction)                                                 \
    870   M(TypeConversion, Instruction)                                        \
    871   M(UShr, BinaryOperation)                                              \
    872   M(Xor, BinaryOperation)                                               \
    873 
    874 #define FOR_EACH_INSTRUCTION(M)                                         \
    875   FOR_EACH_CONCRETE_INSTRUCTION(M)                                      \
    876   M(Constant, Instruction)                                              \
    877   M(UnaryOperation, Instruction)                                        \
    878   M(BinaryOperation, Instruction)                                       \
    879   M(Invoke, Instruction)
    880 
    881 #define FORWARD_DECLARATION(type, super) class H##type;
    882 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
    883 #undef FORWARD_DECLARATION
    884 
    885 #define DECLARE_INSTRUCTION(type)                                       \
    886   InstructionKind GetKind() const OVERRIDE { return k##type; }          \
    887   const char* DebugName() const OVERRIDE { return #type; }              \
    888   const H##type* As##type() const OVERRIDE { return this; }             \
    889   H##type* As##type() OVERRIDE { return this; }                         \
    890   bool InstructionTypeEquals(HInstruction* other) const OVERRIDE {      \
    891     return other->Is##type();                                           \
    892   }                                                                     \
    893   void Accept(HGraphVisitor* visitor) OVERRIDE
    894 
    895 template <typename T> class HUseList;
    896 
    897 template <typename T>
    898 class HUseListNode : public ArenaObject<kArenaAllocMisc> {
    899  public:
    900   HUseListNode* GetPrevious() const { return prev_; }
    901   HUseListNode* GetNext() const { return next_; }
    902   T GetUser() const { return user_; }
    903   size_t GetIndex() const { return index_; }
    904   void SetIndex(size_t index) { index_ = index; }
    905 
    906  private:
    907   HUseListNode(T user, size_t index)
    908       : user_(user), index_(index), prev_(nullptr), next_(nullptr) {}
    909 
    910   T const user_;
    911   size_t index_;
    912   HUseListNode<T>* prev_;
    913   HUseListNode<T>* next_;
    914 
    915   friend class HUseList<T>;
    916 
    917   DISALLOW_COPY_AND_ASSIGN(HUseListNode);
    918 };
    919 
    920 template <typename T>
    921 class HUseList : public ValueObject {
    922  public:
    923   HUseList() : first_(nullptr) {}
    924 
    925   void Clear() {
    926     first_ = nullptr;
    927   }
    928 
    929   // Adds a new entry at the beginning of the use list and returns
    930   // the newly created node.
    931   HUseListNode<T>* AddUse(T user, size_t index, ArenaAllocator* arena) {
    932     HUseListNode<T>* new_node = new (arena) HUseListNode<T>(user, index);
    933     if (IsEmpty()) {
    934       first_ = new_node;
    935     } else {
    936       first_->prev_ = new_node;
    937       new_node->next_ = first_;
    938       first_ = new_node;
    939     }
    940     return new_node;
    941   }
    942 
    943   HUseListNode<T>* GetFirst() const {
    944     return first_;
    945   }
    946 
    947   void Remove(HUseListNode<T>* node) {
    948     DCHECK(node != nullptr);
    949     DCHECK(Contains(node));
    950 
    951     if (node->prev_ != nullptr) {
    952       node->prev_->next_ = node->next_;
    953     }
    954     if (node->next_ != nullptr) {
    955       node->next_->prev_ = node->prev_;
    956     }
    957     if (node == first_) {
    958       first_ = node->next_;
    959     }
    960   }
    961 
    962   bool Contains(const HUseListNode<T>* node) const {
    963     if (node == nullptr) {
    964       return false;
    965     }
    966     for (HUseListNode<T>* current = first_; current != nullptr; current = current->GetNext()) {
    967       if (current == node) {
    968         return true;
    969       }
    970     }
    971     return false;
    972   }
    973 
    974   bool IsEmpty() const {
    975     return first_ == nullptr;
    976   }
    977 
    978   bool HasOnlyOneUse() const {
    979     return first_ != nullptr && first_->next_ == nullptr;
    980   }
    981 
    982   size_t SizeSlow() const {
    983     size_t count = 0;
    984     for (HUseListNode<T>* current = first_; current != nullptr; current = current->GetNext()) {
    985       ++count;
    986     }
    987     return count;
    988   }
    989 
    990  private:
    991   HUseListNode<T>* first_;
    992 };
    993 
    994 template<typename T>
    995 class HUseIterator : public ValueObject {
    996  public:
    997   explicit HUseIterator(const HUseList<T>& uses) : current_(uses.GetFirst()) {}
    998 
    999   bool Done() const { return current_ == nullptr; }
   1000 
   1001   void Advance() {
   1002     DCHECK(!Done());
   1003     current_ = current_->GetNext();
   1004   }
   1005 
   1006   HUseListNode<T>* Current() const {
   1007     DCHECK(!Done());
   1008     return current_;
   1009   }
   1010 
   1011  private:
   1012   HUseListNode<T>* current_;
   1013 
   1014   friend class HValue;
   1015 };
   1016 
   1017 // This class is used by HEnvironment and HInstruction classes to record the
   1018 // instructions they use and pointers to the corresponding HUseListNodes kept
   1019 // by the used instructions.
   1020 template <typename T>
   1021 class HUserRecord : public ValueObject {
   1022  public:
   1023   HUserRecord() : instruction_(nullptr), use_node_(nullptr) {}
   1024   explicit HUserRecord(HInstruction* instruction) : instruction_(instruction), use_node_(nullptr) {}
   1025 
   1026   HUserRecord(const HUserRecord<T>& old_record, HUseListNode<T>* use_node)
   1027     : instruction_(old_record.instruction_), use_node_(use_node) {
   1028     DCHECK(instruction_ != nullptr);
   1029     DCHECK(use_node_ != nullptr);
   1030     DCHECK(old_record.use_node_ == nullptr);
   1031   }
   1032 
   1033   HInstruction* GetInstruction() const { return instruction_; }
   1034   HUseListNode<T>* GetUseNode() const { return use_node_; }
   1035 
   1036  private:
   1037   // Instruction used by the user.
   1038   HInstruction* instruction_;
   1039 
   1040   // Corresponding entry in the use list kept by 'instruction_'.
   1041   HUseListNode<T>* use_node_;
   1042 };
   1043 
   1044 // TODO: Add better documentation to this class and maybe refactor with more suggestive names.
   1045 // - Has(All)SideEffects suggests that all the side effects are present but only ChangesSomething
   1046 //   flag is consider.
   1047 // - DependsOn suggests that there is a real dependency between side effects but it only
   1048 //   checks DependendsOnSomething flag.
   1049 //
   1050 // Represents the side effects an instruction may have.
   1051 class SideEffects : public ValueObject {
   1052  public:
   1053   SideEffects() : flags_(0) {}
   1054 
   1055   static SideEffects None() {
   1056     return SideEffects(0);
   1057   }
   1058 
   1059   static SideEffects All() {
   1060     return SideEffects(ChangesSomething().flags_ | DependsOnSomething().flags_);
   1061   }
   1062 
   1063   static SideEffects ChangesSomething() {
   1064     return SideEffects((1 << kFlagChangesCount) - 1);
   1065   }
   1066 
   1067   static SideEffects DependsOnSomething() {
   1068     int count = kFlagDependsOnCount - kFlagChangesCount;
   1069     return SideEffects(((1 << count) - 1) << kFlagChangesCount);
   1070   }
   1071 
   1072   SideEffects Union(SideEffects other) const {
   1073     return SideEffects(flags_ | other.flags_);
   1074   }
   1075 
   1076   bool HasSideEffects() const {
   1077     size_t all_bits_set = (1 << kFlagChangesCount) - 1;
   1078     return (flags_ & all_bits_set) != 0;
   1079   }
   1080 
   1081   bool HasAllSideEffects() const {
   1082     size_t all_bits_set = (1 << kFlagChangesCount) - 1;
   1083     return all_bits_set == (flags_ & all_bits_set);
   1084   }
   1085 
   1086   bool DependsOn(SideEffects other) const {
   1087     size_t depends_flags = other.ComputeDependsFlags();
   1088     return (flags_ & depends_flags) != 0;
   1089   }
   1090 
   1091   bool HasDependencies() const {
   1092     int count = kFlagDependsOnCount - kFlagChangesCount;
   1093     size_t all_bits_set = (1 << count) - 1;
   1094     return ((flags_ >> kFlagChangesCount) & all_bits_set) != 0;
   1095   }
   1096 
   1097  private:
   1098   static constexpr int kFlagChangesSomething = 0;
   1099   static constexpr int kFlagChangesCount = kFlagChangesSomething + 1;
   1100 
   1101   static constexpr int kFlagDependsOnSomething = kFlagChangesCount;
   1102   static constexpr int kFlagDependsOnCount = kFlagDependsOnSomething + 1;
   1103 
   1104   explicit SideEffects(size_t flags) : flags_(flags) {}
   1105 
   1106   size_t ComputeDependsFlags() const {
   1107     return flags_ << kFlagChangesCount;
   1108   }
   1109 
   1110   size_t flags_;
   1111 };
   1112 
   1113 // A HEnvironment object contains the values of virtual registers at a given location.
   1114 class HEnvironment : public ArenaObject<kArenaAllocMisc> {
   1115  public:
   1116   HEnvironment(ArenaAllocator* arena,
   1117                size_t number_of_vregs,
   1118                const DexFile& dex_file,
   1119                uint32_t method_idx,
   1120                uint32_t dex_pc)
   1121      : vregs_(arena, number_of_vregs),
   1122        locations_(arena, number_of_vregs),
   1123        parent_(nullptr),
   1124        dex_file_(dex_file),
   1125        method_idx_(method_idx),
   1126        dex_pc_(dex_pc) {
   1127     vregs_.SetSize(number_of_vregs);
   1128     for (size_t i = 0; i < number_of_vregs; i++) {
   1129       vregs_.Put(i, HUserRecord<HEnvironment*>());
   1130     }
   1131 
   1132     locations_.SetSize(number_of_vregs);
   1133     for (size_t i = 0; i < number_of_vregs; ++i) {
   1134       locations_.Put(i, Location());
   1135     }
   1136   }
   1137 
   1138   void SetAndCopyParentChain(ArenaAllocator* allocator, HEnvironment* parent) {
   1139     parent_ = new (allocator) HEnvironment(allocator,
   1140                                            parent->Size(),
   1141                                            parent->GetDexFile(),
   1142                                            parent->GetMethodIdx(),
   1143                                            parent->GetDexPc());
   1144     if (parent->GetParent() != nullptr) {
   1145       parent_->SetAndCopyParentChain(allocator, parent->GetParent());
   1146     }
   1147     parent_->CopyFrom(parent);
   1148   }
   1149 
   1150   void CopyFrom(const GrowableArray<HInstruction*>& locals);
   1151   void CopyFrom(HEnvironment* environment);
   1152 
   1153   // Copy from `env`. If it's a loop phi for `loop_header`, copy the first
   1154   // input to the loop phi instead. This is for inserting instructions that
   1155   // require an environment (like HDeoptimization) in the loop pre-header.
   1156   void CopyFromWithLoopPhiAdjustment(HEnvironment* env, HBasicBlock* loop_header);
   1157 
   1158   void SetRawEnvAt(size_t index, HInstruction* instruction) {
   1159     vregs_.Put(index, HUserRecord<HEnvironment*>(instruction));
   1160   }
   1161 
   1162   HInstruction* GetInstructionAt(size_t index) const {
   1163     return vregs_.Get(index).GetInstruction();
   1164   }
   1165 
   1166   void RemoveAsUserOfInput(size_t index) const;
   1167 
   1168   size_t Size() const { return vregs_.Size(); }
   1169 
   1170   HEnvironment* GetParent() const { return parent_; }
   1171 
   1172   void SetLocationAt(size_t index, Location location) {
   1173     locations_.Put(index, location);
   1174   }
   1175 
   1176   Location GetLocationAt(size_t index) const {
   1177     return locations_.Get(index);
   1178   }
   1179 
   1180   uint32_t GetDexPc() const {
   1181     return dex_pc_;
   1182   }
   1183 
   1184   uint32_t GetMethodIdx() const {
   1185     return method_idx_;
   1186   }
   1187 
   1188   const DexFile& GetDexFile() const {
   1189     return dex_file_;
   1190   }
   1191 
   1192  private:
   1193   // Record instructions' use entries of this environment for constant-time removal.
   1194   // It should only be called by HInstruction when a new environment use is added.
   1195   void RecordEnvUse(HUseListNode<HEnvironment*>* env_use) {
   1196     DCHECK(env_use->GetUser() == this);
   1197     size_t index = env_use->GetIndex();
   1198     vregs_.Put(index, HUserRecord<HEnvironment*>(vregs_.Get(index), env_use));
   1199   }
   1200 
   1201   GrowableArray<HUserRecord<HEnvironment*> > vregs_;
   1202   GrowableArray<Location> locations_;
   1203   HEnvironment* parent_;
   1204   const DexFile& dex_file_;
   1205   const uint32_t method_idx_;
   1206   const uint32_t dex_pc_;
   1207 
   1208   friend class HInstruction;
   1209 
   1210   DISALLOW_COPY_AND_ASSIGN(HEnvironment);
   1211 };
   1212 
   1213 class ReferenceTypeInfo : ValueObject {
   1214  public:
   1215   typedef Handle<mirror::Class> TypeHandle;
   1216 
   1217   static ReferenceTypeInfo Create(TypeHandle type_handle, bool is_exact)
   1218       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1219     if (type_handle->IsObjectClass()) {
   1220       // Override the type handle to be consistent with the case when we get to
   1221       // Top but don't have the Object class available. It avoids having to guess
   1222       // what value the type_handle has when it's Top.
   1223       return ReferenceTypeInfo(TypeHandle(), is_exact, true);
   1224     } else {
   1225       return ReferenceTypeInfo(type_handle, is_exact, false);
   1226     }
   1227   }
   1228 
   1229   static ReferenceTypeInfo CreateTop(bool is_exact) {
   1230     return ReferenceTypeInfo(TypeHandle(), is_exact, true);
   1231   }
   1232 
   1233   bool IsExact() const { return is_exact_; }
   1234   bool IsTop() const { return is_top_; }
   1235 
   1236   Handle<mirror::Class> GetTypeHandle() const { return type_handle_; }
   1237 
   1238   bool IsSupertypeOf(ReferenceTypeInfo rti) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1239     if (IsTop()) {
   1240       // Top (equivalent for java.lang.Object) is supertype of anything.
   1241       return true;
   1242     }
   1243     if (rti.IsTop()) {
   1244       // If we get here `this` is not Top() so it can't be a supertype.
   1245       return false;
   1246     }
   1247     return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get());
   1248   }
   1249 
   1250   // Returns true if the type information provide the same amount of details.
   1251   // Note that it does not mean that the instructions have the same actual type
   1252   // (e.g. tops are equal but they can be the result of a merge).
   1253   bool IsEqual(ReferenceTypeInfo rti) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1254     if (IsExact() != rti.IsExact()) {
   1255       return false;
   1256     }
   1257     if (IsTop() && rti.IsTop()) {
   1258       // `Top` means java.lang.Object, so the types are equivalent.
   1259       return true;
   1260     }
   1261     if (IsTop() || rti.IsTop()) {
   1262       // If only one is top or object than they are not equivalent.
   1263       // NB: We need this extra check because the type_handle of `Top` is invalid
   1264       // and we cannot inspect its reference.
   1265       return false;
   1266     }
   1267 
   1268     // Finally check the types.
   1269     return GetTypeHandle().Get() == rti.GetTypeHandle().Get();
   1270   }
   1271 
   1272  private:
   1273   ReferenceTypeInfo() : ReferenceTypeInfo(TypeHandle(), false, true) {}
   1274   ReferenceTypeInfo(TypeHandle type_handle, bool is_exact, bool is_top)
   1275       : type_handle_(type_handle), is_exact_(is_exact), is_top_(is_top) {}
   1276 
   1277   // The class of the object.
   1278   TypeHandle type_handle_;
   1279   // Whether or not the type is exact or a superclass of the actual type.
   1280   // Whether or not we have any information about this type.
   1281   bool is_exact_;
   1282   // A true value here means that the object type should be java.lang.Object.
   1283   // We don't have access to the corresponding mirror object every time so this
   1284   // flag acts as a substitute. When true, the TypeHandle refers to a null
   1285   // pointer and should not be used.
   1286   bool is_top_;
   1287 };
   1288 
   1289 std::ostream& operator<<(std::ostream& os, const ReferenceTypeInfo& rhs);
   1290 
   1291 class HInstruction : public ArenaObject<kArenaAllocMisc> {
   1292  public:
   1293   explicit HInstruction(SideEffects side_effects)
   1294       : previous_(nullptr),
   1295         next_(nullptr),
   1296         block_(nullptr),
   1297         id_(-1),
   1298         ssa_index_(-1),
   1299         environment_(nullptr),
   1300         locations_(nullptr),
   1301         live_interval_(nullptr),
   1302         lifetime_position_(kNoLifetime),
   1303         side_effects_(side_effects),
   1304         reference_type_info_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {}
   1305 
   1306   virtual ~HInstruction() {}
   1307 
   1308 #define DECLARE_KIND(type, super) k##type,
   1309   enum InstructionKind {
   1310     FOR_EACH_INSTRUCTION(DECLARE_KIND)
   1311   };
   1312 #undef DECLARE_KIND
   1313 
   1314   HInstruction* GetNext() const { return next_; }
   1315   HInstruction* GetPrevious() const { return previous_; }
   1316 
   1317   HInstruction* GetNextDisregardingMoves() const;
   1318   HInstruction* GetPreviousDisregardingMoves() const;
   1319 
   1320   HBasicBlock* GetBlock() const { return block_; }
   1321   void SetBlock(HBasicBlock* block) { block_ = block; }
   1322   bool IsInBlock() const { return block_ != nullptr; }
   1323   bool IsInLoop() const { return block_->IsInLoop(); }
   1324   bool IsLoopHeaderPhi() { return IsPhi() && block_->IsLoopHeader(); }
   1325 
   1326   virtual size_t InputCount() const = 0;
   1327   HInstruction* InputAt(size_t i) const { return InputRecordAt(i).GetInstruction(); }
   1328 
   1329   virtual void Accept(HGraphVisitor* visitor) = 0;
   1330   virtual const char* DebugName() const = 0;
   1331 
   1332   virtual Primitive::Type GetType() const { return Primitive::kPrimVoid; }
   1333   void SetRawInputAt(size_t index, HInstruction* input) {
   1334     SetRawInputRecordAt(index, HUserRecord<HInstruction*>(input));
   1335   }
   1336 
   1337   virtual bool NeedsEnvironment() const { return false; }
   1338   virtual uint32_t GetDexPc() const {
   1339     LOG(FATAL) << "GetDexPc() cannot be called on an instruction that"
   1340                   " does not need an environment";
   1341     UNREACHABLE();
   1342   }
   1343   virtual bool IsControlFlow() const { return false; }
   1344   virtual bool CanThrow() const { return false; }
   1345   bool HasSideEffects() const { return side_effects_.HasSideEffects(); }
   1346 
   1347   // Does not apply for all instructions, but having this at top level greatly
   1348   // simplifies the null check elimination.
   1349   virtual bool CanBeNull() const {
   1350     DCHECK_EQ(GetType(), Primitive::kPrimNot) << "CanBeNull only applies to reference types";
   1351     return true;
   1352   }
   1353 
   1354   virtual bool CanDoImplicitNullCheckOn(HInstruction* obj) const {
   1355     UNUSED(obj);
   1356     return false;
   1357   }
   1358 
   1359   void SetReferenceTypeInfo(ReferenceTypeInfo reference_type_info) {
   1360     DCHECK_EQ(GetType(), Primitive::kPrimNot);
   1361     reference_type_info_ = reference_type_info;
   1362   }
   1363 
   1364   ReferenceTypeInfo GetReferenceTypeInfo() const {
   1365     DCHECK_EQ(GetType(), Primitive::kPrimNot);
   1366     return reference_type_info_;
   1367   }
   1368 
   1369   void AddUseAt(HInstruction* user, size_t index) {
   1370     DCHECK(user != nullptr);
   1371     HUseListNode<HInstruction*>* use =
   1372         uses_.AddUse(user, index, GetBlock()->GetGraph()->GetArena());
   1373     user->SetRawInputRecordAt(index, HUserRecord<HInstruction*>(user->InputRecordAt(index), use));
   1374   }
   1375 
   1376   void AddEnvUseAt(HEnvironment* user, size_t index) {
   1377     DCHECK(user != nullptr);
   1378     HUseListNode<HEnvironment*>* env_use =
   1379         env_uses_.AddUse(user, index, GetBlock()->GetGraph()->GetArena());
   1380     user->RecordEnvUse(env_use);
   1381   }
   1382 
   1383   void RemoveAsUserOfInput(size_t input) {
   1384     HUserRecord<HInstruction*> input_use = InputRecordAt(input);
   1385     input_use.GetInstruction()->uses_.Remove(input_use.GetUseNode());
   1386   }
   1387 
   1388   const HUseList<HInstruction*>& GetUses() const { return uses_; }
   1389   const HUseList<HEnvironment*>& GetEnvUses() const { return env_uses_; }
   1390 
   1391   bool HasUses() const { return !uses_.IsEmpty() || !env_uses_.IsEmpty(); }
   1392   bool HasEnvironmentUses() const { return !env_uses_.IsEmpty(); }
   1393   bool HasNonEnvironmentUses() const { return !uses_.IsEmpty(); }
   1394   bool HasOnlyOneNonEnvironmentUse() const {
   1395     return !HasEnvironmentUses() && GetUses().HasOnlyOneUse();
   1396   }
   1397 
   1398   // Does this instruction strictly dominate `other_instruction`?
   1399   // Returns false if this instruction and `other_instruction` are the same.
   1400   // Aborts if this instruction and `other_instruction` are both phis.
   1401   bool StrictlyDominates(HInstruction* other_instruction) const;
   1402 
   1403   int GetId() const { return id_; }
   1404   void SetId(int id) { id_ = id; }
   1405 
   1406   int GetSsaIndex() const { return ssa_index_; }
   1407   void SetSsaIndex(int ssa_index) { ssa_index_ = ssa_index; }
   1408   bool HasSsaIndex() const { return ssa_index_ != -1; }
   1409 
   1410   bool HasEnvironment() const { return environment_ != nullptr; }
   1411   HEnvironment* GetEnvironment() const { return environment_; }
   1412   // Set the `environment_` field. Raw because this method does not
   1413   // update the uses lists.
   1414   void SetRawEnvironment(HEnvironment* environment) { environment_ = environment; }
   1415 
   1416   // Set the environment of this instruction, copying it from `environment`. While
   1417   // copying, the uses lists are being updated.
   1418   void CopyEnvironmentFrom(HEnvironment* environment) {
   1419     ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena();
   1420     environment_ = new (allocator) HEnvironment(
   1421         allocator,
   1422         environment->Size(),
   1423         environment->GetDexFile(),
   1424         environment->GetMethodIdx(),
   1425         environment->GetDexPc());
   1426     environment_->CopyFrom(environment);
   1427     if (environment->GetParent() != nullptr) {
   1428       environment_->SetAndCopyParentChain(allocator, environment->GetParent());
   1429     }
   1430   }
   1431 
   1432   void CopyEnvironmentFromWithLoopPhiAdjustment(HEnvironment* environment,
   1433                                                 HBasicBlock* block) {
   1434     ArenaAllocator* allocator = GetBlock()->GetGraph()->GetArena();
   1435     environment_ = new (allocator) HEnvironment(
   1436         allocator,
   1437         environment->Size(),
   1438         environment->GetDexFile(),
   1439         environment->GetMethodIdx(),
   1440         environment->GetDexPc());
   1441     if (environment->GetParent() != nullptr) {
   1442       environment_->SetAndCopyParentChain(allocator, environment->GetParent());
   1443     }
   1444     environment_->CopyFromWithLoopPhiAdjustment(environment, block);
   1445   }
   1446 
   1447   // Returns the number of entries in the environment. Typically, that is the
   1448   // number of dex registers in a method. It could be more in case of inlining.
   1449   size_t EnvironmentSize() const;
   1450 
   1451   LocationSummary* GetLocations() const { return locations_; }
   1452   void SetLocations(LocationSummary* locations) { locations_ = locations; }
   1453 
   1454   void ReplaceWith(HInstruction* instruction);
   1455   void ReplaceInput(HInstruction* replacement, size_t index);
   1456 
   1457   // This is almost the same as doing `ReplaceWith()`. But in this helper, the
   1458   // uses of this instruction by `other` are *not* updated.
   1459   void ReplaceWithExceptInReplacementAtIndex(HInstruction* other, size_t use_index) {
   1460     ReplaceWith(other);
   1461     other->ReplaceInput(this, use_index);
   1462   }
   1463 
   1464   // Move `this` instruction before `cursor`.
   1465   void MoveBefore(HInstruction* cursor);
   1466 
   1467 #define INSTRUCTION_TYPE_CHECK(type, super)                                    \
   1468   bool Is##type() const { return (As##type() != nullptr); }                    \
   1469   virtual const H##type* As##type() const { return nullptr; }                  \
   1470   virtual H##type* As##type() { return nullptr; }
   1471 
   1472   FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
   1473 #undef INSTRUCTION_TYPE_CHECK
   1474 
   1475   // Returns whether the instruction can be moved within the graph.
   1476   virtual bool CanBeMoved() const { return false; }
   1477 
   1478   // Returns whether the two instructions are of the same kind.
   1479   virtual bool InstructionTypeEquals(HInstruction* other) const {
   1480     UNUSED(other);
   1481     return false;
   1482   }
   1483 
   1484   // Returns whether any data encoded in the two instructions is equal.
   1485   // This method does not look at the inputs. Both instructions must be
   1486   // of the same type, otherwise the method has undefined behavior.
   1487   virtual bool InstructionDataEquals(HInstruction* other) const {
   1488     UNUSED(other);
   1489     return false;
   1490   }
   1491 
   1492   // Returns whether two instructions are equal, that is:
   1493   // 1) They have the same type and contain the same data (InstructionDataEquals).
   1494   // 2) Their inputs are identical.
   1495   bool Equals(HInstruction* other) const;
   1496 
   1497   virtual InstructionKind GetKind() const = 0;
   1498 
   1499   virtual size_t ComputeHashCode() const {
   1500     size_t result = GetKind();
   1501     for (size_t i = 0, e = InputCount(); i < e; ++i) {
   1502       result = (result * 31) + InputAt(i)->GetId();
   1503     }
   1504     return result;
   1505   }
   1506 
   1507   SideEffects GetSideEffects() const { return side_effects_; }
   1508 
   1509   size_t GetLifetimePosition() const { return lifetime_position_; }
   1510   void SetLifetimePosition(size_t position) { lifetime_position_ = position; }
   1511   LiveInterval* GetLiveInterval() const { return live_interval_; }
   1512   void SetLiveInterval(LiveInterval* interval) { live_interval_ = interval; }
   1513   bool HasLiveInterval() const { return live_interval_ != nullptr; }
   1514 
   1515   bool IsSuspendCheckEntry() const { return IsSuspendCheck() && GetBlock()->IsEntryBlock(); }
   1516 
   1517   // Returns whether the code generation of the instruction will require to have access
   1518   // to the current method. Such instructions are:
   1519   // (1): Instructions that require an environment, as calling the runtime requires
   1520   //      to walk the stack and have the current method stored at a specific stack address.
   1521   // (2): Object literals like classes and strings, that are loaded from the dex cache
   1522   //      fields of the current method.
   1523   bool NeedsCurrentMethod() const {
   1524     return NeedsEnvironment() || IsLoadClass() || IsLoadString();
   1525   }
   1526 
   1527   virtual bool NeedsDexCache() const { return false; }
   1528 
   1529  protected:
   1530   virtual const HUserRecord<HInstruction*> InputRecordAt(size_t i) const = 0;
   1531   virtual void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) = 0;
   1532 
   1533  private:
   1534   void RemoveEnvironmentUser(HUseListNode<HEnvironment*>* use_node) { env_uses_.Remove(use_node); }
   1535 
   1536   HInstruction* previous_;
   1537   HInstruction* next_;
   1538   HBasicBlock* block_;
   1539 
   1540   // An instruction gets an id when it is added to the graph.
   1541   // It reflects creation order. A negative id means the instruction
   1542   // has not been added to the graph.
   1543   int id_;
   1544 
   1545   // When doing liveness analysis, instructions that have uses get an SSA index.
   1546   int ssa_index_;
   1547 
   1548   // List of instructions that have this instruction as input.
   1549   HUseList<HInstruction*> uses_;
   1550 
   1551   // List of environments that contain this instruction.
   1552   HUseList<HEnvironment*> env_uses_;
   1553 
   1554   // The environment associated with this instruction. Not null if the instruction
   1555   // might jump out of the method.
   1556   HEnvironment* environment_;
   1557 
   1558   // Set by the code generator.
   1559   LocationSummary* locations_;
   1560 
   1561   // Set by the liveness analysis.
   1562   LiveInterval* live_interval_;
   1563 
   1564   // Set by the liveness analysis, this is the position in a linear
   1565   // order of blocks where this instruction's live interval start.
   1566   size_t lifetime_position_;
   1567 
   1568   const SideEffects side_effects_;
   1569 
   1570   // TODO: for primitive types this should be marked as invalid.
   1571   ReferenceTypeInfo reference_type_info_;
   1572 
   1573   friend class GraphChecker;
   1574   friend class HBasicBlock;
   1575   friend class HEnvironment;
   1576   friend class HGraph;
   1577   friend class HInstructionList;
   1578 
   1579   DISALLOW_COPY_AND_ASSIGN(HInstruction);
   1580 };
   1581 std::ostream& operator<<(std::ostream& os, const HInstruction::InstructionKind& rhs);
   1582 
   1583 class HInputIterator : public ValueObject {
   1584  public:
   1585   explicit HInputIterator(HInstruction* instruction) : instruction_(instruction), index_(0) {}
   1586 
   1587   bool Done() const { return index_ == instruction_->InputCount(); }
   1588   HInstruction* Current() const { return instruction_->InputAt(index_); }
   1589   void Advance() { index_++; }
   1590 
   1591  private:
   1592   HInstruction* instruction_;
   1593   size_t index_;
   1594 
   1595   DISALLOW_COPY_AND_ASSIGN(HInputIterator);
   1596 };
   1597 
   1598 class HInstructionIterator : public ValueObject {
   1599  public:
   1600   explicit HInstructionIterator(const HInstructionList& instructions)
   1601       : instruction_(instructions.first_instruction_) {
   1602     next_ = Done() ? nullptr : instruction_->GetNext();
   1603   }
   1604 
   1605   bool Done() const { return instruction_ == nullptr; }
   1606   HInstruction* Current() const { return instruction_; }
   1607   void Advance() {
   1608     instruction_ = next_;
   1609     next_ = Done() ? nullptr : instruction_->GetNext();
   1610   }
   1611 
   1612  private:
   1613   HInstruction* instruction_;
   1614   HInstruction* next_;
   1615 
   1616   DISALLOW_COPY_AND_ASSIGN(HInstructionIterator);
   1617 };
   1618 
   1619 class HBackwardInstructionIterator : public ValueObject {
   1620  public:
   1621   explicit HBackwardInstructionIterator(const HInstructionList& instructions)
   1622       : instruction_(instructions.last_instruction_) {
   1623     next_ = Done() ? nullptr : instruction_->GetPrevious();
   1624   }
   1625 
   1626   bool Done() const { return instruction_ == nullptr; }
   1627   HInstruction* Current() const { return instruction_; }
   1628   void Advance() {
   1629     instruction_ = next_;
   1630     next_ = Done() ? nullptr : instruction_->GetPrevious();
   1631   }
   1632 
   1633  private:
   1634   HInstruction* instruction_;
   1635   HInstruction* next_;
   1636 
   1637   DISALLOW_COPY_AND_ASSIGN(HBackwardInstructionIterator);
   1638 };
   1639 
   1640 // An embedded container with N elements of type T.  Used (with partial
   1641 // specialization for N=0) because embedded arrays cannot have size 0.
   1642 template<typename T, intptr_t N>
   1643 class EmbeddedArray {
   1644  public:
   1645   EmbeddedArray() : elements_() {}
   1646 
   1647   intptr_t GetLength() const { return N; }
   1648 
   1649   const T& operator[](intptr_t i) const {
   1650     DCHECK_LT(i, GetLength());
   1651     return elements_[i];
   1652   }
   1653 
   1654   T& operator[](intptr_t i) {
   1655     DCHECK_LT(i, GetLength());
   1656     return elements_[i];
   1657   }
   1658 
   1659   const T& At(intptr_t i) const {
   1660     return (*this)[i];
   1661   }
   1662 
   1663   void SetAt(intptr_t i, const T& val) {
   1664     (*this)[i] = val;
   1665   }
   1666 
   1667  private:
   1668   T elements_[N];
   1669 };
   1670 
   1671 template<typename T>
   1672 class EmbeddedArray<T, 0> {
   1673  public:
   1674   intptr_t length() const { return 0; }
   1675   const T& operator[](intptr_t i) const {
   1676     UNUSED(i);
   1677     LOG(FATAL) << "Unreachable";
   1678     UNREACHABLE();
   1679   }
   1680   T& operator[](intptr_t i) {
   1681     UNUSED(i);
   1682     LOG(FATAL) << "Unreachable";
   1683     UNREACHABLE();
   1684   }
   1685 };
   1686 
   1687 template<intptr_t N>
   1688 class HTemplateInstruction: public HInstruction {
   1689  public:
   1690   HTemplateInstruction<N>(SideEffects side_effects)
   1691       : HInstruction(side_effects), inputs_() {}
   1692   virtual ~HTemplateInstruction() {}
   1693 
   1694   size_t InputCount() const OVERRIDE { return N; }
   1695 
   1696  protected:
   1697   const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_[i]; }
   1698 
   1699   void SetRawInputRecordAt(size_t i, const HUserRecord<HInstruction*>& input) OVERRIDE {
   1700     inputs_[i] = input;
   1701   }
   1702 
   1703  private:
   1704   EmbeddedArray<HUserRecord<HInstruction*>, N> inputs_;
   1705 
   1706   friend class SsaBuilder;
   1707 };
   1708 
   1709 template<intptr_t N>
   1710 class HExpression : public HTemplateInstruction<N> {
   1711  public:
   1712   HExpression<N>(Primitive::Type type, SideEffects side_effects)
   1713       : HTemplateInstruction<N>(side_effects), type_(type) {}
   1714   virtual ~HExpression() {}
   1715 
   1716   Primitive::Type GetType() const OVERRIDE { return type_; }
   1717 
   1718  protected:
   1719   Primitive::Type type_;
   1720 };
   1721 
   1722 // Represents dex's RETURN_VOID opcode. A HReturnVoid is a control flow
   1723 // instruction that branches to the exit block.
   1724 class HReturnVoid : public HTemplateInstruction<0> {
   1725  public:
   1726   HReturnVoid() : HTemplateInstruction(SideEffects::None()) {}
   1727 
   1728   bool IsControlFlow() const OVERRIDE { return true; }
   1729 
   1730   DECLARE_INSTRUCTION(ReturnVoid);
   1731 
   1732  private:
   1733   DISALLOW_COPY_AND_ASSIGN(HReturnVoid);
   1734 };
   1735 
   1736 // Represents dex's RETURN opcodes. A HReturn is a control flow
   1737 // instruction that branches to the exit block.
   1738 class HReturn : public HTemplateInstruction<1> {
   1739  public:
   1740   explicit HReturn(HInstruction* value) : HTemplateInstruction(SideEffects::None()) {
   1741     SetRawInputAt(0, value);
   1742   }
   1743 
   1744   bool IsControlFlow() const OVERRIDE { return true; }
   1745 
   1746   DECLARE_INSTRUCTION(Return);
   1747 
   1748  private:
   1749   DISALLOW_COPY_AND_ASSIGN(HReturn);
   1750 };
   1751 
   1752 // The exit instruction is the only instruction of the exit block.
   1753 // Instructions aborting the method (HThrow and HReturn) must branch to the
   1754 // exit block.
   1755 class HExit : public HTemplateInstruction<0> {
   1756  public:
   1757   HExit() : HTemplateInstruction(SideEffects::None()) {}
   1758 
   1759   bool IsControlFlow() const OVERRIDE { return true; }
   1760 
   1761   DECLARE_INSTRUCTION(Exit);
   1762 
   1763  private:
   1764   DISALLOW_COPY_AND_ASSIGN(HExit);
   1765 };
   1766 
   1767 // Jumps from one block to another.
   1768 class HGoto : public HTemplateInstruction<0> {
   1769  public:
   1770   HGoto() : HTemplateInstruction(SideEffects::None()) {}
   1771 
   1772   bool IsControlFlow() const OVERRIDE { return true; }
   1773 
   1774   HBasicBlock* GetSuccessor() const {
   1775     return GetBlock()->GetSuccessors().Get(0);
   1776   }
   1777 
   1778   DECLARE_INSTRUCTION(Goto);
   1779 
   1780  private:
   1781   DISALLOW_COPY_AND_ASSIGN(HGoto);
   1782 };
   1783 
   1784 
   1785 // Conditional branch. A block ending with an HIf instruction must have
   1786 // two successors.
   1787 class HIf : public HTemplateInstruction<1> {
   1788  public:
   1789   explicit HIf(HInstruction* input) : HTemplateInstruction(SideEffects::None()) {
   1790     SetRawInputAt(0, input);
   1791   }
   1792 
   1793   bool IsControlFlow() const OVERRIDE { return true; }
   1794 
   1795   HBasicBlock* IfTrueSuccessor() const {
   1796     return GetBlock()->GetSuccessors().Get(0);
   1797   }
   1798 
   1799   HBasicBlock* IfFalseSuccessor() const {
   1800     return GetBlock()->GetSuccessors().Get(1);
   1801   }
   1802 
   1803   DECLARE_INSTRUCTION(If);
   1804 
   1805  private:
   1806   DISALLOW_COPY_AND_ASSIGN(HIf);
   1807 };
   1808 
   1809 // Deoptimize to interpreter, upon checking a condition.
   1810 class HDeoptimize : public HTemplateInstruction<1> {
   1811  public:
   1812   HDeoptimize(HInstruction* cond, uint32_t dex_pc)
   1813       : HTemplateInstruction(SideEffects::None()),
   1814         dex_pc_(dex_pc) {
   1815     SetRawInputAt(0, cond);
   1816   }
   1817 
   1818   bool NeedsEnvironment() const OVERRIDE { return true; }
   1819   bool CanThrow() const OVERRIDE { return true; }
   1820   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   1821 
   1822   DECLARE_INSTRUCTION(Deoptimize);
   1823 
   1824  private:
   1825   uint32_t dex_pc_;
   1826 
   1827   DISALLOW_COPY_AND_ASSIGN(HDeoptimize);
   1828 };
   1829 
   1830 class HUnaryOperation : public HExpression<1> {
   1831  public:
   1832   HUnaryOperation(Primitive::Type result_type, HInstruction* input)
   1833       : HExpression(result_type, SideEffects::None()) {
   1834     SetRawInputAt(0, input);
   1835   }
   1836 
   1837   HInstruction* GetInput() const { return InputAt(0); }
   1838   Primitive::Type GetResultType() const { return GetType(); }
   1839 
   1840   bool CanBeMoved() const OVERRIDE { return true; }
   1841   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   1842     UNUSED(other);
   1843     return true;
   1844   }
   1845 
   1846   // Try to statically evaluate `operation` and return a HConstant
   1847   // containing the result of this evaluation.  If `operation` cannot
   1848   // be evaluated as a constant, return null.
   1849   HConstant* TryStaticEvaluation() const;
   1850 
   1851   // Apply this operation to `x`.
   1852   virtual int32_t Evaluate(int32_t x) const = 0;
   1853   virtual int64_t Evaluate(int64_t x) const = 0;
   1854 
   1855   DECLARE_INSTRUCTION(UnaryOperation);
   1856 
   1857  private:
   1858   DISALLOW_COPY_AND_ASSIGN(HUnaryOperation);
   1859 };
   1860 
   1861 class HBinaryOperation : public HExpression<2> {
   1862  public:
   1863   HBinaryOperation(Primitive::Type result_type,
   1864                    HInstruction* left,
   1865                    HInstruction* right) : HExpression(result_type, SideEffects::None()) {
   1866     SetRawInputAt(0, left);
   1867     SetRawInputAt(1, right);
   1868   }
   1869 
   1870   HInstruction* GetLeft() const { return InputAt(0); }
   1871   HInstruction* GetRight() const { return InputAt(1); }
   1872   Primitive::Type GetResultType() const { return GetType(); }
   1873 
   1874   virtual bool IsCommutative() const { return false; }
   1875 
   1876   // Put constant on the right.
   1877   // Returns whether order is changed.
   1878   bool OrderInputsWithConstantOnTheRight() {
   1879     HInstruction* left = InputAt(0);
   1880     HInstruction* right = InputAt(1);
   1881     if (left->IsConstant() && !right->IsConstant()) {
   1882       ReplaceInput(right, 0);
   1883       ReplaceInput(left, 1);
   1884       return true;
   1885     }
   1886     return false;
   1887   }
   1888 
   1889   // Order inputs by instruction id, but favor constant on the right side.
   1890   // This helps GVN for commutative ops.
   1891   void OrderInputs() {
   1892     DCHECK(IsCommutative());
   1893     HInstruction* left = InputAt(0);
   1894     HInstruction* right = InputAt(1);
   1895     if (left == right || (!left->IsConstant() && right->IsConstant())) {
   1896       return;
   1897     }
   1898     if (OrderInputsWithConstantOnTheRight()) {
   1899       return;
   1900     }
   1901     // Order according to instruction id.
   1902     if (left->GetId() > right->GetId()) {
   1903       ReplaceInput(right, 0);
   1904       ReplaceInput(left, 1);
   1905     }
   1906   }
   1907 
   1908   bool CanBeMoved() const OVERRIDE { return true; }
   1909   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   1910     UNUSED(other);
   1911     return true;
   1912   }
   1913 
   1914   // Try to statically evaluate `operation` and return a HConstant
   1915   // containing the result of this evaluation.  If `operation` cannot
   1916   // be evaluated as a constant, return null.
   1917   HConstant* TryStaticEvaluation() const;
   1918 
   1919   // Apply this operation to `x` and `y`.
   1920   virtual int32_t Evaluate(int32_t x, int32_t y) const = 0;
   1921   virtual int64_t Evaluate(int64_t x, int64_t y) const = 0;
   1922 
   1923   // Returns an input that can legally be used as the right input and is
   1924   // constant, or null.
   1925   HConstant* GetConstantRight() const;
   1926 
   1927   // If `GetConstantRight()` returns one of the input, this returns the other
   1928   // one. Otherwise it returns null.
   1929   HInstruction* GetLeastConstantLeft() const;
   1930 
   1931   DECLARE_INSTRUCTION(BinaryOperation);
   1932 
   1933  private:
   1934   DISALLOW_COPY_AND_ASSIGN(HBinaryOperation);
   1935 };
   1936 
   1937 class HCondition : public HBinaryOperation {
   1938  public:
   1939   HCondition(HInstruction* first, HInstruction* second)
   1940       : HBinaryOperation(Primitive::kPrimBoolean, first, second),
   1941         needs_materialization_(true) {}
   1942 
   1943   bool NeedsMaterialization() const { return needs_materialization_; }
   1944   void ClearNeedsMaterialization() { needs_materialization_ = false; }
   1945 
   1946   // For code generation purposes, returns whether this instruction is just before
   1947   // `instruction`, and disregard moves in between.
   1948   bool IsBeforeWhenDisregardMoves(HInstruction* instruction) const;
   1949 
   1950   DECLARE_INSTRUCTION(Condition);
   1951 
   1952   virtual IfCondition GetCondition() const = 0;
   1953 
   1954  private:
   1955   // For register allocation purposes, returns whether this instruction needs to be
   1956   // materialized (that is, not just be in the processor flags).
   1957   bool needs_materialization_;
   1958 
   1959   DISALLOW_COPY_AND_ASSIGN(HCondition);
   1960 };
   1961 
   1962 // Instruction to check if two inputs are equal to each other.
   1963 class HEqual : public HCondition {
   1964  public:
   1965   HEqual(HInstruction* first, HInstruction* second)
   1966       : HCondition(first, second) {}
   1967 
   1968   bool IsCommutative() const OVERRIDE { return true; }
   1969 
   1970   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   1971     return x == y ? 1 : 0;
   1972   }
   1973   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   1974     return x == y ? 1 : 0;
   1975   }
   1976 
   1977   DECLARE_INSTRUCTION(Equal);
   1978 
   1979   IfCondition GetCondition() const OVERRIDE {
   1980     return kCondEQ;
   1981   }
   1982 
   1983  private:
   1984   DISALLOW_COPY_AND_ASSIGN(HEqual);
   1985 };
   1986 
   1987 class HNotEqual : public HCondition {
   1988  public:
   1989   HNotEqual(HInstruction* first, HInstruction* second)
   1990       : HCondition(first, second) {}
   1991 
   1992   bool IsCommutative() const OVERRIDE { return true; }
   1993 
   1994   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   1995     return x != y ? 1 : 0;
   1996   }
   1997   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   1998     return x != y ? 1 : 0;
   1999   }
   2000 
   2001   DECLARE_INSTRUCTION(NotEqual);
   2002 
   2003   IfCondition GetCondition() const OVERRIDE {
   2004     return kCondNE;
   2005   }
   2006 
   2007  private:
   2008   DISALLOW_COPY_AND_ASSIGN(HNotEqual);
   2009 };
   2010 
   2011 class HLessThan : public HCondition {
   2012  public:
   2013   HLessThan(HInstruction* first, HInstruction* second)
   2014       : HCondition(first, second) {}
   2015 
   2016   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2017     return x < y ? 1 : 0;
   2018   }
   2019   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2020     return x < y ? 1 : 0;
   2021   }
   2022 
   2023   DECLARE_INSTRUCTION(LessThan);
   2024 
   2025   IfCondition GetCondition() const OVERRIDE {
   2026     return kCondLT;
   2027   }
   2028 
   2029  private:
   2030   DISALLOW_COPY_AND_ASSIGN(HLessThan);
   2031 };
   2032 
   2033 class HLessThanOrEqual : public HCondition {
   2034  public:
   2035   HLessThanOrEqual(HInstruction* first, HInstruction* second)
   2036       : HCondition(first, second) {}
   2037 
   2038   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2039     return x <= y ? 1 : 0;
   2040   }
   2041   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2042     return x <= y ? 1 : 0;
   2043   }
   2044 
   2045   DECLARE_INSTRUCTION(LessThanOrEqual);
   2046 
   2047   IfCondition GetCondition() const OVERRIDE {
   2048     return kCondLE;
   2049   }
   2050 
   2051  private:
   2052   DISALLOW_COPY_AND_ASSIGN(HLessThanOrEqual);
   2053 };
   2054 
   2055 class HGreaterThan : public HCondition {
   2056  public:
   2057   HGreaterThan(HInstruction* first, HInstruction* second)
   2058       : HCondition(first, second) {}
   2059 
   2060   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2061     return x > y ? 1 : 0;
   2062   }
   2063   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2064     return x > y ? 1 : 0;
   2065   }
   2066 
   2067   DECLARE_INSTRUCTION(GreaterThan);
   2068 
   2069   IfCondition GetCondition() const OVERRIDE {
   2070     return kCondGT;
   2071   }
   2072 
   2073  private:
   2074   DISALLOW_COPY_AND_ASSIGN(HGreaterThan);
   2075 };
   2076 
   2077 class HGreaterThanOrEqual : public HCondition {
   2078  public:
   2079   HGreaterThanOrEqual(HInstruction* first, HInstruction* second)
   2080       : HCondition(first, second) {}
   2081 
   2082   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2083     return x >= y ? 1 : 0;
   2084   }
   2085   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2086     return x >= y ? 1 : 0;
   2087   }
   2088 
   2089   DECLARE_INSTRUCTION(GreaterThanOrEqual);
   2090 
   2091   IfCondition GetCondition() const OVERRIDE {
   2092     return kCondGE;
   2093   }
   2094 
   2095  private:
   2096   DISALLOW_COPY_AND_ASSIGN(HGreaterThanOrEqual);
   2097 };
   2098 
   2099 
   2100 // Instruction to check how two inputs compare to each other.
   2101 // Result is 0 if input0 == input1, 1 if input0 > input1, or -1 if input0 < input1.
   2102 class HCompare : public HBinaryOperation {
   2103  public:
   2104   // The bias applies for floating point operations and indicates how NaN
   2105   // comparisons are treated:
   2106   enum Bias {
   2107     kNoBias,  // bias is not applicable (i.e. for long operation)
   2108     kGtBias,  // return 1 for NaN comparisons
   2109     kLtBias,  // return -1 for NaN comparisons
   2110   };
   2111 
   2112   HCompare(Primitive::Type type,
   2113            HInstruction* first,
   2114            HInstruction* second,
   2115            Bias bias,
   2116            uint32_t dex_pc)
   2117       : HBinaryOperation(Primitive::kPrimInt, first, second), bias_(bias), dex_pc_(dex_pc) {
   2118     DCHECK_EQ(type, first->GetType());
   2119     DCHECK_EQ(type, second->GetType());
   2120   }
   2121 
   2122   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2123     return
   2124       x == y ? 0 :
   2125       x > y ? 1 :
   2126       -1;
   2127   }
   2128 
   2129   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2130     return
   2131       x == y ? 0 :
   2132       x > y ? 1 :
   2133       -1;
   2134   }
   2135 
   2136   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2137     return bias_ == other->AsCompare()->bias_;
   2138   }
   2139 
   2140   bool IsGtBias() { return bias_ == kGtBias; }
   2141 
   2142   uint32_t GetDexPc() const { return dex_pc_; }
   2143 
   2144   DECLARE_INSTRUCTION(Compare);
   2145 
   2146  private:
   2147   const Bias bias_;
   2148   const uint32_t dex_pc_;
   2149 
   2150   DISALLOW_COPY_AND_ASSIGN(HCompare);
   2151 };
   2152 
   2153 // A local in the graph. Corresponds to a Dex register.
   2154 class HLocal : public HTemplateInstruction<0> {
   2155  public:
   2156   explicit HLocal(uint16_t reg_number)
   2157       : HTemplateInstruction(SideEffects::None()), reg_number_(reg_number) {}
   2158 
   2159   DECLARE_INSTRUCTION(Local);
   2160 
   2161   uint16_t GetRegNumber() const { return reg_number_; }
   2162 
   2163  private:
   2164   // The Dex register number.
   2165   const uint16_t reg_number_;
   2166 
   2167   DISALLOW_COPY_AND_ASSIGN(HLocal);
   2168 };
   2169 
   2170 // Load a given local. The local is an input of this instruction.
   2171 class HLoadLocal : public HExpression<1> {
   2172  public:
   2173   HLoadLocal(HLocal* local, Primitive::Type type)
   2174       : HExpression(type, SideEffects::None()) {
   2175     SetRawInputAt(0, local);
   2176   }
   2177 
   2178   HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
   2179 
   2180   DECLARE_INSTRUCTION(LoadLocal);
   2181 
   2182  private:
   2183   DISALLOW_COPY_AND_ASSIGN(HLoadLocal);
   2184 };
   2185 
   2186 // Store a value in a given local. This instruction has two inputs: the value
   2187 // and the local.
   2188 class HStoreLocal : public HTemplateInstruction<2> {
   2189  public:
   2190   HStoreLocal(HLocal* local, HInstruction* value) : HTemplateInstruction(SideEffects::None()) {
   2191     SetRawInputAt(0, local);
   2192     SetRawInputAt(1, value);
   2193   }
   2194 
   2195   HLocal* GetLocal() const { return reinterpret_cast<HLocal*>(InputAt(0)); }
   2196 
   2197   DECLARE_INSTRUCTION(StoreLocal);
   2198 
   2199  private:
   2200   DISALLOW_COPY_AND_ASSIGN(HStoreLocal);
   2201 };
   2202 
   2203 class HConstant : public HExpression<0> {
   2204  public:
   2205   explicit HConstant(Primitive::Type type) : HExpression(type, SideEffects::None()) {}
   2206 
   2207   bool CanBeMoved() const OVERRIDE { return true; }
   2208 
   2209   virtual bool IsMinusOne() const { return false; }
   2210   virtual bool IsZero() const { return false; }
   2211   virtual bool IsOne() const { return false; }
   2212 
   2213   DECLARE_INSTRUCTION(Constant);
   2214 
   2215  private:
   2216   DISALLOW_COPY_AND_ASSIGN(HConstant);
   2217 };
   2218 
   2219 class HFloatConstant : public HConstant {
   2220  public:
   2221   float GetValue() const { return value_; }
   2222 
   2223   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2224     return bit_cast<uint32_t, float>(other->AsFloatConstant()->value_) ==
   2225         bit_cast<uint32_t, float>(value_);
   2226   }
   2227 
   2228   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
   2229 
   2230   bool IsMinusOne() const OVERRIDE {
   2231     return bit_cast<uint32_t, float>(AsFloatConstant()->GetValue()) ==
   2232         bit_cast<uint32_t, float>((-1.0f));
   2233   }
   2234   bool IsZero() const OVERRIDE {
   2235     return AsFloatConstant()->GetValue() == 0.0f;
   2236   }
   2237   bool IsOne() const OVERRIDE {
   2238     return bit_cast<uint32_t, float>(AsFloatConstant()->GetValue()) ==
   2239         bit_cast<uint32_t, float>(1.0f);
   2240   }
   2241 
   2242   DECLARE_INSTRUCTION(FloatConstant);
   2243 
   2244  private:
   2245   explicit HFloatConstant(float value) : HConstant(Primitive::kPrimFloat), value_(value) {}
   2246   explicit HFloatConstant(int32_t value)
   2247       : HConstant(Primitive::kPrimFloat), value_(bit_cast<float, int32_t>(value)) {}
   2248 
   2249   const float value_;
   2250 
   2251   // Only the SsaBuilder and HGraph can create floating-point constants.
   2252   friend class SsaBuilder;
   2253   friend class HGraph;
   2254   DISALLOW_COPY_AND_ASSIGN(HFloatConstant);
   2255 };
   2256 
   2257 class HDoubleConstant : public HConstant {
   2258  public:
   2259   double GetValue() const { return value_; }
   2260 
   2261   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2262     return bit_cast<uint64_t, double>(other->AsDoubleConstant()->value_) ==
   2263         bit_cast<uint64_t, double>(value_);
   2264   }
   2265 
   2266   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
   2267 
   2268   bool IsMinusOne() const OVERRIDE {
   2269     return bit_cast<uint64_t, double>(AsDoubleConstant()->GetValue()) ==
   2270         bit_cast<uint64_t, double>((-1.0));
   2271   }
   2272   bool IsZero() const OVERRIDE {
   2273     return AsDoubleConstant()->GetValue() == 0.0;
   2274   }
   2275   bool IsOne() const OVERRIDE {
   2276     return bit_cast<uint64_t, double>(AsDoubleConstant()->GetValue()) ==
   2277         bit_cast<uint64_t, double>(1.0);
   2278   }
   2279 
   2280   DECLARE_INSTRUCTION(DoubleConstant);
   2281 
   2282  private:
   2283   explicit HDoubleConstant(double value) : HConstant(Primitive::kPrimDouble), value_(value) {}
   2284   explicit HDoubleConstant(int64_t value)
   2285       : HConstant(Primitive::kPrimDouble), value_(bit_cast<double, int64_t>(value)) {}
   2286 
   2287   const double value_;
   2288 
   2289   // Only the SsaBuilder and HGraph can create floating-point constants.
   2290   friend class SsaBuilder;
   2291   friend class HGraph;
   2292   DISALLOW_COPY_AND_ASSIGN(HDoubleConstant);
   2293 };
   2294 
   2295 class HNullConstant : public HConstant {
   2296  public:
   2297   bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE {
   2298     return true;
   2299   }
   2300 
   2301   size_t ComputeHashCode() const OVERRIDE { return 0; }
   2302 
   2303   DECLARE_INSTRUCTION(NullConstant);
   2304 
   2305  private:
   2306   HNullConstant() : HConstant(Primitive::kPrimNot) {}
   2307 
   2308   friend class HGraph;
   2309   DISALLOW_COPY_AND_ASSIGN(HNullConstant);
   2310 };
   2311 
   2312 // Constants of the type int. Those can be from Dex instructions, or
   2313 // synthesized (for example with the if-eqz instruction).
   2314 class HIntConstant : public HConstant {
   2315  public:
   2316   int32_t GetValue() const { return value_; }
   2317 
   2318   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2319     return other->AsIntConstant()->value_ == value_;
   2320   }
   2321 
   2322   size_t ComputeHashCode() const OVERRIDE { return GetValue(); }
   2323 
   2324   bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
   2325   bool IsZero() const OVERRIDE { return GetValue() == 0; }
   2326   bool IsOne() const OVERRIDE { return GetValue() == 1; }
   2327 
   2328   DECLARE_INSTRUCTION(IntConstant);
   2329 
   2330  private:
   2331   explicit HIntConstant(int32_t value) : HConstant(Primitive::kPrimInt), value_(value) {}
   2332 
   2333   const int32_t value_;
   2334 
   2335   friend class HGraph;
   2336   ART_FRIEND_TEST(GraphTest, InsertInstructionBefore);
   2337   ART_FRIEND_TYPED_TEST(ParallelMoveTest, ConstantLast);
   2338   DISALLOW_COPY_AND_ASSIGN(HIntConstant);
   2339 };
   2340 
   2341 class HLongConstant : public HConstant {
   2342  public:
   2343   int64_t GetValue() const { return value_; }
   2344 
   2345   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2346     return other->AsLongConstant()->value_ == value_;
   2347   }
   2348 
   2349   size_t ComputeHashCode() const OVERRIDE { return static_cast<size_t>(GetValue()); }
   2350 
   2351   bool IsMinusOne() const OVERRIDE { return GetValue() == -1; }
   2352   bool IsZero() const OVERRIDE { return GetValue() == 0; }
   2353   bool IsOne() const OVERRIDE { return GetValue() == 1; }
   2354 
   2355   DECLARE_INSTRUCTION(LongConstant);
   2356 
   2357  private:
   2358   explicit HLongConstant(int64_t value) : HConstant(Primitive::kPrimLong), value_(value) {}
   2359 
   2360   const int64_t value_;
   2361 
   2362   friend class HGraph;
   2363   DISALLOW_COPY_AND_ASSIGN(HLongConstant);
   2364 };
   2365 
   2366 enum class Intrinsics {
   2367 #define OPTIMIZING_INTRINSICS(Name, IsStatic) k ## Name,
   2368 #include "intrinsics_list.h"
   2369   kNone,
   2370   INTRINSICS_LIST(OPTIMIZING_INTRINSICS)
   2371 #undef INTRINSICS_LIST
   2372 #undef OPTIMIZING_INTRINSICS
   2373 };
   2374 std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic);
   2375 
   2376 class HInvoke : public HInstruction {
   2377  public:
   2378   size_t InputCount() const OVERRIDE { return inputs_.Size(); }
   2379 
   2380   // Runtime needs to walk the stack, so Dex -> Dex calls need to
   2381   // know their environment.
   2382   bool NeedsEnvironment() const OVERRIDE { return true; }
   2383 
   2384   void SetArgumentAt(size_t index, HInstruction* argument) {
   2385     SetRawInputAt(index, argument);
   2386   }
   2387 
   2388   // Return the number of arguments.  This number can be lower than
   2389   // the number of inputs returned by InputCount(), as some invoke
   2390   // instructions (e.g. HInvokeStaticOrDirect) can have non-argument
   2391   // inputs at the end of their list of inputs.
   2392   uint32_t GetNumberOfArguments() const { return number_of_arguments_; }
   2393 
   2394   Primitive::Type GetType() const OVERRIDE { return return_type_; }
   2395 
   2396   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2397 
   2398   uint32_t GetDexMethodIndex() const { return dex_method_index_; }
   2399 
   2400   Intrinsics GetIntrinsic() const {
   2401     return intrinsic_;
   2402   }
   2403 
   2404   void SetIntrinsic(Intrinsics intrinsic) {
   2405     intrinsic_ = intrinsic;
   2406   }
   2407 
   2408   DECLARE_INSTRUCTION(Invoke);
   2409 
   2410  protected:
   2411   HInvoke(ArenaAllocator* arena,
   2412           uint32_t number_of_arguments,
   2413           uint32_t number_of_other_inputs,
   2414           Primitive::Type return_type,
   2415           uint32_t dex_pc,
   2416           uint32_t dex_method_index)
   2417     : HInstruction(SideEffects::All()),
   2418       number_of_arguments_(number_of_arguments),
   2419       inputs_(arena, number_of_arguments),
   2420       return_type_(return_type),
   2421       dex_pc_(dex_pc),
   2422       dex_method_index_(dex_method_index),
   2423       intrinsic_(Intrinsics::kNone) {
   2424     uint32_t number_of_inputs = number_of_arguments + number_of_other_inputs;
   2425     inputs_.SetSize(number_of_inputs);
   2426   }
   2427 
   2428   const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
   2429   void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
   2430     inputs_.Put(index, input);
   2431   }
   2432 
   2433   uint32_t number_of_arguments_;
   2434   GrowableArray<HUserRecord<HInstruction*> > inputs_;
   2435   const Primitive::Type return_type_;
   2436   const uint32_t dex_pc_;
   2437   const uint32_t dex_method_index_;
   2438   Intrinsics intrinsic_;
   2439 
   2440  private:
   2441   DISALLOW_COPY_AND_ASSIGN(HInvoke);
   2442 };
   2443 
   2444 class HInvokeStaticOrDirect : public HInvoke {
   2445  public:
   2446   // Requirements of this method call regarding the class
   2447   // initialization (clinit) check of its declaring class.
   2448   enum class ClinitCheckRequirement {
   2449     kNone,      // Class already initialized.
   2450     kExplicit,  // Static call having explicit clinit check as last input.
   2451     kImplicit,  // Static call implicitly requiring a clinit check.
   2452   };
   2453 
   2454   HInvokeStaticOrDirect(ArenaAllocator* arena,
   2455                         uint32_t number_of_arguments,
   2456                         Primitive::Type return_type,
   2457                         uint32_t dex_pc,
   2458                         uint32_t dex_method_index,
   2459                         bool is_recursive,
   2460                         int32_t string_init_offset,
   2461                         InvokeType original_invoke_type,
   2462                         InvokeType invoke_type,
   2463                         ClinitCheckRequirement clinit_check_requirement)
   2464       : HInvoke(arena,
   2465                 number_of_arguments,
   2466                 clinit_check_requirement == ClinitCheckRequirement::kExplicit ? 1u : 0u,
   2467                 return_type,
   2468                 dex_pc,
   2469                 dex_method_index),
   2470         original_invoke_type_(original_invoke_type),
   2471         invoke_type_(invoke_type),
   2472         is_recursive_(is_recursive),
   2473         clinit_check_requirement_(clinit_check_requirement),
   2474         string_init_offset_(string_init_offset) {}
   2475 
   2476   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   2477     UNUSED(obj);
   2478     // We access the method via the dex cache so we can't do an implicit null check.
   2479     // TODO: for intrinsics we can generate implicit null checks.
   2480     return false;
   2481   }
   2482 
   2483   InvokeType GetOriginalInvokeType() const { return original_invoke_type_; }
   2484   InvokeType GetInvokeType() const { return invoke_type_; }
   2485   bool IsRecursive() const { return is_recursive_; }
   2486   bool NeedsDexCache() const OVERRIDE { return !IsRecursive(); }
   2487   bool IsStringInit() const { return string_init_offset_ != 0; }
   2488   int32_t GetStringInitOffset() const { return string_init_offset_; }
   2489 
   2490   // Is this instruction a call to a static method?
   2491   bool IsStatic() const {
   2492     return GetInvokeType() == kStatic;
   2493   }
   2494 
   2495   // Remove the art::HLoadClass instruction set as last input by
   2496   // art::PrepareForRegisterAllocation::VisitClinitCheck in lieu of
   2497   // the initial art::HClinitCheck instruction (only relevant for
   2498   // static calls with explicit clinit check).
   2499   void RemoveLoadClassAsLastInput() {
   2500     DCHECK(IsStaticWithExplicitClinitCheck());
   2501     size_t last_input_index = InputCount() - 1;
   2502     HInstruction* last_input = InputAt(last_input_index);
   2503     DCHECK(last_input != nullptr);
   2504     DCHECK(last_input->IsLoadClass()) << last_input->DebugName();
   2505     RemoveAsUserOfInput(last_input_index);
   2506     inputs_.DeleteAt(last_input_index);
   2507     clinit_check_requirement_ = ClinitCheckRequirement::kImplicit;
   2508     DCHECK(IsStaticWithImplicitClinitCheck());
   2509   }
   2510 
   2511   // Is this a call to a static method whose declaring class has an
   2512   // explicit intialization check in the graph?
   2513   bool IsStaticWithExplicitClinitCheck() const {
   2514     return IsStatic() && (clinit_check_requirement_ == ClinitCheckRequirement::kExplicit);
   2515   }
   2516 
   2517   // Is this a call to a static method whose declaring class has an
   2518   // implicit intialization check requirement?
   2519   bool IsStaticWithImplicitClinitCheck() const {
   2520     return IsStatic() && (clinit_check_requirement_ == ClinitCheckRequirement::kImplicit);
   2521   }
   2522 
   2523   DECLARE_INSTRUCTION(InvokeStaticOrDirect);
   2524 
   2525  protected:
   2526   const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE {
   2527     const HUserRecord<HInstruction*> input_record = HInvoke::InputRecordAt(i);
   2528     if (kIsDebugBuild && IsStaticWithExplicitClinitCheck() && (i == InputCount() - 1)) {
   2529       HInstruction* input = input_record.GetInstruction();
   2530       // `input` is the last input of a static invoke marked as having
   2531       // an explicit clinit check. It must either be:
   2532       // - an art::HClinitCheck instruction, set by art::HGraphBuilder; or
   2533       // - an art::HLoadClass instruction, set by art::PrepareForRegisterAllocation.
   2534       DCHECK(input != nullptr);
   2535       DCHECK(input->IsClinitCheck() || input->IsLoadClass()) << input->DebugName();
   2536     }
   2537     return input_record;
   2538   }
   2539 
   2540  private:
   2541   const InvokeType original_invoke_type_;
   2542   const InvokeType invoke_type_;
   2543   const bool is_recursive_;
   2544   ClinitCheckRequirement clinit_check_requirement_;
   2545   // Thread entrypoint offset for string init method if this is a string init invoke.
   2546   // Note that there are multiple string init methods, each having its own offset.
   2547   int32_t string_init_offset_;
   2548 
   2549   DISALLOW_COPY_AND_ASSIGN(HInvokeStaticOrDirect);
   2550 };
   2551 
   2552 class HInvokeVirtual : public HInvoke {
   2553  public:
   2554   HInvokeVirtual(ArenaAllocator* arena,
   2555                  uint32_t number_of_arguments,
   2556                  Primitive::Type return_type,
   2557                  uint32_t dex_pc,
   2558                  uint32_t dex_method_index,
   2559                  uint32_t vtable_index)
   2560       : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index),
   2561         vtable_index_(vtable_index) {}
   2562 
   2563   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   2564     // TODO: Add implicit null checks in intrinsics.
   2565     return (obj == InputAt(0)) && !GetLocations()->Intrinsified();
   2566   }
   2567 
   2568   uint32_t GetVTableIndex() const { return vtable_index_; }
   2569 
   2570   DECLARE_INSTRUCTION(InvokeVirtual);
   2571 
   2572  private:
   2573   const uint32_t vtable_index_;
   2574 
   2575   DISALLOW_COPY_AND_ASSIGN(HInvokeVirtual);
   2576 };
   2577 
   2578 class HInvokeInterface : public HInvoke {
   2579  public:
   2580   HInvokeInterface(ArenaAllocator* arena,
   2581                    uint32_t number_of_arguments,
   2582                    Primitive::Type return_type,
   2583                    uint32_t dex_pc,
   2584                    uint32_t dex_method_index,
   2585                    uint32_t imt_index)
   2586       : HInvoke(arena, number_of_arguments, 0u, return_type, dex_pc, dex_method_index),
   2587         imt_index_(imt_index) {}
   2588 
   2589   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   2590     // TODO: Add implicit null checks in intrinsics.
   2591     return (obj == InputAt(0)) && !GetLocations()->Intrinsified();
   2592   }
   2593 
   2594   uint32_t GetImtIndex() const { return imt_index_; }
   2595   uint32_t GetDexMethodIndex() const { return dex_method_index_; }
   2596 
   2597   DECLARE_INSTRUCTION(InvokeInterface);
   2598 
   2599  private:
   2600   const uint32_t imt_index_;
   2601 
   2602   DISALLOW_COPY_AND_ASSIGN(HInvokeInterface);
   2603 };
   2604 
   2605 class HNewInstance : public HExpression<0> {
   2606  public:
   2607   HNewInstance(uint32_t dex_pc, uint16_t type_index, QuickEntrypointEnum entrypoint)
   2608       : HExpression(Primitive::kPrimNot, SideEffects::None()),
   2609         dex_pc_(dex_pc),
   2610         type_index_(type_index),
   2611         entrypoint_(entrypoint) {}
   2612 
   2613   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2614   uint16_t GetTypeIndex() const { return type_index_; }
   2615 
   2616   // Calls runtime so needs an environment.
   2617   bool NeedsEnvironment() const OVERRIDE { return true; }
   2618   // It may throw when called on:
   2619   //   - interfaces
   2620   //   - abstract/innaccessible/unknown classes
   2621   // TODO: optimize when possible.
   2622   bool CanThrow() const OVERRIDE { return true; }
   2623 
   2624   bool CanBeNull() const OVERRIDE { return false; }
   2625 
   2626   QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }
   2627 
   2628   DECLARE_INSTRUCTION(NewInstance);
   2629 
   2630  private:
   2631   const uint32_t dex_pc_;
   2632   const uint16_t type_index_;
   2633   const QuickEntrypointEnum entrypoint_;
   2634 
   2635   DISALLOW_COPY_AND_ASSIGN(HNewInstance);
   2636 };
   2637 
   2638 class HNeg : public HUnaryOperation {
   2639  public:
   2640   explicit HNeg(Primitive::Type result_type, HInstruction* input)
   2641       : HUnaryOperation(result_type, input) {}
   2642 
   2643   int32_t Evaluate(int32_t x) const OVERRIDE { return -x; }
   2644   int64_t Evaluate(int64_t x) const OVERRIDE { return -x; }
   2645 
   2646   DECLARE_INSTRUCTION(Neg);
   2647 
   2648  private:
   2649   DISALLOW_COPY_AND_ASSIGN(HNeg);
   2650 };
   2651 
   2652 class HNewArray : public HExpression<1> {
   2653  public:
   2654   HNewArray(HInstruction* length,
   2655             uint32_t dex_pc,
   2656             uint16_t type_index,
   2657             QuickEntrypointEnum entrypoint)
   2658       : HExpression(Primitive::kPrimNot, SideEffects::None()),
   2659         dex_pc_(dex_pc),
   2660         type_index_(type_index),
   2661         entrypoint_(entrypoint) {
   2662     SetRawInputAt(0, length);
   2663   }
   2664 
   2665   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2666   uint16_t GetTypeIndex() const { return type_index_; }
   2667 
   2668   // Calls runtime so needs an environment.
   2669   bool NeedsEnvironment() const OVERRIDE { return true; }
   2670 
   2671   // May throw NegativeArraySizeException, OutOfMemoryError, etc.
   2672   bool CanThrow() const OVERRIDE { return true; }
   2673 
   2674   bool CanBeNull() const OVERRIDE { return false; }
   2675 
   2676   QuickEntrypointEnum GetEntrypoint() const { return entrypoint_; }
   2677 
   2678   DECLARE_INSTRUCTION(NewArray);
   2679 
   2680  private:
   2681   const uint32_t dex_pc_;
   2682   const uint16_t type_index_;
   2683   const QuickEntrypointEnum entrypoint_;
   2684 
   2685   DISALLOW_COPY_AND_ASSIGN(HNewArray);
   2686 };
   2687 
   2688 class HAdd : public HBinaryOperation {
   2689  public:
   2690   HAdd(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2691       : HBinaryOperation(result_type, left, right) {}
   2692 
   2693   bool IsCommutative() const OVERRIDE { return true; }
   2694 
   2695   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2696     return x + y;
   2697   }
   2698   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2699     return x + y;
   2700   }
   2701 
   2702   DECLARE_INSTRUCTION(Add);
   2703 
   2704  private:
   2705   DISALLOW_COPY_AND_ASSIGN(HAdd);
   2706 };
   2707 
   2708 class HSub : public HBinaryOperation {
   2709  public:
   2710   HSub(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2711       : HBinaryOperation(result_type, left, right) {}
   2712 
   2713   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2714     return x - y;
   2715   }
   2716   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2717     return x - y;
   2718   }
   2719 
   2720   DECLARE_INSTRUCTION(Sub);
   2721 
   2722  private:
   2723   DISALLOW_COPY_AND_ASSIGN(HSub);
   2724 };
   2725 
   2726 class HMul : public HBinaryOperation {
   2727  public:
   2728   HMul(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2729       : HBinaryOperation(result_type, left, right) {}
   2730 
   2731   bool IsCommutative() const OVERRIDE { return true; }
   2732 
   2733   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x * y; }
   2734   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x * y; }
   2735 
   2736   DECLARE_INSTRUCTION(Mul);
   2737 
   2738  private:
   2739   DISALLOW_COPY_AND_ASSIGN(HMul);
   2740 };
   2741 
   2742 class HDiv : public HBinaryOperation {
   2743  public:
   2744   HDiv(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc)
   2745       : HBinaryOperation(result_type, left, right), dex_pc_(dex_pc) {}
   2746 
   2747   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2748     // Our graph structure ensures we never have 0 for `y` during constant folding.
   2749     DCHECK_NE(y, 0);
   2750     // Special case -1 to avoid getting a SIGFPE on x86(_64).
   2751     return (y == -1) ? -x : x / y;
   2752   }
   2753 
   2754   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2755     DCHECK_NE(y, 0);
   2756     // Special case -1 to avoid getting a SIGFPE on x86(_64).
   2757     return (y == -1) ? -x : x / y;
   2758   }
   2759 
   2760   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2761 
   2762   DECLARE_INSTRUCTION(Div);
   2763 
   2764  private:
   2765   const uint32_t dex_pc_;
   2766 
   2767   DISALLOW_COPY_AND_ASSIGN(HDiv);
   2768 };
   2769 
   2770 class HRem : public HBinaryOperation {
   2771  public:
   2772   HRem(Primitive::Type result_type, HInstruction* left, HInstruction* right, uint32_t dex_pc)
   2773       : HBinaryOperation(result_type, left, right), dex_pc_(dex_pc) {}
   2774 
   2775   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2776     DCHECK_NE(y, 0);
   2777     // Special case -1 to avoid getting a SIGFPE on x86(_64).
   2778     return (y == -1) ? 0 : x % y;
   2779   }
   2780 
   2781   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2782     DCHECK_NE(y, 0);
   2783     // Special case -1 to avoid getting a SIGFPE on x86(_64).
   2784     return (y == -1) ? 0 : x % y;
   2785   }
   2786 
   2787   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2788 
   2789   DECLARE_INSTRUCTION(Rem);
   2790 
   2791  private:
   2792   const uint32_t dex_pc_;
   2793 
   2794   DISALLOW_COPY_AND_ASSIGN(HRem);
   2795 };
   2796 
   2797 class HDivZeroCheck : public HExpression<1> {
   2798  public:
   2799   HDivZeroCheck(HInstruction* value, uint32_t dex_pc)
   2800       : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
   2801     SetRawInputAt(0, value);
   2802   }
   2803 
   2804   bool CanBeMoved() const OVERRIDE { return true; }
   2805 
   2806   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2807     UNUSED(other);
   2808     return true;
   2809   }
   2810 
   2811   bool NeedsEnvironment() const OVERRIDE { return true; }
   2812   bool CanThrow() const OVERRIDE { return true; }
   2813 
   2814   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   2815 
   2816   DECLARE_INSTRUCTION(DivZeroCheck);
   2817 
   2818  private:
   2819   const uint32_t dex_pc_;
   2820 
   2821   DISALLOW_COPY_AND_ASSIGN(HDivZeroCheck);
   2822 };
   2823 
   2824 class HShl : public HBinaryOperation {
   2825  public:
   2826   HShl(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2827       : HBinaryOperation(result_type, left, right) {}
   2828 
   2829   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x << (y & kMaxIntShiftValue); }
   2830   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x << (y & kMaxLongShiftValue); }
   2831 
   2832   DECLARE_INSTRUCTION(Shl);
   2833 
   2834  private:
   2835   DISALLOW_COPY_AND_ASSIGN(HShl);
   2836 };
   2837 
   2838 class HShr : public HBinaryOperation {
   2839  public:
   2840   HShr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2841       : HBinaryOperation(result_type, left, right) {}
   2842 
   2843   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x >> (y & kMaxIntShiftValue); }
   2844   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x >> (y & kMaxLongShiftValue); }
   2845 
   2846   DECLARE_INSTRUCTION(Shr);
   2847 
   2848  private:
   2849   DISALLOW_COPY_AND_ASSIGN(HShr);
   2850 };
   2851 
   2852 class HUShr : public HBinaryOperation {
   2853  public:
   2854   HUShr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2855       : HBinaryOperation(result_type, left, right) {}
   2856 
   2857   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE {
   2858     uint32_t ux = static_cast<uint32_t>(x);
   2859     uint32_t uy = static_cast<uint32_t>(y) & kMaxIntShiftValue;
   2860     return static_cast<int32_t>(ux >> uy);
   2861   }
   2862 
   2863   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE {
   2864     uint64_t ux = static_cast<uint64_t>(x);
   2865     uint64_t uy = static_cast<uint64_t>(y) & kMaxLongShiftValue;
   2866     return static_cast<int64_t>(ux >> uy);
   2867   }
   2868 
   2869   DECLARE_INSTRUCTION(UShr);
   2870 
   2871  private:
   2872   DISALLOW_COPY_AND_ASSIGN(HUShr);
   2873 };
   2874 
   2875 class HAnd : public HBinaryOperation {
   2876  public:
   2877   HAnd(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2878       : HBinaryOperation(result_type, left, right) {}
   2879 
   2880   bool IsCommutative() const OVERRIDE { return true; }
   2881 
   2882   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x & y; }
   2883   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x & y; }
   2884 
   2885   DECLARE_INSTRUCTION(And);
   2886 
   2887  private:
   2888   DISALLOW_COPY_AND_ASSIGN(HAnd);
   2889 };
   2890 
   2891 class HOr : public HBinaryOperation {
   2892  public:
   2893   HOr(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2894       : HBinaryOperation(result_type, left, right) {}
   2895 
   2896   bool IsCommutative() const OVERRIDE { return true; }
   2897 
   2898   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x | y; }
   2899   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x | y; }
   2900 
   2901   DECLARE_INSTRUCTION(Or);
   2902 
   2903  private:
   2904   DISALLOW_COPY_AND_ASSIGN(HOr);
   2905 };
   2906 
   2907 class HXor : public HBinaryOperation {
   2908  public:
   2909   HXor(Primitive::Type result_type, HInstruction* left, HInstruction* right)
   2910       : HBinaryOperation(result_type, left, right) {}
   2911 
   2912   bool IsCommutative() const OVERRIDE { return true; }
   2913 
   2914   int32_t Evaluate(int32_t x, int32_t y) const OVERRIDE { return x ^ y; }
   2915   int64_t Evaluate(int64_t x, int64_t y) const OVERRIDE { return x ^ y; }
   2916 
   2917   DECLARE_INSTRUCTION(Xor);
   2918 
   2919  private:
   2920   DISALLOW_COPY_AND_ASSIGN(HXor);
   2921 };
   2922 
   2923 // The value of a parameter in this method. Its location depends on
   2924 // the calling convention.
   2925 class HParameterValue : public HExpression<0> {
   2926  public:
   2927   HParameterValue(uint8_t index, Primitive::Type parameter_type, bool is_this = false)
   2928       : HExpression(parameter_type, SideEffects::None()), index_(index), is_this_(is_this) {}
   2929 
   2930   uint8_t GetIndex() const { return index_; }
   2931 
   2932   bool CanBeNull() const OVERRIDE { return !is_this_; }
   2933 
   2934   DECLARE_INSTRUCTION(ParameterValue);
   2935 
   2936  private:
   2937   // The index of this parameter in the parameters list. Must be less
   2938   // than HGraph::number_of_in_vregs_.
   2939   const uint8_t index_;
   2940 
   2941   // Whether or not the parameter value corresponds to 'this' argument.
   2942   const bool is_this_;
   2943 
   2944   DISALLOW_COPY_AND_ASSIGN(HParameterValue);
   2945 };
   2946 
   2947 class HNot : public HUnaryOperation {
   2948  public:
   2949   explicit HNot(Primitive::Type result_type, HInstruction* input)
   2950       : HUnaryOperation(result_type, input) {}
   2951 
   2952   bool CanBeMoved() const OVERRIDE { return true; }
   2953   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2954     UNUSED(other);
   2955     return true;
   2956   }
   2957 
   2958   int32_t Evaluate(int32_t x) const OVERRIDE { return ~x; }
   2959   int64_t Evaluate(int64_t x) const OVERRIDE { return ~x; }
   2960 
   2961   DECLARE_INSTRUCTION(Not);
   2962 
   2963  private:
   2964   DISALLOW_COPY_AND_ASSIGN(HNot);
   2965 };
   2966 
   2967 class HBooleanNot : public HUnaryOperation {
   2968  public:
   2969   explicit HBooleanNot(HInstruction* input)
   2970       : HUnaryOperation(Primitive::Type::kPrimBoolean, input) {}
   2971 
   2972   bool CanBeMoved() const OVERRIDE { return true; }
   2973   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   2974     UNUSED(other);
   2975     return true;
   2976   }
   2977 
   2978   int32_t Evaluate(int32_t x) const OVERRIDE {
   2979     DCHECK(IsUint<1>(x));
   2980     return !x;
   2981   }
   2982 
   2983   int64_t Evaluate(int64_t x ATTRIBUTE_UNUSED) const OVERRIDE {
   2984     LOG(FATAL) << DebugName() << " cannot be used with 64-bit values";
   2985     UNREACHABLE();
   2986   }
   2987 
   2988   DECLARE_INSTRUCTION(BooleanNot);
   2989 
   2990  private:
   2991   DISALLOW_COPY_AND_ASSIGN(HBooleanNot);
   2992 };
   2993 
   2994 class HTypeConversion : public HExpression<1> {
   2995  public:
   2996   // Instantiate a type conversion of `input` to `result_type`.
   2997   HTypeConversion(Primitive::Type result_type, HInstruction* input, uint32_t dex_pc)
   2998       : HExpression(result_type, SideEffects::None()), dex_pc_(dex_pc) {
   2999     SetRawInputAt(0, input);
   3000     DCHECK_NE(input->GetType(), result_type);
   3001   }
   3002 
   3003   HInstruction* GetInput() const { return InputAt(0); }
   3004   Primitive::Type GetInputType() const { return GetInput()->GetType(); }
   3005   Primitive::Type GetResultType() const { return GetType(); }
   3006 
   3007   // Required by the x86 and ARM code generators when producing calls
   3008   // to the runtime.
   3009   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3010 
   3011   bool CanBeMoved() const OVERRIDE { return true; }
   3012   bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE { return true; }
   3013 
   3014   DECLARE_INSTRUCTION(TypeConversion);
   3015 
   3016  private:
   3017   const uint32_t dex_pc_;
   3018 
   3019   DISALLOW_COPY_AND_ASSIGN(HTypeConversion);
   3020 };
   3021 
   3022 static constexpr uint32_t kNoRegNumber = -1;
   3023 
   3024 class HPhi : public HInstruction {
   3025  public:
   3026   HPhi(ArenaAllocator* arena, uint32_t reg_number, size_t number_of_inputs, Primitive::Type type)
   3027       : HInstruction(SideEffects::None()),
   3028         inputs_(arena, number_of_inputs),
   3029         reg_number_(reg_number),
   3030         type_(type),
   3031         is_live_(false),
   3032         can_be_null_(true) {
   3033     inputs_.SetSize(number_of_inputs);
   3034   }
   3035 
   3036   // Returns a type equivalent to the given `type`, but that a `HPhi` can hold.
   3037   static Primitive::Type ToPhiType(Primitive::Type type) {
   3038     switch (type) {
   3039       case Primitive::kPrimBoolean:
   3040       case Primitive::kPrimByte:
   3041       case Primitive::kPrimShort:
   3042       case Primitive::kPrimChar:
   3043         return Primitive::kPrimInt;
   3044       default:
   3045         return type;
   3046     }
   3047   }
   3048 
   3049   size_t InputCount() const OVERRIDE { return inputs_.Size(); }
   3050 
   3051   void AddInput(HInstruction* input);
   3052   void RemoveInputAt(size_t index);
   3053 
   3054   Primitive::Type GetType() const OVERRIDE { return type_; }
   3055   void SetType(Primitive::Type type) { type_ = type; }
   3056 
   3057   bool CanBeNull() const OVERRIDE { return can_be_null_; }
   3058   void SetCanBeNull(bool can_be_null) { can_be_null_ = can_be_null; }
   3059 
   3060   uint32_t GetRegNumber() const { return reg_number_; }
   3061 
   3062   void SetDead() { is_live_ = false; }
   3063   void SetLive() { is_live_ = true; }
   3064   bool IsDead() const { return !is_live_; }
   3065   bool IsLive() const { return is_live_; }
   3066 
   3067   // Returns the next equivalent phi (starting from the current one) or null if there is none.
   3068   // An equivalent phi is a phi having the same dex register and type.
   3069   // It assumes that phis with the same dex register are adjacent.
   3070   HPhi* GetNextEquivalentPhiWithSameType() {
   3071     HInstruction* next = GetNext();
   3072     while (next != nullptr && next->AsPhi()->GetRegNumber() == reg_number_) {
   3073       if (next->GetType() == GetType()) {
   3074         return next->AsPhi();
   3075       }
   3076       next = next->GetNext();
   3077     }
   3078     return nullptr;
   3079   }
   3080 
   3081   DECLARE_INSTRUCTION(Phi);
   3082 
   3083  protected:
   3084   const HUserRecord<HInstruction*> InputRecordAt(size_t i) const OVERRIDE { return inputs_.Get(i); }
   3085 
   3086   void SetRawInputRecordAt(size_t index, const HUserRecord<HInstruction*>& input) OVERRIDE {
   3087     inputs_.Put(index, input);
   3088   }
   3089 
   3090  private:
   3091   GrowableArray<HUserRecord<HInstruction*> > inputs_;
   3092   const uint32_t reg_number_;
   3093   Primitive::Type type_;
   3094   bool is_live_;
   3095   bool can_be_null_;
   3096 
   3097   DISALLOW_COPY_AND_ASSIGN(HPhi);
   3098 };
   3099 
   3100 class HNullCheck : public HExpression<1> {
   3101  public:
   3102   HNullCheck(HInstruction* value, uint32_t dex_pc)
   3103       : HExpression(value->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
   3104     SetRawInputAt(0, value);
   3105   }
   3106 
   3107   bool CanBeMoved() const OVERRIDE { return true; }
   3108   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3109     UNUSED(other);
   3110     return true;
   3111   }
   3112 
   3113   bool NeedsEnvironment() const OVERRIDE { return true; }
   3114 
   3115   bool CanThrow() const OVERRIDE { return true; }
   3116 
   3117   bool CanBeNull() const OVERRIDE { return false; }
   3118 
   3119   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3120 
   3121   DECLARE_INSTRUCTION(NullCheck);
   3122 
   3123  private:
   3124   const uint32_t dex_pc_;
   3125 
   3126   DISALLOW_COPY_AND_ASSIGN(HNullCheck);
   3127 };
   3128 
   3129 class FieldInfo : public ValueObject {
   3130  public:
   3131   FieldInfo(MemberOffset field_offset, Primitive::Type field_type, bool is_volatile)
   3132       : field_offset_(field_offset), field_type_(field_type), is_volatile_(is_volatile) {}
   3133 
   3134   MemberOffset GetFieldOffset() const { return field_offset_; }
   3135   Primitive::Type GetFieldType() const { return field_type_; }
   3136   bool IsVolatile() const { return is_volatile_; }
   3137 
   3138  private:
   3139   const MemberOffset field_offset_;
   3140   const Primitive::Type field_type_;
   3141   const bool is_volatile_;
   3142 };
   3143 
   3144 class HInstanceFieldGet : public HExpression<1> {
   3145  public:
   3146   HInstanceFieldGet(HInstruction* value,
   3147                     Primitive::Type field_type,
   3148                     MemberOffset field_offset,
   3149                     bool is_volatile)
   3150       : HExpression(field_type, SideEffects::DependsOnSomething()),
   3151         field_info_(field_offset, field_type, is_volatile) {
   3152     SetRawInputAt(0, value);
   3153   }
   3154 
   3155   bool CanBeMoved() const OVERRIDE { return !IsVolatile(); }
   3156 
   3157   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3158     HInstanceFieldGet* other_get = other->AsInstanceFieldGet();
   3159     return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue();
   3160   }
   3161 
   3162   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   3163     return (obj == InputAt(0)) && GetFieldOffset().Uint32Value() < kPageSize;
   3164   }
   3165 
   3166   size_t ComputeHashCode() const OVERRIDE {
   3167     return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue();
   3168   }
   3169 
   3170   const FieldInfo& GetFieldInfo() const { return field_info_; }
   3171   MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
   3172   Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
   3173   bool IsVolatile() const { return field_info_.IsVolatile(); }
   3174 
   3175   DECLARE_INSTRUCTION(InstanceFieldGet);
   3176 
   3177  private:
   3178   const FieldInfo field_info_;
   3179 
   3180   DISALLOW_COPY_AND_ASSIGN(HInstanceFieldGet);
   3181 };
   3182 
   3183 class HInstanceFieldSet : public HTemplateInstruction<2> {
   3184  public:
   3185   HInstanceFieldSet(HInstruction* object,
   3186                     HInstruction* value,
   3187                     Primitive::Type field_type,
   3188                     MemberOffset field_offset,
   3189                     bool is_volatile)
   3190       : HTemplateInstruction(SideEffects::ChangesSomething()),
   3191         field_info_(field_offset, field_type, is_volatile) {
   3192     SetRawInputAt(0, object);
   3193     SetRawInputAt(1, value);
   3194   }
   3195 
   3196   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   3197     return (obj == InputAt(0)) && GetFieldOffset().Uint32Value() < kPageSize;
   3198   }
   3199 
   3200   const FieldInfo& GetFieldInfo() const { return field_info_; }
   3201   MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
   3202   Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
   3203   bool IsVolatile() const { return field_info_.IsVolatile(); }
   3204   HInstruction* GetValue() const { return InputAt(1); }
   3205 
   3206   DECLARE_INSTRUCTION(InstanceFieldSet);
   3207 
   3208  private:
   3209   const FieldInfo field_info_;
   3210 
   3211   DISALLOW_COPY_AND_ASSIGN(HInstanceFieldSet);
   3212 };
   3213 
   3214 class HArrayGet : public HExpression<2> {
   3215  public:
   3216   HArrayGet(HInstruction* array, HInstruction* index, Primitive::Type type)
   3217       : HExpression(type, SideEffects::DependsOnSomething()) {
   3218     SetRawInputAt(0, array);
   3219     SetRawInputAt(1, index);
   3220   }
   3221 
   3222   bool CanBeMoved() const OVERRIDE { return true; }
   3223   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3224     UNUSED(other);
   3225     return true;
   3226   }
   3227   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   3228     UNUSED(obj);
   3229     // TODO: We can be smarter here.
   3230     // Currently, the array access is always preceded by an ArrayLength or a NullCheck
   3231     // which generates the implicit null check. There are cases when these can be removed
   3232     // to produce better code. If we ever add optimizations to do so we should allow an
   3233     // implicit check here (as long as the address falls in the first page).
   3234     return false;
   3235   }
   3236 
   3237   void SetType(Primitive::Type type) { type_ = type; }
   3238 
   3239   HInstruction* GetArray() const { return InputAt(0); }
   3240   HInstruction* GetIndex() const { return InputAt(1); }
   3241 
   3242   DECLARE_INSTRUCTION(ArrayGet);
   3243 
   3244  private:
   3245   DISALLOW_COPY_AND_ASSIGN(HArrayGet);
   3246 };
   3247 
   3248 class HArraySet : public HTemplateInstruction<3> {
   3249  public:
   3250   HArraySet(HInstruction* array,
   3251             HInstruction* index,
   3252             HInstruction* value,
   3253             Primitive::Type expected_component_type,
   3254             uint32_t dex_pc)
   3255       : HTemplateInstruction(SideEffects::ChangesSomething()),
   3256         dex_pc_(dex_pc),
   3257         expected_component_type_(expected_component_type),
   3258         needs_type_check_(value->GetType() == Primitive::kPrimNot) {
   3259     SetRawInputAt(0, array);
   3260     SetRawInputAt(1, index);
   3261     SetRawInputAt(2, value);
   3262   }
   3263 
   3264   bool NeedsEnvironment() const OVERRIDE {
   3265     // We currently always call a runtime method to catch array store
   3266     // exceptions.
   3267     return needs_type_check_;
   3268   }
   3269 
   3270   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   3271     UNUSED(obj);
   3272     // TODO: Same as for ArrayGet.
   3273     return false;
   3274   }
   3275 
   3276   void ClearNeedsTypeCheck() {
   3277     needs_type_check_ = false;
   3278   }
   3279 
   3280   bool NeedsTypeCheck() const { return needs_type_check_; }
   3281 
   3282   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3283 
   3284   HInstruction* GetArray() const { return InputAt(0); }
   3285   HInstruction* GetIndex() const { return InputAt(1); }
   3286   HInstruction* GetValue() const { return InputAt(2); }
   3287 
   3288   Primitive::Type GetComponentType() const {
   3289     // The Dex format does not type floating point index operations. Since the
   3290     // `expected_component_type_` is set during building and can therefore not
   3291     // be correct, we also check what is the value type. If it is a floating
   3292     // point type, we must use that type.
   3293     Primitive::Type value_type = GetValue()->GetType();
   3294     return ((value_type == Primitive::kPrimFloat) || (value_type == Primitive::kPrimDouble))
   3295         ? value_type
   3296         : expected_component_type_;
   3297   }
   3298 
   3299   DECLARE_INSTRUCTION(ArraySet);
   3300 
   3301  private:
   3302   const uint32_t dex_pc_;
   3303   const Primitive::Type expected_component_type_;
   3304   bool needs_type_check_;
   3305 
   3306   DISALLOW_COPY_AND_ASSIGN(HArraySet);
   3307 };
   3308 
   3309 class HArrayLength : public HExpression<1> {
   3310  public:
   3311   explicit HArrayLength(HInstruction* array)
   3312       : HExpression(Primitive::kPrimInt, SideEffects::None()) {
   3313     // Note that arrays do not change length, so the instruction does not
   3314     // depend on any write.
   3315     SetRawInputAt(0, array);
   3316   }
   3317 
   3318   bool CanBeMoved() const OVERRIDE { return true; }
   3319   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3320     UNUSED(other);
   3321     return true;
   3322   }
   3323   bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE {
   3324     return obj == InputAt(0);
   3325   }
   3326 
   3327   DECLARE_INSTRUCTION(ArrayLength);
   3328 
   3329  private:
   3330   DISALLOW_COPY_AND_ASSIGN(HArrayLength);
   3331 };
   3332 
   3333 class HBoundsCheck : public HExpression<2> {
   3334  public:
   3335   HBoundsCheck(HInstruction* index, HInstruction* length, uint32_t dex_pc)
   3336       : HExpression(index->GetType(), SideEffects::None()), dex_pc_(dex_pc) {
   3337     DCHECK(index->GetType() == Primitive::kPrimInt);
   3338     SetRawInputAt(0, index);
   3339     SetRawInputAt(1, length);
   3340   }
   3341 
   3342   bool CanBeMoved() const OVERRIDE { return true; }
   3343   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3344     UNUSED(other);
   3345     return true;
   3346   }
   3347 
   3348   bool NeedsEnvironment() const OVERRIDE { return true; }
   3349 
   3350   bool CanThrow() const OVERRIDE { return true; }
   3351 
   3352   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3353 
   3354   DECLARE_INSTRUCTION(BoundsCheck);
   3355 
   3356  private:
   3357   const uint32_t dex_pc_;
   3358 
   3359   DISALLOW_COPY_AND_ASSIGN(HBoundsCheck);
   3360 };
   3361 
   3362 /**
   3363  * Some DEX instructions are folded into multiple HInstructions that need
   3364  * to stay live until the last HInstruction. This class
   3365  * is used as a marker for the baseline compiler to ensure its preceding
   3366  * HInstruction stays live. `index` represents the stack location index of the
   3367  * instruction (the actual offset is computed as index * vreg_size).
   3368  */
   3369 class HTemporary : public HTemplateInstruction<0> {
   3370  public:
   3371   explicit HTemporary(size_t index) : HTemplateInstruction(SideEffects::None()), index_(index) {}
   3372 
   3373   size_t GetIndex() const { return index_; }
   3374 
   3375   Primitive::Type GetType() const OVERRIDE {
   3376     // The previous instruction is the one that will be stored in the temporary location.
   3377     DCHECK(GetPrevious() != nullptr);
   3378     return GetPrevious()->GetType();
   3379   }
   3380 
   3381   DECLARE_INSTRUCTION(Temporary);
   3382 
   3383  private:
   3384   const size_t index_;
   3385 
   3386   DISALLOW_COPY_AND_ASSIGN(HTemporary);
   3387 };
   3388 
   3389 class HSuspendCheck : public HTemplateInstruction<0> {
   3390  public:
   3391   explicit HSuspendCheck(uint32_t dex_pc)
   3392       : HTemplateInstruction(SideEffects::None()), dex_pc_(dex_pc), slow_path_(nullptr) {}
   3393 
   3394   bool NeedsEnvironment() const OVERRIDE {
   3395     return true;
   3396   }
   3397 
   3398   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3399   void SetSlowPath(SlowPathCode* slow_path) { slow_path_ = slow_path; }
   3400   SlowPathCode* GetSlowPath() const { return slow_path_; }
   3401 
   3402   DECLARE_INSTRUCTION(SuspendCheck);
   3403 
   3404  private:
   3405   const uint32_t dex_pc_;
   3406 
   3407   // Only used for code generation, in order to share the same slow path between back edges
   3408   // of a same loop.
   3409   SlowPathCode* slow_path_;
   3410 
   3411   DISALLOW_COPY_AND_ASSIGN(HSuspendCheck);
   3412 };
   3413 
   3414 /**
   3415  * Instruction to load a Class object.
   3416  */
   3417 class HLoadClass : public HExpression<0> {
   3418  public:
   3419   HLoadClass(uint16_t type_index,
   3420              bool is_referrers_class,
   3421              uint32_t dex_pc)
   3422       : HExpression(Primitive::kPrimNot, SideEffects::None()),
   3423         type_index_(type_index),
   3424         is_referrers_class_(is_referrers_class),
   3425         dex_pc_(dex_pc),
   3426         generate_clinit_check_(false),
   3427         loaded_class_rti_(ReferenceTypeInfo::CreateTop(/* is_exact */ false)) {}
   3428 
   3429   bool CanBeMoved() const OVERRIDE { return true; }
   3430 
   3431   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3432     return other->AsLoadClass()->type_index_ == type_index_;
   3433   }
   3434 
   3435   size_t ComputeHashCode() const OVERRIDE { return type_index_; }
   3436 
   3437   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3438   uint16_t GetTypeIndex() const { return type_index_; }
   3439   bool IsReferrersClass() const { return is_referrers_class_; }
   3440   bool CanBeNull() const OVERRIDE { return false; }
   3441 
   3442   bool NeedsEnvironment() const OVERRIDE {
   3443     // Will call runtime and load the class if the class is not loaded yet.
   3444     // TODO: finer grain decision.
   3445     return !is_referrers_class_;
   3446   }
   3447 
   3448   bool MustGenerateClinitCheck() const {
   3449     return generate_clinit_check_;
   3450   }
   3451 
   3452   void SetMustGenerateClinitCheck() {
   3453     generate_clinit_check_ = true;
   3454   }
   3455 
   3456   bool CanCallRuntime() const {
   3457     return MustGenerateClinitCheck() || !is_referrers_class_;
   3458   }
   3459 
   3460   bool CanThrow() const OVERRIDE {
   3461     // May call runtime and and therefore can throw.
   3462     // TODO: finer grain decision.
   3463     return !is_referrers_class_;
   3464   }
   3465 
   3466   ReferenceTypeInfo GetLoadedClassRTI() {
   3467     return loaded_class_rti_;
   3468   }
   3469 
   3470   void SetLoadedClassRTI(ReferenceTypeInfo rti) {
   3471     // Make sure we only set exact types (the loaded class should never be merged).
   3472     DCHECK(rti.IsExact());
   3473     loaded_class_rti_ = rti;
   3474   }
   3475 
   3476   bool IsResolved() {
   3477     return loaded_class_rti_.IsExact();
   3478   }
   3479 
   3480   bool NeedsDexCache() const OVERRIDE { return !is_referrers_class_; }
   3481 
   3482   DECLARE_INSTRUCTION(LoadClass);
   3483 
   3484  private:
   3485   const uint16_t type_index_;
   3486   const bool is_referrers_class_;
   3487   const uint32_t dex_pc_;
   3488   // Whether this instruction must generate the initialization check.
   3489   // Used for code generation.
   3490   bool generate_clinit_check_;
   3491 
   3492   ReferenceTypeInfo loaded_class_rti_;
   3493 
   3494   DISALLOW_COPY_AND_ASSIGN(HLoadClass);
   3495 };
   3496 
   3497 class HLoadString : public HExpression<0> {
   3498  public:
   3499   HLoadString(uint32_t string_index, uint32_t dex_pc)
   3500       : HExpression(Primitive::kPrimNot, SideEffects::None()),
   3501         string_index_(string_index),
   3502         dex_pc_(dex_pc) {}
   3503 
   3504   bool CanBeMoved() const OVERRIDE { return true; }
   3505 
   3506   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3507     return other->AsLoadString()->string_index_ == string_index_;
   3508   }
   3509 
   3510   size_t ComputeHashCode() const OVERRIDE { return string_index_; }
   3511 
   3512   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3513   uint32_t GetStringIndex() const { return string_index_; }
   3514 
   3515   // TODO: Can we deopt or debug when we resolve a string?
   3516   bool NeedsEnvironment() const OVERRIDE { return false; }
   3517   bool NeedsDexCache() const OVERRIDE { return true; }
   3518 
   3519   DECLARE_INSTRUCTION(LoadString);
   3520 
   3521  private:
   3522   const uint32_t string_index_;
   3523   const uint32_t dex_pc_;
   3524 
   3525   DISALLOW_COPY_AND_ASSIGN(HLoadString);
   3526 };
   3527 
   3528 /**
   3529  * Performs an initialization check on its Class object input.
   3530  */
   3531 class HClinitCheck : public HExpression<1> {
   3532  public:
   3533   explicit HClinitCheck(HLoadClass* constant, uint32_t dex_pc)
   3534       : HExpression(Primitive::kPrimNot, SideEffects::ChangesSomething()),
   3535         dex_pc_(dex_pc) {
   3536     SetRawInputAt(0, constant);
   3537   }
   3538 
   3539   bool CanBeMoved() const OVERRIDE { return true; }
   3540   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3541     UNUSED(other);
   3542     return true;
   3543   }
   3544 
   3545   bool NeedsEnvironment() const OVERRIDE {
   3546     // May call runtime to initialize the class.
   3547     return true;
   3548   }
   3549 
   3550   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3551 
   3552   HLoadClass* GetLoadClass() const { return InputAt(0)->AsLoadClass(); }
   3553 
   3554   DECLARE_INSTRUCTION(ClinitCheck);
   3555 
   3556  private:
   3557   const uint32_t dex_pc_;
   3558 
   3559   DISALLOW_COPY_AND_ASSIGN(HClinitCheck);
   3560 };
   3561 
   3562 class HStaticFieldGet : public HExpression<1> {
   3563  public:
   3564   HStaticFieldGet(HInstruction* cls,
   3565                   Primitive::Type field_type,
   3566                   MemberOffset field_offset,
   3567                   bool is_volatile)
   3568       : HExpression(field_type, SideEffects::DependsOnSomething()),
   3569         field_info_(field_offset, field_type, is_volatile) {
   3570     SetRawInputAt(0, cls);
   3571   }
   3572 
   3573 
   3574   bool CanBeMoved() const OVERRIDE { return !IsVolatile(); }
   3575 
   3576   bool InstructionDataEquals(HInstruction* other) const OVERRIDE {
   3577     HStaticFieldGet* other_get = other->AsStaticFieldGet();
   3578     return GetFieldOffset().SizeValue() == other_get->GetFieldOffset().SizeValue();
   3579   }
   3580 
   3581   size_t ComputeHashCode() const OVERRIDE {
   3582     return (HInstruction::ComputeHashCode() << 7) | GetFieldOffset().SizeValue();
   3583   }
   3584 
   3585   const FieldInfo& GetFieldInfo() const { return field_info_; }
   3586   MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
   3587   Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
   3588   bool IsVolatile() const { return field_info_.IsVolatile(); }
   3589 
   3590   DECLARE_INSTRUCTION(StaticFieldGet);
   3591 
   3592  private:
   3593   const FieldInfo field_info_;
   3594 
   3595   DISALLOW_COPY_AND_ASSIGN(HStaticFieldGet);
   3596 };
   3597 
   3598 class HStaticFieldSet : public HTemplateInstruction<2> {
   3599  public:
   3600   HStaticFieldSet(HInstruction* cls,
   3601                   HInstruction* value,
   3602                   Primitive::Type field_type,
   3603                   MemberOffset field_offset,
   3604                   bool is_volatile)
   3605       : HTemplateInstruction(SideEffects::ChangesSomething()),
   3606         field_info_(field_offset, field_type, is_volatile) {
   3607     SetRawInputAt(0, cls);
   3608     SetRawInputAt(1, value);
   3609   }
   3610 
   3611   const FieldInfo& GetFieldInfo() const { return field_info_; }
   3612   MemberOffset GetFieldOffset() const { return field_info_.GetFieldOffset(); }
   3613   Primitive::Type GetFieldType() const { return field_info_.GetFieldType(); }
   3614   bool IsVolatile() const { return field_info_.IsVolatile(); }
   3615 
   3616   HInstruction* GetValue() const { return InputAt(1); }
   3617 
   3618   DECLARE_INSTRUCTION(StaticFieldSet);
   3619 
   3620  private:
   3621   const FieldInfo field_info_;
   3622 
   3623   DISALLOW_COPY_AND_ASSIGN(HStaticFieldSet);
   3624 };
   3625 
   3626 // Implement the move-exception DEX instruction.
   3627 class HLoadException : public HExpression<0> {
   3628  public:
   3629   HLoadException() : HExpression(Primitive::kPrimNot, SideEffects::None()) {}
   3630 
   3631   DECLARE_INSTRUCTION(LoadException);
   3632 
   3633  private:
   3634   DISALLOW_COPY_AND_ASSIGN(HLoadException);
   3635 };
   3636 
   3637 class HThrow : public HTemplateInstruction<1> {
   3638  public:
   3639   HThrow(HInstruction* exception, uint32_t dex_pc)
   3640       : HTemplateInstruction(SideEffects::None()), dex_pc_(dex_pc) {
   3641     SetRawInputAt(0, exception);
   3642   }
   3643 
   3644   bool IsControlFlow() const OVERRIDE { return true; }
   3645 
   3646   bool NeedsEnvironment() const OVERRIDE { return true; }
   3647 
   3648   bool CanThrow() const OVERRIDE { return true; }
   3649 
   3650   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3651 
   3652   DECLARE_INSTRUCTION(Throw);
   3653 
   3654  private:
   3655   const uint32_t dex_pc_;
   3656 
   3657   DISALLOW_COPY_AND_ASSIGN(HThrow);
   3658 };
   3659 
   3660 class HInstanceOf : public HExpression<2> {
   3661  public:
   3662   HInstanceOf(HInstruction* object,
   3663               HLoadClass* constant,
   3664               bool class_is_final,
   3665               uint32_t dex_pc)
   3666       : HExpression(Primitive::kPrimBoolean, SideEffects::None()),
   3667         class_is_final_(class_is_final),
   3668         must_do_null_check_(true),
   3669         dex_pc_(dex_pc) {
   3670     SetRawInputAt(0, object);
   3671     SetRawInputAt(1, constant);
   3672   }
   3673 
   3674   bool CanBeMoved() const OVERRIDE { return true; }
   3675 
   3676   bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE {
   3677     return true;
   3678   }
   3679 
   3680   bool NeedsEnvironment() const OVERRIDE {
   3681     return false;
   3682   }
   3683 
   3684   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3685 
   3686   bool IsClassFinal() const { return class_is_final_; }
   3687 
   3688   // Used only in code generation.
   3689   bool MustDoNullCheck() const { return must_do_null_check_; }
   3690   void ClearMustDoNullCheck() { must_do_null_check_ = false; }
   3691 
   3692   DECLARE_INSTRUCTION(InstanceOf);
   3693 
   3694  private:
   3695   const bool class_is_final_;
   3696   bool must_do_null_check_;
   3697   const uint32_t dex_pc_;
   3698 
   3699   DISALLOW_COPY_AND_ASSIGN(HInstanceOf);
   3700 };
   3701 
   3702 class HBoundType : public HExpression<1> {
   3703  public:
   3704   HBoundType(HInstruction* input, ReferenceTypeInfo bound_type)
   3705       : HExpression(Primitive::kPrimNot, SideEffects::None()),
   3706         bound_type_(bound_type) {
   3707     DCHECK_EQ(input->GetType(), Primitive::kPrimNot);
   3708     SetRawInputAt(0, input);
   3709   }
   3710 
   3711   const ReferenceTypeInfo& GetBoundType() const { return bound_type_; }
   3712 
   3713   bool CanBeNull() const OVERRIDE {
   3714     // `null instanceof ClassX` always return false so we can't be null.
   3715     return false;
   3716   }
   3717 
   3718   DECLARE_INSTRUCTION(BoundType);
   3719 
   3720  private:
   3721   // Encodes the most upper class that this instruction can have. In other words
   3722   // it is always the case that GetBoundType().IsSupertypeOf(GetReferenceType()).
   3723   // It is used to bound the type in cases like `if (x instanceof ClassX) {}`
   3724   const ReferenceTypeInfo bound_type_;
   3725 
   3726   DISALLOW_COPY_AND_ASSIGN(HBoundType);
   3727 };
   3728 
   3729 class HCheckCast : public HTemplateInstruction<2> {
   3730  public:
   3731   HCheckCast(HInstruction* object,
   3732              HLoadClass* constant,
   3733              bool class_is_final,
   3734              uint32_t dex_pc)
   3735       : HTemplateInstruction(SideEffects::None()),
   3736         class_is_final_(class_is_final),
   3737         must_do_null_check_(true),
   3738         dex_pc_(dex_pc) {
   3739     SetRawInputAt(0, object);
   3740     SetRawInputAt(1, constant);
   3741   }
   3742 
   3743   bool CanBeMoved() const OVERRIDE { return true; }
   3744 
   3745   bool InstructionDataEquals(HInstruction* other ATTRIBUTE_UNUSED) const OVERRIDE {
   3746     return true;
   3747   }
   3748 
   3749   bool NeedsEnvironment() const OVERRIDE {
   3750     // Instruction may throw a CheckCastError.
   3751     return true;
   3752   }
   3753 
   3754   bool CanThrow() const OVERRIDE { return true; }
   3755 
   3756   bool MustDoNullCheck() const { return must_do_null_check_; }
   3757   void ClearMustDoNullCheck() { must_do_null_check_ = false; }
   3758 
   3759   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3760 
   3761   bool IsClassFinal() const { return class_is_final_; }
   3762 
   3763   DECLARE_INSTRUCTION(CheckCast);
   3764 
   3765  private:
   3766   const bool class_is_final_;
   3767   bool must_do_null_check_;
   3768   const uint32_t dex_pc_;
   3769 
   3770   DISALLOW_COPY_AND_ASSIGN(HCheckCast);
   3771 };
   3772 
   3773 class HMemoryBarrier : public HTemplateInstruction<0> {
   3774  public:
   3775   explicit HMemoryBarrier(MemBarrierKind barrier_kind)
   3776       : HTemplateInstruction(SideEffects::None()),
   3777         barrier_kind_(barrier_kind) {}
   3778 
   3779   MemBarrierKind GetBarrierKind() { return barrier_kind_; }
   3780 
   3781   DECLARE_INSTRUCTION(MemoryBarrier);
   3782 
   3783  private:
   3784   const MemBarrierKind barrier_kind_;
   3785 
   3786   DISALLOW_COPY_AND_ASSIGN(HMemoryBarrier);
   3787 };
   3788 
   3789 class HMonitorOperation : public HTemplateInstruction<1> {
   3790  public:
   3791   enum OperationKind {
   3792     kEnter,
   3793     kExit,
   3794   };
   3795 
   3796   HMonitorOperation(HInstruction* object, OperationKind kind, uint32_t dex_pc)
   3797     : HTemplateInstruction(SideEffects::None()), kind_(kind), dex_pc_(dex_pc) {
   3798     SetRawInputAt(0, object);
   3799   }
   3800 
   3801   // Instruction may throw a Java exception, so we need an environment.
   3802   bool NeedsEnvironment() const OVERRIDE { return true; }
   3803   bool CanThrow() const OVERRIDE { return true; }
   3804 
   3805   uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
   3806 
   3807   bool IsEnter() const { return kind_ == kEnter; }
   3808 
   3809   DECLARE_INSTRUCTION(MonitorOperation);
   3810 
   3811  private:
   3812   const OperationKind kind_;
   3813   const uint32_t dex_pc_;
   3814 
   3815  private:
   3816   DISALLOW_COPY_AND_ASSIGN(HMonitorOperation);
   3817 };
   3818 
   3819 class MoveOperands : public ArenaObject<kArenaAllocMisc> {
   3820  public:
   3821   MoveOperands(Location source,
   3822                Location destination,
   3823                Primitive::Type type,
   3824                HInstruction* instruction)
   3825       : source_(source), destination_(destination), type_(type), instruction_(instruction) {}
   3826 
   3827   Location GetSource() const { return source_; }
   3828   Location GetDestination() const { return destination_; }
   3829 
   3830   void SetSource(Location value) { source_ = value; }
   3831   void SetDestination(Location value) { destination_ = value; }
   3832 
   3833   // The parallel move resolver marks moves as "in-progress" by clearing the
   3834   // destination (but not the source).
   3835   Location MarkPending() {
   3836     DCHECK(!IsPending());
   3837     Location dest = destination_;
   3838     destination_ = Location::NoLocation();
   3839     return dest;
   3840   }
   3841 
   3842   void ClearPending(Location dest) {
   3843     DCHECK(IsPending());
   3844     destination_ = dest;
   3845   }
   3846 
   3847   bool IsPending() const {
   3848     DCHECK(!source_.IsInvalid() || destination_.IsInvalid());
   3849     return destination_.IsInvalid() && !source_.IsInvalid();
   3850   }
   3851 
   3852   // True if this blocks a move from the given location.
   3853   bool Blocks(Location loc) const {
   3854     return !IsEliminated() && source_.OverlapsWith(loc);
   3855   }
   3856 
   3857   // A move is redundant if it's been eliminated, if its source and
   3858   // destination are the same, or if its destination is unneeded.
   3859   bool IsRedundant() const {
   3860     return IsEliminated() || destination_.IsInvalid() || source_.Equals(destination_);
   3861   }
   3862 
   3863   // We clear both operands to indicate move that's been eliminated.
   3864   void Eliminate() {
   3865     source_ = destination_ = Location::NoLocation();
   3866   }
   3867 
   3868   bool IsEliminated() const {
   3869     DCHECK(!source_.IsInvalid() || destination_.IsInvalid());
   3870     return source_.IsInvalid();
   3871   }
   3872 
   3873   Primitive::Type GetType() const { return type_; }
   3874 
   3875   bool Is64BitMove() const {
   3876     return Primitive::Is64BitType(type_);
   3877   }
   3878 
   3879   HInstruction* GetInstruction() const { return instruction_; }
   3880 
   3881  private:
   3882   Location source_;
   3883   Location destination_;
   3884   // The type this move is for.
   3885   Primitive::Type type_;
   3886   // The instruction this move is assocatied with. Null when this move is
   3887   // for moving an input in the expected locations of user (including a phi user).
   3888   // This is only used in debug mode, to ensure we do not connect interval siblings
   3889   // in the same parallel move.
   3890   HInstruction* instruction_;
   3891 };
   3892 
   3893 static constexpr size_t kDefaultNumberOfMoves = 4;
   3894 
   3895 class HParallelMove : public HTemplateInstruction<0> {
   3896  public:
   3897   explicit HParallelMove(ArenaAllocator* arena)
   3898       : HTemplateInstruction(SideEffects::None()), moves_(arena, kDefaultNumberOfMoves) {}
   3899 
   3900   void AddMove(Location source,
   3901                Location destination,
   3902                Primitive::Type type,
   3903                HInstruction* instruction) {
   3904     DCHECK(source.IsValid());
   3905     DCHECK(destination.IsValid());
   3906     if (kIsDebugBuild) {
   3907       if (instruction != nullptr) {
   3908         for (size_t i = 0, e = moves_.Size(); i < e; ++i) {
   3909           if (moves_.Get(i).GetInstruction() == instruction) {
   3910             // Special case the situation where the move is for the spill slot
   3911             // of the instruction.
   3912             if ((GetPrevious() == instruction)
   3913                 || ((GetPrevious() == nullptr)
   3914                     && instruction->IsPhi()
   3915                     && instruction->GetBlock() == GetBlock())) {
   3916               DCHECK_NE(destination.GetKind(), moves_.Get(i).GetDestination().GetKind())
   3917                   << "Doing parallel moves for the same instruction.";
   3918             } else {
   3919               DCHECK(false) << "Doing parallel moves for the same instruction.";
   3920             }
   3921           }
   3922         }
   3923       }
   3924       for (size_t i = 0, e = moves_.Size(); i < e; ++i) {
   3925         DCHECK(!destination.OverlapsWith(moves_.Get(i).GetDestination()))
   3926             << "Overlapped destination for two moves in a parallel move.";
   3927       }
   3928     }
   3929     moves_.Add(MoveOperands(source, destination, type, instruction));
   3930   }
   3931 
   3932   MoveOperands* MoveOperandsAt(size_t index) const {
   3933     return moves_.GetRawStorage() + index;
   3934   }
   3935 
   3936   size_t NumMoves() const { return moves_.Size(); }
   3937 
   3938   DECLARE_INSTRUCTION(ParallelMove);
   3939 
   3940  private:
   3941   GrowableArray<MoveOperands> moves_;
   3942 
   3943   DISALLOW_COPY_AND_ASSIGN(HParallelMove);
   3944 };
   3945 
   3946 class HGraphVisitor : public ValueObject {
   3947  public:
   3948   explicit HGraphVisitor(HGraph* graph) : graph_(graph) {}
   3949   virtual ~HGraphVisitor() {}
   3950 
   3951   virtual void VisitInstruction(HInstruction* instruction) { UNUSED(instruction); }
   3952   virtual void VisitBasicBlock(HBasicBlock* block);
   3953 
   3954   // Visit the graph following basic block insertion order.
   3955   void VisitInsertionOrder();
   3956 
   3957   // Visit the graph following dominator tree reverse post-order.
   3958   void VisitReversePostOrder();
   3959 
   3960   HGraph* GetGraph() const { return graph_; }
   3961 
   3962   // Visit functions for instruction classes.
   3963 #define DECLARE_VISIT_INSTRUCTION(name, super)                                        \
   3964   virtual void Visit##name(H##name* instr) { VisitInstruction(instr); }
   3965 
   3966   FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
   3967 
   3968 #undef DECLARE_VISIT_INSTRUCTION
   3969 
   3970  private:
   3971   HGraph* const graph_;
   3972 
   3973   DISALLOW_COPY_AND_ASSIGN(HGraphVisitor);
   3974 };
   3975 
   3976 class HGraphDelegateVisitor : public HGraphVisitor {
   3977  public:
   3978   explicit HGraphDelegateVisitor(HGraph* graph) : HGraphVisitor(graph) {}
   3979   virtual ~HGraphDelegateVisitor() {}
   3980 
   3981   // Visit functions that delegate to to super class.
   3982 #define DECLARE_VISIT_INSTRUCTION(name, super)                                        \
   3983   void Visit##name(H##name* instr) OVERRIDE { Visit##super(instr); }
   3984 
   3985   FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
   3986 
   3987 #undef DECLARE_VISIT_INSTRUCTION
   3988 
   3989  private:
   3990   DISALLOW_COPY_AND_ASSIGN(HGraphDelegateVisitor);
   3991 };
   3992 
   3993 class HInsertionOrderIterator : public ValueObject {
   3994  public:
   3995   explicit HInsertionOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {}
   3996 
   3997   bool Done() const { return index_ == graph_.GetBlocks().Size(); }
   3998   HBasicBlock* Current() const { return graph_.GetBlocks().Get(index_); }
   3999   void Advance() { ++index_; }
   4000 
   4001  private:
   4002   const HGraph& graph_;
   4003   size_t index_;
   4004 
   4005   DISALLOW_COPY_AND_ASSIGN(HInsertionOrderIterator);
   4006 };
   4007 
   4008 class HReversePostOrderIterator : public ValueObject {
   4009  public:
   4010   explicit HReversePostOrderIterator(const HGraph& graph) : graph_(graph), index_(0) {
   4011     // Check that reverse post order of the graph has been built.
   4012     DCHECK(!graph.GetReversePostOrder().IsEmpty());
   4013   }
   4014 
   4015   bool Done() const { return index_ == graph_.GetReversePostOrder().Size(); }
   4016   HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_); }
   4017   void Advance() { ++index_; }
   4018 
   4019  private:
   4020   const HGraph& graph_;
   4021   size_t index_;
   4022 
   4023   DISALLOW_COPY_AND_ASSIGN(HReversePostOrderIterator);
   4024 };
   4025 
   4026 class HPostOrderIterator : public ValueObject {
   4027  public:
   4028   explicit HPostOrderIterator(const HGraph& graph)
   4029       : graph_(graph), index_(graph_.GetReversePostOrder().Size()) {
   4030     // Check that reverse post order of the graph has been built.
   4031     DCHECK(!graph.GetReversePostOrder().IsEmpty());
   4032   }
   4033 
   4034   bool Done() const { return index_ == 0; }
   4035   HBasicBlock* Current() const { return graph_.GetReversePostOrder().Get(index_ - 1); }
   4036   void Advance() { --index_; }
   4037 
   4038  private:
   4039   const HGraph& graph_;
   4040   size_t index_;
   4041 
   4042   DISALLOW_COPY_AND_ASSIGN(HPostOrderIterator);
   4043 };
   4044 
   4045 class HLinearPostOrderIterator : public ValueObject {
   4046  public:
   4047   explicit HLinearPostOrderIterator(const HGraph& graph)
   4048       : order_(graph.GetLinearOrder()), index_(graph.GetLinearOrder().Size()) {}
   4049 
   4050   bool Done() const { return index_ == 0; }
   4051 
   4052   HBasicBlock* Current() const { return order_.Get(index_ -1); }
   4053 
   4054   void Advance() {
   4055     --index_;
   4056     DCHECK_GE(index_, 0U);
   4057   }
   4058 
   4059  private:
   4060   const GrowableArray<HBasicBlock*>& order_;
   4061   size_t index_;
   4062 
   4063   DISALLOW_COPY_AND_ASSIGN(HLinearPostOrderIterator);
   4064 };
   4065 
   4066 class HLinearOrderIterator : public ValueObject {
   4067  public:
   4068   explicit HLinearOrderIterator(const HGraph& graph)
   4069       : order_(graph.GetLinearOrder()), index_(0) {}
   4070 
   4071   bool Done() const { return index_ == order_.Size(); }
   4072   HBasicBlock* Current() const { return order_.Get(index_); }
   4073   void Advance() { ++index_; }
   4074 
   4075  private:
   4076   const GrowableArray<HBasicBlock*>& order_;
   4077   size_t index_;
   4078 
   4079   DISALLOW_COPY_AND_ASSIGN(HLinearOrderIterator);
   4080 };
   4081 
   4082 // Iterator over the blocks that art part of the loop. Includes blocks part
   4083 // of an inner loop. The order in which the blocks are iterated is on their
   4084 // block id.
   4085 class HBlocksInLoopIterator : public ValueObject {
   4086  public:
   4087   explicit HBlocksInLoopIterator(const HLoopInformation& info)
   4088       : blocks_in_loop_(info.GetBlocks()),
   4089         blocks_(info.GetHeader()->GetGraph()->GetBlocks()),
   4090         index_(0) {
   4091     if (!blocks_in_loop_.IsBitSet(index_)) {
   4092       Advance();
   4093     }
   4094   }
   4095 
   4096   bool Done() const { return index_ == blocks_.Size(); }
   4097   HBasicBlock* Current() const { return blocks_.Get(index_); }
   4098   void Advance() {
   4099     ++index_;
   4100     for (size_t e = blocks_.Size(); index_ < e; ++index_) {
   4101       if (blocks_in_loop_.IsBitSet(index_)) {
   4102         break;
   4103       }
   4104     }
   4105   }
   4106 
   4107  private:
   4108   const BitVector& blocks_in_loop_;
   4109   const GrowableArray<HBasicBlock*>& blocks_;
   4110   size_t index_;
   4111 
   4112   DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopIterator);
   4113 };
   4114 
   4115 // Iterator over the blocks that art part of the loop. Includes blocks part
   4116 // of an inner loop. The order in which the blocks are iterated is reverse
   4117 // post order.
   4118 class HBlocksInLoopReversePostOrderIterator : public ValueObject {
   4119  public:
   4120   explicit HBlocksInLoopReversePostOrderIterator(const HLoopInformation& info)
   4121       : blocks_in_loop_(info.GetBlocks()),
   4122         blocks_(info.GetHeader()->GetGraph()->GetReversePostOrder()),
   4123         index_(0) {
   4124     if (!blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
   4125       Advance();
   4126     }
   4127   }
   4128 
   4129   bool Done() const { return index_ == blocks_.Size(); }
   4130   HBasicBlock* Current() const { return blocks_.Get(index_); }
   4131   void Advance() {
   4132     ++index_;
   4133     for (size_t e = blocks_.Size(); index_ < e; ++index_) {
   4134       if (blocks_in_loop_.IsBitSet(blocks_.Get(index_)->GetBlockId())) {
   4135         break;
   4136       }
   4137     }
   4138   }
   4139 
   4140  private:
   4141   const BitVector& blocks_in_loop_;
   4142   const GrowableArray<HBasicBlock*>& blocks_;
   4143   size_t index_;
   4144 
   4145   DISALLOW_COPY_AND_ASSIGN(HBlocksInLoopReversePostOrderIterator);
   4146 };
   4147 
   4148 inline int64_t Int64FromConstant(HConstant* constant) {
   4149   DCHECK(constant->IsIntConstant() || constant->IsLongConstant());
   4150   return constant->IsIntConstant() ? constant->AsIntConstant()->GetValue()
   4151                                    : constant->AsLongConstant()->GetValue();
   4152 }
   4153 
   4154 }  // namespace art
   4155 
   4156 #endif  // ART_COMPILER_OPTIMIZING_NODES_H_
   4157