@@ -42,21 +42,14 @@ During allocation, it's necessary to determine which VReg is in a PReg
4242to generate the right move(s) for eviction.
4343` vreg_in_preg ` is a vector that stores this information.
4444
45- ## Available PRegs For Use In Instruction (` available_pregs_for_regs ` , ` available_pregs_for_any ` )
45+ ## Available PRegs For Use In Instruction (` available_pregs ` )
4646
47- These are a 2-tuples of ` PRegSet ` s, a bitset of physical registers, one for
48- the instruction's early phase and one for the late phase.
49- They are used to determine which registers are available for use in the
50- early/late phases of an instruction.
47+ This is a 2-tuple of PRegSets, a bitset of physical registers, one for the
48+ instruction's early phase and one for the late phase. They are used to determine
49+ which registers are available for use in the early/late phases of an instruction.
5150
52- Prior to the beginning of any instruction's allocation, ` available_pregs_for_regs `
53- is reset to include all allocatable physical registers, some of which may already
54- contain a VReg.
55-
56- The two sets have the same function, except that ` available_pregs_for_regs ` is
57- used to determine which registers are available for operands with a register-only
58- constraint while ` available_pregs_for_any ` is used to determine which registers
59- are available for operands with no constraints.
51+ Prior to the beginning of any instruction's allocation, this set is reset to
52+ include all allocatable physical registers, some of which may already contain a VReg.
6053
6154## VReg Liverange Location Info (` vreg_to_live_inst_range ` )
6255
@@ -66,6 +59,35 @@ to be in throughout that liverange.
6659This is used to build the debug locations vector after allocation
6760is complete.
6861
62+ ## Number of Available Registers (` num_available_registers ` )
63+
64+ These are counters that keep track of the number of registers that
65+ can be allocated to any-reg and anywhere operands for int, float and
66+ vector registers, in the late, early and both phases of an instruction.
67+
68+ Prior to the beginning of any instruction, this set is reset to
69+ include the number of all allocatable physical registers.
70+
71+ ## Number of Any-Reg Operands (` num_any_reg_operands ` )
72+
73+ These are counters that keep track of the number of any-reg
74+ operands that are yet to be allocated in an instruction.
75+
76+ It is closely associated with ` num_available_registers ` and
77+ are used together for the same purpose.
78+ The two counters are used together to avoid allocating too many
79+ registers to anywhere operands when any-reg operands need them.
80+ When register reservations are made, the corresponding number
81+ of available registers in ` num_available_registers ` are decremented.
82+ When an any-reg operand is allocated, the corresponding
83+ ` num_any_reg_operands ` is decremented.
84+ The sole purpose of this is so that when anywhere operands are
85+ allocated, a check can be made to see if the available registers
86+ ` num_available_registers ` are enough to cover the remaining
87+ any-reg operands in the instruction ` num_any_reg_operands ` ,
88+ to determine whether or not it is safe to allocate a register to
89+ the operand instead of a spillslot.
90+
6991# Allocation Process Breakdown
7092
7193Allocation proceeds in reverse: from the last block to the first block,
@@ -76,11 +98,11 @@ in four phases: selection, assignment, eviction, and edit insertion.
7698
7799## Allocation Phase: Selection
78100
79- In this phase, a PReg is selected from ` available_pregs_for_regs ` or
80- ` available_pregs_for_any ` for the operand based on the operand constraints.
81- Depending on the operand's position, the selected PReg is removed from either
82- the early or late phase or both, indicating that the PReg is no longer available
83- for allocation by other operands in that phase.
101+ In this phase, a PReg is selected from available_pregs for the operand
102+ based on the operand constraints. Depending on the operand's position
103+ the selected PReg is removed from either the early or late phase or both,
104+ indicating that the PReg is no longer available for allocation by other
105+ operands in that phase.
84106
85107## Allocation Phase: Assignment
86108
@@ -128,118 +150,112 @@ arguments will be in their dedicated spillslots.
1281504 . At the beginning of a block, all branch parameters and livein
129151virtual registers will be in their dedicated spillslots.
130152
131- There is an exception to invariant 3: if a branch instruction defines
153+ There is an exception to invariant 2 and 3: if a branch instruction defines
132154the VReg used as a branch arg, then there may be no opportunity for
133155the VReg to be placed in its spillslot.
134156
135157# Instruction Allocation
136158
137- To allocate a single instruction, the first step is to reset the
138- ` available_pregs_for_regs ` sets to all allocatable PRegs.
139-
140- Next, the selection phase is carried out for all operands with
141- fixed register constraints: the registers they are constrained to use are
142- marked as unavailable in the ` available_pregs_for_regs ` set, depending on the
143- phase that they are valid in. If the operand is an early use or late
144- def operand, then the register will be marked as unavailable in the
145- early set or late set, respectively. Otherwise, the PReg is marked
146- as unavailable in both the early and late sets, because a PReg
147- assigned to an early def or late use operand cannot be reused by another
148- operand in the same instruction.
149-
150- Next, all clobbers are removed from the early and late ` available_pregs_for_regs `
151- sets to avoid allocating a clobber to a def.
152-
153- Next, registers are reserved for register-only operands and marked as
154- unavailable in ` available_pregs_for_regs ` .
155- Then ` available_pregs_for_any ` for the instruction is derived from
156- ` available_pregs_for_regs ` by marking all other registers not reserved as
157- available. This is to avoid a situation where operands with no
158- constraints take up all available registers, leaving none for operands
159- with register-only constraints.
160-
161- After selection for register-only operands, the eviction phase is
162- carried out for fixed register operands. Any VReg in their selected
163- registers, indicated by ` vreg_in_preg ` , is evicted: a dedicated
164- spillslot is allocated for the VReg (if it doesn't have one already),
165- an edit is inserted to move from the slot to the PReg, which is where
166- the VReg expected to be after the instruction, and its current
167- allocation in ` vreg_allocs ` is set to the spillslot.
168- The same is then done for clobbers, then register-only operands.
169-
170- Next, the selection, assignment, eviction, and edit insertion phases are
171- carried out for all def operands. When each def operand's allocation is
172- complete, the def operand is immediately freed, marking the end of the
173- VReg's liverange. It is removed from the ` live_vregs ` set, its allocation
174- in ` vreg_allocs ` is set to none, and if it was in a PReg, that PReg's
175- entry in ` vreg_in_preg ` is set to none. The selection and eviction phases
176- are omitted if the operand has a fixed constraint, as those phases have
177- already been carried out.
178-
179- Next, the selection, assignment, and eviction phases are carried out for all
180- use operands. As with def operands, the selection and eviction phases are
181- omitted if the operand has a fixed constraint, as those phases have already
182- been carried out.
183-
184- Then the edit insertion phase is carried out for all use operands.
185-
186- Lastly, if the instruction being processed is a branch instruction, the
187- parallel move resolver is used to insert edits before the instruction
188- to move from the branch arguments spillslots to the block parameter
189- spillslots.
159+ To allocate a single instruction, the first step is to reset the
160+ ` available_pregs ` sets to all allocatable PRegs.
161+
162+ Next, the selection phase is carried out for all operands with
163+ fixed register constraints: the registers they are constrained
164+ to use are marked as unavailable in the ` available_pregs ` set,
165+ depending on the phase that they are valid in. If the operand
166+ is an early use or late def operand, then the register will be
167+ marked as unavailable in the early set or late set, respectively.
168+ Otherwise, the PReg is marked as unavailable in both the early
169+ and late sets, because a PReg assigned to an early def or late
170+ use operand cannot be reused by another operand in the same instruction.
171+
172+ After selection for fixed register operands, the eviction phase
173+ is carried out for fixed register operands. Any VReg in their
174+ selected registers, indicated by vreg_in_preg, is evicted: a
175+ dedicated spillslot is allocated for the VReg (if it doesn't
176+ have one already), an edit is inserted to move from the slot to
177+ the PReg, which is where the VReg expected to be after the instruction,
178+ and its current allocation in vreg_allocs is set to the spillslot.
179+
180+ Next, all clobbers are removed from the late ` available_pregs ` set
181+ to avoid allocating a clobber to a late operand.
182+
183+ Next, the selection, assignment, eviction, and edit insertion
184+ phases are carried out for all late operands, both defs and uses.
185+ Then the early operands are processed in the same manner, after the
186+ late operands.
187+
188+ In both late and early processing, when a def operand's
189+ allocation is complete, the def operand is immediately freed,
190+ marking the end of the VReg's liverange. It is removed from the
191+ ` live_vregs ` set, its allocation in ` vreg_allocs ` is set to none,
192+ and if it was in a PReg, that PReg's entry in ` vreg_in_preg ` is
193+ set to none. The selection and eviction phases are omitted if the
194+ operand has a fixed constraint, as those phases have already been
195+ carried out.
196+
197+ When a use operand is processed, the selection, assignment, and eviction
198+ phases only are carried out. As with def operands, the selection and
199+ eviction phases are omitted if the operand has a fixed constraint, as
200+ those phases have already been carried out.
201+
202+ After the late and early operands have completed processing,
203+ the edit insertion phase is carried out for all use operands.
204+
205+ Lastly, if the instruction being processed is a branch instruction,
206+ the parallel move resolver is used to insert edits before the instruction
207+ to move from the branch arguments spillslots to the block parameter spillslots.
190208
191209## Operand Allocation
192210
193211During the allocation of an operand, a check is first made to
194212see if the VReg's current allocation as indicated in
195213` vreg_allocs ` is within the operand constraints.
196214
197- If it is, the assignment phase is carried out, setting the final
198- allocation output's entry for that operand to the allocation.
199- The selection phase is carried out, marking the PReg
200- (if the allocation is a PReg) as unavailable in the respective
201- early/late sets. The state of the LRUs is also updated to reflect
202- the new most recently used PReg.
203- No eviction needs to be done since the VReg is already in the
204- allocation and no edit insertion needs to be done either.
205-
206- On the other hand, if the VReg's current allocation is not within
207- constraints, the selection and eviction phases are carried out for
208- non-fixed operands. First, a set of PRegs that can be drawn from is
209- created from ` available_pregs_for_regs ` or ` available_pregs_for_any ` ,
210- depending on whether the operand has a register-only constraint
211- or no constraint. For early uses and late defs,
212- this draw-from set is the early set or late set, respectively.
213- For late uses and early defs, the draw-from set is an intersection
214- of the available early and late sets (because a PReg used for a late
215- use can't be reassigned to another operand in the early phase;
216- likewise, a PReg used for an early def can't be reassigned to another
217- operand in the late phase).
218- The LRU for the VReg's regclass is then traversed from the end to find
219- the least recently used PReg in the draw-from set. Once a PReg is found,
220- it is marked as the most recently used in the LRU, unavailable in both
221- available pregs sets, and whatever VReg was in it before is evicted.
222-
223- The assignment phase is carried out next. The final allocation for the
215+ If it is, the assignment phase is carried out, setting the
216+ final allocation output's entry for that operand to the allocation.
217+ The selection phase is carried out, marking the PReg (if the
218+ allocation is a PReg) as unavailable in the respective early/late
219+ sets. The state of the LRUs is also updated to reflect the new
220+ most recently used PReg. No eviction needs to be done since the
221+ VReg is already in the allocation and no edit insertion needs to
222+ be done either.
223+
224+ On the other hand, if the VReg's current allocation is not within
225+ constraints, the selection and eviction phases are carried out
226+ for non-fixed operands. First, a set of PRegs that can be drawn
227+ from is created from ` available_pregs ` . For early uses and late
228+ defs, this draw-from set is the early set or late set, respectively.
229+ For late uses and early defs, the draw-from set is an intersection
230+ of the available early and late sets (because a PReg used for a
231+ late use can't be reassigned to another operand in the early phase;
232+ likewise, a PReg used for an early def can't be reassigned to another
233+ operand in the late phase). The LRU for the VReg's regclass is then
234+ traversed from the end to find the least recently used PReg in the
235+ draw-from set. Once a PReg is found, it is marked as the most recently
236+ used in the LRU, unavailable in the ` available_pregs ` sets, and whatever
237+ VReg was in it before is evicted.
238+
239+ The assignment phase is carried out next. The final allocation for the
224240operand is set to the selected register.
225241
226- If the newly allocated operand has not been allocated before, that is,
227- this is the first use/def of the VReg encountered; the VReg is
228- inserted into ` live_vregs ` and marked as the value in the allocated
229- PReg in ` vreg_in_preg ` .
230-
231- Otherwise, if the VReg has been allocated before, then an edit will need
232- to be inserted to ensure that the dataflow remains correct.
233- The edit insertion phase is now carried out if the operand is a def
234- operand: an edit is inserted after the instruction to move from the
235- new allocation to the allocation it's expected to be in after the
236- instruction.
237-
238- The edit insertion phase for use operands is done after all operands
239- have been processed. Edits are inserted to move from the current
240- allocations in ` vreg_allocs ` to the final allocated position before
241- the instruction. This is to account for the possibility of multiple
242- uses of the same operand in the instruction.
242+ If the newly allocated operand has not been allocated before,
243+ that is, this is the first use/def of the VReg encountered;
244+ the VReg is inserted into live_vregs and marked as the value
245+ in the allocated PReg in vreg_in_preg.
246+
247+ Otherwise, if the VReg has been allocated before, then an edit
248+ will need to be inserted to ensure that the dataflow remains correct.
249+ The edit insertion phase is now carried out if the operand is a
250+ def operand: an edit is inserted after the instruction to move
251+ from the new allocation to the allocation it's expected to be
252+ in after the instruction.
253+
254+ The edit insertion phase for use operands is done after all
255+ operands have been processed. Edits are inserted to move from
256+ the current allocations in ` vreg_allocs ` to the final allocated
257+ position before the instruction. This is to account for the
258+ possibility of multiple uses of the same operand in the instruction.
243259
244260## Reuse Operands
245261
0 commit comments