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

Side by Side Diff: runtime/vm/flow_graph_allocator.cc

Issue 1992963002: Enable optimizer pipeline for DBC. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_allocator.h" 5 #include "vm/flow_graph_allocator.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/intermediate_language.h" 8 #include "vm/intermediate_language.h"
9 #include "vm/il_printer.h" 9 #include "vm/il_printer.h"
10 #include "vm/flow_graph.h" 10 #include "vm/flow_graph.h"
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
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());
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id()); 600 range->MarkHasOnlyUnconstrainedUsesInLoop(block_info->loop_id());
592 } 601 }
593 } 602 }
594 } 603 }
595 604
596 if (block->IsJoinEntry()) { 605 if (block->IsJoinEntry()) {
597 ConnectIncomingPhiMoves(block->AsJoinEntry()); 606 ConnectIncomingPhiMoves(block->AsJoinEntry());
598 } else if (block->IsCatchBlockEntry()) { 607 } else if (block->IsCatchBlockEntry()) {
599 // Process initial definitions. 608 // Process initial definitions.
600 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry(); 609 CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
610 #if defined(TARGET_ARCH_DBC)
611 // TODO(vegorov) support try-catch/finally for DBC.
612 flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "Catch");
613 #endif
601 for (intptr_t i = 0; 614 for (intptr_t i = 0;
602 i < catch_entry->initial_definitions()->length(); 615 i < catch_entry->initial_definitions()->length();
603 i++) { 616 i++) {
604 Definition* defn = (*catch_entry->initial_definitions())[i]; 617 Definition* defn = (*catch_entry->initial_definitions())[i];
605 LiveRange* range = GetLiveRange(defn->ssa_temp_index()); 618 LiveRange* range = GetLiveRange(defn->ssa_temp_index());
606 range->DefineAt(catch_entry->start_pos()); // Defined at block entry. 619 range->DefineAt(catch_entry->start_pos()); // Defined at block entry.
607 ProcessInitialDefinition(defn, range, catch_entry); 620 ProcessInitialDefinition(defn, range, catch_entry);
608 } 621 }
609 // Block the two fixed registers used by CatchBlockEntryInstr from the 622 // Block the two fixed registers used by CatchBlockEntryInstr from the
610 // block start to until the end of the instruction so that they are 623 // 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
645 ASSERT((flow_graph_.num_copied_params() == 0) || 658 ASSERT((flow_graph_.num_copied_params() == 0) ||
646 (flow_graph_.num_non_copied_params() == 0)); 659 (flow_graph_.num_non_copied_params() == 0));
647 intptr_t slot_index = param->index(); 660 intptr_t slot_index = param->index();
648 ASSERT((param->base_reg() == FPREG) || (param->base_reg() == SPREG)); 661 ASSERT((param->base_reg() == FPREG) || (param->base_reg() == SPREG));
649 if (param->base_reg() == FPREG) { 662 if (param->base_reg() == FPREG) {
650 // Slot index for the leftmost copied parameter is 0. 663 // Slot index for the leftmost copied parameter is 0.
651 // Slot index for the rightmost fixed parameter is -1. 664 // Slot index for the rightmost fixed parameter is -1.
652 slot_index -= flow_graph_.num_non_copied_params(); 665 slot_index -= flow_graph_.num_non_copied_params();
653 } 666 }
654 667
668 #if defined(TARGET_ARCH_DBC)
669 ASSERT(param->base_reg() == FPREG);
670 if (slot_index >= 0) {
671 AssignSafepoints(defn, range);
672 range->finger()->Initialize(range);
673 range->set_assigned_location(Location::RegisterLocation(slot_index));
674 if (range->End() > kNormalEntryPos) {
675 LiveRange* tail = range->SplitAt(kNormalEntryPos);
676 CompleteRange(tail, Location::kRegister);
677 }
678 ConvertAllUses(range);
679 return;
680 }
681 #endif // defined(TARGET_ARCH_DBC)
655 range->set_assigned_location(Location::StackSlot(slot_index, 682 range->set_assigned_location(Location::StackSlot(slot_index,
656 param->base_reg())); 683 param->base_reg()));
657 range->set_spill_slot(Location::StackSlot(slot_index, 684 range->set_spill_slot(Location::StackSlot(slot_index,
658 param->base_reg())); 685 param->base_reg()));
686
659 } else if (defn->IsCurrentContext()) { 687 } else if (defn->IsCurrentContext()) {
688 #if !defined(TARGET_ARCH_DBC)
689 const Register context_reg = CTX;
690 #else
691 const intptr_t context_reg = flow_graph_.num_copied_params();
692 #endif
693
660 AssignSafepoints(defn, range); 694 AssignSafepoints(defn, range);
661 range->finger()->Initialize(range); 695 range->finger()->Initialize(range);
662 range->set_assigned_location(Location::RegisterLocation(CTX)); 696 range->set_assigned_location(Location::RegisterLocation(context_reg));
663 if (range->End() > kNormalEntryPos) { 697 if (range->End() > kNormalEntryPos) {
664 LiveRange* tail = range->SplitAt(kNormalEntryPos); 698 LiveRange* tail = range->SplitAt(kNormalEntryPos);
665 CompleteRange(tail, Location::kRegister); 699 CompleteRange(tail, Location::kRegister);
666 } 700 }
667 ConvertAllUses(range); 701 ConvertAllUses(range);
668 return; 702 return;
669 } else { 703 } else {
670 ConstantInstr* constant = defn->AsConstant(); 704 ConstantInstr* constant = defn->AsConstant();
671 ASSERT(constant != NULL); 705 ASSERT(constant != NULL);
672 range->set_assigned_location(Location::Constant(constant)); 706 range->set_assigned_location(Location::Constant(constant));
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
1316 } else if (temp.IsUnallocated()) { 1350 } else if (temp.IsUnallocated()) {
1317 LiveRange* range = MakeLiveRangeForTemporary(); 1351 LiveRange* range = MakeLiveRangeForTemporary();
1318 range->AddUseInterval(pos, pos + 1); 1352 range->AddUseInterval(pos, pos + 1);
1319 range->AddUse(pos, locs->temp_slot(j)); 1353 range->AddUse(pos, locs->temp_slot(j));
1320 CompleteRange(range, RegisterKindFromPolicy(temp)); 1354 CompleteRange(range, RegisterKindFromPolicy(temp));
1321 } else { 1355 } else {
1322 UNREACHABLE(); 1356 UNREACHABLE();
1323 } 1357 }
1324 } 1358 }
1325 1359
1326 // Block all allocatable registers for calls and record the stack bitmap. 1360 // Block all allocatable registers for calls.
1361 // Note that on DBC registers are always essentially spilled so
1362 // we don't need to block anything.
1363 #if !defined(TARGET_ARCH_DBC)
1327 if (locs->always_calls()) { 1364 if (locs->always_calls()) {
1328 // Expected shape of live range: 1365 // Expected shape of live range:
1329 // 1366 //
1330 // i i' 1367 // i i'
1331 // [--) 1368 // [--)
1332 // 1369 //
1333 // The stack bitmap describes the position i. 1370 // The stack bitmap describes the position i.
1334 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) { 1371 for (intptr_t reg = 0; reg < kNumberOfCpuRegisters; reg++) {
1335 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)), 1372 BlockLocation(Location::RegisterLocation(static_cast<Register>(reg)),
1336 pos, 1373 pos,
(...skipping 29 matching lines...) Expand all
1366 1403
1367 if (locs->out(0).IsPairLocation()) { 1404 if (locs->out(0).IsPairLocation()) {
1368 PairLocation* pair = locs->out_slot(0)->AsPairLocation(); 1405 PairLocation* pair = locs->out_slot(0)->AsPairLocation();
1369 ASSERT(!pair->At(0).IsUnallocated()); 1406 ASSERT(!pair->At(0).IsUnallocated());
1370 ASSERT(!pair->At(1).IsUnallocated()); 1407 ASSERT(!pair->At(1).IsUnallocated());
1371 } else { 1408 } else {
1372 ASSERT(!locs->out(0).IsUnallocated()); 1409 ASSERT(!locs->out(0).IsUnallocated());
1373 } 1410 }
1374 #endif 1411 #endif
1375 } 1412 }
1413 #endif
1376 1414
1377 if (locs->can_call()) { 1415 if (locs->can_call()) {
1378 safepoints_.Add(current); 1416 safepoints_.Add(current);
1379 } 1417 }
1380 1418
1381 if (def == NULL) { 1419 if (def == NULL) {
1382 ASSERT(locs->out(0).IsInvalid()); 1420 ASSERT(locs->out(0).IsInvalid());
1383 return; 1421 return;
1384 } 1422 }
1385 1423
(...skipping 513 matching lines...) Expand 10 before | Expand all | Expand 10 after
1899 from)); 1937 from));
1900 } 1938 }
1901 } 1939 }
1902 1940
1903 LiveRange* tail = range->SplitAt(from); 1941 LiveRange* tail = range->SplitAt(from);
1904 Spill(tail); 1942 Spill(tail);
1905 } 1943 }
1906 1944
1907 1945
1908 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) { 1946 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
1947 #if defined(TARGET_ARCH_DBC)
1948 // There is no need to support spilling on DBC because we have a lot of
1949 // registers and registers and spill-slots have the same performance
1950 // characteristics.
1951 flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "SPILL");
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
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
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);
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
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
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
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 // We store number of used DBC registers in the spill slot count to avoid
3072 // introducing a separate field. It has roughly the same meaning:
3073 // number of used registers determines how big of a frame to reserve for
3074 // this function on DBC stack.
3075 entry->set_spill_slot_count(Utils::Maximum((last_used_cpu_register + 1) +
3076 (last_used_fpu_register + 1),
3077 flow_graph_.num_copied_params()));
3078 #endif
3079
3000 if (FLAG_print_ssa_liveranges) { 3080 if (FLAG_print_ssa_liveranges) {
3001 const Function& function = flow_graph_.function(); 3081 const Function& function = flow_graph_.function();
3002 3082
3003 THR_Print("-- [after ssa allocator] ranges [%s] ---------\n", 3083 THR_Print("-- [after ssa allocator] ranges [%s] ---------\n",
3004 function.ToFullyQualifiedCString()); 3084 function.ToFullyQualifiedCString());
3005 PrintLiveRanges(); 3085 PrintLiveRanges();
3006 THR_Print("----------------------------------------------\n"); 3086 THR_Print("----------------------------------------------\n");
3007 3087
3008 THR_Print("-- [after ssa allocator] ir [%s] -------------\n", 3088 THR_Print("-- [after ssa allocator] ir [%s] -------------\n",
3009 function.ToFullyQualifiedCString()); 3089 function.ToFullyQualifiedCString());
3010 if (FLAG_support_il_printer) { 3090 if (FLAG_support_il_printer) {
3011 #ifndef PRODUCT 3091 #ifndef PRODUCT
3012 FlowGraphPrinter printer(flow_graph_, true); 3092 FlowGraphPrinter printer(flow_graph_, true);
3013 printer.PrintBlocks(); 3093 printer.PrintBlocks();
3014 #endif 3094 #endif
3015 } 3095 }
3016 THR_Print("----------------------------------------------\n"); 3096 THR_Print("----------------------------------------------\n");
3017 } 3097 }
3018 } 3098 }
3019 3099
3020 3100
3021 } // namespace dart 3101 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_allocator.h ('k') | runtime/vm/flow_graph_builder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698