OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/il_printer.h" | 5 #include "vm/il_printer.h" |
6 | 6 |
7 #include "vm/intermediate_language.h" | 7 #include "vm/intermediate_language.h" |
8 #include "vm/os.h" | 8 #include "vm/os.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 | 58 |
59 | 59 |
60 void FlowGraphPrinter::PrintComputation(Computation* comp) { | 60 void FlowGraphPrinter::PrintComputation(Computation* comp) { |
61 char str[120]; | 61 char str[120]; |
62 BufferFormatter f(str, sizeof(str)); | 62 BufferFormatter f(str, sizeof(str)); |
63 comp->PrintTo(&f); | 63 comp->PrintTo(&f); |
64 OS::Print("%s", str); | 64 OS::Print("%s", str); |
65 } | 65 } |
66 | 66 |
67 | 67 |
68 | |
69 void Computation::PrintTo(BufferFormatter* f) const { | 68 void Computation::PrintTo(BufferFormatter* f) const { |
70 f->Print("%s(", DebugName()); | 69 f->Print("%s(", DebugName()); |
71 PrintOperandsTo(f); | 70 PrintOperandsTo(f); |
72 f->Print(")"); | 71 f->Print(")"); |
73 } | 72 } |
74 | 73 |
75 | 74 |
76 void Computation::PrintOperandsTo(BufferFormatter* f) const { | 75 void Computation::PrintOperandsTo(BufferFormatter* f) const { |
77 for (int i = 0; i < InputCount(); ++i) { | 76 for (int i = 0; i < InputCount(); ++i) { |
78 if (i > 0) f->Print(", "); | 77 if (i > 0) f->Print(", "); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
344 void BranchInstr::PrintTo(BufferFormatter* f) const { | 343 void BranchInstr::PrintTo(BufferFormatter* f) const { |
345 f->Print(" %s ", DebugName()); | 344 f->Print(" %s ", DebugName()); |
346 f->Print("if "); | 345 f->Print("if "); |
347 value()->PrintTo(f); | 346 value()->PrintTo(f); |
348 f->Print(" goto (%d, %d)", | 347 f->Print(" goto (%d, %d)", |
349 true_successor()->block_id(), | 348 true_successor()->block_id(), |
350 false_successor()->block_id()); | 349 false_successor()->block_id()); |
351 } | 350 } |
352 | 351 |
353 | 352 |
| 353 void FlowGraphVisualizer::Print(const char* format, ...) { |
| 354 OS::FPrint(file_, "%*s", 2 * indent_, ""); |
| 355 va_list args; |
| 356 va_start(args, format); |
| 357 OS::VFPrint(file_, format, args); |
| 358 va_end(args); |
| 359 } |
| 360 |
| 361 |
| 362 void FlowGraphVisualizer::PrintInstruction(Instruction* instr) { |
| 363 char str[120]; |
| 364 BufferFormatter f(str, sizeof(str)); |
| 365 instr->PrintToVisualizer(&f); |
| 366 Print("%s <|@\n", str); |
| 367 } |
| 368 |
| 369 |
| 370 void FlowGraphVisualizer::PrintFunction() { |
| 371 #define BEGIN(name) \ |
| 372 Print("begin_%s\n", name); \ |
| 373 indent_++; |
| 374 #define END(name) \ |
| 375 Print("end_%s\n", name); \ |
| 376 indent_--; |
| 377 |
| 378 { |
| 379 BEGIN("compilation"); |
| 380 const char* name = function_.ToFullyQualifiedCString(); |
| 381 Print("%s \"%s\"\n", "name", name); |
| 382 Print("%s \"%s\"\n", "method", name); |
| 383 Print("%s %d\n", "date", 0); // Required field. Unused. |
| 384 END("compilation"); |
| 385 } |
| 386 |
| 387 { |
| 388 BEGIN("cfg"); |
| 389 Print("%s \"%s\"\n", "name", "Flow graph builder"); |
| 390 |
| 391 for (intptr_t i = 0; i < block_order_.length(); ++i) { |
| 392 BEGIN("block"); |
| 393 BlockEntryInstr* entry = block_order_[i]; |
| 394 Print("%s \"B%d\"\n", "name", entry->block_id()); |
| 395 Print("%s %d\n", "from_bci", -1); // Required field. Unused. |
| 396 Print("%s %d\n", "to_bci", -1); // Required field. Unused. |
| 397 |
| 398 Print("predecessors"); |
| 399 for (intptr_t j = 0; j < entry->PredecessorCount(); ++j) { |
| 400 BlockEntryInstr* pred = entry->PredecessorAt(j); |
| 401 Print(" \"B%d\"", pred->block_id()); |
| 402 } |
| 403 Print("\n"); |
| 404 |
| 405 Print("successors"); |
| 406 Instruction* last = entry->last_instruction(); |
| 407 for (intptr_t j = 0; j < last->SuccessorCount(); ++j) { |
| 408 intptr_t next_id = last->SuccessorAt(j)->block_id(); |
| 409 Print(" \"B%d\"", next_id); |
| 410 } |
| 411 Print("\n"); |
| 412 |
| 413 // TODO(fschneider): Use this for exception handlers. |
| 414 Print("xhandlers\n"); |
| 415 |
| 416 // Can be freely used to mark blocks |
| 417 Print("flags\n"); |
| 418 |
| 419 if (entry->dominator() != NULL) { |
| 420 Print("%s \"B%d\"\n", "dominator", entry->dominator()->block_id()); |
| 421 } |
| 422 |
| 423 // TODO(fschneider): Mark blocks with loop nesting level. |
| 424 Print("%s %d\n", "loop_depth", 0); |
| 425 |
| 426 { |
| 427 BEGIN("states"); // Required section. |
| 428 { |
| 429 BEGIN("locals"); // Required section. |
| 430 // TODO(fschneider): Insert phi-instructions here. |
| 431 intptr_t num_phis = 0; |
| 432 Print("%s %d\n", "size", num_phis); |
| 433 END("locals"); |
| 434 } |
| 435 END("states"); |
| 436 } |
| 437 |
| 438 { |
| 439 BEGIN("HIR"); |
| 440 // Print the block entry. |
| 441 Print("0 0 "); // Required fields "bci" and "use". Unused. |
| 442 Instruction* current = block_order_[i]; |
| 443 PrintInstruction(current); |
| 444 current = current->StraightLineSuccessor(); |
| 445 // And all the successors until an exit, branch, or a block entry. |
| 446 while ((current != NULL) && !current->IsBlockEntry()) { |
| 447 Print("0 0 "); |
| 448 PrintInstruction(current); |
| 449 current = current->StraightLineSuccessor(); |
| 450 } |
| 451 BlockEntryInstr* successor = |
| 452 (current == NULL) ? NULL : current->AsBlockEntry(); |
| 453 if (successor != NULL) { |
| 454 Print("0 0 _ Goto B%d <|@\n", successor->block_id()); |
| 455 } |
| 456 END("HIR"); |
| 457 } |
| 458 END("block"); |
| 459 } |
| 460 END("cfg"); |
| 461 } |
| 462 #undef BEGIN |
| 463 #undef END |
| 464 } |
| 465 |
| 466 |
| 467 // === Printing instructions in a visualizer-understandable format: |
| 468 // "result instruction(op1, op2)" where result is a temporary name |
| 469 // or _ for instruction without result. |
| 470 void GraphEntryInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 471 f->Print("_ [graph]"); |
| 472 } |
| 473 |
| 474 |
| 475 void JoinEntryInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 476 f->Print("_ [join]"); |
| 477 } |
| 478 |
| 479 |
| 480 void TargetEntryInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 481 f->Print("_ [target"); |
| 482 if (HasTryIndex()) { |
| 483 f->Print(" catch %d]", try_index()); |
| 484 } else { |
| 485 f->Print("]"); |
| 486 } |
| 487 } |
| 488 |
| 489 |
| 490 void DoInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 491 f->Print("_ "); |
| 492 computation()->PrintTo(f); |
| 493 } |
| 494 |
| 495 |
| 496 void BindInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 497 f->Print("t%d ", temp_index()); |
| 498 computation()->PrintTo(f); |
| 499 } |
| 500 |
| 501 |
| 502 void ReturnInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 503 f->Print("_ %s ", DebugName()); |
| 504 value()->PrintTo(f); |
| 505 } |
| 506 |
| 507 |
| 508 void ThrowInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 509 f->Print("_ %s ", DebugName()); |
| 510 exception()->PrintTo(f); |
| 511 } |
| 512 |
| 513 |
| 514 void ReThrowInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 515 f->Print("_ %s ", DebugName()); |
| 516 exception()->PrintTo(f); |
| 517 f->Print(", "); |
| 518 stack_trace()->PrintTo(f); |
| 519 } |
| 520 |
| 521 |
| 522 void BranchInstr::PrintToVisualizer(BufferFormatter* f) const { |
| 523 f->Print("_ %s ", DebugName()); |
| 524 f->Print("if "); |
| 525 value()->PrintTo(f); |
| 526 f->Print(" goto (B%d, B%d)", |
| 527 true_successor()->block_id(), |
| 528 false_successor()->block_id()); |
| 529 } |
| 530 |
| 531 |
354 } // namespace dart | 532 } // namespace dart |
OLD | NEW |