1/* PR rtl-optimization/25432 */
2
3void *malloc (__SIZE_TYPE__);
4void *realloc (void *, __SIZE_TYPE__);
5
6struct A { double x, y; };
7struct B { double x0, y0, x1, y1; };
8struct C { int n_points; int dir; struct B bbox; struct A *points; };
9struct D { int n_segs; struct C segs[1]; };
10
11void foo (int, int, int *, int, int *, struct A **, int *, int *,
12	  struct D *, int *, struct D **, int *, int **);
13int baz (struct A, struct A, struct A, struct A);
14
15static void
16bar (struct D *svp, int *n_points_max,
17     struct A p, int *seg_map, int *active_segs, int i)
18{
19  int asi, n_points;
20  struct C *seg;
21
22  asi = seg_map[active_segs[i]];
23  seg = &svp->segs[asi];
24  n_points = seg->n_points;
25  seg->points = ((struct A *)
26		realloc (seg->points, (n_points_max[asi] <<= 1) * sizeof (struct A)));
27  seg->points[n_points] = p;
28  seg->bbox.y1 = p.y;
29  seg->n_points++;
30}
31
32struct D *
33test (struct D *vp)
34{
35  int *active_segs, n_active_segs, *cursor, seg_idx;
36  double y, share_x;
37  int tmp1, tmp2, asi, i, j, *n_ips, *n_ips_max, n_segs_max;
38  struct A **ips, p_curs, *pts;
39  struct D *new_vp;
40  int *n_points_max, *seg_map, first_share;
41
42  n_segs_max = 16;
43  new_vp = (struct D *) malloc (sizeof (struct D) +
44				(n_segs_max - 1) * sizeof (struct C));
45  new_vp->n_segs = 0;
46
47  if (vp->n_segs == 0)
48    return new_vp;
49
50  active_segs = ((int *) malloc ((vp->n_segs) * sizeof (int)));
51  cursor = ((int *) malloc ((vp->n_segs) * sizeof (int)));
52
53  seg_map = ((int *) malloc ((vp->n_segs) * sizeof (int)));
54  n_ips = ((int *) malloc ((vp->n_segs) * sizeof (int)));
55  n_ips_max = ((int *) malloc ((vp->n_segs) * sizeof (int)));
56  ips = ((struct A * *) malloc ((vp->n_segs) * sizeof (struct A *)));
57
58  n_points_max = ((int *) malloc ((n_segs_max) * sizeof (int)));
59
60  n_active_segs = 0;
61  seg_idx = 0;
62  y = vp->segs[0].points[0].y;
63  while (seg_idx < vp->n_segs || n_active_segs > 0)
64    {
65      for (i = 0; i < n_active_segs; i++)
66	{
67	  asi = active_segs[i];
68	  if (vp->segs[asi].n_points - 1 == cursor[asi] &&
69	      vp->segs[asi].points[cursor[asi]].y == y)
70	    i--;
71	}
72
73      while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y)
74	{
75	  cursor[seg_idx] = 0;
76	  n_ips[seg_idx] = 1;
77	  n_ips_max[seg_idx] = 2;
78	  ips[seg_idx] =
79	    ((struct A *) malloc ((n_ips_max[seg_idx]) * sizeof (struct A)));
80	  ips[seg_idx][0] = vp->segs[seg_idx].points[0];
81	  pts = ((struct A *) malloc ((16) * sizeof (struct A)));
82	  pts[0] = vp->segs[seg_idx].points[0];
83	  tmp1 = seg_idx;
84	  for (j = i; j < n_active_segs; j++)
85	    {
86	      tmp2 = active_segs[j];
87	      active_segs[j] = tmp1;
88	      tmp1 = tmp2;
89	    }
90	  active_segs[n_active_segs] = tmp1;
91	  n_active_segs++;
92	  seg_idx++;
93	}
94      first_share = -1;
95      share_x = 0;
96
97      for (i = 0; i < n_active_segs; i++)
98	{
99	  asi = active_segs[i];
100	  p_curs = ips[asi][1];
101	  if (p_curs.y == y)
102	    {
103	      bar (new_vp, n_points_max,
104		   p_curs, seg_map, active_segs, i);
105
106	      n_ips[asi]--;
107	      for (j = 0; j < n_ips[asi]; j++)
108		ips[asi][j] = ips[asi][j + 1];
109
110	      if (first_share < 0 || p_curs.x != share_x)
111		{
112		  foo (first_share, i,
113		       active_segs, n_active_segs,
114		       cursor, ips, n_ips, n_ips_max, vp, seg_map,
115		       &new_vp, &n_segs_max, &n_points_max);
116		  first_share = i;
117		  share_x = p_curs.x;
118		}
119	    }
120	  else
121	    {
122	      foo (first_share, i,
123		   active_segs, n_active_segs,
124		   cursor, ips, n_ips, n_ips_max, vp, seg_map,
125		   &new_vp, &n_segs_max, &n_points_max);
126	      first_share = -1;
127	    }
128	}
129    }
130  return new_vp;
131}
132