diff mbox

[RFA,middle-end/53623] Improve extension elimination

Message ID 52CE2909.7030009@redhat.com
State New
Headers show

Commit Message

Jeff Law Jan. 9, 2014, 4:43 a.m. UTC
On 01/08/14 16:13, Jakub Jelinek wrote:
>
> Please add a function comment for it (perhaps saying that it is like
> single_set but never allows more than one SET).
>
> Ok with that change.
My bad.  Thanks for catching it.

Attaching the installed patch for reference.

Jeff
commit 12e467a657653de484178f0d0d66786a92d62ebe
Author: law <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Thu Jan 9 04:42:38 2014 +0000

            * ree.c (get_sub_rtx): New function, extracted from...
            (merge_def_and_ext): Here.
            (combine_reaching_defs): Use get_sub_rtx.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@206454 138bc75d-0d04-0410-961f-82ee72b054a4
diff mbox

Patch

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f63918e..e4872f2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@ 
+2014-01-08  Jeff Law  <law@redhat.com>
+
+	* ree.c (get_sub_rtx): New function, extracted from...
+	(merge_def_and_ext): Here.
+	(combine_reaching_defs): Use get_sub_rtx.
+
 2014-01-08  Eric Botcazou  <ebotcazou@adacore.com>
 
 	* cgraph.h (varpool_variable_node): Do not choke on null node.
diff --git a/gcc/ree.c b/gcc/ree.c
index ec09c7a..1c4f3ad 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -580,27 +580,21 @@  make_defs_and_copies_lists (rtx extend_insn, const_rtx set_pat,
   return ret;
 }
 
-/* Merge the DEF_INSN with an extension.  Calls combine_set_extension
-   on the SET pattern.  */
-
-static bool
-merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
+/* If DEF_INSN has single SET expression, possibly buried inside
+   a PARALLEL, return the address of the SET expression, else
+   return NULL.  This is similar to single_set, except that
+   single_set allows multiple SETs when all but one is dead.  */
+static rtx *
+get_sub_rtx (rtx def_insn)
 {
-  enum machine_mode ext_src_mode;
-  enum rtx_code code;
-  rtx *sub_rtx;
-  rtx s_expr;
-  int i;
-
-  ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0));
-  code = GET_CODE (PATTERN (def_insn));
-  sub_rtx = NULL;
+  enum rtx_code code = GET_CODE (PATTERN (def_insn));
+  rtx *sub_rtx = NULL;
 
   if (code == PARALLEL)
     {
-      for (i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++)
+      for (int i = 0; i < XVECLEN (PATTERN (def_insn), 0); i++)
         {
-          s_expr = XVECEXP (PATTERN (def_insn), 0, i);
+          rtx s_expr = XVECEXP (PATTERN (def_insn), 0, i);
           if (GET_CODE (s_expr) != SET)
             continue;
 
@@ -609,7 +603,7 @@  merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
           else
             {
               /* PARALLEL with multiple SETs.  */
-              return false;
+              return NULL;
             }
         }
     }
@@ -618,10 +612,27 @@  merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
   else
     {
       /* It is not a PARALLEL or a SET, what could it be ? */
-      return false;
+      return NULL;
     }
 
   gcc_assert (sub_rtx != NULL);
+  return sub_rtx;
+}
+
+/* Merge the DEF_INSN with an extension.  Calls combine_set_extension
+   on the SET pattern.  */
+
+static bool
+merge_def_and_ext (ext_cand *cand, rtx def_insn, ext_state *state)
+{
+  enum machine_mode ext_src_mode;
+  rtx *sub_rtx;
+
+  ext_src_mode = GET_MODE (XEXP (SET_SRC (cand->expr), 0));
+  sub_rtx = get_sub_rtx (def_insn);
+
+  if (sub_rtx == NULL)
+    return false;
 
   if (REG_P (SET_DEST (*sub_rtx))
       && (GET_MODE (SET_DEST (*sub_rtx)) == ext_src_mode
@@ -707,8 +718,13 @@  combine_reaching_defs (ext_cand *cand, const_rtx set_pat, ext_state *state)
       /* If there is an overlap between the destination of DEF_INSN and
 	 CAND->insn, then this transformation is not safe.  Note we have
 	 to test in the widened mode.  */
+      rtx *dest_sub_rtx = get_sub_rtx (def_insn);
+      if (dest_sub_rtx == NULL
+	  || !REG_P (SET_DEST (*dest_sub_rtx)))
+	return false;
+
       rtx tmp_reg = gen_rtx_REG (GET_MODE (SET_DEST (PATTERN (cand->insn))),
-				 REGNO (SET_DEST (PATTERN (def_insn))));
+				 REGNO (SET_DEST (*dest_sub_rtx)));
       if (reg_overlap_mentioned_p (tmp_reg, SET_DEST (PATTERN (cand->insn))))
 	return false;