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

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

Powered by Google App Engine
This is Rietveld 408576698