OLD | NEW |
---|---|
(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 | |
OLD | NEW |