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