Chromium Code Reviews| 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 |