From 093865cc12334ed3f2db42e3c7b19b1d7ef4559a Mon Sep 17 00:00:00 2001 From: Lulu Cheng Date: Sun, 9 Oct 2022 17:54:38 +0800 Subject: [PATCH] LoongArch: Optimize immediate load. Optimize the link of https://sourceware.org/pipermail/libc-alpha/2022-September/142202.html said in a number of repeated loading immediately. gcc/ChangeLog: * config/loongarch/loongarch.cc (struct loongarch_integer_op): Add the member curr_value to the structure to represent the result of the immediate count of the load instruction at each step. (loongarch_build_integer): Assign a value to the member curr_value. (loongarch_move_integer): Optimize immediate load. --- gcc/config/loongarch/loongarch.cc | 57 ++++++++++++++++++------------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 70918d41860..38d822bcd49 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -154,7 +154,11 @@ enum loongarch_load_imm_method struct loongarch_integer_op { enum rtx_code code; + /* Current Immediate Count The immediate count of the load instruction. */ HOST_WIDE_INT value; + /* Represent the result of the immediate count of the load instruction at + each step. */ + HOST_WIDE_INT curr_value; enum loongarch_load_imm_method method; }; @@ -1523,24 +1527,27 @@ loongarch_build_integer (struct loongarch_integer_op *codes, { /* The value of the lower 32 bit be loaded with one instruction. lu12i.w. */ - codes[0].code = UNKNOWN; - codes[0].method = METHOD_NORMAL; - codes[0].value = low_part; + codes[cost].code = UNKNOWN; + codes[cost].method = METHOD_NORMAL; + codes[cost].value = low_part; + codes[cost].curr_value = low_part; cost++; } else { /* lu12i.w + ior. */ - codes[0].code = UNKNOWN; - codes[0].method = METHOD_NORMAL; - codes[0].value = low_part & ~(IMM_REACH - 1); + codes[cost].code = UNKNOWN; + codes[cost].method = METHOD_NORMAL; + codes[cost].value = low_part & ~(IMM_REACH - 1); + codes[cost].curr_value = codes[cost].value; cost++; HOST_WIDE_INT iorv = low_part & (IMM_REACH - 1); if (iorv != 0) { - codes[1].code = IOR; - codes[1].method = METHOD_NORMAL; - codes[1].value = iorv; + codes[cost].code = IOR; + codes[cost].method = METHOD_NORMAL; + codes[cost].value = iorv; + codes[cost].curr_value = low_part; cost++; } } @@ -1563,11 +1570,15 @@ loongarch_build_integer (struct loongarch_integer_op *codes, { codes[cost].method = METHOD_LU52I; codes[cost].value = value & LU52I_B; + codes[cost].curr_value = codes[cost].value | (codes[cost-1].curr_value & + 0xfffffffffffff); return cost + 1; } codes[cost].method = METHOD_LU32I; codes[cost].value = (value & LU32I_B) | (sign51 ? LU52I_B : 0); + codes[cost].curr_value = codes[cost].value | (codes[cost-1].curr_value & + 0xffffffff); cost++; /* Determine whether the 52-61 bits are sign-extended from the low order, @@ -1576,6 +1587,8 @@ loongarch_build_integer (struct loongarch_integer_op *codes, { codes[cost].method = METHOD_LU52I; codes[cost].value = value & LU52I_B; + codes[cost].curr_value = codes[cost].value | (codes[cost-1].curr_value & + 0xfffffffffffff); cost++; } } @@ -2959,29 +2972,27 @@ loongarch_move_integer (rtx temp, rtx dest, unsigned HOST_WIDE_INT value) else x = force_reg (mode, x); + set_unique_reg_note (get_last_insn (), REG_EQUAL, GEN_INT (codes[i-1].curr_value)); + switch (codes[i].method) { case METHOD_NORMAL: + /* mov or ior. */ x = gen_rtx_fmt_ee (codes[i].code, mode, x, GEN_INT (codes[i].value)); break; case METHOD_LU32I: - emit_insn ( - gen_rtx_SET (x, - gen_rtx_IOR (DImode, - gen_rtx_ZERO_EXTEND ( - DImode, gen_rtx_SUBREG (SImode, x, 0)), - GEN_INT (codes[i].value)))); + gcc_assert (mode == DImode); + /* lu32i_d */ + x = gen_rtx_IOR (mode, gen_rtx_ZERO_EXTEND (mode, + gen_rtx_SUBREG (SImode, x, 0)), + GEN_INT (codes[i].value)); break; case METHOD_LU52I: - emit_insn (gen_lu52i_d (x, x, GEN_INT (0xfffffffffffff), - GEN_INT (codes[i].value))); - break; - case METHOD_INSV: - emit_insn ( - gen_rtx_SET (gen_rtx_ZERO_EXTRACT (DImode, x, GEN_INT (20), - GEN_INT (32)), - gen_rtx_REG (DImode, 0))); + gcc_assert (mode == DImode); + /*lu52i_d*/ + x = gen_rtx_IOR (mode, gen_rtx_AND (mode, x, GEN_INT (0xfffffffffffff)), + GEN_INT (codes[i].value)); break; default: gcc_unreachable (); -- 2.31.1