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#include "instruction_simplifier.h"
18
19#include "art_method-inl.h"
20#include "class_linker-inl.h"
21#include "escape.h"
22#include "intrinsics.h"
23#include "mirror/class-inl.h"
24#include "sharpening.h"
25#include "scoped_thread_state_change-inl.h"
26
27namespace art {
28
29class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
30 public:
31  InstructionSimplifierVisitor(HGraph* graph,
32                               CodeGenerator* codegen,
33                               OptimizingCompilerStats* stats)
34      : HGraphDelegateVisitor(graph),
35        codegen_(codegen),
36        stats_(stats) {}
37
38  void Run();
39
40 private:
41  void RecordSimplification() {
42    simplification_occurred_ = true;
43    simplifications_at_current_position_++;
44    MaybeRecordStat(kInstructionSimplifications);
45  }
46
47  void MaybeRecordStat(MethodCompilationStat stat) {
48    if (stats_ != nullptr) {
49      stats_->RecordStat(stat);
50    }
51  }
52
53  bool ReplaceRotateWithRor(HBinaryOperation* op, HUShr* ushr, HShl* shl);
54  bool TryReplaceWithRotate(HBinaryOperation* instruction);
55  bool TryReplaceWithRotateConstantPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
56  bool TryReplaceWithRotateRegisterNegPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
57  bool TryReplaceWithRotateRegisterSubPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
58
59  bool TryMoveNegOnInputsAfterBinop(HBinaryOperation* binop);
60  // `op` should be either HOr or HAnd.
61  // De Morgan's laws:
62  // ~a & ~b = ~(a | b)  and  ~a | ~b = ~(a & b)
63  bool TryDeMorganNegationFactoring(HBinaryOperation* op);
64  bool TryHandleAssociativeAndCommutativeOperation(HBinaryOperation* instruction);
65  bool TrySubtractionChainSimplification(HBinaryOperation* instruction);
66
67  void VisitShift(HBinaryOperation* shift);
68
69  void VisitEqual(HEqual* equal) OVERRIDE;
70  void VisitNotEqual(HNotEqual* equal) OVERRIDE;
71  void VisitBooleanNot(HBooleanNot* bool_not) OVERRIDE;
72  void VisitInstanceFieldSet(HInstanceFieldSet* equal) OVERRIDE;
73  void VisitStaticFieldSet(HStaticFieldSet* equal) OVERRIDE;
74  void VisitArraySet(HArraySet* equal) OVERRIDE;
75  void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE;
76  void VisitNullCheck(HNullCheck* instruction) OVERRIDE;
77  void VisitArrayLength(HArrayLength* instruction) OVERRIDE;
78  void VisitCheckCast(HCheckCast* instruction) OVERRIDE;
79  void VisitAdd(HAdd* instruction) OVERRIDE;
80  void VisitAnd(HAnd* instruction) OVERRIDE;
81  void VisitCondition(HCondition* instruction) OVERRIDE;
82  void VisitGreaterThan(HGreaterThan* condition) OVERRIDE;
83  void VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) OVERRIDE;
84  void VisitLessThan(HLessThan* condition) OVERRIDE;
85  void VisitLessThanOrEqual(HLessThanOrEqual* condition) OVERRIDE;
86  void VisitBelow(HBelow* condition) OVERRIDE;
87  void VisitBelowOrEqual(HBelowOrEqual* condition) OVERRIDE;
88  void VisitAbove(HAbove* condition) OVERRIDE;
89  void VisitAboveOrEqual(HAboveOrEqual* condition) OVERRIDE;
90  void VisitDiv(HDiv* instruction) OVERRIDE;
91  void VisitMul(HMul* instruction) OVERRIDE;
92  void VisitNeg(HNeg* instruction) OVERRIDE;
93  void VisitNot(HNot* instruction) OVERRIDE;
94  void VisitOr(HOr* instruction) OVERRIDE;
95  void VisitShl(HShl* instruction) OVERRIDE;
96  void VisitShr(HShr* instruction) OVERRIDE;
97  void VisitSub(HSub* instruction) OVERRIDE;
98  void VisitUShr(HUShr* instruction) OVERRIDE;
99  void VisitXor(HXor* instruction) OVERRIDE;
100  void VisitSelect(HSelect* select) OVERRIDE;
101  void VisitIf(HIf* instruction) OVERRIDE;
102  void VisitInstanceOf(HInstanceOf* instruction) OVERRIDE;
103  void VisitInvoke(HInvoke* invoke) OVERRIDE;
104  void VisitDeoptimize(HDeoptimize* deoptimize) OVERRIDE;
105
106  bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
107
108  void SimplifyRotate(HInvoke* invoke, bool is_left, Primitive::Type type);
109  void SimplifySystemArrayCopy(HInvoke* invoke);
110  void SimplifyStringEquals(HInvoke* invoke);
111  void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
112  void SimplifyIsNaN(HInvoke* invoke);
113  void SimplifyFP2Int(HInvoke* invoke);
114  void SimplifyStringCharAt(HInvoke* invoke);
115  void SimplifyStringIsEmptyOrLength(HInvoke* invoke);
116  void SimplifyNPEOnArgN(HInvoke* invoke, size_t);
117  void SimplifyReturnThis(HInvoke* invoke);
118  void SimplifyAllocationIntrinsic(HInvoke* invoke);
119  void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
120
121  CodeGenerator* codegen_;
122  OptimizingCompilerStats* stats_;
123  bool simplification_occurred_ = false;
124  int simplifications_at_current_position_ = 0;
125  // We ensure we do not loop infinitely. The value should not be too high, since that
126  // would allow looping around the same basic block too many times. The value should
127  // not be too low either, however, since we want to allow revisiting a basic block
128  // with many statements and simplifications at least once.
129  static constexpr int kMaxSamePositionSimplifications = 50;
130};
131
132void InstructionSimplifier::Run() {
133  InstructionSimplifierVisitor visitor(graph_, codegen_, stats_);
134  visitor.Run();
135}
136
137void InstructionSimplifierVisitor::Run() {
138  // Iterate in reverse post order to open up more simplifications to users
139  // of instructions that got simplified.
140  for (HBasicBlock* block : GetGraph()->GetReversePostOrder()) {
141    // The simplification of an instruction to another instruction may yield
142    // possibilities for other simplifications. So although we perform a reverse
143    // post order visit, we sometimes need to revisit an instruction index.
144    do {
145      simplification_occurred_ = false;
146      VisitBasicBlock(block);
147    } while (simplification_occurred_ &&
148             (simplifications_at_current_position_ < kMaxSamePositionSimplifications));
149    simplifications_at_current_position_ = 0;
150  }
151}
152
153namespace {
154
155bool AreAllBitsSet(HConstant* constant) {
156  return Int64FromConstant(constant) == -1;
157}
158
159}  // namespace
160
161// Returns true if the code was simplified to use only one negation operation
162// after the binary operation instead of one on each of the inputs.
163bool InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop(HBinaryOperation* binop) {
164  DCHECK(binop->IsAdd() || binop->IsSub());
165  DCHECK(binop->GetLeft()->IsNeg() && binop->GetRight()->IsNeg());
166  HNeg* left_neg = binop->GetLeft()->AsNeg();
167  HNeg* right_neg = binop->GetRight()->AsNeg();
168  if (!left_neg->HasOnlyOneNonEnvironmentUse() ||
169      !right_neg->HasOnlyOneNonEnvironmentUse()) {
170    return false;
171  }
172  // Replace code looking like
173  //    NEG tmp1, a
174  //    NEG tmp2, b
175  //    ADD dst, tmp1, tmp2
176  // with
177  //    ADD tmp, a, b
178  //    NEG dst, tmp
179  // Note that we cannot optimize `(-a) + (-b)` to `-(a + b)` for floating-point.
180  // When `a` is `-0.0` and `b` is `0.0`, the former expression yields `0.0`,
181  // while the later yields `-0.0`.
182  if (!Primitive::IsIntegralType(binop->GetType())) {
183    return false;
184  }
185  binop->ReplaceInput(left_neg->GetInput(), 0);
186  binop->ReplaceInput(right_neg->GetInput(), 1);
187  left_neg->GetBlock()->RemoveInstruction(left_neg);
188  right_neg->GetBlock()->RemoveInstruction(right_neg);
189  HNeg* neg = new (GetGraph()->GetArena()) HNeg(binop->GetType(), binop);
190  binop->GetBlock()->InsertInstructionBefore(neg, binop->GetNext());
191  binop->ReplaceWithExceptInReplacementAtIndex(neg, 0);
192  RecordSimplification();
193  return true;
194}
195
196bool InstructionSimplifierVisitor::TryDeMorganNegationFactoring(HBinaryOperation* op) {
197  DCHECK(op->IsAnd() || op->IsOr()) << op->DebugName();
198  Primitive::Type type = op->GetType();
199  HInstruction* left = op->GetLeft();
200  HInstruction* right = op->GetRight();
201
202  // We can apply De Morgan's laws if both inputs are Not's and are only used
203  // by `op`.
204  if (((left->IsNot() && right->IsNot()) ||
205       (left->IsBooleanNot() && right->IsBooleanNot())) &&
206      left->HasOnlyOneNonEnvironmentUse() &&
207      right->HasOnlyOneNonEnvironmentUse()) {
208    // Replace code looking like
209    //    NOT nota, a
210    //    NOT notb, b
211    //    AND dst, nota, notb (respectively OR)
212    // with
213    //    OR or, a, b         (respectively AND)
214    //    NOT dest, or
215    HInstruction* src_left = left->InputAt(0);
216    HInstruction* src_right = right->InputAt(0);
217    uint32_t dex_pc = op->GetDexPc();
218
219    // Remove the negations on the inputs.
220    left->ReplaceWith(src_left);
221    right->ReplaceWith(src_right);
222    left->GetBlock()->RemoveInstruction(left);
223    right->GetBlock()->RemoveInstruction(right);
224
225    // Replace the `HAnd` or `HOr`.
226    HBinaryOperation* hbin;
227    if (op->IsAnd()) {
228      hbin = new (GetGraph()->GetArena()) HOr(type, src_left, src_right, dex_pc);
229    } else {
230      hbin = new (GetGraph()->GetArena()) HAnd(type, src_left, src_right, dex_pc);
231    }
232    HInstruction* hnot;
233    if (left->IsBooleanNot()) {
234      hnot = new (GetGraph()->GetArena()) HBooleanNot(hbin, dex_pc);
235    } else {
236      hnot = new (GetGraph()->GetArena()) HNot(type, hbin, dex_pc);
237    }
238
239    op->GetBlock()->InsertInstructionBefore(hbin, op);
240    op->GetBlock()->ReplaceAndRemoveInstructionWith(op, hnot);
241
242    RecordSimplification();
243    return true;
244  }
245
246  return false;
247}
248
249void InstructionSimplifierVisitor::VisitShift(HBinaryOperation* instruction) {
250  DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr());
251  HInstruction* shift_amount = instruction->GetRight();
252  HInstruction* value = instruction->GetLeft();
253
254  int64_t implicit_mask = (value->GetType() == Primitive::kPrimLong)
255      ? kMaxLongShiftDistance
256      : kMaxIntShiftDistance;
257
258  if (shift_amount->IsConstant()) {
259    int64_t cst = Int64FromConstant(shift_amount->AsConstant());
260    if ((cst & implicit_mask) == 0) {
261      // Replace code looking like
262      //    SHL dst, value, 0
263      // with
264      //    value
265      instruction->ReplaceWith(value);
266      instruction->GetBlock()->RemoveInstruction(instruction);
267      RecordSimplification();
268      return;
269    }
270  }
271
272  // Shift operations implicitly mask the shift amount according to the type width. Get rid of
273  // unnecessary explicit masking operations on the shift amount.
274  // Replace code looking like
275  //    AND masked_shift, shift, <superset of implicit mask>
276  //    SHL dst, value, masked_shift
277  // with
278  //    SHL dst, value, shift
279  if (shift_amount->IsAnd()) {
280    HAnd* and_insn = shift_amount->AsAnd();
281    HConstant* mask = and_insn->GetConstantRight();
282    if ((mask != nullptr) && ((Int64FromConstant(mask) & implicit_mask) == implicit_mask)) {
283      instruction->ReplaceInput(and_insn->GetLeastConstantLeft(), 1);
284      RecordSimplification();
285    }
286  }
287}
288
289static bool IsSubRegBitsMinusOther(HSub* sub, size_t reg_bits, HInstruction* other) {
290  return (sub->GetRight() == other &&
291          sub->GetLeft()->IsConstant() &&
292          (Int64FromConstant(sub->GetLeft()->AsConstant()) & (reg_bits - 1)) == 0);
293}
294
295bool InstructionSimplifierVisitor::ReplaceRotateWithRor(HBinaryOperation* op,
296                                                        HUShr* ushr,
297                                                        HShl* shl) {
298  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr()) << op->DebugName();
299  HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(), ushr->GetLeft(), ushr->GetRight());
300  op->GetBlock()->ReplaceAndRemoveInstructionWith(op, ror);
301  if (!ushr->HasUses()) {
302    ushr->GetBlock()->RemoveInstruction(ushr);
303  }
304  if (!ushr->GetRight()->HasUses()) {
305    ushr->GetRight()->GetBlock()->RemoveInstruction(ushr->GetRight());
306  }
307  if (!shl->HasUses()) {
308    shl->GetBlock()->RemoveInstruction(shl);
309  }
310  if (!shl->GetRight()->HasUses()) {
311    shl->GetRight()->GetBlock()->RemoveInstruction(shl->GetRight());
312  }
313  RecordSimplification();
314  return true;
315}
316
317// Try to replace a binary operation flanked by one UShr and one Shl with a bitfield rotation.
318bool InstructionSimplifierVisitor::TryReplaceWithRotate(HBinaryOperation* op) {
319  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
320  HInstruction* left = op->GetLeft();
321  HInstruction* right = op->GetRight();
322  // If we have an UShr and a Shl (in either order).
323  if ((left->IsUShr() && right->IsShl()) || (left->IsShl() && right->IsUShr())) {
324    HUShr* ushr = left->IsUShr() ? left->AsUShr() : right->AsUShr();
325    HShl* shl = left->IsShl() ? left->AsShl() : right->AsShl();
326    DCHECK(Primitive::IsIntOrLongType(ushr->GetType()));
327    if (ushr->GetType() == shl->GetType() &&
328        ushr->GetLeft() == shl->GetLeft()) {
329      if (ushr->GetRight()->IsConstant() && shl->GetRight()->IsConstant()) {
330        // Shift distances are both constant, try replacing with Ror if they
331        // add up to the register size.
332        return TryReplaceWithRotateConstantPattern(op, ushr, shl);
333      } else if (ushr->GetRight()->IsSub() || shl->GetRight()->IsSub()) {
334        // Shift distances are potentially of the form x and (reg_size - x).
335        return TryReplaceWithRotateRegisterSubPattern(op, ushr, shl);
336      } else if (ushr->GetRight()->IsNeg() || shl->GetRight()->IsNeg()) {
337        // Shift distances are potentially of the form d and -d.
338        return TryReplaceWithRotateRegisterNegPattern(op, ushr, shl);
339      }
340    }
341  }
342  return false;
343}
344
345// Try replacing code looking like (x >>> #rdist OP x << #ldist):
346//    UShr dst, x,   #rdist
347//    Shl  tmp, x,   #ldist
348//    OP   dst, dst, tmp
349// or like (x >>> #rdist OP x << #-ldist):
350//    UShr dst, x,   #rdist
351//    Shl  tmp, x,   #-ldist
352//    OP   dst, dst, tmp
353// with
354//    Ror  dst, x,   #rdist
355bool InstructionSimplifierVisitor::TryReplaceWithRotateConstantPattern(HBinaryOperation* op,
356                                                                       HUShr* ushr,
357                                                                       HShl* shl) {
358  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
359  size_t reg_bits = Primitive::ComponentSize(ushr->GetType()) * kBitsPerByte;
360  size_t rdist = Int64FromConstant(ushr->GetRight()->AsConstant());
361  size_t ldist = Int64FromConstant(shl->GetRight()->AsConstant());
362  if (((ldist + rdist) & (reg_bits - 1)) == 0) {
363    ReplaceRotateWithRor(op, ushr, shl);
364    return true;
365  }
366  return false;
367}
368
369// Replace code looking like (x >>> -d OP x << d):
370//    Neg  neg, d
371//    UShr dst, x,   neg
372//    Shl  tmp, x,   d
373//    OP   dst, dst, tmp
374// with
375//    Neg  neg, d
376//    Ror  dst, x,   neg
377// *** OR ***
378// Replace code looking like (x >>> d OP x << -d):
379//    UShr dst, x,   d
380//    Neg  neg, d
381//    Shl  tmp, x,   neg
382//    OP   dst, dst, tmp
383// with
384//    Ror  dst, x,   d
385bool InstructionSimplifierVisitor::TryReplaceWithRotateRegisterNegPattern(HBinaryOperation* op,
386                                                                          HUShr* ushr,
387                                                                          HShl* shl) {
388  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
389  DCHECK(ushr->GetRight()->IsNeg() || shl->GetRight()->IsNeg());
390  bool neg_is_left = shl->GetRight()->IsNeg();
391  HNeg* neg = neg_is_left ? shl->GetRight()->AsNeg() : ushr->GetRight()->AsNeg();
392  // And the shift distance being negated is the distance being shifted the other way.
393  if (neg->InputAt(0) == (neg_is_left ? ushr->GetRight() : shl->GetRight())) {
394    ReplaceRotateWithRor(op, ushr, shl);
395  }
396  return false;
397}
398
399// Try replacing code looking like (x >>> d OP x << (#bits - d)):
400//    UShr dst, x,     d
401//    Sub  ld,  #bits, d
402//    Shl  tmp, x,     ld
403//    OP   dst, dst,   tmp
404// with
405//    Ror  dst, x,     d
406// *** OR ***
407// Replace code looking like (x >>> (#bits - d) OP x << d):
408//    Sub  rd,  #bits, d
409//    UShr dst, x,     rd
410//    Shl  tmp, x,     d
411//    OP   dst, dst,   tmp
412// with
413//    Neg  neg, d
414//    Ror  dst, x,     neg
415bool InstructionSimplifierVisitor::TryReplaceWithRotateRegisterSubPattern(HBinaryOperation* op,
416                                                                          HUShr* ushr,
417                                                                          HShl* shl) {
418  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
419  DCHECK(ushr->GetRight()->IsSub() || shl->GetRight()->IsSub());
420  size_t reg_bits = Primitive::ComponentSize(ushr->GetType()) * kBitsPerByte;
421  HInstruction* shl_shift = shl->GetRight();
422  HInstruction* ushr_shift = ushr->GetRight();
423  if ((shl_shift->IsSub() && IsSubRegBitsMinusOther(shl_shift->AsSub(), reg_bits, ushr_shift)) ||
424      (ushr_shift->IsSub() && IsSubRegBitsMinusOther(ushr_shift->AsSub(), reg_bits, shl_shift))) {
425    return ReplaceRotateWithRor(op, ushr, shl);
426  }
427  return false;
428}
429
430void InstructionSimplifierVisitor::VisitNullCheck(HNullCheck* null_check) {
431  HInstruction* obj = null_check->InputAt(0);
432  if (!obj->CanBeNull()) {
433    null_check->ReplaceWith(obj);
434    null_check->GetBlock()->RemoveInstruction(null_check);
435    if (stats_ != nullptr) {
436      stats_->RecordStat(MethodCompilationStat::kRemovedNullCheck);
437    }
438  }
439}
440
441bool InstructionSimplifierVisitor::CanEnsureNotNullAt(HInstruction* input, HInstruction* at) const {
442  if (!input->CanBeNull()) {
443    return true;
444  }
445
446  for (const HUseListNode<HInstruction*>& use : input->GetUses()) {
447    HInstruction* user = use.GetUser();
448    if (user->IsNullCheck() && user->StrictlyDominates(at)) {
449      return true;
450    }
451  }
452
453  return false;
454}
455
456// Returns whether doing a type test between the class of `object` against `klass` has
457// a statically known outcome. The result of the test is stored in `outcome`.
458static bool TypeCheckHasKnownOutcome(HLoadClass* klass, HInstruction* object, bool* outcome) {
459  DCHECK(!object->IsNullConstant()) << "Null constants should be special cased";
460  ReferenceTypeInfo obj_rti = object->GetReferenceTypeInfo();
461  ScopedObjectAccess soa(Thread::Current());
462  if (!obj_rti.IsValid()) {
463    // We run the simplifier before the reference type propagation so type info might not be
464    // available.
465    return false;
466  }
467
468  ReferenceTypeInfo class_rti = klass->GetLoadedClassRTI();
469  if (!class_rti.IsValid()) {
470    // Happens when the loaded class is unresolved.
471    return false;
472  }
473  DCHECK(class_rti.IsExact());
474  if (class_rti.IsSupertypeOf(obj_rti)) {
475    *outcome = true;
476    return true;
477  } else if (obj_rti.IsExact()) {
478    // The test failed at compile time so will also fail at runtime.
479    *outcome = false;
480    return true;
481  } else if (!class_rti.IsInterface()
482             && !obj_rti.IsInterface()
483             && !obj_rti.IsSupertypeOf(class_rti)) {
484    // Different type hierarchy. The test will fail.
485    *outcome = false;
486    return true;
487  }
488  return false;
489}
490
491void InstructionSimplifierVisitor::VisitCheckCast(HCheckCast* check_cast) {
492  HInstruction* object = check_cast->InputAt(0);
493  HLoadClass* load_class = check_cast->InputAt(1)->AsLoadClass();
494  if (load_class->NeedsAccessCheck()) {
495    // If we need to perform an access check we cannot remove the instruction.
496    return;
497  }
498
499  if (CanEnsureNotNullAt(object, check_cast)) {
500    check_cast->ClearMustDoNullCheck();
501  }
502
503  if (object->IsNullConstant()) {
504    check_cast->GetBlock()->RemoveInstruction(check_cast);
505    MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast);
506    return;
507  }
508
509  // Note: The `outcome` is initialized to please valgrind - the compiler can reorder
510  // the return value check with the `outcome` check, b/27651442 .
511  bool outcome = false;
512  if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) {
513    if (outcome) {
514      check_cast->GetBlock()->RemoveInstruction(check_cast);
515      MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast);
516      if (!load_class->HasUses()) {
517        // We cannot rely on DCE to remove the class because the `HLoadClass` thinks it can throw.
518        // However, here we know that it cannot because the checkcast was successfull, hence
519        // the class was already loaded.
520        load_class->GetBlock()->RemoveInstruction(load_class);
521      }
522    } else {
523      // Don't do anything for exceptional cases for now. Ideally we should remove
524      // all instructions and blocks this instruction dominates.
525    }
526  }
527}
528
529void InstructionSimplifierVisitor::VisitInstanceOf(HInstanceOf* instruction) {
530  HInstruction* object = instruction->InputAt(0);
531  HLoadClass* load_class = instruction->InputAt(1)->AsLoadClass();
532  if (load_class->NeedsAccessCheck()) {
533    // If we need to perform an access check we cannot remove the instruction.
534    return;
535  }
536
537  bool can_be_null = true;
538  if (CanEnsureNotNullAt(object, instruction)) {
539    can_be_null = false;
540    instruction->ClearMustDoNullCheck();
541  }
542
543  HGraph* graph = GetGraph();
544  if (object->IsNullConstant()) {
545    MaybeRecordStat(kRemovedInstanceOf);
546    instruction->ReplaceWith(graph->GetIntConstant(0));
547    instruction->GetBlock()->RemoveInstruction(instruction);
548    RecordSimplification();
549    return;
550  }
551
552  // Note: The `outcome` is initialized to please valgrind - the compiler can reorder
553  // the return value check with the `outcome` check, b/27651442 .
554  bool outcome = false;
555  if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) {
556    MaybeRecordStat(kRemovedInstanceOf);
557    if (outcome && can_be_null) {
558      // Type test will succeed, we just need a null test.
559      HNotEqual* test = new (graph->GetArena()) HNotEqual(graph->GetNullConstant(), object);
560      instruction->GetBlock()->InsertInstructionBefore(test, instruction);
561      instruction->ReplaceWith(test);
562    } else {
563      // We've statically determined the result of the instanceof.
564      instruction->ReplaceWith(graph->GetIntConstant(outcome));
565    }
566    RecordSimplification();
567    instruction->GetBlock()->RemoveInstruction(instruction);
568    if (outcome && !load_class->HasUses()) {
569      // We cannot rely on DCE to remove the class because the `HLoadClass` thinks it can throw.
570      // However, here we know that it cannot because the instanceof check was successfull, hence
571      // the class was already loaded.
572      load_class->GetBlock()->RemoveInstruction(load_class);
573    }
574  }
575}
576
577void InstructionSimplifierVisitor::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
578  if ((instruction->GetValue()->GetType() == Primitive::kPrimNot)
579      && CanEnsureNotNullAt(instruction->GetValue(), instruction)) {
580    instruction->ClearValueCanBeNull();
581  }
582}
583
584void InstructionSimplifierVisitor::VisitStaticFieldSet(HStaticFieldSet* instruction) {
585  if ((instruction->GetValue()->GetType() == Primitive::kPrimNot)
586      && CanEnsureNotNullAt(instruction->GetValue(), instruction)) {
587    instruction->ClearValueCanBeNull();
588  }
589}
590
591static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* arena, HInstruction* cond) {
592  HInstruction *lhs = cond->InputAt(0);
593  HInstruction *rhs = cond->InputAt(1);
594  switch (cond->GetKind()) {
595    case HInstruction::kEqual:
596      return new (arena) HEqual(rhs, lhs);
597    case HInstruction::kNotEqual:
598      return new (arena) HNotEqual(rhs, lhs);
599    case HInstruction::kLessThan:
600      return new (arena) HGreaterThan(rhs, lhs);
601    case HInstruction::kLessThanOrEqual:
602      return new (arena) HGreaterThanOrEqual(rhs, lhs);
603    case HInstruction::kGreaterThan:
604      return new (arena) HLessThan(rhs, lhs);
605    case HInstruction::kGreaterThanOrEqual:
606      return new (arena) HLessThanOrEqual(rhs, lhs);
607    case HInstruction::kBelow:
608      return new (arena) HAbove(rhs, lhs);
609    case HInstruction::kBelowOrEqual:
610      return new (arena) HAboveOrEqual(rhs, lhs);
611    case HInstruction::kAbove:
612      return new (arena) HBelow(rhs, lhs);
613    case HInstruction::kAboveOrEqual:
614      return new (arena) HBelowOrEqual(rhs, lhs);
615    default:
616      LOG(FATAL) << "Unknown ConditionType " << cond->GetKind();
617  }
618  return nullptr;
619}
620
621static bool CmpHasBoolType(HInstruction* input, HInstruction* cmp) {
622  if (input->GetType() == Primitive::kPrimBoolean) {
623    return true;  // input has direct boolean type
624  } else if (cmp->GetUses().HasExactlyOneElement()) {
625    // Comparison also has boolean type if both its input and the instruction
626    // itself feed into the same phi node.
627    HInstruction* user = cmp->GetUses().front().GetUser();
628    return user->IsPhi() && user->HasInput(input) && user->HasInput(cmp);
629  }
630  return false;
631}
632
633void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
634  HInstruction* input_const = equal->GetConstantRight();
635  if (input_const != nullptr) {
636    HInstruction* input_value = equal->GetLeastConstantLeft();
637    if (CmpHasBoolType(input_value, equal) && input_const->IsIntConstant()) {
638      HBasicBlock* block = equal->GetBlock();
639      // We are comparing the boolean to a constant which is of type int and can
640      // be any constant.
641      if (input_const->AsIntConstant()->IsTrue()) {
642        // Replace (bool_value == true) with bool_value
643        equal->ReplaceWith(input_value);
644        block->RemoveInstruction(equal);
645        RecordSimplification();
646      } else if (input_const->AsIntConstant()->IsFalse()) {
647        // Replace (bool_value == false) with !bool_value
648        equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, equal));
649        block->RemoveInstruction(equal);
650        RecordSimplification();
651      } else {
652        // Replace (bool_value == integer_not_zero_nor_one_constant) with false
653        equal->ReplaceWith(GetGraph()->GetIntConstant(0));
654        block->RemoveInstruction(equal);
655        RecordSimplification();
656      }
657    } else {
658      VisitCondition(equal);
659    }
660  } else {
661    VisitCondition(equal);
662  }
663}
664
665void InstructionSimplifierVisitor::VisitNotEqual(HNotEqual* not_equal) {
666  HInstruction* input_const = not_equal->GetConstantRight();
667  if (input_const != nullptr) {
668    HInstruction* input_value = not_equal->GetLeastConstantLeft();
669    if (CmpHasBoolType(input_value, not_equal) && input_const->IsIntConstant()) {
670      HBasicBlock* block = not_equal->GetBlock();
671      // We are comparing the boolean to a constant which is of type int and can
672      // be any constant.
673      if (input_const->AsIntConstant()->IsTrue()) {
674        // Replace (bool_value != true) with !bool_value
675        not_equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, not_equal));
676        block->RemoveInstruction(not_equal);
677        RecordSimplification();
678      } else if (input_const->AsIntConstant()->IsFalse()) {
679        // Replace (bool_value != false) with bool_value
680        not_equal->ReplaceWith(input_value);
681        block->RemoveInstruction(not_equal);
682        RecordSimplification();
683      } else {
684        // Replace (bool_value != integer_not_zero_nor_one_constant) with true
685        not_equal->ReplaceWith(GetGraph()->GetIntConstant(1));
686        block->RemoveInstruction(not_equal);
687        RecordSimplification();
688      }
689    } else {
690      VisitCondition(not_equal);
691    }
692  } else {
693    VisitCondition(not_equal);
694  }
695}
696
697void InstructionSimplifierVisitor::VisitBooleanNot(HBooleanNot* bool_not) {
698  HInstruction* input = bool_not->InputAt(0);
699  HInstruction* replace_with = nullptr;
700
701  if (input->IsIntConstant()) {
702    // Replace !(true/false) with false/true.
703    if (input->AsIntConstant()->IsTrue()) {
704      replace_with = GetGraph()->GetIntConstant(0);
705    } else {
706      DCHECK(input->AsIntConstant()->IsFalse()) << input->AsIntConstant()->GetValue();
707      replace_with = GetGraph()->GetIntConstant(1);
708    }
709  } else if (input->IsBooleanNot()) {
710    // Replace (!(!bool_value)) with bool_value.
711    replace_with = input->InputAt(0);
712  } else if (input->IsCondition() &&
713             // Don't change FP compares. The definition of compares involving
714             // NaNs forces the compares to be done as written by the user.
715             !Primitive::IsFloatingPointType(input->InputAt(0)->GetType())) {
716    // Replace condition with its opposite.
717    replace_with = GetGraph()->InsertOppositeCondition(input->AsCondition(), bool_not);
718  }
719
720  if (replace_with != nullptr) {
721    bool_not->ReplaceWith(replace_with);
722    bool_not->GetBlock()->RemoveInstruction(bool_not);
723    RecordSimplification();
724  }
725}
726
727void InstructionSimplifierVisitor::VisitSelect(HSelect* select) {
728  HInstruction* replace_with = nullptr;
729  HInstruction* condition = select->GetCondition();
730  HInstruction* true_value = select->GetTrueValue();
731  HInstruction* false_value = select->GetFalseValue();
732
733  if (condition->IsBooleanNot()) {
734    // Change ((!cond) ? x : y) to (cond ? y : x).
735    condition = condition->InputAt(0);
736    std::swap(true_value, false_value);
737    select->ReplaceInput(false_value, 0);
738    select->ReplaceInput(true_value, 1);
739    select->ReplaceInput(condition, 2);
740    RecordSimplification();
741  }
742
743  if (true_value == false_value) {
744    // Replace (cond ? x : x) with (x).
745    replace_with = true_value;
746  } else if (condition->IsIntConstant()) {
747    if (condition->AsIntConstant()->IsTrue()) {
748      // Replace (true ? x : y) with (x).
749      replace_with = true_value;
750    } else {
751      // Replace (false ? x : y) with (y).
752      DCHECK(condition->AsIntConstant()->IsFalse()) << condition->AsIntConstant()->GetValue();
753      replace_with = false_value;
754    }
755  } else if (true_value->IsIntConstant() && false_value->IsIntConstant()) {
756    if (true_value->AsIntConstant()->IsTrue() && false_value->AsIntConstant()->IsFalse()) {
757      // Replace (cond ? true : false) with (cond).
758      replace_with = condition;
759    } else if (true_value->AsIntConstant()->IsFalse() && false_value->AsIntConstant()->IsTrue()) {
760      // Replace (cond ? false : true) with (!cond).
761      replace_with = GetGraph()->InsertOppositeCondition(condition, select);
762    }
763  }
764
765  if (replace_with != nullptr) {
766    select->ReplaceWith(replace_with);
767    select->GetBlock()->RemoveInstruction(select);
768    RecordSimplification();
769  }
770}
771
772void InstructionSimplifierVisitor::VisitIf(HIf* instruction) {
773  HInstruction* condition = instruction->InputAt(0);
774  if (condition->IsBooleanNot()) {
775    // Swap successors if input is negated.
776    instruction->ReplaceInput(condition->InputAt(0), 0);
777    instruction->GetBlock()->SwapSuccessors();
778    RecordSimplification();
779  }
780}
781
782void InstructionSimplifierVisitor::VisitArrayLength(HArrayLength* instruction) {
783  HInstruction* input = instruction->InputAt(0);
784  // If the array is a NewArray with constant size, replace the array length
785  // with the constant instruction. This helps the bounds check elimination phase.
786  if (input->IsNewArray()) {
787    input = input->AsNewArray()->GetLength();
788    if (input->IsIntConstant()) {
789      instruction->ReplaceWith(input);
790    }
791  }
792}
793
794void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) {
795  HInstruction* value = instruction->GetValue();
796  if (value->GetType() != Primitive::kPrimNot) return;
797
798  if (CanEnsureNotNullAt(value, instruction)) {
799    instruction->ClearValueCanBeNull();
800  }
801
802  if (value->IsArrayGet()) {
803    if (value->AsArrayGet()->GetArray() == instruction->GetArray()) {
804      // If the code is just swapping elements in the array, no need for a type check.
805      instruction->ClearNeedsTypeCheck();
806      return;
807    }
808  }
809
810  if (value->IsNullConstant()) {
811    instruction->ClearNeedsTypeCheck();
812    return;
813  }
814
815  ScopedObjectAccess soa(Thread::Current());
816  ReferenceTypeInfo array_rti = instruction->GetArray()->GetReferenceTypeInfo();
817  ReferenceTypeInfo value_rti = value->GetReferenceTypeInfo();
818  if (!array_rti.IsValid()) {
819    return;
820  }
821
822  if (value_rti.IsValid() && array_rti.CanArrayHold(value_rti)) {
823    instruction->ClearNeedsTypeCheck();
824    return;
825  }
826
827  if (array_rti.IsObjectArray()) {
828    if (array_rti.IsExact()) {
829      instruction->ClearNeedsTypeCheck();
830      return;
831    }
832    instruction->SetStaticTypeOfArrayIsObjectArray();
833  }
834}
835
836static bool IsTypeConversionImplicit(Primitive::Type input_type, Primitive::Type result_type) {
837  // Invariant: We should never generate a conversion to a Boolean value.
838  DCHECK_NE(Primitive::kPrimBoolean, result_type);
839
840  // Besides conversion to the same type, widening integral conversions are implicit,
841  // excluding conversions to long and the byte->char conversion where we need to
842  // clear the high 16 bits of the 32-bit sign-extended representation of byte.
843  return result_type == input_type ||
844      (result_type == Primitive::kPrimInt && (input_type == Primitive::kPrimBoolean ||
845                                              input_type == Primitive::kPrimByte ||
846                                              input_type == Primitive::kPrimShort ||
847                                              input_type == Primitive::kPrimChar)) ||
848      (result_type == Primitive::kPrimChar && input_type == Primitive::kPrimBoolean) ||
849      (result_type == Primitive::kPrimShort && (input_type == Primitive::kPrimBoolean ||
850                                                input_type == Primitive::kPrimByte)) ||
851      (result_type == Primitive::kPrimByte && input_type == Primitive::kPrimBoolean);
852}
853
854static bool IsTypeConversionLossless(Primitive::Type input_type, Primitive::Type result_type) {
855  // The conversion to a larger type is loss-less with the exception of two cases,
856  //   - conversion to char, the only unsigned type, where we may lose some bits, and
857  //   - conversion from float to long, the only FP to integral conversion with smaller FP type.
858  // For integral to FP conversions this holds because the FP mantissa is large enough.
859  DCHECK_NE(input_type, result_type);
860  return Primitive::ComponentSize(result_type) > Primitive::ComponentSize(input_type) &&
861      result_type != Primitive::kPrimChar &&
862      !(result_type == Primitive::kPrimLong && input_type == Primitive::kPrimFloat);
863}
864
865void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruction) {
866  HInstruction* input = instruction->GetInput();
867  Primitive::Type input_type = input->GetType();
868  Primitive::Type result_type = instruction->GetResultType();
869  if (IsTypeConversionImplicit(input_type, result_type)) {
870    // Remove the implicit conversion; this includes conversion to the same type.
871    instruction->ReplaceWith(input);
872    instruction->GetBlock()->RemoveInstruction(instruction);
873    RecordSimplification();
874    return;
875  }
876
877  if (input->IsTypeConversion()) {
878    HTypeConversion* input_conversion = input->AsTypeConversion();
879    HInstruction* original_input = input_conversion->GetInput();
880    Primitive::Type original_type = original_input->GetType();
881
882    // When the first conversion is lossless, a direct conversion from the original type
883    // to the final type yields the same result, even for a lossy second conversion, for
884    // example float->double->int or int->double->float.
885    bool is_first_conversion_lossless = IsTypeConversionLossless(original_type, input_type);
886
887    // For integral conversions, see if the first conversion loses only bits that the second
888    // doesn't need, i.e. the final type is no wider than the intermediate. If so, direct
889    // conversion yields the same result, for example long->int->short or int->char->short.
890    bool integral_conversions_with_non_widening_second =
891        Primitive::IsIntegralType(input_type) &&
892        Primitive::IsIntegralType(original_type) &&
893        Primitive::IsIntegralType(result_type) &&
894        Primitive::ComponentSize(result_type) <= Primitive::ComponentSize(input_type);
895
896    if (is_first_conversion_lossless || integral_conversions_with_non_widening_second) {
897      // If the merged conversion is implicit, do the simplification unconditionally.
898      if (IsTypeConversionImplicit(original_type, result_type)) {
899        instruction->ReplaceWith(original_input);
900        instruction->GetBlock()->RemoveInstruction(instruction);
901        if (!input_conversion->HasUses()) {
902          // Don't wait for DCE.
903          input_conversion->GetBlock()->RemoveInstruction(input_conversion);
904        }
905        RecordSimplification();
906        return;
907      }
908      // Otherwise simplify only if the first conversion has no other use.
909      if (input_conversion->HasOnlyOneNonEnvironmentUse()) {
910        input_conversion->ReplaceWith(original_input);
911        input_conversion->GetBlock()->RemoveInstruction(input_conversion);
912        RecordSimplification();
913        return;
914      }
915    }
916  } else if (input->IsAnd() && Primitive::IsIntegralType(result_type)) {
917    DCHECK(Primitive::IsIntegralType(input_type));
918    HAnd* input_and = input->AsAnd();
919    HConstant* constant = input_and->GetConstantRight();
920    if (constant != nullptr) {
921      int64_t value = Int64FromConstant(constant);
922      DCHECK_NE(value, -1);  // "& -1" would have been optimized away in VisitAnd().
923      size_t trailing_ones = CTZ(~static_cast<uint64_t>(value));
924      if (trailing_ones >= kBitsPerByte * Primitive::ComponentSize(result_type)) {
925        // The `HAnd` is useless, for example in `(byte) (x & 0xff)`, get rid of it.
926        HInstruction* original_input = input_and->GetLeastConstantLeft();
927        if (IsTypeConversionImplicit(original_input->GetType(), result_type)) {
928          instruction->ReplaceWith(original_input);
929          instruction->GetBlock()->RemoveInstruction(instruction);
930          RecordSimplification();
931          return;
932        } else if (input->HasOnlyOneNonEnvironmentUse()) {
933          input_and->ReplaceWith(original_input);
934          input_and->GetBlock()->RemoveInstruction(input_and);
935          RecordSimplification();
936          return;
937        }
938      }
939    }
940  }
941}
942
943void InstructionSimplifierVisitor::VisitAdd(HAdd* instruction) {
944  HConstant* input_cst = instruction->GetConstantRight();
945  HInstruction* input_other = instruction->GetLeastConstantLeft();
946  bool integral_type = Primitive::IsIntegralType(instruction->GetType());
947  if ((input_cst != nullptr) && input_cst->IsArithmeticZero()) {
948    // Replace code looking like
949    //    ADD dst, src, 0
950    // with
951    //    src
952    // Note that we cannot optimize `x + 0.0` to `x` for floating-point. When
953    // `x` is `-0.0`, the former expression yields `0.0`, while the later
954    // yields `-0.0`.
955    if (integral_type) {
956      instruction->ReplaceWith(input_other);
957      instruction->GetBlock()->RemoveInstruction(instruction);
958      RecordSimplification();
959      return;
960    }
961  }
962
963  HInstruction* left = instruction->GetLeft();
964  HInstruction* right = instruction->GetRight();
965  bool left_is_neg = left->IsNeg();
966  bool right_is_neg = right->IsNeg();
967
968  if (left_is_neg && right_is_neg) {
969    if (TryMoveNegOnInputsAfterBinop(instruction)) {
970      return;
971    }
972  }
973
974  HNeg* neg = left_is_neg ? left->AsNeg() : right->AsNeg();
975  if ((left_is_neg ^ right_is_neg) && neg->HasOnlyOneNonEnvironmentUse()) {
976    // Replace code looking like
977    //    NEG tmp, b
978    //    ADD dst, a, tmp
979    // with
980    //    SUB dst, a, b
981    // We do not perform the optimization if the input negation has environment
982    // uses or multiple non-environment uses as it could lead to worse code. In
983    // particular, we do not want the live range of `b` to be extended if we are
984    // not sure the initial 'NEG' instruction can be removed.
985    HInstruction* other = left_is_neg ? right : left;
986    HSub* sub = new(GetGraph()->GetArena()) HSub(instruction->GetType(), other, neg->GetInput());
987    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, sub);
988    RecordSimplification();
989    neg->GetBlock()->RemoveInstruction(neg);
990    return;
991  }
992
993  if (TryReplaceWithRotate(instruction)) {
994    return;
995  }
996
997  // TryHandleAssociativeAndCommutativeOperation() does not remove its input,
998  // so no need to return.
999  TryHandleAssociativeAndCommutativeOperation(instruction);
1000
1001  if ((left->IsSub() || right->IsSub()) &&
1002      TrySubtractionChainSimplification(instruction)) {
1003    return;
1004  }
1005
1006  if (integral_type) {
1007    // Replace code patterns looking like
1008    //    SUB dst1, x, y        SUB dst1, x, y
1009    //    ADD dst2, dst1, y     ADD dst2, y, dst1
1010    // with
1011    //    SUB dst1, x, y
1012    // ADD instruction is not needed in this case, we may use
1013    // one of inputs of SUB instead.
1014    if (left->IsSub() && left->InputAt(1) == right) {
1015      instruction->ReplaceWith(left->InputAt(0));
1016      RecordSimplification();
1017      instruction->GetBlock()->RemoveInstruction(instruction);
1018      return;
1019    } else if (right->IsSub() && right->InputAt(1) == left) {
1020      instruction->ReplaceWith(right->InputAt(0));
1021      RecordSimplification();
1022      instruction->GetBlock()->RemoveInstruction(instruction);
1023      return;
1024    }
1025  }
1026}
1027
1028void InstructionSimplifierVisitor::VisitAnd(HAnd* instruction) {
1029  HConstant* input_cst = instruction->GetConstantRight();
1030  HInstruction* input_other = instruction->GetLeastConstantLeft();
1031
1032  if (input_cst != nullptr) {
1033    int64_t value = Int64FromConstant(input_cst);
1034    if (value == -1) {
1035      // Replace code looking like
1036      //    AND dst, src, 0xFFF...FF
1037      // with
1038      //    src
1039      instruction->ReplaceWith(input_other);
1040      instruction->GetBlock()->RemoveInstruction(instruction);
1041      RecordSimplification();
1042      return;
1043    }
1044    // Eliminate And from UShr+And if the And-mask contains all the bits that
1045    // can be non-zero after UShr. Transform Shr+And to UShr if the And-mask
1046    // precisely clears the shifted-in sign bits.
1047    if ((input_other->IsUShr() || input_other->IsShr()) && input_other->InputAt(1)->IsConstant()) {
1048      size_t reg_bits = (instruction->GetResultType() == Primitive::kPrimLong) ? 64 : 32;
1049      size_t shift = Int64FromConstant(input_other->InputAt(1)->AsConstant()) & (reg_bits - 1);
1050      size_t num_tail_bits_set = CTZ(value + 1);
1051      if ((num_tail_bits_set >= reg_bits - shift) && input_other->IsUShr()) {
1052        // This AND clears only bits known to be clear, for example "(x >>> 24) & 0xff".
1053        instruction->ReplaceWith(input_other);
1054        instruction->GetBlock()->RemoveInstruction(instruction);
1055        RecordSimplification();
1056        return;
1057      }  else if ((num_tail_bits_set == reg_bits - shift) && IsPowerOfTwo(value + 1) &&
1058          input_other->HasOnlyOneNonEnvironmentUse()) {
1059        DCHECK(input_other->IsShr());  // For UShr, we would have taken the branch above.
1060        // Replace SHR+AND with USHR, for example "(x >> 24) & 0xff" -> "x >>> 24".
1061        HUShr* ushr = new (GetGraph()->GetArena()) HUShr(instruction->GetType(),
1062                                                         input_other->InputAt(0),
1063                                                         input_other->InputAt(1),
1064                                                         input_other->GetDexPc());
1065        instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, ushr);
1066        input_other->GetBlock()->RemoveInstruction(input_other);
1067        RecordSimplification();
1068        return;
1069      }
1070    }
1071  }
1072
1073  // We assume that GVN has run before, so we only perform a pointer comparison.
1074  // If for some reason the values are equal but the pointers are different, we
1075  // are still correct and only miss an optimization opportunity.
1076  if (instruction->GetLeft() == instruction->GetRight()) {
1077    // Replace code looking like
1078    //    AND dst, src, src
1079    // with
1080    //    src
1081    instruction->ReplaceWith(instruction->GetLeft());
1082    instruction->GetBlock()->RemoveInstruction(instruction);
1083    RecordSimplification();
1084    return;
1085  }
1086
1087  if (TryDeMorganNegationFactoring(instruction)) {
1088    return;
1089  }
1090
1091  // TryHandleAssociativeAndCommutativeOperation() does not remove its input,
1092  // so no need to return.
1093  TryHandleAssociativeAndCommutativeOperation(instruction);
1094}
1095
1096void InstructionSimplifierVisitor::VisitGreaterThan(HGreaterThan* condition) {
1097  VisitCondition(condition);
1098}
1099
1100void InstructionSimplifierVisitor::VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) {
1101  VisitCondition(condition);
1102}
1103
1104void InstructionSimplifierVisitor::VisitLessThan(HLessThan* condition) {
1105  VisitCondition(condition);
1106}
1107
1108void InstructionSimplifierVisitor::VisitLessThanOrEqual(HLessThanOrEqual* condition) {
1109  VisitCondition(condition);
1110}
1111
1112void InstructionSimplifierVisitor::VisitBelow(HBelow* condition) {
1113  VisitCondition(condition);
1114}
1115
1116void InstructionSimplifierVisitor::VisitBelowOrEqual(HBelowOrEqual* condition) {
1117  VisitCondition(condition);
1118}
1119
1120void InstructionSimplifierVisitor::VisitAbove(HAbove* condition) {
1121  VisitCondition(condition);
1122}
1123
1124void InstructionSimplifierVisitor::VisitAboveOrEqual(HAboveOrEqual* condition) {
1125  VisitCondition(condition);
1126}
1127
1128// Recognize the following pattern:
1129// obj.getClass() ==/!= Foo.class
1130// And replace it with a constant value if the type of `obj` is statically known.
1131static bool RecognizeAndSimplifyClassCheck(HCondition* condition) {
1132  HInstruction* input_one = condition->InputAt(0);
1133  HInstruction* input_two = condition->InputAt(1);
1134  HLoadClass* load_class = input_one->IsLoadClass()
1135      ? input_one->AsLoadClass()
1136      : input_two->AsLoadClass();
1137  if (load_class == nullptr) {
1138    return false;
1139  }
1140
1141  ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
1142  if (!class_rti.IsValid()) {
1143    // Unresolved class.
1144    return false;
1145  }
1146
1147  HInstanceFieldGet* field_get = (load_class == input_one)
1148      ? input_two->AsInstanceFieldGet()
1149      : input_one->AsInstanceFieldGet();
1150  if (field_get == nullptr) {
1151    return false;
1152  }
1153
1154  HInstruction* receiver = field_get->InputAt(0);
1155  ReferenceTypeInfo receiver_type = receiver->GetReferenceTypeInfo();
1156  if (!receiver_type.IsExact()) {
1157    return false;
1158  }
1159
1160  {
1161    ScopedObjectAccess soa(Thread::Current());
1162    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1163    ArtField* field = class_linker->GetClassRoot(ClassLinker::kJavaLangObject)->GetInstanceField(0);
1164    DCHECK_EQ(std::string(field->GetName()), "shadow$_klass_");
1165    if (field_get->GetFieldInfo().GetField() != field) {
1166      return false;
1167    }
1168
1169    // We can replace the compare.
1170    int value = 0;
1171    if (receiver_type.IsEqual(class_rti)) {
1172      value = condition->IsEqual() ? 1 : 0;
1173    } else {
1174      value = condition->IsNotEqual() ? 1 : 0;
1175    }
1176    condition->ReplaceWith(condition->GetBlock()->GetGraph()->GetIntConstant(value));
1177    return true;
1178  }
1179}
1180
1181void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) {
1182  if (condition->IsEqual() || condition->IsNotEqual()) {
1183    if (RecognizeAndSimplifyClassCheck(condition)) {
1184      return;
1185    }
1186  }
1187
1188  // Reverse condition if left is constant. Our code generators prefer constant
1189  // on the right hand side.
1190  if (condition->GetLeft()->IsConstant() && !condition->GetRight()->IsConstant()) {
1191    HBasicBlock* block = condition->GetBlock();
1192    HCondition* replacement = GetOppositeConditionSwapOps(block->GetGraph()->GetArena(), condition);
1193    // If it is a fp we must set the opposite bias.
1194    if (replacement != nullptr) {
1195      if (condition->IsLtBias()) {
1196        replacement->SetBias(ComparisonBias::kGtBias);
1197      } else if (condition->IsGtBias()) {
1198        replacement->SetBias(ComparisonBias::kLtBias);
1199      }
1200      block->ReplaceAndRemoveInstructionWith(condition, replacement);
1201      RecordSimplification();
1202
1203      condition = replacement;
1204    }
1205  }
1206
1207  HInstruction* left = condition->GetLeft();
1208  HInstruction* right = condition->GetRight();
1209
1210  // Try to fold an HCompare into this HCondition.
1211
1212  // We can only replace an HCondition which compares a Compare to 0.
1213  // Both 'dx' and 'jack' generate a compare to 0 when compiling a
1214  // condition with a long, float or double comparison as input.
1215  if (!left->IsCompare() || !right->IsConstant() || right->AsIntConstant()->GetValue() != 0) {
1216    // Conversion is not possible.
1217    return;
1218  }
1219
1220  // Is the Compare only used for this purpose?
1221  if (!left->GetUses().HasExactlyOneElement()) {
1222    // Someone else also wants the result of the compare.
1223    return;
1224  }
1225
1226  if (!left->GetEnvUses().empty()) {
1227    // There is a reference to the compare result in an environment. Do we really need it?
1228    if (GetGraph()->IsDebuggable()) {
1229      return;
1230    }
1231
1232    // We have to ensure that there are no deopt points in the sequence.
1233    if (left->HasAnyEnvironmentUseBefore(condition)) {
1234      return;
1235    }
1236  }
1237
1238  // Clean up any environment uses from the HCompare, if any.
1239  left->RemoveEnvironmentUsers();
1240
1241  // We have decided to fold the HCompare into the HCondition. Transfer the information.
1242  condition->SetBias(left->AsCompare()->GetBias());
1243
1244  // Replace the operands of the HCondition.
1245  condition->ReplaceInput(left->InputAt(0), 0);
1246  condition->ReplaceInput(left->InputAt(1), 1);
1247
1248  // Remove the HCompare.
1249  left->GetBlock()->RemoveInstruction(left);
1250
1251  RecordSimplification();
1252}
1253
1254// Return whether x / divisor == x * (1.0f / divisor), for every float x.
1255static constexpr bool CanDivideByReciprocalMultiplyFloat(int32_t divisor) {
1256  // True, if the most significant bits of divisor are 0.
1257  return ((divisor & 0x7fffff) == 0);
1258}
1259
1260// Return whether x / divisor == x * (1.0 / divisor), for every double x.
1261static constexpr bool CanDivideByReciprocalMultiplyDouble(int64_t divisor) {
1262  // True, if the most significant bits of divisor are 0.
1263  return ((divisor & ((UINT64_C(1) << 52) - 1)) == 0);
1264}
1265
1266void InstructionSimplifierVisitor::VisitDiv(HDiv* instruction) {
1267  HConstant* input_cst = instruction->GetConstantRight();
1268  HInstruction* input_other = instruction->GetLeastConstantLeft();
1269  Primitive::Type type = instruction->GetType();
1270
1271  if ((input_cst != nullptr) && input_cst->IsOne()) {
1272    // Replace code looking like
1273    //    DIV dst, src, 1
1274    // with
1275    //    src
1276    instruction->ReplaceWith(input_other);
1277    instruction->GetBlock()->RemoveInstruction(instruction);
1278    RecordSimplification();
1279    return;
1280  }
1281
1282  if ((input_cst != nullptr) && input_cst->IsMinusOne()) {
1283    // Replace code looking like
1284    //    DIV dst, src, -1
1285    // with
1286    //    NEG dst, src
1287    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(
1288        instruction, new (GetGraph()->GetArena()) HNeg(type, input_other));
1289    RecordSimplification();
1290    return;
1291  }
1292
1293  if ((input_cst != nullptr) && Primitive::IsFloatingPointType(type)) {
1294    // Try replacing code looking like
1295    //    DIV dst, src, constant
1296    // with
1297    //    MUL dst, src, 1 / constant
1298    HConstant* reciprocal = nullptr;
1299    if (type == Primitive::Primitive::kPrimDouble) {
1300      double value = input_cst->AsDoubleConstant()->GetValue();
1301      if (CanDivideByReciprocalMultiplyDouble(bit_cast<int64_t, double>(value))) {
1302        reciprocal = GetGraph()->GetDoubleConstant(1.0 / value);
1303      }
1304    } else {
1305      DCHECK_EQ(type, Primitive::kPrimFloat);
1306      float value = input_cst->AsFloatConstant()->GetValue();
1307      if (CanDivideByReciprocalMultiplyFloat(bit_cast<int32_t, float>(value))) {
1308        reciprocal = GetGraph()->GetFloatConstant(1.0f / value);
1309      }
1310    }
1311
1312    if (reciprocal != nullptr) {
1313      instruction->GetBlock()->ReplaceAndRemoveInstructionWith(
1314          instruction, new (GetGraph()->GetArena()) HMul(type, input_other, reciprocal));
1315      RecordSimplification();
1316      return;
1317    }
1318  }
1319}
1320
1321void InstructionSimplifierVisitor::VisitMul(HMul* instruction) {
1322  HConstant* input_cst = instruction->GetConstantRight();
1323  HInstruction* input_other = instruction->GetLeastConstantLeft();
1324  Primitive::Type type = instruction->GetType();
1325  HBasicBlock* block = instruction->GetBlock();
1326  ArenaAllocator* allocator = GetGraph()->GetArena();
1327
1328  if (input_cst == nullptr) {
1329    return;
1330  }
1331
1332  if (input_cst->IsOne()) {
1333    // Replace code looking like
1334    //    MUL dst, src, 1
1335    // with
1336    //    src
1337    instruction->ReplaceWith(input_other);
1338    instruction->GetBlock()->RemoveInstruction(instruction);
1339    RecordSimplification();
1340    return;
1341  }
1342
1343  if (input_cst->IsMinusOne() &&
1344      (Primitive::IsFloatingPointType(type) || Primitive::IsIntOrLongType(type))) {
1345    // Replace code looking like
1346    //    MUL dst, src, -1
1347    // with
1348    //    NEG dst, src
1349    HNeg* neg = new (allocator) HNeg(type, input_other);
1350    block->ReplaceAndRemoveInstructionWith(instruction, neg);
1351    RecordSimplification();
1352    return;
1353  }
1354
1355  if (Primitive::IsFloatingPointType(type) &&
1356      ((input_cst->IsFloatConstant() && input_cst->AsFloatConstant()->GetValue() == 2.0f) ||
1357       (input_cst->IsDoubleConstant() && input_cst->AsDoubleConstant()->GetValue() == 2.0))) {
1358    // Replace code looking like
1359    //    FP_MUL dst, src, 2.0
1360    // with
1361    //    FP_ADD dst, src, src
1362    // The 'int' and 'long' cases are handled below.
1363    block->ReplaceAndRemoveInstructionWith(instruction,
1364                                           new (allocator) HAdd(type, input_other, input_other));
1365    RecordSimplification();
1366    return;
1367  }
1368
1369  if (Primitive::IsIntOrLongType(type)) {
1370    int64_t factor = Int64FromConstant(input_cst);
1371    // Even though constant propagation also takes care of the zero case, other
1372    // optimizations can lead to having a zero multiplication.
1373    if (factor == 0) {
1374      // Replace code looking like
1375      //    MUL dst, src, 0
1376      // with
1377      //    0
1378      instruction->ReplaceWith(input_cst);
1379      instruction->GetBlock()->RemoveInstruction(instruction);
1380      RecordSimplification();
1381      return;
1382    } else if (IsPowerOfTwo(factor)) {
1383      // Replace code looking like
1384      //    MUL dst, src, pow_of_2
1385      // with
1386      //    SHL dst, src, log2(pow_of_2)
1387      HIntConstant* shift = GetGraph()->GetIntConstant(WhichPowerOf2(factor));
1388      HShl* shl = new (allocator) HShl(type, input_other, shift);
1389      block->ReplaceAndRemoveInstructionWith(instruction, shl);
1390      RecordSimplification();
1391      return;
1392    } else if (IsPowerOfTwo(factor - 1)) {
1393      // Transform code looking like
1394      //    MUL dst, src, (2^n + 1)
1395      // into
1396      //    SHL tmp, src, n
1397      //    ADD dst, src, tmp
1398      HShl* shl = new (allocator) HShl(type,
1399                                       input_other,
1400                                       GetGraph()->GetIntConstant(WhichPowerOf2(factor - 1)));
1401      HAdd* add = new (allocator) HAdd(type, input_other, shl);
1402
1403      block->InsertInstructionBefore(shl, instruction);
1404      block->ReplaceAndRemoveInstructionWith(instruction, add);
1405      RecordSimplification();
1406      return;
1407    } else if (IsPowerOfTwo(factor + 1)) {
1408      // Transform code looking like
1409      //    MUL dst, src, (2^n - 1)
1410      // into
1411      //    SHL tmp, src, n
1412      //    SUB dst, tmp, src
1413      HShl* shl = new (allocator) HShl(type,
1414                                       input_other,
1415                                       GetGraph()->GetIntConstant(WhichPowerOf2(factor + 1)));
1416      HSub* sub = new (allocator) HSub(type, shl, input_other);
1417
1418      block->InsertInstructionBefore(shl, instruction);
1419      block->ReplaceAndRemoveInstructionWith(instruction, sub);
1420      RecordSimplification();
1421      return;
1422    }
1423  }
1424
1425  // TryHandleAssociativeAndCommutativeOperation() does not remove its input,
1426  // so no need to return.
1427  TryHandleAssociativeAndCommutativeOperation(instruction);
1428}
1429
1430void InstructionSimplifierVisitor::VisitNeg(HNeg* instruction) {
1431  HInstruction* input = instruction->GetInput();
1432  if (input->IsNeg()) {
1433    // Replace code looking like
1434    //    NEG tmp, src
1435    //    NEG dst, tmp
1436    // with
1437    //    src
1438    HNeg* previous_neg = input->AsNeg();
1439    instruction->ReplaceWith(previous_neg->GetInput());
1440    instruction->GetBlock()->RemoveInstruction(instruction);
1441    // We perform the optimization even if the input negation has environment
1442    // uses since it allows removing the current instruction. But we only delete
1443    // the input negation only if it is does not have any uses left.
1444    if (!previous_neg->HasUses()) {
1445      previous_neg->GetBlock()->RemoveInstruction(previous_neg);
1446    }
1447    RecordSimplification();
1448    return;
1449  }
1450
1451  if (input->IsSub() && input->HasOnlyOneNonEnvironmentUse() &&
1452      !Primitive::IsFloatingPointType(input->GetType())) {
1453    // Replace code looking like
1454    //    SUB tmp, a, b
1455    //    NEG dst, tmp
1456    // with
1457    //    SUB dst, b, a
1458    // We do not perform the optimization if the input subtraction has
1459    // environment uses or multiple non-environment uses as it could lead to
1460    // worse code. In particular, we do not want the live ranges of `a` and `b`
1461    // to be extended if we are not sure the initial 'SUB' instruction can be
1462    // removed.
1463    // We do not perform optimization for fp because we could lose the sign of zero.
1464    HSub* sub = input->AsSub();
1465    HSub* new_sub =
1466        new (GetGraph()->GetArena()) HSub(instruction->GetType(), sub->GetRight(), sub->GetLeft());
1467    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, new_sub);
1468    if (!sub->HasUses()) {
1469      sub->GetBlock()->RemoveInstruction(sub);
1470    }
1471    RecordSimplification();
1472  }
1473}
1474
1475void InstructionSimplifierVisitor::VisitNot(HNot* instruction) {
1476  HInstruction* input = instruction->GetInput();
1477  if (input->IsNot()) {
1478    // Replace code looking like
1479    //    NOT tmp, src
1480    //    NOT dst, tmp
1481    // with
1482    //    src
1483    // We perform the optimization even if the input negation has environment
1484    // uses since it allows removing the current instruction. But we only delete
1485    // the input negation only if it is does not have any uses left.
1486    HNot* previous_not = input->AsNot();
1487    instruction->ReplaceWith(previous_not->GetInput());
1488    instruction->GetBlock()->RemoveInstruction(instruction);
1489    if (!previous_not->HasUses()) {
1490      previous_not->GetBlock()->RemoveInstruction(previous_not);
1491    }
1492    RecordSimplification();
1493  }
1494}
1495
1496void InstructionSimplifierVisitor::VisitOr(HOr* instruction) {
1497  HConstant* input_cst = instruction->GetConstantRight();
1498  HInstruction* input_other = instruction->GetLeastConstantLeft();
1499
1500  if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) {
1501    // Replace code looking like
1502    //    OR dst, src, 0
1503    // with
1504    //    src
1505    instruction->ReplaceWith(input_other);
1506    instruction->GetBlock()->RemoveInstruction(instruction);
1507    RecordSimplification();
1508    return;
1509  }
1510
1511  // We assume that GVN has run before, so we only perform a pointer comparison.
1512  // If for some reason the values are equal but the pointers are different, we
1513  // are still correct and only miss an optimization opportunity.
1514  if (instruction->GetLeft() == instruction->GetRight()) {
1515    // Replace code looking like
1516    //    OR dst, src, src
1517    // with
1518    //    src
1519    instruction->ReplaceWith(instruction->GetLeft());
1520    instruction->GetBlock()->RemoveInstruction(instruction);
1521    RecordSimplification();
1522    return;
1523  }
1524
1525  if (TryDeMorganNegationFactoring(instruction)) return;
1526
1527  if (TryReplaceWithRotate(instruction)) {
1528    return;
1529  }
1530
1531  // TryHandleAssociativeAndCommutativeOperation() does not remove its input,
1532  // so no need to return.
1533  TryHandleAssociativeAndCommutativeOperation(instruction);
1534}
1535
1536void InstructionSimplifierVisitor::VisitShl(HShl* instruction) {
1537  VisitShift(instruction);
1538}
1539
1540void InstructionSimplifierVisitor::VisitShr(HShr* instruction) {
1541  VisitShift(instruction);
1542}
1543
1544void InstructionSimplifierVisitor::VisitSub(HSub* instruction) {
1545  HConstant* input_cst = instruction->GetConstantRight();
1546  HInstruction* input_other = instruction->GetLeastConstantLeft();
1547
1548  Primitive::Type type = instruction->GetType();
1549  if (Primitive::IsFloatingPointType(type)) {
1550    return;
1551  }
1552
1553  if ((input_cst != nullptr) && input_cst->IsArithmeticZero()) {
1554    // Replace code looking like
1555    //    SUB dst, src, 0
1556    // with
1557    //    src
1558    // Note that we cannot optimize `x - 0.0` to `x` for floating-point. When
1559    // `x` is `-0.0`, the former expression yields `0.0`, while the later
1560    // yields `-0.0`.
1561    instruction->ReplaceWith(input_other);
1562    instruction->GetBlock()->RemoveInstruction(instruction);
1563    RecordSimplification();
1564    return;
1565  }
1566
1567  HBasicBlock* block = instruction->GetBlock();
1568  ArenaAllocator* allocator = GetGraph()->GetArena();
1569
1570  HInstruction* left = instruction->GetLeft();
1571  HInstruction* right = instruction->GetRight();
1572  if (left->IsConstant()) {
1573    if (Int64FromConstant(left->AsConstant()) == 0) {
1574      // Replace code looking like
1575      //    SUB dst, 0, src
1576      // with
1577      //    NEG dst, src
1578      // Note that we cannot optimize `0.0 - x` to `-x` for floating-point. When
1579      // `x` is `0.0`, the former expression yields `0.0`, while the later
1580      // yields `-0.0`.
1581      HNeg* neg = new (allocator) HNeg(type, right);
1582      block->ReplaceAndRemoveInstructionWith(instruction, neg);
1583      RecordSimplification();
1584      return;
1585    }
1586  }
1587
1588  if (left->IsNeg() && right->IsNeg()) {
1589    if (TryMoveNegOnInputsAfterBinop(instruction)) {
1590      return;
1591    }
1592  }
1593
1594  if (right->IsNeg() && right->HasOnlyOneNonEnvironmentUse()) {
1595    // Replace code looking like
1596    //    NEG tmp, b
1597    //    SUB dst, a, tmp
1598    // with
1599    //    ADD dst, a, b
1600    HAdd* add = new(GetGraph()->GetArena()) HAdd(type, left, right->AsNeg()->GetInput());
1601    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, add);
1602    RecordSimplification();
1603    right->GetBlock()->RemoveInstruction(right);
1604    return;
1605  }
1606
1607  if (left->IsNeg() && left->HasOnlyOneNonEnvironmentUse()) {
1608    // Replace code looking like
1609    //    NEG tmp, a
1610    //    SUB dst, tmp, b
1611    // with
1612    //    ADD tmp, a, b
1613    //    NEG dst, tmp
1614    // The second version is not intrinsically better, but enables more
1615    // transformations.
1616    HAdd* add = new(GetGraph()->GetArena()) HAdd(type, left->AsNeg()->GetInput(), right);
1617    instruction->GetBlock()->InsertInstructionBefore(add, instruction);
1618    HNeg* neg = new (GetGraph()->GetArena()) HNeg(instruction->GetType(), add);
1619    instruction->GetBlock()->InsertInstructionBefore(neg, instruction);
1620    instruction->ReplaceWith(neg);
1621    instruction->GetBlock()->RemoveInstruction(instruction);
1622    RecordSimplification();
1623    left->GetBlock()->RemoveInstruction(left);
1624    return;
1625  }
1626
1627  if (TrySubtractionChainSimplification(instruction)) {
1628    return;
1629  }
1630
1631  if (left->IsAdd()) {
1632    // Replace code patterns looking like
1633    //    ADD dst1, x, y        ADD dst1, x, y
1634    //    SUB dst2, dst1, y     SUB dst2, dst1, x
1635    // with
1636    //    ADD dst1, x, y
1637    // SUB instruction is not needed in this case, we may use
1638    // one of inputs of ADD instead.
1639    // It is applicable to integral types only.
1640    DCHECK(Primitive::IsIntegralType(type));
1641    if (left->InputAt(1) == right) {
1642      instruction->ReplaceWith(left->InputAt(0));
1643      RecordSimplification();
1644      instruction->GetBlock()->RemoveInstruction(instruction);
1645      return;
1646    } else if (left->InputAt(0) == right) {
1647      instruction->ReplaceWith(left->InputAt(1));
1648      RecordSimplification();
1649      instruction->GetBlock()->RemoveInstruction(instruction);
1650      return;
1651    }
1652  }
1653}
1654
1655void InstructionSimplifierVisitor::VisitUShr(HUShr* instruction) {
1656  VisitShift(instruction);
1657}
1658
1659void InstructionSimplifierVisitor::VisitXor(HXor* instruction) {
1660  HConstant* input_cst = instruction->GetConstantRight();
1661  HInstruction* input_other = instruction->GetLeastConstantLeft();
1662
1663  if ((input_cst != nullptr) && input_cst->IsZeroBitPattern()) {
1664    // Replace code looking like
1665    //    XOR dst, src, 0
1666    // with
1667    //    src
1668    instruction->ReplaceWith(input_other);
1669    instruction->GetBlock()->RemoveInstruction(instruction);
1670    RecordSimplification();
1671    return;
1672  }
1673
1674  if ((input_cst != nullptr) && input_cst->IsOne()
1675      && input_other->GetType() == Primitive::kPrimBoolean) {
1676    // Replace code looking like
1677    //    XOR dst, src, 1
1678    // with
1679    //    BOOLEAN_NOT dst, src
1680    HBooleanNot* boolean_not = new (GetGraph()->GetArena()) HBooleanNot(input_other);
1681    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, boolean_not);
1682    RecordSimplification();
1683    return;
1684  }
1685
1686  if ((input_cst != nullptr) && AreAllBitsSet(input_cst)) {
1687    // Replace code looking like
1688    //    XOR dst, src, 0xFFF...FF
1689    // with
1690    //    NOT dst, src
1691    HNot* bitwise_not = new (GetGraph()->GetArena()) HNot(instruction->GetType(), input_other);
1692    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, bitwise_not);
1693    RecordSimplification();
1694    return;
1695  }
1696
1697  HInstruction* left = instruction->GetLeft();
1698  HInstruction* right = instruction->GetRight();
1699  if (((left->IsNot() && right->IsNot()) ||
1700       (left->IsBooleanNot() && right->IsBooleanNot())) &&
1701      left->HasOnlyOneNonEnvironmentUse() &&
1702      right->HasOnlyOneNonEnvironmentUse()) {
1703    // Replace code looking like
1704    //    NOT nota, a
1705    //    NOT notb, b
1706    //    XOR dst, nota, notb
1707    // with
1708    //    XOR dst, a, b
1709    instruction->ReplaceInput(left->InputAt(0), 0);
1710    instruction->ReplaceInput(right->InputAt(0), 1);
1711    left->GetBlock()->RemoveInstruction(left);
1712    right->GetBlock()->RemoveInstruction(right);
1713    RecordSimplification();
1714    return;
1715  }
1716
1717  if (TryReplaceWithRotate(instruction)) {
1718    return;
1719  }
1720
1721  // TryHandleAssociativeAndCommutativeOperation() does not remove its input,
1722  // so no need to return.
1723  TryHandleAssociativeAndCommutativeOperation(instruction);
1724}
1725
1726void InstructionSimplifierVisitor::SimplifyStringEquals(HInvoke* instruction) {
1727  HInstruction* argument = instruction->InputAt(1);
1728  HInstruction* receiver = instruction->InputAt(0);
1729  if (receiver == argument) {
1730    // Because String.equals is an instance call, the receiver is
1731    // a null check if we don't know it's null. The argument however, will
1732    // be the actual object. So we cannot end up in a situation where both
1733    // are equal but could be null.
1734    DCHECK(CanEnsureNotNullAt(argument, instruction));
1735    instruction->ReplaceWith(GetGraph()->GetIntConstant(1));
1736    instruction->GetBlock()->RemoveInstruction(instruction);
1737  } else {
1738    StringEqualsOptimizations optimizations(instruction);
1739    if (CanEnsureNotNullAt(argument, instruction)) {
1740      optimizations.SetArgumentNotNull();
1741    }
1742    ScopedObjectAccess soa(Thread::Current());
1743    ReferenceTypeInfo argument_rti = argument->GetReferenceTypeInfo();
1744    if (argument_rti.IsValid() && argument_rti.IsStringClass()) {
1745      optimizations.SetArgumentIsString();
1746    }
1747  }
1748}
1749
1750void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
1751                                                  bool is_left,
1752                                                  Primitive::Type type) {
1753  DCHECK(invoke->IsInvokeStaticOrDirect());
1754  DCHECK_EQ(invoke->GetInvokeType(), InvokeType::kStatic);
1755  HInstruction* value = invoke->InputAt(0);
1756  HInstruction* distance = invoke->InputAt(1);
1757  // Replace the invoke with an HRor.
1758  if (is_left) {
1759    // Unconditionally set the type of the negated distance to `int`,
1760    // as shift and rotate operations expect a 32-bit (or narrower)
1761    // value for their distance input.
1762    distance = new (GetGraph()->GetArena()) HNeg(Primitive::kPrimInt, distance);
1763    invoke->GetBlock()->InsertInstructionBefore(distance, invoke);
1764  }
1765  HRor* ror = new (GetGraph()->GetArena()) HRor(type, value, distance);
1766  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, ror);
1767  // Remove ClinitCheck and LoadClass, if possible.
1768  HInstruction* clinit = invoke->GetInputs().back();
1769  if (clinit->IsClinitCheck() && !clinit->HasUses()) {
1770    clinit->GetBlock()->RemoveInstruction(clinit);
1771    HInstruction* ldclass = clinit->InputAt(0);
1772    if (ldclass->IsLoadClass() && !ldclass->HasUses()) {
1773      ldclass->GetBlock()->RemoveInstruction(ldclass);
1774    }
1775  }
1776}
1777
1778static bool IsArrayLengthOf(HInstruction* potential_length, HInstruction* potential_array) {
1779  if (potential_length->IsArrayLength()) {
1780    return potential_length->InputAt(0) == potential_array;
1781  }
1782
1783  if (potential_array->IsNewArray()) {
1784    return potential_array->AsNewArray()->GetLength() == potential_length;
1785  }
1786
1787  return false;
1788}
1789
1790void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction) {
1791  HInstruction* source = instruction->InputAt(0);
1792  HInstruction* destination = instruction->InputAt(2);
1793  HInstruction* count = instruction->InputAt(4);
1794  SystemArrayCopyOptimizations optimizations(instruction);
1795  if (CanEnsureNotNullAt(source, instruction)) {
1796    optimizations.SetSourceIsNotNull();
1797  }
1798  if (CanEnsureNotNullAt(destination, instruction)) {
1799    optimizations.SetDestinationIsNotNull();
1800  }
1801  if (destination == source) {
1802    optimizations.SetDestinationIsSource();
1803  }
1804
1805  if (IsArrayLengthOf(count, source)) {
1806    optimizations.SetCountIsSourceLength();
1807  }
1808
1809  if (IsArrayLengthOf(count, destination)) {
1810    optimizations.SetCountIsDestinationLength();
1811  }
1812
1813  {
1814    ScopedObjectAccess soa(Thread::Current());
1815    Primitive::Type source_component_type = Primitive::kPrimVoid;
1816    Primitive::Type destination_component_type = Primitive::kPrimVoid;
1817    ReferenceTypeInfo destination_rti = destination->GetReferenceTypeInfo();
1818    if (destination_rti.IsValid()) {
1819      if (destination_rti.IsObjectArray()) {
1820        if (destination_rti.IsExact()) {
1821          optimizations.SetDoesNotNeedTypeCheck();
1822        }
1823        optimizations.SetDestinationIsTypedObjectArray();
1824      }
1825      if (destination_rti.IsPrimitiveArrayClass()) {
1826        destination_component_type =
1827            destination_rti.GetTypeHandle()->GetComponentType()->GetPrimitiveType();
1828        optimizations.SetDestinationIsPrimitiveArray();
1829      } else if (destination_rti.IsNonPrimitiveArrayClass()) {
1830        optimizations.SetDestinationIsNonPrimitiveArray();
1831      }
1832    }
1833    ReferenceTypeInfo source_rti = source->GetReferenceTypeInfo();
1834    if (source_rti.IsValid()) {
1835      if (destination_rti.IsValid() && destination_rti.CanArrayHoldValuesOf(source_rti)) {
1836        optimizations.SetDoesNotNeedTypeCheck();
1837      }
1838      if (source_rti.IsPrimitiveArrayClass()) {
1839        optimizations.SetSourceIsPrimitiveArray();
1840        source_component_type = source_rti.GetTypeHandle()->GetComponentType()->GetPrimitiveType();
1841      } else if (source_rti.IsNonPrimitiveArrayClass()) {
1842        optimizations.SetSourceIsNonPrimitiveArray();
1843      }
1844    }
1845    // For primitive arrays, use their optimized ArtMethod implementations.
1846    if ((source_component_type != Primitive::kPrimVoid) &&
1847        (source_component_type == destination_component_type)) {
1848      ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1849      PointerSize image_size = class_linker->GetImagePointerSize();
1850      HInvokeStaticOrDirect* invoke = instruction->AsInvokeStaticOrDirect();
1851      mirror::Class* system = invoke->GetResolvedMethod()->GetDeclaringClass();
1852      ArtMethod* method = nullptr;
1853      switch (source_component_type) {
1854        case Primitive::kPrimBoolean:
1855          method = system->FindDeclaredDirectMethod("arraycopy", "([ZI[ZII)V", image_size);
1856          break;
1857        case Primitive::kPrimByte:
1858          method = system->FindDeclaredDirectMethod("arraycopy", "([BI[BII)V", image_size);
1859          break;
1860        case Primitive::kPrimChar:
1861          method = system->FindDeclaredDirectMethod("arraycopy", "([CI[CII)V", image_size);
1862          break;
1863        case Primitive::kPrimShort:
1864          method = system->FindDeclaredDirectMethod("arraycopy", "([SI[SII)V", image_size);
1865          break;
1866        case Primitive::kPrimInt:
1867          method = system->FindDeclaredDirectMethod("arraycopy", "([II[III)V", image_size);
1868          break;
1869        case Primitive::kPrimFloat:
1870          method = system->FindDeclaredDirectMethod("arraycopy", "([FI[FII)V", image_size);
1871          break;
1872        case Primitive::kPrimLong:
1873          method = system->FindDeclaredDirectMethod("arraycopy", "([JI[JII)V", image_size);
1874          break;
1875        case Primitive::kPrimDouble:
1876          method = system->FindDeclaredDirectMethod("arraycopy", "([DI[DII)V", image_size);
1877          break;
1878        default:
1879          LOG(FATAL) << "Unreachable";
1880      }
1881      DCHECK(method != nullptr);
1882      invoke->SetResolvedMethod(method);
1883      // Sharpen the new invoke. Note that we do not update the dex method index of
1884      // the invoke, as we would need to look it up in the current dex file, and it
1885      // is unlikely that it exists. The most usual situation for such typed
1886      // arraycopy methods is a direct pointer to the boot image.
1887      HSharpening::SharpenInvokeStaticOrDirect(invoke, codegen_);
1888    }
1889  }
1890}
1891
1892void InstructionSimplifierVisitor::SimplifyCompare(HInvoke* invoke,
1893                                                   bool is_signum,
1894                                                   Primitive::Type type) {
1895  DCHECK(invoke->IsInvokeStaticOrDirect());
1896  uint32_t dex_pc = invoke->GetDexPc();
1897  HInstruction* left = invoke->InputAt(0);
1898  HInstruction* right;
1899  if (!is_signum) {
1900    right = invoke->InputAt(1);
1901  } else if (type == Primitive::kPrimLong) {
1902    right = GetGraph()->GetLongConstant(0);
1903  } else {
1904    right = GetGraph()->GetIntConstant(0);
1905  }
1906  HCompare* compare = new (GetGraph()->GetArena())
1907      HCompare(type, left, right, ComparisonBias::kNoBias, dex_pc);
1908  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, compare);
1909}
1910
1911void InstructionSimplifierVisitor::SimplifyIsNaN(HInvoke* invoke) {
1912  DCHECK(invoke->IsInvokeStaticOrDirect());
1913  uint32_t dex_pc = invoke->GetDexPc();
1914  // IsNaN(x) is the same as x != x.
1915  HInstruction* x = invoke->InputAt(0);
1916  HCondition* condition = new (GetGraph()->GetArena()) HNotEqual(x, x, dex_pc);
1917  condition->SetBias(ComparisonBias::kLtBias);
1918  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, condition);
1919}
1920
1921void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) {
1922  DCHECK(invoke->IsInvokeStaticOrDirect());
1923  uint32_t dex_pc = invoke->GetDexPc();
1924  HInstruction* x = invoke->InputAt(0);
1925  Primitive::Type type = x->GetType();
1926  // Set proper bit pattern for NaN and replace intrinsic with raw version.
1927  HInstruction* nan;
1928  if (type == Primitive::kPrimDouble) {
1929    nan = GetGraph()->GetLongConstant(0x7ff8000000000000L);
1930    invoke->SetIntrinsic(Intrinsics::kDoubleDoubleToRawLongBits,
1931                         kNeedsEnvironmentOrCache,
1932                         kNoSideEffects,
1933                         kNoThrow);
1934  } else {
1935    DCHECK_EQ(type, Primitive::kPrimFloat);
1936    nan = GetGraph()->GetIntConstant(0x7fc00000);
1937    invoke->SetIntrinsic(Intrinsics::kFloatFloatToRawIntBits,
1938                         kNeedsEnvironmentOrCache,
1939                         kNoSideEffects,
1940                         kNoThrow);
1941  }
1942  // Test IsNaN(x), which is the same as x != x.
1943  HCondition* condition = new (GetGraph()->GetArena()) HNotEqual(x, x, dex_pc);
1944  condition->SetBias(ComparisonBias::kLtBias);
1945  invoke->GetBlock()->InsertInstructionBefore(condition, invoke->GetNext());
1946  // Select between the two.
1947  HInstruction* select = new (GetGraph()->GetArena()) HSelect(condition, nan, invoke, dex_pc);
1948  invoke->GetBlock()->InsertInstructionBefore(select, condition->GetNext());
1949  invoke->ReplaceWithExceptInReplacementAtIndex(select, 0);  // false at index 0
1950}
1951
1952void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) {
1953  HInstruction* str = invoke->InputAt(0);
1954  HInstruction* index = invoke->InputAt(1);
1955  uint32_t dex_pc = invoke->GetDexPc();
1956  ArenaAllocator* arena = GetGraph()->GetArena();
1957  // We treat String as an array to allow DCE and BCE to seamlessly work on strings,
1958  // so create the HArrayLength, HBoundsCheck and HArrayGet.
1959  HArrayLength* length = new (arena) HArrayLength(str, dex_pc, /* is_string_length */ true);
1960  invoke->GetBlock()->InsertInstructionBefore(length, invoke);
1961  HBoundsCheck* bounds_check = new (arena) HBoundsCheck(
1962      index, length, dex_pc, invoke->GetDexMethodIndex());
1963  invoke->GetBlock()->InsertInstructionBefore(bounds_check, invoke);
1964  HArrayGet* array_get = new (arena) HArrayGet(
1965      str, bounds_check, Primitive::kPrimChar, dex_pc, /* is_string_char_at */ true);
1966  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, array_get);
1967  bounds_check->CopyEnvironmentFrom(invoke->GetEnvironment());
1968  GetGraph()->SetHasBoundsChecks(true);
1969}
1970
1971void InstructionSimplifierVisitor::SimplifyStringIsEmptyOrLength(HInvoke* invoke) {
1972  HInstruction* str = invoke->InputAt(0);
1973  uint32_t dex_pc = invoke->GetDexPc();
1974  // We treat String as an array to allow DCE and BCE to seamlessly work on strings,
1975  // so create the HArrayLength.
1976  HArrayLength* length =
1977      new (GetGraph()->GetArena()) HArrayLength(str, dex_pc, /* is_string_length */ true);
1978  HInstruction* replacement;
1979  if (invoke->GetIntrinsic() == Intrinsics::kStringIsEmpty) {
1980    // For String.isEmpty(), create the `HEqual` representing the `length == 0`.
1981    invoke->GetBlock()->InsertInstructionBefore(length, invoke);
1982    HIntConstant* zero = GetGraph()->GetIntConstant(0);
1983    HEqual* equal = new (GetGraph()->GetArena()) HEqual(length, zero, dex_pc);
1984    replacement = equal;
1985  } else {
1986    DCHECK_EQ(invoke->GetIntrinsic(), Intrinsics::kStringLength);
1987    replacement = length;
1988  }
1989  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, replacement);
1990}
1991
1992// This method should only be used on intrinsics whose sole way of throwing an
1993// exception is raising a NPE when the nth argument is null. If that argument
1994// is provably non-null, we can clear the flag.
1995void InstructionSimplifierVisitor::SimplifyNPEOnArgN(HInvoke* invoke, size_t n) {
1996  HInstruction* arg = invoke->InputAt(n);
1997  if (invoke->CanThrow() && !arg->CanBeNull()) {
1998    invoke->SetCanThrow(false);
1999  }
2000}
2001
2002// Methods that return "this" can replace the returned value with the receiver.
2003void InstructionSimplifierVisitor::SimplifyReturnThis(HInvoke* invoke) {
2004  if (invoke->HasUses()) {
2005    HInstruction* receiver = invoke->InputAt(0);
2006    invoke->ReplaceWith(receiver);
2007    RecordSimplification();
2008  }
2009}
2010
2011// Helper method for StringBuffer escape analysis.
2012static bool NoEscapeForStringBufferReference(HInstruction* reference, HInstruction* user) {
2013  if (user->IsInvokeStaticOrDirect()) {
2014    // Any constructor on StringBuffer is okay.
2015    return user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
2016           user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
2017           user->InputAt(0) == reference;
2018  } else if (user->IsInvokeVirtual()) {
2019    switch (user->AsInvokeVirtual()->GetIntrinsic()) {
2020      case Intrinsics::kStringBufferLength:
2021      case Intrinsics::kStringBufferToString:
2022        DCHECK_EQ(user->InputAt(0), reference);
2023        return true;
2024      case Intrinsics::kStringBufferAppend:
2025        // Returns "this", so only okay if no further uses.
2026        DCHECK_EQ(user->InputAt(0), reference);
2027        DCHECK_NE(user->InputAt(1), reference);
2028        return !user->HasUses();
2029      default:
2030        break;
2031    }
2032  }
2033  return false;
2034}
2035
2036// Certain allocation intrinsics are not removed by dead code elimination
2037// because of potentially throwing an OOM exception or other side effects.
2038// This method removes such intrinsics when special circumstances allow.
2039void InstructionSimplifierVisitor::SimplifyAllocationIntrinsic(HInvoke* invoke) {
2040  if (!invoke->HasUses()) {
2041    // Instruction has no uses. If unsynchronized, we can remove right away, safely ignoring
2042    // the potential OOM of course. Otherwise, we must ensure the receiver object of this
2043    // call does not escape since only thread-local synchronization may be removed.
2044    bool is_synchronized = invoke->GetIntrinsic() == Intrinsics::kStringBufferToString;
2045    HInstruction* receiver = invoke->InputAt(0);
2046    if (!is_synchronized || DoesNotEscape(receiver, NoEscapeForStringBufferReference)) {
2047      invoke->GetBlock()->RemoveInstruction(invoke);
2048      RecordSimplification();
2049    }
2050  }
2051}
2052
2053void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind) {
2054  uint32_t dex_pc = invoke->GetDexPc();
2055  HMemoryBarrier* mem_barrier = new (GetGraph()->GetArena()) HMemoryBarrier(barrier_kind, dex_pc);
2056  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, mem_barrier);
2057}
2058
2059void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
2060  switch (instruction->GetIntrinsic()) {
2061    case Intrinsics::kStringEquals:
2062      SimplifyStringEquals(instruction);
2063      break;
2064    case Intrinsics::kSystemArrayCopy:
2065      SimplifySystemArrayCopy(instruction);
2066      break;
2067    case Intrinsics::kIntegerRotateRight:
2068      SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimInt);
2069      break;
2070    case Intrinsics::kLongRotateRight:
2071      SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimLong);
2072      break;
2073    case Intrinsics::kIntegerRotateLeft:
2074      SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimInt);
2075      break;
2076    case Intrinsics::kLongRotateLeft:
2077      SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimLong);
2078      break;
2079    case Intrinsics::kIntegerCompare:
2080      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimInt);
2081      break;
2082    case Intrinsics::kLongCompare:
2083      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimLong);
2084      break;
2085    case Intrinsics::kIntegerSignum:
2086      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimInt);
2087      break;
2088    case Intrinsics::kLongSignum:
2089      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimLong);
2090      break;
2091    case Intrinsics::kFloatIsNaN:
2092    case Intrinsics::kDoubleIsNaN:
2093      SimplifyIsNaN(instruction);
2094      break;
2095    case Intrinsics::kFloatFloatToIntBits:
2096    case Intrinsics::kDoubleDoubleToLongBits:
2097      SimplifyFP2Int(instruction);
2098      break;
2099    case Intrinsics::kStringCharAt:
2100      SimplifyStringCharAt(instruction);
2101      break;
2102    case Intrinsics::kStringIsEmpty:
2103    case Intrinsics::kStringLength:
2104      SimplifyStringIsEmptyOrLength(instruction);
2105      break;
2106    case Intrinsics::kStringStringIndexOf:
2107    case Intrinsics::kStringStringIndexOfAfter:
2108      SimplifyNPEOnArgN(instruction, 1);  // 0th has own NullCheck
2109      break;
2110    case Intrinsics::kStringBufferAppend:
2111    case Intrinsics::kStringBuilderAppend:
2112      SimplifyReturnThis(instruction);
2113      break;
2114    case Intrinsics::kStringBufferToString:
2115    case Intrinsics::kStringBuilderToString:
2116      SimplifyAllocationIntrinsic(instruction);
2117      break;
2118    case Intrinsics::kUnsafeLoadFence:
2119      SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
2120      break;
2121    case Intrinsics::kUnsafeStoreFence:
2122      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
2123      break;
2124    case Intrinsics::kUnsafeFullFence:
2125      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
2126      break;
2127    default:
2128      break;
2129  }
2130}
2131
2132void InstructionSimplifierVisitor::VisitDeoptimize(HDeoptimize* deoptimize) {
2133  HInstruction* cond = deoptimize->InputAt(0);
2134  if (cond->IsConstant()) {
2135    if (cond->AsIntConstant()->IsFalse()) {
2136      // Never deopt: instruction can be removed.
2137      if (deoptimize->GuardsAnInput()) {
2138        deoptimize->ReplaceWith(deoptimize->GuardedInput());
2139      }
2140      deoptimize->GetBlock()->RemoveInstruction(deoptimize);
2141    } else {
2142      // Always deopt.
2143    }
2144  }
2145}
2146
2147// Replace code looking like
2148//    OP y, x, const1
2149//    OP z, y, const2
2150// with
2151//    OP z, x, const3
2152// where OP is both an associative and a commutative operation.
2153bool InstructionSimplifierVisitor::TryHandleAssociativeAndCommutativeOperation(
2154    HBinaryOperation* instruction) {
2155  DCHECK(instruction->IsCommutative());
2156
2157  if (!Primitive::IsIntegralType(instruction->GetType())) {
2158    return false;
2159  }
2160
2161  HInstruction* left = instruction->GetLeft();
2162  HInstruction* right = instruction->GetRight();
2163  // Variable names as described above.
2164  HConstant* const2;
2165  HBinaryOperation* y;
2166
2167  if (instruction->InstructionTypeEquals(left) && right->IsConstant()) {
2168    const2 = right->AsConstant();
2169    y = left->AsBinaryOperation();
2170  } else if (left->IsConstant() && instruction->InstructionTypeEquals(right)) {
2171    const2 = left->AsConstant();
2172    y = right->AsBinaryOperation();
2173  } else {
2174    // The node does not match the pattern.
2175    return false;
2176  }
2177
2178  // If `y` has more than one use, we do not perform the optimization
2179  // because it might increase code size (e.g. if the new constant is
2180  // no longer encodable as an immediate operand in the target ISA).
2181  if (!y->HasOnlyOneNonEnvironmentUse()) {
2182    return false;
2183  }
2184
2185  // GetConstantRight() can return both left and right constants
2186  // for commutative operations.
2187  HConstant* const1 = y->GetConstantRight();
2188  if (const1 == nullptr) {
2189    return false;
2190  }
2191
2192  instruction->ReplaceInput(const1, 0);
2193  instruction->ReplaceInput(const2, 1);
2194  HConstant* const3 = instruction->TryStaticEvaluation();
2195  DCHECK(const3 != nullptr);
2196  instruction->ReplaceInput(y->GetLeastConstantLeft(), 0);
2197  instruction->ReplaceInput(const3, 1);
2198  RecordSimplification();
2199  return true;
2200}
2201
2202static HBinaryOperation* AsAddOrSub(HInstruction* binop) {
2203  return (binop->IsAdd() || binop->IsSub()) ? binop->AsBinaryOperation() : nullptr;
2204}
2205
2206// Helper function that performs addition statically, considering the result type.
2207static int64_t ComputeAddition(Primitive::Type type, int64_t x, int64_t y) {
2208  // Use the Compute() method for consistency with TryStaticEvaluation().
2209  if (type == Primitive::kPrimInt) {
2210    return HAdd::Compute<int32_t>(x, y);
2211  } else {
2212    DCHECK_EQ(type, Primitive::kPrimLong);
2213    return HAdd::Compute<int64_t>(x, y);
2214  }
2215}
2216
2217// Helper function that handles the child classes of HConstant
2218// and returns an integer with the appropriate sign.
2219static int64_t GetValue(HConstant* constant, bool is_negated) {
2220  int64_t ret = Int64FromConstant(constant);
2221  return is_negated ? -ret : ret;
2222}
2223
2224// Replace code looking like
2225//    OP1 y, x, const1
2226//    OP2 z, y, const2
2227// with
2228//    OP3 z, x, const3
2229// where OPx is either ADD or SUB, and at least one of OP{1,2} is SUB.
2230bool InstructionSimplifierVisitor::TrySubtractionChainSimplification(
2231    HBinaryOperation* instruction) {
2232  DCHECK(instruction->IsAdd() || instruction->IsSub()) << instruction->DebugName();
2233
2234  Primitive::Type type = instruction->GetType();
2235  if (!Primitive::IsIntegralType(type)) {
2236    return false;
2237  }
2238
2239  HInstruction* left = instruction->GetLeft();
2240  HInstruction* right = instruction->GetRight();
2241  // Variable names as described above.
2242  HConstant* const2 = right->IsConstant() ? right->AsConstant() : left->AsConstant();
2243  if (const2 == nullptr) {
2244    return false;
2245  }
2246
2247  HBinaryOperation* y = (AsAddOrSub(left) != nullptr)
2248      ? left->AsBinaryOperation()
2249      : AsAddOrSub(right);
2250  // If y has more than one use, we do not perform the optimization because
2251  // it might increase code size (e.g. if the new constant is no longer
2252  // encodable as an immediate operand in the target ISA).
2253  if ((y == nullptr) || !y->HasOnlyOneNonEnvironmentUse()) {
2254    return false;
2255  }
2256
2257  left = y->GetLeft();
2258  HConstant* const1 = left->IsConstant() ? left->AsConstant() : y->GetRight()->AsConstant();
2259  if (const1 == nullptr) {
2260    return false;
2261  }
2262
2263  HInstruction* x = (const1 == left) ? y->GetRight() : left;
2264  // If both inputs are constants, let the constant folding pass deal with it.
2265  if (x->IsConstant()) {
2266    return false;
2267  }
2268
2269  bool is_const2_negated = (const2 == right) && instruction->IsSub();
2270  int64_t const2_val = GetValue(const2, is_const2_negated);
2271  bool is_y_negated = (y == right) && instruction->IsSub();
2272  right = y->GetRight();
2273  bool is_const1_negated = is_y_negated ^ ((const1 == right) && y->IsSub());
2274  int64_t const1_val = GetValue(const1, is_const1_negated);
2275  bool is_x_negated = is_y_negated ^ ((x == right) && y->IsSub());
2276  int64_t const3_val = ComputeAddition(type, const1_val, const2_val);
2277  HBasicBlock* block = instruction->GetBlock();
2278  HConstant* const3 = block->GetGraph()->GetConstant(type, const3_val);
2279  ArenaAllocator* arena = instruction->GetArena();
2280  HInstruction* z;
2281
2282  if (is_x_negated) {
2283    z = new (arena) HSub(type, const3, x, instruction->GetDexPc());
2284  } else {
2285    z = new (arena) HAdd(type, x, const3, instruction->GetDexPc());
2286  }
2287
2288  block->ReplaceAndRemoveInstructionWith(instruction, z);
2289  RecordSimplification();
2290  return true;
2291}
2292
2293}  // namespace art
2294