OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 3428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3439 // range grows). | 3439 // range grows). |
3440 // | 3440 // |
3441 // The precondition is that new_check follows UpperCheck() and | 3441 // The precondition is that new_check follows UpperCheck() and |
3442 // LowerCheck() in the same basic block, and that new_offset is not | 3442 // LowerCheck() in the same basic block, and that new_offset is not |
3443 // covered (otherwise we could simply remove new_check). | 3443 // covered (otherwise we could simply remove new_check). |
3444 // | 3444 // |
3445 // If HasSingleCheck() is true then new_check is added as "second check" | 3445 // If HasSingleCheck() is true then new_check is added as "second check" |
3446 // (either upper or lower; note that HasSingleCheck() becomes false). | 3446 // (either upper or lower; note that HasSingleCheck() becomes false). |
3447 // Otherwise one of the current checks is modified so that it also covers | 3447 // Otherwise one of the current checks is modified so that it also covers |
3448 // new_offset, and new_check is removed. | 3448 // new_offset, and new_check is removed. |
3449 void CoverCheck(HBoundsCheck* new_check, | 3449 // |
3450 // If the check cannot be modified because the context is unknown it | |
3451 // returns false, otherwise it returns true. | |
3452 bool CoverCheck(HBoundsCheck* new_check, | |
3450 int32_t new_offset) { | 3453 int32_t new_offset) { |
3451 ASSERT(new_check->index()->representation().IsInteger32()); | 3454 ASSERT(new_check->index()->representation().IsInteger32()); |
3452 bool keep_new_check = false; | 3455 bool keep_new_check = false; |
3453 | 3456 |
3454 if (new_offset > upper_offset_) { | 3457 if (new_offset > upper_offset_) { |
3455 upper_offset_ = new_offset; | 3458 upper_offset_ = new_offset; |
3456 if (HasSingleCheck()) { | 3459 if (HasSingleCheck()) { |
3457 keep_new_check = true; | 3460 keep_new_check = true; |
3458 upper_check_ = new_check; | 3461 upper_check_ = new_check; |
3459 } else { | 3462 } else { |
3460 BuildOffsetAdd(upper_check_, | 3463 bool result = BuildOffsetAdd(upper_check_, |
3461 &added_upper_index_, | 3464 &added_upper_index_, |
3462 &added_upper_offset_, | 3465 &added_upper_offset_, |
3463 Key()->IndexBase(), | 3466 Key()->IndexBase(), |
3464 new_check->index()->representation(), | 3467 new_check->index()->representation(), |
3465 new_offset); | 3468 new_offset); |
3469 if (!result) return false; | |
3466 upper_check_->SetOperandAt(0, added_upper_index_); | 3470 upper_check_->SetOperandAt(0, added_upper_index_); |
3467 } | 3471 } |
3468 } else if (new_offset < lower_offset_) { | 3472 } else if (new_offset < lower_offset_) { |
3469 lower_offset_ = new_offset; | 3473 lower_offset_ = new_offset; |
3470 if (HasSingleCheck()) { | 3474 if (HasSingleCheck()) { |
3471 keep_new_check = true; | 3475 keep_new_check = true; |
3472 lower_check_ = new_check; | 3476 lower_check_ = new_check; |
3473 } else { | 3477 } else { |
3474 BuildOffsetAdd(lower_check_, | 3478 bool result = BuildOffsetAdd(lower_check_, |
3475 &added_lower_index_, | 3479 &added_lower_index_, |
3476 &added_lower_offset_, | 3480 &added_lower_offset_, |
3477 Key()->IndexBase(), | 3481 Key()->IndexBase(), |
3478 new_check->index()->representation(), | 3482 new_check->index()->representation(), |
3479 new_offset); | 3483 new_offset); |
3484 if (!result) return false; | |
3480 lower_check_->SetOperandAt(0, added_lower_index_); | 3485 lower_check_->SetOperandAt(0, added_lower_index_); |
3481 } | 3486 } |
3482 } else { | 3487 } else { |
3483 ASSERT(false); | 3488 ASSERT(false); |
3484 } | 3489 } |
3485 | 3490 |
3486 if (!keep_new_check) { | 3491 if (!keep_new_check) { |
3487 new_check->DeleteAndReplaceWith(NULL); | 3492 new_check->DeleteAndReplaceWith(NULL); |
3488 } | 3493 } |
3494 | |
3495 return true; | |
3489 } | 3496 } |
3490 | 3497 |
3491 void RemoveZeroOperations() { | 3498 void RemoveZeroOperations() { |
3492 RemoveZeroAdd(&added_lower_index_, &added_lower_offset_); | 3499 RemoveZeroAdd(&added_lower_index_, &added_lower_offset_); |
3493 RemoveZeroAdd(&added_upper_index_, &added_upper_offset_); | 3500 RemoveZeroAdd(&added_upper_index_, &added_upper_offset_); |
3494 } | 3501 } |
3495 | 3502 |
3496 BoundsCheckBbData(BoundsCheckKey* key, | 3503 BoundsCheckBbData(BoundsCheckKey* key, |
3497 int32_t lower_offset, | 3504 int32_t lower_offset, |
3498 int32_t upper_offset, | 3505 int32_t upper_offset, |
(...skipping 22 matching lines...) Expand all Loading... | |
3521 HBasicBlock* basic_block_; | 3528 HBasicBlock* basic_block_; |
3522 HBoundsCheck* lower_check_; | 3529 HBoundsCheck* lower_check_; |
3523 HBoundsCheck* upper_check_; | 3530 HBoundsCheck* upper_check_; |
3524 HAdd* added_lower_index_; | 3531 HAdd* added_lower_index_; |
3525 HConstant* added_lower_offset_; | 3532 HConstant* added_lower_offset_; |
3526 HAdd* added_upper_index_; | 3533 HAdd* added_upper_index_; |
3527 HConstant* added_upper_offset_; | 3534 HConstant* added_upper_offset_; |
3528 BoundsCheckBbData* next_in_bb_; | 3535 BoundsCheckBbData* next_in_bb_; |
3529 BoundsCheckBbData* father_in_dt_; | 3536 BoundsCheckBbData* father_in_dt_; |
3530 | 3537 |
3531 void BuildOffsetAdd(HBoundsCheck* check, | 3538 // Given an existing add instruction and a bounds check it tries to |
3539 // find the current context (either of the add or of the check index). | |
3540 HValue* IndexContext(HAdd* add, HBoundsCheck* check) { | |
3541 if (add != NULL) | |
3542 return add->context(); | |
Jakob Kummerow
2012/12/11 13:42:15
nit: {}
| |
3543 if (check->index()->IsBinaryOperation()) | |
3544 return HBinaryOperation::cast(check->index())->context(); | |
Jakob Kummerow
2012/12/11 13:42:15
nit: {}
| |
3545 return NULL; | |
3546 } | |
3547 | |
3548 // This function returns false if it cannot build the add because the | |
3549 // current context cannot be determined. | |
3550 bool BuildOffsetAdd(HBoundsCheck* check, | |
3532 HAdd** add, | 3551 HAdd** add, |
3533 HConstant** constant, | 3552 HConstant** constant, |
3534 HValue* original_value, | 3553 HValue* original_value, |
3535 Representation representation, | 3554 Representation representation, |
3536 int32_t new_offset) { | 3555 int32_t new_offset) { |
3556 HValue* index_context = IndexContext(*add, check); | |
3557 if (index_context == NULL) return false; | |
3558 | |
3537 HConstant* new_constant = new(BasicBlock()->zone()) | 3559 HConstant* new_constant = new(BasicBlock()->zone()) |
3538 HConstant(new_offset, Representation::Integer32()); | 3560 HConstant(new_offset, Representation::Integer32()); |
3539 if (*add == NULL) { | 3561 if (*add == NULL) { |
3540 new_constant->InsertBefore(check); | 3562 new_constant->InsertBefore(check); |
3541 // Because of the bounds checks elimination algorithm, the index is always | 3563 *add = new(BasicBlock()->zone()) HAdd(index_context, |
3542 // an HAdd or an HSub here, so we can safely cast to an HBinaryOperation. | |
3543 HValue* context = HBinaryOperation::cast(check->index())->context(); | |
3544 *add = new(BasicBlock()->zone()) HAdd(context, | |
3545 original_value, | 3564 original_value, |
3546 new_constant); | 3565 new_constant); |
3547 (*add)->AssumeRepresentation(representation); | 3566 (*add)->AssumeRepresentation(representation); |
3548 (*add)->InsertBefore(check); | 3567 (*add)->InsertBefore(check); |
3549 } else { | 3568 } else { |
3550 new_constant->InsertBefore(*add); | 3569 new_constant->InsertBefore(*add); |
3551 (*constant)->DeleteAndReplaceWith(new_constant); | 3570 (*constant)->DeleteAndReplaceWith(new_constant); |
3552 } | 3571 } |
3553 *constant = new_constant; | 3572 *constant = new_constant; |
3573 return true; | |
3554 } | 3574 } |
3555 | 3575 |
3556 void RemoveZeroAdd(HAdd** add, HConstant** constant) { | 3576 void RemoveZeroAdd(HAdd** add, HConstant** constant) { |
3557 if (*add != NULL && (*constant)->Integer32Value() == 0) { | 3577 if (*add != NULL && (*constant)->Integer32Value() == 0) { |
3558 (*add)->DeleteAndReplaceWith((*add)->left()); | 3578 (*add)->DeleteAndReplaceWith((*add)->left()); |
3559 (*constant)->DeleteAndReplaceWith(NULL); | 3579 (*constant)->DeleteAndReplaceWith(NULL); |
3560 } | 3580 } |
3561 } | 3581 } |
3562 }; | 3582 }; |
3563 | 3583 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3618 offset, | 3638 offset, |
3619 offset, | 3639 offset, |
3620 bb, | 3640 bb, |
3621 check, | 3641 check, |
3622 check, | 3642 check, |
3623 bb_data_list, | 3643 bb_data_list, |
3624 NULL); | 3644 NULL); |
3625 *data_p = bb_data_list; | 3645 *data_p = bb_data_list; |
3626 } else if (data->OffsetIsCovered(offset)) { | 3646 } else if (data->OffsetIsCovered(offset)) { |
3627 check->DeleteAndReplaceWith(NULL); | 3647 check->DeleteAndReplaceWith(NULL); |
3628 } else if (data->BasicBlock() == bb) { | 3648 } else if (data->BasicBlock() != bb || |
3629 data->CoverCheck(check, offset); | 3649 !data->CoverCheck(check, offset)) { |
Jakob Kummerow
2012/12/11 13:42:15
nit: please align:
} else if (data->BasicBlock
| |
3630 } else { | 3650 // If the check is in the current BB we try to modify it by calling |
3651 // "CoverCheck", but if also that fails we record the current offsets | |
3652 // in a new data instance because from now on they are covered. | |
3631 int32_t new_lower_offset = offset < data->LowerOffset() | 3653 int32_t new_lower_offset = offset < data->LowerOffset() |
3632 ? offset | 3654 ? offset |
3633 : data->LowerOffset(); | 3655 : data->LowerOffset(); |
3634 int32_t new_upper_offset = offset > data->UpperOffset() | 3656 int32_t new_upper_offset = offset > data->UpperOffset() |
3635 ? offset | 3657 ? offset |
3636 : data->UpperOffset(); | 3658 : data->UpperOffset(); |
3637 bb_data_list = new(zone()) BoundsCheckBbData(key, | 3659 bb_data_list = new(zone()) BoundsCheckBbData(key, |
3638 new_lower_offset, | 3660 new_lower_offset, |
3639 new_upper_offset, | 3661 new_upper_offset, |
3640 bb, | 3662 bb, |
(...skipping 6451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10092 } | 10114 } |
10093 } | 10115 } |
10094 | 10116 |
10095 #ifdef DEBUG | 10117 #ifdef DEBUG |
10096 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10118 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10097 if (allocator_ != NULL) allocator_->Verify(); | 10119 if (allocator_ != NULL) allocator_->Verify(); |
10098 #endif | 10120 #endif |
10099 } | 10121 } |
10100 | 10122 |
10101 } } // namespace v8::internal | 10123 } } // namespace v8::internal |
OLD | NEW |