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

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

Issue 9719003: Compute preorder as well as postorder basic block orderings. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/flow_graph_builder.h" 5 #include "vm/flow_graph_builder.h"
6 6
7 #include "vm/ast_printer.h" 7 #include "vm/ast_printer.h"
8 #include "vm/flags.h" 8 #include "vm/flags.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/longjump.h" 10 #include "vm/longjump.h"
(...skipping 1310 matching lines...) Expand 10 before | Expand all | Expand 10 after
1321 1321
1322 1322
1323 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) { 1323 void EffectGraphVisitor::VisitInlinedFinallyNode(InlinedFinallyNode* node) {
1324 Bailout("EffectGraphVisitor::VisitInlinedFinallyNode"); 1324 Bailout("EffectGraphVisitor::VisitInlinedFinallyNode");
1325 } 1325 }
1326 1326
1327 1327
1328 // Graph printing. 1328 // Graph printing.
1329 class FlowGraphPrinter : public FlowGraphVisitor { 1329 class FlowGraphPrinter : public FlowGraphVisitor {
1330 public: 1330 public:
1331 explicit FlowGraphPrinter(const Function& function) : function_(function) { } 1331 explicit FlowGraphPrinter(const Function& function,
1332 const GrowableArray<BlockEntryInstr*>& block_order)
srdjan 2012/03/16 22:01:17 remove explicit.
Kevin Millikin (Google) 2012/03/16 22:18:32 Thanks.
1333 : FlowGraphVisitor(block_order), function_(function) { }
1332 1334
1333 virtual ~FlowGraphPrinter() {} 1335 virtual ~FlowGraphPrinter() {}
1334 1336
1335 // Print the instructions in a block terminated by newlines. Add "goto N" 1337 // Print the instructions in a block terminated by newlines. Add "goto N"
1336 // to the end of the block if it ends with an unconditional jump to 1338 // to the end of the block if it ends with an unconditional jump to
1337 // another block and that block is not next in reverse postorder. 1339 // another block and that block is not next in reverse postorder.
1338 void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order); 1340 void VisitBlocks();
1339 1341
1340 // Visiting a computation prints it with no indentation or newline. 1342 // Visiting a computation prints it with no indentation or newline.
1341 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ 1343 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \
1342 virtual void Visit##ShortName(ClassName* comp); 1344 virtual void Visit##ShortName(ClassName* comp);
1343 1345
1344 // Visiting an instruction prints it with a four space indent and no 1346 // Visiting an instruction prints it with a four space indent and no
1345 // trailing newline. Basic block entries are labeled with their block 1347 // trailing newline. Basic block entries are labeled with their block
1346 // number. 1348 // number.
1347 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ 1349 #define DECLARE_VISIT_INSTRUCTION(ShortName) \
1348 virtual void Visit##ShortName(ShortName##Instr* instr); 1350 virtual void Visit##ShortName(ShortName##Instr* instr);
1349 1351
1350 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) 1352 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION)
1351 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) 1353 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION)
1352 1354
1353 #undef DECLARE_VISIT_COMPUTATION 1355 #undef DECLARE_VISIT_COMPUTATION
1354 #undef DECLARE_VISIT_INSTRUCTION 1356 #undef DECLARE_VISIT_INSTRUCTION
1355 1357
1356 private: 1358 private:
1357 const Function& function_; 1359 const Function& function_;
1358 1360
1359 DISALLOW_COPY_AND_ASSIGN(FlowGraphPrinter); 1361 DISALLOW_COPY_AND_ASSIGN(FlowGraphPrinter);
1360 }; 1362 };
1361 1363
1362 1364
1363 void FlowGraphPrinter::VisitBlocks( 1365 void FlowGraphPrinter::VisitBlocks() {
1364 const GrowableArray<BlockEntryInstr*>& block_order) {
1365 OS::Print("==== %s\n", function_.ToFullyQualifiedCString()); 1366 OS::Print("==== %s\n", function_.ToFullyQualifiedCString());
1366 1367
1367 for (intptr_t i = block_order.length() - 1; i >= 0; --i) { 1368 for (intptr_t i = 0; i < block_order_.length(); ++i) {
1368 // Print the block entry. 1369 // Print the block entry.
1369 Instruction* current = block_order[i]->Accept(this); 1370 Instruction* current = block_order_[i]->Accept(this);
1370 // And all the successors until an exit, branch, or a block entry. 1371 // And all the successors until an exit, branch, or a block entry.
1371 while ((current != NULL) && !current->IsBlockEntry()) { 1372 while ((current != NULL) && !current->IsBlockEntry()) {
1372 OS::Print("\n"); 1373 OS::Print("\n");
1373 current = current->Accept(this); 1374 current = current->Accept(this);
1374 } 1375 }
1375 BlockEntryInstr* successor = 1376 BlockEntryInstr* successor =
1376 (current == NULL) ? NULL : current->AsBlockEntry(); 1377 (current == NULL) ? NULL : current->AsBlockEntry();
1377 if (successor != NULL) { 1378 if (successor != NULL) {
1378 OS::Print(" goto %d", successor->block_number()); 1379 // For readability label blocks with their reverse postorder index,
1380 // not their postorder block number, so the first block is 0 (not
1381 // n-1).
1382 OS::Print(" goto %d", reverse_index(successor->postorder_number()));
1379 } 1383 }
1380 OS::Print("\n"); 1384 OS::Print("\n");
1381 } 1385 }
1382 } 1386 }
1383 1387
1384 1388
1385 void FlowGraphPrinter::VisitTemp(TempVal* val) { 1389 void FlowGraphPrinter::VisitTemp(TempVal* val) {
1386 OS::Print("t%d", val->index()); 1390 OS::Print("t%d", val->index());
1387 } 1391 }
1388 1392
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
1582 ExtractConstructorInstantiatorComp* comp) { 1586 ExtractConstructorInstantiatorComp* comp) {
1583 OS::Print("ExtractConstructorInstantiator("); 1587 OS::Print("ExtractConstructorInstantiator(");
1584 comp->instantiator()->Accept(this); 1588 comp->instantiator()->Accept(this);
1585 OS::Print(", "); 1589 OS::Print(", ");
1586 comp->discard_value()->Accept(this); 1590 comp->discard_value()->Accept(this);
1587 OS::Print(")"); 1591 OS::Print(")");
1588 } 1592 }
1589 1593
1590 1594
1591 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) { 1595 void FlowGraphPrinter::VisitJoinEntry(JoinEntryInstr* instr) {
1592 OS::Print("%2d: [join]", instr->block_number()); 1596 OS::Print("%2d: [join]", reverse_index(instr->postorder_number()));
1593 } 1597 }
1594 1598
1595 1599
1596 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) { 1600 void FlowGraphPrinter::VisitTargetEntry(TargetEntryInstr* instr) {
1597 OS::Print("%2d: [target]", instr->block_number()); 1601 OS::Print("%2d: [target]", reverse_index(instr->postorder_number()));
1598 } 1602 }
1599 1603
1600 1604
1601 void FlowGraphPrinter::VisitPickTemp(PickTempInstr* instr) { 1605 void FlowGraphPrinter::VisitPickTemp(PickTempInstr* instr) {
1602 OS::Print(" t%d <- Pick(t%d)", instr->destination(), instr->source()); 1606 OS::Print(" t%d <- Pick(t%d)", instr->destination(), instr->source());
1603 } 1607 }
1604 1608
1605 1609
1606 void FlowGraphPrinter::VisitTuckTemp(TuckTempInstr* instr) { 1610 void FlowGraphPrinter::VisitTuckTemp(TuckTempInstr* instr) {
1607 OS::Print(" t%d := t%d", instr->destination(), instr->source()); 1611 OS::Print(" t%d := t%d", instr->destination(), instr->source());
(...skipping 30 matching lines...) Expand all
1638 instr->exception()->Accept(this); 1642 instr->exception()->Accept(this);
1639 OS::Print(", "); 1643 OS::Print(", ");
1640 instr->stack_trace()->Accept(this); 1644 instr->stack_trace()->Accept(this);
1641 OS::Print(")"); 1645 OS::Print(")");
1642 } 1646 }
1643 1647
1644 1648
1645 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) { 1649 void FlowGraphPrinter::VisitBranch(BranchInstr* instr) {
1646 OS::Print(" if "); 1650 OS::Print(" if ");
1647 instr->value()->Accept(this); 1651 instr->value()->Accept(this);
1648 OS::Print(" goto(%d, %d)", instr->true_successor()->block_number(), 1652 OS::Print(" goto(%d, %d)",
1649 instr->false_successor()->block_number()); 1653 reverse_index(instr->true_successor()->postorder_number()),
1654 reverse_index(instr->false_successor()->postorder_number()));
1650 } 1655 }
1651 1656
1652 1657
1653 void FlowGraphBuilder::BuildGraph() { 1658 void FlowGraphBuilder::BuildGraph() {
1654 if (FLAG_print_ast) { 1659 if (FLAG_print_ast) {
1655 // Print the function ast before IL generation. 1660 // Print the function ast before IL generation.
1656 AstPrinter::PrintFunctionNodes(parsed_function()); 1661 AstPrinter::PrintFunctionNodes(parsed_function());
1657 } 1662 }
1658 const Function& function = parsed_function().function(); 1663 const Function& function = parsed_function().function();
1659 EffectGraphVisitor for_effect(this, 0); 1664 EffectGraphVisitor for_effect(this, 0);
1660 for_effect.AddInstruction(new TargetEntryInstr()); 1665 for_effect.AddInstruction(new TargetEntryInstr());
1661 parsed_function().node_sequence()->Visit(&for_effect); 1666 parsed_function().node_sequence()->Visit(&for_effect);
1662 // Check that the graph is properly terminated. 1667 // Check that the graph is properly terminated.
1663 ASSERT(!for_effect.is_open()); 1668 ASSERT(!for_effect.is_open());
1664 if (for_effect.entry() != NULL) { 1669 if (for_effect.entry() != NULL) {
1665 // Accumulate basic block entries via postorder traversal. 1670 // Perform a depth-first traversal of the graph to build preorder and
1666 for_effect.entry()->Postorder(&postorder_block_entries_); 1671 // postorder block orders.
1667 // Number the blocks in reverse postorder starting with 0. 1672 for_effect.entry()->DepthFirstSearch(&preorder_block_entries_,
1668 intptr_t last_index = postorder_block_entries_.length() - 1; 1673 &postorder_block_entries_);
1669 for (intptr_t i = last_index; i >= 0; --i) {
1670 postorder_block_entries_[i]->set_block_number(last_index - i);
1671 }
1672 } 1674 }
1673 if (FLAG_print_flow_graph) { 1675 if (FLAG_print_flow_graph) {
1674 FlowGraphPrinter printer(function); 1676 intptr_t length = postorder_block_entries_.length();
1675 printer.VisitBlocks(postorder_block_entries_); 1677 GrowableArray<BlockEntryInstr*> reverse_postorder(length);
1678 for (intptr_t i = length - 1; i >= 0; --i) {
1679 reverse_postorder.Add(postorder_block_entries_[i]);
1680 }
1681 FlowGraphPrinter printer(function, reverse_postorder);
1682 printer.VisitBlocks();
1676 } 1683 }
1677 } 1684 }
1678 1685
1679 1686
1680 void FlowGraphBuilder::Bailout(const char* reason) { 1687 void FlowGraphBuilder::Bailout(const char* reason) {
1681 const char* kFormat = "FlowGraphBuilder Bailout: %s %s"; 1688 const char* kFormat = "FlowGraphBuilder Bailout: %s %s";
1682 const char* function_name = parsed_function_.function().ToCString(); 1689 const char* function_name = parsed_function_.function().ToCString();
1683 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; 1690 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1;
1684 char* chars = reinterpret_cast<char*>( 1691 char* chars = reinterpret_cast<char*>(
1685 Isolate::Current()->current_zone()->Allocate(len)); 1692 Isolate::Current()->current_zone()->Allocate(len));
1686 OS::SNPrint(chars, len, kFormat, function_name, reason); 1693 OS::SNPrint(chars, len, kFormat, function_name, reason);
1687 const Error& error = Error::Handle( 1694 const Error& error = Error::Handle(
1688 LanguageError::New(String::Handle(String::New(chars)))); 1695 LanguageError::New(String::Handle(String::New(chars))));
1689 Isolate::Current()->long_jump_base()->Jump(1, error); 1696 Isolate::Current()->long_jump_base()->Jump(1, error);
1690 } 1697 }
1691 1698
1692 1699
1693 } // namespace dart 1700 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler_x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698