| Index: lib/compiler/implementation/ssa/nodes.dart
|
| diff --git a/lib/compiler/implementation/ssa/nodes.dart b/lib/compiler/implementation/ssa/nodes.dart
|
| index 30134858fcc2127d3aef2a4a40d8191ec159a48e..55c96d3c1c21364ddf6420c1fcd0ba27096f595f 100644
|
| --- a/lib/compiler/implementation/ssa/nodes.dart
|
| +++ b/lib/compiler/implementation/ssa/nodes.dart
|
| @@ -138,11 +138,12 @@ class HGraph {
|
| return result;
|
| }
|
|
|
| - HBasicBlock addNewLoopHeaderBlock(int type,
|
| + HBasicBlock addNewLoopHeaderBlock(int kind,
|
| TargetElement target,
|
| List<LabelElement> labels) {
|
| HBasicBlock result = addNewBlock();
|
| - result.loopInformation = new HLoopInformation(type, result, target, labels);
|
| + result.blockInformation =
|
| + new HLoopInformation(kind, result, target, labels);
|
| return result;
|
| }
|
|
|
| @@ -413,8 +414,7 @@ class HBasicBlock extends HInstructionList implements Hashable {
|
|
|
| HInstructionList phis;
|
|
|
| - HLoopInformation loopInformation = null;
|
| - HLabeledBlockInformation labeledBlockInformation = null;
|
| + HBlockInformation blockInformation = null;
|
| HBasicBlock parentLoopHeader = null;
|
| List<HTypeGuard> guards;
|
|
|
| @@ -438,8 +438,8 @@ class HBasicBlock extends HInstructionList implements Hashable {
|
| bool isOpen() => status == STATUS_OPEN;
|
| bool isClosed() => status == STATUS_CLOSED;
|
|
|
| - bool isLoopHeader() => loopInformation !== null;
|
| - bool hasLabeledBlockInformation() => labeledBlockInformation !== null;
|
| + bool isLoopHeader() => blockInformation is HLoopInformation;
|
| + bool isLabeledBlock() => blockInformation is HLabeledBlockInformation;
|
|
|
| bool hasGuards() => !guards.isEmpty();
|
|
|
| @@ -548,6 +548,7 @@ class HBasicBlock extends HInstructionList implements Hashable {
|
| assert(isLoopHeader());
|
| // Only the first entry into the loop is from outside the
|
| // loop. All other entries must be back edges.
|
| + HLoopInformation loopInformation = this.blockInformation;
|
| for (int i = 1, length = predecessors.length; i < length; i++) {
|
| loopInformation.addBackEdge(predecessors[i]);
|
| }
|
| @@ -655,100 +656,6 @@ class HBasicBlock extends HInstructionList implements Hashable {
|
| }
|
| }
|
|
|
| -interface HBlockInformation {}
|
| -
|
| -class HLabeledBlockInformation implements HBlockInformation {
|
| - final SubGraph body;
|
| - final HBasicBlock joinBlock;
|
| - final List<LabelElement> labels;
|
| - final TargetElement target;
|
| - final bool isContinue;
|
| -
|
| - HLabeledBlockInformation(this.body, this.joinBlock,
|
| - List<LabelElement> labels,
|
| - [this.isContinue = false]) :
|
| - this.labels = labels, this.target = labels[0].target;
|
| -
|
| - HLabeledBlockInformation.implicit(this.body,
|
| - this.joinBlock,
|
| - this.target,
|
| - [this.isContinue = false])
|
| - : this.labels = const<LabelElement>[];
|
| -}
|
| -
|
| -class LoopTypeVisitor extends AbstractVisitor {
|
| - const LoopTypeVisitor();
|
| - int visitNode(Node node) {
|
| - unreachable();
|
| - }
|
| - int visitWhile(While node) => HLoopInformation.WHILE_LOOP;
|
| - int visitFor(For node) => HLoopInformation.FOR_LOOP;
|
| - int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP;
|
| - int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP;
|
| -}
|
| -
|
| -class HLoopInformation implements HBlockInformation {
|
| - static final int WHILE_LOOP = 0;
|
| - static final int FOR_LOOP = 1;
|
| - static final int DO_WHILE_LOOP = 2;
|
| - static final int FOR_IN_LOOP = 3;
|
| -
|
| - final int type;
|
| - final HBasicBlock header;
|
| - final List<HBasicBlock> blocks;
|
| - final List<HBasicBlock> backEdges;
|
| - final List<LabelElement> labels;
|
| - final TargetElement target;
|
| - SubGraph initializer = null;
|
| - SubExpression condition = null;
|
| - SubGraph body = null;
|
| - SubGraph updates = null;
|
| - HBasicBlock joinBlock;
|
| -
|
| - HLoopInformation(this.type, this.header, this.target, this.labels)
|
| - : blocks = new List<HBasicBlock>(),
|
| - backEdges = new List<HBasicBlock>();
|
| -
|
| - static int loopType(Node node) {
|
| - return node.accept(const LoopTypeVisitor());
|
| - }
|
| -
|
| - void addBackEdge(HBasicBlock predecessor) {
|
| - backEdges.add(predecessor);
|
| - addBlock(predecessor);
|
| - }
|
| -
|
| - // Adds a block and transitively all its predecessors in the loop as
|
| - // loop blocks.
|
| - void addBlock(HBasicBlock block) {
|
| - if (block === header) return;
|
| - HBasicBlock parentHeader = block.parentLoopHeader;
|
| - if (parentHeader === header) {
|
| - // Nothing to do in this case.
|
| - } else if (parentHeader !== null) {
|
| - addBlock(parentHeader);
|
| - } else {
|
| - block.parentLoopHeader = header;
|
| - blocks.add(block);
|
| - for (int i = 0, length = block.predecessors.length; i < length; i++) {
|
| - addBlock(block.predecessors[i]);
|
| - }
|
| - }
|
| - }
|
| -
|
| - HBasicBlock getLastBackEdge() {
|
| - int maxId = -1;
|
| - HBasicBlock result = null;
|
| - for (int i = 0, length = backEdges.length; i < length; i++) {
|
| - HBasicBlock current = backEdges[i];
|
| - if (current.id > maxId) {
|
| - maxId = current.id;
|
| - result = current;
|
| - }
|
| - }
|
| - return result;
|
| - }
|
| -}
|
|
|
| class HType {
|
| final int flag;
|
| @@ -909,7 +816,7 @@ class HInstruction implements Hashable {
|
| /**
|
| * Some instructions have a good idea of their return type, but cannot
|
| * guarantee the type. The [likelyType] does not need to be more specialized
|
| - * than the [propagatedType].
|
| + * than the [propagatedType].
|
| *
|
| * Examples: the [likelyType] of [:x == y:] is a boolean. In most cases this
|
| * cannot be guaranteed, but when merging types we still want to use this
|
| @@ -917,8 +824,8 @@ class HInstruction implements Hashable {
|
| *
|
| * Similarily the [HAdd] instruction is likely a number. Note that, even if
|
| * the [propagatedType] is already set to integer, the [likelyType] still
|
| - * might just return the number type.
|
| - */
|
| + * might just return the number type.
|
| + */
|
| HType get likelyType() => propagatedType;
|
|
|
| /**
|
| @@ -2007,7 +1914,7 @@ class HEquals extends HRelational {
|
| if (right.isNumber()) return HType.NUMBER; // No need to be more precise.
|
| // String equality testing is much more common than array equality
|
| // testing.
|
| - if (right.isStringOrArray()) return HType.STRING;
|
| + if (right.isStringOrArray()) return HType.STRING;
|
| return right.propagatedType;
|
| }
|
| // String equality testing is much more common than array equality testing.
|
| @@ -2223,13 +2130,136 @@ class HIs extends HInstruction {
|
| toString() => "$expression is $typeName";
|
| }
|
|
|
| -class HIfBlockInformation {
|
| - final HIf branch;
|
| +
|
| +interface HBlockInformation {
|
| + bool accept(HBlockInformationVisitor visitor);
|
| +}
|
| +
|
| +interface HBlockInformationVisitor {
|
| + bool visitLabeledBlockInfo(HLabeledBlockInformation info);
|
| + bool visitLoopInfo(HLoopInformation info);
|
| + bool visitIfInfo(HIfBlockInformation info);
|
| + bool visitAndOrInfo(HAndOrBlockInformation info);
|
| +}
|
| +
|
| +class HLabeledBlockInformation implements HBlockInformation {
|
| + final SubGraph body;
|
| + final HBasicBlock joinBlock;
|
| + final List<LabelElement> labels;
|
| + final TargetElement target;
|
| + final bool isContinue;
|
| +
|
| + HLabeledBlockInformation(this.body, this.joinBlock,
|
| + List<LabelElement> labels,
|
| + [this.isContinue = false]) :
|
| + this.labels = labels, this.target = labels[0].target;
|
| +
|
| + HLabeledBlockInformation.implicit(this.body,
|
| + this.joinBlock,
|
| + this.target,
|
| + [this.isContinue = false])
|
| + : this.labels = const<LabelElement>[];
|
| +
|
| + bool accept(HBlockInformationVisitor visitor) =>
|
| + visitor.visitLabeledBlockInfo(this);
|
| +}
|
| +
|
| +class LoopTypeVisitor extends AbstractVisitor {
|
| + const LoopTypeVisitor();
|
| + int visitNode(Node node) {
|
| + unreachable();
|
| + }
|
| + int visitWhile(While node) => HLoopInformation.WHILE_LOOP;
|
| + int visitFor(For node) => HLoopInformation.FOR_LOOP;
|
| + int visitDoWhile(DoWhile node) => HLoopInformation.DO_WHILE_LOOP;
|
| + int visitForIn(ForIn node) => HLoopInformation.FOR_IN_LOOP;
|
| +}
|
| +
|
| +class HLoopInformation implements HBlockInformation {
|
| + static final int WHILE_LOOP = 0;
|
| + static final int FOR_LOOP = 1;
|
| + static final int DO_WHILE_LOOP = 2;
|
| + static final int FOR_IN_LOOP = 3;
|
| +
|
| + final int kind;
|
| + final HBasicBlock header;
|
| + final List<HBasicBlock> blocks;
|
| + final List<HBasicBlock> backEdges;
|
| + final List<LabelElement> labels;
|
| + final TargetElement target;
|
| + SubGraph initializer = null;
|
| + SubExpression condition = null;
|
| + SubGraph body = null;
|
| + SubGraph updates = null;
|
| + HBasicBlock joinBlock;
|
| +
|
| + HLoopInformation(this.kind, this.header, this.target, this.labels)
|
| + : blocks = new List<HBasicBlock>(),
|
| + backEdges = new List<HBasicBlock>();
|
| +
|
| + static int loopType(Node node) {
|
| + return node.accept(const LoopTypeVisitor());
|
| + }
|
| +
|
| + void addBackEdge(HBasicBlock predecessor) {
|
| + backEdges.add(predecessor);
|
| + addBlock(predecessor);
|
| + }
|
| +
|
| + // Adds a block and transitively all its predecessors in the loop as
|
| + // loop blocks.
|
| + void addBlock(HBasicBlock block) {
|
| + if (block === header) return;
|
| + HBasicBlock parentHeader = block.parentLoopHeader;
|
| + if (parentHeader === header) {
|
| + // Nothing to do in this case.
|
| + } else if (parentHeader !== null) {
|
| + addBlock(parentHeader);
|
| + } else {
|
| + block.parentLoopHeader = header;
|
| + blocks.add(block);
|
| + for (int i = 0, length = block.predecessors.length; i < length; i++) {
|
| + addBlock(block.predecessors[i]);
|
| + }
|
| + }
|
| + }
|
| +
|
| + HBasicBlock getLastBackEdge() {
|
| + int maxId = -1;
|
| + HBasicBlock result = null;
|
| + for (int i = 0, length = backEdges.length; i < length; i++) {
|
| + HBasicBlock current = backEdges[i];
|
| + if (current.id > maxId) {
|
| + maxId = current.id;
|
| + result = current;
|
| + }
|
| + }
|
| + return result;
|
| + }
|
| +
|
| + bool accept(HBlockInformationVisitor visitor) => visitor.visitLoopInfo(this);
|
| +}
|
| +
|
| +class HIfBlockInformation implements HBlockInformation {
|
| + final SubExpression condition;
|
| final SubGraph thenGraph;
|
| final SubGraph elseGraph;
|
| final HBasicBlock joinBlock;
|
| - HIfBlockInformation(this.branch,
|
| + HIfBlockInformation(this.condition,
|
| this.thenGraph,
|
| this.elseGraph,
|
| this.joinBlock);
|
| + bool accept(HBlockInformationVisitor visitor) => visitor.visitIfInfo(this);
|
| +}
|
| +
|
| +class HAndOrBlockInformation implements HBlockInformation {
|
| + final bool isAnd;
|
| + final SubExpression left;
|
| + final SubExpression right;
|
| + final HBasicBlock joinBlock;
|
| + HAndOrBlockInformation(this.isAnd,
|
| + this.left,
|
| + this.right,
|
| + this.joinBlock);
|
| + bool accept(HBlockInformationVisitor visitor) => visitor.visitAndOrInfo(this);
|
| }
|
|
|