re PR rtl-optimization/69447 (wrong code with -O2 -fno-schedule-insns and mixed 8/16/32/64bit arithmetics @ armv7a)
PR rtl-opt/69447 * lra-remat.c (subreg_regs): New. (dump_candidates_and_remat_bb_data): Dump it. (operand_to_remat): Reject if operand in subreg_regs. (set_bb_regs): Collect subreg_regs. (lra_remat): Init and free subreg_regs. Compute calculate_local_reg_remat_bb_data before create_cands. From-SVN: r232905
This commit is contained in:
parent
49847d759f
commit
f75ebe779f
|
@ -1,3 +1,13 @@
|
|||
2016-01-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR rtl-opt/69447
|
||||
* lra-remat.c (subreg_regs): New.
|
||||
(dump_candidates_and_remat_bb_data): Dump it.
|
||||
(operand_to_remat): Reject if operand in subreg_regs.
|
||||
(set_bb_regs): Collect subreg_regs.
|
||||
(lra_remat): Init and free subreg_regs. Compute
|
||||
calculate_local_reg_remat_bb_data before create_cands.
|
||||
|
||||
2016-01-27 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR target/68986
|
||||
|
|
|
@ -77,6 +77,9 @@ static int call_used_regs_arr[FIRST_PSEUDO_REGISTER];
|
|||
/* Bitmap used for different calculations. */
|
||||
static bitmap_head temp_bitmap;
|
||||
|
||||
/* Registers accessed via subreg_p. */
|
||||
static bitmap_head subreg_regs;
|
||||
|
||||
typedef struct cand *cand_t;
|
||||
typedef const struct cand *const_cand_t;
|
||||
|
||||
|
@ -383,30 +386,30 @@ operand_to_remat (rtx_insn *insn)
|
|||
return -1;
|
||||
/* First find a pseudo which can be rematerialized. */
|
||||
for (reg = id->regs; reg != NULL; reg = reg->next)
|
||||
/* True FRAME_POINTER_NEEDED might be because we can not follow
|
||||
changing sp offsets, e.g. alloca is used. If the insn contains
|
||||
stack pointer in such case, we can not rematerialize it as we
|
||||
can not know sp offset at a rematerialization place. */
|
||||
if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
|
||||
return -1;
|
||||
else if (reg->type == OP_OUT && ! reg->subreg_p
|
||||
&& find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
|
||||
{
|
||||
/* We permits only one spilled reg. */
|
||||
if (found_reg != NULL)
|
||||
return -1;
|
||||
found_reg = reg;
|
||||
}
|
||||
/* IRA calculates conflicts separately for subregs of two words
|
||||
pseudo. Even if the pseudo lives, e.g. one its subreg can be
|
||||
used lately, another subreg hard register can be already used
|
||||
for something else. In such case, it is not safe to
|
||||
rematerialize the insn. */
|
||||
else if (reg->type == OP_IN && reg->subreg_p
|
||||
&& reg->regno >= FIRST_PSEUDO_REGISTER
|
||||
&& (GET_MODE_SIZE (PSEUDO_REGNO_MODE (reg->regno))
|
||||
== 2 * UNITS_PER_WORD))
|
||||
return -1;
|
||||
{
|
||||
/* True FRAME_POINTER_NEEDED might be because we can not follow
|
||||
changing sp offsets, e.g. alloca is used. If the insn contains
|
||||
stack pointer in such case, we can not rematerialize it as we
|
||||
can not know sp offset at a rematerialization place. */
|
||||
if (reg->regno == STACK_POINTER_REGNUM && frame_pointer_needed)
|
||||
return -1;
|
||||
else if (reg->type == OP_OUT && ! reg->subreg_p
|
||||
&& find_regno_note (insn, REG_UNUSED, reg->regno) == NULL)
|
||||
{
|
||||
/* We permits only one spilled reg. */
|
||||
if (found_reg != NULL)
|
||||
return -1;
|
||||
found_reg = reg;
|
||||
}
|
||||
/* IRA calculates conflicts separately for subregs of two words
|
||||
pseudo. Even if the pseudo lives, e.g. one its subreg can be
|
||||
used lately, another subreg hard register can be already used
|
||||
for something else. In such case, it is not safe to
|
||||
rematerialize the insn. */
|
||||
if (reg->regno >= FIRST_PSEUDO_REGISTER
|
||||
&& bitmap_bit_p (&subreg_regs, reg->regno))
|
||||
return -1;
|
||||
}
|
||||
if (found_reg == NULL)
|
||||
return -1;
|
||||
if (found_reg->regno < FIRST_PSEUDO_REGISTER)
|
||||
|
@ -631,6 +634,9 @@ dump_candidates_and_remat_bb_data (void)
|
|||
lra_dump_bitmap_with_title ("avout cands in BB",
|
||||
&get_remat_bb_data (bb)->avout_cands, bb->index);
|
||||
}
|
||||
fprintf (lra_dump_file, "subreg regs:");
|
||||
dump_regset (&subreg_regs, lra_dump_file);
|
||||
putc ('\n', lra_dump_file);
|
||||
}
|
||||
|
||||
/* Free all BB data. */
|
||||
|
@ -655,21 +661,24 @@ finish_remat_bb_data (void)
|
|||
|
||||
|
||||
|
||||
/* Update changed_regs and dead_regs of BB from INSN. */
|
||||
/* Update changed_regs, dead_regs, subreg_regs of BB from INSN. */
|
||||
static void
|
||||
set_bb_regs (basic_block bb, rtx_insn *insn)
|
||||
{
|
||||
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
|
||||
remat_bb_data_t bb_info = get_remat_bb_data (bb);
|
||||
struct lra_insn_reg *reg;
|
||||
|
||||
for (reg = id->regs; reg != NULL; reg = reg->next)
|
||||
if (reg->type != OP_IN)
|
||||
bitmap_set_bit (&get_remat_bb_data (bb)->changed_regs, reg->regno);
|
||||
else
|
||||
{
|
||||
if (find_regno_note (insn, REG_DEAD, (unsigned) reg->regno) != NULL)
|
||||
bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs, reg->regno);
|
||||
}
|
||||
{
|
||||
unsigned regno = reg->regno;
|
||||
if (reg->type != OP_IN)
|
||||
bitmap_set_bit (&bb_info->changed_regs, regno);
|
||||
else if (find_regno_note (insn, REG_DEAD, regno) != NULL)
|
||||
bitmap_set_bit (&bb_info->dead_regs, regno);
|
||||
if (regno >= FIRST_PSEUDO_REGISTER && reg->subreg_p)
|
||||
bitmap_set_bit (&subreg_regs, regno);
|
||||
}
|
||||
if (CALL_P (insn))
|
||||
for (int i = 0; i < call_used_regs_arr_len; i++)
|
||||
bitmap_set_bit (&get_remat_bb_data (bb)->dead_regs,
|
||||
|
@ -1284,10 +1293,11 @@ lra_remat (void)
|
|||
if (call_used_regs[i])
|
||||
call_used_regs_arr[call_used_regs_arr_len++] = i;
|
||||
initiate_cand_table ();
|
||||
create_cands ();
|
||||
create_remat_bb_data ();
|
||||
bitmap_initialize (&temp_bitmap, ®_obstack);
|
||||
bitmap_initialize (&subreg_regs, ®_obstack);
|
||||
calculate_local_reg_remat_bb_data ();
|
||||
create_cands ();
|
||||
calculate_livein_cands ();
|
||||
calculate_gen_cands ();
|
||||
bitmap_initialize (&all_blocks, ®_obstack);
|
||||
|
@ -1298,6 +1308,7 @@ lra_remat (void)
|
|||
result = do_remat ();
|
||||
all_cands.release ();
|
||||
bitmap_clear (&temp_bitmap);
|
||||
bitmap_clear (&subreg_regs);
|
||||
finish_remat_bb_data ();
|
||||
finish_cand_table ();
|
||||
bitmap_clear (&all_blocks);
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
2015-01-27 Paul Thomas <pault@gcc.gnu.org>
|
||||
2016-01-27 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc.c-torture/execute/pr69447.c: New test.
|
||||
|
||||
2016-01-27 Paul Thomas <pault@gcc.gnu.org>
|
||||
|
||||
PR fortran/69385
|
||||
* gfortran.dg/alloc_comp_assign_15.f03: New test.
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
typedef unsigned char u8;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned long long u64;
|
||||
|
||||
u64 __attribute__((noinline, noclone))
|
||||
foo(u8 u8_0, u16 u16_0, u64 u64_0, u8 u8_1, u16 u16_1, u64 u64_1, u64 u64_2, u8 u8_3, u64 u64_3)
|
||||
{
|
||||
u64_1 *= 0x7730;
|
||||
u64_3 *= u64_3;
|
||||
u16_1 |= u64_3;
|
||||
u64_3 -= 2;
|
||||
u8_3 /= u64_2;
|
||||
u8_0 |= 3;
|
||||
u64_3 %= u8_0;
|
||||
u8_0 -= 1;
|
||||
return u8_0 + u16_0 + u64_0 + u8_1 + u16_1 + u64_1 + u8_3 + u64_3;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned x = foo(1, 1, 1, 1, 1, 1, 1, 1, 1);
|
||||
if (x != 0x7737)
|
||||
__builtin_abort();
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue