OLD | NEW |
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 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 UNREACHABLE(); | 391 UNREACHABLE(); |
392 } | 392 } |
393 } | 393 } |
394 | 394 |
395 | 395 |
396 void LiveRange::Print() { | 396 void LiveRange::Print() { |
397 if (first_use_interval() == NULL) { | 397 if (first_use_interval() == NULL) { |
398 return; | 398 return; |
399 } | 399 } |
400 | 400 |
401 OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", | 401 OS::Print(" live range v%" Pd " [%" Pd ", %" Pd ") in ", vreg(), |
402 vreg(), Start(), End()); | 402 Start(), |
| 403 End()); |
403 assigned_location().Print(); | 404 assigned_location().Print(); |
| 405 if (spill_slot_.HasStackIndex()) { |
| 406 intptr_t stack_slot = spill_slot_.stack_index(); |
| 407 OS::Print(" allocated spill slot: %" Pd "", stack_slot); |
| 408 } |
404 OS::Print("\n"); | 409 OS::Print("\n"); |
405 | 410 |
| 411 SafepointPosition* safepoint = first_safepoint(); |
| 412 while (safepoint != NULL) { |
| 413 OS::Print(" Safepoint [%" Pd "]: ", safepoint->pos()); |
| 414 safepoint->locs()->stack_bitmap()->Print(); |
| 415 OS::Print("\n"); |
| 416 safepoint = safepoint->next(); |
| 417 } |
| 418 |
406 UsePosition* use_pos = uses_; | 419 UsePosition* use_pos = uses_; |
407 for (UseInterval* interval = first_use_interval_; | 420 for (UseInterval* interval = first_use_interval_; |
408 interval != NULL; | 421 interval != NULL; |
409 interval = interval->next()) { | 422 interval = interval->next()) { |
410 OS::Print(" use interval [%" Pd ", %" Pd ")\n", | 423 OS::Print(" use interval [%" Pd ", %" Pd ")\n", |
411 interval->start(), | 424 interval->start(), |
412 interval->end()); | 425 interval->end()); |
413 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) { | 426 while ((use_pos != NULL) && (use_pos->pos() <= interval->end())) { |
414 OS::Print(" use at %" Pd "", use_pos->pos()); | 427 OS::Print(" use at %" Pd "", use_pos->pos()); |
415 if (use_pos->location_slot() != NULL) { | 428 if (use_pos->location_slot() != NULL) { |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 start, | 570 start, |
558 ToInstructionEnd(start)); | 571 ToInstructionEnd(start)); |
559 } | 572 } |
560 } | 573 } |
561 | 574 |
562 // Process incoming parameters and constants. Do this after all other | 575 // Process incoming parameters and constants. Do this after all other |
563 // instructions so that safepoints for all calls have already been found. | 576 // instructions so that safepoints for all calls have already been found. |
564 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); | 577 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
565 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { | 578 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { |
566 Definition* defn = (*graph_entry->initial_definitions())[i]; | 579 Definition* defn = (*graph_entry->initial_definitions())[i]; |
| 580 ASSERT(!defn->HasPairRepresentation()); |
567 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); | 581 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); |
568 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); | 582 range->AddUseInterval(graph_entry->start_pos(), graph_entry->end_pos()); |
569 range->DefineAt(graph_entry->start_pos()); | 583 range->DefineAt(graph_entry->start_pos()); |
570 ProcessInitialDefinition(defn, range, graph_entry); | 584 ProcessInitialDefinition(defn, range, graph_entry); |
571 } | 585 } |
572 } | 586 } |
573 | 587 |
574 | 588 |
575 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn, | 589 void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn, |
576 LiveRange* range, | 590 LiveRange* range, |
(...skipping 28 matching lines...) Expand all Loading... |
605 SplitBetween(range, block->start_pos(), use->pos()); | 619 SplitBetween(range, block->start_pos(), use->pos()); |
606 // Parameters and constants are tagged, so allocated to CPU registers. | 620 // Parameters and constants are tagged, so allocated to CPU registers. |
607 CompleteRange(tail, Location::kRegister); | 621 CompleteRange(tail, Location::kRegister); |
608 } | 622 } |
609 ConvertAllUses(range); | 623 ConvertAllUses(range); |
610 if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) { | 624 if (defn->IsParameter() && (range->spill_slot().stack_index() >= 0)) { |
611 // Parameters above the frame pointer consume spill slots and are marked | 625 // Parameters above the frame pointer consume spill slots and are marked |
612 // in stack maps. | 626 // in stack maps. |
613 spill_slots_.Add(range_end); | 627 spill_slots_.Add(range_end); |
614 quad_spill_slots_.Add(false); | 628 quad_spill_slots_.Add(false); |
| 629 untagged_spill_slots_.Add(false); |
| 630 // Note, all incoming parameters are assumed to be tagged. |
615 MarkAsObjectAtSafepoints(range); | 631 MarkAsObjectAtSafepoints(range); |
616 } else if (defn->IsConstant() && block->IsCatchBlockEntry()) { | 632 } else if (defn->IsConstant() && block->IsCatchBlockEntry()) { |
617 // Constants at catch block entries consume spill slots. | 633 // Constants at catch block entries consume spill slots. |
618 spill_slots_.Add(range_end); | 634 spill_slots_.Add(range_end); |
619 quad_spill_slots_.Add(false); | 635 quad_spill_slots_.Add(false); |
| 636 untagged_spill_slots_.Add(false); |
620 } | 637 } |
621 } | 638 } |
622 | 639 |
623 | 640 |
624 static Location::Kind RegisterKindFromPolicy(Location loc) { | 641 static Location::Kind RegisterKindFromPolicy(Location loc) { |
625 if (loc.policy() == Location::kRequiresFpuRegister) { | 642 if (loc.policy() == Location::kRequiresFpuRegister) { |
626 return Location::kFpuRegister; | 643 return Location::kFpuRegister; |
627 } else { | 644 } else { |
628 return Location::kRegister; | 645 return Location::kRegister; |
629 } | 646 } |
630 } | 647 } |
631 | 648 |
632 | 649 |
633 static Location::Kind RegisterKindForResult(Instruction* instr) { | 650 static Location::Kind RegisterKindForResult(Instruction* instr) { |
634 if ((instr->representation() == kUnboxedDouble) || | 651 if ((instr->representation() == kUnboxedDouble) || |
635 (instr->representation() == kUnboxedMint) || | |
636 (instr->representation() == kUnboxedFloat32x4) || | 652 (instr->representation() == kUnboxedFloat32x4) || |
637 (instr->representation() == kUnboxedInt32x4) || | 653 (instr->representation() == kUnboxedInt32x4) || |
638 (instr->representation() == kUnboxedFloat64x2) || | 654 (instr->representation() == kUnboxedFloat64x2) || |
639 (instr->representation() == kPairOfUnboxedDouble)) { | 655 (instr->representation() == kPairOfUnboxedDouble)) { |
640 return Location::kFpuRegister; | 656 return Location::kFpuRegister; |
641 } else { | 657 } else { |
642 return Location::kRegister; | 658 return Location::kRegister; |
643 } | 659 } |
644 } | 660 } |
645 | 661 |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
795 } | 811 } |
796 | 812 |
797 const intptr_t block_start_pos = block->start_pos(); | 813 const intptr_t block_start_pos = block->start_pos(); |
798 const intptr_t use_pos = current->lifetime_position() + 1; | 814 const intptr_t use_pos = current->lifetime_position() + 1; |
799 | 815 |
800 Location* locations = | 816 Location* locations = |
801 Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); | 817 Isolate::Current()->current_zone()->Alloc<Location>(env->Length()); |
802 | 818 |
803 for (intptr_t i = 0; i < env->Length(); ++i) { | 819 for (intptr_t i = 0; i < env->Length(); ++i) { |
804 Value* value = env->ValueAt(i); | 820 Value* value = env->ValueAt(i); |
805 locations[i] = Location::Any(); | |
806 Definition* def = value->definition(); | 821 Definition* def = value->definition(); |
| 822 if (def->HasPairRepresentation()) { |
| 823 locations[i] = Location::Pair(Location::Any(), Location::Any()); |
| 824 } else { |
| 825 locations[i] = Location::Any(); |
| 826 } |
807 | 827 |
808 if (def->IsPushArgument()) { | 828 if (def->IsPushArgument()) { |
809 // Frame size is unknown until after allocation. | 829 // Frame size is unknown until after allocation. |
810 locations[i] = Location::NoLocation(); | 830 locations[i] = Location::NoLocation(); |
811 continue; | 831 continue; |
812 } | 832 } |
813 | 833 |
814 ConstantInstr* constant = def->AsConstant(); | 834 ConstantInstr* constant = def->AsConstant(); |
815 if (constant != NULL) { | 835 if (constant != NULL) { |
816 locations[i] = Location::Constant(constant->value()); | 836 locations[i] = Location::Constant(constant->value()); |
817 continue; | 837 continue; |
818 } | 838 } |
819 | 839 |
820 MaterializeObjectInstr* mat = def->AsMaterializeObject(); | 840 MaterializeObjectInstr* mat = def->AsMaterializeObject(); |
821 if (mat != NULL) { | 841 if (mat != NULL) { |
822 // MaterializeObject itself produces no value. But its uses | 842 // MaterializeObject itself produces no value. But its uses |
823 // are treated as part of the environment: allocated locations | 843 // are treated as part of the environment: allocated locations |
824 // will be used when building deoptimization data. | 844 // will be used when building deoptimization data. |
825 locations[i] = Location::NoLocation(); | 845 locations[i] = Location::NoLocation(); |
826 ProcessMaterializationUses(block, block_start_pos, use_pos, mat); | 846 ProcessMaterializationUses(block, block_start_pos, use_pos, mat); |
827 continue; | 847 continue; |
828 } | 848 } |
829 | 849 |
830 LiveRange* range = GetLiveRange(def->ssa_temp_index()); | |
831 range->AddUseInterval(block_start_pos, use_pos); | |
832 range->AddUse(use_pos, &locations[i]); | |
833 | |
834 if (def->HasPairRepresentation()) { | 850 if (def->HasPairRepresentation()) { |
835 LiveRange* range = | 851 PairLocation* location_pair = locations[i].AsPairLocation(); |
| 852 { |
| 853 // First live range. |
| 854 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
| 855 range->AddUseInterval(block_start_pos, use_pos); |
| 856 range->AddUse(use_pos, location_pair->SlotAt(0)); |
| 857 } |
| 858 { |
| 859 // Second live range. |
| 860 LiveRange* range = |
836 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); | 861 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
| 862 range->AddUseInterval(block_start_pos, use_pos); |
| 863 range->AddUse(use_pos, location_pair->SlotAt(1)); |
| 864 } |
| 865 } else { |
| 866 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
837 range->AddUseInterval(block_start_pos, use_pos); | 867 range->AddUseInterval(block_start_pos, use_pos); |
838 range->AddUse(use_pos, &locations[i]); | 868 range->AddUse(use_pos, &locations[i]); |
839 } | 869 } |
840 } | 870 } |
841 | 871 |
842 env->set_locations(locations); | 872 env->set_locations(locations); |
843 env = env->outer(); | 873 env = env->outer(); |
844 } | 874 } |
845 } | 875 } |
846 | 876 |
(...skipping 15 matching lines...) Expand all Loading... |
862 | 892 |
863 for (intptr_t i = 0; i < mat->InputCount(); ++i) { | 893 for (intptr_t i = 0; i < mat->InputCount(); ++i) { |
864 Definition* def = mat->InputAt(i)->definition(); | 894 Definition* def = mat->InputAt(i)->definition(); |
865 | 895 |
866 ConstantInstr* constant = def->AsConstant(); | 896 ConstantInstr* constant = def->AsConstant(); |
867 if (constant != NULL) { | 897 if (constant != NULL) { |
868 locations[i] = Location::Constant(constant->value()); | 898 locations[i] = Location::Constant(constant->value()); |
869 continue; | 899 continue; |
870 } | 900 } |
871 | 901 |
872 locations[i] = Location::Any(); | |
873 | |
874 LiveRange* range = GetLiveRange(def->ssa_temp_index()); | |
875 range->AddUseInterval(block_start_pos, use_pos); | |
876 range->AddUse(use_pos, &locations[i]); | |
877 if (def->HasPairRepresentation()) { | 902 if (def->HasPairRepresentation()) { |
878 LiveRange* range = GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); | 903 locations[i] = Location::Pair(Location::Any(), Location::Any()); |
| 904 PairLocation* location_pair = locations[i].AsPairLocation(); |
| 905 { |
| 906 // First live range. |
| 907 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
| 908 range->AddUseInterval(block_start_pos, use_pos); |
| 909 range->AddUse(use_pos, location_pair->SlotAt(0)); |
| 910 } |
| 911 { |
| 912 // Second live range. |
| 913 LiveRange* range = |
| 914 GetLiveRange(ToSecondPairVreg(def->ssa_temp_index())); |
| 915 range->AddUseInterval(block_start_pos, use_pos); |
| 916 range->AddUse(use_pos, location_pair->SlotAt(1)); |
| 917 } |
| 918 } else { |
| 919 locations[i] = Location::Any(); |
| 920 LiveRange* range = GetLiveRange(def->ssa_temp_index()); |
879 range->AddUseInterval(block_start_pos, use_pos); | 921 range->AddUseInterval(block_start_pos, use_pos); |
880 range->AddUse(use_pos, &locations[i]); | 922 range->AddUse(use_pos, &locations[i]); |
881 } | 923 } |
882 } | 924 } |
883 | 925 |
884 mat->set_locations(locations); | 926 mat->set_locations(locations); |
885 } | 927 } |
886 | 928 |
887 | 929 |
888 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, | 930 void FlowGraphAllocator::ProcessOneInput(BlockEntryInstr* block, |
889 intptr_t pos, | 931 intptr_t pos, |
890 Location* in_ref, | 932 Location* in_ref, |
891 Value* input, | 933 Value* input, |
892 intptr_t vreg) { | 934 intptr_t vreg, |
| 935 RegisterSet* live_registers) { |
893 ASSERT(in_ref != NULL); | 936 ASSERT(in_ref != NULL); |
894 ASSERT(!in_ref->IsPairLocation()); | 937 ASSERT(!in_ref->IsPairLocation()); |
895 ASSERT(input != NULL); | 938 ASSERT(input != NULL); |
896 ASSERT(block != NULL); | 939 ASSERT(block != NULL); |
897 LiveRange* range = GetLiveRange(vreg); | 940 LiveRange* range = GetLiveRange(vreg); |
898 if (in_ref->IsMachineRegister()) { | 941 if (in_ref->IsMachineRegister()) { |
899 // Input is expected in a fixed register. Expected shape of | 942 // Input is expected in a fixed register. Expected shape of |
900 // live ranges: | 943 // live ranges: |
901 // | 944 // |
902 // j' i i' | 945 // j' i i' |
903 // value --* | 946 // value --* |
904 // register [-----) | 947 // register [-----) |
905 // | 948 // |
| 949 if (live_registers != NULL) { |
| 950 live_registers->Add(*in_ref, range->representation()); |
| 951 } |
906 MoveOperands* move = | 952 MoveOperands* move = |
907 AddMoveAt(pos - 1, *in_ref, Location::Any()); | 953 AddMoveAt(pos - 1, *in_ref, Location::Any()); |
908 BlockLocation(*in_ref, pos - 1, pos + 1); | 954 BlockLocation(*in_ref, pos - 1, pos + 1); |
909 range->AddUseInterval(block->start_pos(), pos - 1); | 955 range->AddUseInterval(block->start_pos(), pos - 1); |
910 range->AddHintedUse(pos - 1, move->src_slot(), in_ref); | 956 range->AddHintedUse(pos - 1, move->src_slot(), in_ref); |
911 } else if (in_ref->IsUnallocated()) { | 957 } else if (in_ref->IsUnallocated()) { |
912 if (in_ref->policy() == Location::kWritableRegister) { | 958 if (in_ref->policy() == Location::kWritableRegister) { |
913 // Writable unallocated input. Expected shape of | 959 // Writable unallocated input. Expected shape of |
914 // live ranges: | 960 // live ranges: |
915 // | 961 // |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1107 if (locs->out(0).IsUnallocated() && | 1153 if (locs->out(0).IsUnallocated() && |
1108 (locs->out(0).policy() == Location::kSameAsFirstInput) && | 1154 (locs->out(0).policy() == Location::kSameAsFirstInput) && |
1109 (locs->in(0).IsMachineRegister())) { | 1155 (locs->in(0).IsMachineRegister())) { |
1110 locs->set_out(0, locs->in(0)); | 1156 locs->set_out(0, locs->in(0)); |
1111 } | 1157 } |
1112 | 1158 |
1113 const bool output_same_as_first_input = | 1159 const bool output_same_as_first_input = |
1114 locs->out(0).IsUnallocated() && | 1160 locs->out(0).IsUnallocated() && |
1115 (locs->out(0).policy() == Location::kSameAsFirstInput); | 1161 (locs->out(0).policy() == Location::kSameAsFirstInput); |
1116 | 1162 |
| 1163 // Output is same as first input which is a pair. |
| 1164 if (output_same_as_first_input && locs->in(0).IsPairLocation()) { |
| 1165 // Make out into a PairLocation. |
| 1166 locs->set_out(0, Location::Pair(Location::RequiresRegister(), |
| 1167 Location::RequiresRegister())); |
| 1168 } |
1117 // Add uses from the deoptimization environment. | 1169 // Add uses from the deoptimization environment. |
1118 if (current->env() != NULL) ProcessEnvironmentUses(block, current); | 1170 if (current->env() != NULL) ProcessEnvironmentUses(block, current); |
1119 | 1171 |
1120 // Process inputs. | 1172 // Process inputs. |
1121 // Skip the first input if output is specified with kSameAsFirstInput policy, | 1173 // Skip the first input if output is specified with kSameAsFirstInput policy, |
1122 // they will be processed together at the very end. | 1174 // they will be processed together at the very end. |
1123 { | 1175 { |
1124 for (intptr_t j = output_same_as_first_input ? 1 : 0; | 1176 for (intptr_t j = output_same_as_first_input ? 1 : 0; |
1125 j < locs->input_count(); | 1177 j < locs->input_count(); |
1126 j++) { | 1178 j++) { |
1127 // Determine if we are dealing with a value pair, and if so, whether | 1179 // Determine if we are dealing with a value pair, and if so, whether |
1128 // the location is the first register or second register. | 1180 // the location is the first register or second register. |
1129 Value* input = current->InputAt(j); | 1181 Value* input = current->InputAt(j); |
1130 Location* in_ref = locs->in_slot(j); | 1182 Location* in_ref = locs->in_slot(j); |
| 1183 RegisterSet* live_registers = NULL; |
| 1184 if (locs->HasCallOnSlowPath()) { |
| 1185 live_registers = locs->live_registers(); |
| 1186 } |
1131 if (in_ref->IsPairLocation()) { | 1187 if (in_ref->IsPairLocation()) { |
1132 ASSERT(input->definition()->HasPairRepresentation()); | 1188 ASSERT(input->definition()->HasPairRepresentation()); |
1133 PairLocation* pair = in_ref->AsPairLocation(); | 1189 PairLocation* pair = in_ref->AsPairLocation(); |
1134 const intptr_t vreg = input->definition()->ssa_temp_index(); | 1190 const intptr_t vreg = input->definition()->ssa_temp_index(); |
1135 // Each element of the pair is assigned it's own virtual register number | 1191 // Each element of the pair is assigned it's own virtual register number |
1136 // and is allocated its own LiveRange. | 1192 // and is allocated its own LiveRange. |
1137 ProcessOneInput(block, pos, pair->SlotAt(0), | 1193 ProcessOneInput(block, pos, pair->SlotAt(0), |
1138 input, vreg); | 1194 input, vreg, live_registers); |
1139 ProcessOneInput(block, pos, pair->SlotAt(1), input, | 1195 ProcessOneInput(block, pos, pair->SlotAt(1), input, |
1140 ToSecondPairVreg(vreg)); | 1196 ToSecondPairVreg(vreg), live_registers); |
1141 } else { | 1197 } else { |
1142 ProcessOneInput(block, pos, in_ref, input, | 1198 ProcessOneInput(block, pos, in_ref, input, |
1143 input->definition()->ssa_temp_index()); | 1199 input->definition()->ssa_temp_index(), live_registers); |
1144 } | 1200 } |
1145 } | 1201 } |
1146 } | 1202 } |
1147 | 1203 |
1148 // Process temps. | 1204 // Process temps. |
1149 for (intptr_t j = 0; j < locs->temp_count(); j++) { | 1205 for (intptr_t j = 0; j < locs->temp_count(); j++) { |
1150 // Expected shape of live range: | 1206 // Expected shape of live range: |
1151 // | 1207 // |
1152 // i i' | 1208 // i i' |
1153 // [--) | 1209 // [--) |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1515 Location* loc = use->location_slot(); | 1571 Location* loc = use->location_slot(); |
1516 if (loc->IsUnallocated() && loc->IsRegisterBeneficial()) { | 1572 if (loc->IsUnallocated() && loc->IsRegisterBeneficial()) { |
1517 first_register_beneficial_use_ = use; | 1573 first_register_beneficial_use_ = use; |
1518 return use; | 1574 return use; |
1519 } | 1575 } |
1520 } | 1576 } |
1521 return NULL; | 1577 return NULL; |
1522 } | 1578 } |
1523 | 1579 |
1524 | 1580 |
| 1581 UsePosition* AllocationFinger::FirstInterferingUse(intptr_t after) { |
| 1582 if (IsInstructionEndPosition(after)) { |
| 1583 // If after is a position at the end of the instruction disregard |
| 1584 // any use occuring at it. |
| 1585 after += 1; |
| 1586 } |
| 1587 return FirstRegisterUse(after); |
| 1588 } |
| 1589 |
| 1590 |
1525 void AllocationFinger::UpdateAfterSplit(intptr_t first_use_after_split_pos) { | 1591 void AllocationFinger::UpdateAfterSplit(intptr_t first_use_after_split_pos) { |
1526 if ((first_register_use_ != NULL) && | 1592 if ((first_register_use_ != NULL) && |
1527 (first_register_use_->pos() >= first_use_after_split_pos)) { | 1593 (first_register_use_->pos() >= first_use_after_split_pos)) { |
1528 first_register_use_ = NULL; | 1594 first_register_use_ = NULL; |
1529 } | 1595 } |
1530 | 1596 |
1531 if ((first_register_beneficial_use_ != NULL) && | 1597 if ((first_register_beneficial_use_ != NULL) && |
1532 (first_register_beneficial_use_->pos() >= first_use_after_split_pos)) { | 1598 (first_register_beneficial_use_->pos() >= first_use_after_split_pos)) { |
1533 first_register_beneficial_use_ = NULL; | 1599 first_register_beneficial_use_ = NULL; |
1534 } | 1600 } |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1688 // Split at block's start. | 1754 // Split at block's start. |
1689 split_pos = split_block->entry()->lifetime_position(); | 1755 split_pos = split_block->entry()->lifetime_position(); |
1690 } else { | 1756 } else { |
1691 // Interval [from, to) is contained inside a single block. | 1757 // Interval [from, to) is contained inside a single block. |
1692 | 1758 |
1693 // Split at position corresponding to the end of the previous | 1759 // Split at position corresponding to the end of the previous |
1694 // instruction. | 1760 // instruction. |
1695 split_pos = ToInstructionStart(to) - 1; | 1761 split_pos = ToInstructionStart(to) - 1; |
1696 } | 1762 } |
1697 | 1763 |
1698 ASSERT((split_pos != kIllegalPosition) && (from < split_pos)); | 1764 ASSERT(split_pos != kIllegalPosition); |
| 1765 ASSERT(from < split_pos); |
1699 | 1766 |
1700 return range->SplitAt(split_pos); | 1767 return range->SplitAt(split_pos); |
1701 } | 1768 } |
1702 | 1769 |
1703 | 1770 |
1704 void FlowGraphAllocator::SpillBetween(LiveRange* range, | 1771 void FlowGraphAllocator::SpillBetween(LiveRange* range, |
1705 intptr_t from, | 1772 intptr_t from, |
1706 intptr_t to) { | 1773 intptr_t to) { |
1707 ASSERT(from < to); | 1774 ASSERT(from < to); |
1708 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") " | 1775 TRACE_ALLOC(OS::Print("spill v%" Pd " [%" Pd ", %" Pd ") " |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1762 // During fpu register allocation spill slot indices are computed in terms of | 1829 // During fpu register allocation spill slot indices are computed in terms of |
1763 // double (64bit) stack slots. We treat quad stack slot (128bit) as a | 1830 // double (64bit) stack slots. We treat quad stack slot (128bit) as a |
1764 // consecutive pair of two double spill slots. | 1831 // consecutive pair of two double spill slots. |
1765 // Special care is taken to never allocate the same index to both | 1832 // Special care is taken to never allocate the same index to both |
1766 // double and quad spill slots as it complicates disambiguation during | 1833 // double and quad spill slots as it complicates disambiguation during |
1767 // parallel move resolution. | 1834 // parallel move resolution. |
1768 const bool need_quad = (register_kind_ == Location::kFpuRegister) && | 1835 const bool need_quad = (register_kind_ == Location::kFpuRegister) && |
1769 ((range->representation() == kUnboxedFloat32x4) || | 1836 ((range->representation() == kUnboxedFloat32x4) || |
1770 (range->representation() == kUnboxedInt32x4) || | 1837 (range->representation() == kUnboxedInt32x4) || |
1771 (range->representation() == kUnboxedFloat64x2)); | 1838 (range->representation() == kUnboxedFloat64x2)); |
| 1839 const bool need_untagged = (register_kind_ == Location::kRegister) && |
| 1840 ((range->representation() == kUntagged)); |
1772 | 1841 |
1773 // Search for a free spill slot among allocated: the value in it should be | 1842 // Search for a free spill slot among allocated: the value in it should be |
1774 // dead and its type should match (e.g. it should not be a part of the quad if | 1843 // dead and its type should match (e.g. it should not be a part of the quad if |
1775 // we are allocating normal double slot). | 1844 // we are allocating normal double slot). |
1776 // For CPU registers we need to take reserved slots for try-catch into | 1845 // For CPU registers we need to take reserved slots for try-catch into |
1777 // account. | 1846 // account. |
1778 intptr_t idx = register_kind_ == Location::kRegister | 1847 intptr_t idx = register_kind_ == Location::kRegister |
1779 ? flow_graph_.graph_entry()->fixed_slot_count() | 1848 ? flow_graph_.graph_entry()->fixed_slot_count() |
1780 : 0; | 1849 : 0; |
1781 for (; idx < spill_slots_.length(); idx++) { | 1850 for (; idx < spill_slots_.length(); idx++) { |
1782 if ((need_quad == quad_spill_slots_[idx]) && | 1851 if ((need_quad == quad_spill_slots_[idx]) && |
| 1852 (need_untagged == untagged_spill_slots_[idx]) && |
1783 (spill_slots_[idx] <= start)) { | 1853 (spill_slots_[idx] <= start)) { |
1784 break; | 1854 break; |
1785 } | 1855 } |
1786 } | 1856 } |
1787 | 1857 |
1788 if (idx == spill_slots_.length()) { | 1858 if (idx == spill_slots_.length()) { |
1789 // No free spill slot found. Allocate a new one. | 1859 // No free spill slot found. Allocate a new one. |
1790 spill_slots_.Add(0); | 1860 spill_slots_.Add(0); |
1791 quad_spill_slots_.Add(need_quad); | 1861 quad_spill_slots_.Add(need_quad); |
| 1862 untagged_spill_slots_.Add(need_untagged); |
1792 if (need_quad) { // Allocate two double stack slots if we need quad slot. | 1863 if (need_quad) { // Allocate two double stack slots if we need quad slot. |
1793 spill_slots_.Add(0); | 1864 spill_slots_.Add(0); |
1794 quad_spill_slots_.Add(need_quad); | 1865 quad_spill_slots_.Add(need_quad); |
| 1866 untagged_spill_slots_.Add(need_untagged); |
1795 } | 1867 } |
1796 } | 1868 } |
1797 | 1869 |
1798 // Set spill slot expiration boundary to the live range's end. | 1870 // Set spill slot expiration boundary to the live range's end. |
1799 spill_slots_[idx] = end; | 1871 spill_slots_[idx] = end; |
1800 if (need_quad) { | 1872 if (need_quad) { |
1801 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]); | 1873 ASSERT(quad_spill_slots_[idx] && quad_spill_slots_[idx + 1]); |
1802 idx++; // Use the higher index it corresponds to the lower stack address. | 1874 idx++; // Use the higher index it corresponds to the lower stack address. |
1803 spill_slots_[idx] = end; | 1875 spill_slots_[idx] = end; |
1804 } else { | 1876 } else { |
(...skipping 10 matching lines...) Expand all Loading... |
1815 const intptr_t slot_idx = cpu_spill_slot_count_ + | 1887 const intptr_t slot_idx = cpu_spill_slot_count_ + |
1816 idx * kDoubleSpillFactor + (kDoubleSpillFactor - 1); | 1888 idx * kDoubleSpillFactor + (kDoubleSpillFactor - 1); |
1817 | 1889 |
1818 Location location; | 1890 Location location; |
1819 if ((range->representation() == kUnboxedFloat32x4) || | 1891 if ((range->representation() == kUnboxedFloat32x4) || |
1820 (range->representation() == kUnboxedInt32x4) || | 1892 (range->representation() == kUnboxedInt32x4) || |
1821 (range->representation() == kUnboxedFloat64x2)) { | 1893 (range->representation() == kUnboxedFloat64x2)) { |
1822 ASSERT(need_quad); | 1894 ASSERT(need_quad); |
1823 location = Location::QuadStackSlot(slot_idx); | 1895 location = Location::QuadStackSlot(slot_idx); |
1824 } else { | 1896 } else { |
1825 ASSERT((range->representation() == kUnboxedDouble) || | 1897 ASSERT((range->representation() == kUnboxedDouble)); |
1826 (range->representation() == kUnboxedMint)); | |
1827 location = Location::DoubleStackSlot(slot_idx); | 1898 location = Location::DoubleStackSlot(slot_idx); |
1828 } | 1899 } |
1829 range->set_spill_slot(location); | 1900 range->set_spill_slot(location); |
1830 } | 1901 } |
1831 | 1902 |
1832 spilled_.Add(range); | 1903 spilled_.Add(range); |
1833 } | 1904 } |
1834 | 1905 |
1835 | 1906 |
1836 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { | 1907 void FlowGraphAllocator::MarkAsObjectAtSafepoints(LiveRange* range) { |
1837 intptr_t stack_index = range->spill_slot().stack_index(); | 1908 intptr_t stack_index = range->spill_slot().stack_index(); |
1838 ASSERT(stack_index >= 0); | 1909 ASSERT(stack_index >= 0); |
1839 | 1910 |
1840 while (range != NULL) { | 1911 while (range != NULL) { |
1841 for (SafepointPosition* safepoint = range->first_safepoint(); | 1912 for (SafepointPosition* safepoint = range->first_safepoint(); |
1842 safepoint != NULL; | 1913 safepoint != NULL; |
1843 safepoint = safepoint->next()) { | 1914 safepoint = safepoint->next()) { |
| 1915 // Mark the stack slot as having an object. |
1844 safepoint->locs()->stack_bitmap()->Set(stack_index, true); | 1916 safepoint->locs()->stack_bitmap()->Set(stack_index, true); |
1845 } | 1917 } |
1846 range = range->next_sibling(); | 1918 range = range->next_sibling(); |
1847 } | 1919 } |
1848 } | 1920 } |
1849 | 1921 |
1850 | 1922 |
1851 void FlowGraphAllocator::Spill(LiveRange* range) { | 1923 void FlowGraphAllocator::Spill(LiveRange* range) { |
1852 LiveRange* parent = GetLiveRange(range->vreg()); | 1924 LiveRange* parent = GetLiveRange(range->vreg()); |
1853 if (parent->spill_slot().IsInvalid()) { | 1925 if (parent->spill_slot().IsInvalid()) { |
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2192 UseInterval* first_pending_use_interval = | 2264 UseInterval* first_pending_use_interval = |
2193 allocated->finger()->first_pending_use_interval(); | 2265 allocated->finger()->first_pending_use_interval(); |
2194 if (first_pending_use_interval->Contains(start)) { | 2266 if (first_pending_use_interval->Contains(start)) { |
2195 // This is an active interval. | 2267 // This is an active interval. |
2196 if (allocated->vreg() < 0) { | 2268 if (allocated->vreg() < 0) { |
2197 // This register blocked by an interval that | 2269 // This register blocked by an interval that |
2198 // can't be spilled. | 2270 // can't be spilled. |
2199 return false; | 2271 return false; |
2200 } | 2272 } |
2201 | 2273 |
2202 const UsePosition* use = | 2274 UsePosition* use = |
2203 allocated->finger()->FirstRegisterBeneficialUse(unallocated->Start()); | 2275 allocated->finger()->FirstInterferingUse(start); |
2204 | |
2205 if ((use != NULL) && ((ToInstructionStart(use->pos()) - start) <= 1)) { | 2276 if ((use != NULL) && ((ToInstructionStart(use->pos()) - start) <= 1)) { |
2206 // This register is blocked by interval that is used | 2277 // This register is blocked by interval that is used |
2207 // as register in the current instruction and can't | 2278 // as register in the current instruction and can't |
2208 // be spilled. | 2279 // be spilled. |
2209 return false; | 2280 return false; |
2210 } | 2281 } |
2211 | 2282 |
2212 const intptr_t use_pos = (use != NULL) ? use->pos() | 2283 const intptr_t use_pos = (use != NULL) ? use->pos() |
2213 : allocated->End(); | 2284 : allocated->End(); |
2214 | 2285 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2274 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, | 2345 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, |
2275 LiveRange* unallocated) { | 2346 LiveRange* unallocated) { |
2276 UseInterval* first_unallocated = | 2347 UseInterval* first_unallocated = |
2277 unallocated->finger()->first_pending_use_interval(); | 2348 unallocated->finger()->first_pending_use_interval(); |
2278 const intptr_t intersection = FirstIntersection( | 2349 const intptr_t intersection = FirstIntersection( |
2279 allocated->finger()->first_pending_use_interval(), | 2350 allocated->finger()->first_pending_use_interval(), |
2280 first_unallocated); | 2351 first_unallocated); |
2281 if (intersection == kMaxPosition) return false; | 2352 if (intersection == kMaxPosition) return false; |
2282 | 2353 |
2283 const intptr_t spill_position = first_unallocated->start(); | 2354 const intptr_t spill_position = first_unallocated->start(); |
2284 UsePosition* use = allocated->finger()->FirstRegisterUse(spill_position); | 2355 UsePosition* use = allocated->finger()->FirstInterferingUse(spill_position); |
2285 if (use == NULL) { | 2356 if (use == NULL) { |
2286 // No register uses after this point. | 2357 // No register uses after this point. |
2287 SpillAfter(allocated, spill_position); | 2358 SpillAfter(allocated, spill_position); |
2288 } else { | 2359 } else { |
2289 const intptr_t restore_position = | 2360 const intptr_t restore_position = |
2290 (spill_position < intersection) ? MinPosition(intersection, use->pos()) | 2361 (spill_position < intersection) ? MinPosition(intersection, use->pos()) |
2291 : use->pos(); | 2362 : use->pos(); |
2292 | 2363 |
2293 SpillBetween(allocated, spill_position, restore_position); | 2364 SpillBetween(allocated, spill_position, restore_position); |
2294 } | 2365 } |
(...skipping 14 matching lines...) Expand all Loading... |
2309 parallel_move = CreateParallelMoveBefore(instr, pos); | 2380 parallel_move = CreateParallelMoveBefore(instr, pos); |
2310 } else { | 2381 } else { |
2311 parallel_move = CreateParallelMoveAfter(instr, pos); | 2382 parallel_move = CreateParallelMoveAfter(instr, pos); |
2312 } | 2383 } |
2313 | 2384 |
2314 return parallel_move->AddMove(to, from); | 2385 return parallel_move->AddMove(to, from); |
2315 } | 2386 } |
2316 | 2387 |
2317 | 2388 |
2318 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { | 2389 void FlowGraphAllocator::ConvertUseTo(UsePosition* use, Location loc) { |
| 2390 ASSERT(!loc.IsPairLocation()); |
2319 ASSERT(use->location_slot() != NULL); | 2391 ASSERT(use->location_slot() != NULL); |
2320 Location* slot = use->location_slot(); | 2392 Location* slot = use->location_slot(); |
2321 ASSERT(slot->IsUnallocated()); | 2393 ASSERT(slot->IsUnallocated()); |
2322 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos())); | 2394 TRACE_ALLOC(OS::Print(" use at %" Pd " converted to ", use->pos())); |
2323 TRACE_ALLOC(loc.Print()); | 2395 TRACE_ALLOC(loc.Print()); |
2324 TRACE_ALLOC(OS::Print("\n")); | 2396 TRACE_ALLOC(OS::Print("\n")); |
2325 *slot = loc; | 2397 *slot = loc; |
2326 } | 2398 } |
2327 | 2399 |
2328 | 2400 |
(...skipping 14 matching lines...) Expand all Loading... |
2343 } | 2415 } |
2344 | 2416 |
2345 // Add live registers at all safepoints for instructions with slow-path | 2417 // Add live registers at all safepoints for instructions with slow-path |
2346 // code. | 2418 // code. |
2347 if (loc.IsMachineRegister()) { | 2419 if (loc.IsMachineRegister()) { |
2348 for (SafepointPosition* safepoint = range->first_safepoint(); | 2420 for (SafepointPosition* safepoint = range->first_safepoint(); |
2349 safepoint != NULL; | 2421 safepoint != NULL; |
2350 safepoint = safepoint->next()) { | 2422 safepoint = safepoint->next()) { |
2351 if (!safepoint->locs()->always_calls()) { | 2423 if (!safepoint->locs()->always_calls()) { |
2352 ASSERT(safepoint->locs()->can_call()); | 2424 ASSERT(safepoint->locs()->can_call()); |
2353 safepoint->locs()->live_registers()->Add(loc); | 2425 safepoint->locs()->live_registers()->Add(loc, range->representation()); |
2354 } | 2426 } |
2355 } | 2427 } |
2356 } | 2428 } |
2357 } | 2429 } |
2358 | 2430 |
2359 | 2431 |
2360 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { | 2432 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { |
2361 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) { | 2433 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) { |
2362 if (registers_[reg]->is_empty()) continue; | 2434 if (registers_[reg]->is_empty()) continue; |
2363 | 2435 |
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2662 ASSERT(range->assigned_location().Equals(range->spill_slot())); | 2734 ASSERT(range->assigned_location().Equals(range->spill_slot())); |
2663 } else { | 2735 } else { |
2664 AddMoveAt(range->Start() + 1, | 2736 AddMoveAt(range->Start() + 1, |
2665 range->spill_slot(), | 2737 range->spill_slot(), |
2666 range->assigned_location()); | 2738 range->assigned_location()); |
2667 } | 2739 } |
2668 } | 2740 } |
2669 } | 2741 } |
2670 | 2742 |
2671 | 2743 |
| 2744 static Representation RepresentationForRange(Representation definition_rep) { |
| 2745 if (definition_rep == kUnboxedMint) { |
| 2746 // kUnboxedMint is split into two ranges, each of which are kUntagged. |
| 2747 return kUntagged; |
| 2748 } |
| 2749 return definition_rep; |
| 2750 } |
| 2751 |
| 2752 |
2672 void FlowGraphAllocator::CollectRepresentations() { | 2753 void FlowGraphAllocator::CollectRepresentations() { |
2673 // Parameters. | 2754 // Parameters. |
2674 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); | 2755 GraphEntryInstr* graph_entry = flow_graph_.graph_entry(); |
2675 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); ++i) { | 2756 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); ++i) { |
2676 Definition* def = (*graph_entry->initial_definitions())[i]; | 2757 Definition* def = (*graph_entry->initial_definitions())[i]; |
2677 value_representations_[def->ssa_temp_index()] = def->representation(); | 2758 value_representations_[def->ssa_temp_index()] = |
| 2759 RepresentationForRange(def->representation()); |
2678 ASSERT(!def->HasPairRepresentation()); | 2760 ASSERT(!def->HasPairRepresentation()); |
2679 } | 2761 } |
2680 | 2762 |
2681 for (BlockIterator it = flow_graph_.reverse_postorder_iterator(); | 2763 for (BlockIterator it = flow_graph_.reverse_postorder_iterator(); |
2682 !it.Done(); | 2764 !it.Done(); |
2683 it.Advance()) { | 2765 it.Advance()) { |
2684 BlockEntryInstr* block = it.Current(); | 2766 BlockEntryInstr* block = it.Current(); |
2685 | 2767 |
2686 // Catch entry. | 2768 // Catch entry. |
2687 if (block->IsCatchBlockEntry()) { | 2769 if (block->IsCatchBlockEntry()) { |
2688 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); | 2770 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); |
2689 for (intptr_t i = 0; | 2771 for (intptr_t i = 0; |
2690 i < catch_entry->initial_definitions()->length(); | 2772 i < catch_entry->initial_definitions()->length(); |
2691 ++i) { | 2773 ++i) { |
2692 Definition* def = (*catch_entry->initial_definitions())[i]; | 2774 Definition* def = (*catch_entry->initial_definitions())[i]; |
2693 value_representations_[def->ssa_temp_index()] = def->representation(); | 2775 ASSERT(!def->HasPairRepresentation()); |
| 2776 value_representations_[def->ssa_temp_index()] = |
| 2777 RepresentationForRange(def->representation()); |
2694 } | 2778 } |
2695 } | 2779 } |
2696 // Phis. | 2780 // Phis. |
2697 if (block->IsJoinEntry()) { | 2781 if (block->IsJoinEntry()) { |
2698 JoinEntryInstr* join = block->AsJoinEntry(); | 2782 JoinEntryInstr* join = block->AsJoinEntry(); |
2699 for (PhiIterator it(join); !it.Done(); it.Advance()) { | 2783 for (PhiIterator it(join); !it.Done(); it.Advance()) { |
2700 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. | 2784 // TODO(johnmccutchan): Fix handling of PhiInstr with PairLocation. |
2701 PhiInstr* phi = it.Current(); | 2785 PhiInstr* phi = it.Current(); |
2702 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { | 2786 if ((phi != NULL) && (phi->ssa_temp_index() >= 0)) { |
2703 value_representations_[phi->ssa_temp_index()] = phi->representation(); | 2787 ASSERT(!phi->HasPairRepresentation()); |
| 2788 value_representations_[phi->ssa_temp_index()] = |
| 2789 RepresentationForRange(phi->representation()); |
2704 } | 2790 } |
2705 } | 2791 } |
2706 } | 2792 } |
2707 // Normal instructions. | 2793 // Normal instructions. |
2708 for (ForwardInstructionIterator instr_it(block); | 2794 for (ForwardInstructionIterator instr_it(block); |
2709 !instr_it.Done(); | 2795 !instr_it.Done(); |
2710 instr_it.Advance()) { | 2796 instr_it.Advance()) { |
2711 Definition* def = instr_it.Current()->AsDefinition(); | 2797 Definition* def = instr_it.Current()->AsDefinition(); |
2712 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { | 2798 if ((def != NULL) && (def->ssa_temp_index() >= 0)) { |
2713 const intptr_t vreg = def->ssa_temp_index(); | 2799 const intptr_t vreg = def->ssa_temp_index(); |
2714 value_representations_[vreg] = def->representation(); | 2800 value_representations_[vreg] = |
| 2801 RepresentationForRange(def->representation()); |
2715 if (def->HasPairRepresentation()) { | 2802 if (def->HasPairRepresentation()) { |
2716 value_representations_[ToSecondPairVreg(vreg)] = def->representation(); | 2803 value_representations_[ToSecondPairVreg(vreg)] = |
| 2804 RepresentationForRange(def->representation()); |
2717 } | 2805 } |
2718 } | 2806 } |
2719 } | 2807 } |
2720 } | 2808 } |
2721 } | 2809 } |
2722 | 2810 |
2723 | 2811 |
2724 void FlowGraphAllocator::AllocateRegisters() { | 2812 void FlowGraphAllocator::AllocateRegisters() { |
2725 CollectRepresentations(); | 2813 CollectRepresentations(); |
2726 | 2814 |
(...skipping 27 matching lines...) Expand all Loading... |
2754 PrepareForAllocation(Location::kRegister, | 2842 PrepareForAllocation(Location::kRegister, |
2755 kNumberOfCpuRegisters, | 2843 kNumberOfCpuRegisters, |
2756 unallocated_cpu_, | 2844 unallocated_cpu_, |
2757 cpu_regs_, | 2845 cpu_regs_, |
2758 blocked_cpu_registers_); | 2846 blocked_cpu_registers_); |
2759 AllocateUnallocatedRanges(); | 2847 AllocateUnallocatedRanges(); |
2760 | 2848 |
2761 cpu_spill_slot_count_ = spill_slots_.length(); | 2849 cpu_spill_slot_count_ = spill_slots_.length(); |
2762 spill_slots_.Clear(); | 2850 spill_slots_.Clear(); |
2763 quad_spill_slots_.Clear(); | 2851 quad_spill_slots_.Clear(); |
| 2852 untagged_spill_slots_.Clear(); |
2764 | 2853 |
2765 PrepareForAllocation(Location::kFpuRegister, | 2854 PrepareForAllocation(Location::kFpuRegister, |
2766 kNumberOfFpuRegisters, | 2855 kNumberOfFpuRegisters, |
2767 unallocated_xmm_, | 2856 unallocated_xmm_, |
2768 fpu_regs_, | 2857 fpu_regs_, |
2769 blocked_fpu_registers_); | 2858 blocked_fpu_registers_); |
2770 AllocateUnallocatedRanges(); | 2859 AllocateUnallocatedRanges(); |
2771 | 2860 |
2772 ResolveControlFlow(); | 2861 ResolveControlFlow(); |
2773 | 2862 |
(...skipping 13 matching lines...) Expand all Loading... |
2787 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", | 2876 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", |
2788 function.ToFullyQualifiedCString()); | 2877 function.ToFullyQualifiedCString()); |
2789 FlowGraphPrinter printer(flow_graph_, true); | 2878 FlowGraphPrinter printer(flow_graph_, true); |
2790 printer.PrintBlocks(); | 2879 printer.PrintBlocks(); |
2791 OS::Print("----------------------------------------------\n"); | 2880 OS::Print("----------------------------------------------\n"); |
2792 } | 2881 } |
2793 } | 2882 } |
2794 | 2883 |
2795 | 2884 |
2796 } // namespace dart | 2885 } // namespace dart |
OLD | NEW |