| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 abstract class HVisitor<R> { | 7 abstract class HVisitor<R> { |
| 8 R visitAdd(HAdd node); | 8 R visitAdd(HAdd node); |
| 9 R visitBailoutTarget(HBailoutTarget node); | 9 R visitBailoutTarget(HBailoutTarget node); |
| 10 R visitBitAnd(HBitAnd node); | 10 R visitBitAnd(HBitAnd node); |
| 11 R visitBitNot(HBitNot node); | 11 R visitBitNot(HBitNot node); |
| 12 R visitBitOr(HBitOr node); | 12 R visitBitOr(HBitOr node); |
| 13 R visitBitXor(HBitXor node); | 13 R visitBitXor(HBitXor node); |
| 14 R visitBoolify(HBoolify node); | 14 R visitBoolify(HBoolify node); |
| 15 R visitBoundsCheck(HBoundsCheck node); | 15 R visitBoundsCheck(HBoundsCheck node); |
| 16 R visitBreak(HBreak node); | 16 R visitBreak(HBreak node); |
| 17 R visitConstant(HConstant node); | 17 R visitConstant(HConstant node); |
| 18 R visitContinue(HContinue node); | 18 R visitContinue(HContinue node); |
| 19 R visitDivide(HDivide node); | 19 R visitDivide(HDivide node); |
| 20 R visitEquals(HEquals node); | 20 R visitEquals(HEquals node); |
| 21 R visitExit(HExit node); | 21 R visitExit(HExit node); |
| 22 R visitExitTry(HExitTry node); |
| 22 R visitFieldGet(HFieldGet node); | 23 R visitFieldGet(HFieldGet node); |
| 23 R visitFieldSet(HFieldSet node); | 24 R visitFieldSet(HFieldSet node); |
| 24 R visitForeign(HForeign node); | 25 R visitForeign(HForeign node); |
| 25 R visitForeignNew(HForeignNew node); | 26 R visitForeignNew(HForeignNew node); |
| 26 R visitGoto(HGoto node); | 27 R visitGoto(HGoto node); |
| 27 R visitGreater(HGreater node); | 28 R visitGreater(HGreater node); |
| 28 R visitGreaterEqual(HGreaterEqual node); | 29 R visitGreaterEqual(HGreaterEqual node); |
| 29 R visitIdentity(HIdentity node); | 30 R visitIdentity(HIdentity node); |
| 30 R visitIf(HIf node); | 31 R visitIf(HIf node); |
| 31 R visitIndex(HIndex node); | 32 R visitIndex(HIndex node); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 } | 214 } |
| 214 | 215 |
| 215 void assignDominators() { | 216 void assignDominators() { |
| 216 // Run through the blocks in order of increasing ids so we are | 217 // Run through the blocks in order of increasing ids so we are |
| 217 // guaranteed that we have computed dominators for all blocks | 218 // guaranteed that we have computed dominators for all blocks |
| 218 // higher up in the dominator tree. | 219 // higher up in the dominator tree. |
| 219 for (int i = 0, length = blocks.length; i < length; i++) { | 220 for (int i = 0, length = blocks.length; i < length; i++) { |
| 220 HBasicBlock block = blocks[i]; | 221 HBasicBlock block = blocks[i]; |
| 221 List<HBasicBlock> predecessors = block.predecessors; | 222 List<HBasicBlock> predecessors = block.predecessors; |
| 222 if (block.isLoopHeader()) { | 223 if (block.isLoopHeader()) { |
| 223 assert(predecessors.length >= 2); | |
| 224 block.assignCommonDominator(predecessors[0]); | 224 block.assignCommonDominator(predecessors[0]); |
| 225 } else { | 225 } else { |
| 226 for (int j = predecessors.length - 1; j >= 0; j--) { | 226 for (int j = predecessors.length - 1; j >= 0; j--) { |
| 227 block.assignCommonDominator(predecessors[j]); | 227 block.assignCommonDominator(predecessors[j]); |
| 228 } | 228 } |
| 229 } | 229 } |
| 230 } | 230 } |
| 231 } | 231 } |
| 232 | 232 |
| 233 bool isValid() { | 233 bool isValid() { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 272 visitBitXor(HBitXor node) => visitBinaryBitOp(node); | 272 visitBitXor(HBitXor node) => visitBinaryBitOp(node); |
| 273 visitBoolify(HBoolify node) => visitInstruction(node); | 273 visitBoolify(HBoolify node) => visitInstruction(node); |
| 274 visitBoundsCheck(HBoundsCheck node) => visitCheck(node); | 274 visitBoundsCheck(HBoundsCheck node) => visitCheck(node); |
| 275 visitBreak(HBreak node) => visitJump(node); | 275 visitBreak(HBreak node) => visitJump(node); |
| 276 visitContinue(HContinue node) => visitJump(node); | 276 visitContinue(HContinue node) => visitJump(node); |
| 277 visitCheck(HCheck node) => visitInstruction(node); | 277 visitCheck(HCheck node) => visitInstruction(node); |
| 278 visitConstant(HConstant node) => visitInstruction(node); | 278 visitConstant(HConstant node) => visitInstruction(node); |
| 279 visitDivide(HDivide node) => visitBinaryArithmetic(node); | 279 visitDivide(HDivide node) => visitBinaryArithmetic(node); |
| 280 visitEquals(HEquals node) => visitRelational(node); | 280 visitEquals(HEquals node) => visitRelational(node); |
| 281 visitExit(HExit node) => visitControlFlow(node); | 281 visitExit(HExit node) => visitControlFlow(node); |
| 282 visitExitTry(HExitTry node) => visitControlFlow(node); |
| 282 visitFieldGet(HFieldGet node) => visitFieldAccess(node); | 283 visitFieldGet(HFieldGet node) => visitFieldAccess(node); |
| 283 visitFieldSet(HFieldSet node) => visitFieldAccess(node); | 284 visitFieldSet(HFieldSet node) => visitFieldAccess(node); |
| 284 visitForeign(HForeign node) => visitInstruction(node); | 285 visitForeign(HForeign node) => visitInstruction(node); |
| 285 visitForeignNew(HForeignNew node) => visitForeign(node); | 286 visitForeignNew(HForeignNew node) => visitForeign(node); |
| 286 visitGoto(HGoto node) => visitControlFlow(node); | 287 visitGoto(HGoto node) => visitControlFlow(node); |
| 287 visitGreater(HGreater node) => visitRelational(node); | 288 visitGreater(HGreater node) => visitRelational(node); |
| 288 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); | 289 visitGreaterEqual(HGreaterEqual node) => visitRelational(node); |
| 289 visitIdentity(HIdentity node) => visitRelational(node); | 290 visitIdentity(HIdentity node) => visitRelational(node); |
| 290 visitIf(HIf node) => visitConditionalBranch(node); | 291 visitIf(HIf node) => visitConditionalBranch(node); |
| 291 visitIndex(HIndex node) => visitInvokeStatic(node); | 292 visitIndex(HIndex node) => visitInvokeStatic(node); |
| (...skipping 1734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 class HTry extends HControlFlow { | 2027 class HTry extends HControlFlow { |
| 2027 HParameterValue exception; | 2028 HParameterValue exception; |
| 2028 HBasicBlock catchBlock; | 2029 HBasicBlock catchBlock; |
| 2029 HBasicBlock finallyBlock; | 2030 HBasicBlock finallyBlock; |
| 2030 HTry() : super(const <HInstruction>[]); | 2031 HTry() : super(const <HInstruction>[]); |
| 2031 toString() => 'try'; | 2032 toString() => 'try'; |
| 2032 accept(HVisitor visitor) => visitor.visitTry(this); | 2033 accept(HVisitor visitor) => visitor.visitTry(this); |
| 2033 HBasicBlock get joinBlock => this.block.successors.last; | 2034 HBasicBlock get joinBlock => this.block.successors.last; |
| 2034 } | 2035 } |
| 2035 | 2036 |
| 2037 // An [HExitTry] control flow node is used when the body of a try or |
| 2038 // the body of a catch contains a return, break or continue. To build |
| 2039 // the control flow graph, we explicitely mark the body that |
| 2040 // leads to one of this instruction a predecessor of catch and |
| 2041 // finally. |
| 2042 class HExitTry extends HControlFlow { |
| 2043 HExitTry() : super(const <HInstruction>[]); |
| 2044 toString() => 'exit try'; |
| 2045 accept(HVisitor visitor) => visitor.visitExitTry(this); |
| 2046 HBasicBlock get bodyTrySuccessor => block.successors[0]; |
| 2047 } |
| 2048 |
| 2036 class HIf extends HConditionalBranch { | 2049 class HIf extends HConditionalBranch { |
| 2037 HBlockFlow blockInformation = null; | 2050 HBlockFlow blockInformation = null; |
| 2038 HIf(HInstruction condition) : super(<HInstruction>[condition]); | 2051 HIf(HInstruction condition) : super(<HInstruction>[condition]); |
| 2039 toString() => 'if'; | 2052 toString() => 'if'; |
| 2040 accept(HVisitor visitor) => visitor.visitIf(this); | 2053 accept(HVisitor visitor) => visitor.visitIf(this); |
| 2041 | 2054 |
| 2042 HBasicBlock get thenBlock { | 2055 HBasicBlock get thenBlock { |
| 2043 assert(identical(block.dominatedBlocks[0], block.successors[0])); | 2056 assert(identical(block.dominatedBlocks[0], block.successors[0])); |
| 2044 return block.successors[0]; | 2057 return block.successors[0]; |
| 2045 } | 2058 } |
| (...skipping 861 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2907 } | 2920 } |
| 2908 return condition.start; | 2921 return condition.start; |
| 2909 } | 2922 } |
| 2910 | 2923 |
| 2911 HBasicBlock get loopHeader { | 2924 HBasicBlock get loopHeader { |
| 2912 return kind == DO_WHILE_LOOP ? body.start : condition.start; | 2925 return kind == DO_WHILE_LOOP ? body.start : condition.start; |
| 2913 } | 2926 } |
| 2914 | 2927 |
| 2915 HBasicBlock get end { | 2928 HBasicBlock get end { |
| 2916 if (updates != null) return updates.end; | 2929 if (updates != null) return updates.end; |
| 2917 if (kind == DO_WHILE_LOOP) { | 2930 if (kind == DO_WHILE_LOOP && condition != null) { |
| 2918 return condition.end; | 2931 return condition.end; |
| 2919 } | 2932 } |
| 2920 return body.end; | 2933 return body.end; |
| 2921 } | 2934 } |
| 2922 | 2935 |
| 2923 static int loopType(Node node) { | 2936 static int loopType(Node node) { |
| 2924 return node.accept(const LoopTypeVisitor()); | 2937 return node.accept(const LoopTypeVisitor()); |
| 2925 } | 2938 } |
| 2926 | 2939 |
| 2927 bool accept(HStatementInformationVisitor visitor) => | 2940 bool accept(HStatementInformationVisitor visitor) => |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3002 HBasicBlock get start => expression.start; | 3015 HBasicBlock get start => expression.start; |
| 3003 HBasicBlock get end { | 3016 HBasicBlock get end { |
| 3004 // We don't create a switch block if there are no cases. | 3017 // We don't create a switch block if there are no cases. |
| 3005 assert(!statements.isEmpty); | 3018 assert(!statements.isEmpty); |
| 3006 return statements.last.end; | 3019 return statements.last.end; |
| 3007 } | 3020 } |
| 3008 | 3021 |
| 3009 bool accept(HStatementInformationVisitor visitor) => | 3022 bool accept(HStatementInformationVisitor visitor) => |
| 3010 visitor.visitSwitchInfo(this); | 3023 visitor.visitSwitchInfo(this); |
| 3011 } | 3024 } |
| OLD | NEW |