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