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

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

Issue 10828018: Add support for fixed parameters in the register allocator. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 5 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 | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | runtime/vm/flow_graph_builder.cc » ('J')
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_builder.h"
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 BlockEntryInstr* pred = block->PredecessorAt(k); 132 BlockEntryInstr* pred = block->PredecessorAt(k);
133 const intptr_t use = val->AsUse()->definition()->ssa_temp_index(); 133 const intptr_t use = val->AsUse()->definition()->ssa_temp_index();
134 live_out_[pred->postorder_number()]->Add(use); 134 live_out_[pred->postorder_number()]->Add(use);
135 } 135 }
136 } 136 }
137 } 137 }
138 } 138 }
139 } 139 }
140 } 140 }
141 141
142 // Process incomming parameters.
srdjan 2012/07/26 00:33:56 s/incomming/incoming/
Vyacheslav Egorov (Google) 2012/07/26 11:33:53 Done.
143 GraphEntryInstr* graph_entry = postorder_[block_count - 1]->AsGraphEntry();
144 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
145 Value* val = graph_entry->start_env()->values()[i];
146 if (val->IsUse()) {
147 const intptr_t vreg = val->AsUse()->definition()->ssa_temp_index();
148 kill_[0]->Add(vreg);
Kevin Millikin (Google) 2012/07/26 09:29:08 It probably doesn't make a big difference to anyth
Vyacheslav Egorov (Google) 2012/07/26 11:33:53 It does not change anything. I just choose to defi
149 live_in_[0]->Remove(vreg);
150 }
151 }
152
142 // Update initial live_in sets to match live_out sets. Has to be 153 // Update initial live_in sets to match live_out sets. Has to be
143 // done in a separate path because of backwards branches. 154 // done in a separate path because of backwards branches.
144 for (intptr_t i = 0; i < block_count; i++) { 155 for (intptr_t i = 0; i < block_count; i++) {
145 UpdateLiveIn(*postorder_[i]); 156 UpdateLiveIn(*postorder_[i]);
146 } 157 }
147 } 158 }
148 159
149 160
150 bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) { 161 bool FlowGraphAllocator::UpdateLiveOut(const BlockEntryInstr& instr) {
151 BitVector* live_out = live_out_[instr.postorder_number()]; 162 BitVector* live_out = live_out_[instr.postorder_number()];
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 while (current != block) { 400 while (current != block) {
390 // Skip parallel moves that we insert while processing instructions. 401 // Skip parallel moves that we insert while processing instructions.
391 if (!current->IsParallelMove()) { 402 if (!current->IsParallelMove()) {
392 ProcessOneInstruction(block, current); 403 ProcessOneInstruction(block, current);
393 } 404 }
394 current = current->previous(); 405 current = current->previous();
395 } 406 }
396 407
397 ConnectIncomingPhiMoves(block); 408 ConnectIncomingPhiMoves(block);
398 } 409 }
410
411 // Process incomming parameters.
srdjan 2012/07/26 00:33:56 ditto
Vyacheslav Egorov (Google) 2012/07/26 11:33:53 Done.
412 GraphEntryInstr* graph_entry = postorder_[block_count - 1]->AsGraphEntry();
413 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) {
414 Value* val = graph_entry->start_env()->values()[i];
415 if (val->IsUse()) {
416 ParameterInstr* param = val->AsUse()->definition()->AsParameter();
417
418 LiveRange* range = GetLiveRange(param->ssa_temp_index());
419 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos());
420 range->DefineAt(graph_entry->start_pos());
421 range->set_assigned_location(Location::StackSlot(param->index()));
422
423 range->finger()->Initialize(range);
424 UsePosition* use = range->finger()->FirstRegisterBeneficialUse(
425 graph_entry->start_pos());
426 if (use != NULL) {
427 LiveRange* tail = SplitBetween(range,
428 graph_entry->start_pos(),
429 use->pos());
430 AddToUnallocated(tail);
431 }
432 ConvertAllUses(range);
433 }
434 }
399 } 435 }
400 436
401 // 437 //
402 // When describing shape of live ranges in comments below we are going to use 438 // When describing shape of live ranges in comments below we are going to use
403 // the following notation: 439 // the following notation:
404 // 440 //
405 // B block entry 441 // B block entry
406 // g goto instruction 442 // g goto instruction
407 // m parallel move 443 // m parallel move
408 // i any other instruction 444 // i any other instruction
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 const intptr_t pos = current->lifetime_position(); 576 const intptr_t pos = current->lifetime_position();
541 ASSERT(IsInstructionPosition(pos)); 577 ASSERT(IsInstructionPosition(pos));
542 578
543 LocationSummary* locs = current->locs(); 579 LocationSummary* locs = current->locs();
544 580
545 // TODO(vegorov): number of inputs must match number of input locations. 581 // TODO(vegorov): number of inputs must match number of input locations.
546 if (locs->input_count() != current->InputCount()) { 582 if (locs->input_count() != current->InputCount()) {
547 builder_->Bailout("ssa allocator: number of input locations mismatch"); 583 builder_->Bailout("ssa allocator: number of input locations mismatch");
548 } 584 }
549 585
586 // Normalize same-as-first-input output if input is specified as
587 // fixed register.
588 if (locs->out().IsUnallocated() &&
589 (locs->out().policy() == Location::kSameAsFirstInput) &&
590 (locs->in(0).IsRegister())) {
591 locs->set_out(locs->in(0));
592 }
593
550 const bool output_same_as_first_input = 594 const bool output_same_as_first_input =
551 locs->out().IsUnallocated() && 595 locs->out().IsUnallocated() &&
552 (locs->out().policy() == Location::kSameAsFirstInput); 596 (locs->out().policy() == Location::kSameAsFirstInput);
553 597
554 // Add uses from the deoptimization environment. 598 // Add uses from the deoptimization environment.
555 if (current->env() != NULL) { 599 if (current->env() != NULL) {
556 // Any value mentioned in the deoptimization environment should survive 600 // Any value mentioned in the deoptimization environment should survive
557 // until the end of instruction but it does not need to be in the register. 601 // until the end of instruction but it does not need to be in the register.
558 // Expected shape of live range: 602 // Expected shape of live range:
559 // 603 //
(...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after
1088 return i; 1132 return i;
1089 } 1133 }
1090 } 1134 }
1091 spill_slots_.Add(0); 1135 spill_slots_.Add(0);
1092 return spill_slots_.length() - 1; 1136 return spill_slots_.length() - 1;
1093 } 1137 }
1094 1138
1095 1139
1096 void FlowGraphAllocator::Spill(LiveRange* range) { 1140 void FlowGraphAllocator::Spill(LiveRange* range) {
1097 const intptr_t spill_index = AllocateSpillSlotFor(range); 1141 const intptr_t spill_index = AllocateSpillSlotFor(range);
1098 ASSERT(spill_slots_[spill_index] < range->Start()); 1142 ASSERT(spill_slots_[spill_index] <= range->Start());
1099 spill_slots_[spill_index] = range->End(); 1143 spill_slots_[spill_index] = range->End();
1100 range->set_assigned_location(Location::SpillSlot(spill_index)); 1144 range->set_assigned_location(Location::StackSlot(spill_index));
1101 ConvertAllUses(range); 1145 ConvertAllUses(range);
1102 } 1146 }
1103 1147
1104 1148
1105 intptr_t FlowGraphAllocator::FirstIntersectionWithAllocated( 1149 intptr_t FlowGraphAllocator::FirstIntersectionWithAllocated(
1106 Register reg, LiveRange* unallocated) { 1150 Register reg, LiveRange* unallocated) {
1107 intptr_t intersection = kMaxPosition; 1151 intptr_t intersection = kMaxPosition;
1108 for (intptr_t i = 0; i < cpu_regs_[reg].length(); i++) { 1152 for (intptr_t i = 0; i < cpu_regs_[reg].length(); i++) {
1109 LiveRange* allocated = cpu_regs_[reg][i]; 1153 LiveRange* allocated = cpu_regs_[reg][i];
1110 if (allocated == NULL) continue; 1154 if (allocated == NULL) continue;
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after
1568 LiveRange* range = GetLiveRange(it.Current()); 1612 LiveRange* range = GetLiveRange(it.Current());
1569 for (intptr_t j = 0; j < block->PredecessorCount(); j++) { 1613 for (intptr_t j = 0; j < block->PredecessorCount(); j++) {
1570 ConnectSplitSiblings(range, block->PredecessorAt(j), block); 1614 ConnectSplitSiblings(range, block->PredecessorAt(j), block);
1571 } 1615 }
1572 } 1616 }
1573 } 1617 }
1574 } 1618 }
1575 1619
1576 1620
1577 void FlowGraphAllocator::AllocateRegisters() { 1621 void FlowGraphAllocator::AllocateRegisters() {
1578 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
1579 ASSERT(entry != NULL);
1580
1581 for (intptr_t i = 0; i < entry->start_env()->values().length(); i++) {
1582 if (entry->start_env()->values()[i]->IsUse()) {
1583 builder_->Bailout("ssa allocator: unsupported start environment");
1584 }
1585 }
1586
1587 AnalyzeLiveness(); 1622 AnalyzeLiveness();
1588 1623
1589 BuildLiveRanges(); 1624 BuildLiveRanges();
1590 1625
1591 if (FLAG_print_ssa_liveness) { 1626 if (FLAG_print_ssa_liveness) {
1592 DumpLiveness(); 1627 DumpLiveness();
1593 } 1628 }
1594 1629
1595 if (FLAG_trace_ssa_allocator) { 1630 if (FLAG_trace_ssa_allocator) {
1596 PrintLiveRanges(); 1631 PrintLiveRanges();
1597 } 1632 }
1598 1633
1599 AllocateCPURegisters(); 1634 AllocateCPURegisters();
1600 1635
1601 ResolveControlFlow(); 1636 ResolveControlFlow();
1602 1637
1638 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry();
1639 ASSERT(entry != NULL);
1640 entry->set_spill_slot_count(spill_slots_.length());
1641
1603 if (FLAG_trace_ssa_allocator) { 1642 if (FLAG_trace_ssa_allocator) {
1604 OS::Print("-- ir after allocation -------------------------\n"); 1643 OS::Print("-- ir after allocation -------------------------\n");
1605 FlowGraphPrinter printer(Function::Handle(), block_order_, true); 1644 FlowGraphPrinter printer(Function::Handle(), block_order_, true);
1606 printer.PrintBlocks(); 1645 printer.PrintBlocks();
1607 } 1646 }
1608 } 1647 }
1609 1648
1610 1649
1611 } // namespace dart 1650 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_builder.h » ('j') | runtime/vm/flow_graph_builder.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698