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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
340 node.element = cls.lookupSelector(selector); | 340 node.element = cls.lookupSelector(selector); |
341 } | 341 } |
342 return node; | 342 return node; |
343 } | 343 } |
344 | 344 |
345 bool isFixedSizeListConstructor(HInvokeStatic node) { | 345 bool isFixedSizeListConstructor(HInvokeStatic node) { |
346 Element element = node.target.element; | 346 Element element = node.target.element; |
347 if (backend.fixedLengthListConstructor == null) { | 347 if (backend.fixedLengthListConstructor == null) { |
348 backend.fixedLengthListConstructor = | 348 backend.fixedLengthListConstructor = |
349 compiler.listClass.lookupConstructor( | 349 compiler.listClass.lookupConstructor( |
350 new Selector.callConstructor(const SourceString("fixedLength"), | 350 new Selector.callConstructor(const SourceString(""), |
floitsch
2013/02/26 13:54:19
please test (manually) that this catches the right
Lasse Reichstein Nielsen
2013/02/26 15:26:00
Done.
| |
351 compiler.listClass.getLibrary())); | 351 compiler.listClass.getLibrary())); |
352 } | 352 } |
353 // TODO(ngeoffray): checking if the second input is an integer | 353 // TODO(ngeoffray): checking if the second input is an integer |
354 // should not be necessary but it currently makes it easier for | 354 // should not be necessary but it currently makes it easier for |
355 // other optimizations to reason on a fixed length constructor | 355 // other optimizations to reason on a fixed length constructor |
356 // that we know takes an int. | 356 // that we know takes an int. |
357 return element == backend.fixedLengthListConstructor | 357 return element == backend.fixedLengthListConstructor |
358 && node.inputs.length == 2 | |
358 && node.inputs[1].isInteger(); | 359 && node.inputs[1].isInteger(); |
359 } | 360 } |
360 | 361 |
361 HInstruction visitInvokeStatic(HInvokeStatic node) { | 362 HInstruction visitInvokeStatic(HInvokeStatic node) { |
362 if (isFixedSizeListConstructor(node)) { | 363 if (isFixedSizeListConstructor(node)) { |
363 node.instructionType = HType.FIXED_ARRAY; | 364 node.instructionType = HType.FIXED_ARRAY; |
364 } | 365 } |
365 return node; | 366 return node; |
366 } | 367 } |
367 | 368 |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
582 Selector selector) { | 583 Selector selector) { |
583 HType receiverType = receiver.instructionType; | 584 HType receiverType = receiver.instructionType; |
584 return compiler.world.locateSingleField( | 585 return compiler.world.locateSingleField( |
585 receiverType.refine(selector, compiler)); | 586 receiverType.refine(selector, compiler)); |
586 } | 587 } |
587 | 588 |
588 HInstruction visitFieldGet(HFieldGet node) { | 589 HInstruction visitFieldGet(HFieldGet node) { |
589 if (node.element == backend.jsArrayLength) { | 590 if (node.element == backend.jsArrayLength) { |
590 if (node.receiver is HInvokeStatic) { | 591 if (node.receiver is HInvokeStatic) { |
591 // Try to recognize the length getter with input | 592 // Try to recognize the length getter with input |
592 // [:new List.fixedLength(int):]. | 593 // [:new List(int):]. |
593 HInvokeStatic call = node.receiver; | 594 HInvokeStatic call = node.receiver; |
594 if (isFixedSizeListConstructor(call)) { | 595 if (isFixedSizeListConstructor(call)) { |
595 return call.inputs[1]; | 596 return call.inputs[1]; |
596 } | 597 } |
597 } | 598 } |
598 } | 599 } |
599 return node; | 600 return node; |
600 } | 601 } |
601 | 602 |
602 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { | 603 HInstruction visitInvokeDynamicGetter(HInvokeDynamicGetter node) { |
(...skipping 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1073 } | 1074 } |
1074 visitBasicBlock(dominated, successorValues); | 1075 visitBasicBlock(dominated, successorValues); |
1075 } | 1076 } |
1076 } | 1077 } |
1077 | 1078 |
1078 void computeChangesFlags(HGraph graph) { | 1079 void computeChangesFlags(HGraph graph) { |
1079 // Create the changes flags lists. Make sure to initialize the | 1080 // Create the changes flags lists. Make sure to initialize the |
1080 // loop changes flags list to zero so we can use bitwise or when | 1081 // loop changes flags list to zero so we can use bitwise or when |
1081 // propagating loop changes upwards. | 1082 // propagating loop changes upwards. |
1082 final int length = graph.blocks.length; | 1083 final int length = graph.blocks.length; |
1083 blockChangesFlags = new List<int>.fixedLength(length); | 1084 blockChangesFlags = new List<int>(length); |
1084 loopChangesFlags = new List<int>.fixedLength(length); | 1085 loopChangesFlags = new List<int>(length); |
1085 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; | 1086 for (int i = 0; i < length; i++) loopChangesFlags[i] = 0; |
1086 | 1087 |
1087 // Run through all the basic blocks in the graph and fill in the | 1088 // Run through all the basic blocks in the graph and fill in the |
1088 // changes flags lists. | 1089 // changes flags lists. |
1089 for (int i = length - 1; i >= 0; i--) { | 1090 for (int i = length - 1; i >= 0; i--) { |
1090 final HBasicBlock block = graph.blocks[i]; | 1091 final HBasicBlock block = graph.blocks[i]; |
1091 final int id = block.id; | 1092 final int id = block.id; |
1092 | 1093 |
1093 // Compute block changes flags for the block. | 1094 // Compute block changes flags for the block. |
1094 int changesFlags = 0; | 1095 int changesFlags = 0; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1149 // | 1150 // |
1150 // A basic block looks at its sucessors and finds the intersection of | 1151 // A basic block looks at its sucessors and finds the intersection of |
1151 // these computed ValueSet. It moves all instructions of the | 1152 // these computed ValueSet. It moves all instructions of the |
1152 // intersection into its own list of instructions. | 1153 // intersection into its own list of instructions. |
1153 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { | 1154 class SsaCodeMotion extends HBaseVisitor implements OptimizationPhase { |
1154 final String name = "SsaCodeMotion"; | 1155 final String name = "SsaCodeMotion"; |
1155 | 1156 |
1156 List<ValueSet> values; | 1157 List<ValueSet> values; |
1157 | 1158 |
1158 void visitGraph(HGraph graph) { | 1159 void visitGraph(HGraph graph) { |
1159 values = new List<ValueSet>.fixedLength(graph.blocks.length); | 1160 values = new List<ValueSet>(graph.blocks.length); |
1160 for (int i = 0; i < graph.blocks.length; i++) { | 1161 for (int i = 0; i < graph.blocks.length; i++) { |
1161 values[graph.blocks[i].id] = new ValueSet(); | 1162 values[graph.blocks[i].id] = new ValueSet(); |
1162 } | 1163 } |
1163 visitPostDominatorTree(graph); | 1164 visitPostDominatorTree(graph); |
1164 } | 1165 } |
1165 | 1166 |
1166 void visitBasicBlock(HBasicBlock block) { | 1167 void visitBasicBlock(HBasicBlock block) { |
1167 List<HBasicBlock> successors = block.successors; | 1168 List<HBasicBlock> successors = block.successors; |
1168 | 1169 |
1169 // Phase 1: get the ValueSet of all successors (if there are more than one), | 1170 // 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... | |
1526 HBasicBlock block = user.block; | 1527 HBasicBlock block = user.block; |
1527 block.addAfter(user, interceptor); | 1528 block.addAfter(user, interceptor); |
1528 block.rewrite(user, interceptor); | 1529 block.rewrite(user, interceptor); |
1529 block.remove(user); | 1530 block.remove(user); |
1530 | 1531 |
1531 // The interceptor will be removed in the dead code elimination | 1532 // The interceptor will be removed in the dead code elimination |
1532 // phase. Note that removing it here would not work because of how | 1533 // phase. Note that removing it here would not work because of how |
1533 // the [visitBasicBlock] is implemented. | 1534 // the [visitBasicBlock] is implemented. |
1534 } | 1535 } |
1535 } | 1536 } |
OLD | NEW |