Chromium Code Reviews| Index: lib/compiler/implementation/ssa/nodes.dart |
| diff --git a/lib/compiler/implementation/ssa/nodes.dart b/lib/compiler/implementation/ssa/nodes.dart |
| index b84ddb4dcd280e92c5810067b2ffa8633000041c..0535bef7d9f2ea0055793082546c225f3103021f 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); |
| @@ -299,6 +300,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); |
| @@ -332,7 +334,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; |
| } |
| } |
| @@ -1477,6 +1479,24 @@ 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 succeessor per constant, and one for the default. |
|
floitsch
2012/06/06 11:50:26
successor.
Lasse Reichstein Nielsen
2012/06/06 13:01:21
Done.
|
| + */ |
| +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(); |
|
ngeoffray
2012/06/06 12:03:46
What if the switch does not have a default? Is tha
Lasse Reichstein Nielsen
2012/06/06 13:01:21
It is. Comment added.
|
| + |
| + 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); |
| @@ -2303,6 +2323,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. |
| @@ -2498,3 +2519,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); |
| +} |