| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 import 'sexpr_unstringifier.dart'; | 5 import 'sexpr_unstringifier.dart'; |
| 6 import "package:expect/expect.dart"; | 6 import "package:expect/expect.dart"; |
| 7 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart'; | 7 import 'package:compiler/src/cps_ir/cps_ir_nodes.dart'; |
| 8 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart'; | 8 import 'package:compiler/src/cps_ir/cps_ir_nodes_sexpr.dart'; |
| 9 import 'package:compiler/src/cps_ir/optimizers.dart'; | 9 import 'package:compiler/src/cps_ir/optimizers.dart'; |
| 10 | 10 |
| 11 // The 'read in loop' IR tests the most basic case of redundant phi removal | 11 // The 'read in loop' IR tests the most basic case of redundant phi removal |
| 12 // and represents the following source code: | 12 // and represents the following source code: |
| 13 // | 13 // |
| 14 // void main() { | 14 // void main() { |
| 15 // int j = 42; | 15 // int j = 42; |
| 16 // for (int i = 0; i < 2; i++) { | 16 // for (int i = 0; i < 2; i++) { |
| 17 // print(j.toString()); | 17 // print(j.toString()); |
| 18 // } | 18 // } |
| 19 // } | 19 // } |
| 20 | 20 |
| 21 String READ_IN_LOOP_IN = """ | 21 String READ_IN_LOOP_IN = """ |
| 22 (FunctionDefinition main () return () | 22 (FunctionDefinition main () return () |
| 23 (LetPrim v0 (Constant (Int 42))) | 23 (LetPrim (v0 (Constant (Int 42))) |
| 24 (LetPrim v1 (Constant (Int 0))) | 24 (LetPrim (v1 (Constant (Int 0))) |
| 25 (LetCont* (k0 v2 v3) | 25 (LetCont* (k0 (v2 v3) |
| 26 (LetCont (k1) (LetPrim v4 (Constant (Null))) | 26 (LetCont (k1 () |
| 27 (InvokeContinuation return v4)) | 27 (LetPrim (v4 (Constant (Null))) |
| 28 (LetCont (k2) | 28 (InvokeContinuation return (v4)))) |
| 29 (LetCont (k3 v5) | 29 (LetCont (k2 () |
| 30 (LetCont (k4 v6) (LetPrim v7 (Constant (Int 1))) | 30 (LetCont (k3 (v5) |
| 31 (LetCont (k5 v8) (InvokeContinuation* k0 v2 v8)) | 31 (LetCont (k4 (v6) |
| 32 (InvokeMethod v3 + v7 k5)) | 32 (LetPrim (v7 (Constant (Int 1))) |
| 33 (InvokeStatic print v5 k4)) | 33 (LetCont (k5 (v8) |
| 34 (InvokeMethod v2 toString k3)) | 34 (InvokeContinuation* k0 (v2 v8))) |
| 35 (LetPrim v9 (Constant (Int 2))) | 35 (InvokeMethod v3 + (v7) k5)))) |
| 36 (LetCont (k6 v10) (Branch (IsTrue v10) k2 k1)) | 36 (InvokeStatic print (v5) k4))) |
| 37 (InvokeMethod v3 < v9 k6)) | 37 (InvokeMethod v2 toString () k3))) |
| 38 (InvokeContinuation k0 v0 v1)) | 38 (LetPrim (v9 (Constant (Int 2))) |
| 39 (LetCont (k6 (v10) |
| 40 (Branch (IsTrue v10) k2 k1)) |
| 41 (InvokeMethod v3 < (v9) k6)))))) |
| 42 (InvokeContinuation k0 (v0 v1)))))) |
| 39 """; | 43 """; |
| 40 | 44 |
| 41 String READ_IN_LOOP_OUT = """ | 45 String READ_IN_LOOP_OUT = """ |
| 42 (FunctionDefinition main () return () | 46 (FunctionDefinition main () return () |
| 43 (LetPrim v0 (Constant (Int 42))) | 47 (LetPrim (v0 (Constant (Int 42))) |
| 44 (LetPrim v1 (Constant (Int 0))) | 48 (LetPrim (v1 (Constant (Int 0))) |
| 45 (LetCont* (k0 v2) | 49 (LetCont* (k0 (v2) |
| 46 (LetCont (k1) (LetPrim v3 (Constant (Null))) | 50 (LetCont (k1 () |
| 47 (InvokeContinuation return v3)) | 51 (LetPrim (v3 (Constant (Null))) |
| 48 (LetCont (k2) | 52 (InvokeContinuation return (v3)))) |
| 49 (LetCont (k3 v4) | 53 (LetCont (k2 () |
| 50 (LetCont (k4 v5) (LetPrim v6 (Constant (Int 1))) | 54 (LetCont (k3 (v4) |
| 51 (LetCont (k5 v7) (InvokeContinuation* k0 v7)) | 55 (LetCont (k4 (v5) |
| 52 (InvokeMethod v2 + v6 k5)) | 56 (LetPrim (v6 (Constant (Int 1))) |
| 53 (InvokeStatic print v4 k4)) | 57 (LetCont (k5 (v7) |
| 54 (InvokeMethod v0 toString k3)) | 58 (InvokeContinuation* k0 (v7))) |
| 55 (LetPrim v8 (Constant (Int 2))) | 59 (InvokeMethod v2 + (v6) k5)))) |
| 56 (LetCont (k6 v9) (Branch (IsTrue v9) k2 k1)) | 60 (InvokeStatic print (v4) k4))) |
| 57 (InvokeMethod v2 < v8 k6)) | 61 (InvokeMethod v0 toString () k3))) |
| 58 (InvokeContinuation k0 v1)) | 62 (LetPrim (v8 (Constant (Int 2))) |
| 63 (LetCont (k6 (v9) |
| 64 (Branch (IsTrue v9) k2 k1)) |
| 65 (InvokeMethod v2 < (v8) k6)))))) |
| 66 (InvokeContinuation k0 (v1)))))) |
| 59 """; | 67 """; |
| 60 | 68 |
| 61 // The 'inner loop' IR represents the following source code: | 69 // The 'inner loop' IR represents the following source code: |
| 62 // | 70 // |
| 63 // void main() { | 71 // void main() { |
| 64 // int j = 42; | 72 // int j = 42; |
| 65 // for (int i = 0; i < 2; i++) { | 73 // for (int i = 0; i < 2; i++) { |
| 66 // for (int k = 0; k < 2; k++) { | 74 // for (int k = 0; k < 2; k++) { |
| 67 // print(i.toString()); | 75 // print(i.toString()); |
| 68 // } | 76 // } |
| 69 // } | 77 // } |
| 70 // print(j.toString()); | 78 // print(j.toString()); |
| 71 // } | 79 // } |
| 72 // | 80 // |
| 73 // This test case ensures that iterative optimization works: first, v8 and v9 | 81 // This test case ensures that iterative optimization works: first, v8 and v9 |
| 74 // are removed from k5, and only then can k0 be optimized as well. | 82 // are removed from k5, and only then can k0 be optimized as well. |
| 75 | 83 |
| 76 const String INNER_LOOP_IN = """ | 84 const String INNER_LOOP_IN = """ |
| 77 (FunctionDefinition main () return () | 85 (FunctionDefinition main () return () |
| 78 (LetPrim v0 (Constant (Int 42))) | 86 (LetPrim (v0 (Constant (Int 42))) |
| 79 (LetPrim v1 (Constant (Int 0))) | 87 (LetPrim (v1 (Constant (Int 0))) |
| 80 (LetCont* (k0 v2 v3) | 88 (LetCont* (k0 (v2 v3) |
| 81 (LetCont (k1) | 89 (LetCont (k1 () |
| 82 (LetCont (k2 v4) | 90 (LetCont (k2 (v4) |
| 83 (LetCont (k3 v5) (LetPrim v6 (Constant (Null))) | 91 (LetCont (k3 (v5) |
| 84 (InvokeContinuation return v6)) | 92 (LetPrim (v6 (Constant (Null))) |
| 85 (InvokeStatic print v4 k3)) | 93 (InvokeContinuation return (v6)))) |
| 86 (InvokeMethod v2 toString k2)) | 94 (InvokeStatic print (v4) k3))) |
| 87 (LetCont (k4) (LetPrim v7 (Constant (Int 0))) | 95 (InvokeMethod v2 toString () k2))) |
| 88 (LetCont* (k5 v8 v9 v10) | 96 (LetCont (k4 () |
| 89 (LetCont (k6) (LetPrim v11 (Constant (Int 1))) | 97 (LetPrim (v7 (Constant (Int 0))) |
| 90 (LetCont (k7 v12) (InvokeContinuation* k0 v8 v12)) | 98 (LetCont* (k5 (v8 v9 v10) |
| 91 (InvokeMethod v9 + v11 k7)) | 99 (LetCont (k6 () |
| 92 (LetCont (k8) | 100 (LetPrim (v11 (Constant (Int 1))) |
| 93 (LetCont (k9 v13) | 101 (LetCont (k7 (v12) |
| 94 (LetCont (k10 v14) (LetPrim v15 (Constant (Int 1))) | 102 (InvokeContinuation* k0 (v8 v12))) |
| 95 (LetCont (k11 v16) | 103 (InvokeMethod v9 + (v11) k7)))) |
| 96 (InvokeContinuation* k5 v8 v9 v16)) | 104 (LetCont (k8 () |
| 97 (InvokeMethod v10 + v15 k11)) | 105 (LetCont (k9 (v13) |
| 98 (InvokeStatic print v13 k10)) | 106 (LetCont (k10 (v14) |
| 99 (InvokeMethod v9 toString k9)) | 107 (LetPrim (v15 (Constant (Int 1))) |
| 100 (LetPrim v17 (Constant (Int 2))) | 108 (LetCont (k11 (v16) |
| 101 (LetCont (k12 v18) (Branch (IsTrue v18) k8 k6)) | 109 (InvokeContinuation* k5 (v8 v9 v16))) |
| 102 (InvokeMethod v10 < v17 k12)) | 110 (InvokeMethod v10 + (v15) k11)))) |
| 103 (InvokeContinuation k5 v2 v3 v7)) | 111 (InvokeStatic print (v13) k10))) |
| 104 (LetPrim v19 (Constant (Int 2))) | 112 (InvokeMethod v9 toString () k9))) |
| 105 (LetCont (k13 v20) (Branch (IsTrue v20) k4 k1)) | 113 (LetPrim (v17 (Constant (Int 2))) |
| 106 (InvokeMethod v3 < v19 k13)) | 114 (LetCont (k12 (v18) |
| 107 (InvokeContinuation k0 v0 v1)) | 115 (Branch (IsTrue v18) k8 k6)) |
| 116 (InvokeMethod v10 < (v17) k12)))))) |
| 117 (InvokeContinuation k5 (v2 v3 v7))))) |
| 118 (LetPrim (v19 (Constant (Int 2))) |
| 119 (LetCont (k13 (v20) |
| 120 (Branch (IsTrue v20) k4 k1)) |
| 121 (InvokeMethod v3 < (v19) k13)))))) |
| 122 (InvokeContinuation k0 (v0 v1)))))) |
| 108 """; | 123 """; |
| 109 | 124 |
| 110 const String INNER_LOOP_OUT = """ | 125 const String INNER_LOOP_OUT = """ |
| 111 (FunctionDefinition main () return () | 126 (FunctionDefinition main () return () |
| 112 (LetPrim v0 (Constant (Int 42))) | 127 (LetPrim (v0 (Constant (Int 42))) |
| 113 (LetPrim v1 (Constant (Int 0))) | 128 (LetPrim (v1 (Constant (Int 0))) |
| 114 (LetCont* (k0 v2) | 129 (LetCont* (k0 (v2) |
| 115 (LetCont (k1) | 130 (LetCont (k1 () |
| 116 (LetCont (k2 v3) | 131 (LetCont (k2 (v3) |
| 117 (LetCont (k3 v4) (LetPrim v5 (Constant (Null))) | 132 (LetCont (k3 (v4) |
| 118 (InvokeContinuation return v5)) | 133 (LetPrim (v5 (Constant (Null))) |
| 119 (InvokeStatic print v3 k3)) | 134 (InvokeContinuation return (v5)))) |
| 120 (InvokeMethod v0 toString k2)) | 135 (InvokeStatic print (v3) k3))) |
| 121 (LetCont (k4) (LetPrim v6 (Constant (Int 0))) | 136 (InvokeMethod v0 toString () k2))) |
| 122 (LetCont* (k5 v7) | 137 (LetCont (k4 () |
| 123 (LetCont (k6) (LetPrim v8 (Constant (Int 1))) | 138 (LetPrim (v6 (Constant (Int 0))) |
| 124 (LetCont (k7 v9) (InvokeContinuation* k0 v9)) | 139 (LetCont* (k5 (v7) |
| 125 (InvokeMethod v2 + v8 k7)) | 140 (LetCont (k6 () |
| 126 (LetCont (k8) | 141 (LetPrim (v8 (Constant (Int 1))) |
| 127 (LetCont (k9 v10) | 142 (LetCont (k7 (v9) |
| 128 (LetCont (k10 v11) (LetPrim v12 (Constant (Int 1))) | 143 (InvokeContinuation* k0 (v9))) |
| 129 (LetCont (k11 v13) | 144 (InvokeMethod v2 + (v8) k7)))) |
| 130 (InvokeContinuation* k5 v13)) | 145 (LetCont (k8 () |
| 131 (InvokeMethod v7 + v12 k11)) | 146 (LetCont (k9 (v10) |
| 132 (InvokeStatic print v10 k10)) | 147 (LetCont (k10 (v11) |
| 133 (InvokeMethod v2 toString k9)) | 148 (LetPrim (v12 (Constant (Int 1))) |
| 134 (LetPrim v14 (Constant (Int 2))) | 149 (LetCont (k11 (v13) |
| 135 (LetCont (k12 v15) (Branch (IsTrue v15) k8 k6)) | 150 (InvokeContinuation* k5 (v13))) |
| 136 (InvokeMethod v7 < v14 k12)) | 151 (InvokeMethod v7 + (v12) k11)))) |
| 137 (InvokeContinuation k5 v6)) | 152 (InvokeStatic print (v10) k10))) |
| 138 (LetPrim v16 (Constant (Int 2))) | 153 (InvokeMethod v2 toString () k9))) |
| 139 (LetCont (k13 v17) (Branch (IsTrue v17) k4 k1)) | 154 (LetPrim (v14 (Constant (Int 2))) |
| 140 (InvokeMethod v2 < v16 k13)) | 155 (LetCont (k12 (v15) |
| 141 (InvokeContinuation k0 v1)) | 156 (Branch (IsTrue v15) k8 k6)) |
| 157 (InvokeMethod v7 < (v14) k12)))))) |
| 158 (InvokeContinuation k5 (v6))))) |
| 159 (LetPrim (v16 (Constant (Int 2))) |
| 160 (LetCont (k13 (v17) |
| 161 (Branch (IsTrue v17) k4 k1)) |
| 162 (InvokeMethod v2 < (v16) k13)))))) |
| 163 (InvokeContinuation k0 (v1)))))) |
| 142 """; | 164 """; |
| 143 | 165 |
| 144 // There are no redundant phis in the 'basic loop' IR, and this test ensures | 166 // There are no redundant phis in the 'basic loop' IR, and this test ensures |
| 145 // simply that the optimization does not alter the IR. It represents the | 167 // simply that the optimization does not alter the IR. It represents the |
| 146 // following program: | 168 // following program: |
| 147 // | 169 // |
| 148 // void main() { | 170 // void main() { |
| 149 // for (int i = 0; i < 2; i++) { | 171 // for (int i = 0; i < 2; i++) { |
| 150 // print(i.toString()); | 172 // print(i.toString()); |
| 151 // } | 173 // } |
| 152 // } | 174 // } |
| 153 | 175 |
| 154 String BASIC_LOOP_IN = """ | 176 String BASIC_LOOP_IN = """ |
| 155 (FunctionDefinition main () return () | 177 (FunctionDefinition main () return () |
| 156 (LetPrim v0 (Constant (Int 0))) | 178 (LetPrim (v0 (Constant (Int 0))) |
| 157 (LetCont* (k0 v1) | 179 (LetCont* (k0 (v1) |
| 158 (LetCont (k1) (LetPrim v2 (Constant (Null))) | 180 (LetCont (k1 () |
| 159 (InvokeContinuation return v2)) | 181 (LetPrim (v2 (Constant (Null))) |
| 160 (LetCont (k2) | 182 (InvokeContinuation return (v2)))) |
| 161 (LetCont (k3 v3) | 183 (LetCont (k2 () |
| 162 (LetCont (k4 v4) (LetPrim v5 (Constant (Int 1))) | 184 (LetCont (k3 (v3) |
| 163 (LetCont (k5 v6) (InvokeContinuation* k0 v6)) | 185 (LetCont (k4 (v4) |
| 164 (InvokeMethod v1 + v5 k5)) | 186 (LetPrim (v5 (Constant (Int 1))) |
| 165 (InvokeStatic print v3 k4)) | 187 (LetCont (k5 (v6) |
| 166 (InvokeMethod v1 toString k3)) | 188 (InvokeContinuation* k0 (v6))) |
| 167 (LetPrim v7 (Constant (Int 2))) | 189 (InvokeMethod v1 + (v5) k5)))) |
| 168 (LetCont (k6 v8) (Branch (IsTrue v8) k2 k1)) | 190 (InvokeStatic print (v3) k4))) |
| 169 (InvokeMethod v1 < v7 k6)) | 191 (InvokeMethod v1 toString () k3))) |
| 170 (InvokeContinuation k0 v0)) | 192 (LetPrim (v7 (Constant (Int 2))) |
| 193 (LetCont (k6 (v8) |
| 194 (Branch (IsTrue v8) k2 k1)) |
| 195 (InvokeMethod v1 < (v7) k6)))))) |
| 196 (InvokeContinuation k0 (v0))))) |
| 171 """; | 197 """; |
| 172 | 198 |
| 173 String BASIC_LOOP_OUT = BASIC_LOOP_IN; | 199 String BASIC_LOOP_OUT = BASIC_LOOP_IN; |
| 174 | 200 |
| 175 // Ensures that proper scoping is preserved, i.e. that the optimized | 201 // Ensures that proper scoping is preserved, i.e. that the optimized |
| 176 // continuation body does reference out of scope primitives. | 202 // continuation body does reference out of scope primitives. |
| 177 // IR written by hand since this case is currently not being generated. | 203 // IR written by hand since this case is currently not being generated. |
| 178 | 204 |
| 179 String SCOPING_IN = """ | 205 String SCOPING_IN = """ |
| 180 (FunctionDefinition main () return () | 206 (FunctionDefinition main () return () |
| 181 (LetCont (k0 v1) | 207 (LetCont (k0 (v1) |
| 182 (InvokeStatic print v1 return)) | 208 (InvokeStatic print (v1) return)) |
| 183 (LetPrim v0 (Constant (Int 0))) | 209 (LetPrim (v0 (Constant (Int 0))) |
| 184 (LetPrim v2 (Constant (Null))) | 210 (LetPrim (v2 (Constant (Null))) |
| 185 (InvokeContinuation k0 v0)) | 211 (InvokeContinuation k0 (v0)))))) |
| 186 """; | 212 """; |
| 187 | 213 |
| 188 String SCOPING_OUT = """ | 214 String SCOPING_OUT = """ |
| 189 (FunctionDefinition main () return () | 215 (FunctionDefinition main () return () |
| 190 (LetPrim v0 (Constant (Int 0))) | 216 (LetPrim (v0 (Constant (Int 0))) |
| 191 (LetCont (k0) | 217 (LetCont (k0 () |
| 192 (InvokeStatic print v0 return)) | 218 (InvokeStatic print (v0) return)) |
| 193 (LetPrim v1 (Constant (Null))) | 219 (LetPrim (v1 (Constant (Null))) |
| 194 (InvokeContinuation k0 )) | 220 (InvokeContinuation k0 ()))))) |
| 195 """; | 221 """; |
| 196 | 222 |
| 197 // Ensures that continuations which are never invoked are not optimized. | 223 // Ensures that continuations which are never invoked are not optimized. |
| 198 // IR written by hand. | 224 // IR written by hand. |
| 199 | 225 |
| 200 String NEVER_INVOKED_IN = """ | 226 String NEVER_INVOKED_IN = """ |
| 201 (FunctionDefinition main () return () | 227 (FunctionDefinition main () return () |
| 202 (LetPrim v0 (Constant (Int 0))) | 228 (LetPrim (v0 (Constant (Int 0))) |
| 203 (LetCont (k0 v1) | 229 (LetCont (k0 (v1) |
| 204 (InvokeStatic print v1 return)) | 230 (InvokeStatic print (v1) return)) |
| 205 (InvokeContinuation return v0)) | 231 (InvokeContinuation return (v0))))) |
| 206 """; | 232 """; |
| 207 | 233 |
| 208 String NEVER_INVOKED_OUT = NEVER_INVOKED_IN; | 234 String NEVER_INVOKED_OUT = NEVER_INVOKED_IN; |
| 209 | 235 |
| 210 /// Normalizes whitespace by replacing all whitespace sequences by a single | 236 /// Normalizes whitespace by replacing all whitespace sequences by a single |
| 211 /// space and trimming leading and trailing whitespace. | 237 /// space and trimming leading and trailing whitespace. |
| 212 String normalizeSExpr(String input) { | 238 String normalizeSExpr(String input) { |
| 213 return input.replaceAll(new RegExp(r'[ \n\t]+'), ' ').trim(); | 239 return input.replaceAll(new RegExp(r'[ \n\t]+'), ' ').trim(); |
| 214 } | 240 } |
| 215 | 241 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 229 Expect.equals(expected, actual, "Actual:\n$actual"); | 255 Expect.equals(expected, actual, "Actual:\n$actual"); |
| 230 } | 256 } |
| 231 | 257 |
| 232 void main() { | 258 void main() { |
| 233 testRedundantPhi(READ_IN_LOOP_IN, READ_IN_LOOP_OUT); | 259 testRedundantPhi(READ_IN_LOOP_IN, READ_IN_LOOP_OUT); |
| 234 testRedundantPhi(INNER_LOOP_IN, INNER_LOOP_OUT); | 260 testRedundantPhi(INNER_LOOP_IN, INNER_LOOP_OUT); |
| 235 testRedundantPhi(BASIC_LOOP_IN, BASIC_LOOP_OUT); | 261 testRedundantPhi(BASIC_LOOP_IN, BASIC_LOOP_OUT); |
| 236 testRedundantPhi(SCOPING_IN, SCOPING_OUT); | 262 testRedundantPhi(SCOPING_IN, SCOPING_OUT); |
| 237 testRedundantPhi(NEVER_INVOKED_IN, NEVER_INVOKED_OUT); | 263 testRedundantPhi(NEVER_INVOKED_IN, NEVER_INVOKED_OUT); |
| 238 } | 264 } |
| OLD | NEW |