00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "tree.h"
00027 #include "flags.h"
00028 #include "basic-block.h"
00029 #include "function.h"
00030 #include "diagnostic.h"
00031 #include "bitmap.h"
00032 #include "tree-flow.h"
00033 #include "tree-gimple.h"
00034 #include "tree-inline.h"
00035 #include "timevar.h"
00036 #include "hashtab.h"
00037 #include "tree-dump.h"
00038 #include "tree-ssa-live.h"
00039 #include "tree-pass.h"
00040 #include "langhooks.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 static void
00113 copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
00114 {
00115 int p1, p2, p3;
00116 tree root1, root2;
00117 tree rep1, rep2;
00118 var_ann_t ann1, ann2, ann3;
00119 bool ign1, ign2, abnorm;
00120
00121 gcc_assert (TREE_CODE (var1) == SSA_NAME);
00122 gcc_assert (TREE_CODE (var2) == SSA_NAME);
00123
00124 register_ssa_partition (map, var1, false);
00125 register_ssa_partition (map, var2, true);
00126
00127 p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
00128 p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));
00129
00130 if (debug)
00131 {
00132 fprintf (debug, "Try : ");
00133 print_generic_expr (debug, var1, TDF_SLIM);
00134 fprintf (debug, "(P%d) & ", p1);
00135 print_generic_expr (debug, var2, TDF_SLIM);
00136 fprintf (debug, "(P%d)", p2);
00137 }
00138
00139 gcc_assert (p1 != NO_PARTITION);
00140 gcc_assert (p2 != NO_PARTITION);
00141
00142 rep1 = partition_to_var (map, p1);
00143 rep2 = partition_to_var (map, p2);
00144 root1 = SSA_NAME_VAR (rep1);
00145 root2 = SSA_NAME_VAR (rep2);
00146
00147 ann1 = var_ann (root1);
00148 ann2 = var_ann (root2);
00149
00150 if (p1 == p2)
00151 {
00152 if (debug)
00153 fprintf (debug, " : Already coalesced.\n");
00154 return;
00155 }
00156
00157
00158 abnorm = (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep1)
00159 || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rep2));
00160 if (abnorm)
00161 {
00162 if (debug)
00163 fprintf (debug, " : Abnormal PHI barrier. No coalesce.\n");
00164 return;
00165 }
00166
00167
00168 if (root1 == root2)
00169 {
00170 p1 = partition_union (map->var_partition, p1, p2);
00171 if (debug)
00172 fprintf (debug, " : Same root, coalesced --> P%d.\n", p1);
00173 return;
00174 }
00175
00176
00177 if (TREE_CODE (root1) == PARM_DECL && TREE_CODE (root2) == PARM_DECL)
00178 {
00179 if (debug)
00180 fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n");
00181 return;
00182 }
00183
00184 if ((TREE_CODE (root1) == RESULT_DECL) != (TREE_CODE (root2) == RESULT_DECL))
00185 {
00186 if (debug)
00187 fprintf (debug, " : One root a RESULT_DECL. No coalesce.\n");
00188 return;
00189 }
00190
00191 ign1 = TREE_CODE (root1) == VAR_DECL && DECL_IGNORED_P (root1);
00192 ign2 = TREE_CODE (root2) == VAR_DECL && DECL_IGNORED_P (root2);
00193
00194
00195
00196 if (!ign1 && !ign2)
00197 {
00198 if (DECL_FROM_INLINE (root2))
00199 ign2 = true;
00200 else if (DECL_FROM_INLINE (root1))
00201 ign1 = true;
00202 else
00203 {
00204 if (debug)
00205 fprintf (debug, " : 2 different USER vars. No coalesce.\n");
00206 return;
00207 }
00208 }
00209
00210
00211 if (ann1->symbol_mem_tag
00212 && ann2->symbol_mem_tag
00213 && ann1->symbol_mem_tag != ann2->symbol_mem_tag)
00214 {
00215 if (debug)
00216 fprintf (debug, " : 2 memory tags. No coalesce.\n");
00217 return;
00218 }
00219
00220
00221
00222 if (default_def (root1))
00223 {
00224 if (default_def (root2))
00225 {
00226 if (debug)
00227 fprintf (debug, " : 2 default defs. No coalesce.\n");
00228 return;
00229 }
00230 else
00231 {
00232 ign2 = true;
00233 ign1 = false;
00234 }
00235 }
00236 else if (default_def (root2))
00237 {
00238 ign1 = true;
00239 ign2 = false;
00240 }
00241
00242
00243 if (!lang_hooks.types_compatible_p (TREE_TYPE (root1), TREE_TYPE (root2)))
00244 {
00245 if (debug)
00246 fprintf (debug, " : Incompatible types. No coalesce.\n");
00247 return;
00248 }
00249
00250
00251 if (POINTER_TYPE_P (TREE_TYPE (root1))
00252 && POINTER_TYPE_P (TREE_TYPE (root2))
00253 && get_alias_set (TREE_TYPE (TREE_TYPE (root1)))
00254 != get_alias_set (TREE_TYPE (TREE_TYPE (root2))))
00255 {
00256 if (debug)
00257 fprintf (debug, " : 2 different aliasing sets. No coalesce.\n");
00258 return;
00259 }
00260
00261
00262
00263 p3 = partition_union (map->var_partition, p1, p2);
00264
00265
00266
00267 if (!ign2)
00268 replace_ssa_name_symbol (partition_to_var (map, p3), root2);
00269 else if (!ign1)
00270 replace_ssa_name_symbol (partition_to_var (map, p3), root1);
00271
00272
00273 ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
00274 if (ann1->symbol_mem_tag)
00275 ann3->symbol_mem_tag = ann1->symbol_mem_tag;
00276 else
00277 ann3->symbol_mem_tag = ann2->symbol_mem_tag;
00278
00279 if (debug)
00280 {
00281 fprintf (debug, " --> P%d ", p3);
00282 print_generic_expr (debug, SSA_NAME_VAR (partition_to_var (map, p3)),
00283 TDF_SLIM);
00284 fprintf (debug, "\n");
00285 }
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295 static unsigned int
00296 rename_ssa_copies (void)
00297 {
00298 var_map map;
00299 basic_block bb;
00300 block_stmt_iterator bsi;
00301 tree phi, stmt, var, part_var;
00302 unsigned x;
00303 FILE *debug;
00304
00305 if (dump_file && (dump_flags & TDF_DETAILS))
00306 debug = dump_file;
00307 else
00308 debug = NULL;
00309
00310 map = init_var_map (num_ssa_names + 1);
00311
00312 FOR_EACH_BB (bb)
00313 {
00314
00315 for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
00316 {
00317 stmt = bsi_stmt (bsi);
00318 if (TREE_CODE (stmt) == MODIFY_EXPR)
00319 {
00320 tree lhs = TREE_OPERAND (stmt, 0);
00321 tree rhs = TREE_OPERAND (stmt, 1);
00322
00323 if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
00324 copy_rename_partition_coalesce (map, lhs, rhs, debug);
00325 }
00326 }
00327 }
00328
00329 FOR_EACH_BB (bb)
00330 {
00331
00332 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00333 {
00334 int i;
00335 tree res = PHI_RESULT (phi);
00336
00337
00338 if (!is_gimple_reg (SSA_NAME_VAR (res)))
00339 continue;
00340
00341 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
00342 {
00343 tree arg = PHI_ARG_DEF (phi, i);
00344 if (TREE_CODE (arg) == SSA_NAME)
00345 copy_rename_partition_coalesce (map, res, arg, debug);
00346 }
00347 }
00348 }
00349
00350 if (debug)
00351 dump_var_map (debug, map);
00352
00353
00354
00355
00356 for (x = 1; x <= num_ssa_names; x++)
00357 {
00358 part_var = partition_to_var (map, x);
00359 if (!part_var)
00360 continue;
00361 var = map->partition_to_var[x];
00362 if (debug)
00363 {
00364 if (SSA_NAME_VAR (var) != SSA_NAME_VAR (part_var))
00365 {
00366 fprintf (debug, "Coalesced ");
00367 print_generic_expr (debug, var, TDF_SLIM);
00368 fprintf (debug, " to ");
00369 print_generic_expr (debug, part_var, TDF_SLIM);
00370 fprintf (debug, "\n");
00371 }
00372 }
00373 replace_ssa_name_symbol (var, SSA_NAME_VAR (part_var));
00374 }
00375
00376 delete_var_map (map);
00377 return 0;
00378 }
00379
00380
00381
00382 static bool
00383 gate_copyrename (void)
00384 {
00385 return flag_tree_copyrename != 0;
00386 }
00387
00388 struct tree_opt_pass pass_rename_ssa_copies =
00389 {
00390 "copyrename",
00391 gate_copyrename,
00392 rename_ssa_copies,
00393 NULL,
00394 NULL,
00395 0,
00396 TV_TREE_COPY_RENAME,
00397 PROP_cfg | PROP_ssa | PROP_alias,
00398 0,
00399 0,
00400 0,
00401 TODO_dump_func | TODO_verify_ssa,
00402 0
00403 };
00404