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 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 type, | 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.loopInformation = new HLoopInformation(type, result, target, labels); | 145 result.blockInformation = |
| 146 new HLoopInformation(type, result, target, labels); |
146 return result; | 147 return result; |
147 } | 148 } |
148 | 149 |
149 static HType mapConstantTypeToSsaType(Constant constant) { | 150 static HType mapConstantTypeToSsaType(Constant constant) { |
150 if (constant.isNull()) return HType.UNKNOWN; | 151 if (constant.isNull()) return HType.UNKNOWN; |
151 if (constant.isBool()) return HType.BOOLEAN; | 152 if (constant.isBool()) return HType.BOOLEAN; |
152 if (constant.isInt()) return HType.INTEGER; | 153 if (constant.isInt()) return HType.INTEGER; |
153 if (constant.isDouble()) return HType.DOUBLE; | 154 if (constant.isDouble()) return HType.DOUBLE; |
154 if (constant.isString()) return HType.STRING; | 155 if (constant.isString()) return HType.STRING; |
155 if (constant.isList()) return HType.READABLE_ARRAY; | 156 if (constant.isList()) return HType.READABLE_ARRAY; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 // this [id]. The exception are back-edges. | 407 // this [id]. The exception are back-edges. |
407 int id; | 408 int id; |
408 | 409 |
409 static final int STATUS_NEW = 0; | 410 static final int STATUS_NEW = 0; |
410 static final int STATUS_OPEN = 1; | 411 static final int STATUS_OPEN = 1; |
411 static final int STATUS_CLOSED = 2; | 412 static final int STATUS_CLOSED = 2; |
412 int status = STATUS_NEW; | 413 int status = STATUS_NEW; |
413 | 414 |
414 HInstructionList phis; | 415 HInstructionList phis; |
415 | 416 |
416 HLoopInformation loopInformation = null; | 417 HBlockInformation blockInformation = 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() => loopInformation !== null; | 441 bool isLoopHeader() => blockInformation is HLoopInformation; |
442 bool hasLabeledBlockInformation() => labeledBlockInformation !== null; | 442 bool isLabeledBlock() => blockInformation is HLabeledBlockInformation; |
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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
539 } else { | 539 } else { |
540 successors.add(block); | 540 successors.add(block); |
541 } | 541 } |
542 block.predecessors.add(this); | 542 block.predecessors.add(this); |
543 } | 543 } |
544 | 544 |
545 void postProcessLoopHeader() { | 545 void postProcessLoopHeader() { |
546 assert(isLoopHeader()); | 546 assert(isLoopHeader()); |
547 // Only the first entry into the loop is from outside the | 547 // Only the first entry into the loop is from outside the |
548 // loop. All other entries must be back edges. | 548 // loop. All other entries must be back edges. |
| 549 HLoopInformation loopInformation = this.blockInformation; |
549 for (int i = 1, length = predecessors.length; i < length; i++) { | 550 for (int i = 1, length = predecessors.length; i < length; i++) { |
550 loopInformation.addBackEdge(predecessors[i]); | 551 loopInformation.addBackEdge(predecessors[i]); |
551 } | 552 } |
552 } | 553 } |
553 | 554 |
554 /** | 555 /** |
555 * Rewrites all uses of the [from] instruction to using the [to] | 556 * Rewrites all uses of the [from] instruction to using the [to] |
556 * instruction instead. | 557 * instruction instead. |
557 */ | 558 */ |
558 void rewrite(HInstruction from, HInstruction to) { | 559 void rewrite(HInstruction from, HInstruction to) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
646 } | 647 } |
647 | 648 |
648 bool isValid() { | 649 bool isValid() { |
649 assert(isClosed()); | 650 assert(isClosed()); |
650 HValidator validator = new HValidator(); | 651 HValidator validator = new HValidator(); |
651 validator.visitBasicBlock(this); | 652 validator.visitBasicBlock(this); |
652 return validator.isValid; | 653 return validator.isValid; |
653 } | 654 } |
654 } | 655 } |
655 | 656 |
656 interface HBlockInformation {} | |
657 | |
658 class HLabeledBlockInformation implements HBlockInformation { | |
659 final SubGraph body; | |
660 final HBasicBlock joinBlock; | |
661 final List<LabelElement> labels; | |
662 final TargetElement target; | |
663 final bool isContinue; | |
664 | |
665 HLabeledBlockInformation(this.body, this.joinBlock, | |
666 List<LabelElement> labels, | |
667 [this.isContinue = false]) : | |
668 this.labels = labels, this.target = labels[0].target; | |
669 | |
670 HLabeledBlockInformation.implicit(this.body, | |
671 this.joinBlock, | |
672 this.target, | |
673 [this.isContinue = false]) | |
674 : this.labels = const<LabelElement>[]; | |
675 } | |
676 | |
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; | |
695 final HBasicBlock header; | |
696 final List<HBasicBlock> blocks; | |
697 final List<HBasicBlock> backEdges; | |
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; | |
705 | |
706 HLoopInformation(this.type, this.header, this.target, this.labels) | |
707 : blocks = new List<HBasicBlock>(), | |
708 backEdges = new List<HBasicBlock>(); | |
709 | |
710 static int loopType(Node node) { | |
711 return node.accept(const LoopTypeVisitor()); | |
712 } | |
713 | |
714 void addBackEdge(HBasicBlock predecessor) { | |
715 backEdges.add(predecessor); | |
716 addBlock(predecessor); | |
717 } | |
718 | |
719 // Adds a block and transitively all its predecessors in the loop as | |
720 // loop blocks. | |
721 void addBlock(HBasicBlock block) { | |
722 if (block === header) return; | |
723 HBasicBlock parentHeader = block.parentLoopHeader; | |
724 if (parentHeader === header) { | |
725 // Nothing to do in this case. | |
726 } else if (parentHeader !== null) { | |
727 addBlock(parentHeader); | |
728 } else { | |
729 block.parentLoopHeader = header; | |
730 blocks.add(block); | |
731 for (int i = 0, length = block.predecessors.length; i < length; i++) { | |
732 addBlock(block.predecessors[i]); | |
733 } | |
734 } | |
735 } | |
736 | |
737 HBasicBlock getLastBackEdge() { | |
738 int maxId = -1; | |
739 HBasicBlock result = null; | |
740 for (int i = 0, length = backEdges.length; i < length; i++) { | |
741 HBasicBlock current = backEdges[i]; | |
742 if (current.id > maxId) { | |
743 maxId = current.id; | |
744 result = current; | |
745 } | |
746 } | |
747 return result; | |
748 } | |
749 } | |
750 | 657 |
751 class HType { | 658 class HType { |
752 final int flag; | 659 final int flag; |
753 const HType(int this.flag); | 660 const HType(int this.flag); |
754 | 661 |
755 static final int FLAG_CONFLICTING = 0; | 662 static final int FLAG_CONFLICTING = 0; |
756 static final int FLAG_UNKNOWN = 1; | 663 static final int FLAG_UNKNOWN = 1; |
757 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; | 664 static final int FLAG_BOOLEAN = FLAG_UNKNOWN << 1; |
758 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; | 665 static final int FLAG_INTEGER = FLAG_BOOLEAN << 1; |
759 static final int FLAG_STRING = FLAG_INTEGER << 1; | 666 static final int FLAG_STRING = FLAG_INTEGER << 1; |
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2089 HInstruction get expression() => inputs[0]; | 1996 HInstruction get expression() => inputs[0]; |
2090 | 1997 |
2091 HType computeType() => HType.BOOLEAN; | 1998 HType computeType() => HType.BOOLEAN; |
2092 bool hasExpectedType() => true; | 1999 bool hasExpectedType() => true; |
2093 | 2000 |
2094 accept(HVisitor visitor) => visitor.visitIs(this); | 2001 accept(HVisitor visitor) => visitor.visitIs(this); |
2095 | 2002 |
2096 toString() => "$expression is $typeExpression"; | 2003 toString() => "$expression is $typeExpression"; |
2097 } | 2004 } |
2098 | 2005 |
2099 class HIfBlockInformation { | 2006 |
2100 final HIf branch; | 2007 interface HBlockInformation { |
| 2008 bool accept(HBlockInformationVisitor visitor); |
| 2009 } |
| 2010 |
| 2011 interface HBlockInformationVisitor { |
| 2012 bool visitLabeledBlockInfo(HLabeledBlockInformation info); |
| 2013 bool visitLoopInfo(HLoopInformation info); |
| 2014 bool visitIfInfo(HIfBlockInformation info); |
| 2015 bool visitAndOrInfo(HAndOrBlockInformation info); |
| 2016 } |
| 2017 |
| 2018 class HLabeledBlockInformation implements HBlockInformation { |
| 2019 final SubGraph body; |
| 2020 final HBasicBlock joinBlock; |
| 2021 final List<LabelElement> labels; |
| 2022 final TargetElement target; |
| 2023 final bool isContinue; |
| 2024 |
| 2025 HLabeledBlockInformation(this.body, this.joinBlock, |
| 2026 List<LabelElement> labels, |
| 2027 [this.isContinue = false]) : |
| 2028 this.labels = labels, this.target = labels[0].target; |
| 2029 |
| 2030 HLabeledBlockInformation.implicit(this.body, |
| 2031 this.joinBlock, |
| 2032 this.target, |
| 2033 [this.isContinue = false]) |
| 2034 : this.labels = const<LabelElement>[]; |
| 2035 |
| 2036 bool accept(HBlockInformationVisitor visitor) => |
| 2037 visitor.visitLabeledBlockInfo(this); |
| 2038 } |
| 2039 |
| 2040 class LoopTypeVisitor extends AbstractVisitor { |
| 2041 const LoopTypeVisitor(); |
| 2042 int visitNode(Node node) { |
| 2043 unreachable(); |
| 2044 } |
| 2045 int visitWhile(While node) => HLoopInformation.WHILE_LOOP; |
| 2046 int visitFor(For node) => HLoopInformation.FOR_LOOP; |
| 2047 int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP; |
| 2048 int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP; |
| 2049 } |
| 2050 |
| 2051 class HLoopInformation implements HBlockInformation { |
| 2052 static final int WHILE_LOOP = 0; |
| 2053 static final int FOR_LOOP = 1; |
| 2054 static final int DO_WHILE_LOOP = 2; |
| 2055 static final int FOR_IN_LOOP = 3; |
| 2056 |
| 2057 final int type; |
| 2058 final HBasicBlock header; |
| 2059 final List<HBasicBlock> blocks; |
| 2060 final List<HBasicBlock> backEdges; |
| 2061 final List<LabelElement> labels; |
| 2062 final TargetElement target; |
| 2063 SubGraph initializer = null; |
| 2064 SubExpression condition = null; |
| 2065 SubGraph body = null; |
| 2066 SubGraph updates = null; |
| 2067 HBasicBlock joinBlock; |
| 2068 |
| 2069 HLoopInformation(this.type, this.header, this.target, this.labels) |
| 2070 : blocks = new List<HBasicBlock>(), |
| 2071 backEdges = new List<HBasicBlock>(); |
| 2072 |
| 2073 static int loopType(Node node) { |
| 2074 return node.accept(const LoopTypeVisitor()); |
| 2075 } |
| 2076 |
| 2077 void addBackEdge(HBasicBlock predecessor) { |
| 2078 backEdges.add(predecessor); |
| 2079 addBlock(predecessor); |
| 2080 } |
| 2081 |
| 2082 // Adds a block and transitively all its predecessors in the loop as |
| 2083 // loop blocks. |
| 2084 void addBlock(HBasicBlock block) { |
| 2085 if (block === header) return; |
| 2086 HBasicBlock parentHeader = block.parentLoopHeader; |
| 2087 if (parentHeader === header) { |
| 2088 // Nothing to do in this case. |
| 2089 } else if (parentHeader !== null) { |
| 2090 addBlock(parentHeader); |
| 2091 } else { |
| 2092 block.parentLoopHeader = header; |
| 2093 blocks.add(block); |
| 2094 for (int i = 0, length = block.predecessors.length; i < length; i++) { |
| 2095 addBlock(block.predecessors[i]); |
| 2096 } |
| 2097 } |
| 2098 } |
| 2099 |
| 2100 HBasicBlock getLastBackEdge() { |
| 2101 int maxId = -1; |
| 2102 HBasicBlock result = null; |
| 2103 for (int i = 0, length = backEdges.length; i < length; i++) { |
| 2104 HBasicBlock current = backEdges[i]; |
| 2105 if (current.id > maxId) { |
| 2106 maxId = current.id; |
| 2107 result = current; |
| 2108 } |
| 2109 } |
| 2110 return result; |
| 2111 } |
| 2112 |
| 2113 bool accept(HBlockInformationVisitor visitor) => visitor.visitLoopInfo(this); |
| 2114 } |
| 2115 |
| 2116 class HIfBlockInformation implements HBlockInformation { |
| 2117 final SubExpression condition; |
2101 final SubGraph thenGraph; | 2118 final SubGraph thenGraph; |
2102 final SubGraph elseGraph; | 2119 final SubGraph elseGraph; |
2103 final HBasicBlock joinBlock; | 2120 final HBasicBlock joinBlock; |
2104 HIfBlockInformation(this.branch, | 2121 HIfBlockInformation(this.condition, |
2105 this.thenGraph, | 2122 this.thenGraph, |
2106 this.elseGraph, | 2123 this.elseGraph, |
2107 this.joinBlock); | 2124 this.joinBlock); |
| 2125 bool accept(HBlockInformationVisitor visitor) => visitor.visitIfInfo(this); |
2108 } | 2126 } |
| 2127 |
| 2128 class HAndOrBlockInformation implements HBlockInformation { |
| 2129 final bool isAnd; |
| 2130 final SubExpression left; |
| 2131 final SubExpression right; |
| 2132 final HBasicBlock joinBlock; |
| 2133 HAndOrBlockInformation(this.isAnd, |
| 2134 this.left, |
| 2135 this.right, |
| 2136 this.joinBlock); |
| 2137 bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this); |
| 2138 } |
OLD | NEW |