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

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

Issue 2974233002: VM: Re-format to use at most one newline between functions (Closed)
Patch Set: Rebase and merge Created 3 years, 5 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
« no previous file with comments | « runtime/vm/flow_graph.cc ('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) 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 #ifndef RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_ 5 #ifndef RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_
6 #define RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_ 6 #define RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_
7 7
8 #include "vm/flow_graph.h" 8 #include "vm/flow_graph.h"
9 #include "vm/growable_array.h" 9 #include "vm/growable_array.h"
10 #include "vm/intermediate_language.h" 10 #include "vm/intermediate_language.h"
11 11
12 namespace dart { 12 namespace dart {
13 13
14 class AllocationFinger; 14 class AllocationFinger;
15 class BlockInfo; 15 class BlockInfo;
16 class FlowGraph; 16 class FlowGraph;
17 class LiveRange; 17 class LiveRange;
18 class UseInterval; 18 class UseInterval;
19 class UsePosition; 19 class UsePosition;
20 20
21
22 class ReachingDefs : public ValueObject { 21 class ReachingDefs : public ValueObject {
23 public: 22 public:
24 explicit ReachingDefs(const FlowGraph& flow_graph) 23 explicit ReachingDefs(const FlowGraph& flow_graph)
25 : flow_graph_(flow_graph), phis_(10) {} 24 : flow_graph_(flow_graph), phis_(10) {}
26 25
27 BitVector* Get(PhiInstr* phi); 26 BitVector* Get(PhiInstr* phi);
28 27
29 private: 28 private:
30 void AddPhi(PhiInstr* phi); 29 void AddPhi(PhiInstr* phi);
31 void Compute(); 30 void Compute();
32 31
33 const FlowGraph& flow_graph_; 32 const FlowGraph& flow_graph_;
34 GrowableArray<PhiInstr*> phis_; 33 GrowableArray<PhiInstr*> phis_;
35 }; 34 };
36 35
37
38 class SSALivenessAnalysis : public LivenessAnalysis { 36 class SSALivenessAnalysis : public LivenessAnalysis {
39 public: 37 public:
40 explicit SSALivenessAnalysis(const FlowGraph& flow_graph) 38 explicit SSALivenessAnalysis(const FlowGraph& flow_graph)
41 : LivenessAnalysis(flow_graph.max_virtual_register_number(), 39 : LivenessAnalysis(flow_graph.max_virtual_register_number(),
42 flow_graph.postorder()), 40 flow_graph.postorder()),
43 graph_entry_(flow_graph.graph_entry()) {} 41 graph_entry_(flow_graph.graph_entry()) {}
44 42
45 private: 43 private:
46 // Compute initial values for live-out, kill and live-in sets. 44 // Compute initial values for live-out, kill and live-in sets.
47 virtual void ComputeInitialSets(); 45 virtual void ComputeInitialSets();
48 46
49 GraphEntryInstr* graph_entry_; 47 GraphEntryInstr* graph_entry_;
50 }; 48 };
51 49
52
53 class FlowGraphAllocator : public ValueObject { 50 class FlowGraphAllocator : public ValueObject {
54 public: 51 public:
55 // Number of stack slots needed for a fpu register spill slot. 52 // Number of stack slots needed for a fpu register spill slot.
56 static const intptr_t kDoubleSpillFactor = kDoubleSize / kWordSize; 53 static const intptr_t kDoubleSpillFactor = kDoubleSize / kWordSize;
57 54
58 explicit FlowGraphAllocator(const FlowGraph& flow_graph, 55 explicit FlowGraphAllocator(const FlowGraph& flow_graph,
59 bool intrinsic_mode = false); 56 bool intrinsic_mode = false);
60 57
61 void AllocateRegisters(); 58 void AllocateRegisters();
62 59
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 143
147 // Find all safepoints that are covered by this live range. 144 // Find all safepoints that are covered by this live range.
148 void AssignSafepoints(Definition* defn, LiveRange* range); 145 void AssignSafepoints(Definition* defn, LiveRange* range);
149 146
150 void PrepareForAllocation(Location::Kind register_kind, 147 void PrepareForAllocation(Location::Kind register_kind,
151 intptr_t number_of_registers, 148 intptr_t number_of_registers,
152 const GrowableArray<LiveRange*>& unallocated, 149 const GrowableArray<LiveRange*>& unallocated,
153 LiveRange** blocking_ranges, 150 LiveRange** blocking_ranges,
154 bool* blocked_registers); 151 bool* blocked_registers);
155 152
156
157 // Process live ranges sorted by their start and assign registers 153 // Process live ranges sorted by their start and assign registers
158 // to them 154 // to them
159 void AllocateUnallocatedRanges(); 155 void AllocateUnallocatedRanges();
160 void AdvanceActiveIntervals(const intptr_t start); 156 void AdvanceActiveIntervals(const intptr_t start);
161 157
162 // Connect split siblings over non-linear control flow edges. 158 // Connect split siblings over non-linear control flow edges.
163 void ResolveControlFlow(); 159 void ResolveControlFlow();
164 void ConnectSplitSiblings(LiveRange* range, 160 void ConnectSplitSiblings(LiveRange* range,
165 BlockEntryInstr* source_block, 161 BlockEntryInstr* source_block,
166 BlockEntryInstr* target_block); 162 BlockEntryInstr* target_block);
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 300
305 // Per register lists of allocated live ranges. Contain only those 301 // Per register lists of allocated live ranges. Contain only those
306 // ranges that can be affected by future allocation decisions. 302 // ranges that can be affected by future allocation decisions.
307 // Those live ranges that end before the start of the current live range are 303 // Those live ranges that end before the start of the current live range are
308 // removed from the list and will not be affected. 304 // removed from the list and will not be affected.
309 // The length of both arrays is 'number_of_registers_' 305 // The length of both arrays is 'number_of_registers_'
310 GrowableArray<ZoneGrowableArray<LiveRange*>*> registers_; 306 GrowableArray<ZoneGrowableArray<LiveRange*>*> registers_;
311 307
312 GrowableArray<bool> blocked_registers_; 308 GrowableArray<bool> blocked_registers_;
313 309
314
315 // Worklist for register allocator. Always maintained sorted according 310 // Worklist for register allocator. Always maintained sorted according
316 // to ShouldBeAllocatedBefore predicate. 311 // to ShouldBeAllocatedBefore predicate.
317 GrowableArray<LiveRange*> unallocated_; 312 GrowableArray<LiveRange*> unallocated_;
318 313
319 // List of used spill slots. Contains positions after which spill slots 314 // List of used spill slots. Contains positions after which spill slots
320 // become free and can be reused for allocation. 315 // become free and can be reused for allocation.
321 GrowableArray<intptr_t> spill_slots_; 316 GrowableArray<intptr_t> spill_slots_;
322 317
323 // For every used spill slot contains a flag determines whether it is 318 // For every used spill slot contains a flag determines whether it is
324 // QuadSpillSlot to ensure that indexes of quad and double spill slots 319 // QuadSpillSlot to ensure that indexes of quad and double spill slots
325 // are disjoint. 320 // are disjoint.
326 GrowableArray<bool> quad_spill_slots_; 321 GrowableArray<bool> quad_spill_slots_;
327 322
328 // Track whether a spill slot is expected to hold a tagged or untagged value. 323 // Track whether a spill slot is expected to hold a tagged or untagged value.
329 // This is used to keep tagged and untagged spill slots disjoint. See bug 324 // This is used to keep tagged and untagged spill slots disjoint. See bug
330 // #18955 for details. 325 // #18955 for details.
331 GrowableArray<bool> untagged_spill_slots_; 326 GrowableArray<bool> untagged_spill_slots_;
332 327
333 intptr_t cpu_spill_slot_count_; 328 intptr_t cpu_spill_slot_count_;
334 329
335 const bool intrinsic_mode_; 330 const bool intrinsic_mode_;
336 331
337 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); 332 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator);
338 }; 333 };
339 334
340
341 // Additional information about a block that is not contained in a 335 // Additional information about a block that is not contained in a
342 // block entry. 336 // block entry.
343 class BlockInfo : public ZoneAllocated { 337 class BlockInfo : public ZoneAllocated {
344 public: 338 public:
345 explicit BlockInfo(BlockEntryInstr* entry) 339 explicit BlockInfo(BlockEntryInstr* entry)
346 : entry_(entry), 340 : entry_(entry),
347 loop_(NULL), 341 loop_(NULL),
348 is_loop_header_(false), 342 is_loop_header_(false),
349 backedge_interference_(NULL) {} 343 backedge_interference_(NULL) {}
350 344
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 bool is_loop_header_; 387 bool is_loop_header_;
394 388
395 BlockEntryInstr* last_block_; 389 BlockEntryInstr* last_block_;
396 intptr_t loop_id_; 390 intptr_t loop_id_;
397 391
398 BitVector* backedge_interference_; 392 BitVector* backedge_interference_;
399 393
400 DISALLOW_COPY_AND_ASSIGN(BlockInfo); 394 DISALLOW_COPY_AND_ASSIGN(BlockInfo);
401 }; 395 };
402 396
403
404 // UsePosition represents a single use of an SSA value by some instruction. 397 // UsePosition represents a single use of an SSA value by some instruction.
405 // It points to a location slot which either tells register allocator 398 // It points to a location slot which either tells register allocator
406 // where instruction expects the value (if slot contains a fixed location) or 399 // where instruction expects the value (if slot contains a fixed location) or
407 // asks register allocator to allocate storage (register or spill slot) for 400 // asks register allocator to allocate storage (register or spill slot) for
408 // this use with certain properties (if slot contains an unallocated location). 401 // this use with certain properties (if slot contains an unallocated location).
409 class UsePosition : public ZoneAllocated { 402 class UsePosition : public ZoneAllocated {
410 public: 403 public:
411 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot) 404 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot)
412 : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) { 405 : pos_(pos), location_slot_(location_slot), hint_(NULL), next_(next) {
413 ASSERT(location_slot != NULL); 406 ASSERT(location_slot != NULL);
414 } 407 }
415 408
416 Location* location_slot() const { return location_slot_; } 409 Location* location_slot() const { return location_slot_; }
417 void set_location_slot(Location* location_slot) { 410 void set_location_slot(Location* location_slot) {
418 location_slot_ = location_slot; 411 location_slot_ = location_slot;
419 } 412 }
420 413
421 Location hint() const { 414 Location hint() const {
422 ASSERT(HasHint()); 415 ASSERT(HasHint());
423 return *hint_; 416 return *hint_;
424 } 417 }
425 418
426 void set_hint(Location* hint) { hint_ = hint; } 419 void set_hint(Location* hint) { hint_ = hint; }
427 420
428 bool HasHint() const { return (hint_ != NULL) && !hint_->IsUnallocated(); } 421 bool HasHint() const { return (hint_ != NULL) && !hint_->IsUnallocated(); }
429 422
430
431 void set_next(UsePosition* next) { next_ = next; } 423 void set_next(UsePosition* next) { next_ = next; }
432 UsePosition* next() const { return next_; } 424 UsePosition* next() const { return next_; }
433 425
434 intptr_t pos() const { return pos_; } 426 intptr_t pos() const { return pos_; }
435 427
436 private: 428 private:
437 const intptr_t pos_; 429 const intptr_t pos_;
438 Location* location_slot_; 430 Location* location_slot_;
439 Location* hint_; 431 Location* hint_;
440 UsePosition* next_; 432 UsePosition* next_;
441 433
442 DISALLOW_COPY_AND_ASSIGN(UsePosition); 434 DISALLOW_COPY_AND_ASSIGN(UsePosition);
443 }; 435 };
444 436
445
446 // UseInterval represents a holeless half open interval of liveness for a given 437 // UseInterval represents a holeless half open interval of liveness for a given
447 // SSA value: [start, end) in terms of lifetime positions that 438 // SSA value: [start, end) in terms of lifetime positions that
448 // NumberInstructions assigns to instructions. Register allocator has to keep 439 // NumberInstructions assigns to instructions. Register allocator has to keep
449 // a value live in the register or in a spill slot from start position and until 440 // a value live in the register or in a spill slot from start position and until
450 // the end position. The interval can cover zero or more uses. 441 // the end position. The interval can cover zero or more uses.
451 // Note: currently all uses of the same SSA value are linked together into a 442 // Note: currently all uses of the same SSA value are linked together into a
452 // single list (and not split between UseIntervals). 443 // single list (and not split between UseIntervals).
453 class UseInterval : public ZoneAllocated { 444 class UseInterval : public ZoneAllocated {
454 public: 445 public:
455 UseInterval(intptr_t start, intptr_t end, UseInterval* next) 446 UseInterval(intptr_t start, intptr_t end, UseInterval* next)
(...skipping 16 matching lines...) Expand all
472 private: 463 private:
473 friend class LiveRange; 464 friend class LiveRange;
474 465
475 intptr_t start_; 466 intptr_t start_;
476 intptr_t end_; 467 intptr_t end_;
477 UseInterval* next_; 468 UseInterval* next_;
478 469
479 DISALLOW_COPY_AND_ASSIGN(UseInterval); 470 DISALLOW_COPY_AND_ASSIGN(UseInterval);
480 }; 471 };
481 472
482
483 // AllocationFinger is used to keep track of currently active position 473 // AllocationFinger is used to keep track of currently active position
484 // for the register allocator and cache lookup results. 474 // for the register allocator and cache lookup results.
485 class AllocationFinger : public ValueObject { 475 class AllocationFinger : public ValueObject {
486 public: 476 public:
487 AllocationFinger() 477 AllocationFinger()
488 : first_pending_use_interval_(NULL), 478 : first_pending_use_interval_(NULL),
489 first_register_use_(NULL), 479 first_register_use_(NULL),
490 first_register_beneficial_use_(NULL), 480 first_register_beneficial_use_(NULL),
491 first_hinted_use_(NULL) {} 481 first_hinted_use_(NULL) {}
492 482
(...skipping 12 matching lines...) Expand all
505 495
506 private: 496 private:
507 UseInterval* first_pending_use_interval_; 497 UseInterval* first_pending_use_interval_;
508 UsePosition* first_register_use_; 498 UsePosition* first_register_use_;
509 UsePosition* first_register_beneficial_use_; 499 UsePosition* first_register_beneficial_use_;
510 UsePosition* first_hinted_use_; 500 UsePosition* first_hinted_use_;
511 501
512 DISALLOW_COPY_AND_ASSIGN(AllocationFinger); 502 DISALLOW_COPY_AND_ASSIGN(AllocationFinger);
513 }; 503 };
514 504
515
516 class SafepointPosition : public ZoneAllocated { 505 class SafepointPosition : public ZoneAllocated {
517 public: 506 public:
518 SafepointPosition(intptr_t pos, LocationSummary* locs) 507 SafepointPosition(intptr_t pos, LocationSummary* locs)
519 : pos_(pos), locs_(locs), next_(NULL) {} 508 : pos_(pos), locs_(locs), next_(NULL) {}
520 509
521 void set_next(SafepointPosition* next) { next_ = next; } 510 void set_next(SafepointPosition* next) { next_ = next; }
522 SafepointPosition* next() const { return next_; } 511 SafepointPosition* next() const { return next_; }
523 512
524 intptr_t pos() const { return pos_; } 513 intptr_t pos() const { return pos_; }
525 514
526 LocationSummary* locs() const { return locs_; } 515 LocationSummary* locs() const { return locs_; }
527 516
528 private: 517 private:
529 const intptr_t pos_; 518 const intptr_t pos_;
530 LocationSummary* const locs_; 519 LocationSummary* const locs_;
531 520
532 SafepointPosition* next_; 521 SafepointPosition* next_;
533 }; 522 };
534 523
535
536 // LiveRange represents a sequence of UseIntervals for a given SSA value. 524 // LiveRange represents a sequence of UseIntervals for a given SSA value.
537 class LiveRange : public ZoneAllocated { 525 class LiveRange : public ZoneAllocated {
538 public: 526 public:
539 explicit LiveRange(intptr_t vreg, Representation rep) 527 explicit LiveRange(intptr_t vreg, Representation rep)
540 : vreg_(vreg), 528 : vreg_(vreg),
541 representation_(rep), 529 representation_(rep),
542 assigned_location_(), 530 assigned_location_(),
543 spill_slot_(), 531 spill_slot_(),
544 uses_(NULL), 532 uses_(NULL),
545 first_use_interval_(NULL), 533 first_use_interval_(NULL),
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 LiveRange* next_sibling_; 639 LiveRange* next_sibling_;
652 640
653 intptr_t has_only_any_uses_in_loops_; 641 intptr_t has_only_any_uses_in_loops_;
654 bool is_loop_phi_; 642 bool is_loop_phi_;
655 643
656 AllocationFinger finger_; 644 AllocationFinger finger_;
657 645
658 DISALLOW_COPY_AND_ASSIGN(LiveRange); 646 DISALLOW_COPY_AND_ASSIGN(LiveRange);
659 }; 647 };
660 648
661
662 } // namespace dart 649 } // namespace dart
663 650
664 #endif // RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_ 651 #endif // RUNTIME_VM_FLOW_GRAPH_ALLOCATOR_H_
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.cc ('k') | runtime/vm/flow_graph_allocator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698