Hi, On Wed, Jun 12, 2013 at 01:59:29PM +0200, Martin Jambor wrote: > 2013-06-10 Martin Jambor <mjam...@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 <mjam...@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); + } + } +}