Avoid reusing a register during constant loading (#5379)

Avoid reusing a register when loading a constant, allocating a temporary instead.
This commit is contained in:
Trevor Elliott
2022-12-05 18:37:53 -08:00
committed by GitHub
parent 4933762d81
commit 353a681671
3 changed files with 46 additions and 41 deletions

View File

@@ -53,11 +53,16 @@ impl LoadConstant {
} }
} }
pub(crate) fn load_constant(self, rd: Writable<Reg>) -> SmallInstVec<Inst> { pub(crate) fn load_constant<F: FnMut(Type) -> Writable<Reg>>(
self,
rd: Writable<Reg>,
alloc_tmp: &mut F,
) -> SmallInstVec<Inst> {
let mut insts = SmallInstVec::new(); let mut insts = SmallInstVec::new();
// get current pc. // get current pc.
let pc = alloc_tmp(I64);
insts.push(Inst::Auipc { insts.push(Inst::Auipc {
rd, rd: pc,
imm: Imm20 { bits: 0 }, imm: Imm20 { bits: 0 },
}); });
// load // load
@@ -65,7 +70,7 @@ impl LoadConstant {
rd, rd,
op: self.load_op(), op: self.load_op(),
flags: MemFlags::new(), flags: MemFlags::new(),
from: AMode::RegOffset(rd.to_reg(), 12, self.load_ty()), from: AMode::RegOffset(pc.to_reg(), 12, self.load_ty()),
}); });
let data = self.to_le_bytes(); let data = self.to_le_bytes();
// jump over. // jump over.
@@ -78,10 +83,10 @@ impl LoadConstant {
// load and perform an extra add. // load and perform an extra add.
pub(crate) fn load_constant_and_add(self, rd: Writable<Reg>, rs: Reg) -> SmallInstVec<Inst> { pub(crate) fn load_constant_and_add(self, rd: Writable<Reg>, rs: Reg) -> SmallInstVec<Inst> {
let mut insts = self.load_constant(rd); let mut insts = self.load_constant(rd, &mut |_| rd);
insts.push(Inst::AluRRR { insts.push(Inst::AluRRR {
alu_op: AluOPRRR::Add, alu_op: AluOPRRR::Add,
rd: rd, rd,
rs1: rd.to_reg(), rs1: rd.to_reg(),
rs2: rs, rs2: rs,
}); });

View File

@@ -235,7 +235,7 @@ impl Inst {
alloc_tmp: &mut F, alloc_tmp: &mut F,
) -> SmallInstVec<Inst> { ) -> SmallInstVec<Inst> {
let insts = Inst::load_const_imm(rd, value, alloc_tmp); let insts = Inst::load_const_imm(rd, value, alloc_tmp);
insts.unwrap_or(LoadConstant::U32(value as u32).load_constant(rd)) insts.unwrap_or(LoadConstant::U32(value as u32).load_constant(rd, alloc_tmp))
} }
pub fn load_constant_u64<F: FnMut(Type) -> Writable<Reg>>( pub fn load_constant_u64<F: FnMut(Type) -> Writable<Reg>>(
@@ -244,7 +244,7 @@ impl Inst {
alloc_tmp: &mut F, alloc_tmp: &mut F,
) -> SmallInstVec<Inst> { ) -> SmallInstVec<Inst> {
let insts = Inst::load_const_imm(rd, value, alloc_tmp); let insts = Inst::load_const_imm(rd, value, alloc_tmp);
insts.unwrap_or(LoadConstant::U64(value).load_constant(rd)) insts.unwrap_or(LoadConstant::U64(value).load_constant(rd, alloc_tmp))
} }
pub(crate) fn construct_auipc_and_jalr( pub(crate) fn construct_auipc_and_jalr(

View File

@@ -50,8 +50,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffff0000 ; .8byte 0xffff0000
; ret ; ret
@@ -63,8 +63,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffff00000000 ; .8byte 0xffff00000000
; ret ; ret
@@ -76,8 +76,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffff000000000000 ; .8byte 0xffff000000000000
; ret ; ret
@@ -109,8 +109,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffffffff0000ffff ; .8byte 0xffffffff0000ffff
; ret ; ret
@@ -122,8 +122,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffff0000ffffffff ; .8byte 0xffff0000ffffffff
; ret ; ret
@@ -135,8 +135,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xffffffffffff ; .8byte 0xffffffffffff
; ret ; ret
@@ -148,8 +148,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xf34bf0a31212003a ; .8byte 0xf34bf0a31212003a
; ret ; ret
@@ -161,8 +161,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0x12e900001ef40000 ; .8byte 0x12e900001ef40000
; ret ; ret
@@ -174,8 +174,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0x12e9ffff1ef4ffff ; .8byte 0x12e9ffff1ef4ffff
; ret ; ret
@@ -197,8 +197,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xfffffff7 ; .8byte 0xfffffff7
; ret ; ret
@@ -210,8 +210,8 @@ block0:
} }
; block0: ; block0:
; auipc a0,0 ; auipc t1,0
; ld a0,12(a0) ; ld a0,12(t1)
; j 12 ; j 12
; .8byte 0xfffffff7 ; .8byte 0xfffffff7
; ret ; ret
@@ -233,11 +233,11 @@ block0:
} }
; block0: ; block0:
; auipc t1,0 ; auipc t2,0
; ld t1,12(t1) ; ld t2,12(t2)
; j 12 ; j 12
; .8byte 0x3ff0000000000000 ; .8byte 0x3ff0000000000000
; fmv.d.x fa0,t1 ; fmv.d.x fa0,t2
; ret ; ret
function %f() -> f32 { function %f() -> f32 {
@@ -258,11 +258,11 @@ block0:
} }
; block0: ; block0:
; auipc t1,0 ; auipc t2,0
; ld t1,12(t1) ; ld t2,12(t2)
; j 12 ; j 12
; .8byte 0x4049000000000000 ; .8byte 0x4049000000000000
; fmv.d.x fa0,t1 ; fmv.d.x fa0,t2
; ret ; ret
function %f() -> f32 { function %f() -> f32 {
@@ -305,11 +305,11 @@ block0:
} }
; block0: ; block0:
; auipc t1,0 ; auipc t2,0
; ld t1,12(t1) ; ld t2,12(t2)
; j 12 ; j 12
; .8byte 0xc030000000000000 ; .8byte 0xc030000000000000
; fmv.d.x fa0,t1 ; fmv.d.x fa0,t2
; ret ; ret
function %f() -> f32 { function %f() -> f32 {
@@ -319,10 +319,10 @@ block0:
} }
; block0: ; block0:
; auipc t1,0 ; auipc t2,0
; lwu t1,12(t1) ; lwu t2,12(t2)
; j 8 ; j 8
; .4byte 0xc1800000 ; .4byte 0xc1800000
; fmv.w.x fa0,t1 ; fmv.w.x fa0,t2
; ret ; ret