Handle tied operands that are not killed by their use.

Any tied register uses are interesting enough to be added to the reguses
list if their value is not killed.

A copy needs to be inserted in that case.
This commit is contained in:
Jakob Stoklund Olesen
2017-07-05 14:23:58 -07:00
parent 64f6a98abe
commit f0abff3611
2 changed files with 32 additions and 1 deletions

View File

@@ -15,6 +15,19 @@ ebb0:
return v2 return v2
} }
; Tied operand is live after instruction.
function %tied_alive() -> i32 {
ebb0:
v0 = iconst.i32 12
v1 = iconst.i32 13
; check: $(v0c=$V) = copy $v0
; check: $v2 = isub $v0c, $v1
v2 = isub v0, v1
; check: $v3 = iadd $v2, $v0
v3 = iadd v2, v0
return v3
}
; Fixed register constraint. ; Fixed register constraint.
function %fixed_op() -> i32 { function %fixed_op() -> i32 {
ebb0: ebb0:

View File

@@ -26,6 +26,7 @@ use regalloc::live_value_tracker::{LiveValue, LiveValueTracker};
use regalloc::liveness::Liveness; use regalloc::liveness::Liveness;
use regalloc::pressure::Pressure; use regalloc::pressure::Pressure;
use regalloc::virtregs::VirtRegs; use regalloc::virtregs::VirtRegs;
use std::fmt;
use topo_order::TopoOrder; use topo_order::TopoOrder;
/// Persistent data structures for the spilling pass. /// Persistent data structures for the spilling pass.
@@ -338,7 +339,8 @@ impl<'a> Context<'a> {
} }
// Only collect the interesting register uses. // Only collect the interesting register uses.
if reguse.fixed || reguse.spilled { if reguse.fixed || reguse.tied || reguse.spilled {
dbg!(" reguse: {}", reguse);
self.reg_uses.push(reguse); self.reg_uses.push(reguse);
} }
} }
@@ -578,3 +580,19 @@ impl RegUse {
} }
} }
} }
impl fmt::Display for RegUse {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}@op{}", self.value, self.opidx)?;
if self.fixed {
write!(f, "/fixed")?;
}
if self.spilled {
write!(f, "/spilled")?;
}
if self.tied {
write!(f, "/tied")?;
}
Ok(())
}
}