Pinned-VReg mechanism.
This commit is contained in:
@@ -1718,6 +1718,13 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If either bundle is already assigned (due to a pinned vreg), don't merge.
|
||||||
|
if !self.bundles[from.index()].allocation.is_none()
|
||||||
|
|| !self.bundles[to.index()].allocation.is_none()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(debug)]
|
#[cfg(debug)]
|
||||||
{
|
{
|
||||||
// Sanity check: both bundles should contain only ranges with appropriate VReg classes.
|
// Sanity check: both bundles should contain only ranges with appropriate VReg classes.
|
||||||
@@ -1882,6 +1889,22 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
range = self.ranges[range.index()].next_in_reg;
|
range = self.ranges[range.index()].next_in_reg;
|
||||||
}
|
}
|
||||||
log::debug!("vreg v{} gets bundle{}", vreg.index(), bundle.index());
|
log::debug!("vreg v{} gets bundle{}", vreg.index(), bundle.index());
|
||||||
|
|
||||||
|
// If this vreg is pinned, assign the allocation and block the PRegs.
|
||||||
|
if let Some(preg) = self.func.is_pinned_vreg(self.vreg_regs[vreg.index()]) {
|
||||||
|
self.bundles[bundle.index()].allocation = Allocation::reg(preg);
|
||||||
|
|
||||||
|
let mut iter = self.bundles[bundle.index()].first_range;
|
||||||
|
while iter.is_valid() {
|
||||||
|
let range = self.ranges[iter.index()].range;
|
||||||
|
// Create a new LiveRange for the PReg
|
||||||
|
// reservation, unaffiliated with the VReg, to
|
||||||
|
// reserve it (like a clobber) without the
|
||||||
|
// possibility of eviction.
|
||||||
|
self.add_liverange_to_preg(range, preg);
|
||||||
|
iter = self.ranges[iter.index()].next_in_bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for inst in 0..self.func.insts() {
|
for inst in 0..self.func.insts() {
|
||||||
@@ -2006,6 +2029,11 @@ impl<'a, F: Function> Env<'a, F> {
|
|||||||
let mut lr = self.vregs[vreg.index()].first_range;
|
let mut lr = self.vregs[vreg.index()].first_range;
|
||||||
while lr.is_valid() {
|
while lr.is_valid() {
|
||||||
let bundle = self.ranges[lr.index()].bundle;
|
let bundle = self.ranges[lr.index()].bundle;
|
||||||
|
if !self.bundles[bundle.index()].allocation.is_none() {
|
||||||
|
// Pinned VReg -- already allocated, so skip.
|
||||||
|
lr = self.ranges[lr.index()].next_in_bundle;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if self.bundles[bundle.index()].first_range == lr {
|
if self.bundles[bundle.index()].first_range == lr {
|
||||||
// First time seeing `bundle`: allocate a spillslot for it,
|
// First time seeing `bundle`: allocate a spillslot for it,
|
||||||
// compute its priority, and enqueue it.
|
// compute its priority, and enqueue it.
|
||||||
|
|||||||
@@ -741,6 +741,15 @@ pub trait Function {
|
|||||||
&[]
|
&[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Is the given VReg pinned permanently to a PReg? Note that the
|
||||||
|
/// input program must not contain constraints that contradict
|
||||||
|
/// this (e.g., using another VReg with a fixed-reg policy to a
|
||||||
|
/// given preg at the same time as using a VReg pinned to that
|
||||||
|
/// preg) or else allocation may be impossible.
|
||||||
|
fn is_pinned_vreg(&self, _: VReg) -> Option<PReg> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
// --------------
|
// --------------
|
||||||
// Spills/reloads
|
// Spills/reloads
|
||||||
// --------------
|
// --------------
|
||||||
|
|||||||
Reference in New Issue
Block a user