Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / tree-ssa-align.c
blob1bd13900fa48fcdb67ffe0ff5b34002a2c5f47cc
1 /* Alignment analysis for trees.
2 Copyright (C) 2004 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dberlin@dberlin.org>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 #include "config.h"
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tm.h"
26 #include "tree.h"
27 #include "rtl.h"
28 #include "tm_p.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
31 #include "timevar.h"
32 #include "expr.h"
33 #include "ggc.h"
34 #include "langhooks.h"
35 #include "flags.h"
36 #include "function.h"
37 #include "diagnostic.h"
38 #include "tree-dump.h"
39 #include "tree-gimple.h"
40 #include "tree-flow.h"
41 #include "tree-inline.h"
42 #include "tree-pass.h"
43 #include "convert.h"
44 #include "params.h"
45 #include "tree-ssa-propagate.h"
47 /* Compute alignment/misalignment info for SSA pointers, using
48 results of masks, guaranteed alignment properties, or whatever
49 other information we can find around that tells us something about
50 alignment. */
52 /* Possible lattice values. */
53 typedef enum
55 UNINITIALIZED = 0,
56 KNOWN,
57 UNDEFINED
58 } latticevalue;
61 /* Main structure for CCP. Contains the lattice value and, if it's a
62 constant, the constant value. */
63 typedef struct
65 latticevalue lattice_val;
66 struct
68 unsigned int n;
69 unsigned int offset;
70 } alignment;
71 } value;
73 /* This is used to track the current value of each variable. */
74 static value *value_vector;
76 static void initialize (void);
77 static void finalize (void);
78 static enum ssa_prop_result visit_phi_node (tree);
79 static value cp_lattice_meet (value, value);
80 static enum ssa_prop_result visit_stmt (tree, edge *, tree *);
81 static enum ssa_prop_result visit_assignment (tree, tree *);
82 static void def_to_known_bpu_0 (tree);
83 static bool set_lattice_value (tree, value);
84 static value evaluate_stmt (tree);
85 static void dump_lattice_value (FILE *, const char *, value);
86 static value *get_value (tree);
87 static value get_default_value (tree);
89 /* Main entry point for SSA alignment analysis */
91 static void
92 compute_ptr_alignment (void)
94 unsigned int i = 0;
95 initialize ();
96 ssa_propagate (visit_stmt, visit_phi_node);
99 /* Set the alignments */
100 for (i = 0; i < num_ssa_names; i++)
102 tree ssa_var = ssa_name (i);
103 if (ssa_var && POINTER_TYPE_P (TREE_TYPE (ssa_var)))
105 struct ptr_info_def *pi = get_ptr_info (ssa_var);
106 value *val = get_value (ssa_var);
107 if (val->lattice_val == KNOWN)
109 pi->alignment.n = val->alignment.n;
110 pi->alignment.offset = val->alignment.offset;
114 /* Free allocated memory. */
115 finalize ();
117 /* Debugging dumps. */
118 if (dump_file && (dump_flags & TDF_DETAILS))
120 dump_referenced_vars (dump_file);
121 dump_align_info (dump_file);
122 fprintf (dump_file, "\n\n");
127 /* Loop through the PHI_NODE's parameters for BLOCK and compare their
128 lattice values to determine PHI_NODE's lattice value. The value of a
129 PHI node is determined calling cp_lattice_meet() with all the arguments
130 of the PHI node */
132 static enum ssa_prop_result
133 visit_phi_node (tree phi)
135 value phi_val, *curr_val;
136 int i;
138 if (dump_file && (dump_flags & TDF_DETAILS))
140 fprintf (dump_file, "\nVisiting PHI node: ");
141 print_generic_expr (dump_file, phi, dump_flags);
144 curr_val = get_value (PHI_RESULT (phi));
145 phi_val = *curr_val;
146 if (phi_val.lattice_val == UNINITIALIZED)
147 phi_val.lattice_val = UNDEFINED;
149 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
151 /* Compute the meet operator over all the PHI arguments. */
152 edge e = PHI_ARG_EDGE (phi, i);
153 tree rdef = PHI_ARG_DEF (phi, i);
154 value rdef_val;
155 if (dump_file && (dump_flags & TDF_DETAILS))
157 fprintf (dump_file,
158 "\n Argument #%d (%d -> %d)\n",
159 i, e->src->index, e->dest->index);
161 if (TREE_CODE (rdef) == INTEGER_CST)
163 rdef_val.lattice_val = KNOWN;
164 rdef_val.alignment.n = TREE_INT_CST_LOW (rdef) * BITS_PER_UNIT;
165 if (rdef_val.alignment.n == 0)
166 rdef_val.alignment.n = 1;
167 rdef_val.alignment.offset = 0;
169 else if (TREE_CODE (rdef) == SSA_NAME)
171 rdef_val = *(get_value (rdef));
173 else
175 rdef_val.lattice_val = KNOWN;
176 rdef_val.alignment.n = BITS_PER_UNIT;
177 rdef_val.alignment.offset = 0;
179 phi_val = cp_lattice_meet (phi_val, rdef_val);
181 if (dump_file && (dump_flags & TDF_DETAILS))
183 fprintf (dump_file, "\t");
184 print_generic_expr (dump_file, rdef, dump_flags);
185 dump_lattice_value (dump_file, "\tValue: ", rdef_val);
186 fprintf (dump_file, "\n");
190 if (dump_file && (dump_flags & TDF_DETAILS))
192 dump_lattice_value (dump_file, "\n PHI node value: ", phi_val);
193 fprintf (dump_file, "\n\n");
196 if (set_lattice_value (PHI_RESULT (phi), phi_val))
198 if (phi_val.lattice_val == UNDEFINED)
199 return SSA_PROP_VARYING;
200 else
201 return SSA_PROP_INTERESTING;
203 else
204 return SSA_PROP_NOT_INTERESTING;
208 /* Find the greatest common denominator of A and B. */
210 static int
211 gcd (int a, int b)
214 int x, y, z;
216 x = a;
217 y = b;
219 while (x>0)
221 z = y % x;
222 y = x;
223 x = z;
226 return (y);
229 /* Find the largest power of two alignment such that off1 % newalign
230 == off2 % newalign. */
232 static unsigned int
233 find_largest_common_alignment (unsigned int off1, unsigned int off2)
235 unsigned int mask;
236 mask = ((unsigned HOST_WIDE_INT)1 << ceil_log2 (MIN (off1, off2))) - 1;
237 while ((off1 & mask) != (off2 & mask))
238 mask >>= 1;
239 return mask + 1;
241 /* Compute the meet operator between VAL1 and VAL2:
243 any M UNDEFINED = any
244 n1, off1 M n2, off2 = n1, off1 if n1 == n2 && off1 == off2
245 n1, off1 M n2, off2 = largest_common_alignment (off1 % gcd (n1, n2), off2 % gcd (n1 ,n2))
248 static value
249 cp_lattice_meet (value val1, value val2)
251 value result;
253 /* any M UNDEFINED = any. */
254 if (val1.lattice_val == UNDEFINED)
255 return val2;
256 else if (val2.lattice_val == UNDEFINED)
257 return val1;
259 if (val1.alignment.n == val2.alignment.n
260 && val1.alignment.offset == val2.alignment.offset)
262 result.lattice_val = KNOWN;
263 result.alignment.n = val2.alignment.n;
264 result.alignment.offset = val2.alignment.offset;
266 else
268 unsigned int newalign;
269 unsigned int newoff1;
270 unsigned int newoff2;
271 newalign = gcd (val1.alignment.n, val2.alignment.n);
272 newoff1 = val1.alignment.offset % newalign;
273 newoff2 = val2.alignment.offset % newalign;
274 if (newoff1 != newoff2)
276 newalign = find_largest_common_alignment (newoff1, newoff2);
277 newoff1 = newoff1 % newalign;
278 newoff2 = newoff2 % newalign;
280 result.lattice_val = KNOWN;
281 result.alignment.n = newalign;
282 result.alignment.offset = newoff1;
285 return result;
289 /* Evaluate statement STMT. If the statement produces an alignment value and
290 its evaluation changes the lattice value of its output, do the following:
292 - If the statement is an assignment, add all the SSA edges starting at
293 this definition. */
295 static enum ssa_prop_result
296 visit_stmt (tree stmt, edge *taken_edge_p ATTRIBUTE_UNUSED, tree *output_p)
298 stmt_ann_t ann;
299 tree def;
300 ssa_op_iter iter;
302 if (dump_file && (dump_flags & TDF_DETAILS))
304 fprintf (dump_file, "\nVisiting statement: ");
305 print_generic_stmt (dump_file, stmt, TDF_SLIM);
306 fprintf (dump_file, "\n");
309 ann = stmt_ann (stmt);
311 /* Now examine the statement. If the statement is an assignment that
312 produces a single output value, evaluate its RHS to see if the lattice
313 value of its output has changed. */
314 if (TREE_CODE (stmt) == MODIFY_EXPR
315 && TREE_CODE (TREE_OPERAND (stmt, 0)) == SSA_NAME)
316 return visit_assignment (stmt, output_p);
318 /* Definitions made by statements other than assignments to SSA_NAMEs
319 represent unknown modifications to their outputs. Mark them KNOWN. */
320 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
321 def_to_known_bpu_0 (def);
323 return SSA_PROP_VARYING;
327 /* Visit the assignment statement STMT. Set the value of its LHS to the
328 value computed by the RHS. */
330 static enum ssa_prop_result
331 visit_assignment (tree stmt, tree *output_p)
333 value val;
334 tree lhs, rhs;
336 lhs = TREE_OPERAND (stmt, 0);
337 rhs = TREE_OPERAND (stmt, 1);
338 STRIP_NOPS (rhs);
340 if (TREE_CODE (rhs) == SSA_NAME)
342 /* For a simple copy operation, we copy the lattice values. */
343 value *nval = get_value (rhs);
344 val = *nval;
346 else
348 /* Evaluate the statement. */
349 val = evaluate_stmt (stmt);
352 /* Set the lattice value of the statement's output. */
353 if (set_lattice_value (lhs, val))
355 *output_p = lhs;
356 if (val.lattice_val == UNDEFINED)
357 return SSA_PROP_VARYING;
358 else
359 return SSA_PROP_INTERESTING;
361 else
362 return SSA_PROP_NOT_INTERESTING;
367 /* Evaluate statement STMT. */
369 static value
370 evaluate_stmt (tree stmt)
372 value val;
373 tree rhs;
374 rhs = get_rhs (stmt);
376 if (TREE_CODE (rhs) == INTEGER_CST)
378 val.lattice_val = KNOWN;
379 val.alignment.n = TREE_INT_CST_LOW (rhs) * BITS_PER_UNIT;
380 if (val.alignment.n == 0)
381 val.alignment.n = 1;
382 val.alignment.offset = 0;
384 else if (TREE_CODE (rhs) == PLUS_EXPR || TREE_CODE (rhs) == MINUS_EXPR)
386 tree op1 = TREE_OPERAND (rhs, 0);
387 tree op2 = TREE_OPERAND (rhs, 1);
388 value *op1val = NULL;
389 int newoffset = 0;
390 if (TREE_CODE (op1) == SSA_NAME)
391 op1val = get_value (op1);
392 if (TREE_CODE (op2) == INTEGER_CST)
393 newoffset = TREE_INT_CST_LOW (op2);
394 if (op1val == NULL
395 || newoffset == 0
396 || (op1val && op1val->lattice_val == UNDEFINED))
398 val.lattice_val = KNOWN;
399 val.alignment.n = BITS_PER_UNIT;
400 val.alignment.offset = 0;
402 else
404 val = *op1val;
405 val.alignment.offset += (BITS_PER_UNIT * newoffset) % val.alignment.n;
408 else
410 val.lattice_val = KNOWN;
411 val.alignment.n = BITS_PER_UNIT;
412 val.alignment.offset = 0;
414 return val;
418 /* Debugging dumps. */
420 static void
421 dump_lattice_value (FILE *outf, const char *prefix, value val)
423 switch (val.lattice_val)
425 case UNDEFINED:
426 fprintf (outf, "%sUNDEFINED", prefix);
427 break;
428 case KNOWN:
429 fprintf (outf, "%sKNOWN (%d, %d)", prefix,
430 val.alignment.n, val.alignment.offset);
431 break;
432 default:
433 abort ();
437 /* Initialize local data structures and worklists for CCP. */
439 static void
440 initialize (void)
442 basic_block bb;
444 value_vector = (value *) xmalloc (num_ssa_names * sizeof (value));
445 memset (value_vector, 0, num_ssa_names * sizeof (value));
447 FOR_EACH_BB (bb)
449 tree phi;
450 block_stmt_iterator bsi;
451 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
452 DONT_SIMULATE_AGAIN (phi) = false;
453 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
455 tree stmt = bsi_stmt (bsi);
456 DONT_SIMULATE_AGAIN (stmt) = false;
460 if (dump_file && (dump_flags & TDF_DETAILS))
461 dump_immediate_uses (dump_file);
465 /* Free allocated storage. */
467 static void
468 finalize (void)
471 free (value_vector);
474 /* Set the lattice value for the variable VAR to KNOWN, {BITS PER
475 UNIT, 0}. */
477 static void
478 def_to_known_bpu_0(tree var)
480 value val;
481 val.lattice_val = KNOWN;
482 val.alignment.n = BITS_PER_UNIT;
483 val.alignment.offset = 0;
484 set_lattice_value (var, val);
487 /* Set the lattice value for variable VAR to VAL. */
489 static bool
490 set_lattice_value (tree var, value val)
492 value *old = get_value (var);
494 #ifdef ENABLE_CHECKING
495 if (val.lattice_val == UNDEFINED)
497 /* (KNOWN->UNDEFINED) is never a valid state transition, unless
498 the default value f the var was known. */
499 if (old->lattice_val == KNOWN
500 && get_default_value (var).lattice_val != KNOWN)
501 abort ();
503 #endif
505 if (old->lattice_val != val.lattice_val)
507 if (dump_file && (dump_flags & TDF_DETAILS))
509 dump_lattice_value (dump_file,
510 "Lattice value changed to ", val);
511 fprintf (dump_file, ". Adding definition to SSA edges.\n");
513 *old = val;
514 return true;
516 return false;
519 /* Return a default value for variable VAR using the following rules:
521 1- Global and static variables are considered KNOWN,
522 {BITS_PER_UNIT, 0}, or the minimum alignment required by their
523 underlying type, for pointers.
525 2- Function arguments are considered KNOWN, {BITS_PER_UNIT, 0}, or
526 the minimum alignment required by their underlying type, for pointers.
528 3- Any other value is considered UNDEFINED. This is useful when
529 considering PHI nodes. PHI arguments that are undefined do not
530 change the alignment of the phi. */
532 static value
533 get_default_value (tree var)
535 value val;
536 tree sym;
538 if (TREE_CODE (var) == SSA_NAME)
539 sym = SSA_NAME_VAR (var);
540 else
542 #ifdef ENABLE_CHECKING
543 if (!DECL_P (var))
544 abort ();
545 #endif
546 sym = var;
549 val.lattice_val = UNDEFINED;
550 val.alignment.n = 0;
551 val.alignment.offset = 0;
552 if (TREE_CODE (sym) == PARM_DECL
553 || (decl_function_context (sym) != current_function_decl
554 || TREE_STATIC (sym)))
556 val.lattice_val = KNOWN;
557 /* Pointer types are assumed to have the minimum alignment
558 required by their underlying type. */
559 if (POINTER_TYPE_P (TREE_TYPE (sym)))
560 val.alignment.n = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (sym)));
561 else
562 val.alignment.n = BITS_PER_UNIT;
563 val.alignment.offset = 0;
565 else
567 enum tree_code code;
568 tree stmt = SSA_NAME_DEF_STMT (var);
570 if (stmt && !IS_EMPTY_STMT (stmt))
572 code = TREE_CODE (stmt);
573 if (code != MODIFY_EXPR && code != PHI_NODE)
575 val.lattice_val = KNOWN;
576 val.alignment.n = BITS_PER_UNIT;
577 val.alignment.offset = 0;
581 return val;
586 struct tree_opt_pass pass_align_analysis =
588 "align", /* name */
589 NULL, /* gate */
590 compute_ptr_alignment, /* execute */
591 NULL, /* sub */
592 NULL, /* next */
593 0, /* static_pass_number */
594 0, /* tv_id */
595 PROP_cfg | PROP_ssa, /* properties_required */
596 PROP_align, /* properties_provided */
597 0, /* properties_destroyed */
598 0, /* todo_flags_start */
599 0, /* todo_flags_finish */
600 0 /* letter */
602 /* Get the lattice + alignment info associated with var */
604 static value *
605 get_value (tree var)
607 value *val;
608 if (TREE_CODE (var) != SSA_NAME)
609 abort ();
610 val = &value_vector [SSA_NAME_VERSION (var)];
611 if (val->lattice_val == UNINITIALIZED)
612 *val = get_default_value (var);
613 return val;
616 /* Dump alignment information for SSA_NAME PTR into FILE. */
618 static void
619 dump_align_info_for (FILE *file, tree ptr)
621 struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr);
623 fprintf (file, "Pointer ");
624 print_generic_expr (file, ptr, dump_flags);
626 if (pi == NULL)
627 return;
629 fprintf (file, " alignment n, offset = (%d, %d)\n",
630 pi->alignment.n, pi->alignment.offset);
634 /* Dump alignment information into FILE. NOTE: This function is slow, as
635 it needs to traverse the whole CFG looking for pointer SSA_NAMEs. */
637 void
638 dump_align_info (FILE *file)
640 basic_block bb;
641 block_stmt_iterator si;
642 size_t i;
643 const char *fname =
644 lang_hooks.decl_printable_name (current_function_decl, 2);
645 ssa_op_iter iter;
647 fprintf (file, "\nAlignment info for pointers in %s\n\n", fname);
649 /* First dump points-to information for the default definitions of
650 pointer variables. This is necessary because default definitions are
651 not part of the code. */
652 for (i = 0; i < num_referenced_vars; i++)
654 tree var = referenced_var (i);
655 if (POINTER_TYPE_P (TREE_TYPE (var)))
657 if (default_def (var))
658 dump_align_info_for (file, default_def (var));
662 /* Dump points-to information for every pointer defined in the program. */
663 FOR_EACH_BB (bb)
665 tree phi;
667 for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
669 tree ptr = PHI_RESULT (phi);
670 if (POINTER_TYPE_P (TREE_TYPE (ptr)))
671 dump_align_info_for (file, ptr);
674 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
676 tree stmt = bsi_stmt (si);
677 def_operand_p def_p;
679 FOR_EACH_SSA_DEF_OPERAND (def_p, stmt, iter, SSA_OP_DEF)
680 if (POINTER_TYPE_P (TREE_TYPE (DEF_FROM_PTR (def_p))))
681 dump_align_info_for (file, DEF_FROM_PTR (def_p));
685 fprintf (file, "\n");
688 /* Dump out alignment info for pointers to stderr */
689 void
690 debug_align_info (void)
692 dump_align_info (stderr);