OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 interface HVisitor<R> { | 5 interface HVisitor<R> { |
6 R visitAdd(HAdd node); | 6 R visitAdd(HAdd node); |
7 R visitBitAnd(HBitAnd node); | 7 R visitBitAnd(HBitAnd node); |
8 R visitBitNot(HBitNot node); | 8 R visitBitNot(HBitNot node); |
9 R visitBitOr(HBitOr node); | 9 R visitBitOr(HBitOr node); |
10 R visitBitXor(HBitXor node); | 10 R visitBitXor(HBitXor node); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
45 R visitNegate(HNegate node); | 45 R visitNegate(HNegate node); |
46 R visitNot(HNot node); | 46 R visitNot(HNot node); |
47 R visitParameterValue(HParameterValue node); | 47 R visitParameterValue(HParameterValue node); |
48 R visitPhi(HPhi node); | 48 R visitPhi(HPhi node); |
49 R visitReturn(HReturn node); | 49 R visitReturn(HReturn node); |
50 R visitShiftLeft(HShiftLeft node); | 50 R visitShiftLeft(HShiftLeft node); |
51 R visitShiftRight(HShiftRight node); | 51 R visitShiftRight(HShiftRight node); |
52 R visitStatic(HStatic node); | 52 R visitStatic(HStatic node); |
53 R visitStaticStore(HStaticStore node); | 53 R visitStaticStore(HStaticStore node); |
54 R visitSubtract(HSubtract node); | 54 R visitSubtract(HSubtract node); |
| 55 R visitSwitch(HSwitch node); |
55 R visitThis(HThis node); | 56 R visitThis(HThis node); |
56 R visitThrow(HThrow node); | 57 R visitThrow(HThrow node); |
57 R visitTruncatingDivide(HTruncatingDivide node); | 58 R visitTruncatingDivide(HTruncatingDivide node); |
58 R visitTry(HTry node); | 59 R visitTry(HTry node); |
59 R visitTypeGuard(HTypeGuard node); | 60 R visitTypeGuard(HTypeGuard node); |
60 R visitTypeConversion(HTypeConversion node); | 61 R visitTypeConversion(HTypeConversion node); |
61 } | 62 } |
62 | 63 |
63 class HGraphVisitor { | 64 class HGraphVisitor { |
64 visitDominatorTree(HGraph graph) { | 65 visitDominatorTree(HGraph graph) { |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
293 visitModulo(HModulo node) => visitBinaryArithmetic(node); | 294 visitModulo(HModulo node) => visitBinaryArithmetic(node); |
294 visitNegate(HNegate node) => visitInvokeUnary(node); | 295 visitNegate(HNegate node) => visitInvokeUnary(node); |
295 visitNot(HNot node) => visitInstruction(node); | 296 visitNot(HNot node) => visitInstruction(node); |
296 visitPhi(HPhi node) => visitInstruction(node); | 297 visitPhi(HPhi node) => visitInstruction(node); |
297 visitMultiply(HMultiply node) => visitBinaryArithmetic(node); | 298 visitMultiply(HMultiply node) => visitBinaryArithmetic(node); |
298 visitParameterValue(HParameterValue node) => visitInstruction(node); | 299 visitParameterValue(HParameterValue node) => visitInstruction(node); |
299 visitReturn(HReturn node) => visitControlFlow(node); | 300 visitReturn(HReturn node) => visitControlFlow(node); |
300 visitShiftRight(HShiftRight node) => visitBinaryBitOp(node); | 301 visitShiftRight(HShiftRight node) => visitBinaryBitOp(node); |
301 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node); | 302 visitShiftLeft(HShiftLeft node) => visitBinaryBitOp(node); |
302 visitSubtract(HSubtract node) => visitBinaryArithmetic(node); | 303 visitSubtract(HSubtract node) => visitBinaryArithmetic(node); |
| 304 visitSwitch(HSwitch node) => visitControlFlow(node); |
303 visitStatic(HStatic node) => visitInstruction(node); | 305 visitStatic(HStatic node) => visitInstruction(node); |
304 visitStaticStore(HStaticStore node) => visitInstruction(node); | 306 visitStaticStore(HStaticStore node) => visitInstruction(node); |
305 visitThis(HThis node) => visitParameterValue(node); | 307 visitThis(HThis node) => visitParameterValue(node); |
306 visitThrow(HThrow node) => visitControlFlow(node); | 308 visitThrow(HThrow node) => visitControlFlow(node); |
307 visitTry(HTry node) => visitControlFlow(node); | 309 visitTry(HTry node) => visitControlFlow(node); |
308 visitTruncatingDivide(HTruncatingDivide node) => visitBinaryArithmetic(node); | 310 visitTruncatingDivide(HTruncatingDivide node) => visitBinaryArithmetic(node); |
309 visitTypeGuard(HTypeGuard node) => visitCheck(node); | 311 visitTypeGuard(HTypeGuard node) => visitCheck(node); |
310 visitIs(HIs node) => visitInstruction(node); | 312 visitIs(HIs node) => visitInstruction(node); |
311 visitTypeConversion(HTypeConversion node) => visitCheck(node); | 313 visitTypeConversion(HTypeConversion node) => visitCheck(node); |
312 } | 314 } |
(...skipping 13 matching lines...) Expand all Loading... |
326 } | 328 } |
327 } | 329 } |
328 | 330 |
329 class SubExpression extends SubGraph { | 331 class SubExpression extends SubGraph { |
330 const SubExpression(HBasicBlock start, HBasicBlock end) | 332 const SubExpression(HBasicBlock start, HBasicBlock end) |
331 : super(start, end); | 333 : super(start, end); |
332 | 334 |
333 /** Find the condition expression if this sub-expression is a condition. */ | 335 /** Find the condition expression if this sub-expression is a condition. */ |
334 HInstruction get conditionExpression() { | 336 HInstruction get conditionExpression() { |
335 HInstruction last = end.last; | 337 HInstruction last = end.last; |
336 if (last is HConditionalBranch) return last.inputs[0]; | 338 if (last is HConditionalBranch || last is HSwitch) return last.inputs[0]; |
337 return null; | 339 return null; |
338 } | 340 } |
339 } | 341 } |
340 | 342 |
341 class HInstructionList { | 343 class HInstructionList { |
342 HInstruction first = null; | 344 HInstruction first = null; |
343 HInstruction last = null; | 345 HInstruction last = null; |
344 | 346 |
345 bool isEmpty() { | 347 bool isEmpty() { |
346 return first === null; | 348 return first === null; |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1471 HSubtract(HStatic target, HInstruction left, HInstruction right) | 1473 HSubtract(HStatic target, HInstruction left, HInstruction right) |
1472 : super(target, left, right); | 1474 : super(target, left, right); |
1473 accept(HVisitor visitor) => visitor.visitSubtract(this); | 1475 accept(HVisitor visitor) => visitor.visitSubtract(this); |
1474 | 1476 |
1475 SubtractOperation get operation() => const SubtractOperation(); | 1477 SubtractOperation get operation() => const SubtractOperation(); |
1476 int typeCode() => 9; | 1478 int typeCode() => 9; |
1477 bool typeEquals(other) => other is HSubtract; | 1479 bool typeEquals(other) => other is HSubtract; |
1478 bool dataEquals(HInstruction other) => true; | 1480 bool dataEquals(HInstruction other) => true; |
1479 } | 1481 } |
1480 | 1482 |
| 1483 /** |
| 1484 * An [HSwitch] instruction has one input for the incoming |
| 1485 * value, and one input per constant that it can switch on. |
| 1486 * Its block has one successor per constant, and one for the default. |
| 1487 * If the switch didn't have a default case, the last successor is |
| 1488 * the join block. |
| 1489 */ |
| 1490 class HSwitch extends HControlFlow { |
| 1491 HSwitch(List<HInstruction> inputs) : super(inputs); |
| 1492 |
| 1493 HConstant constant(int index) => inputs[index + 1]; |
| 1494 HInstruction get expression() => inputs[0]; |
| 1495 |
| 1496 HBasicBlock get defaultTarget() => block.successors.last(); |
| 1497 |
| 1498 accept(HVisitor visitor) => visitor.visitSwitch(this); |
| 1499 |
| 1500 String toString() => "HSwitch cases = $inputs"; |
| 1501 } |
| 1502 |
1481 class HTruncatingDivide extends HBinaryArithmetic { | 1503 class HTruncatingDivide extends HBinaryArithmetic { |
1482 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) | 1504 HTruncatingDivide(HStatic target, HInstruction left, HInstruction right) |
1483 : super(target, left, right); | 1505 : super(target, left, right); |
1484 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); | 1506 accept(HVisitor visitor) => visitor.visitTruncatingDivide(this); |
1485 | 1507 |
1486 TruncatingDivideOperation get operation() | 1508 TruncatingDivideOperation get operation() |
1487 => const TruncatingDivideOperation(); | 1509 => const TruncatingDivideOperation(); |
1488 int typeCode() => 10; | 1510 int typeCode() => 10; |
1489 bool typeEquals(other) => other is HTruncatingDivide; | 1511 bool typeEquals(other) => other is HTruncatingDivide; |
1490 bool dataEquals(HInstruction other) => true; | 1512 bool dataEquals(HInstruction other) => true; |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2301 bool accept(HExpressionInformationVisitor visitor); | 2323 bool accept(HExpressionInformationVisitor visitor); |
2302 HInstruction get conditionExpression(); | 2324 HInstruction get conditionExpression(); |
2303 } | 2325 } |
2304 | 2326 |
2305 | 2327 |
2306 interface HStatementInformationVisitor { | 2328 interface HStatementInformationVisitor { |
2307 bool visitLabeledBlockInfo(HLabeledBlockInformation info); | 2329 bool visitLabeledBlockInfo(HLabeledBlockInformation info); |
2308 bool visitLoopInfo(HLoopBlockInformation info); | 2330 bool visitLoopInfo(HLoopBlockInformation info); |
2309 bool visitIfInfo(HIfBlockInformation info); | 2331 bool visitIfInfo(HIfBlockInformation info); |
2310 bool visitTryInfo(HTryBlockInformation info); | 2332 bool visitTryInfo(HTryBlockInformation info); |
| 2333 bool visitSwitchInfo(HSwitchBlockInformation info); |
2311 bool visitSequenceInfo(HStatementSequenceInformation info); | 2334 bool visitSequenceInfo(HStatementSequenceInformation info); |
2312 // Pseudo-structure embedding a dominator-based traversal into | 2335 // Pseudo-structure embedding a dominator-based traversal into |
2313 // the block-structure traversal. This will eventually go away. | 2336 // the block-structure traversal. This will eventually go away. |
2314 bool visitSubGraphInfo(HSubGraphBlockInformation info); | 2337 bool visitSubGraphInfo(HSubGraphBlockInformation info); |
2315 } | 2338 } |
2316 | 2339 |
2317 | 2340 |
2318 interface HExpressionInformationVisitor { | 2341 interface HExpressionInformationVisitor { |
2319 bool visitAndOrInfo(HAndOrBlockInformation info); | 2342 bool visitAndOrInfo(HAndOrBlockInformation info); |
2320 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); | 2343 bool visitSubExpressionInfo(HSubExpressionBlockInformation info); |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2496 this.catchBlock, | 2519 this.catchBlock, |
2497 this.finallyBlock); | 2520 this.finallyBlock); |
2498 | 2521 |
2499 HBasicBlock get start() => body.start; | 2522 HBasicBlock get start() => body.start; |
2500 HBasicBlock get end() => | 2523 HBasicBlock get end() => |
2501 finallyBlock === null ? catchBlock.end : finallyBlock.end; | 2524 finallyBlock === null ? catchBlock.end : finallyBlock.end; |
2502 | 2525 |
2503 bool accept(HStatementInformationVisitor visitor) => | 2526 bool accept(HStatementInformationVisitor visitor) => |
2504 visitor.visitTryInfo(this); | 2527 visitor.visitTryInfo(this); |
2505 } | 2528 } |
| 2529 |
| 2530 |
| 2531 |
| 2532 class HSwitchBlockInformation implements HStatementInformation { |
| 2533 final HExpressionInformation expression; |
| 2534 final List<List<Constant>> matchExpressions; |
| 2535 final List<HStatementInformation> statements; |
| 2536 // If the switch has a default, it's the last statement block, which |
| 2537 // may or may not have other expresions. |
| 2538 final bool hasDefault; |
| 2539 final TargetElement target; |
| 2540 final List<LabelElement> labels; |
| 2541 |
| 2542 HSwitchBlockInformation(this.expression, |
| 2543 this.matchExpressions, |
| 2544 this.statements, |
| 2545 this.hasDefault, |
| 2546 this.target, |
| 2547 this.labels); |
| 2548 |
| 2549 HBasicBlock get start() => expression.start; |
| 2550 HBasicBlock get end() { |
| 2551 // We don't create a switch block if there are no cases. |
| 2552 assert(!statements.isEmpty()); |
| 2553 return statements.last().end; |
| 2554 } |
| 2555 |
| 2556 bool accept(HStatementInformationVisitor visitor) => |
| 2557 visitor.visitSwitchInfo(this); |
| 2558 } |
OLD | NEW |