Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(110)

Side by Side Diff: src/hydrogen-check-elimination.cc

Issue 310593004: Revert "Handle HCheckInstanceType and HIsStringAndBranch in check elimination." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen-check-elimination.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "hydrogen-check-elimination.h" 5 #include "hydrogen-check-elimination.h"
6 6
7 #include "hydrogen-alias-analysis.h" 7 #include "hydrogen-alias-analysis.h"
8 #include "hydrogen-flow-engine.h" 8 #include "hydrogen-flow-engine.h"
9 9
10 #define GLOBAL 1 10 #define GLOBAL 1
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 break; 97 break;
98 } 98 }
99 case HValue::kCompareMap: { 99 case HValue::kCompareMap: {
100 ReduceCompareMap(HCompareMap::cast(instr)); 100 ReduceCompareMap(HCompareMap::cast(instr));
101 break; 101 break;
102 } 102 }
103 case HValue::kCompareObjectEqAndBranch: { 103 case HValue::kCompareObjectEqAndBranch: {
104 ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr)); 104 ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr));
105 break; 105 break;
106 } 106 }
107 case HValue::kIsStringAndBranch: {
108 ReduceIsStringAndBranch(HIsStringAndBranch::cast(instr));
109 break;
110 }
111 case HValue::kTransitionElementsKind: { 107 case HValue::kTransitionElementsKind: {
112 ReduceTransitionElementsKind( 108 ReduceTransitionElementsKind(
113 HTransitionElementsKind::cast(instr)); 109 HTransitionElementsKind::cast(instr));
114 break; 110 break;
115 } 111 }
116 case HValue::kCheckHeapObject: { 112 case HValue::kCheckHeapObject: {
117 ReduceCheckHeapObject(HCheckHeapObject::cast(instr)); 113 ReduceCheckHeapObject(HCheckHeapObject::cast(instr));
118 break; 114 break;
119 } 115 }
120 case HValue::kCheckInstanceType: {
121 ReduceCheckInstanceType(HCheckInstanceType::cast(instr));
122 break;
123 }
124 default: { 116 default: {
125 // If the instruction changes maps uncontrollably, drop everything. 117 // If the instruction changes maps uncontrollably, drop everything.
126 if (instr->CheckChangesFlag(kOsrEntries)) { 118 if (instr->CheckChangesFlag(kOsrEntries)) {
127 Kill(); 119 Kill();
128 break; 120 break;
129 } 121 }
130 if (instr->CheckChangesFlag(kElementsKind) || 122 if (instr->CheckChangesFlag(kElementsKind) ||
131 instr->CheckChangesFlag(kMaps)) { 123 instr->CheckChangesFlag(kMaps)) {
132 KillUnstableEntries(); 124 KillUnstableEntries();
133 } 125 }
134 } 126 }
135 // Improvements possible: 127 // Improvements possible:
136 // - eliminate redundant HCheckSmi instructions 128 // - eliminate redundant HCheckSmi, HCheckInstanceType instructions
137 // - track which values have been HCheckHeapObject'd 129 // - track which values have been HCheckHeapObject'd
138 } 130 }
139 131
140 return this; 132 return this;
141 } 133 }
142 134
143 // Support for global analysis with HFlowEngine: Merge given state with 135 // Support for global analysis with HFlowEngine: Merge given state with
144 // the other incoming state. 136 // the other incoming state.
145 static HCheckTable* Merge(HCheckTable* succ_state, HBasicBlock* succ_block, 137 static HCheckTable* Merge(HCheckTable* succ_state, HBasicBlock* succ_block,
146 HCheckTable* pred_state, HBasicBlock* pred_block, 138 HCheckTable* pred_state, HBasicBlock* pred_block,
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } else { 254 } else {
263 EnsureChecked(le, cmp->left(), cmp); 255 EnsureChecked(le, cmp->left(), cmp);
264 EnsureChecked(re, cmp->right(), cmp); 256 EnsureChecked(re, cmp->right(), cmp);
265 le->maps_ = re->maps_ = le->maps_->Intersect(re->maps_, zone); 257 le->maps_ = re->maps_ = le->maps_->Intersect(re->maps_, zone);
266 le->state_ = re->state_ = HCheckTableEntry::StateMerge( 258 le->state_ = re->state_ = HCheckTableEntry::StateMerge(
267 le->state_, re->state_); 259 le->state_, re->state_);
268 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, le->state_); 260 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, le->state_);
269 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, re->state_); 261 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, re->state_);
270 } 262 }
271 learned = true; 263 learned = true;
272 } else if (end->IsIsStringAndBranch()) {
273 HIsStringAndBranch* cmp = HIsStringAndBranch::cast(end);
274 HValue* object = cmp->value()->ActualValue();
275 HCheckTableEntry* entry = copy->Find(object);
276 if (is_true_branch) {
277 // Learn on the true branch of if(IsString(x)).
278 if (entry == NULL) {
279 copy->Insert(object, NULL, string_maps(),
280 HCheckTableEntry::CHECKED);
281 } else {
282 EnsureChecked(entry, object, cmp);
283 entry->maps_ = entry->maps_->Intersect(string_maps(), zone);
284 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, entry->state_);
285 }
286 } else {
287 // Learn on the false branch of if(IsString(x)).
288 if (entry != NULL) {
289 EnsureChecked(entry, object, cmp);
290 entry->maps_ = entry->maps_->Subtract(string_maps(), zone);
291 ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, entry->state_);
292 }
293 }
294 } 264 }
295 // Learning on false branches requires storing negative facts. 265 // Learning on false branches requires storing negative facts.
296 } 266 }
297 267
298 if (FLAG_trace_check_elimination) { 268 if (FLAG_trace_check_elimination) {
299 PrintF("B%d checkmaps-table %s from B%d:\n", 269 PrintF("B%d checkmaps-table %s from B%d:\n",
300 succ->block_id(), 270 succ->block_id(),
301 learned ? "learned" : "copied", 271 learned ? "learned" : "copied",
302 from_block->block_id()); 272 from_block->block_id());
303 Print(copy); 273 Print(copy);
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
438 } else { 408 } else {
439 // No entry; insert a new one. 409 // No entry; insert a new one.
440 HCheckTableEntry::State state = instr->maps_are_stable() 410 HCheckTableEntry::State state = instr->maps_are_stable()
441 ? HCheckTableEntry::CHECKED_STABLE 411 ? HCheckTableEntry::CHECKED_STABLE
442 : HCheckTableEntry::CHECKED; 412 : HCheckTableEntry::CHECKED;
443 HCheckMaps* check = instr->IsStabilityCheck() ? NULL : instr; 413 HCheckMaps* check = instr->IsStabilityCheck() ? NULL : instr;
444 Insert(object, check, instr->maps(), state); 414 Insert(object, check, instr->maps(), state);
445 } 415 }
446 } 416 }
447 417
448 void ReduceCheckInstanceType(HCheckInstanceType* instr) {
449 HValue* value = instr->value()->ActualValue();
450 HCheckTableEntry* entry = Find(value);
451 if (entry == NULL) {
452 if (instr->check() == HCheckInstanceType::IS_STRING) {
453 Insert(value, NULL, string_maps(), HCheckTableEntry::CHECKED);
454 }
455 return;
456 }
457 UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(
458 entry->maps_->size(), zone());
459 for (int i = 0; i < entry->maps_->size(); ++i) {
460 InstanceType type;
461 Unique<Map> map = entry->maps_->at(i);
462 {
463 // This is safe, because maps don't move and their instance type does
464 // not change.
465 AllowHandleDereference allow_deref;
466 type = map.handle()->instance_type();
467 }
468 if (instr->is_interval_check()) {
469 InstanceType first_type, last_type;
470 instr->GetCheckInterval(&first_type, &last_type);
471 if (first_type <= type && type <= last_type) maps->Add(map, zone());
472 } else {
473 uint8_t mask, tag;
474 instr->GetCheckMaskAndTag(&mask, &tag);
475 if ((type & mask) == tag) maps->Add(map, zone());
476 }
477 }
478 if (maps->size() == entry->maps_->size()) {
479 TRACE(("Removing redundant CheckInstanceType #%d at B%d\n",
480 instr->id(), instr->block()->block_id()));
481 EnsureChecked(entry, value, instr);
482 instr->DeleteAndReplaceWith(value);
483 INC_STAT(removed_cit_);
484 } else if (maps->size() != 0) {
485 entry->maps_ = maps;
486 if (entry->state_ == HCheckTableEntry::UNCHECKED_STABLE) {
487 entry->state_ = HCheckTableEntry::CHECKED_STABLE;
488 }
489 }
490 }
491
492 void ReduceLoadNamedField(HLoadNamedField* instr) { 418 void ReduceLoadNamedField(HLoadNamedField* instr) {
493 // Reduce a load of the map field when it is known to be a constant. 419 // Reduce a load of the map field when it is known to be a constant.
494 if (!instr->access().IsMap()) { 420 if (!instr->access().IsMap()) {
495 // Check if we introduce field maps here. 421 // Check if we introduce field maps here.
496 MapSet maps = instr->maps(); 422 MapSet maps = instr->maps();
497 if (maps != NULL) { 423 if (maps != NULL) {
498 ASSERT_NE(0, maps->size()); 424 ASSERT_NE(0, maps->size());
499 Insert(instr, NULL, maps, HCheckTableEntry::UNCHECKED_STABLE); 425 Insert(instr, NULL, maps, HCheckTableEntry::UNCHECKED_STABLE);
500 } 426 }
501 return; 427 return;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 521
596 TRACE(("Marking redundant CompareObjectEqAndBranch #%d at B%d as false\n", 522 TRACE(("Marking redundant CompareObjectEqAndBranch #%d at B%d as false\n",
597 instr->id(), instr->block()->block_id())); 523 instr->id(), instr->block()->block_id()));
598 int succ = 1; 524 int succ = 1;
599 instr->set_known_successor_index(succ); 525 instr->set_known_successor_index(succ);
600 526
601 int unreachable_succ = 1 - succ; 527 int unreachable_succ = 1 - succ;
602 instr->block()->MarkSuccEdgeUnreachable(unreachable_succ); 528 instr->block()->MarkSuccEdgeUnreachable(unreachable_succ);
603 } 529 }
604 530
605 void ReduceIsStringAndBranch(HIsStringAndBranch* instr) {
606 HValue* value = instr->value()->ActualValue();
607 HCheckTableEntry* entry = Find(value);
608 if (entry == NULL) return;
609 EnsureChecked(entry, value, instr);
610 int succ;
611 if (entry->maps_->IsSubset(string_maps())) {
612 TRACE(("Marking redundant IsStringAndBranch #%d at B%d as true\n",
613 instr->id(), instr->block()->block_id()));
614 succ = 0;
615 } else {
616 MapSet intersection = entry->maps_->Intersect(string_maps(), zone());
617 if (intersection->size() > 0) return;
618 TRACE(("Marking redundant IsStringAndBranch #%d at B%d as false\n",
619 instr->id(), instr->block()->block_id()));
620 succ = 1;
621 }
622 instr->set_known_successor_index(succ);
623 int unreachable_succ = 1 - succ;
624 instr->block()->MarkSuccEdgeUnreachable(unreachable_succ);
625 }
626
627 void ReduceTransitionElementsKind(HTransitionElementsKind* instr) { 531 void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
628 HValue* object = instr->object()->ActualValue(); 532 HValue* object = instr->object()->ActualValue();
629 HCheckTableEntry* entry = Find(object); 533 HCheckTableEntry* entry = Find(object);
630 // Can only learn more about an object that already has a known set of maps. 534 // Can only learn more about an object that already has a known set of maps.
631 if (entry == NULL) return; 535 if (entry == NULL) return;
632 EnsureChecked(entry, object, instr); 536 EnsureChecked(entry, object, instr);
633 if (entry->maps_->Contains(instr->original_map())) { 537 if (entry->maps_->Contains(instr->original_map())) {
634 // If the object has the original map, it will be transitioned. 538 // If the object has the original map, it will be transitioned.
635 UniqueSet<Map>* maps = entry->maps_->Copy(zone()); 539 UniqueSet<Map>* maps = entry->maps_->Copy(zone());
636 maps->Remove(instr->original_map()); 540 maps->Remove(instr->original_map());
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 entry->object_ = object; 681 entry->object_ = object;
778 entry->check_ = check; 682 entry->check_ = check;
779 entry->maps_ = maps; 683 entry->maps_ = maps;
780 entry->state_ = state; 684 entry->state_ = state;
781 // If the table becomes full, wrap around and overwrite older entries. 685 // If the table becomes full, wrap around and overwrite older entries.
782 if (cursor_ == kMaxTrackedObjects) cursor_ = 0; 686 if (cursor_ == kMaxTrackedObjects) cursor_ = 0;
783 if (size_ < kMaxTrackedObjects) size_++; 687 if (size_ < kMaxTrackedObjects) size_++;
784 } 688 }
785 689
786 Zone* zone() const { return phase_->zone(); } 690 Zone* zone() const { return phase_->zone(); }
787 MapSet string_maps() const { return phase_->string_maps(); }
788 691
789 friend class HCheckMapsEffects; 692 friend class HCheckMapsEffects;
790 friend class HCheckEliminationPhase; 693 friend class HCheckEliminationPhase;
791 694
792 HCheckEliminationPhase* phase_; 695 HCheckEliminationPhase* phase_;
793 HCheckTableEntry entries_[kMaxTrackedObjects]; 696 HCheckTableEntry entries_[kMaxTrackedObjects];
794 int16_t cursor_; // Must be <= kMaxTrackedObjects 697 int16_t cursor_; // Must be <= kMaxTrackedObjects
795 int16_t size_; // Must be <= kMaxTrackedObjects 698 int16_t size_; // Must be <= kMaxTrackedObjects
796 STATIC_ASSERT(kMaxTrackedObjects < (1 << 15)); 699 STATIC_ASSERT(kMaxTrackedObjects < (1 << 15));
797 }; 700 };
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
884 // Are we eliminated yet? 787 // Are we eliminated yet?
885 void HCheckEliminationPhase::PrintStats() { 788 void HCheckEliminationPhase::PrintStats() {
886 #if DEBUG 789 #if DEBUG
887 #define PRINT_STAT(x) if (x##_ > 0) PrintF(" %-16s = %2d\n", #x, x##_) 790 #define PRINT_STAT(x) if (x##_ > 0) PrintF(" %-16s = %2d\n", #x, x##_)
888 #else 791 #else
889 #define PRINT_STAT(x) 792 #define PRINT_STAT(x)
890 #endif 793 #endif
891 PRINT_STAT(redundant); 794 PRINT_STAT(redundant);
892 PRINT_STAT(removed); 795 PRINT_STAT(removed);
893 PRINT_STAT(removed_cho); 796 PRINT_STAT(removed_cho);
894 PRINT_STAT(removed_cit);
895 PRINT_STAT(narrowed); 797 PRINT_STAT(narrowed);
896 PRINT_STAT(loads); 798 PRINT_STAT(loads);
897 PRINT_STAT(empty); 799 PRINT_STAT(empty);
898 PRINT_STAT(compares_true); 800 PRINT_STAT(compares_true);
899 PRINT_STAT(compares_false); 801 PRINT_STAT(compares_false);
900 PRINT_STAT(transitions); 802 PRINT_STAT(transitions);
901 } 803 }
902 804
903 } } // namespace v8::internal 805 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/hydrogen-check-elimination.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698