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

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

Issue 252333002: Use GPRs for mints (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 7 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
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
622 if (loc.policy() == Location::kRequiresFpuRegister) { 622 if (loc.policy() == Location::kRequiresFpuRegister) {
623 return Location::kFpuRegister; 623 return Location::kFpuRegister;
624 } else { 624 } else {
625 return Location::kRegister; 625 return Location::kRegister;
626 } 626 }
627 } 627 }
628 628
629 629
630 static Location::Kind RegisterKindForResult(Instruction* instr) { 630 static Location::Kind RegisterKindForResult(Instruction* instr) {
631 if ((instr->representation() == kUnboxedDouble) || 631 if ((instr->representation() == kUnboxedDouble) ||
632 (instr->representation() == kUnboxedMint) ||
633 (instr->representation() == kUnboxedFloat32x4) || 632 (instr->representation() == kUnboxedFloat32x4) ||
634 (instr->representation() == kUnboxedInt32x4) || 633 (instr->representation() == kUnboxedInt32x4) ||
635 (instr->representation() == kUnboxedFloat64x2) || 634 (instr->representation() == kUnboxedFloat64x2) ||
636 (instr->representation() == kPairOfUnboxedDouble)) { 635 (instr->representation() == kPairOfUnboxedDouble)) {
637 return Location::kFpuRegister; 636 return Location::kFpuRegister;
638 } else { 637 } else {
639 return Location::kRegister; 638 return Location::kRegister;
640 } 639 }
641 } 640 }
642 641
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 } 791 }
793 792
794 const intptr_t block_start_pos = block->start_pos(); 793 const intptr_t block_start_pos = block->start_pos();
795 const intptr_t use_pos = current->lifetime_position() + 1; 794 const intptr_t use_pos = current->lifetime_position() + 1;
796 795
797 Location* locations = 796 Location* locations =
798 Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); 797 Isolate::Current()->current_zone()->Alloc<Location>(env->Length());
799 798
800 for (intptr_t i = 0; i < env->Length(); ++i) { 799 for (intptr_t i = 0; i < env->Length(); ++i) {
801 Value* value = env->ValueAt(i); 800 Value* value = env->ValueAt(i);
802 locations[i] = Location::Any();
803 Definition* def = value->definition(); 801 Definition* def = value->definition();
802 if (def->HasPairRepresentation()) {
803 locations[i] = Location::Pair(Location::Any(), Location::Any());
804 } else {
805 locations[i] = Location::Any();
806 }
804 807
805 if (def->IsPushArgument()) { 808 if (def->IsPushArgument()) {
806 // Frame size is unknown until after allocation. 809 // Frame size is unknown until after allocation.
807 locations[i] = Location::NoLocation(); 810 locations[i] = Location::NoLocation();
808 continue; 811 continue;
809 } 812 }
810 813
811 ConstantInstr* constant = def->AsConstant(); 814 ConstantInstr* constant = def->AsConstant();
812 if (constant != NULL) { 815 if (constant != NULL) {
813 locations[i] = Location::Constant(constant->value()); 816 locations[i] = Location::Constant(constant->value());
814 continue; 817 continue;
815 } 818 }
816 819
817 MaterializeObjectInstr* mat = def->AsMaterializeObject(); 820 MaterializeObjectInstr* mat = def->AsMaterializeObject();
818 if (mat != NULL) { 821 if (mat != NULL) {
819 // MaterializeObject itself produces no value. But its uses 822 // MaterializeObject itself produces no value. But its uses
820 // are treated as part of the environment: allocated locations 823 // are treated as part of the environment: allocated locations
821 // will be used when building deoptimization data. 824 // will be used when building deoptimization data.
822 locations[i] = Location::NoLocation(); 825 locations[i] = Location::NoLocation();
823 ProcessMaterializationUses(block, block_start_pos, use_pos, mat); 826 ProcessMaterializationUses(block, block_start_pos, use_pos, mat);
824 continue; 827 continue;
825 } 828 }
826 829
827 LiveRange* range = GetLiveRange(def->ssa_temp_index());
828 range->AddUseInterval(block_start_pos, use_pos);
829 range->AddUse(use_pos, &locations[i]);
830
831 if (def->HasPairRepresentation()) { 830 if (def->HasPairRepresentation()) {
832 LiveRange* range = 831 PairLocation* location_pair = locations[i].AsPairLocation();
832 {
833 // First live range.
834 LiveRange* range = GetLiveRange(def->ssa_temp_index());
835 range->AddUseInterval(block_start_pos, use_pos);
836 range->AddUse(use_pos, location_pair->SlotAt(0));
837 }
838 {
839 // Second live range.
840 LiveRange* range =
833 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); 841 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index()));
842 range->AddUseInterval(block_start_pos, use_pos);
843 range->AddUse(use_pos, location_pair->SlotAt(1));
844 }
845 } else {
846 LiveRange* range = GetLiveRange(def->ssa_temp_index());
834 range->AddUseInterval(block_start_pos, use_pos); 847 range->AddUseInterval(block_start_pos, use_pos);
835 range->AddUse(use_pos, &locations[i]); 848 range->AddUse(use_pos, &locations[i]);
836 } 849 }
837 } 850 }
838 851
839 env->set_locations(locations); 852 env->set_locations(locations);
840 env = env->outer(); 853 env = env->outer();
841 } 854 }
842 } 855 }
843 856
(...skipping 15 matching lines...) Expand all
859 872
860 for (intptr_t i = 0; i < mat->InputCount(); ++i) { 873 for (intptr_t i = 0; i < mat->InputCount(); ++i) {
861 Definition* def = mat->InputAt(i)->definition(); 874 Definition* def = mat->InputAt(i)->definition();
862 875
863 ConstantInstr* constant = def->AsConstant(); 876 ConstantInstr* constant = def->AsConstant();
864 if (constant != NULL) { 877 if (constant != NULL) {
865 locations[i] = Location::Constant(constant->value()); 878 locations[i] = Location::Constant(constant->value());
866 continue; 879 continue;
867 } 880 }
868 881
869 locations[i] = Location::Any();
870
871 LiveRange* range = GetLiveRange(def->ssa_temp_index());
872 range->AddUseInterval(block_start_pos, use_pos);
873 range->AddUse(use_pos, &locations[i]);
874 if (def->HasPairRepresentation()) { 882 if (def->HasPairRepresentation()) {
875 LiveRange* range = GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); 883 locations[i] = Location::Pair(Location::Any(), Location::Any());
884 PairLocation* location_pair = locations[i].AsPairLocation();
885 {
886 // First live range.
887 LiveRange* range = GetLiveRange(def->ssa_temp_index());
888 range->AddUseInterval(block_start_pos, use_pos);
889 range->AddUse(use_pos, location_pair->SlotAt(0));
890 }
891 {
892 // Second live range.
893 LiveRange* range =
894 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index()));
895 range->AddUseInterval(block_start_pos, use_pos);
896 range->AddUse(use_pos, location_pair->SlotAt(1));
897 }
898 } else {
899 locations[i] = Location::Any();
900 LiveRange* range = GetLiveRange(def->ssa_temp_index());
876 range->AddUseInterval(block_start_pos, use_pos); 901 range->AddUseInterval(block_start_pos, use_pos);
877 range->AddUse(use_pos, &locations[i]); 902 range->AddUse(use_pos, &locations[i]);
878 } 903 }
879 } 904 }
880 905
881 mat->set_locations(locations); 906 mat->set_locations(locations);
882 } 907 }
883 908
884 909
885 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, 910 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block,
886 intptr_t pos, 911 intptr_t pos,
887 Location* in_ref, 912 Location* in_ref,
888 Value* input, 913 Value* input,
889 intptr_t vreg) { 914 intptr_t vreg,
915 RegisterSet* live_registers) {
890 ASSERT(in_ref != NULL); 916 ASSERT(in_ref != NULL);
891 ASSERT(!in_ref->IsPairLocation()); 917 ASSERT(!in_ref->IsPairLocation());
892 ASSERT(input != NULL); 918 ASSERT(input != NULL);
893 ASSERT(block != NULL); 919 ASSERT(block != NULL);
894 LiveRange* range = GetLiveRange(vreg); 920 LiveRange* range = GetLiveRange(vreg);
895 if (in_ref->IsMachineRegister()) { 921 if (in_ref->IsMachineRegister()) {
896 // Input is expected in a fixed register. Expected shape of 922 // Input is expected in a fixed register. Expected shape of
897 // live ranges: 923 // live ranges:
898 // 924 //
899 // j' i i' 925 // j' i i'
900 // value --* 926 // value --*
901 // register [-----) 927 // register [-----)
902 // 928 //
929 if (live_registers != NULL) {
930 live_registers->Add(*in_ref, range->representation());
931 }
903 MoveOperands* move = 932 MoveOperands* move =
904 AddMoveAt(pos - 1, *in_ref, Location::Any()); 933 AddMoveAt(pos - 1, *in_ref, Location::Any());
905 BlockLocation(*in_ref, pos - 1, pos + 1); 934 BlockLocation(*in_ref, pos - 1, pos + 1);
906 range->AddUseInterval(block->start_pos(), pos - 1); 935 range->AddUseInterval(block->start_pos(), pos - 1);
907 range->AddHintedUse(pos - 1, move->src_slot(), in_ref); 936 range->AddHintedUse(pos - 1, move->src_slot(), in_ref);
908 } else if (in_ref->IsUnallocated()) { 937 } else if (in_ref->IsUnallocated()) {
909 if (in_ref->policy() == Location::kWritableRegister) { 938 if (in_ref->policy() == Location::kWritableRegister) {
910 // Writable unallocated input. Expected shape of 939 // Writable unallocated input. Expected shape of
911 // live ranges: 940 // live ranges:
912 // 941 //
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 if (locs->out(0).IsUnallocated() && 1133 if (locs->out(0).IsUnallocated() &&
1105 (locs->out(0).policy() == Location::kSameAsFirstInput) && 1134 (locs->out(0).policy() == Location::kSameAsFirstInput) &&
1106 (locs->in(0).IsMachineRegister())) { 1135 (locs->in(0).IsMachineRegister())) {
1107 locs->set_out(0, locs->in(0)); 1136 locs->set_out(0, locs->in(0));
1108 } 1137 }
1109 1138
1110 const bool output_same_as_first_input = 1139 const bool output_same_as_first_input =
1111 locs->out(0).IsUnallocated() && 1140 locs->out(0).IsUnallocated() &&
1112 (locs->out(0).policy() == Location::kSameAsFirstInput); 1141 (locs->out(0).policy() == Location::kSameAsFirstInput);
1113 1142
1143 // Output is same as first input which is a pair.
1144 if (output_same_as_first_input && locs->in(0).IsPairLocation()) {
1145 // Make out into a PairLocation.
1146 locs->set_out(0, Location::Pair(Location::RequiresRegister(),
1147 Location::RequiresRegister()));
1148 }
1114 // Add uses from the deoptimization environment. 1149 // Add uses from the deoptimization environment.
1115 if (current->env() != NULL) ProcessEnvironmentUses(block, current); 1150 if (current->env() != NULL) ProcessEnvironmentUses(block, current);
1116 1151
1117 // Process inputs. 1152 // Process inputs.
1118 // Skip the first input if output is specified with kSameAsFirstInput policy, 1153 // Skip the first input if output is specified with kSameAsFirstInput policy,
1119 // they will be processed together at the very end. 1154 // they will be processed together at the very end.
1120 { 1155 {
1121 for (intptr_t j = output_same_as_first_input ? 1 : 0; 1156 for (intptr_t j = output_same_as_first_input ? 1 : 0;
1122 j < locs->input_count(); 1157 j < locs->input_count();
1123 j++) { 1158 j++) {
1124 // Determine if we are dealing with a value pair, and if so, whether 1159 // Determine if we are dealing with a value pair, and if so, whether
1125 // the location is the first register or second register. 1160 // the location is the first register or second register.
1126 Value* input = current->InputAt(j); 1161 Value* input = current->InputAt(j);
1127 Location* in_ref = locs->in_slot(j); 1162 Location* in_ref = locs->in_slot(j);
1163 RegisterSet* live_registers = NULL;
1164 if (locs->HasCallOnSlowPath()) {
1165 live_registers = locs->live_registers();
1166 }
1128 if (in_ref->IsPairLocation()) { 1167 if (in_ref->IsPairLocation()) {
1129 ASSERT(input->definition()->HasPairRepresentation()); 1168 ASSERT(input->definition()->HasPairRepresentation());
1130 PairLocation* pair = in_ref->AsPairLocation(); 1169 PairLocation* pair = in_ref->AsPairLocation();
1131 const intptr_t vreg = input->definition()->ssa_temp_index(); 1170 const intptr_t vreg = input->definition()->ssa_temp_index();
1132 // Each element of the pair is assigned it's own virtual register number 1171 // Each element of the pair is assigned it's own virtual register number
1133 // and is allocated its own LiveRange. 1172 // and is allocated its own LiveRange.
1134 ProcessOneInput(block, pos, pair->SlotAt(0), 1173 ProcessOneInput(block, pos, pair->SlotAt(0),
1135 input, vreg); 1174 input, vreg, live_registers);
1136 ProcessOneInput(block, pos, pair->SlotAt(1), input, 1175 ProcessOneInput(block, pos, pair->SlotAt(1), input,
1137 ToSecondPairVreg(vreg)); 1176 ToSecondPairVreg(vreg), live_registers);
1138 } else { 1177 } else {
1139 ProcessOneInput(block, pos, in_ref, input, 1178 ProcessOneInput(block, pos, in_ref, input,
1140 input->definition()->ssa_temp_index()); 1179 input->definition()->ssa_temp_index(), live_registers);
1141 } 1180 }
1142 } 1181 }
1143 } 1182 }
1144 1183
1145 // Process temps. 1184 // Process temps.
1146 for (intptr_t j = 0; j < locs->temp_count(); j++) { 1185 for (intptr_t j = 0; j < locs->temp_count(); j++) {
1147 // Expected shape of live range: 1186 // Expected shape of live range:
1148 // 1187 //
1149 // i i' 1188 // i i'
1150 // [--) 1189 // [--)
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 Location* loc = use->location_slot(); 1551 Location* loc = use->location_slot();
1513 if (loc->IsUnallocated() && loc->IsRegisterBeneficial()) { 1552 if (loc->IsUnallocated() && loc->IsRegisterBeneficial()) {
1514 first_register_beneficial_use_ = use; 1553 first_register_beneficial_use_ = use;
1515 return use; 1554 return use;
1516 } 1555 }
1517 } 1556 }
1518 return NULL; 1557 return NULL;
1519 } 1558 }
1520 1559
1521 1560
1561 UsePosition* AllocationFinger::FirstInterferingUse(intptr_t after) {
1562 if (IsInstructionEndPosition(after)) {
1563 // If after is a position at the end of the instruction disregard
1564 // any use occuring at it.
1565 after += 1;
1566 }
1567 return FirstRegisterUse(after);
1568 }
1569
1570
1522 void AllocationFinger::UpdateAfterSplit(intptr_t first_use_after_split_pos) { 1571 void AllocationFinger::UpdateAfterSplit(intptr_t first_use_after_split_pos) {
1523 if ((first_register_use_ != NULL) && 1572 if ((first_register_use_ != NULL) &&
1524 (first_register_use_->pos() >= first_use_after_split_pos)) { 1573 (first_register_use_->pos() >= first_use_after_split_pos)) {
1525 first_register_use_ = NULL; 1574 first_register_use_ = NULL;
1526 } 1575 }
1527 1576
1528 if ((first_register_beneficial_use_ != NULL) && 1577 if ((first_register_beneficial_use_ != NULL) &&
1529 (first_register_beneficial_use_->pos() >= first_use_after_split_pos)) { 1578 (first_register_beneficial_use_->pos() >= first_use_after_split_pos)) {
1530 first_register_beneficial_use_ = NULL; 1579 first_register_beneficial_use_ = NULL;
1531 } 1580 }
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 // Split at block's start. 1734 // Split at block's start.
1686 split_pos = split_block->entry()->lifetime_position(); 1735 split_pos = split_block->entry()->lifetime_position();
1687 } else { 1736 } else {
1688 // Interval [from, to) is contained inside a single block. 1737 // Interval [from, to) is contained inside a single block.
1689 1738
1690 // Split at position corresponding to the end of the previous 1739 // Split at position corresponding to the end of the previous
1691 // instruction. 1740 // instruction.
1692 split_pos = ToInstructionStart(to) - 1; 1741 split_pos = ToInstructionStart(to) - 1;
1693 } 1742 }
1694 1743
1695 ASSERT((split_pos != kIllegalPosition) && (from < split_pos)); 1744 ASSERT(split_pos != kIllegalPosition);
1745 ASSERT(from < split_pos);
1696 1746
1697 return range->SplitAt(split_pos); 1747 return range->SplitAt(split_pos);
1698 } 1748 }
1699 1749
1700 1750
1701 void FlowGraphAllocator::SpillBetween(LiveRange* range, 1751 void FlowGraphAllocator::SpillBetween(LiveRange* range,
1702 intptr_t from, 1752 intptr_t from,
1703 intptr_t to) { 1753 intptr_t to) {
1704 ASSERT(from < to); 1754 ASSERT(from < to);
1705 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") " 1755 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") "
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 const intptr_t slot_idx = cpu_spill_slot_count_ + 1862 const intptr_t slot_idx = cpu_spill_slot_count_ +
1813 idx * kDoubleSpillFactor + (kDoubleSpillFactor - 1); 1863 idx * kDoubleSpillFactor + (kDoubleSpillFactor - 1);
1814 1864
1815 Location location; 1865 Location location;
1816 if ((range->representation() == kUnboxedFloat32x4) || 1866 if ((range->representation() == kUnboxedFloat32x4) ||
1817 (range->representation() == kUnboxedInt32x4) || 1867 (range->representation() == kUnboxedInt32x4) ||
1818 (range->representation() == kUnboxedFloat64x2)) { 1868 (range->representation() == kUnboxedFloat64x2)) {
1819 ASSERT(need_quad); 1869 ASSERT(need_quad);
1820 location = Location::QuadStackSlot(slot_idx); 1870 location = Location::QuadStackSlot(slot_idx);
1821 } else { 1871 } else {
1822 ASSERT((range->representation() == kUnboxedDouble) || 1872 ASSERT((range->representation() == kUnboxedDouble));
1823 (range->representation() == kUnboxedMint));
1824 location = Location::DoubleStackSlot(slot_idx); 1873 location = Location::DoubleStackSlot(slot_idx);
1825 } 1874 }
1826 range->set_spill_slot(location); 1875 range->set_spill_slot(location);
1827 } 1876 }
1828 1877
1829 spilled_.Add(range); 1878 spilled_.Add(range);
1830 } 1879 }
1831 1880
1832 1881
1833 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { 1882 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) {
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
2188 UseInterval* first_pending_use_interval = 2237 UseInterval* first_pending_use_interval =
2189 allocated->finger()->first_pending_use_interval(); 2238 allocated->finger()->first_pending_use_interval();
2190 if (first_pending_use_interval->Contains(start)) { 2239 if (first_pending_use_interval->Contains(start)) {
2191 // This is an active interval. 2240 // This is an active interval.
2192 if (allocated->vreg() < 0) { 2241 if (allocated->vreg() < 0) {
2193 // This register blocked by an interval that 2242 // This register blocked by an interval that
2194 // can't be spilled. 2243 // can't be spilled.
2195 return false; 2244 return false;
2196 } 2245 }
2197 2246
2198 const UsePosition* use = 2247 UsePosition* use =
2199 allocated->finger()->FirstRegisterBeneficialUse(unallocated->Start()); 2248 allocated->finger()->FirstInterferingUse(start);
2200
2201 if ((use != NULL) && ((ToInstructionStart(use->pos()) - start) <= 1)) { 2249 if ((use != NULL) && ((ToInstructionStart(use->pos()) - start) <= 1)) {
2202 // This register is blocked by interval that is used 2250 // This register is blocked by interval that is used
2203 // as register in the current instruction and can't 2251 // as register in the current instruction and can't
2204 // be spilled. 2252 // be spilled.
2205 return false; 2253 return false;
2206 } 2254 }
2207 2255
2208 const intptr_t use_pos = (use != NULL) ? use->pos() 2256 const intptr_t use_pos = (use != NULL) ? use->pos()
2209 : allocated->End(); 2257 : allocated->End();
2210 2258
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2270 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, 2318 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated,
2271 LiveRange* unallocated) { 2319 LiveRange* unallocated) {
2272 UseInterval* first_unallocated = 2320 UseInterval* first_unallocated =
2273 unallocated->finger()->first_pending_use_interval(); 2321 unallocated->finger()->first_pending_use_interval();
2274 const intptr_t intersection = FirstIntersection( 2322 const intptr_t intersection = FirstIntersection(
2275 allocated->finger()->first_pending_use_interval(), 2323 allocated->finger()->first_pending_use_interval(),
2276 first_unallocated); 2324 first_unallocated);
2277 if (intersection == kMaxPosition) return false; 2325 if (intersection == kMaxPosition) return false;
2278 2326
2279 const intptr_t spill_position = first_unallocated->start(); 2327 const intptr_t spill_position = first_unallocated->start();
2280 UsePosition* use = allocated->finger()->FirstRegisterUse(spill_position); 2328 UsePosition* use = allocated->finger()->FirstInterferingUse(spill_position);
2281 if (use == NULL) { 2329 if (use == NULL) {
2282 // No register uses after this point. 2330 // No register uses after this point.
2283 SpillAfter(allocated, spill_position); 2331 SpillAfter(allocated, spill_position);
2284 } else { 2332 } else {
2285 const intptr_t restore_position = 2333 const intptr_t restore_position =
2286 (spill_position < intersection) ? MinPosition(intersection, use->pos()) 2334 (spill_position < intersection) ? MinPosition(intersection, use->pos())
2287 : use->pos(); 2335 : use->pos();
2288 2336
2289 SpillBetween(allocated, spill_position, restore_position); 2337 SpillBetween(allocated, spill_position, restore_position);
2290 } 2338 }
(...skipping 14 matching lines...) Expand all
2305 parallel_move = CreateParallelMoveBefore(instr, pos); 2353 parallel_move = CreateParallelMoveBefore(instr, pos);
2306 } else { 2354 } else {
2307 parallel_move = CreateParallelMoveAfter(instr, pos); 2355 parallel_move = CreateParallelMoveAfter(instr, pos);
2308 } 2356 }
2309 2357
2310 return parallel_move->AddMove(to, from); 2358 return parallel_move->AddMove(to, from);
2311 } 2359 }
2312 2360
2313 2361
2314 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { 2362 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) {
2363 ASSERT(!loc.IsPairLocation());
2315 ASSERT(use->location_slot() != NULL); 2364 ASSERT(use->location_slot() != NULL);
2316 Location* slot = use->location_slot(); 2365 Location* slot = use->location_slot();
2317 ASSERT(slot->IsUnallocated()); 2366 ASSERT(slot->IsUnallocated());
2318 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos())); 2367 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos()));
2319 TRACE_ALLOC(loc.Print()); 2368 TRACE_ALLOC(loc.Print());
2320 TRACE_ALLOC(OS::Print("\n")); 2369 TRACE_ALLOC(OS::Print("\n"));
2321 *slot = loc; 2370 *slot = loc;
2322 } 2371 }
2323 2372
2324 2373
(...skipping 14 matching lines...) Expand all
2339 } 2388 }
2340 2389
2341 // Add live registers at all safepoints for instructions with slow-path 2390 // Add live registers at all safepoints for instructions with slow-path
2342 // code. 2391 // code.
2343 if (loc.IsMachineRegister()) { 2392 if (loc.IsMachineRegister()) {
2344 for (SafepointPosition* safepoint = range->first_safepoint(); 2393 for (SafepointPosition* safepoint = range->first_safepoint();
2345 safepoint != NULL; 2394 safepoint != NULL;
2346 safepoint = safepoint->next()) { 2395 safepoint = safepoint->next()) {
2347 if (!safepoint->locs()->always_calls()) { 2396 if (!safepoint->locs()->always_calls()) {
2348 ASSERT(safepoint->locs()->can_call()); 2397 ASSERT(safepoint->locs()->can_call());
2349 safepoint->locs()->live_registers()->Add(loc); 2398 safepoint->locs()->live_registers()->Add(loc, range->representation());
2350 } 2399 }
2351 } 2400 }
2352 } 2401 }
2353 } 2402 }
2354 2403
2355 2404
2356 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { 2405 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) {
2357 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) { 2406 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) {
2358 if (registers_[reg].is_empty()) continue; 2407 if (registers_[reg].is_empty()) continue;
2359 2408
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
2653 ASSERT(range->assigned_location().Equals(range->spill_slot())); 2702 ASSERT(range->assigned_location().Equals(range->spill_slot()));
2654 } else { 2703 } else {
2655 AddMoveAt(range->Start() + 1, 2704 AddMoveAt(range->Start() + 1,
2656 range->spill_slot(), 2705 range->spill_slot(),
2657 range->assigned_location()); 2706 range->assigned_location());
2658 } 2707 }
2659 } 2708 }
2660 } 2709 }
2661 2710
2662 2711
2712 static Representation RepresentationForRange(Representation definition_rep) {
2713 if (definition_rep == kUnboxedMint) {
2714 // kUnboxedMint is split into two ranges, each of which are kUntagged.
2715 return kUntagged;
2716 }
2717 return definition_rep;
2718 }
2719
2720
2663 void FlowGraphAllocator::CollectRepresentations() { 2721 void FlowGraphAllocator::CollectRepresentations() {
2664 // Parameters. 2722 // Parameters.
2665 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); 2723 GraphEntryInstr* graph_entry = flow_graph_.graph_entry();
2666 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); ++i) { 2724 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); ++i) {
2667 Definition* def = (*graph_entry->initial_definitions())[i]; 2725 Definition* def = (*graph_entry->initial_definitions())[i];
2668 value_representations_[def->ssa_temp_index()] = def->representation(); 2726 value_representations_[def->ssa_temp_index()] =
2727 RepresentationForRange(def->representation());
2669 ASSERT(!def->HasPairRepresentation()); 2728 ASSERT(!def->HasPairRepresentation());
2670 } 2729 }
2671 2730
2672 for (BlockIterator it = flow_graph_.reverse_postorder_iterator(); 2731 for (BlockIterator it = flow_graph_.reverse_postorder_iterator();
2673 !it.Done(); 2732 !it.Done();
2674 it.Advance()) { 2733 it.Advance()) {
2675 BlockEntryInstr* block = it.Current(); 2734 BlockEntryInstr* block = it.Current();
2676 2735
2677 // Catch entry. 2736 // Catch entry.
2678 if (block->IsCatchBlockEntry()) { 2737 if (block->IsCatchBlockEntry()) {
2679 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); 2738 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
2680 for (intptr_t i = 0; 2739 for (intptr_t i = 0;
2681 i < catch_entry->initial_definitions()->length(); 2740 i < catch_entry->initial_definitions()->length();
2682 ++i) { 2741 ++i) {
2683 Definition* def = (*catch_entry->initial_definitions())[i]; 2742 Definition* def = (*catch_entry->initial_definitions())[i];
2684 value_representations_[def->ssa_temp_index()] = def->representation(); 2743 ASSERT(!def->HasPairRepresentation());
2744 value_representations_[def->ssa_temp_index()] =
2745 RepresentationForRange(def->representation());
2685 } 2746 }
2686 } 2747 }
2687 // Phis. 2748 // Phis.
2688 if (block->IsJoinEntry()) { 2749 if (block->IsJoinEntry()) {
2689 JoinEntryInstr* join = block->AsJoinEntry(); 2750 JoinEntryInstr* join = block->AsJoinEntry();
2690 for (PhiIterator it(join); !it.Done(); it.Advance()) { 2751 for (PhiIterator it(join); !it.Done(); it.Advance()) {
2691 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. 2752 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation.
2692 PhiInstr* phi = it.Current(); 2753 PhiInstr* phi = it.Current();
2693 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { 2754 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) {
2694 value_representations_[phi->ssa_temp_index()] = phi->representation(); 2755 ASSERT(!phi->HasPairRepresentation());
2756 value_representations_[phi->ssa_temp_index()] =
2757 RepresentationForRange(phi->representation());
2695 } 2758 }
2696 } 2759 }
2697 } 2760 }
2698 // Normal instructions. 2761 // Normal instructions.
2699 for (ForwardInstructionIterator instr_it(block); 2762 for (ForwardInstructionIterator instr_it(block);
2700 !instr_it.Done(); 2763 !instr_it.Done();
2701 instr_it.Advance()) { 2764 instr_it.Advance()) {
2702 Definition* def = instr_it.Current()->AsDefinition(); 2765 Definition* def = instr_it.Current()->AsDefinition();
2703 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { 2766 if ((def != NULL) && (def->ssa_temp_index() >= 0)) {
2704 const intptr_t vreg = def->ssa_temp_index(); 2767 const intptr_t vreg = def->ssa_temp_index();
2705 value_representations_[vreg] = def->representation(); 2768 value_representations_[vreg] =
2769 RepresentationForRange(def->representation());
2706 if (def->HasPairRepresentation()) { 2770 if (def->HasPairRepresentation()) {
2707 value_representations_[ToSecondPairVreg(vreg)] = def->representation(); 2771 value_representations_[ToSecondPairVreg(vreg)] =
2772 RepresentationForRange(def->representation());
2708 } 2773 }
2709 } 2774 }
2710 } 2775 }
2711 } 2776 }
2712 } 2777 }
2713 2778
2714 2779
2715 void FlowGraphAllocator::AllocateRegisters() { 2780 void FlowGraphAllocator::AllocateRegisters() {
2716 CollectRepresentations(); 2781 CollectRepresentations();
2717 2782
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2778 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2843 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2779 function.ToFullyQualifiedCString()); 2844 function.ToFullyQualifiedCString());
2780 FlowGraphPrinter printer(flow_graph_, true); 2845 FlowGraphPrinter printer(flow_graph_, true);
2781 printer.PrintBlocks(); 2846 printer.PrintBlocks();
2782 OS::Print("----------------------------------------------\n"); 2847 OS::Print("----------------------------------------------\n");
2783 } 2848 }
2784 } 2849 }
2785 2850
2786 2851
2787 } // namespace dart 2852 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698