| Index: lib/compiler/implementation/ssa/nodes.dart
|
| diff --git a/lib/compiler/implementation/ssa/nodes.dart b/lib/compiler/implementation/ssa/nodes.dart
|
| index 9d3892177176b578dc11bef7b240514e27d66b69..9c878cc412c20d4eb7e39d1ab4637f4e180bdaf2 100644
|
| --- a/lib/compiler/implementation/ssa/nodes.dart
|
| +++ b/lib/compiler/implementation/ssa/nodes.dart
|
| @@ -52,6 +52,7 @@ interface HVisitor<R> {
|
| R visitStatic(HStatic node);
|
| R visitStaticStore(HStaticStore node);
|
| R visitSubtract(HSubtract node);
|
| + R visitSwitch(HSwitch node);
|
| R visitThis(HThis node);
|
| R visitThrow(HThrow node);
|
| R visitTruncatingDivide(HTruncatingDivide node);
|
| @@ -300,6 +301,7 @@ class HBaseVisitor extends HGraphVisitor implements HVisitor {
|
| visitShiftRight(HShiftRight node) => visitBinaryBitOp(node);
|
| visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node);
|
| visitSubtract(HSubtract node) => visitBinaryArithmetic(node);
|
| + visitSwitch(HSwitch node) => visitControlFlow(node);
|
| visitStatic(HStatic node) => visitInstruction(node);
|
| visitStaticStore(HStaticStore node) => visitInstruction(node);
|
| visitThis(HThis node) => visitParameterValue(node);
|
| @@ -333,7 +335,7 @@ class SubExpression extends SubGraph {
|
| /** Find the condition expression if this sub-expression is a condition. */
|
| HInstruction get conditionExpression() {
|
| HInstruction last = end.last;
|
| - if (last is HConditionalBranch) return last.inputs[0];
|
| + if (last is HConditionalBranch || last is HSwitch) return last.inputs[0];
|
| return null;
|
| }
|
| }
|
| @@ -1478,6 +1480,26 @@ class HSubtract extends HBinaryArithmetic {
|
| bool dataEquals(HInstruction other) => true;
|
| }
|
|
|
| +/**
|
| + * An [HSwitch] instruction has one input for the incoming
|
| + * value, and one input per constant that it can switch on.
|
| + * Its block has one successor per constant, and one for the default.
|
| + * If the switch didn't have a default case, the last successor is
|
| + * the join block.
|
| + */
|
| +class HSwitch extends HControlFlow {
|
| + HSwitch(List<HInstruction> inputs) : super(inputs);
|
| +
|
| + HConstant constant(int index) => inputs[index + 1];
|
| + HInstruction get expression() => inputs[0];
|
| +
|
| + HBasicBlock get defaultTarget() => block.successors.last();
|
| +
|
| + accept(HVisitor visitor) => visitor.visitSwitch(this);
|
| +
|
| + String toString() => "HSwitch cases = $inputs";
|
| +}
|
| +
|
| class HTruncatingDivide extends HBinaryArithmetic {
|
| HTruncatingDivide(HStatic target, HInstruction left, HInstruction right)
|
| : super(target, left, right);
|
| @@ -2308,6 +2330,7 @@ interface HStatementInformationVisitor {
|
| bool visitLoopInfo(HLoopBlockInformation info);
|
| bool visitIfInfo(HIfBlockInformation info);
|
| bool visitTryInfo(HTryBlockInformation info);
|
| + bool visitSwitchInfo(HSwitchBlockInformation info);
|
| bool visitSequenceInfo(HStatementSequenceInformation info);
|
| // Pseudo-structure embedding a dominator-based traversal into
|
| // the block-structure traversal. This will eventually go away.
|
| @@ -2503,3 +2526,33 @@ class HTryBlockInformation implements HStatementInformation {
|
| bool accept(HStatementInformationVisitor visitor) =>
|
| visitor.visitTryInfo(this);
|
| }
|
| +
|
| +
|
| +
|
| +class HSwitchBlockInformation implements HStatementInformation {
|
| + final HExpressionInformation expression;
|
| + final List<List<Constant>> matchExpressions;
|
| + final List<HStatementInformation> statements;
|
| + // If the switch has a default, it's the last statement block, which
|
| + // may or may not have other expresions.
|
| + final bool hasDefault;
|
| + final TargetElement target;
|
| + final List<LabelElement> labels;
|
| +
|
| + HSwitchBlockInformation(this.expression,
|
| + this.matchExpressions,
|
| + this.statements,
|
| + this.hasDefault,
|
| + this.target,
|
| + this.labels);
|
| +
|
| + HBasicBlock get start() => expression.start;
|
| + HBasicBlock get end() {
|
| + // We don't create a switch block if there are no cases.
|
| + assert(!statements.isEmpty());
|
| + return statements.last().end;
|
| + }
|
| +
|
| + bool accept(HStatementInformationVisitor visitor) =>
|
| + visitor.visitSwitchInfo(this);
|
| +}
|
|
|