From b5105c025cfacc1d7eaed9736c510c3b31eaee80 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Wed, 10 Nov 2021 15:45:43 -0800 Subject: [PATCH] MachInst: always rematerialize constants, rather than assign them registers There were a few previous code paths that attempted to handle this, but this new check handles it for all callers. Rematerializing constants, rather than assigning and reusing a register, allows for lower register pressure. --- cranelift/codegen/src/machinst/lower.rs | 32 ++++++++++-- .../filetests/filetests/isa/x64/i128.clif | 50 ++++++++++--------- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/cranelift/codegen/src/machinst/lower.rs b/cranelift/codegen/src/machinst/lower.rs index e6e608ec3d..8f65449cde 100644 --- a/cranelift/codegen/src/machinst/lower.rs +++ b/cranelift/codegen/src/machinst/lower.rs @@ -16,8 +16,9 @@ use crate::ir::{ ValueDef, ValueLabelAssignments, ValueLabelStart, }; use crate::machinst::{ - writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder, LoweredBlock, MachLabel, VCode, - VCodeBuilder, VCodeConstant, VCodeConstantData, VCodeConstants, VCodeInst, ValueRegs, + non_writable_value_regs, writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder, + LoweredBlock, MachLabel, VCode, VCodeBuilder, VCodeConstant, VCodeConstantData, VCodeConstants, + VCodeInst, ValueRegs, }; use crate::CodegenResult; use alloc::boxed::Box; @@ -1197,7 +1198,32 @@ impl<'func, I: VCodeInst> LowerCtx for Lower<'func, I> { fn put_value_in_regs(&mut self, val: Value) -> ValueRegs { let val = self.f.dfg.resolve_aliases(val); - log::trace!("put_value_in_reg: val {}", val); + log::trace!("put_value_in_regs: val {}", val); + + // If the value is a constant, then (re)materialize it at each use. This + // lowers register pressure. + if let Some(c) = self + .f + .dfg + .value_def(val) + .inst() + .and_then(|inst| self.get_constant(inst)) + { + let ty = self.f.dfg.value_type(val); + + let regs = self.alloc_tmp(ty); + log::trace!(" -> regs {:?}", regs); + assert!(regs.is_valid()); + + let insts = I::gen_constant(regs, c.into(), ty, |ty| { + self.alloc_tmp(ty).only_reg().unwrap() + }); + for inst in insts { + self.emit(inst); + } + return non_writable_value_regs(regs); + } + let mut regs = self.value_regs[val]; log::trace!(" -> regs {:?}", regs); assert!(regs.is_valid()); diff --git a/cranelift/filetests/filetests/isa/x64/i128.clif b/cranelift/filetests/filetests/isa/x64/i128.clif index 3bb3989d9d..fb49847e92 100644 --- a/cranelift/filetests/filetests/isa/x64/i128.clif +++ b/cranelift/filetests/filetests/isa/x64/i128.clif @@ -697,32 +697,34 @@ block2(v6: i128): return v8 ; check: Block 0: -; check: pushq %rbp -; nextln: movq %rsp, %rbp -; nextln: xorq %rdi, %rdi -; nextln: xorq %rsi, %rsi -; nextln: testb $$1, %dl -; nextln: jnz label1; j label2 +; check: pushq %rbp +; nextln: movq %rsp, %rbp +; nextln: testb $$1, %dl +; nextln: jnz label1; j label2 ; check: Block 1: -; check: movl $$1, %ecx -; nextln: xorq %rax, %rax -; nextln: addq %rcx, %rdi -; nextln: adcq %rax, %rsi -; nextln: movq %rdi, %rax -; nextln: movq %rsi, %rdx -; nextln: movq %rbp, %rsp -; nextln: popq %rbp -; nextln: ret +; check: movl $$0, %edi +; nextln: movl $$0, %esi +; nextln: movl $$1, %ecx +; nextln: movl $$0, %eax +; nextln: addq %rcx, %rdi +; nextln: adcq %rax, %rsi +; nextln: movq %rdi, %rax +; nextln: movq %rsi, %rdx +; nextln: movq %rbp, %rsp +; nextln: popq %rbp +; nextln: ret ; check: Block 2: -; check: movl $$2, %ecx -; nextln: xorq %rax, %rax -; nextln: addq %rcx, %rdi -; nextln: adcq %rax, %rsi -; nextln: movq %rdi, %rax -; nextln: movq %rsi, %rdx -; nextln: movq %rbp, %rsp -; nextln: popq %rbp -; nextln: ret +; check: movl $$0, %edi +; nextln: movl $$0, %esi +; nextln: movl $$2, %ecx +; nextln: movl $$0, %eax +; nextln: addq %rcx, %rdi +; nextln: adcq %rax, %rsi +; nextln: movq %rdi, %rax +; nextln: movq %rsi, %rdx +; nextln: movq %rbp, %rsp +; nextln: popq %rbp +; nextln: ret }