js/src/jit/LinearScan.h

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:ee0427072d0e
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 * vim: set ts=8 sts=4 et sw=4 tw=99:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7 #ifndef jit_LinearScan_h
8 #define jit_LinearScan_h
9
10 #include "jit/LiveRangeAllocator.h"
11 #include "js/Vector.h"
12
13 namespace js {
14 namespace jit {
15
16 class LinearScanVirtualRegister : public VirtualRegister
17 {
18 private:
19 LAllocation *canonicalSpill_;
20 CodePosition spillPosition_ ;
21
22 bool spillAtDefinition_ : 1;
23
24 // This bit is used to determine whether both halves of a nunbox have been
25 // processed by freeAllocation().
26 bool finished_ : 1;
27
28 public:
29 LinearScanVirtualRegister(TempAllocator &alloc)
30 : VirtualRegister(alloc)
31 {}
32 void setCanonicalSpill(LAllocation *alloc) {
33 canonicalSpill_ = alloc;
34 }
35 LAllocation *canonicalSpill() const {
36 return canonicalSpill_;
37 }
38 unsigned canonicalSpillSlot() const {
39 return canonicalSpill_->toStackSlot()->slot();
40 }
41 void setFinished() {
42 finished_ = true;
43 }
44 bool finished() const {
45 return finished_;
46 }
47 void setSpillAtDefinition(CodePosition pos) {
48 spillAtDefinition_ = true;
49 setSpillPosition(pos);
50 }
51 bool mustSpillAtDefinition() const {
52 return spillAtDefinition_;
53 }
54 CodePosition spillPosition() const {
55 return spillPosition_;
56 }
57 void setSpillPosition(CodePosition pos) {
58 spillPosition_ = pos;
59 }
60 };
61
62 class LinearScanAllocator
63 : private LiveRangeAllocator<LinearScanVirtualRegister, /* forLSRA = */ true>
64 {
65 friend class C1Spewer;
66 friend class JSONSpewer;
67
68 // Work set of LiveIntervals, sorted by start() and then by priority,
69 // non-monotonically descending from tail to head.
70 class UnhandledQueue : public InlineList<LiveInterval>
71 {
72 public:
73 void enqueueForward(LiveInterval *after, LiveInterval *interval);
74 void enqueueBackward(LiveInterval *interval);
75
76 void assertSorted();
77
78 LiveInterval *dequeue();
79 };
80
81 typedef Vector<LiveInterval *, 0, SystemAllocPolicy> SlotList;
82 SlotList finishedSlots_;
83 SlotList finishedDoubleSlots_;
84 #ifdef JS_NUNBOX32
85 SlotList finishedNunboxSlots_;
86 #endif
87
88 // Run-time state
89 UnhandledQueue unhandled;
90 InlineList<LiveInterval> active;
91 InlineList<LiveInterval> inactive;
92 InlineList<LiveInterval> fixed;
93 InlineList<LiveInterval> handled;
94 LiveInterval *current;
95
96 bool allocateRegisters();
97 bool resolveControlFlow();
98 bool reifyAllocations();
99 bool populateSafepoints();
100
101 // Optimization for the UnsortedQueue.
102 void enqueueVirtualRegisterIntervals();
103
104 uint32_t allocateSlotFor(const LiveInterval *interval);
105 bool splitInterval(LiveInterval *interval, CodePosition pos);
106 bool splitBlockingIntervals(LAllocation allocation);
107 bool assign(LAllocation allocation);
108 bool spill();
109 void freeAllocation(LiveInterval *interval, LAllocation *alloc);
110 void finishInterval(LiveInterval *interval);
111 AnyRegister::Code findBestFreeRegister(CodePosition *freeUntil);
112 AnyRegister::Code findBestBlockedRegister(CodePosition *nextUsed);
113 bool canCoexist(LiveInterval *a, LiveInterval *b);
114 bool moveInputAlloc(CodePosition pos, LAllocation *from, LAllocation *to, LDefinition::Type type);
115 void setIntervalRequirement(LiveInterval *interval);
116 bool isSpilledAt(LiveInterval *interval, CodePosition pos);
117
118 #ifdef DEBUG
119 void validateIntervals();
120 void validateAllocations();
121 #else
122 inline void validateIntervals() { }
123 inline void validateAllocations() { }
124 #endif
125
126 public:
127 LinearScanAllocator(MIRGenerator *mir, LIRGenerator *lir, LIRGraph &graph)
128 : LiveRangeAllocator<LinearScanVirtualRegister, /* forLSRA = */ true>(mir, lir, graph)
129 {
130 }
131
132 bool go();
133 };
134
135 } // namespace jit
136 } // namespace js
137
138 #endif /* jit_LinearScan_h */

mercurial