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

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

Issue 10875030: Add support for XMM registers in SSA code generation pipeline. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: fix a bug pointed out by Florian Created 8 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
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_allocator.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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 #ifndef VM_FLOW_GRAPH_ALLOCATOR_H_ 5 #ifndef VM_FLOW_GRAPH_ALLOCATOR_H_
6 #define VM_FLOW_GRAPH_ALLOCATOR_H_ 6 #define VM_FLOW_GRAPH_ALLOCATOR_H_
7 7
8 #include "vm/growable_array.h" 8 #include "vm/growable_array.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 10
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 LiveRange* MakeLiveRangeForTemporary(); 87 LiveRange* MakeLiveRangeForTemporary();
88 88
89 // Visit instructions in the postorder and build live ranges for 89 // Visit instructions in the postorder and build live ranges for
90 // all SSA values. 90 // all SSA values.
91 void BuildLiveRanges(); 91 void BuildLiveRanges();
92 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); 92 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block);
93 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); 93 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current);
94 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); 94 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr);
95 void ConnectIncomingPhiMoves(BlockEntryInstr* block); 95 void ConnectIncomingPhiMoves(BlockEntryInstr* block);
96 void BlockLocation(Location loc, intptr_t from, intptr_t to); 96 void BlockLocation(Location loc, intptr_t from, intptr_t to);
97 void BlockRegisterLocation(Location loc,
98 intptr_t from,
99 intptr_t to,
100 bool* blocked_registers,
101 LiveRange** blocking_ranges);
102
103 intptr_t NumberOfRegisters() const { return number_of_registers_; }
97 104
98 // Find all safepoints that are covered by this live range. 105 // Find all safepoints that are covered by this live range.
99 void AssignSafepoints(LiveRange* range); 106 void AssignSafepoints(LiveRange* range);
100 107
108 void PrepareForAllocation(Location::Kind register_kind,
109 intptr_t number_of_registers,
110 const GrowableArray<LiveRange*>& unallocated,
111 LiveRange** blocking_ranges,
112 bool* blocked_registers);
113
114
101 // Process live ranges sorted by their start and assign registers 115 // Process live ranges sorted by their start and assign registers
102 // to them 116 // to them
103 void AllocateCPURegisters(); 117 void AllocateUnallocatedRanges();
104 void AdvanceActiveIntervals(const intptr_t start); 118 void AdvanceActiveIntervals(const intptr_t start);
105 119
106 // Connect split siblings over non-linear control flow edges. 120 // Connect split siblings over non-linear control flow edges.
107 void ResolveControlFlow(); 121 void ResolveControlFlow();
108 void ConnectSplitSiblings(LiveRange* range, 122 void ConnectSplitSiblings(LiveRange* range,
109 BlockEntryInstr* source_block, 123 BlockEntryInstr* source_block,
110 BlockEntryInstr* target_block); 124 BlockEntryInstr* target_block);
111 125
112 126
113 // Update location slot corresponding to the use with location allocated for 127 // Update location slot corresponding to the use with location allocated for
114 // the use's live range. 128 // the use's live range.
115 void ConvertUseTo(UsePosition* use, Location loc); 129 void ConvertUseTo(UsePosition* use, Location loc);
116 void ConvertAllUses(LiveRange* range); 130 void ConvertAllUses(LiveRange* range);
117 131
118 // Add live range to the list of unallocated live ranges to be processed 132 // Add live range to the list of unallocated live ranges to be processed
119 // by the allocator. 133 // by the allocator.
120 void AddToUnallocated(LiveRange* range); 134 void AddToUnallocated(LiveRange* range);
135 void CompleteRange(LiveRange* range, Location::Kind kind);
121 #if defined(DEBUG) 136 #if defined(DEBUG)
122 bool UnallocatedIsSorted(); 137 bool UnallocatedIsSorted();
123 #endif 138 #endif
124 139
125 // Try to find a free register for an unallocated live range. 140 // Try to find a free register for an unallocated live range.
126 bool AllocateFreeRegister(LiveRange* unallocated); 141 bool AllocateFreeRegister(LiveRange* unallocated);
127 142
128 // Try to find a register that can be used by a given live range. 143 // Try to find a register that can be used by a given live range.
129 // If all registers are occupied consider evicting interference for 144 // If all registers are occupied consider evicting interference for
130 // a register that is going to be used as far from the start of 145 // a register that is going to be used as far from the start of
131 // the unallocated live range as possible. 146 // the unallocated live range as possible.
132 void AllocateAnyRegister(LiveRange* unallocated); 147 void AllocateAnyRegister(LiveRange* unallocated);
133 148
134 // Assign selected non-free register to an unallocated live range and 149 // Assign selected non-free register to an unallocated live range and
135 // evict any interference that can be evicted by splitting and spilling 150 // evict any interference that can be evicted by splitting and spilling
136 // parts of interfering live ranges. Place non-spilled parts into 151 // parts of interfering live ranges. Place non-spilled parts into
137 // the list of unallocated ranges. 152 // the list of unallocated ranges.
138 void AssignNonFreeRegister(LiveRange* unallocated, Register reg); 153 void AssignNonFreeRegister(LiveRange* unallocated, intptr_t reg);
139 bool EvictIntersection(LiveRange* allocated, LiveRange* unallocated); 154 bool EvictIntersection(LiveRange* allocated, LiveRange* unallocated);
140 void RemoveEvicted(Register reg, intptr_t first_evicted); 155 void RemoveEvicted(intptr_t reg, intptr_t first_evicted);
141 156
142 // Find first intersection between unallocated live range and 157 // Find first intersection between unallocated live range and
143 // live ranges currently allocated to the given register. 158 // live ranges currently allocated to the given register.
144 intptr_t FirstIntersectionWithAllocated(Register reg, 159 intptr_t FirstIntersectionWithAllocated(intptr_t reg,
145 LiveRange* unallocated); 160 LiveRange* unallocated);
146 161
147 bool UpdateFreeUntil(Register reg, 162 bool UpdateFreeUntil(intptr_t reg,
148 LiveRange* unallocated, 163 LiveRange* unallocated,
149 intptr_t* cur_free_until, 164 intptr_t* cur_free_until,
150 intptr_t* cur_blocked_at); 165 intptr_t* cur_blocked_at);
151 166
152 // Split given live range in an optimal position between given positions. 167 // Split given live range in an optimal position between given positions.
153 LiveRange* SplitBetween(LiveRange* range, intptr_t from, intptr_t to); 168 LiveRange* SplitBetween(LiveRange* range, intptr_t from, intptr_t to);
154 169
155 // Find a spill slot that can be used by the given live range. 170 // Find a spill slot that can be used by the given live range.
156 void AllocateSpillSlotFor(LiveRange* range); 171 void AllocateSpillSlotFor(LiveRange* range);
157 172
158 // Allocate the given live range to a spill slot. 173 // Allocate the given live range to a spill slot.
159 void Spill(LiveRange* range); 174 void Spill(LiveRange* range);
160 175
161 // Spill the given live range from the given position onwards. 176 // Spill the given live range from the given position onwards.
162 void SpillAfter(LiveRange* range, intptr_t from); 177 void SpillAfter(LiveRange* range, intptr_t from);
163 178
164 // Spill the given live range from the given position until some 179 // Spill the given live range from the given position until some
165 // position preceding the to position. 180 // position preceding the to position.
166 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to); 181 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to);
167 182
168 // Mark the live range as a live object pointer at all safepoints 183 // Mark the live range as a live object pointer at all safepoints
169 // contained in the range. 184 // contained in the range.
170 void MarkAsObjectAtSafepoints(LiveRange* range); 185 void MarkAsObjectAtSafepoints(LiveRange* range);
171 186
172 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); 187 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from);
173 188
189 Location MakeRegisterLocation(intptr_t reg) {
190 return Location::MachineRegisterLocation(register_kind_, reg);
191 }
192
174 void PrintLiveRanges(); 193 void PrintLiveRanges();
175 194
176 const FlowGraph& flow_graph_; 195 const FlowGraph& flow_graph_;
177 const GrowableArray<BlockEntryInstr*>& block_order_; 196 const GrowableArray<BlockEntryInstr*>& block_order_;
178 const GrowableArray<BlockEntryInstr*>& postorder_; 197 const GrowableArray<BlockEntryInstr*>& postorder_;
179 198
180 // Mapping between lifetime positions and instructions. 199 // Mapping between lifetime positions and instructions.
181 GrowableArray<Instruction*> instructions_; 200 GrowableArray<Instruction*> instructions_;
182 201
183 // Mapping between lifetime positions and blocks containing them. 202 // Mapping between lifetime positions and blocks containing them.
(...skipping 13 matching lines...) Expand all
197 // that are used by this block or its successors. 216 // that are used by this block or its successors.
198 GrowableArray<BitVector*> live_in_; 217 GrowableArray<BitVector*> live_in_;
199 218
200 // Number of virtual registers. Currently equal to the number of 219 // Number of virtual registers. Currently equal to the number of
201 // SSA values. 220 // SSA values.
202 const intptr_t vreg_count_; 221 const intptr_t vreg_count_;
203 222
204 // LiveRanges corresponding to SSA values. 223 // LiveRanges corresponding to SSA values.
205 GrowableArray<LiveRange*> live_ranges_; 224 GrowableArray<LiveRange*> live_ranges_;
206 225
207 // Worklist for register allocator. Always maintained sorted according 226 GrowableArray<LiveRange*> unallocated_cpu_;
208 // to ShouldBeAllocatedBefore predicate. 227 GrowableArray<LiveRange*> unallocated_xmm_;
209 GrowableArray<LiveRange*> unallocated_; 228
229 LiveRange* cpu_regs_[kNumberOfCpuRegisters];
230 LiveRange* xmm_regs_[kNumberOfXmmRegisters];
231
232 bool blocked_cpu_registers_[kNumberOfCpuRegisters];
233 bool blocked_xmm_registers_[kNumberOfXmmRegisters];
210 234
211 #if defined(DEBUG) 235 #if defined(DEBUG)
212 GrowableArray<LiveRange*> temporaries_; 236 GrowableArray<LiveRange*> temporaries_;
213 #endif 237 #endif
214 238
215 // List of spilled live ranges. 239 // List of spilled live ranges.
216 GrowableArray<LiveRange*> spilled_; 240 GrowableArray<LiveRange*> spilled_;
217 241
218 // List of instructions containing calls. 242 // List of instructions containing calls.
219 GrowableArray<Instruction*> safepoints_; 243 GrowableArray<Instruction*> safepoints_;
220 244
245 Location::Kind register_kind_;
246
247 intptr_t number_of_registers_;
248
221 // Per register lists of allocated live ranges. Contain only those 249 // Per register lists of allocated live ranges. Contain only those
222 // ranges that can be affected by future allocation decisions. 250 // ranges that can be affected by future allocation decisions.
223 // Those live ranges that end before the start of the current live range are 251 // Those live ranges that end before the start of the current live range are
224 // removed from the list and will not be affected. 252 // removed from the list and will not be affected.
225 GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters]; 253 GrowableArray<LiveRange*> registers_[kNumberOfCpuRegisters];
254
255 bool blocked_registers_[kNumberOfCpuRegisters];
256
257
258 // Worklist for register allocator. Always maintained sorted according
259 // to ShouldBeAllocatedBefore predicate.
260 GrowableArray<LiveRange*> unallocated_;
226 261
227 // List of used spill slots. Contains positions after which spill slots 262 // List of used spill slots. Contains positions after which spill slots
228 // become free and can be reused for allocation. 263 // become free and can be reused for allocation.
229 GrowableArray<intptr_t> spill_slots_; 264 GrowableArray<intptr_t> spill_slots_;
265 intptr_t cpu_spill_slot_count_;
230 266
231 bool blocked_cpu_regs_[kNumberOfCpuRegisters];
232 267
233 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); 268 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator);
234 }; 269 };
235 270
236 271
237 // Additional information about a block that is not contained in a 272 // Additional information about a block that is not contained in a
238 // block entry. 273 // block entry.
239 class BlockInfo : public ZoneAllocated { 274 class BlockInfo : public ZoneAllocated {
240 public: 275 public:
241 explicit BlockInfo(BlockEntryInstr* entry) 276 explicit BlockInfo(BlockEntryInstr* entry)
(...skipping 26 matching lines...) Expand all
268 303
269 304
270 // UsePosition represents a single use of an SSA value by some instruction. 305 // UsePosition represents a single use of an SSA value by some instruction.
271 // It points to a location slot which either tells register allocator 306 // It points to a location slot which either tells register allocator
272 // where instruction expects the value (if slot contains a fixed location) or 307 // where instruction expects the value (if slot contains a fixed location) or
273 // asks register allocator to allocate storage (register or spill slot) for 308 // asks register allocator to allocate storage (register or spill slot) for
274 // this use with certain properties (if slot contains an unallocated location). 309 // this use with certain properties (if slot contains an unallocated location).
275 class UsePosition : public ZoneAllocated { 310 class UsePosition : public ZoneAllocated {
276 public: 311 public:
277 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot) 312 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot)
278 : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) { } 313 : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) {
314 ASSERT(location_slot != NULL);
315 }
279 316
280 Location* location_slot() const { return location_slot_; } 317 Location* location_slot() const { return location_slot_; }
281 void set_location_slot(Location* location_slot) { 318 void set_location_slot(Location* location_slot) {
282 location_slot_ = location_slot; 319 location_slot_ = location_slot;
283 } 320 }
284 321
285 Location hint() const { 322 Location hint() const {
286 ASSERT(HasHint()); 323 ASSERT(HasHint());
287 return *hint_; 324 return *hint_;
288 } 325 }
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 543
507 AllocationFinger finger_; 544 AllocationFinger finger_;
508 545
509 DISALLOW_COPY_AND_ASSIGN(LiveRange); 546 DISALLOW_COPY_AND_ASSIGN(LiveRange);
510 }; 547 };
511 548
512 549
513 } // namespace dart 550 } // namespace dart
514 551
515 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ 552 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698