1*38fd1498Szrj /* Operations with affine combinations of trees.
2*38fd1498Szrj Copyright (C) 2005-2018 Free Software Foundation, Inc.
3*38fd1498Szrj
4*38fd1498Szrj This file is part of GCC.
5*38fd1498Szrj
6*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it
7*38fd1498Szrj under the terms of the GNU General Public License as published by the
8*38fd1498Szrj Free Software Foundation; either version 3, or (at your option) any
9*38fd1498Szrj later version.
10*38fd1498Szrj
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT
12*38fd1498Szrj ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14*38fd1498Szrj for more details.
15*38fd1498Szrj
16*38fd1498Szrj You should have received a copy of the GNU General Public License
17*38fd1498Szrj along with GCC; see the file COPYING3. If not see
18*38fd1498Szrj <http://www.gnu.org/licenses/>. */
19*38fd1498Szrj
20*38fd1498Szrj /* Affine combination of trees. We keep track of at most MAX_AFF_ELTS elements
21*38fd1498Szrj to make things simpler; this is sufficient in most cases. */
22*38fd1498Szrj
23*38fd1498Szrj #ifndef GCC_TREE_AFFINE_H
24*38fd1498Szrj #define GCC_TREE_AFFINE_H
25*38fd1498Szrj
26*38fd1498Szrj
27*38fd1498Szrj #define MAX_AFF_ELTS 8
28*38fd1498Szrj
29*38fd1498Szrj /* Element of an affine combination. */
30*38fd1498Szrj
31*38fd1498Szrj struct aff_comb_elt
32*38fd1498Szrj {
33*38fd1498Szrj /* The value of the element. */
34*38fd1498Szrj tree val;
35*38fd1498Szrj
36*38fd1498Szrj /* Its coefficient in the combination. */
37*38fd1498Szrj widest_int coef;
38*38fd1498Szrj };
39*38fd1498Szrj
40*38fd1498Szrj struct aff_tree
41*38fd1498Szrj {
42*38fd1498Szrj /* Type of the result of the combination. */
43*38fd1498Szrj tree type;
44*38fd1498Szrj
45*38fd1498Szrj /* Constant offset. */
46*38fd1498Szrj poly_widest_int offset;
47*38fd1498Szrj
48*38fd1498Szrj /* Number of elements of the combination. */
49*38fd1498Szrj unsigned n;
50*38fd1498Szrj
51*38fd1498Szrj /* Elements and their coefficients. Type of elements may be different from
52*38fd1498Szrj TYPE, but their sizes must be the same (STRIP_NOPS is applied to the
53*38fd1498Szrj elements).
54*38fd1498Szrj
55*38fd1498Szrj The coefficients are always sign extended from the precision of TYPE
56*38fd1498Szrj (regardless of signedness of TYPE). */
57*38fd1498Szrj struct aff_comb_elt elts[MAX_AFF_ELTS];
58*38fd1498Szrj
59*38fd1498Szrj /* Remainder of the expression. Usually NULL, used only if there are more
60*38fd1498Szrj than MAX_AFF_ELTS elements. Type of REST will be either sizetype for
61*38fd1498Szrj TYPE of POINTER_TYPEs or TYPE. */
62*38fd1498Szrj tree rest;
63*38fd1498Szrj };
64*38fd1498Szrj
65*38fd1498Szrj struct name_expansion;
66*38fd1498Szrj
67*38fd1498Szrj void aff_combination_const (aff_tree *, tree, const poly_widest_int &);
68*38fd1498Szrj void aff_combination_elt (aff_tree *, tree, tree);
69*38fd1498Szrj void aff_combination_scale (aff_tree *, const widest_int &);
70*38fd1498Szrj void aff_combination_mult (aff_tree *, aff_tree *, aff_tree *);
71*38fd1498Szrj void aff_combination_add (aff_tree *, aff_tree *);
72*38fd1498Szrj void aff_combination_add_elt (aff_tree *, tree, const widest_int &);
73*38fd1498Szrj void aff_combination_remove_elt (aff_tree *, unsigned);
74*38fd1498Szrj void aff_combination_convert (aff_tree *, tree);
75*38fd1498Szrj void tree_to_aff_combination (tree, tree, aff_tree *);
76*38fd1498Szrj tree aff_combination_to_tree (aff_tree *);
77*38fd1498Szrj void unshare_aff_combination (aff_tree *);
78*38fd1498Szrj bool aff_combination_constant_multiple_p (aff_tree *, aff_tree *,
79*38fd1498Szrj poly_widest_int *);
80*38fd1498Szrj void aff_combination_expand (aff_tree *, hash_map<tree, name_expansion *> **);
81*38fd1498Szrj void tree_to_aff_combination_expand (tree, tree, aff_tree *,
82*38fd1498Szrj hash_map<tree, name_expansion *> **);
83*38fd1498Szrj tree get_inner_reference_aff (tree, aff_tree *, poly_widest_int *);
84*38fd1498Szrj void free_affine_expand_cache (hash_map<tree, name_expansion *> **);
85*38fd1498Szrj bool aff_comb_cannot_overlap_p (aff_tree *, const poly_widest_int &,
86*38fd1498Szrj const poly_widest_int &);
87*38fd1498Szrj
88*38fd1498Szrj /* Debugging functions. */
89*38fd1498Szrj void debug_aff (aff_tree *);
90*38fd1498Szrj
91*38fd1498Szrj /* Return AFF's type. */
92*38fd1498Szrj inline tree
aff_combination_type(aff_tree * aff)93*38fd1498Szrj aff_combination_type (aff_tree *aff)
94*38fd1498Szrj {
95*38fd1498Szrj return aff->type;
96*38fd1498Szrj }
97*38fd1498Szrj
98*38fd1498Szrj /* Return true if AFF is actually ZERO. */
99*38fd1498Szrj inline bool
aff_combination_zero_p(aff_tree * aff)100*38fd1498Szrj aff_combination_zero_p (aff_tree *aff)
101*38fd1498Szrj {
102*38fd1498Szrj if (!aff)
103*38fd1498Szrj return true;
104*38fd1498Szrj
105*38fd1498Szrj if (aff->n == 0 && known_eq (aff->offset, 0))
106*38fd1498Szrj return true;
107*38fd1498Szrj
108*38fd1498Szrj return false;
109*38fd1498Szrj }
110*38fd1498Szrj
111*38fd1498Szrj /* Return true if AFF is actually const. */
112*38fd1498Szrj inline bool
aff_combination_const_p(aff_tree * aff)113*38fd1498Szrj aff_combination_const_p (aff_tree *aff)
114*38fd1498Szrj {
115*38fd1498Szrj return (aff == NULL || aff->n == 0);
116*38fd1498Szrj }
117*38fd1498Szrj
118*38fd1498Szrj /* Return true iff AFF contains one (negated) singleton variable. Users need
119*38fd1498Szrj to make sure AFF points to a valid combination. */
120*38fd1498Szrj inline bool
aff_combination_singleton_var_p(aff_tree * aff)121*38fd1498Szrj aff_combination_singleton_var_p (aff_tree *aff)
122*38fd1498Szrj {
123*38fd1498Szrj return (aff->n == 1
124*38fd1498Szrj && known_eq (aff->offset, 0)
125*38fd1498Szrj && (aff->elts[0].coef == 1 || aff->elts[0].coef == -1));
126*38fd1498Szrj }
127*38fd1498Szrj #endif /* GCC_TREE_AFFINE_H */
128