re PR rtl-optimization/66782 (Unable to run 64-bit wine after MS->SYSV register changes)
authorVladimir Makarov <vmakarov@redhat.com>
Thu, 9 Jul 2015 15:39:53 +0000 (15:39 +0000)
committerVladimir Makarov <vmakarov@gcc.gnu.org>
Thu, 9 Jul 2015 15:39:53 +0000 (15:39 +0000)
2015-07-09  Vladimir Makarov  <vmakarov@redhat.com>

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
gcc/lra-constraints.c
gcc/lra-int.h
gcc/lra-lives.c
gcc/lra.c

index 844ff7b..32a4374 100644 (file)
@@ -1,3 +1,14 @@
+2015-07-09  Vladimir Makarov  <vmakarov@redhat.com>
+
+       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  <matz@suse.de>
 
        * genmatch.c (fprintf_indent): New function.
index cdb3a97..7d170b6 100644 (file)
@@ -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)
index a7763e8..5c64042 100644 (file)
@@ -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;
index edf4a91..78f1653 100644 (file)
@@ -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);
 
index cb70130..a7b9919 100644 (file)
--- 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)
        {