00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "coretypes.h"
00026 #include "tm.h"
00027 #include "ggc.h"
00028 #include "tree.h"
00029 #include "tree-flow.h"
00030 #include "hashtab.h"
00031 #include "langhooks.h"
00032 #include "tree-pass.h"
00033 #include "tree-dump.h"
00034 #include "diagnostic.h"
00035
00036
00037 static htab_t value_table;
00038
00039
00040
00041
00042
00043 typedef struct val_expr_pair_d
00044 {
00045
00046 tree v;
00047
00048
00049 tree e;
00050
00051
00052 VEC (tree, gc) *vuses;
00053
00054
00055 hashval_t hashcode;
00056 } *val_expr_pair_t;
00057
00058 static void set_value_handle (tree e, tree v);
00059
00060
00061
00062
00063 static tree
00064 make_value_handle (tree type)
00065 {
00066 static unsigned int id = 0;
00067 tree vh;
00068
00069 vh = build0 (VALUE_HANDLE, type);
00070 VALUE_HANDLE_ID (vh) = id++;
00071 return vh;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 hashval_t
00083 vn_compute (tree expr, hashval_t val)
00084 {
00085
00086
00087 gcc_assert (expr);
00088 gcc_assert (!expr->common.ann
00089 || expr->common.ann->common.type != STMT_ANN);
00090
00091 val = iterative_hash_expr (expr, val);
00092 return val;
00093 }
00094
00095
00096
00097
00098 bool
00099 expressions_equal_p (tree e1, tree e2)
00100 {
00101 tree te1, te2;
00102
00103 if (e1 == e2)
00104 return true;
00105
00106 te1 = TREE_TYPE (e1);
00107 te2 = TREE_TYPE (e2);
00108
00109 if (TREE_CODE (e1) == TREE_LIST && TREE_CODE (e2) == TREE_LIST)
00110 {
00111 tree lop1 = e1;
00112 tree lop2 = e2;
00113 for (lop1 = e1, lop2 = e2;
00114 lop1 || lop2;
00115 lop1 = TREE_CHAIN (lop1), lop2 = TREE_CHAIN (lop2))
00116 {
00117 if (!lop1 || !lop2)
00118 return false;
00119 if (!expressions_equal_p (TREE_VALUE (lop1), TREE_VALUE (lop2)))
00120 return false;
00121 }
00122 return true;
00123
00124 }
00125 else if (TREE_CODE (e1) == TREE_CODE (e2)
00126 && (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
00127 && operand_equal_p (e1, e2, OEP_PURE_SAME))
00128 return true;
00129
00130 return false;
00131 }
00132
00133
00134
00135
00136
00137
00138 static hashval_t
00139 val_expr_pair_hash (const void *p)
00140 {
00141 const val_expr_pair_t ve = (val_expr_pair_t) p;
00142 return ve->hashcode;
00143 }
00144
00145
00146
00147
00148
00149
00150 static int
00151 val_expr_pair_expr_eq (const void *p1, const void *p2)
00152 {
00153 int i;
00154 tree vuse1;
00155 const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
00156 const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
00157
00158 if (! expressions_equal_p (ve1->e, ve2->e))
00159 return false;
00160
00161 if (ve1->vuses == ve2->vuses)
00162 return true;
00163
00164 if (VEC_length (tree, ve1->vuses) != VEC_length (tree, ve2->vuses))
00165 return false;
00166
00167 for (i = 0; VEC_iterate (tree, ve1->vuses, i, vuse1); i++)
00168 {
00169 if (VEC_index (tree, ve2->vuses, i) != vuse1)
00170 return false;
00171 }
00172 return true;
00173 }
00174
00175
00176
00177
00178 static void
00179 set_value_handle (tree e, tree v)
00180 {
00181 if (TREE_CODE (e) == SSA_NAME)
00182 SSA_NAME_VALUE (e) = v;
00183 else if (EXPR_P (e) || DECL_P (e) || TREE_CODE (e) == TREE_LIST
00184 || TREE_CODE (e) == CONSTRUCTOR)
00185 get_tree_common_ann (e)->value_handle = v;
00186 else
00187
00188 gcc_assert (is_gimple_min_invariant (e));
00189 }
00190
00191
00192
00193
00194 static VEC (tree, gc) *
00195 copy_vuses_from_stmt (tree stmt)
00196 {
00197 ssa_op_iter iter;
00198 tree vuse;
00199 VEC (tree, gc) *vuses = NULL;
00200
00201 if (!stmt)
00202 return NULL;
00203
00204 FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
00205 VEC_safe_push (tree, gc, vuses, vuse);
00206
00207 return vuses;
00208 }
00209
00210
00211 static VEC (tree, gc) *shared_lookup_vuses;
00212
00213
00214
00215
00216
00217 static VEC (tree, gc) *
00218 shared_vuses_from_stmt (tree stmt)
00219 {
00220 ssa_op_iter iter;
00221 tree vuse;
00222
00223 if (!stmt)
00224 return NULL;
00225
00226 VEC_truncate (tree, shared_lookup_vuses, 0);
00227
00228 FOR_EACH_SSA_TREE_OPERAND (vuse, stmt, iter, SSA_OP_VUSE)
00229 VEC_safe_push (tree, gc, shared_lookup_vuses, vuse);
00230
00231 if (VEC_length (tree, shared_lookup_vuses) > 1)
00232 sort_vuses (shared_lookup_vuses);
00233
00234 return shared_lookup_vuses;
00235 }
00236
00237
00238
00239
00240 void
00241 vn_add (tree expr, tree val)
00242 {
00243 vn_add_with_vuses (expr, val, NULL);
00244 }
00245
00246
00247
00248
00249
00250
00251 void
00252 vn_add_with_vuses (tree expr, tree val, VEC (tree, gc) *vuses)
00253 {
00254 void **slot;
00255 val_expr_pair_t new_pair;
00256
00257 new_pair = XNEW (struct val_expr_pair_d);
00258 new_pair->e = expr;
00259 new_pair->v = val;
00260 new_pair->vuses = vuses;
00261 new_pair->hashcode = vn_compute (expr, 0);
00262 slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
00263 INSERT);
00264 if (*slot)
00265 free (*slot);
00266 *slot = (void *) new_pair;
00267
00268 set_value_handle (expr, val);
00269 if (TREE_CODE (val) == VALUE_HANDLE)
00270 add_to_value (val, expr);
00271 }
00272
00273
00274
00275
00276
00277
00278
00279 tree
00280 vn_lookup (tree expr, tree stmt)
00281 {
00282 return vn_lookup_with_vuses (expr, shared_vuses_from_stmt (stmt));
00283 }
00284
00285
00286
00287
00288
00289
00290 tree
00291 vn_lookup_with_vuses (tree expr, VEC (tree, gc) *vuses)
00292 {
00293 void **slot;
00294 struct val_expr_pair_d vep = {NULL, NULL, NULL, 0};
00295
00296
00297 if (is_gimple_min_invariant (expr))
00298 return expr;
00299
00300 vep.e = expr;
00301 vep.vuses = vuses;
00302 vep.hashcode = vn_compute (expr, 0);
00303 slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
00304 if (!slot)
00305 return NULL_TREE;
00306 else
00307 return ((val_expr_pair_t) *slot)->v;
00308 }
00309
00310
00311
00312
00313
00314 static int
00315 vuses_compare (const void *pa, const void *pb)
00316 {
00317 const tree vusea = *((const tree *)pa);
00318 const tree vuseb = *((const tree *)pb);
00319 int sn = SSA_NAME_VERSION (vusea) - SSA_NAME_VERSION (vuseb);
00320
00321 return sn;
00322 }
00323
00324
00325
00326
00327
00328
00329 static void
00330 print_creation_to_file (tree v, tree expr, VEC (tree, gc) *vuses)
00331 {
00332 fprintf (dump_file, "Created value ");
00333 print_generic_expr (dump_file, v, dump_flags);
00334 fprintf (dump_file, " for ");
00335 print_generic_expr (dump_file, expr, dump_flags);
00336
00337 if (vuses && VEC_length (tree, vuses) != 0)
00338 {
00339 size_t i;
00340 tree vuse;
00341
00342 fprintf (dump_file, " vuses: (");
00343 for (i = 0; VEC_iterate (tree, vuses, i, vuse); i++)
00344 {
00345 print_generic_expr (dump_file, vuse, dump_flags);
00346 if (VEC_length (tree, vuses) - 1 != i)
00347 fprintf (dump_file, ",");
00348 }
00349 fprintf (dump_file, ")");
00350 }
00351 fprintf (dump_file, "\n");
00352 }
00353
00354
00355
00356
00357
00358
00359 tree
00360 vn_lookup_or_add (tree expr, tree stmt)
00361 {
00362 tree v = vn_lookup (expr, stmt);
00363 if (v == NULL_TREE)
00364 {
00365 VEC(tree,gc) *vuses;
00366
00367 v = make_value_handle (TREE_TYPE (expr));
00368 vuses = copy_vuses_from_stmt (stmt);
00369 sort_vuses (vuses);
00370
00371 if (dump_file && (dump_flags & TDF_DETAILS))
00372 print_creation_to_file (v, expr, vuses);
00373
00374 VALUE_HANDLE_VUSES (v) = vuses;
00375 vn_add_with_vuses (expr, v, vuses);
00376 }
00377
00378 set_value_handle (expr, v);
00379
00380 return v;
00381 }
00382
00383
00384
00385
00386 void
00387 sort_vuses (VEC (tree,gc) *vuses)
00388 {
00389 if (VEC_length (tree, vuses) > 1)
00390 qsort (VEC_address (tree, vuses),
00391 VEC_length (tree, vuses),
00392 sizeof (tree),
00393 vuses_compare);
00394 }
00395
00396
00397
00398
00399
00400
00401 tree
00402 vn_lookup_or_add_with_vuses (tree expr, VEC (tree, gc) *vuses)
00403 {
00404 tree v = vn_lookup_with_vuses (expr, vuses);
00405 if (v == NULL_TREE)
00406 {
00407 v = make_value_handle (TREE_TYPE (expr));
00408 sort_vuses (vuses);
00409
00410 if (dump_file && (dump_flags & TDF_DETAILS))
00411 print_creation_to_file (v, expr, vuses);
00412
00413 VALUE_HANDLE_VUSES (v) = vuses;
00414 vn_add_with_vuses (expr, v, vuses);
00415 }
00416
00417 set_value_handle (expr, v);
00418
00419 return v;
00420 }
00421
00422
00423
00424
00425
00426
00427
00428
00429 tree
00430 get_value_handle (tree expr)
00431 {
00432
00433 if (is_gimple_min_invariant (expr))
00434 return expr;
00435
00436 if (TREE_CODE (expr) == SSA_NAME)
00437 return SSA_NAME_VALUE (expr);
00438 else if (EXPR_P (expr) || DECL_P (expr) || TREE_CODE (expr) == TREE_LIST
00439 || TREE_CODE (expr) == CONSTRUCTOR)
00440 {
00441 tree_ann_common_t ann = tree_common_ann (expr);
00442 return ((ann) ? ann->value_handle : NULL_TREE);
00443 }
00444 else
00445 gcc_unreachable ();
00446 }
00447
00448
00449
00450
00451 void
00452 vn_init (void)
00453 {
00454 value_table = htab_create (511, val_expr_pair_hash,
00455 val_expr_pair_expr_eq, free);
00456 shared_lookup_vuses = NULL;
00457 }
00458
00459
00460
00461
00462 void
00463 vn_delete (void)
00464 {
00465 htab_delete (value_table);
00466 VEC_free (tree, gc, shared_lookup_vuses);
00467 value_table = NULL;
00468 }