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,
|
ValueDef, ValueLabelAssignments, ValueLabelStart,
|
||||||
};
|
};
|
||||||
use crate::machinst::{
|
use crate::machinst::{
|
||||||
writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder, LoweredBlock, MachLabel, VCode,
|
non_writable_value_regs, writable_value_regs, ABICallee, BlockIndex, BlockLoweringOrder,
|
||||||
VCodeBuilder, VCodeConstant, VCodeConstantData, VCodeConstants, VCodeInst, ValueRegs,
|
LoweredBlock, MachLabel, VCode, VCodeBuilder, VCodeConstant, VCodeConstantData, VCodeConstants,
|
||||||
|
VCodeInst, ValueRegs,
|
||||||
};
|
};
|
||||||
use crate::CodegenResult;
|
use crate::CodegenResult;
|
||||||
use alloc::boxed::Box;
|
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> {
|
fn put_value_in_regs(&mut self, val: Value) -> ValueRegs<Reg> {
|
||||||
let val = self.f.dfg.resolve_aliases(val);
|
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];
|
let mut regs = self.value_regs[val];
|
||||||
log::trace!(" -> regs {:?}", regs);
|
log::trace!(" -> regs {:?}", regs);
|
||||||
assert!(regs.is_valid());
|
assert!(regs.is_valid());
|
||||||
|
|||||||
@@ -697,32 +697,34 @@ block2(v6: i128):
|
|||||||
return v8
|
return v8
|
||||||
|
|
||||||
; check: Block 0:
|
; check: Block 0:
|
||||||
; check: pushq %rbp
|
; check: pushq %rbp
|
||||||
; nextln: movq %rsp, %rbp
|
; nextln: movq %rsp, %rbp
|
||||||
; nextln: xorq %rdi, %rdi
|
; nextln: testb $$1, %dl
|
||||||
; nextln: xorq %rsi, %rsi
|
; nextln: jnz label1; j label2
|
||||||
; nextln: testb $$1, %dl
|
|
||||||
; nextln: jnz label1; j label2
|
|
||||||
; check: Block 1:
|
; check: Block 1:
|
||||||
; check: movl $$1, %ecx
|
; check: movl $$0, %edi
|
||||||
; nextln: xorq %rax, %rax
|
; nextln: movl $$0, %esi
|
||||||
; nextln: addq %rcx, %rdi
|
; nextln: movl $$1, %ecx
|
||||||
; nextln: adcq %rax, %rsi
|
; nextln: movl $$0, %eax
|
||||||
; nextln: movq %rdi, %rax
|
; nextln: addq %rcx, %rdi
|
||||||
; nextln: movq %rsi, %rdx
|
; nextln: adcq %rax, %rsi
|
||||||
; nextln: movq %rbp, %rsp
|
; nextln: movq %rdi, %rax
|
||||||
; nextln: popq %rbp
|
; nextln: movq %rsi, %rdx
|
||||||
; nextln: ret
|
; nextln: movq %rbp, %rsp
|
||||||
|
; nextln: popq %rbp
|
||||||
|
; nextln: ret
|
||||||
; check: Block 2:
|
; check: Block 2:
|
||||||
; check: movl $$2, %ecx
|
; check: movl $$0, %edi
|
||||||
; nextln: xorq %rax, %rax
|
; nextln: movl $$0, %esi
|
||||||
; nextln: addq %rcx, %rdi
|
; nextln: movl $$2, %ecx
|
||||||
; nextln: adcq %rax, %rsi
|
; nextln: movl $$0, %eax
|
||||||
; nextln: movq %rdi, %rax
|
; nextln: addq %rcx, %rdi
|
||||||
; nextln: movq %rsi, %rdx
|
; nextln: adcq %rax, %rsi
|
||||||
; nextln: movq %rbp, %rsp
|
; nextln: movq %rdi, %rax
|
||||||
; nextln: popq %rbp
|
; nextln: movq %rsi, %rdx
|
||||||
; nextln: ret
|
; nextln: movq %rbp, %rsp
|
||||||
|
; nextln: popq %rbp
|
||||||
|
; nextln: ret
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user