2005-01-20 Michael Koch <konqueror@gmx.de>
[official-gcc.git] / gcc / tree-ssa-copy.c
blob32db3fa3d868589360a87e9ba3bb2eac1e77c4fc
1 /* Const/copy propagation and SSA_NAME replacement support routines.
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING. If not, write to
18 the Free Software Foundation, 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "tree.h"
26 #include "flags.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "ggc.h"
30 #include "basic-block.h"
31 #include "output.h"
32 #include "errors.h"
33 #include "expr.h"
34 #include "function.h"
35 #include "diagnostic.h"
36 #include "timevar.h"
37 #include "tree-dump.h"
38 #include "tree-flow.h"
39 #include "tree-pass.h"
40 #include "langhooks.h"
42 /* This file provides a handful of interfaces for performing const/copy
43 propagation and simple expression replacement which keep variable
44 annotations up-to-date.
46 We require that for any copy operation where the RHS and LHS have
47 a non-null memory tag that the memory tag be the same. It is OK
48 for one or both of the memory tags to be NULL.
50 We also require tracking if a variable is dereferenced in a load or
51 store operation.
53 We enforce these requirements by having all copy propagation and
54 replacements of one SSA_NAME with a different SSA_NAME to use the
55 APIs defined in this file. */
58 /* Given two SSA_NAMEs, replace the annotations for the one referred to by OP
59 with VAR's annmoptations.
61 If OP is a pointer, copy the memory tag used originally by OP into
62 VAR. This is needed in cases where VAR had never been dereferenced in the
63 program.
65 If FOR_PROPAGATION is true, then perform additional checks to ensure
66 that const/copy propagation of var for OP is valid. */
68 static void
69 replace_ssa_names_ann (tree op,
70 tree var,
71 bool for_propagation ATTRIBUTE_UNUSED)
73 #if defined ENABLE_CHECKING
74 if (for_propagation && !may_propagate_copy (op, var))
75 abort ();
76 #endif
78 /* If VAR doesn't have a memory tag, copy the one from the original
79 operand. Also copy the dereferenced flags. */
80 if (POINTER_TYPE_P (TREE_TYPE (op)))
82 var_ann_t new_ann = var_ann (SSA_NAME_VAR (var));
83 var_ann_t orig_ann = var_ann (SSA_NAME_VAR (op));
85 if (new_ann->type_mem_tag == NULL_TREE)
86 new_ann->type_mem_tag = orig_ann->type_mem_tag;
87 else if (orig_ann->type_mem_tag == NULL_TREE)
88 orig_ann->type_mem_tag = new_ann->type_mem_tag;
89 else if (new_ann->type_mem_tag != orig_ann->type_mem_tag)
90 abort ();
96 /* Common code for propagate_value and replace_exp.
98 Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the
99 replacement is done to propagate a value or not. */
101 static void
102 replace_exp_1 (use_operand_p op_p, tree val, bool for_propagation)
104 if (TREE_CODE (val) == SSA_NAME)
106 if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
107 replace_ssa_names_ann (USE_FROM_PTR (op_p), val, for_propagation);
108 SET_USE (op_p, val);
110 else
111 SET_USE (op_p, lhd_unsave_expr_now (val));
114 /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
115 into the operand pointed by OP_P.
117 Use this version for const/copy propagation as it will perform additional
118 checks to ensure validity of the const/copy propagation. */
120 void
121 propagate_value (use_operand_p op_p, tree val)
123 replace_exp_1 (op_p, val, true);
126 /* Propagate the value VAL (assumed to be a constant or another SSA_NAME)
127 into the tree pointed by OP_P.
129 Use this version for const/copy propagation when SSA operands are not
130 available. It will perform the additional checks to ensure validity of
131 the const/copy propagation, but will not update any operand information.
132 Be sure to mark the stmt as modified. */
134 void
135 propagate_tree_value (tree *op_p, tree val)
137 if (TREE_CODE (val) == SSA_NAME)
139 if (TREE_CODE (*op_p) == SSA_NAME)
140 replace_ssa_names_ann (*op_p, val, true);
141 *op_p = val;
143 else
144 *op_p = lhd_unsave_expr_now (val);
147 /* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME).
149 Use this version when not const/copy propagating values. For example,
150 PRE uses this version when building expressions as they would appear
151 in specific blocks taking into account actions of PHI nodes. */
153 void
154 replace_exp (use_operand_p op_p, tree val)
156 replace_exp_1 (op_p, val, false);
159 /* Replace *OP_P in STMT with any known equivalent value for *OP_P from
160 CONST_AND_COPIES. */
162 static bool
163 cprop_operand (stmt_ann_t ann, use_operand_p op_p, varray_type const_and_copies)
165 bool may_have_exposed_new_symbols = false;
166 tree val;
167 tree op = USE_FROM_PTR (op_p);
169 /* If the operand has a known constant value or it is known to be a
170 copy of some other variable, use the value or copy stored in
171 CONST_AND_COPIES. */
172 val = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (op));
173 if (val)
175 tree op_type, val_type;
177 /* Do not change the base variable in the virtual operand
178 tables. That would make it impossible to reconstruct
179 the renamed virtual operand if we later modify this
180 statement. Also only allow the new value to be an SSA_NAME
181 for propagation into virtual operands. */
182 if (!is_gimple_reg (op)
183 && (get_virtual_var (val) != get_virtual_var (op)
184 || TREE_CODE (val) != SSA_NAME))
185 return false;
187 /* Get the toplevel type of each operand. */
188 op_type = TREE_TYPE (op);
189 val_type = TREE_TYPE (val);
191 /* While both types are pointers, get the type of the object
192 pointed to. */
193 while (POINTER_TYPE_P (op_type) && POINTER_TYPE_P (val_type))
195 op_type = TREE_TYPE (op_type);
196 val_type = TREE_TYPE (val_type);
199 /* Make sure underlying types match before propagating a
200 constant by converting the constant to the proper type. Note
201 that convert may return a non-gimple expression, in which case
202 we ignore this propagation opportunity. */
203 if (!lang_hooks.types_compatible_p (op_type, val_type)
204 && TREE_CODE (val) != SSA_NAME)
206 val = fold_convert (TREE_TYPE (op), val);
207 if (!is_gimple_min_invariant (val)
208 && TREE_CODE (val) != SSA_NAME)
209 return false;
212 /* Certain operands are not allowed to be copy propagated due
213 to their interaction with exception handling and some GCC
214 extensions. */
215 if (TREE_CODE (val) == SSA_NAME
216 && !may_propagate_copy (op, val))
217 return false;
219 /* Dump details. */
220 if (dump_file && (dump_flags & TDF_DETAILS))
222 fprintf (dump_file, " Replaced '");
223 print_generic_expr (dump_file, op, dump_flags);
224 fprintf (dump_file, "' with %s '",
225 (TREE_CODE (val) != SSA_NAME ? "constant" : "variable"));
226 print_generic_expr (dump_file, val, dump_flags);
227 fprintf (dump_file, "'\n");
230 /* If VAL is an ADDR_EXPR or a constant of pointer type, note
231 that we may have exposed a new symbol for SSA renaming. */
232 if (TREE_CODE (val) == ADDR_EXPR
233 || (POINTER_TYPE_P (TREE_TYPE (op))
234 && is_gimple_min_invariant (val)))
235 may_have_exposed_new_symbols = true;
237 propagate_value (op_p, val);
239 /* And note that we modified this statement. This is now
240 safe, even if we changed virtual operands since we will
241 rescan the statement and rewrite its operands again. */
242 ann->modified = 1;
244 return may_have_exposed_new_symbols;
247 /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
248 known value for that SSA_NAME (or NULL if no value is known).
250 Propagate values from CONST_AND_COPIES into the uses, vuses and
251 v_may_def_ops of STMT. */
253 bool
254 cprop_into_stmt (tree stmt, varray_type const_and_copies)
256 bool may_have_exposed_new_symbols = false;
257 stmt_ann_t ann = stmt_ann (stmt);
258 size_t i, num_uses, num_vuses, num_v_may_defs;
259 vuse_optype vuses;
260 v_may_def_optype v_may_defs;
261 use_optype uses;
263 uses = USE_OPS (ann);
264 num_uses = NUM_USES (uses);
265 for (i = 0; i < num_uses; i++)
267 use_operand_p op_p = USE_OP_PTR (uses, i);
268 if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
269 may_have_exposed_new_symbols
270 |= cprop_operand (ann, op_p, const_and_copies);
273 vuses = VUSE_OPS (ann);
274 num_vuses = NUM_VUSES (vuses);
275 for (i = 0; i < num_vuses; i++)
277 use_operand_p op_p = VUSE_OP_PTR (vuses, i);
278 if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
279 may_have_exposed_new_symbols
280 |= cprop_operand (ann, op_p, const_and_copies);
283 v_may_defs = V_MAY_DEF_OPS (ann);
284 num_v_may_defs = NUM_V_MAY_DEFS (v_may_defs);
285 for (i = 0; i < num_v_may_defs; i++)
287 use_operand_p op_p = V_MAY_DEF_OP_PTR (v_may_defs, i);
288 if (TREE_CODE (USE_FROM_PTR (op_p)) == SSA_NAME)
289 may_have_exposed_new_symbols
290 |= cprop_operand (ann, op_p, const_and_copies);
292 return may_have_exposed_new_symbols;
295 /* CONST_AND_COPIES is a table which maps an SSA_NAME to the current
296 known value for that SSA_NAME (or NULL if no value is known).
298 NONZERO_VARS is the set SSA_NAMES known to have a nonzero value,
299 even if we don't know their precise value.
301 Propagate values from CONST_AND_COPIES and NONZERO_VARS into the PHI
302 nodes of the successors of BB. */
304 void
305 cprop_into_successor_phis (basic_block bb,
306 varray_type const_and_copies,
307 bitmap nonzero_vars)
309 edge e;
311 /* This can get rather expensive if the implementation is naive in
312 how it finds the phi alternative associated with a particular edge. */
313 for (e = bb->succ; e; e = e->succ_next)
315 tree phi;
316 int phi_num_args;
317 int hint;
319 /* If this is an abnormal edge, then we do not want to copy propagate
320 into the PHI alternative associated with this edge. */
321 if (e->flags & EDGE_ABNORMAL)
322 continue;
324 phi = phi_nodes (e->dest);
325 if (! phi)
326 continue;
328 /* There is no guarantee that for any two PHI nodes in a block that
329 the phi alternative associated with a particular edge will be
330 at the same index in the phi alternative array.
332 However, it is very likely they will be the same. So we keep
333 track of the index of the alternative where we found the edge in
334 the previous phi node and check that index first in the next
335 phi node. If that hint fails, then we actually search all
336 the entries. */
337 phi_num_args = PHI_NUM_ARGS (phi);
338 hint = phi_num_args;
339 for ( ; phi; phi = PHI_CHAIN (phi))
341 int i;
342 tree new;
343 use_operand_p orig_p;
344 tree orig;
346 /* If the hint is valid (!= phi_num_args), see if it points
347 us to the desired phi alternative. */
348 if (hint != phi_num_args && PHI_ARG_EDGE (phi, hint) == e)
350 else
352 /* The hint was either invalid or did not point to the
353 correct phi alternative. Search all the alternatives
354 for the correct one. Update the hint. */
355 for (i = 0; i < phi_num_args; i++)
356 if (PHI_ARG_EDGE (phi, i) == e)
357 break;
358 hint = i;
361 #ifdef ENABLE_CHECKING
362 /* If we did not find the proper alternative, then something is
363 horribly wrong. */
364 if (hint == phi_num_args)
365 abort ();
366 #endif
368 /* The alternative may be associated with a constant, so verify
369 it is an SSA_NAME before doing anything with it. */
370 orig_p = PHI_ARG_DEF_PTR (phi, hint);
371 orig = USE_FROM_PTR (orig_p);
372 if (TREE_CODE (orig) != SSA_NAME)
373 continue;
375 /* If the alternative is known to have a nonzero value, record
376 that fact in the PHI node itself for future use. */
377 if (bitmap_bit_p (nonzero_vars, SSA_NAME_VERSION (orig)))
378 PHI_ARG_NONZERO (phi, hint) = true;
380 /* If we have *ORIG_P in our constant/copy table, then replace
381 ORIG_P with its value in our constant/copy table. */
382 new = VARRAY_TREE (const_and_copies, SSA_NAME_VERSION (orig));
383 if (new
384 && (TREE_CODE (new) == SSA_NAME
385 || is_gimple_min_invariant (new))
386 && may_propagate_copy (orig, new))
387 propagate_value (orig_p, new);