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

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

Issue 10857016: Refactored FlowGraphBuilder into a separate FlowGraph representation. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Revision based on Kevin's review. Created 8 years, 4 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_allocator.h ('k') | runtime/vm/flow_graph_builder.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_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph.h"
11 #include "vm/flow_graph_compiler.h" 11 #include "vm/flow_graph_compiler.h"
12 #include "vm/parser.h" 12 #include "vm/parser.h"
13 13
14 namespace dart { 14 namespace dart {
15 15
16 DEFINE_FLAG(bool, print_ssa_liveness, false, 16 DEFINE_FLAG(bool, print_ssa_liveness, false,
17 "Print liveness for ssa variables."); 17 "Print liveness for ssa variables.");
18 DEFINE_FLAG(bool, trace_ssa_allocator, false, 18 DEFINE_FLAG(bool, trace_ssa_allocator, false,
19 "Trace register allocation over SSA."); 19 "Trace register allocation over SSA.");
20 DEFINE_FLAG(bool, print_ssa_liveranges, false, 20 DEFINE_FLAG(bool, print_ssa_liveranges, false,
(...skipping 28 matching lines...) Expand all
49 static bool IsInstructionEndPosition(intptr_t pos) { 49 static bool IsInstructionEndPosition(intptr_t pos) {
50 return (pos & 1) == 1; 50 return (pos & 1) == 1;
51 } 51 }
52 52
53 53
54 static intptr_t ToInstructionStart(intptr_t pos) { 54 static intptr_t ToInstructionStart(intptr_t pos) {
55 return (pos & ~1); 55 return (pos & ~1);
56 } 56 }
57 57
58 58
59 FlowGraphAllocator::FlowGraphAllocator( 59 FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph)
60 const GrowableArray<BlockEntryInstr*>& block_order, 60 : flow_graph_(flow_graph),
61 FlowGraphBuilder* builder) 61 block_order_(flow_graph.reverse_postorder()),
62 : builder_(builder), 62 postorder_(flow_graph.postorder()),
63 block_order_(block_order), 63 live_out_(block_order_.length()),
64 postorder_(builder->postorder_block_entries()), 64 kill_(block_order_.length()),
65 live_out_(block_order.length()), 65 live_in_(block_order_.length()),
66 kill_(block_order.length()), 66 vreg_count_(flow_graph.max_virtual_register_number()),
67 live_in_(block_order.length()), 67 live_ranges_(flow_graph.max_virtual_register_number()),
68 vreg_count_(builder->current_ssa_temp_index()),
69 live_ranges_(builder->current_ssa_temp_index()),
70 cpu_regs_(), 68 cpu_regs_(),
71 blocked_cpu_regs_() { 69 blocked_cpu_regs_() {
72 for (intptr_t i = 0; i < vreg_count_; i++) live_ranges_.Add(NULL); 70 for (intptr_t i = 0; i < vreg_count_; i++) live_ranges_.Add(NULL);
73 71
74 blocked_cpu_regs_[CTX] = true; 72 blocked_cpu_regs_[CTX] = true;
75 if (TMP != kNoRegister) { 73 if (TMP != kNoRegister) {
76 blocked_cpu_regs_[TMP] = true; 74 blocked_cpu_regs_[TMP] = true;
77 } 75 }
78 blocked_cpu_regs_[SPREG] = true; 76 blocked_cpu_regs_[SPREG] = true;
79 blocked_cpu_regs_[FPREG] = true; 77 blocked_cpu_regs_[FPREG] = true;
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 // Skip parallel moves that we insert while processing instructions. 496 // Skip parallel moves that we insert while processing instructions.
499 if (!current->IsParallelMove()) { 497 if (!current->IsParallelMove()) {
500 ProcessOneInstruction(block, current); 498 ProcessOneInstruction(block, current);
501 } 499 }
502 current = current->previous(); 500 current = current->previous();
503 } 501 }
504 502
505 ConnectIncomingPhiMoves(block); 503 ConnectIncomingPhiMoves(block);
506 } 504 }
507 505
508 const bool copied = builder_->copied_parameter_count() > 0;
509
510 // Process incoming parameters. Do this after all other instructions so 506 // Process incoming parameters. Do this after all other instructions so
511 // that safepoints for all calls have already been found. 507 // that safepoints for all calls have already been found.
512 const intptr_t fixed_parameters_count =
513 builder_->parsed_function().function().num_fixed_parameters();
514
515 GraphEntryInstr* graph_entry = postorder_[block_count - 1]->AsGraphEntry(); 508 GraphEntryInstr* graph_entry = postorder_[block_count - 1]->AsGraphEntry();
516 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { 509 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
517 Value* val = graph_entry->start_env()->values()[i]; 510 Value* val = graph_entry->start_env()->values()[i];
518 if (val->IsUse()) { 511 if (val->IsUse()) {
519 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); 512 ParameterInstr* param = val->AsUse()->definition()->AsParameter();
520 513
521 LiveRange* range = GetLiveRange(param->ssa_temp_index()); 514 LiveRange* range = GetLiveRange(param->ssa_temp_index());
522 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); 515 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
523 range->DefineAt(graph_entry->start_pos()); 516 range->DefineAt(graph_entry->start_pos());
524 517
518 // Assert that copied and non-copied parameters are mutually exclusive.
519 // This might change in the future and, if so, the index will be wrong.
520 ASSERT(flow_graph_.copied_parameter_count() == 0 ||
521 flow_graph_.non_copied_parameter_count() == 0);
525 // Slot index for the leftmost copied parameter is 0. 522 // Slot index for the leftmost copied parameter is 0.
526 intptr_t slot_index = param->index(); 523 intptr_t slot_index = param->index();
527 if (!copied) { 524 // Slot index for the rightmost fixed parameter is -1.
528 // Slot index for the rightmost fixed parameter is -1. 525 slot_index -= flow_graph_.non_copied_parameter_count();
529 slot_index -= fixed_parameters_count;
530 }
531 526
532 range->set_assigned_location(Location::StackSlot(slot_index)); 527 range->set_assigned_location(Location::StackSlot(slot_index));
533 range->set_spill_slot(Location::StackSlot(slot_index)); 528 range->set_spill_slot(Location::StackSlot(slot_index));
534 if (copied) { 529 if (flow_graph_.copied_parameter_count() > 0) {
535 ASSERT(spill_slots_.length() == slot_index); 530 ASSERT(spill_slots_.length() == slot_index);
536 spill_slots_.Add(range->End()); 531 spill_slots_.Add(range->End());
537 } 532 }
538 533
539 AssignSafepoints(range); 534 AssignSafepoints(range);
540 535
541 range->finger()->Initialize(range); 536 range->finger()->Initialize(range);
542 UsePosition* use = range->finger()->FirstRegisterBeneficialUse( 537 UsePosition* use = range->finger()->FirstRegisterBeneficialUse(
543 graph_entry->start_pos()); 538 graph_entry->start_pos());
544 if (use != NULL) { 539 if (use != NULL) {
545 LiveRange* tail = SplitBetween(range, 540 LiveRange* tail = SplitBetween(range,
546 graph_entry->start_pos(), 541 graph_entry->start_pos(),
547 use->pos()); 542 use->pos());
548 AddToUnallocated(tail); 543 AddToUnallocated(tail);
549 } 544 }
550 ConvertAllUses(range); 545 ConvertAllUses(range);
551 if (copied) MarkAsObjectAtSafepoints(range); 546 if (flow_graph_.copied_parameter_count() > 0) {
547 MarkAsObjectAtSafepoints(range);
548 }
552 } 549 }
553 } 550 }
554 } 551 }
555 552
556 // 553 //
557 // When describing shape of live ranges in comments below we are going to use 554 // When describing shape of live ranges in comments below we are going to use
558 // the following notation: 555 // the following notation:
559 // 556 //
560 // B block entry 557 // B block entry
561 // g g' start and end of goto instruction 558 // g g' start and end of goto instruction
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
739 // temporaries and output. 736 // temporaries and output.
740 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, 737 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
741 Instruction* current) { 738 Instruction* current) {
742 const intptr_t pos = current->lifetime_position(); 739 const intptr_t pos = current->lifetime_position();
743 ASSERT(IsInstructionStartPosition(pos)); 740 ASSERT(IsInstructionStartPosition(pos));
744 741
745 LocationSummary* locs = current->locs(); 742 LocationSummary* locs = current->locs();
746 743
747 // TODO(vegorov): number of inputs must match number of input locations. 744 // TODO(vegorov): number of inputs must match number of input locations.
748 if (locs->input_count() != current->InputCount()) { 745 if (locs->input_count() != current->InputCount()) {
749 builder_->Bailout("ssa allocator: number of input locations mismatch"); 746 flow_graph_.Bailout("ssa allocator: number of input locations mismatch");
750 } 747 }
751 748
752 // Normalize same-as-first-input output if input is specified as 749 // Normalize same-as-first-input output if input is specified as
753 // fixed register. 750 // fixed register.
754 if (locs->out().IsUnallocated() && 751 if (locs->out().IsUnallocated() &&
755 (locs->out().policy() == Location::kSameAsFirstInput) && 752 (locs->out().policy() == Location::kSameAsFirstInput) &&
756 (locs->in(0).IsRegister())) { 753 (locs->in(0).IsRegister())) {
757 locs->set_out(locs->in(0)); 754 locs->set_out(locs->in(0));
758 } 755 }
759 756
(...skipping 1235 matching lines...) Expand 10 before | Expand all | Expand 10 after
1995 1992
1996 DiscoverLoops(); 1993 DiscoverLoops();
1997 1994
1998 BuildLiveRanges(); 1995 BuildLiveRanges();
1999 1996
2000 if (FLAG_print_ssa_liveness) { 1997 if (FLAG_print_ssa_liveness) {
2001 DumpLiveness(); 1998 DumpLiveness();
2002 } 1999 }
2003 2000
2004 if (FLAG_print_ssa_liveranges) { 2001 if (FLAG_print_ssa_liveranges) {
2005 const Function& function = builder_->parsed_function().function(); 2002 const Function& function = flow_graph_.parsed_function().function();
2006 2003
2007 OS::Print("-- [before ssa allocator] ranges [%s] ---------\n", 2004 OS::Print("-- [before ssa allocator] ranges [%s] ---------\n",
2008 function.ToFullyQualifiedCString()); 2005 function.ToFullyQualifiedCString());
2009 PrintLiveRanges(); 2006 PrintLiveRanges();
2010 OS::Print("----------------------------------------------\n"); 2007 OS::Print("----------------------------------------------\n");
2011 2008
2012 OS::Print("-- [before ssa allocator] ir [%s] -------------\n", 2009 OS::Print("-- [before ssa allocator] ir [%s] -------------\n",
2013 function.ToFullyQualifiedCString()); 2010 function.ToFullyQualifiedCString());
2014 FlowGraphPrinter printer(Function::Handle(), block_order_, true); 2011 FlowGraphPrinter printer(flow_graph_, true);
2015 printer.PrintBlocks(); 2012 printer.PrintBlocks();
2016 OS::Print("----------------------------------------------\n"); 2013 OS::Print("----------------------------------------------\n");
2017 } 2014 }
2018 2015
2019 AllocateCPURegisters(); 2016 AllocateCPURegisters();
2020 2017
2021 ResolveControlFlow(); 2018 ResolveControlFlow();
2022 2019
2023 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry(); 2020 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
2024 ASSERT(entry != NULL); 2021 ASSERT(entry != NULL);
2025 entry->set_spill_slot_count(spill_slots_.length()); 2022 entry->set_spill_slot_count(spill_slots_.length());
2026 2023
2027 if (FLAG_print_ssa_liveranges) { 2024 if (FLAG_print_ssa_liveranges) {
2028 const Function& function = builder_->parsed_function().function(); 2025 const Function& function = flow_graph_.parsed_function().function();
2029 2026
2030 OS::Print("-- [after ssa allocator] ranges [%s] ---------\n", 2027 OS::Print("-- [after ssa allocator] ranges [%s] ---------\n",
2031 function.ToFullyQualifiedCString()); 2028 function.ToFullyQualifiedCString());
2032 PrintLiveRanges(); 2029 PrintLiveRanges();
2033 OS::Print("----------------------------------------------\n"); 2030 OS::Print("----------------------------------------------\n");
2034 2031
2035 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2032 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2036 function.ToFullyQualifiedCString()); 2033 function.ToFullyQualifiedCString());
2037 FlowGraphPrinter printer(Function::Handle(), block_order_, true); 2034 FlowGraphPrinter printer(flow_graph_, true);
2038 printer.PrintBlocks(); 2035 printer.PrintBlocks();
2039 OS::Print("----------------------------------------------\n"); 2036 OS::Print("----------------------------------------------\n");
2040 } 2037 }
2041 } 2038 }
2042 2039
2043 2040
2044 } // namespace dart 2041 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698