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