| 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(); | 
 |   3543     } | 
 |   3544     if (check->index()->IsBinaryOperation()) { | 
 |   3545       return HBinaryOperation::cast(check->index())->context(); | 
 |   3546     } | 
 |   3547     return NULL; | 
 |   3548   } | 
 |   3549  | 
 |   3550   // This function returns false if it cannot build the add because the | 
 |   3551   // current context cannot be determined. | 
 |   3552   bool BuildOffsetAdd(HBoundsCheck* check, | 
|   3532                       HAdd** add, |   3553                       HAdd** add, | 
|   3533                       HConstant** constant, |   3554                       HConstant** constant, | 
|   3534                       HValue* original_value, |   3555                       HValue* original_value, | 
|   3535                       Representation representation, |   3556                       Representation representation, | 
|   3536                       int32_t new_offset) { |   3557                       int32_t new_offset) { | 
 |   3558     HValue* index_context = IndexContext(*add, check); | 
 |   3559     if (index_context == NULL) return false; | 
 |   3560  | 
|   3537     HConstant* new_constant = new(BasicBlock()->zone()) |   3561     HConstant* new_constant = new(BasicBlock()->zone()) | 
|   3538        HConstant(new_offset, Representation::Integer32()); |   3562        HConstant(new_offset, Representation::Integer32()); | 
|   3539     if (*add == NULL) { |   3563     if (*add == NULL) { | 
|   3540       new_constant->InsertBefore(check); |   3564       new_constant->InsertBefore(check); | 
|   3541       // Because of the bounds checks elimination algorithm, the index is always |   3565       *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, |   3566                                             original_value, | 
|   3546                                             new_constant); |   3567                                             new_constant); | 
|   3547       (*add)->AssumeRepresentation(representation); |   3568       (*add)->AssumeRepresentation(representation); | 
|   3548       (*add)->InsertBefore(check); |   3569       (*add)->InsertBefore(check); | 
|   3549     } else { |   3570     } else { | 
|   3550       new_constant->InsertBefore(*add); |   3571       new_constant->InsertBefore(*add); | 
|   3551       (*constant)->DeleteAndReplaceWith(new_constant); |   3572       (*constant)->DeleteAndReplaceWith(new_constant); | 
|   3552     } |   3573     } | 
|   3553     *constant = new_constant; |   3574     *constant = new_constant; | 
 |   3575     return true; | 
|   3554   } |   3576   } | 
|   3555  |   3577  | 
|   3556   void RemoveZeroAdd(HAdd** add, HConstant** constant) { |   3578   void RemoveZeroAdd(HAdd** add, HConstant** constant) { | 
|   3557     if (*add != NULL && (*constant)->Integer32Value() == 0) { |   3579     if (*add != NULL && (*constant)->Integer32Value() == 0) { | 
|   3558       (*add)->DeleteAndReplaceWith((*add)->left()); |   3580       (*add)->DeleteAndReplaceWith((*add)->left()); | 
|   3559       (*constant)->DeleteAndReplaceWith(NULL); |   3581       (*constant)->DeleteAndReplaceWith(NULL); | 
|   3560     } |   3582     } | 
|   3561   } |   3583   } | 
|   3562 }; |   3584 }; | 
|   3563  |   3585  | 
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   3618                                                    offset, |   3640                                                    offset, | 
|   3619                                                    offset, |   3641                                                    offset, | 
|   3620                                                    bb, |   3642                                                    bb, | 
|   3621                                                    check, |   3643                                                    check, | 
|   3622                                                    check, |   3644                                                    check, | 
|   3623                                                    bb_data_list, |   3645                                                    bb_data_list, | 
|   3624                                                    NULL); |   3646                                                    NULL); | 
|   3625       *data_p = bb_data_list; |   3647       *data_p = bb_data_list; | 
|   3626     } else if (data->OffsetIsCovered(offset)) { |   3648     } else if (data->OffsetIsCovered(offset)) { | 
|   3627       check->DeleteAndReplaceWith(NULL); |   3649       check->DeleteAndReplaceWith(NULL); | 
|   3628     } else if (data->BasicBlock() == bb) { |   3650     } else if (data->BasicBlock() != bb || | 
|   3629       data->CoverCheck(check, offset); |   3651                !data->CoverCheck(check, offset)) { | 
|   3630     } else { |   3652       // If the check is in the current BB we try to modify it by calling | 
 |   3653       // "CoverCheck", but if also that fails we record the current offsets | 
 |   3654       // in a new data instance because from now on they are covered. | 
|   3631       int32_t new_lower_offset = offset < data->LowerOffset() |   3655       int32_t new_lower_offset = offset < data->LowerOffset() | 
|   3632           ? offset |   3656           ? offset | 
|   3633           : data->LowerOffset(); |   3657           : data->LowerOffset(); | 
|   3634       int32_t new_upper_offset = offset > data->UpperOffset() |   3658       int32_t new_upper_offset = offset > data->UpperOffset() | 
|   3635           ? offset |   3659           ? offset | 
|   3636           : data->UpperOffset(); |   3660           : data->UpperOffset(); | 
|   3637       bb_data_list = new(zone()) BoundsCheckBbData(key, |   3661       bb_data_list = new(zone()) BoundsCheckBbData(key, | 
|   3638                                                    new_lower_offset, |   3662                                                    new_lower_offset, | 
|   3639                                                    new_upper_offset, |   3663                                                    new_upper_offset, | 
|   3640                                                    bb, |   3664                                                    bb, | 
| (...skipping 6451 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  10092     } |  10116     } | 
|  10093   } |  10117   } | 
|  10094  |  10118  | 
|  10095 #ifdef DEBUG |  10119 #ifdef DEBUG | 
|  10096   if (graph_ != NULL) graph_->Verify(false);  // No full verify. |  10120   if (graph_ != NULL) graph_->Verify(false);  // No full verify. | 
|  10097   if (allocator_ != NULL) allocator_->Verify(); |  10121   if (allocator_ != NULL) allocator_->Verify(); | 
|  10098 #endif |  10122 #endif | 
|  10099 } |  10123 } | 
|  10100  |  10124  | 
|  10101 } }  // namespace v8::internal |  10125 } }  // namespace v8::internal | 
| OLD | NEW |