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

Side by Side Diff: src/hydrogen-gvn.cc

Issue 17657004: Refactor Hydrogen GVN into an HPhase and use the phase zone. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 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
« src/hydrogen-gvn.h ('K') | « src/hydrogen-gvn.h ('k') | no next file » | 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 // 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 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { 354 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
355 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); 355 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
356 if (flags.Contains(changes_flag)) { 356 if (flags.Contains(changes_flag)) {
357 if (data_[i] == NULL) count_++; 357 if (data_[i] == NULL) count_++;
358 data_[i] = instr; 358 data_[i] = instr;
359 } 359 }
360 } 360 }
361 } 361 }
362 362
363 363
364 HGlobalValueNumberer::HGlobalValueNumberer(HGraph* graph, CompilationInfo* info) 364 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph,
365 : graph_(graph), 365 Zone* zone)
366 info_(info), 366 : HPhase("H_Global value numbering", graph, zone),
367 removed_side_effects_(false), 367 removed_side_effects_(false),
368 phase_zone_(info->phase_zone()), 368 block_side_effects_(graph->blocks()->length(), zone),
369 phase_zone_scope_(phase_zone_, DELETE_ON_EXIT), 369 loop_side_effects_(graph->blocks()->length(), zone),
370 block_side_effects_(graph->blocks()->length(), phase_zone_), 370 visited_on_paths_(zone, graph->blocks()->length()) {
371 loop_side_effects_(graph->blocks()->length(), phase_zone_),
372 visited_on_paths_(phase_zone_, graph->blocks()->length()) {
373 ASSERT(!AllowHandleAllocation::IsAllowed()); 371 ASSERT(!AllowHandleAllocation::IsAllowed());
374 block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(), 372 block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), zone);
375 phase_zone_); 373 loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), zone);
376 loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length(),
377 phase_zone_);
378 } 374 }
379 375
380 bool HGlobalValueNumberer::Analyze() { 376 bool HGlobalValueNumberingPhase::Analyze() {
381 removed_side_effects_ = false; 377 removed_side_effects_ = false;
382 ComputeBlockSideEffects(); 378 ComputeBlockSideEffects();
383 if (FLAG_loop_invariant_code_motion) { 379 if (FLAG_loop_invariant_code_motion) {
384 LoopInvariantCodeMotion(); 380 LoopInvariantCodeMotion();
385 } 381 }
386 AnalyzeGraph(); 382 AnalyzeGraph();
387 return removed_side_effects_; 383 return removed_side_effects_;
388 } 384 }
389 385
390 386
391 void HGlobalValueNumberer::ComputeBlockSideEffects() { 387 void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
392 // The Analyze phase of GVN can be called multiple times. Clear loop side 388 // The Analyze phase of GVN can be called multiple times. Clear loop side
393 // effects before computing them to erase the contents from previous Analyze 389 // effects before computing them to erase the contents from previous Analyze
394 // passes. 390 // passes.
395 for (int i = 0; i < loop_side_effects_.length(); ++i) { 391 for (int i = 0; i < loop_side_effects_.length(); ++i) {
396 loop_side_effects_[i].RemoveAll(); 392 loop_side_effects_[i].RemoveAll();
397 } 393 }
398 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 394 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
399 // Compute side effects for the block. 395 // Compute side effects for the block.
400 HBasicBlock* block = graph_->blocks()->at(i); 396 HBasicBlock* block = graph()->blocks()->at(i);
401 HInstruction* instr = block->first(); 397 HInstruction* instr = block->first();
402 int id = block->block_id(); 398 int id = block->block_id();
403 GVNFlagSet side_effects; 399 GVNFlagSet side_effects;
404 while (instr != NULL) { 400 while (instr != NULL) {
405 side_effects.Add(instr->ChangesFlags()); 401 side_effects.Add(instr->ChangesFlags());
406 if (instr->IsSoftDeoptimize()) { 402 if (instr->IsSoftDeoptimize()) {
407 block_side_effects_[id].RemoveAll(); 403 block_side_effects_[id].RemoveAll();
408 side_effects.RemoveAll(); 404 side_effects.RemoveAll();
409 break; 405 break;
410 } 406 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 OS::SNPrintF(buffer, "0x%08X", flags.ToIntegral()); 503 OS::SNPrintF(buffer, "0x%08X", flags.ToIntegral());
508 #endif 504 #endif
509 size_t string_len = strlen(underlying_buffer) + 1; 505 size_t string_len = strlen(underlying_buffer) + 1;
510 ASSERT(string_len <= sizeof(underlying_buffer)); 506 ASSERT(string_len <= sizeof(underlying_buffer));
511 char* result = new char[strlen(underlying_buffer) + 1]; 507 char* result = new char[strlen(underlying_buffer) + 1];
512 OS::MemCopy(result, underlying_buffer, string_len); 508 OS::MemCopy(result, underlying_buffer, string_len);
513 return SmartArrayPointer<char>(result); 509 return SmartArrayPointer<char>(result);
514 } 510 }
515 511
516 512
517 void HGlobalValueNumberer::LoopInvariantCodeMotion() { 513 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
518 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n", 514 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n",
519 graph_->use_optimistic_licm() ? "yes" : "no"); 515 graph()->use_optimistic_licm() ? "yes" : "no");
520 for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { 516 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
521 HBasicBlock* block = graph_->blocks()->at(i); 517 HBasicBlock* block = graph()->blocks()->at(i);
522 if (block->IsLoopHeader()) { 518 if (block->IsLoopHeader()) {
523 GVNFlagSet side_effects = loop_side_effects_[block->block_id()]; 519 GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
524 TRACE_GVN_2("Try loop invariant motion for block B%d %s\n", 520 TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
525 block->block_id(), 521 block->block_id(),
526 *GetGVNFlagsString(side_effects)); 522 *GetGVNFlagsString(side_effects));
527 523
528 GVNFlagSet accumulated_first_time_depends; 524 GVNFlagSet accumulated_first_time_depends;
529 GVNFlagSet accumulated_first_time_changes; 525 GVNFlagSet accumulated_first_time_changes;
530 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); 526 HBasicBlock* last = block->loop_information()->GetLastBackEdge();
531 for (int j = block->block_id(); j <= last->block_id(); ++j) { 527 for (int j = block->block_id(); j <= last->block_id(); ++j) {
532 ProcessLoopBlock(graph_->blocks()->at(j), block, side_effects, 528 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects,
533 &accumulated_first_time_depends, 529 &accumulated_first_time_depends,
534 &accumulated_first_time_changes); 530 &accumulated_first_time_changes);
535 } 531 }
536 } 532 }
537 } 533 }
538 } 534 }
539 535
540 536
541 void HGlobalValueNumberer::ProcessLoopBlock( 537 void HGlobalValueNumberingPhase::ProcessLoopBlock(
542 HBasicBlock* block, 538 HBasicBlock* block,
543 HBasicBlock* loop_header, 539 HBasicBlock* loop_header,
544 GVNFlagSet loop_kills, 540 GVNFlagSet loop_kills,
545 GVNFlagSet* first_time_depends, 541 GVNFlagSet* first_time_depends,
546 GVNFlagSet* first_time_changes) { 542 GVNFlagSet* first_time_changes) {
547 HBasicBlock* pre_header = loop_header->predecessors()->at(0); 543 HBasicBlock* pre_header = loop_header->predecessors()->at(0);
548 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); 544 GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
549 TRACE_GVN_2("Loop invariant motion for B%d %s\n", 545 TRACE_GVN_2("Loop invariant motion for B%d %s\n",
550 block->block_id(), 546 block->block_id(),
551 *GetGVNFlagsString(depends_flags)); 547 *GetGVNFlagsString(depends_flags));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
596 if (!(previous_changes == *first_time_changes)) { 592 if (!(previous_changes == *first_time_changes)) {
597 TRACE_GVN_1("Updated first-time accumulated %s\n", 593 TRACE_GVN_1("Updated first-time accumulated %s\n",
598 *GetGVNFlagsString(*first_time_changes)); 594 *GetGVNFlagsString(*first_time_changes));
599 } 595 }
600 } 596 }
601 instr = next; 597 instr = next;
602 } 598 }
603 } 599 }
604 600
605 601
606 bool HGlobalValueNumberer::AllowCodeMotion() { 602 bool HGlobalValueNumberingPhase::AllowCodeMotion() {
607 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; 603 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count;
608 } 604 }
609 605
610 606
611 bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, 607 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr,
612 HBasicBlock* loop_header) { 608 HBasicBlock* loop_header) {
613 // If we've disabled code motion or we're in a block that unconditionally 609 // If we've disabled code motion or we're in a block that unconditionally
614 // deoptimizes, don't move any instructions. 610 // deoptimizes, don't move any instructions.
615 return AllowCodeMotion() && !instr->block()->IsDeoptimizing(); 611 return AllowCodeMotion() && !instr->block()->IsDeoptimizing();
616 } 612 }
617 613
618 614
619 GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( 615 GVNFlagSet HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock
620 HBasicBlock* dominator, HBasicBlock* dominated) { 616 (HBasicBlock* dominator, HBasicBlock* dominated) {
621 GVNFlagSet side_effects; 617 GVNFlagSet side_effects;
622 for (int i = 0; i < dominated->predecessors()->length(); ++i) { 618 for (int i = 0; i < dominated->predecessors()->length(); ++i) {
623 HBasicBlock* block = dominated->predecessors()->at(i); 619 HBasicBlock* block = dominated->predecessors()->at(i);
624 if (dominator->block_id() < block->block_id() && 620 if (dominator->block_id() < block->block_id() &&
625 block->block_id() < dominated->block_id() && 621 block->block_id() < dominated->block_id() &&
626 visited_on_paths_.Add(block->block_id())) { 622 visited_on_paths_.Add(block->block_id())) {
627 side_effects.Add(block_side_effects_[block->block_id()]); 623 side_effects.Add(block_side_effects_[block->block_id()]);
628 if (block->IsLoopHeader()) { 624 if (block->IsLoopHeader()) {
629 side_effects.Add(loop_side_effects_[block->block_id()]); 625 side_effects.Add(loop_side_effects_[block->block_id()]);
630 } 626 }
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
749 HValueMap* map_; 745 HValueMap* map_;
750 HSideEffectMap dominators_; 746 HSideEffectMap dominators_;
751 int dominated_index_; 747 int dominated_index_;
752 int length_; 748 int length_;
753 }; 749 };
754 750
755 // This is a recursive traversal of the dominator tree but it has been turned 751 // This is a recursive traversal of the dominator tree but it has been turned
756 // into a loop to avoid stack overflows. 752 // into a loop to avoid stack overflows.
757 // The logical "stack frames" of the recursion are kept in a list of 753 // The logical "stack frames" of the recursion are kept in a list of
758 // GvnBasicBlockState instances. 754 // GvnBasicBlockState instances.
759 void HGlobalValueNumberer::AnalyzeGraph() { 755 void HGlobalValueNumberingPhase::AnalyzeGraph() {
760 HBasicBlock* entry_block = graph_->entry_block(); 756 HBasicBlock* entry_block = graph()->entry_block();
761 HValueMap* entry_map = new(phase_zone()) HValueMap(phase_zone()); 757 HValueMap* entry_map = new(zone()) HValueMap(zone());
762 GvnBasicBlockState* current = 758 GvnBasicBlockState* current =
763 GvnBasicBlockState::CreateEntry(phase_zone(), entry_block, entry_map); 759 GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map);
764 760
765 while (current != NULL) { 761 while (current != NULL) {
766 HBasicBlock* block = current->block(); 762 HBasicBlock* block = current->block();
767 HValueMap* map = current->map(); 763 HValueMap* map = current->map();
768 HSideEffectMap* dominators = current->dominators(); 764 HSideEffectMap* dominators = current->dominators();
769 765
770 TRACE_GVN_2("Analyzing block B%d%s\n", 766 TRACE_GVN_2("Analyzing block B%d%s\n",
771 block->block_id(), 767 block->block_id(),
772 block->IsLoopHeader() ? " (loop header)" : ""); 768 block->IsLoopHeader() ? " (loop header)" : "");
773 769
(...skipping 21 matching lines...) Expand all
795 if (other != NULL) { 791 if (other != NULL) {
796 ASSERT(instr->Equals(other) && other->Equals(instr)); 792 ASSERT(instr->Equals(other) && other->Equals(instr));
797 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", 793 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n",
798 instr->id(), 794 instr->id(),
799 instr->Mnemonic(), 795 instr->Mnemonic(),
800 other->id(), 796 other->id(),
801 other->Mnemonic()); 797 other->Mnemonic());
802 if (instr->HasSideEffects()) removed_side_effects_ = true; 798 if (instr->HasSideEffects()) removed_side_effects_ = true;
803 instr->DeleteAndReplaceWith(other); 799 instr->DeleteAndReplaceWith(other);
804 } else { 800 } else {
805 map->Add(instr, phase_zone()); 801 map->Add(instr, zone());
806 } 802 }
807 } 803 }
808 if (instr->IsLinked() && 804 if (instr->IsLinked() &&
809 instr->CheckFlag(HValue::kTrackSideEffectDominators)) { 805 instr->CheckFlag(HValue::kTrackSideEffectDominators)) {
810 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { 806 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
811 HValue* other = dominators->at(i); 807 HValue* other = dominators->at(i);
812 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); 808 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
813 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); 809 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i);
814 if (instr->DependsOnFlags().Contains(depends_on_flag) && 810 if (instr->DependsOnFlags().Contains(depends_on_flag) &&
815 (other != NULL)) { 811 (other != NULL)) {
816 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", 812 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n",
817 i, 813 i,
818 instr->id(), 814 instr->id(),
819 instr->Mnemonic(), 815 instr->Mnemonic(),
820 other->id(), 816 other->id(),
821 other->Mnemonic()); 817 other->Mnemonic());
822 instr->SetSideEffectDominator(changes_flag, other); 818 instr->SetSideEffectDominator(changes_flag, other);
823 } 819 }
824 } 820 }
825 } 821 }
826 instr = next; 822 instr = next;
827 } 823 }
828 824
829 HBasicBlock* dominator_block; 825 HBasicBlock* dominator_block;
830 GvnBasicBlockState* next = 826 GvnBasicBlockState* next =
831 current->next_in_dominator_tree_traversal(phase_zone(), 827 current->next_in_dominator_tree_traversal(zone(),
832 &dominator_block); 828 &dominator_block);
833 829
834 if (next != NULL) { 830 if (next != NULL) {
835 HBasicBlock* dominated = next->block(); 831 HBasicBlock* dominated = next->block();
836 HValueMap* successor_map = next->map(); 832 HValueMap* successor_map = next->map();
837 HSideEffectMap* successor_dominators = next->dominators(); 833 HSideEffectMap* successor_dominators = next->dominators();
838 834
839 // Kill everything killed on any path between this block and the 835 // Kill everything killed on any path between this block and the
840 // dominated block. We don't have to traverse these paths if the 836 // dominated block. We don't have to traverse these paths if the
841 // value map and the dominators list is already empty. If the range 837 // value map and the dominators list is already empty. If the range
842 // of block ids (block_id, dominated_id) is empty there are no such 838 // of block ids (block_id, dominated_id) is empty there are no such
843 // paths. 839 // paths.
844 if ((!successor_map->IsEmpty() || !successor_dominators->IsEmpty()) && 840 if ((!successor_map->IsEmpty() || !successor_dominators->IsEmpty()) &&
845 dominator_block->block_id() + 1 < dominated->block_id()) { 841 dominator_block->block_id() + 1 < dominated->block_id()) {
846 visited_on_paths_.Clear(); 842 visited_on_paths_.Clear();
847 GVNFlagSet side_effects_on_all_paths = 843 GVNFlagSet side_effects_on_all_paths =
848 CollectSideEffectsOnPathsToDominatedBlock(dominator_block, 844 CollectSideEffectsOnPathsToDominatedBlock(dominator_block,
849 dominated); 845 dominated);
850 successor_map->Kill(side_effects_on_all_paths); 846 successor_map->Kill(side_effects_on_all_paths);
851 successor_dominators->Kill(side_effects_on_all_paths); 847 successor_dominators->Kill(side_effects_on_all_paths);
852 } 848 }
853 } 849 }
854 current = next; 850 current = next;
855 } 851 }
856 } 852 }
857 853
858 } } // namespace v8::internal 854 } } // namespace v8::internal
OLDNEW
« src/hydrogen-gvn.h ('K') | « src/hydrogen-gvn.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698