Skip to content

Commit fd80a31

Browse files
committed
deps: backport 5f836c from v8 upstream
Original commit message: Fix Hydrogen bounds check elimination When combining bounds checks, they must all be moved before the first load/store that they are guarding. BUG=chromium:344186 LOG=y R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/172093002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@19475 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 fix #8070
1 parent 6b97c2e commit fd80a31

1 file changed

Lines changed: 50 additions & 56 deletions

File tree

deps/v8/src/hydrogen.cc

Lines changed: 50 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3487,42 +3487,35 @@ class BoundsCheckBbData: public ZoneObject {
34873487
keep_new_check = true;
34883488
upper_check_ = new_check;
34893489
} else {
3490-
BuildOffsetAdd(upper_check_,
3491-
&added_upper_index_,
3492-
&added_upper_offset_,
3493-
Key()->IndexBase(),
3494-
new_check->index()->representation(),
3495-
new_offset);
3496-
upper_check_->SetOperandAt(0, added_upper_index_);
3490+
TightenCheck(upper_check_, new_check);
34973491
}
34983492
} else if (new_offset < lower_offset_) {
34993493
lower_offset_ = new_offset;
35003494
if (HasSingleCheck()) {
35013495
keep_new_check = true;
35023496
lower_check_ = new_check;
35033497
} else {
3504-
BuildOffsetAdd(lower_check_,
3505-
&added_lower_index_,
3506-
&added_lower_offset_,
3507-
Key()->IndexBase(),
3508-
new_check->index()->representation(),
3509-
new_offset);
3510-
lower_check_->SetOperandAt(0, added_lower_index_);
3498+
TightenCheck(lower_check_, new_check);
35113499
}
35123500
} else {
3513-
ASSERT(false);
3501+
// Should never have called CoverCheck() in this case.
3502+
UNREACHABLE();
35143503
}
35153504

35163505
if (!keep_new_check) {
35173506
new_check->DeleteAndReplaceWith(NULL);
3507+
} else {
3508+
HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_
3509+
: lower_check_;
3510+
// The length is guaranteed to be live at first_check.
3511+
ASSERT(new_check->length() == first_check->length());
3512+
HInstruction* old_position = new_check->next();
3513+
new_check->Unlink();
3514+
new_check->InsertAfter(first_check);
3515+
MoveIndexIfNecessary(new_check->index(), new_check, old_position);
35183516
}
35193517
}
35203518

3521-
void RemoveZeroOperations() {
3522-
RemoveZeroAdd(&added_lower_index_, &added_lower_offset_);
3523-
RemoveZeroAdd(&added_upper_index_, &added_upper_offset_);
3524-
}
3525-
35263519
BoundsCheckBbData(BoundsCheckKey* key,
35273520
int32_t lower_offset,
35283521
int32_t upper_offset,
@@ -3537,10 +3530,6 @@ class BoundsCheckBbData: public ZoneObject {
35373530
basic_block_(bb),
35383531
lower_check_(lower_check),
35393532
upper_check_(upper_check),
3540-
added_lower_index_(NULL),
3541-
added_lower_offset_(NULL),
3542-
added_upper_index_(NULL),
3543-
added_upper_offset_(NULL),
35443533
next_in_bb_(next_in_bb),
35453534
father_in_dt_(father_in_dt) { }
35463535

@@ -3551,44 +3540,50 @@ class BoundsCheckBbData: public ZoneObject {
35513540
HBasicBlock* basic_block_;
35523541
HBoundsCheck* lower_check_;
35533542
HBoundsCheck* upper_check_;
3554-
HAdd* added_lower_index_;
3555-
HConstant* added_lower_offset_;
3556-
HAdd* added_upper_index_;
3557-
HConstant* added_upper_offset_;
35583543
BoundsCheckBbData* next_in_bb_;
35593544
BoundsCheckBbData* father_in_dt_;
35603545

3561-
void BuildOffsetAdd(HBoundsCheck* check,
3562-
HAdd** add,
3563-
HConstant** constant,
3564-
HValue* original_value,
3565-
Representation representation,
3566-
int32_t new_offset) {
3567-
HConstant* new_constant = new(BasicBlock()->zone())
3568-
HConstant(new_offset, Representation::Integer32());
3569-
if (*add == NULL) {
3570-
new_constant->InsertBefore(check);
3571-
// Because of the bounds checks elimination algorithm, the index is always
3572-
// an HAdd or an HSub here, so we can safely cast to an HBinaryOperation.
3573-
HValue* context = HBinaryOperation::cast(check->index())->context();
3574-
*add = new(BasicBlock()->zone()) HAdd(context,
3575-
original_value,
3576-
new_constant);
3577-
(*add)->AssumeRepresentation(representation);
3578-
(*add)->InsertBefore(check);
3579-
} else {
3580-
new_constant->InsertBefore(*add);
3581-
(*constant)->DeleteAndReplaceWith(new_constant);
3546+
void MoveIndexIfNecessary(HValue* index_raw,
3547+
HBoundsCheck* insert_before,
3548+
HInstruction* end_of_scan_range) {
3549+
ASSERT(index_raw->IsAdd() || index_raw->IsSub());
3550+
HBinaryOperation* index =
3551+
HArithmeticBinaryOperation::cast(index_raw);
3552+
HValue* left_input = index->left();
3553+
HValue* right_input = index->right();
3554+
bool must_move_index = false;
3555+
bool must_move_left_input = false;
3556+
bool must_move_right_input = false;
3557+
for (HInstruction* cursor = end_of_scan_range; cursor != insert_before;) {
3558+
if (cursor == left_input) must_move_left_input = true;
3559+
if (cursor == right_input) must_move_right_input = true;
3560+
if (cursor == index) must_move_index = true;
3561+
if (cursor->previous() == NULL) {
3562+
cursor = cursor->block()->dominator()->end();
3563+
} else {
3564+
cursor = cursor->previous();
3565+
}
35823566
}
3583-
*constant = new_constant;
3584-
}
35853567

3586-
void RemoveZeroAdd(HAdd** add, HConstant** constant) {
3587-
if (*add != NULL && (*constant)->Integer32Value() == 0) {
3588-
(*add)->DeleteAndReplaceWith((*add)->left());
3589-
(*constant)->DeleteAndReplaceWith(NULL);
3568+
// The BCE algorithm only selects mergeable bounds checks that share
3569+
// the same "index_base", so we'll only ever have to move constants.
3570+
if (must_move_left_input) {
3571+
HConstant::cast(left_input)->Unlink();
3572+
HConstant::cast(left_input)->InsertBefore(index);
3573+
}
3574+
if (must_move_right_input) {
3575+
HConstant::cast(right_input)->Unlink();
3576+
HConstant::cast(right_input)->InsertBefore(index);
35903577
}
35913578
}
3579+
3580+
void TightenCheck(HBoundsCheck* original_check,
3581+
HBoundsCheck* tighter_check) {
3582+
ASSERT(original_check->length() == tighter_check->length());
3583+
MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check);
3584+
original_check->ReplaceAllUsesWith(original_check->index());
3585+
original_check->SetOperandAt(0, tighter_check->index());
3586+
}
35923587
};
35933588

35943589

@@ -3683,7 +3678,6 @@ void HGraph::EliminateRedundantBoundsChecks(HBasicBlock* bb,
36833678
for (BoundsCheckBbData* data = bb_data_list;
36843679
data != NULL;
36853680
data = data->NextInBasicBlock()) {
3686-
data->RemoveZeroOperations();
36873681
if (data->FatherInDominatorTree()) {
36883682
table->Insert(data->Key(), data->FatherInDominatorTree(), zone());
36893683
} else {

0 commit comments

Comments
 (0)