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)
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. */
24 #include "coretypes.h"
29 #include "hard-reg-set.h"
30 #include "basic-block.h"
34 #include "langhooks.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"
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
52 /* Possible lattice values. */
61 /* Main structure for CCP. Contains the lattice value and, if it's a
62 constant, the constant value. */
65 latticevalue lattice_val
;
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 */
92 compute_ptr_alignment (void)
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. */
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
132 static enum ssa_prop_result
133 visit_phi_node (tree phi
)
135 value phi_val
, *curr_val
;
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
));
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
);
155 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
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
));
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
;
201 return SSA_PROP_INTERESTING
;
204 return SSA_PROP_NOT_INTERESTING
;
208 /* Find the greatest common denominator of A and B. */
229 /* Find the largest power of two alignment such that off1 % newalign
230 == off2 % newalign. */
233 find_largest_common_alignment (unsigned int off1
, unsigned int off2
)
236 mask
= ((unsigned HOST_WIDE_INT
)1 << ceil_log2 (MIN (off1
, off2
))) - 1;
237 while ((off1
& mask
) != (off2
& mask
))
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))
249 cp_lattice_meet (value val1
, value val2
)
253 /* any M UNDEFINED = any. */
254 if (val1
.lattice_val
== UNDEFINED
)
256 else if (val2
.lattice_val
== UNDEFINED
)
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
;
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
;
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
295 static enum ssa_prop_result
296 visit_stmt (tree stmt
, edge
*taken_edge_p ATTRIBUTE_UNUSED
, tree
*output_p
)
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
)
336 lhs
= TREE_OPERAND (stmt
, 0);
337 rhs
= TREE_OPERAND (stmt
, 1);
340 if (TREE_CODE (rhs
) == SSA_NAME
)
342 /* For a simple copy operation, we copy the lattice values. */
343 value
*nval
= get_value (rhs
);
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
))
356 if (val
.lattice_val
== UNDEFINED
)
357 return SSA_PROP_VARYING
;
359 return SSA_PROP_INTERESTING
;
362 return SSA_PROP_NOT_INTERESTING
;
367 /* Evaluate statement STMT. */
370 evaluate_stmt (tree stmt
)
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)
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
;
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
);
396 || (op1val
&& op1val
->lattice_val
== UNDEFINED
))
398 val
.lattice_val
= KNOWN
;
399 val
.alignment
.n
= BITS_PER_UNIT
;
400 val
.alignment
.offset
= 0;
405 val
.alignment
.offset
+= (BITS_PER_UNIT
* newoffset
) % val
.alignment
.n
;
410 val
.lattice_val
= KNOWN
;
411 val
.alignment
.n
= BITS_PER_UNIT
;
412 val
.alignment
.offset
= 0;
418 /* Debugging dumps. */
421 dump_lattice_value (FILE *outf
, const char *prefix
, value val
)
423 switch (val
.lattice_val
)
426 fprintf (outf
, "%sUNDEFINED", prefix
);
429 fprintf (outf
, "%sKNOWN (%d, %d)", prefix
,
430 val
.alignment
.n
, val
.alignment
.offset
);
437 /* Initialize local data structures and worklists for CCP. */
444 value_vector
= (value
*) xmalloc (num_ssa_names
* sizeof (value
));
445 memset (value_vector
, 0, num_ssa_names
* sizeof (value
));
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. */
474 /* Set the lattice value for the variable VAR to KNOWN, {BITS PER
478 def_to_known_bpu_0(tree var
)
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. */
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
)
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");
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. */
533 get_default_value (tree var
)
538 if (TREE_CODE (var
) == SSA_NAME
)
539 sym
= SSA_NAME_VAR (var
);
542 #ifdef ENABLE_CHECKING
549 val
.lattice_val
= UNDEFINED
;
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
)));
562 val
.alignment
.n
= BITS_PER_UNIT
;
563 val
.alignment
.offset
= 0;
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;
586 struct tree_opt_pass pass_align_analysis
=
590 compute_ptr_alignment
, /* execute */
593 0, /* static_pass_number */
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 */
602 /* Get the lattice + alignment info associated with var */
608 if (TREE_CODE (var
) != SSA_NAME
)
610 val
= &value_vector
[SSA_NAME_VERSION (var
)];
611 if (val
->lattice_val
== UNINITIALIZED
)
612 *val
= get_default_value (var
);
616 /* Dump alignment information for SSA_NAME PTR into FILE. */
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
);
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. */
638 dump_align_info (FILE *file
)
641 block_stmt_iterator si
;
644 lang_hooks
.decl_printable_name (current_function_decl
, 2);
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. */
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
);
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 */
690 debug_align_info (void)
692 dump_align_info (stderr
);