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

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 11571057: Simplify basic block discovery -- handle all blcoks uniformly. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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 | « runtime/vm/intermediate_language.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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 GrowableArray<BlockEntryInstr*>* preorder) { 695 GrowableArray<BlockEntryInstr*>* preorder) {
696 // Detect that a block has been visited as part of the current 696 // Detect that a block has been visited as part of the current
697 // DiscoverBlocks (we can call DiscoverBlocks multiple times). The block 697 // DiscoverBlocks (we can call DiscoverBlocks multiple times). The block
698 // will be 'marked' by (1) having a preorder number in the range of the 698 // will be 'marked' by (1) having a preorder number in the range of the
699 // preorder array and (2) being in the preorder array at that index. 699 // preorder array and (2) being in the preorder array at that index.
700 intptr_t i = block->preorder_number(); 700 intptr_t i = block->preorder_number();
701 return (i >= 0) && (i < preorder->length()) && ((*preorder)[i] == block); 701 return (i >= 0) && (i < preorder->length()) && ((*preorder)[i] == block);
702 } 702 }
703 703
704 704
705 void GraphEntryInstr::DiscoverBlocks( 705 // Base class implementation used for JoinEntry and TargetEntry.
706 BlockEntryInstr* current_block, 706 void BlockEntryInstr::DiscoverBlocks(
707 BlockEntryInstr* predecessor,
707 GrowableArray<BlockEntryInstr*>* preorder, 708 GrowableArray<BlockEntryInstr*>* preorder,
708 GrowableArray<BlockEntryInstr*>* postorder, 709 GrowableArray<BlockEntryInstr*>* postorder,
709 GrowableArray<intptr_t>* parent, 710 GrowableArray<intptr_t>* parent,
710 GrowableArray<BitVector*>* assigned_vars, 711 GrowableArray<BitVector*>* assigned_vars,
711 intptr_t variable_count, 712 intptr_t variable_count,
712 intptr_t fixed_parameter_count) { 713 intptr_t fixed_parameter_count) {
713 // We only visit this block once, first of all blocks. 714 // If this block has a predecessor (i.e., is not the graph entry) we can
714 ASSERT(!IsMarked(this, preorder)); 715 // assume the preorder array is non-empty.
715 ASSERT(current_block == NULL); 716 ASSERT((predecessor == NULL) || !preorder->is_empty());
716 ASSERT(preorder->is_empty());
717 ASSERT(postorder->is_empty());
718 ASSERT(parent->is_empty());
719
720 // This node has no parent, indicated by -1. The preorder number is 0.
721 parent->Add(-1);
722 set_preorder_number(0);
723 preorder->Add(this);
724 BitVector* vars =
725 (variable_count == 0) ? NULL : new BitVector(variable_count);
726 assigned_vars->Add(vars);
727
728 // The graph entry consists of only one instruction.
729 set_last_instruction(this);
730
731 // Iteratively traverse all successors. In the unoptimized code, we will
732 // enter the function at the first successor in reverse postorder, so we
733 // must visit the normal entry last.
734 for (intptr_t i = catch_entries_.length() - 1; i >= 0; --i) {
735 catch_entries_[i]->DiscoverBlocks(this, preorder, postorder,
736 parent, assigned_vars,
737 variable_count, fixed_parameter_count);
738 }
739 normal_entry_->DiscoverBlocks(this, preorder, postorder,
740 parent, assigned_vars,
741 variable_count, fixed_parameter_count);
742
743 // Assign postorder number.
744 set_postorder_number(postorder->length());
745 postorder->Add(this);
746 }
747
748
749 // Base class implementation used for JoinEntry and TargetEntry.
750 void BlockEntryInstr::DiscoverBlocks(
751 BlockEntryInstr* current_block,
752 GrowableArray<BlockEntryInstr*>* preorder,
753 GrowableArray<BlockEntryInstr*>* postorder,
754 GrowableArray<intptr_t>* parent,
755 GrowableArray<BitVector*>* assigned_vars,
756 intptr_t variable_count,
757 intptr_t fixed_parameter_count) {
758 // We have already visited the graph entry, so we can assume current_block
759 // is non-null and preorder array is non-empty.
760 ASSERT(current_block != NULL);
761 ASSERT(!preorder->is_empty());
762 // Blocks with a single predecessor cannot have been reached before. 717 // Blocks with a single predecessor cannot have been reached before.
763 ASSERT(!IsTargetEntry() || !IsMarked(this, preorder)); 718 ASSERT(IsJoinEntry() || !IsMarked(this, preorder));
764 719
765 // 1. If the block has already been reached, add current_block as a 720 // 1. If the block has already been reached, add current_block as a
766 // basic-block predecessor and we are done. 721 // basic-block predecessor and we are done.
767 if (IsMarked(this, preorder)) { 722 if (IsMarked(this, preorder)) {
768 AddPredecessor(current_block); 723 ASSERT(predecessor != NULL);
724 AddPredecessor(predecessor);
769 return; 725 return;
770 } 726 }
771 727
772 // 2. Otherwise, clear the predecessors which might have been computed on 728 // 2. Otherwise, clear the predecessors which might have been computed on
773 // some earlier call to DiscoverBlocks and record this predecessor. For 729 // some earlier call to DiscoverBlocks and record this predecessor.
774 // joins save the original predecessors, if any, so we can garbage collect
775 // phi inputs from unreachable predecessors without recomputing SSA.
776 ClearPredecessors(); 730 ClearPredecessors();
777 AddPredecessor(current_block); 731 if (predecessor != NULL) AddPredecessor(predecessor);
778 732
779 // 3. The current block is the spanning-tree parent. 733 // 3. The predecessor is the spanning-tree parent. The graph entry has no
780 parent->Add(current_block->preorder_number()); 734 // parent, indicated by -1.
735 intptr_t parent_number =
736 (predecessor == NULL) ? -1 : predecessor->preorder_number();
737 parent->Add(parent_number);
781 738
782 // 4. Assign preorder number and add the block entry to the list. 739 // 4. Assign the preorder number and add the block entry to the list.
783 // Allocate an empty set of assigned variables for the block. 740 // Allocate an empty set of assigned variables for the block.
784 set_preorder_number(preorder->length()); 741 set_preorder_number(preorder->length());
785 preorder->Add(this); 742 preorder->Add(this);
786 BitVector* vars = 743 BitVector* vars =
787 (variable_count == 0) ? NULL : new BitVector(variable_count); 744 (variable_count == 0) ? NULL : new BitVector(variable_count);
788 assigned_vars->Add(vars); 745 assigned_vars->Add(vars);
789 // The preorder, parent, and assigned_vars arrays are all indexed by 746 // The preorder, parent, and assigned_vars arrays are all indexed by
790 // preorder block number, so they should stay in lockstep. 747 // preorder block number, so they should stay in lockstep.
791 ASSERT(preorder->length() == parent->length()); 748 ASSERT(preorder->length() == parent->length());
792 ASSERT(preorder->length() == assigned_vars->length()); 749 ASSERT(preorder->length() == assigned_vars->length());
793 750
794 // 5. Iterate straight-line successors until a branch instruction or 751 // 5. Iterate straight-line successors to record assigned variables and
795 // another basic block entry instruction, and visit that instruction. 752 // find the last instruction in the block. The graph entry block consists
796 ASSERT(next() != NULL); 753 // of only the entry instruction, so that is the last instruction in the
797 ASSERT(!next()->IsBlockEntry()); 754 // block.
798 Instruction* next_instr = next(); 755 Instruction* last = this;
799 while ((next_instr != NULL) && 756 for (ForwardInstructionIterator it(this); !it.Done(); it.Advance()) {
800 !next_instr->IsBlockEntry() && 757 last = it.Current();
801 !next_instr->IsControl()) {
802 if (vars != NULL) { 758 if (vars != NULL) {
803 next_instr->RecordAssignedVars(vars, fixed_parameter_count); 759 last->RecordAssignedVars(vars, fixed_parameter_count);
804 } 760 }
805 set_last_instruction(next_instr);
806 GotoInstr* goto_instr = next_instr->AsGoto();
807 next_instr =
808 (goto_instr != NULL) ? goto_instr->successor() : next_instr->next();
809 } 761 }
810 if (next_instr != NULL) { 762 set_last_instruction(last);
811 next_instr->DiscoverBlocks(this, preorder, postorder, 763
812 parent, assigned_vars, 764 // Visit the block's successors in reverse so that they appear forwards
813 variable_count, fixed_parameter_count); 765 // the reverse postorder block ordering.
766 for (intptr_t i = last->SuccessorCount() - 1; i >= 0; --i) {
767 last->SuccessorAt(i)->DiscoverBlocks(this, preorder, postorder,
768 parent, assigned_vars,
769 variable_count, fixed_parameter_count);
814 } 770 }
815 771
816 // 6. Assign postorder number and add the block entry to the list. 772 // 6. Assign postorder number and add the block entry to the list.
817 set_postorder_number(postorder->length()); 773 set_postorder_number(postorder->length());
818 postorder->Add(this); 774 postorder->Add(this);
819 } 775 }
820 776
821 777
822 bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const { 778 bool BlockEntryInstr::Dominates(BlockEntryInstr* other) const {
823 // TODO(fschneider): Make this faster by e.g. storing dominators for each 779 // TODO(fschneider): Make this faster by e.g. storing dominators for each
824 // block while computing the dominator tree. 780 // block while computing the dominator tree.
825 ASSERT(other != NULL); 781 ASSERT(other != NULL);
826 BlockEntryInstr* current = other; 782 BlockEntryInstr* current = other;
827 while (current != NULL && current != this) { 783 while (current != NULL && current != this) {
828 current = current->dominator(); 784 current = current->dominator();
829 } 785 }
830 return current == this; 786 return current == this;
831 } 787 }
832 788
833 789
834 void ControlInstruction::DiscoverBlocks(
835 BlockEntryInstr* current_block,
836 GrowableArray<BlockEntryInstr*>* preorder,
837 GrowableArray<BlockEntryInstr*>* postorder,
838 GrowableArray<intptr_t>* parent,
839 GrowableArray<BitVector*>* assigned_vars,
840 intptr_t variable_count,
841 intptr_t fixed_parameter_count) {
842 current_block->set_last_instruction(this);
843 // Visit the false successor before the true successor so they appear in
844 // true/false order in reverse postorder used as the block ordering in the
845 // nonoptimizing compiler.
846 ASSERT(true_successor_ != NULL);
847 ASSERT(false_successor_ != NULL);
848 false_successor_->DiscoverBlocks(current_block, preorder, postorder,
849 parent, assigned_vars,
850 variable_count, fixed_parameter_count);
851 true_successor_->DiscoverBlocks(current_block, preorder, postorder,
852 parent, assigned_vars,
853 variable_count, fixed_parameter_count);
854 }
855
856
857 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { 790 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) {
858 // Lazily initialize the array of phis. 791 // Lazily initialize the array of phis.
859 // Currently, phis are stored in a sparse array that holds the phi 792 // Currently, phis are stored in a sparse array that holds the phi
860 // for variable with index i at position i. 793 // for variable with index i at position i.
861 // TODO(fschneider): Store phis in a more compact way. 794 // TODO(fschneider): Store phis in a more compact way.
862 if (phis_ == NULL) { 795 if (phis_ == NULL) {
863 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count); 796 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count);
864 for (intptr_t i = 0; i < var_count; i++) { 797 for (intptr_t i = 0; i < var_count; i++) {
865 phis_->Add(NULL); 798 phis_->Add(NULL);
866 } 799 }
(...skipping 1905 matching lines...) Expand 10 before | Expand all | Expand 10 after
2772 default: 2705 default:
2773 UNREACHABLE(); 2706 UNREACHABLE();
2774 return -1; 2707 return -1;
2775 } 2708 }
2776 } 2709 }
2777 2710
2778 2711
2779 #undef __ 2712 #undef __
2780 2713
2781 } // namespace dart 2714 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698