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

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

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

Powered by Google App Engine
This is Rietveld 408576698