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