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