tree.c (substitute_in_expr): Also inline a call if the replacement expression is...
authorEric Botcazou <ebotcazou@adacore.com>
Mon, 1 May 2017 10:18:18 +0000 (10:18 +0000)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 1 May 2017 10:18:18 +0000 (10:18 +0000)
* tree.c (substitute_in_expr) <tcc_vl_exp>: Also inline a call if the
replacement expression is another instance of one of its arguments.

From-SVN: r247431

gcc/ChangeLog
gcc/tree.c

index 52c6a4eb4fa43b2c60af6567387f176aa097d7f8..07b205c81bfb1e7cd77bdde66c6d5de46e99f315 100644 (file)
@@ -1,3 +1,8 @@
+2017-05-01  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * tree.c (substitute_in_expr) <tcc_vl_exp>: Also inline a call if the
+       replacement expression is another instance of one of its arguments.
+
 2017-05-01  Jakub Jelinek  <jakub@redhat.com>
 
        PR target/79430
index bef0071d08777a36ac308e140d662ffa86ea155b..1a926d9a650bde84ee4ab1d19e7540165fc8560a 100644 (file)
@@ -3886,15 +3886,29 @@ substitute_in_expr (tree exp, tree f, tree r)
 
          new_tree = NULL_TREE;
 
-         /* If we are trying to replace F with a constant, inline back
+         /* If we are trying to replace F with a constant or with another
+            instance of one of the arguments of the call, inline back
             functions which do nothing else than computing a value from
             the arguments they are passed.  This makes it possible to
             fold partially or entirely the replacement expression.  */
-         if (CONSTANT_CLASS_P (r) && code == CALL_EXPR)
+         if (code == CALL_EXPR)
            {
-             tree t = maybe_inline_call_in_expr (exp);
-             if (t)
-               return SUBSTITUTE_IN_EXPR (t, f, r);
+             bool maybe_inline = false;
+             if (CONSTANT_CLASS_P (r))
+               maybe_inline = true;
+             else
+               for (i = 3; i < TREE_OPERAND_LENGTH (exp); i++)
+                 if (operand_equal_p (TREE_OPERAND (exp, i), r, 0))
+                   {
+                     maybe_inline = true;
+                     break;
+                   }
+             if (maybe_inline)
+               {
+                 tree t = maybe_inline_call_in_expr (exp);
+                 if (t)
+                   return SUBSTITUTE_IN_EXPR (t, f, r);
+               }
            }
 
          for (i = 1; i < TREE_OPERAND_LENGTH (exp); i++)