instruction_simplifier.cc revision 5b5b9319ff970979ed47d41a41283e4faeffb602
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 "intrinsics.h"
20#include "mirror/class-inl.h"
21#include "scoped_thread_state_change.h"
22
23namespace art {
24
25class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
26 public:
27  InstructionSimplifierVisitor(HGraph* graph, OptimizingCompilerStats* stats)
28      : HGraphDelegateVisitor(graph),
29        stats_(stats) {}
30
31  void Run();
32
33 private:
34  void RecordSimplification() {
35    simplification_occurred_ = true;
36    simplifications_at_current_position_++;
37    MaybeRecordStat(kInstructionSimplifications);
38  }
39
40  void MaybeRecordStat(MethodCompilationStat stat) {
41    if (stats_ != nullptr) {
42      stats_->RecordStat(stat);
43    }
44  }
45
46  bool ReplaceRotateWithRor(HBinaryOperation* op, HUShr* ushr, HShl* shl);
47  bool TryReplaceWithRotate(HBinaryOperation* instruction);
48  bool TryReplaceWithRotateConstantPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
49  bool TryReplaceWithRotateRegisterNegPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
50  bool TryReplaceWithRotateRegisterSubPattern(HBinaryOperation* op, HUShr* ushr, HShl* shl);
51
52  bool TryMoveNegOnInputsAfterBinop(HBinaryOperation* binop);
53  // `op` should be either HOr or HAnd.
54  // De Morgan's laws:
55  // ~a & ~b = ~(a | b)  and  ~a | ~b = ~(a & b)
56  bool TryDeMorganNegationFactoring(HBinaryOperation* op);
57  void VisitShift(HBinaryOperation* shift);
58
59  void VisitSuspendCheck(HSuspendCheck* check) OVERRIDE;
60  void VisitEqual(HEqual* equal) OVERRIDE;
61  void VisitNotEqual(HNotEqual* equal) OVERRIDE;
62  void VisitBooleanNot(HBooleanNot* bool_not) OVERRIDE;
63  void VisitInstanceFieldSet(HInstanceFieldSet* equal) OVERRIDE;
64  void VisitStaticFieldSet(HStaticFieldSet* equal) OVERRIDE;
65  void VisitArraySet(HArraySet* equal) OVERRIDE;
66  void VisitTypeConversion(HTypeConversion* instruction) OVERRIDE;
67  void VisitNullCheck(HNullCheck* instruction) OVERRIDE;
68  void VisitArrayLength(HArrayLength* instruction) OVERRIDE;
69  void VisitCheckCast(HCheckCast* instruction) OVERRIDE;
70  void VisitAdd(HAdd* instruction) OVERRIDE;
71  void VisitAnd(HAnd* instruction) OVERRIDE;
72  void VisitCondition(HCondition* instruction) OVERRIDE;
73  void VisitGreaterThan(HGreaterThan* condition) OVERRIDE;
74  void VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) OVERRIDE;
75  void VisitLessThan(HLessThan* condition) OVERRIDE;
76  void VisitLessThanOrEqual(HLessThanOrEqual* condition) OVERRIDE;
77  void VisitBelow(HBelow* condition) OVERRIDE;
78  void VisitBelowOrEqual(HBelowOrEqual* condition) OVERRIDE;
79  void VisitAbove(HAbove* condition) OVERRIDE;
80  void VisitAboveOrEqual(HAboveOrEqual* condition) OVERRIDE;
81  void VisitDiv(HDiv* instruction) OVERRIDE;
82  void VisitMul(HMul* instruction) OVERRIDE;
83  void VisitNeg(HNeg* instruction) OVERRIDE;
84  void VisitNot(HNot* instruction) OVERRIDE;
85  void VisitOr(HOr* instruction) OVERRIDE;
86  void VisitShl(HShl* instruction) OVERRIDE;
87  void VisitShr(HShr* instruction) OVERRIDE;
88  void VisitSub(HSub* instruction) OVERRIDE;
89  void VisitUShr(HUShr* instruction) OVERRIDE;
90  void VisitXor(HXor* instruction) OVERRIDE;
91  void VisitSelect(HSelect* select) OVERRIDE;
92  void VisitIf(HIf* instruction) OVERRIDE;
93  void VisitInstanceOf(HInstanceOf* instruction) OVERRIDE;
94  void VisitInvoke(HInvoke* invoke) OVERRIDE;
95  void VisitDeoptimize(HDeoptimize* deoptimize) OVERRIDE;
96
97  bool CanEnsureNotNullAt(HInstruction* instr, HInstruction* at) const;
98
99  void SimplifyRotate(HInvoke* invoke, bool is_left, Primitive::Type type);
100  void SimplifySystemArrayCopy(HInvoke* invoke);
101  void SimplifyStringEquals(HInvoke* invoke);
102  void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
103  void SimplifyIsNaN(HInvoke* invoke);
104  void SimplifyFP2Int(HInvoke* invoke);
105  void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
106
107  OptimizingCompilerStats* stats_;
108  bool simplification_occurred_ = false;
109  int simplifications_at_current_position_ = 0;
110  // We ensure we do not loop infinitely. The value is a finger in the air guess
111  // that should allow enough simplification.
112  static constexpr int kMaxSamePositionSimplifications = 10;
113};
114
115void InstructionSimplifier::Run() {
116  InstructionSimplifierVisitor visitor(graph_, stats_);
117  visitor.Run();
118}
119
120void InstructionSimplifierVisitor::Run() {
121  // Iterate in reverse post order to open up more simplifications to users
122  // of instructions that got simplified.
123  for (HReversePostOrderIterator it(*GetGraph()); !it.Done();) {
124    // The simplification of an instruction to another instruction may yield
125    // possibilities for other simplifications. So although we perform a reverse
126    // post order visit, we sometimes need to revisit an instruction index.
127    simplification_occurred_ = false;
128    VisitBasicBlock(it.Current());
129    if (simplification_occurred_ &&
130        (simplifications_at_current_position_ < kMaxSamePositionSimplifications)) {
131      // New simplifications may be applicable to the instruction at the
132      // current index, so don't advance the iterator.
133      continue;
134    }
135    simplifications_at_current_position_ = 0;
136    it.Advance();
137  }
138}
139
140namespace {
141
142bool AreAllBitsSet(HConstant* constant) {
143  return Int64FromConstant(constant) == -1;
144}
145
146}  // namespace
147
148// Returns true if the code was simplified to use only one negation operation
149// after the binary operation instead of one on each of the inputs.
150bool InstructionSimplifierVisitor::TryMoveNegOnInputsAfterBinop(HBinaryOperation* binop) {
151  DCHECK(binop->IsAdd() || binop->IsSub());
152  DCHECK(binop->GetLeft()->IsNeg() && binop->GetRight()->IsNeg());
153  HNeg* left_neg = binop->GetLeft()->AsNeg();
154  HNeg* right_neg = binop->GetRight()->AsNeg();
155  if (!left_neg->HasOnlyOneNonEnvironmentUse() ||
156      !right_neg->HasOnlyOneNonEnvironmentUse()) {
157    return false;
158  }
159  // Replace code looking like
160  //    NEG tmp1, a
161  //    NEG tmp2, b
162  //    ADD dst, tmp1, tmp2
163  // with
164  //    ADD tmp, a, b
165  //    NEG dst, tmp
166  // Note that we cannot optimize `(-a) + (-b)` to `-(a + b)` for floating-point.
167  // When `a` is `-0.0` and `b` is `0.0`, the former expression yields `0.0`,
168  // while the later yields `-0.0`.
169  if (!Primitive::IsIntegralType(binop->GetType())) {
170    return false;
171  }
172  binop->ReplaceInput(left_neg->GetInput(), 0);
173  binop->ReplaceInput(right_neg->GetInput(), 1);
174  left_neg->GetBlock()->RemoveInstruction(left_neg);
175  right_neg->GetBlock()->RemoveInstruction(right_neg);
176  HNeg* neg = new (GetGraph()->GetArena()) HNeg(binop->GetType(), binop);
177  binop->GetBlock()->InsertInstructionBefore(neg, binop->GetNext());
178  binop->ReplaceWithExceptInReplacementAtIndex(neg, 0);
179  RecordSimplification();
180  return true;
181}
182
183bool InstructionSimplifierVisitor::TryDeMorganNegationFactoring(HBinaryOperation* op) {
184  DCHECK(op->IsAnd() || op->IsOr()) << op->DebugName();
185  Primitive::Type type = op->GetType();
186  HInstruction* left = op->GetLeft();
187  HInstruction* right = op->GetRight();
188
189  // We can apply De Morgan's laws if both inputs are Not's and are only used
190  // by `op`.
191  if (((left->IsNot() && right->IsNot()) ||
192       (left->IsBooleanNot() && right->IsBooleanNot())) &&
193      left->HasOnlyOneNonEnvironmentUse() &&
194      right->HasOnlyOneNonEnvironmentUse()) {
195    // Replace code looking like
196    //    NOT nota, a
197    //    NOT notb, b
198    //    AND dst, nota, notb (respectively OR)
199    // with
200    //    OR or, a, b         (respectively AND)
201    //    NOT dest, or
202    HInstruction* src_left = left->InputAt(0);
203    HInstruction* src_right = right->InputAt(0);
204    uint32_t dex_pc = op->GetDexPc();
205
206    // Remove the negations on the inputs.
207    left->ReplaceWith(src_left);
208    right->ReplaceWith(src_right);
209    left->GetBlock()->RemoveInstruction(left);
210    right->GetBlock()->RemoveInstruction(right);
211
212    // Replace the `HAnd` or `HOr`.
213    HBinaryOperation* hbin;
214    if (op->IsAnd()) {
215      hbin = new (GetGraph()->GetArena()) HOr(type, src_left, src_right, dex_pc);
216    } else {
217      hbin = new (GetGraph()->GetArena()) HAnd(type, src_left, src_right, dex_pc);
218    }
219    HInstruction* hnot;
220    if (left->IsBooleanNot()) {
221      hnot = new (GetGraph()->GetArena()) HBooleanNot(hbin, dex_pc);
222    } else {
223      hnot = new (GetGraph()->GetArena()) HNot(type, hbin, dex_pc);
224    }
225
226    op->GetBlock()->InsertInstructionBefore(hbin, op);
227    op->GetBlock()->ReplaceAndRemoveInstructionWith(op, hnot);
228
229    RecordSimplification();
230    return true;
231  }
232
233  return false;
234}
235
236void InstructionSimplifierVisitor::VisitShift(HBinaryOperation* instruction) {
237  DCHECK(instruction->IsShl() || instruction->IsShr() || instruction->IsUShr());
238  HConstant* input_cst = instruction->GetConstantRight();
239  HInstruction* input_other = instruction->GetLeastConstantLeft();
240
241  if (input_cst != nullptr) {
242    int64_t cst = Int64FromConstant(input_cst);
243    int64_t mask = (input_other->GetType() == Primitive::kPrimLong)
244        ? kMaxLongShiftDistance
245        : kMaxIntShiftDistance;
246    if ((cst & mask) == 0) {
247      // Replace code looking like
248      //    SHL dst, src, 0
249      // with
250      //    src
251      instruction->ReplaceWith(input_other);
252      instruction->GetBlock()->RemoveInstruction(instruction);
253    }
254  }
255}
256
257static bool IsSubRegBitsMinusOther(HSub* sub, size_t reg_bits, HInstruction* other) {
258  return (sub->GetRight() == other &&
259          sub->GetLeft()->IsConstant() &&
260          (Int64FromConstant(sub->GetLeft()->AsConstant()) & (reg_bits - 1)) == 0);
261}
262
263bool InstructionSimplifierVisitor::ReplaceRotateWithRor(HBinaryOperation* op,
264                                                        HUShr* ushr,
265                                                        HShl* shl) {
266  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr()) << op->DebugName();
267  HRor* ror = new (GetGraph()->GetArena()) HRor(ushr->GetType(), ushr->GetLeft(), ushr->GetRight());
268  op->GetBlock()->ReplaceAndRemoveInstructionWith(op, ror);
269  if (!ushr->HasUses()) {
270    ushr->GetBlock()->RemoveInstruction(ushr);
271  }
272  if (!ushr->GetRight()->HasUses()) {
273    ushr->GetRight()->GetBlock()->RemoveInstruction(ushr->GetRight());
274  }
275  if (!shl->HasUses()) {
276    shl->GetBlock()->RemoveInstruction(shl);
277  }
278  if (!shl->GetRight()->HasUses()) {
279    shl->GetRight()->GetBlock()->RemoveInstruction(shl->GetRight());
280  }
281  return true;
282}
283
284// Try to replace a binary operation flanked by one UShr and one Shl with a bitfield rotation.
285bool InstructionSimplifierVisitor::TryReplaceWithRotate(HBinaryOperation* op) {
286  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
287  HInstruction* left = op->GetLeft();
288  HInstruction* right = op->GetRight();
289  // If we have an UShr and a Shl (in either order).
290  if ((left->IsUShr() && right->IsShl()) || (left->IsShl() && right->IsUShr())) {
291    HUShr* ushr = left->IsUShr() ? left->AsUShr() : right->AsUShr();
292    HShl* shl = left->IsShl() ? left->AsShl() : right->AsShl();
293    DCHECK(Primitive::IsIntOrLongType(ushr->GetType()));
294    if (ushr->GetType() == shl->GetType() &&
295        ushr->GetLeft() == shl->GetLeft()) {
296      if (ushr->GetRight()->IsConstant() && shl->GetRight()->IsConstant()) {
297        // Shift distances are both constant, try replacing with Ror if they
298        // add up to the register size.
299        return TryReplaceWithRotateConstantPattern(op, ushr, shl);
300      } else if (ushr->GetRight()->IsSub() || shl->GetRight()->IsSub()) {
301        // Shift distances are potentially of the form x and (reg_size - x).
302        return TryReplaceWithRotateRegisterSubPattern(op, ushr, shl);
303      } else if (ushr->GetRight()->IsNeg() || shl->GetRight()->IsNeg()) {
304        // Shift distances are potentially of the form d and -d.
305        return TryReplaceWithRotateRegisterNegPattern(op, ushr, shl);
306      }
307    }
308  }
309  return false;
310}
311
312// Try replacing code looking like (x >>> #rdist OP x << #ldist):
313//    UShr dst, x,   #rdist
314//    Shl  tmp, x,   #ldist
315//    OP   dst, dst, tmp
316// or like (x >>> #rdist OP x << #-ldist):
317//    UShr dst, x,   #rdist
318//    Shl  tmp, x,   #-ldist
319//    OP   dst, dst, tmp
320// with
321//    Ror  dst, x,   #rdist
322bool InstructionSimplifierVisitor::TryReplaceWithRotateConstantPattern(HBinaryOperation* op,
323                                                                       HUShr* ushr,
324                                                                       HShl* shl) {
325  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
326  size_t reg_bits = Primitive::ComponentSize(ushr->GetType()) * kBitsPerByte;
327  size_t rdist = Int64FromConstant(ushr->GetRight()->AsConstant());
328  size_t ldist = Int64FromConstant(shl->GetRight()->AsConstant());
329  if (((ldist + rdist) & (reg_bits - 1)) == 0) {
330    ReplaceRotateWithRor(op, ushr, shl);
331    return true;
332  }
333  return false;
334}
335
336// Replace code looking like (x >>> -d OP x << d):
337//    Neg  neg, d
338//    UShr dst, x,   neg
339//    Shl  tmp, x,   d
340//    OP   dst, dst, tmp
341// with
342//    Neg  neg, d
343//    Ror  dst, x,   neg
344// *** OR ***
345// Replace code looking like (x >>> d OP x << -d):
346//    UShr dst, x,   d
347//    Neg  neg, d
348//    Shl  tmp, x,   neg
349//    OP   dst, dst, tmp
350// with
351//    Ror  dst, x,   d
352bool InstructionSimplifierVisitor::TryReplaceWithRotateRegisterNegPattern(HBinaryOperation* op,
353                                                                          HUShr* ushr,
354                                                                          HShl* shl) {
355  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
356  DCHECK(ushr->GetRight()->IsNeg() || shl->GetRight()->IsNeg());
357  bool neg_is_left = shl->GetRight()->IsNeg();
358  HNeg* neg = neg_is_left ? shl->GetRight()->AsNeg() : ushr->GetRight()->AsNeg();
359  // And the shift distance being negated is the distance being shifted the other way.
360  if (neg->InputAt(0) == (neg_is_left ? ushr->GetRight() : shl->GetRight())) {
361    ReplaceRotateWithRor(op, ushr, shl);
362  }
363  return false;
364}
365
366// Try replacing code looking like (x >>> d OP x << (#bits - d)):
367//    UShr dst, x,     d
368//    Sub  ld,  #bits, d
369//    Shl  tmp, x,     ld
370//    OP   dst, dst,   tmp
371// with
372//    Ror  dst, x,     d
373// *** OR ***
374// Replace code looking like (x >>> (#bits - d) OP x << d):
375//    Sub  rd,  #bits, d
376//    UShr dst, x,     rd
377//    Shl  tmp, x,     d
378//    OP   dst, dst,   tmp
379// with
380//    Neg  neg, d
381//    Ror  dst, x,     neg
382bool InstructionSimplifierVisitor::TryReplaceWithRotateRegisterSubPattern(HBinaryOperation* op,
383                                                                          HUShr* ushr,
384                                                                          HShl* shl) {
385  DCHECK(op->IsAdd() || op->IsXor() || op->IsOr());
386  DCHECK(ushr->GetRight()->IsSub() || shl->GetRight()->IsSub());
387  size_t reg_bits = Primitive::ComponentSize(ushr->GetType()) * kBitsPerByte;
388  HInstruction* shl_shift = shl->GetRight();
389  HInstruction* ushr_shift = ushr->GetRight();
390  if ((shl_shift->IsSub() && IsSubRegBitsMinusOther(shl_shift->AsSub(), reg_bits, ushr_shift)) ||
391      (ushr_shift->IsSub() && IsSubRegBitsMinusOther(ushr_shift->AsSub(), reg_bits, shl_shift))) {
392    return ReplaceRotateWithRor(op, ushr, shl);
393  }
394  return false;
395}
396
397void InstructionSimplifierVisitor::VisitNullCheck(HNullCheck* null_check) {
398  HInstruction* obj = null_check->InputAt(0);
399  if (!obj->CanBeNull()) {
400    null_check->ReplaceWith(obj);
401    null_check->GetBlock()->RemoveInstruction(null_check);
402    if (stats_ != nullptr) {
403      stats_->RecordStat(MethodCompilationStat::kRemovedNullCheck);
404    }
405  }
406}
407
408bool InstructionSimplifierVisitor::CanEnsureNotNullAt(HInstruction* input, HInstruction* at) const {
409  if (!input->CanBeNull()) {
410    return true;
411  }
412
413  for (HUseIterator<HInstruction*> it(input->GetUses()); !it.Done(); it.Advance()) {
414    HInstruction* use = it.Current()->GetUser();
415    if (use->IsNullCheck() && use->StrictlyDominates(at)) {
416      return true;
417    }
418  }
419
420  return false;
421}
422
423// Returns whether doing a type test between the class of `object` against `klass` has
424// a statically known outcome. The result of the test is stored in `outcome`.
425static bool TypeCheckHasKnownOutcome(HLoadClass* klass, HInstruction* object, bool* outcome) {
426  DCHECK(!object->IsNullConstant()) << "Null constants should be special cased";
427  ReferenceTypeInfo obj_rti = object->GetReferenceTypeInfo();
428  ScopedObjectAccess soa(Thread::Current());
429  if (!obj_rti.IsValid()) {
430    // We run the simplifier before the reference type propagation so type info might not be
431    // available.
432    return false;
433  }
434
435  ReferenceTypeInfo class_rti = klass->GetLoadedClassRTI();
436  if (!class_rti.IsValid()) {
437    // Happens when the loaded class is unresolved.
438    return false;
439  }
440  DCHECK(class_rti.IsExact());
441  if (class_rti.IsSupertypeOf(obj_rti)) {
442    *outcome = true;
443    return true;
444  } else if (obj_rti.IsExact()) {
445    // The test failed at compile time so will also fail at runtime.
446    *outcome = false;
447    return true;
448  } else if (!class_rti.IsInterface()
449             && !obj_rti.IsInterface()
450             && !obj_rti.IsSupertypeOf(class_rti)) {
451    // Different type hierarchy. The test will fail.
452    *outcome = false;
453    return true;
454  }
455  return false;
456}
457
458void InstructionSimplifierVisitor::VisitCheckCast(HCheckCast* check_cast) {
459  HInstruction* object = check_cast->InputAt(0);
460  HLoadClass* load_class = check_cast->InputAt(1)->AsLoadClass();
461  if (load_class->NeedsAccessCheck()) {
462    // If we need to perform an access check we cannot remove the instruction.
463    return;
464  }
465
466  if (CanEnsureNotNullAt(object, check_cast)) {
467    check_cast->ClearMustDoNullCheck();
468  }
469
470  if (object->IsNullConstant()) {
471    check_cast->GetBlock()->RemoveInstruction(check_cast);
472    MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast);
473    return;
474  }
475
476  // Note: The `outcome` is initialized to please valgrind - the compiler can reorder
477  // the return value check with the `outcome` check, b/27651442 .
478  bool outcome = false;
479  if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) {
480    if (outcome) {
481      check_cast->GetBlock()->RemoveInstruction(check_cast);
482      MaybeRecordStat(MethodCompilationStat::kRemovedCheckedCast);
483      if (!load_class->HasUses()) {
484        // We cannot rely on DCE to remove the class because the `HLoadClass` thinks it can throw.
485        // However, here we know that it cannot because the checkcast was successfull, hence
486        // the class was already loaded.
487        load_class->GetBlock()->RemoveInstruction(load_class);
488      }
489    } else {
490      // Don't do anything for exceptional cases for now. Ideally we should remove
491      // all instructions and blocks this instruction dominates.
492    }
493  }
494}
495
496void InstructionSimplifierVisitor::VisitInstanceOf(HInstanceOf* instruction) {
497  HInstruction* object = instruction->InputAt(0);
498  HLoadClass* load_class = instruction->InputAt(1)->AsLoadClass();
499  if (load_class->NeedsAccessCheck()) {
500    // If we need to perform an access check we cannot remove the instruction.
501    return;
502  }
503
504  bool can_be_null = true;
505  if (CanEnsureNotNullAt(object, instruction)) {
506    can_be_null = false;
507    instruction->ClearMustDoNullCheck();
508  }
509
510  HGraph* graph = GetGraph();
511  if (object->IsNullConstant()) {
512    MaybeRecordStat(kRemovedInstanceOf);
513    instruction->ReplaceWith(graph->GetIntConstant(0));
514    instruction->GetBlock()->RemoveInstruction(instruction);
515    RecordSimplification();
516    return;
517  }
518
519  // Note: The `outcome` is initialized to please valgrind - the compiler can reorder
520  // the return value check with the `outcome` check, b/27651442 .
521  bool outcome = false;
522  if (TypeCheckHasKnownOutcome(load_class, object, &outcome)) {
523    MaybeRecordStat(kRemovedInstanceOf);
524    if (outcome && can_be_null) {
525      // Type test will succeed, we just need a null test.
526      HNotEqual* test = new (graph->GetArena()) HNotEqual(graph->GetNullConstant(), object);
527      instruction->GetBlock()->InsertInstructionBefore(test, instruction);
528      instruction->ReplaceWith(test);
529    } else {
530      // We've statically determined the result of the instanceof.
531      instruction->ReplaceWith(graph->GetIntConstant(outcome));
532    }
533    RecordSimplification();
534    instruction->GetBlock()->RemoveInstruction(instruction);
535    if (outcome && !load_class->HasUses()) {
536      // We cannot rely on DCE to remove the class because the `HLoadClass` thinks it can throw.
537      // However, here we know that it cannot because the instanceof check was successfull, hence
538      // the class was already loaded.
539      load_class->GetBlock()->RemoveInstruction(load_class);
540    }
541  }
542}
543
544void InstructionSimplifierVisitor::VisitInstanceFieldSet(HInstanceFieldSet* instruction) {
545  if ((instruction->GetValue()->GetType() == Primitive::kPrimNot)
546      && CanEnsureNotNullAt(instruction->GetValue(), instruction)) {
547    instruction->ClearValueCanBeNull();
548  }
549}
550
551void InstructionSimplifierVisitor::VisitStaticFieldSet(HStaticFieldSet* instruction) {
552  if ((instruction->GetValue()->GetType() == Primitive::kPrimNot)
553      && CanEnsureNotNullAt(instruction->GetValue(), instruction)) {
554    instruction->ClearValueCanBeNull();
555  }
556}
557
558void InstructionSimplifierVisitor::VisitSuspendCheck(HSuspendCheck* check) {
559  HBasicBlock* block = check->GetBlock();
560  // Currently always keep the suspend check at entry.
561  if (block->IsEntryBlock()) return;
562
563  // Currently always keep suspend checks at loop entry.
564  if (block->IsLoopHeader() && block->GetFirstInstruction() == check) {
565    DCHECK(block->GetLoopInformation()->GetSuspendCheck() == check);
566    return;
567  }
568
569  // Remove the suspend check that was added at build time for the baseline
570  // compiler.
571  block->RemoveInstruction(check);
572}
573
574static HCondition* GetOppositeConditionSwapOps(ArenaAllocator* arena, HInstruction* cond) {
575  HInstruction *lhs = cond->InputAt(0);
576  HInstruction *rhs = cond->InputAt(1);
577  switch (cond->GetKind()) {
578    case HInstruction::kEqual:
579      return new (arena) HEqual(rhs, lhs);
580    case HInstruction::kNotEqual:
581      return new (arena) HNotEqual(rhs, lhs);
582    case HInstruction::kLessThan:
583      return new (arena) HGreaterThan(rhs, lhs);
584    case HInstruction::kLessThanOrEqual:
585      return new (arena) HGreaterThanOrEqual(rhs, lhs);
586    case HInstruction::kGreaterThan:
587      return new (arena) HLessThan(rhs, lhs);
588    case HInstruction::kGreaterThanOrEqual:
589      return new (arena) HLessThanOrEqual(rhs, lhs);
590    case HInstruction::kBelow:
591      return new (arena) HAbove(rhs, lhs);
592    case HInstruction::kBelowOrEqual:
593      return new (arena) HAboveOrEqual(rhs, lhs);
594    case HInstruction::kAbove:
595      return new (arena) HBelow(rhs, lhs);
596    case HInstruction::kAboveOrEqual:
597      return new (arena) HBelowOrEqual(rhs, lhs);
598    default:
599      LOG(FATAL) << "Unknown ConditionType " << cond->GetKind();
600  }
601  return nullptr;
602}
603
604void InstructionSimplifierVisitor::VisitEqual(HEqual* equal) {
605  HInstruction* input_const = equal->GetConstantRight();
606  if (input_const != nullptr) {
607    HInstruction* input_value = equal->GetLeastConstantLeft();
608    if (input_value->GetType() == Primitive::kPrimBoolean && input_const->IsIntConstant()) {
609      HBasicBlock* block = equal->GetBlock();
610      // We are comparing the boolean to a constant which is of type int and can
611      // be any constant.
612      if (input_const->AsIntConstant()->IsOne()) {
613        // Replace (bool_value == true) with bool_value
614        equal->ReplaceWith(input_value);
615        block->RemoveInstruction(equal);
616        RecordSimplification();
617      } else if (input_const->AsIntConstant()->IsZero()) {
618        equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, equal));
619        block->RemoveInstruction(equal);
620        RecordSimplification();
621      } else {
622        // Replace (bool_value == integer_not_zero_nor_one_constant) with false
623        equal->ReplaceWith(GetGraph()->GetIntConstant(0));
624        block->RemoveInstruction(equal);
625        RecordSimplification();
626      }
627    } else {
628      VisitCondition(equal);
629    }
630  } else {
631    VisitCondition(equal);
632  }
633}
634
635void InstructionSimplifierVisitor::VisitNotEqual(HNotEqual* not_equal) {
636  HInstruction* input_const = not_equal->GetConstantRight();
637  if (input_const != nullptr) {
638    HInstruction* input_value = not_equal->GetLeastConstantLeft();
639    if (input_value->GetType() == Primitive::kPrimBoolean && input_const->IsIntConstant()) {
640      HBasicBlock* block = not_equal->GetBlock();
641      // We are comparing the boolean to a constant which is of type int and can
642      // be any constant.
643      if (input_const->AsIntConstant()->IsOne()) {
644        not_equal->ReplaceWith(GetGraph()->InsertOppositeCondition(input_value, not_equal));
645        block->RemoveInstruction(not_equal);
646        RecordSimplification();
647      } else if (input_const->AsIntConstant()->IsZero()) {
648        // Replace (bool_value != false) with bool_value
649        not_equal->ReplaceWith(input_value);
650        block->RemoveInstruction(not_equal);
651        RecordSimplification();
652      } else {
653        // Replace (bool_value != integer_not_zero_nor_one_constant) with true
654        not_equal->ReplaceWith(GetGraph()->GetIntConstant(1));
655        block->RemoveInstruction(not_equal);
656        RecordSimplification();
657      }
658    } else {
659      VisitCondition(not_equal);
660    }
661  } else {
662    VisitCondition(not_equal);
663  }
664}
665
666void InstructionSimplifierVisitor::VisitBooleanNot(HBooleanNot* bool_not) {
667  HInstruction* input = bool_not->InputAt(0);
668  HInstruction* replace_with = nullptr;
669
670  if (input->IsIntConstant()) {
671    // Replace !(true/false) with false/true.
672    if (input->AsIntConstant()->IsOne()) {
673      replace_with = GetGraph()->GetIntConstant(0);
674    } else {
675      DCHECK(input->AsIntConstant()->IsZero());
676      replace_with = GetGraph()->GetIntConstant(1);
677    }
678  } else if (input->IsBooleanNot()) {
679    // Replace (!(!bool_value)) with bool_value.
680    replace_with = input->InputAt(0);
681  } else if (input->IsCondition() &&
682             // Don't change FP compares. The definition of compares involving
683             // NaNs forces the compares to be done as written by the user.
684             !Primitive::IsFloatingPointType(input->InputAt(0)->GetType())) {
685    // Replace condition with its opposite.
686    replace_with = GetGraph()->InsertOppositeCondition(input->AsCondition(), bool_not);
687  }
688
689  if (replace_with != nullptr) {
690    bool_not->ReplaceWith(replace_with);
691    bool_not->GetBlock()->RemoveInstruction(bool_not);
692    RecordSimplification();
693  }
694}
695
696void InstructionSimplifierVisitor::VisitSelect(HSelect* select) {
697  HInstruction* replace_with = nullptr;
698  HInstruction* condition = select->GetCondition();
699  HInstruction* true_value = select->GetTrueValue();
700  HInstruction* false_value = select->GetFalseValue();
701
702  if (condition->IsBooleanNot()) {
703    // Change ((!cond) ? x : y) to (cond ? y : x).
704    condition = condition->InputAt(0);
705    std::swap(true_value, false_value);
706    select->ReplaceInput(false_value, 0);
707    select->ReplaceInput(true_value, 1);
708    select->ReplaceInput(condition, 2);
709    RecordSimplification();
710  }
711
712  if (true_value == false_value) {
713    // Replace (cond ? x : x) with (x).
714    replace_with = true_value;
715  } else if (condition->IsIntConstant()) {
716    if (condition->AsIntConstant()->IsOne()) {
717      // Replace (true ? x : y) with (x).
718      replace_with = true_value;
719    } else {
720      // Replace (false ? x : y) with (y).
721      DCHECK(condition->AsIntConstant()->IsZero());
722      replace_with = false_value;
723    }
724  } else if (true_value->IsIntConstant() && false_value->IsIntConstant()) {
725    if (true_value->AsIntConstant()->IsOne() && false_value->AsIntConstant()->IsZero()) {
726      // Replace (cond ? true : false) with (cond).
727      replace_with = condition;
728    } else if (true_value->AsIntConstant()->IsZero() && false_value->AsIntConstant()->IsOne()) {
729      // Replace (cond ? false : true) with (!cond).
730      replace_with = GetGraph()->InsertOppositeCondition(condition, select);
731    }
732  }
733
734  if (replace_with != nullptr) {
735    select->ReplaceWith(replace_with);
736    select->GetBlock()->RemoveInstruction(select);
737    RecordSimplification();
738  }
739}
740
741void InstructionSimplifierVisitor::VisitIf(HIf* instruction) {
742  HInstruction* condition = instruction->InputAt(0);
743  if (condition->IsBooleanNot()) {
744    // Swap successors if input is negated.
745    instruction->ReplaceInput(condition->InputAt(0), 0);
746    instruction->GetBlock()->SwapSuccessors();
747    RecordSimplification();
748  }
749}
750
751void InstructionSimplifierVisitor::VisitArrayLength(HArrayLength* instruction) {
752  HInstruction* input = instruction->InputAt(0);
753  // If the array is a NewArray with constant size, replace the array length
754  // with the constant instruction. This helps the bounds check elimination phase.
755  if (input->IsNewArray()) {
756    input = input->InputAt(0);
757    if (input->IsIntConstant()) {
758      instruction->ReplaceWith(input);
759    }
760  }
761}
762
763void InstructionSimplifierVisitor::VisitArraySet(HArraySet* instruction) {
764  HInstruction* value = instruction->GetValue();
765  if (value->GetType() != Primitive::kPrimNot) return;
766
767  if (CanEnsureNotNullAt(value, instruction)) {
768    instruction->ClearValueCanBeNull();
769  }
770
771  if (value->IsArrayGet()) {
772    if (value->AsArrayGet()->GetArray() == instruction->GetArray()) {
773      // If the code is just swapping elements in the array, no need for a type check.
774      instruction->ClearNeedsTypeCheck();
775      return;
776    }
777  }
778
779  if (value->IsNullConstant()) {
780    instruction->ClearNeedsTypeCheck();
781    return;
782  }
783
784  ScopedObjectAccess soa(Thread::Current());
785  ReferenceTypeInfo array_rti = instruction->GetArray()->GetReferenceTypeInfo();
786  ReferenceTypeInfo value_rti = value->GetReferenceTypeInfo();
787  if (!array_rti.IsValid()) {
788    return;
789  }
790
791  if (value_rti.IsValid() && array_rti.CanArrayHold(value_rti)) {
792    instruction->ClearNeedsTypeCheck();
793    return;
794  }
795
796  if (array_rti.IsObjectArray()) {
797    if (array_rti.IsExact()) {
798      instruction->ClearNeedsTypeCheck();
799      return;
800    }
801    instruction->SetStaticTypeOfArrayIsObjectArray();
802  }
803}
804
805static bool IsTypeConversionImplicit(Primitive::Type input_type, Primitive::Type result_type) {
806  // Besides conversion to the same type, widening integral conversions are implicit,
807  // excluding conversions to long and the byte->char conversion where we need to
808  // clear the high 16 bits of the 32-bit sign-extended representation of byte.
809  return result_type == input_type ||
810      (result_type == Primitive::kPrimInt && input_type == Primitive::kPrimByte) ||
811      (result_type == Primitive::kPrimInt && input_type == Primitive::kPrimShort) ||
812      (result_type == Primitive::kPrimInt && input_type == Primitive::kPrimChar) ||
813      (result_type == Primitive::kPrimShort && input_type == Primitive::kPrimByte);
814}
815
816static bool IsTypeConversionLossless(Primitive::Type input_type, Primitive::Type result_type) {
817  // The conversion to a larger type is loss-less with the exception of two cases,
818  //   - conversion to char, the only unsigned type, where we may lose some bits, and
819  //   - conversion from float to long, the only FP to integral conversion with smaller FP type.
820  // For integral to FP conversions this holds because the FP mantissa is large enough.
821  DCHECK_NE(input_type, result_type);
822  return Primitive::ComponentSize(result_type) > Primitive::ComponentSize(input_type) &&
823      result_type != Primitive::kPrimChar &&
824      !(result_type == Primitive::kPrimLong && input_type == Primitive::kPrimFloat);
825}
826
827void InstructionSimplifierVisitor::VisitTypeConversion(HTypeConversion* instruction) {
828  HInstruction* input = instruction->GetInput();
829  Primitive::Type input_type = input->GetType();
830  Primitive::Type result_type = instruction->GetResultType();
831  if (IsTypeConversionImplicit(input_type, result_type)) {
832    // Remove the implicit conversion; this includes conversion to the same type.
833    instruction->ReplaceWith(input);
834    instruction->GetBlock()->RemoveInstruction(instruction);
835    RecordSimplification();
836    return;
837  }
838
839  if (input->IsTypeConversion()) {
840    HTypeConversion* input_conversion = input->AsTypeConversion();
841    HInstruction* original_input = input_conversion->GetInput();
842    Primitive::Type original_type = original_input->GetType();
843
844    // When the first conversion is lossless, a direct conversion from the original type
845    // to the final type yields the same result, even for a lossy second conversion, for
846    // example float->double->int or int->double->float.
847    bool is_first_conversion_lossless = IsTypeConversionLossless(original_type, input_type);
848
849    // For integral conversions, see if the first conversion loses only bits that the second
850    // doesn't need, i.e. the final type is no wider than the intermediate. If so, direct
851    // conversion yields the same result, for example long->int->short or int->char->short.
852    bool integral_conversions_with_non_widening_second =
853        Primitive::IsIntegralType(input_type) &&
854        Primitive::IsIntegralType(original_type) &&
855        Primitive::IsIntegralType(result_type) &&
856        Primitive::ComponentSize(result_type) <= Primitive::ComponentSize(input_type);
857
858    if (is_first_conversion_lossless || integral_conversions_with_non_widening_second) {
859      // If the merged conversion is implicit, do the simplification unconditionally.
860      if (IsTypeConversionImplicit(original_type, result_type)) {
861        instruction->ReplaceWith(original_input);
862        instruction->GetBlock()->RemoveInstruction(instruction);
863        if (!input_conversion->HasUses()) {
864          // Don't wait for DCE.
865          input_conversion->GetBlock()->RemoveInstruction(input_conversion);
866        }
867        RecordSimplification();
868        return;
869      }
870      // Otherwise simplify only if the first conversion has no other use.
871      if (input_conversion->HasOnlyOneNonEnvironmentUse()) {
872        input_conversion->ReplaceWith(original_input);
873        input_conversion->GetBlock()->RemoveInstruction(input_conversion);
874        RecordSimplification();
875        return;
876      }
877    }
878  } else if (input->IsAnd() && Primitive::IsIntegralType(result_type)) {
879    DCHECK(Primitive::IsIntegralType(input_type));
880    HAnd* input_and = input->AsAnd();
881    HConstant* constant = input_and->GetConstantRight();
882    if (constant != nullptr) {
883      int64_t value = Int64FromConstant(constant);
884      DCHECK_NE(value, -1);  // "& -1" would have been optimized away in VisitAnd().
885      size_t trailing_ones = CTZ(~static_cast<uint64_t>(value));
886      if (trailing_ones >= kBitsPerByte * Primitive::ComponentSize(result_type)) {
887        // The `HAnd` is useless, for example in `(byte) (x & 0xff)`, get rid of it.
888        HInstruction* original_input = input_and->GetLeastConstantLeft();
889        if (IsTypeConversionImplicit(original_input->GetType(), result_type)) {
890          instruction->ReplaceWith(original_input);
891          instruction->GetBlock()->RemoveInstruction(instruction);
892          RecordSimplification();
893          return;
894        } else if (input->HasOnlyOneNonEnvironmentUse()) {
895          input_and->ReplaceWith(original_input);
896          input_and->GetBlock()->RemoveInstruction(input_and);
897          RecordSimplification();
898          return;
899        }
900      }
901    }
902  }
903}
904
905void InstructionSimplifierVisitor::VisitAdd(HAdd* instruction) {
906  HConstant* input_cst = instruction->GetConstantRight();
907  HInstruction* input_other = instruction->GetLeastConstantLeft();
908  if ((input_cst != nullptr) && input_cst->IsZero()) {
909    // Replace code looking like
910    //    ADD dst, src, 0
911    // with
912    //    src
913    // Note that we cannot optimize `x + 0.0` to `x` for floating-point. When
914    // `x` is `-0.0`, the former expression yields `0.0`, while the later
915    // yields `-0.0`.
916    if (Primitive::IsIntegralType(instruction->GetType())) {
917      instruction->ReplaceWith(input_other);
918      instruction->GetBlock()->RemoveInstruction(instruction);
919      return;
920    }
921  }
922
923  HInstruction* left = instruction->GetLeft();
924  HInstruction* right = instruction->GetRight();
925  bool left_is_neg = left->IsNeg();
926  bool right_is_neg = right->IsNeg();
927
928  if (left_is_neg && right_is_neg) {
929    if (TryMoveNegOnInputsAfterBinop(instruction)) {
930      return;
931    }
932  }
933
934  HNeg* neg = left_is_neg ? left->AsNeg() : right->AsNeg();
935  if ((left_is_neg ^ right_is_neg) && neg->HasOnlyOneNonEnvironmentUse()) {
936    // Replace code looking like
937    //    NEG tmp, b
938    //    ADD dst, a, tmp
939    // with
940    //    SUB dst, a, b
941    // We do not perform the optimization if the input negation has environment
942    // uses or multiple non-environment uses as it could lead to worse code. In
943    // particular, we do not want the live range of `b` to be extended if we are
944    // not sure the initial 'NEG' instruction can be removed.
945    HInstruction* other = left_is_neg ? right : left;
946    HSub* sub = new(GetGraph()->GetArena()) HSub(instruction->GetType(), other, neg->GetInput());
947    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, sub);
948    RecordSimplification();
949    neg->GetBlock()->RemoveInstruction(neg);
950    return;
951  }
952
953  TryReplaceWithRotate(instruction);
954}
955
956void InstructionSimplifierVisitor::VisitAnd(HAnd* instruction) {
957  HConstant* input_cst = instruction->GetConstantRight();
958  HInstruction* input_other = instruction->GetLeastConstantLeft();
959
960  if (input_cst != nullptr) {
961    int64_t value = Int64FromConstant(input_cst);
962    if (value == -1) {
963      // Replace code looking like
964      //    AND dst, src, 0xFFF...FF
965      // with
966      //    src
967      instruction->ReplaceWith(input_other);
968      instruction->GetBlock()->RemoveInstruction(instruction);
969      RecordSimplification();
970      return;
971    }
972    // Eliminate And from UShr+And if the And-mask contains all the bits that
973    // can be non-zero after UShr. Transform Shr+And to UShr if the And-mask
974    // precisely clears the shifted-in sign bits.
975    if ((input_other->IsUShr() || input_other->IsShr()) && input_other->InputAt(1)->IsConstant()) {
976      size_t reg_bits = (instruction->GetResultType() == Primitive::kPrimLong) ? 64 : 32;
977      size_t shift = Int64FromConstant(input_other->InputAt(1)->AsConstant()) & (reg_bits - 1);
978      size_t num_tail_bits_set = CTZ(value + 1);
979      if ((num_tail_bits_set >= reg_bits - shift) && input_other->IsUShr()) {
980        // This AND clears only bits known to be clear, for example "(x >>> 24) & 0xff".
981        instruction->ReplaceWith(input_other);
982        instruction->GetBlock()->RemoveInstruction(instruction);
983        RecordSimplification();
984        return;
985      }  else if ((num_tail_bits_set == reg_bits - shift) && IsPowerOfTwo(value + 1) &&
986          input_other->HasOnlyOneNonEnvironmentUse()) {
987        DCHECK(input_other->IsShr());  // For UShr, we would have taken the branch above.
988        // Replace SHR+AND with USHR, for example "(x >> 24) & 0xff" -> "x >>> 24".
989        HUShr* ushr = new (GetGraph()->GetArena()) HUShr(instruction->GetType(),
990                                                         input_other->InputAt(0),
991                                                         input_other->InputAt(1),
992                                                         input_other->GetDexPc());
993        instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, ushr);
994        input_other->GetBlock()->RemoveInstruction(input_other);
995        RecordSimplification();
996        return;
997      }
998    }
999  }
1000
1001  // We assume that GVN has run before, so we only perform a pointer comparison.
1002  // If for some reason the values are equal but the pointers are different, we
1003  // are still correct and only miss an optimization opportunity.
1004  if (instruction->GetLeft() == instruction->GetRight()) {
1005    // Replace code looking like
1006    //    AND dst, src, src
1007    // with
1008    //    src
1009    instruction->ReplaceWith(instruction->GetLeft());
1010    instruction->GetBlock()->RemoveInstruction(instruction);
1011    return;
1012  }
1013
1014  TryDeMorganNegationFactoring(instruction);
1015}
1016
1017void InstructionSimplifierVisitor::VisitGreaterThan(HGreaterThan* condition) {
1018  VisitCondition(condition);
1019}
1020
1021void InstructionSimplifierVisitor::VisitGreaterThanOrEqual(HGreaterThanOrEqual* condition) {
1022  VisitCondition(condition);
1023}
1024
1025void InstructionSimplifierVisitor::VisitLessThan(HLessThan* condition) {
1026  VisitCondition(condition);
1027}
1028
1029void InstructionSimplifierVisitor::VisitLessThanOrEqual(HLessThanOrEqual* condition) {
1030  VisitCondition(condition);
1031}
1032
1033void InstructionSimplifierVisitor::VisitBelow(HBelow* condition) {
1034  VisitCondition(condition);
1035}
1036
1037void InstructionSimplifierVisitor::VisitBelowOrEqual(HBelowOrEqual* condition) {
1038  VisitCondition(condition);
1039}
1040
1041void InstructionSimplifierVisitor::VisitAbove(HAbove* condition) {
1042  VisitCondition(condition);
1043}
1044
1045void InstructionSimplifierVisitor::VisitAboveOrEqual(HAboveOrEqual* condition) {
1046  VisitCondition(condition);
1047}
1048
1049void InstructionSimplifierVisitor::VisitCondition(HCondition* condition) {
1050  // Reverse condition if left is constant. Our code generators prefer constant
1051  // on the right hand side.
1052  if (condition->GetLeft()->IsConstant() && !condition->GetRight()->IsConstant()) {
1053    HBasicBlock* block = condition->GetBlock();
1054    HCondition* replacement = GetOppositeConditionSwapOps(block->GetGraph()->GetArena(), condition);
1055    // If it is a fp we must set the opposite bias.
1056    if (replacement != nullptr) {
1057      if (condition->IsLtBias()) {
1058        replacement->SetBias(ComparisonBias::kGtBias);
1059      } else if (condition->IsGtBias()) {
1060        replacement->SetBias(ComparisonBias::kLtBias);
1061      }
1062      block->ReplaceAndRemoveInstructionWith(condition, replacement);
1063      RecordSimplification();
1064
1065      condition = replacement;
1066    }
1067  }
1068
1069  HInstruction* left = condition->GetLeft();
1070  HInstruction* right = condition->GetRight();
1071
1072  // Try to fold an HCompare into this HCondition.
1073
1074  // We can only replace an HCondition which compares a Compare to 0.
1075  // Both 'dx' and 'jack' generate a compare to 0 when compiling a
1076  // condition with a long, float or double comparison as input.
1077  if (!left->IsCompare() || !right->IsConstant() || right->AsIntConstant()->GetValue() != 0) {
1078    // Conversion is not possible.
1079    return;
1080  }
1081
1082  // Is the Compare only used for this purpose?
1083  if (!left->GetUses().HasOnlyOneUse()) {
1084    // Someone else also wants the result of the compare.
1085    return;
1086  }
1087
1088  if (!left->GetEnvUses().IsEmpty()) {
1089    // There is a reference to the compare result in an environment. Do we really need it?
1090    if (GetGraph()->IsDebuggable()) {
1091      return;
1092    }
1093
1094    // We have to ensure that there are no deopt points in the sequence.
1095    if (left->HasAnyEnvironmentUseBefore(condition)) {
1096      return;
1097    }
1098  }
1099
1100  // Clean up any environment uses from the HCompare, if any.
1101  left->RemoveEnvironmentUsers();
1102
1103  // We have decided to fold the HCompare into the HCondition. Transfer the information.
1104  condition->SetBias(left->AsCompare()->GetBias());
1105
1106  // Replace the operands of the HCondition.
1107  condition->ReplaceInput(left->InputAt(0), 0);
1108  condition->ReplaceInput(left->InputAt(1), 1);
1109
1110  // Remove the HCompare.
1111  left->GetBlock()->RemoveInstruction(left);
1112
1113  RecordSimplification();
1114}
1115
1116void InstructionSimplifierVisitor::VisitDiv(HDiv* instruction) {
1117  HConstant* input_cst = instruction->GetConstantRight();
1118  HInstruction* input_other = instruction->GetLeastConstantLeft();
1119  Primitive::Type type = instruction->GetType();
1120
1121  if ((input_cst != nullptr) && input_cst->IsOne()) {
1122    // Replace code looking like
1123    //    DIV dst, src, 1
1124    // with
1125    //    src
1126    instruction->ReplaceWith(input_other);
1127    instruction->GetBlock()->RemoveInstruction(instruction);
1128    return;
1129  }
1130
1131  if ((input_cst != nullptr) && input_cst->IsMinusOne()) {
1132    // Replace code looking like
1133    //    DIV dst, src, -1
1134    // with
1135    //    NEG dst, src
1136    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(
1137        instruction, new (GetGraph()->GetArena()) HNeg(type, input_other));
1138    RecordSimplification();
1139    return;
1140  }
1141
1142  if ((input_cst != nullptr) && Primitive::IsFloatingPointType(type)) {
1143    // Try replacing code looking like
1144    //    DIV dst, src, constant
1145    // with
1146    //    MUL dst, src, 1 / constant
1147    HConstant* reciprocal = nullptr;
1148    if (type == Primitive::Primitive::kPrimDouble) {
1149      double value = input_cst->AsDoubleConstant()->GetValue();
1150      if (CanDivideByReciprocalMultiplyDouble(bit_cast<int64_t, double>(value))) {
1151        reciprocal = GetGraph()->GetDoubleConstant(1.0 / value);
1152      }
1153    } else {
1154      DCHECK_EQ(type, Primitive::kPrimFloat);
1155      float value = input_cst->AsFloatConstant()->GetValue();
1156      if (CanDivideByReciprocalMultiplyFloat(bit_cast<int32_t, float>(value))) {
1157        reciprocal = GetGraph()->GetFloatConstant(1.0f / value);
1158      }
1159    }
1160
1161    if (reciprocal != nullptr) {
1162      instruction->GetBlock()->ReplaceAndRemoveInstructionWith(
1163          instruction, new (GetGraph()->GetArena()) HMul(type, input_other, reciprocal));
1164      RecordSimplification();
1165      return;
1166    }
1167  }
1168}
1169
1170void InstructionSimplifierVisitor::VisitMul(HMul* instruction) {
1171  HConstant* input_cst = instruction->GetConstantRight();
1172  HInstruction* input_other = instruction->GetLeastConstantLeft();
1173  Primitive::Type type = instruction->GetType();
1174  HBasicBlock* block = instruction->GetBlock();
1175  ArenaAllocator* allocator = GetGraph()->GetArena();
1176
1177  if (input_cst == nullptr) {
1178    return;
1179  }
1180
1181  if (input_cst->IsOne()) {
1182    // Replace code looking like
1183    //    MUL dst, src, 1
1184    // with
1185    //    src
1186    instruction->ReplaceWith(input_other);
1187    instruction->GetBlock()->RemoveInstruction(instruction);
1188    return;
1189  }
1190
1191  if (input_cst->IsMinusOne() &&
1192      (Primitive::IsFloatingPointType(type) || Primitive::IsIntOrLongType(type))) {
1193    // Replace code looking like
1194    //    MUL dst, src, -1
1195    // with
1196    //    NEG dst, src
1197    HNeg* neg = new (allocator) HNeg(type, input_other);
1198    block->ReplaceAndRemoveInstructionWith(instruction, neg);
1199    RecordSimplification();
1200    return;
1201  }
1202
1203  if (Primitive::IsFloatingPointType(type) &&
1204      ((input_cst->IsFloatConstant() && input_cst->AsFloatConstant()->GetValue() == 2.0f) ||
1205       (input_cst->IsDoubleConstant() && input_cst->AsDoubleConstant()->GetValue() == 2.0))) {
1206    // Replace code looking like
1207    //    FP_MUL dst, src, 2.0
1208    // with
1209    //    FP_ADD dst, src, src
1210    // The 'int' and 'long' cases are handled below.
1211    block->ReplaceAndRemoveInstructionWith(instruction,
1212                                           new (allocator) HAdd(type, input_other, input_other));
1213    RecordSimplification();
1214    return;
1215  }
1216
1217  if (Primitive::IsIntOrLongType(type)) {
1218    int64_t factor = Int64FromConstant(input_cst);
1219    // Even though constant propagation also takes care of the zero case, other
1220    // optimizations can lead to having a zero multiplication.
1221    if (factor == 0) {
1222      // Replace code looking like
1223      //    MUL dst, src, 0
1224      // with
1225      //    0
1226      instruction->ReplaceWith(input_cst);
1227      instruction->GetBlock()->RemoveInstruction(instruction);
1228    } else if (IsPowerOfTwo(factor)) {
1229      // Replace code looking like
1230      //    MUL dst, src, pow_of_2
1231      // with
1232      //    SHL dst, src, log2(pow_of_2)
1233      HIntConstant* shift = GetGraph()->GetIntConstant(WhichPowerOf2(factor));
1234      HShl* shl = new (allocator) HShl(type, input_other, shift);
1235      block->ReplaceAndRemoveInstructionWith(instruction, shl);
1236      RecordSimplification();
1237    } else if (IsPowerOfTwo(factor - 1)) {
1238      // Transform code looking like
1239      //    MUL dst, src, (2^n + 1)
1240      // into
1241      //    SHL tmp, src, n
1242      //    ADD dst, src, tmp
1243      HShl* shl = new (allocator) HShl(type,
1244                                       input_other,
1245                                       GetGraph()->GetIntConstant(WhichPowerOf2(factor - 1)));
1246      HAdd* add = new (allocator) HAdd(type, input_other, shl);
1247
1248      block->InsertInstructionBefore(shl, instruction);
1249      block->ReplaceAndRemoveInstructionWith(instruction, add);
1250      RecordSimplification();
1251    } else if (IsPowerOfTwo(factor + 1)) {
1252      // Transform code looking like
1253      //    MUL dst, src, (2^n - 1)
1254      // into
1255      //    SHL tmp, src, n
1256      //    SUB dst, tmp, src
1257      HShl* shl = new (allocator) HShl(type,
1258                                       input_other,
1259                                       GetGraph()->GetIntConstant(WhichPowerOf2(factor + 1)));
1260      HSub* sub = new (allocator) HSub(type, shl, input_other);
1261
1262      block->InsertInstructionBefore(shl, instruction);
1263      block->ReplaceAndRemoveInstructionWith(instruction, sub);
1264      RecordSimplification();
1265    }
1266  }
1267}
1268
1269void InstructionSimplifierVisitor::VisitNeg(HNeg* instruction) {
1270  HInstruction* input = instruction->GetInput();
1271  if (input->IsNeg()) {
1272    // Replace code looking like
1273    //    NEG tmp, src
1274    //    NEG dst, tmp
1275    // with
1276    //    src
1277    HNeg* previous_neg = input->AsNeg();
1278    instruction->ReplaceWith(previous_neg->GetInput());
1279    instruction->GetBlock()->RemoveInstruction(instruction);
1280    // We perform the optimization even if the input negation has environment
1281    // uses since it allows removing the current instruction. But we only delete
1282    // the input negation only if it is does not have any uses left.
1283    if (!previous_neg->HasUses()) {
1284      previous_neg->GetBlock()->RemoveInstruction(previous_neg);
1285    }
1286    RecordSimplification();
1287    return;
1288  }
1289
1290  if (input->IsSub() && input->HasOnlyOneNonEnvironmentUse() &&
1291      !Primitive::IsFloatingPointType(input->GetType())) {
1292    // Replace code looking like
1293    //    SUB tmp, a, b
1294    //    NEG dst, tmp
1295    // with
1296    //    SUB dst, b, a
1297    // We do not perform the optimization if the input subtraction has
1298    // environment uses or multiple non-environment uses as it could lead to
1299    // worse code. In particular, we do not want the live ranges of `a` and `b`
1300    // to be extended if we are not sure the initial 'SUB' instruction can be
1301    // removed.
1302    // We do not perform optimization for fp because we could lose the sign of zero.
1303    HSub* sub = input->AsSub();
1304    HSub* new_sub =
1305        new (GetGraph()->GetArena()) HSub(instruction->GetType(), sub->GetRight(), sub->GetLeft());
1306    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, new_sub);
1307    if (!sub->HasUses()) {
1308      sub->GetBlock()->RemoveInstruction(sub);
1309    }
1310    RecordSimplification();
1311  }
1312}
1313
1314void InstructionSimplifierVisitor::VisitNot(HNot* instruction) {
1315  HInstruction* input = instruction->GetInput();
1316  if (input->IsNot()) {
1317    // Replace code looking like
1318    //    NOT tmp, src
1319    //    NOT dst, tmp
1320    // with
1321    //    src
1322    // We perform the optimization even if the input negation has environment
1323    // uses since it allows removing the current instruction. But we only delete
1324    // the input negation only if it is does not have any uses left.
1325    HNot* previous_not = input->AsNot();
1326    instruction->ReplaceWith(previous_not->GetInput());
1327    instruction->GetBlock()->RemoveInstruction(instruction);
1328    if (!previous_not->HasUses()) {
1329      previous_not->GetBlock()->RemoveInstruction(previous_not);
1330    }
1331    RecordSimplification();
1332  }
1333}
1334
1335void InstructionSimplifierVisitor::VisitOr(HOr* instruction) {
1336  HConstant* input_cst = instruction->GetConstantRight();
1337  HInstruction* input_other = instruction->GetLeastConstantLeft();
1338
1339  if ((input_cst != nullptr) && input_cst->IsZero()) {
1340    // Replace code looking like
1341    //    OR dst, src, 0
1342    // with
1343    //    src
1344    instruction->ReplaceWith(input_other);
1345    instruction->GetBlock()->RemoveInstruction(instruction);
1346    return;
1347  }
1348
1349  // We assume that GVN has run before, so we only perform a pointer comparison.
1350  // If for some reason the values are equal but the pointers are different, we
1351  // are still correct and only miss an optimization opportunity.
1352  if (instruction->GetLeft() == instruction->GetRight()) {
1353    // Replace code looking like
1354    //    OR dst, src, src
1355    // with
1356    //    src
1357    instruction->ReplaceWith(instruction->GetLeft());
1358    instruction->GetBlock()->RemoveInstruction(instruction);
1359    return;
1360  }
1361
1362  if (TryDeMorganNegationFactoring(instruction)) return;
1363
1364  TryReplaceWithRotate(instruction);
1365}
1366
1367void InstructionSimplifierVisitor::VisitShl(HShl* instruction) {
1368  VisitShift(instruction);
1369}
1370
1371void InstructionSimplifierVisitor::VisitShr(HShr* instruction) {
1372  VisitShift(instruction);
1373}
1374
1375void InstructionSimplifierVisitor::VisitSub(HSub* instruction) {
1376  HConstant* input_cst = instruction->GetConstantRight();
1377  HInstruction* input_other = instruction->GetLeastConstantLeft();
1378
1379  Primitive::Type type = instruction->GetType();
1380  if (Primitive::IsFloatingPointType(type)) {
1381    return;
1382  }
1383
1384  if ((input_cst != nullptr) && input_cst->IsZero()) {
1385    // Replace code looking like
1386    //    SUB dst, src, 0
1387    // with
1388    //    src
1389    // Note that we cannot optimize `x - 0.0` to `x` for floating-point. When
1390    // `x` is `-0.0`, the former expression yields `0.0`, while the later
1391    // yields `-0.0`.
1392    instruction->ReplaceWith(input_other);
1393    instruction->GetBlock()->RemoveInstruction(instruction);
1394    return;
1395  }
1396
1397  HBasicBlock* block = instruction->GetBlock();
1398  ArenaAllocator* allocator = GetGraph()->GetArena();
1399
1400  HInstruction* left = instruction->GetLeft();
1401  HInstruction* right = instruction->GetRight();
1402  if (left->IsConstant()) {
1403    if (Int64FromConstant(left->AsConstant()) == 0) {
1404      // Replace code looking like
1405      //    SUB dst, 0, src
1406      // with
1407      //    NEG dst, src
1408      // Note that we cannot optimize `0.0 - x` to `-x` for floating-point. When
1409      // `x` is `0.0`, the former expression yields `0.0`, while the later
1410      // yields `-0.0`.
1411      HNeg* neg = new (allocator) HNeg(type, right);
1412      block->ReplaceAndRemoveInstructionWith(instruction, neg);
1413      RecordSimplification();
1414      return;
1415    }
1416  }
1417
1418  if (left->IsNeg() && right->IsNeg()) {
1419    if (TryMoveNegOnInputsAfterBinop(instruction)) {
1420      return;
1421    }
1422  }
1423
1424  if (right->IsNeg() && right->HasOnlyOneNonEnvironmentUse()) {
1425    // Replace code looking like
1426    //    NEG tmp, b
1427    //    SUB dst, a, tmp
1428    // with
1429    //    ADD dst, a, b
1430    HAdd* add = new(GetGraph()->GetArena()) HAdd(type, left, right->AsNeg()->GetInput());
1431    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, add);
1432    RecordSimplification();
1433    right->GetBlock()->RemoveInstruction(right);
1434    return;
1435  }
1436
1437  if (left->IsNeg() && left->HasOnlyOneNonEnvironmentUse()) {
1438    // Replace code looking like
1439    //    NEG tmp, a
1440    //    SUB dst, tmp, b
1441    // with
1442    //    ADD tmp, a, b
1443    //    NEG dst, tmp
1444    // The second version is not intrinsically better, but enables more
1445    // transformations.
1446    HAdd* add = new(GetGraph()->GetArena()) HAdd(type, left->AsNeg()->GetInput(), right);
1447    instruction->GetBlock()->InsertInstructionBefore(add, instruction);
1448    HNeg* neg = new (GetGraph()->GetArena()) HNeg(instruction->GetType(), add);
1449    instruction->GetBlock()->InsertInstructionBefore(neg, instruction);
1450    instruction->ReplaceWith(neg);
1451    instruction->GetBlock()->RemoveInstruction(instruction);
1452    RecordSimplification();
1453    left->GetBlock()->RemoveInstruction(left);
1454  }
1455}
1456
1457void InstructionSimplifierVisitor::VisitUShr(HUShr* instruction) {
1458  VisitShift(instruction);
1459}
1460
1461void InstructionSimplifierVisitor::VisitXor(HXor* instruction) {
1462  HConstant* input_cst = instruction->GetConstantRight();
1463  HInstruction* input_other = instruction->GetLeastConstantLeft();
1464
1465  if ((input_cst != nullptr) && input_cst->IsZero()) {
1466    // Replace code looking like
1467    //    XOR dst, src, 0
1468    // with
1469    //    src
1470    instruction->ReplaceWith(input_other);
1471    instruction->GetBlock()->RemoveInstruction(instruction);
1472    return;
1473  }
1474
1475  if ((input_cst != nullptr) && AreAllBitsSet(input_cst)) {
1476    // Replace code looking like
1477    //    XOR dst, src, 0xFFF...FF
1478    // with
1479    //    NOT dst, src
1480    HNot* bitwise_not = new (GetGraph()->GetArena()) HNot(instruction->GetType(), input_other);
1481    instruction->GetBlock()->ReplaceAndRemoveInstructionWith(instruction, bitwise_not);
1482    RecordSimplification();
1483    return;
1484  }
1485
1486  HInstruction* left = instruction->GetLeft();
1487  HInstruction* right = instruction->GetRight();
1488  if (((left->IsNot() && right->IsNot()) ||
1489       (left->IsBooleanNot() && right->IsBooleanNot())) &&
1490      left->HasOnlyOneNonEnvironmentUse() &&
1491      right->HasOnlyOneNonEnvironmentUse()) {
1492    // Replace code looking like
1493    //    NOT nota, a
1494    //    NOT notb, b
1495    //    XOR dst, nota, notb
1496    // with
1497    //    XOR dst, a, b
1498    instruction->ReplaceInput(left->InputAt(0), 0);
1499    instruction->ReplaceInput(right->InputAt(0), 1);
1500    left->GetBlock()->RemoveInstruction(left);
1501    right->GetBlock()->RemoveInstruction(right);
1502    RecordSimplification();
1503    return;
1504  }
1505
1506  TryReplaceWithRotate(instruction);
1507}
1508
1509void InstructionSimplifierVisitor::SimplifyStringEquals(HInvoke* instruction) {
1510  HInstruction* argument = instruction->InputAt(1);
1511  HInstruction* receiver = instruction->InputAt(0);
1512  if (receiver == argument) {
1513    // Because String.equals is an instance call, the receiver is
1514    // a null check if we don't know it's null. The argument however, will
1515    // be the actual object. So we cannot end up in a situation where both
1516    // are equal but could be null.
1517    DCHECK(CanEnsureNotNullAt(argument, instruction));
1518    instruction->ReplaceWith(GetGraph()->GetIntConstant(1));
1519    instruction->GetBlock()->RemoveInstruction(instruction);
1520  } else {
1521    StringEqualsOptimizations optimizations(instruction);
1522    if (CanEnsureNotNullAt(argument, instruction)) {
1523      optimizations.SetArgumentNotNull();
1524    }
1525    ScopedObjectAccess soa(Thread::Current());
1526    ReferenceTypeInfo argument_rti = argument->GetReferenceTypeInfo();
1527    if (argument_rti.IsValid() && argument_rti.IsStringClass()) {
1528      optimizations.SetArgumentIsString();
1529    }
1530  }
1531}
1532
1533void InstructionSimplifierVisitor::SimplifyRotate(HInvoke* invoke,
1534                                                  bool is_left,
1535                                                  Primitive::Type type) {
1536  DCHECK(invoke->IsInvokeStaticOrDirect());
1537  DCHECK_EQ(invoke->GetOriginalInvokeType(), InvokeType::kStatic);
1538  HInstruction* value = invoke->InputAt(0);
1539  HInstruction* distance = invoke->InputAt(1);
1540  // Replace the invoke with an HRor.
1541  if (is_left) {
1542    distance = new (GetGraph()->GetArena()) HNeg(distance->GetType(), distance);
1543    invoke->GetBlock()->InsertInstructionBefore(distance, invoke);
1544  }
1545  HRor* ror = new (GetGraph()->GetArena()) HRor(type, value, distance);
1546  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, ror);
1547  // Remove ClinitCheck and LoadClass, if possible.
1548  HInstruction* clinit = invoke->InputAt(invoke->InputCount() - 1);
1549  if (clinit->IsClinitCheck() && !clinit->HasUses()) {
1550    clinit->GetBlock()->RemoveInstruction(clinit);
1551    HInstruction* ldclass = clinit->InputAt(0);
1552    if (ldclass->IsLoadClass() && !ldclass->HasUses()) {
1553      ldclass->GetBlock()->RemoveInstruction(ldclass);
1554    }
1555  }
1556}
1557
1558static bool IsArrayLengthOf(HInstruction* potential_length, HInstruction* potential_array) {
1559  if (potential_length->IsArrayLength()) {
1560    return potential_length->InputAt(0) == potential_array;
1561  }
1562
1563  if (potential_array->IsNewArray()) {
1564    return potential_array->InputAt(0) == potential_length;
1565  }
1566
1567  return false;
1568}
1569
1570void InstructionSimplifierVisitor::SimplifySystemArrayCopy(HInvoke* instruction) {
1571  HInstruction* source = instruction->InputAt(0);
1572  HInstruction* destination = instruction->InputAt(2);
1573  HInstruction* count = instruction->InputAt(4);
1574  SystemArrayCopyOptimizations optimizations(instruction);
1575  if (CanEnsureNotNullAt(source, instruction)) {
1576    optimizations.SetSourceIsNotNull();
1577  }
1578  if (CanEnsureNotNullAt(destination, instruction)) {
1579    optimizations.SetDestinationIsNotNull();
1580  }
1581  if (destination == source) {
1582    optimizations.SetDestinationIsSource();
1583  }
1584
1585  if (IsArrayLengthOf(count, source)) {
1586    optimizations.SetCountIsSourceLength();
1587  }
1588
1589  if (IsArrayLengthOf(count, destination)) {
1590    optimizations.SetCountIsDestinationLength();
1591  }
1592
1593  {
1594    ScopedObjectAccess soa(Thread::Current());
1595    ReferenceTypeInfo destination_rti = destination->GetReferenceTypeInfo();
1596    if (destination_rti.IsValid()) {
1597      if (destination_rti.IsObjectArray()) {
1598        if (destination_rti.IsExact()) {
1599          optimizations.SetDoesNotNeedTypeCheck();
1600        }
1601        optimizations.SetDestinationIsTypedObjectArray();
1602      }
1603      if (destination_rti.IsPrimitiveArrayClass()) {
1604        optimizations.SetDestinationIsPrimitiveArray();
1605      } else if (destination_rti.IsNonPrimitiveArrayClass()) {
1606        optimizations.SetDestinationIsNonPrimitiveArray();
1607      }
1608    }
1609    ReferenceTypeInfo source_rti = source->GetReferenceTypeInfo();
1610    if (source_rti.IsValid()) {
1611      if (destination_rti.IsValid() && destination_rti.CanArrayHoldValuesOf(source_rti)) {
1612        optimizations.SetDoesNotNeedTypeCheck();
1613      }
1614      if (source_rti.IsPrimitiveArrayClass()) {
1615        optimizations.SetSourceIsPrimitiveArray();
1616      } else if (source_rti.IsNonPrimitiveArrayClass()) {
1617        optimizations.SetSourceIsNonPrimitiveArray();
1618      }
1619    }
1620  }
1621}
1622
1623void InstructionSimplifierVisitor::SimplifyCompare(HInvoke* invoke,
1624                                                   bool is_signum,
1625                                                   Primitive::Type type) {
1626  DCHECK(invoke->IsInvokeStaticOrDirect());
1627  uint32_t dex_pc = invoke->GetDexPc();
1628  HInstruction* left = invoke->InputAt(0);
1629  HInstruction* right;
1630  if (!is_signum) {
1631    right = invoke->InputAt(1);
1632  } else if (type == Primitive::kPrimLong) {
1633    right = GetGraph()->GetLongConstant(0);
1634  } else {
1635    right = GetGraph()->GetIntConstant(0);
1636  }
1637  HCompare* compare = new (GetGraph()->GetArena())
1638      HCompare(type, left, right, ComparisonBias::kNoBias, dex_pc);
1639  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, compare);
1640}
1641
1642void InstructionSimplifierVisitor::SimplifyIsNaN(HInvoke* invoke) {
1643  DCHECK(invoke->IsInvokeStaticOrDirect());
1644  uint32_t dex_pc = invoke->GetDexPc();
1645  // IsNaN(x) is the same as x != x.
1646  HInstruction* x = invoke->InputAt(0);
1647  HCondition* condition = new (GetGraph()->GetArena()) HNotEqual(x, x, dex_pc);
1648  condition->SetBias(ComparisonBias::kLtBias);
1649  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, condition);
1650}
1651
1652void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) {
1653  DCHECK(invoke->IsInvokeStaticOrDirect());
1654  uint32_t dex_pc = invoke->GetDexPc();
1655  HInstruction* x = invoke->InputAt(0);
1656  Primitive::Type type = x->GetType();
1657  // Set proper bit pattern for NaN and replace intrinsic with raw version.
1658  HInstruction* nan;
1659  if (type == Primitive::kPrimDouble) {
1660    nan = GetGraph()->GetLongConstant(0x7ff8000000000000L);
1661    invoke->SetIntrinsic(Intrinsics::kDoubleDoubleToRawLongBits,
1662                         kNeedsEnvironmentOrCache,
1663                         kNoSideEffects,
1664                         kNoThrow);
1665  } else {
1666    DCHECK_EQ(type, Primitive::kPrimFloat);
1667    nan = GetGraph()->GetIntConstant(0x7fc00000);
1668    invoke->SetIntrinsic(Intrinsics::kFloatFloatToRawIntBits,
1669                         kNeedsEnvironmentOrCache,
1670                         kNoSideEffects,
1671                         kNoThrow);
1672  }
1673  // Test IsNaN(x), which is the same as x != x.
1674  HCondition* condition = new (GetGraph()->GetArena()) HNotEqual(x, x, dex_pc);
1675  condition->SetBias(ComparisonBias::kLtBias);
1676  invoke->GetBlock()->InsertInstructionBefore(condition, invoke->GetNext());
1677  // Select between the two.
1678  HInstruction* select = new (GetGraph()->GetArena()) HSelect(condition, nan, invoke, dex_pc);
1679  invoke->GetBlock()->InsertInstructionBefore(select, condition->GetNext());
1680  invoke->ReplaceWithExceptInReplacementAtIndex(select, 0);  // false at index 0
1681}
1682
1683void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind) {
1684  uint32_t dex_pc = invoke->GetDexPc();
1685  HMemoryBarrier* mem_barrier = new (GetGraph()->GetArena()) HMemoryBarrier(barrier_kind, dex_pc);
1686  invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, mem_barrier);
1687}
1688
1689void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
1690  switch (instruction->GetIntrinsic()) {
1691    case Intrinsics::kStringEquals:
1692      SimplifyStringEquals(instruction);
1693      break;
1694    case Intrinsics::kSystemArrayCopy:
1695      SimplifySystemArrayCopy(instruction);
1696      break;
1697    case Intrinsics::kIntegerRotateRight:
1698      SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimInt);
1699      break;
1700    case Intrinsics::kLongRotateRight:
1701      SimplifyRotate(instruction, /* is_left */ false, Primitive::kPrimLong);
1702      break;
1703    case Intrinsics::kIntegerRotateLeft:
1704      SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimInt);
1705      break;
1706    case Intrinsics::kLongRotateLeft:
1707      SimplifyRotate(instruction, /* is_left */ true, Primitive::kPrimLong);
1708      break;
1709    case Intrinsics::kIntegerCompare:
1710      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimInt);
1711      break;
1712    case Intrinsics::kLongCompare:
1713      SimplifyCompare(instruction, /* is_signum */ false, Primitive::kPrimLong);
1714      break;
1715    case Intrinsics::kIntegerSignum:
1716      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimInt);
1717      break;
1718    case Intrinsics::kLongSignum:
1719      SimplifyCompare(instruction, /* is_signum */ true, Primitive::kPrimLong);
1720      break;
1721    case Intrinsics::kFloatIsNaN:
1722    case Intrinsics::kDoubleIsNaN:
1723      SimplifyIsNaN(instruction);
1724      break;
1725    case Intrinsics::kFloatFloatToIntBits:
1726    case Intrinsics::kDoubleDoubleToLongBits:
1727      SimplifyFP2Int(instruction);
1728      break;
1729    case Intrinsics::kUnsafeLoadFence:
1730      SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
1731      break;
1732    case Intrinsics::kUnsafeStoreFence:
1733      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyStore);
1734      break;
1735    case Intrinsics::kUnsafeFullFence:
1736      SimplifyMemBarrier(instruction, MemBarrierKind::kAnyAny);
1737      break;
1738    default:
1739      break;
1740  }
1741}
1742
1743void InstructionSimplifierVisitor::VisitDeoptimize(HDeoptimize* deoptimize) {
1744  HInstruction* cond = deoptimize->InputAt(0);
1745  if (cond->IsConstant()) {
1746    if (cond->AsIntConstant()->IsZero()) {
1747      // Never deopt: instruction can be removed.
1748      deoptimize->GetBlock()->RemoveInstruction(deoptimize);
1749    } else {
1750      // Always deopt.
1751    }
1752  }
1753}
1754
1755}  // namespace art
1756