diff options
author | Jeff Law <jlaw@ventanamicro.com> | 2024-07-22 08:45:10 -0600 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro.com> | 2024-07-22 08:45:10 -0600 |
commit | 88d16194d0c8a6bdc2896c8944bfbf3e6038c9d2 (patch) | |
tree | 29b0382cf8e2f3c997ec15c8231f0ce1ca0e48c3 /gcc | |
parent | a8e61cd71f0cda04d583722ca4c66301358b01e1 (diff) | |
download | gcc-88d16194d0c8a6bdc2896c8944bfbf3e6038c9d2.zip gcc-88d16194d0c8a6bdc2896c8944bfbf3e6038c9d2.tar.gz gcc-88d16194d0c8a6bdc2896c8944bfbf3e6038c9d2.tar.bz2 |
[NFC][PR rtl-optimization/115877] Avoid setting irrelevant bit groups as live in ext-dce
Another patch to refine liveness computations. This should be NFC and is
designed to help debugging.
In simplest terms the patch avoids setting bit groups outside the size of a
pseudo as live. Consider a HImode pseudo, bits 16..63 for such a pseudo don't
really have meaning, yet we often set bit groups related to bits 16.63 on in
the liveness bitmaps.
This makes debugging harder than it needs to be by simply having larger bitmaps
to verify when walking through the code in a debugger.
This has been bootstrapped and regression tested on x86_64. It's also been
tested on the crosses in my tester without regressions.
Pushing to the trunk,
PR rtl-optimization/115877
gcc/
* ext-dce.cc (group_limit): New function.
(mark_reg_live): Likewise.
(ext_dce_process_sets): Use new functions.
(ext_dce_process_uses): Likewise.
(ext_dce_init): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ext-dce.cc | 64 |
1 files changed, 57 insertions, 7 deletions
diff --git a/gcc/ext-dce.cc b/gcc/ext-dce.cc index cbecfc5..44f64e2 100644 --- a/gcc/ext-dce.cc +++ b/gcc/ext-dce.cc @@ -48,6 +48,57 @@ static bool modify; bit 16..31 bit 32..BITS_PER_WORD-1 */ +/* For the given REG, return the number of bit groups implied by the + size of the REG's mode, up to a maximum of 4 (number of bit groups + tracked by this pass). + + For partial integer and variable sized modes also return 4. This + could possibly be refined for something like PSI mode, but it + does not seem worth the effort. */ + +static int +group_limit (const_rtx reg) +{ + machine_mode mode = GET_MODE (reg); + + if (!GET_MODE_BITSIZE (mode).is_constant ()) + return 4; + + int size = GET_MODE_SIZE (mode).to_constant (); + + size = exact_log2 (size); + + if (size < 0) + return 4; + + size++; + return (size > 4 ? 4 : size); +} + +/* Make all bit groups live for REGNO in bitmap BMAP. For hard regs, + we assume all groups are live. For a pseudo we consider the size + of the pseudo to avoid creating unnecessarily live chunks of data. */ + +static void +make_reg_live (bitmap bmap, int regno) +{ + int limit; + + /* For pseudos we can use the mode to limit how many bit groups + are marked as live since a pseudo only has one mode. Hard + registers have to be handled more conservatively. */ + if (regno > FIRST_PSEUDO_REGISTER) + { + rtx reg = regno_reg_rtx[regno]; + limit = group_limit (reg); + } + else + limit = 4; + + for (int i = 0; i < limit; i++) + bitmap_set_bit (bmap, regno * 4 + i); +} + /* Note this pass could be used to narrow memory loads too. It's not clear if that's profitable or not in general. */ @@ -196,7 +247,8 @@ ext_dce_process_sets (rtx_insn *insn, rtx obj, bitmap live_tmp) /* Transfer all the LIVENOW bits for X into LIVE_TMP. */ HOST_WIDE_INT rn = REGNO (SUBREG_REG (x)); - for (HOST_WIDE_INT i = 4 * rn; i < 4 * rn + 4; i++) + int limit = group_limit (SUBREG_REG (x)); + for (HOST_WIDE_INT i = 4 * rn; i < 4 * rn + limit; i++) if (bitmap_bit_p (livenow, i)) bitmap_set_bit (live_tmp, i); @@ -260,7 +312,8 @@ ext_dce_process_sets (rtx_insn *insn, rtx obj, bitmap live_tmp) /* Transfer the appropriate bits from LIVENOW into LIVE_TMP. */ HOST_WIDE_INT rn = REGNO (x); - for (HOST_WIDE_INT i = 4 * rn; i < 4 * rn + 4; i++) + int limit = group_limit (x); + for (HOST_WIDE_INT i = 4 * rn; i < 4 * rn + limit; i++) if (bitmap_bit_p (livenow, i)) bitmap_set_bit (live_tmp, i); @@ -692,7 +745,7 @@ ext_dce_process_uses (rtx_insn *insn, rtx obj, bitmap live_tmp) /* If we have a register reference that is not otherwise handled, just assume all the chunks are live. */ else if (REG_P (x)) - bitmap_set_range (livenow, REGNO (x) * 4, 4); + bitmap_set_range (livenow, REGNO (x) * 4, group_limit (x)); } } @@ -819,10 +872,7 @@ ext_dce_init (void) unsigned i; bitmap_iterator bi; EXECUTE_IF_SET_IN_BITMAP (refs, 0, i, bi) - { - for (int j = 0; j < 4; j++) - bitmap_set_bit (&livein[EXIT_BLOCK], i * 4 + j); - } + make_reg_live (&livein[EXIT_BLOCK], i); livenow = BITMAP_ALLOC (NULL); all_blocks = BITMAP_ALLOC (NULL); |