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

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 9414003: Initial implementation of a flow-graph builder for Dart's AST. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Rely on assumption that code can reach both branches of a condition. Created 8 years, 10 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
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/handles_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
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.
4
5 #include "vm/flow_graph_builder.h"
6
7 #include "vm/flags.h"
8 #include "vm/intermediate_language.h"
9 #include "vm/os.h"
10 #include "vm/parser.h"
11
12 namespace dart {
13
14 DEFINE_FLAG(bool, trace_bailout, false, "Print bailout from graph builder.");
15 DEFINE_FLAG(bool, print_flow_graph, false, "Print the IR flow graph.");
16 DECLARE_FLAG(bool, enable_type_checks);
17
18 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) {
19 ASSERT(is_open());
20 if (other_fragment.is_empty()) return;
21 if (is_empty()) {
22 entry_ = other_fragment.entry();
23 exit_ = other_fragment.exit();
24 } else {
25 exit()->set_successor(other_fragment.entry());
26 exit_ = other_fragment.exit();
27 }
28 }
29
30
31 void EffectGraphVisitor::AddInstruction(Instruction* instruction) {
32 ASSERT(is_open());
33 if (is_empty()) {
34 entry_ = exit_ = instruction;
35 } else {
36 exit()->set_successor(instruction);
37 exit_ = instruction;
38 }
39 }
40
41
42 void EffectGraphVisitor::Join(const TestGraphVisitor& test_fragment,
43 const EffectGraphVisitor& true_fragment,
44 const EffectGraphVisitor& false_fragment) {
45 // We have: a test graph fragment with zero, one, or two available exits;
46 // and a pair of effect graph fragments with zero or one available exits.
47 // We want to append the branch and (if necessary) a join node to this
48 // graph fragment.
49 ASSERT(is_open());
50
51 // 1. Connect the test to this graph.
52 Append(test_fragment);
53
54 // 2. Connect the true and false bodies to the test if they are reachable,
55 // and if so record their exits (if any).
56 if (test_fragment.can_be_true()) {
57 Instruction* true_exit = NULL;
58 Instruction* false_exit = NULL;
59 TargetEntryInstr* true_entry = new TargetEntryInstr();
60 *test_fragment.true_successor_address() = true_entry;
61 true_entry->set_successor(true_fragment.entry());
62 true_exit = true_fragment.is_empty() ? true_entry : true_fragment.exit();
63
64 TargetEntryInstr* false_entry = new TargetEntryInstr();
65 *test_fragment.false_successor_address() = false_entry;
66 false_entry->set_successor(false_fragment.entry());
67 false_exit =
68 false_fragment.is_empty() ? false_entry : false_fragment.exit();
69
70 exit_ = new JoinEntryInstr();
71 true_exit->set_successor(exit_);
72 false_exit->set_successor(exit_);
73 }
74 }
75
76
77 void EffectGraphVisitor::TieLoop(const TestGraphVisitor& test_fragment,
78 const EffectGraphVisitor& body_fragment) {
79 // We have: a test graph fragment with zero, one, or two available exits;
80 // and an effect graph fragment with zero or one available exits. We want
81 // to append the 'while loop' consisting of the test graph fragment as
82 // condition and the effect graph fragment as body.
83 ASSERT(is_open());
84
85 // 1. Connect the body to the test if it is reachable, and if so record
86 // its exit (if any).
87 Instruction* body_exit = NULL;
88 if (test_fragment.can_be_true()) {
89 TargetEntryInstr* body_entry = new TargetEntryInstr();
90 *test_fragment.true_successor_address() = body_entry;
91 body_entry->set_successor(body_fragment.entry());
92 body_exit = body_fragment.is_empty() ? body_entry : body_fragment.exit();
93 }
94
95 // 2. Connect the test to this graph, including the body if reachable and
96 // using a fresh join node if the body is reachable and has an open exit.
97 if (body_exit == NULL) {
98 Append(test_fragment);
99 } else {
100 JoinEntryInstr* join = new JoinEntryInstr();
101 AddInstruction(join);
102 join->set_successor(test_fragment.entry());
103 body_exit->set_successor(join);
104 }
105
106 // 3. Set the exit to the graph to be empty or a fresh target node
107 // depending on whether the false branch of the test is reachable.
108 if (test_fragment.can_be_false()) {
109 exit_ = *test_fragment.false_successor_address() = new TargetEntryInstr();
110 } else {
111 exit_ = NULL;
112 }
113 }
114
115
116 void TestGraphVisitor::BranchOnValue(Value* value) {
117 BranchInstr* branch = new BranchInstr(value);
118 AddInstruction(branch);
119 CloseFragment();
120 true_successor_address_ = branch->true_successor_address();
121 false_successor_address_ = branch->false_successor_address();
122 }
123
124
125 void EffectGraphVisitor::Bailout(const char* reason) {
126 if (FLAG_trace_bailout) {
127 OS::Print("Flow Graph Bailout: %s\n", reason);
128 }
129 owner()->Bailout(reason);
130 }
131
132
133 // 'bailout' is a statement (without a semicolon), typically a return.
134 #define CHECK_ALIVE(bailout) \
135 do { \
136 if (owner()->HasBailedOut() || !is_open()) { \
137 bailout; \
138 } \
139 } while (false)
140
141
142 // <Statement> ::= Return { value: <Expression>
143 // inlined_finally_list: <InlinedFinally>* }
144 void EffectGraphVisitor::VisitReturnNode(ReturnNode* node) {
145 ValueGraphVisitor for_value(owner(), temp_index());
146 node->value()->Visit(&for_value);
147 Append(for_value);
148 CHECK_ALIVE(return);
149
150 for (intptr_t i = 0; i < node->inlined_finally_list_length(); i++) {
151 EffectGraphVisitor for_effect(owner(), for_value.temp_index());
152 node->InlinedFinallyNodeAt(i)->Visit(&for_effect);
153 Append(for_effect);
154 CHECK_ALIVE(return);
155 }
156
157 Value* return_value = for_value.value();
158 if (FLAG_enable_type_checks) {
159 const RawFunction::Kind kind = owner()->parsed_function().function().kind();
160 // Implicit getters do not need a type check at return.
161 if ((kind != RawFunction::kImplicitGetter) &&
162 (kind != RawFunction::kConstImplicitGetter)) {
163 const AbstractType& type =
164 AbstractType::ZoneHandle(
165 owner()->parsed_function().function().result_type());
166 AssertAssignableComp* assert =
167 new AssertAssignableComp(return_value, type);
168 AddInstruction(new BindInstr(temp_index(), assert));
169 return_value = new TempValue(temp_index());
170 }
171 }
172
173 AddInstruction(new ReturnInstr(return_value));
174 CloseFragment();
175 }
176
177 void ValueGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
178 void TestGraphVisitor::VisitReturnNode(ReturnNode* node) { UNREACHABLE(); }
179
180
181 // <Expression> ::= Literal { literal: Instance }
182 void EffectGraphVisitor::VisitLiteralNode(LiteralNode* node) {
183 return;
184 }
185
186 void ValueGraphVisitor::VisitLiteralNode(LiteralNode* node) {
187 ReturnValue(new ConstantValue(node->literal()));
188 }
189
190 void TestGraphVisitor::VisitLiteralNode(LiteralNode* node) {
191 BranchOnValue(new ConstantValue(node->literal()));
192 }
193
194
195 // Type nodes only occur as the right-hand side of instanceof comparisons,
196 // and they are handled specially in that context.
197 void EffectGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
198 void ValueGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
199 void TestGraphVisitor::VisitTypeNode(TypeNode* node) { UNREACHABLE(); }
200
201
202 // <Expression> :: Assignable { expr: <Expression>
203 // type: AbstractType
204 // dst_name: String }
205 AssertAssignableComp* EffectGraphVisitor::TranslateAssignable(
206 const AssignableNode& node) {
207 ValueGraphVisitor for_value(owner(), temp_index());
208 node.expr()->Visit(&for_value);
209 Append(for_value);
210 CHECK_ALIVE(return NULL);
211
212 return new AssertAssignableComp(for_value.value(), node.type());
213 }
214
215 void EffectGraphVisitor::VisitAssignableNode(AssignableNode* node) {
216 AssertAssignableComp* assert = TranslateAssignable(*node);
217 CHECK_ALIVE(return);
218 DoComputation(assert);
219 }
220
221 void ValueGraphVisitor::VisitAssignableNode(AssignableNode* node) {
222 AssertAssignableComp* assert = TranslateAssignable(*node);
223 CHECK_ALIVE(return);
224 ReturnValueOf(assert);
225 }
226
227
228 void TestGraphVisitor::VisitAssignableNode(AssignableNode* node) {
229 AssertAssignableComp* assert = TranslateAssignable(*node);
230 CHECK_ALIVE(return);
231 BranchOnValueOf(assert);
232 }
233
234
235 // <Expression> :: BinaryOp { kind: Token::Kind
236 // left: <Expression>
237 // right: <Expression> }
238 InstanceCallComp* EffectGraphVisitor::TranslateBinaryOp(
239 const BinaryOpNode& node) {
240 if ((node.kind() == Token::kAND) || (node.kind() == Token::kOR)) {
241 Bailout("EffectGraphVisitor::VisitBinaryOpNode");
242 return NULL;
243 }
244 ValueGraphVisitor for_left_value(owner(), temp_index());
245 node.left()->Visit(&for_left_value);
246 Append(for_left_value);
247 CHECK_ALIVE(return NULL);
248 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
249 node.right()->Visit(&for_right_value);
250 Append(for_right_value);
251 CHECK_ALIVE(return NULL);
252 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
253 arguments->Add(for_left_value.value());
254 arguments->Add(for_right_value.value());
255 return new InstanceCallComp(node.Name(), arguments);
256 }
257
258 void EffectGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
259 InstanceCallComp* call = TranslateBinaryOp(*node);
260 CHECK_ALIVE(return);
261 DoComputation(call);
262 }
263
264 void ValueGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
265 InstanceCallComp* call = TranslateBinaryOp(*node);
266 CHECK_ALIVE(return);
267 ReturnValueOf(call);
268 }
269
270 void TestGraphVisitor::VisitBinaryOpNode(BinaryOpNode* node) {
271 InstanceCallComp* call = TranslateBinaryOp(*node);
272 CHECK_ALIVE(return);
273 BranchOnValueOf(call);
274 }
275
276
277 void EffectGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
278 Bailout("EffectGraphVisitor::VisitStringConcatNode");
279 }
280 void ValueGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
281 Bailout("ValueGraphVisitor::VisitStringConcatNode");
282 }
283 void TestGraphVisitor::VisitStringConcatNode(StringConcatNode* node) {
284 Bailout("TestGraphVisitor::VisitStringConcatNode");
285 }
286
287
288 // <Expression> :: Comparison { kind: Token::Kind
289 // left: <Expression>
290 // right: <Expression> }
291 InstanceCallComp* EffectGraphVisitor::TranslateComparison(
292 const ComparisonNode& node) {
293 if (Token::IsInstanceofOperator(node.kind()) ||
294 Token::IsEqualityOperator(node.kind())) {
295 Bailout("Some kind of comparison we don't handle yet");
296 return NULL;
297 }
298 ValueGraphVisitor for_left_value(owner(), temp_index());
299 node.left()->Visit(&for_left_value);
300 Append(for_left_value);
301 CHECK_ALIVE(return NULL);
302 ValueGraphVisitor for_right_value(owner(), for_left_value.temp_index());
303 node.right()->Visit(&for_right_value);
304 Append(for_right_value);
305 CHECK_ALIVE(return NULL);
306 ZoneGrowableArray<Value*>* arguments = new ZoneGrowableArray<Value*>(2);
307 arguments->Add(for_left_value.value());
308 arguments->Add(for_right_value.value());
309 return new InstanceCallComp(node.Name(), arguments);
310 }
311
312 void EffectGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
313 InstanceCallComp* call = TranslateComparison(*node);
314 CHECK_ALIVE(return);
315 DoComputation(call);
316 }
317
318 void ValueGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
319 InstanceCallComp* call = TranslateComparison(*node);
320 CHECK_ALIVE(return);
321 ReturnValueOf(call);
322 }
323
324 void TestGraphVisitor::VisitComparisonNode(ComparisonNode* node) {
325 InstanceCallComp* call = TranslateComparison(*node);
326 CHECK_ALIVE(return);
327 BranchOnValueOf(call);
328 }
329
330
331 void EffectGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
332 Bailout("EffectGraphVisitor::VisitUnaryOpNode");
333 }
334 void ValueGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
335 Bailout("ValueGraphVisitor::VisitUnaryOpNode");
336 }
337 void TestGraphVisitor::VisitUnaryOpNode(UnaryOpNode* node) {
338 Bailout("TestGraphVisitor::VisitUnaryOpNode");
339 }
340
341
342 void EffectGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
343 Bailout("EffectGraphVisitor::VisitIncrOpLocalNode");
344 }
345 void ValueGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
346 Bailout("ValueGraphVisitor::VisitIncrOpLocalNode");
347 }
348 void TestGraphVisitor::VisitIncrOpLocalNode(IncrOpLocalNode* node) {
349 Bailout("TestGraphVisitor::VisitIncrOpLocalNode");
350 }
351
352
353 void EffectGraphVisitor::VisitIncrOpInstanceFieldNode(
354 IncrOpInstanceFieldNode* node) {
355 Bailout("EffectGraphVisitor::VisitIncrOpInstanceFieldNode");
356 }
357 void ValueGraphVisitor::VisitIncrOpInstanceFieldNode(
358 IncrOpInstanceFieldNode* node) {
359 Bailout("ValueGraphVisitor::VisitIncrOpInstanceFieldNode");
360 }
361 void TestGraphVisitor::VisitIncrOpInstanceFieldNode(
362 IncrOpInstanceFieldNode* node) {
363 Bailout("TestGraphVisitor::VisitIncrOpInstanceFieldNode");
364 }
365
366
367 void EffectGraphVisitor::VisitIncrOpStaticFieldNode(
368 IncrOpStaticFieldNode* node) {
369 Bailout("EffectGraphVisitor::VisitIncrOpStaticFieldNode");
370 }
371 void ValueGraphVisitor::VisitIncrOpStaticFieldNode(
372 IncrOpStaticFieldNode* node) {
373 Bailout("ValueGraphVisitor::VisitIncrOpStaticFieldNode");
374 }
375 void TestGraphVisitor::VisitIncrOpStaticFieldNode(IncrOpStaticFieldNode* node) {
376 Bailout("TestGraphVisitor::VisitIncrOpStaticFieldNode");
377 }
378
379
380 void EffectGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
381 Bailout("EffectGraphVisitor::VisitIncrOpIndexedNode");
382 }
383 void ValueGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
384 Bailout("ValueGraphVisitor::VisitIncrOpIndexedNode");
385 }
386 void TestGraphVisitor::VisitIncrOpIndexedNode(IncrOpIndexedNode* node) {
387 Bailout("TestGraphVisitor::VisitIncrOpIndexedNode");
388 }
389
390
391 void EffectGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
392 Bailout("EffectGraphVisitor::VisitConditionalExprNode");
393 }
394 void ValueGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
395 Bailout("ValueGraphVisitor::VisitConditionalExprNode");
396 }
397 void TestGraphVisitor::VisitConditionalExprNode(ConditionalExprNode* node) {
398 Bailout("TestGraphVisitor::VisitConditionalExprNode");
399 }
400
401
402 // <Statement> ::= If { condition: <Expression>
403 // true_branch: <Sequence>
404 // false_branch: <Sequence> }
405 void EffectGraphVisitor::VisitIfNode(IfNode* node) {
406 TestGraphVisitor for_test(owner(), temp_index());
407 node->condition()->Visit(&for_test);
408 Append(for_test);
409
410 EffectGraphVisitor for_true(owner(), temp_index());
411 EffectGraphVisitor for_false(owner(), temp_index());
412
413 if (for_test.can_be_true()) {
414 node->true_branch()->Visit(&for_true);
415 // The for_false graph fragment will be empty (default graph fragment)
416 // if we do not call Visit.
417 if (node->false_branch() != NULL) node->false_branch()->Visit(&for_false);
418 }
419 Join(for_test, for_true, for_false);
420 }
421
422 void ValueGraphVisitor::VisitIfNode(IfNode* node) { UNREACHABLE(); }
423 void TestGraphVisitor::VisitIfNode(IfNode* node) { UNREACHABLE(); }
424
425
426 void EffectGraphVisitor::VisitSwitchNode(SwitchNode* node) {
427 Bailout("EffectGraphVisitor::VisitSwitchNode");
428 }
429 void ValueGraphVisitor::VisitSwitchNode(SwitchNode* node) {
430 Bailout("ValueGraphVisitor::VisitSwitchNode");
431 }
432 void TestGraphVisitor::VisitSwitchNode(SwitchNode* node) {
433 Bailout("TestGraphVisitor::VisitSwitchNode");
434 }
435
436
437 void EffectGraphVisitor::VisitCaseNode(CaseNode* node) {
438 Bailout("EffectGraphVisitor::VisitCaseNode");
439 }
440 void ValueGraphVisitor::VisitCaseNode(CaseNode* node) {
441 Bailout("ValueGraphVisitor::VisitCaseNode");
442 }
443 void TestGraphVisitor::VisitCaseNode(CaseNode* node) {
444 Bailout("TestGraphVisitor::VisitCaseNode");
445 }
446
447
448 // <Statement> ::= While { label: SourceLabel
449 // condition: <Expression>
450 // body: <Sequence> }
451 void EffectGraphVisitor::VisitWhileNode(WhileNode* node) {
452 TestGraphVisitor for_test(owner(), temp_index());
453 node->condition()->Visit(&for_test);
454
455 EffectGraphVisitor for_body(owner(), temp_index());
456 if (for_test.can_be_true()) node->body()->Visit(&for_body);
457 TieLoop(for_test, for_body);
458 }
459
460 void ValueGraphVisitor::VisitWhileNode(WhileNode* node) { UNREACHABLE(); }
461 void TestGraphVisitor::VisitWhileNode(WhileNode* node) { UNREACHABLE(); }
462
463
464 void EffectGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
465 Bailout("EffectGraphVisitor::VisitDoWhileNode");
466 }
467 void ValueGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
468 Bailout("ValueGraphVisitor::VisitDoWhileNode");
469 }
470 void TestGraphVisitor::VisitDoWhileNode(DoWhileNode* node) {
471 Bailout("TestGraphVisitor::VisitDoWhileNode");
472 }
473
474
475 void EffectGraphVisitor::VisitForNode(ForNode* node) {
476 Bailout("EffectGraphVisitor::VisitForNode");
477 }
478 void ValueGraphVisitor::VisitForNode(ForNode* node) {
479 Bailout("ValueGraphVisitor::VisitForNode");
480 }
481 void TestGraphVisitor::VisitForNode(ForNode* node) {
482 Bailout("TestGraphVisitor::VisitForNode");
483 }
484
485
486 void EffectGraphVisitor::VisitJumpNode(JumpNode* node) {
487 Bailout("EffectGraphVisitor::VisitJumpNode");
488 }
489 void ValueGraphVisitor::VisitJumpNode(JumpNode* node) {
490 Bailout("ValueGraphVisitor::VisitJumpNode");
491 }
492 void TestGraphVisitor::VisitJumpNode(JumpNode* node) {
493 Bailout("TestGraphVisitor::VisitJumpNode");
494 }
495
496
497 void EffectGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
498 UNREACHABLE();
499 }
500 void ValueGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
501 UNREACHABLE();
502 }
503 void TestGraphVisitor::VisitArgumentListNode(ArgumentListNode* node) {
504 UNREACHABLE();
505 }
506
507
508 void EffectGraphVisitor::VisitArrayNode(ArrayNode* node) {
509 Bailout("EffectGraphVisitor::VisitArrayNode");
510 }
511 void ValueGraphVisitor::VisitArrayNode(ArrayNode* node) {
512 Bailout("ValueGraphVisitor::VisitArrayNode");
513 }
514 void TestGraphVisitor::VisitArrayNode(ArrayNode* node) {
515 Bailout("TestGraphVisitor::VisitArrayNode");
516 }
517
518
519 void EffectGraphVisitor::VisitClosureNode(ClosureNode* node) {
520 Bailout("EffectGraphVisitor::VisitClosureNode");
521 }
522 void ValueGraphVisitor::VisitClosureNode(ClosureNode* node) {
523 Bailout("ValueGraphVisitor::VisitClosureNode");
524 }
525 void TestGraphVisitor::VisitClosureNode(ClosureNode* node) {
526 Bailout("TestGraphVisitor::VisitClosureNode");
527 }
528
529
530 void EffectGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
531 Bailout("EffectGraphVisitor::VisitInstanceCallNode");
532 }
533 void ValueGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
534 Bailout("ValueGraphVisitor::VisitInstanceCallNode");
535 }
536 void TestGraphVisitor::VisitInstanceCallNode(InstanceCallNode* node) {
537 Bailout("TestGraphVisitor::VisitInstanceCallNode");
538 }
539
540
541 // <Expression> ::= StaticCall { function: Function
542 // arguments: <ArgumentList> }
543 StaticCallComp* EffectGraphVisitor::TranslateStaticCall(
544 const StaticCallNode& node) {
545 ArgumentListNode* arguments = node.arguments();
546 int length = arguments->length();
547 ZoneGrowableArray<Value*>* values = new ZoneGrowableArray<Value*>(length);
548 int index = temp_index();
549 for (intptr_t i = 0; i < length; ++i) {
550 ValueGraphVisitor for_value(owner(), index);
551 arguments->NodeAt(i)->Visit(&for_value);
552 Append(for_value);
553 CHECK_ALIVE(return NULL);
554 values->Add(for_value.value());
555 index = for_value.temp_index();
556 }
557 return new StaticCallComp(node.function(), values);
558 }
559
560 void EffectGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
561 StaticCallComp* call = TranslateStaticCall(*node);
562 CHECK_ALIVE(return);
563 DoComputation(call);
564 }
565
566 void ValueGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
567 StaticCallComp* call = TranslateStaticCall(*node);
568 CHECK_ALIVE(return);
569 ReturnValueOf(call);
570 }
571
572 void TestGraphVisitor::VisitStaticCallNode(StaticCallNode* node) {
573 StaticCallComp* call = TranslateStaticCall(*node);
574 CHECK_ALIVE(return);
575 BranchOnValueOf(call);
576 }
577
578
579 void EffectGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
580 Bailout("EffectGraphVisitor::VisitClosureCallNode");
581 }
582 void ValueGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
583 Bailout("ValueGraphVisitor::VisitClosureCallNode");
584 }
585 void TestGraphVisitor::VisitClosureCallNode(ClosureCallNode* node) {
586 Bailout("TestGraphVisitor::VisitClosureCallNode");
587 }
588
589
590 void EffectGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
591 Bailout("EffectGraphVisitor::VisitCloneContextNode");
592 }
593 void ValueGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
594 Bailout("ValueGraphVisitor::VisitCloneContextNode");
595 }
596 void TestGraphVisitor::VisitCloneContextNode(CloneContextNode* node) {
597 Bailout("TestGraphVisitor::VisitCloneContextNode");
598 }
599
600
601 void EffectGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
602 Bailout("EffectGraphVisitor::VisitConstructorCallNode");
603 }
604 void ValueGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
605 Bailout("ValueGraphVisitor::VisitConstructorCallNode");
606 }
607 void TestGraphVisitor::VisitConstructorCallNode(ConstructorCallNode* node) {
608 Bailout("TestGraphVisitor::VisitConstructorCallNode");
609 }
610
611
612 void EffectGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
613 Bailout("EffectGraphVisitor::VisitInstanceGetterNode");
614 }
615 void ValueGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
616 Bailout("ValueGraphVisitor::VisitInstanceGetterNode");
617 }
618 void TestGraphVisitor::VisitInstanceGetterNode(InstanceGetterNode* node) {
619 Bailout("TestGraphVisitor::VisitInstanceGetterNode");
620 }
621
622
623 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
624 Bailout("EffectGraphVisitor::VisitInstanceSetterNode");
625 }
626 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
627 Bailout("ValueGraphVisitor::VisitInstanceSetterNode");
628 }
629 void TestGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
630 Bailout("TestGraphVisitor::VisitInstanceSetterNode");
631 }
632
633
634 void EffectGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
635 Bailout("EffectGraphVisitor::VisitStaticGetterNode");
636 }
637 void ValueGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
638 Bailout("ValueGraphVisitor::VisitStaticGetterNode");
639 }
640 void TestGraphVisitor::VisitStaticGetterNode(StaticGetterNode* node) {
641 Bailout("TestGraphVisitor::VisitStaticGetterNode");
642 }
643
644
645 void EffectGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
646 Bailout("EffectGraphVisitor::VisitStaticSetterNode");
647 }
648 void ValueGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
649 Bailout("ValueGraphVisitor::VisitStaticSetterNode");
650 }
651 void TestGraphVisitor::VisitStaticSetterNode(StaticSetterNode* node) {
652 Bailout("TestGraphVisitor::VisitStaticSetterNode");
653 }
654
655
656 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
657 Bailout("EffectGraphVisitor::VisitNativeBodyNode");
658 }
659 void ValueGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
660 Bailout("ValueGraphVisitor::VisitNativeBodyNode");
661 }
662 void TestGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
663 Bailout("TestGraphVisitor::VisitNativeBodyNode");
664 }
665
666
667 void EffectGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
668 Bailout("EffectGraphVisitor::VisitPrimaryNode");
669 }
670 void ValueGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
671 Bailout("ValueGraphVisitor::VisitPrimaryNode");
672 }
673 void TestGraphVisitor::VisitPrimaryNode(PrimaryNode* node) {
674 Bailout("TestGraphVisitor::VisitPrimaryNode");
675 }
676
677
678 // <Expression> ::= LoadLocal { local: LocalVariable }
679 void EffectGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
680 return;
681 }
682
683 void ValueGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
684 LoadLocalComp* load = new LoadLocalComp(node->local());
685 ReturnValueOf(load);
686 }
687
688 void TestGraphVisitor::VisitLoadLocalNode(LoadLocalNode* node) {
689 LoadLocalComp* load = new LoadLocalComp(node->local());
690 BranchOnValueOf(load);
691 }
692
693
694 // <Expression> ::= StoreLocal { local: LocalVariable
695 // value: <Expression> }
696 StoreLocalComp* EffectGraphVisitor::TranslateStoreLocal(
697 const StoreLocalNode& node) {
698 ValueGraphVisitor for_value(owner(), temp_index());
699 node.value()->Visit(&for_value);
700 Append(for_value);
701 CHECK_ALIVE(return NULL);
702 return new StoreLocalComp(node.local(), for_value.value());
703 }
704
705 void EffectGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
706 StoreLocalComp* store = TranslateStoreLocal(*node);
707 CHECK_ALIVE(return);
708 DoComputation(store);
709 }
710
711 void ValueGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
712 StoreLocalComp* store = TranslateStoreLocal(*node);
713 CHECK_ALIVE(return);
714 ReturnValueOf(store);
715 }
716
717 void TestGraphVisitor::VisitStoreLocalNode(StoreLocalNode* node) {
718 StoreLocalComp* store = TranslateStoreLocal(*node);
719 CHECK_ALIVE(return);
720 BranchOnValueOf(store);
721 }
722
723
724 void EffectGraphVisitor::VisitLoadInstanceFieldNode(
725 LoadInstanceFieldNode* node) {
726 Bailout("EffectGraphVisitor::VisitLoadInstanceFieldNode");
727 }
728 void ValueGraphVisitor::VisitLoadInstanceFieldNode(
729 LoadInstanceFieldNode* node) {
730 Bailout("ValueGraphVisitor::VisitLoadInstanceFieldNode");
731 }
732 void TestGraphVisitor::VisitLoadInstanceFieldNode(LoadInstanceFieldNode* node) {
733 Bailout("TestGraphVisitor::VisitLoadInstanceFieldNode");
734 }
735
736
737 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
738 StoreInstanceFieldNode* node) {
739 Bailout("EffectGraphVisitor::VisitStoreInstanceFieldNode");
740 }
741 void ValueGraphVisitor::VisitStoreInstanceFieldNode(
742 StoreInstanceFieldNode* node) {
743 Bailout("ValueGraphVisitor::VisitStoreInstanceFieldNode");
744 }
745 void TestGraphVisitor::VisitStoreInstanceFieldNode(
746 StoreInstanceFieldNode* node) {
747 Bailout("TestGraphVisitor::VisitStoreInstanceFieldNode");
748 }
749
750
751 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
752 Bailout("EffectGraphVisitor::VisitLoadStaticFieldNode");
753 }
754 void ValueGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
755 Bailout("ValueGraphVisitor::VisitLoadStaticFieldNode");
756 }
757 void TestGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
758 Bailout("TestGraphVisitor::VisitLoadStaticFieldNode");
759 }
760
761
762 void EffectGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
763 Bailout("EffectGraphVisitor::VisitStoreStaticFieldNode");
764 }
765 void ValueGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
766 Bailout("ValueGraphVisitor::VisitStoreStaticFieldNode");
767 }
768 void TestGraphVisitor::VisitStoreStaticFieldNode(StoreStaticFieldNode* node) {
769 Bailout("TestGraphVisitor::VisitStoreStaticFieldNode");
770 }
771
772
773 void EffectGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
774 Bailout("EffectGraphVisitor::VisitLoadIndexedNode");
775 }
776 void ValueGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
777 Bailout("ValueGraphVisitor::VisitLoadIndexedNode");
778 }
779 void TestGraphVisitor::VisitLoadIndexedNode(LoadIndexedNode* node) {
780 Bailout("TestGraphVisitor::VisitLoadIndexedNode");
781 }
782
783
784 void EffectGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
785 Bailout("EffectGraphVisitor::VisitStoreIndexedNode");
786 }
787 void ValueGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
788 Bailout("ValueGraphVisitor::VisitStoreIndexedNode");
789 }
790 void TestGraphVisitor::VisitStoreIndexedNode(StoreIndexedNode* node) {
791 Bailout("TestGraphVisitor::VisitStoreIndexedNode");
792 }
793
794
795 // <Statement> ::= Sequence { scope: LocalScope
796 // nodes: <Statement>*
797 // label: SourceLabel }
798 void EffectGraphVisitor::VisitSequenceNode(SequenceNode* node) {
799 if ((node->scope() != NULL) &&
800 (node->scope()->num_context_variables() != 0)) {
801 Bailout("Sequence needs a context. Gotta have a context.");
802 }
803 for (intptr_t i = 0; i < node->length(); ++i) {
804 EffectGraphVisitor for_effect(owner(), temp_index());
805 node->NodeAt(i)->Visit(&for_effect);
806 Append(for_effect);
807 CHECK_ALIVE(return);
808 }
809 }
810
811 void ValueGraphVisitor::VisitSequenceNode(SequenceNode* node) { UNREACHABLE(); }
812 void TestGraphVisitor::VisitSequenceNode(SequenceNode* node) { UNREACHABLE(); }
813
814
815 void EffectGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
816 Bailout("EffectGraphVisitor::VisitCatchClauseNode");
817 }
818 void ValueGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
819 Bailout("ValueGraphVisitor::VisitCatchClauseNode");
820 }
821 void TestGraphVisitor::VisitCatchClauseNode(CatchClauseNode* node) {
822 Bailout("TestGraphVisitor::VisitCatchClauseNode");
823 }
824
825
826 void EffectGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
827 Bailout("EffectGraphVisitor::VisitTryCatchNode");
828 }
829 void ValueGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
830 Bailout("ValueGraphVisitor::VisitTryCatchNode");
831 }
832 void TestGraphVisitor::VisitTryCatchNode(TryCatchNode* node) {
833 Bailout("TestGraphVisitor::VisitTryCatchNode");
834 }
835
836
837 void EffectGraphVisitor::VisitThrowNode(ThrowNode* node) {
838 Bailout("EffectGraphVisitor::VisitThrowNode");
839 }
840 void ValueGraphVisitor::VisitThrowNode(ThrowNode* node) {
841 Bailout("ValueGraphVisitor::VisitThrowNode");
842 }
843 void TestGraphVisitor::VisitThrowNode(ThrowNode* node) {
844 Bailout("TestGraphVisitor::VisitThrowNode");
845 }
846
847
848 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
849 Bailout("EffectGraphVisitor::VisitInlinedFinallyNode");
850 }
851 void ValueGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
852 Bailout("ValueGraphVisitor::VisitInlinedFinallyNode");
853 }
854 void TestGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
855 Bailout("TestGraphVisitor::VisitInlinedFinallyNode");
856 }
857
858
859 void FlowGraphBuilder::TraceBailout() const {
860 if (FLAG_trace_bailout && HasBailedOut()) {
861 OS::Print("Failed: %s in %s\n",
862 bailout_reason_,
863 parsed_function().function().ToFullyQualifiedCString());
864 }
865 }
866
867
868 void FlowGraphBuilder::PrintGraph() const {
869 if (!FLAG_print_flow_graph || HasBailedOut()) return;
870
871 OS::Print("==== %s\n",
872 parsed_function().function().ToFullyQualifiedCString());
873
874 for (intptr_t i = postorder_.length() - 1; i >= 0; --i) {
875 OS::Print("%8d: ", postorder_.length() - i);
876 postorder_[i]->Print(i, postorder_);
877 OS::Print("\n");
878 }
879 OS::Print("\n");
880 }
881
882
883 void FlowGraphBuilder::BuildGraph() {
884 EffectGraphVisitor for_effect(this, 0);
885 parsed_function().node_sequence()->Visit(&for_effect);
886 TraceBailout();
887 if (!HasBailedOut() && (for_effect.entry() != NULL)) {
888 for_effect.entry()->Postorder(&postorder_);
889 }
890 PrintGraph();
891 }
892
893 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/handles_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698