OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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 "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/common-operator.h" | 8 #include "src/compiler/common-operator.h" |
9 #include "src/compiler/graph.h" | 9 #include "src/compiler/graph.h" |
10 #include "src/compiler/graph-visualizer.h" | 10 #include "src/compiler/graph-visualizer.h" |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
139 CHECK_NE(NULL, loop); | 139 CHECK_NE(NULL, loop); |
140 | 140 |
141 CHECK(header_count == static_cast<int>(loop->HeaderSize())); | 141 CHECK(header_count == static_cast<int>(loop->HeaderSize())); |
142 for (int i = 0; i < header_count; i++) { | 142 for (int i = 0; i < header_count; i++) { |
143 // Each header node should be in the loop. | 143 // Each header node should be in the loop. |
144 CHECK_EQ(loop, tree->ContainingLoop(header[i])); | 144 CHECK_EQ(loop, tree->ContainingLoop(header[i])); |
145 CheckRangeContains(tree->HeaderNodes(loop), header[i]); | 145 CheckRangeContains(tree->HeaderNodes(loop), header[i]); |
146 } | 146 } |
147 | 147 |
148 CHECK_EQ(body_count, static_cast<int>(loop->BodySize())); | 148 CHECK_EQ(body_count, static_cast<int>(loop->BodySize())); |
149 // TODO(turbofan): O(n^2) set equivalence in this test. | |
149 for (int i = 0; i < body_count; i++) { | 150 for (int i = 0; i < body_count; i++) { |
150 // Each body node should be contained in the loop. | 151 // Each body node should be contained in the loop. |
151 CHECK(tree->Contains(loop, body[i])); | 152 CHECK(tree->Contains(loop, body[i])); |
152 CheckRangeContains(tree->BodyNodes(loop), body[i]); | 153 CheckRangeContains(tree->BodyNodes(loop), body[i]); |
153 } | 154 } |
154 } | 155 } |
155 | 156 |
156 void CheckRangeContains(NodeRange range, Node* node) { | 157 void CheckRangeContains(NodeRange range, Node* node) { |
157 // O(n) ftw. | |
158 CHECK_NE(range.end(), std::find(range.begin(), range.end(), node)); | 158 CHECK_NE(range.end(), std::find(range.begin(), range.end(), node)); |
159 } | 159 } |
160 | 160 |
161 void CheckNestedLoops(Node** chain, int chain_count) { | 161 void CheckNestedLoops(Node** chain, int chain_count) { |
162 LoopTree* tree = GetLoopTree(); | 162 LoopTree* tree = GetLoopTree(); |
163 for (int i = 0; i < chain_count; i++) { | 163 for (int i = 0; i < chain_count; i++) { |
164 Node* header = chain[i]; | 164 Node* header = chain[i]; |
165 // Each header should be in a loop. | 165 // Each header should be in a loop. |
166 LoopTree::Loop* loop = tree->ContainingLoop(header); | 166 LoopTree::Loop* loop = tree->ContainingLoop(header); |
167 CHECK_NE(NULL, loop); | 167 CHECK_NE(NULL, loop); |
168 // Check parentage. | 168 // Check parentage. |
169 LoopTree::Loop* parent = | 169 LoopTree::Loop* parent = |
170 i == 0 ? NULL : tree->ContainingLoop(chain[i - 1]); | 170 i == 0 ? NULL : tree->ContainingLoop(chain[i - 1]); |
171 CHECK_EQ(parent, loop->parent()); | 171 CHECK_EQ(parent, loop->parent()); |
172 for (int j = i - 1; j >= 0; j--) { | 172 for (int j = i - 1; j >= 0; j--) { |
173 // This loop should be nested inside all the outer loops. | 173 // This loop should be nested inside all the outer loops. |
174 Node* outer_header = chain[j]; | 174 Node* outer_header = chain[j]; |
175 LoopTree::Loop* outer = tree->ContainingLoop(outer_header); | 175 LoopTree::Loop* outer = tree->ContainingLoop(outer_header); |
176 CHECK(tree->Contains(outer, header)); | 176 CHECK(tree->Contains(outer, header)); |
177 CHECK(!tree->Contains(loop, outer_header)); | 177 CHECK(!tree->Contains(loop, outer_header)); |
178 } | 178 } |
179 } | 179 } |
180 } | 180 } |
181 | |
182 Zone* zone() { return main_zone(); } | |
181 }; | 183 }; |
182 | 184 |
183 | 185 |
184 struct While { | 186 struct While { |
185 LoopFinderTester& t; | 187 LoopFinderTester& t; |
186 Node* branch; | 188 Node* branch; |
187 Node* if_true; | 189 Node* if_true; |
188 Node* exit; | 190 Node* exit; |
189 Node* loop; | 191 Node* loop; |
190 | 192 |
(...skipping 641 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
832 phi3, cond3, branch3, if_true3}; | 834 phi3, cond3, branch3, if_true3}; |
833 t.CheckLoop(header2, 2, body2, 9); | 835 t.CheckLoop(header2, 2, body2, 9); |
834 | 836 |
835 Node* header3[] = {loop3, phi3}; | 837 Node* header3[] = {loop3, phi3}; |
836 Node* body3[] = {cond3, branch3, if_true3}; | 838 Node* body3[] = {cond3, branch3, if_true3}; |
837 t.CheckLoop(header3, 2, body3, 3); | 839 t.CheckLoop(header3, 2, body3, 3); |
838 } | 840 } |
839 | 841 |
840 | 842 |
841 // Runs all combinations with a fixed {i}. | 843 // Runs all combinations with a fixed {i}. |
842 void RunEdgeMatrix3_i(int i) { | 844 static void RunEdgeMatrix3_i(int i) { |
843 for (int a = 0; a < 1; a++) { | 845 for (int a = 0; a < 1; a++) { |
844 for (int b = 0; b < 1; b++) { | 846 for (int b = 0; b < 1; b++) { |
845 for (int c = 0; c < 4; c++) { | 847 for (int c = 0; c < 4; c++) { |
846 for (int d = 0; d < 3; d++) { | 848 for (int d = 0; d < 3; d++) { |
847 for (int e = 0; e < 3; e++) { | 849 for (int e = 0; e < 3; e++) { |
848 for (int f = 0; f < 6; f++) { | 850 for (int f = 0; f < 6; f++) { |
849 for (int g = 0; g < 5; g++) { | 851 for (int g = 0; g < 5; g++) { |
850 for (int h = 0; h < 5; h++) { | 852 for (int h = 0; h < 5; h++) { |
851 RunEdgeMatrix3(a, b, c, d, e, f, g, h, i); | 853 RunEdgeMatrix3(a, b, c, d, e, f, g, h, i); |
852 } | 854 } |
(...skipping 17 matching lines...) Expand all Loading... | |
870 TEST(LaEdgeMatrix3_2) { RunEdgeMatrix3_i(2); } | 872 TEST(LaEdgeMatrix3_2) { RunEdgeMatrix3_i(2); } |
871 | 873 |
872 | 874 |
873 TEST(LaEdgeMatrix3_3) { RunEdgeMatrix3_i(3); } | 875 TEST(LaEdgeMatrix3_3) { RunEdgeMatrix3_i(3); } |
874 | 876 |
875 | 877 |
876 TEST(LaEdgeMatrix3_4) { RunEdgeMatrix3_i(4); } | 878 TEST(LaEdgeMatrix3_4) { RunEdgeMatrix3_i(4); } |
877 | 879 |
878 | 880 |
879 TEST(LaEdgeMatrix3_5) { RunEdgeMatrix3_i(5); } | 881 TEST(LaEdgeMatrix3_5) { RunEdgeMatrix3_i(5); } |
882 | |
883 | |
884 static void RunManyChainedLoops_i(int count) { | |
885 LoopFinderTester t; | |
886 Node** nodes = t.zone()->NewArray<Node*>(count * 4); | |
887 Node* k11 = t.jsgraph.Int32Constant(11); | |
888 Node* k12 = t.jsgraph.Int32Constant(12); | |
889 Node* last = t.start; | |
890 | |
891 // Build loops. | |
892 for (int i = 0; i < count; i++) { | |
893 Node* loop = t.graph.NewNode(t.common.Loop(2), last, t.start); | |
894 Node* phi = t.graph.NewNode(t.common.Phi(kMachInt32, 2), k11, k12, loop); | |
895 Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop); | |
896 Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch); | |
897 Node* exit = t.graph.NewNode(t.common.IfFalse(), branch); | |
898 loop->ReplaceInput(1, if_true); | |
899 | |
900 nodes[i * 4 + 0] = loop; | |
901 nodes[i * 4 + 1] = phi; | |
902 nodes[i * 4 + 2] = branch; | |
903 nodes[i * 4 + 3] = if_true; | |
904 | |
905 last = exit; | |
906 } | |
907 | |
908 Node* ret = t.graph.NewNode(t.common.Return(), t.p0, t.start, last); | |
909 t.graph.SetEnd(ret); | |
910 | |
911 // Verify loops. | |
912 for (int i = 0; i < count; i++) { | |
913 t.CheckLoop(nodes + i * 4, 2, nodes + i * 4 + 2, 2); | |
914 } | |
915 } | |
916 | |
917 | |
918 static void RunManyNestedLoops_i(int count) { | |
919 LoopFinderTester t; | |
920 Node** nodes = t.zone()->NewArray<Node*>(count * 5); | |
921 Node* k11 = t.jsgraph.Int32Constant(11); | |
922 Node* k12 = t.jsgraph.Int32Constant(12); | |
923 Node* outer = nullptr; | |
924 Node* entry = t.start; | |
925 | |
926 // Build loops. | |
927 for (int i = 0; i < count; i++) { | |
928 Node* loop = t.graph.NewNode(t.common.Loop(2), entry, t.start); | |
929 Node* phi = t.graph.NewNode(t.common.Phi(kMachInt32, 2), k11, k12, loop); | |
930 Node* branch = t.graph.NewNode(t.common.Branch(), phi, loop); | |
931 Node* if_true = t.graph.NewNode(t.common.IfTrue(), branch); | |
932 Node* exit = t.graph.NewNode(t.common.IfFalse(), branch); | |
933 | |
934 nodes[i * 5 + 0] = exit; // outside | |
935 nodes[i * 5 + 1] = loop; // header | |
936 nodes[i * 5 + 2] = phi; // header | |
937 nodes[i * 5 + 3] = branch; // body | |
938 nodes[i * 5 + 4] = if_true; // body | |
939 | |
940 if (outer != nullptr) { | |
941 // inner loop. | |
942 outer->ReplaceInput(1, exit); | |
943 } else { | |
944 // outer loop. | |
945 Node* ret = t.graph.NewNode(t.common.Return(), t.p0, t.start, exit); | |
946 t.graph.SetEnd(ret); | |
947 } | |
948 outer = loop; | |
949 entry = if_true; | |
950 } | |
951 outer->ReplaceInput(1, entry); // innermost loop. | |
952 | |
953 // Verify loops. | |
954 for (int i = 0; i < count; i++) { | |
955 int k = i * 5; | |
956 t.CheckLoop(nodes + k + 1, 2, nodes + k + 3, count * 5 - k - 3); | |
957 } | |
958 } | |
959 | |
960 | |
961 TEST(LaManyChained_30) { RunManyChainedLoops_i(30); } | |
962 TEST(LaManyChained_31) { RunManyChainedLoops_i(30); } | |
Michael Starzinger
2015/01/19 12:51:20
nit: s/30/31/ here.
titzer
2015/01/19 12:54:49
Done.
| |
963 TEST(LaManyChained_32) { RunManyChainedLoops_i(32); } | |
964 TEST(LaManyChained_33) { RunManyChainedLoops_i(33); } | |
965 TEST(LaManyChained_34) { RunManyChainedLoops_i(34); } | |
966 TEST(LaManyChained_62) { RunManyChainedLoops_i(62); } | |
967 TEST(LaManyChained_63) { RunManyChainedLoops_i(63); } | |
968 TEST(LaManyChained_64) { RunManyChainedLoops_i(64); } | |
969 | |
970 TEST(LaManyNested_30) { RunManyNestedLoops_i(30); } | |
971 TEST(LaManyNested_31) { RunManyNestedLoops_i(30); } | |
Michael Starzinger
2015/01/19 12:51:20
nit: s/30/31/ here.
titzer
2015/01/19 12:54:49
Done.
| |
972 TEST(LaManyNested_32) { RunManyNestedLoops_i(32); } | |
973 TEST(LaManyNested_33) { RunManyNestedLoops_i(33); } | |
974 TEST(LaManyNested_34) { RunManyNestedLoops_i(34); } | |
975 TEST(LaManyNested_62) { RunManyNestedLoops_i(62); } | |
976 TEST(LaManyNested_63) { RunManyNestedLoops_i(63); } | |
977 TEST(LaManyNested_64) { RunManyNestedLoops_i(64); } | |
OLD | NEW |