Add fixed_nonallocatable constraints when appropriate (#5253)

Plumb the set of allocatable registers through the OperandCollector and use it validate uses of fixed-nonallocatable registers, like %rsp on x86_64.
This commit is contained in:
Trevor Elliott
2022-11-15 12:49:17 -08:00
committed by GitHub
parent f6ae67f3f0
commit a007e02bd2
13 changed files with 133 additions and 66 deletions

View File

@@ -1369,6 +1369,7 @@ impl MachInstEmit for Inst {
}
&Inst::MovFromPReg { rd, rm } => {
let rd = allocs.next_writable(rd);
allocs.next_fixed_nonallocatable(rm);
let rm: Reg = rm.into();
debug_assert!([
regs::fp_reg(),
@@ -1383,6 +1384,7 @@ impl MachInstEmit for Inst {
Inst::Mov { size, rd, rm }.emit(&[], sink, emit_info, state);
}
&Inst::MovToPReg { rd, rm } => {
allocs.next_fixed_nonallocatable(rd);
let rd: Writable<Reg> = Writable::from_reg(rd.into());
let rm = allocs.next(rm);
debug_assert!([

View File

@@ -655,25 +655,13 @@ fn aarch64_get_operands<F: Fn(VReg) -> VReg>(inst: &Inst, collector: &mut Operan
collector.reg_use(rm);
}
&Inst::MovFromPReg { rd, rm } => {
debug_assert!([
regs::fp_reg(),
regs::stack_reg(),
regs::link_reg(),
regs::pinned_reg()
]
.contains(&rm.into()));
debug_assert!(rd.to_reg().is_virtual());
collector.reg_def(rd);
collector.reg_fixed_nonallocatable(rm);
}
&Inst::MovToPReg { rd, rm } => {
debug_assert!([
regs::fp_reg(),
regs::stack_reg(),
regs::link_reg(),
regs::pinned_reg()
]
.contains(&rd.into()));
debug_assert!(rm.is_virtual());
collector.reg_fixed_nonallocatable(rd);
collector.reg_use(rm);
}
&Inst::MovK { rd, rn, .. } => {
@@ -1568,10 +1556,12 @@ impl Inst {
}
&Inst::MovFromPReg { rd, rm } => {
let rd = pretty_print_ireg(rd.to_reg(), OperandSize::Size64, allocs);
allocs.next_fixed_nonallocatable(rm);
let rm = show_ireg_sized(rm.into(), OperandSize::Size64);
format!("mov {}, {}", rd, rm)
}
&Inst::MovToPReg { rd, rm } => {
allocs.next_fixed_nonallocatable(rd);
let rd = show_ireg_sized(rd.into(), OperandSize::Size64);
let rm = pretty_print_ireg(rm, OperandSize::Size64, allocs);
format!("mov {}, {}", rd, rm)

View File

@@ -57,20 +57,11 @@ impl AArch64Backend {
fn compile_vcode(
&self,
func: &Function,
flags: shared_settings::Flags,
) -> CodegenResult<(VCode<inst::Inst>, regalloc2::Output)> {
let emit_info = EmitInfo::new(flags.clone());
let emit_info = EmitInfo::new(self.flags.clone());
let sigs = SigSet::new::<abi::AArch64MachineDeps>(func, &self.flags)?;
let abi = abi::AArch64Callee::new(func, self, &self.isa_flags, &sigs)?;
compile::compile::<AArch64Backend>(
func,
flags,
self,
abi,
&self.machine_env,
emit_info,
sigs,
)
compile::compile::<AArch64Backend>(func, self, abi, emit_info, sigs)
}
}
@@ -80,10 +71,13 @@ impl TargetIsa for AArch64Backend {
func: &Function,
want_disasm: bool,
) -> CodegenResult<CompiledCodeStencil> {
let flags = self.flags();
let (vcode, regalloc_result) = self.compile_vcode(func, flags.clone())?;
let (vcode, regalloc_result) = self.compile_vcode(func)?;
let emit_result = vcode.emit(&regalloc_result, want_disasm, flags.machine_code_cfg_info());
let emit_result = vcode.emit(
&regalloc_result,
want_disasm,
self.flags.machine_code_cfg_info(),
);
let frame_size = emit_result.frame_size;
let value_labels_ranges = emit_result.value_labels_ranges;
let buffer = emit_result.buffer.finish();
@@ -119,6 +113,10 @@ impl TargetIsa for AArch64Backend {
&self.flags
}
fn machine_env(&self) -> &MachineEnv {
&self.machine_env
}
fn isa_flags(&self) -> Vec<shared_settings::Value> {
self.isa_flags.iter().collect()
}