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