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

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

Issue 10828115: Implement simple spill store elimination. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address Srdjan's comments Created 8 years, 4 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 | « no previous file | 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 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
69 // required to resolve data flow between split siblings when allocation 69 // required to resolve data flow between split siblings when allocation
70 // is finished. 70 // is finished.
71 // For specific examples see comments inside ProcessOneInstruction. 71 // For specific examples see comments inside ProcessOneInstruction.
72 // Additionally creates parallel moves at the joins' predecessors 72 // Additionally creates parallel moves at the joins' predecessors
73 // that will be used for phi resolution. 73 // that will be used for phi resolution.
74 void NumberInstructions(); 74 void NumberInstructions();
75 Instruction* InstructionAt(intptr_t pos) const; 75 Instruction* InstructionAt(intptr_t pos) const;
76 bool IsBlockEntry(intptr_t pos) const; 76 bool IsBlockEntry(intptr_t pos) const;
77 77
78 LiveRange* GetLiveRange(intptr_t vreg); 78 LiveRange* GetLiveRange(intptr_t vreg);
79 LiveRange* MakeLiveRangeForTemporary();
79 80
80 // Visit instructions in the postorder and build live ranges for 81 // Visit instructions in the postorder and build live ranges for
81 // all SSA values. 82 // all SSA values.
82 void BuildLiveRanges(); 83 void BuildLiveRanges();
83 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); 84 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block);
84 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); 85 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr);
85 void ConnectIncomingPhiMoves(BlockEntryInstr* block); 86 void ConnectIncomingPhiMoves(BlockEntryInstr* block);
86 void BlockLocation(Location loc, intptr_t pos); 87 void BlockLocation(Location loc, intptr_t pos);
87 88
88 // Process live ranges sorted by their start and assign registers 89 // Process live ranges sorted by their start and assign registers
89 // to them 90 // to them
90 void AllocateCPURegisters(); 91 void AllocateCPURegisters();
91 void AdvanceActiveIntervals(const intptr_t start); 92 void AdvanceActiveIntervals(const intptr_t start);
92 93
93 // Connect split siblings over non-linear control flow edges. 94 // Connect split siblings over non-linear control flow edges.
94 void ResolveControlFlow(); 95 void ResolveControlFlow();
95 void ConnectSplitSiblings(LiveRange* range, 96 void ConnectSplitSiblings(LiveRange* range,
96 BlockEntryInstr* source_block, 97 BlockEntryInstr* source_block,
97 BlockEntryInstr* target_block); 98 BlockEntryInstr* target_block);
98 99
99 100
100 // Update location slot corresponding to the use with location allocated for 101 // Update location slot corresponding to the use with location allocated for
101 // the use's live range. 102 // the use's live range.
102 void ConvertUseTo(UsePosition* use, Location loc); 103 void ConvertUseTo(UsePosition* use, Location loc);
103 void ConvertAllUses(LiveRange* range); 104 void ConvertAllUses(LiveRange* range);
104 105
105 // Add live range to the list of unallocated live ranges to be processed 106 // Add live range to the list of unallocated live ranges to be processed
106 // by the allocator. 107 // by the allocator.
107 void AddToUnallocated(LiveRange* range); 108 void AddToUnallocated(LiveRange* range);
108 #ifdef DEBUG 109 #if defined(DEBUG)
109 bool UnallocatedIsSorted(); 110 bool UnallocatedIsSorted();
110 #endif 111 #endif
111 112
112 // Try to find a free register for an unallocated live range. 113 // Try to find a free register for an unallocated live range.
113 bool AllocateFreeRegister(LiveRange* unallocated); 114 bool AllocateFreeRegister(LiveRange* unallocated);
114 115
115 // Try to find a register that can be used by a given live range. 116 // Try to find a register that can be used by a given live range.
116 // If all registers are occupied consider evicting interference for 117 // If all registers are occupied consider evicting interference for
117 // a register that is going to be used as far from the start of 118 // a register that is going to be used as far from the start of
118 // the unallocated live range as possible. 119 // the unallocated live range as possible.
(...skipping 14 matching lines...) Expand all
133 134
134 bool UpdateFreeUntil(Register reg, 135 bool UpdateFreeUntil(Register reg,
135 LiveRange* unallocated, 136 LiveRange* unallocated,
136 intptr_t* cur_free_until, 137 intptr_t* cur_free_until,
137 intptr_t* cur_blocked_at); 138 intptr_t* cur_blocked_at);
138 139
139 // Split given live range in an optimal position between given positions. 140 // Split given live range in an optimal position between given positions.
140 LiveRange* SplitBetween(LiveRange* range, intptr_t from, intptr_t to); 141 LiveRange* SplitBetween(LiveRange* range, intptr_t from, intptr_t to);
141 142
142 // Find a spill slot that can be used by the given live range. 143 // Find a spill slot that can be used by the given live range.
143 intptr_t AllocateSpillSlotFor(LiveRange* range); 144 void AllocateSpillSlotFor(LiveRange* range);
144 145
145 // Allocate the given live range to a spill slot. 146 // Allocate the given live range to a spill slot.
146 void Spill(LiveRange* range); 147 void Spill(LiveRange* range);
147 148
148 // Spill the given live range from the given position onwards. 149 // Spill the given live range from the given position onwards.
149 void SpillAfter(LiveRange* range, intptr_t from); 150 void SpillAfter(LiveRange* range, intptr_t from);
150 151
151 // Spill the given live range from the given position until some 152 // Spill the given live range from the given position until some
152 // position preceeding the to position. 153 // position preceeding the to position.
153 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to); 154 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to);
(...skipping 29 matching lines...) Expand all
183 // SSA values. 184 // SSA values.
184 const intptr_t vreg_count_; 185 const intptr_t vreg_count_;
185 186
186 // LiveRanges corresponding to SSA values. 187 // LiveRanges corresponding to SSA values.
187 GrowableArray<LiveRange*> live_ranges_; 188 GrowableArray<LiveRange*> live_ranges_;
188 189
189 // Worklist for register allocator. Always maintained sorted according 190 // Worklist for register allocator. Always maintained sorted according
190 // to ShouldBeAllocatedBefore predicate. 191 // to ShouldBeAllocatedBefore predicate.
191 GrowableArray<LiveRange*> unallocated_; 192 GrowableArray<LiveRange*> unallocated_;
192 193
194 #if defined(DEBUG)
195 GrowableArray<LiveRange*> temporaries_;
196 #endif
197
198 GrowableArray<LiveRange*> spilled_;
199
193 // Per register lists of allocated live ranges. Contain only those 200 // Per register lists of allocated live ranges. Contain only those
194 // ranges that can be affected by future allocation decisions. 201 // ranges that can be affected by future allocation decisions.
195 // Those live ranges that end before the start of the current live range are 202 // Those live ranges that end before the start of the current live range are
196 // removed from the list and will not be affected. 203 // removed from the list and will not be affected.
197 GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters]; 204 GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters];
198 205
199 // List of used spill slots. Contain positions after which spill slots 206 // List of used spill slots. Contain positions after which spill slots
200 // become free and can be reused for allocation. 207 // become free and can be reused for allocation.
201 GrowableArray<intptr_t> spill_slots_; 208 GrowableArray<intptr_t> spill_slots_;
202 209
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 DISALLOW_COPY_AND_ASSIGN(AllocationFinger); 321 DISALLOW_COPY_AND_ASSIGN(AllocationFinger);
315 }; 322 };
316 323
317 324
318 // LiveRange represents a sequence of UseIntervals for a given SSA value. 325 // LiveRange represents a sequence of UseIntervals for a given SSA value.
319 class LiveRange : public ZoneAllocated { 326 class LiveRange : public ZoneAllocated {
320 public: 327 public:
321 explicit LiveRange(intptr_t vreg) 328 explicit LiveRange(intptr_t vreg)
322 : vreg_(vreg), 329 : vreg_(vreg),
323 assigned_location_(), 330 assigned_location_(),
331 spill_slot_(),
324 uses_(NULL), 332 uses_(NULL),
325 first_use_interval_(NULL), 333 first_use_interval_(NULL),
326 last_use_interval_(NULL), 334 last_use_interval_(NULL),
327 next_sibling_(NULL), 335 next_sibling_(NULL),
328 finger_() { 336 finger_() {
329 } 337 }
330 338
331 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot); 339 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot);
332 340
333 intptr_t vreg() const { return vreg_; } 341 intptr_t vreg() const { return vreg_; }
334 LiveRange* next_sibling() const { return next_sibling_; } 342 LiveRange* next_sibling() const { return next_sibling_; }
335 UsePosition* first_use() const { return uses_; } 343 UsePosition* first_use() const { return uses_; }
336 void set_first_use(UsePosition* use) { uses_ = use; } 344 void set_first_use(UsePosition* use) { uses_ = use; }
337 UseInterval* first_use_interval() const { return first_use_interval_; } 345 UseInterval* first_use_interval() const { return first_use_interval_; }
338 UseInterval* last_use_interval() const { return last_use_interval_; } 346 UseInterval* last_use_interval() const { return last_use_interval_; }
339 Location assigned_location() const { return assigned_location_; } 347 Location assigned_location() const { return assigned_location_; }
340 intptr_t Start() const { return first_use_interval()->start(); } 348 intptr_t Start() const { return first_use_interval()->start(); }
341 intptr_t End() const { return last_use_interval()->end(); } 349 intptr_t End() const { return last_use_interval()->end(); }
342 350
343 AllocationFinger* finger() { return &finger_; } 351 AllocationFinger* finger() { return &finger_; }
344 352
345 void set_assigned_location(Location location) { 353 void set_assigned_location(Location location) {
346 assigned_location_ = location; 354 assigned_location_ = location;
347 } 355 }
348 356
357 void set_spill_slot(Location spill_slot) {
358 spill_slot_ = spill_slot;
359 }
360
349 void DefineAt(intptr_t pos); 361 void DefineAt(intptr_t pos);
350 362
351 void AddUse(intptr_t pos, Location* location_slot); 363 void AddUse(intptr_t pos, Location* location_slot);
352 void AddUseInterval(intptr_t start, intptr_t end); 364 void AddUseInterval(intptr_t start, intptr_t end);
353 365
354 void Print(); 366 void Print();
355 367
356 void AssignLocation(UseInterval* use, Location loc); 368 void AssignLocation(UseInterval* use, Location loc);
357 369
358 LiveRange* SplitAt(intptr_t pos); 370 LiveRange* SplitAt(intptr_t pos);
359 371
360 bool CanCover(intptr_t pos) const { 372 bool CanCover(intptr_t pos) const {
361 return (Start() <= pos) && (pos < End()); 373 return (Start() <= pos) && (pos < End());
362 } 374 }
363 375
376 Location spill_slot() const {
377 return spill_slot_;
378 }
379
364 private: 380 private:
365 LiveRange(intptr_t vreg, 381 LiveRange(intptr_t vreg,
366 UsePosition* uses, 382 UsePosition* uses,
367 UseInterval* first_use_interval, 383 UseInterval* first_use_interval,
368 UseInterval* last_use_interval, 384 UseInterval* last_use_interval,
369 LiveRange* next_sibling) 385 LiveRange* next_sibling)
370 : vreg_(vreg), 386 : vreg_(vreg),
371 assigned_location_(), 387 assigned_location_(),
372 uses_(uses), 388 uses_(uses),
373 first_use_interval_(first_use_interval), 389 first_use_interval_(first_use_interval),
374 last_use_interval_(last_use_interval), 390 last_use_interval_(last_use_interval),
375 next_sibling_(next_sibling), 391 next_sibling_(next_sibling),
376 finger_() { 392 finger_() {
377 } 393 }
378 394
379 const intptr_t vreg_; 395 const intptr_t vreg_;
380 Location assigned_location_; 396 Location assigned_location_;
397 Location spill_slot_;
381 398
382 UsePosition* uses_; 399 UsePosition* uses_;
383 UseInterval* first_use_interval_; 400 UseInterval* first_use_interval_;
384 UseInterval* last_use_interval_; 401 UseInterval* last_use_interval_;
385 402
386 LiveRange* next_sibling_; 403 LiveRange* next_sibling_;
387 404
388 AllocationFinger finger_; 405 AllocationFinger finger_;
389 406
390 DISALLOW_COPY_AND_ASSIGN(LiveRange); 407 DISALLOW_COPY_AND_ASSIGN(LiveRange);
391 }; 408 };
392 409
393 410
394 } // namespace dart 411 } // namespace dart
395 412
396 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ 413 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698