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 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 | 145 |
146 BitVector* kill = kill_[i]; | 146 BitVector* kill = kill_[i]; |
147 BitVector* live_in = live_in_[i]; | 147 BitVector* live_in = live_in_[i]; |
148 | 148 |
149 // Iterate backwards starting at the last instruction. | 149 // Iterate backwards starting at the last instruction. |
150 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 150 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
151 Instruction* current = it.Current(); | 151 Instruction* current = it.Current(); |
152 | 152 |
153 // Initialize location summary for instruction. | 153 // Initialize location summary for instruction. |
154 current->InitializeLocationSummary(zone(), true); // opt | 154 current->InitializeLocationSummary(zone(), true); // opt |
155 #if defined(TARGET_ARCH_DBC) | |
156 // TODO(vegorov) remove this once we have ported all necessary | |
157 // instructions to DBC. | |
158 if (!current->HasLocs()) { | |
159 graph_entry_->parsed_function().Bailout("SSALivenessAnalysis", | |
160 current->ToCString()); | |
161 } | |
162 #endif | |
163 | |
155 LocationSummary* locs = current->locs(); | 164 LocationSummary* locs = current->locs(); |
156 #if defined(DEBUG) | 165 #if defined(DEBUG) |
157 locs->DiscoverWritableInputs(); | 166 locs->DiscoverWritableInputs(); |
158 #endif | 167 #endif |
159 | 168 |
160 // Handle definitions. | 169 // Handle definitions. |
161 Definition* current_def = current->AsDefinition(); | 170 Definition* current_def = current->AsDefinition(); |
162 if ((current_def != NULL) && current_def->HasSSATemp()) { | 171 if ((current_def != NULL) && current_def->HasSSATemp()) { |
163 kill->Add(current_def->ssa_temp_index()); | 172 kill->Add(current_def->ssa_temp_index()); |
164 live_in->Remove(current_def->ssa_temp_index()); | 173 live_in->Remove(current_def->ssa_temp_index()); |
165 if (current_def->HasPairRepresentation()) { | 174 if (current_def->HasPairRepresentation()) { |
166 kill->Add(ToSecondPairVreg(current_def->ssa_temp_index())); | 175 kill->Add(ToSecondPairVreg(current_def->ssa_temp_index())); |
167 live_in->Remove(ToSecondPairVreg(current_def->ssa_temp_index())); | 176 live_in->Remove(ToSecondPairVreg(current_def->ssa_temp_index())); |
168 } | 177 } |
169 } | 178 } |
170 | 179 |
171 // Handle uses. | 180 // Handle uses. |
181 if (locs->input_count() != current->InputCount()) { | |
Florian Schneider
2016/05/19 13:21:39
Left-over from debugging?
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
182 fprintf(stderr, "%s\n", current->ToCString()); | |
183 } | |
172 ASSERT(locs->input_count() == current->InputCount()); | 184 ASSERT(locs->input_count() == current->InputCount()); |
173 for (intptr_t j = 0; j < current->InputCount(); j++) { | 185 for (intptr_t j = 0; j < current->InputCount(); j++) { |
174 Value* input = current->InputAt(j); | 186 Value* input = current->InputAt(j); |
175 | 187 |
176 ASSERT(!locs->in(j).IsConstant() || input->BindsToConstant()); | 188 ASSERT(!locs->in(j).IsConstant() || input->BindsToConstant()); |
177 if (locs->in(j).IsConstant()) continue; | 189 if (locs->in(j).IsConstant()) continue; |
178 | 190 |
179 live_in->Add(input->definition()->ssa_temp_index()); | 191 live_in->Add(input->definition()->ssa_temp_index()); |
180 if (input->definition()->HasPairRepresentation()) { | 192 if (input->definition()->HasPairRepresentation()) { |
181 live_in->Add(ToSecondPairVreg(input->definition()->ssa_temp_index())); | 193 live_in->Add(ToSecondPairVreg(input->definition()->ssa_temp_index())); |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id()); | 603 range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id()); |
592 } | 604 } |
593 } | 605 } |
594 } | 606 } |
595 | 607 |
596 if (block->IsJoinEntry()) { | 608 if (block->IsJoinEntry()) { |
597 ConnectIncomingPhiMoves(block->AsJoinEntry()); | 609 ConnectIncomingPhiMoves(block->AsJoinEntry()); |
598 } else if (block->IsCatchBlockEntry()) { | 610 } else if (block->IsCatchBlockEntry()) { |
599 // Process initial definitions. | 611 // Process initial definitions. |
600 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); | 612 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); |
613 #if defined(TARGET_ARCH_DBC) | |
614 flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "Catch"); | |
Florian Schneider
2016/05/19 13:21:39
Add TODO to implement try-catch.
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
615 #endif | |
601 for (intptr_t i = 0; | 616 for (intptr_t i = 0; |
602 i < catch_entry->initial_definitions()->length(); | 617 i < catch_entry->initial_definitions()->length(); |
603 i++) { | 618 i++) { |
604 Definition* defn = (*catch_entry->initial_definitions())[i]; | 619 Definition* defn = (*catch_entry->initial_definitions())[i]; |
605 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); | 620 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); |
606 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. | 621 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. |
607 ProcessInitialDefinition(defn, range, catch_entry); | 622 ProcessInitialDefinition(defn, range, catch_entry); |
608 } | 623 } |
609 // Block the two fixed registers used by CatchBlockEntryInstr from the | 624 // Block the two fixed registers used by CatchBlockEntryInstr from the |
610 // block start to until the end of the instruction so that they are | 625 // block start to until the end of the instruction so that they are |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 ASSERT((flow_graph_.num_copied_params() == 0) || | 660 ASSERT((flow_graph_.num_copied_params() == 0) || |
646 (flow_graph_.num_non_copied_params() == 0)); | 661 (flow_graph_.num_non_copied_params() == 0)); |
647 intptr_t slot_index = param->index(); | 662 intptr_t slot_index = param->index(); |
648 ASSERT((param->base_reg() == FPREG) || (param->base_reg() == SPREG)); | 663 ASSERT((param->base_reg() == FPREG) || (param->base_reg() == SPREG)); |
649 if (param->base_reg() == FPREG) { | 664 if (param->base_reg() == FPREG) { |
650 // Slot index for the leftmost copied parameter is 0. | 665 // Slot index for the leftmost copied parameter is 0. |
651 // Slot index for the rightmost fixed parameter is -1. | 666 // Slot index for the rightmost fixed parameter is -1. |
652 slot_index -= flow_graph_.num_non_copied_params(); | 667 slot_index -= flow_graph_.num_non_copied_params(); |
653 } | 668 } |
654 | 669 |
670 #if defined(TARGET_ARCH_DBC) | |
671 ASSERT(param->base_reg() == FPREG); | |
672 if (slot_index >= 0) { | |
673 AssignSafepoints(defn, range); | |
674 range->finger()->Initialize(range); | |
675 range->set_assigned_location(Location::RegisterLocation(slot_index)); | |
676 if (range->End() > kNormalEntryPos) { | |
677 LiveRange* tail = range->SplitAt(kNormalEntryPos); | |
678 CompleteRange(tail, Location::kRegister); | |
679 } | |
680 ConvertAllUses(range); | |
681 return; | |
682 } | |
683 #endif // defined(TARGET_ARCH_DBC) | |
655 range->set_assigned_location(Location::StackSlot(slot_index, | 684 range->set_assigned_location(Location::StackSlot(slot_index, |
656 param->base_reg())); | 685 param->base_reg())); |
657 range->set_spill_slot(Location::StackSlot(slot_index, | 686 range->set_spill_slot(Location::StackSlot(slot_index, |
658 param->base_reg())); | 687 param->base_reg())); |
688 | |
659 } else if (defn->IsCurrentContext()) { | 689 } else if (defn->IsCurrentContext()) { |
690 #if !defined(TARGET_ARCH_DBC) | |
691 const Register context_reg = CTX; | |
692 #else | |
693 const intptr_t context_reg = flow_graph_.num_copied_params(); | |
694 #endif | |
695 | |
660 AssignSafepoints(defn, range); | 696 AssignSafepoints(defn, range); |
661 range->finger()->Initialize(range); | 697 range->finger()->Initialize(range); |
662 range->set_assigned_location(Location::RegisterLocation(CTX)); | 698 range->set_assigned_location(Location::RegisterLocation(context_reg)); |
663 if (range->End() > kNormalEntryPos) { | 699 if (range->End() > kNormalEntryPos) { |
664 LiveRange* tail = range->SplitAt(kNormalEntryPos); | 700 LiveRange* tail = range->SplitAt(kNormalEntryPos); |
665 CompleteRange(tail, Location::kRegister); | 701 CompleteRange(tail, Location::kRegister); |
666 } | 702 } |
667 ConvertAllUses(range); | 703 ConvertAllUses(range); |
668 return; | 704 return; |
669 } else { | 705 } else { |
670 ConstantInstr* constant = defn->AsConstant(); | 706 ConstantInstr* constant = defn->AsConstant(); |
671 ASSERT(constant != NULL); | 707 ASSERT(constant != NULL); |
672 range->set_assigned_location(Location::Constant(constant)); | 708 range->set_assigned_location(Location::Constant(constant)); |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1316 } else if (temp.IsUnallocated()) { | 1352 } else if (temp.IsUnallocated()) { |
1317 LiveRange* range = MakeLiveRangeForTemporary(); | 1353 LiveRange* range = MakeLiveRangeForTemporary(); |
1318 range->AddUseInterval(pos, pos + 1); | 1354 range->AddUseInterval(pos, pos + 1); |
1319 range->AddUse(pos, locs->temp_slot(j)); | 1355 range->AddUse(pos, locs->temp_slot(j)); |
1320 CompleteRange(range, RegisterKindFromPolicy(temp)); | 1356 CompleteRange(range, RegisterKindFromPolicy(temp)); |
1321 } else { | 1357 } else { |
1322 UNREACHABLE(); | 1358 UNREACHABLE(); |
1323 } | 1359 } |
1324 } | 1360 } |
1325 | 1361 |
1326 // Block all allocatable registers for calls and record the stack bitmap. | 1362 // Block all allocatable registers for calls. |
1363 // Note that on DBC registers are always essentially spilled so | |
1364 // we don't need to block anything. | |
1365 #if !defined(TARGET_ARCH_DBC) | |
1327 if (locs->always_calls()) { | 1366 if (locs->always_calls()) { |
1328 // Expected shape of live range: | 1367 // Expected shape of live range: |
1329 // | 1368 // |
1330 // i i' | 1369 // i i' |
1331 // [--) | 1370 // [--) |
1332 // | 1371 // |
1333 // The stack bitmap describes the position i. | 1372 // The stack bitmap describes the position i. |
1334 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { | 1373 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { |
1335 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), | 1374 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), |
1336 pos, | 1375 pos, |
(...skipping 29 matching lines...) Expand all Loading... | |
1366 | 1405 |
1367 if (locs->out(0).IsPairLocation()) { | 1406 if (locs->out(0).IsPairLocation()) { |
1368 PairLocation* pair = locs->out_slot(0)->AsPairLocation(); | 1407 PairLocation* pair = locs->out_slot(0)->AsPairLocation(); |
1369 ASSERT(!pair->At(0).IsUnallocated()); | 1408 ASSERT(!pair->At(0).IsUnallocated()); |
1370 ASSERT(!pair->At(1).IsUnallocated()); | 1409 ASSERT(!pair->At(1).IsUnallocated()); |
1371 } else { | 1410 } else { |
1372 ASSERT(!locs->out(0).IsUnallocated()); | 1411 ASSERT(!locs->out(0).IsUnallocated()); |
1373 } | 1412 } |
1374 #endif | 1413 #endif |
1375 } | 1414 } |
1415 #endif | |
1376 | 1416 |
1377 if (locs->can_call()) { | 1417 if (locs->can_call()) { |
1378 safepoints_.Add(current); | 1418 safepoints_.Add(current); |
1379 } | 1419 } |
1380 | 1420 |
1381 if (def == NULL) { | 1421 if (def == NULL) { |
1382 ASSERT(locs->out(0).IsInvalid()); | 1422 ASSERT(locs->out(0).IsInvalid()); |
1383 return; | 1423 return; |
1384 } | 1424 } |
1385 | 1425 |
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1899 from)); | 1939 from)); |
1900 } | 1940 } |
1901 } | 1941 } |
1902 | 1942 |
1903 LiveRange* tail = range->SplitAt(from); | 1943 LiveRange* tail = range->SplitAt(from); |
1904 Spill(tail); | 1944 Spill(tail); |
1905 } | 1945 } |
1906 | 1946 |
1907 | 1947 |
1908 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { | 1948 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { |
1949 #if defined(TARGET_ARCH_DBC) | |
1950 // We don't support spilling on DBC for now because we have access | |
Florian Schneider
2016/05/19 13:21:39
unterminated sentence?
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
1951 flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "SPILL"); | |
Florian Schneider
2016/05/19 13:21:40
Indentation.
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
Done.
| |
1952 UNREACHABLE(); | |
1953 #endif | |
1954 | |
1909 ASSERT(range->spill_slot().IsInvalid()); | 1955 ASSERT(range->spill_slot().IsInvalid()); |
1910 | 1956 |
1911 // Compute range start and end. | 1957 // Compute range start and end. |
1912 LiveRange* last_sibling = range; | 1958 LiveRange* last_sibling = range; |
1913 while (last_sibling->next_sibling() != NULL) { | 1959 while (last_sibling->next_sibling() != NULL) { |
1914 last_sibling = last_sibling->next_sibling(); | 1960 last_sibling = last_sibling->next_sibling(); |
1915 } | 1961 } |
1916 | 1962 |
1917 const intptr_t start = range->Start(); | 1963 const intptr_t start = range->Start(); |
1918 const intptr_t end = last_sibling->End(); | 1964 const intptr_t end = last_sibling->End(); |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2235 | 2281 |
2236 if (free_until != kMaxPosition) { | 2282 if (free_until != kMaxPosition) { |
2237 // There was an intersection. Split unallocated. | 2283 // There was an intersection. Split unallocated. |
2238 TRACE_ALLOC(THR_Print(" splitting at %" Pd "\n", free_until)); | 2284 TRACE_ALLOC(THR_Print(" splitting at %" Pd "\n", free_until)); |
2239 LiveRange* tail = unallocated->SplitAt(free_until); | 2285 LiveRange* tail = unallocated->SplitAt(free_until); |
2240 AddToUnallocated(tail); | 2286 AddToUnallocated(tail); |
2241 } | 2287 } |
2242 | 2288 |
2243 registers_[candidate]->Add(unallocated); | 2289 registers_[candidate]->Add(unallocated); |
2244 unallocated->set_assigned_location(MakeRegisterLocation(candidate)); | 2290 unallocated->set_assigned_location(MakeRegisterLocation(candidate)); |
2291 #if defined(TARGET_ARCH_DBC) | |
2292 last_used_register_ = Utils::Maximum(last_used_register_, candidate); | |
2293 #endif | |
2245 | 2294 |
2246 return true; | 2295 return true; |
2247 } | 2296 } |
2248 | 2297 |
2249 | 2298 |
2250 bool FlowGraphAllocator::RangeHasOnlyUnconstrainedUsesInLoop(LiveRange* range, | 2299 bool FlowGraphAllocator::RangeHasOnlyUnconstrainedUsesInLoop(LiveRange* range, |
2251 intptr_t loop_id) { | 2300 intptr_t loop_id) { |
2252 if (range->vreg() >= 0) { | 2301 if (range->vreg() >= 0) { |
2253 LiveRange* parent = GetLiveRange(range->vreg()); | 2302 LiveRange* parent = GetLiveRange(range->vreg()); |
2254 return parent->HasOnlyUnconstrainedUsesInLoop(loop_id); | 2303 return parent->HasOnlyUnconstrainedUsesInLoop(loop_id); |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2434 (*registers_[reg])[i] = NULL; | 2483 (*registers_[reg])[i] = NULL; |
2435 first_evicted = i; | 2484 first_evicted = i; |
2436 } | 2485 } |
2437 } | 2486 } |
2438 | 2487 |
2439 // Remove evicted ranges from the array. | 2488 // Remove evicted ranges from the array. |
2440 if (first_evicted != -1) RemoveEvicted(reg, first_evicted); | 2489 if (first_evicted != -1) RemoveEvicted(reg, first_evicted); |
2441 | 2490 |
2442 registers_[reg]->Add(unallocated); | 2491 registers_[reg]->Add(unallocated); |
2443 unallocated->set_assigned_location(MakeRegisterLocation(reg)); | 2492 unallocated->set_assigned_location(MakeRegisterLocation(reg)); |
2493 #if defined(TARGET_ARCH_DBC) | |
2494 last_used_register_ = Utils::Maximum(last_used_register_, reg); | |
Florian Schneider
2016/05/19 13:21:40
Is this reachable?
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
It is - allocating non-free registers does not imp
| |
2495 #endif | |
2444 } | 2496 } |
2445 | 2497 |
2446 | 2498 |
2447 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, | 2499 bool FlowGraphAllocator::EvictIntersection(LiveRange* allocated, |
2448 LiveRange* unallocated) { | 2500 LiveRange* unallocated) { |
2449 UseInterval* first_unallocated = | 2501 UseInterval* first_unallocated = |
2450 unallocated->finger()->first_pending_use_interval(); | 2502 unallocated->finger()->first_pending_use_interval(); |
2451 const intptr_t intersection = FirstIntersection( | 2503 const intptr_t intersection = FirstIntersection( |
2452 allocated->finger()->first_pending_use_interval(), | 2504 allocated->finger()->first_pending_use_interval(), |
2453 first_unallocated); | 2505 first_unallocated); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2523 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { | 2575 for (UsePosition* use = range->first_use(); use != NULL; use = use->next()) { |
2524 ConvertUseTo(use, loc); | 2576 ConvertUseTo(use, loc); |
2525 } | 2577 } |
2526 | 2578 |
2527 // Add live registers at all safepoints for instructions with slow-path | 2579 // Add live registers at all safepoints for instructions with slow-path |
2528 // code. | 2580 // code. |
2529 if (loc.IsMachineRegister()) { | 2581 if (loc.IsMachineRegister()) { |
2530 for (SafepointPosition* safepoint = range->first_safepoint(); | 2582 for (SafepointPosition* safepoint = range->first_safepoint(); |
2531 safepoint != NULL; | 2583 safepoint != NULL; |
2532 safepoint = safepoint->next()) { | 2584 safepoint = safepoint->next()) { |
2585 #if !defined(TARGET_ARCH_DBC) | |
2533 if (!safepoint->locs()->always_calls()) { | 2586 if (!safepoint->locs()->always_calls()) { |
2534 ASSERT(safepoint->locs()->can_call()); | 2587 ASSERT(safepoint->locs()->can_call()); |
2535 safepoint->locs()->live_registers()->Add(loc, range->representation()); | 2588 safepoint->locs()->live_registers()->Add(loc, range->representation()); |
2536 } | 2589 } |
2590 #else | |
2591 if (range->representation() == kTagged) { | |
2592 safepoint->locs()->SetStackBit(loc.reg()); | |
2593 } | |
2594 #endif // !defined(TARGET_ARCH_DBC) | |
2537 } | 2595 } |
2538 } | 2596 } |
2539 } | 2597 } |
2540 | 2598 |
2541 | 2599 |
2542 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { | 2600 void FlowGraphAllocator::AdvanceActiveIntervals(const intptr_t start) { |
2543 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) { | 2601 for (intptr_t reg = 0; reg < NumberOfRegisters(); reg++) { |
2544 if (registers_[reg]->is_empty()) continue; | 2602 if (registers_[reg]->is_empty()) continue; |
2545 | 2603 |
2546 intptr_t first_evicted = -1; | 2604 intptr_t first_evicted = -1; |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2676 for (intptr_t reg = 0; reg < number_of_registers; reg++) { | 2734 for (intptr_t reg = 0; reg < number_of_registers; reg++) { |
2677 blocked_registers_[reg] = blocked_registers[reg]; | 2735 blocked_registers_[reg] = blocked_registers[reg]; |
2678 ASSERT(registers_[reg]->is_empty()); | 2736 ASSERT(registers_[reg]->is_empty()); |
2679 | 2737 |
2680 LiveRange* range = blocking_ranges[reg]; | 2738 LiveRange* range = blocking_ranges[reg]; |
2681 if (range != NULL) { | 2739 if (range != NULL) { |
2682 range->finger()->Initialize(range); | 2740 range->finger()->Initialize(range); |
2683 registers_[reg]->Add(range); | 2741 registers_[reg]->Add(range); |
2684 } | 2742 } |
2685 } | 2743 } |
2744 | |
2745 #if defined(TARGET_ARCH_DBC) | |
2746 last_used_register_ = -1; | |
2747 #endif | |
2686 } | 2748 } |
2687 | 2749 |
2688 | 2750 |
2689 void FlowGraphAllocator::AllocateUnallocatedRanges() { | 2751 void FlowGraphAllocator::AllocateUnallocatedRanges() { |
2690 #if defined(DEBUG) | 2752 #if defined(DEBUG) |
2691 ASSERT(UnallocatedIsSorted()); | 2753 ASSERT(UnallocatedIsSorted()); |
2692 #endif | 2754 #endif |
2693 | 2755 |
2694 while (!unallocated_.is_empty()) { | 2756 while (!unallocated_.is_empty()) { |
2695 LiveRange* range = unallocated_.RemoveLast(); | 2757 LiveRange* range = unallocated_.RemoveLast(); |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2942 CollectRepresentations(); | 3004 CollectRepresentations(); |
2943 | 3005 |
2944 liveness_.Analyze(); | 3006 liveness_.Analyze(); |
2945 | 3007 |
2946 NumberInstructions(); | 3008 NumberInstructions(); |
2947 | 3009 |
2948 DiscoverLoops(); | 3010 DiscoverLoops(); |
2949 | 3011 |
2950 BuildLiveRanges(); | 3012 BuildLiveRanges(); |
2951 | 3013 |
2952 if (FLAG_print_ssa_liveness) { | |
2953 liveness_.Dump(); | |
2954 } | |
2955 | |
2956 if (FLAG_print_ssa_liveranges) { | 3014 if (FLAG_print_ssa_liveranges) { |
2957 const Function& function = flow_graph_.function(); | 3015 const Function& function = flow_graph_.function(); |
2958 THR_Print("-- [before ssa allocator] ranges [%s] ---------\n", | 3016 THR_Print("-- [before ssa allocator] ranges [%s] ---------\n", |
2959 function.ToFullyQualifiedCString()); | 3017 function.ToFullyQualifiedCString()); |
2960 PrintLiveRanges(); | 3018 PrintLiveRanges(); |
2961 THR_Print("----------------------------------------------\n"); | 3019 THR_Print("----------------------------------------------\n"); |
2962 | 3020 |
2963 THR_Print("-- [before ssa allocator] ir [%s] -------------\n", | 3021 THR_Print("-- [before ssa allocator] ir [%s] -------------\n", |
2964 function.ToFullyQualifiedCString()); | 3022 function.ToFullyQualifiedCString()); |
2965 if (FLAG_support_il_printer) { | 3023 if (FLAG_support_il_printer) { |
2966 #ifndef PRODUCT | 3024 #ifndef PRODUCT |
2967 FlowGraphPrinter printer(flow_graph_, true); | 3025 FlowGraphPrinter printer(flow_graph_, true); |
2968 printer.PrintBlocks(); | 3026 printer.PrintBlocks(); |
2969 #endif | 3027 #endif |
2970 } | 3028 } |
2971 THR_Print("----------------------------------------------\n"); | 3029 THR_Print("----------------------------------------------\n"); |
2972 } | 3030 } |
2973 | 3031 |
2974 PrepareForAllocation(Location::kRegister, | 3032 PrepareForAllocation(Location::kRegister, |
2975 kNumberOfCpuRegisters, | 3033 kNumberOfCpuRegisters, |
2976 unallocated_cpu_, | 3034 unallocated_cpu_, |
2977 cpu_regs_, | 3035 cpu_regs_, |
2978 blocked_cpu_registers_); | 3036 blocked_cpu_registers_); |
2979 AllocateUnallocatedRanges(); | 3037 AllocateUnallocatedRanges(); |
3038 #if defined(TARGET_ARCH_DBC) | |
3039 const intptr_t last_used_cpu_register = last_used_register_; | |
3040 #endif | |
2980 | 3041 |
2981 cpu_spill_slot_count_ = spill_slots_.length(); | 3042 cpu_spill_slot_count_ = spill_slots_.length(); |
2982 spill_slots_.Clear(); | 3043 spill_slots_.Clear(); |
2983 quad_spill_slots_.Clear(); | 3044 quad_spill_slots_.Clear(); |
2984 untagged_spill_slots_.Clear(); | 3045 untagged_spill_slots_.Clear(); |
2985 | 3046 |
2986 PrepareForAllocation(Location::kFpuRegister, | 3047 PrepareForAllocation(Location::kFpuRegister, |
2987 kNumberOfFpuRegisters, | 3048 kNumberOfFpuRegisters, |
2988 unallocated_xmm_, | 3049 unallocated_xmm_, |
2989 fpu_regs_, | 3050 fpu_regs_, |
2990 blocked_fpu_registers_); | 3051 blocked_fpu_registers_); |
2991 AllocateUnallocatedRanges(); | 3052 AllocateUnallocatedRanges(); |
3053 #if defined(TARGET_ARCH_DBC) | |
3054 const intptr_t last_used_fpu_register = last_used_register_; | |
3055 ASSERT(last_used_fpu_register == -1); // Not supported right now. | |
3056 #endif | |
2992 | 3057 |
2993 ResolveControlFlow(); | 3058 ResolveControlFlow(); |
2994 | 3059 |
2995 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry(); | 3060 GraphEntryInstr* entry = block_order_[0]->AsGraphEntry(); |
2996 ASSERT(entry != NULL); | 3061 ASSERT(entry != NULL); |
2997 intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor; | 3062 intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor; |
2998 entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count); | 3063 entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count); |
2999 | 3064 |
3065 #if defined(TARGET_ARCH_DBC) | |
3066 // Spilling is unsupported on DBC. | |
3067 if (entry->spill_slot_count() != 0) { | |
3068 UNREACHABLE(); | |
3069 } | |
3070 | |
3071 entry->set_spill_slot_count(Utils::Maximum((last_used_cpu_register + 1) + | |
Florian Schneider
2016/05/19 13:21:40
spill_slot_count is a confusing name... maybe stac
Vyacheslav Egorov (Google)
2016/05/19 15:19:40
I added a comment.
| |
3072 (last_used_fpu_register + 1), | |
3073 flow_graph_.num_copied_params())); | |
3074 #endif | |
3075 | |
3000 if (FLAG_print_ssa_liveranges) { | 3076 if (FLAG_print_ssa_liveranges) { |
3001 const Function& function = flow_graph_.function(); | 3077 const Function& function = flow_graph_.function(); |
3002 | 3078 |
3003 THR_Print("-- [after ssa allocator] ranges [%s] ---------\n", | 3079 THR_Print("-- [after ssa allocator] ranges [%s] ---------\n", |
3004 function.ToFullyQualifiedCString()); | 3080 function.ToFullyQualifiedCString()); |
3005 PrintLiveRanges(); | 3081 PrintLiveRanges(); |
3006 THR_Print("----------------------------------------------\n"); | 3082 THR_Print("----------------------------------------------\n"); |
3007 | 3083 |
3008 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", | 3084 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", |
3009 function.ToFullyQualifiedCString()); | 3085 function.ToFullyQualifiedCString()); |
3010 if (FLAG_support_il_printer) { | 3086 if (FLAG_support_il_printer) { |
3011 #ifndef PRODUCT | 3087 #ifndef PRODUCT |
3012 FlowGraphPrinter printer(flow_graph_, true); | 3088 FlowGraphPrinter printer(flow_graph_, true); |
3013 printer.PrintBlocks(); | 3089 printer.PrintBlocks(); |
3014 #endif | 3090 #endif |
3015 } | 3091 } |
3016 THR_Print("----------------------------------------------\n"); | 3092 THR_Print("----------------------------------------------\n"); |
3017 } | 3093 } |
3018 } | 3094 } |
3019 | 3095 |
3020 | 3096 |
3021 } // namespace dart | 3097 } // namespace dart |
OLD | NEW |