| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
| 6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
| 7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
| 8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
| 9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
| 10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 blocks.add(block); | 131 blocks.add(block); |
| 132 assert(blocks[id] === block); | 132 assert(blocks[id] === block); |
| 133 } | 133 } |
| 134 | 134 |
| 135 HBasicBlock addNewBlock() { | 135 HBasicBlock addNewBlock() { |
| 136 HBasicBlock result = new HBasicBlock(); | 136 HBasicBlock result = new HBasicBlock(); |
| 137 addBlock(result); | 137 addBlock(result); |
| 138 return result; | 138 return result; |
| 139 } | 139 } |
| 140 | 140 |
| 141 HBasicBlock addNewLoopHeaderBlock(List<LabelElement> labels) { | 141 HBasicBlock addNewLoopHeaderBlock(int type, |
| 142 TargetElement target, |
| 143 List<LabelElement> labels) { |
| 142 HBasicBlock result = addNewBlock(); | 144 HBasicBlock result = addNewBlock(); |
| 143 result.loopInformation = new HLoopInformation(result, labels); | 145 result.loopInformation = new HLoopInformation(type, result, target, labels); |
| 144 return result; | 146 return result; |
| 145 } | 147 } |
| 146 | 148 |
| 147 static HType mapConstantTypeToSsaType(Constant constant) { | 149 static HType mapConstantTypeToSsaType(Constant constant) { |
| 148 if (constant.isNull()) return HType.UNKNOWN; | 150 if (constant.isNull()) return HType.UNKNOWN; |
| 149 if (constant.isBool()) return HType.BOOLEAN; | 151 if (constant.isBool()) return HType.BOOLEAN; |
| 150 if (constant.isInt()) return HType.INTEGER; | 152 if (constant.isInt()) return HType.INTEGER; |
| 151 if (constant.isDouble()) return HType.DOUBLE; | 153 if (constant.isDouble()) return HType.DOUBLE; |
| 152 if (constant.isString()) return HType.STRING; | 154 if (constant.isString()) return HType.STRING; |
| 153 if (constant.isList()) return HType.ARRAY; | 155 if (constant.isList()) return HType.ARRAY; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 const SubGraph(this.start, this.end); | 315 const SubGraph(this.start, this.end); |
| 314 | 316 |
| 315 bool contains(HBasicBlock block) { | 317 bool contains(HBasicBlock block) { |
| 316 assert(start !== null); | 318 assert(start !== null); |
| 317 assert(end !== null); | 319 assert(end !== null); |
| 318 assert(block !== null); | 320 assert(block !== null); |
| 319 return start.id <= block.id && block.id <= end.id; | 321 return start.id <= block.id && block.id <= end.id; |
| 320 } | 322 } |
| 321 } | 323 } |
| 322 | 324 |
| 325 class SubExpression extends SubGraph { |
| 326 final HInstruction expression; |
| 327 const SubExpression(HBasicBlock start, HBasicBlock end, this.expression) |
| 328 : super(start, end); |
| 329 } |
| 330 |
| 323 class HInstructionList { | 331 class HInstructionList { |
| 324 HInstruction first = null; | 332 HInstruction first = null; |
| 325 HInstruction last = null; | 333 HInstruction last = null; |
| 326 | 334 |
| 327 bool isEmpty() { | 335 bool isEmpty() { |
| 328 return first === null; | 336 return first === null; |
| 329 } | 337 } |
| 330 | 338 |
| 331 void addAfter(HInstruction cursor, HInstruction instruction) { | 339 void addAfter(HInstruction cursor, HInstruction instruction) { |
| 332 if (cursor === null) { | 340 if (cursor === null) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 } | 646 } |
| 639 | 647 |
| 640 bool isValid() { | 648 bool isValid() { |
| 641 assert(isClosed()); | 649 assert(isClosed()); |
| 642 HValidator validator = new HValidator(); | 650 HValidator validator = new HValidator(); |
| 643 validator.visitBasicBlock(this); | 651 validator.visitBasicBlock(this); |
| 644 return validator.isValid; | 652 return validator.isValid; |
| 645 } | 653 } |
| 646 } | 654 } |
| 647 | 655 |
| 648 class HLabeledBlockInformation { | 656 interface HBlockInformation {} |
| 657 |
| 658 class HLabeledBlockInformation implements HBlockInformation { |
| 649 final SubGraph body; | 659 final SubGraph body; |
| 650 final HBasicBlock joinBlock; | 660 final HBasicBlock joinBlock; |
| 651 final List<LabelElement> labels; | 661 final List<LabelElement> labels; |
| 652 final TargetElement target; | 662 final TargetElement target; |
| 653 final bool isContinue; | 663 final bool isContinue; |
| 654 | 664 |
| 655 HLabeledBlockInformation(this.body, this.joinBlock, | 665 HLabeledBlockInformation(this.body, this.joinBlock, |
| 656 List<LabelElement> labels, | 666 List<LabelElement> labels, |
| 657 [this.isContinue = false]) : | 667 [this.isContinue = false]) : |
| 658 this.labels = labels, this.target = labels[0].target; | 668 this.labels = labels, this.target = labels[0].target; |
| 659 | 669 |
| 660 HLabeledBlockInformation.implicit(this.body, | 670 HLabeledBlockInformation.implicit(this.body, |
| 661 this.joinBlock, | 671 this.joinBlock, |
| 662 this.target, | 672 this.target, |
| 663 [this.isContinue = false]) | 673 [this.isContinue = false]) |
| 664 : this.labels = const<LabelElement>[]; | 674 : this.labels = const<LabelElement>[]; |
| 665 } | 675 } |
| 666 | 676 |
| 667 class HLoopInformation { | 677 class LoopTypeVisitor extends AbstractVisitor { |
| 678 const LoopTypeVisitor(); |
| 679 int visitNode(Node node) { |
| 680 unreachable(); |
| 681 } |
| 682 int visitWhile(While node) => HLoopInformation.WHILE_LOOP; |
| 683 int visitFor(For node) => HLoopInformation.FOR_LOOP; |
| 684 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP; |
| 685 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP; |
| 686 } |
| 687 |
| 688 class HLoopInformation implements HBlockInformation { |
| 689 static final int WHILE_LOOP = 0; |
| 690 static final int FOR_LOOP = 1; |
| 691 static final int DO_WHILE_LOOP = 2; |
| 692 static final int FOR_IN_LOOP = 3; |
| 693 |
| 694 final int type; |
| 668 final HBasicBlock header; | 695 final HBasicBlock header; |
| 669 final List<HBasicBlock> blocks; | 696 final List<HBasicBlock> blocks; |
| 670 final List<HBasicBlock> backEdges; | 697 final List<HBasicBlock> backEdges; |
| 671 final List<LabelElement> labels; | 698 final List<LabelElement> labels; |
| 699 final TargetElement target; |
| 700 SubGraph initializer = null; |
| 701 SubExpression condition = null; |
| 702 SubGraph body = null; |
| 703 SubGraph updates = null; |
| 704 HBasicBlock joinBlock; |
| 672 | 705 |
| 673 HLoopInformation(this.header, this.labels) | 706 HLoopInformation(this.type, this.header, this.target, this.labels) |
| 674 : blocks = new List<HBasicBlock>(), | 707 : blocks = new List<HBasicBlock>(), |
| 675 backEdges = new List<HBasicBlock>(); | 708 backEdges = new List<HBasicBlock>(); |
| 676 | 709 |
| 710 static int loopType(Node node) { |
| 711 return node.accept(const LoopTypeVisitor()); |
| 712 } |
| 713 |
| 677 void addBackEdge(HBasicBlock predecessor) { | 714 void addBackEdge(HBasicBlock predecessor) { |
| 678 backEdges.add(predecessor); | 715 backEdges.add(predecessor); |
| 679 addBlock(predecessor); | 716 addBlock(predecessor); |
| 680 } | 717 } |
| 681 | 718 |
| 682 // Adds a block and transitively all its predecessors in the loop as | 719 // Adds a block and transitively all its predecessors in the loop as |
| 683 // loop blocks. | 720 // loop blocks. |
| 684 void addBlock(HBasicBlock block) { | 721 void addBlock(HBasicBlock block) { |
| 685 if (block === header) return; | 722 if (block === header) return; |
| 686 HBasicBlock parentHeader = block.parentLoopHeader; | 723 HBasicBlock parentHeader = block.parentLoopHeader; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 799 | 836 |
| 800 int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1); | 837 int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1); |
| 801 bool hasSideEffects() => getChangesFlags() != 0; | 838 bool hasSideEffects() => getChangesFlags() != 0; |
| 802 void prepareGvn() { setAllSideEffects(); } | 839 void prepareGvn() { setAllSideEffects(); } |
| 803 | 840 |
| 804 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); } | 841 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); } |
| 805 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } | 842 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } |
| 806 | 843 |
| 807 bool useGvn() => getFlag(FLAG_USE_GVN); | 844 bool useGvn() => getFlag(FLAG_USE_GVN); |
| 808 void setUseGvn() { setFlag(FLAG_USE_GVN); } | 845 void setUseGvn() { setFlag(FLAG_USE_GVN); } |
| 846 // Does this node pNotentially affect control flow. |
| 847 bool isControlFlow() => false; |
| 809 | 848 |
| 810 bool isArray() => type.isArray(); | 849 bool isArray() => type.isArray(); |
| 811 bool isBoolean() => type.isBoolean(); | 850 bool isBoolean() => type.isBoolean(); |
| 812 bool isInteger() => type.isInteger(); | 851 bool isInteger() => type.isInteger(); |
| 813 bool isNumber() => type.isNumber(); | 852 bool isNumber() => type.isNumber(); |
| 814 bool isString() => type.isString(); | 853 bool isString() => type.isString(); |
| 815 bool isTypeUnknown() => type.isUnknown(); | 854 bool isTypeUnknown() => type.isUnknown(); |
| 816 bool isStringOrArray() => type.isStringOrArray(); | 855 bool isStringOrArray() => type.isStringOrArray(); |
| 817 | 856 |
| 818 // Compute the type of the instruction. | 857 // Compute the type of the instruction. |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 int typeCode() => 0; | 1021 int typeCode() => 0; |
| 983 bool typeEquals(other) => other is HBoolify; | 1022 bool typeEquals(other) => other is HBoolify; |
| 984 bool dataEquals(HInstruction other) => true; | 1023 bool dataEquals(HInstruction other) => true; |
| 985 } | 1024 } |
| 986 | 1025 |
| 987 class HCheck extends HInstruction { | 1026 class HCheck extends HInstruction { |
| 988 HCheck(inputs) : super(inputs); | 1027 HCheck(inputs) : super(inputs); |
| 989 | 1028 |
| 990 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1029 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 991 abstract accept(HVisitor visitor); | 1030 abstract accept(HVisitor visitor); |
| 1031 |
| 1032 bool isControlFlow() => true; |
| 992 } | 1033 } |
| 993 | 1034 |
| 994 class HTypeGuard extends HInstruction { | 1035 class HTypeGuard extends HInstruction { |
| 995 int state; | 1036 int state; |
| 996 HTypeGuard(int this.state, List<HInstruction> env) : super(env); | 1037 HTypeGuard(int this.state, List<HInstruction> env) : super(env); |
| 997 | 1038 |
| 998 void prepareGvn() { | 1039 void prepareGvn() { |
| 999 assert(!hasSideEffects()); | 1040 assert(!hasSideEffects()); |
| 1000 setUseGvn(); | 1041 setUseGvn(); |
| 1001 } | 1042 } |
| 1002 | 1043 |
| 1003 HInstruction get guarded() => inputs.last(); | 1044 HInstruction get guarded() => inputs.last(); |
| 1004 | 1045 |
| 1005 HType computeType() => type; | 1046 HType computeType() => type; |
| 1006 bool hasExpectedType() => true; | 1047 bool hasExpectedType() => true; |
| 1007 | 1048 |
| 1049 bool isControlFlow() => true; |
| 1050 |
| 1008 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1051 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1009 int typeCode() => 1; | 1052 int typeCode() => 1; |
| 1010 bool typeEquals(other) => other is HTypeGuard; | 1053 bool typeEquals(other) => other is HTypeGuard; |
| 1011 bool dataEquals(HTypeGuard other) => type == other.type; | 1054 bool dataEquals(HTypeGuard other) => type == other.type; |
| 1012 } | 1055 } |
| 1013 | 1056 |
| 1014 class HBoundsCheck extends HCheck { | 1057 class HBoundsCheck extends HCheck { |
| 1015 HBoundsCheck(length, index) : super(<HInstruction>[length, index]) { | 1058 HBoundsCheck(length, index) : super(<HInstruction>[length, index]) { |
| 1016 type = HType.INTEGER; | 1059 type = HType.INTEGER; |
| 1017 } | 1060 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1056 HConditionalBranch(inputs) : super(inputs); | 1099 HConditionalBranch(inputs) : super(inputs); |
| 1057 HInstruction get condition() => inputs[0]; | 1100 HInstruction get condition() => inputs[0]; |
| 1058 HBasicBlock get trueBranch() => block.successors[0]; | 1101 HBasicBlock get trueBranch() => block.successors[0]; |
| 1059 HBasicBlock get falseBranch() => block.successors[1]; | 1102 HBasicBlock get falseBranch() => block.successors[1]; |
| 1060 abstract toString(); | 1103 abstract toString(); |
| 1061 } | 1104 } |
| 1062 | 1105 |
| 1063 class HControlFlow extends HInstruction { | 1106 class HControlFlow extends HInstruction { |
| 1064 HControlFlow(inputs) : super(inputs); | 1107 HControlFlow(inputs) : super(inputs); |
| 1065 abstract toString(); | 1108 abstract toString(); |
| 1109 bool isControlFlow() => true; |
| 1066 } | 1110 } |
| 1067 | 1111 |
| 1068 class HInvoke extends HInstruction { | 1112 class HInvoke extends HInstruction { |
| 1069 /** | 1113 /** |
| 1070 * The first argument must be the target: either an [HStatic] node, or | 1114 * The first argument must be the target: either an [HStatic] node, or |
| 1071 * the receiver of a method-call. The remaining inputs are the arguments | 1115 * the receiver of a method-call. The remaining inputs are the arguments |
| 1072 * to the invocation. | 1116 * to the invocation. |
| 1073 */ | 1117 */ |
| 1074 final Selector selector; | 1118 final Selector selector; |
| 1075 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); | 1119 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 final bool getter; | 1214 final bool getter; |
| 1171 | 1215 |
| 1172 HInvokeInterceptor(Selector selector, | 1216 HInvokeInterceptor(Selector selector, |
| 1173 SourceString this.name, | 1217 SourceString this.name, |
| 1174 bool this.getter, | 1218 bool this.getter, |
| 1175 List<HInstruction> inputs) | 1219 List<HInstruction> inputs) |
| 1176 : super(selector, inputs); | 1220 : super(selector, inputs); |
| 1177 toString() => 'invoke interceptor: ${element.name}'; | 1221 toString() => 'invoke interceptor: ${element.name}'; |
| 1178 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); | 1222 accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); |
| 1179 | 1223 |
| 1180 | 1224 |
| 1181 String get builtinJsName() { | 1225 String get builtinJsName() { |
| 1182 if (getter | 1226 if (getter |
| 1183 && name == const SourceString('length') | 1227 && name == const SourceString('length') |
| 1184 && inputs[1].isStringOrArray()) { | 1228 && inputs[1].isStringOrArray()) { |
| 1185 return 'length'; | 1229 return 'length'; |
| 1186 } else if (name == const SourceString('add') && inputs[1].isArray()) { | 1230 } else if (name == const SourceString('add') && inputs[1].isArray()) { |
| 1187 return 'push'; | 1231 return 'push'; |
| 1188 } else if (name == const SourceString('removeLast') | 1232 } else if (name == const SourceString('removeLast') |
| 1189 && inputs[1].isArray()) { | 1233 && inputs[1].isArray()) { |
| 1190 return 'pop'; | 1234 return 'pop'; |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 class HIfBlockInformation { | 2118 class HIfBlockInformation { |
| 2075 final HIf branch; | 2119 final HIf branch; |
| 2076 final SubGraph thenGraph; | 2120 final SubGraph thenGraph; |
| 2077 final SubGraph elseGraph; | 2121 final SubGraph elseGraph; |
| 2078 final HBasicBlock joinBlock; | 2122 final HBasicBlock joinBlock; |
| 2079 HIfBlockInformation(this.branch, | 2123 HIfBlockInformation(this.branch, |
| 2080 this.thenGraph, | 2124 this.thenGraph, |
| 2081 this.elseGraph, | 2125 this.elseGraph, |
| 2082 this.joinBlock); | 2126 this.joinBlock); |
| 2083 } | 2127 } |
| OLD | NEW |