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

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: Created 8 years, 9 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
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 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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698