Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: frog/leg/ssa/nodes.dart

Issue 9863037: Generate prettier loops. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Address review comments. Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « frog/leg/ssa/codegen.dart ('k') | frog/leg/tree/nodes.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « frog/leg/ssa/codegen.dart ('k') | frog/leg/tree/nodes.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698