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

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

Issue 10949020: Reapply "Initial implementation of sparse conditional constant propagation." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rebase to HEAD. Created 8 years, 3 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
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 // graph entry with no predecessor. Joins are the only nodes with multiple 600 // graph entry with no predecessor. Joins are the only nodes with multiple
601 // predecessors. Targets are all other basic block entries. The types 601 // predecessors. Targets are all other basic block entries. The types
602 // enforce edge-split form---joins are forbidden as the successors of 602 // enforce edge-split form---joins are forbidden as the successors of
603 // branches. 603 // branches.
604 class BlockEntryInstr : public Instruction { 604 class BlockEntryInstr : public Instruction {
605 public: 605 public:
606 virtual BlockEntryInstr* AsBlockEntry() { return this; } 606 virtual BlockEntryInstr* AsBlockEntry() { return this; }
607 607
608 virtual intptr_t PredecessorCount() const = 0; 608 virtual intptr_t PredecessorCount() const = 0;
609 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; 609 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0;
610 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
611 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0; 610 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0;
612 611
613 intptr_t preorder_number() const { return preorder_number_; } 612 intptr_t preorder_number() const { return preorder_number_; }
614 void set_preorder_number(intptr_t number) { preorder_number_ = number; } 613 void set_preorder_number(intptr_t number) { preorder_number_ = number; }
615 614
616 intptr_t postorder_number() const { return postorder_number_; } 615 intptr_t postorder_number() const { return postorder_number_; }
617 void set_postorder_number(intptr_t number) { postorder_number_ = number; } 616 void set_postorder_number(intptr_t number) { postorder_number_ = number; }
618 617
619 intptr_t block_id() const { return block_id_; } 618 intptr_t block_id() const { return block_id_; }
620 void set_block_id(intptr_t value) { block_id_ = value; } 619 void set_block_id(intptr_t value) { block_id_ = value; }
621 620
622 void set_start_pos(intptr_t pos) { start_pos_ = pos; } 621 void set_start_pos(intptr_t pos) { start_pos_ = pos; }
623 intptr_t start_pos() const { return start_pos_; } 622 intptr_t start_pos() const { return start_pos_; }
624 void set_end_pos(intptr_t pos) { end_pos_ = pos; } 623 void set_end_pos(intptr_t pos) { end_pos_ = pos; }
625 intptr_t end_pos() const { return end_pos_; } 624 intptr_t end_pos() const { return end_pos_; }
626 625
627 BlockEntryInstr* dominator() const { return dominator_; } 626 BlockEntryInstr* dominator() const { return dominator_; }
628 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } 627 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; }
629 628
630 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { 629 const GrowableArray<BlockEntryInstr*>& dominated_blocks() {
631 return dominated_blocks_; 630 return dominated_blocks_;
632 } 631 }
633 632
634 void AddDominatedBlock(BlockEntryInstr* block) { 633 void AddDominatedBlock(BlockEntryInstr* block) {
635 dominated_blocks_.Add(block); 634 dominated_blocks_.Add(block);
636 } 635 }
636 void ClearDominatedBlocks() { dominated_blocks_.Clear(); }
637 637
638 bool Dominates(BlockEntryInstr* other) const; 638 bool Dominates(BlockEntryInstr* other) const;
639 639
640 Instruction* last_instruction() const { return last_instruction_; } 640 Instruction* last_instruction() const { return last_instruction_; }
641 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; } 641 void set_last_instruction(Instruction* instr) { last_instruction_ = instr; }
642 642
643 ParallelMoveInstr* parallel_move() const { 643 ParallelMoveInstr* parallel_move() const {
644 return parallel_move_; 644 return parallel_move_;
645 } 645 }
646 646
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
690 preorder_number_(-1), 690 preorder_number_(-1),
691 postorder_number_(-1), 691 postorder_number_(-1),
692 block_id_(-1), 692 block_id_(-1),
693 dominator_(NULL), 693 dominator_(NULL),
694 dominated_blocks_(1), 694 dominated_blocks_(1),
695 last_instruction_(NULL), 695 last_instruction_(NULL),
696 parallel_move_(NULL), 696 parallel_move_(NULL),
697 loop_info_(NULL) { } 697 loop_info_(NULL) { }
698 698
699 private: 699 private:
700 virtual void ClearPredecessors() = 0;
701 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0;
702
700 const intptr_t try_index_; 703 const intptr_t try_index_;
701 intptr_t preorder_number_; 704 intptr_t preorder_number_;
702 intptr_t postorder_number_; 705 intptr_t postorder_number_;
703 // Starting and ending lifetime positions for this block. Used by 706 // Starting and ending lifetime positions for this block. Used by
704 // the linear scan register allocator. 707 // the linear scan register allocator.
705 intptr_t block_id_; 708 intptr_t block_id_;
706 intptr_t start_pos_; 709 intptr_t start_pos_;
707 intptr_t end_pos_; 710 intptr_t end_pos_;
708 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. 711 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry.
709 // TODO(fschneider): Optimize the case of one child to save space. 712 // TODO(fschneider): Optimize the case of one child to save space.
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 public: 781 public:
779 explicit GraphEntryInstr(TargetEntryInstr* normal_entry); 782 explicit GraphEntryInstr(TargetEntryInstr* normal_entry);
780 783
781 DECLARE_INSTRUCTION(GraphEntry) 784 DECLARE_INSTRUCTION(GraphEntry)
782 785
783 virtual intptr_t PredecessorCount() const { return 0; } 786 virtual intptr_t PredecessorCount() const { return 0; }
784 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { 787 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const {
785 UNREACHABLE(); 788 UNREACHABLE();
786 return NULL; 789 return NULL;
787 } 790 }
788 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
789
790 virtual intptr_t SuccessorCount() const; 791 virtual intptr_t SuccessorCount() const;
791 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 792 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
792 793
793 virtual void DiscoverBlocks( 794 virtual void DiscoverBlocks(
794 BlockEntryInstr* current_block, 795 BlockEntryInstr* current_block,
795 GrowableArray<BlockEntryInstr*>* preorder, 796 GrowableArray<BlockEntryInstr*>* preorder,
796 GrowableArray<BlockEntryInstr*>* postorder, 797 GrowableArray<BlockEntryInstr*>* postorder,
797 GrowableArray<intptr_t>* parent, 798 GrowableArray<intptr_t>* parent,
798 GrowableArray<BitVector*>* assigned_vars, 799 GrowableArray<BitVector*>* assigned_vars,
799 intptr_t variable_count, 800 intptr_t variable_count,
(...skipping 13 matching lines...) Expand all
813 ASSERT(count >= 0); 814 ASSERT(count >= 0);
814 spill_slot_count_ = count; 815 spill_slot_count_ = count;
815 } 816 }
816 817
817 TargetEntryInstr* normal_entry() const { return normal_entry_; } 818 TargetEntryInstr* normal_entry() const { return normal_entry_; }
818 819
819 virtual void PrintTo(BufferFormatter* f) const; 820 virtual void PrintTo(BufferFormatter* f) const;
820 virtual void PrintToVisualizer(BufferFormatter* f) const; 821 virtual void PrintToVisualizer(BufferFormatter* f) const;
821 822
822 private: 823 private:
824 virtual void ClearPredecessors() { UNREACHABLE(); }
825 virtual void AddPredecessor(BlockEntryInstr* predecessor) { UNREACHABLE(); }
826
823 TargetEntryInstr* normal_entry_; 827 TargetEntryInstr* normal_entry_;
824 GrowableArray<TargetEntryInstr*> catch_entries_; 828 GrowableArray<TargetEntryInstr*> catch_entries_;
825 GrowableArray<Definition*> initial_definitions_; 829 GrowableArray<Definition*> initial_definitions_;
826 intptr_t spill_slot_count_; 830 intptr_t spill_slot_count_;
827 831
828 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); 832 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr);
829 }; 833 };
830 834
831 835
832 class JoinEntryInstr : public BlockEntryInstr { 836 class JoinEntryInstr : public BlockEntryInstr {
833 public: 837 public:
834 explicit JoinEntryInstr(intptr_t try_index) 838 explicit JoinEntryInstr(intptr_t try_index)
835 : BlockEntryInstr(try_index), 839 : BlockEntryInstr(try_index),
836 predecessors_(2), // Two is the assumed to be the common case. 840 predecessors_(2), // Two is the assumed to be the common case.
837 phis_(NULL), 841 phis_(NULL),
838 phi_count_(0) { } 842 phi_count_(0) { }
839 843
840 DECLARE_INSTRUCTION(JoinEntry) 844 DECLARE_INSTRUCTION(JoinEntry)
841 845
842 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } 846 virtual intptr_t PredecessorCount() const { return predecessors_.length(); }
843 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { 847 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const {
844 return predecessors_[index]; 848 return predecessors_[index];
845 } 849 }
846 virtual void AddPredecessor(BlockEntryInstr* predecessor) {
847 predecessors_.Add(predecessor);
848 }
849 850
850 // Returns -1 if pred is not in the list. 851 // Returns -1 if pred is not in the list.
851 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; 852 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const;
852 853
853 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } 854 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; }
854 855
855 virtual void PrepareEntry(FlowGraphCompiler* compiler); 856 virtual void PrepareEntry(FlowGraphCompiler* compiler);
856 857
857 void InsertPhi(intptr_t var_index, intptr_t var_count); 858 void InsertPhi(intptr_t var_index, intptr_t var_count);
858 void RemoveDeadPhis(); 859 void RemoveDeadPhis();
859 860
860 intptr_t phi_count() const { return phi_count_; } 861 intptr_t phi_count() const { return phi_count_; }
861 862
862 virtual void PrintTo(BufferFormatter* f) const; 863 virtual void PrintTo(BufferFormatter* f) const;
863 virtual void PrintToVisualizer(BufferFormatter* f) const; 864 virtual void PrintToVisualizer(BufferFormatter* f) const;
864 865
866 // After recomputing predecessors to eliminate unreachable ones,
867 // reorganize phi inputs to match the predecessor order and to eliminate
868 // unreachable inputs.
869 void EliminateUnreachablePhiInputs();
870
865 private: 871 private:
872 virtual void ClearPredecessors() {
873 // Keep a 'backup' of any existing predecessors to enable garbage
874 // collection of phis after eliminating unreachable code and recomputing
875 // predecessors.
876 stale_predecessors_.Clear();
877 stale_predecessors_.AddArray(predecessors_);
878 predecessors_.Clear();
879 }
880 virtual void AddPredecessor(BlockEntryInstr* predecessor) {
881 predecessors_.Add(predecessor);
882 }
883
866 GrowableArray<BlockEntryInstr*> predecessors_; 884 GrowableArray<BlockEntryInstr*> predecessors_;
867 ZoneGrowableArray<PhiInstr*>* phis_; 885 ZoneGrowableArray<PhiInstr*>* phis_;
868 intptr_t phi_count_; 886 intptr_t phi_count_;
887 GrowableArray<BlockEntryInstr*> stale_predecessors_;
869 888
870 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); 889 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr);
871 }; 890 };
872 891
873 892
874 class TargetEntryInstr : public BlockEntryInstr { 893 class TargetEntryInstr : public BlockEntryInstr {
875 public: 894 public:
876 explicit TargetEntryInstr(intptr_t try_index) 895 explicit TargetEntryInstr(intptr_t try_index)
877 : BlockEntryInstr(try_index), 896 : BlockEntryInstr(try_index),
878 predecessor_(NULL), 897 predecessor_(NULL),
879 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } 898 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { }
880 899
881 // Used for exception catch entries. 900 // Used for exception catch entries.
882 TargetEntryInstr(intptr_t try_index, intptr_t catch_try_index) 901 TargetEntryInstr(intptr_t try_index, intptr_t catch_try_index)
883 : BlockEntryInstr(try_index), 902 : BlockEntryInstr(try_index),
884 predecessor_(NULL), 903 predecessor_(NULL),
885 catch_try_index_(catch_try_index) { } 904 catch_try_index_(catch_try_index) { }
886 905
887 DECLARE_INSTRUCTION(TargetEntry) 906 DECLARE_INSTRUCTION(TargetEntry)
888 907
889 virtual intptr_t PredecessorCount() const { 908 virtual intptr_t PredecessorCount() const {
890 return (predecessor_ == NULL) ? 0 : 1; 909 return (predecessor_ == NULL) ? 0 : 1;
891 } 910 }
892 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { 911 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const {
893 ASSERT((index == 0) && (predecessor_ != NULL)); 912 ASSERT((index == 0) && (predecessor_ != NULL));
894 return predecessor_; 913 return predecessor_;
895 } 914 }
896 virtual void AddPredecessor(BlockEntryInstr* predecessor) {
897 ASSERT(predecessor_ == NULL);
898 predecessor_ = predecessor;
899 }
900 915
901 // Returns true if this Block is an entry of a catch handler. 916 // Returns true if this Block is an entry of a catch handler.
902 bool IsCatchEntry() const { 917 bool IsCatchEntry() const {
903 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex; 918 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex;
904 } 919 }
905 920
906 // Returns try index for the try block to which this catch handler 921 // Returns try index for the try block to which this catch handler
907 // corresponds. 922 // corresponds.
908 intptr_t catch_try_index() const { 923 intptr_t catch_try_index() const {
909 ASSERT(IsCatchEntry()); 924 ASSERT(IsCatchEntry());
910 return catch_try_index_; 925 return catch_try_index_;
911 } 926 }
912 927
913 virtual void PrepareEntry(FlowGraphCompiler* compiler); 928 virtual void PrepareEntry(FlowGraphCompiler* compiler);
914 929
915 virtual void PrintTo(BufferFormatter* f) const; 930 virtual void PrintTo(BufferFormatter* f) const;
916 virtual void PrintToVisualizer(BufferFormatter* f) const; 931 virtual void PrintToVisualizer(BufferFormatter* f) const;
917 932
918 private: 933 private:
934 virtual void ClearPredecessors() { predecessor_ = NULL; }
935 virtual void AddPredecessor(BlockEntryInstr* predecessor) {
936 ASSERT(predecessor_ == NULL);
937 predecessor_ = predecessor;
938 }
939
919 BlockEntryInstr* predecessor_; 940 BlockEntryInstr* predecessor_;
920 const intptr_t catch_try_index_; 941 const intptr_t catch_try_index_;
921 942
922 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); 943 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr);
923 }; 944 };
924 945
925 946
926 // Abstract super-class of all instructions that define a value (Bind, Phi). 947 // Abstract super-class of all instructions that define a value (Bind, Phi).
927 class Definition : public Instruction { 948 class Definition : public Instruction {
928 public: 949 public:
929 enum UseKind { kEffect, kValue }; 950 enum UseKind { kEffect, kValue };
930 951
931 Definition() 952 Definition();
932 : temp_index_(-1),
933 ssa_temp_index_(-1),
934 propagated_type_(AbstractType::Handle()),
935 propagated_cid_(kIllegalCid),
936 input_use_list_(NULL),
937 env_use_list_(NULL),
938 use_kind_(kValue) { // Phis and parameters rely on this default.
939 }
940 953
941 virtual Definition* AsDefinition() { return this; } 954 virtual Definition* AsDefinition() { return this; }
942 955
943 bool IsComparison() { return (AsComparison() != NULL); } 956 bool IsComparison() { return (AsComparison() != NULL); }
944 virtual ComparisonInstr* AsComparison() { return NULL; } 957 virtual ComparisonInstr* AsComparison() { return NULL; }
945 958
946 // Overridden by definitions that push arguments. 959 // Overridden by definitions that push arguments.
947 virtual intptr_t ArgumentCount() const { return 0; } 960 virtual intptr_t ArgumentCount() const { return 0; }
948 961
949 intptr_t temp_index() const { return temp_index_; } 962 intptr_t temp_index() const { return temp_index_; }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 1064
1052 // Get the block entry for that instruction. 1065 // Get the block entry for that instruction.
1053 virtual BlockEntryInstr* GetBlock() const; 1066 virtual BlockEntryInstr* GetBlock() const;
1054 1067
1055 // Printing support. These functions are sometimes overridden for custom 1068 // Printing support. These functions are sometimes overridden for custom
1056 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)". 1069 // formatting. Otherwise, it prints in the format "opcode(op1, op2, op3)".
1057 virtual void PrintTo(BufferFormatter* f) const; 1070 virtual void PrintTo(BufferFormatter* f) const;
1058 virtual void PrintOperandsTo(BufferFormatter* f) const; 1071 virtual void PrintOperandsTo(BufferFormatter* f) const;
1059 virtual void PrintToVisualizer(BufferFormatter* f) const; 1072 virtual void PrintToVisualizer(BufferFormatter* f) const;
1060 1073
1074 // A value in the constant propagation lattice.
1075 // - non-constant sentinel
1076 // - a constant (any non-sentinel value)
1077 // - unknown sentinel
1078 Object& constant_value() const { return constant_value_; }
1079
1061 private: 1080 private:
1062 intptr_t temp_index_; 1081 intptr_t temp_index_;
1063 intptr_t ssa_temp_index_; 1082 intptr_t ssa_temp_index_;
1064 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; 1083 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_;
1065 // For now: 1084 // For now:
1066 AbstractType& propagated_type_; 1085 AbstractType& propagated_type_;
1067 intptr_t propagated_cid_; 1086 intptr_t propagated_cid_;
1068 Value* input_use_list_; 1087 Value* input_use_list_;
1069 Value* env_use_list_; 1088 Value* env_use_list_;
1070 UseKind use_kind_; 1089 UseKind use_kind_;
1071 1090
1091 Object& constant_value_;
1092
1072 DISALLOW_COPY_AND_ASSIGN(Definition); 1093 DISALLOW_COPY_AND_ASSIGN(Definition);
1073 }; 1094 };
1074 1095
1075 1096
1076 class PhiInstr : public Definition { 1097 class PhiInstr : public Definition {
1077 public: 1098 public:
1078 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) 1099 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
1079 : block_(block), 1100 : block_(block),
1080 inputs_(num_inputs), 1101 inputs_(num_inputs),
1081 is_alive_(false), 1102 is_alive_(false),
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 UNREACHABLE(); 1153 UNREACHABLE();
1133 return kIllegalCid; 1154 return kIllegalCid;
1134 } 1155 }
1135 1156
1136 DECLARE_INSTRUCTION(Phi) 1157 DECLARE_INSTRUCTION(Phi)
1137 1158
1138 virtual void PrintTo(BufferFormatter* f) const; 1159 virtual void PrintTo(BufferFormatter* f) const;
1139 virtual void PrintToVisualizer(BufferFormatter* f) const; 1160 virtual void PrintToVisualizer(BufferFormatter* f) const;
1140 1161
1141 private: 1162 private:
1163 friend class JoinEntryInstr; // Direct access to inputs_ array.
1164
1142 JoinEntryInstr* block_; 1165 JoinEntryInstr* block_;
1143 GrowableArray<Value*> inputs_; 1166 GrowableArray<Value*> inputs_;
1144 bool is_alive_; 1167 bool is_alive_;
1145 Representation representation_; 1168 Representation representation_;
1146 1169
1147 DISALLOW_COPY_AND_ASSIGN(PhiInstr); 1170 DISALLOW_COPY_AND_ASSIGN(PhiInstr);
1148 }; 1171 };
1149 1172
1150 1173
1151 class ParameterInstr : public Definition { 1174 class ParameterInstr : public Definition {
(...skipping 2487 matching lines...) Expand 10 before | Expand all | Expand 10 after
3639 ForwardInstructionIterator* current_iterator_; 3662 ForwardInstructionIterator* current_iterator_;
3640 3663
3641 private: 3664 private:
3642 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 3665 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
3643 }; 3666 };
3644 3667
3645 3668
3646 } // namespace dart 3669 } // namespace dart
3647 3670
3648 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 3671 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698