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

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

Issue 686213002: Inline trivial OperatorProperties methods. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 1 month 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
« no previous file with comments | « src/compiler/typer.cc ('k') | test/cctest/compiler/simplified-graph-builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/verifier.h" 5 #include "src/compiler/verifier.h"
6 6
7 #include <deque> 7 #include <deque>
8 #include <queue> 8 #include <queue>
9 #include <sstream> 9 #include <sstream>
10 #include <string> 10 #include <string>
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 bounds(input).upper->PrintTo(str); 114 bounds(input).upper->PrintTo(str);
115 str << " is not "; 115 str << " is not ";
116 type->PrintTo(str); 116 type->PrintTo(str);
117 V8_Fatal(__FILE__, __LINE__, str.str().c_str()); 117 V8_Fatal(__FILE__, __LINE__, str.str().c_str());
118 } 118 }
119 } 119 }
120 }; 120 };
121 121
122 122
123 GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) { 123 GenericGraphVisit::Control Verifier::Visitor::Pre(Node* node) {
124 int value_count = OperatorProperties::GetValueInputCount(node->op()); 124 int value_count = node->op()->ValueInputCount();
125 int context_count = OperatorProperties::GetContextInputCount(node->op()); 125 int context_count = OperatorProperties::GetContextInputCount(node->op());
126 int frame_state_count = 126 int frame_state_count =
127 OperatorProperties::GetFrameStateInputCount(node->op()); 127 OperatorProperties::GetFrameStateInputCount(node->op());
128 int effect_count = OperatorProperties::GetEffectInputCount(node->op()); 128 int effect_count = node->op()->EffectInputCount();
129 int control_count = OperatorProperties::GetControlInputCount(node->op()); 129 int control_count = node->op()->ControlInputCount();
130 130
131 // Verify number of inputs matches up. 131 // Verify number of inputs matches up.
132 int input_count = value_count + context_count + frame_state_count + 132 int input_count = value_count + context_count + frame_state_count +
133 effect_count + control_count; 133 effect_count + control_count;
134 CHECK_EQ(input_count, node->InputCount()); 134 CHECK_EQ(input_count, node->InputCount());
135 135
136 // Verify that frame state has been inserted for the nodes that need it. 136 // Verify that frame state has been inserted for the nodes that need it.
137 if (OperatorProperties::HasFrameStateInput(node->op())) { 137 if (OperatorProperties::HasFrameStateInput(node->op())) {
138 Node* frame_state = NodeProperties::GetFrameStateInput(node); 138 Node* frame_state = NodeProperties::GetFrameStateInput(node);
139 CHECK(frame_state->opcode() == IrOpcode::kFrameState || 139 CHECK(frame_state->opcode() == IrOpcode::kFrameState ||
140 // kFrameState uses undefined as a sentinel. 140 // kFrameState uses undefined as a sentinel.
141 (node->opcode() == IrOpcode::kFrameState && 141 (node->opcode() == IrOpcode::kFrameState &&
142 frame_state->opcode() == IrOpcode::kHeapConstant)); 142 frame_state->opcode() == IrOpcode::kHeapConstant));
143 CHECK(IsDefUseChainLinkPresent(frame_state, node)); 143 CHECK(IsDefUseChainLinkPresent(frame_state, node));
144 CHECK(IsUseDefChainLinkPresent(frame_state, node)); 144 CHECK(IsUseDefChainLinkPresent(frame_state, node));
145 } 145 }
146 146
147 // Verify all value inputs actually produce a value. 147 // Verify all value inputs actually produce a value.
148 for (int i = 0; i < value_count; ++i) { 148 for (int i = 0; i < value_count; ++i) {
149 Node* value = NodeProperties::GetValueInput(node, i); 149 Node* value = NodeProperties::GetValueInput(node, i);
150 CHECK(OperatorProperties::HasValueOutput(value->op())); 150 CHECK(value->op()->ValueOutputCount() > 0);
151 CHECK(IsDefUseChainLinkPresent(value, node)); 151 CHECK(IsDefUseChainLinkPresent(value, node));
152 CHECK(IsUseDefChainLinkPresent(value, node)); 152 CHECK(IsUseDefChainLinkPresent(value, node));
153 } 153 }
154 154
155 // Verify all context inputs are value nodes. 155 // Verify all context inputs are value nodes.
156 for (int i = 0; i < context_count; ++i) { 156 for (int i = 0; i < context_count; ++i) {
157 Node* context = NodeProperties::GetContextInput(node); 157 Node* context = NodeProperties::GetContextInput(node);
158 CHECK(OperatorProperties::HasValueOutput(context->op())); 158 CHECK(context->op()->ValueOutputCount() > 0);
159 CHECK(IsDefUseChainLinkPresent(context, node)); 159 CHECK(IsDefUseChainLinkPresent(context, node));
160 CHECK(IsUseDefChainLinkPresent(context, node)); 160 CHECK(IsUseDefChainLinkPresent(context, node));
161 } 161 }
162 162
163 // Verify all effect inputs actually have an effect. 163 // Verify all effect inputs actually have an effect.
164 for (int i = 0; i < effect_count; ++i) { 164 for (int i = 0; i < effect_count; ++i) {
165 Node* effect = NodeProperties::GetEffectInput(node); 165 Node* effect = NodeProperties::GetEffectInput(node);
166 CHECK(OperatorProperties::HasEffectOutput(effect->op())); 166 CHECK(effect->op()->EffectOutputCount() > 0);
167 CHECK(IsDefUseChainLinkPresent(effect, node)); 167 CHECK(IsDefUseChainLinkPresent(effect, node));
168 CHECK(IsUseDefChainLinkPresent(effect, node)); 168 CHECK(IsUseDefChainLinkPresent(effect, node));
169 } 169 }
170 170
171 // Verify all control inputs are control nodes. 171 // Verify all control inputs are control nodes.
172 for (int i = 0; i < control_count; ++i) { 172 for (int i = 0; i < control_count; ++i) {
173 Node* control = NodeProperties::GetControlInput(node, i); 173 Node* control = NodeProperties::GetControlInput(node, i);
174 CHECK(OperatorProperties::HasControlOutput(control->op())); 174 CHECK(control->op()->ControlOutputCount() > 0);
175 CHECK(IsDefUseChainLinkPresent(control, node)); 175 CHECK(IsDefUseChainLinkPresent(control, node));
176 CHECK(IsUseDefChainLinkPresent(control, node)); 176 CHECK(IsUseDefChainLinkPresent(control, node));
177 } 177 }
178 178
179 // Verify all successors are projections if multiple value outputs exist. 179 // Verify all successors are projections if multiple value outputs exist.
180 if (OperatorProperties::GetValueOutputCount(node->op()) > 1) { 180 if (node->op()->ValueOutputCount() > 1) {
181 Node::Uses uses = node->uses(); 181 Node::Uses uses = node->uses();
182 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) { 182 for (Node::Uses::iterator it = uses.begin(); it != uses.end(); ++it) {
183 CHECK(!NodeProperties::IsValueEdge(it.edge()) || 183 CHECK(!NodeProperties::IsValueEdge(it.edge()) ||
184 (*it)->opcode() == IrOpcode::kProjection || 184 (*it)->opcode() == IrOpcode::kProjection ||
185 (*it)->opcode() == IrOpcode::kParameter); 185 (*it)->opcode() == IrOpcode::kParameter);
186 } 186 }
187 } 187 }
188 188
189 switch (node->opcode()) { 189 switch (node->opcode()) {
190 case IrOpcode::kStart: 190 case IrOpcode::kStart:
191 // Start has no inputs. 191 // Start has no inputs.
192 CHECK_EQ(0, input_count); 192 CHECK_EQ(0, input_count);
193 // Type is a tuple. 193 // Type is a tuple.
194 // TODO(rossberg): Multiple outputs are currently typed as Internal. 194 // TODO(rossberg): Multiple outputs are currently typed as Internal.
195 CheckUpperIs(node, Type::Internal()); 195 CheckUpperIs(node, Type::Internal());
196 break; 196 break;
197 case IrOpcode::kEnd: 197 case IrOpcode::kEnd:
198 // End has no outputs. 198 // End has no outputs.
199 CHECK(!OperatorProperties::HasValueOutput(node->op())); 199 CHECK(node->op()->ValueOutputCount() == 0);
200 CHECK(!OperatorProperties::HasEffectOutput(node->op())); 200 CHECK(node->op()->EffectOutputCount() == 0);
201 CHECK(!OperatorProperties::HasControlOutput(node->op())); 201 CHECK(node->op()->ControlOutputCount() == 0);
202 // Type is empty. 202 // Type is empty.
203 CheckNotTyped(node); 203 CheckNotTyped(node);
204 break; 204 break;
205 case IrOpcode::kDead: 205 case IrOpcode::kDead:
206 // Dead is never connected to the graph. 206 // Dead is never connected to the graph.
207 UNREACHABLE(); 207 UNREACHABLE();
208 case IrOpcode::kBranch: { 208 case IrOpcode::kBranch: {
209 // Branch uses are IfTrue and IfFalse. 209 // Branch uses are IfTrue and IfFalse.
210 Node::Uses uses = node->uses(); 210 Node::Uses uses = node->uses();
211 int count_true = 0, count_false = 0; 211 int count_true = 0, count_false = 0;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 // ---------------- 254 // ----------------
255 case IrOpcode::kParameter: { 255 case IrOpcode::kParameter: {
256 // Parameters have the start node as inputs. 256 // Parameters have the start node as inputs.
257 CHECK_EQ(1, input_count); 257 CHECK_EQ(1, input_count);
258 CHECK_EQ(IrOpcode::kStart, 258 CHECK_EQ(IrOpcode::kStart,
259 NodeProperties::GetValueInput(node, 0)->opcode()); 259 NodeProperties::GetValueInput(node, 0)->opcode());
260 // Parameter has an input that produces enough values. 260 // Parameter has an input that produces enough values.
261 int index = OpParameter<int>(node); 261 int index = OpParameter<int>(node);
262 Node* input = NodeProperties::GetValueInput(node, 0); 262 Node* input = NodeProperties::GetValueInput(node, 0);
263 // Currently, parameter indices start at -1 instead of 0. 263 // Currently, parameter indices start at -1 instead of 0.
264 CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index + 1); 264 CHECK_GT(input->op()->ValueOutputCount(), index + 1);
265 // Type can be anything. 265 // Type can be anything.
266 CheckUpperIs(node, Type::Any()); 266 CheckUpperIs(node, Type::Any());
267 break; 267 break;
268 } 268 }
269 case IrOpcode::kInt32Constant: // TODO(rossberg): rename Word32Constant? 269 case IrOpcode::kInt32Constant: // TODO(rossberg): rename Word32Constant?
270 // Constants have no inputs. 270 // Constants have no inputs.
271 CHECK_EQ(0, input_count); 271 CHECK_EQ(0, input_count);
272 // Type is a 32 bit integer, signed or unsigned. 272 // Type is a 32 bit integer, signed or unsigned.
273 CheckUpperIs(node, Type::Integral32()); 273 CheckUpperIs(node, Type::Integral32());
274 break; 274 break;
(...skipping 21 matching lines...) Expand all
296 case IrOpcode::kExternalConstant: 296 case IrOpcode::kExternalConstant:
297 // Constants have no inputs. 297 // Constants have no inputs.
298 CHECK_EQ(0, input_count); 298 CHECK_EQ(0, input_count);
299 // Type is considered internal. 299 // Type is considered internal.
300 CheckUpperIs(node, Type::Internal()); 300 CheckUpperIs(node, Type::Internal());
301 break; 301 break;
302 case IrOpcode::kProjection: { 302 case IrOpcode::kProjection: {
303 // Projection has an input that produces enough values. 303 // Projection has an input that produces enough values.
304 int index = static_cast<int>(OpParameter<size_t>(node->op())); 304 int index = static_cast<int>(OpParameter<size_t>(node->op()));
305 Node* input = NodeProperties::GetValueInput(node, 0); 305 Node* input = NodeProperties::GetValueInput(node, 0);
306 CHECK_GT(OperatorProperties::GetValueOutputCount(input->op()), index); 306 CHECK_GT(input->op()->ValueOutputCount(), index);
307 // Type can be anything. 307 // Type can be anything.
308 // TODO(rossberg): Introduce tuple types for this. 308 // TODO(rossberg): Introduce tuple types for this.
309 // TODO(titzer): Convince rossberg not to. 309 // TODO(titzer): Convince rossberg not to.
310 CheckUpperIs(node, Type::Any()); 310 CheckUpperIs(node, Type::Any());
311 break; 311 break;
312 } 312 }
313 case IrOpcode::kSelect: { 313 case IrOpcode::kSelect: {
314 CHECK_EQ(0, effect_count); 314 CHECK_EQ(0, effect_count);
315 CHECK_EQ(0, control_count); 315 CHECK_EQ(0, control_count);
316 CHECK_EQ(3, value_count); 316 CHECK_EQ(3, value_count);
317 break; 317 break;
318 } 318 }
319 case IrOpcode::kPhi: { 319 case IrOpcode::kPhi: {
320 // Phi input count matches parent control node. 320 // Phi input count matches parent control node.
321 CHECK_EQ(0, effect_count); 321 CHECK_EQ(0, effect_count);
322 CHECK_EQ(1, control_count); 322 CHECK_EQ(1, control_count);
323 Node* control = NodeProperties::GetControlInput(node, 0); 323 Node* control = NodeProperties::GetControlInput(node, 0);
324 CHECK_EQ(value_count, 324 CHECK_EQ(value_count, control->op()->ControlInputCount());
325 OperatorProperties::GetControlInputCount(control->op()));
326 CHECK_EQ(input_count, 1 + value_count); 325 CHECK_EQ(input_count, 1 + value_count);
327 // Type must be subsumed by all input types. 326 // Type must be subsumed by all input types.
328 // TODO(rossberg): for now at least, narrowing does not really hold. 327 // TODO(rossberg): for now at least, narrowing does not really hold.
329 /* 328 /*
330 for (int i = 0; i < value_count; ++i) { 329 for (int i = 0; i < value_count; ++i) {
331 // TODO(rossberg, jarin): Figure out what to do about lower bounds. 330 // TODO(rossberg, jarin): Figure out what to do about lower bounds.
332 // CHECK(bounds(node).lower->Is(bounds(ValueInput(node, i)).lower)); 331 // CHECK(bounds(node).lower->Is(bounds(ValueInput(node, i)).lower));
333 CHECK(bounds(ValueInput(node, i)).upper->Is(bounds(node).upper)); 332 CHECK(bounds(ValueInput(node, i)).upper->Is(bounds(node).upper));
334 } 333 }
335 */ 334 */
336 break; 335 break;
337 } 336 }
338 case IrOpcode::kEffectPhi: { 337 case IrOpcode::kEffectPhi: {
339 // EffectPhi input count matches parent control node. 338 // EffectPhi input count matches parent control node.
340 CHECK_EQ(0, value_count); 339 CHECK_EQ(0, value_count);
341 CHECK_EQ(1, control_count); 340 CHECK_EQ(1, control_count);
342 Node* control = NodeProperties::GetControlInput(node, 0); 341 Node* control = NodeProperties::GetControlInput(node, 0);
343 CHECK_EQ(effect_count, 342 CHECK_EQ(effect_count, control->op()->ControlInputCount());
344 OperatorProperties::GetControlInputCount(control->op()));
345 CHECK_EQ(input_count, 1 + effect_count); 343 CHECK_EQ(input_count, 1 + effect_count);
346 break; 344 break;
347 } 345 }
348 case IrOpcode::kValueEffect: 346 case IrOpcode::kValueEffect:
349 // TODO(rossberg): what are the constraints on these? 347 // TODO(rossberg): what are the constraints on these?
350 break; 348 break;
351 case IrOpcode::kFinish: { 349 case IrOpcode::kFinish: {
352 // TODO(rossberg): what are the constraints on these? 350 // TODO(rossberg): what are the constraints on these?
353 // Type must be subsumed by input type. 351 // Type must be subsumed by input type.
354 if (typing == TYPED) { 352 if (typing == TYPED) {
(...skipping 415 matching lines...) Expand 10 before | Expand all | Expand 10 after
770 return true; 768 return true;
771 } 769 }
772 sub = sub->dominator(); 770 sub = sub->dominator();
773 } 771 }
774 return false; 772 return false;
775 } 773 }
776 774
777 775
778 static void CheckInputsDominate(Schedule* schedule, BasicBlock* block, 776 static void CheckInputsDominate(Schedule* schedule, BasicBlock* block,
779 Node* node, int use_pos) { 777 Node* node, int use_pos) {
780 for (int j = OperatorProperties::GetValueInputCount(node->op()) - 1; j >= 0; 778 for (int j = node->op()->ValueInputCount() - 1; j >= 0; j--) {
781 j--) {
782 BasicBlock* use_block = block; 779 BasicBlock* use_block = block;
783 if (node->opcode() == IrOpcode::kPhi) { 780 if (node->opcode() == IrOpcode::kPhi) {
784 use_block = use_block->PredecessorAt(j); 781 use_block = use_block->PredecessorAt(j);
785 use_pos = static_cast<int>(use_block->NodeCount()) - 1; 782 use_pos = static_cast<int>(use_block->NodeCount()) - 1;
786 } 783 }
787 Node* input = node->InputAt(j); 784 Node* input = node->InputAt(j);
788 if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block, 785 if (!HasDominatingDef(schedule, node->InputAt(j), block, use_block,
789 use_pos)) { 786 use_pos)) {
790 V8_Fatal(__FILE__, __LINE__, 787 V8_Fatal(__FILE__, __LINE__,
791 "Node #%d:%s in B%d is not dominated by input@%d #%d:%s", 788 "Node #%d:%s in B%d is not dominated by input@%d #%d:%s",
792 node->id(), node->op()->mnemonic(), block->id().ToInt(), j, 789 node->id(), node->op()->mnemonic(), block->id().ToInt(), j,
793 input->id(), input->op()->mnemonic()); 790 input->id(), input->op()->mnemonic());
794 } 791 }
795 } 792 }
796 // Ensure that nodes are dominated by their control inputs; 793 // Ensure that nodes are dominated by their control inputs;
797 // kEnd is an exception, as unreachable blocks resulting from kMerge 794 // kEnd is an exception, as unreachable blocks resulting from kMerge
798 // are not in the RPO. 795 // are not in the RPO.
799 if (OperatorProperties::GetControlInputCount(node->op()) == 1 && 796 if (node->op()->ControlInputCount() == 1 &&
800 node->opcode() != IrOpcode::kEnd) { 797 node->opcode() != IrOpcode::kEnd) {
801 Node* ctl = NodeProperties::GetControlInput(node); 798 Node* ctl = NodeProperties::GetControlInput(node);
802 if (!Dominates(schedule, ctl, node)) { 799 if (!Dominates(schedule, ctl, node)) {
803 V8_Fatal(__FILE__, __LINE__, 800 V8_Fatal(__FILE__, __LINE__,
804 "Node #%d:%s in B%d is not dominated by control input #%d:%s", 801 "Node #%d:%s in B%d is not dominated by control input #%d:%s",
805 node->id(), node->op()->mnemonic(), block->id(), ctl->id(), 802 node->id(), node->op()->mnemonic(), block->id(), ctl->id(),
806 ctl->op()->mnemonic()); 803 ctl->op()->mnemonic());
807 } 804 }
808 } 805 }
809 } 806 }
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
944 } 941 }
945 942
946 // Verify phis are placed in the block of their control input. 943 // Verify phis are placed in the block of their control input.
947 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end(); 944 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
948 ++b) { 945 ++b) {
949 for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) { 946 for (BasicBlock::const_iterator i = (*b)->begin(); i != (*b)->end(); ++i) {
950 Node* phi = *i; 947 Node* phi = *i;
951 if (phi->opcode() != IrOpcode::kPhi) continue; 948 if (phi->opcode() != IrOpcode::kPhi) continue;
952 // TODO(titzer): Nasty special case. Phis from RawMachineAssembler 949 // TODO(titzer): Nasty special case. Phis from RawMachineAssembler
953 // schedules don't have control inputs. 950 // schedules don't have control inputs.
954 if (phi->InputCount() > 951 if (phi->InputCount() > phi->op()->ValueInputCount()) {
955 OperatorProperties::GetValueInputCount(phi->op())) {
956 Node* control = NodeProperties::GetControlInput(phi); 952 Node* control = NodeProperties::GetControlInput(phi);
957 CHECK(control->opcode() == IrOpcode::kMerge || 953 CHECK(control->opcode() == IrOpcode::kMerge ||
958 control->opcode() == IrOpcode::kLoop); 954 control->opcode() == IrOpcode::kLoop);
959 CHECK_EQ((*b), schedule->block(control)); 955 CHECK_EQ((*b), schedule->block(control));
960 } 956 }
961 } 957 }
962 } 958 }
963 959
964 // Verify that all uses are dominated by their definitions. 960 // Verify that all uses are dominated by their definitions.
965 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end(); 961 for (BasicBlockVector::iterator b = rpo_order->begin(); b != rpo_order->end();
(...skipping 10 matching lines...) Expand all
976 // Check inputs for all nodes in the block. 972 // Check inputs for all nodes in the block.
977 for (size_t i = 0; i < block->NodeCount(); i++) { 973 for (size_t i = 0; i < block->NodeCount(); i++) {
978 Node* node = block->NodeAt(i); 974 Node* node = block->NodeAt(i);
979 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1); 975 CheckInputsDominate(schedule, block, node, static_cast<int>(i) - 1);
980 } 976 }
981 } 977 }
982 } 978 }
983 } 979 }
984 } 980 }
985 } // namespace v8::internal::compiler 981 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/typer.cc ('k') | test/cctest/compiler/simplified-graph-builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698