From 81be349c4f0ebcc00a97a930ef6ae444398a32ca Mon Sep 17 00:00:00 2001 From: vmakarov Date: Fri, 15 Jan 2016 19:33:33 +0000 Subject: [PATCH] 2016-01-15 Vladimir Makarov PR rtl-optimization/69030 * lra-spills.c (remove_pseudos): Check nrefs and make the function returning bool. (spill_pseudos): Delete debug insn for dead pseudo. (lra_spill): Initiate spill_hard_reg and slots memory separately. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@232445 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++- gcc/lra-spills.c | 142 +++++++++++++++++++------------- gcc/testsuite/ChangeLog | 5 ++ gcc/testsuite/gcc.target/i386/pr69030.c | 28 +++++++ 4 files changed, 126 insertions(+), 59 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr69030.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba191dceafd..e3dc3280a95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-01-15 Vladimir Makarov + + PR rtl-optimization/69030 + * lra-spills.c (remove_pseudos): Check nrefs and make the function + returning bool. + (spill_pseudos): Delete debug insn for dead pseudo. + (lra_spill): Initiate spill_hard_reg and slots memory separately. + 2016-01-15 Jiong Wang * config/aarch64/aarch64-builtins.c (aarch64_types_unopus_qualifiers): @@ -51,7 +59,7 @@ (vcvtns_u32_f32): Likewise. (vcvtpd_u64_f64): Likewise. (vcvtps_u32_f32): Likewise. - + 2016-01-15 Kyrylo Tkachov * config/aarch64/aarch64.c (aarch64_if_then_else_costs): Handle diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c index 1dbba93609f..fa0a579d74c 100644 --- a/gcc/lra-spills.c +++ b/gcc/lra-spills.c @@ -396,17 +396,19 @@ assign_stack_slot_num_and_sort_pseudos (int *pseudo_regnos, int n) /* Recursively process LOC in INSN and change spilled pseudos to the corresponding memory or spilled hard reg. Ignore spilled pseudos - created from the scratches. */ -static void + created from the scratches. Return true if the pseudo nrefs equal + to 0 (don't change the pseudo in this case). Otherwise return false. */ +static bool remove_pseudos (rtx *loc, rtx_insn *insn) { int i; rtx hard_reg; const char *fmt; enum rtx_code code; - + bool res = false; + if (*loc == NULL_RTX) - return; + return res; code = GET_CODE (*loc); if (code == REG && (i = REGNO (*loc)) >= FIRST_PSEUDO_REGISTER && lra_get_regno_hard_regno (i) < 0 @@ -416,6 +418,9 @@ remove_pseudos (rtx *loc, rtx_insn *insn) into scratches back. */ && ! lra_former_scratch_p (i)) { + if (lra_reg_info[i].nrefs == 0 + && pseudo_slots[i].mem == NULL && spill_hard_reg[i] == NULL) + return true; if ((hard_reg = spill_hard_reg[i]) != NULL_RTX) *loc = copy_rtx (hard_reg); else @@ -425,22 +430,23 @@ remove_pseudos (rtx *loc, rtx_insn *insn) false, false, 0, true); *loc = x != pseudo_slots[i].mem ? x : copy_rtx (x); } - return; + return res; } fmt = GET_RTX_FORMAT (code); for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) { if (fmt[i] == 'e') - remove_pseudos (&XEXP (*loc, i), insn); + res = remove_pseudos (&XEXP (*loc, i), insn) || res; else if (fmt[i] == 'E') { int j; for (j = XVECLEN (*loc, i) - 1; j >= 0; j--) - remove_pseudos (&XVECEXP (*loc, i, j), insn); + res = remove_pseudos (&XVECEXP (*loc, i, j), insn) || res; } } + return res; } /* Convert spilled pseudos into their stack slots or spill hard regs, @@ -450,7 +456,7 @@ static void spill_pseudos (void) { basic_block bb; - rtx_insn *insn; + rtx_insn *insn, *curr; int i; bitmap_head spilled_pseudos, changed_insns; @@ -467,52 +473,70 @@ spill_pseudos (void) } FOR_EACH_BB_FN (bb, cfun) { - FOR_BB_INSNS (bb, insn) - if (bitmap_bit_p (&changed_insns, INSN_UID (insn))) - { - rtx *link_loc, link; - remove_pseudos (&PATTERN (insn), insn); - if (CALL_P (insn)) - remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn); - for (link_loc = ®_NOTES (insn); - (link = *link_loc) != NULL_RTX; - link_loc = &XEXP (link, 1)) - { - switch (REG_NOTE_KIND (link)) - { - case REG_FRAME_RELATED_EXPR: - case REG_CFA_DEF_CFA: - case REG_CFA_ADJUST_CFA: - case REG_CFA_OFFSET: - case REG_CFA_REGISTER: - case REG_CFA_EXPRESSION: - case REG_CFA_RESTORE: - case REG_CFA_SET_VDRAP: - remove_pseudos (&XEXP (link, 0), insn); - break; - default: - break; - } - } - if (lra_dump_file != NULL) - fprintf (lra_dump_file, - "Changing spilled pseudos to memory in insn #%u\n", - INSN_UID (insn)); - lra_push_insn (insn); - if (lra_reg_spill_p || targetm.different_addr_displacement_p ()) - lra_set_used_insn_alternative (insn, -1); - } - else if (CALL_P (insn)) - /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE does - not affect value of insn_bitmap of the corresponding - lra_reg_info. That is because we don't need to reload - pseudos in CALL_INSN_FUNCTION_USAGEs. So if we process - only insns in the insn_bitmap of given pseudo here, we - can miss the pseudo in some - CALL_INSN_FUNCTION_USAGEs. */ - remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn); - bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos); - bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos); + FOR_BB_INSNS_SAFE (bb, insn, curr) + { + bool removed_pseudo_p = false; + + if (bitmap_bit_p (&changed_insns, INSN_UID (insn))) + { + rtx *link_loc, link; + + removed_pseudo_p = remove_pseudos (&PATTERN (insn), insn); + if (CALL_P (insn) + && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn)) + removed_pseudo_p = true; + for (link_loc = ®_NOTES (insn); + (link = *link_loc) != NULL_RTX; + link_loc = &XEXP (link, 1)) + { + switch (REG_NOTE_KIND (link)) + { + case REG_FRAME_RELATED_EXPR: + case REG_CFA_DEF_CFA: + case REG_CFA_ADJUST_CFA: + case REG_CFA_OFFSET: + case REG_CFA_REGISTER: + case REG_CFA_EXPRESSION: + case REG_CFA_RESTORE: + case REG_CFA_SET_VDRAP: + if (remove_pseudos (&XEXP (link, 0), insn)) + removed_pseudo_p = true; + break; + default: + break; + } + } + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + "Changing spilled pseudos to memory in insn #%u\n", + INSN_UID (insn)); + lra_push_insn (insn); + if (lra_reg_spill_p || targetm.different_addr_displacement_p ()) + lra_set_used_insn_alternative (insn, -1); + } + else if (CALL_P (insn) + /* Presence of any pseudo in CALL_INSN_FUNCTION_USAGE + does not affect value of insn_bitmap of the + corresponding lra_reg_info. That is because we + don't need to reload pseudos in + CALL_INSN_FUNCTION_USAGEs. So if we process only + insns in the insn_bitmap of given pseudo here, we + can miss the pseudo in some + CALL_INSN_FUNCTION_USAGEs. */ + && remove_pseudos (&CALL_INSN_FUNCTION_USAGE (insn), insn)) + removed_pseudo_p = true; + if (removed_pseudo_p) + { + lra_assert (DEBUG_INSN_P (insn)); + lra_set_insn_deleted (insn); + if (lra_dump_file != NULL) + fprintf (lra_dump_file, + "Debug insn #%u is deleted as containing removed pseudo\n", + INSN_UID (insn)); + } + bitmap_and_compl_into (df_get_live_in (bb), &spilled_pseudos); + bitmap_and_compl_into (df_get_live_out (bb), &spilled_pseudos); + } } bitmap_clear (&spilled_pseudos); bitmap_clear (&changed_insns); @@ -548,12 +572,14 @@ lra_spill (void) if (lra_reg_info[i].nrefs != 0 && lra_get_regno_hard_regno (i) < 0 /* We do not want to assign memory for former scratches. */ && ! lra_former_scratch_p (i)) - { - spill_hard_reg[i] = NULL_RTX; - pseudo_regnos[n++] = i; - } + pseudo_regnos[n++] = i; lra_assert (n > 0); pseudo_slots = XNEWVEC (struct pseudo_slot, regs_num); + for (i = FIRST_PSEUDO_REGISTER; i < regs_num; i++) + { + spill_hard_reg[i] = NULL_RTX; + pseudo_slots[i].mem = NULL_RTX; + } slots = XNEWVEC (struct slot, regs_num); /* Sort regnos according their usage frequencies. */ qsort (pseudo_regnos, n, sizeof (int), regno_freq_compare); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 2cc8508c340..0a4e6e737bc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-01-15 Vladimir Makarov + + PR rtl-optimization/69030 + * gcc.target/i386/pr69030.c: New. + 2016-01-15 Kyrylo Tkachov * gcc.target/aarch64/target_attr_17.c: New test. diff --git a/gcc/testsuite/gcc.target/i386/pr69030.c b/gcc/testsuite/gcc.target/i386/pr69030.c new file mode 100644 index 00000000000..30919c72c91 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr69030.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -w" } */ + +int a, b, c = 7, d; +static unsigned e, g; +char f; +static unsigned fn1() { + unsigned h = e - b ^ c; + int i = h / c & a * g, j = g * h; + if (h) { + if (d) + h = e; + j = a; + a = (a && (g % f && i) % h) | c | ~2; + if (b) + printf("", 1); + } + c = i; + a = j; + return 2; +} + +int main() { + for (; b < -18; --b) + g = 0; + fn1(); + return 0; +} -- 2.11.4.GIT