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