Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-reassoc.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
104 | 104 |
105 Then build a binary op of d + e | 105 Then build a binary op of d + e |
106 mergetmp2 = d + e | 106 mergetmp2 = d + e |
107 | 107 |
108 and put mergetmp2 on the merge worklist. | 108 and put mergetmp2 on the merge worklist. |
109 | 109 |
110 so merge worklist = {mergetmp, c, mergetmp2} | 110 so merge worklist = {mergetmp, c, mergetmp2} |
111 | 111 |
112 Continue building binary ops of these operations until you have only | 112 Continue building binary ops of these operations until you have only |
113 one operation left on the worklist. | 113 one operation left on the worklist. |
114 | 114 |
115 So we have | 115 So we have |
116 | 116 |
117 build binary op | 117 build binary op |
118 mergetmp3 = mergetmp + c | 118 mergetmp3 = mergetmp + c |
119 | 119 |
120 worklist = {mergetmp2, mergetmp3} | 120 worklist = {mergetmp2, mergetmp3} |
121 | 121 |
122 mergetmp4 = mergetmp2 + mergetmp3 | 122 mergetmp4 = mergetmp2 + mergetmp3 |
123 | 123 |
124 worklist = {mergetmp4} | 124 worklist = {mergetmp4} |
125 | 125 |
126 because we have one operation left, we can now just set the original | 126 because we have one operation left, we can now just set the original |
127 statement equal to the result of that operation. | 127 statement equal to the result of that operation. |
128 | 128 |
129 This will at least expose a + b and d + e to redundancy elimination | 129 This will at least expose a + b and d + e to redundancy elimination |
130 as binary operations. | 130 as binary operations. |
131 | 131 |
132 For extra points, you can reuse the old statements to build the | 132 For extra points, you can reuse the old statements to build the |
133 mergetmps, since you shouldn't run out. | 133 mergetmps, since you shouldn't run out. |
134 | 134 |
135 So why don't we do this? | 135 So why don't we do this? |
136 | 136 |
137 Because it's expensive, and rarely will help. Most trees we are | 137 Because it's expensive, and rarely will help. Most trees we are |
138 reassociating have 3 or less ops. If they have 2 ops, they already | 138 reassociating have 3 or less ops. If they have 2 ops, they already |
139 will be written into a nice single binary op. If you have 3 ops, a | 139 will be written into a nice single binary op. If you have 3 ops, a |
140 single simple check suffices to tell you whether the first two are of the | 140 single simple check suffices to tell you whether the first two are of the |
141 same rank. If so, you know to order it | 141 same rank. If so, you know to order it |
142 | 142 |
143 mergetmp = op1 + op2 | 143 mergetmp = op1 + op2 |
144 newstmt = mergetmp + op3 | 144 newstmt = mergetmp + op3 |
145 | 145 |
146 instead of | 146 instead of |
147 mergetmp = op2 + op3 | 147 mergetmp = op2 + op3 |
148 newstmt = mergetmp + op1 | 148 newstmt = mergetmp + op1 |
149 | 149 |
150 If all three are of the same rank, you can't expose them all in a | 150 If all three are of the same rank, you can't expose them all in a |
151 single binary operator anyway, so the above is *still* the best you | 151 single binary operator anyway, so the above is *still* the best you |
152 can do. | 152 can do. |
153 | 153 |
154 Thus, this is what we do. When we have three ops left, we check to see | 154 Thus, this is what we do. When we have three ops left, we check to see |
155 what order to put them in, and call it a day. As a nod to vector sum | 155 what order to put them in, and call it a day. As a nod to vector sum |
156 reduction, we check if any of the ops are really a phi node that is a | 156 reduction, we check if any of the ops are really a phi node that is a |
157 destructive update for the associating op, and keep the destructive | 157 destructive update for the associating op, and keep the destructive |
158 update together for vector sum reduction recognition. */ | 158 update together for vector sum reduction recognition. */ |
190 | 190 |
191 static inline long | 191 static inline long |
192 find_operand_rank (tree e) | 192 find_operand_rank (tree e) |
193 { | 193 { |
194 void **slot = pointer_map_contains (operand_rank, e); | 194 void **slot = pointer_map_contains (operand_rank, e); |
195 return slot ? (long) *slot : -1; | 195 return slot ? (long) (intptr_t) *slot : -1; |
196 } | 196 } |
197 | 197 |
198 /* Insert {E,RANK} into the operand rank hashtable. */ | 198 /* Insert {E,RANK} into the operand rank hashtable. */ |
199 | 199 |
200 static inline void | 200 static inline void |
202 { | 202 { |
203 void **slot; | 203 void **slot; |
204 gcc_assert (rank > 0); | 204 gcc_assert (rank > 0); |
205 slot = pointer_map_insert (operand_rank, e); | 205 slot = pointer_map_insert (operand_rank, e); |
206 gcc_assert (!*slot); | 206 gcc_assert (!*slot); |
207 *slot = (void *) rank; | 207 *slot = (void *) (intptr_t) rank; |
208 } | 208 } |
209 | 209 |
210 /* Given an expression E, return the rank of the expression. */ | 210 /* Given an expression E, return the rank of the expression. */ |
211 | 211 |
212 static long | 212 static long |
240 stmt = SSA_NAME_DEF_STMT (e); | 240 stmt = SSA_NAME_DEF_STMT (e); |
241 if (gimple_bb (stmt) == NULL) | 241 if (gimple_bb (stmt) == NULL) |
242 return 0; | 242 return 0; |
243 | 243 |
244 if (!is_gimple_assign (stmt) | 244 if (!is_gimple_assign (stmt) |
245 || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS)) | 245 || gimple_vdef (stmt)) |
246 return bb_rank[gimple_bb (stmt)->index]; | 246 return bb_rank[gimple_bb (stmt)->index]; |
247 | 247 |
248 /* If we already have a rank for this expression, use that. */ | 248 /* If we already have a rank for this expression, use that. */ |
249 rank = find_operand_rank (e); | 249 rank = find_operand_rank (e); |
250 if (rank != -1) | 250 if (rank != -1) |
445 | 445 |
446 if (VEC_length (operand_entry_t, *ops) == 2) | 446 if (VEC_length (operand_entry_t, *ops) == 2) |
447 { | 447 { |
448 VEC_free (operand_entry_t, heap, *ops); | 448 VEC_free (operand_entry_t, heap, *ops); |
449 *ops = NULL; | 449 *ops = NULL; |
450 add_to_ops_vec (ops, fold_convert (TREE_TYPE (last->op), | 450 add_to_ops_vec (ops, fold_convert (TREE_TYPE (last->op), |
451 integer_zero_node)); | 451 integer_zero_node)); |
452 *all_done = true; | 452 *all_done = true; |
453 } | 453 } |
454 else | 454 else |
455 { | 455 { |
509 print_generic_expr (dump_file, oe->op, 0); | 509 print_generic_expr (dump_file, oe->op, 0); |
510 fprintf (dump_file, " -> 0\n"); | 510 fprintf (dump_file, " -> 0\n"); |
511 } | 511 } |
512 | 512 |
513 VEC_ordered_remove (operand_entry_t, *ops, i); | 513 VEC_ordered_remove (operand_entry_t, *ops, i); |
514 add_to_ops_vec (ops, fold_convert(TREE_TYPE (oe->op), | 514 add_to_ops_vec (ops, fold_convert(TREE_TYPE (oe->op), |
515 integer_zero_node)); | 515 integer_zero_node)); |
516 VEC_ordered_remove (operand_entry_t, *ops, currindex); | 516 VEC_ordered_remove (operand_entry_t, *ops, currindex); |
517 reassociate_stats.ops_eliminated ++; | 517 reassociate_stats.ops_eliminated ++; |
518 | 518 |
519 return true; | 519 return true; |
577 oe->op = fold_convert (TREE_TYPE (oe->op), integer_zero_node); | 577 oe->op = fold_convert (TREE_TYPE (oe->op), integer_zero_node); |
578 else if (opcode == BIT_IOR_EXPR) | 578 else if (opcode == BIT_IOR_EXPR) |
579 oe->op = build_low_bits_mask (TREE_TYPE (oe->op), | 579 oe->op = build_low_bits_mask (TREE_TYPE (oe->op), |
580 TYPE_PRECISION (TREE_TYPE (oe->op))); | 580 TYPE_PRECISION (TREE_TYPE (oe->op))); |
581 | 581 |
582 reassociate_stats.ops_eliminated | 582 reassociate_stats.ops_eliminated |
583 += VEC_length (operand_entry_t, *ops) - 1; | 583 += VEC_length (operand_entry_t, *ops) - 1; |
584 VEC_free (operand_entry_t, heap, *ops); | 584 VEC_free (operand_entry_t, heap, *ops); |
585 *ops = NULL; | 585 *ops = NULL; |
586 VEC_safe_push (operand_entry_t, heap, *ops, oe); | 586 VEC_safe_push (operand_entry_t, heap, *ops, oe); |
587 return true; | 587 return true; |
616 if (VEC_length (operand_entry_t, *ops) != 1) | 616 if (VEC_length (operand_entry_t, *ops) != 1) |
617 { | 617 { |
618 if (dump_file && (dump_flags & TDF_DETAILS)) | 618 if (dump_file && (dump_flags & TDF_DETAILS)) |
619 fprintf (dump_file, "Found & 0, removing all other ops\n"); | 619 fprintf (dump_file, "Found & 0, removing all other ops\n"); |
620 | 620 |
621 reassociate_stats.ops_eliminated | 621 reassociate_stats.ops_eliminated |
622 += VEC_length (operand_entry_t, *ops) - 1; | 622 += VEC_length (operand_entry_t, *ops) - 1; |
623 | 623 |
624 VEC_free (operand_entry_t, heap, *ops); | 624 VEC_free (operand_entry_t, heap, *ops); |
625 *ops = NULL; | 625 *ops = NULL; |
626 VEC_safe_push (operand_entry_t, heap, *ops, oelast); | 626 VEC_safe_push (operand_entry_t, heap, *ops, oelast); |
627 return; | 627 return; |
628 } | 628 } |
644 if (VEC_length (operand_entry_t, *ops) != 1) | 644 if (VEC_length (operand_entry_t, *ops) != 1) |
645 { | 645 { |
646 if (dump_file && (dump_flags & TDF_DETAILS)) | 646 if (dump_file && (dump_flags & TDF_DETAILS)) |
647 fprintf (dump_file, "Found | -1, removing all other ops\n"); | 647 fprintf (dump_file, "Found | -1, removing all other ops\n"); |
648 | 648 |
649 reassociate_stats.ops_eliminated | 649 reassociate_stats.ops_eliminated |
650 += VEC_length (operand_entry_t, *ops) - 1; | 650 += VEC_length (operand_entry_t, *ops) - 1; |
651 | 651 |
652 VEC_free (operand_entry_t, heap, *ops); | 652 VEC_free (operand_entry_t, heap, *ops); |
653 *ops = NULL; | 653 *ops = NULL; |
654 VEC_safe_push (operand_entry_t, heap, *ops, oelast); | 654 VEC_safe_push (operand_entry_t, heap, *ops, oelast); |
655 return; | 655 return; |
656 } | 656 } |
657 } | 657 } |
658 else if (integer_zerop (oelast->op)) | 658 else if (integer_zerop (oelast->op)) |
659 { | 659 { |
660 if (VEC_length (operand_entry_t, *ops) != 1) | 660 if (VEC_length (operand_entry_t, *ops) != 1) |
661 { | 661 { |
662 if (dump_file && (dump_flags & TDF_DETAILS)) | 662 if (dump_file && (dump_flags & TDF_DETAILS)) |
675 { | 675 { |
676 if (VEC_length (operand_entry_t, *ops) != 1) | 676 if (VEC_length (operand_entry_t, *ops) != 1) |
677 { | 677 { |
678 if (dump_file && (dump_flags & TDF_DETAILS)) | 678 if (dump_file && (dump_flags & TDF_DETAILS)) |
679 fprintf (dump_file, "Found * 0, removing all other ops\n"); | 679 fprintf (dump_file, "Found * 0, removing all other ops\n"); |
680 | 680 |
681 reassociate_stats.ops_eliminated | 681 reassociate_stats.ops_eliminated |
682 += VEC_length (operand_entry_t, *ops) - 1; | 682 += VEC_length (operand_entry_t, *ops) - 1; |
683 VEC_free (operand_entry_t, heap, *ops); | 683 VEC_free (operand_entry_t, heap, *ops); |
684 *ops = NULL; | 684 *ops = NULL; |
685 VEC_safe_push (operand_entry_t, heap, *ops, oelast); | 685 VEC_safe_push (operand_entry_t, heap, *ops, oelast); |
686 return; | 686 return; |
1738 | 1738 |
1739 /* Break up subtract operations in block BB. | 1739 /* Break up subtract operations in block BB. |
1740 | 1740 |
1741 We do this top down because we don't know whether the subtract is | 1741 We do this top down because we don't know whether the subtract is |
1742 part of a possible chain of reassociation except at the top. | 1742 part of a possible chain of reassociation except at the top. |
1743 | 1743 |
1744 IE given | 1744 IE given |
1745 d = f + g | 1745 d = f + g |
1746 c = a + e | 1746 c = a + e |
1747 b = c - d | 1747 b = c - d |
1748 q = b - r | 1748 q = b - r |
1749 k = t - q | 1749 k = t - q |
1750 | 1750 |
1751 we want to break up k = t - q, but we won't until we've transformed q | 1751 we want to break up k = t - q, but we won't until we've transformed q |
1752 = b - r, which won't be broken up until we transform b = c - d. | 1752 = b - r, which won't be broken up until we transform b = c - d. |
1753 | 1753 |
1754 En passant, clear the GIMPLE visited flag on every statement. */ | 1754 En passant, clear the GIMPLE visited flag on every statement. */ |
1755 | 1755 |
2068 execute_reassoc, /* execute */ | 2068 execute_reassoc, /* execute */ |
2069 NULL, /* sub */ | 2069 NULL, /* sub */ |
2070 NULL, /* next */ | 2070 NULL, /* next */ |
2071 0, /* static_pass_number */ | 2071 0, /* static_pass_number */ |
2072 TV_TREE_REASSOC, /* tv_id */ | 2072 TV_TREE_REASSOC, /* tv_id */ |
2073 PROP_cfg | PROP_ssa | PROP_alias, /* properties_required */ | 2073 PROP_cfg | PROP_ssa, /* properties_required */ |
2074 0, /* properties_provided */ | 2074 0, /* properties_provided */ |
2075 0, /* properties_destroyed */ | 2075 0, /* properties_destroyed */ |
2076 0, /* todo_flags_start */ | 2076 0, /* todo_flags_start */ |
2077 TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ | 2077 TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ |
2078 } | 2078 } |