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.
This commit is contained in:
@@ -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<Reg> {
|
||||
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());
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user