1 /* Reassociation for trees.
2 Copyright (C) 2005 Free Software Foundation, Inc.
3 Contributed by Daniel Berlin <dan@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, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "coretypes.h"
29 #include "basic-block.h"
30 #include "diagnostic.h"
31 #include "tree-inline.h"
32 #include "tree-flow.h"
33 #include "tree-gimple.h"
34 #include "tree-dump.h"
37 #include "tree-iterator.h"
38 #include "tree-pass.h"
40 /* This is a simple global reassociation pass that uses a combination
41 of heuristics and a hashtable to try to expose more operations to
44 The basic idea behind the heuristic is to rank expressions by
45 depth of the computation tree and loop depth, and try to produce
46 expressions consisting of small rank operations, as they are more
47 likely to reoccur. In addition, we use a hashtable to try to see
48 if we can transpose an operation into something we have seen
51 Note that the way the hashtable is structured will sometimes find
52 matches that will not expose additional redundancies, since it is
53 not unwound as we traverse back up one branch of the dominator
54 tree and down another. However, the cost of improving this is
55 probably not worth the additional benefits it will bring. */
60 int reassociated_by_rank
;
61 int reassociated_by_match
;
66 /* Seen binary operator hashtable. */
67 static htab_t seen_binops
;
69 /* Binary operator struct. */
71 typedef struct seen_binop_d
77 /* Return a SEEN_BINOP_T if we have seen an associative binary
78 operator with OP1 and OP2 in it. */
81 find_seen_binop (tree op1
, tree op2
)
84 struct seen_binop_d sbd
;
87 slot
= htab_find_slot (seen_binops
, &sbd
, NO_INSERT
);
90 return ((seen_binop_t
) *slot
);
93 /* Insert a binary operator consisting of OP1 and OP2 into the
97 insert_seen_binop (tree op1
, tree op2
)
100 seen_binop_t new_pair
= xmalloc (sizeof (*new_pair
));
103 slot
= htab_find_slot (seen_binops
, new_pair
, INSERT
);
109 /* Return the hash value for a seen binop structure pointed to by P.
110 Because all the binops we consider are associative, we just add the
111 hash value for op1 and op2. */
114 seen_binop_hash (const void *p
)
116 const seen_binop_t sb
= (seen_binop_t
) p
;
117 return iterative_hash_expr (sb
->op1
, 0) + iterative_hash_expr (sb
->op2
, 0);
120 /* Return true if two seen binop structures pointed to by P1 and P2 are equal.
121 We have to check the operators both ways because we don't know what
122 order they appear in the table. */
125 seen_binop_eq (const void *p1
, const void *p2
)
127 const seen_binop_t sb1
= (seen_binop_t
) p1
;
128 const seen_binop_t sb2
= (seen_binop_t
) p2
;
129 return (sb1
->op1
== sb2
->op1
&& sb1
->op2
== sb2
->op2
)
130 || (sb1
->op2
== sb2
->op1
&& sb1
->op1
== sb2
->op2
);
133 /* Value rank structure. */
135 typedef struct valrank_d
141 /* Starting rank number for a given basic block, so that we can rank
142 operations using unmovable instructions in that BB based on the bb
144 static unsigned int *bb_rank
;
146 /* Value rank hashtable. */
147 static htab_t value_rank
;
150 /* Look up the value rank structure for expression E. */
153 find_value_rank (tree e
)
156 struct valrank_d vrd
;
158 slot
= htab_find_slot (value_rank
, &vrd
, NO_INSERT
);
161 return ((valrank_t
) *slot
);
164 /* Insert {E,RANK} into the value rank hashtable. */
167 insert_value_rank (tree e
, unsigned int rank
)
170 valrank_t new_pair
= xmalloc (sizeof (*new_pair
));
172 new_pair
->rank
= rank
;
173 slot
= htab_find_slot (value_rank
, new_pair
, INSERT
);
174 gcc_assert (*slot
== NULL
);
180 /* Return the hash value for a value rank structure */
183 valrank_hash (const void *p
)
185 const valrank_t vr
= (valrank_t
) p
;
186 return iterative_hash_expr (vr
->e
, 0);
189 /* Return true if two value rank structures are equal. */
192 valrank_eq (const void *p1
, const void *p2
)
194 const valrank_t vr1
= (valrank_t
) p1
;
195 const valrank_t vr2
= (valrank_t
) p2
;
196 return vr1
->e
== vr2
->e
;
200 /* Initialize the reassociation pass. */
206 unsigned int rank
= 2;
209 int *bbs
= xmalloc ((last_basic_block
+ 1) * sizeof (int));
211 memset (&reassociate_stats
, 0, sizeof (reassociate_stats
));
213 /* Reverse RPO (Reverse Post Order) will give us something where
214 deeper loops come later. */
215 flow_reverse_top_sort_order_compute (bbs
);
216 bb_rank
= xcalloc (last_basic_block
+ 1, sizeof (unsigned int));
217 value_rank
= htab_create (511, valrank_hash
,
219 seen_binops
= htab_create (511, seen_binop_hash
,
220 seen_binop_eq
, free
);
222 /* Give each argument a distinct rank. */
223 for (param
= DECL_ARGUMENTS (current_function_decl
);
225 param
= TREE_CHAIN (param
))
227 if (default_def (param
) != NULL
)
229 tree def
= default_def (param
);
230 insert_value_rank (def
, ++rank
);
233 /* Give the chain decl a distinct rank. */
234 if (cfun
->static_chain_decl
!= NULL
)
236 tree def
= default_def (cfun
->static_chain_decl
);
238 insert_value_rank (def
, ++rank
);
241 /* Set up rank for each BB */
242 for (i
= 0; i
< n_basic_blocks
; i
++)
243 bb_rank
[bbs
[i
]] = ++rank
<< 16;
246 calculate_dominance_info (CDI_DOMINATORS
);
250 /* Cleanup after the reassociation pass, and print stats if
257 if (dump_file
&& (dump_flags
& TDF_STATS
))
259 fprintf (dump_file
, "Reassociation stats:\n");
260 fprintf (dump_file
, "Reassociated by rank: %d\n", reassociate_stats
.reassociated_by_rank
);
261 fprintf (dump_file
, "Reassociated by match: %d\n", reassociate_stats
.reassociated_by_match
);
263 htab_delete (value_rank
);
264 htab_delete (seen_binops
);
268 /* Given an expression E, return the rank of the expression. */
275 /* Constants have rank 0. */
276 if (is_gimple_min_invariant (e
))
279 /* SSA_NAME's have the rank of the expression they are the result
281 For globals and uninitialized values, the rank is 0.
282 For function arguments, use the pre-setup rank.
283 For PHI nodes, stores, asm statements, etc, we use the rank of
285 For simple operations, the rank is the maximum rank of any of
286 its operands, or the bb_rank, whichever is less.
287 I make no claims that this is optimal, however, it gives good
290 if (TREE_CODE (e
) == SSA_NAME
)
294 unsigned int rank
, maxrank
;
297 if (TREE_CODE (SSA_NAME_VAR (e
)) == PARM_DECL
298 && e
== default_def (SSA_NAME_VAR (e
)))
299 return find_value_rank (e
)->rank
;
301 stmt
= SSA_NAME_DEF_STMT (e
);
302 if (bb_for_stmt (stmt
) == NULL
)
305 if (TREE_CODE (stmt
) != MODIFY_EXPR
306 || !ZERO_SSA_OPERANDS (stmt
, SSA_OP_VIRTUAL_DEFS
))
307 return bb_rank
[bb_for_stmt (stmt
)->index
];
309 /* If we already have a rank for this expression, use that. */
310 vr
= find_value_rank (e
);
314 /* Otherwise, find the maximum rank for the operands, or the bb
315 rank, whichever is less. */
317 maxrank
= bb_rank
[bb_for_stmt(stmt
)->index
];
318 rhs
= TREE_OPERAND (stmt
, 1);
319 if (TREE_CODE_LENGTH (TREE_CODE (rhs
)) == 0)
320 rank
= MAX (rank
, get_rank (rhs
));
324 i
< TREE_CODE_LENGTH (TREE_CODE (rhs
))
325 && TREE_OPERAND (rhs
, i
)
326 && rank
!= maxrank
; i
++)
327 rank
= MAX(rank
, get_rank (TREE_OPERAND (rhs
, i
)));
330 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
332 fprintf (dump_file
, "Rank for ");
333 print_generic_expr (dump_file
, e
, 0);
334 fprintf (dump_file
, " is %d\n", (rank
+ 1));
337 /* Note the rank in the hashtable so we don't recompute it. */
338 insert_value_rank (e
, (rank
+ 1));
342 /* Globals, etc, are rank 0 */
347 /* Decide whether we should transpose RHS and some operand of
349 If yes, then return true and set TAKEOP to the operand number of LHSDEFOP to
351 Otherwise, return false. */
354 should_transpose (tree rhs ATTRIBUTE_UNUSED
,
355 unsigned int rhsrank
,
356 tree lhsdefop
, unsigned int *takeop
)
358 /* Attempt to expose the low ranked
359 arguments to CSE if we have something like:
360 a = <rank 2> + c (rank 1)
361 b = a (rank 3) + d (rank 1)
362 We want to transform this into:
364 b = <rank 2> + <rank 3>
366 The op finding part wouldn't be necessary if
367 we could swap the operands above and not have
368 update_stmt change them back on us.
370 unsigned int lowrankop
;
371 unsigned int lowrank
;
372 unsigned int highrank
;
373 unsigned int highrankop
;
378 lowrank
= get_rank (TREE_OPERAND (lhsdefop
, 0));
379 temp
= get_rank (TREE_OPERAND (lhsdefop
, 1));
391 /* If highrank == lowrank, then we had something
393 a = <rank 1> + <rank 1>
394 already, so there is no guarantee that
395 swapping our argument in is going to be
397 If we run reassoc twice, we could probably
398 have a flag that switches this behavior on,
399 so that we try once without it, and once with
400 it, so that redundancy elimination sees it
404 if (lowrank
== rhsrank
&& highrank
!= lowrank
)
407 /* Also, see if the LHS's high ranked op should be switched with our
408 RHS simply because it is greater in rank than our current RHS. */
409 if (TREE_CODE (TREE_OPERAND (lhsdefop
, highrankop
)) == SSA_NAME
)
411 tree iop
= SSA_NAME_DEF_STMT (TREE_OPERAND (lhsdefop
, highrankop
));
412 if (TREE_CODE (iop
) == MODIFY_EXPR
)
413 iop
= TREE_OPERAND (iop
, 1);
414 if (TREE_CODE (iop
) == TREE_CODE (lhsdefop
))
416 if (rhsrank
< get_rank (TREE_OPERAND (lhsdefop
, *takeop
)))
423 /* Attempt to reassociate the associative binary operator BEXPR, which
424 is in the statement pointed to by CURRBSI. Return true if we
425 changed the statement. */
428 reassociate_expr (tree bexpr
, block_stmt_iterator
*currbsi
)
430 tree lhs
= TREE_OPERAND (bexpr
, 0);
431 tree rhs
= TREE_OPERAND (bexpr
, 1);
434 bool changed
= false;
435 unsigned int lhsrank
= get_rank (lhs
);
436 unsigned int rhsrank
= get_rank (rhs
);
438 /* If unsafe math optimizations we can do reassociation for non-integral
440 if ((!INTEGRAL_TYPE_P (TREE_TYPE (lhs
))
441 || !INTEGRAL_TYPE_P (TREE_TYPE (rhs
)))
442 && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE (rhs
))
443 || !SCALAR_FLOAT_TYPE_P (TREE_TYPE(lhs
))
444 || !flag_unsafe_math_optimizations
))
447 /* We want the greater ranked operand to be our "LHS" for simplicity
448 sake. There is no point in actually modifying the expression, as
449 update_stmt will simply resort the operands anyway. */
450 if (lhsrank
< rhsrank
)
462 /* If the high ranked operand is an SSA_NAME, and the binary
463 operator is not something we've already seen somewhere else
464 (i.e., it may be redundant), attempt to reassociate it.
466 We can't reassociate expressions unless the expression we are
467 going to reassociate with is only used in our current expression,
468 or else we may screw up other computations, like so:
475 We cannot reassociate and rewrite the "a = ..." ,
476 because that would change the value of the computation of
478 if (TREE_CODE (lhs
) == SSA_NAME
&& !find_seen_binop (lhs
, rhs
))
480 lhsdef
= SSA_NAME_DEF_STMT (lhs
);
481 if (TREE_CODE (lhsdef
) == MODIFY_EXPR
)
483 lhsi
= TREE_OPERAND (lhsdef
, 1);
484 if (TREE_CODE (lhsi
) == TREE_CODE (bexpr
))
488 if (single_imm_use (lhs
, &use
, &usestmt
))
490 unsigned int takeop
= 0;
491 unsigned int otherop
= 1;
492 bool foundmatch
= false;
493 bool foundrank
= false;
495 /* If we can easily transpose this into an operation
496 we've already seen, let's do that.
497 otherwise, let's try to expose low ranked ops to
499 if (find_seen_binop (TREE_OPERAND (lhsi
, 1), rhs
))
505 else if (find_seen_binop (TREE_OPERAND (lhsi
, 0),
512 else if (should_transpose (rhs
, rhsrank
, lhsi
,
517 if (foundmatch
|| foundrank
)
519 block_stmt_iterator lhsbsi
= bsi_for_stmt (lhsdef
);
520 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
522 fprintf (dump_file
, "Reassociating by %s\n",
523 foundmatch
? "match" : "rank");
524 fprintf (dump_file
, "Before LHS:");
525 print_generic_stmt (dump_file
, lhsi
, 0);
526 fprintf (dump_file
, "Before curr expr:");
527 print_generic_stmt (dump_file
, bexpr
, 0);
529 TREE_OPERAND (bexpr
, 0) = TREE_OPERAND (lhsi
, takeop
);
530 TREE_OPERAND (lhsi
, takeop
) = rhs
;
531 TREE_OPERAND (bexpr
, 1) = TREE_OPERAND (lhsdef
, 0);
532 if (dump_file
&& (dump_flags
& TDF_DETAILS
))
534 fprintf (dump_file
, "After LHS:");
535 print_generic_stmt (dump_file
, lhsi
, 0);
536 fprintf (dump_file
, "After curr expr:");
537 print_generic_stmt (dump_file
, bexpr
, 0);
539 bsi_move_before (&lhsbsi
, currbsi
);
540 update_stmt (lhsdef
);
541 update_stmt (bsi_stmt (*currbsi
));
542 lhsbsi
= bsi_for_stmt (lhsdef
);
543 update_stmt (bsi_stmt (lhsbsi
));
545 /* If update_stmt didn't reorder our operands,
546 we'd like to recurse on the expression we
547 just reassociated and reassociate it
548 top-down, exposing further opportunities.
549 Unfortunately, update_stmt does reorder them,
550 so we can't do this cheaply. */
552 reassociate_stats
.reassociated_by_rank
++;
554 reassociate_stats
.reassociated_by_match
++;
564 /* Reassociate expressions in basic block BB and its dominator as
565 children , return true if any
566 expressions changed. */
569 reassociate_bb (basic_block bb
)
571 bool changed
= false;
572 block_stmt_iterator bsi
;
575 for (bsi
= bsi_start (bb
); !bsi_end_p (bsi
); bsi_next (&bsi
))
577 tree stmt
= bsi_stmt (bsi
);
579 if (TREE_CODE (stmt
) == MODIFY_EXPR
)
581 tree rhs
= TREE_OPERAND (stmt
, 1);
582 if (associative_tree_code (TREE_CODE (rhs
)))
584 if (reassociate_expr (rhs
, &bsi
))
589 insert_seen_binop (TREE_OPERAND (rhs
, 0),
590 TREE_OPERAND (rhs
, 1));
594 for (son
= first_dom_son (CDI_DOMINATORS
, bb
);
596 son
= next_dom_son (CDI_DOMINATORS
, son
))
598 changed
|= reassociate_bb (son
);
607 bool changed
= false;
609 changed
= reassociate_bb (ENTRY_BLOCK_PTR
);
615 /* Gate and execute functions for Reassociation. */
618 execute_reassoc (void)
625 struct tree_opt_pass pass_reassoc
=
627 "reassoc", /* name */
629 execute_reassoc
, /* execute */
632 0, /* static_pass_number */
633 TV_TREE_REASSOC
, /* tv_id */
634 PROP_cfg
| PROP_ssa
| PROP_alias
, /* properties_required */
635 0, /* properties_provided */
636 0, /* properties_destroyed */
637 0, /* todo_flags_start */
638 TODO_update_ssa
| TODO_dump_func
639 | TODO_ggc_collect
| TODO_verify_ssa
, /* todo_flags_finish */