Chromium Code Reviews| 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 visitBailoutTarget(HBailoutTarget node); | 7 R visitBailoutTarget(HBailoutTarget node); |
| 8 R visitBitAnd(HBitAnd node); | 8 R visitBitAnd(HBitAnd node); |
| 9 R visitBitNot(HBitNot node); | 9 R visitBitNot(HBitNot node); |
| 10 R visitBitOr(HBitOr node); | 10 R visitBitOr(HBitOr node); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 132 blocks.add(block); | 132 blocks.add(block); |
| 133 assert(blocks[id] === block); | 133 assert(blocks[id] === block); |
| 134 } | 134 } |
| 135 | 135 |
| 136 HBasicBlock addNewBlock() { | 136 HBasicBlock addNewBlock() { |
| 137 HBasicBlock result = new HBasicBlock(); | 137 HBasicBlock result = new HBasicBlock(); |
| 138 addBlock(result); | 138 addBlock(result); |
| 139 return result; | 139 return result; |
| 140 } | 140 } |
| 141 | 141 |
| 142 HBasicBlock addNewLoopHeaderBlock(List<LabelElement> labels) { | 142 HBasicBlock addNewLoopHeaderBlock(int type, |
| 143 TargetElement target, | |
| 144 List<LabelElement> labels) { | |
| 143 HBasicBlock result = addNewBlock(); | 145 HBasicBlock result = addNewBlock(); |
| 144 result.loopInformation = new HLoopInformation(result, labels); | 146 result.loopInformation = new HLoopInformation(type, result, target, labels); |
| 145 return result; | 147 return result; |
| 146 } | 148 } |
| 147 | 149 |
| 148 static HType mapConstantTypeToSsaType(Constant constant) { | 150 static HType mapConstantTypeToSsaType(Constant constant) { |
| 149 if (constant.isNull()) return HType.UNKNOWN; | 151 if (constant.isNull()) return HType.UNKNOWN; |
| 150 if (constant.isBool()) return HType.BOOLEAN; | 152 if (constant.isBool()) return HType.BOOLEAN; |
| 151 if (constant.isInt()) return HType.INTEGER; | 153 if (constant.isInt()) return HType.INTEGER; |
| 152 if (constant.isDouble()) return HType.DOUBLE; | 154 if (constant.isDouble()) return HType.DOUBLE; |
| 153 if (constant.isString()) return HType.STRING; | 155 if (constant.isString()) return HType.STRING; |
| 154 if (constant.isList()) return HType.ARRAY; | 156 if (constant.isList()) return HType.ARRAY; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 315 const SubGraph(this.start, this.end); | 317 const SubGraph(this.start, this.end); |
| 316 | 318 |
| 317 bool contains(HBasicBlock block) { | 319 bool contains(HBasicBlock block) { |
| 318 assert(start !== null); | 320 assert(start !== null); |
| 319 assert(end !== null); | 321 assert(end !== null); |
| 320 assert(block !== null); | 322 assert(block !== null); |
| 321 return start.id <= block.id && block.id <= end.id; | 323 return start.id <= block.id && block.id <= end.id; |
| 322 } | 324 } |
| 323 } | 325 } |
| 324 | 326 |
| 327 class SubExpression extends SubGraph { | |
| 328 final HInstruction expression; | |
| 329 const SubExpression(HBasicBlock start, HBasicBlock end, this.expression) | |
| 330 : super(start, end); | |
| 331 } | |
| 332 | |
| 325 class HInstructionList { | 333 class HInstructionList { |
| 326 HInstruction first = null; | 334 HInstruction first = null; |
| 327 HInstruction last = null; | 335 HInstruction last = null; |
| 328 | 336 |
| 329 bool isEmpty() { | 337 bool isEmpty() { |
| 330 return first === null; | 338 return first === null; |
| 331 } | 339 } |
| 332 | 340 |
| 333 void addAfter(HInstruction cursor, HInstruction instruction) { | 341 void addAfter(HInstruction cursor, HInstruction instruction) { |
| 334 if (cursor === null) { | 342 if (cursor === null) { |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 640 } | 648 } |
| 641 | 649 |
| 642 bool isValid() { | 650 bool isValid() { |
| 643 assert(isClosed()); | 651 assert(isClosed()); |
| 644 HValidator validator = new HValidator(); | 652 HValidator validator = new HValidator(); |
| 645 validator.visitBasicBlock(this); | 653 validator.visitBasicBlock(this); |
| 646 return validator.isValid; | 654 return validator.isValid; |
| 647 } | 655 } |
| 648 } | 656 } |
| 649 | 657 |
| 650 class HLabeledBlockInformation { | 658 interface HBlockInformation {} |
| 659 | |
| 660 class HLabeledBlockInformation implements HBlockInformation { | |
| 651 final SubGraph body; | 661 final SubGraph body; |
| 652 final HBasicBlock joinBlock; | 662 final HBasicBlock joinBlock; |
| 653 final List<LabelElement> labels; | 663 final List<LabelElement> labels; |
| 654 final TargetElement target; | 664 final TargetElement target; |
| 655 final bool isContinue; | 665 final bool isContinue; |
| 656 | 666 |
| 657 HLabeledBlockInformation(this.body, this.joinBlock, | 667 HLabeledBlockInformation(this.body, this.joinBlock, |
| 658 List<LabelElement> labels, | 668 List<LabelElement> labels, |
| 659 [this.isContinue = false]) : | 669 [this.isContinue = false]) : |
| 660 this.labels = labels, this.target = labels[0].target; | 670 this.labels = labels, this.target = labels[0].target; |
| 661 | 671 |
| 662 HLabeledBlockInformation.implicit(this.body, | 672 HLabeledBlockInformation.implicit(this.body, |
| 663 this.joinBlock, | 673 this.joinBlock, |
| 664 this.target, | 674 this.target, |
| 665 [this.isContinue = false]) | 675 [this.isContinue = false]) |
| 666 : this.labels = const<LabelElement>[]; | 676 : this.labels = const<LabelElement>[]; |
| 667 } | 677 } |
| 668 | 678 |
| 669 class HLoopInformation { | 679 class LoopTypeVisitor extends AbstractVisitor { |
| 680 const LoopTypeVisitor(); | |
| 681 int visitNode(Node node) { | |
| 682 unreachable(); | |
| 683 } | |
| 684 int visitWhile(While node) => HLoopInformation.WHILE_LOOP; | |
| 685 int visitFor(For node) => HLoopInformation.FOR_LOOP; | |
| 686 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP; | |
| 687 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP; | |
| 688 } | |
| 689 | |
| 690 class HLoopInformation implements HBlockInformation { | |
| 691 static final int WHILE_LOOP = 0; | |
| 692 static final int FOR_LOOP = 1; | |
| 693 static final int DO_WHILE_LOOP = 2; | |
| 694 static final int FOR_IN_LOOP = 3; | |
| 695 | |
| 696 final int type; | |
| 670 final HBasicBlock header; | 697 final HBasicBlock header; |
| 671 final List<HBasicBlock> blocks; | 698 final List<HBasicBlock> blocks; |
| 672 final List<HBasicBlock> backEdges; | 699 final List<HBasicBlock> backEdges; |
| 673 final List<LabelElement> labels; | 700 final List<LabelElement> labels; |
| 701 final TargetElement target; | |
| 702 SubGraph initializer = null; | |
| 703 SubExpression condition = null; | |
| 704 SubGraph body = null; | |
| 705 SubGraph updates = null; | |
| 706 HBasicBlock joinBlock; | |
| 674 | 707 |
| 675 HLoopInformation(this.header, this.labels) | 708 HLoopInformation(this.type, this.header, this.target, this.labels) |
| 676 : blocks = new List<HBasicBlock>(), | 709 : blocks = new List<HBasicBlock>(), |
| 677 backEdges = new List<HBasicBlock>(); | 710 backEdges = new List<HBasicBlock>(); |
| 678 | 711 |
| 712 static int loopType(Node node) { | |
| 713 return node.accept(const LoopTypeVisitor()); | |
| 714 } | |
| 715 | |
| 679 void addBackEdge(HBasicBlock predecessor) { | 716 void addBackEdge(HBasicBlock predecessor) { |
| 680 backEdges.add(predecessor); | 717 backEdges.add(predecessor); |
| 681 addBlock(predecessor); | 718 addBlock(predecessor); |
| 682 } | 719 } |
| 683 | 720 |
| 684 // Adds a block and transitively all its predecessors in the loop as | 721 // Adds a block and transitively all its predecessors in the loop as |
| 685 // loop blocks. | 722 // loop blocks. |
| 686 void addBlock(HBasicBlock block) { | 723 void addBlock(HBasicBlock block) { |
| 687 if (block === header) return; | 724 if (block === header) return; |
| 688 HBasicBlock parentHeader = block.parentLoopHeader; | 725 HBasicBlock parentHeader = block.parentLoopHeader; |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 801 | 838 |
| 802 int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1); | 839 int getChangesFlags() => flags & ((1 << FLAG_CHANGES_COUNT) - 1); |
| 803 bool hasSideEffects() => getChangesFlags() != 0; | 840 bool hasSideEffects() => getChangesFlags() != 0; |
| 804 void prepareGvn() { setAllSideEffects(); } | 841 void prepareGvn() { setAllSideEffects(); } |
| 805 | 842 |
| 806 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); } | 843 void setAllSideEffects() { flags |= ((1 << FLAG_CHANGES_COUNT) - 1); } |
| 807 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } | 844 void clearAllSideEffects() { flags &= ~((1 << FLAG_CHANGES_COUNT) - 1); } |
| 808 | 845 |
| 809 bool useGvn() => getFlag(FLAG_USE_GVN); | 846 bool useGvn() => getFlag(FLAG_USE_GVN); |
| 810 void setUseGvn() { setFlag(FLAG_USE_GVN); } | 847 void setUseGvn() { setFlag(FLAG_USE_GVN); } |
| 848 // Does this node ootentially affect control flow. | |
|
floitsch
2012/03/28 04:03:48
potentially
| |
| 849 bool isControlFlow() => false; | |
| 811 | 850 |
| 812 bool isArray() => type.isArray(); | 851 bool isArray() => type.isArray(); |
| 813 bool isBoolean() => type.isBoolean(); | 852 bool isBoolean() => type.isBoolean(); |
| 814 bool isInteger() => type.isInteger(); | 853 bool isInteger() => type.isInteger(); |
| 815 bool isNumber() => type.isNumber(); | 854 bool isNumber() => type.isNumber(); |
| 816 bool isString() => type.isString(); | 855 bool isString() => type.isString(); |
| 817 bool isTypeUnknown() => type.isUnknown(); | 856 bool isTypeUnknown() => type.isUnknown(); |
| 818 bool isStringOrArray() => type.isStringOrArray(); | 857 bool isStringOrArray() => type.isStringOrArray(); |
| 819 | 858 |
| 820 // Compute the type of the instruction. | 859 // Compute the type of the instruction. |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 984 int typeCode() => 0; | 1023 int typeCode() => 0; |
| 985 bool typeEquals(other) => other is HBoolify; | 1024 bool typeEquals(other) => other is HBoolify; |
| 986 bool dataEquals(HInstruction other) => true; | 1025 bool dataEquals(HInstruction other) => true; |
| 987 } | 1026 } |
| 988 | 1027 |
| 989 class HCheck extends HInstruction { | 1028 class HCheck extends HInstruction { |
| 990 HCheck(inputs) : super(inputs); | 1029 HCheck(inputs) : super(inputs); |
| 991 | 1030 |
| 992 // TODO(floitsch): make class abstract instead of adding an abstract method. | 1031 // TODO(floitsch): make class abstract instead of adding an abstract method. |
| 993 abstract accept(HVisitor visitor); | 1032 abstract accept(HVisitor visitor); |
| 1033 | |
| 1034 bool isControlFlow() => true; | |
| 994 } | 1035 } |
| 995 | 1036 |
| 996 class HTypeGuard extends HInstruction { | 1037 class HTypeGuard extends HInstruction { |
| 997 // Instruction id of the original guarded instruction. | 1038 // Instruction id of the original guarded instruction. |
| 998 final int originalGuardedId; | 1039 final int originalGuardedId; |
| 999 | 1040 |
| 1000 HTypeGuard(HType type, List<HInstruction> env, int this.originalGuardedId) | 1041 HTypeGuard(HType type, List<HInstruction> env, int this.originalGuardedId) |
| 1001 : super(env) { | 1042 : super(env) { |
| 1002 this.type = type; | 1043 this.type = type; |
| 1003 } | 1044 } |
| 1004 | 1045 |
| 1005 void prepareGvn() { | 1046 void prepareGvn() { |
| 1006 assert(!hasSideEffects()); | 1047 assert(!hasSideEffects()); |
| 1007 setUseGvn(); | 1048 setUseGvn(); |
| 1008 } | 1049 } |
| 1009 | 1050 |
| 1010 HInstruction get guarded() => inputs.last(); | 1051 HInstruction get guarded() => inputs.last(); |
| 1011 | 1052 |
| 1012 HType computeType() => type; | 1053 HType computeType() => type; |
| 1013 bool hasExpectedType() => true; | 1054 bool hasExpectedType() => true; |
| 1014 | 1055 |
| 1056 bool isControlFlow() => true; | |
| 1057 | |
| 1015 accept(HVisitor visitor) => visitor.visitTypeGuard(this); | 1058 accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| 1016 int typeCode() => 1; | 1059 int typeCode() => 1; |
| 1017 bool typeEquals(other) => other is HTypeGuard; | 1060 bool typeEquals(other) => other is HTypeGuard; |
| 1018 bool dataEquals(HTypeGuard other) => type == other.type; | 1061 bool dataEquals(HTypeGuard other) => type == other.type; |
| 1019 } | 1062 } |
| 1020 | 1063 |
| 1021 class HBailoutTarget extends HInstruction { | 1064 class HBailoutTarget extends HInstruction { |
| 1022 final int state; | 1065 final int state; |
| 1023 HBailoutTarget(this.state, inputs) : super(inputs); | 1066 HBailoutTarget(this.state, inputs) : super(inputs); |
| 1024 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); | 1067 accept(HVisitor visitor) => visitor.visitBailoutTarget(this); |
| 1068 bool isControlFlow() => true; | |
| 1025 } | 1069 } |
| 1026 | 1070 |
| 1027 class HBoundsCheck extends HCheck { | 1071 class HBoundsCheck extends HCheck { |
| 1028 HBoundsCheck(length, index) : super(<HInstruction>[length, index]) { | 1072 HBoundsCheck(length, index) : super(<HInstruction>[length, index]) { |
| 1029 type = HType.INTEGER; | 1073 type = HType.INTEGER; |
| 1030 } | 1074 } |
| 1031 | 1075 |
| 1032 HInstruction get length() => inputs[0]; | 1076 HInstruction get length() => inputs[0]; |
| 1033 HInstruction get index() => inputs[1]; | 1077 HInstruction get index() => inputs[1]; |
| 1034 | 1078 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1069 HConditionalBranch(inputs) : super(inputs); | 1113 HConditionalBranch(inputs) : super(inputs); |
| 1070 HInstruction get condition() => inputs[0]; | 1114 HInstruction get condition() => inputs[0]; |
| 1071 HBasicBlock get trueBranch() => block.successors[0]; | 1115 HBasicBlock get trueBranch() => block.successors[0]; |
| 1072 HBasicBlock get falseBranch() => block.successors[1]; | 1116 HBasicBlock get falseBranch() => block.successors[1]; |
| 1073 abstract toString(); | 1117 abstract toString(); |
| 1074 } | 1118 } |
| 1075 | 1119 |
| 1076 class HControlFlow extends HInstruction { | 1120 class HControlFlow extends HInstruction { |
| 1077 HControlFlow(inputs) : super(inputs); | 1121 HControlFlow(inputs) : super(inputs); |
| 1078 abstract toString(); | 1122 abstract toString(); |
| 1123 bool isControlFlow() => true; | |
| 1079 } | 1124 } |
| 1080 | 1125 |
| 1081 class HInvoke extends HInstruction { | 1126 class HInvoke extends HInstruction { |
| 1082 /** | 1127 /** |
| 1083 * The first argument must be the target: either an [HStatic] node, or | 1128 * The first argument must be the target: either an [HStatic] node, or |
| 1084 * the receiver of a method-call. The remaining inputs are the arguments | 1129 * the receiver of a method-call. The remaining inputs are the arguments |
| 1085 * to the invocation. | 1130 * to the invocation. |
| 1086 */ | 1131 */ |
| 1087 final Selector selector; | 1132 final Selector selector; |
| 1088 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); | 1133 HInvoke(Selector this.selector, List<HInstruction> inputs) : super(inputs); |
| (...skipping 989 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2078 class HIfBlockInformation { | 2123 class HIfBlockInformation { |
| 2079 final HIf branch; | 2124 final HIf branch; |
| 2080 final SubGraph thenGraph; | 2125 final SubGraph thenGraph; |
| 2081 final SubGraph elseGraph; | 2126 final SubGraph elseGraph; |
| 2082 final HBasicBlock joinBlock; | 2127 final HBasicBlock joinBlock; |
| 2083 HIfBlockInformation(this.branch, | 2128 HIfBlockInformation(this.branch, |
| 2084 this.thenGraph, | 2129 this.thenGraph, |
| 2085 this.elseGraph, | 2130 this.elseGraph, |
| 2086 this.joinBlock); | 2131 this.joinBlock); |
| 2087 } | 2132 } |
| OLD | NEW |