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