|
|
e93883 |
From fd80a31e0697d6317ce8c2d289575399f4e06d21 Mon Sep 17 00:00:00 2001
|
|
|
e93883 |
From: Fedor Indutny <fedor@indutny.com>
|
|
|
e93883 |
Date: Thu, 14 Aug 2014 19:29:28 +0400
|
|
|
e93883 |
Subject: [PATCH] deps: backport 5f836c from v8 upstream
|
|
|
e93883 |
|
|
|
e93883 |
Original commit message:
|
|
|
e93883 |
|
|
|
e93883 |
Fix Hydrogen bounds check elimination
|
|
|
e93883 |
|
|
|
e93883 |
When combining bounds checks, they must all be moved before the first load/store
|
|
|
e93883 |
that they are guarding.
|
|
|
e93883 |
|
|
|
e93883 |
BUG=chromium:344186
|
|
|
e93883 |
LOG=y
|
|
|
e93883 |
R=svenpanne@chromium.org
|
|
|
e93883 |
|
|
|
e93883 |
Review URL: https://codereview.chromium.org/172093002
|
|
|
e93883 |
|
|
|
e93883 |
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@19475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
|
|
|
e93883 |
|
|
|
e93883 |
fix #8070
|
|
|
e93883 |
---
|
|
|
e93883 |
src/hydrogen.cc | 106 +++++++++++++++++++++++-------------------------
|
|
|
e93883 |
1 file changed, 50 insertions(+), 56 deletions(-)
|
|
|
e93883 |
|
|
|
e93883 |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
|
|
e93883 |
index e3f79ee..50d8e49 100644
|
|
|
e93883 |
--- a/src/hydrogen.cc
|
|
|
e93883 |
+++ b/src/hydrogen.cc
|
|
|
e93883 |
@@ -3487,13 +3487,7 @@ class BoundsCheckBbData: public ZoneObject {
|
|
|
e93883 |
keep_new_check = true;
|
|
|
e93883 |
upper_check_ = new_check;
|
|
|
e93883 |
} else {
|
|
|
e93883 |
- BuildOffsetAdd(upper_check_,
|
|
|
e93883 |
- &added_upper_index_,
|
|
|
e93883 |
- &added_upper_offset_,
|
|
|
e93883 |
- Key()->IndexBase(),
|
|
|
e93883 |
- new_check->index()->representation(),
|
|
|
e93883 |
- new_offset);
|
|
|
e93883 |
- upper_check_->SetOperandAt(0, added_upper_index_);
|
|
|
e93883 |
+ TightenCheck(upper_check_, new_check);
|
|
|
e93883 |
}
|
|
|
e93883 |
} else if (new_offset < lower_offset_) {
|
|
|
e93883 |
lower_offset_ = new_offset;
|
|
|
e93883 |
@@ -3501,28 +3495,27 @@ class BoundsCheckBbData: public ZoneObject {
|
|
|
e93883 |
keep_new_check = true;
|
|
|
e93883 |
lower_check_ = new_check;
|
|
|
e93883 |
} else {
|
|
|
e93883 |
- BuildOffsetAdd(lower_check_,
|
|
|
e93883 |
- &added_lower_index_,
|
|
|
e93883 |
- &added_lower_offset_,
|
|
|
e93883 |
- Key()->IndexBase(),
|
|
|
e93883 |
- new_check->index()->representation(),
|
|
|
e93883 |
- new_offset);
|
|
|
e93883 |
- lower_check_->SetOperandAt(0, added_lower_index_);
|
|
|
e93883 |
+ TightenCheck(lower_check_, new_check);
|
|
|
e93883 |
}
|
|
|
e93883 |
} else {
|
|
|
e93883 |
- ASSERT(false);
|
|
|
e93883 |
+ // Should never have called CoverCheck() in this case.
|
|
|
e93883 |
+ UNREACHABLE();
|
|
|
e93883 |
}
|
|
|
e93883 |
|
|
|
e93883 |
if (!keep_new_check) {
|
|
|
e93883 |
new_check->DeleteAndReplaceWith(NULL);
|
|
|
e93883 |
+ } else {
|
|
|
e93883 |
+ HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_
|
|
|
e93883 |
+ : lower_check_;
|
|
|
e93883 |
+ // The length is guaranteed to be live at first_check.
|
|
|
e93883 |
+ ASSERT(new_check->length() == first_check->length());
|
|
|
e93883 |
+ HInstruction* old_position = new_check->next();
|
|
|
e93883 |
+ new_check->Unlink();
|
|
|
e93883 |
+ new_check->InsertAfter(first_check);
|
|
|
e93883 |
+ MoveIndexIfNecessary(new_check->index(), new_check, old_position);
|
|
|
e93883 |
}
|
|
|
e93883 |
}
|
|
|
e93883 |
|
|
|
e93883 |
- void RemoveZeroOperations() {
|
|
|
e93883 |
- RemoveZeroAdd(&added_lower_index_, &added_lower_offset_);
|
|
|
e93883 |
- RemoveZeroAdd(&added_upper_index_, &added_upper_offset_);
|
|
|
e93883 |
- }
|
|
|
e93883 |
-
|
|
|
e93883 |
BoundsCheckBbData(BoundsCheckKey* key,
|
|
|
e93883 |
int32_t lower_offset,
|
|
|
e93883 |
int32_t upper_offset,
|
|
|
e93883 |
@@ -3537,10 +3530,6 @@ class BoundsCheckBbData: public ZoneObject {
|
|
|
e93883 |
basic_block_(bb),
|
|
|
e93883 |
lower_check_(lower_check),
|
|
|
e93883 |
upper_check_(upper_check),
|
|
|
e93883 |
- added_lower_index_(NULL),
|
|
|
e93883 |
- added_lower_offset_(NULL),
|
|
|
e93883 |
- added_upper_index_(NULL),
|
|
|
e93883 |
- added_upper_offset_(NULL),
|
|
|
e93883 |
next_in_bb_(next_in_bb),
|
|
|
e93883 |
father_in_dt_(father_in_dt) { }
|
|
|
e93883 |
|
|
|
e93883 |
@@ -3551,44 +3540,50 @@ class BoundsCheckBbData: public ZoneObject {
|
|
|
e93883 |
HBasicBlock* basic_block_;
|
|
|
e93883 |
HBoundsCheck* lower_check_;
|
|
|
e93883 |
HBoundsCheck* upper_check_;
|
|
|
e93883 |
- HAdd* added_lower_index_;
|
|
|
e93883 |
- HConstant* added_lower_offset_;
|
|
|
e93883 |
- HAdd* added_upper_index_;
|
|
|
e93883 |
- HConstant* added_upper_offset_;
|
|
|
e93883 |
BoundsCheckBbData* next_in_bb_;
|
|
|
e93883 |
BoundsCheckBbData* father_in_dt_;
|
|
|
e93883 |
|
|
|
e93883 |
- void BuildOffsetAdd(HBoundsCheck* check,
|
|
|
e93883 |
- HAdd** add,
|
|
|
e93883 |
- HConstant** constant,
|
|
|
e93883 |
- HValue* original_value,
|
|
|
e93883 |
- Representation representation,
|
|
|
e93883 |
- int32_t new_offset) {
|
|
|
e93883 |
- HConstant* new_constant = new(BasicBlock()->zone())
|
|
|
e93883 |
- HConstant(new_offset, Representation::Integer32());
|
|
|
e93883 |
- if (*add == NULL) {
|
|
|
e93883 |
- new_constant->InsertBefore(check);
|
|
|
e93883 |
- // Because of the bounds checks elimination algorithm, the index is always
|
|
|
e93883 |
- // an HAdd or an HSub here, so we can safely cast to an HBinaryOperation.
|
|
|
e93883 |
- HValue* context = HBinaryOperation::cast(check->index())->context();
|
|
|
e93883 |
- *add = new(BasicBlock()->zone()) HAdd(context,
|
|
|
e93883 |
- original_value,
|
|
|
e93883 |
- new_constant);
|
|
|
e93883 |
- (*add)->AssumeRepresentation(representation);
|
|
|
e93883 |
- (*add)->InsertBefore(check);
|
|
|
e93883 |
- } else {
|
|
|
e93883 |
- new_constant->InsertBefore(*add);
|
|
|
e93883 |
- (*constant)->DeleteAndReplaceWith(new_constant);
|
|
|
e93883 |
+ void MoveIndexIfNecessary(HValue* index_raw,
|
|
|
e93883 |
+ HBoundsCheck* insert_before,
|
|
|
e93883 |
+ HInstruction* end_of_scan_range) {
|
|
|
e93883 |
+ ASSERT(index_raw->IsAdd() || index_raw->IsSub());
|
|
|
e93883 |
+ HBinaryOperation* index =
|
|
|
e93883 |
+ HArithmeticBinaryOperation::cast(index_raw);
|
|
|
e93883 |
+ HValue* left_input = index->left();
|
|
|
e93883 |
+ HValue* right_input = index->right();
|
|
|
e93883 |
+ bool must_move_index = false;
|
|
|
e93883 |
+ bool must_move_left_input = false;
|
|
|
e93883 |
+ bool must_move_right_input = false;
|
|
|
e93883 |
+ for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) {
|
|
|
e93883 |
+ if (cursor == left_input) must_move_left_input = true;
|
|
|
e93883 |
+ if (cursor == right_input) must_move_right_input = true;
|
|
|
e93883 |
+ if (cursor == index) must_move_index = true;
|
|
|
e93883 |
+ if (cursor->previous() == NULL) {
|
|
|
e93883 |
+ cursor = cursor->block()->dominator()->end();
|
|
|
e93883 |
+ } else {
|
|
|
e93883 |
+ cursor = cursor->previous();
|
|
|
e93883 |
+ }
|
|
|
e93883 |
}
|
|
|
e93883 |
- *constant = new_constant;
|
|
|
e93883 |
- }
|
|
|
e93883 |
|
|
|
e93883 |
- void RemoveZeroAdd(HAdd** add, HConstant** constant) {
|
|
|
e93883 |
- if (*add != NULL && (*constant)->Integer32Value() == 0) {
|
|
|
e93883 |
- (*add)->DeleteAndReplaceWith((*add)->left());
|
|
|
e93883 |
- (*constant)->DeleteAndReplaceWith(NULL);
|
|
|
e93883 |
+ // The BCE algorithm only selects mergeable bounds checks that share
|
|
|
e93883 |
+ // the same "index_base", so we'll only ever have to move constants.
|
|
|
e93883 |
+ if (must_move_left_input) {
|
|
|
e93883 |
+ HConstant::cast(left_input)->Unlink();
|
|
|
e93883 |
+ HConstant::cast(left_input)->InsertBefore(index);
|
|
|
e93883 |
+ }
|
|
|
e93883 |
+ if (must_move_right_input) {
|
|
|
e93883 |
+ HConstant::cast(right_input)->Unlink();
|
|
|
e93883 |
+ HConstant::cast(right_input)->InsertBefore(index);
|
|
|
e93883 |
}
|
|
|
e93883 |
}
|
|
|
e93883 |
+
|
|
|
e93883 |
+ void TightenCheck(HBoundsCheck* original_check,
|
|
|
e93883 |
+ HBoundsCheck* tighter_check) {
|
|
|
e93883 |
+ ASSERT(original_check->length() == tighter_check->length());
|
|
|
e93883 |
+ MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check);
|
|
|
e93883 |
+ original_check->ReplaceAllUsesWith(original_check->index());
|
|
|
e93883 |
+ original_check->SetOperandAt(0, tighter_check->index());
|
|
|
e93883 |
+ }
|
|
|
e93883 |
};
|
|
|
e93883 |
|
|
|
e93883 |
|
|
|
e93883 |
@@ -3683,7 +3678,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
|
|
|
e93883 |
for (BoundsCheckBbData* data = bb_data_list;
|
|
|
e93883 |
data != NULL;
|
|
|
e93883 |
data = data->NextInBasicBlock()) {
|
|
|
e93883 |
- data->RemoveZeroOperations();
|
|
|
e93883 |
if (data->FatherInDominatorTree()) {
|
|
|
e93883 |
table->Insert(data->Key(), data->FatherInDominatorTree(), zone());
|
|
|
e93883 |
} else {
|