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 vuse_optype 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
00083
00084
00085 hashval_t
00086 vn_compute (tree expr, hashval_t val, vuse_optype vuses)
00087 {
00088 size_t i;
00089
00090
00091
00092 gcc_assert (expr);
00093 gcc_assert (!expr->common.ann
00094 || expr->common.ann->common.type != STMT_ANN);
00095
00096 val = iterative_hash_expr (expr, val);
00097
00098
00099
00100 for (i = 0; i < NUM_VUSES (vuses); i++)
00101 val = iterative_hash_expr (VUSE_OP (vuses, i), val);
00102
00103 return val;
00104 }
00105
00106
00107
00108
00109
00110 bool
00111 expressions_equal_p (tree e1, tree e2)
00112 {
00113 tree te1, te2;
00114
00115 if (e1 == e2)
00116 return true;
00117
00118 te1 = TREE_TYPE (e1);
00119 te2 = TREE_TYPE (e2);
00120
00121 if (TREE_CODE (e1) == TREE_CODE (e2)
00122 && (te1 == te2 || lang_hooks.types_compatible_p (te1, te2))
00123 && operand_equal_p (e1, e2, OEP_PURE_SAME))
00124 return true;
00125
00126 return false;
00127 }
00128
00129
00130
00131
00132
00133
00134 static hashval_t
00135 val_expr_pair_hash (const void *p)
00136 {
00137 const val_expr_pair_t ve = (val_expr_pair_t) p;
00138 return ve->hashcode;
00139 }
00140
00141
00142
00143
00144
00145
00146 static int
00147 val_expr_pair_expr_eq (const void *p1, const void *p2)
00148 {
00149 const val_expr_pair_t ve1 = (val_expr_pair_t) p1;
00150 const val_expr_pair_t ve2 = (val_expr_pair_t) p2;
00151 size_t i;
00152
00153 if (! expressions_equal_p (ve1->e, ve2->e))
00154 return false;
00155
00156 if (NUM_VUSES (ve1->vuses) != NUM_VUSES (ve2->vuses))
00157 return false;
00158
00159 for (i = 0; i < NUM_VUSES (ve1->vuses); i++)
00160 if (! expressions_equal_p (VUSE_OP (ve1->vuses, i),
00161 VUSE_OP (ve2->vuses, i)))
00162 return false;
00163
00164 return true;
00165 }
00166
00167
00168
00169
00170 static void
00171 set_value_handle (tree e, tree v)
00172 {
00173 if (TREE_CODE (e) == SSA_NAME)
00174 SSA_NAME_VALUE (e) = v;
00175 else if (EXPR_P (e) || DECL_P (e))
00176 get_tree_ann (e)->common.value_handle = v;
00177 else
00178
00179 gcc_assert (is_gimple_min_invariant (e));
00180 }
00181
00182
00183
00184
00185
00186
00187
00188 void
00189 vn_add (tree expr, tree val, vuse_optype vuses)
00190 {
00191 void **slot;
00192 val_expr_pair_t new_pair;
00193
00194 new_pair = xmalloc (sizeof (struct val_expr_pair_d));
00195 new_pair->e = expr;
00196 new_pair->v = val;
00197 new_pair->vuses = vuses;
00198 new_pair->hashcode = vn_compute (expr, 0, vuses);
00199 slot = htab_find_slot_with_hash (value_table, new_pair, new_pair->hashcode,
00200 INSERT);
00201 if (*slot)
00202 free (*slot);
00203 *slot = (void *) new_pair;
00204
00205 set_value_handle (expr, val);
00206 add_to_value (val, expr);
00207 }
00208
00209
00210
00211
00212
00213
00214
00215 tree
00216 vn_lookup (tree expr, vuse_optype vuses)
00217 {
00218 void **slot;
00219 struct val_expr_pair_d vep = {NULL, NULL, NULL, 0};
00220
00221
00222 if (is_gimple_min_invariant (expr))
00223 return expr;
00224
00225 vep.e = expr;
00226 vep.vuses = vuses;
00227 vep.hashcode = vn_compute (expr, 0, vuses);
00228 slot = htab_find_slot_with_hash (value_table, &vep, vep.hashcode, NO_INSERT);
00229 if (!slot)
00230 return NULL_TREE;
00231 else
00232 return ((val_expr_pair_t) *slot)->v;
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242 tree
00243 vn_lookup_or_add (tree expr, vuse_optype vuses)
00244 {
00245 tree v = vn_lookup (expr, vuses);
00246 if (v == NULL_TREE)
00247 {
00248 v = make_value_handle (TREE_TYPE (expr));
00249
00250 if (dump_file && (dump_flags & TDF_DETAILS))
00251 {
00252 fprintf (dump_file, "Created value ");
00253 print_generic_expr (dump_file, v, dump_flags);
00254 fprintf (dump_file, " for ");
00255 print_generic_expr (dump_file, expr, dump_flags);
00256 fprintf (dump_file, "\n");
00257 }
00258
00259 vn_add (expr, v, vuses);
00260 }
00261
00262 set_value_handle (expr, v);
00263
00264 return v;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273 tree
00274 get_value_handle (tree expr)
00275 {
00276
00277 if (is_gimple_min_invariant (expr))
00278 return expr;
00279
00280 if (TREE_CODE (expr) == SSA_NAME)
00281 return SSA_NAME_VALUE (expr);
00282 else if (EXPR_P (expr) || DECL_P (expr))
00283 {
00284 tree_ann_t ann = tree_ann (expr);
00285 return ((ann) ? ann->common.value_handle : NULL_TREE);
00286 }
00287 else
00288 gcc_unreachable ();
00289 }
00290
00291
00292
00293
00294 void
00295 vn_init (void)
00296 {
00297 value_table = htab_create (511, val_expr_pair_hash,
00298 val_expr_pair_expr_eq, free);
00299 }
00300
00301
00302
00303
00304 void
00305 vn_delete (void)
00306 {
00307 htab_delete (value_table);
00308 value_table = NULL;
00309 }