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

Side by Side Diff: src/lithium-allocator.h

Issue 310003003: More aggressive reuse of spill slots in the register allocator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebase 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
« no previous file with comments | « src/hydrogen.cc ('k') | src/lithium-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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_LITHIUM_ALLOCATOR_H_ 5 #ifndef V8_LITHIUM_ALLOCATOR_H_
6 #define V8_LITHIUM_ALLOCATOR_H_ 6 #define V8_LITHIUM_ALLOCATOR_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/allocation.h" 10 #include "src/allocation.h"
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 } 146 }
147 147
148 private: 148 private:
149 void set_start(LifetimePosition start) { start_ = start; } 149 void set_start(LifetimePosition start) { start_ = start; }
150 void set_next(UseInterval* next) { next_ = next; } 150 void set_next(UseInterval* next) { next_ = next; }
151 151
152 LifetimePosition start_; 152 LifetimePosition start_;
153 LifetimePosition end_; 153 LifetimePosition end_;
154 UseInterval* next_; 154 UseInterval* next_;
155 155
156 friend class LAllocator; // Assigns to next_.
157 friend class SpillRange; // Assigns to next_.
156 friend class LiveRange; // Assigns to start_. 158 friend class LiveRange; // Assigns to start_.
157 }; 159 };
158 160
159 // Representation of a use position. 161 // Representation of a use position.
160 class UsePosition: public ZoneObject { 162 class UsePosition: public ZoneObject {
161 public: 163 public:
162 UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint); 164 UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint);
163 165
164 LOperand* operand() const { return operand_; } 166 LOperand* operand() const { return operand_; }
165 bool HasOperand() const { return operand_ != NULL; } 167 bool HasOperand() const { return operand_ != NULL; }
(...skipping 12 matching lines...) Expand all
178 LOperand* const operand_; 180 LOperand* const operand_;
179 LOperand* const hint_; 181 LOperand* const hint_;
180 LifetimePosition const pos_; 182 LifetimePosition const pos_;
181 UsePosition* next_; 183 UsePosition* next_;
182 bool requires_reg_; 184 bool requires_reg_;
183 bool register_beneficial_; 185 bool register_beneficial_;
184 186
185 friend class LiveRange; 187 friend class LiveRange;
186 }; 188 };
187 189
190 class SpillRange;
191
188 // Representation of SSA values' live ranges as a collection of (continuous) 192 // Representation of SSA values' live ranges as a collection of (continuous)
189 // intervals over the instruction ordering. 193 // intervals over the instruction ordering.
190 class LiveRange: public ZoneObject { 194 class LiveRange: public ZoneObject {
191 public: 195 public:
192 static const int kInvalidAssignment = 0x7fffffff; 196 static const int kInvalidAssignment = 0x7fffffff;
193 197
194 LiveRange(int id, Zone* zone); 198 LiveRange(int id, Zone* zone);
195 199
196 UseInterval* first_interval() const { return first_interval_; } 200 UseInterval* first_interval() const { return first_interval_; }
197 UsePosition* first_pos() const { return first_pos_; } 201 UsePosition* first_pos() const { return first_pos_; }
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
260 264
261 LifetimePosition End() const { 265 LifetimePosition End() const {
262 DCHECK(!IsEmpty()); 266 DCHECK(!IsEmpty());
263 return last_interval_->end(); 267 return last_interval_->end();
264 } 268 }
265 269
266 bool HasAllocatedSpillOperand() const; 270 bool HasAllocatedSpillOperand() const;
267 LOperand* GetSpillOperand() const { return spill_operand_; } 271 LOperand* GetSpillOperand() const { return spill_operand_; }
268 void SetSpillOperand(LOperand* operand); 272 void SetSpillOperand(LOperand* operand);
269 273
274 void SetSpillRange(SpillRange* spill_range) { spill_range_ = spill_range; }
275 SpillRange* GetSpillRange() const { return spill_range_; }
276 void CommitSpillOperand(LOperand* operand);
277
270 void SetSpillStartIndex(int start) { 278 void SetSpillStartIndex(int start) {
271 spill_start_index_ = Min(start, spill_start_index_); 279 spill_start_index_ = Min(start, spill_start_index_);
272 } 280 }
273 281
274 bool ShouldBeAllocatedBefore(const LiveRange* other) const; 282 bool ShouldBeAllocatedBefore(const LiveRange* other) const;
275 bool CanCover(LifetimePosition position) const; 283 bool CanCover(LifetimePosition position) const;
276 bool Covers(LifetimePosition position); 284 bool Covers(LifetimePosition position);
277 LifetimePosition FirstIntersection(LiveRange* other); 285 LifetimePosition FirstIntersection(LiveRange* other);
278 286
279 // Add a new interval or a new use position to this live range. 287 // Add a new interval or a new use position to this live range.
(...skipping 12 matching lines...) Expand all
292 void ShortenTo(LifetimePosition start); 300 void ShortenTo(LifetimePosition start);
293 301
294 #ifdef DEBUG 302 #ifdef DEBUG
295 // True if target overlaps an existing interval. 303 // True if target overlaps an existing interval.
296 bool HasOverlap(UseInterval* target) const; 304 bool HasOverlap(UseInterval* target) const;
297 void Verify() const; 305 void Verify() const;
298 #endif 306 #endif
299 307
300 private: 308 private:
301 void ConvertOperands(Zone* zone); 309 void ConvertOperands(Zone* zone);
310 void ConvertUsesToOperand(LOperand* op);
302 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; 311 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
303 void AdvanceLastProcessedMarker(UseInterval* to_start_of, 312 void AdvanceLastProcessedMarker(UseInterval* to_start_of,
304 LifetimePosition but_not_past) const; 313 LifetimePosition but_not_past) const;
305 314
306 int id_; 315 int id_;
307 bool spilled_; 316 bool spilled_;
308 RegisterKind kind_; 317 RegisterKind kind_;
309 int assigned_register_; 318 int assigned_register_;
310 UseInterval* last_interval_; 319 UseInterval* last_interval_;
311 UseInterval* first_interval_; 320 UseInterval* first_interval_;
312 UsePosition* first_pos_; 321 UsePosition* first_pos_;
313 LiveRange* parent_; 322 LiveRange* parent_;
314 LiveRange* next_; 323 LiveRange* next_;
315 // This is used as a cache, it doesn't affect correctness. 324 // This is used as a cache, it doesn't affect correctness.
316 mutable UseInterval* current_interval_; 325 mutable UseInterval* current_interval_;
317 UsePosition* last_processed_use_; 326 UsePosition* last_processed_use_;
318 // This is used as a cache, it's invalid outside of BuildLiveRanges. 327 // This is used as a cache, it's invalid outside of BuildLiveRanges.
319 LOperand* current_hint_operand_; 328 LOperand* current_hint_operand_;
320 LOperand* spill_operand_; 329 LOperand* spill_operand_;
321 int spill_start_index_; 330 int spill_start_index_;
331 SpillRange* spill_range_;
322 332
323 friend class LAllocator; // Assigns to kind_. 333 friend class LAllocator; // Assigns to kind_.
324 }; 334 };
325 335
326 336
337 class SpillRange : public ZoneObject {
338 public:
339 SpillRange(LiveRange* range, int id, Zone* zone);
340
341 bool TryMerge(SpillRange* other, Zone* zone);
342 void SetOperand(LOperand* op);
343 bool IsEmpty() { return live_ranges_.length() == 0; }
344 int id() const { return id_; }
345 UseInterval* interval() { return use_interval_; }
346 RegisterKind Kind() const { return live_ranges_.at(0)->Kind(); }
347 LifetimePosition End() const { return end_position_; }
348 bool IsIntersectingWith(SpillRange* other);
349
350 private:
351 int id_;
352 ZoneList<LiveRange*> live_ranges_;
353 UseInterval* use_interval_;
354 LifetimePosition end_position_;
355
356 // Merge intervals, making sure the use intervals are sorted
357 void MergeDisjointIntervals(UseInterval* other, Zone* zone);
358 };
359
360
327 class LAllocator BASE_EMBEDDED { 361 class LAllocator BASE_EMBEDDED {
328 public: 362 public:
329 LAllocator(int first_virtual_register, HGraph* graph); 363 LAllocator(int first_virtual_register, HGraph* graph);
330 364
331 static void TraceAlloc(const char* msg, ...); 365 static void TraceAlloc(const char* msg, ...);
332 366
333 // Checks whether the value of a given virtual register is tagged. 367 // Checks whether the value of a given virtual register is tagged.
334 bool HasTaggedValue(int virtual_register) const; 368 bool HasTaggedValue(int virtual_register) const;
335 369
336 // Returns the register kind required by the given virtual register. 370 // Returns the register kind required by the given virtual register.
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 private: 417 private:
384 void MeetRegisterConstraints(); 418 void MeetRegisterConstraints();
385 void ResolvePhis(); 419 void ResolvePhis();
386 void BuildLiveRanges(); 420 void BuildLiveRanges();
387 void AllocateGeneralRegisters(); 421 void AllocateGeneralRegisters();
388 void AllocateDoubleRegisters(); 422 void AllocateDoubleRegisters();
389 void ConnectRanges(); 423 void ConnectRanges();
390 void ResolveControlFlow(); 424 void ResolveControlFlow();
391 void PopulatePointerMaps(); 425 void PopulatePointerMaps();
392 void AllocateRegisters(); 426 void AllocateRegisters();
427 void ReuseSpillSlots();
393 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; 428 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const;
394 inline bool SafePointsAreInOrder() const; 429 inline bool SafePointsAreInOrder() const;
395 430
396 // Liveness analysis support. 431 // Liveness analysis support.
397 void InitializeLivenessAnalysis(); 432 void InitializeLivenessAnalysis();
398 BitVector* ComputeLiveOut(HBasicBlock* block); 433 BitVector* ComputeLiveOut(HBasicBlock* block);
399 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); 434 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out);
400 void ProcessInstructions(HBasicBlock* block, BitVector* live); 435 void ProcessInstructions(HBasicBlock* block, BitVector* live);
401 void MeetRegisterConstraints(HBasicBlock* block); 436 void MeetRegisterConstraints(HBasicBlock* block);
402 void MeetConstraintsBetween(LInstruction* first, 437 void MeetConstraintsBetween(LInstruction* first,
(...skipping 15 matching lines...) Expand all
418 void AddToActive(LiveRange* range); 453 void AddToActive(LiveRange* range);
419 void AddToInactive(LiveRange* range); 454 void AddToInactive(LiveRange* range);
420 void AddToUnhandledSorted(LiveRange* range); 455 void AddToUnhandledSorted(LiveRange* range);
421 void AddToUnhandledUnsorted(LiveRange* range); 456 void AddToUnhandledUnsorted(LiveRange* range);
422 void SortUnhandled(); 457 void SortUnhandled();
423 bool UnhandledIsSorted(); 458 bool UnhandledIsSorted();
424 void ActiveToHandled(LiveRange* range); 459 void ActiveToHandled(LiveRange* range);
425 void ActiveToInactive(LiveRange* range); 460 void ActiveToInactive(LiveRange* range);
426 void InactiveToHandled(LiveRange* range); 461 void InactiveToHandled(LiveRange* range);
427 void InactiveToActive(LiveRange* range); 462 void InactiveToActive(LiveRange* range);
428 void FreeSpillSlot(LiveRange* range); 463 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
429 LOperand* TryReuseSpillSlot(LiveRange* range);
430 464
431 // Helper methods for allocating registers. 465 // Helper methods for allocating registers.
432 bool TryAllocateFreeReg(LiveRange* range); 466 bool TryAllocateFreeReg(LiveRange* range);
433 void AllocateBlockedReg(LiveRange* range); 467 void AllocateBlockedReg(LiveRange* range);
468 bool TryReuseSpillForPhi(LiveRange* range);
434 469
435 // Live range splitting helpers. 470 // Live range splitting helpers.
436 471
437 // Split the given range at the given position. 472 // Split the given range at the given position.
438 // If range starts at or after the given position then the 473 // If range starts at or after the given position then the
439 // original range is returned. 474 // original range is returned.
440 // Otherwise returns the live range that starts at pos and contains 475 // Otherwise returns the live range that starts at pos and contains
441 // all uses from the original range that follow pos. Uses at pos will 476 // all uses from the original range that follow pos. Uses at pos will
442 // still be owned by the original range after splitting. 477 // still be owned by the original range after splitting.
443 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos); 478 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 558
524 // Lists of live ranges 559 // Lists of live ranges
525 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters> 560 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters>
526 fixed_live_ranges_; 561 fixed_live_ranges_;
527 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters> 562 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters>
528 fixed_double_live_ranges_; 563 fixed_double_live_ranges_;
529 ZoneList<LiveRange*> unhandled_live_ranges_; 564 ZoneList<LiveRange*> unhandled_live_ranges_;
530 ZoneList<LiveRange*> active_live_ranges_; 565 ZoneList<LiveRange*> active_live_ranges_;
531 ZoneList<LiveRange*> inactive_live_ranges_; 566 ZoneList<LiveRange*> inactive_live_ranges_;
532 ZoneList<LiveRange*> reusable_slots_; 567 ZoneList<LiveRange*> reusable_slots_;
568 ZoneList<SpillRange*> spill_ranges_;
533 569
534 // Next virtual register number to be assigned to temporaries. 570 // Next virtual register number to be assigned to temporaries.
535 int next_virtual_register_; 571 int next_virtual_register_;
536 int first_artificial_register_; 572 int first_artificial_register_;
537 GrowableBitVector double_artificial_registers_; 573 GrowableBitVector double_artificial_registers_;
538 574
539 RegisterKind mode_; 575 RegisterKind mode_;
540 int num_registers_; 576 int num_registers_;
541 577
542 BitVector* assigned_registers_; 578 BitVector* assigned_registers_;
(...skipping 23 matching lines...) Expand all
566 LAllocator* allocator_; 602 LAllocator* allocator_;
567 unsigned allocator_zone_start_allocation_size_; 603 unsigned allocator_zone_start_allocation_size_;
568 604
569 DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase); 605 DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase);
570 }; 606 };
571 607
572 608
573 } } // namespace v8::internal 609 } } // namespace v8::internal
574 610
575 #endif // V8_LITHIUM_ALLOCATOR_H_ 611 #endif // V8_LITHIUM_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/lithium-allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698