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

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

Issue 10919008: Unbox phis that were proven to be of type Double. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 8 years, 3 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/deopt_instructions.cc ('k') | runtime/vm/flow_graph_optimizer.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.h" 10 #include "vm/flow_graph.h"
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 UsePosition* use = 573 UsePosition* use =
574 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos()); 574 range->finger()->FirstRegisterBeneficialUse(graph_entry->start_pos());
575 if (use != NULL) { 575 if (use != NULL) {
576 LiveRange* tail = SplitBetween(range, graph_entry->start_pos(), use->pos()); 576 LiveRange* tail = SplitBetween(range, graph_entry->start_pos(), use->pos());
577 CompleteRange(tail, Location::kRegister); 577 CompleteRange(tail, Location::kRegister);
578 } 578 }
579 ConvertAllUses(range); 579 ConvertAllUses(range);
580 } 580 }
581 581
582 582
583 static Location::Kind RegisterKindFromPolicy(Location loc) {
584 if (loc.policy() == Location::kRequiresXmmRegister) {
585 return Location::kXmmRegister;
586 } else {
587 return Location::kRegister;
588 }
589 }
590
591
592 static Location::Kind RegisterKindForResult(Instruction* instr) {
593 if (instr->representation() == kUnboxedDouble) {
594 return Location::kXmmRegister;
595 } else {
596 return Location::kRegister;
597 }
598 }
599
600
583 // 601 //
584 // When describing shape of live ranges in comments below we are going to use 602 // When describing shape of live ranges in comments below we are going to use
585 // the following notation: 603 // the following notation:
586 // 604 //
587 // B block entry 605 // B block entry
588 // g g' start and end of goto instruction 606 // g g' start and end of goto instruction
589 // i i' start and end of any other instruction 607 // i i' start and end of any other instruction
590 // j j' start and end of any other instruction 608 // j j' start and end of any other instruction
591 609
592 // - body of a use interval 610 // - body of a use interval
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 MoveOperands* move = 711 MoveOperands* move =
694 goto_instr->parallel_move()->MoveOperandsAt(move_idx); 712 goto_instr->parallel_move()->MoveOperandsAt(move_idx);
695 move->set_dest(Location::PrefersRegister()); 713 move->set_dest(Location::PrefersRegister());
696 range->AddUse(pos, move->dest_slot()); 714 range->AddUse(pos, move->dest_slot());
697 } 715 }
698 716
699 // All phi resolution moves are connected. Phi's live range is 717 // All phi resolution moves are connected. Phi's live range is
700 // complete. 718 // complete.
701 AssignSafepoints(range); 719 AssignSafepoints(range);
702 720
703 // TODO(vegorov): unboxed double phis. 721 CompleteRange(range, RegisterKindForResult(phi));
704 CompleteRange(range, Location::kRegister);
705 722
706 move_idx++; 723 move_idx++;
707 } 724 }
708 } 725 }
709 } 726 }
710 727
711 728
712 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block, 729 void FlowGraphAllocator::ProcessEnvironmentUses(BlockEntryInstr* block,
713 Instruction* current) { 730 Instruction* current) {
714 ASSERT(current->env() != NULL); 731 ASSERT(current->env() != NULL);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 const intptr_t vreg = def->ssa_temp_index(); 763 const intptr_t vreg = def->ssa_temp_index();
747 LiveRange* range = GetLiveRange(vreg); 764 LiveRange* range = GetLiveRange(vreg);
748 range->AddUseInterval(block_start_pos, use_pos); 765 range->AddUseInterval(block_start_pos, use_pos);
749 range->AddUse(use_pos, &locations[i]); 766 range->AddUse(use_pos, &locations[i]);
750 } 767 }
751 768
752 env->set_locations(locations); 769 env->set_locations(locations);
753 } 770 }
754 771
755 772
756 static Location::Kind RegisterKindFromPolicy(Location loc) {
757 if (loc.policy() == Location::kRequiresXmmRegister) {
758 return Location::kXmmRegister;
759 } else {
760 return Location::kRegister;
761 }
762 }
763
764
765 static Location::Kind RegisterKindForResult(Instruction* instr) {
766 if (instr->representation() == kUnboxedDouble) {
767 return Location::kXmmRegister;
768 } else {
769 return Location::kRegister;
770 }
771 }
772
773
774 // Create and update live ranges corresponding to instruction's inputs, 773 // Create and update live ranges corresponding to instruction's inputs,
775 // temporaries and output. 774 // temporaries and output.
776 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block, 775 void FlowGraphAllocator::ProcessOneInstruction(BlockEntryInstr* block,
777 Instruction* current) { 776 Instruction* current) {
778 const intptr_t pos = current->lifetime_position(); 777 const intptr_t pos = current->lifetime_position();
779 ASSERT(IsInstructionStartPosition(pos)); 778 ASSERT(IsInstructionStartPosition(pos));
780 779
781 LocationSummary* locs = current->locs(); 780 LocationSummary* locs = current->locs();
782 781
783 // Number of input locations and number of input operands have to agree. 782 // Number of input locations and number of input operands have to agree.
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
864 // i i' 863 // i i'
865 // [--) 864 // [--)
866 // 865 //
867 // The stack bitmap describes the position i. 866 // The stack bitmap describes the position i.
868 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { 867 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
869 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), 868 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)),
870 pos, 869 pos,
871 pos + 1); 870 pos + 1);
872 } 871 }
873 872
873 for (intptr_t reg = 0; reg < kNumberOfXmmRegisters; reg++) {
874 BlockLocation(
875 Location::XmmRegisterLocation(static_cast<XmmRegister>(reg)),
876 pos,
877 pos + 1);
878 }
879
880
874 #if defined(DEBUG) 881 #if defined(DEBUG)
875 // Verify that temps, inputs and output were specified as fixed 882 // Verify that temps, inputs and output were specified as fixed
876 // locations. Every register is blocked now so attempt to 883 // locations. Every register is blocked now so attempt to
877 // allocate will not succeed. 884 // allocate will not succeed.
878 for (intptr_t j = 0; j < locs->temp_count(); j++) { 885 for (intptr_t j = 0; j < locs->temp_count(); j++) {
879 ASSERT(!locs->temp(j).IsUnallocated()); 886 ASSERT(!locs->temp(j).IsUnallocated());
880 } 887 }
881 888
882 for (intptr_t j = 0; j < locs->input_count(); j++) { 889 for (intptr_t j = 0; j < locs->input_count(); j++) {
883 ASSERT(!locs->in(j).IsUnallocated()); 890 ASSERT(!locs->in(j).IsUnallocated());
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 return use; 1188 return use;
1182 } 1189 }
1183 1190
1184 1191
1185 UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) { 1192 UsePosition* AllocationFinger::FirstRegisterUse(intptr_t after) {
1186 for (UsePosition* use = FirstUseAfter(first_register_use_, after); 1193 for (UsePosition* use = FirstUseAfter(first_register_use_, after);
1187 use != NULL; 1194 use != NULL;
1188 use = use->next()) { 1195 use = use->next()) {
1189 Location* loc = use->location_slot(); 1196 Location* loc = use->location_slot();
1190 if (loc->IsUnallocated() && 1197 if (loc->IsUnallocated() &&
1191 (loc->policy() == Location::kRequiresRegister)) { 1198 ((loc->policy() == Location::kRequiresRegister) ||
1199 (loc->policy() == Location::kRequiresXmmRegister))) {
1192 first_register_use_ = use; 1200 first_register_use_ = use;
1193 return use; 1201 return use;
1194 } 1202 }
1195 } 1203 }
1196 return NULL; 1204 return NULL;
1197 } 1205 }
1198 1206
1199 1207
1200 UsePosition* AllocationFinger::FirstRegisterBeneficialUse(intptr_t after) { 1208 UsePosition* AllocationFinger::FirstRegisterBeneficialUse(intptr_t after) {
1201 for (UsePosition* use = FirstUseAfter(first_register_beneficial_use_, after); 1209 for (UsePosition* use = FirstUseAfter(first_register_beneficial_use_, after);
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 LiveRange* last_sibling = range; 1435 LiveRange* last_sibling = range;
1428 while (last_sibling->next_sibling() != NULL) { 1436 while (last_sibling->next_sibling() != NULL) {
1429 last_sibling = last_sibling->next_sibling(); 1437 last_sibling = last_sibling->next_sibling();
1430 } 1438 }
1431 1439
1432 spill_slots_[idx] = last_sibling->End(); 1440 spill_slots_[idx] = last_sibling->End();
1433 1441
1434 if (register_kind_ == Location::kRegister) { 1442 if (register_kind_ == Location::kRegister) {
1435 range->set_spill_slot(Location::StackSlot(idx)); 1443 range->set_spill_slot(Location::StackSlot(idx));
1436 } else { 1444 } else {
1445 // Double spill slots are essentially one (x64) or two (ia32) normal
1446 // word size spill slots. We use the index of the slot with the lowest
1447 // address as an index for the double spill slot. In terms of indexes
1448 // this relation is inverted: so we have to take the highest index.
1449 const intptr_t slot_idx =
1450 idx * kDoubleSpillSlotFactor + (kDoubleSpillSlotFactor - 1);
1437 range->set_spill_slot( 1451 range->set_spill_slot(
1438 Location::DoubleStackSlot( 1452 Location::DoubleStackSlot(
1439 cpu_spill_slot_count_ + idx * kDoubleSpillSlotFactor)); 1453 cpu_spill_slot_count_ + slot_idx));
1440 } 1454 }
1441 1455
1442 spilled_.Add(range); 1456 spilled_.Add(range);
1443 } 1457 }
1444 1458
1445 1459
1446 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { 1460 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) {
1447 intptr_t stack_index = range->spill_slot().stack_index(); 1461 intptr_t stack_index = range->spill_slot().stack_index();
1448 ASSERT(stack_index >= 0); 1462 ASSERT(stack_index >= 0);
1449 1463
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 1681
1668 1682
1669 void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated, 1683 void FlowGraphAllocator::AssignNonFreeRegister(LiveRange* unallocated,
1670 intptr_t reg) { 1684 intptr_t reg) {
1671 intptr_t first_evicted = -1; 1685 intptr_t first_evicted = -1;
1672 for (intptr_t i = registers_[reg].length() - 1; i >= 0; i--) { 1686 for (intptr_t i = registers_[reg].length() - 1; i >= 0; i--) {
1673 LiveRange* allocated = registers_[reg][i]; 1687 LiveRange* allocated = registers_[reg][i];
1674 if (allocated->vreg() < 0) continue; // Can't be evicted. 1688 if (allocated->vreg() < 0) continue; // Can't be evicted.
1675 if (EvictIntersection(allocated, unallocated)) { 1689 if (EvictIntersection(allocated, unallocated)) {
1676 // If allocated was not spilled convert all pending uses. 1690 // If allocated was not spilled convert all pending uses.
1677 if (allocated->assigned_location().IsRegister()) { 1691 if (allocated->assigned_location().IsMachineRegister()) {
1678 ASSERT(allocated->End() <= unallocated->Start()); 1692 ASSERT(allocated->End() <= unallocated->Start());
1679 ConvertAllUses(allocated); 1693 ConvertAllUses(allocated);
1680 } 1694 }
1681 registers_[reg][i] = NULL; 1695 registers_[reg][i] = NULL;
1682 first_evicted = i; 1696 first_evicted = i;
1683 } 1697 }
1684 } 1698 }
1685 1699
1686 // Remove evicted ranges from the array. 1700 // Remove evicted ranges from the array.
1687 if (first_evicted != -1) RemoveEvicted(reg, first_evicted); 1701 if (first_evicted != -1) RemoveEvicted(reg, first_evicted);
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2145 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2132 function.ToFullyQualifiedCString()); 2146 function.ToFullyQualifiedCString());
2133 FlowGraphPrinter printer(flow_graph_, true); 2147 FlowGraphPrinter printer(flow_graph_, true);
2134 printer.PrintBlocks(); 2148 printer.PrintBlocks();
2135 OS::Print("----------------------------------------------\n"); 2149 OS::Print("----------------------------------------------\n");
2136 } 2150 }
2137 } 2151 }
2138 2152
2139 2153
2140 } // namespace dart 2154 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/deopt_instructions.cc ('k') | runtime/vm/flow_graph_optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698