1*38fd1498Szrj /* Common subexpression elimination for GNU compiler.
2*38fd1498Szrj Copyright (C) 1987-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 under
7*38fd1498Szrj the terms of the GNU General Public License as published by the Free
8*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
9*38fd1498Szrj version.
10*38fd1498Szrj
11*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*38fd1498Szrj 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 #ifndef GCC_CSELIB_H
21*38fd1498Szrj #define GCC_CSELIB_H
22*38fd1498Szrj
23*38fd1498Szrj /* Describe a value. */
24*38fd1498Szrj struct cselib_val
25*38fd1498Szrj {
26*38fd1498Szrj /* The hash value. */
27*38fd1498Szrj unsigned int hash;
28*38fd1498Szrj
29*38fd1498Szrj /* A unique id assigned to values. */
30*38fd1498Szrj int uid;
31*38fd1498Szrj
32*38fd1498Szrj /* A VALUE rtx that points back to this structure. */
33*38fd1498Szrj rtx val_rtx;
34*38fd1498Szrj
35*38fd1498Szrj /* All rtl expressions that hold this value at the current time during a
36*38fd1498Szrj scan. */
37*38fd1498Szrj struct elt_loc_list *locs;
38*38fd1498Szrj
39*38fd1498Szrj /* If this value is used as an address, points to a list of values that
40*38fd1498Szrj use it as an address in a MEM. */
41*38fd1498Szrj struct elt_list *addr_list;
42*38fd1498Szrj
43*38fd1498Szrj struct cselib_val *next_containing_mem;
44*38fd1498Szrj };
45*38fd1498Szrj
46*38fd1498Szrj /* A list of rtl expressions that hold the same value. */
47*38fd1498Szrj struct elt_loc_list {
48*38fd1498Szrj /* Next element in the list. */
49*38fd1498Szrj struct elt_loc_list *next;
50*38fd1498Szrj /* An rtl expression that holds the value. */
51*38fd1498Szrj rtx loc;
52*38fd1498Szrj /* The insn that made the equivalence. */
53*38fd1498Szrj rtx_insn *setting_insn;
54*38fd1498Szrj };
55*38fd1498Szrj
56*38fd1498Szrj /* Describe a single set that is part of an insn. */
57*38fd1498Szrj struct cselib_set
58*38fd1498Szrj {
59*38fd1498Szrj rtx src;
60*38fd1498Szrj rtx dest;
61*38fd1498Szrj cselib_val *src_elt;
62*38fd1498Szrj cselib_val *dest_addr_elt;
63*38fd1498Szrj };
64*38fd1498Szrj
65*38fd1498Szrj enum cselib_record_what
66*38fd1498Szrj {
67*38fd1498Szrj CSELIB_RECORD_MEMORY = 1,
68*38fd1498Szrj CSELIB_PRESERVE_CONSTANTS = 2
69*38fd1498Szrj };
70*38fd1498Szrj
71*38fd1498Szrj extern void (*cselib_discard_hook) (cselib_val *);
72*38fd1498Szrj extern void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets,
73*38fd1498Szrj int n_sets);
74*38fd1498Szrj
75*38fd1498Szrj extern cselib_val *cselib_lookup (rtx, machine_mode,
76*38fd1498Szrj int, machine_mode);
77*38fd1498Szrj extern cselib_val *cselib_lookup_from_insn (rtx, machine_mode,
78*38fd1498Szrj int, machine_mode, rtx_insn *);
79*38fd1498Szrj extern void cselib_init (int);
80*38fd1498Szrj extern void cselib_clear_table (void);
81*38fd1498Szrj extern void cselib_finish (void);
82*38fd1498Szrj extern void cselib_process_insn (rtx_insn *);
83*38fd1498Szrj extern bool fp_setter_insn (rtx_insn *);
84*38fd1498Szrj extern machine_mode cselib_reg_set_mode (const_rtx);
85*38fd1498Szrj extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int);
86*38fd1498Szrj extern int references_value_p (const_rtx, int);
87*38fd1498Szrj extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
88*38fd1498Szrj typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
89*38fd1498Szrj extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int,
90*38fd1498Szrj cselib_expand_callback, void *);
91*38fd1498Szrj extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int,
92*38fd1498Szrj cselib_expand_callback, void *);
93*38fd1498Szrj extern rtx cselib_subst_to_values (rtx, machine_mode);
94*38fd1498Szrj extern rtx cselib_subst_to_values_from_insn (rtx, machine_mode, rtx_insn *);
95*38fd1498Szrj extern void cselib_invalidate_rtx (rtx);
96*38fd1498Szrj
97*38fd1498Szrj extern void cselib_reset_table (unsigned int);
98*38fd1498Szrj extern unsigned int cselib_get_next_uid (void);
99*38fd1498Szrj extern void cselib_preserve_value (cselib_val *);
100*38fd1498Szrj extern bool cselib_preserved_value_p (cselib_val *);
101*38fd1498Szrj extern void cselib_preserve_only_values (void);
102*38fd1498Szrj extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
103*38fd1498Szrj extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx_insn *);
104*38fd1498Szrj extern bool cselib_have_permanent_equivalences (void);
105*38fd1498Szrj extern void cselib_set_value_sp_based (cselib_val *);
106*38fd1498Szrj extern bool cselib_sp_based_value_p (cselib_val *);
107*38fd1498Szrj
108*38fd1498Szrj extern void dump_cselib_table (FILE *);
109*38fd1498Szrj
110*38fd1498Szrj /* Return the canonical value for VAL, following the equivalence chain
111*38fd1498Szrj towards the earliest (== lowest uid) equivalent value. */
112*38fd1498Szrj
113*38fd1498Szrj static inline cselib_val *
canonical_cselib_val(cselib_val * val)114*38fd1498Szrj canonical_cselib_val (cselib_val *val)
115*38fd1498Szrj {
116*38fd1498Szrj cselib_val *canon;
117*38fd1498Szrj
118*38fd1498Szrj if (!val->locs || val->locs->next
119*38fd1498Szrj || !val->locs->loc || GET_CODE (val->locs->loc) != VALUE
120*38fd1498Szrj || val->uid < CSELIB_VAL_PTR (val->locs->loc)->uid)
121*38fd1498Szrj return val;
122*38fd1498Szrj
123*38fd1498Szrj canon = CSELIB_VAL_PTR (val->locs->loc);
124*38fd1498Szrj gcc_checking_assert (canonical_cselib_val (canon) == canon);
125*38fd1498Szrj return canon;
126*38fd1498Szrj }
127*38fd1498Szrj
128*38fd1498Szrj /* Return nonzero if we can prove that X and Y contain the same value, taking
129*38fd1498Szrj our gathered information into account. */
130*38fd1498Szrj
131*38fd1498Szrj static inline int
rtx_equal_for_cselib_p(rtx x,rtx y)132*38fd1498Szrj rtx_equal_for_cselib_p (rtx x, rtx y)
133*38fd1498Szrj {
134*38fd1498Szrj if (x == y)
135*38fd1498Szrj return 1;
136*38fd1498Szrj
137*38fd1498Szrj return rtx_equal_for_cselib_1 (x, y, VOIDmode, 0);
138*38fd1498Szrj }
139*38fd1498Szrj
140*38fd1498Szrj #endif /* GCC_CSELIB_H */
141