| 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 |