Chromium Code Reviews| 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 part of ssa; | 5 part of ssa; |
| 6 | 6 |
| 7 class HValidator extends HInstructionVisitor { | 7 class HValidator extends HInstructionVisitor { |
| 8 bool isValid = true; | 8 bool isValid = true; |
| 9 HGraph graph; | 9 HGraph graph; |
| 10 | 10 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 29 if (block.first == null || block.last == null) { | 29 if (block.first == null || block.last == null) { |
| 30 markInvalid("empty block"); | 30 markInvalid("empty block"); |
| 31 } | 31 } |
| 32 if (block.last is !HControlFlow) { | 32 if (block.last is !HControlFlow) { |
| 33 markInvalid("block ends with non-tail node."); | 33 markInvalid("block ends with non-tail node."); |
| 34 } | 34 } |
| 35 if (block.last is HIf && block.successors.length != 2) { | 35 if (block.last is HIf && block.successors.length != 2) { |
| 36 markInvalid("If node without two successors"); | 36 markInvalid("If node without two successors"); |
| 37 } | 37 } |
| 38 if (block.last is HConditionalBranch && block.successors.length != 2) { | 38 if (block.last is HConditionalBranch && block.successors.length != 2) { |
| 39 markInvalid("Conditional node without two successors"); | 39 markInvalid("Conditional node without two successors"); |
| 40 } | |
| 41 if (block.last is HLoopBranch) { | |
| 42 // Assert that the block we inserted to avoid critical edges satisfies | |
| 43 // our assumptions. That is, it must not contain any instructions | |
| 44 // (although it may contain phi-updates). | |
| 45 HBasicBlock avoidCriticalEdgeBlock = block.successors.last; | |
| 46 if (avoidCriticalEdgeBlock.first is! HGoto) { | |
| 47 markInvalid("Critical edge block contains instructions"); | |
| 48 } | |
| 40 } | 49 } |
| 41 if (block.last is HGoto && block.successors.length != 1) { | 50 if (block.last is HGoto && block.successors.length != 1) { |
| 42 markInvalid("Goto node with not exactly one successor"); | 51 markInvalid("Goto node with not exactly one successor"); |
| 43 } | 52 } |
| 44 if (block.last is HJump && block.successors.length != 1) { | 53 if (block.last is HJump && block.successors.length != 1) { |
| 45 markInvalid("Break or continue node without one successor"); | 54 markInvalid("Break or continue node without one successor"); |
| 46 } | 55 } |
| 47 if ((block.last is HReturn || block.last is HThrow) && | 56 if ((block.last is HReturn || block.last is HThrow) && |
| 48 (block.successors.length != 1 || !block.successors[0].isExitBlock())) { | 57 (block.successors.length != 1 || !block.successors[0].isExitBlock())) { |
| 49 markInvalid("Return or throw node with > 1 successor " | 58 markInvalid("Return or throw node with > 1 successor " |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 60 // Check that successors ids are always higher than the current one. | 69 // Check that successors ids are always higher than the current one. |
| 61 // TODO(floitsch): this is, of course, not true for back-branches. | 70 // TODO(floitsch): this is, of course, not true for back-branches. |
| 62 if (block.id == null) markInvalid("block without id"); | 71 if (block.id == null) markInvalid("block without id"); |
| 63 for (HBasicBlock successor in block.successors) { | 72 for (HBasicBlock successor in block.successors) { |
| 64 if (!isValid) break; | 73 if (!isValid) break; |
| 65 if (successor.id == null) markInvalid("successor without id"); | 74 if (successor.id == null) markInvalid("successor without id"); |
| 66 if (successor.id <= block.id && !successor.isLoopHeader()) { | 75 if (successor.id <= block.id && !successor.isLoopHeader()) { |
| 67 markInvalid("successor with lower id, but not a loop-header"); | 76 markInvalid("successor with lower id, but not a loop-header"); |
| 68 } | 77 } |
| 69 } | 78 } |
| 79 // Make sure we don't have a critical edge. | |
| 80 if (isValid && block.successors.length > 1 && | |
| 81 block.last is! HTry && block.last is! HExitTry && | |
| 82 block.last is! HSwitch) { | |
|
ngeoffray
2014/06/25 07:55:22
Wow, did not realize there was that many special c
floitsch
2014/06/25 08:27:18
Didn't know either, until all kinds of tests bombe
| |
| 83 for (HBasicBlock successor in block.successors) { | |
| 84 if (!isValid) break; | |
| 85 if (successor.predecessors.length >= 2) { | |
| 86 markInvalid("SSA graph contains critical edge."); | |
| 87 } | |
| 88 } | |
| 89 } | |
| 70 | 90 |
| 71 // Check that the entries in the dominated-list are sorted. | 91 // Check that the entries in the dominated-list are sorted. |
| 72 int lastId = 0; | 92 int lastId = 0; |
| 73 for (HBasicBlock dominated in block.dominatedBlocks) { | 93 for (HBasicBlock dominated in block.dominatedBlocks) { |
| 74 if (!isValid) break; | 94 if (!isValid) break; |
| 75 if (!identical(dominated.dominator, block)) { | 95 if (!identical(dominated.dominator, block)) { |
| 76 markInvalid("dominated block not pointing back"); | 96 markInvalid("dominated block not pointing back"); |
| 77 } | 97 } |
| 78 if (dominated.id == null || dominated.id <= lastId) { | 98 if (dominated.id == null || dominated.id <= lastId) { |
| 79 markInvalid("dominated.id == null or dominated has <= id"); | 99 markInvalid("dominated.id == null or dominated has <= id"); |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 171 markInvalid("Instruction in wrong block"); | 191 markInvalid("Instruction in wrong block"); |
| 172 } | 192 } |
| 173 if (!hasCorrectInputs()) { | 193 if (!hasCorrectInputs()) { |
| 174 markInvalid("Incorrect inputs"); | 194 markInvalid("Incorrect inputs"); |
| 175 } | 195 } |
| 176 if (!hasCorrectUses()) { | 196 if (!hasCorrectUses()) { |
| 177 markInvalid("Incorrect uses"); | 197 markInvalid("Incorrect uses"); |
| 178 } | 198 } |
| 179 } | 199 } |
| 180 } | 200 } |
| OLD | NEW |