Chromium Code Reviews| Index: frog/leg/ssa/nodes.dart |
| diff --git a/frog/leg/ssa/nodes.dart b/frog/leg/ssa/nodes.dart |
| index e73473a3470272d4e7227e01f8551cf20d545311..09d7251ac06a655bf1b6095396f331f508ca6f26 100644 |
| --- a/frog/leg/ssa/nodes.dart |
| +++ b/frog/leg/ssa/nodes.dart |
| @@ -138,9 +138,11 @@ class HGraph { |
| return result; |
| } |
| - HBasicBlock addNewLoopHeaderBlock(List<LabelElement> labels) { |
| + HBasicBlock addNewLoopHeaderBlock(int type, |
| + TargetElement target, |
| + List<LabelElement> labels) { |
| HBasicBlock result = addNewBlock(); |
| - result.loopInformation = new HLoopInformation(result, labels); |
| + result.loopInformation = new HLoopInformation(type, result, target, labels); |
| return result; |
| } |
| @@ -320,6 +322,12 @@ class SubGraph { |
| } |
| } |
| +class SubExpression extends SubGraph { |
| + final HInstruction expression; |
| + const SubExpression(HBasicBlock start, HBasicBlock end, this.expression) |
| + : super(start, end); |
| +} |
| + |
| class HInstructionList { |
| HInstruction first = null; |
| HInstruction last = null; |
| @@ -645,7 +653,9 @@ class HBasicBlock extends HInstructionList implements Hashable { |
| } |
| } |
| -class HLabeledBlockInformation { |
| +interface HBlockInformation {} |
| + |
| +class HLabeledBlockInformation implements HBlockInformation { |
| final SubGraph body; |
| final HBasicBlock joinBlock; |
| final List<LabelElement> labels; |
| @@ -664,16 +674,43 @@ class HLabeledBlockInformation { |
| : this.labels = const<LabelElement>[]; |
| } |
| -class HLoopInformation { |
| +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.header, this.labels) |
| + 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); |
| @@ -806,6 +843,8 @@ class HInstruction implements Hashable { |
| bool useGvn() => getFlag(FLAG_USE_GVN); |
| void setUseGvn() { setFlag(FLAG_USE_GVN); } |
| + // Does this node pNotentially affect control flow. |
| + bool isControlFlow() => false; |
| bool isArray() => type.isArray(); |
| bool isBoolean() => type.isBoolean(); |
| @@ -989,6 +1028,8 @@ class HCheck extends HInstruction { |
| // TODO(floitsch): make class abstract instead of adding an abstract method. |
| abstract accept(HVisitor visitor); |
| + |
| + bool isControlFlow() => true; |
| } |
| class HTypeGuard extends HInstruction { |
| @@ -1005,6 +1046,8 @@ class HTypeGuard extends HInstruction { |
| HType computeType() => type; |
| bool hasExpectedType() => true; |
| + bool isControlFlow() => true; |
| + |
| accept(HVisitor visitor) => visitor.visitTypeGuard(this); |
| int typeCode() => 1; |
| bool typeEquals(other) => other is HTypeGuard; |
| @@ -1063,6 +1106,7 @@ class HConditionalBranch extends HControlFlow { |
| class HControlFlow extends HInstruction { |
| HControlFlow(inputs) : super(inputs); |
| abstract toString(); |
| + bool isControlFlow() => true; |
| } |
| class HInvoke extends HInstruction { |
| @@ -1177,7 +1221,7 @@ class HInvokeInterceptor extends HInvokeStatic { |
| toString() => 'invoke interceptor: ${element.name}'; |
| accept(HVisitor visitor) => visitor.visitInvokeInterceptor(this); |
| - |
| + |
| String get builtinJsName() { |
| if (getter |
| && name == const SourceString('length') |
| @@ -1954,7 +1998,9 @@ class HThrow extends HControlFlow { |
| class HStatic extends HInstruction { |
| Element element; |
| - HStatic(this.element) : super(<HInstruction>[]); |
| + HStatic(this.element) : super(<HInstruction>[]) { |
| + if (element === null) throw "WHAT?!?"; |
|
floitsch
2012/03/29 21:44:11
debug?
Lasse Reichstein Nielsen
2012/03/30 09:37:17
Done.
|
| + } |
| void prepareGvn() { |
| if (!element.isAssignable()) { |