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