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 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
348 node.element = cls.lookupSelector(selector); | 348 node.element = cls.lookupSelector(selector); |
349 } | 349 } |
350 return node; | 350 return node; |
351 } | 351 } |
352 | 352 |
353 bool isFixedSizeListConstructor(HInvokeStatic node) { | 353 bool isFixedSizeListConstructor(HInvokeStatic node) { |
354 Element element = node.target.element; | 354 Element element = node.target.element; |
355 if (backend.fixedLengthListConstructor == null) { | 355 if (backend.fixedLengthListConstructor == null) { |
356 backend.fixedLengthListConstructor = | 356 backend.fixedLengthListConstructor = |
357 compiler.listClass.lookupConstructor( | 357 compiler.listClass.lookupConstructor( |
358 new Selector.callConstructor(const SourceString("fixedLength"), | 358 new Selector.callConstructor(const SourceString(""), |
359 compiler.listClass.getLibrary())); | 359 compiler.listClass.getLibrary())); |
360 } | 360 } |
361 // TODO(ngeoffray): checking if the second input is an integer | 361 // TODO(ngeoffray): checking if the second input is an integer |
362 // should not be necessary but it currently makes it easier for | 362 // should not be necessary but it currently makes it easier for |
363 // other optimizations to reason on a fixed length constructor | 363 // other optimizations to reason on a fixed length constructor |
364 // that we know takes an int. | 364 // that we know takes an int. |
365 return element == backend.fixedLengthListConstructor | 365 return element == backend.fixedLengthListConstructor |
| 366 && node.inputs.length == 2 |
366 && node.inputs[1].isInteger(); | 367 && node.inputs[1].isInteger(); |
367 } | 368 } |
368 | 369 |
369 HInstruction visitInvokeStatic(HInvokeStatic node) { | 370 HInstruction visitInvokeStatic(HInvokeStatic node) { |
370 if (isFixedSizeListConstructor(node)) { | 371 if (isFixedSizeListConstructor(node)) { |
371 node.instructionType = HType.FIXED_ARRAY; | 372 node.instructionType = HType.FIXED_ARRAY; |
372 } | 373 } |
373 return node; | 374 return node; |
374 } | 375 } |
375 | 376 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
590 Selector selector) { | 591 Selector selector) { |
591 HType receiverType = receiver.instructionType; | 592 HType receiverType = receiver.instructionType; |
592 return compiler.world.locateSingleField( | 593 return compiler.world.locateSingleField( |
593 receiverType.refine(selector, compiler)); | 594 receiverType.refine(selector, compiler)); |
594 } | 595 } |
595 | 596 |
596 HInstruction visitFieldGet(HFieldGet node) { | 597 HInstruction visitFieldGet(HFieldGet node) { |
597 if (node.element == backend.jsArrayLength) { | 598 if (node.element == backend.jsArrayLength) { |
598 if (node.receiver is HInvokeStatic) { | 599 if (node.receiver is HInvokeStatic) { |
599 // Try to recognize the length getter with input | 600 // Try to recognize the length getter with input |
600 // [:new List.fixedLength(int):]. | 601 // [:new List(int):]. |
601 HInvokeStatic call = node.receiver; | 602 HInvokeStatic call = node.receiver; |
602 if (isFixedSizeListConstructor(call)) { | 603 if (isFixedSizeListConstructor(call)) { |
603 return call.inputs[1]; | 604 return call.inputs[1]; |
604 } | 605 } |
605 } | 606 } |
606 } | 607 } |
607 return node; | 608 return node; |
608 } | 609 } |
609 | 610 |
610 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 611 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1081 } | 1082 } |
1082 visitBasicBlock(dominated, successorValues); | 1083 visitBasicBlock(dominated, successorValues); |
1083 } | 1084 } |
1084 } | 1085 } |
1085 | 1086 |
1086 void computeChangesFlags(HGraph graph) { | 1087 void computeChangesFlags(HGraph graph) { |
1087 // Create the changes flags lists. Make sure to initialize the | 1088 // Create the changes flags lists. Make sure to initialize the |
1088 // loop changes flags list to zero so we can use bitwise or when | 1089 // loop changes flags list to zero so we can use bitwise or when |
1089 // propagating loop changes upwards. | 1090 // propagating loop changes upwards. |
1090 final int length = graph.blocks.length; | 1091 final int length = graph.blocks.length; |
1091 blockChangesFlags = new List<int>.fixedLength(length); | 1092 blockChangesFlags = new List<int>(length); |
1092 loopChangesFlags = new List<int>.fixedLength(length); | 1093 loopChangesFlags = new List<int>(length); |
1093 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; | 1094 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; |
1094 | 1095 |
1095 // Run through all the basic blocks in the graph and fill in the | 1096 // Run through all the basic blocks in the graph and fill in the |
1096 // changes flags lists. | 1097 // changes flags lists. |
1097 for (int i = length - 1; i >= 0; i--) { | 1098 for (int i = length - 1; i >= 0; i--) { |
1098 final HBasicBlock block = graph.blocks[i]; | 1099 final HBasicBlock block = graph.blocks[i]; |
1099 final int id = block.id; | 1100 final int id = block.id; |
1100 | 1101 |
1101 // Compute block changes flags for the block. | 1102 // Compute block changes flags for the block. |
1102 int changesFlags = 0; | 1103 int changesFlags = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1157 // | 1158 // |
1158 // A basic block looks at its sucessors and finds the intersection of | 1159 // A basic block looks at its sucessors and finds the intersection of |
1159 // these computed ValueSet. It moves all instructions of the | 1160 // these computed ValueSet. It moves all instructions of the |
1160 // intersection into its own list of instructions. | 1161 // intersection into its own list of instructions. |
1161 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { | 1162 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { |
1162 final String name = "SsaCodeMotion"; | 1163 final String name = "SsaCodeMotion"; |
1163 | 1164 |
1164 List<ValueSet> values; | 1165 List<ValueSet> values; |
1165 | 1166 |
1166 void visitGraph(HGraph graph) { | 1167 void visitGraph(HGraph graph) { |
1167 values = new List<ValueSet>.fixedLength(graph.blocks.length); | 1168 values = new List<ValueSet>(graph.blocks.length); |
1168 for (int i = 0; i < graph.blocks.length; i++) { | 1169 for (int i = 0; i < graph.blocks.length; i++) { |
1169 values[graph.blocks[i].id] = new ValueSet(); | 1170 values[graph.blocks[i].id] = new ValueSet(); |
1170 } | 1171 } |
1171 visitPostDominatorTree(graph); | 1172 visitPostDominatorTree(graph); |
1172 } | 1173 } |
1173 | 1174 |
1174 void visitBasicBlock(HBasicBlock block) { | 1175 void visitBasicBlock(HBasicBlock block) { |
1175 List<HBasicBlock> successors = block.successors; | 1176 List<HBasicBlock> successors = block.successors; |
1176 | 1177 |
1177 // Phase 1: get the ValueSet of all successors (if there are more than one), | 1178 // Phase 1: get the ValueSet of all successors (if there are more than one), |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1534 HBasicBlock block = user.block; | 1535 HBasicBlock block = user.block; |
1535 block.addAfter(user, interceptor); | 1536 block.addAfter(user, interceptor); |
1536 block.rewrite(user, interceptor); | 1537 block.rewrite(user, interceptor); |
1537 block.remove(user); | 1538 block.remove(user); |
1538 | 1539 |
1539 // The interceptor will be removed in the dead code elimination | 1540 // The interceptor will be removed in the dead code elimination |
1540 // phase. Note that removing it here would not work because of how | 1541 // phase. Note that removing it here would not work because of how |
1541 // the [visitBasicBlock] is implemented. | 1542 // the [visitBasicBlock] is implemented. |
1542 } | 1543 } |
1543 } | 1544 } |
OLD | NEW |