Index: src/hydrogen-bce.cc |
diff --git a/src/hydrogen-bce.cc b/src/hydrogen-bce.cc |
index 65c2b142c5f3c803a5a3533b57e9c9cb28ba43fa..c72a8c55d865f7bfdf4c7e21c675a710fd3b9ddd 100644 |
--- a/src/hydrogen-bce.cc |
+++ b/src/hydrogen-bce.cc |
@@ -54,6 +54,9 @@ class BoundsCheckKey : public ZoneObject { |
constant = HConstant::cast(index->right()); |
index_base = index->left(); |
} |
+ } else if (check->index()->IsConstant()) { |
+ index_base = check->block()->graph()->GetConstant0(); |
+ constant = HConstant::cast(check->index()); |
} |
if (constant != NULL && constant->HasInteger32Value()) { |
@@ -222,41 +225,56 @@ class BoundsCheckBbData: public ZoneObject { |
void MoveIndexIfNecessary(HValue* index_raw, |
HBoundsCheck* insert_before, |
HInstruction* end_of_scan_range) { |
- if (!index_raw->IsAdd() && !index_raw->IsSub()) { |
- // index_raw can be HAdd(index_base, offset), HSub(index_base, offset), |
- // or index_base directly. In the latter case, no need to move anything. |
- return; |
- } |
- HArithmeticBinaryOperation* index = |
- HArithmeticBinaryOperation::cast(index_raw); |
- HValue* left_input = index->left(); |
- HValue* right_input = index->right(); |
- bool must_move_index = false; |
- bool must_move_left_input = false; |
- bool must_move_right_input = false; |
- for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) { |
- if (cursor == left_input) must_move_left_input = true; |
- if (cursor == right_input) must_move_right_input = true; |
- if (cursor == index) must_move_index = true; |
- if (cursor->previous() == NULL) { |
- cursor = cursor->block()->dominator()->end(); |
- } else { |
- cursor = cursor->previous(); |
+ // index_raw can be HAdd(index_base, offset), HSub(index_base, offset), |
+ // HConstant(offset) or index_base directly. |
+ // In the latter case, no need to move anything. |
+ if (index_raw->IsAdd() || index_raw->IsSub()) { |
+ HArithmeticBinaryOperation* index = |
+ HArithmeticBinaryOperation::cast(index_raw); |
+ HValue* left_input = index->left(); |
+ HValue* right_input = index->right(); |
+ bool must_move_index = false; |
+ bool must_move_left_input = false; |
+ bool must_move_right_input = false; |
+ for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) { |
+ if (cursor == left_input) must_move_left_input = true; |
+ if (cursor == right_input) must_move_right_input = true; |
+ if (cursor == index) must_move_index = true; |
+ if (cursor->previous() == NULL) { |
+ cursor = cursor->block()->dominator()->end(); |
+ } else { |
+ cursor = cursor->previous(); |
+ } |
+ } |
+ if (must_move_index) { |
+ index->Unlink(); |
+ index->InsertBefore(insert_before); |
+ } |
+ // The BCE algorithm only selects mergeable bounds checks that share |
+ // the same "index_base", so we'll only ever have to move constants. |
+ if (must_move_left_input) { |
+ HConstant::cast(left_input)->Unlink(); |
+ HConstant::cast(left_input)->InsertBefore(index); |
+ } |
+ if (must_move_right_input) { |
+ HConstant::cast(right_input)->Unlink(); |
+ HConstant::cast(right_input)->InsertBefore(index); |
+ } |
+ } else if (index_raw->IsConstant()) { |
+ HConstant* index = HConstant::cast(index_raw); |
+ bool must_move = false; |
+ for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) { |
+ if (cursor == index) must_move = true; |
+ if (cursor->previous() == NULL) { |
+ cursor = cursor->block()->dominator()->end(); |
+ } else { |
+ cursor = cursor->previous(); |
+ } |
+ } |
+ if (must_move) { |
+ index->Unlink(); |
+ index->InsertBefore(insert_before); |
} |
- } |
- if (must_move_index) { |
- index->Unlink(); |
- index->InsertBefore(insert_before); |
- } |
- // The BCE algorithm only selects mergeable bounds checks that share |
- // the same "index_base", so we'll only ever have to move constants. |
- if (must_move_left_input) { |
- HConstant::cast(left_input)->Unlink(); |
- HConstant::cast(left_input)->InsertBefore(index); |
- } |
- if (must_move_right_input) { |
- HConstant::cast(right_input)->Unlink(); |
- HConstant::cast(right_input)->InsertBefore(index); |
} |
} |