Line data Source code
1 : /* Common subexpression elimination for GNU compiler.
2 : Copyright (C) 1987-2026 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 : /* True if this value is entered in cselib_preserved_hash_table. */
30 : unsigned int in_preserved_table_p : 1;
31 :
32 : /* True if every value referenced by every element of LOCS is known
33 : to be a preserved value. */
34 : unsigned int all_locs_preserved_p : 1;
35 :
36 : /* A VALUE rtx that points back to this structure. */
37 : rtx val_rtx;
38 :
39 : /* All rtl expressions that hold this value at the current time during a
40 : scan. */
41 : struct elt_loc_list *locs;
42 :
43 : /* If this value is used as an address, points to a list of values that
44 : use it as an address in a MEM. */
45 : struct elt_list *addr_list;
46 :
47 : struct cselib_val *next_containing_mem;
48 : };
49 :
50 : /* A list of rtl expressions that hold the same value. */
51 : struct elt_loc_list {
52 : /* Next element in the list. */
53 : struct elt_loc_list *next;
54 : /* An rtl expression that holds the value. */
55 : rtx loc;
56 : /* The insn that made the equivalence. */
57 : rtx_insn *setting_insn;
58 : };
59 :
60 : /* Describe a single set that is part of an insn. */
61 : struct cselib_set
62 : {
63 : rtx src;
64 : rtx dest;
65 : cselib_val *src_elt;
66 : cselib_val *dest_addr_elt;
67 : };
68 :
69 : enum cselib_record_what
70 : {
71 : CSELIB_RECORD_MEMORY = 1,
72 : CSELIB_PRESERVE_CONSTANTS = 2
73 : };
74 :
75 : extern void (*cselib_discard_hook) (cselib_val *);
76 : extern void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets,
77 : int n_sets);
78 :
79 : extern cselib_val *cselib_lookup (rtx, machine_mode,
80 : int, machine_mode);
81 : extern cselib_val *cselib_lookup_from_insn (rtx, machine_mode,
82 : int, machine_mode, rtx_insn *);
83 : extern void cselib_init (int);
84 : extern void cselib_clear_table (void);
85 : extern void cselib_finish (void);
86 : extern void cselib_process_insn (rtx_insn *);
87 : extern bool fp_setter_insn (rtx_insn *);
88 : extern machine_mode cselib_reg_set_mode (const_rtx);
89 : extern bool rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int);
90 : extern bool cselib_redundant_set_p (rtx);
91 : extern bool references_value_p (const_rtx);
92 : extern rtx cselib_expand_value_rtx (rtx, bitmap, int);
93 : typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *);
94 : extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int,
95 : cselib_expand_callback, void *);
96 : extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int,
97 : cselib_expand_callback, void *);
98 : extern rtx cselib_subst_to_values (rtx, machine_mode);
99 : extern rtx cselib_subst_to_values_from_insn (rtx, machine_mode, rtx_insn *);
100 : extern void cselib_invalidate_rtx (rtx);
101 :
102 : extern void cselib_reset_table (unsigned int);
103 : extern unsigned int cselib_get_next_uid (void);
104 : extern void cselib_preserve_value (cselib_val *);
105 : extern bool cselib_preserved_value_p (cselib_val *);
106 : extern void cselib_preserve_only_values (void);
107 : extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int);
108 : extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx_insn *);
109 : extern bool cselib_have_permanent_equivalences (void);
110 : extern void cselib_set_value_sp_based (cselib_val *);
111 : extern bool cselib_sp_based_value_p (cselib_val *);
112 : extern void cselib_record_sp_cfa_base_equiv (HOST_WIDE_INT, rtx_insn *);
113 : extern bool cselib_sp_derived_value_p (cselib_val *);
114 :
115 : extern void dump_cselib_table (FILE *);
116 :
117 : /* Return the canonical value for VAL, following the equivalence chain
118 : towards the earliest (== lowest uid) equivalent value. */
119 :
120 : inline cselib_val *
121 2448847352 : canonical_cselib_val (cselib_val *val)
122 : {
123 2448847352 : cselib_val *canon;
124 :
125 1732963072 : if (!val->locs || val->locs->next
126 844754420 : || !val->locs->loc || GET_CODE (val->locs->loc) != VALUE
127 2468304591 : || CSELIB_VAL_UID (val->val_rtx) < CSELIB_VAL_UID (val->locs->loc))
128 : return val;
129 :
130 19445198 : canon = CSELIB_VAL_PTR (val->locs->loc);
131 19445198 : gcc_checking_assert (canonical_cselib_val (canon) == canon);
132 : return canon;
133 : }
134 :
135 : /* Return true if we can prove that X and Y contain the same value, taking
136 : our gathered information into account. */
137 :
138 : inline bool
139 55397992 : rtx_equal_for_cselib_p (rtx x, rtx y)
140 : {
141 55397992 : if (x == y)
142 : return true;
143 :
144 55382262 : return rtx_equal_for_cselib_1 (x, y, VOIDmode, 0);
145 : }
146 :
147 : #endif /* GCC_CSELIB_H */
|