OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 return succ_state->Merge(succ_block, pred_state, pred_block, zone); | 130 return succ_state->Merge(succ_block, pred_state, pred_block, zone); |
131 } | 131 } |
132 } | 132 } |
133 | 133 |
134 // Support for global analysis with HFlowEngine: Given state merged with all | 134 // Support for global analysis with HFlowEngine: Given state merged with all |
135 // the other incoming states, prepare it for use. | 135 // the other incoming states, prepare it for use. |
136 static HCheckTable* Finish(HCheckTable* state, HBasicBlock* block, | 136 static HCheckTable* Finish(HCheckTable* state, HBasicBlock* block, |
137 Zone* zone) { | 137 Zone* zone) { |
138 if (state == NULL) { | 138 if (state == NULL) { |
139 block->MarkUnreachable(); | 139 block->MarkUnreachable(); |
| 140 } else if (block->IsUnreachable()) { |
| 141 state = NULL; |
| 142 } |
| 143 if (FLAG_trace_check_elimination) { |
| 144 PrintF("Processing B%d, checkmaps-table:\n", block->block_id()); |
| 145 Print(state); |
140 } | 146 } |
141 return state; | 147 return state; |
142 } | 148 } |
143 | 149 |
144 private: | 150 private: |
145 // Copy state to successor block. | 151 // Copy state to successor block. |
146 HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) { | 152 HCheckTable* Copy(HBasicBlock* succ, HBasicBlock* from_block, Zone* zone) { |
147 HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_); | 153 HCheckTable* copy = new(phase_->zone()) HCheckTable(phase_); |
148 for (int i = 0; i < size_; i++) { | 154 for (int i = 0; i < size_; i++) { |
149 HCheckTableEntry* old_entry = &entries_[i]; | 155 HCheckTableEntry* old_entry = &entries_[i]; |
| 156 ASSERT(old_entry->maps_->size() > 0); |
150 HCheckTableEntry* new_entry = ©->entries_[i]; | 157 HCheckTableEntry* new_entry = ©->entries_[i]; |
151 new_entry->object_ = old_entry->object_; | 158 new_entry->object_ = old_entry->object_; |
152 new_entry->maps_ = old_entry->maps_->Copy(phase_->zone()); | 159 new_entry->maps_ = old_entry->maps_->Copy(phase_->zone()); |
153 // Keep the check if the existing check's block dominates the successor. | 160 // Keep the check if the existing check's block dominates the successor. |
154 if (old_entry->check_ != NULL && | 161 if (old_entry->check_ != NULL && |
155 old_entry->check_->block()->Dominates(succ)) { | 162 old_entry->check_->block()->Dominates(succ)) { |
156 new_entry->check_ = old_entry->check_; | 163 new_entry->check_ = old_entry->check_; |
157 } else { | 164 } else { |
158 // Leave it NULL till we meet a new check instruction for this object | 165 // Leave it NULL till we meet a new check instruction for this object |
159 // in the control flow. | 166 // in the control flow. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
229 learned = true; | 236 learned = true; |
230 } | 237 } |
231 // Learning on false branches requires storing negative facts. | 238 // Learning on false branches requires storing negative facts. |
232 } | 239 } |
233 | 240 |
234 if (FLAG_trace_check_elimination) { | 241 if (FLAG_trace_check_elimination) { |
235 PrintF("B%d checkmaps-table %s from B%d:\n", | 242 PrintF("B%d checkmaps-table %s from B%d:\n", |
236 succ->block_id(), | 243 succ->block_id(), |
237 learned ? "learned" : "copied", | 244 learned ? "learned" : "copied", |
238 from_block->block_id()); | 245 from_block->block_id()); |
239 copy->Print(); | 246 Print(copy); |
240 } | 247 } |
241 | 248 |
242 return copy; | 249 return copy; |
243 } | 250 } |
244 | 251 |
245 // Merge this state with the other incoming state. | 252 // Merge this state with the other incoming state. |
246 HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that, | 253 HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that, |
247 HBasicBlock* pred_block, Zone* zone) { | 254 HBasicBlock* pred_block, Zone* zone) { |
248 if (that->size_ == 0) { | 255 if (that->size_ == 0) { |
249 // If the other state is empty, simply reset. | 256 // If the other state is empty, simply reset. |
(...skipping 26 matching lines...) Expand all Loading... |
276 } | 283 } |
277 ASSERT(this_entry->maps_->size() > 0); | 284 ASSERT(this_entry->maps_->size() > 0); |
278 } | 285 } |
279 } | 286 } |
280 if (compact) Compact(); | 287 if (compact) Compact(); |
281 } | 288 } |
282 | 289 |
283 if (FLAG_trace_check_elimination) { | 290 if (FLAG_trace_check_elimination) { |
284 PrintF("B%d checkmaps-table merged with B%d table:\n", | 291 PrintF("B%d checkmaps-table merged with B%d table:\n", |
285 succ->block_id(), pred_block->block_id()); | 292 succ->block_id(), pred_block->block_id()); |
286 Print(); | 293 Print(this); |
287 } | 294 } |
288 return this; | 295 return this; |
289 } | 296 } |
290 | 297 |
291 void ReduceCheckMaps(HCheckMaps* instr) { | 298 void ReduceCheckMaps(HCheckMaps* instr) { |
292 HValue* object = instr->value()->ActualValue(); | 299 HValue* object = instr->value()->ActualValue(); |
293 HCheckTableEntry* entry = Find(object); | 300 HCheckTableEntry* entry = Find(object); |
294 if (entry != NULL) { | 301 if (entry != NULL) { |
295 // entry found; | 302 // entry found; |
296 MapSet a = entry->maps_; | 303 MapSet a = entry->maps_; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
339 instr->id(), instr->block()->block_id(), entry->check_->id())); | 346 instr->id(), instr->block()->block_id(), entry->check_->id())); |
340 instr->DeleteAndReplaceWith(entry->check_); | 347 instr->DeleteAndReplaceWith(entry->check_); |
341 } else { | 348 } else { |
342 TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(), | 349 TRACE(("CheckMaps #%d at B%d narrowed\n", instr->id(), |
343 instr->block()->block_id())); | 350 instr->block()->block_id())); |
344 instr->set_map_set(intersection, graph->zone()); | 351 instr->set_map_set(intersection, graph->zone()); |
345 entry->check_ = instr; | 352 entry->check_ = instr; |
346 } | 353 } |
347 | 354 |
348 if (FLAG_trace_check_elimination) { | 355 if (FLAG_trace_check_elimination) { |
349 Print(); | 356 Print(this); |
350 } | 357 } |
351 INC_STAT(narrowed_); | 358 INC_STAT(narrowed_); |
352 } | 359 } |
353 } | 360 } |
354 } else { | 361 } else { |
355 // No entry; insert a new one. | 362 // No entry; insert a new one. |
356 Insert(object, instr, instr->map_set().Copy(phase_->zone())); | 363 Insert(object, instr, instr->map_set().Copy(phase_->zone())); |
357 } | 364 } |
358 } | 365 } |
359 | 366 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 int R = size_ - cursor_; | 540 int R = size_ - cursor_; |
534 | 541 |
535 OS::MemMove(&tmp_entries[0], &entries_[0], L * sizeof(HCheckTableEntry)); | 542 OS::MemMove(&tmp_entries[0], &entries_[0], L * sizeof(HCheckTableEntry)); |
536 OS::MemMove(&entries_[0], &entries_[L], R * sizeof(HCheckTableEntry)); | 543 OS::MemMove(&entries_[0], &entries_[L], R * sizeof(HCheckTableEntry)); |
537 OS::MemMove(&entries_[R], &tmp_entries[0], L * sizeof(HCheckTableEntry)); | 544 OS::MemMove(&entries_[R], &tmp_entries[0], L * sizeof(HCheckTableEntry)); |
538 } | 545 } |
539 | 546 |
540 cursor_ = size_; // Move cursor to end. | 547 cursor_ = size_; // Move cursor to end. |
541 } | 548 } |
542 | 549 |
543 void Print() { | 550 static void Print(HCheckTable* table) { |
544 for (int i = 0; i < size_; i++) { | 551 if (table == NULL) { |
545 HCheckTableEntry* entry = &entries_[i]; | 552 PrintF(" unreachable\n"); |
| 553 return; |
| 554 } |
| 555 |
| 556 for (int i = 0; i < table->size_; i++) { |
| 557 HCheckTableEntry* entry = &table->entries_[i]; |
546 ASSERT(entry->object_ != NULL); | 558 ASSERT(entry->object_ != NULL); |
547 PrintF(" checkmaps-table @%d: %s #%d ", i, | 559 PrintF(" checkmaps-table @%d: %s #%d ", i, |
548 entry->object_->IsPhi() ? "phi" : "object", entry->object_->id()); | 560 entry->object_->IsPhi() ? "phi" : "object", entry->object_->id()); |
549 if (entry->check_ != NULL) { | 561 if (entry->check_ != NULL) { |
550 PrintF("check #%d ", entry->check_->id()); | 562 PrintF("check #%d ", entry->check_->id()); |
551 } | 563 } |
552 MapSet list = entry->maps_; | 564 MapSet list = entry->maps_; |
553 PrintF("%d maps { ", list->size()); | 565 PrintF("%d maps { ", list->size()); |
554 for (int j = 0; j < list->size(); j++) { | 566 for (int j = 0; j < list->size(); j++) { |
555 if (j > 0) PrintF(", "); | 567 if (j > 0) PrintF(", "); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
703 PRINT_STAT(removed_cho); | 715 PRINT_STAT(removed_cho); |
704 PRINT_STAT(narrowed); | 716 PRINT_STAT(narrowed); |
705 PRINT_STAT(loads); | 717 PRINT_STAT(loads); |
706 PRINT_STAT(empty); | 718 PRINT_STAT(empty); |
707 PRINT_STAT(compares_true); | 719 PRINT_STAT(compares_true); |
708 PRINT_STAT(compares_false); | 720 PRINT_STAT(compares_false); |
709 PRINT_STAT(transitions); | 721 PRINT_STAT(transitions); |
710 } | 722 } |
711 | 723 |
712 } } // namespace v8::internal | 724 } } // namespace v8::internal |
OLD | NEW |