xref: /dflybsd-src/contrib/gcc-4.7/gcc/tree-affine.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
1*e4b17023SJohn Marino /* Operations with affine combinations of trees.
2*e4b17023SJohn Marino    Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
3*e4b17023SJohn Marino 
4*e4b17023SJohn Marino This file is part of GCC.
5*e4b17023SJohn Marino 
6*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it
7*e4b17023SJohn Marino under the terms of the GNU General Public License as published by the
8*e4b17023SJohn Marino Free Software Foundation; either version 3, or (at your option) any
9*e4b17023SJohn Marino later version.
10*e4b17023SJohn Marino 
11*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT
12*e4b17023SJohn Marino ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*e4b17023SJohn Marino for more details.
15*e4b17023SJohn Marino 
16*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
17*e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
18*e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
19*e4b17023SJohn Marino 
20*e4b17023SJohn Marino #include "config.h"
21*e4b17023SJohn Marino #include "system.h"
22*e4b17023SJohn Marino #include "coretypes.h"
23*e4b17023SJohn Marino #include "tree.h"
24*e4b17023SJohn Marino #include "output.h"
25*e4b17023SJohn Marino #include "tree-pretty-print.h"
26*e4b17023SJohn Marino #include "tree-dump.h"
27*e4b17023SJohn Marino #include "pointer-set.h"
28*e4b17023SJohn Marino #include "tree-affine.h"
29*e4b17023SJohn Marino #include "gimple.h"
30*e4b17023SJohn Marino #include "flags.h"
31*e4b17023SJohn Marino 
32*e4b17023SJohn Marino /* Extends CST as appropriate for the affine combinations COMB.  */
33*e4b17023SJohn Marino 
34*e4b17023SJohn Marino double_int
double_int_ext_for_comb(double_int cst,aff_tree * comb)35*e4b17023SJohn Marino double_int_ext_for_comb (double_int cst, aff_tree *comb)
36*e4b17023SJohn Marino {
37*e4b17023SJohn Marino   return double_int_sext (cst, TYPE_PRECISION (comb->type));
38*e4b17023SJohn Marino }
39*e4b17023SJohn Marino 
40*e4b17023SJohn Marino /* Initializes affine combination COMB so that its value is zero in TYPE.  */
41*e4b17023SJohn Marino 
42*e4b17023SJohn Marino static void
aff_combination_zero(aff_tree * comb,tree type)43*e4b17023SJohn Marino aff_combination_zero (aff_tree *comb, tree type)
44*e4b17023SJohn Marino {
45*e4b17023SJohn Marino   comb->type = type;
46*e4b17023SJohn Marino   comb->offset = double_int_zero;
47*e4b17023SJohn Marino   comb->n = 0;
48*e4b17023SJohn Marino   comb->rest = NULL_TREE;
49*e4b17023SJohn Marino }
50*e4b17023SJohn Marino 
51*e4b17023SJohn Marino /* Sets COMB to CST.  */
52*e4b17023SJohn Marino 
53*e4b17023SJohn Marino void
aff_combination_const(aff_tree * comb,tree type,double_int cst)54*e4b17023SJohn Marino aff_combination_const (aff_tree *comb, tree type, double_int cst)
55*e4b17023SJohn Marino {
56*e4b17023SJohn Marino   aff_combination_zero (comb, type);
57*e4b17023SJohn Marino   comb->offset = double_int_ext_for_comb (cst, comb);
58*e4b17023SJohn Marino }
59*e4b17023SJohn Marino 
60*e4b17023SJohn Marino /* Sets COMB to single element ELT.  */
61*e4b17023SJohn Marino 
62*e4b17023SJohn Marino void
aff_combination_elt(aff_tree * comb,tree type,tree elt)63*e4b17023SJohn Marino aff_combination_elt (aff_tree *comb, tree type, tree elt)
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino   aff_combination_zero (comb, type);
66*e4b17023SJohn Marino 
67*e4b17023SJohn Marino   comb->n = 1;
68*e4b17023SJohn Marino   comb->elts[0].val = elt;
69*e4b17023SJohn Marino   comb->elts[0].coef = double_int_one;
70*e4b17023SJohn Marino }
71*e4b17023SJohn Marino 
72*e4b17023SJohn Marino /* Scales COMB by SCALE.  */
73*e4b17023SJohn Marino 
74*e4b17023SJohn Marino void
aff_combination_scale(aff_tree * comb,double_int scale)75*e4b17023SJohn Marino aff_combination_scale (aff_tree *comb, double_int scale)
76*e4b17023SJohn Marino {
77*e4b17023SJohn Marino   unsigned i, j;
78*e4b17023SJohn Marino 
79*e4b17023SJohn Marino   scale = double_int_ext_for_comb (scale, comb);
80*e4b17023SJohn Marino   if (double_int_one_p (scale))
81*e4b17023SJohn Marino     return;
82*e4b17023SJohn Marino 
83*e4b17023SJohn Marino   if (double_int_zero_p (scale))
84*e4b17023SJohn Marino     {
85*e4b17023SJohn Marino       aff_combination_zero (comb, comb->type);
86*e4b17023SJohn Marino       return;
87*e4b17023SJohn Marino     }
88*e4b17023SJohn Marino 
89*e4b17023SJohn Marino   comb->offset
90*e4b17023SJohn Marino     = double_int_ext_for_comb (double_int_mul (scale, comb->offset), comb);
91*e4b17023SJohn Marino   for (i = 0, j = 0; i < comb->n; i++)
92*e4b17023SJohn Marino     {
93*e4b17023SJohn Marino       double_int new_coef;
94*e4b17023SJohn Marino 
95*e4b17023SJohn Marino       new_coef
96*e4b17023SJohn Marino 	= double_int_ext_for_comb (double_int_mul (scale, comb->elts[i].coef),
97*e4b17023SJohn Marino 				   comb);
98*e4b17023SJohn Marino       /* A coefficient may become zero due to overflow.  Remove the zero
99*e4b17023SJohn Marino 	 elements.  */
100*e4b17023SJohn Marino       if (double_int_zero_p (new_coef))
101*e4b17023SJohn Marino 	continue;
102*e4b17023SJohn Marino       comb->elts[j].coef = new_coef;
103*e4b17023SJohn Marino       comb->elts[j].val = comb->elts[i].val;
104*e4b17023SJohn Marino       j++;
105*e4b17023SJohn Marino     }
106*e4b17023SJohn Marino   comb->n = j;
107*e4b17023SJohn Marino 
108*e4b17023SJohn Marino   if (comb->rest)
109*e4b17023SJohn Marino     {
110*e4b17023SJohn Marino       tree type = comb->type;
111*e4b17023SJohn Marino       if (POINTER_TYPE_P (type))
112*e4b17023SJohn Marino 	type = sizetype;
113*e4b17023SJohn Marino       if (comb->n < MAX_AFF_ELTS)
114*e4b17023SJohn Marino 	{
115*e4b17023SJohn Marino 	  comb->elts[comb->n].coef = scale;
116*e4b17023SJohn Marino 	  comb->elts[comb->n].val = comb->rest;
117*e4b17023SJohn Marino 	  comb->rest = NULL_TREE;
118*e4b17023SJohn Marino 	  comb->n++;
119*e4b17023SJohn Marino 	}
120*e4b17023SJohn Marino       else
121*e4b17023SJohn Marino 	comb->rest = fold_build2 (MULT_EXPR, type, comb->rest,
122*e4b17023SJohn Marino 				  double_int_to_tree (type, scale));
123*e4b17023SJohn Marino     }
124*e4b17023SJohn Marino }
125*e4b17023SJohn Marino 
126*e4b17023SJohn Marino /* Adds ELT * SCALE to COMB.  */
127*e4b17023SJohn Marino 
128*e4b17023SJohn Marino void
aff_combination_add_elt(aff_tree * comb,tree elt,double_int scale)129*e4b17023SJohn Marino aff_combination_add_elt (aff_tree *comb, tree elt, double_int scale)
130*e4b17023SJohn Marino {
131*e4b17023SJohn Marino   unsigned i;
132*e4b17023SJohn Marino   tree type;
133*e4b17023SJohn Marino 
134*e4b17023SJohn Marino   scale = double_int_ext_for_comb (scale, comb);
135*e4b17023SJohn Marino   if (double_int_zero_p (scale))
136*e4b17023SJohn Marino     return;
137*e4b17023SJohn Marino 
138*e4b17023SJohn Marino   for (i = 0; i < comb->n; i++)
139*e4b17023SJohn Marino     if (operand_equal_p (comb->elts[i].val, elt, 0))
140*e4b17023SJohn Marino       {
141*e4b17023SJohn Marino 	double_int new_coef;
142*e4b17023SJohn Marino 
143*e4b17023SJohn Marino 	new_coef = double_int_add (comb->elts[i].coef, scale);
144*e4b17023SJohn Marino 	new_coef = double_int_ext_for_comb (new_coef, comb);
145*e4b17023SJohn Marino 	if (!double_int_zero_p (new_coef))
146*e4b17023SJohn Marino 	  {
147*e4b17023SJohn Marino 	    comb->elts[i].coef = new_coef;
148*e4b17023SJohn Marino 	    return;
149*e4b17023SJohn Marino 	  }
150*e4b17023SJohn Marino 
151*e4b17023SJohn Marino 	comb->n--;
152*e4b17023SJohn Marino 	comb->elts[i] = comb->elts[comb->n];
153*e4b17023SJohn Marino 
154*e4b17023SJohn Marino 	if (comb->rest)
155*e4b17023SJohn Marino 	  {
156*e4b17023SJohn Marino 	    gcc_assert (comb->n == MAX_AFF_ELTS - 1);
157*e4b17023SJohn Marino 	    comb->elts[comb->n].coef = double_int_one;
158*e4b17023SJohn Marino 	    comb->elts[comb->n].val = comb->rest;
159*e4b17023SJohn Marino 	    comb->rest = NULL_TREE;
160*e4b17023SJohn Marino 	    comb->n++;
161*e4b17023SJohn Marino 	  }
162*e4b17023SJohn Marino 	return;
163*e4b17023SJohn Marino       }
164*e4b17023SJohn Marino   if (comb->n < MAX_AFF_ELTS)
165*e4b17023SJohn Marino     {
166*e4b17023SJohn Marino       comb->elts[comb->n].coef = scale;
167*e4b17023SJohn Marino       comb->elts[comb->n].val = elt;
168*e4b17023SJohn Marino       comb->n++;
169*e4b17023SJohn Marino       return;
170*e4b17023SJohn Marino     }
171*e4b17023SJohn Marino 
172*e4b17023SJohn Marino   type = comb->type;
173*e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
174*e4b17023SJohn Marino     type = sizetype;
175*e4b17023SJohn Marino 
176*e4b17023SJohn Marino   if (double_int_one_p (scale))
177*e4b17023SJohn Marino     elt = fold_convert (type, elt);
178*e4b17023SJohn Marino   else
179*e4b17023SJohn Marino     elt = fold_build2 (MULT_EXPR, type,
180*e4b17023SJohn Marino 		       fold_convert (type, elt),
181*e4b17023SJohn Marino 		       double_int_to_tree (type, scale));
182*e4b17023SJohn Marino 
183*e4b17023SJohn Marino   if (comb->rest)
184*e4b17023SJohn Marino     comb->rest = fold_build2 (PLUS_EXPR, type, comb->rest,
185*e4b17023SJohn Marino 			      elt);
186*e4b17023SJohn Marino   else
187*e4b17023SJohn Marino     comb->rest = elt;
188*e4b17023SJohn Marino }
189*e4b17023SJohn Marino 
190*e4b17023SJohn Marino /* Adds CST to C.  */
191*e4b17023SJohn Marino 
192*e4b17023SJohn Marino static void
aff_combination_add_cst(aff_tree * c,double_int cst)193*e4b17023SJohn Marino aff_combination_add_cst (aff_tree *c, double_int cst)
194*e4b17023SJohn Marino {
195*e4b17023SJohn Marino   c->offset = double_int_ext_for_comb (double_int_add (c->offset, cst), c);
196*e4b17023SJohn Marino }
197*e4b17023SJohn Marino 
198*e4b17023SJohn Marino /* Adds COMB2 to COMB1.  */
199*e4b17023SJohn Marino 
200*e4b17023SJohn Marino void
aff_combination_add(aff_tree * comb1,aff_tree * comb2)201*e4b17023SJohn Marino aff_combination_add (aff_tree *comb1, aff_tree *comb2)
202*e4b17023SJohn Marino {
203*e4b17023SJohn Marino   unsigned i;
204*e4b17023SJohn Marino 
205*e4b17023SJohn Marino   aff_combination_add_cst (comb1, comb2->offset);
206*e4b17023SJohn Marino   for (i = 0; i < comb2->n; i++)
207*e4b17023SJohn Marino     aff_combination_add_elt (comb1, comb2->elts[i].val, comb2->elts[i].coef);
208*e4b17023SJohn Marino   if (comb2->rest)
209*e4b17023SJohn Marino     aff_combination_add_elt (comb1, comb2->rest, double_int_one);
210*e4b17023SJohn Marino }
211*e4b17023SJohn Marino 
212*e4b17023SJohn Marino /* Converts affine combination COMB to TYPE.  */
213*e4b17023SJohn Marino 
214*e4b17023SJohn Marino void
aff_combination_convert(aff_tree * comb,tree type)215*e4b17023SJohn Marino aff_combination_convert (aff_tree *comb, tree type)
216*e4b17023SJohn Marino {
217*e4b17023SJohn Marino   unsigned i, j;
218*e4b17023SJohn Marino   tree comb_type = comb->type;
219*e4b17023SJohn Marino 
220*e4b17023SJohn Marino   if  (TYPE_PRECISION (type) > TYPE_PRECISION (comb_type))
221*e4b17023SJohn Marino     {
222*e4b17023SJohn Marino       tree val = fold_convert (type, aff_combination_to_tree (comb));
223*e4b17023SJohn Marino       tree_to_aff_combination (val, type, comb);
224*e4b17023SJohn Marino       return;
225*e4b17023SJohn Marino     }
226*e4b17023SJohn Marino 
227*e4b17023SJohn Marino   comb->type = type;
228*e4b17023SJohn Marino   if (comb->rest && !POINTER_TYPE_P (type))
229*e4b17023SJohn Marino     comb->rest = fold_convert (type, comb->rest);
230*e4b17023SJohn Marino 
231*e4b17023SJohn Marino   if (TYPE_PRECISION (type) == TYPE_PRECISION (comb_type))
232*e4b17023SJohn Marino     return;
233*e4b17023SJohn Marino 
234*e4b17023SJohn Marino   comb->offset = double_int_ext_for_comb (comb->offset, comb);
235*e4b17023SJohn Marino   for (i = j = 0; i < comb->n; i++)
236*e4b17023SJohn Marino     {
237*e4b17023SJohn Marino       double_int new_coef = double_int_ext_for_comb (comb->elts[i].coef, comb);
238*e4b17023SJohn Marino       if (double_int_zero_p (new_coef))
239*e4b17023SJohn Marino 	continue;
240*e4b17023SJohn Marino       comb->elts[j].coef = new_coef;
241*e4b17023SJohn Marino       comb->elts[j].val = fold_convert (type, comb->elts[i].val);
242*e4b17023SJohn Marino       j++;
243*e4b17023SJohn Marino     }
244*e4b17023SJohn Marino 
245*e4b17023SJohn Marino   comb->n = j;
246*e4b17023SJohn Marino   if (comb->n < MAX_AFF_ELTS && comb->rest)
247*e4b17023SJohn Marino     {
248*e4b17023SJohn Marino       comb->elts[comb->n].coef = double_int_one;
249*e4b17023SJohn Marino       comb->elts[comb->n].val = comb->rest;
250*e4b17023SJohn Marino       comb->rest = NULL_TREE;
251*e4b17023SJohn Marino       comb->n++;
252*e4b17023SJohn Marino     }
253*e4b17023SJohn Marino }
254*e4b17023SJohn Marino 
255*e4b17023SJohn Marino /* Splits EXPR into an affine combination of parts.  */
256*e4b17023SJohn Marino 
257*e4b17023SJohn Marino void
tree_to_aff_combination(tree expr,tree type,aff_tree * comb)258*e4b17023SJohn Marino tree_to_aff_combination (tree expr, tree type, aff_tree *comb)
259*e4b17023SJohn Marino {
260*e4b17023SJohn Marino   aff_tree tmp;
261*e4b17023SJohn Marino   enum tree_code code;
262*e4b17023SJohn Marino   tree cst, core, toffset;
263*e4b17023SJohn Marino   HOST_WIDE_INT bitpos, bitsize;
264*e4b17023SJohn Marino   enum machine_mode mode;
265*e4b17023SJohn Marino   int unsignedp, volatilep;
266*e4b17023SJohn Marino 
267*e4b17023SJohn Marino   STRIP_NOPS (expr);
268*e4b17023SJohn Marino 
269*e4b17023SJohn Marino   code = TREE_CODE (expr);
270*e4b17023SJohn Marino   switch (code)
271*e4b17023SJohn Marino     {
272*e4b17023SJohn Marino     case INTEGER_CST:
273*e4b17023SJohn Marino       aff_combination_const (comb, type, tree_to_double_int (expr));
274*e4b17023SJohn Marino       return;
275*e4b17023SJohn Marino 
276*e4b17023SJohn Marino     case POINTER_PLUS_EXPR:
277*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
278*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
279*e4b17023SJohn Marino       aff_combination_add (comb, &tmp);
280*e4b17023SJohn Marino       return;
281*e4b17023SJohn Marino 
282*e4b17023SJohn Marino     case PLUS_EXPR:
283*e4b17023SJohn Marino     case MINUS_EXPR:
284*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
285*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 1), type, &tmp);
286*e4b17023SJohn Marino       if (code == MINUS_EXPR)
287*e4b17023SJohn Marino 	aff_combination_scale (&tmp, double_int_minus_one);
288*e4b17023SJohn Marino       aff_combination_add (comb, &tmp);
289*e4b17023SJohn Marino       return;
290*e4b17023SJohn Marino 
291*e4b17023SJohn Marino     case MULT_EXPR:
292*e4b17023SJohn Marino       cst = TREE_OPERAND (expr, 1);
293*e4b17023SJohn Marino       if (TREE_CODE (cst) != INTEGER_CST)
294*e4b17023SJohn Marino 	break;
295*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
296*e4b17023SJohn Marino       aff_combination_scale (comb, tree_to_double_int (cst));
297*e4b17023SJohn Marino       return;
298*e4b17023SJohn Marino 
299*e4b17023SJohn Marino     case NEGATE_EXPR:
300*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
301*e4b17023SJohn Marino       aff_combination_scale (comb, double_int_minus_one);
302*e4b17023SJohn Marino       return;
303*e4b17023SJohn Marino 
304*e4b17023SJohn Marino     case BIT_NOT_EXPR:
305*e4b17023SJohn Marino       /* ~x = -x - 1 */
306*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
307*e4b17023SJohn Marino       aff_combination_scale (comb, double_int_minus_one);
308*e4b17023SJohn Marino       aff_combination_add_cst (comb, double_int_minus_one);
309*e4b17023SJohn Marino       return;
310*e4b17023SJohn Marino 
311*e4b17023SJohn Marino     case ADDR_EXPR:
312*e4b17023SJohn Marino       /* Handle &MEM[ptr + CST] which is equivalent to POINTER_PLUS_EXPR.  */
313*e4b17023SJohn Marino       if (TREE_CODE (TREE_OPERAND (expr, 0)) == MEM_REF)
314*e4b17023SJohn Marino 	{
315*e4b17023SJohn Marino 	  expr = TREE_OPERAND (expr, 0);
316*e4b17023SJohn Marino 	  tree_to_aff_combination (TREE_OPERAND (expr, 0), type, comb);
317*e4b17023SJohn Marino 	  tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
318*e4b17023SJohn Marino 	  aff_combination_add (comb, &tmp);
319*e4b17023SJohn Marino 	  return;
320*e4b17023SJohn Marino 	}
321*e4b17023SJohn Marino       core = get_inner_reference (TREE_OPERAND (expr, 0), &bitsize, &bitpos,
322*e4b17023SJohn Marino 				  &toffset, &mode, &unsignedp, &volatilep,
323*e4b17023SJohn Marino 				  false);
324*e4b17023SJohn Marino       if (bitpos % BITS_PER_UNIT != 0)
325*e4b17023SJohn Marino 	break;
326*e4b17023SJohn Marino       aff_combination_const (comb, type,
327*e4b17023SJohn Marino 			     uhwi_to_double_int (bitpos / BITS_PER_UNIT));
328*e4b17023SJohn Marino       core = build_fold_addr_expr (core);
329*e4b17023SJohn Marino       if (TREE_CODE (core) == ADDR_EXPR)
330*e4b17023SJohn Marino 	aff_combination_add_elt (comb, core, double_int_one);
331*e4b17023SJohn Marino       else
332*e4b17023SJohn Marino 	{
333*e4b17023SJohn Marino 	  tree_to_aff_combination (core, type, &tmp);
334*e4b17023SJohn Marino 	  aff_combination_add (comb, &tmp);
335*e4b17023SJohn Marino 	}
336*e4b17023SJohn Marino       if (toffset)
337*e4b17023SJohn Marino 	{
338*e4b17023SJohn Marino 	  tree_to_aff_combination (toffset, type, &tmp);
339*e4b17023SJohn Marino 	  aff_combination_add (comb, &tmp);
340*e4b17023SJohn Marino 	}
341*e4b17023SJohn Marino       return;
342*e4b17023SJohn Marino 
343*e4b17023SJohn Marino     case MEM_REF:
344*e4b17023SJohn Marino       if (TREE_CODE (TREE_OPERAND (expr, 0)) == ADDR_EXPR)
345*e4b17023SJohn Marino 	tree_to_aff_combination (TREE_OPERAND (TREE_OPERAND (expr, 0), 0),
346*e4b17023SJohn Marino 				 type, comb);
347*e4b17023SJohn Marino       else if (integer_zerop (TREE_OPERAND (expr, 1)))
348*e4b17023SJohn Marino 	{
349*e4b17023SJohn Marino 	  aff_combination_elt (comb, type, expr);
350*e4b17023SJohn Marino 	  return;
351*e4b17023SJohn Marino 	}
352*e4b17023SJohn Marino       else
353*e4b17023SJohn Marino 	aff_combination_elt (comb, type,
354*e4b17023SJohn Marino 			     build2 (MEM_REF, TREE_TYPE (expr),
355*e4b17023SJohn Marino 				     TREE_OPERAND (expr, 0),
356*e4b17023SJohn Marino 				     build_int_cst
357*e4b17023SJohn Marino 				      (TREE_TYPE (TREE_OPERAND (expr, 1)), 0)));
358*e4b17023SJohn Marino       tree_to_aff_combination (TREE_OPERAND (expr, 1), sizetype, &tmp);
359*e4b17023SJohn Marino       aff_combination_add (comb, &tmp);
360*e4b17023SJohn Marino       return;
361*e4b17023SJohn Marino 
362*e4b17023SJohn Marino     default:
363*e4b17023SJohn Marino       break;
364*e4b17023SJohn Marino     }
365*e4b17023SJohn Marino 
366*e4b17023SJohn Marino   aff_combination_elt (comb, type, expr);
367*e4b17023SJohn Marino }
368*e4b17023SJohn Marino 
369*e4b17023SJohn Marino /* Creates EXPR + ELT * SCALE in TYPE.  EXPR is taken from affine
370*e4b17023SJohn Marino    combination COMB.  */
371*e4b17023SJohn Marino 
372*e4b17023SJohn Marino static tree
add_elt_to_tree(tree expr,tree type,tree elt,double_int scale,aff_tree * comb)373*e4b17023SJohn Marino add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
374*e4b17023SJohn Marino 		 aff_tree *comb)
375*e4b17023SJohn Marino {
376*e4b17023SJohn Marino   enum tree_code code;
377*e4b17023SJohn Marino   tree type1 = type;
378*e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
379*e4b17023SJohn Marino     type1 = sizetype;
380*e4b17023SJohn Marino 
381*e4b17023SJohn Marino   scale = double_int_ext_for_comb (scale, comb);
382*e4b17023SJohn Marino   elt = fold_convert (type1, elt);
383*e4b17023SJohn Marino 
384*e4b17023SJohn Marino   if (double_int_one_p (scale))
385*e4b17023SJohn Marino     {
386*e4b17023SJohn Marino       if (!expr)
387*e4b17023SJohn Marino 	return fold_convert (type, elt);
388*e4b17023SJohn Marino 
389*e4b17023SJohn Marino       if (POINTER_TYPE_P (type))
390*e4b17023SJohn Marino         return fold_build_pointer_plus (expr, elt);
391*e4b17023SJohn Marino       return fold_build2 (PLUS_EXPR, type, expr, elt);
392*e4b17023SJohn Marino     }
393*e4b17023SJohn Marino 
394*e4b17023SJohn Marino   if (double_int_minus_one_p (scale))
395*e4b17023SJohn Marino     {
396*e4b17023SJohn Marino       if (!expr)
397*e4b17023SJohn Marino 	return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt));
398*e4b17023SJohn Marino 
399*e4b17023SJohn Marino       if (POINTER_TYPE_P (type))
400*e4b17023SJohn Marino 	{
401*e4b17023SJohn Marino 	  elt = fold_build1 (NEGATE_EXPR, type1, elt);
402*e4b17023SJohn Marino 	  return fold_build_pointer_plus (expr, elt);
403*e4b17023SJohn Marino 	}
404*e4b17023SJohn Marino       return fold_build2 (MINUS_EXPR, type, expr, elt);
405*e4b17023SJohn Marino     }
406*e4b17023SJohn Marino 
407*e4b17023SJohn Marino   if (!expr)
408*e4b17023SJohn Marino     return fold_convert (type,
409*e4b17023SJohn Marino 			 fold_build2 (MULT_EXPR, type1, elt,
410*e4b17023SJohn Marino 				      double_int_to_tree (type1, scale)));
411*e4b17023SJohn Marino 
412*e4b17023SJohn Marino   if (double_int_negative_p (scale))
413*e4b17023SJohn Marino     {
414*e4b17023SJohn Marino       code = MINUS_EXPR;
415*e4b17023SJohn Marino       scale = double_int_neg (scale);
416*e4b17023SJohn Marino     }
417*e4b17023SJohn Marino   else
418*e4b17023SJohn Marino     code = PLUS_EXPR;
419*e4b17023SJohn Marino 
420*e4b17023SJohn Marino   elt = fold_build2 (MULT_EXPR, type1, elt,
421*e4b17023SJohn Marino 		     double_int_to_tree (type1, scale));
422*e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
423*e4b17023SJohn Marino     {
424*e4b17023SJohn Marino       if (code == MINUS_EXPR)
425*e4b17023SJohn Marino         elt = fold_build1 (NEGATE_EXPR, type1, elt);
426*e4b17023SJohn Marino       return fold_build_pointer_plus (expr, elt);
427*e4b17023SJohn Marino     }
428*e4b17023SJohn Marino   return fold_build2 (code, type, expr, elt);
429*e4b17023SJohn Marino }
430*e4b17023SJohn Marino 
431*e4b17023SJohn Marino /* Makes tree from the affine combination COMB.  */
432*e4b17023SJohn Marino 
433*e4b17023SJohn Marino tree
aff_combination_to_tree(aff_tree * comb)434*e4b17023SJohn Marino aff_combination_to_tree (aff_tree *comb)
435*e4b17023SJohn Marino {
436*e4b17023SJohn Marino   tree type = comb->type;
437*e4b17023SJohn Marino   tree expr = NULL_TREE;
438*e4b17023SJohn Marino   unsigned i;
439*e4b17023SJohn Marino   double_int off, sgn;
440*e4b17023SJohn Marino   tree type1 = type;
441*e4b17023SJohn Marino   if (POINTER_TYPE_P (type))
442*e4b17023SJohn Marino     type1 = sizetype;
443*e4b17023SJohn Marino 
444*e4b17023SJohn Marino   gcc_assert (comb->n == MAX_AFF_ELTS || comb->rest == NULL_TREE);
445*e4b17023SJohn Marino 
446*e4b17023SJohn Marino   for (i = 0; i < comb->n; i++)
447*e4b17023SJohn Marino     expr = add_elt_to_tree (expr, type, comb->elts[i].val, comb->elts[i].coef,
448*e4b17023SJohn Marino 			    comb);
449*e4b17023SJohn Marino 
450*e4b17023SJohn Marino   if (comb->rest)
451*e4b17023SJohn Marino     expr = add_elt_to_tree (expr, type, comb->rest, double_int_one, comb);
452*e4b17023SJohn Marino 
453*e4b17023SJohn Marino   /* Ensure that we get x - 1, not x + (-1) or x + 0xff..f if x is
454*e4b17023SJohn Marino      unsigned.  */
455*e4b17023SJohn Marino   if (double_int_negative_p (comb->offset))
456*e4b17023SJohn Marino     {
457*e4b17023SJohn Marino       off = double_int_neg (comb->offset);
458*e4b17023SJohn Marino       sgn = double_int_minus_one;
459*e4b17023SJohn Marino     }
460*e4b17023SJohn Marino   else
461*e4b17023SJohn Marino     {
462*e4b17023SJohn Marino       off = comb->offset;
463*e4b17023SJohn Marino       sgn = double_int_one;
464*e4b17023SJohn Marino     }
465*e4b17023SJohn Marino   return add_elt_to_tree (expr, type, double_int_to_tree (type1, off), sgn,
466*e4b17023SJohn Marino 			  comb);
467*e4b17023SJohn Marino }
468*e4b17023SJohn Marino 
469*e4b17023SJohn Marino /* Copies the tree elements of COMB to ensure that they are not shared.  */
470*e4b17023SJohn Marino 
471*e4b17023SJohn Marino void
unshare_aff_combination(aff_tree * comb)472*e4b17023SJohn Marino unshare_aff_combination (aff_tree *comb)
473*e4b17023SJohn Marino {
474*e4b17023SJohn Marino   unsigned i;
475*e4b17023SJohn Marino 
476*e4b17023SJohn Marino   for (i = 0; i < comb->n; i++)
477*e4b17023SJohn Marino     comb->elts[i].val = unshare_expr (comb->elts[i].val);
478*e4b17023SJohn Marino   if (comb->rest)
479*e4b17023SJohn Marino     comb->rest = unshare_expr (comb->rest);
480*e4b17023SJohn Marino }
481*e4b17023SJohn Marino 
482*e4b17023SJohn Marino /* Remove M-th element from COMB.  */
483*e4b17023SJohn Marino 
484*e4b17023SJohn Marino void
aff_combination_remove_elt(aff_tree * comb,unsigned m)485*e4b17023SJohn Marino aff_combination_remove_elt (aff_tree *comb, unsigned m)
486*e4b17023SJohn Marino {
487*e4b17023SJohn Marino   comb->n--;
488*e4b17023SJohn Marino   if (m <= comb->n)
489*e4b17023SJohn Marino     comb->elts[m] = comb->elts[comb->n];
490*e4b17023SJohn Marino   if (comb->rest)
491*e4b17023SJohn Marino     {
492*e4b17023SJohn Marino       comb->elts[comb->n].coef = double_int_one;
493*e4b17023SJohn Marino       comb->elts[comb->n].val = comb->rest;
494*e4b17023SJohn Marino       comb->rest = NULL_TREE;
495*e4b17023SJohn Marino       comb->n++;
496*e4b17023SJohn Marino     }
497*e4b17023SJohn Marino }
498*e4b17023SJohn Marino 
499*e4b17023SJohn Marino /* Adds C * COEF * VAL to R.  VAL may be NULL, in that case only
500*e4b17023SJohn Marino    C * COEF is added to R.  */
501*e4b17023SJohn Marino 
502*e4b17023SJohn Marino 
503*e4b17023SJohn Marino static void
aff_combination_add_product(aff_tree * c,double_int coef,tree val,aff_tree * r)504*e4b17023SJohn Marino aff_combination_add_product (aff_tree *c, double_int coef, tree val,
505*e4b17023SJohn Marino 			     aff_tree *r)
506*e4b17023SJohn Marino {
507*e4b17023SJohn Marino   unsigned i;
508*e4b17023SJohn Marino   tree aval, type;
509*e4b17023SJohn Marino 
510*e4b17023SJohn Marino   for (i = 0; i < c->n; i++)
511*e4b17023SJohn Marino     {
512*e4b17023SJohn Marino       aval = c->elts[i].val;
513*e4b17023SJohn Marino       if (val)
514*e4b17023SJohn Marino 	{
515*e4b17023SJohn Marino 	  type = TREE_TYPE (aval);
516*e4b17023SJohn Marino 	  aval = fold_build2 (MULT_EXPR, type, aval,
517*e4b17023SJohn Marino 			      fold_convert (type, val));
518*e4b17023SJohn Marino 	}
519*e4b17023SJohn Marino 
520*e4b17023SJohn Marino       aff_combination_add_elt (r, aval,
521*e4b17023SJohn Marino 			       double_int_mul (coef, c->elts[i].coef));
522*e4b17023SJohn Marino     }
523*e4b17023SJohn Marino 
524*e4b17023SJohn Marino   if (c->rest)
525*e4b17023SJohn Marino     {
526*e4b17023SJohn Marino       aval = c->rest;
527*e4b17023SJohn Marino       if (val)
528*e4b17023SJohn Marino 	{
529*e4b17023SJohn Marino 	  type = TREE_TYPE (aval);
530*e4b17023SJohn Marino 	  aval = fold_build2 (MULT_EXPR, type, aval,
531*e4b17023SJohn Marino 			      fold_convert (type, val));
532*e4b17023SJohn Marino 	}
533*e4b17023SJohn Marino 
534*e4b17023SJohn Marino       aff_combination_add_elt (r, aval, coef);
535*e4b17023SJohn Marino     }
536*e4b17023SJohn Marino 
537*e4b17023SJohn Marino   if (val)
538*e4b17023SJohn Marino     aff_combination_add_elt (r, val,
539*e4b17023SJohn Marino 			     double_int_mul (coef, c->offset));
540*e4b17023SJohn Marino   else
541*e4b17023SJohn Marino     aff_combination_add_cst (r, double_int_mul (coef, c->offset));
542*e4b17023SJohn Marino }
543*e4b17023SJohn Marino 
544*e4b17023SJohn Marino /* Multiplies C1 by C2, storing the result to R  */
545*e4b17023SJohn Marino 
546*e4b17023SJohn Marino void
aff_combination_mult(aff_tree * c1,aff_tree * c2,aff_tree * r)547*e4b17023SJohn Marino aff_combination_mult (aff_tree *c1, aff_tree *c2, aff_tree *r)
548*e4b17023SJohn Marino {
549*e4b17023SJohn Marino   unsigned i;
550*e4b17023SJohn Marino   gcc_assert (TYPE_PRECISION (c1->type) == TYPE_PRECISION (c2->type));
551*e4b17023SJohn Marino 
552*e4b17023SJohn Marino   aff_combination_zero (r, c1->type);
553*e4b17023SJohn Marino 
554*e4b17023SJohn Marino   for (i = 0; i < c2->n; i++)
555*e4b17023SJohn Marino     aff_combination_add_product (c1, c2->elts[i].coef, c2->elts[i].val, r);
556*e4b17023SJohn Marino   if (c2->rest)
557*e4b17023SJohn Marino     aff_combination_add_product (c1, double_int_one, c2->rest, r);
558*e4b17023SJohn Marino   aff_combination_add_product (c1, c2->offset, NULL, r);
559*e4b17023SJohn Marino }
560*e4b17023SJohn Marino 
561*e4b17023SJohn Marino /* Returns the element of COMB whose value is VAL, or NULL if no such
562*e4b17023SJohn Marino    element exists.  If IDX is not NULL, it is set to the index of VAL in
563*e4b17023SJohn Marino    COMB.  */
564*e4b17023SJohn Marino 
565*e4b17023SJohn Marino static struct aff_comb_elt *
aff_combination_find_elt(aff_tree * comb,tree val,unsigned * idx)566*e4b17023SJohn Marino aff_combination_find_elt (aff_tree *comb, tree val, unsigned *idx)
567*e4b17023SJohn Marino {
568*e4b17023SJohn Marino   unsigned i;
569*e4b17023SJohn Marino 
570*e4b17023SJohn Marino   for (i = 0; i < comb->n; i++)
571*e4b17023SJohn Marino     if (operand_equal_p (comb->elts[i].val, val, 0))
572*e4b17023SJohn Marino       {
573*e4b17023SJohn Marino 	if (idx)
574*e4b17023SJohn Marino 	  *idx = i;
575*e4b17023SJohn Marino 
576*e4b17023SJohn Marino 	return &comb->elts[i];
577*e4b17023SJohn Marino       }
578*e4b17023SJohn Marino 
579*e4b17023SJohn Marino   return NULL;
580*e4b17023SJohn Marino }
581*e4b17023SJohn Marino 
582*e4b17023SJohn Marino /* Element of the cache that maps ssa name NAME to its expanded form
583*e4b17023SJohn Marino    as an affine expression EXPANSION.  */
584*e4b17023SJohn Marino 
585*e4b17023SJohn Marino struct name_expansion
586*e4b17023SJohn Marino {
587*e4b17023SJohn Marino   aff_tree expansion;
588*e4b17023SJohn Marino 
589*e4b17023SJohn Marino   /* True if the expansion for the name is just being generated.  */
590*e4b17023SJohn Marino   unsigned in_progress : 1;
591*e4b17023SJohn Marino };
592*e4b17023SJohn Marino 
593*e4b17023SJohn Marino /* Expands SSA names in COMB recursively.  CACHE is used to cache the
594*e4b17023SJohn Marino    results.  */
595*e4b17023SJohn Marino 
596*e4b17023SJohn Marino void
aff_combination_expand(aff_tree * comb ATTRIBUTE_UNUSED,struct pointer_map_t ** cache ATTRIBUTE_UNUSED)597*e4b17023SJohn Marino aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
598*e4b17023SJohn Marino 			struct pointer_map_t **cache ATTRIBUTE_UNUSED)
599*e4b17023SJohn Marino {
600*e4b17023SJohn Marino   unsigned i;
601*e4b17023SJohn Marino   aff_tree to_add, current, curre;
602*e4b17023SJohn Marino   tree e, rhs;
603*e4b17023SJohn Marino   gimple def;
604*e4b17023SJohn Marino   double_int scale;
605*e4b17023SJohn Marino   void **slot;
606*e4b17023SJohn Marino   struct name_expansion *exp;
607*e4b17023SJohn Marino 
608*e4b17023SJohn Marino   aff_combination_zero (&to_add, comb->type);
609*e4b17023SJohn Marino   for (i = 0; i < comb->n; i++)
610*e4b17023SJohn Marino     {
611*e4b17023SJohn Marino       tree type, name;
612*e4b17023SJohn Marino       enum tree_code code;
613*e4b17023SJohn Marino 
614*e4b17023SJohn Marino       e = comb->elts[i].val;
615*e4b17023SJohn Marino       type = TREE_TYPE (e);
616*e4b17023SJohn Marino       name = e;
617*e4b17023SJohn Marino       /* Look through some conversions.  */
618*e4b17023SJohn Marino       if (TREE_CODE (e) == NOP_EXPR
619*e4b17023SJohn Marino           && (TYPE_PRECISION (type)
620*e4b17023SJohn Marino 	      >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (e, 0)))))
621*e4b17023SJohn Marino 	name = TREE_OPERAND (e, 0);
622*e4b17023SJohn Marino       if (TREE_CODE (name) != SSA_NAME)
623*e4b17023SJohn Marino 	continue;
624*e4b17023SJohn Marino       def = SSA_NAME_DEF_STMT (name);
625*e4b17023SJohn Marino       if (!is_gimple_assign (def) || gimple_assign_lhs (def) != name)
626*e4b17023SJohn Marino 	continue;
627*e4b17023SJohn Marino 
628*e4b17023SJohn Marino       code = gimple_assign_rhs_code (def);
629*e4b17023SJohn Marino       if (code != SSA_NAME
630*e4b17023SJohn Marino 	  && !IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
631*e4b17023SJohn Marino 	  && (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
632*e4b17023SJohn Marino 	      || !is_gimple_min_invariant (gimple_assign_rhs1 (def))))
633*e4b17023SJohn Marino 	continue;
634*e4b17023SJohn Marino 
635*e4b17023SJohn Marino       /* We do not know whether the reference retains its value at the
636*e4b17023SJohn Marino 	 place where the expansion is used.  */
637*e4b17023SJohn Marino       if (TREE_CODE_CLASS (code) == tcc_reference)
638*e4b17023SJohn Marino 	continue;
639*e4b17023SJohn Marino 
640*e4b17023SJohn Marino       if (!*cache)
641*e4b17023SJohn Marino 	*cache = pointer_map_create ();
642*e4b17023SJohn Marino       slot = pointer_map_insert (*cache, e);
643*e4b17023SJohn Marino       exp = (struct name_expansion *) *slot;
644*e4b17023SJohn Marino 
645*e4b17023SJohn Marino       if (!exp)
646*e4b17023SJohn Marino 	{
647*e4b17023SJohn Marino 	  exp = XNEW (struct name_expansion);
648*e4b17023SJohn Marino 	  exp->in_progress = 1;
649*e4b17023SJohn Marino 	  *slot = exp;
650*e4b17023SJohn Marino 	  /* In principle this is a generally valid folding, but
651*e4b17023SJohn Marino 	     it is not unconditionally an optimization, so do it
652*e4b17023SJohn Marino 	     here and not in fold_unary.  */
653*e4b17023SJohn Marino 	  /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
654*e4b17023SJohn Marino 	     than the type of X and overflow for the type of X is
655*e4b17023SJohn Marino 	     undefined.  */
656*e4b17023SJohn Marino 	  if (e != name
657*e4b17023SJohn Marino 	      && INTEGRAL_TYPE_P (type)
658*e4b17023SJohn Marino 	      && INTEGRAL_TYPE_P (TREE_TYPE (name))
659*e4b17023SJohn Marino 	      && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (name))
660*e4b17023SJohn Marino 	      && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (name))
661*e4b17023SJohn Marino 	      && (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
662*e4b17023SJohn Marino 	      && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
663*e4b17023SJohn Marino 	    rhs = fold_build2 (code, type,
664*e4b17023SJohn Marino 			       fold_convert (type, gimple_assign_rhs1 (def)),
665*e4b17023SJohn Marino 			       fold_convert (type, gimple_assign_rhs2 (def)));
666*e4b17023SJohn Marino 	  else
667*e4b17023SJohn Marino 	    {
668*e4b17023SJohn Marino 	      rhs = gimple_assign_rhs_to_tree (def);
669*e4b17023SJohn Marino 	      if (e != name)
670*e4b17023SJohn Marino 		rhs = fold_convert (type, rhs);
671*e4b17023SJohn Marino 	    }
672*e4b17023SJohn Marino 	  tree_to_aff_combination_expand (rhs, comb->type, &current, cache);
673*e4b17023SJohn Marino 	  exp->expansion = current;
674*e4b17023SJohn Marino 	  exp->in_progress = 0;
675*e4b17023SJohn Marino 	}
676*e4b17023SJohn Marino       else
677*e4b17023SJohn Marino 	{
678*e4b17023SJohn Marino 	  /* Since we follow the definitions in the SSA form, we should not
679*e4b17023SJohn Marino 	     enter a cycle unless we pass through a phi node.  */
680*e4b17023SJohn Marino 	  gcc_assert (!exp->in_progress);
681*e4b17023SJohn Marino 	  current = exp->expansion;
682*e4b17023SJohn Marino 	}
683*e4b17023SJohn Marino 
684*e4b17023SJohn Marino       /* Accumulate the new terms to TO_ADD, so that we do not modify
685*e4b17023SJohn Marino 	 COMB while traversing it; include the term -coef * E, to remove
686*e4b17023SJohn Marino          it from COMB.  */
687*e4b17023SJohn Marino       scale = comb->elts[i].coef;
688*e4b17023SJohn Marino       aff_combination_zero (&curre, comb->type);
689*e4b17023SJohn Marino       aff_combination_add_elt (&curre, e, double_int_neg (scale));
690*e4b17023SJohn Marino       aff_combination_scale (&current, scale);
691*e4b17023SJohn Marino       aff_combination_add (&to_add, &current);
692*e4b17023SJohn Marino       aff_combination_add (&to_add, &curre);
693*e4b17023SJohn Marino     }
694*e4b17023SJohn Marino   aff_combination_add (comb, &to_add);
695*e4b17023SJohn Marino }
696*e4b17023SJohn Marino 
697*e4b17023SJohn Marino /* Similar to tree_to_aff_combination, but follows SSA name definitions
698*e4b17023SJohn Marino    and expands them recursively.  CACHE is used to cache the expansions
699*e4b17023SJohn Marino    of the ssa names, to avoid exponential time complexity for cases
700*e4b17023SJohn Marino    like
701*e4b17023SJohn Marino 
702*e4b17023SJohn Marino    a1 = a0 + a0;
703*e4b17023SJohn Marino    a2 = a1 + a1;
704*e4b17023SJohn Marino    a3 = a2 + a2;
705*e4b17023SJohn Marino    ...  */
706*e4b17023SJohn Marino 
707*e4b17023SJohn Marino void
tree_to_aff_combination_expand(tree expr,tree type,aff_tree * comb,struct pointer_map_t ** cache)708*e4b17023SJohn Marino tree_to_aff_combination_expand (tree expr, tree type, aff_tree *comb,
709*e4b17023SJohn Marino 				struct pointer_map_t **cache)
710*e4b17023SJohn Marino {
711*e4b17023SJohn Marino   tree_to_aff_combination (expr, type, comb);
712*e4b17023SJohn Marino   aff_combination_expand (comb, cache);
713*e4b17023SJohn Marino }
714*e4b17023SJohn Marino 
715*e4b17023SJohn Marino /* Frees memory occupied by struct name_expansion in *VALUE.  Callback for
716*e4b17023SJohn Marino    pointer_map_traverse.  */
717*e4b17023SJohn Marino 
718*e4b17023SJohn Marino static bool
free_name_expansion(const void * key ATTRIBUTE_UNUSED,void ** value,void * data ATTRIBUTE_UNUSED)719*e4b17023SJohn Marino free_name_expansion (const void *key ATTRIBUTE_UNUSED, void **value,
720*e4b17023SJohn Marino 		     void *data ATTRIBUTE_UNUSED)
721*e4b17023SJohn Marino {
722*e4b17023SJohn Marino   struct name_expansion *const exp = (struct name_expansion *) *value;
723*e4b17023SJohn Marino 
724*e4b17023SJohn Marino   free (exp);
725*e4b17023SJohn Marino   return true;
726*e4b17023SJohn Marino }
727*e4b17023SJohn Marino 
728*e4b17023SJohn Marino /* Frees memory allocated for the CACHE used by
729*e4b17023SJohn Marino    tree_to_aff_combination_expand.  */
730*e4b17023SJohn Marino 
731*e4b17023SJohn Marino void
free_affine_expand_cache(struct pointer_map_t ** cache)732*e4b17023SJohn Marino free_affine_expand_cache (struct pointer_map_t **cache)
733*e4b17023SJohn Marino {
734*e4b17023SJohn Marino   if (!*cache)
735*e4b17023SJohn Marino     return;
736*e4b17023SJohn Marino 
737*e4b17023SJohn Marino   pointer_map_traverse (*cache, free_name_expansion, NULL);
738*e4b17023SJohn Marino   pointer_map_destroy (*cache);
739*e4b17023SJohn Marino   *cache = NULL;
740*e4b17023SJohn Marino }
741*e4b17023SJohn Marino 
742*e4b17023SJohn Marino /* If VAL != CST * DIV for any constant CST, returns false.
743*e4b17023SJohn Marino    Otherwise, if VAL != 0 (and hence CST != 0), and *MULT_SET is true,
744*e4b17023SJohn Marino    additionally compares CST and MULT, and if they are different,
745*e4b17023SJohn Marino    returns false.  Finally, if neither of these two cases occur,
746*e4b17023SJohn Marino    true is returned, and if CST != 0, CST is stored to MULT and
747*e4b17023SJohn Marino    MULT_SET is set to true.  */
748*e4b17023SJohn Marino 
749*e4b17023SJohn Marino static bool
double_int_constant_multiple_p(double_int val,double_int div,bool * mult_set,double_int * mult)750*e4b17023SJohn Marino double_int_constant_multiple_p (double_int val, double_int div,
751*e4b17023SJohn Marino 				bool *mult_set, double_int *mult)
752*e4b17023SJohn Marino {
753*e4b17023SJohn Marino   double_int rem, cst;
754*e4b17023SJohn Marino 
755*e4b17023SJohn Marino   if (double_int_zero_p (val))
756*e4b17023SJohn Marino     return true;
757*e4b17023SJohn Marino 
758*e4b17023SJohn Marino   if (double_int_zero_p (div))
759*e4b17023SJohn Marino     return false;
760*e4b17023SJohn Marino 
761*e4b17023SJohn Marino   cst = double_int_sdivmod (val, div, FLOOR_DIV_EXPR, &rem);
762*e4b17023SJohn Marino   if (!double_int_zero_p (rem))
763*e4b17023SJohn Marino     return false;
764*e4b17023SJohn Marino 
765*e4b17023SJohn Marino   if (*mult_set && !double_int_equal_p (*mult, cst))
766*e4b17023SJohn Marino     return false;
767*e4b17023SJohn Marino 
768*e4b17023SJohn Marino   *mult_set = true;
769*e4b17023SJohn Marino   *mult = cst;
770*e4b17023SJohn Marino   return true;
771*e4b17023SJohn Marino }
772*e4b17023SJohn Marino 
773*e4b17023SJohn Marino /* Returns true if VAL = X * DIV for some constant X.  If this is the case,
774*e4b17023SJohn Marino    X is stored to MULT.  */
775*e4b17023SJohn Marino 
776*e4b17023SJohn Marino bool
aff_combination_constant_multiple_p(aff_tree * val,aff_tree * div,double_int * mult)777*e4b17023SJohn Marino aff_combination_constant_multiple_p (aff_tree *val, aff_tree *div,
778*e4b17023SJohn Marino 				     double_int *mult)
779*e4b17023SJohn Marino {
780*e4b17023SJohn Marino   bool mult_set = false;
781*e4b17023SJohn Marino   unsigned i;
782*e4b17023SJohn Marino 
783*e4b17023SJohn Marino   if (val->n == 0 && double_int_zero_p (val->offset))
784*e4b17023SJohn Marino     {
785*e4b17023SJohn Marino       *mult = double_int_zero;
786*e4b17023SJohn Marino       return true;
787*e4b17023SJohn Marino     }
788*e4b17023SJohn Marino   if (val->n != div->n)
789*e4b17023SJohn Marino     return false;
790*e4b17023SJohn Marino 
791*e4b17023SJohn Marino   if (val->rest || div->rest)
792*e4b17023SJohn Marino     return false;
793*e4b17023SJohn Marino 
794*e4b17023SJohn Marino   if (!double_int_constant_multiple_p (val->offset, div->offset,
795*e4b17023SJohn Marino 				       &mult_set, mult))
796*e4b17023SJohn Marino     return false;
797*e4b17023SJohn Marino 
798*e4b17023SJohn Marino   for (i = 0; i < div->n; i++)
799*e4b17023SJohn Marino     {
800*e4b17023SJohn Marino       struct aff_comb_elt *elt
801*e4b17023SJohn Marino 	      = aff_combination_find_elt (val, div->elts[i].val, NULL);
802*e4b17023SJohn Marino       if (!elt)
803*e4b17023SJohn Marino 	return false;
804*e4b17023SJohn Marino       if (!double_int_constant_multiple_p (elt->coef, div->elts[i].coef,
805*e4b17023SJohn Marino 					   &mult_set, mult))
806*e4b17023SJohn Marino 	return false;
807*e4b17023SJohn Marino     }
808*e4b17023SJohn Marino 
809*e4b17023SJohn Marino   gcc_assert (mult_set);
810*e4b17023SJohn Marino   return true;
811*e4b17023SJohn Marino }
812*e4b17023SJohn Marino 
813*e4b17023SJohn Marino /* Prints the affine VAL to the FILE. */
814*e4b17023SJohn Marino 
815*e4b17023SJohn Marino void
print_aff(FILE * file,aff_tree * val)816*e4b17023SJohn Marino print_aff (FILE *file, aff_tree *val)
817*e4b17023SJohn Marino {
818*e4b17023SJohn Marino   unsigned i;
819*e4b17023SJohn Marino   bool uns = TYPE_UNSIGNED (val->type);
820*e4b17023SJohn Marino   if (POINTER_TYPE_P (val->type))
821*e4b17023SJohn Marino     uns = false;
822*e4b17023SJohn Marino   fprintf (file, "{\n  type = ");
823*e4b17023SJohn Marino   print_generic_expr (file, val->type, TDF_VOPS|TDF_MEMSYMS);
824*e4b17023SJohn Marino   fprintf (file, "\n  offset = ");
825*e4b17023SJohn Marino   dump_double_int (file, val->offset, uns);
826*e4b17023SJohn Marino   if (val->n > 0)
827*e4b17023SJohn Marino     {
828*e4b17023SJohn Marino       fprintf (file, "\n  elements = {\n");
829*e4b17023SJohn Marino       for (i = 0; i < val->n; i++)
830*e4b17023SJohn Marino 	{
831*e4b17023SJohn Marino 	  fprintf (file, "    [%d] = ", i);
832*e4b17023SJohn Marino 	  print_generic_expr (file, val->elts[i].val, TDF_VOPS|TDF_MEMSYMS);
833*e4b17023SJohn Marino 
834*e4b17023SJohn Marino 	  fprintf (file, " * ");
835*e4b17023SJohn Marino 	  dump_double_int (file, val->elts[i].coef, uns);
836*e4b17023SJohn Marino 	  if (i != val->n - 1)
837*e4b17023SJohn Marino 	    fprintf (file, ", \n");
838*e4b17023SJohn Marino 	}
839*e4b17023SJohn Marino       fprintf (file, "\n  }");
840*e4b17023SJohn Marino   }
841*e4b17023SJohn Marino   if (val->rest)
842*e4b17023SJohn Marino     {
843*e4b17023SJohn Marino       fprintf (file, "\n  rest = ");
844*e4b17023SJohn Marino       print_generic_expr (file, val->rest, TDF_VOPS|TDF_MEMSYMS);
845*e4b17023SJohn Marino     }
846*e4b17023SJohn Marino   fprintf (file, "\n}");
847*e4b17023SJohn Marino }
848*e4b17023SJohn Marino 
849*e4b17023SJohn Marino /* Prints the affine VAL to the standard error, used for debugging.  */
850*e4b17023SJohn Marino 
851*e4b17023SJohn Marino DEBUG_FUNCTION void
debug_aff(aff_tree * val)852*e4b17023SJohn Marino debug_aff (aff_tree *val)
853*e4b17023SJohn Marino {
854*e4b17023SJohn Marino   print_aff (stderr, val);
855*e4b17023SJohn Marino   fprintf (stderr, "\n");
856*e4b17023SJohn Marino }
857*e4b17023SJohn Marino 
858*e4b17023SJohn Marino /* Returns address of the reference REF in ADDR.  The size of the accessed
859*e4b17023SJohn Marino    location is stored to SIZE.  */
860*e4b17023SJohn Marino 
861*e4b17023SJohn Marino void
get_inner_reference_aff(tree ref,aff_tree * addr,double_int * size)862*e4b17023SJohn Marino get_inner_reference_aff (tree ref, aff_tree *addr, double_int *size)
863*e4b17023SJohn Marino {
864*e4b17023SJohn Marino   HOST_WIDE_INT bitsize, bitpos;
865*e4b17023SJohn Marino   tree toff;
866*e4b17023SJohn Marino   enum machine_mode mode;
867*e4b17023SJohn Marino   int uns, vol;
868*e4b17023SJohn Marino   aff_tree tmp;
869*e4b17023SJohn Marino   tree base = get_inner_reference (ref, &bitsize, &bitpos, &toff, &mode,
870*e4b17023SJohn Marino 				   &uns, &vol, false);
871*e4b17023SJohn Marino   tree base_addr = build_fold_addr_expr (base);
872*e4b17023SJohn Marino 
873*e4b17023SJohn Marino   /* ADDR = &BASE + TOFF + BITPOS / BITS_PER_UNIT.  */
874*e4b17023SJohn Marino 
875*e4b17023SJohn Marino   tree_to_aff_combination (base_addr, sizetype, addr);
876*e4b17023SJohn Marino 
877*e4b17023SJohn Marino   if (toff)
878*e4b17023SJohn Marino     {
879*e4b17023SJohn Marino       tree_to_aff_combination (toff, sizetype, &tmp);
880*e4b17023SJohn Marino       aff_combination_add (addr, &tmp);
881*e4b17023SJohn Marino     }
882*e4b17023SJohn Marino 
883*e4b17023SJohn Marino   aff_combination_const (&tmp, sizetype,
884*e4b17023SJohn Marino 			 shwi_to_double_int (bitpos / BITS_PER_UNIT));
885*e4b17023SJohn Marino   aff_combination_add (addr, &tmp);
886*e4b17023SJohn Marino 
887*e4b17023SJohn Marino   *size = shwi_to_double_int ((bitsize + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
888*e4b17023SJohn Marino }
889*e4b17023SJohn Marino 
890*e4b17023SJohn Marino /* Returns true if a region of size SIZE1 at position 0 and a region of
891*e4b17023SJohn Marino    size SIZE2 at position DIFF cannot overlap.  */
892*e4b17023SJohn Marino 
893*e4b17023SJohn Marino bool
aff_comb_cannot_overlap_p(aff_tree * diff,double_int size1,double_int size2)894*e4b17023SJohn Marino aff_comb_cannot_overlap_p (aff_tree *diff, double_int size1, double_int size2)
895*e4b17023SJohn Marino {
896*e4b17023SJohn Marino   double_int d, bound;
897*e4b17023SJohn Marino 
898*e4b17023SJohn Marino   /* Unless the difference is a constant, we fail.  */
899*e4b17023SJohn Marino   if (diff->n != 0)
900*e4b17023SJohn Marino     return false;
901*e4b17023SJohn Marino 
902*e4b17023SJohn Marino   d = diff->offset;
903*e4b17023SJohn Marino   if (double_int_negative_p (d))
904*e4b17023SJohn Marino     {
905*e4b17023SJohn Marino       /* The second object is before the first one, we succeed if the last
906*e4b17023SJohn Marino 	 element of the second object is before the start of the first one.  */
907*e4b17023SJohn Marino       bound = double_int_add (d, double_int_add (size2, double_int_minus_one));
908*e4b17023SJohn Marino       return double_int_negative_p (bound);
909*e4b17023SJohn Marino     }
910*e4b17023SJohn Marino   else
911*e4b17023SJohn Marino     {
912*e4b17023SJohn Marino       /* We succeed if the second object starts after the first one ends.  */
913*e4b17023SJohn Marino       return double_int_scmp (size1, d) <= 0;
914*e4b17023SJohn Marino     }
915*e4b17023SJohn Marino }
916*e4b17023SJohn Marino 
917