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

Side by Side Diff: src/compiler/verifier.cc

Issue 426233002: Land the Fan (disabled) (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/compiler/verifier.h"
6
7 #include "src/compiler/generic-algorithm.h"
8 #include "src/compiler/generic-node-inl.h"
9 #include "src/compiler/generic-node.h"
10 #include "src/compiler/graph-inl.h"
11 #include "src/compiler/graph.h"
12 #include "src/compiler/node.h"
13 #include "src/compiler/node-properties-inl.h"
14 #include "src/compiler/node-properties.h"
15 #include "src/compiler/opcodes.h"
16 #include "src/compiler/operator.h"
17
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21
22
23 static bool IsDefUseChainLinkPresent(Node* def, Node* use) {
24 Node::Uses uses = def->uses();
25 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
26 if (*it == use) return true;
27 }
28 return false;
29 }
30
31
32 static bool IsUseDefChainLinkPresent(Node* def, Node* use) {
33 Node::Inputs inputs = use->inputs();
34 for (Node::Inputs::iterator it = inputs.begin(); it != inputs.end(); ++it) {
35 if (*it == def) return true;
36 }
37 return false;
38 }
39
40
41 class Verifier::Visitor : public NullNodeVisitor {
42 public:
43 explicit Visitor(Zone* zone) :
44 reached_from_start(NodeSet::key_compare(), NodeSet::allocator_type(zone)),
45 reached_from_end(NodeSet::key_compare(), NodeSet::allocator_type(zone)) {
46 }
47
48 // Fulfills the PreNodeCallback interface.
49 GenericGraphVisit::Control Pre(Node* node);
50
51 bool from_start;
52 NodeSet reached_from_start;
53 NodeSet reached_from_end;
54 };
55
56
57 GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
58 int value_count = NodeProperties::GetValueInputCount(node);
59 int context_count = NodeProperties::GetContextInputCount(node);
60 int effect_count = NodeProperties::GetEffectInputCount(node);
61 int control_count = NodeProperties::GetControlInputCount(node);
62
63 // Verify number of inputs matches up.
64 int input_count = value_count + context_count + effect_count + control_count;
65 CHECK_EQ(input_count, node->InputCount());
66
67 // Verify all value inputs actually produce a value.
68 for (int i = 0; i < value_count; ++i) {
69 Node* value = NodeProperties::GetValueInput(node, i);
70 CHECK(NodeProperties::HasValueOutput(value));
71 CHECK(IsDefUseChainLinkPresent(value, node));
72 CHECK(IsUseDefChainLinkPresent(value, node));
73 }
74
75 // Verify all context inputs are value nodes.
76 for (int i = 0; i < context_count; ++i) {
77 Node* context = NodeProperties::GetContextInput(node);
78 CHECK(NodeProperties::HasValueOutput(context));
79 CHECK(IsDefUseChainLinkPresent(context, node));
80 CHECK(IsUseDefChainLinkPresent(context, node));
81 }
82
83 // Verify all effect inputs actually have an effect.
84 for (int i = 0; i < effect_count; ++i) {
85 Node* effect = NodeProperties::GetEffectInput(node);
86 CHECK(NodeProperties::HasEffectOutput(effect));
87 CHECK(IsDefUseChainLinkPresent(effect, node));
88 CHECK(IsUseDefChainLinkPresent(effect, node));
89 }
90
91 // Verify all control inputs are control nodes.
92 for (int i = 0; i < control_count; ++i) {
93 Node* control = NodeProperties::GetControlInput(node, i);
94 CHECK(NodeProperties::HasControlOutput(control));
95 CHECK(IsDefUseChainLinkPresent(control, node));
96 CHECK(IsUseDefChainLinkPresent(control, node));
97 }
98
99 // Verify all successors are projections if multiple value outputs exist.
100 if (NodeProperties::GetValueOutputCount(node) > 1) {
101 Node::Uses uses = node->uses();
102 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
103 CHECK(!NodeProperties::IsValueEdge(it.edge()) ||
104 (*it)->opcode() == IrOpcode::kProjection);
105 }
106 }
107
108 switch (node->opcode()) {
109 case IrOpcode::kStart:
110 // Start has no inputs.
111 CHECK_EQ(0, input_count);
112 break;
113 case IrOpcode::kEnd:
114 // End has no outputs.
115 CHECK(!NodeProperties::HasValueOutput(node));
116 CHECK(!NodeProperties::HasEffectOutput(node));
117 CHECK(!NodeProperties::HasControlOutput(node));
118 break;
119 case IrOpcode::kDead:
120 // Dead is never connected to the graph.
121 UNREACHABLE();
122 case IrOpcode::kBranch: {
123 // Branch uses are IfTrue and IfFalse.
124 Node::Uses uses = node->uses();
125 bool got_true = false, got_false = false;
126 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
127 CHECK(((*it)->opcode() == IrOpcode::kIfTrue && !got_true) ||
128 ((*it)->opcode() == IrOpcode::kIfFalse && !got_false));
129 if ((*it)->opcode() == IrOpcode::kIfTrue) got_true = true;
130 if ((*it)->opcode() == IrOpcode::kIfFalse) got_false = true;
131 }
132 // TODO(rossberg): Currently fails for various tests.
133 // CHECK(got_true && got_false);
134 break;
135 }
136 case IrOpcode::kIfTrue:
137 case IrOpcode::kIfFalse:
138 CHECK_EQ(IrOpcode::kBranch,
139 NodeProperties::GetControlInput(node, 0)->opcode());
140 break;
141 case IrOpcode::kLoop:
142 case IrOpcode::kMerge:
143 break;
144 case IrOpcode::kReturn:
145 // TODO(rossberg): check successor is End
146 break;
147 case IrOpcode::kThrow:
148 // TODO(rossberg): what are the constraints on these?
149 break;
150 case IrOpcode::kParameter:
151 // Parameters have no inputs.
152 CHECK_EQ(0, input_count);
153 break;
154 case IrOpcode::kInt32Constant:
155 case IrOpcode::kInt64Constant:
156 case IrOpcode::kFloat64Constant:
157 case IrOpcode::kExternalConstant:
158 case IrOpcode::kNumberConstant:
159 case IrOpcode::kHeapConstant:
160 // Constants have no inputs.
161 CHECK_EQ(0, input_count);
162 break;
163 case IrOpcode::kPhi: {
164 // Phi input count matches parent control node.
165 CHECK_EQ(1, control_count);
166 Node* control = NodeProperties::GetControlInput(node, 0);
167 CHECK_EQ(value_count, NodeProperties::GetControlInputCount(control));
168 break;
169 }
170 case IrOpcode::kEffectPhi: {
171 // EffectPhi input count matches parent control node.
172 CHECK_EQ(1, control_count);
173 Node* control = NodeProperties::GetControlInput(node, 0);
174 CHECK_EQ(effect_count, NodeProperties::GetControlInputCount(control));
175 break;
176 }
177 case IrOpcode::kLazyDeoptimization:
178 // TODO(jarin): what are the constraints on these?
179 break;
180 case IrOpcode::kDeoptimize:
181 // TODO(jarin): what are the constraints on these?
182 break;
183 case IrOpcode::kFrameState:
184 // TODO(jarin): what are the constraints on these?
185 break;
186 case IrOpcode::kCall:
187 // TODO(rossberg): what are the constraints on these?
188 break;
189 case IrOpcode::kContinuation:
190 // TODO(jarin): what are the constraints on these?
191 break;
192 case IrOpcode::kProjection: {
193 // Projection has an input that produces enough values.
194 int index = static_cast<Operator1<int>*>(node->op())->parameter();
195 Node* input = NodeProperties::GetValueInput(node, 0);
196 CHECK_GT(NodeProperties::GetValueOutputCount(input), index);
197 break;
198 }
199 default:
200 // TODO(rossberg): Check other node kinds.
201 break;
202 }
203
204 if (from_start) {
205 reached_from_start.insert(node);
206 } else {
207 reached_from_end.insert(node);
208 }
209
210 return GenericGraphVisit::CONTINUE;
211 }
212
213
214 void Verifier::Run(Graph* graph) {
215 Visitor visitor(graph->zone());
216
217 visitor.from_start = true;
218 graph->VisitNodeUsesFromStart(&visitor);
219 visitor.from_start = false;
220 graph->VisitNodeInputsFromEnd(&visitor);
221
222 // All control nodes reachable from end are reachable from start.
223 for (NodeSet::iterator it = visitor.reached_from_end.begin();
224 it != visitor.reached_from_end.end(); ++it) {
225 CHECK(!NodeProperties::IsControl(*it) ||
226 visitor.reached_from_start.count(*it));
227 }
228 }
229
230
231 } } } // namespace v8::internal::compiler
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698