| 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 |