Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6)

Side by Side Diff: pkg/compiler/lib/src/ssa/validate.dart

Issue 1859343004: dartfmt pkg/compiler (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 import 'nodes.dart'; 5 import 'nodes.dart';
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
11 void visitGraph(HGraph visitee) { 11 void visitGraph(HGraph visitee) {
12 graph = visitee; 12 graph = visitee;
13 visitDominatorTree(visitee); 13 visitDominatorTree(visitee);
14 } 14 }
15 15
16 void markInvalid(String reason) { 16 void markInvalid(String reason) {
17 print(reason); 17 print(reason);
18 isValid = false; 18 isValid = false;
19 } 19 }
20 20
21 // Note that during construction of the Ssa graph the basic blocks are 21 // Note that during construction of the Ssa graph the basic blocks are
22 // not required to be valid yet. 22 // not required to be valid yet.
23 void visitBasicBlock(HBasicBlock block) { 23 void visitBasicBlock(HBasicBlock block) {
24 currentBlock = block; 24 currentBlock = block;
25 if (!isValid) return; // Don't need to continue if we are already invalid. 25 if (!isValid) return; // Don't need to continue if we are already invalid.
26 26
27 // Test that the last instruction is a branching instruction and that the 27 // Test that the last instruction is a branching instruction and that the
28 // basic block contains the branch-target. 28 // basic block contains the branch-target.
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 } 40 }
41 if (block.last is HLoopBranch) { 41 if (block.last is HLoopBranch) {
42 // Assert that the block we inserted to avoid critical edges satisfies 42 // Assert that the block we inserted to avoid critical edges satisfies
43 // our assumptions. That is, it must not contain any instructions 43 // our assumptions. That is, it must not contain any instructions
44 // (although it may contain phi-updates). 44 // (although it may contain phi-updates).
45 HBasicBlock avoidCriticalEdgeBlock = block.successors.last; 45 HBasicBlock avoidCriticalEdgeBlock = block.successors.last;
46 if (avoidCriticalEdgeBlock.first is! HGoto) { 46 if (avoidCriticalEdgeBlock.first is! HGoto) {
47 markInvalid("Critical edge block contains instructions"); 47 markInvalid("Critical edge block contains instructions");
48 } 48 }
49 } 49 }
50 if (block.last is HGoto && block.successors.length != 1) { 50 if (block.last is HGoto && block.successors.length != 1) {
51 markInvalid("Goto node with not exactly one successor"); 51 markInvalid("Goto node with not exactly one successor");
52 } 52 }
53 if (block.last is HJump && block.successors.length != 1) { 53 if (block.last is HJump && block.successors.length != 1) {
54 markInvalid("Break or continue node without one successor"); 54 markInvalid("Break or continue node without one successor");
55 } 55 }
56 if ((block.last is HReturn || block.last is HThrow) && 56 if ((block.last is HReturn || block.last is HThrow) &&
57 (block.successors.length != 1 || !block.successors[0].isExitBlock())) { 57 (block.successors.length != 1 || !block.successors[0].isExitBlock())) {
58 markInvalid("Return or throw node with > 1 successor " 58 markInvalid("Return or throw node with > 1 successor "
59 "or not going to exit-block"); 59 "or not going to exit-block");
60 } 60 }
61 if (block.last is HExit && !block.successors.isEmpty) { 61 if (block.last is HExit && !block.successors.isEmpty) {
62 markInvalid("Exit block with successor"); 62 markInvalid("Exit block with successor");
63 } 63 }
64 64
65 if (block.successors.isEmpty && !block.isExitBlock()) { 65 if (block.successors.isEmpty && !block.isExitBlock()) {
66 markInvalid("Non-exit block without successor"); 66 markInvalid("Non-exit block without successor");
67 } 67 }
68 68
69 // Check that successors ids are always higher than the current one. 69 // Check that successors ids are always higher than the current one.
70 // TODO(floitsch): this is, of course, not true for back-branches. 70 // TODO(floitsch): this is, of course, not true for back-branches.
71 if (block.id == null) markInvalid("block without id"); 71 if (block.id == null) markInvalid("block without id");
72 for (HBasicBlock successor in block.successors) { 72 for (HBasicBlock successor in block.successors) {
73 if (!isValid) break; 73 if (!isValid) break;
74 if (successor.id == null) markInvalid("successor without id"); 74 if (successor.id == null) markInvalid("successor without id");
75 if (successor.id <= block.id && !successor.isLoopHeader()) { 75 if (successor.id <= block.id && !successor.isLoopHeader()) {
76 markInvalid("successor with lower id, but not a loop-header"); 76 markInvalid("successor with lower id, but not a loop-header");
77 } 77 }
78 } 78 }
79 // Make sure we don't have a critical edge. 79 // Make sure we don't have a critical edge.
80 if (isValid && block.successors.length > 1 && 80 if (isValid &&
81 block.last is! HTry && block.last is! HExitTry && 81 block.successors.length > 1 &&
82 block.last is! HTry &&
83 block.last is! HExitTry &&
82 block.last is! HSwitch) { 84 block.last is! HSwitch) {
83 for (HBasicBlock successor in block.successors) { 85 for (HBasicBlock successor in block.successors) {
84 if (!isValid) break; 86 if (!isValid) break;
85 if (successor.predecessors.length >= 2) { 87 if (successor.predecessors.length >= 2) {
86 markInvalid("SSA graph contains critical edge."); 88 markInvalid("SSA graph contains critical edge.");
87 } 89 }
88 } 90 }
89 } 91 }
90 92
91 // Check that the entries in the dominated-list are sorted. 93 // Check that the entries in the dominated-list are sorted.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
124 if (!input.block.dominates(block)) { 126 if (!input.block.dominates(block)) {
125 markInvalid("Definition does not dominate use"); 127 markInvalid("Definition does not dominate use");
126 } 128 }
127 } 129 }
128 }); 130 });
129 131
130 super.visitBasicBlock(block); 132 super.visitBasicBlock(block);
131 } 133 }
132 134
133 /** Returns how often [instruction] is contained in [instructions]. */ 135 /** Returns how often [instruction] is contained in [instructions]. */
134 static int countInstruction(List<HInstruction> instructions, 136 static int countInstruction(
135 HInstruction instruction) { 137 List<HInstruction> instructions, HInstruction instruction) {
136 int result = 0; 138 int result = 0;
137 for (int i = 0; i < instructions.length; i++) { 139 for (int i = 0; i < instructions.length; i++) {
138 if (identical(instructions[i], instruction)) result++; 140 if (identical(instructions[i], instruction)) result++;
139 } 141 }
140 return result; 142 return result;
141 } 143 }
142 144
143 /** 145 /**
144 * Returns true if the predicate returns true for every instruction in the 146 * Returns true if the predicate returns true for every instruction in the
145 * list. The argument to [f] is an instruction with the count of how often 147 * list. The argument to [f] is an instruction with the count of how often
(...skipping 17 matching lines...) Expand all
163 } 165 }
164 return true; 166 return true;
165 } 167 }
166 168
167 void visitInstruction(HInstruction instruction) { 169 void visitInstruction(HInstruction instruction) {
168 // Verifies that we are in the use list of our inputs. 170 // Verifies that we are in the use list of our inputs.
169 bool hasCorrectInputs() { 171 bool hasCorrectInputs() {
170 bool inBasicBlock = instruction.isInBasicBlock(); 172 bool inBasicBlock = instruction.isInBasicBlock();
171 return everyInstruction(instruction.inputs, (input, count) { 173 return everyInstruction(instruction.inputs, (input, count) {
172 if (inBasicBlock) { 174 if (inBasicBlock) {
173 return input.isInBasicBlock() 175 return input.isInBasicBlock() &&
174 && countInstruction(input.usedBy, instruction) == count; 176 countInstruction(input.usedBy, instruction) == count;
175 } else { 177 } else {
176 return countInstruction(input.usedBy, instruction) == 0; 178 return countInstruction(input.usedBy, instruction) == 0;
177 } 179 }
178 }); 180 });
179 } 181 }
180 182
181 // Verifies that all our uses have us in their inputs. 183 // Verifies that all our uses have us in their inputs.
182 bool hasCorrectUses() { 184 bool hasCorrectUses() {
183 if (!instruction.isInBasicBlock()) return true; 185 if (!instruction.isInBasicBlock()) return true;
184 return everyInstruction(instruction.usedBy, (use, count) { 186 return everyInstruction(instruction.usedBy, (use, count) {
185 return use.isInBasicBlock() 187 return use.isInBasicBlock() &&
186 && countInstruction(use.inputs, instruction) == count; 188 countInstruction(use.inputs, instruction) == count;
187 }); 189 });
188 } 190 }
189 191
190 if (!identical(instruction.block, currentBlock)) { 192 if (!identical(instruction.block, currentBlock)) {
191 markInvalid("Instruction in wrong block"); 193 markInvalid("Instruction in wrong block");
192 } 194 }
193 if (!hasCorrectInputs()) { 195 if (!hasCorrectInputs()) {
194 markInvalid("Incorrect inputs"); 196 markInvalid("Incorrect inputs");
195 } 197 }
196 if (!hasCorrectUses()) { 198 if (!hasCorrectUses()) {
197 markInvalid("Incorrect uses"); 199 markInvalid("Incorrect uses");
198 } 200 }
199 } 201 }
200 } 202 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/types_propagation.dart ('k') | pkg/compiler/lib/src/ssa/value_range_analyzer.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698