Mercurial > hg > CbC > CbC_gcc
comparison gcc/tree-ssa-dom.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
27 #include "flags.h" | 27 #include "flags.h" |
28 #include "tm_p.h" | 28 #include "tm_p.h" |
29 #include "basic-block.h" | 29 #include "basic-block.h" |
30 #include "cfgloop.h" | 30 #include "cfgloop.h" |
31 #include "output.h" | 31 #include "output.h" |
32 #include "expr.h" | |
33 #include "function.h" | 32 #include "function.h" |
34 #include "diagnostic.h" | |
35 #include "tree-pretty-print.h" | 33 #include "tree-pretty-print.h" |
36 #include "gimple-pretty-print.h" | 34 #include "gimple-pretty-print.h" |
37 #include "timevar.h" | 35 #include "timevar.h" |
38 #include "tree-dump.h" | 36 #include "tree-dump.h" |
39 #include "tree-flow.h" | 37 #include "tree-flow.h" |
51 enum expr_kind | 49 enum expr_kind |
52 { | 50 { |
53 EXPR_SINGLE, | 51 EXPR_SINGLE, |
54 EXPR_UNARY, | 52 EXPR_UNARY, |
55 EXPR_BINARY, | 53 EXPR_BINARY, |
54 EXPR_TERNARY, | |
56 EXPR_CALL | 55 EXPR_CALL |
57 }; | 56 }; |
58 | 57 |
59 struct hashable_expr | 58 struct hashable_expr |
60 { | 59 { |
61 tree type; | 60 tree type; |
62 enum expr_kind kind; | 61 enum expr_kind kind; |
63 union { | 62 union { |
64 struct { tree rhs; } single; | 63 struct { tree rhs; } single; |
65 struct { enum tree_code op; tree opnd; } unary; | 64 struct { enum tree_code op; tree opnd; } unary; |
66 struct { enum tree_code op; tree opnd0; tree opnd1; } binary; | 65 struct { enum tree_code op; tree opnd0, opnd1; } binary; |
66 struct { enum tree_code op; tree opnd0, opnd1, opnd2; } ternary; | |
67 struct { tree fn; bool pure; size_t nargs; tree *args; } call; | 67 struct { tree fn; bool pure; size_t nargs; tree *args; } call; |
68 } ops; | 68 } ops; |
69 }; | 69 }; |
70 | 70 |
71 /* Structure for recording known values of a conditional expression | 71 /* Structure for recording known values of a conditional expression |
72 at the exits from its block. */ | 72 at the exits from its block. */ |
73 | 73 |
74 struct cond_equivalence | 74 typedef struct cond_equivalence_s |
75 { | 75 { |
76 struct hashable_expr cond; | 76 struct hashable_expr cond; |
77 tree value; | 77 tree value; |
78 }; | 78 } cond_equivalence; |
79 | |
80 DEF_VEC_O(cond_equivalence); | |
81 DEF_VEC_ALLOC_O(cond_equivalence,heap); | |
79 | 82 |
80 /* Structure for recording edge equivalences as well as any pending | 83 /* Structure for recording edge equivalences as well as any pending |
81 edge redirections during the dominator optimizer. | 84 edge redirections during the dominator optimizer. |
82 | 85 |
83 Computing and storing the edge equivalences instead of creating | 86 Computing and storing the edge equivalences instead of creating |
97 the equivalence will be stored here. */ | 100 the equivalence will be stored here. */ |
98 tree lhs; | 101 tree lhs; |
99 tree rhs; | 102 tree rhs; |
100 | 103 |
101 /* Traversing an edge may also indicate one or more particular conditions | 104 /* Traversing an edge may also indicate one or more particular conditions |
102 are true or false. The number of recorded conditions can vary, but | 105 are true or false. */ |
103 can be determined by the condition's code. So we have an array | 106 VEC(cond_equivalence, heap) *cond_equivalences; |
104 and its maximum index rather than use a varray. */ | |
105 struct cond_equivalence *cond_equivalences; | |
106 unsigned int max_cond_equivalences; | |
107 }; | 107 }; |
108 | 108 |
109 /* Hash table with expressions made available during the renaming process. | 109 /* Hash table with expressions made available during the renaming process. |
110 When an assignment of the form X_i = EXPR is found, the statement is | 110 When an assignment of the form X_i = EXPR is found, the statement is |
111 stored in this table. If the same expression EXPR is later found on the | 111 stored in this table. If the same expression EXPR is later found on the |
177 static tree lookup_avail_expr (gimple, bool); | 177 static tree lookup_avail_expr (gimple, bool); |
178 static hashval_t avail_expr_hash (const void *); | 178 static hashval_t avail_expr_hash (const void *); |
179 static hashval_t real_avail_expr_hash (const void *); | 179 static hashval_t real_avail_expr_hash (const void *); |
180 static int avail_expr_eq (const void *, const void *); | 180 static int avail_expr_eq (const void *, const void *); |
181 static void htab_statistics (FILE *, htab_t); | 181 static void htab_statistics (FILE *, htab_t); |
182 static void record_cond (struct cond_equivalence *); | 182 static void record_cond (cond_equivalence *); |
183 static void record_const_or_copy (tree, tree); | 183 static void record_const_or_copy (tree, tree); |
184 static void record_equality (tree, tree); | 184 static void record_equality (tree, tree); |
185 static void record_equivalences_from_phis (basic_block); | 185 static void record_equivalences_from_phis (basic_block); |
186 static void record_equivalences_from_incoming_edge (basic_block); | 186 static void record_equivalences_from_incoming_edge (basic_block); |
187 static void eliminate_redundant_computations (gimple_stmt_iterator *); | 187 static void eliminate_redundant_computations (gimple_stmt_iterator *); |
211 expr->type = NULL_TREE; | 211 expr->type = NULL_TREE; |
212 | 212 |
213 switch (get_gimple_rhs_class (subcode)) | 213 switch (get_gimple_rhs_class (subcode)) |
214 { | 214 { |
215 case GIMPLE_SINGLE_RHS: | 215 case GIMPLE_SINGLE_RHS: |
216 expr->kind = EXPR_SINGLE; | 216 expr->kind = EXPR_SINGLE; |
217 expr->ops.single.rhs = gimple_assign_rhs1 (stmt); | 217 expr->ops.single.rhs = gimple_assign_rhs1 (stmt); |
218 break; | 218 break; |
219 case GIMPLE_UNARY_RHS: | 219 case GIMPLE_UNARY_RHS: |
220 expr->kind = EXPR_UNARY; | 220 expr->kind = EXPR_UNARY; |
221 expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); | 221 expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); |
222 expr->ops.unary.op = subcode; | 222 expr->ops.unary.op = subcode; |
223 expr->ops.unary.opnd = gimple_assign_rhs1 (stmt); | 223 expr->ops.unary.opnd = gimple_assign_rhs1 (stmt); |
224 break; | 224 break; |
225 case GIMPLE_BINARY_RHS: | 225 case GIMPLE_BINARY_RHS: |
226 expr->kind = EXPR_BINARY; | 226 expr->kind = EXPR_BINARY; |
227 expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); | 227 expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); |
228 expr->ops.binary.op = subcode; | 228 expr->ops.binary.op = subcode; |
229 expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt); | 229 expr->ops.binary.opnd0 = gimple_assign_rhs1 (stmt); |
230 expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt); | 230 expr->ops.binary.opnd1 = gimple_assign_rhs2 (stmt); |
231 break; | 231 break; |
232 case GIMPLE_TERNARY_RHS: | |
233 expr->kind = EXPR_TERNARY; | |
234 expr->type = TREE_TYPE (gimple_assign_lhs (stmt)); | |
235 expr->ops.ternary.op = subcode; | |
236 expr->ops.ternary.opnd0 = gimple_assign_rhs1 (stmt); | |
237 expr->ops.ternary.opnd1 = gimple_assign_rhs2 (stmt); | |
238 expr->ops.ternary.opnd2 = gimple_assign_rhs3 (stmt); | |
239 break; | |
232 default: | 240 default: |
233 gcc_unreachable (); | 241 gcc_unreachable (); |
234 } | 242 } |
235 } | 243 } |
236 else if (code == GIMPLE_COND) | 244 else if (code == GIMPLE_COND) |
371 | 379 |
372 return operand_equal_p (expr0->ops.unary.opnd, | 380 return operand_equal_p (expr0->ops.unary.opnd, |
373 expr1->ops.unary.opnd, 0); | 381 expr1->ops.unary.opnd, 0); |
374 | 382 |
375 case EXPR_BINARY: | 383 case EXPR_BINARY: |
376 { | 384 if (expr0->ops.binary.op != expr1->ops.binary.op) |
377 if (expr0->ops.binary.op != expr1->ops.binary.op) | 385 return false; |
378 return false; | 386 |
379 | 387 if (operand_equal_p (expr0->ops.binary.opnd0, |
380 if (operand_equal_p (expr0->ops.binary.opnd0, | 388 expr1->ops.binary.opnd0, 0) |
381 expr1->ops.binary.opnd0, 0) | 389 && operand_equal_p (expr0->ops.binary.opnd1, |
382 && operand_equal_p (expr0->ops.binary.opnd1, | 390 expr1->ops.binary.opnd1, 0)) |
383 expr1->ops.binary.opnd1, 0)) | 391 return true; |
384 return true; | 392 |
385 | 393 /* For commutative ops, allow the other order. */ |
386 /* For commutative ops, allow the other order. */ | 394 return (commutative_tree_code (expr0->ops.binary.op) |
387 return (commutative_tree_code (expr0->ops.binary.op) | 395 && operand_equal_p (expr0->ops.binary.opnd0, |
388 && operand_equal_p (expr0->ops.binary.opnd0, | 396 expr1->ops.binary.opnd1, 0) |
389 expr1->ops.binary.opnd1, 0) | 397 && operand_equal_p (expr0->ops.binary.opnd1, |
390 && operand_equal_p (expr0->ops.binary.opnd1, | 398 expr1->ops.binary.opnd0, 0)); |
391 expr1->ops.binary.opnd0, 0)); | 399 |
392 } | 400 case EXPR_TERNARY: |
401 if (expr0->ops.ternary.op != expr1->ops.ternary.op | |
402 || !operand_equal_p (expr0->ops.ternary.opnd2, | |
403 expr1->ops.ternary.opnd2, 0)) | |
404 return false; | |
405 | |
406 if (operand_equal_p (expr0->ops.ternary.opnd0, | |
407 expr1->ops.ternary.opnd0, 0) | |
408 && operand_equal_p (expr0->ops.ternary.opnd1, | |
409 expr1->ops.ternary.opnd1, 0)) | |
410 return true; | |
411 | |
412 /* For commutative ops, allow the other order. */ | |
413 return (commutative_ternary_tree_code (expr0->ops.ternary.op) | |
414 && operand_equal_p (expr0->ops.ternary.opnd0, | |
415 expr1->ops.ternary.opnd1, 0) | |
416 && operand_equal_p (expr0->ops.ternary.opnd1, | |
417 expr1->ops.ternary.opnd0, 0)); | |
393 | 418 |
394 case EXPR_CALL: | 419 case EXPR_CALL: |
395 { | 420 { |
396 size_t i; | 421 size_t i; |
397 | 422 |
450 break; | 475 break; |
451 | 476 |
452 case EXPR_BINARY: | 477 case EXPR_BINARY: |
453 val = iterative_hash_object (expr->ops.binary.op, val); | 478 val = iterative_hash_object (expr->ops.binary.op, val); |
454 if (commutative_tree_code (expr->ops.binary.op)) | 479 if (commutative_tree_code (expr->ops.binary.op)) |
455 val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0, | 480 val = iterative_hash_exprs_commutative (expr->ops.binary.opnd0, |
456 expr->ops.binary.opnd1, val); | 481 expr->ops.binary.opnd1, val); |
457 else | 482 else |
458 { | 483 { |
459 val = iterative_hash_expr (expr->ops.binary.opnd0, val); | 484 val = iterative_hash_expr (expr->ops.binary.opnd0, val); |
460 val = iterative_hash_expr (expr->ops.binary.opnd1, val); | 485 val = iterative_hash_expr (expr->ops.binary.opnd1, val); |
461 } | 486 } |
462 break; | 487 break; |
463 | 488 |
489 case EXPR_TERNARY: | |
490 val = iterative_hash_object (expr->ops.ternary.op, val); | |
491 if (commutative_ternary_tree_code (expr->ops.ternary.op)) | |
492 val = iterative_hash_exprs_commutative (expr->ops.ternary.opnd0, | |
493 expr->ops.ternary.opnd1, val); | |
494 else | |
495 { | |
496 val = iterative_hash_expr (expr->ops.ternary.opnd0, val); | |
497 val = iterative_hash_expr (expr->ops.ternary.opnd1, val); | |
498 } | |
499 val = iterative_hash_expr (expr->ops.ternary.opnd2, val); | |
500 break; | |
501 | |
464 case EXPR_CALL: | 502 case EXPR_CALL: |
465 { | 503 { |
466 size_t i; | 504 size_t i; |
467 enum tree_code code = CALL_EXPR; | 505 enum tree_code code = CALL_EXPR; |
468 | 506 |
509 | 547 |
510 case EXPR_BINARY: | 548 case EXPR_BINARY: |
511 print_generic_expr (stream, element->expr.ops.binary.opnd0, 0); | 549 print_generic_expr (stream, element->expr.ops.binary.opnd0, 0); |
512 fprintf (stream, " %s ", tree_code_name[element->expr.ops.binary.op]); | 550 fprintf (stream, " %s ", tree_code_name[element->expr.ops.binary.op]); |
513 print_generic_expr (stream, element->expr.ops.binary.opnd1, 0); | 551 print_generic_expr (stream, element->expr.ops.binary.opnd1, 0); |
552 break; | |
553 | |
554 case EXPR_TERNARY: | |
555 fprintf (stream, " %s <", tree_code_name[element->expr.ops.ternary.op]); | |
556 print_generic_expr (stream, element->expr.ops.ternary.opnd0, 0); | |
557 fputs (", ", stream); | |
558 print_generic_expr (stream, element->expr.ops.ternary.opnd1, 0); | |
559 fputs (", ", stream); | |
560 print_generic_expr (stream, element->expr.ops.ternary.opnd2, 0); | |
561 fputs (">", stream); | |
514 break; | 562 break; |
515 | 563 |
516 case EXPR_CALL: | 564 case EXPR_CALL: |
517 { | 565 { |
518 size_t i; | 566 size_t i; |
586 struct edge_info *edge_info = (struct edge_info *) e->aux; | 634 struct edge_info *edge_info = (struct edge_info *) e->aux; |
587 | 635 |
588 if (edge_info) | 636 if (edge_info) |
589 { | 637 { |
590 if (edge_info->cond_equivalences) | 638 if (edge_info->cond_equivalences) |
591 free (edge_info->cond_equivalences); | 639 VEC_free (cond_equivalence, heap, edge_info->cond_equivalences); |
592 free (edge_info); | 640 free (edge_info); |
593 e->aux = NULL; | 641 e->aux = NULL; |
594 } | 642 } |
595 } | 643 } |
596 } | 644 } |
749 TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ | 797 TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ |
750 PROP_cfg | PROP_ssa, /* properties_required */ | 798 PROP_cfg | PROP_ssa, /* properties_required */ |
751 0, /* properties_provided */ | 799 0, /* properties_provided */ |
752 0, /* properties_destroyed */ | 800 0, /* properties_destroyed */ |
753 0, /* todo_flags_start */ | 801 0, /* todo_flags_start */ |
754 TODO_dump_func | 802 TODO_cleanup_cfg |
755 | TODO_update_ssa | 803 | TODO_update_ssa |
756 | TODO_cleanup_cfg | 804 | TODO_verify_ssa |
757 | TODO_verify_ssa /* todo_flags_finish */ | 805 | TODO_verify_flow |
806 | TODO_dump_func /* todo_flags_finish */ | |
758 } | 807 } |
759 }; | 808 }; |
760 | 809 |
761 | 810 |
762 /* Given a conditional statement CONDSTMT, convert the | 811 /* Given a conditional statement CONDSTMT, convert the |
1009 | 1058 |
1010 if (edge_info) | 1059 if (edge_info) |
1011 { | 1060 { |
1012 tree lhs = edge_info->lhs; | 1061 tree lhs = edge_info->lhs; |
1013 tree rhs = edge_info->rhs; | 1062 tree rhs = edge_info->rhs; |
1014 struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; | 1063 cond_equivalence *eq; |
1015 | 1064 |
1016 if (lhs) | 1065 if (lhs) |
1017 record_equality (lhs, rhs); | 1066 record_equality (lhs, rhs); |
1018 | 1067 |
1019 if (cond_equivalences) | 1068 for (i = 0; VEC_iterate (cond_equivalence, |
1020 for (i = 0; i < edge_info->max_cond_equivalences; i++) | 1069 edge_info->cond_equivalences, i, eq); ++i) |
1021 record_cond (&cond_equivalences[i]); | 1070 record_cond (eq); |
1022 } | 1071 } |
1023 } | 1072 } |
1024 } | 1073 } |
1025 | 1074 |
1026 /* Dump SSA statistics on FILE. */ | 1075 /* Dump SSA statistics on FILE. */ |
1040 } | 1089 } |
1041 | 1090 |
1042 | 1091 |
1043 /* Dump SSA statistics on stderr. */ | 1092 /* Dump SSA statistics on stderr. */ |
1044 | 1093 |
1045 void | 1094 DEBUG_FUNCTION void |
1046 debug_dominator_optimization_stats (void) | 1095 debug_dominator_optimization_stats (void) |
1047 { | 1096 { |
1048 dump_dominator_optimization_stats (stderr); | 1097 dump_dominator_optimization_stats (stderr); |
1049 } | 1098 } |
1050 | 1099 |
1064 /* Enter condition equivalence into the expression hash table. | 1113 /* Enter condition equivalence into the expression hash table. |
1065 This indicates that a conditional expression has a known | 1114 This indicates that a conditional expression has a known |
1066 boolean value. */ | 1115 boolean value. */ |
1067 | 1116 |
1068 static void | 1117 static void |
1069 record_cond (struct cond_equivalence *p) | 1118 record_cond (cond_equivalence *p) |
1070 { | 1119 { |
1071 struct expr_hash_elt *element = XCNEW (struct expr_hash_elt); | 1120 struct expr_hash_elt *element = XCNEW (struct expr_hash_elt); |
1072 void **slot; | 1121 void **slot; |
1073 | 1122 |
1074 initialize_hash_element_from_expr (&p->cond, p->value, element); | 1123 initialize_hash_element_from_expr (&p->cond, p->value, element); |
1090 else | 1139 else |
1091 free (element); | 1140 free (element); |
1092 } | 1141 } |
1093 | 1142 |
1094 /* Build a cond_equivalence record indicating that the comparison | 1143 /* Build a cond_equivalence record indicating that the comparison |
1095 CODE holds between operands OP0 and OP1. */ | 1144 CODE holds between operands OP0 and OP1 and push it to **P. */ |
1096 | 1145 |
1097 static void | 1146 static void |
1098 build_and_record_new_cond (enum tree_code code, | 1147 build_and_record_new_cond (enum tree_code code, |
1099 tree op0, tree op1, | 1148 tree op0, tree op1, |
1100 struct cond_equivalence *p) | 1149 VEC(cond_equivalence, heap) **p) |
1101 { | 1150 { |
1102 struct hashable_expr *cond = &p->cond; | 1151 cond_equivalence c; |
1152 struct hashable_expr *cond = &c.cond; | |
1103 | 1153 |
1104 gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison); | 1154 gcc_assert (TREE_CODE_CLASS (code) == tcc_comparison); |
1105 | 1155 |
1106 cond->type = boolean_type_node; | 1156 cond->type = boolean_type_node; |
1107 cond->kind = EXPR_BINARY; | 1157 cond->kind = EXPR_BINARY; |
1108 cond->ops.binary.op = code; | 1158 cond->ops.binary.op = code; |
1109 cond->ops.binary.opnd0 = op0; | 1159 cond->ops.binary.opnd0 = op0; |
1110 cond->ops.binary.opnd1 = op1; | 1160 cond->ops.binary.opnd1 = op1; |
1111 | 1161 |
1112 p->value = boolean_true_node; | 1162 c.value = boolean_true_node; |
1163 VEC_safe_push (cond_equivalence, heap, *p, &c); | |
1113 } | 1164 } |
1114 | 1165 |
1115 /* Record that COND is true and INVERTED is false into the edge information | 1166 /* Record that COND is true and INVERTED is false into the edge information |
1116 structure. Also record that any conditions dominated by COND are true | 1167 structure. Also record that any conditions dominated by COND are true |
1117 as well. | 1168 as well. |
1120 | 1171 |
1121 static void | 1172 static void |
1122 record_conditions (struct edge_info *edge_info, tree cond, tree inverted) | 1173 record_conditions (struct edge_info *edge_info, tree cond, tree inverted) |
1123 { | 1174 { |
1124 tree op0, op1; | 1175 tree op0, op1; |
1176 cond_equivalence c; | |
1125 | 1177 |
1126 if (!COMPARISON_CLASS_P (cond)) | 1178 if (!COMPARISON_CLASS_P (cond)) |
1127 return; | 1179 return; |
1128 | 1180 |
1129 op0 = TREE_OPERAND (cond, 0); | 1181 op0 = TREE_OPERAND (cond, 0); |
1133 { | 1185 { |
1134 case LT_EXPR: | 1186 case LT_EXPR: |
1135 case GT_EXPR: | 1187 case GT_EXPR: |
1136 if (FLOAT_TYPE_P (TREE_TYPE (op0))) | 1188 if (FLOAT_TYPE_P (TREE_TYPE (op0))) |
1137 { | 1189 { |
1138 edge_info->max_cond_equivalences = 6; | |
1139 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 6); | |
1140 build_and_record_new_cond (ORDERED_EXPR, op0, op1, | 1190 build_and_record_new_cond (ORDERED_EXPR, op0, op1, |
1141 &edge_info->cond_equivalences[4]); | 1191 &edge_info->cond_equivalences); |
1142 build_and_record_new_cond (LTGT_EXPR, op0, op1, | 1192 build_and_record_new_cond (LTGT_EXPR, op0, op1, |
1143 &edge_info->cond_equivalences[5]); | 1193 &edge_info->cond_equivalences); |
1144 } | |
1145 else | |
1146 { | |
1147 edge_info->max_cond_equivalences = 4; | |
1148 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4); | |
1149 } | 1194 } |
1150 | 1195 |
1151 build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR | 1196 build_and_record_new_cond ((TREE_CODE (cond) == LT_EXPR |
1152 ? LE_EXPR : GE_EXPR), | 1197 ? LE_EXPR : GE_EXPR), |
1153 op0, op1, &edge_info->cond_equivalences[2]); | 1198 op0, op1, &edge_info->cond_equivalences); |
1154 build_and_record_new_cond (NE_EXPR, op0, op1, | 1199 build_and_record_new_cond (NE_EXPR, op0, op1, |
1155 &edge_info->cond_equivalences[3]); | 1200 &edge_info->cond_equivalences); |
1156 break; | 1201 break; |
1157 | 1202 |
1158 case GE_EXPR: | 1203 case GE_EXPR: |
1159 case LE_EXPR: | 1204 case LE_EXPR: |
1160 if (FLOAT_TYPE_P (TREE_TYPE (op0))) | 1205 if (FLOAT_TYPE_P (TREE_TYPE (op0))) |
1161 { | 1206 { |
1162 edge_info->max_cond_equivalences = 3; | |
1163 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 3); | |
1164 build_and_record_new_cond (ORDERED_EXPR, op0, op1, | 1207 build_and_record_new_cond (ORDERED_EXPR, op0, op1, |
1165 &edge_info->cond_equivalences[2]); | 1208 &edge_info->cond_equivalences); |
1166 } | |
1167 else | |
1168 { | |
1169 edge_info->max_cond_equivalences = 2; | |
1170 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2); | |
1171 } | 1209 } |
1172 break; | 1210 break; |
1173 | 1211 |
1174 case EQ_EXPR: | 1212 case EQ_EXPR: |
1175 if (FLOAT_TYPE_P (TREE_TYPE (op0))) | 1213 if (FLOAT_TYPE_P (TREE_TYPE (op0))) |
1176 { | 1214 { |
1177 edge_info->max_cond_equivalences = 5; | |
1178 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 5); | |
1179 build_and_record_new_cond (ORDERED_EXPR, op0, op1, | 1215 build_and_record_new_cond (ORDERED_EXPR, op0, op1, |
1180 &edge_info->cond_equivalences[4]); | 1216 &edge_info->cond_equivalences); |
1181 } | |
1182 else | |
1183 { | |
1184 edge_info->max_cond_equivalences = 4; | |
1185 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4); | |
1186 } | 1217 } |
1187 build_and_record_new_cond (LE_EXPR, op0, op1, | 1218 build_and_record_new_cond (LE_EXPR, op0, op1, |
1188 &edge_info->cond_equivalences[2]); | 1219 &edge_info->cond_equivalences); |
1189 build_and_record_new_cond (GE_EXPR, op0, op1, | 1220 build_and_record_new_cond (GE_EXPR, op0, op1, |
1190 &edge_info->cond_equivalences[3]); | 1221 &edge_info->cond_equivalences); |
1191 break; | 1222 break; |
1192 | 1223 |
1193 case UNORDERED_EXPR: | 1224 case UNORDERED_EXPR: |
1194 edge_info->max_cond_equivalences = 8; | |
1195 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 8); | |
1196 build_and_record_new_cond (NE_EXPR, op0, op1, | 1225 build_and_record_new_cond (NE_EXPR, op0, op1, |
1197 &edge_info->cond_equivalences[2]); | 1226 &edge_info->cond_equivalences); |
1198 build_and_record_new_cond (UNLE_EXPR, op0, op1, | 1227 build_and_record_new_cond (UNLE_EXPR, op0, op1, |
1199 &edge_info->cond_equivalences[3]); | 1228 &edge_info->cond_equivalences); |
1200 build_and_record_new_cond (UNGE_EXPR, op0, op1, | 1229 build_and_record_new_cond (UNGE_EXPR, op0, op1, |
1201 &edge_info->cond_equivalences[4]); | 1230 &edge_info->cond_equivalences); |
1202 build_and_record_new_cond (UNEQ_EXPR, op0, op1, | 1231 build_and_record_new_cond (UNEQ_EXPR, op0, op1, |
1203 &edge_info->cond_equivalences[5]); | 1232 &edge_info->cond_equivalences); |
1204 build_and_record_new_cond (UNLT_EXPR, op0, op1, | 1233 build_and_record_new_cond (UNLT_EXPR, op0, op1, |
1205 &edge_info->cond_equivalences[6]); | 1234 &edge_info->cond_equivalences); |
1206 build_and_record_new_cond (UNGT_EXPR, op0, op1, | 1235 build_and_record_new_cond (UNGT_EXPR, op0, op1, |
1207 &edge_info->cond_equivalences[7]); | 1236 &edge_info->cond_equivalences); |
1208 break; | 1237 break; |
1209 | 1238 |
1210 case UNLT_EXPR: | 1239 case UNLT_EXPR: |
1211 case UNGT_EXPR: | 1240 case UNGT_EXPR: |
1212 edge_info->max_cond_equivalences = 4; | |
1213 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4); | |
1214 build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR | 1241 build_and_record_new_cond ((TREE_CODE (cond) == UNLT_EXPR |
1215 ? UNLE_EXPR : UNGE_EXPR), | 1242 ? UNLE_EXPR : UNGE_EXPR), |
1216 op0, op1, &edge_info->cond_equivalences[2]); | 1243 op0, op1, &edge_info->cond_equivalences); |
1217 build_and_record_new_cond (NE_EXPR, op0, op1, | 1244 build_and_record_new_cond (NE_EXPR, op0, op1, |
1218 &edge_info->cond_equivalences[3]); | 1245 &edge_info->cond_equivalences); |
1219 break; | 1246 break; |
1220 | 1247 |
1221 case UNEQ_EXPR: | 1248 case UNEQ_EXPR: |
1222 edge_info->max_cond_equivalences = 4; | |
1223 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4); | |
1224 build_and_record_new_cond (UNLE_EXPR, op0, op1, | 1249 build_and_record_new_cond (UNLE_EXPR, op0, op1, |
1225 &edge_info->cond_equivalences[2]); | 1250 &edge_info->cond_equivalences); |
1226 build_and_record_new_cond (UNGE_EXPR, op0, op1, | 1251 build_and_record_new_cond (UNGE_EXPR, op0, op1, |
1227 &edge_info->cond_equivalences[3]); | 1252 &edge_info->cond_equivalences); |
1228 break; | 1253 break; |
1229 | 1254 |
1230 case LTGT_EXPR: | 1255 case LTGT_EXPR: |
1231 edge_info->max_cond_equivalences = 4; | |
1232 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 4); | |
1233 build_and_record_new_cond (NE_EXPR, op0, op1, | 1256 build_and_record_new_cond (NE_EXPR, op0, op1, |
1234 &edge_info->cond_equivalences[2]); | 1257 &edge_info->cond_equivalences); |
1235 build_and_record_new_cond (ORDERED_EXPR, op0, op1, | 1258 build_and_record_new_cond (ORDERED_EXPR, op0, op1, |
1236 &edge_info->cond_equivalences[3]); | 1259 &edge_info->cond_equivalences); |
1237 break; | 1260 break; |
1238 | 1261 |
1239 default: | 1262 default: |
1240 edge_info->max_cond_equivalences = 2; | |
1241 edge_info->cond_equivalences = XNEWVEC (struct cond_equivalence, 2); | |
1242 break; | 1263 break; |
1243 } | 1264 } |
1244 | 1265 |
1245 /* Now store the original true and false conditions into the first | 1266 /* Now store the original true and false conditions into the first |
1246 two slots. */ | 1267 two slots. */ |
1247 initialize_expr_from_cond (cond, &edge_info->cond_equivalences[0].cond); | 1268 initialize_expr_from_cond (cond, &c.cond); |
1248 edge_info->cond_equivalences[0].value = boolean_true_node; | 1269 c.value = boolean_true_node; |
1270 VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c); | |
1249 | 1271 |
1250 /* It is possible for INVERTED to be the negation of a comparison, | 1272 /* It is possible for INVERTED to be the negation of a comparison, |
1251 and not a valid RHS or GIMPLE_COND condition. This happens because | 1273 and not a valid RHS or GIMPLE_COND condition. This happens because |
1252 invert_truthvalue may return such an expression when asked to invert | 1274 invert_truthvalue may return such an expression when asked to invert |
1253 a floating-point comparison. These comparisons are not assumed to | 1275 a floating-point comparison. These comparisons are not assumed to |
1254 obey the trichotomy law. */ | 1276 obey the trichotomy law. */ |
1255 initialize_expr_from_cond (inverted, &edge_info->cond_equivalences[1].cond); | 1277 initialize_expr_from_cond (inverted, &c.cond); |
1256 edge_info->cond_equivalences[1].value = boolean_false_node; | 1278 c.value = boolean_false_node; |
1279 VEC_safe_push (cond_equivalence, heap, edge_info->cond_equivalences, &c); | |
1257 } | 1280 } |
1258 | 1281 |
1259 /* A helper function for record_const_or_copy and record_equality. | 1282 /* A helper function for record_const_or_copy and record_equality. |
1260 Do the work of recording the value and undo info. */ | 1283 Do the work of recording the value and undo info. */ |
1261 | 1284 |
1585 } | 1608 } |
1586 | 1609 |
1587 edge_info = allocate_edge_info (false_edge); | 1610 edge_info = allocate_edge_info (false_edge); |
1588 record_conditions (edge_info, inverted, cond); | 1611 record_conditions (edge_info, inverted, cond); |
1589 | 1612 |
1590 if (code == NE_EXPR) | 1613 if (TREE_CODE (inverted) == EQ_EXPR) |
1591 { | 1614 { |
1592 edge_info->lhs = op1; | 1615 edge_info->lhs = op1; |
1593 edge_info->rhs = op0; | 1616 edge_info->rhs = op0; |
1594 } | 1617 } |
1595 } | 1618 } |
1612 } | 1635 } |
1613 | 1636 |
1614 edge_info = allocate_edge_info (false_edge); | 1637 edge_info = allocate_edge_info (false_edge); |
1615 record_conditions (edge_info, inverted, cond); | 1638 record_conditions (edge_info, inverted, cond); |
1616 | 1639 |
1617 if (TREE_CODE (cond) == NE_EXPR) | 1640 if (TREE_CODE (inverted) == EQ_EXPR) |
1618 { | 1641 { |
1619 edge_info->lhs = op0; | 1642 edge_info->lhs = op0; |
1620 edge_info->rhs = op1; | 1643 edge_info->rhs = op1; |
1621 } | 1644 } |
1622 } | 1645 } |
1699 | 1722 |
1700 /* If we have info associated with this edge, record it into | 1723 /* If we have info associated with this edge, record it into |
1701 our equivalence tables. */ | 1724 our equivalence tables. */ |
1702 if (edge_info) | 1725 if (edge_info) |
1703 { | 1726 { |
1704 struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; | 1727 cond_equivalence *eq; |
1705 tree lhs = edge_info->lhs; | 1728 tree lhs = edge_info->lhs; |
1706 tree rhs = edge_info->rhs; | 1729 tree rhs = edge_info->rhs; |
1707 | 1730 |
1708 /* If we have a simple NAME = VALUE equivalence, record it. */ | 1731 /* If we have a simple NAME = VALUE equivalence, record it. */ |
1709 if (lhs && TREE_CODE (lhs) == SSA_NAME) | 1732 if (lhs && TREE_CODE (lhs) == SSA_NAME) |
1710 record_const_or_copy (lhs, rhs); | 1733 record_const_or_copy (lhs, rhs); |
1711 | 1734 |
1712 /* If we have 0 = COND or 1 = COND equivalences, record them | 1735 /* If we have 0 = COND or 1 = COND equivalences, record them |
1713 into our expression hash tables. */ | 1736 into our expression hash tables. */ |
1714 if (cond_equivalences) | 1737 for (i = 0; VEC_iterate (cond_equivalence, |
1715 for (i = 0; i < edge_info->max_cond_equivalences; i++) | 1738 edge_info->cond_equivalences, i, eq); ++i) |
1716 record_cond (&cond_equivalences[i]); | 1739 record_cond (eq); |
1717 } | 1740 } |
1718 | 1741 |
1719 dom_thread_across_edge (walk_data, true_edge); | 1742 dom_thread_across_edge (walk_data, true_edge); |
1720 | 1743 |
1721 /* And restore the various tables to their state before | 1744 /* And restore the various tables to their state before |
1734 | 1757 |
1735 /* If we have info associated with this edge, record it into | 1758 /* If we have info associated with this edge, record it into |
1736 our equivalence tables. */ | 1759 our equivalence tables. */ |
1737 if (edge_info) | 1760 if (edge_info) |
1738 { | 1761 { |
1739 struct cond_equivalence *cond_equivalences = edge_info->cond_equivalences; | 1762 cond_equivalence *eq; |
1740 tree lhs = edge_info->lhs; | 1763 tree lhs = edge_info->lhs; |
1741 tree rhs = edge_info->rhs; | 1764 tree rhs = edge_info->rhs; |
1742 | 1765 |
1743 /* If we have a simple NAME = VALUE equivalence, record it. */ | 1766 /* If we have a simple NAME = VALUE equivalence, record it. */ |
1744 if (lhs && TREE_CODE (lhs) == SSA_NAME) | 1767 if (lhs && TREE_CODE (lhs) == SSA_NAME) |
1745 record_const_or_copy (lhs, rhs); | 1768 record_const_or_copy (lhs, rhs); |
1746 | 1769 |
1747 /* If we have 0 = COND or 1 = COND equivalences, record them | 1770 /* If we have 0 = COND or 1 = COND equivalences, record them |
1748 into our expression hash tables. */ | 1771 into our expression hash tables. */ |
1749 if (cond_equivalences) | 1772 for (i = 0; VEC_iterate (cond_equivalence, |
1750 for (i = 0; i < edge_info->max_cond_equivalences; i++) | 1773 edge_info->cond_equivalences, i, eq); ++i) |
1751 record_cond (&cond_equivalences[i]); | 1774 record_cond (eq); |
1752 } | 1775 } |
1753 | 1776 |
1754 /* Now thread the edge. */ | 1777 /* Now thread the edge. */ |
1755 dom_thread_across_edge (walk_data, false_edge); | 1778 dom_thread_across_edge (walk_data, false_edge); |
1756 | 1779 |
1828 if ((TREE_CODE (cached_lhs) != SSA_NAME | 1851 if ((TREE_CODE (cached_lhs) != SSA_NAME |
1829 && (assigns_var_p | 1852 && (assigns_var_p |
1830 || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))) | 1853 || useless_type_conversion_p (expr_type, TREE_TYPE (cached_lhs)))) |
1831 || may_propagate_copy_into_stmt (stmt, cached_lhs)) | 1854 || may_propagate_copy_into_stmt (stmt, cached_lhs)) |
1832 { | 1855 { |
1833 #if defined ENABLE_CHECKING | 1856 gcc_checking_assert (TREE_CODE (cached_lhs) == SSA_NAME |
1834 gcc_assert (TREE_CODE (cached_lhs) == SSA_NAME | 1857 || is_gimple_min_invariant (cached_lhs)); |
1835 || is_gimple_min_invariant (cached_lhs)); | |
1836 #endif | |
1837 | 1858 |
1838 if (dump_file && (dump_flags & TDF_DETAILS)) | 1859 if (dump_file && (dump_flags & TDF_DETAILS)) |
1839 { | 1860 { |
1840 fprintf (dump_file, " Replaced redundant expr '"); | 1861 fprintf (dump_file, " Replaced redundant expr '"); |
1841 print_gimple_expr (dump_file, stmt, 0, dump_flags); | 1862 print_gimple_expr (dump_file, stmt, 0, dump_flags); |
2154 } | 2175 } |
2155 | 2176 |
2156 update_stmt_if_modified (stmt); | 2177 update_stmt_if_modified (stmt); |
2157 eliminate_redundant_computations (&si); | 2178 eliminate_redundant_computations (&si); |
2158 stmt = gsi_stmt (si); | 2179 stmt = gsi_stmt (si); |
2180 | |
2181 /* Perform simple redundant store elimination. */ | |
2182 if (gimple_assign_single_p (stmt) | |
2183 && TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) | |
2184 { | |
2185 tree lhs = gimple_assign_lhs (stmt); | |
2186 tree rhs = gimple_assign_rhs1 (stmt); | |
2187 tree cached_lhs; | |
2188 gimple new_stmt; | |
2189 if (TREE_CODE (rhs) == SSA_NAME) | |
2190 { | |
2191 tree tem = SSA_NAME_VALUE (rhs); | |
2192 if (tem) | |
2193 rhs = tem; | |
2194 } | |
2195 /* Build a new statement with the RHS and LHS exchanged. */ | |
2196 if (TREE_CODE (rhs) == SSA_NAME) | |
2197 { | |
2198 gimple defstmt = SSA_NAME_DEF_STMT (rhs); | |
2199 new_stmt = gimple_build_assign (rhs, lhs); | |
2200 SSA_NAME_DEF_STMT (rhs) = defstmt; | |
2201 } | |
2202 else | |
2203 new_stmt = gimple_build_assign (rhs, lhs); | |
2204 gimple_set_vuse (new_stmt, gimple_vuse (stmt)); | |
2205 cached_lhs = lookup_avail_expr (new_stmt, false); | |
2206 if (cached_lhs | |
2207 && rhs == cached_lhs) | |
2208 { | |
2209 basic_block bb = gimple_bb (stmt); | |
2210 int lp_nr = lookup_stmt_eh_lp (stmt); | |
2211 unlink_stmt_vdef (stmt); | |
2212 gsi_remove (&si, true); | |
2213 if (lp_nr != 0) | |
2214 { | |
2215 bitmap_set_bit (need_eh_cleanup, bb->index); | |
2216 if (dump_file && (dump_flags & TDF_DETAILS)) | |
2217 fprintf (dump_file, " Flagged to clear EH edges.\n"); | |
2218 } | |
2219 return; | |
2220 } | |
2221 } | |
2159 } | 2222 } |
2160 | 2223 |
2161 /* Record any additional equivalences created by this statement. */ | 2224 /* Record any additional equivalences created by this statement. */ |
2162 if (is_gimple_assign (stmt)) | 2225 if (is_gimple_assign (stmt)) |
2163 record_equivalences_from_stmt (stmt, may_optimize_p); | 2226 record_equivalences_from_stmt (stmt, may_optimize_p); |
2504 continue; | 2567 continue; |
2505 | 2568 |
2506 /* It's not always safe to propagate into an ASM_EXPR. */ | 2569 /* It's not always safe to propagate into an ASM_EXPR. */ |
2507 if (gimple_code (use_stmt) == GIMPLE_ASM | 2570 if (gimple_code (use_stmt) == GIMPLE_ASM |
2508 && ! may_propagate_copy_into_asm (lhs)) | 2571 && ! may_propagate_copy_into_asm (lhs)) |
2572 { | |
2573 all = false; | |
2574 continue; | |
2575 } | |
2576 | |
2577 /* It's not ok to propagate into the definition stmt of RHS. | |
2578 <bb 9>: | |
2579 # prephitmp.12_36 = PHI <g_67.1_6(9)> | |
2580 g_67.1_6 = prephitmp.12_36; | |
2581 goto <bb 9>; | |
2582 While this is strictly all dead code we do not want to | |
2583 deal with this here. */ | |
2584 if (TREE_CODE (rhs) == SSA_NAME | |
2585 && SSA_NAME_DEF_STMT (rhs) == use_stmt) | |
2509 { | 2586 { |
2510 all = false; | 2587 all = false; |
2511 continue; | 2588 continue; |
2512 } | 2589 } |
2513 | 2590 |