OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/hydrogen-bce.h" | 5 #include "src/hydrogen-bce.h" |
6 | 6 |
7 namespace v8 { | 7 namespace v8 { |
8 namespace internal { | 8 namespace internal { |
9 | 9 |
10 | 10 |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 | 106 |
107 bool OffsetIsCovered(int32_t offset) const { | 107 bool OffsetIsCovered(int32_t offset) const { |
108 return offset >= LowerOffset() && offset <= UpperOffset(); | 108 return offset >= LowerOffset() && offset <= UpperOffset(); |
109 } | 109 } |
110 | 110 |
111 bool HasSingleCheck() { return lower_check_ == upper_check_; } | 111 bool HasSingleCheck() { return lower_check_ == upper_check_; } |
112 | 112 |
113 void UpdateUpperOffsets(HBoundsCheck* check, int32_t offset) { | 113 void UpdateUpperOffsets(HBoundsCheck* check, int32_t offset) { |
114 BoundsCheckBbData* data = FatherInDominatorTree(); | 114 BoundsCheckBbData* data = FatherInDominatorTree(); |
115 while (data != NULL && data->UpperCheck() == check) { | 115 while (data != NULL && data->UpperCheck() == check) { |
116 ASSERT(data->upper_offset_ < offset); | 116 DCHECK(data->upper_offset_ < offset); |
117 data->upper_offset_ = offset; | 117 data->upper_offset_ = offset; |
118 data = data->FatherInDominatorTree(); | 118 data = data->FatherInDominatorTree(); |
119 } | 119 } |
120 } | 120 } |
121 | 121 |
122 void UpdateLowerOffsets(HBoundsCheck* check, int32_t offset) { | 122 void UpdateLowerOffsets(HBoundsCheck* check, int32_t offset) { |
123 BoundsCheckBbData* data = FatherInDominatorTree(); | 123 BoundsCheckBbData* data = FatherInDominatorTree(); |
124 while (data != NULL && data->LowerCheck() == check) { | 124 while (data != NULL && data->LowerCheck() == check) { |
125 ASSERT(data->lower_offset_ > offset); | 125 DCHECK(data->lower_offset_ > offset); |
126 data->lower_offset_ = offset; | 126 data->lower_offset_ = offset; |
127 data = data->FatherInDominatorTree(); | 127 data = data->FatherInDominatorTree(); |
128 } | 128 } |
129 } | 129 } |
130 | 130 |
131 // The goal of this method is to modify either upper_offset_ or | 131 // The goal of this method is to modify either upper_offset_ or |
132 // lower_offset_ so that also new_offset is covered (the covered | 132 // lower_offset_ so that also new_offset is covered (the covered |
133 // range grows). | 133 // range grows). |
134 // | 134 // |
135 // The precondition is that new_check follows UpperCheck() and | 135 // The precondition is that new_check follows UpperCheck() and |
136 // LowerCheck() in the same basic block, and that new_offset is not | 136 // LowerCheck() in the same basic block, and that new_offset is not |
137 // covered (otherwise we could simply remove new_check). | 137 // covered (otherwise we could simply remove new_check). |
138 // | 138 // |
139 // If HasSingleCheck() is true then new_check is added as "second check" | 139 // If HasSingleCheck() is true then new_check is added as "second check" |
140 // (either upper or lower; note that HasSingleCheck() becomes false). | 140 // (either upper or lower; note that HasSingleCheck() becomes false). |
141 // Otherwise one of the current checks is modified so that it also covers | 141 // Otherwise one of the current checks is modified so that it also covers |
142 // new_offset, and new_check is removed. | 142 // new_offset, and new_check is removed. |
143 void CoverCheck(HBoundsCheck* new_check, | 143 void CoverCheck(HBoundsCheck* new_check, |
144 int32_t new_offset) { | 144 int32_t new_offset) { |
145 ASSERT(new_check->index()->representation().IsSmiOrInteger32()); | 145 DCHECK(new_check->index()->representation().IsSmiOrInteger32()); |
146 bool keep_new_check = false; | 146 bool keep_new_check = false; |
147 | 147 |
148 if (new_offset > upper_offset_) { | 148 if (new_offset > upper_offset_) { |
149 upper_offset_ = new_offset; | 149 upper_offset_ = new_offset; |
150 if (HasSingleCheck()) { | 150 if (HasSingleCheck()) { |
151 keep_new_check = true; | 151 keep_new_check = true; |
152 upper_check_ = new_check; | 152 upper_check_ = new_check; |
153 } else { | 153 } else { |
154 TightenCheck(upper_check_, new_check, new_offset); | 154 TightenCheck(upper_check_, new_check, new_offset); |
155 UpdateUpperOffsets(upper_check_, upper_offset_); | 155 UpdateUpperOffsets(upper_check_, upper_offset_); |
(...skipping 21 matching lines...) Expand all Loading... |
177 bounds_checks_eliminated()->Increment(); | 177 bounds_checks_eliminated()->Increment(); |
178 new_check->DeleteAndReplaceWith(new_check->ActualValue()); | 178 new_check->DeleteAndReplaceWith(new_check->ActualValue()); |
179 } else { | 179 } else { |
180 HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_ | 180 HBoundsCheck* first_check = new_check == lower_check_ ? upper_check_ |
181 : lower_check_; | 181 : lower_check_; |
182 if (FLAG_trace_bce) { | 182 if (FLAG_trace_bce) { |
183 base::OS::Print("Moving second check #%d after first check #%d\n", | 183 base::OS::Print("Moving second check #%d after first check #%d\n", |
184 new_check->id(), first_check->id()); | 184 new_check->id(), first_check->id()); |
185 } | 185 } |
186 // The length is guaranteed to be live at first_check. | 186 // The length is guaranteed to be live at first_check. |
187 ASSERT(new_check->length() == first_check->length()); | 187 DCHECK(new_check->length() == first_check->length()); |
188 HInstruction* old_position = new_check->next(); | 188 HInstruction* old_position = new_check->next(); |
189 new_check->Unlink(); | 189 new_check->Unlink(); |
190 new_check->InsertAfter(first_check); | 190 new_check->InsertAfter(first_check); |
191 MoveIndexIfNecessary(new_check->index(), new_check, old_position); | 191 MoveIndexIfNecessary(new_check->index(), new_check, old_position); |
192 } | 192 } |
193 } | 193 } |
194 | 194 |
195 BoundsCheckBbData(BoundsCheckKey* key, | 195 BoundsCheckBbData(BoundsCheckKey* key, |
196 int32_t lower_offset, | 196 int32_t lower_offset, |
197 int32_t upper_offset, | 197 int32_t upper_offset, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 if (must_move) { | 271 if (must_move) { |
272 index->Unlink(); | 272 index->Unlink(); |
273 index->InsertBefore(insert_before); | 273 index->InsertBefore(insert_before); |
274 } | 274 } |
275 } | 275 } |
276 } | 276 } |
277 | 277 |
278 void TightenCheck(HBoundsCheck* original_check, | 278 void TightenCheck(HBoundsCheck* original_check, |
279 HBoundsCheck* tighter_check, | 279 HBoundsCheck* tighter_check, |
280 int32_t new_offset) { | 280 int32_t new_offset) { |
281 ASSERT(original_check->length() == tighter_check->length()); | 281 DCHECK(original_check->length() == tighter_check->length()); |
282 MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check); | 282 MoveIndexIfNecessary(tighter_check->index(), original_check, tighter_check); |
283 original_check->ReplaceAllUsesWith(original_check->index()); | 283 original_check->ReplaceAllUsesWith(original_check->index()); |
284 original_check->SetOperandAt(0, tighter_check->index()); | 284 original_check->SetOperandAt(0, tighter_check->index()); |
285 if (FLAG_trace_bce) { | 285 if (FLAG_trace_bce) { |
286 base::OS::Print("Tightened check #%d with offset %d from #%d\n", | 286 base::OS::Print("Tightened check #%d with offset %d from #%d\n", |
287 original_check->id(), new_offset, tighter_check->id()); | 287 original_check->id(), new_offset, tighter_check->id()); |
288 } | 288 } |
289 } | 289 } |
290 | 290 |
291 DISALLOW_COPY_AND_ASSIGN(BoundsCheckBbData); | 291 DISALLOW_COPY_AND_ASSIGN(BoundsCheckBbData); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
456 if (data->FatherInDominatorTree()) { | 456 if (data->FatherInDominatorTree()) { |
457 table_.Insert(data->Key(), data->FatherInDominatorTree(), zone()); | 457 table_.Insert(data->Key(), data->FatherInDominatorTree(), zone()); |
458 } else { | 458 } else { |
459 table_.Delete(data->Key()); | 459 table_.Delete(data->Key()); |
460 } | 460 } |
461 data = data->NextInBasicBlock(); | 461 data = data->NextInBasicBlock(); |
462 } | 462 } |
463 } | 463 } |
464 | 464 |
465 } } // namespace v8::internal | 465 } } // namespace v8::internal |
OLD | NEW |