This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Patch/pass for PR 14016
- From: Andrew MacLeod <amacleod at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: 27 Feb 2004 12:41:13 -0500
- Subject: [tree-ssa] Patch/pass for PR 14016
This patch takes care of, among other issues, PR 14016.
It implements a very quick pass which scans the program for copies
involving temporaries, and attempts to rename the temporaries into
versions of the other variable involved in the copy. Preference is
given to user variables of course, resulting in things like PR 14016
continuing to use user variables instead of new temporaries. ie:
void test55 (void)
{
int u;
int XXX, YYY;
XXX = foo ();
YYY = bar ();
if (XXX != 5 && YYY)
{
u = XXX + 22;
if (u != 27)
baz ();
}
}
use to become:
test55 ()
{
int YYY;
int XXX;
int u;
int T.1;
int T.0;
<bb 0>:
T.0<D1067> = foo ();
T.1<D1068> = bar ();
if (T.0<D1067> != 5) goto <L0>; else goto <L3>;
<L0>:;
if (T.1<D1068> != 0) goto <L1>; else goto <L3>;
<L1>:;
if (T.0<D1067> + 22 != 27) goto <L2>; else goto <L3>;
<L2>:;
baz ();
<L3>:;
return;
}
and with this pass, it instead becomes:
test55 ()
{
int YYY;
int XXX;
int u;
int T.1;
int T.0;
<bb 0>:
XXX<D1062> = foo ();
YYY<D1063> = bar ();
if (XXX<D1062> != 5) goto <L0>; else goto <L3>;
<L0>:;
if (YYY<D1063> != 0) goto <L1>; else goto <L3>;
<L1>:;
if (XXX<D1062> + 22 != 27) goto <L2>; else goto <L3>;
<L2>:;
baz ();
<L3>:;
return;
}
so we are back to using the user variables. yay!
The other benefit of this pass is we can sometimes get rid of copies
between different variables. Unless DOM could copy propagate a copy
away, it would often live throughout the compilation phase. SSA->normal
only attemps to coalesce copies where the RHS and LHS are versions of
the same base variable.
This pass looks for SSA_NAMEs involved in copies with different
SSA_NAME_VAR base variables, and attempts to change the base variable,
if possible.
ie given:
T.3_5 = foo()
a_2 = T.3_5
if possible, the base variable for SSA_NAME version 5 will be changed to
a, so we end up with:
a_5 = foo()
a_2 = a_5
and lots of wonderful things can now happen. There is more detailed
commentary in the comments of the new file tree-ssa-copyrename.c.
Fundamentally we can perform this operation because we treat different
versions of the same variable as totally different variables until we
mash them back together. Changing the base variable is simply a bit of
magic hand waving...
So, yes, this is a new pass. But it is actually quite small, and
blindingly fast. (one pass through the IL). On a compilation of Geralds
C++ testcase, a 78 second compile on my machine spend 0.11 seconds
running this pass twice.
It delivers some much needed support for debugging, as PR 14016
demonstrates. Its also worth 2 SPEC marks (consistantly) on my spec2000
runs on a P4.
So here it is. It ran a full testsuite a couple of days ago, and runs
spec2000 fine. Added no new regressions, and bootstraped. I've cleaned
it up a bit, and Im running it through the passes on a new code base
from today.
Should we consider adding it to tree-ssa before the merge, or hold onto
it for a couple of months?
Andrew
2004-02-27 Andrew MacLeod <amacleod@redhat.com>
* Makefile.in (tree-ssa-copyrename.o): New object.
* timevar.def (TV_TREE_COPY_RENAME): New time variable.
* tree-optimize.c (init_tree_optimization_passes): Add copy rename
pass.
* tree-pass.h (pass_rename_ssa_copies): New pass structure.
* tree-ssa-copyrename.c : New file.
(copy_rename_partition_coalesce): Coalesce partitions for renaming.
(rename_ssa_copies): Find renamable copies.
(pass_rename_ssa_copies): Initialize.
* tree-ssa-live.c (register_ssa_partition): Move to tree-ssa-live.h.
* tree-ssa-live.h (register_ssa_partition): Moved from tree-ssa-live.c.
Index: Makefile.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v
retrieving revision 1.903.2.186
diff -c -p -r1.903.2.186 Makefile.in
*** Makefile.in 24 Feb 2004 16:30:44 -0000 1.903.2.186
--- Makefile.in 27 Feb 2004 16:06:35 -0000
*************** OBJS-common = \
*** 868,874 ****
tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-simple.o \
tree-alias-type.o gimplify.o tree-pretty-print.o \
tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o \
! tree-ssa-copy.o tree-nrv.o \
tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o \
tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o \
tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o \
--- 868,874 ----
tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-simple.o \
tree-alias-type.o gimplify.o tree-pretty-print.o \
tree-alias-common.o tree-ssa-ccp.o tree-browser.o @ANDER@ tree-ssa-dce.o \
! tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o \
tree-ssa-pre.o tree-ssa-live.o tree-ssa-operands.o tree-ssa-alias.o \
tree-ssa-phiopt.o tree-ssa-forwprop.o tree-nested.o tree-ssa-dse.o \
tree-ssa-dom.o domwalk.o tree-tailcall.o gimple-low.o tree-iterator.o \
*************** tree-ssa-live.o : tree-ssa-live.c $(TREE
*** 1587,1592 ****
--- 1587,1596 ----
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
errors.h toplev.h function.h $(TIMEVAR_H) tree-alias-common.h \
$(TM_H) coretypes.h $(TREE_DUMP_H) tree-ssa-live.h
+ tree-ssa-copyrename.o : tree-ssa-copyrename.c $(TREE_FLOW_H) $(CONFIG_H) \
+ $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h \
+ diagnostic.h errors.h toplev.h function.h $(TIMEVAR_H) tree-pass.h \
+ tree-alias-common.h $(TM_H) coretypes.h $(TREE_DUMP_H) tree-ssa-live.h
tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) \
$(GGC_H) output.h diagnostic.h errors.h toplev.h $(TIMEVAR_H) \
Index: timevar.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/timevar.def,v
retrieving revision 1.14.2.38
diff -c -p -r1.14.2.38 timevar.def
*** timevar.def 24 Feb 2004 16:30:45 -0000 1.14.2.38
--- timevar.def 27 Feb 2004 16:06:35 -0000
*************** DEFTIMEVAR (TV_TREE_LOOP , "tree lo
*** 84,89 ****
--- 84,90 ----
DEFTIMEVAR (TV_TREE_CH , "tree copy headers")
DEFTIMEVAR (TV_TREE_SSA_TO_NORMAL , "tree SSA to normal")
DEFTIMEVAR (TV_TREE_NRV , "tree NRV optimization")
+ DEFTIMEVAR (TV_TREE_COPY_RENAME , "tree rename SSA copies")
DEFTIMEVAR (TV_TREE_SSA_VERIFY , "tree SSA verifier")
DEFTIMEVAR (TV_TREE_STMT_VERIFY , "tree STMT verifier")
DEFTIMEVAR (TV_CGRAPH_VERIFY , "callgraph verifier")
Index: tree-optimize.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v
retrieving revision 1.1.4.130
diff -c -p -r1.1.4.130 tree-optimize.c
*** tree-optimize.c 25 Feb 2004 03:22:47 -0000 1.1.4.130
--- tree-optimize.c 27 Feb 2004 16:06:35 -0000
*************** init_tree_optimization_passes (void)
*** 279,284 ****
--- 279,285 ----
NEXT_PASS (pass_referenced_vars);
NEXT_PASS (pass_build_pta);
NEXT_PASS (pass_build_ssa);
+ NEXT_PASS (pass_rename_ssa_copies);
NEXT_PASS (pass_early_warn_uninitialized);
NEXT_PASS (pass_dce);
NEXT_PASS (pass_dominator);
*************** init_tree_optimization_passes (void)
*** 292,297 ****
--- 293,299 ----
NEXT_PASS (pass_profile);
NEXT_PASS (pass_lower_complex);
NEXT_PASS (pass_sra);
+ NEXT_PASS (DUP_PASS (pass_rename_ssa_copies));
NEXT_PASS (DUP_PASS (pass_dominator));
NEXT_PASS (DUP_PASS (pass_redundant_phi));
NEXT_PASS (DUP_PASS (pass_dce));
Index: tree-pass.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-pass.h,v
retrieving revision 1.1.2.18
diff -c -p -r1.1.2.18 tree-pass.h
*** tree-pass.h 25 Feb 2004 03:22:47 -0000 1.1.2.18
--- tree-pass.h 27 Feb 2004 16:06:35 -0000
*************** extern struct tree_opt_pass pass_redunda
*** 124,129 ****
--- 124,130 ----
extern struct tree_opt_pass pass_dse;
extern struct tree_opt_pass pass_nrv;
extern struct tree_opt_pass pass_remove_useless_vars;
+ extern struct tree_opt_pass pass_rename_ssa_copies;
#endif /* GCC_TREE_PASS_H */
Index: tree-ssa-copyrename.c
===================================================================
RCS file: tree-ssa-copyrename.c
diff -N tree-ssa-copyrename.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- tree-ssa-copyrename.c 27 Feb 2004 16:06:35 -0000
***************
*** 0 ****
--- 1,353 ----
+ /* Rename SSA copies.
+ Copyright (C) 2004 Free Software Foundation, Inc.
+ Contributed by Andrew MacLeod <amacleod@redhat.com>
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING. If not, write to
+ the Free Software Foundation, 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ #include "config.h"
+ #include "system.h"
+ #include "coretypes.h"
+ #include "tm.h"
+ #include "tree.h"
+ #include "flags.h"
+ #include "basic-block.h"
+ #include "function.h"
+ #include "diagnostic.h"
+ #include "bitmap.h"
+ #include "tree-flow.h"
+ #include "tree-simple.h"
+ #include "tree-inline.h"
+ #include "timevar.h"
+ #include "tree-alias-common.h"
+ #include "hashtab.h"
+ #include "tree-dump.h"
+ #include "tree-ssa-live.h"
+ #include "tree-pass.h"
+
+ extern void rename_ssa_copies (void);
+
+ /* The following routines implement the SSA copy renaming phase.
+
+ This optimization looks for copies between 2 SSA_NAMES, either through a
+ direct copy, or an implicit one via a PHI node result and its arguments.
+
+ Each copy is examined to determine if it is possible to rename the base
+ variable of one of the operands to the same variable as the other operand.
+ ie.
+ T.3_5 = <blah>
+ a_1 = T.3_5
+
+ If this copy couldn't be copy propagated, it could possibly remain in the
+ program throughout the optimization phases. After SSA->normal, it would
+ become:
+
+ T.3 = <blah>
+ a = T.3
+
+ Since T.3_5 is distinct from all other SSA versions of T.3, there is no
+ fundamental reason why the base variable needs to be T.3, subject to
+ certain restrictions. This optimization attempts to determine if we can
+ change the base variable on copies like this, and result in code such as:
+
+ a_5 = <blah>
+ a_1 = a_5
+
+ This gives the SSA->normal pass a shot at coalescing a_1 and a_5. If it is
+ possible, the copy goes away completely. If it isn't possible, a new temp
+ will be created for a_5, and you will end up with the exact same code:
+
+ a.8 = <blah>
+ a = a.8
+
+ The other benefit of performing this optimization relates to what variables
+ are chosen in copies. Gimplification of the program uses temporaries for
+ a lot of things. expressions like
+
+ a_1 = <blah>
+ <blah2> = a_1
+
+ get turned into
+
+ T.3_5 = <blah>
+ a_1 = T.3_5
+ <blah2> = a_1
+
+ Copy propagation is done in a forward direction, and if we can propagate
+ through the copy, we end up with:
+
+ T.3_5 = <blah>
+ <blah2> = T.3_5
+
+ The copy is gone, but so is all reference to the user variable 'a'. By
+ performing this optimization, we would see the sequence:
+
+ a_5 = <blah>
+ a_1 = a_5
+ <blah2> = a_1
+
+ which copy propagation would then turn into:
+
+ a_5 = <blah>
+ <blah2> = a_5
+
+ and so we still retain the user variable whenever possible. */
+
+
+ /* Coalesce two partitions if appropriate, and choose an appropriate
+ representative. */
+
+ static void
+ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug)
+ {
+ int p1, p2, p3;
+ tree root1, root2;
+ var_ann_t ann1, ann2, ann3;
+ bool gimp1, gimp2;
+
+ #ifdef ENABLE_CHECKING
+ if (TREE_CODE (var1) != SSA_NAME || TREE_CODE (var2) != SSA_NAME)
+ abort ();
+ #endif
+
+ register_ssa_partition (map, var1, false);
+ register_ssa_partition (map, var2, true);
+
+ p1 = partition_find (map->var_partition, SSA_NAME_VERSION (var1));
+ p2 = partition_find (map->var_partition, SSA_NAME_VERSION (var2));
+
+ if (debug)
+ {
+ fprintf (debug, "Try : ");
+ print_generic_expr (debug, var1, TDF_SLIM);
+ fprintf (debug, "(P%d) & ", p1);
+ print_generic_expr (debug, var2, TDF_SLIM);
+ fprintf (debug, "(P%d)", p2);
+ }
+
+ #ifdef ENABLE_CHECKING
+ if (p1 == NO_PARTITION || p2 == NO_PARTITION)
+ abort ();
+ #endif
+
+ root1 = SSA_NAME_VAR (partition_to_var (map, p1));
+ root2 = SSA_NAME_VAR (partition_to_var (map, p2));
+ ann1 = var_ann (root1);
+ ann2 = var_ann (root2);
+
+ if (p1 == p2)
+ {
+ if (debug)
+ fprintf (debug, " : Already coalesced.\n");
+ return;
+ }
+
+ /* Partitions already have the same root, simply merge them. */
+ if (root1 == root2)
+ {
+ p1 = partition_union (map->var_partition, p1, p2);
+ if (debug)
+ fprintf (debug, " : Same root, coalesced --> P%d.\n", p1);
+ return;
+ }
+
+ /* Never attempt to coalesce 2 difference parameters. */
+ if (TREE_CODE (root1) == PARM_DECL && TREE_CODE (root2) == PARM_DECL)
+ {
+ if (debug)
+ fprintf (debug, " : 2 different PARM_DECLS. No coalesce.\n");
+ return;
+ }
+
+ gimp1 = is_gimple_tmp_var (root1);
+ gimp2 = is_gimple_tmp_var (root2);
+
+ /* Never attempt to coalesce 2 user variables. */
+ if (!gimp1 && !gimp2)
+ {
+ if (debug)
+ fprintf (debug, " : 2 different USER vars. No coalesce.\n");
+ return;
+ }
+
+
+ /* Don't coalesce if there are two different memory tags. */
+ if (ann1->type_mem_tag && ann2->type_mem_tag
+ && ann1->type_mem_tag != ann2->type_mem_tag)
+ {
+ if (debug)
+ fprintf (debug, " : 2 memory tags. No coalesce.\n");
+ return;
+ }
+
+ /* If both values have default defs, we can't coalesce. If only one has a
+ tag, make sure that variable is the new root partition. */
+ if (default_def (root1))
+ {
+ if (default_def (root2))
+ {
+ if (debug)
+ fprintf (debug, " : 2 default defs. No coalesce.\n");
+ return;
+ }
+ else
+ {
+ gimp2 = true;
+ gimp1 = false;
+ }
+ }
+ else
+ if (default_def (root2))
+ {
+ gimp1 = true;
+ gimp2 = false;
+ }
+
+ /* Merge the two partitions. */
+ p3 = partition_union (map->var_partition, p1, p2);
+
+ /* Set the root variable of the partition to the better choice. */
+ if (!gimp2)
+ SSA_NAME_VAR (partition_to_var (map, p3)) = root2;
+ else
+ if (!gimp1)
+ SSA_NAME_VAR (partition_to_var (map, p3)) = root1;
+
+ /* Update the various flag widgitry of the current base representative. */
+ ann3 = var_ann (SSA_NAME_VAR (partition_to_var (map, p3)));
+ ann3->is_stored = ann1->is_stored | ann2->is_stored;
+ ann3->is_dereferenced_store
+ = (ann1->is_dereferenced_store | ann2->is_dereferenced_store);
+ ann3->is_dereferenced_load
+ = (ann1->is_dereferenced_load | ann2->is_dereferenced_load);
+ if (ann1->type_mem_tag)
+ ann3->type_mem_tag = ann1->type_mem_tag;
+ else
+ ann3->type_mem_tag = ann2->type_mem_tag;
+
+ if (debug)
+ {
+ fprintf (debug, " --> P%d ", p3);
+ print_generic_expr (debug, SSA_NAME_VAR (partition_to_var (map, p3)),
+ TDF_SLIM);
+ fprintf (debug, "\n");
+ }
+ }
+
+
+ /* This function will make a pass through the IL, and attempt to coalesce any
+ SSA versions which occur in PHI's or copies. Coalescing is accomplished by
+ changing the underlying root variable of all coalesced version. This will
+ then cause the SSA->normal pass to attempt to coalesce them all to the same
+ variable. */
+
+ void
+ rename_ssa_copies (void)
+ {
+ var_map map;
+ basic_block bb;
+ block_stmt_iterator bsi;
+ tree phi, stmt, var, part_var;
+ unsigned x;
+ FILE *debug;
+
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ debug = dump_file;
+ else
+ debug = NULL;
+
+ map = init_var_map (highest_ssa_version + 1);
+
+ FOR_EACH_BB (bb)
+ {
+ /* Treat PHI nodes as copies between the result and each argument. */
+ for (phi = phi_nodes (bb); phi; phi = TREE_CHAIN (phi))
+ {
+ int i;
+ tree res = PHI_RESULT (phi);
+ /* Dont process virtual SSA_NAMES. */
+ if (!is_gimple_reg (SSA_NAME_VAR (res)))
+ continue;
+ for (i = 0; i < PHI_NUM_ARGS (phi); i++)
+ {
+ tree arg = PHI_ARG_DEF (phi, i);
+ if (TREE_CODE (arg) == SSA_NAME)
+ copy_rename_partition_coalesce (map, res, arg, debug);
+ }
+ }
+
+ /* Scan for real copies. */
+ for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
+ {
+ stmt = bsi_stmt (bsi);
+ if (TREE_CODE (stmt) == MODIFY_EXPR)
+ {
+ tree lhs = TREE_OPERAND (stmt, 0);
+ tree rhs = TREE_OPERAND (stmt, 1);
+
+ if (TREE_CODE (lhs) == SSA_NAME && TREE_CODE (rhs) == SSA_NAME)
+ copy_rename_partition_coalesce (map, lhs, rhs, debug);
+ }
+ }
+ }
+
+ if (debug)
+ dump_var_map (debug, map);
+
+ /* Now one more pass to make all elements of a partition share the same
+ root variable. */
+
+ for (x = 1; x <= highest_ssa_version; x++)
+ {
+ part_var = partition_to_var (map, x);
+ if (!part_var)
+ continue;
+ var = map->partition_to_var[x];
+ if (debug)
+ {
+ if (SSA_NAME_VAR (var) != SSA_NAME_VAR (part_var))
+ {
+ fprintf (debug, "Coalesced ");
+ print_generic_expr (debug, var, TDF_SLIM);
+ fprintf (debug, " to ");
+ print_generic_expr (debug, part_var, TDF_SLIM);
+ fprintf (debug, "\n");
+ }
+ }
+ SSA_NAME_VAR (var) = SSA_NAME_VAR (part_var);
+ }
+
+ delete_var_map (map);
+ }
+
+
+ struct tree_opt_pass pass_rename_ssa_copies =
+ {
+ "copyrename", /* name */
+ NULL, /* gate */
+ rename_ssa_copies, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_COPY_RENAME, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */
+ };
+
Index: tree-ssa-live.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.c,v
retrieving revision 1.1.2.36
diff -c -p -r1.1.2.36 tree-ssa-live.c
*** tree-ssa-live.c 17 Feb 2004 20:59:52 -0000 1.1.2.36
--- tree-ssa-live.c 27 Feb 2004 16:06:35 -0000
*************** delete_var_map (var_map map)
*** 98,131 ****
free (map);
}
- /* This routine registers an SSA versioned variable with the partition
- manager. Any unregistered partitions may be compacted out later. */
-
- static inline void
- register_ssa_partition (var_map map, tree ssa_var, bool is_use)
- {
- int version;
-
- #if defined ENABLE_CHECKING
- if (TREE_CODE (ssa_var) != SSA_NAME)
- abort ();
-
- if (!is_gimple_reg (SSA_NAME_VAR (ssa_var)))
- {
- fprintf (stderr, "Illegally registering a virtual SSA name :");
- print_generic_expr (stderr, ssa_var, TDF_SLIM);
- fprintf (stderr, " in the SSA->Normal phase.\n");
- abort();
- }
- #endif
-
- version = SSA_NAME_VERSION (ssa_var);
- if (is_use && map->ref_count)
- map->ref_count[version]++;
-
- if (map->partition_to_var[version] == NULL_TREE)
- map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
- }
/* This function will combine 2 partitions. Returns the partition which
represents the new partition. If the two partitions cannot be combined,
--- 98,103 ----
Index: tree-ssa-live.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.h,v
retrieving revision 1.1.2.16
diff -c -p -r1.1.2.16 tree-ssa-live.h
*** tree-ssa-live.h 11 Feb 2004 16:28:41 -0000 1.1.2.16
--- tree-ssa-live.h 27 Feb 2004 16:06:35 -0000
*************** static inline tree partition_to_var (var
*** 79,84 ****
--- 79,85 ----
static inline int var_to_partition (var_map, tree);
static inline tree version_to_var (var_map, int);
static inline int version_ref_count (var_map, tree);
+ static inline void register_ssa_partition (var_map, tree, bool);
#define SSA_VAR_MAP_REF_COUNT 0x01
extern var_map create_ssa_var_map (int);
*************** var_to_partition_to_var (var_map map, tr
*** 167,172 ****
--- 168,203 ----
return partition_to_var (map, part);
}
+ /* This routine registers an SSA versioned variable with the partition
+ manager. Any unregistered partitions may be compacted out later. */
+
+ static inline void
+ register_ssa_partition (var_map map, tree ssa_var, bool is_use)
+ {
+ int version;
+
+ #if defined ENABLE_CHECKING
+ if (TREE_CODE (ssa_var) != SSA_NAME)
+ abort ();
+
+ if (!is_gimple_reg (SSA_NAME_VAR (ssa_var)))
+ {
+ fprintf (stderr, "Illegally registering a virtual SSA name :");
+ print_generic_expr (stderr, ssa_var, TDF_SLIM);
+ fprintf (stderr, " in the SSA->Normal phase.\n");
+ abort();
+ }
+ #endif
+
+ version = SSA_NAME_VERSION (ssa_var);
+ if (is_use && map->ref_count)
+ map->ref_count[version]++;
+
+ if (map->partition_to_var[version] == NULL_TREE)
+ map->partition_to_var[SSA_NAME_VERSION (ssa_var)] = ssa_var;
+ }
+
+
/* ---------------- live on entry/exit info ------------------------------
This structure is used to represent live range information on SSA based