===================================================================
@@ -1,5 +1,4 @@
/* { dg-do run } */
-/* { dg-xfail-run-if "" { "*-*-*" } { "-O2" "-O3" "-Os" } } */
struct PMC {
unsigned flags;
===================================================================
@@ -0,0 +1,109 @@
+/* { dg-do compile } */
+
+struct PMC {
+ unsigned flags;
+};
+
+struct PVC {
+ unsigned flags, other_stuff;
+};
+
+
+typedef struct Pcc_cell
+{
+ struct PMC *p;
+ long bla;
+ long type;
+} Pcc_cell;
+
+int gi;
+int cond;
+
+struct PVC g_pvc;
+
+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, struct PVC pvc)
+ __attribute__((__nonnull__(1)));
+
+static void
+mark_cell(int * interp, Pcc_cell *c, struct PVC pvc)
+{
+ if (!cond)
+ return;
+
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<8)))
+ never_ever(gi + 1, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<7)))
+ never_ever(gi + 2, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<6)))
+ never_ever(gi + 3, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<5)))
+ never_ever(gi + 4, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<4)))
+ never_ever(gi + 5, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<3)))
+ never_ever(gi + 6, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<2)))
+ never_ever(gi + 7, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<1)))
+ never_ever(gi + 8, c->p);
+ if (c && c->type == 4 && c->p
+ && !(c->p->flags & (1<<9)))
+ never_ever(gi + 9, c->p);
+}
+
+static void
+foo(int * interp, Pcc_cell *c)
+{
+ mark_cell(interp, c, g_pvc);
+}
+
+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, g_pvc);
+}
+
+void
+bar_2 (int * interp, Pcc_cell *c, struct PVC pvc)
+{
+ c->bla += 2;
+ mark_cell(interp, c, pvc);
+}
+
===================================================================
@@ -946,7 +946,7 @@ split_function (struct split_point *spli
bitmap args_to_skip = BITMAP_ALLOC (NULL);
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,39 @@ 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);
+ /* This parm might not have been used up to now, but is going to be
+ used, hence register it. */
+ add_referenced_var (parm);
+ if (is_gimple_reg (parm))
+ {
+ arg = gimple_default_def (cfun, parm);
+ if (!arg)
+ {
+ arg = make_ssa_name (parm, gimple_build_nop ());
+ set_default_def (parm, arg);
+ }
+ }
+ else
+ arg = parm;
+
if (TYPE_MAIN_VARIANT (DECL_ARG_TYPE (parm))
!= TYPE_MAIN_VARIANT (TREE_TYPE (arg)))
{
@@ -1057,9 +1079,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 +1090,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)