blob: 62f5b9aa520702db34f8e30c63f961e3cf0ee202 [file] [log] [blame]
Mingyao Yangf384f882014-10-22 16:08:18 -07001/*
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
Mathieu Chartierb666f482015-02-18 14:33:14 -080017#include "base/arena_containers.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070018#include "bounds_check_elimination.h"
Aart Bik22af3be2015-09-10 12:50:58 -070019#include "induction_var_range.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070020#include "nodes.h"
Mingyao Yangf384f882014-10-22 16:08:18 -070021
22namespace art {
23
24class MonotonicValueRange;
25
26/**
27 * A value bound is represented as a pair of value and constant,
28 * e.g. array.length - 1.
29 */
30class ValueBound : public ValueObject {
31 public:
Mingyao Yang0304e182015-01-30 16:41:29 -080032 ValueBound(HInstruction* instruction, int32_t constant) {
Mingyao Yang64197522014-12-05 15:56:23 -080033 if (instruction != nullptr && instruction->IsIntConstant()) {
Mingyao Yang0304e182015-01-30 16:41:29 -080034 // Normalize ValueBound with constant instruction.
35 int32_t instr_const = instruction->AsIntConstant()->GetValue();
Mingyao Yang8c8bad82015-02-09 18:13:26 -080036 if (!WouldAddOverflowOrUnderflow(instr_const, constant)) {
Mingyao Yang64197522014-12-05 15:56:23 -080037 instruction_ = nullptr;
38 constant_ = instr_const + constant;
39 return;
40 }
Mingyao Yangf384f882014-10-22 16:08:18 -070041 }
Mingyao Yang64197522014-12-05 15:56:23 -080042 instruction_ = instruction;
43 constant_ = constant;
44 }
45
Mingyao Yang8c8bad82015-02-09 18:13:26 -080046 // Return whether (left + right) overflows or underflows.
47 static bool WouldAddOverflowOrUnderflow(int32_t left, int32_t right) {
48 if (right == 0) {
49 return false;
50 }
51 if ((right > 0) && (left <= INT_MAX - right)) {
52 // No overflow.
53 return false;
54 }
55 if ((right < 0) && (left >= INT_MIN - right)) {
56 // No underflow.
57 return false;
58 }
59 return true;
60 }
61
Mingyao Yang0304e182015-01-30 16:41:29 -080062 static bool IsAddOrSubAConstant(HInstruction* instruction,
63 HInstruction** left_instruction,
64 int* right_constant) {
65 if (instruction->IsAdd() || instruction->IsSub()) {
66 HBinaryOperation* bin_op = instruction->AsBinaryOperation();
67 HInstruction* left = bin_op->GetLeft();
68 HInstruction* right = bin_op->GetRight();
69 if (right->IsIntConstant()) {
70 *left_instruction = left;
71 int32_t c = right->AsIntConstant()->GetValue();
72 *right_constant = instruction->IsAdd() ? c : -c;
73 return true;
74 }
75 }
76 *left_instruction = nullptr;
77 *right_constant = 0;
78 return false;
79 }
80
Mingyao Yang64197522014-12-05 15:56:23 -080081 // Try to detect useful value bound format from an instruction, e.g.
82 // a constant or array length related value.
83 static ValueBound DetectValueBoundFromValue(HInstruction* instruction, bool* found) {
84 DCHECK(instruction != nullptr);
Mingyao Yangf384f882014-10-22 16:08:18 -070085 if (instruction->IsIntConstant()) {
Mingyao Yang64197522014-12-05 15:56:23 -080086 *found = true;
87 return ValueBound(nullptr, instruction->AsIntConstant()->GetValue());
Mingyao Yangf384f882014-10-22 16:08:18 -070088 }
Mingyao Yang64197522014-12-05 15:56:23 -080089
90 if (instruction->IsArrayLength()) {
91 *found = true;
92 return ValueBound(instruction, 0);
93 }
94 // Try to detect (array.length + c) format.
Mingyao Yang0304e182015-01-30 16:41:29 -080095 HInstruction *left;
96 int32_t right;
97 if (IsAddOrSubAConstant(instruction, &left, &right)) {
98 if (left->IsArrayLength()) {
Mingyao Yang64197522014-12-05 15:56:23 -080099 *found = true;
Mingyao Yang0304e182015-01-30 16:41:29 -0800100 return ValueBound(left, right);
Mingyao Yang64197522014-12-05 15:56:23 -0800101 }
102 }
103
104 // No useful bound detected.
105 *found = false;
106 return ValueBound::Max();
Mingyao Yangf384f882014-10-22 16:08:18 -0700107 }
108
109 HInstruction* GetInstruction() const { return instruction_; }
Mingyao Yang0304e182015-01-30 16:41:29 -0800110 int32_t GetConstant() const { return constant_; }
Mingyao Yangf384f882014-10-22 16:08:18 -0700111
Mingyao Yang0304e182015-01-30 16:41:29 -0800112 bool IsRelatedToArrayLength() const {
113 // Some bounds are created with HNewArray* as the instruction instead
114 // of HArrayLength*. They are treated the same.
115 return (instruction_ != nullptr) &&
116 (instruction_->IsArrayLength() || instruction_->IsNewArray());
Mingyao Yangf384f882014-10-22 16:08:18 -0700117 }
118
119 bool IsConstant() const {
120 return instruction_ == nullptr;
121 }
122
123 static ValueBound Min() { return ValueBound(nullptr, INT_MIN); }
124 static ValueBound Max() { return ValueBound(nullptr, INT_MAX); }
125
126 bool Equals(ValueBound bound) const {
127 return instruction_ == bound.instruction_ && constant_ == bound.constant_;
128 }
129
Aart Bik22af3be2015-09-10 12:50:58 -0700130 /*
131 * Hunt "under the hood" of array lengths (leading to array references),
132 * null checks (also leading to array references), and new arrays
133 * (leading to the actual length). This makes it more likely related
134 * instructions become actually comparable.
135 */
136 static HInstruction* HuntForDeclaration(HInstruction* instruction) {
137 while (instruction->IsArrayLength() ||
138 instruction->IsNullCheck() ||
139 instruction->IsNewArray()) {
140 instruction = instruction->InputAt(0);
Mingyao Yang0304e182015-01-30 16:41:29 -0800141 }
142 return instruction;
143 }
144
145 static bool Equal(HInstruction* instruction1, HInstruction* instruction2) {
146 if (instruction1 == instruction2) {
147 return true;
148 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800149 if (instruction1 == nullptr || instruction2 == nullptr) {
Mingyao Yangf384f882014-10-22 16:08:18 -0700150 return false;
151 }
Aart Bik22af3be2015-09-10 12:50:58 -0700152 instruction1 = HuntForDeclaration(instruction1);
153 instruction2 = HuntForDeclaration(instruction2);
Mingyao Yang0304e182015-01-30 16:41:29 -0800154 return instruction1 == instruction2;
155 }
156
157 // Returns if it's certain this->bound >= `bound`.
158 bool GreaterThanOrEqualTo(ValueBound bound) const {
159 if (Equal(instruction_, bound.instruction_)) {
160 return constant_ >= bound.constant_;
161 }
Mingyao Yangf384f882014-10-22 16:08:18 -0700162 // Not comparable. Just return false.
163 return false;
164 }
165
Mingyao Yang0304e182015-01-30 16:41:29 -0800166 // Returns if it's certain this->bound <= `bound`.
167 bool LessThanOrEqualTo(ValueBound bound) const {
168 if (Equal(instruction_, bound.instruction_)) {
169 return constant_ <= bound.constant_;
Mingyao Yangf384f882014-10-22 16:08:18 -0700170 }
Mingyao Yangf384f882014-10-22 16:08:18 -0700171 // Not comparable. Just return false.
172 return false;
173 }
174
175 // Try to narrow lower bound. Returns the greatest of the two if possible.
176 // Pick one if they are not comparable.
177 static ValueBound NarrowLowerBound(ValueBound bound1, ValueBound bound2) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800178 if (bound1.GreaterThanOrEqualTo(bound2)) {
179 return bound1;
180 }
181 if (bound2.GreaterThanOrEqualTo(bound1)) {
182 return bound2;
Mingyao Yangf384f882014-10-22 16:08:18 -0700183 }
184
185 // Not comparable. Just pick one. We may lose some info, but that's ok.
186 // Favor constant as lower bound.
187 return bound1.IsConstant() ? bound1 : bound2;
188 }
189
190 // Try to narrow upper bound. Returns the lowest of the two if possible.
191 // Pick one if they are not comparable.
192 static ValueBound NarrowUpperBound(ValueBound bound1, ValueBound bound2) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800193 if (bound1.LessThanOrEqualTo(bound2)) {
194 return bound1;
195 }
196 if (bound2.LessThanOrEqualTo(bound1)) {
197 return bound2;
Mingyao Yangf384f882014-10-22 16:08:18 -0700198 }
199
200 // Not comparable. Just pick one. We may lose some info, but that's ok.
201 // Favor array length as upper bound.
Mingyao Yang0304e182015-01-30 16:41:29 -0800202 return bound1.IsRelatedToArrayLength() ? bound1 : bound2;
Mingyao Yangf384f882014-10-22 16:08:18 -0700203 }
204
Mingyao Yang0304e182015-01-30 16:41:29 -0800205 // Add a constant to a ValueBound.
206 // `overflow` or `underflow` will return whether the resulting bound may
207 // overflow or underflow an int.
208 ValueBound Add(int32_t c, bool* overflow, bool* underflow) const {
209 *overflow = *underflow = false;
Mingyao Yangf384f882014-10-22 16:08:18 -0700210 if (c == 0) {
211 return *this;
212 }
213
Mingyao Yang0304e182015-01-30 16:41:29 -0800214 int32_t new_constant;
Mingyao Yangf384f882014-10-22 16:08:18 -0700215 if (c > 0) {
216 if (constant_ > INT_MAX - c) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800217 *overflow = true;
Mingyao Yang64197522014-12-05 15:56:23 -0800218 return Max();
Mingyao Yangf384f882014-10-22 16:08:18 -0700219 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800220
221 new_constant = constant_ + c;
222 // (array.length + non-positive-constant) won't overflow an int.
223 if (IsConstant() || (IsRelatedToArrayLength() && new_constant <= 0)) {
224 return ValueBound(instruction_, new_constant);
225 }
226 // Be conservative.
227 *overflow = true;
228 return Max();
Mingyao Yangf384f882014-10-22 16:08:18 -0700229 } else {
230 if (constant_ < INT_MIN - c) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800231 *underflow = true;
232 return Min();
Mingyao Yangf384f882014-10-22 16:08:18 -0700233 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800234
235 new_constant = constant_ + c;
236 // Regardless of the value new_constant, (array.length+new_constant) will
237 // never underflow since array.length is no less than 0.
238 if (IsConstant() || IsRelatedToArrayLength()) {
239 return ValueBound(instruction_, new_constant);
240 }
241 // Be conservative.
242 *underflow = true;
243 return Min();
Mingyao Yangf384f882014-10-22 16:08:18 -0700244 }
Mingyao Yangf384f882014-10-22 16:08:18 -0700245 }
246
247 private:
Mingyao Yangf384f882014-10-22 16:08:18 -0700248 HInstruction* instruction_;
Mingyao Yang0304e182015-01-30 16:41:29 -0800249 int32_t constant_;
Mingyao Yangf384f882014-10-22 16:08:18 -0700250};
251
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700252// Collect array access data for a loop.
253// TODO: make it work for multiple arrays inside the loop.
254class ArrayAccessInsideLoopFinder : public ValueObject {
255 public:
256 explicit ArrayAccessInsideLoopFinder(HInstruction* induction_variable)
257 : induction_variable_(induction_variable),
258 found_array_length_(nullptr),
259 offset_low_(INT_MAX),
260 offset_high_(INT_MIN) {
261 Run();
262 }
263
264 HArrayLength* GetFoundArrayLength() const { return found_array_length_; }
265 bool HasFoundArrayLength() const { return found_array_length_ != nullptr; }
266 int32_t GetOffsetLow() const { return offset_low_; }
267 int32_t GetOffsetHigh() const { return offset_high_; }
268
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700269 // Returns if `block` that is in loop_info may exit the loop, unless it's
270 // the loop header for loop_info.
271 static bool EarlyExit(HBasicBlock* block, HLoopInformation* loop_info) {
272 DCHECK(loop_info->Contains(*block));
273 if (block == loop_info->GetHeader()) {
274 // Loop header of loop_info. Exiting loop is normal.
275 return false;
276 }
Vladimir Marko60584552015-09-03 13:35:12 +0000277 for (HBasicBlock* successor : block->GetSuccessors()) {
278 if (!loop_info->Contains(*successor)) {
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700279 // One of the successors exits the loop.
280 return true;
281 }
282 }
283 return false;
284 }
285
Nicolas Geoffraydb216f42015-05-05 17:02:20 +0100286 static bool DominatesAllBackEdges(HBasicBlock* block, HLoopInformation* loop_info) {
Vladimir Markofa6b93c2015-09-15 10:15:55 +0100287 for (HBasicBlock* back_edge : loop_info->GetBackEdges()) {
Nicolas Geoffraydb216f42015-05-05 17:02:20 +0100288 if (!block->Dominates(back_edge)) {
289 return false;
290 }
291 }
292 return true;
293 }
294
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700295 void Run() {
296 HLoopInformation* loop_info = induction_variable_->GetBlock()->GetLoopInformation();
Mingyao Yang3584bce2015-05-19 16:01:59 -0700297 HBlocksInLoopReversePostOrderIterator it_loop(*loop_info);
298 HBasicBlock* block = it_loop.Current();
299 DCHECK(block == induction_variable_->GetBlock());
300 // Skip loop header. Since narrowed value range of a MonotonicValueRange only
301 // applies to the loop body (after the test at the end of the loop header).
302 it_loop.Advance();
303 for (; !it_loop.Done(); it_loop.Advance()) {
304 block = it_loop.Current();
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700305 DCHECK(block->IsInLoop());
Nicolas Geoffraydb216f42015-05-05 17:02:20 +0100306 if (!DominatesAllBackEdges(block, loop_info)) {
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700307 // In order not to trigger deoptimization unnecessarily, make sure
308 // that all array accesses collected are really executed in the loop.
309 // For array accesses in a branch inside the loop, don't collect the
310 // access. The bounds check in that branch might not be eliminated.
311 continue;
312 }
313 if (EarlyExit(block, loop_info)) {
314 // If the loop body can exit loop (like break, return, etc.), it's not guaranteed
315 // that the loop will loop through the full monotonic value range from
316 // initial_ to end_. So adding deoptimization might be too aggressive and can
317 // trigger deoptimization unnecessarily even if the loop won't actually throw
Mingyao Yang3584bce2015-05-19 16:01:59 -0700318 // AIOOBE.
Mingyao Yang9d750ef2015-04-26 18:15:30 -0700319 found_array_length_ = nullptr;
320 return;
321 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700322 for (HInstruction* instruction = block->GetFirstInstruction();
323 instruction != nullptr;
324 instruction = instruction->GetNext()) {
Mingyao Yang3584bce2015-05-19 16:01:59 -0700325 if (!instruction->IsBoundsCheck()) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700326 continue;
327 }
328
Mingyao Yang3584bce2015-05-19 16:01:59 -0700329 HInstruction* length_value = instruction->InputAt(1);
330 if (length_value->IsIntConstant()) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700331 // TODO: may optimize for constant case.
332 continue;
333 }
334
Mingyao Yang3584bce2015-05-19 16:01:59 -0700335 if (length_value->IsPhi()) {
Nicolas Geoffray3cde6222015-06-17 10:17:49 +0100336 // When adding deoptimizations in outer loops, we might create
337 // a phi for the array length, and update all uses of the
338 // length in the loop to that phi. Therefore, inner loops having
339 // bounds checks on the same array will use that phi.
340 // TODO: handle these cases.
Mingyao Yang3584bce2015-05-19 16:01:59 -0700341 continue;
342 }
343
344 DCHECK(length_value->IsArrayLength());
345 HArrayLength* array_length = length_value->AsArrayLength();
346
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700347 HInstruction* array = array_length->InputAt(0);
348 if (array->IsNullCheck()) {
349 array = array->AsNullCheck()->InputAt(0);
350 }
351 if (loop_info->Contains(*array->GetBlock())) {
352 // Array is defined inside the loop. Skip.
353 continue;
354 }
355
356 if (found_array_length_ != nullptr && found_array_length_ != array_length) {
357 // There is already access for another array recorded for the loop.
358 // TODO: handle multiple arrays.
359 continue;
360 }
361
Mingyao Yang3584bce2015-05-19 16:01:59 -0700362 HInstruction* index = instruction->AsBoundsCheck()->InputAt(0);
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700363 HInstruction* left = index;
364 int32_t right = 0;
365 if (left == induction_variable_ ||
366 (ValueBound::IsAddOrSubAConstant(index, &left, &right) &&
367 left == induction_variable_)) {
368 // For patterns like array[i] or array[i + 2].
369 if (right < offset_low_) {
370 offset_low_ = right;
371 }
372 if (right > offset_high_) {
373 offset_high_ = right;
374 }
375 } else {
376 // Access not in induction_variable/(induction_variable_ + constant)
377 // format. Skip.
378 continue;
379 }
380 // Record this array.
381 found_array_length_ = array_length;
382 }
383 }
384 }
385
386 private:
387 // The instruction that corresponds to a MonotonicValueRange.
388 HInstruction* induction_variable_;
389
Mingyao Yang3584bce2015-05-19 16:01:59 -0700390 // The array length of the array that's accessed inside the loop body.
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700391 HArrayLength* found_array_length_;
392
393 // The lowest and highest constant offsets relative to induction variable
394 // instruction_ in all array accesses.
395 // If array access are: array[i-1], array[i], array[i+1],
396 // offset_low_ is -1 and offset_high is 1.
397 int32_t offset_low_;
398 int32_t offset_high_;
399
400 DISALLOW_COPY_AND_ASSIGN(ArrayAccessInsideLoopFinder);
401};
402
Mingyao Yangf384f882014-10-22 16:08:18 -0700403/**
404 * Represent a range of lower bound and upper bound, both being inclusive.
405 * Currently a ValueRange may be generated as a result of the following:
406 * comparisons related to array bounds, array bounds check, add/sub on top
Mingyao Yang0304e182015-01-30 16:41:29 -0800407 * of an existing value range, NewArray or a loop phi corresponding to an
Mingyao Yangf384f882014-10-22 16:08:18 -0700408 * incrementing/decrementing array index (MonotonicValueRange).
409 */
410class ValueRange : public ArenaObject<kArenaAllocMisc> {
411 public:
412 ValueRange(ArenaAllocator* allocator, ValueBound lower, ValueBound upper)
413 : allocator_(allocator), lower_(lower), upper_(upper) {}
414
415 virtual ~ValueRange() {}
416
Mingyao Yang57e04752015-02-09 18:13:26 -0800417 virtual MonotonicValueRange* AsMonotonicValueRange() { return nullptr; }
418 bool IsMonotonicValueRange() {
Mingyao Yangf384f882014-10-22 16:08:18 -0700419 return AsMonotonicValueRange() != nullptr;
420 }
421
422 ArenaAllocator* GetAllocator() const { return allocator_; }
423 ValueBound GetLower() const { return lower_; }
424 ValueBound GetUpper() const { return upper_; }
425
Mingyao Yang3584bce2015-05-19 16:01:59 -0700426 bool IsConstantValueRange() { return lower_.IsConstant() && upper_.IsConstant(); }
427
Mingyao Yangf384f882014-10-22 16:08:18 -0700428 // If it's certain that this value range fits in other_range.
429 virtual bool FitsIn(ValueRange* other_range) const {
430 if (other_range == nullptr) {
431 return true;
432 }
433 DCHECK(!other_range->IsMonotonicValueRange());
Mingyao Yang0304e182015-01-30 16:41:29 -0800434 return lower_.GreaterThanOrEqualTo(other_range->lower_) &&
435 upper_.LessThanOrEqualTo(other_range->upper_);
Mingyao Yangf384f882014-10-22 16:08:18 -0700436 }
437
438 // Returns the intersection of this and range.
439 // If it's not possible to do intersection because some
440 // bounds are not comparable, it's ok to pick either bound.
441 virtual ValueRange* Narrow(ValueRange* range) {
442 if (range == nullptr) {
443 return this;
444 }
445
446 if (range->IsMonotonicValueRange()) {
447 return this;
448 }
449
450 return new (allocator_) ValueRange(
451 allocator_,
452 ValueBound::NarrowLowerBound(lower_, range->lower_),
453 ValueBound::NarrowUpperBound(upper_, range->upper_));
454 }
455
Mingyao Yang0304e182015-01-30 16:41:29 -0800456 // Shift a range by a constant.
457 ValueRange* Add(int32_t constant) const {
458 bool overflow, underflow;
459 ValueBound lower = lower_.Add(constant, &overflow, &underflow);
460 if (underflow) {
461 // Lower bound underflow will wrap around to positive values
462 // and invalidate the upper bound.
463 return nullptr;
Mingyao Yangf384f882014-10-22 16:08:18 -0700464 }
Mingyao Yang0304e182015-01-30 16:41:29 -0800465 ValueBound upper = upper_.Add(constant, &overflow, &underflow);
466 if (overflow) {
467 // Upper bound overflow will wrap around to negative values
468 // and invalidate the lower bound.
469 return nullptr;
Mingyao Yangf384f882014-10-22 16:08:18 -0700470 }
471 return new (allocator_) ValueRange(allocator_, lower, upper);
472 }
473
Mingyao Yangf384f882014-10-22 16:08:18 -0700474 private:
475 ArenaAllocator* const allocator_;
476 const ValueBound lower_; // inclusive
477 const ValueBound upper_; // inclusive
478
479 DISALLOW_COPY_AND_ASSIGN(ValueRange);
480};
481
482/**
483 * A monotonically incrementing/decrementing value range, e.g.
484 * the variable i in "for (int i=0; i<array.length; i++)".
485 * Special care needs to be taken to account for overflow/underflow
486 * of such value ranges.
487 */
488class MonotonicValueRange : public ValueRange {
489 public:
Mingyao Yang64197522014-12-05 15:56:23 -0800490 MonotonicValueRange(ArenaAllocator* allocator,
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700491 HPhi* induction_variable,
Mingyao Yang64197522014-12-05 15:56:23 -0800492 HInstruction* initial,
Mingyao Yang0304e182015-01-30 16:41:29 -0800493 int32_t increment,
Mingyao Yang64197522014-12-05 15:56:23 -0800494 ValueBound bound)
495 // To be conservative, give it full range [INT_MIN, INT_MAX] in case it's
496 // used as a regular value range, due to possible overflow/underflow.
497 : ValueRange(allocator, ValueBound::Min(), ValueBound::Max()),
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700498 induction_variable_(induction_variable),
Mingyao Yang64197522014-12-05 15:56:23 -0800499 initial_(initial),
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700500 end_(nullptr),
501 inclusive_(false),
Mingyao Yang64197522014-12-05 15:56:23 -0800502 increment_(increment),
503 bound_(bound) {}
Mingyao Yangf384f882014-10-22 16:08:18 -0700504
505 virtual ~MonotonicValueRange() {}
506
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700507 HInstruction* GetInductionVariable() const { return induction_variable_; }
Mingyao Yang57e04752015-02-09 18:13:26 -0800508 int32_t GetIncrement() const { return increment_; }
Mingyao Yang57e04752015-02-09 18:13:26 -0800509 ValueBound GetBound() const { return bound_; }
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700510 void SetEnd(HInstruction* end) { end_ = end; }
511 void SetInclusive(bool inclusive) { inclusive_ = inclusive; }
Mingyao Yang3584bce2015-05-19 16:01:59 -0700512 HBasicBlock* GetLoopHeader() const {
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700513 DCHECK(induction_variable_->GetBlock()->IsLoopHeader());
514 return induction_variable_->GetBlock();
515 }
Mingyao Yang57e04752015-02-09 18:13:26 -0800516
517 MonotonicValueRange* AsMonotonicValueRange() OVERRIDE { return this; }
Mingyao Yangf384f882014-10-22 16:08:18 -0700518
Mingyao Yang3584bce2015-05-19 16:01:59 -0700519 HBasicBlock* GetLoopHeaderSuccesorInLoop() {
520 HBasicBlock* header = GetLoopHeader();
521 HInstruction* instruction = header->GetLastInstruction();
522 DCHECK(instruction->IsIf());
523 HIf* h_if = instruction->AsIf();
524 HLoopInformation* loop_info = header->GetLoopInformation();
525 bool true_successor_in_loop = loop_info->Contains(*h_if->IfTrueSuccessor());
526 bool false_successor_in_loop = loop_info->Contains(*h_if->IfFalseSuccessor());
527
528 // Just in case it's some strange loop structure.
529 if (true_successor_in_loop && false_successor_in_loop) {
530 return nullptr;
531 }
532 DCHECK(true_successor_in_loop || false_successor_in_loop);
533 return false_successor_in_loop ? h_if->IfFalseSuccessor() : h_if->IfTrueSuccessor();
534 }
535
Mingyao Yangf384f882014-10-22 16:08:18 -0700536 // If it's certain that this value range fits in other_range.
537 bool FitsIn(ValueRange* other_range) const OVERRIDE {
538 if (other_range == nullptr) {
539 return true;
540 }
541 DCHECK(!other_range->IsMonotonicValueRange());
542 return false;
543 }
544
545 // Try to narrow this MonotonicValueRange given another range.
546 // Ideally it will return a normal ValueRange. But due to
547 // possible overflow/underflow, that may not be possible.
548 ValueRange* Narrow(ValueRange* range) OVERRIDE {
549 if (range == nullptr) {
550 return this;
551 }
552 DCHECK(!range->IsMonotonicValueRange());
553
554 if (increment_ > 0) {
555 // Monotonically increasing.
Mingyao Yang64197522014-12-05 15:56:23 -0800556 ValueBound lower = ValueBound::NarrowLowerBound(bound_, range->GetLower());
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700557 if (!lower.IsConstant() || lower.GetConstant() == INT_MIN) {
558 // Lower bound isn't useful. Leave it to deoptimization.
559 return this;
560 }
Mingyao Yangf384f882014-10-22 16:08:18 -0700561
562 // We currently conservatively assume max array length is INT_MAX. If we can
563 // make assumptions about the max array length, e.g. due to the max heap size,
564 // divided by the element size (such as 4 bytes for each integer array), we can
565 // lower this number and rule out some possible overflows.
Mingyao Yang0304e182015-01-30 16:41:29 -0800566 int32_t max_array_len = INT_MAX;
Mingyao Yangf384f882014-10-22 16:08:18 -0700567
Mingyao Yang0304e182015-01-30 16:41:29 -0800568 // max possible integer value of range's upper value.
569 int32_t upper = INT_MAX;
570 // Try to lower upper.
571 ValueBound upper_bound = range->GetUpper();
572 if (upper_bound.IsConstant()) {
573 upper = upper_bound.GetConstant();
574 } else if (upper_bound.IsRelatedToArrayLength() && upper_bound.GetConstant() <= 0) {
575 // Normal case. e.g. <= array.length - 1.
576 upper = max_array_len + upper_bound.GetConstant();
Mingyao Yangf384f882014-10-22 16:08:18 -0700577 }
578
579 // If we can prove for the last number in sequence of initial_,
580 // initial_ + increment_, initial_ + 2 x increment_, ...
581 // that's <= upper, (last_num_in_sequence + increment_) doesn't trigger overflow,
582 // then this MonoticValueRange is narrowed to a normal value range.
583
584 // Be conservative first, assume last number in the sequence hits upper.
Mingyao Yang0304e182015-01-30 16:41:29 -0800585 int32_t last_num_in_sequence = upper;
Mingyao Yangf384f882014-10-22 16:08:18 -0700586 if (initial_->IsIntConstant()) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800587 int32_t initial_constant = initial_->AsIntConstant()->GetValue();
Mingyao Yangf384f882014-10-22 16:08:18 -0700588 if (upper <= initial_constant) {
589 last_num_in_sequence = upper;
590 } else {
Mingyao Yang0304e182015-01-30 16:41:29 -0800591 // Cast to int64_t for the substraction part to avoid int32_t overflow.
Mingyao Yangf384f882014-10-22 16:08:18 -0700592 last_num_in_sequence = initial_constant +
593 ((int64_t)upper - (int64_t)initial_constant) / increment_ * increment_;
594 }
595 }
596 if (last_num_in_sequence <= INT_MAX - increment_) {
597 // No overflow. The sequence will be stopped by the upper bound test as expected.
598 return new (GetAllocator()) ValueRange(GetAllocator(), lower, range->GetUpper());
599 }
600
601 // There might be overflow. Give up narrowing.
602 return this;
603 } else {
604 DCHECK_NE(increment_, 0);
605 // Monotonically decreasing.
Mingyao Yang64197522014-12-05 15:56:23 -0800606 ValueBound upper = ValueBound::NarrowUpperBound(bound_, range->GetUpper());
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700607 if ((!upper.IsConstant() || upper.GetConstant() == INT_MAX) &&
608 !upper.IsRelatedToArrayLength()) {
609 // Upper bound isn't useful. Leave it to deoptimization.
610 return this;
611 }
Mingyao Yangf384f882014-10-22 16:08:18 -0700612
613 // Need to take care of underflow. Try to prove underflow won't happen
Mingyao Yang0304e182015-01-30 16:41:29 -0800614 // for common cases.
Mingyao Yangf384f882014-10-22 16:08:18 -0700615 if (range->GetLower().IsConstant()) {
Mingyao Yang0304e182015-01-30 16:41:29 -0800616 int32_t constant = range->GetLower().GetConstant();
Mingyao Yangf384f882014-10-22 16:08:18 -0700617 if (constant >= INT_MIN - increment_) {
618 return new (GetAllocator()) ValueRange(GetAllocator(), range->GetLower(), upper);
619 }
620 }
621
Mingyao Yang0304e182015-01-30 16:41:29 -0800622 // For non-constant lower bound, just assume might be underflow. Give up narrowing.
Mingyao Yangf384f882014-10-22 16:08:18 -0700623 return this;
624 }
625 }
626
Mingyao Yang3584bce2015-05-19 16:01:59 -0700627 // Try to add HDeoptimize's in the loop pre-header first to narrow this range.
628 // For example, this loop:
629 //
630 // for (int i = start; i < end; i++) {
631 // array[i - 1] = array[i] + array[i + 1];
632 // }
633 //
634 // will be transformed to:
635 //
636 // int array_length_in_loop_body_if_needed;
637 // if (start >= end) {
638 // array_length_in_loop_body_if_needed = 0;
639 // } else {
640 // if (start < 1) deoptimize();
641 // if (array == null) deoptimize();
642 // array_length = array.length;
643 // if (end > array_length - 1) deoptimize;
644 // array_length_in_loop_body_if_needed = array_length;
645 // }
646 // for (int i = start; i < end; i++) {
647 // // No more null check and bounds check.
648 // // array.length value is replaced with array_length_in_loop_body_if_needed
649 // // in the loop body.
650 // array[i - 1] = array[i] + array[i + 1];
651 // }
652 //
653 // We basically first go through the loop body and find those array accesses whose
654 // index is at a constant offset from the induction variable ('i' in the above example),
655 // and update offset_low and offset_high along the way. We then add the following
656 // deoptimizations in the loop pre-header (suppose end is not inclusive).
657 // if (start < -offset_low) deoptimize();
658 // if (end >= array.length - offset_high) deoptimize();
659 // It might be necessary to first hoist array.length (and the null check on it) out of
660 // the loop with another deoptimization.
661 //
662 // In order not to trigger deoptimization unnecessarily, we want to make a strong
663 // guarantee that no deoptimization is triggered if the loop body itself doesn't
664 // throw AIOOBE. (It's the same as saying if deoptimization is triggered, the loop
665 // body must throw AIOOBE).
666 // This is achieved by the following:
667 // 1) We only process loops that iterate through the full monotonic range from
668 // initial_ to end_. We do the following checks to make sure that's the case:
669 // a) The loop doesn't have early exit (via break, return, etc.)
670 // b) The increment_ is 1/-1. An increment of 2, for example, may skip end_.
671 // 2) We only collect array accesses of blocks in the loop body that dominate
672 // all loop back edges, these array accesses are guaranteed to happen
673 // at each loop iteration.
674 // With 1) and 2), if the loop body doesn't throw AIOOBE, collected array accesses
675 // when the induction variable is at initial_ and end_ must be in a legal range.
676 // Since the added deoptimizations are basically checking the induction variable
677 // at initial_ and end_ values, no deoptimization will be triggered either.
678 //
679 // A special case is the loop body isn't entered at all. In that case, we may still
680 // add deoptimization due to the analysis described above. In order not to trigger
681 // deoptimization, we do a test between initial_ and end_ first and skip over
682 // the added deoptimization.
683 ValueRange* NarrowWithDeoptimization() {
684 if (increment_ != 1 && increment_ != -1) {
685 // In order not to trigger deoptimization unnecessarily, we want to
686 // make sure the loop iterates through the full range from initial_ to
687 // end_ so that boundaries are covered by the loop. An increment of 2,
688 // for example, may skip end_.
689 return this;
690 }
691
692 if (end_ == nullptr) {
693 // No full info to add deoptimization.
694 return this;
695 }
696
697 HBasicBlock* header = induction_variable_->GetBlock();
698 DCHECK(header->IsLoopHeader());
699 HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
700 if (!initial_->GetBlock()->Dominates(pre_header) ||
701 !end_->GetBlock()->Dominates(pre_header)) {
702 // Can't add a check in loop pre-header if the value isn't available there.
703 return this;
704 }
705
706 ArrayAccessInsideLoopFinder finder(induction_variable_);
707
708 if (!finder.HasFoundArrayLength()) {
709 // No array access was found inside the loop that can benefit
710 // from deoptimization.
711 return this;
712 }
713
714 if (!AddDeoptimization(finder)) {
715 return this;
716 }
717
718 // After added deoptimizations, induction variable fits in
719 // [-offset_low, array.length-1-offset_high], adjusted with collected offsets.
720 ValueBound lower = ValueBound(0, -finder.GetOffsetLow());
721 ValueBound upper = ValueBound(finder.GetFoundArrayLength(), -1 - finder.GetOffsetHigh());
722 // We've narrowed the range after added deoptimizations.
723 return new (GetAllocator()) ValueRange(GetAllocator(), lower, upper);
724 }
725
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700726 // Returns true if adding a (constant >= value) check for deoptimization
727 // is allowed and will benefit compiled code.
Mingyao Yang3584bce2015-05-19 16:01:59 -0700728 bool CanAddDeoptimizationConstant(HInstruction* value, int32_t constant, bool* is_proven) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700729 *is_proven = false;
Mingyao Yang3584bce2015-05-19 16:01:59 -0700730 HBasicBlock* header = induction_variable_->GetBlock();
731 DCHECK(header->IsLoopHeader());
732 HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
733 DCHECK(value->GetBlock()->Dominates(pre_header));
734
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700735 // See if we can prove the relationship first.
736 if (value->IsIntConstant()) {
737 if (value->AsIntConstant()->GetValue() >= constant) {
738 // Already true.
739 *is_proven = true;
740 return true;
741 } else {
742 // May throw exception. Don't add deoptimization.
743 // Keep bounds checks in the loops.
744 return false;
745 }
746 }
747 // Can benefit from deoptimization.
748 return true;
749 }
750
Mingyao Yang3584bce2015-05-19 16:01:59 -0700751 // Try to filter out cases that the loop entry test will never be true.
752 bool LoopEntryTestUseful() {
753 if (initial_->IsIntConstant() && end_->IsIntConstant()) {
754 int32_t initial_val = initial_->AsIntConstant()->GetValue();
755 int32_t end_val = end_->AsIntConstant()->GetValue();
756 if (increment_ == 1) {
757 if (inclusive_) {
758 return initial_val > end_val;
759 } else {
760 return initial_val >= end_val;
761 }
762 } else {
Andreas Gampe45d68f12015-06-10 18:33:26 -0700763 DCHECK_EQ(increment_, -1);
Mingyao Yang3584bce2015-05-19 16:01:59 -0700764 if (inclusive_) {
765 return initial_val < end_val;
766 } else {
767 return initial_val <= end_val;
768 }
769 }
770 }
771 return true;
772 }
773
774 // Returns the block for adding deoptimization.
775 HBasicBlock* TransformLoopForDeoptimizationIfNeeded() {
776 HBasicBlock* header = induction_variable_->GetBlock();
777 DCHECK(header->IsLoopHeader());
778 HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
779 // Deoptimization is only added when both initial_ and end_ are defined
780 // before the loop.
781 DCHECK(initial_->GetBlock()->Dominates(pre_header));
782 DCHECK(end_->GetBlock()->Dominates(pre_header));
783
784 // If it can be proven the loop body is definitely entered (unless exception
785 // is thrown in the loop header for which triggering deoptimization is fine),
786 // there is no need for tranforming the loop. In that case, deoptimization
787 // will just be added in the loop pre-header.
788 if (!LoopEntryTestUseful()) {
789 return pre_header;
790 }
791
792 HGraph* graph = header->GetGraph();
793 graph->TransformLoopHeaderForBCE(header);
794 HBasicBlock* new_pre_header = header->GetDominator();
795 DCHECK(new_pre_header == header->GetLoopInformation()->GetPreHeader());
796 HBasicBlock* if_block = new_pre_header->GetDominator();
Vladimir Marko60584552015-09-03 13:35:12 +0000797 HBasicBlock* dummy_block = if_block->GetSuccessor(0); // True successor.
798 HBasicBlock* deopt_block = if_block->GetSuccessor(1); // False successor.
Mingyao Yang3584bce2015-05-19 16:01:59 -0700799
800 dummy_block->AddInstruction(new (graph->GetArena()) HGoto());
801 deopt_block->AddInstruction(new (graph->GetArena()) HGoto());
802 new_pre_header->AddInstruction(new (graph->GetArena()) HGoto());
803 return deopt_block;
804 }
805
806 // Adds a test between initial_ and end_ to see if the loop body is entered.
807 // If the loop body isn't entered at all, it jumps to the loop pre-header (after
808 // transformation) to avoid any deoptimization.
809 void AddLoopBodyEntryTest() {
810 HBasicBlock* header = induction_variable_->GetBlock();
811 DCHECK(header->IsLoopHeader());
812 HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
813 HBasicBlock* if_block = pre_header->GetDominator();
814 HGraph* graph = header->GetGraph();
815
816 HCondition* cond;
817 if (increment_ == 1) {
818 if (inclusive_) {
819 cond = new (graph->GetArena()) HGreaterThan(initial_, end_);
820 } else {
821 cond = new (graph->GetArena()) HGreaterThanOrEqual(initial_, end_);
822 }
823 } else {
Andreas Gampe45d68f12015-06-10 18:33:26 -0700824 DCHECK_EQ(increment_, -1);
Mingyao Yang3584bce2015-05-19 16:01:59 -0700825 if (inclusive_) {
826 cond = new (graph->GetArena()) HLessThan(initial_, end_);
827 } else {
828 cond = new (graph->GetArena()) HLessThanOrEqual(initial_, end_);
829 }
830 }
831 HIf* h_if = new (graph->GetArena()) HIf(cond);
832 if_block->AddInstruction(cond);
833 if_block->AddInstruction(h_if);
834 }
835
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700836 // Adds a check that (value >= constant), and HDeoptimize otherwise.
837 void AddDeoptimizationConstant(HInstruction* value,
Mingyao Yang3584bce2015-05-19 16:01:59 -0700838 int32_t constant,
839 HBasicBlock* deopt_block,
840 bool loop_entry_test_block_added) {
841 HBasicBlock* header = induction_variable_->GetBlock();
842 DCHECK(header->IsLoopHeader());
843 HBasicBlock* pre_header = header->GetDominator();
844 if (loop_entry_test_block_added) {
Vladimir Marko60584552015-09-03 13:35:12 +0000845 DCHECK(deopt_block->GetSuccessor(0) == pre_header);
Mingyao Yang3584bce2015-05-19 16:01:59 -0700846 } else {
847 DCHECK(deopt_block == pre_header);
848 }
849 HGraph* graph = header->GetGraph();
850 HSuspendCheck* suspend_check = header->GetLoopInformation()->GetSuspendCheck();
851 if (loop_entry_test_block_added) {
Vladimir Marko60584552015-09-03 13:35:12 +0000852 DCHECK_EQ(deopt_block, header->GetDominator()->GetDominator()->GetSuccessor(1));
Mingyao Yang3584bce2015-05-19 16:01:59 -0700853 }
854
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700855 HIntConstant* const_instr = graph->GetIntConstant(constant);
856 HCondition* cond = new (graph->GetArena()) HLessThan(value, const_instr);
857 HDeoptimize* deoptimize = new (graph->GetArena())
858 HDeoptimize(cond, suspend_check->GetDexPc());
Mingyao Yang3584bce2015-05-19 16:01:59 -0700859 deopt_block->InsertInstructionBefore(cond, deopt_block->GetLastInstruction());
860 deopt_block->InsertInstructionBefore(deoptimize, deopt_block->GetLastInstruction());
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700861 deoptimize->CopyEnvironmentFromWithLoopPhiAdjustment(
Mingyao Yang3584bce2015-05-19 16:01:59 -0700862 suspend_check->GetEnvironment(), header);
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700863 }
864
865 // Returns true if adding a (value <= array_length + offset) check for deoptimization
866 // is allowed and will benefit compiled code.
867 bool CanAddDeoptimizationArrayLength(HInstruction* value,
868 HArrayLength* array_length,
869 int32_t offset,
870 bool* is_proven) {
871 *is_proven = false;
Mingyao Yang3584bce2015-05-19 16:01:59 -0700872 HBasicBlock* header = induction_variable_->GetBlock();
873 DCHECK(header->IsLoopHeader());
874 HBasicBlock* pre_header = header->GetLoopInformation()->GetPreHeader();
875 DCHECK(value->GetBlock()->Dominates(pre_header));
876
877 if (array_length->GetBlock() == header) {
878 // array_length_in_loop_body_if_needed only has correct value when the loop
879 // body is entered. We bail out in this case. Usually array_length defined
880 // in the loop header is already hoisted by licm.
881 return false;
882 } else {
883 // array_length is defined either before the loop header already, or in
884 // the loop body since it's used in the loop body. If it's defined in the loop body,
885 // a phi array_length_in_loop_body_if_needed is used to replace it. In that case,
886 // all the uses of array_length must be dominated by its definition in the loop
887 // body. array_length_in_loop_body_if_needed is guaranteed to be the same as
888 // array_length once the loop body is entered so all the uses of the phi will
889 // use the correct value.
890 }
891
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700892 if (offset > 0) {
893 // There might be overflow issue.
894 // TODO: handle this, possibly with some distance relationship between
895 // offset_low and offset_high, or using another deoptimization to make
896 // sure (array_length + offset) doesn't overflow.
897 return false;
898 }
899
900 // See if we can prove the relationship first.
901 if (value == array_length) {
902 if (offset >= 0) {
903 // Already true.
904 *is_proven = true;
905 return true;
906 } else {
907 // May throw exception. Don't add deoptimization.
908 // Keep bounds checks in the loops.
909 return false;
910 }
911 }
912 // Can benefit from deoptimization.
913 return true;
914 }
915
916 // Adds a check that (value <= array_length + offset), and HDeoptimize otherwise.
917 void AddDeoptimizationArrayLength(HInstruction* value,
918 HArrayLength* array_length,
Mingyao Yang3584bce2015-05-19 16:01:59 -0700919 int32_t offset,
920 HBasicBlock* deopt_block,
921 bool loop_entry_test_block_added) {
922 HBasicBlock* header = induction_variable_->GetBlock();
923 DCHECK(header->IsLoopHeader());
924 HBasicBlock* pre_header = header->GetDominator();
925 if (loop_entry_test_block_added) {
Vladimir Marko60584552015-09-03 13:35:12 +0000926 DCHECK(deopt_block->GetSuccessor(0) == pre_header);
Mingyao Yang3584bce2015-05-19 16:01:59 -0700927 } else {
928 DCHECK(deopt_block == pre_header);
929 }
930 HGraph* graph = header->GetGraph();
931 HSuspendCheck* suspend_check = header->GetLoopInformation()->GetSuspendCheck();
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700932
933 // We may need to hoist null-check and array_length out of loop first.
Mingyao Yang3584bce2015-05-19 16:01:59 -0700934 if (!array_length->GetBlock()->Dominates(deopt_block)) {
935 // array_length must be defined in the loop body.
936 DCHECK(header->GetLoopInformation()->Contains(*array_length->GetBlock()));
937 DCHECK(array_length->GetBlock() != header);
938
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700939 HInstruction* array = array_length->InputAt(0);
940 HNullCheck* null_check = array->AsNullCheck();
941 if (null_check != nullptr) {
942 array = null_check->InputAt(0);
943 }
Mingyao Yang3584bce2015-05-19 16:01:59 -0700944 // We've already made sure the array is defined before the loop when collecting
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700945 // array accesses for the loop.
Mingyao Yang3584bce2015-05-19 16:01:59 -0700946 DCHECK(array->GetBlock()->Dominates(deopt_block));
947 if (null_check != nullptr && !null_check->GetBlock()->Dominates(deopt_block)) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700948 // Hoist null check out of loop with a deoptimization.
949 HNullConstant* null_constant = graph->GetNullConstant();
950 HCondition* null_check_cond = new (graph->GetArena()) HEqual(array, null_constant);
951 // TODO: for one dex_pc, share the same deoptimization slow path.
952 HDeoptimize* null_check_deoptimize = new (graph->GetArena())
953 HDeoptimize(null_check_cond, suspend_check->GetDexPc());
Mingyao Yang3584bce2015-05-19 16:01:59 -0700954 deopt_block->InsertInstructionBefore(
955 null_check_cond, deopt_block->GetLastInstruction());
956 deopt_block->InsertInstructionBefore(
957 null_check_deoptimize, deopt_block->GetLastInstruction());
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700958 // Eliminate null check in the loop.
959 null_check->ReplaceWith(array);
960 null_check->GetBlock()->RemoveInstruction(null_check);
961 null_check_deoptimize->CopyEnvironmentFromWithLoopPhiAdjustment(
Mingyao Yang3584bce2015-05-19 16:01:59 -0700962 suspend_check->GetEnvironment(), header);
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700963 }
Mingyao Yang3584bce2015-05-19 16:01:59 -0700964
965 HArrayLength* new_array_length = new (graph->GetArena()) HArrayLength(array);
966 deopt_block->InsertInstructionBefore(new_array_length, deopt_block->GetLastInstruction());
967
968 if (loop_entry_test_block_added) {
969 // Replace array_length defined inside the loop body with a phi
970 // array_length_in_loop_body_if_needed. This is a synthetic phi so there is
971 // no vreg number for it.
972 HPhi* phi = new (graph->GetArena()) HPhi(
973 graph->GetArena(), kNoRegNumber, 2, Primitive::kPrimInt);
974 // Set to 0 if the loop body isn't entered.
975 phi->SetRawInputAt(0, graph->GetIntConstant(0));
976 // Set to array.length if the loop body is entered.
977 phi->SetRawInputAt(1, new_array_length);
978 pre_header->AddPhi(phi);
979 array_length->ReplaceWith(phi);
980 // Make sure phi is only used after the loop body is entered.
981 if (kIsDebugBuild) {
982 for (HUseIterator<HInstruction*> it(phi->GetUses());
983 !it.Done();
984 it.Advance()) {
985 HInstruction* user = it.Current()->GetUser();
986 DCHECK(GetLoopHeaderSuccesorInLoop()->Dominates(user->GetBlock()));
987 }
988 }
989 } else {
990 array_length->ReplaceWith(new_array_length);
991 }
992
993 array_length->GetBlock()->RemoveInstruction(array_length);
994 // Use new_array_length for deopt.
995 array_length = new_array_length;
Mingyao Yang206d6fd2015-04-13 16:46:28 -0700996 }
997
Mingyao Yang3584bce2015-05-19 16:01:59 -0700998 HInstruction* added = array_length;
999 if (offset != 0) {
1000 HIntConstant* offset_instr = graph->GetIntConstant(offset);
1001 added = new (graph->GetArena()) HAdd(Primitive::kPrimInt, array_length, offset_instr);
1002 deopt_block->InsertInstructionBefore(added, deopt_block->GetLastInstruction());
1003 }
1004 HCondition* cond = new (graph->GetArena()) HGreaterThan(value, added);
1005 HDeoptimize* deopt = new (graph->GetArena()) HDeoptimize(cond, suspend_check->GetDexPc());
1006 deopt_block->InsertInstructionBefore(cond, deopt_block->GetLastInstruction());
1007 deopt_block->InsertInstructionBefore(deopt, deopt_block->GetLastInstruction());
1008 deopt->CopyEnvironmentFromWithLoopPhiAdjustment(suspend_check->GetEnvironment(), header);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001009 }
1010
Mingyao Yang3584bce2015-05-19 16:01:59 -07001011 // Adds deoptimizations in loop pre-header with the collected array access
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001012 // data so that value ranges can be established in loop body.
1013 // Returns true if deoptimizations are successfully added, or if it's proven
1014 // it's not necessary.
1015 bool AddDeoptimization(const ArrayAccessInsideLoopFinder& finder) {
1016 int32_t offset_low = finder.GetOffsetLow();
1017 int32_t offset_high = finder.GetOffsetHigh();
1018 HArrayLength* array_length = finder.GetFoundArrayLength();
1019
1020 HBasicBlock* pre_header =
1021 induction_variable_->GetBlock()->GetLoopInformation()->GetPreHeader();
1022 if (!initial_->GetBlock()->Dominates(pre_header) ||
1023 !end_->GetBlock()->Dominates(pre_header)) {
1024 // Can't move initial_ or end_ into pre_header for comparisons.
1025 return false;
1026 }
1027
Mingyao Yang3584bce2015-05-19 16:01:59 -07001028 HBasicBlock* deopt_block;
1029 bool loop_entry_test_block_added = false;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001030 bool is_constant_proven, is_length_proven;
Mingyao Yang3584bce2015-05-19 16:01:59 -07001031
1032 HInstruction* const_comparing_instruction;
1033 int32_t const_compared_to;
1034 HInstruction* array_length_comparing_instruction;
1035 int32_t array_length_offset;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001036 if (increment_ == 1) {
1037 // Increasing from initial_ to end_.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001038 const_comparing_instruction = initial_;
1039 const_compared_to = -offset_low;
1040 array_length_comparing_instruction = end_;
1041 array_length_offset = inclusive_ ? -offset_high - 1 : -offset_high;
1042 } else {
1043 const_comparing_instruction = end_;
1044 const_compared_to = inclusive_ ? -offset_low : -offset_low - 1;
1045 array_length_comparing_instruction = initial_;
1046 array_length_offset = -offset_high - 1;
1047 }
1048
1049 if (CanAddDeoptimizationConstant(const_comparing_instruction,
1050 const_compared_to,
1051 &is_constant_proven) &&
1052 CanAddDeoptimizationArrayLength(array_length_comparing_instruction,
1053 array_length,
1054 array_length_offset,
1055 &is_length_proven)) {
1056 if (!is_constant_proven || !is_length_proven) {
1057 deopt_block = TransformLoopForDeoptimizationIfNeeded();
1058 loop_entry_test_block_added = (deopt_block != pre_header);
1059 if (loop_entry_test_block_added) {
1060 // Loop body may be entered.
1061 AddLoopBodyEntryTest();
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001062 }
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001063 }
Mingyao Yang3584bce2015-05-19 16:01:59 -07001064 if (!is_constant_proven) {
1065 AddDeoptimizationConstant(const_comparing_instruction,
1066 const_compared_to,
1067 deopt_block,
1068 loop_entry_test_block_added);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001069 }
Mingyao Yang3584bce2015-05-19 16:01:59 -07001070 if (!is_length_proven) {
1071 AddDeoptimizationArrayLength(array_length_comparing_instruction,
1072 array_length,
1073 array_length_offset,
1074 deopt_block,
1075 loop_entry_test_block_added);
1076 }
1077 return true;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001078 }
1079 return false;
1080 }
1081
Mingyao Yangf384f882014-10-22 16:08:18 -07001082 private:
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001083 HPhi* const induction_variable_; // Induction variable for this monotonic value range.
1084 HInstruction* const initial_; // Initial value.
1085 HInstruction* end_; // End value.
1086 bool inclusive_; // Whether end value is inclusive.
1087 const int32_t increment_; // Increment for each loop iteration.
1088 const ValueBound bound_; // Additional value bound info for initial_.
Mingyao Yangf384f882014-10-22 16:08:18 -07001089
1090 DISALLOW_COPY_AND_ASSIGN(MonotonicValueRange);
1091};
1092
1093class BCEVisitor : public HGraphVisitor {
1094 public:
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001095 // The least number of bounds checks that should be eliminated by triggering
1096 // the deoptimization technique.
1097 static constexpr size_t kThresholdForAddingDeoptimize = 2;
1098
1099 // Very large constant index is considered as an anomaly. This is a threshold
1100 // beyond which we don't bother to apply the deoptimization technique since
1101 // it's likely some AIOOBE will be thrown.
1102 static constexpr int32_t kMaxConstantForAddingDeoptimize = INT_MAX - 1024 * 1024;
1103
Mingyao Yang3584bce2015-05-19 16:01:59 -07001104 // Added blocks for loop body entry test.
1105 bool IsAddedBlock(HBasicBlock* block) const {
1106 return block->GetBlockId() >= initial_block_size_;
1107 }
1108
Aart Bik22af3be2015-09-10 12:50:58 -07001109 BCEVisitor(HGraph* graph, HInductionVarAnalysis* induction_analysis)
1110 : HGraphVisitor(graph),
Vladimir Markofa6b93c2015-09-15 10:15:55 +01001111 maps_(graph->GetBlocks().size()),
Aart Bik22af3be2015-09-10 12:50:58 -07001112 need_to_revisit_block_(false),
Vladimir Markofa6b93c2015-09-15 10:15:55 +01001113 initial_block_size_(graph->GetBlocks().size()),
Aart Bik22af3be2015-09-10 12:50:58 -07001114 induction_range_(induction_analysis) {}
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001115
1116 void VisitBasicBlock(HBasicBlock* block) OVERRIDE {
Mingyao Yang3584bce2015-05-19 16:01:59 -07001117 DCHECK(!IsAddedBlock(block));
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001118 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 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001128
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) {
Mingyao Yang3584bce2015-05-19 16:01:59 -07001132 if (IsAddedBlock(basic_block)) {
1133 // Added blocks don't keep value ranges.
1134 return nullptr;
1135 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001136 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);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001150 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));
Mingyao Yangf384f882014-10-22 16:08:18 -07001156 }
1157 basic_block = basic_block->GetDominator();
1158 }
1159 // Didn't find any.
1160 return nullptr;
1161 }
1162
Aart Bik22af3be2015-09-10 12:50:58 -07001163 // Return the range resulting from induction variable analysis of "instruction" when the value
1164 // is used from "context", for example, an index used from a bounds-check inside a loop body.
1165 ValueRange* LookupInductionRange(HInstruction* context, HInstruction* instruction) {
1166 InductionVarRange::Value v1 = induction_range_.GetMinInduction(context, instruction);
1167 InductionVarRange::Value v2 = induction_range_.GetMaxInduction(context, instruction);
1168 if ((v1.a_constant == 0 || v1.a_constant == 1) && v1.b_constant != INT_MIN &&
1169 (v2.a_constant == 0 || v2.a_constant == 1) && v2.b_constant != INT_MAX) {
1170 DCHECK(v1.a_constant == 1 || v1.instruction == nullptr);
1171 DCHECK(v2.a_constant == 1 || v2.instruction == nullptr);
1172 ValueBound low = ValueBound(v1.instruction, v1.b_constant);
1173 ValueBound up = ValueBound(v2.instruction, v2.b_constant);
1174 return new (GetGraph()->GetArena()) ValueRange(GetGraph()->GetArena(), low, up);
1175 }
1176 // Didn't find anything useful.
1177 return nullptr;
1178 }
1179
Mingyao Yang0304e182015-01-30 16:41:29 -08001180 // Narrow the value range of `instruction` at the end of `basic_block` with `range`,
1181 // and push the narrowed value range to `successor`.
Mingyao Yangf384f882014-10-22 16:08:18 -07001182 void ApplyRangeFromComparison(HInstruction* instruction, HBasicBlock* basic_block,
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001183 HBasicBlock* successor, ValueRange* range) {
Mingyao Yangf384f882014-10-22 16:08:18 -07001184 ValueRange* existing_range = LookupValueRange(instruction, basic_block);
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001185 if (existing_range == nullptr) {
1186 if (range != nullptr) {
1187 GetValueRangeMap(successor)->Overwrite(instruction->GetId(), range);
1188 }
1189 return;
1190 }
1191 if (existing_range->IsMonotonicValueRange()) {
1192 DCHECK(instruction->IsLoopHeaderPhi());
1193 // Make sure the comparison is in the loop header so each increment is
1194 // checked with a comparison.
1195 if (instruction->GetBlock() != basic_block) {
1196 return;
1197 }
1198 }
1199 ValueRange* narrowed_range = existing_range->Narrow(range);
Nicolas Geoffraya09ff9c2015-06-24 10:38:27 +01001200 GetValueRangeMap(successor)->Overwrite(instruction->GetId(), narrowed_range);
Mingyao Yangf384f882014-10-22 16:08:18 -07001201 }
1202
Mingyao Yang57e04752015-02-09 18:13:26 -08001203 // Special case that we may simultaneously narrow two MonotonicValueRange's to
1204 // regular value ranges.
1205 void HandleIfBetweenTwoMonotonicValueRanges(HIf* instruction,
1206 HInstruction* left,
1207 HInstruction* right,
1208 IfCondition cond,
1209 MonotonicValueRange* left_range,
1210 MonotonicValueRange* right_range) {
1211 DCHECK(left->IsLoopHeaderPhi());
1212 DCHECK(right->IsLoopHeaderPhi());
1213 if (instruction->GetBlock() != left->GetBlock()) {
1214 // Comparison needs to be in loop header to make sure it's done after each
1215 // increment/decrement.
1216 return;
1217 }
1218
1219 // Handle common cases which also don't have overflow/underflow concerns.
1220 if (left_range->GetIncrement() == 1 &&
1221 left_range->GetBound().IsConstant() &&
1222 right_range->GetIncrement() == -1 &&
1223 right_range->GetBound().IsRelatedToArrayLength() &&
1224 right_range->GetBound().GetConstant() < 0) {
Mingyao Yang57e04752015-02-09 18:13:26 -08001225 HBasicBlock* successor = nullptr;
1226 int32_t left_compensation = 0;
1227 int32_t right_compensation = 0;
1228 if (cond == kCondLT) {
1229 left_compensation = -1;
1230 right_compensation = 1;
1231 successor = instruction->IfTrueSuccessor();
1232 } else if (cond == kCondLE) {
1233 successor = instruction->IfTrueSuccessor();
1234 } else if (cond == kCondGT) {
1235 successor = instruction->IfFalseSuccessor();
1236 } else if (cond == kCondGE) {
1237 left_compensation = -1;
1238 right_compensation = 1;
1239 successor = instruction->IfFalseSuccessor();
1240 } else {
1241 // We don't handle '=='/'!=' test in case left and right can cross and
1242 // miss each other.
1243 return;
1244 }
1245
1246 if (successor != nullptr) {
1247 bool overflow;
1248 bool underflow;
1249 ValueRange* new_left_range = new (GetGraph()->GetArena()) ValueRange(
1250 GetGraph()->GetArena(),
1251 left_range->GetBound(),
1252 right_range->GetBound().Add(left_compensation, &overflow, &underflow));
1253 if (!overflow && !underflow) {
1254 ApplyRangeFromComparison(left, instruction->GetBlock(), successor,
1255 new_left_range);
1256 }
1257
1258 ValueRange* new_right_range = new (GetGraph()->GetArena()) ValueRange(
1259 GetGraph()->GetArena(),
1260 left_range->GetBound().Add(right_compensation, &overflow, &underflow),
1261 right_range->GetBound());
1262 if (!overflow && !underflow) {
1263 ApplyRangeFromComparison(right, instruction->GetBlock(), successor,
1264 new_right_range);
1265 }
1266 }
1267 }
1268 }
1269
Mingyao Yangf384f882014-10-22 16:08:18 -07001270 // Handle "if (left cmp_cond right)".
1271 void HandleIf(HIf* instruction, HInstruction* left, HInstruction* right, IfCondition cond) {
1272 HBasicBlock* block = instruction->GetBlock();
1273
1274 HBasicBlock* true_successor = instruction->IfTrueSuccessor();
1275 // There should be no critical edge at this point.
Vladimir Marko60584552015-09-03 13:35:12 +00001276 DCHECK_EQ(true_successor->GetPredecessors().size(), 1u);
Mingyao Yangf384f882014-10-22 16:08:18 -07001277
1278 HBasicBlock* false_successor = instruction->IfFalseSuccessor();
1279 // There should be no critical edge at this point.
Vladimir Marko60584552015-09-03 13:35:12 +00001280 DCHECK_EQ(false_successor->GetPredecessors().size(), 1u);
Mingyao Yangf384f882014-10-22 16:08:18 -07001281
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001282 ValueRange* left_range = LookupValueRange(left, block);
1283 MonotonicValueRange* left_monotonic_range = nullptr;
1284 if (left_range != nullptr) {
1285 left_monotonic_range = left_range->AsMonotonicValueRange();
1286 if (left_monotonic_range != nullptr) {
Mingyao Yang3584bce2015-05-19 16:01:59 -07001287 HBasicBlock* loop_head = left_monotonic_range->GetLoopHeader();
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001288 if (instruction->GetBlock() != loop_head) {
1289 // For monotonic value range, don't handle `instruction`
1290 // if it's not defined in the loop header.
1291 return;
1292 }
1293 }
1294 }
1295
Mingyao Yang64197522014-12-05 15:56:23 -08001296 bool found;
1297 ValueBound bound = ValueBound::DetectValueBoundFromValue(right, &found);
Mingyao Yang0304e182015-01-30 16:41:29 -08001298 // Each comparison can establish a lower bound and an upper bound
1299 // for the left hand side.
Mingyao Yangf384f882014-10-22 16:08:18 -07001300 ValueBound lower = bound;
1301 ValueBound upper = bound;
1302 if (!found) {
Mingyao Yang0304e182015-01-30 16:41:29 -08001303 // No constant or array.length+c format bound found.
Mingyao Yangf384f882014-10-22 16:08:18 -07001304 // For i<j, we can still use j's upper bound as i's upper bound. Same for lower.
Mingyao Yang57e04752015-02-09 18:13:26 -08001305 ValueRange* right_range = LookupValueRange(right, block);
1306 if (right_range != nullptr) {
1307 if (right_range->IsMonotonicValueRange()) {
Mingyao Yang57e04752015-02-09 18:13:26 -08001308 if (left_range != nullptr && left_range->IsMonotonicValueRange()) {
1309 HandleIfBetweenTwoMonotonicValueRanges(instruction, left, right, cond,
1310 left_range->AsMonotonicValueRange(),
1311 right_range->AsMonotonicValueRange());
1312 return;
1313 }
1314 }
1315 lower = right_range->GetLower();
1316 upper = right_range->GetUpper();
Mingyao Yangf384f882014-10-22 16:08:18 -07001317 } else {
1318 lower = ValueBound::Min();
1319 upper = ValueBound::Max();
1320 }
1321 }
1322
Mingyao Yang0304e182015-01-30 16:41:29 -08001323 bool overflow, underflow;
Mingyao Yangf384f882014-10-22 16:08:18 -07001324 if (cond == kCondLT || cond == kCondLE) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001325 if (left_monotonic_range != nullptr) {
1326 // Update the info for monotonic value range.
1327 if (left_monotonic_range->GetInductionVariable() == left &&
1328 left_monotonic_range->GetIncrement() < 0 &&
Mingyao Yang3584bce2015-05-19 16:01:59 -07001329 block == left_monotonic_range->GetLoopHeader() &&
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001330 instruction->IfFalseSuccessor()->GetLoopInformation() == block->GetLoopInformation()) {
1331 left_monotonic_range->SetEnd(right);
1332 left_monotonic_range->SetInclusive(cond == kCondLT);
1333 }
1334 }
1335
Mingyao Yangf384f882014-10-22 16:08:18 -07001336 if (!upper.Equals(ValueBound::Max())) {
Mingyao Yang0304e182015-01-30 16:41:29 -08001337 int32_t compensation = (cond == kCondLT) ? -1 : 0; // upper bound is inclusive
1338 ValueBound new_upper = upper.Add(compensation, &overflow, &underflow);
1339 if (overflow || underflow) {
1340 return;
Mingyao Yang64197522014-12-05 15:56:23 -08001341 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001342 ValueRange* new_range = new (GetGraph()->GetArena())
1343 ValueRange(GetGraph()->GetArena(), ValueBound::Min(), new_upper);
1344 ApplyRangeFromComparison(left, block, true_successor, new_range);
1345 }
1346
1347 // array.length as a lower bound isn't considered useful.
Mingyao Yang0304e182015-01-30 16:41:29 -08001348 if (!lower.Equals(ValueBound::Min()) && !lower.IsRelatedToArrayLength()) {
1349 int32_t compensation = (cond == kCondLE) ? 1 : 0; // lower bound is inclusive
1350 ValueBound new_lower = lower.Add(compensation, &overflow, &underflow);
1351 if (overflow || underflow) {
1352 return;
Mingyao Yang64197522014-12-05 15:56:23 -08001353 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001354 ValueRange* new_range = new (GetGraph()->GetArena())
1355 ValueRange(GetGraph()->GetArena(), new_lower, ValueBound::Max());
1356 ApplyRangeFromComparison(left, block, false_successor, new_range);
1357 }
1358 } else if (cond == kCondGT || cond == kCondGE) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001359 if (left_monotonic_range != nullptr) {
1360 // Update the info for monotonic value range.
1361 if (left_monotonic_range->GetInductionVariable() == left &&
1362 left_monotonic_range->GetIncrement() > 0 &&
Mingyao Yang3584bce2015-05-19 16:01:59 -07001363 block == left_monotonic_range->GetLoopHeader() &&
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001364 instruction->IfFalseSuccessor()->GetLoopInformation() == block->GetLoopInformation()) {
1365 left_monotonic_range->SetEnd(right);
1366 left_monotonic_range->SetInclusive(cond == kCondGT);
1367 }
1368 }
1369
Mingyao Yangf384f882014-10-22 16:08:18 -07001370 // array.length as a lower bound isn't considered useful.
Mingyao Yang0304e182015-01-30 16:41:29 -08001371 if (!lower.Equals(ValueBound::Min()) && !lower.IsRelatedToArrayLength()) {
1372 int32_t compensation = (cond == kCondGT) ? 1 : 0; // lower bound is inclusive
1373 ValueBound new_lower = lower.Add(compensation, &overflow, &underflow);
1374 if (overflow || underflow) {
1375 return;
Mingyao Yang64197522014-12-05 15:56:23 -08001376 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001377 ValueRange* new_range = new (GetGraph()->GetArena())
1378 ValueRange(GetGraph()->GetArena(), new_lower, ValueBound::Max());
1379 ApplyRangeFromComparison(left, block, true_successor, new_range);
1380 }
1381
1382 if (!upper.Equals(ValueBound::Max())) {
Mingyao Yang0304e182015-01-30 16:41:29 -08001383 int32_t compensation = (cond == kCondGE) ? -1 : 0; // upper bound is inclusive
1384 ValueBound new_upper = upper.Add(compensation, &overflow, &underflow);
1385 if (overflow || underflow) {
1386 return;
Mingyao Yang64197522014-12-05 15:56:23 -08001387 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001388 ValueRange* new_range = new (GetGraph()->GetArena())
1389 ValueRange(GetGraph()->GetArena(), ValueBound::Min(), new_upper);
1390 ApplyRangeFromComparison(left, block, false_successor, new_range);
1391 }
1392 }
1393 }
1394
1395 void VisitBoundsCheck(HBoundsCheck* bounds_check) {
1396 HBasicBlock* block = bounds_check->GetBlock();
1397 HInstruction* index = bounds_check->InputAt(0);
1398 HInstruction* array_length = bounds_check->InputAt(1);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001399 DCHECK(array_length->IsIntConstant() ||
1400 array_length->IsArrayLength() ||
1401 array_length->IsPhi());
1402
1403 if (array_length->IsPhi()) {
1404 // Input 1 of the phi contains the real array.length once the loop body is
1405 // entered. That value will be used for bound analysis. The graph is still
Nicolas Geoffray8df886b2015-06-24 14:57:44 +01001406 // strictly in SSA form.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001407 array_length = array_length->AsPhi()->InputAt(1)->AsArrayLength();
1408 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001409
Mingyao Yang0304e182015-01-30 16:41:29 -08001410 if (!index->IsIntConstant()) {
Aart Bik22af3be2015-09-10 12:50:58 -07001411 ValueBound lower = ValueBound(nullptr, 0); // constant 0
1412 ValueBound upper = ValueBound(array_length, -1); // array_length - 1
1413 ValueRange array_range(GetGraph()->GetArena(), lower, upper);
1414 // Try range obtained by local analysis.
Mingyao Yang0304e182015-01-30 16:41:29 -08001415 ValueRange* index_range = LookupValueRange(index, block);
Aart Bik22af3be2015-09-10 12:50:58 -07001416 if (index_range != nullptr && index_range->FitsIn(&array_range)) {
1417 ReplaceBoundsCheck(bounds_check, index);
1418 return;
1419 }
1420 // Try range obtained by induction variable analysis.
1421 index_range = LookupInductionRange(bounds_check, index);
1422 if (index_range != nullptr && index_range->FitsIn(&array_range)) {
1423 ReplaceBoundsCheck(bounds_check, index);
1424 return;
Mingyao Yangf384f882014-10-22 16:08:18 -07001425 }
Mingyao Yang0304e182015-01-30 16:41:29 -08001426 } else {
1427 int32_t constant = index->AsIntConstant()->GetValue();
1428 if (constant < 0) {
1429 // Will always throw exception.
1430 return;
1431 }
1432 if (array_length->IsIntConstant()) {
1433 if (constant < array_length->AsIntConstant()->GetValue()) {
1434 ReplaceBoundsCheck(bounds_check, index);
1435 }
1436 return;
1437 }
1438
1439 DCHECK(array_length->IsArrayLength());
1440 ValueRange* existing_range = LookupValueRange(array_length, block);
1441 if (existing_range != nullptr) {
1442 ValueBound lower = existing_range->GetLower();
1443 DCHECK(lower.IsConstant());
1444 if (constant < lower.GetConstant()) {
1445 ReplaceBoundsCheck(bounds_check, index);
1446 return;
1447 } else {
1448 // Existing range isn't strong enough to eliminate the bounds check.
1449 // Fall through to update the array_length range with info from this
1450 // bounds check.
1451 }
1452 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001453
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001454 if (first_constant_index_bounds_check_map_.find(array_length->GetId()) ==
1455 first_constant_index_bounds_check_map_.end()) {
1456 // Remember the first bounds check against array_length of a constant index.
1457 // That bounds check instruction has an associated HEnvironment where we
1458 // may add an HDeoptimize to eliminate bounds checks of constant indices
1459 // against array_length.
1460 first_constant_index_bounds_check_map_.Put(array_length->GetId(), bounds_check);
1461 } else {
1462 // We've seen it at least twice. It's beneficial to introduce a compare with
1463 // deoptimization fallback to eliminate the bounds checks.
1464 need_to_revisit_block_ = true;
1465 }
1466
Mingyao Yangf384f882014-10-22 16:08:18 -07001467 // Once we have an array access like 'array[5] = 1', we record array.length >= 6.
Mingyao Yang0304e182015-01-30 16:41:29 -08001468 // We currently don't do it for non-constant index since a valid array[i] can't prove
1469 // a valid array[i-1] yet due to the lower bound side.
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001470 if (constant == INT_MAX) {
1471 // INT_MAX as an index will definitely throw AIOOBE.
1472 return;
1473 }
Mingyao Yang64197522014-12-05 15:56:23 -08001474 ValueBound lower = ValueBound(nullptr, constant + 1);
Mingyao Yangf384f882014-10-22 16:08:18 -07001475 ValueBound upper = ValueBound::Max();
1476 ValueRange* range = new (GetGraph()->GetArena())
1477 ValueRange(GetGraph()->GetArena(), lower, upper);
Mingyao Yang0304e182015-01-30 16:41:29 -08001478 GetValueRangeMap(block)->Overwrite(array_length->GetId(), range);
Mingyao Yangf384f882014-10-22 16:08:18 -07001479 }
1480 }
1481
1482 void ReplaceBoundsCheck(HInstruction* bounds_check, HInstruction* index) {
1483 bounds_check->ReplaceWith(index);
1484 bounds_check->GetBlock()->RemoveInstruction(bounds_check);
1485 }
1486
Nicolas Geoffraydb216f42015-05-05 17:02:20 +01001487 static bool HasSameInputAtBackEdges(HPhi* phi) {
1488 DCHECK(phi->IsLoopHeaderPhi());
1489 // Start with input 1. Input 0 is from the incoming block.
1490 HInstruction* input1 = phi->InputAt(1);
1491 DCHECK(phi->GetBlock()->GetLoopInformation()->IsBackEdge(
Vladimir Marko60584552015-09-03 13:35:12 +00001492 *phi->GetBlock()->GetPredecessor(1)));
Nicolas Geoffraydb216f42015-05-05 17:02:20 +01001493 for (size_t i = 2, e = phi->InputCount(); i < e; ++i) {
1494 DCHECK(phi->GetBlock()->GetLoopInformation()->IsBackEdge(
Vladimir Marko60584552015-09-03 13:35:12 +00001495 *phi->GetBlock()->GetPredecessor(i)));
Nicolas Geoffraydb216f42015-05-05 17:02:20 +01001496 if (input1 != phi->InputAt(i)) {
1497 return false;
1498 }
1499 }
1500 return true;
1501 }
1502
Mingyao Yangf384f882014-10-22 16:08:18 -07001503 void VisitPhi(HPhi* phi) {
Nicolas Geoffraydb216f42015-05-05 17:02:20 +01001504 if (phi->IsLoopHeaderPhi()
1505 && (phi->GetType() == Primitive::kPrimInt)
1506 && HasSameInputAtBackEdges(phi)) {
Mingyao Yangf384f882014-10-22 16:08:18 -07001507 HInstruction* instruction = phi->InputAt(1);
Mingyao Yang0304e182015-01-30 16:41:29 -08001508 HInstruction *left;
1509 int32_t increment;
1510 if (ValueBound::IsAddOrSubAConstant(instruction, &left, &increment)) {
1511 if (left == phi) {
Mingyao Yangf384f882014-10-22 16:08:18 -07001512 HInstruction* initial_value = phi->InputAt(0);
1513 ValueRange* range = nullptr;
Mingyao Yang64197522014-12-05 15:56:23 -08001514 if (increment == 0) {
Mingyao Yangf384f882014-10-22 16:08:18 -07001515 // Add constant 0. It's really a fixed value.
1516 range = new (GetGraph()->GetArena()) ValueRange(
1517 GetGraph()->GetArena(),
Mingyao Yang64197522014-12-05 15:56:23 -08001518 ValueBound(initial_value, 0),
1519 ValueBound(initial_value, 0));
Mingyao Yangf384f882014-10-22 16:08:18 -07001520 } else {
1521 // Monotonically increasing/decreasing.
Mingyao Yang64197522014-12-05 15:56:23 -08001522 bool found;
1523 ValueBound bound = ValueBound::DetectValueBoundFromValue(
1524 initial_value, &found);
1525 if (!found) {
1526 // No constant or array.length+c bound found.
1527 // For i=j, we can still use j's upper bound as i's upper bound.
1528 // Same for lower.
1529 ValueRange* initial_range = LookupValueRange(initial_value, phi->GetBlock());
1530 if (initial_range != nullptr) {
1531 bound = increment > 0 ? initial_range->GetLower() :
1532 initial_range->GetUpper();
1533 } else {
1534 bound = increment > 0 ? ValueBound::Min() : ValueBound::Max();
1535 }
1536 }
1537 range = new (GetGraph()->GetArena()) MonotonicValueRange(
Mingyao Yangf384f882014-10-22 16:08:18 -07001538 GetGraph()->GetArena(),
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001539 phi,
Mingyao Yangf384f882014-10-22 16:08:18 -07001540 initial_value,
Mingyao Yang64197522014-12-05 15:56:23 -08001541 increment,
1542 bound);
Mingyao Yangf384f882014-10-22 16:08:18 -07001543 }
1544 GetValueRangeMap(phi->GetBlock())->Overwrite(phi->GetId(), range);
1545 }
1546 }
1547 }
1548 }
1549
1550 void VisitIf(HIf* instruction) {
1551 if (instruction->InputAt(0)->IsCondition()) {
1552 HCondition* cond = instruction->InputAt(0)->AsCondition();
1553 IfCondition cmp = cond->GetCondition();
1554 if (cmp == kCondGT || cmp == kCondGE ||
1555 cmp == kCondLT || cmp == kCondLE) {
1556 HInstruction* left = cond->GetLeft();
1557 HInstruction* right = cond->GetRight();
1558 HandleIf(instruction, left, right, cmp);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001559
1560 HBasicBlock* block = instruction->GetBlock();
1561 ValueRange* left_range = LookupValueRange(left, block);
1562 if (left_range == nullptr) {
1563 return;
1564 }
1565
1566 if (left_range->IsMonotonicValueRange() &&
Mingyao Yang3584bce2015-05-19 16:01:59 -07001567 block == left_range->AsMonotonicValueRange()->GetLoopHeader()) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001568 // The comparison is for an induction variable in the loop header.
1569 DCHECK(left == left_range->AsMonotonicValueRange()->GetInductionVariable());
Mingyao Yang3584bce2015-05-19 16:01:59 -07001570 HBasicBlock* loop_body_successor =
1571 left_range->AsMonotonicValueRange()->GetLoopHeaderSuccesorInLoop();
1572 if (loop_body_successor == nullptr) {
1573 // In case it's some strange loop structure.
1574 return;
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001575 }
1576 ValueRange* new_left_range = LookupValueRange(left, loop_body_successor);
Mingyao Yang3584bce2015-05-19 16:01:59 -07001577 if ((new_left_range == left_range) ||
1578 // Range narrowed with deoptimization is usually more useful than
1579 // a constant range.
1580 new_left_range->IsConstantValueRange()) {
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001581 // We are not successful in narrowing the monotonic value range to
1582 // a regular value range. Try using deoptimization.
1583 new_left_range = left_range->AsMonotonicValueRange()->
1584 NarrowWithDeoptimization();
1585 if (new_left_range != left_range) {
Mingyao Yang3584bce2015-05-19 16:01:59 -07001586 GetValueRangeMap(loop_body_successor)->Overwrite(left->GetId(), new_left_range);
Mingyao Yang206d6fd2015-04-13 16:46:28 -07001587 }
1588 }
1589 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001590 }
1591 }
1592 }
1593
1594 void VisitAdd(HAdd* add) {
1595 HInstruction* right = add->GetRight();
1596 if (right->IsIntConstant()) {
1597 ValueRange* left_range = LookupValueRange(add->GetLeft(), add->GetBlock());
1598 if (left_range == nullptr) {
1599 return;
1600 }
1601 ValueRange* range = left_range->Add(right->AsIntConstant()->GetValue());
1602 if (range != nullptr) {
1603 GetValueRangeMap(add->GetBlock())->Overwrite(add->GetId(), range);
1604 }
1605 }
1606 }
1607
1608 void VisitSub(HSub* sub) {
1609 HInstruction* left = sub->GetLeft();
1610 HInstruction* right = sub->GetRight();
1611 if (right->IsIntConstant()) {
1612 ValueRange* left_range = LookupValueRange(left, sub->GetBlock());
1613 if (left_range == nullptr) {
1614 return;
1615 }
1616 ValueRange* range = left_range->Add(-right->AsIntConstant()->GetValue());
1617 if (range != nullptr) {
1618 GetValueRangeMap(sub->GetBlock())->Overwrite(sub->GetId(), range);
1619 return;
1620 }
1621 }
1622
1623 // Here we are interested in the typical triangular case of nested loops,
1624 // such as the inner loop 'for (int j=0; j<array.length-i; j++)' where i
1625 // is the index for outer loop. In this case, we know j is bounded by array.length-1.
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001626
1627 // Try to handle (array.length - i) or (array.length + c - i) format.
1628 HInstruction* left_of_left; // left input of left.
1629 int32_t right_const = 0;
1630 if (ValueBound::IsAddOrSubAConstant(left, &left_of_left, &right_const)) {
1631 left = left_of_left;
1632 }
1633 // The value of left input of the sub equals (left + right_const).
1634
Mingyao Yangf384f882014-10-22 16:08:18 -07001635 if (left->IsArrayLength()) {
1636 HInstruction* array_length = left->AsArrayLength();
1637 ValueRange* right_range = LookupValueRange(right, sub->GetBlock());
1638 if (right_range != nullptr) {
1639 ValueBound lower = right_range->GetLower();
1640 ValueBound upper = right_range->GetUpper();
Mingyao Yang0304e182015-01-30 16:41:29 -08001641 if (lower.IsConstant() && upper.IsRelatedToArrayLength()) {
Mingyao Yangf384f882014-10-22 16:08:18 -07001642 HInstruction* upper_inst = upper.GetInstruction();
Mingyao Yang0304e182015-01-30 16:41:29 -08001643 // Make sure it's the same array.
1644 if (ValueBound::Equal(array_length, upper_inst)) {
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001645 int32_t c0 = right_const;
1646 int32_t c1 = lower.GetConstant();
1647 int32_t c2 = upper.GetConstant();
1648 // (array.length + c0 - v) where v is in [c1, array.length + c2]
1649 // gets [c0 - c2, array.length + c0 - c1] as its value range.
1650 if (!ValueBound::WouldAddOverflowOrUnderflow(c0, -c2) &&
1651 !ValueBound::WouldAddOverflowOrUnderflow(c0, -c1)) {
1652 if ((c0 - c1) <= 0) {
1653 // array.length + (c0 - c1) won't overflow/underflow.
1654 ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
1655 GetGraph()->GetArena(),
1656 ValueBound(nullptr, right_const - upper.GetConstant()),
1657 ValueBound(array_length, right_const - lower.GetConstant()));
1658 GetValueRangeMap(sub->GetBlock())->Overwrite(sub->GetId(), range);
1659 }
1660 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001661 }
1662 }
1663 }
1664 }
1665 }
1666
Mingyao Yang8c8bad82015-02-09 18:13:26 -08001667 void FindAndHandlePartialArrayLength(HBinaryOperation* instruction) {
1668 DCHECK(instruction->IsDiv() || instruction->IsShr() || instruction->IsUShr());
1669 HInstruction* right = instruction->GetRight();
1670 int32_t right_const;
1671 if (right->IsIntConstant()) {
1672 right_const = right->AsIntConstant()->GetValue();
1673 // Detect division by two or more.
1674 if ((instruction->IsDiv() && right_const <= 1) ||
1675 (instruction->IsShr() && right_const < 1) ||
1676 (instruction->IsUShr() && right_const < 1)) {
1677 return;
1678 }
1679 } else {
1680 return;
1681 }
1682
1683 // Try to handle array.length/2 or (array.length-1)/2 format.
1684 HInstruction* left = instruction->GetLeft();
1685 HInstruction* left_of_left; // left input of left.
1686 int32_t c = 0;
1687 if (ValueBound::IsAddOrSubAConstant(left, &left_of_left, &c)) {
1688 left = left_of_left;
1689 }
1690 // The value of left input of instruction equals (left + c).
1691
1692 // (array_length + 1) or smaller divided by two or more
1693 // always generate a value in [INT_MIN, array_length].
1694 // This is true even if array_length is INT_MAX.
1695 if (left->IsArrayLength() && c <= 1) {
1696 if (instruction->IsUShr() && c < 0) {
1697 // Make sure for unsigned shift, left side is not negative.
1698 // e.g. if array_length is 2, ((array_length - 3) >>> 2) is way bigger
1699 // than array_length.
1700 return;
1701 }
1702 ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
1703 GetGraph()->GetArena(),
1704 ValueBound(nullptr, INT_MIN),
1705 ValueBound(left, 0));
1706 GetValueRangeMap(instruction->GetBlock())->Overwrite(instruction->GetId(), range);
1707 }
1708 }
1709
1710 void VisitDiv(HDiv* div) {
1711 FindAndHandlePartialArrayLength(div);
1712 }
1713
1714 void VisitShr(HShr* shr) {
1715 FindAndHandlePartialArrayLength(shr);
1716 }
1717
1718 void VisitUShr(HUShr* ushr) {
1719 FindAndHandlePartialArrayLength(ushr);
1720 }
1721
Mingyao Yang4559f002015-02-27 14:43:53 -08001722 void VisitAnd(HAnd* instruction) {
1723 if (instruction->GetRight()->IsIntConstant()) {
1724 int32_t constant = instruction->GetRight()->AsIntConstant()->GetValue();
1725 if (constant > 0) {
1726 // constant serves as a mask so any number masked with it
1727 // gets a [0, constant] value range.
1728 ValueRange* range = new (GetGraph()->GetArena()) ValueRange(
1729 GetGraph()->GetArena(),
1730 ValueBound(nullptr, 0),
1731 ValueBound(nullptr, constant));
1732 GetValueRangeMap(instruction->GetBlock())->Overwrite(instruction->GetId(), range);
1733 }
1734 }
1735 }
1736
Mingyao Yang0304e182015-01-30 16:41:29 -08001737 void VisitNewArray(HNewArray* new_array) {
1738 HInstruction* len = new_array->InputAt(0);
1739 if (!len->IsIntConstant()) {
1740 HInstruction *left;
1741 int32_t right_const;
1742 if (ValueBound::IsAddOrSubAConstant(len, &left, &right_const)) {
1743 // (left + right_const) is used as size to new the array.
1744 // We record "-right_const <= left <= new_array - right_const";
1745 ValueBound lower = ValueBound(nullptr, -right_const);
1746 // We use new_array for the bound instead of new_array.length,
1747 // which isn't available as an instruction yet. new_array will
1748 // be treated the same as new_array.length when it's used in a ValueBound.
1749 ValueBound upper = ValueBound(new_array, -right_const);
1750 ValueRange* range = new (GetGraph()->GetArena())
1751 ValueRange(GetGraph()->GetArena(), lower, upper);
Nicolas Geoffraya09ff9c2015-06-24 10:38:27 +01001752 ValueRange* existing_range = LookupValueRange(left, new_array->GetBlock());
1753 if (existing_range != nullptr) {
1754 range = existing_range->Narrow(range);
1755 }
Mingyao Yang0304e182015-01-30 16:41:29 -08001756 GetValueRangeMap(new_array->GetBlock())->Overwrite(left->GetId(), range);
1757 }
1758 }
1759 }
1760
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001761 void VisitDeoptimize(HDeoptimize* deoptimize) {
1762 // Right now it's only HLessThanOrEqual.
1763 DCHECK(deoptimize->InputAt(0)->IsLessThanOrEqual());
1764 HLessThanOrEqual* less_than_or_equal = deoptimize->InputAt(0)->AsLessThanOrEqual();
1765 HInstruction* instruction = less_than_or_equal->InputAt(0);
1766 if (instruction->IsArrayLength()) {
1767 HInstruction* constant = less_than_or_equal->InputAt(1);
1768 DCHECK(constant->IsIntConstant());
1769 DCHECK(constant->AsIntConstant()->GetValue() <= kMaxConstantForAddingDeoptimize);
1770 ValueBound lower = ValueBound(nullptr, constant->AsIntConstant()->GetValue() + 1);
1771 ValueRange* range = new (GetGraph()->GetArena())
1772 ValueRange(GetGraph()->GetArena(), lower, ValueBound::Max());
1773 GetValueRangeMap(deoptimize->GetBlock())->Overwrite(instruction->GetId(), range);
1774 }
1775 }
1776
1777 void AddCompareWithDeoptimization(HInstruction* array_length,
1778 HIntConstant* const_instr,
1779 HBasicBlock* block) {
1780 DCHECK(array_length->IsArrayLength());
1781 ValueRange* range = LookupValueRange(array_length, block);
1782 ValueBound lower_bound = range->GetLower();
1783 DCHECK(lower_bound.IsConstant());
1784 DCHECK(const_instr->GetValue() <= kMaxConstantForAddingDeoptimize);
Nicolas Geoffray8d82a0c2015-06-20 23:49:01 +01001785 // Note that the lower bound of the array length may have been refined
1786 // through other instructions (such as `HNewArray(length - 4)`).
1787 DCHECK_LE(const_instr->GetValue() + 1, lower_bound.GetConstant());
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001788
1789 // If array_length is less than lower_const, deoptimize.
1790 HBoundsCheck* bounds_check = first_constant_index_bounds_check_map_.Get(
1791 array_length->GetId())->AsBoundsCheck();
1792 HCondition* cond = new (GetGraph()->GetArena()) HLessThanOrEqual(array_length, const_instr);
1793 HDeoptimize* deoptimize = new (GetGraph()->GetArena())
1794 HDeoptimize(cond, bounds_check->GetDexPc());
1795 block->InsertInstructionBefore(cond, bounds_check);
1796 block->InsertInstructionBefore(deoptimize, bounds_check);
Nicolas Geoffray3dcd58c2015-04-03 11:02:38 +01001797 deoptimize->CopyEnvironmentFrom(bounds_check->GetEnvironment());
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001798 }
1799
1800 void AddComparesWithDeoptimization(HBasicBlock* block) {
1801 for (ArenaSafeMap<int, HBoundsCheck*>::iterator it =
1802 first_constant_index_bounds_check_map_.begin();
1803 it != first_constant_index_bounds_check_map_.end();
1804 ++it) {
1805 HBoundsCheck* bounds_check = it->second;
Nicolas Geoffray8df886b2015-06-24 14:57:44 +01001806 HInstruction* array_length = bounds_check->InputAt(1);
1807 if (!array_length->IsArrayLength()) {
1808 // Prior deoptimizations may have changed the array length to a phi.
1809 // TODO(mingyao): propagate the range to the phi?
1810 DCHECK(array_length->IsPhi()) << array_length->DebugName();
1811 continue;
1812 }
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001813 HIntConstant* lower_bound_const_instr = nullptr;
1814 int32_t lower_bound_const = INT_MIN;
1815 size_t counter = 0;
1816 // Count the constant indexing for which bounds checks haven't
1817 // been removed yet.
1818 for (HUseIterator<HInstruction*> it2(array_length->GetUses());
1819 !it2.Done();
1820 it2.Advance()) {
1821 HInstruction* user = it2.Current()->GetUser();
1822 if (user->GetBlock() == block &&
1823 user->IsBoundsCheck() &&
1824 user->AsBoundsCheck()->InputAt(0)->IsIntConstant()) {
1825 DCHECK_EQ(array_length, user->AsBoundsCheck()->InputAt(1));
1826 HIntConstant* const_instr = user->AsBoundsCheck()->InputAt(0)->AsIntConstant();
1827 if (const_instr->GetValue() > lower_bound_const) {
1828 lower_bound_const = const_instr->GetValue();
1829 lower_bound_const_instr = const_instr;
1830 }
1831 counter++;
1832 }
1833 }
1834 if (counter >= kThresholdForAddingDeoptimize &&
1835 lower_bound_const_instr->GetValue() <= kMaxConstantForAddingDeoptimize) {
1836 AddCompareWithDeoptimization(array_length, lower_bound_const_instr, block);
1837 }
1838 }
1839 }
1840
Mingyao Yangf384f882014-10-22 16:08:18 -07001841 std::vector<std::unique_ptr<ArenaSafeMap<int, ValueRange*>>> maps_;
1842
Mingyao Yangd43b3ac2015-04-01 14:03:04 -07001843 // Map an HArrayLength instruction's id to the first HBoundsCheck instruction in
1844 // a block that checks a constant index against that HArrayLength.
1845 SafeMap<int, HBoundsCheck*> first_constant_index_bounds_check_map_;
1846
1847 // For the block, there is at least one HArrayLength instruction for which there
1848 // is more than one bounds check instruction with constant indexing. And it's
1849 // beneficial to add a compare instruction that has deoptimization fallback and
1850 // eliminate those bounds checks.
1851 bool need_to_revisit_block_;
1852
Mingyao Yang3584bce2015-05-19 16:01:59 -07001853 // Initial number of blocks.
Vladimir Markofa6b93c2015-09-15 10:15:55 +01001854 uint32_t initial_block_size_;
Mingyao Yang3584bce2015-05-19 16:01:59 -07001855
Aart Bik22af3be2015-09-10 12:50:58 -07001856 // Range analysis based on induction variables.
1857 InductionVarRange induction_range_;
1858
Mingyao Yangf384f882014-10-22 16:08:18 -07001859 DISALLOW_COPY_AND_ASSIGN(BCEVisitor);
1860};
1861
1862void BoundsCheckElimination::Run() {
Mark Mendell1152c922015-04-24 17:06:35 -04001863 if (!graph_->HasBoundsChecks()) {
Mingyao Yange4335eb2015-03-02 15:14:13 -08001864 return;
1865 }
1866
Aart Bik22af3be2015-09-10 12:50:58 -07001867 BCEVisitor visitor(graph_, induction_analysis_);
Mingyao Yangf384f882014-10-22 16:08:18 -07001868 // Reverse post order guarantees a node's dominators are visited first.
1869 // We want to visit in the dominator-based order since if a value is known to
1870 // be bounded by a range at one instruction, it must be true that all uses of
1871 // that value dominated by that instruction fits in that range. Range of that
1872 // value can be narrowed further down in the dominator tree.
1873 //
1874 // TODO: only visit blocks that dominate some array accesses.
Mingyao Yang3584bce2015-05-19 16:01:59 -07001875 HBasicBlock* last_visited_block = nullptr;
1876 for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) {
1877 HBasicBlock* current = it.Current();
1878 if (current == last_visited_block) {
1879 // We may insert blocks into the reverse post order list when processing
1880 // a loop header. Don't process it again.
1881 DCHECK(current->IsLoopHeader());
1882 continue;
1883 }
1884 if (visitor.IsAddedBlock(current)) {
1885 // Skip added blocks. Their effects are already taken care of.
1886 continue;
1887 }
1888 visitor.VisitBasicBlock(current);
1889 last_visited_block = current;
1890 }
Mingyao Yangf384f882014-10-22 16:08:18 -07001891}
1892
1893} // namespace art