Hi,

On Wed, Aug 31, 2011 at 09:33:03AM +0200, Richard Guenther wrote:
> On Tue, Aug 30, 2011 at 6:50 PM, Martin Jambor <mjam...@suse.cz> wrote:
> > Ping.  Re-bootstrapped and re-tested yesterday on x86_64-linux.
> 
> Ok.  Does this also apply (maybe in modifed form) to the 4.6 branch?
> 

Below is a modified patch for the 4.6 branch.  It already has the fix
for PR 50260 that my trunk patch introduced and its testcase.  It also
makes ipa-split test for type attributes itself rather than doing it
in ipa-inline-analysis.c because there is no such file in 4.6 and I
did not want to change meaning of flags on the branch.

Bootstrapped and tested on x86_64-linux, OK for the branch?

Thanks,

Martin



2011-09-01  Martin Jambor  <mjam...@suse.cz>

        PR middle-end/49886
        * ipa-split.c (split_function): Do not skip any arguments if
        can_change_signature is set or there are function type attributes.

        * testsuite/gcc.c-torture/execute/pr49886.c: New testcase.
        * testsuite/gfortran.fortran-torture/compile/pr50260.f90: Likewise.

Index: gcc/testsuite/gcc.c-torture/execute/pr49886.c
===================================================================
--- gcc/testsuite/gcc.c-torture/execute/pr49886.c       (revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr49886.c       (revision 0)
@@ -0,0 +1,100 @@
+struct PMC {
+    unsigned flags;
+};
+
+typedef struct Pcc_cell
+{
+    struct PMC *p;
+    long bla;
+    long type;
+} Pcc_cell;
+
+int gi;
+int cond;
+
+extern void abort ();
+extern void never_ever(int interp, struct PMC *pmc)
+  __attribute__((noinline,noclone));
+
+void never_ever (int interp, struct PMC *pmc)
+{
+  abort ();
+}
+
+static void mark_cell(int * interp, Pcc_cell *c)
+  __attribute__((__nonnull__(1)));
+
+static void
+mark_cell(int * interp, Pcc_cell *c)
+{
+  if (!cond)
+    return;
+
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<18)))
+    never_ever(gi + 1, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<17)))
+    never_ever(gi + 2, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<16)))
+    never_ever(gi + 3, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<15)))
+    never_ever(gi + 4, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<14)))
+    never_ever(gi + 5, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<13)))
+    never_ever(gi + 6, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<12)))
+    never_ever(gi + 7, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<11)))
+    never_ever(gi + 8, c->p);
+  if (c && c->type == 4 && c->p
+      && !(c->p->flags & (1<<10)))
+    never_ever(gi + 9, c->p);
+}
+
+static void
+foo(int * interp, Pcc_cell *c)
+{
+  mark_cell(interp, c);
+}
+
+static struct Pcc_cell *
+__attribute__((noinline,noclone))
+getnull(void)
+{
+  return (struct Pcc_cell *) 0;
+}
+
+
+int main()
+{
+  int i;
+
+  cond = 1;
+  for (i = 0; i < 100; i++)
+    foo (&gi, getnull ());
+  return 0;
+}
+
+
+void
+bar_1 (int * interp, Pcc_cell *c)
+{
+  c->bla += 1;
+  mark_cell(interp, c);
+}
+
+void
+bar_2 (int * interp, Pcc_cell *c)
+{
+  c->bla += 2;
+  mark_cell(interp, c);
+}
+
Index: gcc/testsuite/gfortran.fortran-torture/compile/pr50260.f90
===================================================================
--- gcc/testsuite/gfortran.fortran-torture/compile/pr50260.f90  (revision 0)
+++ gcc/testsuite/gfortran.fortran-torture/compile/pr50260.f90  (revision 0)
@@ -0,0 +1,48 @@
+MODULE cp_parser_methods
+  INTEGER, PARAMETER :: default_string_length=80
+  INTEGER, PARAMETER :: default_path_length=250
+  TYPE ilist_type
+     LOGICAL                              :: in_use
+  END TYPE ilist_type
+  TYPE cp_parser_type
+     CHARACTER(LEN=default_path_length)             :: ifn
+     INTEGER                                        :: icol,icol1,icol2
+     TYPE(ilist_type), POINTER                      :: ilist
+  END TYPE cp_parser_type
+  TYPE cp_error_type
+  END TYPE cp_error_type
+CONTAINS
+  FUNCTION cts(i) RESULT(res)
+    CHARACTER(len=6)                         :: res
+  END FUNCTION cts
+  FUNCTION parser_location(parser,error) RESULT(res)
+    TYPE(cp_parser_type), POINTER            :: parser
+    TYPE(cp_error_type), INTENT(inout)       :: error
+    CHARACTER(len=default_path_length+default_string_length)       :: res
+    LOGICAL                                  :: failure
+    IF (.NOT. failure) THEN
+       res="file:'"//TRIM(parser%ifn)//"' line:"//cts(parser%icol)
+    END IF
+  END FUNCTION parser_location
+  SUBROUTINE parser_get_integer(parser,at_end, error)
+    TYPE(cp_parser_type), POINTER            :: parser
+    TYPE(cp_error_type), INTENT(inout)       :: error
+    LOGICAL                                  :: failure, my_at_end
+    IF (.NOT.failure) THEN
+       IF (.NOT.parser%ilist%in_use) THEN
+          CALL cp_assert("A"// TRIM(parser_location(parser,error)))
+       END IF
+    END IF
+  END SUBROUTINE parser_get_integer
+  SUBROUTINE parser_get_string(parser,at_end,error)
+    TYPE(cp_parser_type), POINTER            :: parser
+    LOGICAL, INTENT(out), OPTIONAL           :: at_end
+    TYPE(cp_error_type), INTENT(inout)       :: error
+    LOGICAL                                  :: failure, my_at_end
+    IF (.NOT.failure) THEN
+       IF (PRESENT(at_end)) THEN
+          CALL cp_assert("s"//TRIM(parser_location(parser,error)))
+       END IF
+    END IF
+  END SUBROUTINE parser_get_string
+END MODULE cp_parser_methods
Index: gcc/ipa-split.c
===================================================================
--- gcc/ipa-split.c     (revision 178386)
+++ gcc/ipa-split.c     (working copy)
@@ -943,10 +943,10 @@ static void
 split_function (struct split_point *split_point)
 {
   VEC (tree, heap) *args_to_pass = NULL;
-  bitmap args_to_skip = BITMAP_ALLOC (NULL);
+  bitmap args_to_skip;
   tree parm;
   int num = 0;
-  struct cgraph_node *node;
+  struct cgraph_node *node, *cur_node = cgraph_node (current_function_decl);
   basic_block return_bb = find_return_bb ();
   basic_block call_bb;
   gimple_stmt_iterator gsi;
@@ -966,17 +966,34 @@ split_function (struct split_point *spli
       dump_split_point (dump_file, split_point);
     }
 
+  if (cur_node->local.can_change_signature
+      && !TYPE_ATTRIBUTES (TREE_TYPE (cur_node->decl)))
+    args_to_skip = BITMAP_ALLOC (NULL);
+  else
+    args_to_skip = NULL;
+
   /* Collect the parameters of new function and args_to_skip bitmap.  */
   for (parm = DECL_ARGUMENTS (current_function_decl);
        parm; parm = DECL_CHAIN (parm), num++)
-    if (!is_gimple_reg (parm)
-       || !gimple_default_def (cfun, parm)
-       || !bitmap_bit_p (split_point->ssa_names_to_pass,
-                         SSA_NAME_VERSION (gimple_default_def (cfun, parm))))
+    if (args_to_skip
+       && (!is_gimple_reg (parm)
+           || !gimple_default_def (cfun, parm)
+           || !bitmap_bit_p (split_point->ssa_names_to_pass,
+                             SSA_NAME_VERSION (gimple_default_def (cfun,
+                                                                   parm)))))
       bitmap_set_bit (args_to_skip, num);
     else
       {
        arg = gimple_default_def (cfun, parm);
+       if (!arg)
+         {
+           /* This parm wasn't used up to now, but is going to be used,
+              hence register it.  */
+           add_referenced_var (parm);
+           arg = make_ssa_name (parm, gimple_build_nop ());
+           set_default_def (parm, arg);
+         }
+
        if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm))
            != TYPE_MAIN_VARIANT (TREE_TYPE (arg)))
          {
@@ -1057,9 +1074,7 @@ split_function (struct split_point *spli
 
   /* Now create the actual clone.  */
   rebuild_cgraph_edges ();
-  node = cgraph_function_versioning (cgraph_node (current_function_decl),
-                                    NULL, NULL,
-                                    args_to_skip,
+  node = cgraph_function_versioning (cur_node, NULL, NULL, args_to_skip,
                                     split_point->split_bbs,
                                     split_point->entry_bb, "part");
   /* For usual cloning it is enough to clear builtin only when signature
@@ -1070,7 +1085,7 @@ split_function (struct split_point *spli
       DECL_BUILT_IN_CLASS (node->decl) = NOT_BUILT_IN;
       DECL_FUNCTION_CODE (node->decl) = (enum built_in_function) 0;
     }
-  cgraph_node_remove_callees (cgraph_node (current_function_decl));
+  cgraph_node_remove_callees (cur_node);
   if (!split_part_return_p)
     TREE_THIS_VOLATILE (node->decl) = 1;
   if (dump_file)

Reply via email to