Patchwork [PR,57539] Testcase produced by multidelta and indent

login
register
mail settings
Submitter Martin Jambor
Date June 12, 2013, 12:13 p.m.
Message ID <20130612121345.GC26236@virgil.suse>
Download mbox | patch
Permalink /patch/250748/
State New
Headers show

Comments

Martin Jambor - June 12, 2013, 12:13 p.m.
Hi,

On Wed, Jun 12, 2013 at 01:59:29PM +0200, Martin Jambor wrote:
> 2013-06-10  Martin Jambor  <mjambor@suse.cz>
> 
> 	PR tree-optimization/57539
> 	* cgraphclones.c (cgraph_clone_node): Add parameter new_inlined_to, set
> 	global.inlined_to of the new node to it.  All callers changed.
> 	* ipa-inline-transform.c (clone_inlined_nodes): New variable
> 	inlining_into, pass it to cgraph_clone_node.
> 	* ipa-prop.c (ipa_propagate_indirect_call_infos): Do not call
> 	ipa_free_edge_args_substructures.
> 	(ipa_edge_duplication_hook): Only add edges from inlined nodes to
> 	rdesc linked list.  Do not assert rdesc edges have inlined caller.
> 	Assert we have found an rdesc in the rdesc list.

Creating a testcase for this bug from scratch is not particularly easy
or reliable because it requires inliner to build up a particular data
structure (and then inline it again), which depends on inlining order
which can easily change.  So I did not want to spend too much time on
it.

However, by running multidelta (several times), indent, multidelta and
indent again on the testcase supplied by the reporter I quickly came
up with the following beast.  The downside is that I have very little
understanding what the testcase does with all potential problems in
the future.  Thus I'm not sure if we want such a testcase in the
testsuite at all.  Nevertheless, it currently tests for the bug, does
not warn (without any -W options) and I'll be fine with reverting it
should any problems arise.

So, is it also OK for the trunk?

Thanks,

Martin


2013-06-11  Martin Jambor  <mjambor@suse.cz>

testsuite/
	PR tree-optimization/57539
	* gcc.dg/ipa/pr57539.c: New test.
Martin Jambor - Aug. 6, 2013, 5:48 p.m.
Hi,

nobody replied to this, presumably because nobody has any objections
but also nobody really cares, and the patch sits there in my queue.
OTOH, some time ago people on IRC told me to just commit it.  It only
adds a testcase so I'll take the risk of being yelled at and go ahead.
I believe there will be no problems but of course I'll revert it
immediately if any occur (more information why trouble may happen
below in the original mail).

Martin


On Wed, Jun 12, 2013 at 02:13:45PM +0200, Martin Jambor wrote:
> Hi,
> 
> On Wed, Jun 12, 2013 at 01:59:29PM +0200, Martin Jambor wrote:
> > 2013-06-10  Martin Jambor  <mjambor@suse.cz>
> > 
> > 	PR tree-optimization/57539
> > 	* cgraphclones.c (cgraph_clone_node): Add parameter new_inlined_to, set
> > 	global.inlined_to of the new node to it.  All callers changed.
> > 	* ipa-inline-transform.c (clone_inlined_nodes): New variable
> > 	inlining_into, pass it to cgraph_clone_node.
> > 	* ipa-prop.c (ipa_propagate_indirect_call_infos): Do not call
> > 	ipa_free_edge_args_substructures.
> > 	(ipa_edge_duplication_hook): Only add edges from inlined nodes to
> > 	rdesc linked list.  Do not assert rdesc edges have inlined caller.
> > 	Assert we have found an rdesc in the rdesc list.
> 
> Creating a testcase for this bug from scratch is not particularly easy
> or reliable because it requires inliner to build up a particular data
> structure (and then inline it again), which depends on inlining order
> which can easily change.  So I did not want to spend too much time on
> it.
> 
> However, by running multidelta (several times), indent, multidelta and
> indent again on the testcase supplied by the reporter I quickly came
> up with the following beast.  The downside is that I have very little
> understanding what the testcase does with all potential problems in
> the future.  Thus I'm not sure if we want such a testcase in the
> testsuite at all.  Nevertheless, it currently tests for the bug, does
> not warn (without any -W options) and I'll be fine with reverting it
> should any problems arise.
> 
> So, is it also OK for the trunk?
> 
> Thanks,
> 
> Martin
> 
> 
> 2013-06-11  Martin Jambor  <mjambor@suse.cz>
> 
> testsuite/
> 	PR tree-optimization/57539
> 	* gcc.dg/ipa/pr57539.c: New test.
> 
> Index: src/gcc/testsuite/gcc.dg/ipa/pr57539.c
> ===================================================================
> --- /dev/null
> +++ src/gcc/testsuite/gcc.dg/ipa/pr57539.c
> @@ -0,0 +1,218 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O3" } */
> +
> +typedef long unsigned int size_t;
> +typedef struct
> +{
> +}
> +box;
> +typedef struct
> +{
> +}
> +textpara_t;
> +typedef struct _dtlink_s Dtlink_t;
> +typedef struct _dtdisc_s Dtdisc_t;
> +typedef struct _dtmethod_s Dtmethod_t;
> +typedef struct _dt_s Dt_t;
> +typedef void *(*Dtmemory_f) (Dt_t *, void *, size_t, Dtdisc_t *);
> +typedef void *(*Dtsearch_f) (Dt_t *, void *, int);
> +typedef void *(*Dtmake_f) (Dt_t *, void *, Dtdisc_t *);
> +typedef void (*Dtfree_f) (Dt_t *, void *, Dtdisc_t *);
> +typedef int (*Dtcompar_f) (Dt_t *, void *, void *, Dtdisc_t *);
> +typedef unsigned int (*Dthash_f) (Dt_t *, void *, Dtdisc_t *);
> +typedef int (*Dtevent_f) (Dt_t *, int, void *, Dtdisc_t *);
> +struct _dtlink_s
> +{
> +  Dtlink_t *right;
> +};
> +struct _dtdisc_s
> +{
> +  int key;
> +  int size;
> +  int link;
> +  Dtmake_f makef;
> +  Dtfree_f freef;
> +  Dtcompar_f comparf;
> +  Dthash_f hashf;
> +  Dtmemory_f memoryf;
> +  Dtevent_f eventf;
> +};
> +struct _dt_s
> +{
> +  Dtsearch_f searchf;
> +};
> +extern Dtmethod_t *Dtobag;
> +extern Dt_t *dtopen (Dtdisc_t *, Dtmethod_t *);
> +extern Dtlink_t *dtflatten (Dt_t *);
> +typedef struct Agobj_s Agobj_t;
> +typedef struct Agraph_s Agraph_t;
> +typedef struct Agnode_s Agnode_t;
> +typedef struct Agedge_s Agedge_t;
> +typedef struct Agdesc_s Agdesc_t;
> +typedef struct Agdisc_s Agdisc_t;
> +typedef struct Agrec_s Agrec_t;
> +struct Agobj_s
> +{
> +  Agrec_t *data;
> +};
> +struct Agdesc_s
> +{
> +};
> +extern Agraph_t *agopen (char *name, Agdesc_t desc, Agdisc_t * disc);
> +extern Agnode_t *agfstnode (Agraph_t * g);
> +extern Agnode_t *agnxtnode (Agraph_t * g, Agnode_t * n);
> +extern Agedge_t *agedge (Agraph_t * g, Agnode_t * t, Agnode_t * h, char *name,
> +			 int createflag);
> +extern Agedge_t *agfstout (Agraph_t * g, Agnode_t * n);
> +extern Agedge_t *agnxtout (Agraph_t * g, Agedge_t * e);
> +extern Agdesc_t Agdirected, Agstrictdirected, Agundirected,
> +  Agstrictundirected;
> +typedef struct Agraph_s graph_t;
> +typedef struct Agnode_s node_t;
> +typedef struct Agedge_s edge_t;
> +typedef union inside_t
> +{
> +  unsigned short minlen;
> +}
> +Agedgeinfo_t;
> +extern void *gmalloc (size_t);
> +typedef enum
> +{ AM_NONE, AM_VOR, AM_SCALE, AM_NSCALE, AM_SCALEXY, AM_PUSH, AM_PUSHPULL,
> +    AM_ORTHO, AM_ORTHO_YX, AM_ORTHOXY, AM_ORTHOYX, AM_PORTHO, AM_PORTHO_YX,
> +    AM_PORTHOXY, AM_PORTHOYX, AM_COMPRESS, AM_VPSC, AM_IPSEP, AM_PRISM }
> +adjust_mode;
> +typedef struct nitem
> +{
> +  Dtlink_t link;
> +  int val;
> +  node_t *cnode;
> +  box bb;
> +}
> +nitem;
> +typedef int (*distfn) (box *, box *);
> +typedef int (*intersectfn) (nitem *, nitem *);
> +static int
> +cmpitem (Dt_t * d, int *p1, int *p2, Dtdisc_t * disc)
> +{
> +}
> +static Dtdisc_t constr =
> +  { __builtin_offsetof (nitem, val), sizeof (int), __builtin_offsetof (nitem,
> +								       link),
> +((Dtmake_f) 0), ((Dtfree_f) 0), (Dtcompar_f) cmpitem, ((Dthash_f) 0), ((Dtmemory_f) 0),
> +((Dtevent_f) 0) };
> +static int
> +distX (box * b1, box * b2)
> +{
> +}
> +
> +static int
> +intersectY0 (nitem * p, nitem * q)
> +{
> +}
> +
> +static int
> +intersectY (nitem * p, nitem * q)
> +{
> +}
> +
> +static void
> +mapGraphs (graph_t * g, graph_t * cg, distfn dist)
> +{
> +  node_t *n;
> +  edge_t *e;
> +  edge_t *ce;
> +  node_t *t;
> +  node_t *h;
> +  nitem *tp;
> +  nitem *hp;
> +  int delta;
> +  for (n = agfstnode (g); n; n = agnxtnode (g, n))
> +    {
> +      for (e = agfstout (g, n); e; e = agnxtout (g, e))
> +	{
> +	  delta = dist (&tp->bb, &hp->bb);
> +	  ce = agedge (cg, t, h, ((void *) 0), 1);
> +	  if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) < delta)
> +	    {
> +	      if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) ==
> +		  0.0)
> +		{
> +		}
> +	    }
> +	}
> +    }
> +}
> +
> +static graph_t *
> +mkNConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
> +{
> +  nitem *p;
> +  nitem *nxp;
> +  edge_t *e;
> +  graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
> +  for (p = (nitem *) dtflatten (list); p;
> +       p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
> +    {
> +      for (nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right); nxp;
> +	   nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) nxp))->right))
> +	{
> +	  if (intersect (p, nxp))
> +	    {
> +	      e = agedge (cg, p->cnode, nxp->cnode, ((void *) 0), 1);
> +	    }
> +  }} for (p = (nitem *) dtflatten (list); p;
> +	    p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
> +    {
> +    }
> +}
> +
> +static graph_t *
> +mkConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
> +{
> +  graph_t *vg;
> +  graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
> +  mapGraphs (vg, cg, dist);
> +}
> +
> +static void
> +constrainX (graph_t * g, nitem * nlist, int nnodes, intersectfn ifn,
> +	    int ortho)
> +{
> +  Dt_t *list = dtopen (&constr, Dtobag);
> +  nitem *p = nlist;
> +  graph_t *cg;
> +  int i;
> +  for (i = 0; i < nnodes; i++)
> +    {
> +      (*(((Dt_t *) (list))->searchf)) ((list), (void *) (p), 0000001);
> +      p++;
> +  } if (ortho)
> +    cg = mkConstraintG (g, list, ifn, distX);
> +  else
> +    cg = mkNConstraintG (g, list, ifn, distX);
> +}
> +
> +int
> +cAdjust (graph_t * g, int mode)
> +{
> +  int ret, i, nnodes = agnnodes (g);
> +  nitem *nlist = (nitem *) gmalloc ((nnodes) * sizeof (nitem));
> +  node_t *n;
> +  for (n = agfstnode (g); n; n = agnxtnode (g, n))
> +    {
> +    }
> +  if (overlaps (nlist, nnodes))
> +    {
> +      switch ((adjust_mode) mode)
> +	{
> +	case AM_ORTHOXY:
> +	  constrainX (g, nlist, nnodes, intersectY, 1);
> +	case AM_ORTHO:
> +	  constrainX (g, nlist, nnodes, intersectY0, 1);
> +	  constrainX (g, nlist, nnodes, intersectY, 1);
> +	case AM_PORTHO:
> +	default:
> +	  constrainX (g, nlist, nnodes, intersectY0, 0);
> +	}
> +    }
> +}
>

Patch

Index: src/gcc/testsuite/gcc.dg/ipa/pr57539.c
===================================================================
--- /dev/null
+++ src/gcc/testsuite/gcc.dg/ipa/pr57539.c
@@ -0,0 +1,218 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef long unsigned int size_t;
+typedef struct
+{
+}
+box;
+typedef struct
+{
+}
+textpara_t;
+typedef struct _dtlink_s Dtlink_t;
+typedef struct _dtdisc_s Dtdisc_t;
+typedef struct _dtmethod_s Dtmethod_t;
+typedef struct _dt_s Dt_t;
+typedef void *(*Dtmemory_f) (Dt_t *, void *, size_t, Dtdisc_t *);
+typedef void *(*Dtsearch_f) (Dt_t *, void *, int);
+typedef void *(*Dtmake_f) (Dt_t *, void *, Dtdisc_t *);
+typedef void (*Dtfree_f) (Dt_t *, void *, Dtdisc_t *);
+typedef int (*Dtcompar_f) (Dt_t *, void *, void *, Dtdisc_t *);
+typedef unsigned int (*Dthash_f) (Dt_t *, void *, Dtdisc_t *);
+typedef int (*Dtevent_f) (Dt_t *, int, void *, Dtdisc_t *);
+struct _dtlink_s
+{
+  Dtlink_t *right;
+};
+struct _dtdisc_s
+{
+  int key;
+  int size;
+  int link;
+  Dtmake_f makef;
+  Dtfree_f freef;
+  Dtcompar_f comparf;
+  Dthash_f hashf;
+  Dtmemory_f memoryf;
+  Dtevent_f eventf;
+};
+struct _dt_s
+{
+  Dtsearch_f searchf;
+};
+extern Dtmethod_t *Dtobag;
+extern Dt_t *dtopen (Dtdisc_t *, Dtmethod_t *);
+extern Dtlink_t *dtflatten (Dt_t *);
+typedef struct Agobj_s Agobj_t;
+typedef struct Agraph_s Agraph_t;
+typedef struct Agnode_s Agnode_t;
+typedef struct Agedge_s Agedge_t;
+typedef struct Agdesc_s Agdesc_t;
+typedef struct Agdisc_s Agdisc_t;
+typedef struct Agrec_s Agrec_t;
+struct Agobj_s
+{
+  Agrec_t *data;
+};
+struct Agdesc_s
+{
+};
+extern Agraph_t *agopen (char *name, Agdesc_t desc, Agdisc_t * disc);
+extern Agnode_t *agfstnode (Agraph_t * g);
+extern Agnode_t *agnxtnode (Agraph_t * g, Agnode_t * n);
+extern Agedge_t *agedge (Agraph_t * g, Agnode_t * t, Agnode_t * h, char *name,
+			 int createflag);
+extern Agedge_t *agfstout (Agraph_t * g, Agnode_t * n);
+extern Agedge_t *agnxtout (Agraph_t * g, Agedge_t * e);
+extern Agdesc_t Agdirected, Agstrictdirected, Agundirected,
+  Agstrictundirected;
+typedef struct Agraph_s graph_t;
+typedef struct Agnode_s node_t;
+typedef struct Agedge_s edge_t;
+typedef union inside_t
+{
+  unsigned short minlen;
+}
+Agedgeinfo_t;
+extern void *gmalloc (size_t);
+typedef enum
+{ AM_NONE, AM_VOR, AM_SCALE, AM_NSCALE, AM_SCALEXY, AM_PUSH, AM_PUSHPULL,
+    AM_ORTHO, AM_ORTHO_YX, AM_ORTHOXY, AM_ORTHOYX, AM_PORTHO, AM_PORTHO_YX,
+    AM_PORTHOXY, AM_PORTHOYX, AM_COMPRESS, AM_VPSC, AM_IPSEP, AM_PRISM }
+adjust_mode;
+typedef struct nitem
+{
+  Dtlink_t link;
+  int val;
+  node_t *cnode;
+  box bb;
+}
+nitem;
+typedef int (*distfn) (box *, box *);
+typedef int (*intersectfn) (nitem *, nitem *);
+static int
+cmpitem (Dt_t * d, int *p1, int *p2, Dtdisc_t * disc)
+{
+}
+static Dtdisc_t constr =
+  { __builtin_offsetof (nitem, val), sizeof (int), __builtin_offsetof (nitem,
+								       link),
+((Dtmake_f) 0), ((Dtfree_f) 0), (Dtcompar_f) cmpitem, ((Dthash_f) 0), ((Dtmemory_f) 0),
+((Dtevent_f) 0) };
+static int
+distX (box * b1, box * b2)
+{
+}
+
+static int
+intersectY0 (nitem * p, nitem * q)
+{
+}
+
+static int
+intersectY (nitem * p, nitem * q)
+{
+}
+
+static void
+mapGraphs (graph_t * g, graph_t * cg, distfn dist)
+{
+  node_t *n;
+  edge_t *e;
+  edge_t *ce;
+  node_t *t;
+  node_t *h;
+  nitem *tp;
+  nitem *hp;
+  int delta;
+  for (n = agfstnode (g); n; n = agnxtnode (g, n))
+    {
+      for (e = agfstout (g, n); e; e = agnxtout (g, e))
+	{
+	  delta = dist (&tp->bb, &hp->bb);
+	  ce = agedge (cg, t, h, ((void *) 0), 1);
+	  if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) < delta)
+	    {
+	      if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) ==
+		  0.0)
+		{
+		}
+	    }
+	}
+    }
+}
+
+static graph_t *
+mkNConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
+{
+  nitem *p;
+  nitem *nxp;
+  edge_t *e;
+  graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
+  for (p = (nitem *) dtflatten (list); p;
+       p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
+    {
+      for (nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right); nxp;
+	   nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) nxp))->right))
+	{
+	  if (intersect (p, nxp))
+	    {
+	      e = agedge (cg, p->cnode, nxp->cnode, ((void *) 0), 1);
+	    }
+  }} for (p = (nitem *) dtflatten (list); p;
+	    p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
+    {
+    }
+}
+
+static graph_t *
+mkConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
+{
+  graph_t *vg;
+  graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
+  mapGraphs (vg, cg, dist);
+}
+
+static void
+constrainX (graph_t * g, nitem * nlist, int nnodes, intersectfn ifn,
+	    int ortho)
+{
+  Dt_t *list = dtopen (&constr, Dtobag);
+  nitem *p = nlist;
+  graph_t *cg;
+  int i;
+  for (i = 0; i < nnodes; i++)
+    {
+      (*(((Dt_t *) (list))->searchf)) ((list), (void *) (p), 0000001);
+      p++;
+  } if (ortho)
+    cg = mkConstraintG (g, list, ifn, distX);
+  else
+    cg = mkNConstraintG (g, list, ifn, distX);
+}
+
+int
+cAdjust (graph_t * g, int mode)
+{
+  int ret, i, nnodes = agnnodes (g);
+  nitem *nlist = (nitem *) gmalloc ((nnodes) * sizeof (nitem));
+  node_t *n;
+  for (n = agfstnode (g); n; n = agnxtnode (g, n))
+    {
+    }
+  if (overlaps (nlist, nnodes))
+    {
+      switch ((adjust_mode) mode)
+	{
+	case AM_ORTHOXY:
+	  constrainX (g, nlist, nnodes, intersectY, 1);
+	case AM_ORTHO:
+	  constrainX (g, nlist, nnodes, intersectY0, 1);
+	  constrainX (g, nlist, nnodes, intersectY, 1);
+	case AM_PORTHO:
+	default:
+	  constrainX (g, nlist, nnodes, intersectY0, 0);
+	}
+    }
+}