annotate gcc/gcse-common.c @ 16:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16
kono
parents:
diff changeset
1 /* Shared code for before and after reload gcse implementations.
kono
parents:
diff changeset
2 Copyright (C) 1997-2017 Free Software Foundation, Inc.
kono
parents:
diff changeset
3
kono
parents:
diff changeset
4 This file is part of GCC.
kono
parents:
diff changeset
5
kono
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
kono
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
kono
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
kono
parents:
diff changeset
9 version.
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
kono
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
kono
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
kono
parents:
diff changeset
14 for more details.
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
kono
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
kono
parents:
diff changeset
18 <http://www.gnu.org/licenses/>.
kono
parents:
diff changeset
19
kono
parents:
diff changeset
20 It is expected that more hunks of gcse.c and postreload-gcse.c should
kono
parents:
diff changeset
21 migrate into this file. */
kono
parents:
diff changeset
22
kono
parents:
diff changeset
23 #include "config.h"
kono
parents:
diff changeset
24 #include "system.h"
kono
parents:
diff changeset
25 #include "coretypes.h"
kono
parents:
diff changeset
26 #include "backend.h"
kono
parents:
diff changeset
27 #include "rtl.h"
kono
parents:
diff changeset
28 #include "df.h"
kono
parents:
diff changeset
29 #include "gcse-common.h"
kono
parents:
diff changeset
30
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 /* Record all of the canonicalized MEMs of record_last_mem_set_info's insn.
kono
parents:
diff changeset
33 Note we store a pair of elements in the list, so they have to be
kono
parents:
diff changeset
34 taken off pairwise. */
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 void
kono
parents:
diff changeset
37 canon_list_insert (rtx dest, const_rtx x ATTRIBUTE_UNUSED, void *data)
kono
parents:
diff changeset
38 {
kono
parents:
diff changeset
39 rtx dest_addr;
kono
parents:
diff changeset
40 int bb;
kono
parents:
diff changeset
41 modify_pair pair;
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 while (GET_CODE (dest) == SUBREG
kono
parents:
diff changeset
44 || GET_CODE (dest) == ZERO_EXTRACT
kono
parents:
diff changeset
45 || GET_CODE (dest) == STRICT_LOW_PART)
kono
parents:
diff changeset
46 dest = XEXP (dest, 0);
kono
parents:
diff changeset
47
kono
parents:
diff changeset
48 /* If DEST is not a MEM, then it will not conflict with a load. Note
kono
parents:
diff changeset
49 that function calls are assumed to clobber memory, but are handled
kono
parents:
diff changeset
50 elsewhere. */
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 if (! MEM_P (dest))
kono
parents:
diff changeset
53 return;
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 dest_addr = get_addr (XEXP (dest, 0));
kono
parents:
diff changeset
56 dest_addr = canon_rtx (dest_addr);
kono
parents:
diff changeset
57 rtx_insn *insn = ((struct gcse_note_stores_info *)data)->insn;
kono
parents:
diff changeset
58 bb = BLOCK_FOR_INSN (insn)->index;
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 pair.dest = dest;
kono
parents:
diff changeset
61 pair.dest_addr = dest_addr;
kono
parents:
diff changeset
62 vec<modify_pair> *canon_mem_list
kono
parents:
diff changeset
63 = ((struct gcse_note_stores_info *)data)->canon_mem_list;
kono
parents:
diff changeset
64 canon_mem_list[bb].safe_push (pair);
kono
parents:
diff changeset
65 }
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 /* Record memory modification information for INSN. We do not actually care
kono
parents:
diff changeset
68 about the memory location(s) that are set, or even how they are set (consider
kono
parents:
diff changeset
69 a CALL_INSN). We merely need to record which insns modify memory. */
kono
parents:
diff changeset
70
kono
parents:
diff changeset
71 void
kono
parents:
diff changeset
72 record_last_mem_set_info_common (rtx_insn *insn,
kono
parents:
diff changeset
73 vec<rtx_insn *> *modify_mem_list,
kono
parents:
diff changeset
74 vec<modify_pair> *canon_modify_mem_list,
kono
parents:
diff changeset
75 bitmap modify_mem_list_set,
kono
parents:
diff changeset
76 bitmap blocks_with_calls)
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 {
kono
parents:
diff changeset
79 int bb;
kono
parents:
diff changeset
80
kono
parents:
diff changeset
81 bb = BLOCK_FOR_INSN (insn)->index;
kono
parents:
diff changeset
82 modify_mem_list[bb].safe_push (insn);
kono
parents:
diff changeset
83 bitmap_set_bit (modify_mem_list_set, bb);
kono
parents:
diff changeset
84
kono
parents:
diff changeset
85 if (CALL_P (insn))
kono
parents:
diff changeset
86 bitmap_set_bit (blocks_with_calls, bb);
kono
parents:
diff changeset
87 else
kono
parents:
diff changeset
88 {
kono
parents:
diff changeset
89 struct gcse_note_stores_info data;
kono
parents:
diff changeset
90 data.insn = insn;
kono
parents:
diff changeset
91 data.canon_mem_list = canon_modify_mem_list;
kono
parents:
diff changeset
92 note_stores (PATTERN (insn), canon_list_insert, (void*) &data);
kono
parents:
diff changeset
93 }
kono
parents:
diff changeset
94 }
kono
parents:
diff changeset
95
kono
parents:
diff changeset
96
kono
parents:
diff changeset
97 /* For each block, compute whether X is transparent. X is either an
kono
parents:
diff changeset
98 expression or an assignment [though we don't care which, for this context
kono
parents:
diff changeset
99 an assignment is treated as an expression]. For each block where an
kono
parents:
diff changeset
100 element of X is modified, reset the INDX bit in BMAP.
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 BLOCKS_WITH_CALLS indicates which blocks contain CALL_INSNs which kill
kono
parents:
diff changeset
103 memory.
kono
parents:
diff changeset
104
kono
parents:
diff changeset
105 MODIFY_MEM_LIST_SET indicates which blocks have memory stores which might
kono
parents:
diff changeset
106 kill a particular memory location.
kono
parents:
diff changeset
107
kono
parents:
diff changeset
108 CANON_MODIFY_MEM_LIST is the canonicalized list of memory locations modified
kono
parents:
diff changeset
109 for each block. */
kono
parents:
diff changeset
110
kono
parents:
diff changeset
111 void
kono
parents:
diff changeset
112 compute_transp (const_rtx x, int indx, sbitmap *bmap,
kono
parents:
diff changeset
113 bitmap blocks_with_calls,
kono
parents:
diff changeset
114 bitmap modify_mem_list_set,
kono
parents:
diff changeset
115 vec<modify_pair> *canon_modify_mem_list)
kono
parents:
diff changeset
116 {
kono
parents:
diff changeset
117 int i, j;
kono
parents:
diff changeset
118 enum rtx_code code;
kono
parents:
diff changeset
119 const char *fmt;
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 /* repeat is used to turn tail-recursion into iteration since GCC
kono
parents:
diff changeset
122 can't do it when there's no return value. */
kono
parents:
diff changeset
123 repeat:
kono
parents:
diff changeset
124
kono
parents:
diff changeset
125 if (x == 0)
kono
parents:
diff changeset
126 return;
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 code = GET_CODE (x);
kono
parents:
diff changeset
129 switch (code)
kono
parents:
diff changeset
130 {
kono
parents:
diff changeset
131 case REG:
kono
parents:
diff changeset
132 {
kono
parents:
diff changeset
133 df_ref def;
kono
parents:
diff changeset
134 for (def = DF_REG_DEF_CHAIN (REGNO (x));
kono
parents:
diff changeset
135 def;
kono
parents:
diff changeset
136 def = DF_REF_NEXT_REG (def))
kono
parents:
diff changeset
137 bitmap_clear_bit (bmap[DF_REF_BB (def)->index], indx);
kono
parents:
diff changeset
138 }
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 return;
kono
parents:
diff changeset
141
kono
parents:
diff changeset
142 case MEM:
kono
parents:
diff changeset
143 if (! MEM_READONLY_P (x))
kono
parents:
diff changeset
144 {
kono
parents:
diff changeset
145 bitmap_iterator bi;
kono
parents:
diff changeset
146 unsigned bb_index;
kono
parents:
diff changeset
147 rtx x_addr;
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 x_addr = get_addr (XEXP (x, 0));
kono
parents:
diff changeset
150 x_addr = canon_rtx (x_addr);
kono
parents:
diff changeset
151
kono
parents:
diff changeset
152 /* First handle all the blocks with calls. We don't need to
kono
parents:
diff changeset
153 do any list walking for them. */
kono
parents:
diff changeset
154 EXECUTE_IF_SET_IN_BITMAP (blocks_with_calls, 0, bb_index, bi)
kono
parents:
diff changeset
155 {
kono
parents:
diff changeset
156 bitmap_clear_bit (bmap[bb_index], indx);
kono
parents:
diff changeset
157 }
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 /* Now iterate over the blocks which have memory modifications
kono
parents:
diff changeset
160 but which do not have any calls. */
kono
parents:
diff changeset
161 EXECUTE_IF_AND_COMPL_IN_BITMAP (modify_mem_list_set,
kono
parents:
diff changeset
162 blocks_with_calls,
kono
parents:
diff changeset
163 0, bb_index, bi)
kono
parents:
diff changeset
164 {
kono
parents:
diff changeset
165 vec<modify_pair> list
kono
parents:
diff changeset
166 = canon_modify_mem_list[bb_index];
kono
parents:
diff changeset
167 modify_pair *pair;
kono
parents:
diff changeset
168 unsigned ix;
kono
parents:
diff changeset
169
kono
parents:
diff changeset
170 FOR_EACH_VEC_ELT_REVERSE (list, ix, pair)
kono
parents:
diff changeset
171 {
kono
parents:
diff changeset
172 rtx dest = pair->dest;
kono
parents:
diff changeset
173 rtx dest_addr = pair->dest_addr;
kono
parents:
diff changeset
174
kono
parents:
diff changeset
175 if (canon_true_dependence (dest, GET_MODE (dest),
kono
parents:
diff changeset
176 dest_addr, x, x_addr))
kono
parents:
diff changeset
177 {
kono
parents:
diff changeset
178 bitmap_clear_bit (bmap[bb_index], indx);
kono
parents:
diff changeset
179 break;
kono
parents:
diff changeset
180 }
kono
parents:
diff changeset
181 }
kono
parents:
diff changeset
182 }
kono
parents:
diff changeset
183 }
kono
parents:
diff changeset
184
kono
parents:
diff changeset
185 x = XEXP (x, 0);
kono
parents:
diff changeset
186 goto repeat;
kono
parents:
diff changeset
187
kono
parents:
diff changeset
188 case PC:
kono
parents:
diff changeset
189 case CC0: /*FIXME*/
kono
parents:
diff changeset
190 case CONST:
kono
parents:
diff changeset
191 CASE_CONST_ANY:
kono
parents:
diff changeset
192 case SYMBOL_REF:
kono
parents:
diff changeset
193 case LABEL_REF:
kono
parents:
diff changeset
194 case ADDR_VEC:
kono
parents:
diff changeset
195 case ADDR_DIFF_VEC:
kono
parents:
diff changeset
196 return;
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 default:
kono
parents:
diff changeset
199 break;
kono
parents:
diff changeset
200 }
kono
parents:
diff changeset
201
kono
parents:
diff changeset
202 for (i = GET_RTX_LENGTH (code) - 1, fmt = GET_RTX_FORMAT (code); i >= 0; i--)
kono
parents:
diff changeset
203 {
kono
parents:
diff changeset
204 if (fmt[i] == 'e')
kono
parents:
diff changeset
205 {
kono
parents:
diff changeset
206 /* If we are about to do the last recursive call
kono
parents:
diff changeset
207 needed at this level, change it into iteration.
kono
parents:
diff changeset
208 This function is called enough to be worth it. */
kono
parents:
diff changeset
209 if (i == 0)
kono
parents:
diff changeset
210 {
kono
parents:
diff changeset
211 x = XEXP (x, i);
kono
parents:
diff changeset
212 goto repeat;
kono
parents:
diff changeset
213 }
kono
parents:
diff changeset
214
kono
parents:
diff changeset
215 compute_transp (XEXP (x, i), indx, bmap, blocks_with_calls,
kono
parents:
diff changeset
216 modify_mem_list_set, canon_modify_mem_list);
kono
parents:
diff changeset
217 }
kono
parents:
diff changeset
218 else if (fmt[i] == 'E')
kono
parents:
diff changeset
219 for (j = 0; j < XVECLEN (x, i); j++)
kono
parents:
diff changeset
220 compute_transp (XVECEXP (x, i, j), indx, bmap, blocks_with_calls,
kono
parents:
diff changeset
221 modify_mem_list_set, canon_modify_mem_list);
kono
parents:
diff changeset
222 }
kono
parents:
diff changeset
223 }