2009-11-21 Martin Jambor <mjambor@suse.cz>
authorjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Nov 2009 22:56:36 +0000 (22:56 +0000)
committerjamborm <jamborm@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 21 Nov 2009 22:56:36 +0000 (22:56 +0000)
PR middle-end/42025
* tree-sra.c (access_precludes_ipa_sra_p): New function.
(splice_param_accesses): Check all accesses by calling
access_precludes_ipa_sra_p.
(sra_ipa_modify_expr): Rename argument erite to dont_convert and do
not convert types if it is true.
(sra_ipa_modify_assign): Convert types in case of mismatch.

* testsuite/gcc.c-torture/compile/pr42025-1.c: New test.
* testsuite/gcc.c-torture/compile/pr42025-2.c: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154413 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/compile/pr42025-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr42025-2.c [new file with mode: 0644]
gcc/tree-sra.c

index b34a81f..5f5a2e6 100644 (file)
@@ -1,3 +1,13 @@
+2009-11-21  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/42025
+       * tree-sra.c (access_precludes_ipa_sra_p): New function.
+       (splice_param_accesses): Check all accesses by calling
+       access_precludes_ipa_sra_p.
+       (sra_ipa_modify_expr): Rename argument erite to dont_convert and do
+       not convert types if it is true.
+       (sra_ipa_modify_assign): Convert types in case of mismatch.
+
 2009-11-21  Kaushik Phatak  <kaushik.phatak@kpitcummins.com>
 
        * config/sh/sh.md (cmpeqsi_t-1): Use logical_operand predicate
index 445691a..a23042d 100644 (file)
@@ -1,3 +1,9 @@
+2009-11-21  Martin Jambor  <mjambor@suse.cz>
+
+       PR middle-end/42025
+       * gcc.c-torture/compile/pr42025-1.c: New test.
+       * gcc.c-torture/compile/pr42025-2.c: New test.
+
 2009-11-21  Adam Nemet  <adambnemet@gmail.com>
 
        * gcc.target/mips/mult-1.c: Forbid octeon.
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr42025-1.c b/gcc/testsuite/gcc.c-torture/compile/pr42025-1.c
new file mode 100644 (file)
index 0000000..f19123e
--- /dev/null
@@ -0,0 +1,24 @@
+typedef void* Ptr;
+
+struct A
+{
+  int i;
+  union
+  {
+    Ptr p;
+    char *q;
+  } u;
+};
+
+static void foo(struct A *p, char *q)
+{
+  if (p->i)
+    p->u.p = 0;
+  else
+    p->u.q = q;
+}
+
+void bar(struct A *p, char *q)
+{
+  foo(p, q);
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr42025-2.c b/gcc/testsuite/gcc.c-torture/compile/pr42025-2.c
new file mode 100644 (file)
index 0000000..14cb36d
--- /dev/null
@@ -0,0 +1,32 @@
+typedef struct
+{
+  void *p;
+} Ptr;
+
+struct A
+{
+  int i;
+  union
+  {
+    Ptr p;
+    char *q;
+  } u;
+};
+
+extern Ptr get_stuff (void);
+extern void use_stuff (char *);
+
+static void foo(struct A p, char *q)
+{
+  if (p.i)
+    p.u.p = get_stuff ();
+  else
+    p.u.q = q;
+
+  use_stuff (p.u.q);
+}
+
+void bar(struct A *p, char *q)
+{
+  foo(*p, q);
+}
index 67001a6..fe82d98 100644 (file)
@@ -3042,6 +3042,27 @@ unmodified_by_ref_scalar_representative (tree parm)
   return repr;
 }
 
+/* Return true iff this access precludes IPA-SRA of the parameter it is
+   associated with. */
+
+static bool
+access_precludes_ipa_sra_p (struct access *access)
+{
+  /* Avoid issues such as the second simple testcase in PR 42025.  The problem
+     is incompatible assign in a call statement (and possibly even in asm
+     statements).  This can be relaxed by using a new temporary but only for
+     non-TREE_ADDRESSABLE types and is probably not worth the complexity. (In
+     intraprocedural SRA we deal with this by keeping the old aggregate around,
+     something we cannot do in IPA-SRA.)  */
+  if (access->write
+      && (is_gimple_call (access->stmt)
+         || gimple_code (access->stmt) == GIMPLE_ASM))
+    return true;
+
+  return false;
+}
+
+
 /* Sort collected accesses for parameter PARM, identify representatives for
    each accessed region and link them together.  Return NULL if there are
    different but overlapping accesses, return the special ptr value meaning
@@ -3073,6 +3094,8 @@ splice_param_accesses (tree parm, bool *ro_grp)
       bool modification;
       access = VEC_index (access_p, access_vec, i);
       modification = access->write;
+      if (access_precludes_ipa_sra_p (access))
+       return NULL;
 
       /* Access is about to become group representative unless we find some
         nasty overlap which would preclude us from breaking this parameter
@@ -3093,6 +3116,9 @@ splice_param_accesses (tree parm, bool *ro_grp)
          else if (ac2->size != access->size)
            return NULL;
 
+         if (access_precludes_ipa_sra_p (ac2))
+           return NULL;
+
          modification |= ac2->write;
          ac2->group_representative = access;
          ac2->next_sibling = access->next_sibling;
@@ -3523,13 +3549,19 @@ replace_removed_params_ssa_names (gimple stmt, void *data)
   return true;
 }
 
-/* Callback for scan_function.  If the expression *EXPR should be replaced by a
-   reduction of a parameter, do so.  DATA is a pointer to a vector of
-   adjustments.  */
+/* Callback for scan_function and helper to sra_ipa_modify_assign.  If the
+   expression *EXPR should be replaced by a reduction of a parameter, do so.
+   DATA is a pointer to a vector of adjustments.  DONT_CONVERT specifies
+   whether the function should care about type incompatibility the current and
+   new expressions.  If it is true, the function will leave incompatibility
+   issues to the caller.
+
+   When called directly by scan_function, DONT_CONVERT is true when the EXPR is
+   a write (LHS) expression.  */
 
 static bool
 sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
-                    bool write ATTRIBUTE_UNUSED, void *data)
+                    bool dont_convert, void *data)
 {
   ipa_parm_adjustment_vec adjustments;
   int i, len;
@@ -3543,10 +3575,10 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
   if (TREE_CODE (*expr) == BIT_FIELD_REF
       || TREE_CODE (*expr) == IMAGPART_EXPR
       || TREE_CODE (*expr) == REALPART_EXPR)
-    expr = &TREE_OPERAND (*expr, 0);
-  while (TREE_CODE (*expr) == NOP_EXPR
-        || TREE_CODE (*expr) == VIEW_CONVERT_EXPR)
-    expr = &TREE_OPERAND (*expr, 0);
+    {
+      expr = &TREE_OPERAND (*expr, 0);
+      dont_convert = false;
+    }
 
   base = get_ref_base_and_extent (*expr, &offset, &size, &max_size);
   if (!base || size == -1 || max_size == -1)
@@ -3594,13 +3626,14 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
       fprintf (dump_file, "\n");
     }
 
-  if (!useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
+  if (!dont_convert
+      && !useless_type_conversion_p (TREE_TYPE (*expr), cand->type))
     {
       tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (*expr), src);
       *expr = vce;
     }
-    else
-      *expr = src;
+  else
+    *expr = src;
   return true;
 }
 
@@ -3608,20 +3641,37 @@ sra_ipa_modify_expr (tree *expr, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
    essentially the same function like sra_ipa_modify_expr.  */
 
 static enum scan_assign_result
-sra_ipa_modify_assign (gimple *stmt_ptr,
-                      gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED, void *data)
+sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi, void *data)
 {
   gimple stmt = *stmt_ptr;
-  bool any = false;
+  tree *lhs_p, *rhs_p;
+  bool any;
 
   if (!gimple_assign_single_p (stmt))
     return SRA_SA_NONE;
 
-  any |= sra_ipa_modify_expr (gimple_assign_rhs1_ptr (stmt), gsi, false,
-                             data);
-  any |= sra_ipa_modify_expr (gimple_assign_lhs_ptr (stmt), gsi, true, data);
+  rhs_p = gimple_assign_rhs1_ptr (stmt);
+  lhs_p = gimple_assign_lhs_ptr (stmt);
+
+  any = sra_ipa_modify_expr (rhs_p, gsi, true, data);
+  any |= sra_ipa_modify_expr (lhs_p, gsi, true, data);
+  if (any)
+    {
+      if (!useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
+       {
+         location_t loc = gimple_location (stmt);
+         tree vce = fold_build1_loc (loc, VIEW_CONVERT_EXPR,
+                                     TREE_TYPE (*lhs_p), *rhs_p);
+         tree tmp = force_gimple_operand_gsi (gsi, vce, true, NULL_TREE,
+                                              true, GSI_SAME_STMT);
+
+         gimple_assign_set_rhs_from_tree (gsi, tmp);
+       }
+
+      return SRA_SA_PROCESSED;
+    }
 
-  return any ? SRA_SA_PROCESSED : SRA_SA_NONE;
+  return SRA_SA_NONE;
 }
 
 /* Call gimple_debug_bind_reset_value on all debug statements describing