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

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

Powered by Google App Engine
This is Rietveld 408576698