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

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

Issue 513213002: Generate some intrinsics using our IR. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
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 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 static intptr_t ToInstructionStart(intptr_t pos) { 65 static intptr_t ToInstructionStart(intptr_t pos) {
66 return (pos & ~1); 66 return (pos & ~1);
67 } 67 }
68 68
69 69
70 static intptr_t ToInstructionEnd(intptr_t pos) { 70 static intptr_t ToInstructionEnd(intptr_t pos) {
71 return (pos | 1); 71 return (pos | 1);
72 } 72 }
73 73
74 74
75 FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph) 75 FlowGraphAllocator::FlowGraphAllocator(const FlowGraph& flow_graph,
76 bool intrinsic_mode)
76 : flow_graph_(flow_graph), 77 : flow_graph_(flow_graph),
77 reaching_defs_(flow_graph), 78 reaching_defs_(flow_graph),
78 value_representations_(flow_graph.max_virtual_register_number()), 79 value_representations_(flow_graph.max_virtual_register_number()),
79 block_order_(flow_graph.reverse_postorder()), 80 block_order_(flow_graph.reverse_postorder()),
80 postorder_(flow_graph.postorder()), 81 postorder_(flow_graph.postorder()),
81 liveness_(flow_graph), 82 liveness_(flow_graph),
82 vreg_count_(flow_graph.max_virtual_register_number()), 83 vreg_count_(flow_graph.max_virtual_register_number()),
83 live_ranges_(flow_graph.max_virtual_register_number()), 84 live_ranges_(flow_graph.max_virtual_register_number()),
84 cpu_regs_(), 85 cpu_regs_(),
85 fpu_regs_(), 86 fpu_regs_(),
86 blocked_cpu_registers_(), 87 blocked_cpu_registers_(),
87 blocked_fpu_registers_(), 88 blocked_fpu_registers_(),
88 number_of_registers_(0), 89 number_of_registers_(0),
89 registers_(), 90 registers_(),
90 blocked_registers_(), 91 blocked_registers_(),
91 cpu_spill_slot_count_(0) { 92 cpu_spill_slot_count_(0),
93 intrinsic_mode_(intrinsic_mode) {
92 for (intptr_t i = 0; i < vreg_count_; i++) { 94 for (intptr_t i = 0; i < vreg_count_; i++) {
93 live_ranges_.Add(NULL); 95 live_ranges_.Add(NULL);
94 } 96 }
95 for (intptr_t i = 0; i < vreg_count_; i++) { 97 for (intptr_t i = 0; i < vreg_count_; i++) {
96 value_representations_.Add(kNoRepresentation); 98 value_representations_.Add(kNoRepresentation);
97 } 99 }
98 100
99 // All registers are marked as "not blocked" (array initialized to false). 101 // All registers are marked as "not blocked" (array initialized to false).
100 // Mark the unavailable ones as "blocked" (true). 102 // Mark the unavailable ones as "blocked" (true).
101 for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) { 103 for (intptr_t i = 0; i < kFirstFreeCpuRegister; i++) {
(...skipping 10 matching lines...) Expand all
112 blocked_cpu_registers_[TMP2] = true; 114 blocked_cpu_registers_[TMP2] = true;
113 } 115 }
114 if (PP != kNoRegister) { 116 if (PP != kNoRegister) {
115 blocked_cpu_registers_[PP] = true; 117 blocked_cpu_registers_[PP] = true;
116 } 118 }
117 blocked_cpu_registers_[SPREG] = true; 119 blocked_cpu_registers_[SPREG] = true;
118 blocked_cpu_registers_[FPREG] = true; 120 blocked_cpu_registers_[FPREG] = true;
119 121
120 // FpuTMP is used as scratch by optimized code and parallel move resolver. 122 // FpuTMP is used as scratch by optimized code and parallel move resolver.
121 blocked_fpu_registers_[FpuTMP] = true; 123 blocked_fpu_registers_[FpuTMP] = true;
124
125 // Block additional registers needed preserved when generating intrinsics.
126 // TODO(fschneider): Handle saving and restoring these registers when
127 // generating intrinsic code.
128 if (intrinsic_mode) {
129 blocked_cpu_registers_[ICREG] = true;
130 blocked_cpu_registers_[ARGS_DESC_REG] = true;
131 }
122 } 132 }
123 133
124 134
125 static void DeepLiveness(MaterializeObjectInstr* mat, BitVector* live_in) { 135 static void DeepLiveness(MaterializeObjectInstr* mat, BitVector* live_in) {
126 if (mat->was_visited_for_liveness()) { 136 if (mat->was_visited_for_liveness()) {
127 return; 137 return;
128 } 138 }
129 mat->mark_visited_for_liveness(); 139 mat->mark_visited_for_liveness();
130 140
131 for (intptr_t i = 0; i < mat->InputCount(); i++) { 141 for (intptr_t i = 0; i < mat->InputCount(); i++) {
(...skipping 474 matching lines...) Expand 10 before | Expand all | Expand 10 after
606 LiveRange* range, 616 LiveRange* range,
607 BlockEntryInstr* block) { 617 BlockEntryInstr* block) {
608 // Save the range end because it may change below. 618 // Save the range end because it may change below.
609 intptr_t range_end = range->End(); 619 intptr_t range_end = range->End();
610 if (defn->IsParameter()) { 620 if (defn->IsParameter()) {
611 ParameterInstr* param = defn->AsParameter(); 621 ParameterInstr* param = defn->AsParameter();
612 // Assert that copied and non-copied parameters are mutually exclusive. 622 // Assert that copied and non-copied parameters are mutually exclusive.
613 // This might change in the future and, if so, the index will be wrong. 623 // This might change in the future and, if so, the index will be wrong.
614 ASSERT((flow_graph_.num_copied_params() == 0) || 624 ASSERT((flow_graph_.num_copied_params() == 0) ||
615 (flow_graph_.num_non_copied_params() == 0)); 625 (flow_graph_.num_non_copied_params() == 0));
616 // Slot index for the leftmost copied parameter is 0.
617 intptr_t slot_index = param->index(); 626 intptr_t slot_index = param->index();
618 // Slot index for the rightmost fixed parameter is -1. 627 ASSERT(param->base_reg() == FPREG || param->base_reg() == SPREG);
619 slot_index -= flow_graph_.num_non_copied_params(); 628 if (param->base_reg() == FPREG) {
629 // Slot index for the leftmost copied parameter is 0.
630 // Slot index for the rightmost fixed parameter is -1.
631 slot_index -= flow_graph_.num_non_copied_params();
632 }
620 633
621 range->set_assigned_location(Location::StackSlot(slot_index)); 634 range->set_assigned_location(Location::StackSlot(slot_index,
622 range->set_spill_slot(Location::StackSlot(slot_index)); 635 param->base_reg()));
636 range->set_spill_slot(Location::StackSlot(slot_index,
637 param->base_reg()));
623 } else { 638 } else {
624 ConstantInstr* constant = defn->AsConstant(); 639 ConstantInstr* constant = defn->AsConstant();
625 ASSERT(constant != NULL); 640 ASSERT(constant != NULL);
626 range->set_assigned_location(Location::Constant(constant)); 641 range->set_assigned_location(Location::Constant(constant));
627 range->set_spill_slot(Location::Constant(constant)); 642 range->set_spill_slot(Location::Constant(constant));
628 } 643 }
629 AssignSafepoints(defn, range); 644 AssignSafepoints(defn, range);
630 range->finger()->Initialize(range); 645 range->finger()->Initialize(range);
631 UsePosition* use = 646 UsePosition* use =
632 range->finger()->FirstRegisterBeneficialUse(block->start_pos()); 647 range->finger()->FirstRegisterBeneficialUse(block->start_pos());
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range, 1776 LiveRange* FlowGraphAllocator::SplitBetween(LiveRange* range,
1762 intptr_t from, 1777 intptr_t from,
1763 intptr_t to) { 1778 intptr_t to) {
1764 TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %" Pd 1779 TRACE_ALLOC(OS::Print("split v%" Pd " [%" Pd ", %" Pd
1765 ") between [%" Pd ", %" Pd ")\n", 1780 ") between [%" Pd ", %" Pd ")\n",
1766 range->vreg(), range->Start(), range->End(), from, to)); 1781 range->vreg(), range->Start(), range->End(), from, to));
1767 1782
1768 intptr_t split_pos = kIllegalPosition; 1783 intptr_t split_pos = kIllegalPosition;
1769 1784
1770 BlockInfo* split_block = BlockInfoAt(to); 1785 BlockInfo* split_block = BlockInfoAt(to);
1771 if (from < split_block->entry()->lifetime_position()) { 1786 if (from < split_block->entry()->lifetime_position() &&
1787 split_block->loop() != NULL) {
1772 // Interval [from, to) spans multiple blocks. 1788 // Interval [from, to) spans multiple blocks.
1773 1789
1774 // If last block is inside a loop prefer splitting at outermost loop's 1790 // If last block is inside a loop prefer splitting at outermost loop's
1775 // header. 1791 // header.
1776 BlockInfo* loop_header = split_block->loop(); 1792 BlockInfo* loop_header = split_block->loop();
1777 while ((loop_header != NULL) && 1793 while ((loop_header != NULL) &&
1778 (from < loop_header->entry()->lifetime_position())) { 1794 (from < loop_header->entry()->lifetime_position())) {
1779 split_block = loop_header; 1795 split_block = loop_header;
1780 loop_header = loop_header->loop(); 1796 loop_header = loop_header->loop();
1781 } 1797 }
(...skipping 833 matching lines...) Expand 10 before | Expand all | Expand 10 after
2615 const intptr_t start = range->Start(); 2631 const intptr_t start = range->Start();
2616 TRACE_ALLOC(OS::Print("Processing live range for v%" Pd " " 2632 TRACE_ALLOC(OS::Print("Processing live range for v%" Pd " "
2617 "starting at %" Pd "\n", 2633 "starting at %" Pd "\n",
2618 range->vreg(), 2634 range->vreg(),
2619 start)); 2635 start));
2620 2636
2621 // TODO(vegorov): eagerly spill liveranges without register uses. 2637 // TODO(vegorov): eagerly spill liveranges without register uses.
2622 AdvanceActiveIntervals(start); 2638 AdvanceActiveIntervals(start);
2623 2639
2624 if (!AllocateFreeRegister(range)) { 2640 if (!AllocateFreeRegister(range)) {
2641 if (intrinsic_mode_) {
2642 // No spilling when compiling intrinsics.
2643 // TODO(fschneider): Handle spilling in intrinsics. For now, the
2644 // IR has to be built so that there are enough free registers.
2645 UNREACHABLE();
2646 }
2625 AllocateAnyRegister(range); 2647 AllocateAnyRegister(range);
2626 } 2648 }
2627 } 2649 }
2628 2650
2629 // All allocation decisions were done. 2651 // All allocation decisions were done.
2630 ASSERT(unallocated_.is_empty()); 2652 ASSERT(unallocated_.is_empty());
2631 2653
2632 // Finish allocation. 2654 // Finish allocation.
2633 AdvanceActiveIntervals(kMaxPosition); 2655 AdvanceActiveIntervals(kMaxPosition);
2634 TRACE_ALLOC(OS::Print("Allocation completed\n")); 2656 TRACE_ALLOC(OS::Print("Allocation completed\n"));
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
2917 OS::Print("-- [after ssa allocator] ir [%s] -------------\n", 2939 OS::Print("-- [after ssa allocator] ir [%s] -------------\n",
2918 function.ToFullyQualifiedCString()); 2940 function.ToFullyQualifiedCString());
2919 FlowGraphPrinter printer(flow_graph_, true); 2941 FlowGraphPrinter printer(flow_graph_, true);
2920 printer.PrintBlocks(); 2942 printer.PrintBlocks();
2921 OS::Print("----------------------------------------------\n"); 2943 OS::Print("----------------------------------------------\n");
2922 } 2944 }
2923 } 2945 }
2924 2946
2925 2947
2926 } // namespace dart 2948 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698