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

Side by Side Diff: lib/compiler/implementation/ssa/nodes.dart

Issue 9956172: Revert "Refactoring if block-information." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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
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(int kind, 141 HBasicBlock addNewLoopHeaderBlock(int type,
142 TargetElement target, 142 TargetElement target,
143 List<LabelElement> labels) { 143 List<LabelElement> labels) {
144 HBasicBlock result = addNewBlock(); 144 HBasicBlock result = addNewBlock();
145 result.blockInformation = 145 result.loopInformation = new HLoopInformation(type, result, target, labels);
146 new HLoopInformation(kind, result, target, labels);
147 return result; 146 return result;
148 } 147 }
149 148
150 static HType mapConstantTypeToSsaType(Constant constant) { 149 static HType mapConstantTypeToSsaType(Constant constant) {
151 if (constant.isNull()) return HType.UNKNOWN; 150 if (constant.isNull()) return HType.UNKNOWN;
152 if (constant.isBool()) return HType.BOOLEAN; 151 if (constant.isBool()) return HType.BOOLEAN;
153 if (constant.isInt()) return HType.INTEGER; 152 if (constant.isInt()) return HType.INTEGER;
154 if (constant.isDouble()) return HType.DOUBLE; 153 if (constant.isDouble()) return HType.DOUBLE;
155 if (constant.isString()) return HType.STRING; 154 if (constant.isString()) return HType.STRING;
156 if (constant.isList()) return HType.READABLE_ARRAY; 155 if (constant.isList()) return HType.READABLE_ARRAY;
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
407 // this [id]. The exception are back-edges. 406 // this [id]. The exception are back-edges.
408 int id; 407 int id;
409 408
410 static final int STATUS_NEW = 0; 409 static final int STATUS_NEW = 0;
411 static final int STATUS_OPEN = 1; 410 static final int STATUS_OPEN = 1;
412 static final int STATUS_CLOSED = 2; 411 static final int STATUS_CLOSED = 2;
413 int status = STATUS_NEW; 412 int status = STATUS_NEW;
414 413
415 HInstructionList phis; 414 HInstructionList phis;
416 415
417 HBlockInformation blockInformation = null; 416 HLoopInformation loopInformation = null;
417 HLabeledBlockInformation labeledBlockInformation = null;
418 HBasicBlock parentLoopHeader = null; 418 HBasicBlock parentLoopHeader = null;
419 List<HTypeGuard> guards; 419 List<HTypeGuard> guards;
420 420
421 final List<HBasicBlock> predecessors; 421 final List<HBasicBlock> predecessors;
422 List<HBasicBlock> successors; 422 List<HBasicBlock> successors;
423 423
424 HBasicBlock dominator = null; 424 HBasicBlock dominator = null;
425 final List<HBasicBlock> dominatedBlocks; 425 final List<HBasicBlock> dominatedBlocks;
426 426
427 HBasicBlock() : this.withId(null); 427 HBasicBlock() : this.withId(null);
428 HBasicBlock.withId(this.id) 428 HBasicBlock.withId(this.id)
429 : phis = new HInstructionList(), 429 : phis = new HInstructionList(),
430 predecessors = <HBasicBlock>[], 430 predecessors = <HBasicBlock>[],
431 successors = const <HBasicBlock>[], 431 successors = const <HBasicBlock>[],
432 dominatedBlocks = <HBasicBlock>[], 432 dominatedBlocks = <HBasicBlock>[],
433 guards = <HTypeGuard>[]; 433 guards = <HTypeGuard>[];
434 434
435 int hashCode() => id; 435 int hashCode() => id;
436 436
437 bool isNew() => status == STATUS_NEW; 437 bool isNew() => status == STATUS_NEW;
438 bool isOpen() => status == STATUS_OPEN; 438 bool isOpen() => status == STATUS_OPEN;
439 bool isClosed() => status == STATUS_CLOSED; 439 bool isClosed() => status == STATUS_CLOSED;
440 440
441 bool isLoopHeader() => blockInformation is HLoopInformation; 441 bool isLoopHeader() => loopInformation !== null;
442 bool isLabeledBlock() => blockInformation is HLabeledBlockInformation; 442 bool hasLabeledBlockInformation() => labeledBlockInformation !== null;
443 443
444 bool hasGuards() => !guards.isEmpty(); 444 bool hasGuards() => !guards.isEmpty();
445 445
446 void open() { 446 void open() {
447 assert(isNew()); 447 assert(isNew());
448 status = STATUS_OPEN; 448 status = STATUS_OPEN;
449 } 449 }
450 450
451 void close(HControlFlow end) { 451 void close(HControlFlow end) {
452 assert(isOpen()); 452 assert(isOpen());
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 } else { 541 } else {
542 successors.add(block); 542 successors.add(block);
543 } 543 }
544 block.predecessors.add(this); 544 block.predecessors.add(this);
545 } 545 }
546 546
547 void postProcessLoopHeader() { 547 void postProcessLoopHeader() {
548 assert(isLoopHeader()); 548 assert(isLoopHeader());
549 // Only the first entry into the loop is from outside the 549 // Only the first entry into the loop is from outside the
550 // loop. All other entries must be back edges. 550 // loop. All other entries must be back edges.
551 HLoopInformation loopInformation = this.blockInformation;
552 for (int i = 1, length = predecessors.length; i < length; i++) { 551 for (int i = 1, length = predecessors.length; i < length; i++) {
553 loopInformation.addBackEdge(predecessors[i]); 552 loopInformation.addBackEdge(predecessors[i]);
554 } 553 }
555 } 554 }
556 555
557 /** 556 /**
558 * Rewrites all uses of the [from] instruction to using the [to] 557 * Rewrites all uses of the [from] instruction to using the [to]
559 * instruction instead. 558 * instruction instead.
560 */ 559 */
561 void rewrite(HInstruction from, HInstruction to) { 560 void rewrite(HInstruction from, HInstruction to) {
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 } 648 }
650 649
651 bool isValid() { 650 bool isValid() {
652 assert(isClosed()); 651 assert(isClosed());
653 HValidator validator = new HValidator(); 652 HValidator validator = new HValidator();
654 validator.visitBasicBlock(this); 653 validator.visitBasicBlock(this);
655 return validator.isValid; 654 return validator.isValid;
656 } 655 }
657 } 656 }
658 657
658 interface HBlockInformation {}
659
660 class HLabeledBlockInformation implements HBlockInformation {
661 final SubGraph body;
662 final HBasicBlock joinBlock;
663 final List<LabelElement> labels;
664 final TargetElement target;
665 final bool isContinue;
666
667 HLabeledBlockInformation(this.body, this.joinBlock,
668 List<LabelElement> labels,
669 [this.isContinue = false]) :
670 this.labels = labels, this.target = labels[0].target;
671
672 HLabeledBlockInformation.implicit(this.body,
673 this.joinBlock,
674 this.target,
675 [this.isContinue = false])
676 : this.labels = const<LabelElement>[];
677 }
678
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;
697 final HBasicBlock header;
698 final List<HBasicBlock> blocks;
699 final List<HBasicBlock> backEdges;
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;
707
708 HLoopInformation(this.type, this.header, this.target, this.labels)
709 : blocks = new List<HBasicBlock>(),
710 backEdges = new List<HBasicBlock>();
711
712 static int loopType(Node node) {
713 return node.accept(const LoopTypeVisitor());
714 }
715
716 void addBackEdge(HBasicBlock predecessor) {
717 backEdges.add(predecessor);
718 addBlock(predecessor);
719 }
720
721 // Adds a block and transitively all its predecessors in the loop as
722 // loop blocks.
723 void addBlock(HBasicBlock block) {
724 if (block === header) return;
725 HBasicBlock parentHeader = block.parentLoopHeader;
726 if (parentHeader === header) {
727 // Nothing to do in this case.
728 } else if (parentHeader !== null) {
729 addBlock(parentHeader);
730 } else {
731 block.parentLoopHeader = header;
732 blocks.add(block);
733 for (int i = 0, length = block.predecessors.length; i < length; i++) {
734 addBlock(block.predecessors[i]);
735 }
736 }
737 }
738
739 HBasicBlock getLastBackEdge() {
740 int maxId = -1;
741 HBasicBlock result = null;
742 for (int i = 0, length = backEdges.length; i < length; i++) {
743 HBasicBlock current = backEdges[i];
744 if (current.id > maxId) {
745 maxId = current.id;
746 result = current;
747 }
748 }
749 return result;
750 }
751 }
659 752
660 class HType { 753 class HType {
661 final int flag; 754 final int flag;
662 const HType(int this.flag); 755 const HType(int this.flag);
663 756
664 static final int FLAG_CONFLICTING = 0; 757 static final int FLAG_CONFLICTING = 0;
665 static final int FLAG_UNKNOWN = 1; 758 static final int FLAG_UNKNOWN = 1;
666 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; 759 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1;
667 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; 760 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1;
668 static final int FLAG_STRING = FLAG_INTEGER << 1; 761 static final int FLAG_STRING = FLAG_INTEGER << 1;
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
809 * 902 *
810 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with 903 * Note that the [propagatedType] may only be set to [HType.CONFLICTING] with
811 * speculative types (as otherwise the instruction either sets the output 904 * speculative types (as otherwise the instruction either sets the output
812 * type to [HType.UNKNOWN] or a specific type. 905 * type to [HType.UNKNOWN] or a specific type.
813 */ 906 */
814 HType propagatedType = HType.UNKNOWN; 907 HType propagatedType = HType.UNKNOWN;
815 908
816 /** 909 /**
817 * Some instructions have a good idea of their return type, but cannot 910 * Some instructions have a good idea of their return type, but cannot
818 * guarantee the type. The [likelyType] does not need to be more specialized 911 * guarantee the type. The [likelyType] does not need to be more specialized
819 * than the [propagatedType]. 912 * than the [propagatedType].
820 * 913 *
821 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this 914 * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this
822 * cannot be guaranteed, but when merging types we still want to use this 915 * cannot be guaranteed, but when merging types we still want to use this
823 * information. 916 * information.
824 * 917 *
825 * Similarily the [HAdd] instruction is likely a number. Note that, even if 918 * Similarily the [HAdd] instruction is likely a number. Note that, even if
826 * the [propagatedType] is already set to integer, the [likelyType] still 919 * the [propagatedType] is already set to integer, the [likelyType] still
827 * might just return the number type. 920 * might just return the number type.
828 */ 921 */
829 HType get likelyType() => propagatedType; 922 HType get likelyType() => propagatedType;
830 923
831 /** 924 /**
832 * Compute the type of the instruction by propagating the input types through 925 * Compute the type of the instruction by propagating the input types through
833 * the instruction. 926 * the instruction.
834 * 927 *
835 * By default just copy the guaranteed type. 928 * By default just copy the guaranteed type.
836 */ 929 */
837 HType computeTypeFromInputTypes() => guaranteedType; 930 HType computeTypeFromInputTypes() => guaranteedType;
838 931
(...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 2000
1908 HType computeDesiredTypeForNonTargetInput(HInstruction input) { 2001 HType computeDesiredTypeForNonTargetInput(HInstruction input) {
1909 if (input == left && right.propagatedType.isUseful()) { 2002 if (input == left && right.propagatedType.isUseful()) {
1910 // All our useful types have === semantics. But we don't want to 2003 // All our useful types have === semantics. But we don't want to
1911 // speculatively test for all possible types. Therefore we try to match 2004 // speculatively test for all possible types. Therefore we try to match
1912 // the two types. That is, if we see x == 3, then we speculatively test 2005 // the two types. That is, if we see x == 3, then we speculatively test
1913 // if x is a number and bailout if it isn't. 2006 // if x is a number and bailout if it isn't.
1914 if (right.isNumber()) return HType.NUMBER; // No need to be more precise. 2007 if (right.isNumber()) return HType.NUMBER; // No need to be more precise.
1915 // String equality testing is much more common than array equality 2008 // String equality testing is much more common than array equality
1916 // testing. 2009 // testing.
1917 if (right.isStringOrArray()) return HType.STRING; 2010 if (right.isStringOrArray()) return HType.STRING;
1918 return right.propagatedType; 2011 return right.propagatedType;
1919 } 2012 }
1920 // String equality testing is much more common than array equality testing. 2013 // String equality testing is much more common than array equality testing.
1921 if (input == left && left.isStringOrArray()) { 2014 if (input == left && left.isStringOrArray()) {
1922 return HType.READABLE_ARRAY; 2015 return HType.READABLE_ARRAY;
1923 } 2016 }
1924 // String equality testing is much more common than array equality testing. 2017 // String equality testing is much more common than array equality testing.
1925 if (input == right && right.isStringOrArray()) { 2018 if (input == right && right.isStringOrArray()) {
1926 return HType.STRING; 2019 return HType.STRING;
1927 } 2020 }
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2123 2216
2124 HInstruction get expression() => inputs[0]; 2217 HInstruction get expression() => inputs[0];
2125 2218
2126 HType get guaranteedType() => HType.BOOLEAN; 2219 HType get guaranteedType() => HType.BOOLEAN;
2127 2220
2128 accept(HVisitor visitor) => visitor.visitIs(this); 2221 accept(HVisitor visitor) => visitor.visitIs(this);
2129 2222
2130 toString() => "$expression is $typeName"; 2223 toString() => "$expression is $typeName";
2131 } 2224 }
2132 2225
2133 2226 class HIfBlockInformation {
2134 interface HBlockInformation { 2227 final HIf branch;
2135 bool accept(HBlockInformationVisitor visitor);
2136 }
2137
2138 interface HBlockInformationVisitor {
2139 bool visitLabeledBlockInfo(HLabeledBlockInformation info);
2140 bool visitLoopInfo(HLoopInformation info);
2141 bool visitIfInfo(HIfBlockInformation info);
2142 bool visitAndOrInfo(HAndOrBlockInformation info);
2143 }
2144
2145 class HLabeledBlockInformation implements HBlockInformation {
2146 final SubGraph body;
2147 final HBasicBlock joinBlock;
2148 final List<LabelElement> labels;
2149 final TargetElement target;
2150 final bool isContinue;
2151
2152 HLabeledBlockInformation(this.body, this.joinBlock,
2153 List<LabelElement> labels,
2154 [this.isContinue = false]) :
2155 this.labels = labels, this.target = labels[0].target;
2156
2157 HLabeledBlockInformation.implicit(this.body,
2158 this.joinBlock,
2159 this.target,
2160 [this.isContinue = false])
2161 : this.labels = const<LabelElement>[];
2162
2163 bool accept(HBlockInformationVisitor visitor) =>
2164 visitor.visitLabeledBlockInfo(this);
2165 }
2166
2167 class LoopTypeVisitor extends AbstractVisitor {
2168 const LoopTypeVisitor();
2169 int visitNode(Node node) {
2170 unreachable();
2171 }
2172 int visitWhile(While node) => HLoopInformation.WHILE_LOOP;
2173 int visitFor(For node) => HLoopInformation.FOR_LOOP;
2174 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP;
2175 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP;
2176 }
2177
2178 class HLoopInformation implements HBlockInformation {
2179 static final int WHILE_LOOP = 0;
2180 static final int FOR_LOOP = 1;
2181 static final int DO_WHILE_LOOP = 2;
2182 static final int FOR_IN_LOOP = 3;
2183
2184 final int kind;
2185 final HBasicBlock header;
2186 final List<HBasicBlock> blocks;
2187 final List<HBasicBlock> backEdges;
2188 final List<LabelElement> labels;
2189 final TargetElement target;
2190 SubGraph initializer = null;
2191 SubExpression condition = null;
2192 SubGraph body = null;
2193 SubGraph updates = null;
2194 HBasicBlock joinBlock;
2195
2196 HLoopInformation(this.kind, this.header, this.target, this.labels)
2197 : blocks = new List<HBasicBlock>(),
2198 backEdges = new List<HBasicBlock>();
2199
2200 static int loopType(Node node) {
2201 return node.accept(const LoopTypeVisitor());
2202 }
2203
2204 void addBackEdge(HBasicBlock predecessor) {
2205 backEdges.add(predecessor);
2206 addBlock(predecessor);
2207 }
2208
2209 // Adds a block and transitively all its predecessors in the loop as
2210 // loop blocks.
2211 void addBlock(HBasicBlock block) {
2212 if (block === header) return;
2213 HBasicBlock parentHeader = block.parentLoopHeader;
2214 if (parentHeader === header) {
2215 // Nothing to do in this case.
2216 } else if (parentHeader !== null) {
2217 addBlock(parentHeader);
2218 } else {
2219 block.parentLoopHeader = header;
2220 blocks.add(block);
2221 for (int i = 0, length = block.predecessors.length; i < length; i++) {
2222 addBlock(block.predecessors[i]);
2223 }
2224 }
2225 }
2226
2227 HBasicBlock getLastBackEdge() {
2228 int maxId = -1;
2229 HBasicBlock result = null;
2230 for (int i = 0, length = backEdges.length; i < length; i++) {
2231 HBasicBlock current = backEdges[i];
2232 if (current.id > maxId) {
2233 maxId = current.id;
2234 result = current;
2235 }
2236 }
2237 return result;
2238 }
2239
2240 bool accept(HBlockInformationVisitor visitor) => visitor.visitLoopInfo(this);
2241 }
2242
2243 class HIfBlockInformation implements HBlockInformation {
2244 final SubExpression condition;
2245 final SubGraph thenGraph; 2228 final SubGraph thenGraph;
2246 final SubGraph elseGraph; 2229 final SubGraph elseGraph;
2247 final HBasicBlock joinBlock; 2230 final HBasicBlock joinBlock;
2248 HIfBlockInformation(this.condition, 2231 HIfBlockInformation(this.branch,
2249 this.thenGraph, 2232 this.thenGraph,
2250 this.elseGraph, 2233 this.elseGraph,
2251 this.joinBlock); 2234 this.joinBlock);
2252 bool accept(HBlockInformationVisitor visitor) => visitor.visitIfInfo(this);
2253 } 2235 }
2254
2255 class HAndOrBlockInformation implements HBlockInformation {
2256 final bool isAnd;
2257 final SubExpression left;
2258 final SubExpression right;
2259 final HBasicBlock joinBlock;
2260 HAndOrBlockInformation(this.isAnd,
2261 this.left,
2262 this.right,
2263 this.joinBlock);
2264 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this);
2265 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/codegen.dart ('k') | lib/compiler/implementation/ssa/optimize.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698