OLD | NEW |
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 part of ssa; | 5 part of ssa; |
6 | 6 |
7 abstract class OptimizationPhase { | 7 abstract class OptimizationPhase { |
8 String get name; | 8 String get name; |
9 void visitGraph(HGraph graph); | 9 void visitGraph(HGraph graph); |
10 } | 10 } |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 HInvokeDynamicMethod result = new HInvokeDynamicMethod( | 263 HInvokeDynamicMethod result = new HInvokeDynamicMethod( |
264 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); | 264 node.selector, node.inputs.getRange(1, node.inputs.length - 1)); |
265 result.element = target; | 265 result.element = target; |
266 return result; | 266 return result; |
267 } | 267 } |
268 return node; | 268 return node; |
269 } | 269 } |
270 | 270 |
271 bool isFixedSizeListConstructor(HInvokeStatic node) { | 271 bool isFixedSizeListConstructor(HInvokeStatic node) { |
272 Element element = node.target.element; | 272 Element element = node.target.element; |
273 return element.getEnclosingClass() == compiler.listClass | 273 if (element.getEnclosingClass() != compiler.listClass) return false; |
274 && node.inputs.length == 2 | 274 if (!element.isConstructor()) return false; |
275 && node.inputs[1].isInteger(types); | 275 // Check that the constructor is called with an argument and that this |
| 276 // argument is an integer. |
| 277 // TODO(ngeoffray): maybe change the name of the function to reflect that |
| 278 // we also look at the argument. |
| 279 if (node.inputs.length != 2) return false; |
| 280 if (!node.inputs[1].isInteger(types)) return false; |
| 281 |
| 282 // TODO(ngeoffray): cache constructor. |
| 283 FunctionElement fixedLengthListConstructor = |
| 284 compiler.listClass.lookupConstructor( |
| 285 new Selector.callConstructor(const SourceString("fixedLength"), |
| 286 compiler.listClass.getLibrary())); |
| 287 return element == fixedLengthListConstructor.defaultImplementation; |
276 } | 288 } |
277 | 289 |
278 HInstruction visitInvokeStatic(HInvokeStatic node) { | 290 HInstruction visitInvokeStatic(HInvokeStatic node) { |
279 if (isFixedSizeListConstructor(node)) { | 291 if (isFixedSizeListConstructor(node)) { |
280 node.guaranteedType = HType.FIXED_ARRAY; | 292 node.guaranteedType = HType.FIXED_ARRAY; |
281 } | 293 } |
282 return node; | 294 return node; |
283 } | 295 } |
284 | 296 |
285 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { | 297 HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) { |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 if (!receiverType.isUseful()) return null; | 613 if (!receiverType.isUseful()) return null; |
602 if (receiverType.canBeNull()) return null; | 614 if (receiverType.canBeNull()) return null; |
603 DartType type = receiverType.computeType(compiler); | 615 DartType type = receiverType.computeType(compiler); |
604 if (type == null) return null; | 616 if (type == null) return null; |
605 return compiler.world.locateSingleField(type, selector); | 617 return compiler.world.locateSingleField(type, selector); |
606 } | 618 } |
607 | 619 |
608 HInstruction visitFieldGet(HFieldGet node) { | 620 HInstruction visitFieldGet(HFieldGet node) { |
609 if (node.element == backend.jsArrayLength) { | 621 if (node.element == backend.jsArrayLength) { |
610 if (node.receiver is HInvokeStatic) { | 622 if (node.receiver is HInvokeStatic) { |
611 // Try to recognize the length getter with input [:new List(int):]. | 623 // Try to recognize the length getter with input |
| 624 // [:new List.fixedLength(int):]. |
612 HInvokeStatic call = node.receiver; | 625 HInvokeStatic call = node.receiver; |
613 if (isFixedSizeListConstructor(call)) { | 626 if (isFixedSizeListConstructor(call)) { |
614 return call.inputs[1]; | 627 return call.inputs[1]; |
615 } | 628 } |
616 } | 629 } |
617 } | 630 } |
618 return node; | 631 return node; |
619 } | 632 } |
620 | 633 |
621 HInstruction optimizeLengthInterceptedCall(HInvokeDynamicGetter node) { | 634 HInstruction optimizeLengthInterceptedCall(HInvokeDynamicGetter node) { |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1083 } | 1096 } |
1084 visitBasicBlock(dominated, successorValues); | 1097 visitBasicBlock(dominated, successorValues); |
1085 } | 1098 } |
1086 } | 1099 } |
1087 | 1100 |
1088 void computeChangesFlags(HGraph graph) { | 1101 void computeChangesFlags(HGraph graph) { |
1089 // Create the changes flags lists. Make sure to initialize the | 1102 // Create the changes flags lists. Make sure to initialize the |
1090 // loop changes flags list to zero so we can use bitwise or when | 1103 // loop changes flags list to zero so we can use bitwise or when |
1091 // propagating loop changes upwards. | 1104 // propagating loop changes upwards. |
1092 final int length = graph.blocks.length; | 1105 final int length = graph.blocks.length; |
1093 blockChangesFlags = new List<int>(length); | 1106 blockChangesFlags = new List<int>.fixedLength(length); |
1094 loopChangesFlags = new List<int>(length); | 1107 loopChangesFlags = new List<int>.fixedLength(length); |
1095 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; | 1108 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; |
1096 | 1109 |
1097 // Run through all the basic blocks in the graph and fill in the | 1110 // Run through all the basic blocks in the graph and fill in the |
1098 // changes flags lists. | 1111 // changes flags lists. |
1099 for (int i = length - 1; i >= 0; i--) { | 1112 for (int i = length - 1; i >= 0; i--) { |
1100 final HBasicBlock block = graph.blocks[i]; | 1113 final HBasicBlock block = graph.blocks[i]; |
1101 final int id = block.id; | 1114 final int id = block.id; |
1102 | 1115 |
1103 // Compute block changes flags for the block. | 1116 // Compute block changes flags for the block. |
1104 int changesFlags = 0; | 1117 int changesFlags = 0; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1160 // | 1173 // |
1161 // A basic block looks at its sucessors and finds the intersection of | 1174 // A basic block looks at its sucessors and finds the intersection of |
1162 // these computed ValueSet. It moves all instructions of the | 1175 // these computed ValueSet. It moves all instructions of the |
1163 // intersection into its own list of instructions. | 1176 // intersection into its own list of instructions. |
1164 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { | 1177 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { |
1165 final String name = "SsaCodeMotion"; | 1178 final String name = "SsaCodeMotion"; |
1166 | 1179 |
1167 List<ValueSet> values; | 1180 List<ValueSet> values; |
1168 | 1181 |
1169 void visitGraph(HGraph graph) { | 1182 void visitGraph(HGraph graph) { |
1170 values = new List<ValueSet>(graph.blocks.length); | 1183 values = new List<ValueSet>.fixedLength(graph.blocks.length); |
1171 for (int i = 0; i < graph.blocks.length; i++) { | 1184 for (int i = 0; i < graph.blocks.length; i++) { |
1172 values[graph.blocks[i].id] = new ValueSet(); | 1185 values[graph.blocks[i].id] = new ValueSet(); |
1173 } | 1186 } |
1174 visitPostDominatorTree(graph); | 1187 visitPostDominatorTree(graph); |
1175 } | 1188 } |
1176 | 1189 |
1177 void visitBasicBlock(HBasicBlock block) { | 1190 void visitBasicBlock(HBasicBlock block) { |
1178 List<HBasicBlock> successors = block.successors; | 1191 List<HBasicBlock> successors = block.successors; |
1179 | 1192 |
1180 // Phase 1: get the ValueSet of all successors (if there are more than one), | 1193 // Phase 1: get the ValueSet of all successors (if there are more than one), |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 HInstruction receiver = interceptor.receiver; | 1484 HInstruction receiver = interceptor.receiver; |
1472 for (var user in receiver.usedBy) { | 1485 for (var user in receiver.usedBy) { |
1473 if (user is HInterceptor && interceptor.dominates(user)) { | 1486 if (user is HInterceptor && interceptor.dominates(user)) { |
1474 user.interceptedClasses = interceptor.interceptedClasses; | 1487 user.interceptedClasses = interceptor.interceptedClasses; |
1475 } | 1488 } |
1476 } | 1489 } |
1477 } | 1490 } |
1478 | 1491 |
1479 // TODO(ngeoffray): Also implement it for non-intercepted calls. | 1492 // TODO(ngeoffray): Also implement it for non-intercepted calls. |
1480 } | 1493 } |
OLD | NEW |