| 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 class HValidator extends HInstructionVisitor { | 5 class HValidator extends HInstructionVisitor { |
| 6 bool isValid = true; | 6 bool isValid = true; |
| 7 HGraph graph; | 7 HGraph graph; |
| 8 | 8 |
| 9 void visitGraph(HGraph visitee) { | 9 void visitGraph(HGraph visitee) { |
| 10 graph = visitee; | 10 graph = visitee; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 if (block.last is HThrow && !block.successors.isEmpty()) { | 49 if (block.last is HThrow && !block.successors.isEmpty()) { |
| 50 markInvalid("Throw block with successor"); | 50 markInvalid("Throw block with successor"); |
| 51 } | 51 } |
| 52 | 52 |
| 53 if (block.successors.isEmpty() && | 53 if (block.successors.isEmpty() && |
| 54 block.last is !HThrow && | 54 block.last is !HThrow && |
| 55 !block.isExitBlock()) { | 55 !block.isExitBlock()) { |
| 56 markInvalid("Non-exit or throw block without successor"); | 56 markInvalid("Non-exit or throw block without successor"); |
| 57 } | 57 } |
| 58 | 58 |
| 59 // Make sure that successors ids are always higher than the current one. | 59 // Check that successors ids are always higher than the current one. |
| 60 // TODO(floitsch): this is, of course, not true for back-branches. | 60 // TODO(floitsch): this is, of course, not true for back-branches. |
| 61 if (block.id === null) markInvalid("block without id"); | 61 if (block.id === null) markInvalid("block without id"); |
| 62 for (HBasicBlock successor in block.successors) { | 62 for (HBasicBlock successor in block.successors) { |
| 63 if (!isValid) break; | 63 if (!isValid) break; |
| 64 if (successor.id === null) markInvalid("successor without id"); | 64 if (successor.id === null) markInvalid("successor without id"); |
| 65 if (successor.id <= block.id && !successor.isLoopHeader()) { | 65 if (successor.id <= block.id && !successor.isLoopHeader()) { |
| 66 markInvalid("successor with lower id, but not a loop-header"); | 66 markInvalid("successor with lower id, but not a loop-header"); |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 // Make sure that the entries in the dominated-list are sorted. | 70 // Check that the entries in the dominated-list are sorted. |
| 71 int lastId = 0; | 71 int lastId = 0; |
| 72 for (HBasicBlock dominated in block.dominatedBlocks) { | 72 for (HBasicBlock dominated in block.dominatedBlocks) { |
| 73 if (!isValid) break; | 73 if (!isValid) break; |
| 74 if (dominated.dominator !== block) { | 74 if (dominated.dominator !== block) { |
| 75 markInvalid("dominated block not pointing back"); | 75 markInvalid("dominated block not pointing back"); |
| 76 } | 76 } |
| 77 if (dominated.id === null || dominated.id <= lastId) { | 77 if (dominated.id === null || dominated.id <= lastId) { |
| 78 markInvalid("dominated.id === null or dominated has <= id"); | 78 markInvalid("dominated.id === null or dominated has <= id"); |
| 79 } | 79 } |
| 80 lastId = dominated.id; | 80 lastId = dominated.id; |
| 81 } | 81 } |
| 82 | 82 |
| 83 if (!isValid) return; | 83 if (!isValid) return; |
| 84 block.forEachPhi(visitInstruction); | 84 block.forEachPhi(visitInstruction); |
| 85 | 85 |
| 86 // Make sure the parameters of a phi are dominating the | 86 // Check that the blocks of the parameters of a phi are dominating the |
| 87 // corresponding predecessor block. | 87 // corresponding predecessor block. Note that a block dominates |
| 88 // itself. |
| 88 block.forEachPhi((HPhi phi) { | 89 block.forEachPhi((HPhi phi) { |
| 89 for (int i = 0; i < phi.inputs.length; i++) { | 90 for (int i = 0; i < phi.inputs.length; i++) { |
| 90 HInstruction input = phi.inputs[i]; | 91 HInstruction input = phi.inputs[i]; |
| 91 if (!input.block.dominates(block.predecessors[i])) { | 92 if (!input.block.dominates(block.predecessors[i])) { |
| 92 markInvalid("Definition does not dominate use"); | 93 markInvalid("Definition does not dominate use"); |
| 93 } | 94 } |
| 94 } | 95 } |
| 95 }); | 96 }); |
| 96 | 97 |
| 97 // Make sure the inputs of an instruction dominate the | 98 // Check that the blocks of the inputs of an instruction dominate the |
| 98 // instruction. | 99 // instruction's block. |
| 99 block.forEachInstruction((HInstruction instruction) { | 100 block.forEachInstruction((HInstruction instruction) { |
| 100 for (HInstruction input in instruction.inputs) { | 101 for (HInstruction input in instruction.inputs) { |
| 101 if (!input.block.dominates(block)) { | 102 if (!input.block.dominates(block)) { |
| 102 markInvalid("Definition does not dominate use"); | 103 markInvalid("Definition does not dominate use"); |
| 103 } | 104 } |
| 104 } | 105 } |
| 105 }); | 106 }); |
| 106 | 107 |
| 107 super.visitBasicBlock(block); | 108 super.visitBasicBlock(block); |
| 108 } | 109 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 markInvalid("Instruction in wrong block"); | 167 markInvalid("Instruction in wrong block"); |
| 167 } | 168 } |
| 168 if (!hasCorrectInputs()) { | 169 if (!hasCorrectInputs()) { |
| 169 markInvalid("Incorrect inputs"); | 170 markInvalid("Incorrect inputs"); |
| 170 } | 171 } |
| 171 if (!hasCorrectUses()) { | 172 if (!hasCorrectUses()) { |
| 172 markInvalid("Incorrect uses"); | 173 markInvalid("Incorrect uses"); |
| 173 } | 174 } |
| 174 } | 175 } |
| 175 } | 176 } |
| OLD | NEW |