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

Side by Side Diff: test/cctest/compiler/test-loop-analysis.cc

Issue 855653002: [turbofan] Improve loop analysis to handle more than 32 loops. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 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
« no previous file with comments | « src/compiler/loop-analysis.cc ('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 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
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
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
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(31); }
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(31); }
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); }
OLDNEW
« no previous file with comments | « src/compiler/loop-analysis.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698