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

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

Issue 11361161: Try allocating loop phi into a register even if phi has only unconstrained uses but there are cheap… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: address comments Created 8 years, 1 month 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 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 146
147 // Try to find a free register for an unallocated live range. 147 // Try to find a free register for an unallocated live range.
148 bool AllocateFreeRegister(LiveRange* unallocated); 148 bool AllocateFreeRegister(LiveRange* unallocated);
149 149
150 // Try to find a register that can be used by a given live range. 150 // Try to find a register that can be used by a given live range.
151 // If all registers are occupied consider evicting interference for 151 // If all registers are occupied consider evicting interference for
152 // a register that is going to be used as far from the start of 152 // a register that is going to be used as far from the start of
153 // the unallocated live range as possible. 153 // the unallocated live range as possible.
154 void AllocateAnyRegister(LiveRange* unallocated); 154 void AllocateAnyRegister(LiveRange* unallocated);
155 155
156 // Returns true if the given range has only unconstrained uses in
157 // the given loop.
158 bool RangeHasOnlyUnconstrainedUsesInLoop(LiveRange* range, intptr_t loop_id);
159
160 // Returns true if there is a register blocked by a range that
161 // has only unconstrained uses in the loop. Such range is a good
162 // eviction candidate when allocator tries to allocate loop phi.
163 // Spilling loop phi will have a bigger negative impact on the
164 // performance because it introduces multiple operations with memory
165 // inside the loop body and on the back edge.
166 bool HasCheapEvictionCandidate(LiveRange* phi_range);
167 bool IsCheapToEvictRegisterInLoop(BlockInfo* loop, intptr_t reg);
168
156 // Assign selected non-free register to an unallocated live range and 169 // Assign selected non-free register to an unallocated live range and
157 // evict any interference that can be evicted by splitting and spilling 170 // evict any interference that can be evicted by splitting and spilling
158 // parts of interfering live ranges. Place non-spilled parts into 171 // parts of interfering live ranges. Place non-spilled parts into
159 // the list of unallocated ranges. 172 // the list of unallocated ranges.
160 void AssignNonFreeRegister(LiveRange* unallocated, intptr_t reg); 173 void AssignNonFreeRegister(LiveRange* unallocated, intptr_t reg);
161 bool EvictIntersection(LiveRange* allocated, LiveRange* unallocated); 174 bool EvictIntersection(LiveRange* allocated, LiveRange* unallocated);
162 void RemoveEvicted(intptr_t reg, intptr_t first_evicted); 175 void RemoveEvicted(intptr_t reg, intptr_t first_evicted);
163 176
164 // Find first intersection between unallocated live range and 177 // Find first intersection between unallocated live range and
165 // live ranges currently allocated to the given register. 178 // live ranges currently allocated to the given register.
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // outer loop not to themselves. 311 // outer loop not to themselves.
299 BlockInfo* loop() const { return loop_; } 312 BlockInfo* loop() const { return loop_; }
300 313
301 void mark_loop_header() { is_loop_header_ = true; } 314 void mark_loop_header() { is_loop_header_ = true; }
302 void set_loop(BlockInfo* loop) { 315 void set_loop(BlockInfo* loop) {
303 ASSERT(loop_ == NULL); 316 ASSERT(loop_ == NULL);
304 ASSERT((loop == NULL) || loop->is_loop_header()); 317 ASSERT((loop == NULL) || loop->is_loop_header());
305 loop_ = loop; 318 loop_ = loop;
306 } 319 }
307 320
321 BlockEntryInstr* last_block() const { return last_block_; }
322 void set_last_block(BlockEntryInstr* last_block) {
323 last_block_ = last_block;
324 }
325
326 intptr_t loop_id() const { return loop_id_; }
327 void set_loop_id(intptr_t loop_id) { loop_id_ = loop_id; }
328
308 private: 329 private:
309 BlockEntryInstr* entry_; 330 BlockEntryInstr* entry_;
310 BlockInfo* loop_; 331 BlockInfo* loop_;
311 bool is_loop_header_; 332 bool is_loop_header_;
312 333
334 BlockEntryInstr* last_block_;
335 intptr_t loop_id_;
336
313 DISALLOW_COPY_AND_ASSIGN(BlockInfo); 337 DISALLOW_COPY_AND_ASSIGN(BlockInfo);
314 }; 338 };
315 339
316 340
317 // UsePosition represents a single use of an SSA value by some instruction. 341 // UsePosition represents a single use of an SSA value by some instruction.
318 // It points to a location slot which either tells register allocator 342 // It points to a location slot which either tells register allocator
319 // where instruction expects the value (if slot contains a fixed location) or 343 // where instruction expects the value (if slot contains a fixed location) or
320 // asks register allocator to allocate storage (register or spill slot) for 344 // asks register allocator to allocate storage (register or spill slot) for
321 // this use with certain properties (if slot contains an unallocated location). 345 // this use with certain properties (if slot contains an unallocated location).
322 class UsePosition : public ZoneAllocated { 346 class UsePosition : public ZoneAllocated {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 : vreg_(vreg), 484 : vreg_(vreg),
461 representation_(rep), 485 representation_(rep),
462 assigned_location_(), 486 assigned_location_(),
463 spill_slot_(), 487 spill_slot_(),
464 uses_(NULL), 488 uses_(NULL),
465 first_use_interval_(NULL), 489 first_use_interval_(NULL),
466 last_use_interval_(NULL), 490 last_use_interval_(NULL),
467 first_safepoint_(NULL), 491 first_safepoint_(NULL),
468 last_safepoint_(NULL), 492 last_safepoint_(NULL),
469 next_sibling_(NULL), 493 next_sibling_(NULL),
494 has_only_any_uses_in_loops_(0),
495 is_loop_phi_(false),
470 finger_() { 496 finger_() {
471 } 497 }
472 498
473 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot); 499 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot);
474 500
475 intptr_t vreg() const { return vreg_; } 501 intptr_t vreg() const { return vreg_; }
476 Location::Representation representation() const { return representation_; } 502 Location::Representation representation() const { return representation_; }
477 LiveRange* next_sibling() const { return next_sibling_; } 503 LiveRange* next_sibling() const { return next_sibling_; }
478 UsePosition* first_use() const { return uses_; } 504 UsePosition* first_use() const { return uses_; }
479 void set_first_use(UsePosition* use) { uses_ = use; } 505 void set_first_use(UsePosition* use) { uses_ = use; }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
517 return (Start() <= pos) && (pos < End()); 543 return (Start() <= pos) && (pos < End());
518 } 544 }
519 545
520 // True if the range contains the given position. 546 // True if the range contains the given position.
521 bool Contains(intptr_t pos) const; 547 bool Contains(intptr_t pos) const;
522 548
523 Location spill_slot() const { 549 Location spill_slot() const {
524 return spill_slot_; 550 return spill_slot_;
525 } 551 }
526 552
553 bool HasOnlyUnconstrainedUsesInLoop(intptr_t loop_id) const {
554 if (loop_id < kBitsPerWord) {
555 const intptr_t mask = static_cast<intptr_t>(1) << loop_id;
556 return (has_only_any_uses_in_loops_ & mask) != 0;
557 }
558 return false;
559 }
560
561 void MarkHasOnlyUnconstrainedUsesInLoop(intptr_t loop_id) {
562 if (loop_id < kBitsPerWord) {
563 has_only_any_uses_in_loops_ |= static_cast<intptr_t>(1) << loop_id;
564 }
565 }
566
567 bool is_loop_phi() const { return is_loop_phi_; }
568 void mark_loop_phi() {
569 is_loop_phi_ = true;
570 }
571
527 private: 572 private:
528 LiveRange(intptr_t vreg, 573 LiveRange(intptr_t vreg,
529 Location::Representation rep, 574 Location::Representation rep,
530 UsePosition* uses, 575 UsePosition* uses,
531 UseInterval* first_use_interval, 576 UseInterval* first_use_interval,
532 UseInterval* last_use_interval, 577 UseInterval* last_use_interval,
533 SafepointPosition* first_safepoint, 578 SafepointPosition* first_safepoint,
534 LiveRange* next_sibling) 579 LiveRange* next_sibling)
535 : vreg_(vreg), 580 : vreg_(vreg),
536 representation_(rep), 581 representation_(rep),
537 assigned_location_(), 582 assigned_location_(),
538 uses_(uses), 583 uses_(uses),
539 first_use_interval_(first_use_interval), 584 first_use_interval_(first_use_interval),
540 last_use_interval_(last_use_interval), 585 last_use_interval_(last_use_interval),
541 first_safepoint_(first_safepoint), 586 first_safepoint_(first_safepoint),
542 last_safepoint_(NULL), 587 last_safepoint_(NULL),
543 next_sibling_(next_sibling), 588 next_sibling_(next_sibling),
589 has_only_any_uses_in_loops_(0),
590 is_loop_phi_(false),
544 finger_() { 591 finger_() {
545 } 592 }
546 593
547 const intptr_t vreg_; 594 const intptr_t vreg_;
548 Location::Representation representation_; 595 Location::Representation representation_;
549 Location assigned_location_; 596 Location assigned_location_;
550 Location spill_slot_; 597 Location spill_slot_;
551 598
552 UsePosition* uses_; 599 UsePosition* uses_;
553 UseInterval* first_use_interval_; 600 UseInterval* first_use_interval_;
554 UseInterval* last_use_interval_; 601 UseInterval* last_use_interval_;
555 602
556 SafepointPosition* first_safepoint_; 603 SafepointPosition* first_safepoint_;
557 SafepointPosition* last_safepoint_; 604 SafepointPosition* last_safepoint_;
558 605
559 LiveRange* next_sibling_; 606 LiveRange* next_sibling_;
560 607
608 intptr_t has_only_any_uses_in_loops_;
609 bool is_loop_phi_;
610
561 AllocationFinger finger_; 611 AllocationFinger finger_;
562 612
563 DISALLOW_COPY_AND_ASSIGN(LiveRange); 613 DISALLOW_COPY_AND_ASSIGN(LiveRange);
564 }; 614 };
565 615
566 616
567 } // namespace dart 617 } // namespace dart
568 618
569 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ 619 #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