tree-ssa-copyrename.c

Go to the documentation of this file.
00001 /* Rename SSA copies.
00002    Copyright (C) 2004 Free Software Foundation, Inc.
00003    Contributed by Andrew MacLeod <amacleod@redhat.com>
00004 
00005 This file is part of GCC.
00006 
00007 GCC is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2, or (at your option)
00010 any later version.
00011 
00012 GCC is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GCC; see the file COPYING.  If not, write to
00019 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
00020 Boston, MA 02110-1301, USA.  */
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 /* The following routines implement the SSA copy renaming phase.
00043 
00044    This optimization looks for copies between 2 SSA_NAMES, either through a
00045    direct copy, or an implicit one via a PHI node result and its arguments.
00046 
00047    Each copy is examined to determine if it is possible to rename the base
00048    variable of one of the operands to the same variable as the other operand.
00049    i.e.
00050    T.3_5 = <blah>
00051    a_1 = T.3_5
00052 
00053    If this copy couldn't be copy propagated, it could possibly remain in the 
00054    program throughout the optimization phases.   After SSA->normal, it would 
00055    become:
00056 
00057    T.3 = <blah>
00058    a = T.3
00059    
00060    Since T.3_5 is distinct from all other SSA versions of T.3, there is no 
00061    fundamental reason why the base variable needs to be T.3, subject to 
00062    certain restrictions.  This optimization attempts to determine if we can 
00063    change the base variable on copies like this, and result in code such as:
00064 
00065    a_5 = <blah>
00066    a_1 = a_5
00067 
00068    This gives the SSA->normal pass a shot at coalescing a_1 and a_5. If it is 
00069    possible, the copy goes away completely. If it isn't possible, a new temp
00070    will be created for a_5, and you will end up with the exact same code:
00071 
00072    a.8 = <blah>
00073    a = a.8
00074 
00075    The other benefit of performing this optimization relates to what variables
00076    are chosen in copies.  Gimplification of the program uses temporaries for
00077    a lot of things. expressions like
00078 
00079    a_1 = <blah>
00080    <blah2> = a_1
00081 
00082    get turned into 
00083     
00084    T.3_5 = <blah>
00085    a_1 = T.3_5
00086    <blah2> = a_1
00087 
00088    Copy propagation is done in a forward direction, and if we can propagate
00089    through the copy, we end up with:
00090 
00091    T.3_5 = <blah>
00092    <blah2> = T.3_5
00093 
00094    The copy is gone, but so is all reference to the user variable 'a'. By
00095    performing this optimization, we would see the sequence:
00096 
00097    a_5 = <blah>
00098    a_1 = a_5
00099    <blah2> = a_1
00100 
00101    which copy propagation would then turn into:
00102    
00103    a_5 = <blah>
00104    <blah2> = a_5
00105 
00106    and so we still retain the user variable whenever possible.  */
00107 
00108 
00109 /* Coalesce the partitions in MAP representing VAR1 and VAR2 if it is valid.
00110    Choose a representative for the partition, and send debug info to DEBUG.  */
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   /* Don't coalesce if one of the variables occurs in an abnormal PHI.  */
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   /* Partitions already have the same root, simply merge them.  */
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   /* Never attempt to coalesce 2 difference parameters.  */
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   /* Never attempt to coalesce 2 user variables unless one is an inline 
00195      variable.  */
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   /* Don't coalesce if there are two different memory tags.  */
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   /* If both values have default defs, we can't coalesce.  If only one has a 
00221      tag, make sure that variable is the new root partition.  */
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   /* Don't coalesce if the two variables aren't type compatible.  */
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   /* Don't coalesce if the aliasing sets of the types are different.  */
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   /* Merge the two partitions.  */
00263   p3 = partition_union (map->var_partition, p1, p2);
00264 
00265   /* Set the root variable of the partition to the better choice, if there is 
00266      one.  */
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   /* Update the various flag widgitry of the current base representative.  */
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 /* This function will make a pass through the IL, and attempt to coalesce any
00290    SSA versions which occur in PHI's or copies.  Coalescing is accomplished by
00291    changing the underlying root variable of all coalesced version.  This will 
00292    then cause the SSA->normal pass to attempt to coalesce them all to the same 
00293    variable.  */
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       /* Scan for real copies.  */
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       /* Treat PHI nodes as copies between the result and each argument.  */
00332       for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
00333         {
00334           int i;
00335           tree res = PHI_RESULT (phi);
00336 
00337           /* Do not process virtual SSA_NAMES.  */
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   /* Now one more pass to make all elements of a partition share the same
00354      root variable.  */
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 /* Return true if copy rename is to be performed.  */
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",                         /* name */
00391   gate_copyrename,                      /* gate */
00392   rename_ssa_copies,                    /* execute */
00393   NULL,                                 /* sub */
00394   NULL,                                 /* next */
00395   0,                                    /* static_pass_number */
00396   TV_TREE_COPY_RENAME,                  /* tv_id */
00397   PROP_cfg | PROP_ssa | PROP_alias,     /* properties_required */
00398   0,                                    /* properties_provided */
00399   0,                                    /* properties_destroyed */
00400   0,                                    /* todo_flags_start */ 
00401   TODO_dump_func | TODO_verify_ssa,     /* todo_flags_finish */
00402   0                                     /* letter */
00403 }; 
00404 

Generated on Sun Sep 17 18:03:30 2006 for Tree SSA by  doxygen 1.4.6