From 46081bb341bba053f5aa906029c5d2fa89569fc2 Mon Sep 17 00:00:00 2001 From: Stuart Hastings Date: Thu, 10 Oct 2002 23:16:54 +0000 Subject: [PATCH] cse.c (struct cse_reg_info): Add subreg_ticked. 2002-10-10 Stuart Hastings * cse.c (struct cse_reg_info): Add subreg_ticked. (SUBREG_TICKED): New. (get_cse_reg_info): Initialize SUBREG_TICKED. (mention_regs): Use it. (invalidate): Set SUBREG_TICKED. (invalidate_for_call): Likewise. (addr_affects_sp_p): Likewise. From-SVN: r58035 --- gcc/ChangeLog | 10 +++++ gcc/cse.c | 37 +++++++++++++++---- .../gcc.c-torture/execute/20021010-2.c | 37 +++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/20021010-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2159736d1cd..a7d8310a2c3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2002-10-10 Stuart Hastings + + * cse.c (struct cse_reg_info): Add subreg_ticked. + (SUBREG_TICKED): New. + (get_cse_reg_info): Initialize SUBREG_TICKED. + (mention_regs): Use it. + (invalidate): Set SUBREG_TICKED. + (invalidate_for_call): Likewise. + (addr_affects_sp_p): Likewise. + 2002-10-10 Jakub Jelinek * config/i386/i386.md (tls_local_dynamic_base): Put pic reg diff --git a/gcc/cse.c b/gcc/cse.c index 378a91292b3..f212fd94a98 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -316,6 +316,10 @@ struct cse_reg_info reg_tick value, such expressions existing in the hash table are invalid. */ int reg_in_table; + + /* The SUBREG that was set when REG_TICK was last incremented. Set + to -1 if the last store was to the whole register, not a subreg. */ + int subreg_ticked; }; /* A free list of cse_reg_info entries. */ @@ -514,6 +518,11 @@ struct table_elt #define REG_IN_TABLE(N) ((GET_CSE_REG_INFO (N))->reg_in_table) +/* Get the SUBREG set at the last increment to REG_TICK (-1 if not a + SUBREG). */ + +#define SUBREG_TICKED(N) ((GET_CSE_REG_INFO (N))->subreg_ticked) + /* Get the quantity number for REG. */ #define REG_QTY(N) ((GET_CSE_REG_INFO (N))->reg_qty) @@ -957,6 +966,7 @@ get_cse_reg_info (regno) /* Initialize it. */ p->reg_tick = 1; p->reg_in_table = -1; + p->subreg_ticked = -1; p->reg_qty = regno; p->regno = regno; p->next = cse_reg_info_used_list; @@ -1191,6 +1201,7 @@ mention_regs (x) remove_invalid_refs (i); REG_IN_TABLE (i) = REG_TICK (i); + SUBREG_TICKED (i) = -1; } return 0; @@ -1206,17 +1217,20 @@ mention_regs (x) if (REG_IN_TABLE (i) >= 0 && REG_IN_TABLE (i) != REG_TICK (i)) { - /* If reg_tick has been incremented more than once since - reg_in_table was last set, that means that the entire - register has been set before, so discard anything memorized - for the entire register, including all SUBREG expressions. */ - if (REG_IN_TABLE (i) != REG_TICK (i) - 1) + /* If REG_IN_TABLE (i) differs from REG_TICK (i) by one, and + the last store to this register really stored into this + subreg, then remove the memory of this subreg. + Otherwise, remove any memory of the entire register and + all its subregs from the table. */ + if (REG_TICK (i) - REG_IN_TABLE (i) > 1 + || SUBREG_TICKED (i) != SUBREG_REG (x)) remove_invalid_refs (i); else remove_invalid_subreg_refs (i, SUBREG_BYTE (x), GET_MODE (x)); } REG_IN_TABLE (i) = REG_TICK (i); + SUBREG_TICKED (i) = SUBREG_REG (x); return 0; } @@ -1861,6 +1875,7 @@ invalidate (x, full_mode) delete_reg_equiv (regno); REG_TICK (regno)++; + SUBREG_TICKED (regno) = -1; if (regno >= FIRST_PSEUDO_REGISTER) { @@ -1888,6 +1903,7 @@ invalidate (x, full_mode) CLEAR_HARD_REG_BIT (hard_regs_in_table, rn); delete_reg_equiv (rn); REG_TICK (rn)++; + SUBREG_TICKED (rn) = -1; } if (in_table) @@ -2093,7 +2109,10 @@ invalidate_for_call () { delete_reg_equiv (regno); if (REG_TICK (regno) >= 0) - REG_TICK (regno)++; + { + REG_TICK (regno)++; + SUBREG_TICKED (regno) = -1; + } in_table |= (TEST_HARD_REG_BIT (hard_regs_in_table, regno) != 0); } @@ -6407,7 +6426,11 @@ addr_affects_sp_p (addr) && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM) { if (REG_TICK (STACK_POINTER_REGNUM) >= 0) - REG_TICK (STACK_POINTER_REGNUM)++; + { + REG_TICK (STACK_POINTER_REGNUM)++; + /* Is it possible to use a subreg of SP? */ + SUBREG_TICKED (STACK_POINTER_REGNUM) = -1; + } /* This should be *very* rare. */ if (TEST_HARD_REG_BIT (hard_regs_in_table, STACK_POINTER_REGNUM)) diff --git a/gcc/testsuite/gcc.c-torture/execute/20021010-2.c b/gcc/testsuite/gcc.c-torture/execute/20021010-2.c new file mode 100644 index 00000000000..425a8f6e4c8 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/20021010-2.c @@ -0,0 +1,37 @@ +/* cse.c failure on x86 target. + Contributed by Stuart Hastings 10 Oct 2002 */ +#include + +typedef signed short SInt16; + +typedef struct { + SInt16 minx; + SInt16 maxx; + SInt16 miny; + SInt16 maxy; +} IOGBounds; + +int expectedwidth = 50; + +unsigned int *global_vramPtr = (unsigned int *)0xa000; + +IOGBounds global_bounds = { 100, 150, 100, 150 }; +IOGBounds global_saveRect = { 75, 175, 75, 175 }; + +main() +{ + unsigned int *vramPtr; + int width; + IOGBounds saveRect = global_saveRect; + IOGBounds bounds = global_bounds; + + if (saveRect.minx < bounds.minx) saveRect.minx = bounds.minx; + if (saveRect.maxx > bounds.maxx) saveRect.maxx = bounds.maxx; + + vramPtr = global_vramPtr + (saveRect.miny - bounds.miny) ; + width = saveRect.maxx - saveRect.minx; + + if (width != expectedwidth) + abort (); + exit (0); +} -- 2.30.2