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 "base/arena_containers.h"
     18 #include "bounds_check_elimination.h"
     19 #include "nodes.h"
     20 
     21 namespace art {
     22 
     23 class MonotonicValueRange;
     24 
     25 /**
     26  * A value bound is represented as a pair of value and constant,
     27  * e.g. array.length - 1.
     28  */
     29 class ValueBound : public ValueObject {
     30  public:
     31   ValueBound(HInstruction* instruction, int32_t constant) {
     32     if (instruction != nullptr && instruction->IsIntConstant()) {
     33       // Normalize ValueBound with constant instruction.
     34       int32_t instr_const = instruction->AsIntConstant()->GetValue();
     35       if (!WouldAddOverflowOrUnderflow(instr_const, constant)) {
     36         instruction_ = nullptr;
     37         constant_ = instr_const + constant;
     38         return;
     39       }
     40     }
     41     instruction_ = instruction;
     42     constant_ = constant;
     43   }
     44 
     45   // Return whether (left + right) overflows or underflows.
     46   static bool WouldAddOverflowOrUnderflow(int32_t left, int32_t right) {
     47     if (right == 0) {
     48       return false;
     49     }
     50     if ((right > 0) && (left <= INT_MAX - right)) {
     51       // No overflow.
     52       return false;
     53     }
     54     if ((right < 0) && (left >= INT_MIN - right)) {
     55       // No underflow.
     56       return false;
     57     }
     58     return true;
     59   }
     60 
     61   static bool IsAddOrSubAConstant(HInstruction* instruction,
     62                                   HInstruction** left_instruction,
     63                                   int* right_constant) {
     64     if (instruction->IsAdd() || instruction->IsSub()) {
     65       HBinaryOperation* bin_op = instruction->AsBinaryOperation();
     66       HInstruction* left = bin_op->GetLeft();
     67       HInstruction* right = bin_op->GetRight();
     68       if (right->IsIntConstant()) {
     69         *left_instruction = left;
     70         int32_t c = right->AsIntConstant()->GetValue();
     71         *right_constant = instruction->IsAdd() ? c : -c;
     72         return true;
     73       }
     74     }
     75     *left_instruction = nullptr;
     76     *right_constant = 0;
     77     return false;
     78   }
     79 
     80   // Try to detect useful value bound format from an instruction, e.g.
     81   // a constant or array length related value.
     82   static ValueBound DetectValueBoundFromValue(HInstruction* instruction, bool* found) {
     83     DCHECK(instruction != nullptr);
     84     if (instruction->IsIntConstant()) {
     85       *found = true;
     86       return ValueBound(nullptr, instruction->AsIntConstant()->GetValue());
     87     }
     88 
     89     if (instruction->IsArrayLength()) {
     90       *found = true;
     91       return ValueBound(instruction, 0);
     92     }
     93     // Try to detect (array.length + c) format.
     94     HInstruction *left;
     95     int32_t right;
     96     if (IsAddOrSubAConstant(instruction, &left, &right)) {
     97       if (left->IsArrayLength()) {
     98         *found = true;
     99         return ValueBound(left, right);
    100       }
    101     }
    102 
    103     // No useful bound detected.
    104     *found = false;
    105     return ValueBound::Max();
    106   }
    107 
    108   HInstruction* GetInstruction() const { return instruction_; }
    109   int32_t GetConstant() const { return constant_; }
    110 
    111   bool IsRelatedToArrayLength() const {
    112     // Some bounds are created with HNewArray* as the instruction instead
    113     // of HArrayLength*. They are treated the same.
    114     return (instruction_ != nullptr) &&
    115            (instruction_->IsArrayLength() || instruction_->IsNewArray());
    116   }
    117 
    118   bool IsConstant() const {
    119     return instruction_ == nullptr;
    120   }
    121 
    122   static ValueBound Min() { return ValueBound(nullptr, INT_MIN); }
    123   static ValueBound Max() { return ValueBound(nullptr, INT_MAX); }
    124 
    125   bool Equals(ValueBound bound) const {
    126     return instruction_ == bound.instruction_ && constant_ == bound.constant_;
    127   }
    128 
    129   static HInstruction* FromArrayLengthToArray(HInstruction* instruction) {
    130     DCHECK(instruction->IsArrayLength() || instruction->IsNewArray());
    131     if (instruction->IsArrayLength()) {
    132       HInstruction* input = instruction->InputAt(0);
    133       if (input->IsNullCheck()) {
    134         input = input->AsNullCheck()->InputAt(0);
    135       }
    136       return input;
    137     }
    138     return instruction;
    139   }
    140 
    141   static bool Equal(HInstruction* instruction1, HInstruction* instruction2) {
    142     if (instruction1 == instruction2) {
    143       return true;
    144     }
    145 
    146     if (instruction1 == nullptr || instruction2 == nullptr) {
    147       return false;
    148     }
    149 
    150     // Some bounds are created with HNewArray* as the instruction instead
    151     // of HArrayLength*. They are treated the same.
    152     // HArrayLength with the same array input are considered equal also.
    153     instruction1 = FromArrayLengthToArray(instruction1);
    154     instruction2 = FromArrayLengthToArray(instruction2);
    155     return instruction1 == instruction2;
    156   }
    157 
    158   // Returns if it's certain this->bound >= `bound`.
    159   bool GreaterThanOrEqualTo(ValueBound bound) const {
    160     if (Equal(instruction_, bound.instruction_)) {
    161       return constant_ >= bound.constant_;
    162     }
    163     // Not comparable. Just return false.
    164     return false;
    165   }
    166 
    167   // Returns if it's certain this->bound <= `bound`.
    168   bool LessThanOrEqualTo(ValueBound bound) const {
    169     if (Equal(instruction_, bound.instruction_)) {
    170       return constant_ <= bound.constant_;
    171     }
    172     // Not comparable. Just return false.
    173     return false;
    174   }
    175 
    176   // Try to narrow lower bound. Returns the greatest of the two if possible.
    177   // Pick one if they are not comparable.
    178   static ValueBound NarrowLowerBound(ValueBound bound1, ValueBound bound2) {
    179     if (bound1.GreaterThanOrEqualTo(bound2)) {
    180       return bound1;
    181     }
    182     if (bound2.GreaterThanOrEqualTo(bound1)) {
    183       return bound2;
    184     }
    185 
    186     // Not comparable. Just pick one. We may lose some info, but that's ok.
    187     // Favor constant as lower bound.
    188     return bound1.IsConstant() ? bound1 : bound2;
    189   }
    190 
    191   // Try to narrow upper bound. Returns the lowest of the two if possible.
    192   // Pick one if they are not comparable.
    193   static ValueBound NarrowUpperBound(ValueBound bound1, ValueBound bound2) {
    194     if (bound1.LessThanOrEqualTo(bound2)) {
    195       return bound1;
    196     }
    197     if (bound2.LessThanOrEqualTo(bound1)) {
    198       return bound2;
    199     }
    200 
    201     // Not comparable. Just pick one. We may lose some info, but that's ok.
    202     // Favor array length as upper bound.
    203     return bound1.IsRelatedToArrayLength() ? bound1 : bound2;
    204   }
    205 
    206   // Add a constant to a ValueBound.
    207   // `overflow` or `underflow` will return whether the resulting bound may
    208   // overflow or underflow an int.
    209   ValueBound Add(int32_t c, bool* overflow, bool* underflow) const {
    210     *overflow = *underflow = false;
    211     if (c == 0) {
    212       return *this;
    213     }
    214 
    215     int32_t new_constant;
    216     if (c > 0) {
    217       if (constant_ > INT_MAX - c) {
    218         *overflow = true;
    219         return Max();
    220       }
    221 
    222       new_constant = constant_ + c;
    223       // (array.length + non-positive-constant) won't overflow an int.
    224       if (IsConstant() || (IsRelatedToArrayLength() && new_constant <= 0)) {
    225         return ValueBound(instruction_, new_constant);
    226       }
    227       // Be conservative.
    228       *overflow = true;
    229       return Max();
    230     } else {
    231       if (constant_ < INT_MIN - c) {
    232         *underflow = true;
    233         return Min();
    234       }
    235 
    236       new_constant = constant_ + c;
    237       // Regardless of the value new_constant, (array.length+new_constant) will
    238       // never underflow since array.length is no less than 0.
    239       if (IsConstant() || IsRelatedToArrayLength()) {
    240         return ValueBound(instruction_, new_constant);
    241       }
    242       // Be conservative.
    243       *underflow = true;
    244       return Min();
    245     }
    246   }
    247 
    248  private:
    249   HInstruction* instruction_;
    250   int32_t constant_;
    251 };
    252 
    253 // Collect array access data for a loop.
    254 // TODO: make it work for multiple arrays inside the loop.
    255 class ArrayAccessInsideLoopFinder : public ValueObject {
    256  public:
    257   explicit ArrayAccessInsideLoopFinder(HInstruction* induction_variable)
    258       : induction_variable_(induction_variable),
    259         found_array_length_(nullptr),
    260         offset_low_(INT_MAX),
    261         offset_high_(INT_MIN) {
    262     Run();
    263   }
    264 
    265   HArrayLength* GetFoundArrayLength() const { return found_array_length_; }
    266   bool HasFoundArrayLength() const { return found_array_length_ != nullptr; }
    267   int32_t GetOffsetLow() const { return offset_low_; }
    268   int32_t GetOffsetHigh() const { return offset_high_; }
    269 
    270   // Returns if `block` that is in loop_info may exit the loop, unless it's
    271   // the loop header for loop_info.
    272   static bool EarlyExit(HBasicBlock* block, HLoopInformation* loop_info) {
    273     DCHECK(loop_info->Contains(*block));
    274     if (block == loop_info->GetHeader()) {
    275       // Loop header of loop_info. Exiting loop is normal.
    276       return false;
    277     }
    278     const GrowableArray<HBasicBlock*>& successors = block->GetSuccessors();
    279     for (size_t i = 0; i < successors.Size(); i++) {
    280       if (!loop_info->Contains(*successors.Get(i))) {
    281         // One of the successors exits the loop.
    282         return true;
    283       }
    284     }
    285     return false;
    286   }
    287 
    288   static bool DominatesAllBackEdges(HBasicBlock* block, HLoopInformation* loop_info) {
    289     for (size_t i = 0, e = loop_info->GetBackEdges().Size(); i < e; ++i) {
    290       HBasicBlock* back_edge = loop_info->GetBackEdges().Get(i);
    291       if (!block->Dominates(back_edge)) {
    292         return false;
    293       }
    294     }
    295     return true;
    296   }
    297 
    298   void Run() {
    299     HLoopInformation* loop_info = induction_variable_->GetBlock()->GetLoopInformation();
    300     HBlocksInLoopReversePostOrderIterator it_loop(*loop_info);
    301     HBasicBlock* block = it_loop.Current();
    302     DCHECK(block == induction_variable_->GetBlock());
    303     // Skip loop header. Since narrowed value range of a MonotonicValueRange only
    304     // applies to the loop body (after the test at the end of the loop header).
    305     it_loop.Advance();
    306     for (; !it_loop.Done(); it_loop.Advance()) {
    307       block = it_loop.Current();
    308       DCHECK(block->IsInLoop());
    309       if (!DominatesAllBackEdges(block, loop_info)) {
    310         // In order not to trigger deoptimization unnecessarily, make sure
    311         // that all array accesses collected are really executed in the loop.
    312         // For array accesses in a branch inside the loop, don't collect the
    313         // access. The bounds check in that branch might not be eliminated.
    314         continue;
    315       }
    316       if (EarlyExit(block, loop_info)) {
    317         // If the loop body can exit loop (like break, return, etc.), it's not guaranteed
    318         // that the loop will loop through the full monotonic value range from
    319         // initial_ to end_. So adding deoptimization might be too aggressive and can
    320         // trigger deoptimization unnecessarily even if the loop won't actually throw
    321         // AIOOBE.
    322         found_array_length_ = nullptr;
    323         return;
    324       }
    325       for (HInstruction* instruction = block->GetFirstInstruction();
    326            instruction != nullptr;
    327            instruction = instruction->GetNext()) {
    328         if (!instruction->IsBoundsCheck()) {
    329           continue;
    330         }
    331 
    332         HInstruction* length_value = instruction->InputAt(1);
    333         if (length_value->IsIntConstant()) {
    334           // TODO: may optimize for constant case.
    335           continue;
    336         }
    337 
    338         if (length_value->IsPhi()) {
    339           // When adding deoptimizations in outer loops, we might create
    340           // a phi for the array length, and update all uses of the
    341           // length in the loop to that phi. Therefore, inner loops having
    342           // bounds checks on the same array will use that phi.
    343           // TODO: handle these cases.
    344           continue;
    345         }
    346 
    347         DCHECK(length_value->IsArrayLength());
    348         HArrayLength* array_length = length_value->AsArrayLength();
    349 
    350         HInstruction* array = array_length->InputAt(0);
    351         if (array->IsNullCheck()) {
    352           array = array->AsNullCheck()->InputAt(0);
    353         }
    354         if (loop_info->Contains(*array->GetBlock())) {
    355           // Array is defined inside the loop. Skip.
    356           continue;
    357         }
    358 
    359         if (found_array_length_ != nullptr && found_array_length_ != array_length) {
    360           // There is already access for another array recorded for the loop.
    361           // TODO: handle multiple arrays.
    362           continue;
    363         }
    364 
    365         HInstruction* index = instruction->AsBoundsCheck()->InputAt(0);
    366         HInstruction* left = index;
    367         int32_t right = 0;
    368         if (left == induction_variable_ ||
    369             (ValueBound::IsAddOrSubAConstant(index, &left, &right) &&
    370              left == induction_variable_)) {
    371           // For patterns like array[i] or array[i + 2].
    372           if (right < offset_low_) {
    373             offset_low_ = right;
    374           }
    375           if (right > offset_high_) {
    376             offset_high_ = right;
    377           }
    378         } else {
    379           // Access not in induction_variable/(induction_variable_ + constant)
    380           // format. Skip.
    381           continue;
    382         }
    383         // Record this array.
    384         found_array_length_ = array_length;
    385       }
    386     }
    387   }
    388 
    389  private:
    390   // The instruction that corresponds to a MonotonicValueRange.
    391   HInstruction* induction_variable_;
    392 
    393   // The array length of the array that's accessed inside the loop body.
    394   HArrayLength* found_array_length_;
    395 
    396   // The lowest and highest constant offsets relative to induction variable
    397   // instruction_ in all array accesses.
    398   // If array access are: array[i-1], array[i], array[i+1],
    399   // offset_low_ is -1 and offset_high is 1.
    400   int32_t offset_low_;
    401   int32_t offset_high_;
    402 
    403   DISALLOW_COPY_AND_ASSIGN(ArrayAccessInsideLoopFinder);
    404 };
    405 
    406 /**
    407  * Represent a range of lower bound and upper bound, both being inclusive.
    408  * Currently a ValueRange may be generated as a result of the following:
    409  * comparisons related to array bounds, array bounds check, add/sub on top
    410  * of an existing value range, NewArray or a loop phi corresponding to an
    411  * incrementing/decrementing array index (MonotonicValueRange).
    412  */
    413 class ValueRange : public ArenaObject<kArenaAllocMisc> {
    414  public:
    415   ValueRange(ArenaAllocator* allocator, ValueBound lower, ValueBound upper)
    416       : allocator_(allocator), lower_(lower), upper_(upper) {}
    417 
    418   virtual ~ValueRange() {}
    419 
    420   virtual MonotonicValueRange* AsMonotonicValueRange() { return nullptr; }
    421   bool IsMonotonicValueRange() {
    422     return AsMonotonicValueRange() != nullptr;
    423   }
    424 
    425   ArenaAllocator* GetAllocator() const { return allocator_; }
    426   ValueBound GetLower() const { return lower_; }
    427   ValueBound GetUpper() const { return upper_; }
    428 
    429   bool IsConstantValueRange() { return lower_.IsConstant() && upper_.IsConstant(); }
    430 
    431   // If it's certain that this value range fits in other_range.
    432   virtual bool FitsIn(ValueRange* other_range) const {
    433     if (other_range == nullptr) {
    434       return true;
    435     }
    436     DCHECK(!other_range->IsMonotonicValueRange());
    437     return lower_.GreaterThanOrEqualTo(other_range->lower_) &&
    438            upper_.LessThanOrEqualTo(other_range->upper_);
    439   }
    440 
    441   // Returns the intersection of this and range.
    442   // If it's not possible to do intersection because some
    443   // bounds are not comparable, it's ok to pick either bound.
    444   virtual ValueRange* Narrow(ValueRange* range) {
    445     if (range == nullptr) {
    446       return this;
    447     }
    448 
    449     if (range->IsMonotonicValueRange()) {
    450       return this;
    451     }
    452 
    453     return new (allocator_) ValueRange(
    454         allocator_,
    455         ValueBound::NarrowLowerBound(lower_, range->lower_),
    456         ValueBound::NarrowUpperBound(upper_, range->upper_));
    457   }
    458 
    459   // Shift a range by a constant.
    460   ValueRange* Add(int32_t constant) const {
    461     bool overflow, underflow;
    462     ValueBound lower = lower_.Add(constant, &overflow, &underflow);
    463     if (underflow) {
    464       // Lower bound underflow will wrap around to positive values
    465       // and invalidate the upper bound.
    466       return nullptr;
    467     }
    468     ValueBound upper = upper_.Add(constant, &overflow, &underflow);
    469     if (overflow) {
    470       // Upper bound overflow will wrap around to negative values
    471       // and invalidate the lower bound.
    472       return nullptr;
    473     }
    474     return new (allocator_) ValueRange(allocator_, lower, upper);
    475   }
    476 
    477  private:
    478   ArenaAllocator* const allocator_;
    479   const ValueBound lower_;  // inclusive
    480   const ValueBound upper_;  // inclusive
    481 
    482   DISALLOW_COPY_AND_ASSIGN(ValueRange);
    483 };
    484 
    485 /**
    486  * A monotonically incrementing/decrementing value range, e.g.
    487  * the variable i in "for (int i=0; i<array.length; i++)".
    488  * Special care needs to be taken to account for overflow/underflow
    489  * of such value ranges.
    490  */
    491 class MonotonicValueRange : public ValueRange {
    492  public:
    493   MonotonicValueRange(ArenaAllocator* allocator,
    494                       HPhi* induction_variable,
    495                       HInstruction* initial,
    496                       int32_t increment,
    497                       ValueBound bound)
    498       // To be conservative, give it full range [INT_MIN, INT_MAX] in case it's
    499       // used as a regular value range, due to possible overflow/underflow.
    500       : ValueRange(allocator, ValueBound::Min(), ValueBound::Max()),
    501         induction_variable_(induction_variable),
    502         initial_(initial),
    503         end_(nullptr),
    504         inclusive_(false),
    505         increment_(increment),
    506         bound_(bound) {}
    507 
    508   virtual ~MonotonicValueRange() {}
    509 
    510   HInstruction* GetInductionVariable() const { return induction_variable_; }
    511   int32_t GetIncrement() const { return increment_; }
    512   ValueBound GetBound() const { return bound_; }
    513   void SetEnd(HInstruction* end) { end_ = end; }
    514   void SetInclusive(bool inclusive) { inclusive_ = inclusive; }
    515   HBasicBlock* GetLoopHeader() const {
    516     DCHECK(induction_variable_->GetBlock()->IsLoopHeader());
    517     return induction_variable_->GetBlock();
    518   }
    519 
    520   MonotonicValueRange* AsMonotonicValueRange() OVERRIDE { return this; }
    521 
    522   HBasicBlock* GetLoopHeaderSuccesorInLoop() {
    523     HBasicBlock* header = GetLoopHeader();
    524     HInstruction* instruction = header->GetLastInstruction();
    525     DCHECK(instruction->IsIf());
    526     HIf* h_if = instruction->AsIf();
    527     HLoopInformation* loop_info = header->GetLoopInformation();
    528     bool true_successor_in_loop = loop_info->Contains(*h_if->IfTrueSuccessor());
    529     bool false_successor_in_loop = loop_info->Contains(*h_if->IfFalseSuccessor());
    530 
    531     // Just in case it's some strange loop structure.
    532     if (true_successor_in_loop && false_successor_in_loop) {
    533       return nullptr;
    534     }
    535     DCHECK(true_successor_in_loop || false_successor_in_loop);
    536     return false_successor_in_loop ? h_if->IfFalseSuccessor() : h_if->IfTrueSuccessor();
    537   }
    538 
    539   // If it's certain that this value range fits in other_range.
    540   bool FitsIn(ValueRange* other_range) const OVERRIDE {
    541     if (other_range == nullptr) {
    542       return true;
    543     }
    544     DCHECK(!other_range->IsMonotonicValueRange());
    545     return false;
    546   }
    547 
    548   // Try to narrow this MonotonicValueRange given another range.
    549   // Ideally it will return a normal ValueRange. But due to
    550   // possible overflow/underflow, that may not be possible.
    551   ValueRange* Narrow(ValueRange* range) OVERRIDE {
    552     if (range == nullptr) {
    553       return this;
    554     }
    555     DCHECK(!range->IsMonotonicValueRange());
    556 
    557     if (increment_ > 0) {
    558       // Monotonically increasing.
    559       ValueBound lower = ValueBound::NarrowLowerBound(bound_, range->GetLower());
    560       if (!lower.IsConstant() || lower.GetConstant() == INT_MIN) {
    561         // Lower bound isn't useful. Leave it to deoptimization.
    562         return this;
    563       }
    564 
    565       // We currently conservatively assume max array length is INT_MAX. If we can
    566       // make assumptions about the max array length, e.g. due to the max heap size,
    567       // divided by the element size (such as 4 bytes for each integer array), we can
    568       // lower this number and rule out some possible overflows.
    569       int32_t max_array_len = INT_MAX;
    570 
    571       // max possible integer value of range's upper value.
    572       int32_t upper = INT_MAX;
    573       // Try to lower upper.
    574       ValueBound upper_bound = range->GetUpper();
    575       if (upper_bound.IsConstant()) {
    576         upper = upper_bound.GetConstant();
    577       } else if (upper_bound.IsRelatedToArrayLength() && upper_bound.GetConstant() <= 0) {
    578         // Normal case. e.g. <= array.length - 1.
    579         upper = max_array_len + upper_bound.GetConstant();
    580       }
    581 
    582       // If we can prove for the last number in sequence of initial_,
    583       // initial_ + increment_, initial_ + 2 x increment_, ...
    584       // that's <= upper, (last_num_in_sequence + increment_) doesn't trigger overflow,
    585       // then this MonoticValueRange is narrowed to a normal value range.
    586 
    587       // Be conservative first, assume last number in the sequence hits upper.
    588       int32_t last_num_in_sequence = upper;
    589       if (initial_->IsIntConstant()) {
    590         int32_t initial_constant = initial_->AsIntConstant()->GetValue();
    591         if (upper <= initial_constant) {
    592           last_num_in_sequence = upper;
    593         } else {
    594           // Cast to int64_t for the substraction part to avoid int32_t overflow.
    595           last_num_in_sequence = initial_constant +
    596               ((int64_t)upper - (int64_t)initial_constant) / increment_ * increment_;
    597         }
    598       }
    599       if (last_num_in_sequence <= INT_MAX - increment_) {
    600         // No overflow. The sequence will be stopped by the upper bound test as expected.
    601         return new (GetAllocator()) ValueRange(GetAllocator(), lower, range->GetUpper());
    602       }
    603 
    604       // There might be overflow. Give up narrowing.
    605       return this;
    606     } else {
    607       DCHECK_NE(increment_, 0);
    608       // Monotonically decreasing.
    609       ValueBound upper = ValueBound::NarrowUpperBound(bound_, range->GetUpper());
    610       if ((!upper.IsConstant() || upper.GetConstant() == INT_MAX) &&
    611           !upper.IsRelatedToArrayLength()) {
    612         // Upper bound isn't useful. Leave it to deoptimization.
    613         return this;
    614       }
    615 
    616       // Need to take care of underflow. Try to prove underflow won't happen
    617       // for common cases.
    618       if (range->GetLower().IsConstant()) {
    619         int32_t constant = range->GetLower().GetConstant();
    620         if (constant >= INT_MIN - increment_) {
    621           return new (GetAllocator()) ValueRange(GetAllocator(), range->GetLower(), upper);
    622         }
    623       }
    624 
    625       // For non-constant lower bound, just assume might be underflow. Give up narrowing.
    626       return this;
    627     }
    628   }
    629 
    630   // Try to add HDeoptimize's in the loop pre-header first to narrow this range.
    631   // For example, this loop:
    632   //
    633   //   for (int i = start; i < end; i++) {
    634   //     array[i - 1] = array[i] + array[i + 1];
    635   //   }
    636   //
    637   // will be transformed to:
    638   //
    639   //   int array_length_in_loop_body_if_needed;
    640   //   if (start >= end) {
    641   //     array_length_in_loop_body_if_needed = 0;
    642   //   } else {
    643   //     if (start < 1) deoptimize();
    644   //     if (array == null) deoptimize();
    645   //     array_length = array.length;
    646   //     if (end > array_length - 1) deoptimize;
    647   //     array_length_in_loop_body_if_needed = array_length;
    648   //   }
    649   //   for (int i = start; i < end; i++) {
    650   //     // No more null check and bounds check.
    651   //     // array.length value is replaced with array_length_in_loop_body_if_needed
    652   //     // in the loop body.
    653   //     array[i - 1] = array[i] + array[i + 1];
    654   //   }
    655   //
    656   // We basically first go through the loop body and find those array accesses whose
    657   // index is at a constant offset from the induction variable ('i' in the above example),
    658   // and update offset_low and offset_high along the way. We then add the following
    659   // deoptimizations in the loop pre-header (suppose end is not inclusive).
    660   //   if (start < -offset_low) deoptimize();
    661   //   if (end >= array.length - offset_high) deoptimize();
    662   // It might be necessary to first hoist array.length (and the null check on it) out of
    663   // the loop with another deoptimization.
    664   //
    665   // In order not to trigger deoptimization unnecessarily, we want to make a strong
    666   // guarantee that no deoptimization is triggered if the loop body itself doesn't
    667   // throw AIOOBE. (It's the same as saying if deoptimization is triggered, the loop
    668   // body must throw AIOOBE).
    669   // This is achieved by the following:
    670   // 1) We only process loops that iterate through the full monotonic range from
    671   //    initial_ to end_. We do the following checks to make sure that's the case:
    672   //    a) The loop doesn't have early exit (via break, return, etc.)
    673   //    b) The increment_ is 1/-1. An increment of 2, for example, may skip end_.
    674   // 2) We only collect array accesses of blocks in the loop body that dominate
    675   //    all loop back edges, these array accesses are guaranteed to happen
    676   //    at each loop iteration.
    677   // With 1) and 2), if the loop body doesn't throw AIOOBE, collected array accesses
    678   // when the induction variable is at initial_ and end_ must be in a legal range.
    679   // Since the added deoptimizations are basically checking the induction variable
    680   // at initial_ and end_ values, no deoptimization will be triggered either.
    681   //
    682   // A special case is the loop body isn't entered at all. In that case, we may still
    683   // add deoptimization due to the analysis described above. In order not to trigger
    684   // deoptimization, we do a test between initial_ and end_ first and skip over
    685   // the added deoptimization.
    686   ValueRange* NarrowWithDeoptimization() {
    687     if (increment_ != 1 && increment_ != -1) {
    688       // In order not to trigger deoptimization unnecessarily, we want to
    689       // make sure the loop iterates through the full range from initial_ to
    690       // end_ so that boundaries are covered by the loop. An increment of 2,
    691       // for example, may skip end_.
    692       return this;
    693     }
    694 
    695     if (end_ == nullptr) {
    696       // No full info to add deoptimization.
    697       return this;
    698     }
    699 
    700     HBasicBlock* header = induction_variable_->GetBlock();
    701     DCHECK(header->IsLoopHeader());
    702     HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
    703     if (!initial_->GetBlock()->Dominates(pre_header) ||
    704         !end_->GetBlock()->Dominates(pre_header)) {
    705       // Can't add a check in loop pre-header if the value isn't available there.
    706       return this;
    707     }
    708 
    709     ArrayAccessInsideLoopFinder finder(induction_variable_);
    710 
    711     if (!finder.HasFoundArrayLength()) {
    712       // No array access was found inside the loop that can benefit
    713       // from deoptimization.
    714       return this;
    715     }
    716 
    717     if (!AddDeoptimization(finder)) {
    718       return this;
    719     }
    720 
    721     // After added deoptimizations, induction variable fits in
    722     // [-offset_low, array.length-1-offset_high], adjusted with collected offsets.
    723     ValueBound lower = ValueBound(0, -finder.GetOffsetLow());
    724     ValueBound upper = ValueBound(finder.GetFoundArrayLength(), -1 - finder.GetOffsetHigh());
    725     // We've narrowed the range after added deoptimizations.
    726     return new (GetAllocator()) ValueRange(GetAllocator(), lower, upper);
    727   }
    728 
    729   // Returns true if adding a (constant >= value) check for deoptimization
    730   // is allowed and will benefit compiled code.
    731   bool CanAddDeoptimizationConstant(HInstruction* value, int32_t constant, bool* is_proven) {
    732     *is_proven = false;
    733     HBasicBlock* header = induction_variable_->GetBlock();
    734     DCHECK(header->IsLoopHeader());
    735     HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
    736     DCHECK(value->GetBlock()->Dominates(pre_header));
    737 
    738     // See if we can prove the relationship first.
    739     if (value->IsIntConstant()) {
    740       if (value->AsIntConstant()->GetValue() >= constant) {
    741         // Already true.
    742         *is_proven = true;
    743         return true;
    744       } else {
    745         // May throw exception. Don't add deoptimization.
    746         // Keep bounds checks in the loops.
    747         return false;
    748       }
    749     }
    750     // Can benefit from deoptimization.
    751     return true;
    752   }
    753 
    754   // Try to filter out cases that the loop entry test will never be true.
    755   bool LoopEntryTestUseful() {
    756     if (initial_->IsIntConstant() && end_->IsIntConstant()) {
    757       int32_t initial_val = initial_->AsIntConstant()->GetValue();
    758       int32_t end_val = end_->AsIntConstant()->GetValue();
    759       if (increment_ == 1) {
    760         if (inclusive_) {
    761           return initial_val > end_val;
    762         } else {
    763           return initial_val >= end_val;
    764         }
    765       } else {
    766         DCHECK_EQ(increment_, -1);
    767         if (inclusive_) {
    768           return initial_val < end_val;
    769         } else {
    770           return initial_val <= end_val;
    771         }
    772       }
    773     }
    774     return true;
    775   }
    776 
    777   // Returns the block for adding deoptimization.
    778   HBasicBlock* TransformLoopForDeoptimizationIfNeeded() {
    779     HBasicBlock* header = induction_variable_->GetBlock();
    780     DCHECK(header->IsLoopHeader());
    781     HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
    782     // Deoptimization is only added when both initial_ and end_ are defined
    783     // before the loop.
    784     DCHECK(initial_->GetBlock()->Dominates(pre_header));
    785     DCHECK(end_->GetBlock()->Dominates(pre_header));
    786 
    787     // If it can be proven the loop body is definitely entered (unless exception
    788     // is thrown in the loop header for which triggering deoptimization is fine),
    789     // there is no need for tranforming the loop. In that case, deoptimization
    790     // will just be added in the loop pre-header.
    791     if (!LoopEntryTestUseful()) {
    792       return pre_header;
    793     }
    794 
    795     HGraph* graph = header->GetGraph();
    796     graph->TransformLoopHeaderForBCE(header);
    797     HBasicBlock* new_pre_header = header->GetDominator();
    798     DCHECK(new_pre_header == header->GetLoopInformation()->GetPreHeader());
    799     HBasicBlock* if_block = new_pre_header->GetDominator();
    800     HBasicBlock* dummy_block = if_block->GetSuccessors().Get(0);  // True successor.
    801     HBasicBlock* deopt_block = if_block->GetSuccessors().Get(1);  // False successor.
    802 
    803     dummy_block->AddInstruction(new (graph->GetArena()) HGoto());
    804     deopt_block->AddInstruction(new (graph->GetArena()) HGoto());
    805     new_pre_header->AddInstruction(new (graph->GetArena()) HGoto());
    806     return deopt_block;
    807   }
    808 
    809   // Adds a test between initial_ and end_ to see if the loop body is entered.
    810   // If the loop body isn't entered at all, it jumps to the loop pre-header (after
    811   // transformation) to avoid any deoptimization.
    812   void AddLoopBodyEntryTest() {
    813     HBasicBlock* header = induction_variable_->GetBlock();
    814     DCHECK(header->IsLoopHeader());
    815     HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
    816     HBasicBlock* if_block = pre_header->GetDominator();
    817     HGraph* graph = header->GetGraph();
    818 
    819     HCondition* cond;
    820     if (increment_ == 1) {
    821       if (inclusive_) {
    822         cond = new (graph->GetArena()) HGreaterThan(initial_, end_);
    823       } else {
    824         cond = new (graph->GetArena()) HGreaterThanOrEqual(initial_, end_);
    825       }
    826     } else {
    827       DCHECK_EQ(increment_, -1);
    828       if (inclusive_) {
    829         cond = new (graph->GetArena()) HLessThan(initial_, end_);
    830       } else {
    831         cond = new (graph->GetArena()) HLessThanOrEqual(initial_, end_);
    832       }
    833     }
    834     HIf* h_if = new (graph->GetArena()) HIf(cond);
    835     if_block->AddInstruction(cond);
    836     if_block->AddInstruction(h_if);
    837   }
    838 
    839   // Adds a check that (value >= constant), and HDeoptimize otherwise.
    840   void AddDeoptimizationConstant(HInstruction* value,
    841                                  int32_t constant,
    842                                  HBasicBlock* deopt_block,
    843                                  bool loop_entry_test_block_added) {
    844     HBasicBlock* header = induction_variable_->GetBlock();
    845     DCHECK(header->IsLoopHeader());
    846     HBasicBlock* pre_header = header->GetDominator();
    847     if (loop_entry_test_block_added) {
    848       DCHECK(deopt_block->GetSuccessors().Get(0) == pre_header);
    849     } else {
    850       DCHECK(deopt_block == pre_header);
    851     }
    852     HGraph* graph = header->GetGraph();
    853     HSuspendCheck* suspend_check = header->GetLoopInformation()->GetSuspendCheck();
    854     if (loop_entry_test_block_added) {
    855       DCHECK_EQ(deopt_block, header->GetDominator()->GetDominator()->GetSuccessors().Get(1));
    856     }
    857 
    858     HIntConstant* const_instr = graph->GetIntConstant(constant);
    859     HCondition* cond = new (graph->GetArena()) HLessThan(value, const_instr);
    860     HDeoptimize* deoptimize = new (graph->GetArena())
    861         HDeoptimize(cond, suspend_check->GetDexPc());
    862     deopt_block->InsertInstructionBefore(cond, deopt_block->GetLastInstruction());
    863     deopt_block->InsertInstructionBefore(deoptimize, deopt_block->GetLastInstruction());
    864     deoptimize->CopyEnvironmentFromWithLoopPhiAdjustment(
    865         suspend_check->GetEnvironment(), header);
    866   }
    867 
    868   // Returns true if adding a (value <= array_length + offset) check for deoptimization
    869   // is allowed and will benefit compiled code.
    870   bool CanAddDeoptimizationArrayLength(HInstruction* value,
    871                                        HArrayLength* array_length,
    872                                        int32_t offset,
    873                                        bool* is_proven) {
    874     *is_proven = false;
    875     HBasicBlock* header = induction_variable_->GetBlock();
    876     DCHECK(header->IsLoopHeader());
    877     HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
    878     DCHECK(value->GetBlock()->Dominates(pre_header));
    879 
    880     if (array_length->GetBlock() == header) {
    881       // array_length_in_loop_body_if_needed only has correct value when the loop
    882       // body is entered. We bail out in this case. Usually array_length defined
    883       // in the loop header is already hoisted by licm.
    884       return false;
    885     } else {
    886       // array_length is defined either before the loop header already, or in
    887       // the loop body since it's used in the loop body. If it's defined in the loop body,
    888       // a phi array_length_in_loop_body_if_needed is used to replace it. In that case,
    889       // all the uses of array_length must be dominated by its definition in the loop
    890       // body. array_length_in_loop_body_if_needed is guaranteed to be the same as
    891       // array_length once the loop body is entered so all the uses of the phi will
    892       // use the correct value.
    893     }
    894 
    895     if (offset > 0) {
    896       // There might be overflow issue.
    897       // TODO: handle this, possibly with some distance relationship between
    898       // offset_low and offset_high, or using another deoptimization to make
    899       // sure (array_length + offset) doesn't overflow.
    900       return false;
    901     }
    902 
    903     // See if we can prove the relationship first.
    904     if (value == array_length) {
    905       if (offset >= 0) {
    906         // Already true.
    907         *is_proven = true;
    908         return true;
    909       } else {
    910         // May throw exception. Don't add deoptimization.
    911         // Keep bounds checks in the loops.
    912         return false;
    913       }
    914     }
    915     // Can benefit from deoptimization.
    916     return true;
    917   }
    918 
    919   // Adds a check that (value <= array_length + offset), and HDeoptimize otherwise.
    920   void AddDeoptimizationArrayLength(HInstruction* value,
    921                                     HArrayLength* array_length,
    922                                     int32_t offset,
    923                                     HBasicBlock* deopt_block,
    924                                     bool loop_entry_test_block_added) {
    925     HBasicBlock* header = induction_variable_->GetBlock();
    926     DCHECK(header->IsLoopHeader());
    927     HBasicBlock* pre_header = header->GetDominator();
    928     if (loop_entry_test_block_added) {
    929       DCHECK(deopt_block->GetSuccessors().Get(0) == pre_header);
    930     } else {
    931       DCHECK(deopt_block == pre_header);
    932     }
    933     HGraph* graph = header->GetGraph();
    934     HSuspendCheck* suspend_check = header->GetLoopInformation()->GetSuspendCheck();
    935 
    936     // We may need to hoist null-check and array_length out of loop first.
    937     if (!array_length->GetBlock()->Dominates(deopt_block)) {
    938       // array_length must be defined in the loop body.
    939       DCHECK(header->GetLoopInformation()->Contains(*array_length->GetBlock()));
    940       DCHECK(array_length->GetBlock() != header);
    941 
    942       HInstruction* array = array_length->InputAt(0);
    943       HNullCheck* null_check = array->AsNullCheck();
    944       if (null_check != nullptr) {
    945         array = null_check->InputAt(0);
    946       }
    947       // We've already made sure the array is defined before the loop when collecting
    948       // array accesses for the loop.
    949       DCHECK(array->GetBlock()->Dominates(deopt_block));
    950       if (null_check != nullptr && !null_check->GetBlock()->Dominates(deopt_block)) {
    951         // Hoist null check out of loop with a deoptimization.
    952         HNullConstant* null_constant = graph->GetNullConstant();
    953         HCondition* null_check_cond = new (graph->GetArena()) HEqual(array, null_constant);
    954         // TODO: for one dex_pc, share the same deoptimization slow path.
    955         HDeoptimize* null_check_deoptimize = new (graph->GetArena())
    956             HDeoptimize(null_check_cond, suspend_check->GetDexPc());
    957         deopt_block->InsertInstructionBefore(
    958             null_check_cond, deopt_block->GetLastInstruction());
    959         deopt_block->InsertInstructionBefore(
    960             null_check_deoptimize, deopt_block->GetLastInstruction());
    961         // Eliminate null check in the loop.
    962         null_check->ReplaceWith(array);
    963         null_check->GetBlock()->RemoveInstruction(null_check);
    964         null_check_deoptimize->CopyEnvironmentFromWithLoopPhiAdjustment(
    965             suspend_check->GetEnvironment(), header);
    966       }
    967 
    968       HArrayLength* new_array_length = new (graph->GetArena()) HArrayLength(array);
    969       deopt_block->InsertInstructionBefore(new_array_length, deopt_block->GetLastInstruction());
    970 
    971       if (loop_entry_test_block_added) {
    972         // Replace array_length defined inside the loop body with a phi
    973         // array_length_in_loop_body_if_needed. This is a synthetic phi so there is
    974         // no vreg number for it.
    975         HPhi* phi = new (graph->GetArena()) HPhi(
    976             graph->GetArena(), kNoRegNumber, 2, Primitive::kPrimInt);
    977         // Set to 0 if the loop body isn't entered.
    978         phi->SetRawInputAt(0, graph->GetIntConstant(0));
    979         // Set to array.length if the loop body is entered.
    980         phi->SetRawInputAt(1, new_array_length);
    981         pre_header->AddPhi(phi);
    982         array_length->ReplaceWith(phi);
    983         // Make sure phi is only used after the loop body is entered.
    984         if (kIsDebugBuild) {
    985           for (HUseIterator<HInstruction*> it(phi->GetUses());
    986                !it.Done();
    987                it.Advance()) {
    988             HInstruction* user = it.Current()->GetUser();
    989             DCHECK(GetLoopHeaderSuccesorInLoop()->Dominates(user->GetBlock()));
    990           }
    991         }
    992       } else {
    993         array_length->ReplaceWith(new_array_length);
    994       }
    995 
    996       array_length->GetBlock()->RemoveInstruction(array_length);
    997       // Use new_array_length for deopt.
    998       array_length = new_array_length;
    999     }
   1000 
   1001     HInstruction* added = array_length;
   1002     if (offset != 0) {
   1003       HIntConstant* offset_instr = graph->GetIntConstant(offset);
   1004       added = new (graph->GetArena()) HAdd(Primitive::kPrimInt, array_length, offset_instr);
   1005       deopt_block->InsertInstructionBefore(added, deopt_block->GetLastInstruction());
   1006     }
   1007     HCondition* cond = new (graph->GetArena()) HGreaterThan(value, added);
   1008     HDeoptimize* deopt = new (graph->GetArena()) HDeoptimize(cond, suspend_check->GetDexPc());
   1009     deopt_block->InsertInstructionBefore(cond, deopt_block->GetLastInstruction());
   1010     deopt_block->InsertInstructionBefore(deopt, deopt_block->GetLastInstruction());
   1011     deopt->CopyEnvironmentFromWithLoopPhiAdjustment(suspend_check->GetEnvironment(), header);
   1012   }
   1013 
   1014   // Adds deoptimizations in loop pre-header with the collected array access
   1015   // data so that value ranges can be established in loop body.
   1016   // Returns true if deoptimizations are successfully added, or if it's proven
   1017   // it's not necessary.
   1018   bool AddDeoptimization(const ArrayAccessInsideLoopFinder& finder) {
   1019     int32_t offset_low = finder.GetOffsetLow();
   1020     int32_t offset_high = finder.GetOffsetHigh();
   1021     HArrayLength* array_length = finder.GetFoundArrayLength();
   1022 
   1023     HBasicBlock* pre_header =
   1024         induction_variable_->GetBlock()->GetLoopInformation()->GetPreHeader();
   1025     if (!initial_->GetBlock()->Dominates(pre_header) ||
   1026         !end_->GetBlock()->Dominates(pre_header)) {
   1027       // Can't move initial_ or end_ into pre_header for comparisons.
   1028       return false;
   1029     }
   1030 
   1031     HBasicBlock* deopt_block;
   1032     bool loop_entry_test_block_added = false;
   1033     bool is_constant_proven, is_length_proven;
   1034 
   1035     HInstruction* const_comparing_instruction;
   1036     int32_t const_compared_to;
   1037     HInstruction* array_length_comparing_instruction;
   1038     int32_t array_length_offset;
   1039     if (increment_ == 1) {
   1040       // Increasing from initial_ to end_.
   1041       const_comparing_instruction = initial_;
   1042       const_compared_to = -offset_low;
   1043       array_length_comparing_instruction = end_;
   1044       array_length_offset = inclusive_ ? -offset_high - 1 : -offset_high;
   1045     } else {
   1046       const_comparing_instruction = end_;
   1047       const_compared_to = inclusive_ ? -offset_low : -offset_low - 1;
   1048       array_length_comparing_instruction = initial_;
   1049       array_length_offset = -offset_high - 1;
   1050     }
   1051 
   1052     if (CanAddDeoptimizationConstant(const_comparing_instruction,
   1053                                      const_compared_to,
   1054                                      &is_constant_proven) &&
   1055         CanAddDeoptimizationArrayLength(array_length_comparing_instruction,
   1056                                         array_length,
   1057                                         array_length_offset,
   1058                                         &is_length_proven)) {
   1059       if (!is_constant_proven || !is_length_proven) {
   1060         deopt_block = TransformLoopForDeoptimizationIfNeeded();
   1061         loop_entry_test_block_added = (deopt_block != pre_header);
   1062         if (loop_entry_test_block_added) {
   1063           // Loop body may be entered.
   1064           AddLoopBodyEntryTest();
   1065         }
   1066       }
   1067       if (!is_constant_proven) {
   1068         AddDeoptimizationConstant(const_comparing_instruction,
   1069                                   const_compared_to,
   1070                                   deopt_block,
   1071                                   loop_entry_test_block_added);
   1072       }
   1073       if (!is_length_proven) {
   1074         AddDeoptimizationArrayLength(array_length_comparing_instruction,
   1075                                      array_length,
   1076                                      array_length_offset,
   1077                                      deopt_block,
   1078                                      loop_entry_test_block_added);
   1079       }
   1080       return true;
   1081     }
   1082     return false;
   1083   }
   1084 
   1085  private:
   1086   HPhi* const induction_variable_;  // Induction variable for this monotonic value range.
   1087   HInstruction* const initial_;     // Initial value.
   1088   HInstruction* end_;               // End value.
   1089   bool inclusive_;                  // Whether end value is inclusive.
   1090   const int32_t increment_;         // Increment for each loop iteration.
   1091   const ValueBound bound_;          // Additional value bound info for initial_.
   1092 
   1093   DISALLOW_COPY_AND_ASSIGN(MonotonicValueRange);
   1094 };
   1095 
   1096 class BCEVisitor : public HGraphVisitor {
   1097  public:
   1098   // The least number of bounds checks that should be eliminated by triggering
   1099   // the deoptimization technique.
   1100   static constexpr size_t kThresholdForAddingDeoptimize = 2;
   1101 
   1102   // Very large constant index is considered as an anomaly. This is a threshold
   1103   // beyond which we don't bother to apply the deoptimization technique since
   1104   // it's likely some AIOOBE will be thrown.
   1105   static constexpr int32_t kMaxConstantForAddingDeoptimize = INT_MAX - 1024 * 1024;
   1106 
   1107   // Added blocks for loop body entry test.
   1108   bool IsAddedBlock(HBasicBlock* block) const {
   1109     return block->GetBlockId() >= initial_block_size_;
   1110   }
   1111 
   1112   explicit BCEVisitor(HGraph* graph)
   1113       : HGraphVisitor(graph), maps_(graph->GetBlocks().Size()),
   1114         need_to_revisit_block_(false), initial_block_size_(graph->GetBlocks().Size()) {}
   1115 
   1116   void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
   1117     DCHECK(!IsAddedBlock(block));
   1118     first_constant_index_bounds_check_map_.clear();
   1119     HGraphVisitor::VisitBasicBlock(block);
   1120     if (need_to_revisit_block_) {
   1121       AddComparesWithDeoptimization(block);
   1122       need_to_revisit_block_ = false;
   1123       first_constant_index_bounds_check_map_.clear();
   1124       GetValueRangeMap(block)->clear();
   1125       HGraphVisitor::VisitBasicBlock(block);
   1126     }
   1127   }
   1128 
   1129  private:
   1130   // Return the map of proven value ranges at the beginning of a basic block.
   1131   ArenaSafeMap<int, ValueRange*>* GetValueRangeMap(HBasicBlock* basic_block) {
   1132     if (IsAddedBlock(basic_block)) {
   1133       // Added blocks don't keep value ranges.
   1134       return nullptr;
   1135     }
   1136     int block_id = basic_block->GetBlockId();
   1137     if (maps_.at(block_id) == nullptr) {
   1138       std::unique_ptr<ArenaSafeMap<int, ValueRange*>> map(
   1139           new ArenaSafeMap<int, ValueRange*>(
   1140               std::less<int>(), GetGraph()->GetArena()->Adapter()));
   1141       maps_.at(block_id) = std::move(map);
   1142     }
   1143     return maps_.at(block_id).get();
   1144   }
   1145 
   1146   // Traverse up the dominator tree to look for value range info.
   1147   ValueRange* LookupValueRange(HInstruction* instruction, HBasicBlock* basic_block) {
   1148     while (basic_block != nullptr) {
   1149       ArenaSafeMap<int, ValueRange*>* map = GetValueRangeMap(basic_block);
   1150       if (map != nullptr) {
   1151         if (map->find(instruction->GetId()) != map->end()) {
   1152           return map->Get(instruction->GetId());
   1153         }
   1154       } else {
   1155         DCHECK(IsAddedBlock(basic_block));
   1156       }
   1157       basic_block = basic_block->GetDominator();
   1158     }
   1159     // Didn't find any.
   1160     return nullptr;
   1161   }
   1162 
   1163   // Narrow the value range of `instruction` at the end of `basic_block` with `range`,
   1164   // and push the narrowed value range to `successor`.
   1165   void ApplyRangeFromComparison(HInstruction* instruction, HBasicBlock* basic_block,
   1166                                 HBasicBlock* successor, ValueRange* range) {
   1167     ValueRange* existing_range = LookupValueRange(instruction, basic_block);
   1168     if (existing_range == nullptr) {
   1169       if (range != nullptr) {
   1170         GetValueRangeMap(successor)->Overwrite(instruction->GetId(), range);
   1171       }
   1172       return;
   1173     }
   1174     if (existing_range->IsMonotonicValueRange()) {
   1175       DCHECK(instruction->IsLoopHeaderPhi());
   1176       // Make sure the comparison is in the loop header so each increment is
   1177       // checked with a comparison.
   1178       if (instruction->GetBlock() != basic_block) {
   1179         return;
   1180       }
   1181     }
   1182     ValueRange* narrowed_range = existing_range->Narrow(range);
   1183     GetValueRangeMap(successor)->Overwrite(instruction->GetId(), narrowed_range);
   1184   }
   1185 
   1186   // Special case that we may simultaneously narrow two MonotonicValueRange's to
   1187   // regular value ranges.
   1188   void HandleIfBetweenTwoMonotonicValueRanges(HIf* instruction,
   1189                                               HInstruction* left,
   1190                                               HInstruction* right,
   1191                                               IfCondition cond,
   1192                                               MonotonicValueRange* left_range,
   1193                                               MonotonicValueRange* right_range) {
   1194     DCHECK(left->IsLoopHeaderPhi());
   1195     DCHECK(right->IsLoopHeaderPhi());
   1196     if (instruction->GetBlock() != left->GetBlock()) {
   1197       // Comparison needs to be in loop header to make sure it's done after each
   1198       // increment/decrement.
   1199       return;
   1200     }
   1201 
   1202     // Handle common cases which also don't have overflow/underflow concerns.
   1203     if (left_range->GetIncrement() == 1 &&
   1204         left_range->GetBound().IsConstant() &&
   1205         right_range->GetIncrement() == -1 &&
   1206         right_range->GetBound().IsRelatedToArrayLength() &&
   1207         right_range->GetBound().GetConstant() < 0) {
   1208       HBasicBlock* successor = nullptr;
   1209       int32_t left_compensation = 0;
   1210       int32_t right_compensation = 0;
   1211       if (cond == kCondLT) {
   1212         left_compensation = -1;
   1213         right_compensation = 1;
   1214         successor = instruction->IfTrueSuccessor();
   1215       } else if (cond == kCondLE) {
   1216         successor = instruction->IfTrueSuccessor();
   1217       } else if (cond == kCondGT) {
   1218         successor = instruction->IfFalseSuccessor();
   1219       } else if (cond == kCondGE) {
   1220         left_compensation = -1;
   1221         right_compensation = 1;
   1222         successor = instruction->IfFalseSuccessor();
   1223       } else {
   1224         // We don't handle '=='/'!=' test in case left and right can cross and
   1225         // miss each other.
   1226         return;
   1227       }
   1228 
   1229       if (successor != nullptr) {
   1230         bool overflow;
   1231         bool underflow;
   1232         ValueRange* new_left_range = new (GetGraph()->GetArena()) ValueRange(
   1233             GetGraph()->GetArena(),
   1234             left_range->GetBound(),
   1235             right_range->GetBound().Add(left_compensation, &overflow, &underflow));
   1236         if (!overflow && !underflow) {
   1237           ApplyRangeFromComparison(left, instruction->GetBlock(), successor,
   1238                                    new_left_range);
   1239         }
   1240 
   1241         ValueRange* new_right_range = new (GetGraph()->GetArena()) ValueRange(
   1242             GetGraph()->GetArena(),
   1243             left_range->GetBound().Add(right_compensation, &overflow, &underflow),
   1244             right_range->GetBound());
   1245         if (!overflow && !underflow) {
   1246           ApplyRangeFromComparison(right, instruction->GetBlock(), successor,
   1247                                    new_right_range);
   1248         }
   1249       }
   1250     }
   1251   }
   1252 
   1253   // Handle "if (left cmp_cond right)".
   1254   void HandleIf(HIf* instruction, HInstruction* left, HInstruction* right, IfCondition cond) {
   1255     HBasicBlock* block = instruction->GetBlock();
   1256 
   1257     HBasicBlock* true_successor = instruction->IfTrueSuccessor();
   1258     // There should be no critical edge at this point.
   1259     DCHECK_EQ(true_successor->GetPredecessors().Size(), 1u);
   1260 
   1261     HBasicBlock* false_successor = instruction->IfFalseSuccessor();
   1262     // There should be no critical edge at this point.
   1263     DCHECK_EQ(false_successor->GetPredecessors().Size(), 1u);
   1264 
   1265     ValueRange* left_range = LookupValueRange(left, block);
   1266     MonotonicValueRange* left_monotonic_range = nullptr;
   1267     if (left_range != nullptr) {
   1268       left_monotonic_range = left_range->AsMonotonicValueRange();
   1269       if (left_monotonic_range != nullptr) {
   1270         HBasicBlock* loop_head = left_monotonic_range->GetLoopHeader();
   1271         if (instruction->GetBlock() != loop_head) {
   1272           // For monotonic value range, don't handle `instruction`
   1273           // if it's not defined in the loop header.
   1274           return;
   1275         }
   1276       }
   1277     }
   1278 
   1279     bool found;
   1280     ValueBound bound = ValueBound::DetectValueBoundFromValue(right, &found);
   1281     // Each comparison can establish a lower bound and an upper bound
   1282     // for the left hand side.
   1283     ValueBound lower = bound;
   1284     ValueBound upper = bound;
   1285     if (!found) {
   1286       // No constant or array.length+c format bound found.
   1287       // For i<j, we can still use j's upper bound as i's upper bound. Same for lower.
   1288       ValueRange* right_range = LookupValueRange(right, block);
   1289       if (right_range != nullptr) {
   1290         if (right_range->IsMonotonicValueRange()) {
   1291           if (left_range != nullptr && left_range->IsMonotonicValueRange()) {
   1292             HandleIfBetweenTwoMonotonicValueRanges(instruction, left, right, cond,
   1293                                                    left_range->AsMonotonicValueRange(),
   1294                                                    right_range->AsMonotonicValueRange());
   1295             return;
   1296           }
   1297         }
   1298         lower = right_range->GetLower();
   1299         upper = right_range->GetUpper();
   1300       } else {
   1301         lower = ValueBound::Min();
   1302         upper = ValueBound::Max();
   1303       }
   1304     }
   1305 
   1306     bool overflow, underflow;
   1307     if (cond == kCondLT || cond == kCondLE) {
   1308       if (left_monotonic_range != nullptr) {
   1309         // Update the info for monotonic value range.
   1310         if (left_monotonic_range->GetInductionVariable() == left &&
   1311             left_monotonic_range->GetIncrement() < 0 &&
   1312             block == left_monotonic_range->GetLoopHeader() &&
   1313             instruction->IfFalseSuccessor()->GetLoopInformation() == block->GetLoopInformation()) {
   1314           left_monotonic_range->SetEnd(right);
   1315           left_monotonic_range->SetInclusive(cond == kCondLT);
   1316         }
   1317       }
   1318 
   1319       if (!upper.Equals(ValueBound::Max())) {
   1320         int32_t compensation = (cond == kCondLT) ? -1 : 0;  // upper bound is inclusive
   1321         ValueBound new_upper = upper.Add(compensation, &overflow, &underflow);
   1322         if (overflow || underflow) {
   1323           return;
   1324         }
   1325         ValueRange* new_range = new (GetGraph()->GetArena())
   1326             ValueRange(GetGraph()->GetArena(), ValueBound::Min(), new_upper);
   1327         ApplyRangeFromComparison(left, block, true_successor, new_range);
   1328       }
   1329 
   1330       // array.length as a lower bound isn't considered useful.
   1331       if (!lower.Equals(ValueBound::Min()) && !lower.IsRelatedToArrayLength()) {
   1332         int32_t compensation = (cond == kCondLE) ? 1 : 0;  // lower bound is inclusive
   1333         ValueBound new_lower = lower.Add(compensation, &overflow, &underflow);
   1334         if (overflow || underflow) {
   1335           return;
   1336         }
   1337         ValueRange* new_range = new (GetGraph()->GetArena())
   1338             ValueRange(GetGraph()->GetArena(), new_lower, ValueBound::Max());
   1339         ApplyRangeFromComparison(left, block, false_successor, new_range);
   1340       }
   1341     } else if (cond == kCondGT || cond == kCondGE) {
   1342       if (left_monotonic_range != nullptr) {
   1343         // Update the info for monotonic value range.
   1344         if (left_monotonic_range->GetInductionVariable() == left &&
   1345             left_monotonic_range->GetIncrement() > 0 &&
   1346             block == left_monotonic_range->GetLoopHeader() &&
   1347             instruction->IfFalseSuccessor()->GetLoopInformation() == block->GetLoopInformation()) {
   1348           left_monotonic_range->SetEnd(right);
   1349           left_monotonic_range->SetInclusive(cond == kCondGT);
   1350         }
   1351       }
   1352 
   1353       // array.length as a lower bound isn't considered useful.
   1354       if (!lower.Equals(ValueBound::Min()) && !lower.IsRelatedToArrayLength()) {
   1355         int32_t compensation = (cond == kCondGT) ? 1 : 0;  // lower bound is inclusive
   1356         ValueBound new_lower = lower.Add(compensation, &overflow, &underflow);
   1357         if (overflow || underflow) {
   1358           return;
   1359         }
   1360         ValueRange* new_range = new (GetGraph()->GetArena())
   1361             ValueRange(GetGraph()->GetArena(), new_lower, ValueBound::Max());
   1362         ApplyRangeFromComparison(left, block, true_successor, new_range);
   1363       }
   1364 
   1365       if (!upper.Equals(ValueBound::Max())) {
   1366         int32_t compensation = (cond == kCondGE) ? -1 : 0;  // upper bound is inclusive
   1367         ValueBound new_upper = upper.Add(compensation, &overflow, &underflow);
   1368         if (overflow || underflow) {
   1369           return;
   1370         }
   1371         ValueRange* new_range = new (GetGraph()->GetArena())
   1372             ValueRange(GetGraph()->GetArena(), ValueBound::Min(), new_upper);
   1373         ApplyRangeFromComparison(left, block, false_successor, new_range);
   1374       }
   1375     }
   1376   }
   1377 
   1378   void VisitBoundsCheck(HBoundsCheck* bounds_check) {
   1379     HBasicBlock* block = bounds_check->GetBlock();
   1380     HInstruction* index = bounds_check->InputAt(0);
   1381     HInstruction* array_length = bounds_check->InputAt(1);
   1382     DCHECK(array_length->IsIntConstant() ||
   1383            array_length->IsArrayLength() ||
   1384            array_length->IsPhi());
   1385 
   1386     if (array_length->IsPhi()) {
   1387       // Input 1 of the phi contains the real array.length once the loop body is
   1388       // entered. That value will be used for bound analysis. The graph is still
   1389       // strictly in SSA form.
   1390       array_length = array_length->AsPhi()->InputAt(1)->AsArrayLength();
   1391     }
   1392 
   1393     if (!index->IsIntConstant()) {
   1394       ValueRange* index_range = LookupValueRange(index, block);
   1395       if (index_range != nullptr) {
   1396         ValueBound lower = ValueBound(nullptr, 0);        // constant 0
   1397         ValueBound upper = ValueBound(array_length, -1);  // array_length - 1
   1398         ValueRange* array_range = new (GetGraph()->GetArena())
   1399             ValueRange(GetGraph()->GetArena(), lower, upper);
   1400         if (index_range->FitsIn(array_range)) {
   1401           ReplaceBoundsCheck(bounds_check, index);
   1402           return;
   1403         }
   1404       }
   1405     } else {
   1406       int32_t constant = index->AsIntConstant()->GetValue();
   1407       if (constant < 0) {
   1408         // Will always throw exception.
   1409         return;
   1410       }
   1411       if (array_length->IsIntConstant()) {
   1412         if (constant < array_length->AsIntConstant()->GetValue()) {
   1413           ReplaceBoundsCheck(bounds_check, index);
   1414         }
   1415         return;
   1416       }
   1417 
   1418       DCHECK(array_length->IsArrayLength());
   1419       ValueRange* existing_range = LookupValueRange(array_length, block);
   1420       if (existing_range != nullptr) {
   1421         ValueBound lower = existing_range->GetLower();
   1422         DCHECK(lower.IsConstant());
   1423         if (constant < lower.GetConstant()) {
   1424           ReplaceBoundsCheck(bounds_check, index);
   1425           return;
   1426         } else {
   1427           // Existing range isn't strong enough to eliminate the bounds check.
   1428           // Fall through to update the array_length range with info from this
   1429           // bounds check.
   1430         }
   1431       }
   1432 
   1433       if (first_constant_index_bounds_check_map_.find(array_length->GetId()) ==
   1434           first_constant_index_bounds_check_map_.end()) {
   1435         // Remember the first bounds check against array_length of a constant index.
   1436         // That bounds check instruction has an associated HEnvironment where we
   1437         // may add an HDeoptimize to eliminate bounds checks of constant indices
   1438         // against array_length.
   1439         first_constant_index_bounds_check_map_.Put(array_length->GetId(), bounds_check);
   1440       } else {
   1441         // We've seen it at least twice. It's beneficial to introduce a compare with
   1442         // deoptimization fallback to eliminate the bounds checks.
   1443         need_to_revisit_block_ = true;
   1444       }
   1445 
   1446       // Once we have an array access like 'array[5] = 1', we record array.length >= 6.
   1447       // We currently don't do it for non-constant index since a valid array[i] can't prove
   1448       // a valid array[i-1] yet due to the lower bound side.
   1449       if (constant == INT_MAX) {
   1450         // INT_MAX as an index will definitely throw AIOOBE.
   1451         return;
   1452       }
   1453       ValueBound lower = ValueBound(nullptr, constant + 1);
   1454       ValueBound upper = ValueBound::Max();
   1455       ValueRange* range = new (GetGraph()->GetArena())
   1456           ValueRange(GetGraph()->GetArena(), lower, upper);
   1457       GetValueRangeMap(block)->Overwrite(array_length->GetId(), range);
   1458     }
   1459   }
   1460 
   1461   void ReplaceBoundsCheck(HInstruction* bounds_check, HInstruction* index) {
   1462     bounds_check->ReplaceWith(index);
   1463     bounds_check->GetBlock()->RemoveInstruction(bounds_check);
   1464   }
   1465 
   1466   static bool HasSameInputAtBackEdges(HPhi* phi) {
   1467     DCHECK(phi->IsLoopHeaderPhi());
   1468     // Start with input 1. Input 0 is from the incoming block.
   1469     HInstruction* input1 = phi->InputAt(1);
   1470     DCHECK(phi->GetBlock()->GetLoopInformation()->IsBackEdge(
   1471         *phi->GetBlock()->GetPredecessors().Get(1)));
   1472     for (size_t i = 2, e = phi->InputCount(); i < e; ++i) {
   1473       DCHECK(phi->GetBlock()->GetLoopInformation()->IsBackEdge(
   1474           *phi->GetBlock()->GetPredecessors().Get(i)));
   1475       if (input1 != phi->InputAt(i)) {
   1476         return false;
   1477       }
   1478     }
   1479     return true;
   1480   }
   1481 
   1482   void VisitPhi(HPhi* phi) {
   1483     if (phi->IsLoopHeaderPhi()
   1484         && (phi->GetType() == Primitive::kPrimInt)
   1485         && HasSameInputAtBackEdges(phi)) {
   1486       HInstruction* instruction = phi->InputAt(1);
   1487       HInstruction *left;
   1488       int32_t increment;
   1489       if (ValueBound::IsAddOrSubAConstant(instruction, &left, &increment)) {
   1490         if (left == phi) {
   1491           HInstruction* initial_value = phi->InputAt(0);
   1492           ValueRange* range = nullptr;
   1493           if (increment == 0) {
   1494             // Add constant 0. It's really a fixed value.
   1495             range = new (GetGraph()->GetArena()) ValueRange(
   1496                 GetGraph()->GetArena(),
   1497                 ValueBound(initial_value, 0),
   1498                 ValueBound(initial_value, 0));
   1499           } else {
   1500             // Monotonically increasing/decreasing.
   1501             bool found;
   1502             ValueBound bound = ValueBound::DetectValueBoundFromValue(
   1503                 initial_value, &found);
   1504             if (!found) {
   1505               // No constant or array.length+c bound found.
   1506               // For i=j, we can still use j's upper bound as i's upper bound.
   1507               // Same for lower.
   1508               ValueRange* initial_range = LookupValueRange(initial_value, phi->GetBlock());
   1509               if (initial_range != nullptr) {
   1510                 bound = increment > 0 ? initial_range->GetLower() :
   1511                                         initial_range->GetUpper();
   1512               } else {
   1513                 bound = increment > 0 ? ValueBound::Min() : ValueBound::Max();
   1514               }
   1515             }
   1516             range = new (GetGraph()->GetArena()) MonotonicValueRange(
   1517                 GetGraph()->GetArena(),
   1518                 phi,
   1519                 initial_value,
   1520                 increment,
   1521                 bound);
   1522           }
   1523           GetValueRangeMap(phi->GetBlock())->Overwrite(phi->GetId(), range);
   1524         }
   1525       }
   1526     }
   1527   }
   1528 
   1529   void VisitIf(HIf* instruction) {
   1530     if (instruction->InputAt(0)->IsCondition()) {
   1531       HCondition* cond = instruction->InputAt(0)->AsCondition();
   1532       IfCondition cmp = cond->GetCondition();
   1533       if (cmp == kCondGT || cmp == kCondGE ||
   1534           cmp == kCondLT || cmp == kCondLE) {
   1535         HInstruction* left = cond->GetLeft();
   1536         HInstruction* right = cond->GetRight();
   1537         HandleIf(instruction, left, right, cmp);
   1538 
   1539         HBasicBlock* block = instruction->GetBlock();
   1540         ValueRange* left_range = LookupValueRange(left, block);
   1541         if (left_range == nullptr) {
   1542           return;
   1543         }
   1544 
   1545         if (left_range->IsMonotonicValueRange() &&
   1546             block == left_range->AsMonotonicValueRange()->GetLoopHeader()) {
   1547           // The comparison is for an induction variable in the loop header.
   1548           DCHECK(left == left_range->AsMonotonicValueRange()->GetInductionVariable());
   1549           HBasicBlock* loop_body_successor =
   1550             left_range->AsMonotonicValueRange()->GetLoopHeaderSuccesorInLoop();
   1551           if (loop_body_successor == nullptr) {
   1552             // In case it's some strange loop structure.
   1553             return;
   1554           }
   1555           ValueRange* new_left_range = LookupValueRange(left, loop_body_successor);
   1556           if ((new_left_range == left_range) ||
   1557               // Range narrowed with deoptimization is usually more useful than
   1558               // a constant range.
   1559               new_left_range->IsConstantValueRange()) {
   1560             // We are not successful in narrowing the monotonic value range to
   1561             // a regular value range. Try using deoptimization.
   1562             new_left_range = left_range->AsMonotonicValueRange()->
   1563                 NarrowWithDeoptimization();
   1564             if (new_left_range != left_range) {
   1565               GetValueRangeMap(loop_body_successor)->Overwrite(left->GetId(), new_left_range);
   1566             }
   1567           }
   1568         }
   1569       }
   1570     }
   1571   }
   1572 
   1573   void VisitAdd(HAdd* add) {
   1574     HInstruction* right = add->GetRight();
   1575     if (right->IsIntConstant()) {
   1576       ValueRange* left_range = LookupValueRange(add->GetLeft(), add->GetBlock());
   1577       if (left_range == nullptr) {
   1578         return;
   1579       }
   1580       ValueRange* range = left_range->Add(right->AsIntConstant()->GetValue());
   1581       if (range != nullptr) {
   1582         GetValueRangeMap(add->GetBlock())->Overwrite(add->GetId(), range);
   1583       }
   1584     }
   1585   }
   1586 
   1587   void VisitSub(HSub* sub) {
   1588     HInstruction* left = sub->GetLeft();
   1589     HInstruction* right = sub->GetRight();
   1590     if (right->IsIntConstant()) {
   1591       ValueRange* left_range = LookupValueRange(left, sub->GetBlock());
   1592       if (left_range == nullptr) {
   1593         return;
   1594       }
   1595       ValueRange* range = left_range->Add(-right->AsIntConstant()->GetValue());
   1596       if (range != nullptr) {
   1597         GetValueRangeMap(sub->GetBlock())->Overwrite(sub->GetId(), range);
   1598         return;
   1599       }
   1600     }
   1601 
   1602     // Here we are interested in the typical triangular case of nested loops,
   1603     // such as the inner loop 'for (int j=0; j<array.length-i; j++)' where i
   1604     // is the index for outer loop. In this case, we know j is bounded by array.length-1.
   1605 
   1606     // Try to handle (array.length - i) or (array.length + c - i) format.
   1607     HInstruction* left_of_left;  // left input of left.
   1608     int32_t right_const = 0;
   1609     if (ValueBound::IsAddOrSubAConstant(left, &left_of_left, &right_const)) {
   1610       left = left_of_left;
   1611     }
   1612     // The value of left input of the sub equals (left + right_const).
   1613 
   1614     if (left->IsArrayLength()) {
   1615       HInstruction* array_length = left->AsArrayLength();
   1616       ValueRange* right_range = LookupValueRange(right, sub->GetBlock());
   1617       if (right_range != nullptr) {
   1618         ValueBound lower = right_range->GetLower();
   1619         ValueBound upper = right_range->GetUpper();
   1620         if (lower.IsConstant() && upper.IsRelatedToArrayLength()) {
   1621           HInstruction* upper_inst = upper.GetInstruction();
   1622           // Make sure it's the same array.
   1623           if (ValueBound::Equal(array_length, upper_inst)) {
   1624             int32_t c0 = right_const;
   1625             int32_t c1 = lower.GetConstant();
   1626             int32_t c2 = upper.GetConstant();
   1627             // (array.length + c0 - v) where v is in [c1, array.length + c2]
   1628             // gets [c0 - c2, array.length + c0 - c1] as its value range.
   1629             if (!ValueBound::WouldAddOverflowOrUnderflow(c0, -c2) &&
   1630                 !ValueBound::WouldAddOverflowOrUnderflow(c0, -c1)) {
   1631               if ((c0 - c1) <= 0) {
   1632                 // array.length + (c0 - c1) won't overflow/underflow.
   1633                 ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
   1634                     GetGraph()->GetArena(),
   1635                     ValueBound(nullptr, right_const - upper.GetConstant()),
   1636                     ValueBound(array_length, right_const - lower.GetConstant()));
   1637                 GetValueRangeMap(sub->GetBlock())->Overwrite(sub->GetId(), range);
   1638               }
   1639             }
   1640           }
   1641         }
   1642       }
   1643     }
   1644   }
   1645 
   1646   void FindAndHandlePartialArrayLength(HBinaryOperation* instruction) {
   1647     DCHECK(instruction->IsDiv() || instruction->IsShr() || instruction->IsUShr());
   1648     HInstruction* right = instruction->GetRight();
   1649     int32_t right_const;
   1650     if (right->IsIntConstant()) {
   1651       right_const = right->AsIntConstant()->GetValue();
   1652       // Detect division by two or more.
   1653       if ((instruction->IsDiv() && right_const <= 1) ||
   1654           (instruction->IsShr() && right_const < 1) ||
   1655           (instruction->IsUShr() && right_const < 1)) {
   1656         return;
   1657       }
   1658     } else {
   1659       return;
   1660     }
   1661 
   1662     // Try to handle array.length/2 or (array.length-1)/2 format.
   1663     HInstruction* left = instruction->GetLeft();
   1664     HInstruction* left_of_left;  // left input of left.
   1665     int32_t c = 0;
   1666     if (ValueBound::IsAddOrSubAConstant(left, &left_of_left, &c)) {
   1667       left = left_of_left;
   1668     }
   1669     // The value of left input of instruction equals (left + c).
   1670 
   1671     // (array_length + 1) or smaller divided by two or more
   1672     // always generate a value in [INT_MIN, array_length].
   1673     // This is true even if array_length is INT_MAX.
   1674     if (left->IsArrayLength() && c <= 1) {
   1675       if (instruction->IsUShr() && c < 0) {
   1676         // Make sure for unsigned shift, left side is not negative.
   1677         // e.g. if array_length is 2, ((array_length - 3) >>> 2) is way bigger
   1678         // than array_length.
   1679         return;
   1680       }
   1681       ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
   1682           GetGraph()->GetArena(),
   1683           ValueBound(nullptr, INT_MIN),
   1684           ValueBound(left, 0));
   1685       GetValueRangeMap(instruction->GetBlock())->Overwrite(instruction->GetId(), range);
   1686     }
   1687   }
   1688 
   1689   void VisitDiv(HDiv* div) {
   1690     FindAndHandlePartialArrayLength(div);
   1691   }
   1692 
   1693   void VisitShr(HShr* shr) {
   1694     FindAndHandlePartialArrayLength(shr);
   1695   }
   1696 
   1697   void VisitUShr(HUShr* ushr) {
   1698     FindAndHandlePartialArrayLength(ushr);
   1699   }
   1700 
   1701   void VisitAnd(HAnd* instruction) {
   1702     if (instruction->GetRight()->IsIntConstant()) {
   1703       int32_t constant = instruction->GetRight()->AsIntConstant()->GetValue();
   1704       if (constant > 0) {
   1705         // constant serves as a mask so any number masked with it
   1706         // gets a [0, constant] value range.
   1707         ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
   1708             GetGraph()->GetArena(),
   1709             ValueBound(nullptr, 0),
   1710             ValueBound(nullptr, constant));
   1711         GetValueRangeMap(instruction->GetBlock())->Overwrite(instruction->GetId(), range);
   1712       }
   1713     }
   1714   }
   1715 
   1716   void VisitNewArray(HNewArray* new_array) {
   1717     HInstruction* len = new_array->InputAt(0);
   1718     if (!len->IsIntConstant()) {
   1719       HInstruction *left;
   1720       int32_t right_const;
   1721       if (ValueBound::IsAddOrSubAConstant(len, &left, &right_const)) {
   1722         // (left + right_const) is used as size to new the array.
   1723         // We record "-right_const <= left <= new_array - right_const";
   1724         ValueBound lower = ValueBound(nullptr, -right_const);
   1725         // We use new_array for the bound instead of new_array.length,
   1726         // which isn't available as an instruction yet. new_array will
   1727         // be treated the same as new_array.length when it's used in a ValueBound.
   1728         ValueBound upper = ValueBound(new_array, -right_const);
   1729         ValueRange* range = new (GetGraph()->GetArena())
   1730             ValueRange(GetGraph()->GetArena(), lower, upper);
   1731         ValueRange* existing_range = LookupValueRange(left, new_array->GetBlock());
   1732         if (existing_range != nullptr) {
   1733           range = existing_range->Narrow(range);
   1734         }
   1735         GetValueRangeMap(new_array->GetBlock())->Overwrite(left->GetId(), range);
   1736       }
   1737     }
   1738   }
   1739 
   1740   void VisitDeoptimize(HDeoptimize* deoptimize) {
   1741     // Right now it's only HLessThanOrEqual.
   1742     DCHECK(deoptimize->InputAt(0)->IsLessThanOrEqual());
   1743     HLessThanOrEqual* less_than_or_equal = deoptimize->InputAt(0)->AsLessThanOrEqual();
   1744     HInstruction* instruction = less_than_or_equal->InputAt(0);
   1745     if (instruction->IsArrayLength()) {
   1746       HInstruction* constant = less_than_or_equal->InputAt(1);
   1747       DCHECK(constant->IsIntConstant());
   1748       DCHECK(constant->AsIntConstant()->GetValue() <= kMaxConstantForAddingDeoptimize);
   1749       ValueBound lower = ValueBound(nullptr, constant->AsIntConstant()->GetValue() + 1);
   1750       ValueRange* range = new (GetGraph()->GetArena())
   1751           ValueRange(GetGraph()->GetArena(), lower, ValueBound::Max());
   1752       GetValueRangeMap(deoptimize->GetBlock())->Overwrite(instruction->GetId(), range);
   1753     }
   1754   }
   1755 
   1756   void AddCompareWithDeoptimization(HInstruction* array_length,
   1757                                     HIntConstant* const_instr,
   1758                                     HBasicBlock* block) {
   1759     DCHECK(array_length->IsArrayLength());
   1760     ValueRange* range = LookupValueRange(array_length, block);
   1761     ValueBound lower_bound = range->GetLower();
   1762     DCHECK(lower_bound.IsConstant());
   1763     DCHECK(const_instr->GetValue() <= kMaxConstantForAddingDeoptimize);
   1764     // Note that the lower bound of the array length may have been refined
   1765     // through other instructions (such as `HNewArray(length - 4)`).
   1766     DCHECK_LE(const_instr->GetValue() + 1, lower_bound.GetConstant());
   1767 
   1768     // If array_length is less than lower_const, deoptimize.
   1769     HBoundsCheck* bounds_check = first_constant_index_bounds_check_map_.Get(
   1770         array_length->GetId())->AsBoundsCheck();
   1771     HCondition* cond = new (GetGraph()->GetArena()) HLessThanOrEqual(array_length, const_instr);
   1772     HDeoptimize* deoptimize = new (GetGraph()->GetArena())
   1773         HDeoptimize(cond, bounds_check->GetDexPc());
   1774     block->InsertInstructionBefore(cond, bounds_check);
   1775     block->InsertInstructionBefore(deoptimize, bounds_check);
   1776     deoptimize->CopyEnvironmentFrom(bounds_check->GetEnvironment());
   1777   }
   1778 
   1779   void AddComparesWithDeoptimization(HBasicBlock* block) {
   1780     for (ArenaSafeMap<int, HBoundsCheck*>::iterator it =
   1781              first_constant_index_bounds_check_map_.begin();
   1782          it != first_constant_index_bounds_check_map_.end();
   1783          ++it) {
   1784       HBoundsCheck* bounds_check = it->second;
   1785       HInstruction* array_length = bounds_check->InputAt(1);
   1786       if (!array_length->IsArrayLength()) {
   1787         // Prior deoptimizations may have changed the array length to a phi.
   1788         // TODO(mingyao): propagate the range to the phi?
   1789         DCHECK(array_length->IsPhi()) << array_length->DebugName();
   1790         continue;
   1791       }
   1792       HIntConstant* lower_bound_const_instr = nullptr;
   1793       int32_t lower_bound_const = INT_MIN;
   1794       size_t counter = 0;
   1795       // Count the constant indexing for which bounds checks haven't
   1796       // been removed yet.
   1797       for (HUseIterator<HInstruction*> it2(array_length->GetUses());
   1798            !it2.Done();
   1799            it2.Advance()) {
   1800         HInstruction* user = it2.Current()->GetUser();
   1801         if (user->GetBlock() == block &&
   1802             user->IsBoundsCheck() &&
   1803             user->AsBoundsCheck()->InputAt(0)->IsIntConstant()) {
   1804           DCHECK_EQ(array_length, user->AsBoundsCheck()->InputAt(1));
   1805           HIntConstant* const_instr = user->AsBoundsCheck()->InputAt(0)->AsIntConstant();
   1806           if (const_instr->GetValue() > lower_bound_const) {
   1807             lower_bound_const = const_instr->GetValue();
   1808             lower_bound_const_instr = const_instr;
   1809           }
   1810           counter++;
   1811         }
   1812       }
   1813       if (counter >= kThresholdForAddingDeoptimize &&
   1814           lower_bound_const_instr->GetValue() <= kMaxConstantForAddingDeoptimize) {
   1815         AddCompareWithDeoptimization(array_length, lower_bound_const_instr, block);
   1816       }
   1817     }
   1818   }
   1819 
   1820   std::vector<std::unique_ptr<ArenaSafeMap<int, ValueRange*>>> maps_;
   1821 
   1822   // Map an HArrayLength instruction's id to the first HBoundsCheck instruction in
   1823   // a block that checks a constant index against that HArrayLength.
   1824   SafeMap<int, HBoundsCheck*> first_constant_index_bounds_check_map_;
   1825 
   1826   // For the block, there is at least one HArrayLength instruction for which there
   1827   // is more than one bounds check instruction with constant indexing. And it's
   1828   // beneficial to add a compare instruction that has deoptimization fallback and
   1829   // eliminate those bounds checks.
   1830   bool need_to_revisit_block_;
   1831 
   1832   // Initial number of blocks.
   1833   int32_t initial_block_size_;
   1834 
   1835   DISALLOW_COPY_AND_ASSIGN(BCEVisitor);
   1836 };
   1837 
   1838 void BoundsCheckElimination::Run() {
   1839   if (!graph_->HasBoundsChecks()) {
   1840     return;
   1841   }
   1842 
   1843   BCEVisitor visitor(graph_);
   1844   // Reverse post order guarantees a node's dominators are visited first.
   1845   // We want to visit in the dominator-based order since if a value is known to
   1846   // be bounded by a range at one instruction, it must be true that all uses of
   1847   // that value dominated by that instruction fits in that range. Range of that
   1848   // value can be narrowed further down in the dominator tree.
   1849   //
   1850   // TODO: only visit blocks that dominate some array accesses.
   1851   HBasicBlock* last_visited_block = nullptr;
   1852   for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
   1853     HBasicBlock* current = it.Current();
   1854     if (current == last_visited_block) {
   1855       // We may insert blocks into the reverse post order list when processing
   1856       // a loop header. Don't process it again.
   1857       DCHECK(current->IsLoopHeader());
   1858       continue;
   1859     }
   1860     if (visitor.IsAddedBlock(current)) {
   1861       // Skip added blocks. Their effects are already taken care of.
   1862       continue;
   1863     }
   1864     visitor.VisitBasicBlock(current);
   1865     last_visited_block = current;
   1866   }
   1867 }
   1868 
   1869 }  // namespace art
   1870