From 9d86e84ec0b576bd3586cf05f6605fee316c9cd4 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Thu, 9 Jul 2015 15:39:53 +0000 Subject: [PATCH] re PR rtl-optimization/66782 (Unable to run 64-bit wine after MS->SYSV register changes) 2015-07-09 Vladimir Makarov PR rtl-optimization/66782 * lra-int.h (struct lra_insn_recog_data): Add comment about clobbered hard regs for arg_hard_regs. * lra.c (lra_set_insn_recog_data): Add clobbered hard regs. * lra-lives.c (process_bb_lives): Process clobbered hard regs. Add condition for processing used hard regs. * lra-constraints.c (update_ebb_live_info, inherit_in_ebb): Process clobbered hard regs. From-SVN: r225618 --- gcc/ChangeLog | 11 +++++++++++ gcc/lra-constraints.c | 18 +++++++++++++++--- gcc/lra-int.h | 8 +++++--- gcc/lra-lives.c | 15 ++++++++++++++- gcc/lra.c | 7 +++++-- 5 files changed, 50 insertions(+), 9 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 844ff7b3f47..32a43744f47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2015-07-09 Vladimir Makarov + + PR rtl-optimization/66782 + * lra-int.h (struct lra_insn_recog_data): Add comment about + clobbered hard regs for arg_hard_regs. + * lra.c (lra_set_insn_recog_data): Add clobbered hard regs. + * lra-lives.c (process_bb_lives): Process clobbered hard regs. + Add condition for processing used hard regs. + * lra-constraints.c (update_ebb_live_info, inherit_in_ebb): + Process clobbered hard regs. + 2015-07-09 Michael Matz * genmatch.c (fprintf_indent): New function. diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index cdb3a9707ab..7d170b63bc8 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -5149,6 +5149,11 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg->subreg_p) bitmap_clear_bit (&live_regs, reg->regno); + if (curr_id->arg_hard_regs != NULL) + /* Make clobbered argument hard registers die. */ + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + bitmap_clear_bit (&live_regs, regno - FIRST_PSEUDO_REGISTER); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type != OP_OUT @@ -5159,9 +5164,10 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) && bitmap_bit_p (&check_only_regs, reg->regno)) bitmap_set_bit (&live_regs, reg->regno); if (curr_id->arg_hard_regs != NULL) - /* Make argument hard registers live. */ + /* Make used argument hard registers live. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - if (bitmap_bit_p (&check_only_regs, regno)) + if (regno < FIRST_PSEUDO_REGISTER + && bitmap_bit_p (&check_only_regs, regno)) bitmap_set_bit (&live_regs, regno); /* It is quite important to remove dead move insns because it means removing dead store. We don't need to process them for @@ -5471,6 +5477,12 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) } } } + /* Process clobbered call regs. */ + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (dst_regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (dst_regno >= FIRST_PSEUDO_REGISTER) + usage_insns[dst_regno - FIRST_PSEUDO_REGISTER].check + = -(int) INSN_UID (curr_insn); if (! JUMP_P (curr_insn)) for (i = 0; i < to_inherit_num; i++) if (inherit_reload_reg (true, to_inherit[i].regno, @@ -5578,7 +5590,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) add_next_usage_insn (src_regno, use_insn, reloads_num); } } - /* Process call args. */ + /* Process used call regs. */ if (curr_id->arg_hard_regs != NULL) for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (src_regno < FIRST_PSEUDO_REGISTER) diff --git a/gcc/lra-int.h b/gcc/lra-int.h index a7763e856dd..5c640426686 100644 --- a/gcc/lra-int.h +++ b/gcc/lra-int.h @@ -267,9 +267,11 @@ struct lra_insn_recog_data duplication numbers: */ rtx **operand_loc; /* The operand locations, NULL if no operands. */ rtx **dup_loc; /* The dup locations, NULL if no dups. */ - /* Number of hard registers implicitly used in given call insn. The - value can be NULL or points to array of the hard register numbers - ending with a negative value. */ + /* Number of hard registers implicitly used/clobbered in given call + insn. The value can be NULL or points to array of the hard + register numbers ending with a negative value. To differ + clobbered and used hard regs, clobbered hard regs are incremented + by FIRST_PSEUDO_REGISTER. */ int *arg_hard_regs; /* Cached value of get_preferred_alternatives. */ alternative_mask preferred_alternatives; diff --git a/gcc/lra-lives.c b/gcc/lra-lives.c index edf4a91028e..78f16531559 100644 --- a/gcc/lra-lives.c +++ b/gcc/lra-lives.c @@ -814,6 +814,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg->type != OP_IN) make_hard_regno_born (reg->regno, false); + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + /* It is a clobber. */ + make_hard_regno_born (regno - FIRST_PSEUDO_REGISTER, false); + sparseset_copy (unused_set, start_living); sparseset_clear (start_dying); @@ -829,6 +835,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p) make_hard_regno_dead (reg->regno); + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + /* It is a clobber. */ + make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); + if (call_p) { if (flag_ipa_ra) @@ -877,7 +889,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) /* Make argument hard registers live. Don't create conflict of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - make_hard_regno_born (regno, true); + if (regno < FIRST_PSEUDO_REGISTER) + make_hard_regno_born (regno, true); sparseset_and_compl (dead_set, start_living, start_dying); diff --git a/gcc/lra.c b/gcc/lra.c index cb7013088bc..a7b9919e6fc 100644 --- a/gcc/lra.c +++ b/gcc/lra.c @@ -1055,6 +1055,7 @@ lra_set_insn_recog_data (rtx_insn *insn) data->arg_hard_regs = NULL; if (CALL_P (insn)) { + bool use_p; rtx link; int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER]; @@ -1065,14 +1066,16 @@ lra_set_insn_recog_data (rtx_insn *insn) for (link = CALL_INSN_FUNCTION_USAGE (insn); link != NULL_RTX; link = XEXP (link, 1)) - if (GET_CODE (XEXP (link, 0)) == USE + if (((use_p = GET_CODE (XEXP (link, 0)) == USE) + || GET_CODE (XEXP (link, 0)) == CLOBBER) && REG_P (XEXP (XEXP (link, 0), 0))) { regno = REGNO (XEXP (XEXP (link, 0), 0)); lra_assert (regno < FIRST_PSEUDO_REGISTER); /* It is an argument register. */ for (i = REG_NREGS (XEXP (XEXP (link, 0), 0)) - 1; i >= 0; i--) - arg_hard_regs[n_hard_regs++] = regno + i; + arg_hard_regs[n_hard_regs++] + = regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER); } if (n_hard_regs != 0) { -- 2.30.2