]>
Commit | Line | Data |
---|---|---|
1617c276 | 1 | /* Common subexpression elimination for GNU compiler. |
fbd26352 | 2 | Copyright (C) 1987-2019 Free Software Foundation, Inc. |
1617c276 | 3 | |
f12b58b3 | 4 | This file is part of GCC. |
1617c276 | 5 | |
f12b58b3 | 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 | |
8c4c00c1 | 8 | Software Foundation; either version 3, or (at your option) any later |
f12b58b3 | 9 | version. |
1617c276 | 10 | |
f12b58b3 | 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. | |
1617c276 | 15 | |
16 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ | |
1617c276 | 19 | |
ce6bb0f3 | 20 | #ifndef GCC_CSELIB_H |
21 | #define GCC_CSELIB_H | |
22 | ||
1617c276 | 23 | /* Describe a value. */ |
f7d27fdc | 24 | struct cselib_val |
25 | { | |
1617c276 | 26 | /* The hash value. */ |
01df1184 | 27 | unsigned int hash; |
28 | ||
29 | /* A unique id assigned to values. */ | |
30 | int uid; | |
e3951cfd | 31 | |
32 | /* A VALUE rtx that points back to this structure. */ | |
33 | rtx val_rtx; | |
1617c276 | 34 | |
35 | /* All rtl expressions that hold this value at the current time during a | |
36 | scan. */ | |
37 | struct elt_loc_list *locs; | |
e3951cfd | 38 | |
1617c276 | 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; | |
bb5b3af8 | 42 | |
b3e7c666 | 43 | struct cselib_val *next_containing_mem; |
44 | }; | |
1617c276 | 45 | |
46 | /* A list of rtl expressions that hold the same value. */ | |
a641ee36 | 47 | struct elt_loc_list { |
1617c276 | 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. */ | |
e722456b | 53 | rtx_insn *setting_insn; |
1617c276 | 54 | }; |
55 | ||
9845d120 | 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 | ||
35af0188 | 65 | enum cselib_record_what |
66 | { | |
67 | CSELIB_RECORD_MEMORY = 1, | |
68 | CSELIB_PRESERVE_CONSTANTS = 2 | |
69 | }; | |
70 | ||
3072d30e | 71 | extern void (*cselib_discard_hook) (cselib_val *); |
8591d646 | 72 | extern void (*cselib_record_sets_hook) (rtx_insn *insn, struct cselib_set *sets, |
9845d120 | 73 | int n_sets); |
3072d30e | 74 | |
3754d046 | 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 *); | |
35af0188 | 79 | extern void cselib_init (int); |
defc8016 | 80 | extern void cselib_clear_table (void); |
8ec3a57b | 81 | extern void cselib_finish (void); |
ebabb7a3 | 82 | extern void cselib_process_insn (rtx_insn *); |
33923896 | 83 | extern bool fp_setter_insn (rtx_insn *); |
3754d046 | 84 | extern machine_mode cselib_reg_set_mode (const_rtx); |
6ac7eb85 | 85 | extern int rtx_equal_for_cselib_1 (rtx, rtx, machine_mode, int); |
52d07779 | 86 | extern int references_value_p (const_rtx, int); |
3072d30e | 87 | extern rtx cselib_expand_value_rtx (rtx, bitmap, int); |
9845d120 | 88 | typedef rtx (*cselib_expand_callback)(rtx, bitmap, int, void *); |
89 | extern rtx cselib_expand_value_rtx_cb (rtx, bitmap, int, | |
bc95df68 | 90 | cselib_expand_callback, void *); |
91 | extern bool cselib_dummy_expand_value_rtx_cb (rtx, bitmap, int, | |
92 | cselib_expand_callback, void *); | |
3754d046 | 93 | extern rtx cselib_subst_to_values (rtx, machine_mode); |
94 | extern rtx cselib_subst_to_values_from_insn (rtx, machine_mode, rtx_insn *); | |
52620891 | 95 | extern void cselib_invalidate_rtx (rtx, const_rtx = NULL); |
9845d120 | 96 | |
01df1184 | 97 | extern void cselib_reset_table (unsigned int); |
98 | extern unsigned int cselib_get_next_uid (void); | |
9845d120 | 99 | extern void cselib_preserve_value (cselib_val *); |
100 | extern bool cselib_preserved_value_p (cselib_val *); | |
c77c64d8 | 101 | extern void cselib_preserve_only_values (void); |
4573d576 | 102 | extern void cselib_preserve_cfa_base_value (cselib_val *, unsigned int); |
e722456b | 103 | extern void cselib_add_permanent_equiv (cselib_val *, rtx, rtx_insn *); |
85b6e75b | 104 | extern bool cselib_have_permanent_equivalences (void); |
bb75e83f | 105 | extern void cselib_set_value_sp_based (cselib_val *); |
106 | extern bool cselib_sp_based_value_p (cselib_val *); | |
9845d120 | 107 | |
108 | extern void dump_cselib_table (FILE *); | |
8081d3a6 | 109 | |
110 | /* Return the canonical value for VAL, following the equivalence chain | |
111 | towards the earliest (== lowest uid) equivalent value. */ | |
112 | ||
113 | static inline cselib_val * | |
114 | canonical_cselib_val (cselib_val *val) | |
115 | { | |
116 | cselib_val *canon; | |
117 | ||
118 | if (!val->locs || val->locs->next | |
119 | || !val->locs->loc || GET_CODE (val->locs->loc) != VALUE | |
120 | || val->uid < CSELIB_VAL_PTR (val->locs->loc)->uid) | |
121 | return val; | |
122 | ||
123 | canon = CSELIB_VAL_PTR (val->locs->loc); | |
124 | gcc_checking_assert (canonical_cselib_val (canon) == canon); | |
125 | return canon; | |
126 | } | |
ce6bb0f3 | 127 | |
56d8dd53 | 128 | /* Return nonzero if we can prove that X and Y contain the same value, taking |
129 | our gathered information into account. */ | |
130 | ||
131 | static inline int | |
132 | rtx_equal_for_cselib_p (rtx x, rtx y) | |
133 | { | |
134 | if (x == y) | |
135 | return 1; | |
136 | ||
6ac7eb85 | 137 | return rtx_equal_for_cselib_1 (x, y, VOIDmode, 0); |
56d8dd53 | 138 | } |
139 | ||
ce6bb0f3 | 140 | #endif /* GCC_CSELIB_H */ |