This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Tree-SSA self checking infrastructure


On Wed, 2003-11-19 at 14:13, law@redhat.com wrote:
> In message <20031119190649.GQ16923@atrey.karlin.mff.cuni.cz>, Jan Hubicka write
> s:
>  >This brings me into questions about my tail call updating code.
>  >Perhaps I need to re-do SSA form on call cobbered variables after
>  >removing the call?
> Are you changing the CFG?  Are you changing the dominator tree?  Those
> are the key questions.
> 
>  >> The exception is the dominator based jump threader where we do rerewrite
>  >> existing SSA_NAMEs.  In that case we know there are no overlaps as we have
>  >> done no optimizations which could have created an overlap.
>  >
>  >I see.  It would be nice to drop a comment somewhere in tree-optimize.c
>  >clarifying what can be renamed when.
> Err, I thought there was a comment regarding this issue in the code.  
> Regardless, from discussions with Andrew we may have the ability to
> un-ssa specific variables, which would make this a non-issue.

If you want to hack around with it, the following *ought* to get you
what you are looking for.  If you can create the var_map like
create_ssa_var_map does to include only the things you are interested
in. (and it ought to include *all* versions of a variable or the live
range stuff wont be right when its coalesced back to the root variable).

The only thing I had to break out was the bits that physically rewrote
the trees.

Your entry point is the function "remove_ssa_form (var_map)"

I'll work through any problems you run into, but thats the basic gist of
what needs to be done.

I haven't run tests or anything on this to make sure I didnt break
anything, but they are running now. I would expect no problems with
existing code, and I would think that if you create a var_map the new
entry point ought to workl just fine. There isnt much new there, so it
should work fine.


Andrew


Index: tree-ssa-live.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-live.h,v
retrieving revision 1.1.2.10
diff -c -p -r1.1.2.10 tree-ssa-live.h
*** tree-ssa-live.h	14 Nov 2003 16:50:02 -0000	1.1.2.10
--- tree-ssa-live.h	19 Nov 2003 19:34:59 -0000
*************** extern void dump_var_map (FILE *, var_ma
*** 62,67 ****
--- 62,68 ----
  extern int var_union (var_map, tree, tree);
  extern void change_partition_var (var_map, tree, int);
  extern void compact_var_map (var_map, int);
+ extern void remove_ssa_form (var_map);
  
  static inline int num_var_partitions (var_map);
  static inline tree var_to_partition_to_var (var_map, tree);
Index: tree-ssa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa.c,v
retrieving revision 1.1.4.153
diff -c -p -r1.1.4.153 tree-ssa.c
*** tree-ssa.c	16 Nov 2003 11:00:40 -0000	1.1.4.153
--- tree-ssa.c	19 Nov 2003 19:35:00 -0000
*************** dump_replaceable_exprs (FILE *f, tree *e
*** 2313,2396 ****
  }
  
  
! /* Take function FNDECL out of SSA form.
! 
!    PHASE indicates which dump file from the DUMP_FILES array to use when
!    dumping debugging information.  */
! 
! void
! rewrite_out_of_ssa (tree fndecl, enum tree_dump_index phase)
  {
    basic_block bb;
    block_stmt_iterator si;
    edge e;
!   var_map map;
!   tree phi, next;
!   elim_graph g;
!   tree_live_info_p liveinfo;
!   tree *values = NULL;
!   int var_flags = 0;
! 
!   timevar_push (TV_TREE_SSA_TO_NORMAL);
! 
!   dump_file = dump_begin (phase, &dump_flags);
! 
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
! 
!   if (flag_tree_ter)
!     var_flags = SSA_VAR_MAP_REF_COUNT;
!   map = create_ssa_var_map (var_flags);
!   eliminate_extraneous_phis (map);
! 
!   /* Shrink the map to include only referenced variables.  */
!   if (flag_tree_combine_temps)
!     compact_var_map (map, VARMAP_NORMAL);
!   else
!     compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
! 
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     dump_var_map (dump_file, map);
! 
!   liveinfo = coalesce_ssa_name (map);
! 
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     {
!       fprintf (dump_file, "After Coalescing:\n");
!       dump_var_map (dump_file, map);
!     }
!   if (!flag_tree_combine_temps)
!     compact_var_map (map, VARMAP_NORMAL);
! 
!   /* This is the final var list, so assign real variables to the different
!      partitions.  */
!   assign_vars (map);
! 
!   if (dump_file && (dump_flags & TDF_DETAILS))
!     {
!       fprintf (dump_file, "After Root variable replacement:\n");
!       dump_var_map (dump_file, map);
!     }
! 
!   if (flag_tree_ter)
!     {
!       values = find_replaceable_exprs (map);
!       if (values && dump_file && (dump_flags & TDF_DETAILS))
! 	dump_replaceable_exprs (dump_file, values);
!     }
! 
!   if (flag_tree_combine_temps && liveinfo)
!     {
!       coalesce_vars (map, liveinfo);
!       if (dump_file && (dump_flags & TDF_DETAILS))
! 	{
! 	  fprintf (dump_file, "After variable memory coalescing:\n");
! 	  dump_var_map (dump_file, map);
! 	}
!     }
! 
!   if (liveinfo)
!     delete_tree_live_info (liveinfo);
  
    /* Replace PHI nodes with any required copies.  */
    g = new_elim_graph (map->num_partitions);
--- 2313,2326 ----
  }
  
  
! static void
! rewrite_trees (var_map map, tree *values)
  {
+   elim_graph g;
    basic_block bb;
    block_stmt_iterator si;
    edge e;
!   tree phi;
  
    /* Replace PHI nodes with any required copies.  */
    g = new_elim_graph (map->num_partitions);
*************** rewrite_out_of_ssa (tree fndecl, enum tr
*** 2460,2480 ****
          {
  	  for (e = bb->pred; e; e = e->pred_next)
  	    eliminate_phi (e, phi_arg_from_edge (phi, e), g);
- 	  for ( ; phi; phi = next)
- 	    {
- 	      next = TREE_CHAIN (phi);
- 	      remove_phi_node (phi, NULL_TREE, bb);
- 	    }
  	}
      }
  
    delete_elim_graph (g);
  
!   if (values)
!     free (values);
  
    /* If any copies were inserted on edges, actually insert them now.  */
    bsi_commit_edge_inserts (0, NULL);
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
--- 2390,2524 ----
          {
  	  for (e = bb->pred; e; e = e->pred_next)
  	    eliminate_phi (e, phi_arg_from_edge (phi, e), g);
  	}
      }
  
    delete_elim_graph (g);
+ }
+ 
+ /* Remove the variables specified in a var map from SSA form.  */
+ void
+ remove_ssa_form (var_map map)
+ {
+   tree_live_info_p liveinfo;
+   basic_block bb;
+   tree phi, next;
+   FILE *save;
+ 
+   save = dump_file;
+   dump_file = NULL;
+ 
+   compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
+   liveinfo = coalesce_ssa_name (map);
+   compact_var_map (map, VARMAP_NORMAL);
+   assign_vars (map);
+   if (liveinfo)
+     delete_tree_live_info (liveinfo);
+   rewrite_trees (map, NULL);
  
!   /* Remove phi nodes which have been translated back to real variables.  */
!   FOR_EACH_BB (bb)
!     {
!       for (phi = phi_nodes (bb); phi; phi = next)
! 	{
! 	  next = TREE_CHAIN (phi);
! 	  if (var_to_partition (map, PHI_RESULT (phi)) != NO_PARTITION)
! 	    remove_phi_node (phi, NULL_TREE, bb);
! 	}
!     }
  
    /* If any copies were inserted on edges, actually insert them now.  */
    bsi_commit_edge_inserts (0, NULL);
+ 
+   dump_file = save;
+ }
+ 
+ /* Take function FNDECL out of SSA form.
+ 
+    PHASE indicates which dump file from the DUMP_FILES array to use when
+    dumping debugging information.  */
+ 
+ void
+ rewrite_out_of_ssa (tree fndecl, enum tree_dump_index phase)
+ {
+   basic_block bb;
+   var_map map;
+   tree phi, next;
+   tree_live_info_p liveinfo;
+   tree *values = NULL;
+   int var_flags = 0;
+ 
+   timevar_push (TV_TREE_SSA_TO_NORMAL);
+ 
+   dump_file = dump_begin (phase, &dump_flags);
+ 
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);
+ 
+   if (flag_tree_ter)
+     var_flags = SSA_VAR_MAP_REF_COUNT;
+   map = create_ssa_var_map (var_flags);
+   eliminate_extraneous_phis (map);
+ 
+   /* Shrink the map to include only referenced variables.  */
+   if (flag_tree_combine_temps)
+     compact_var_map (map, VARMAP_NORMAL);
+   else
+     compact_var_map (map, VARMAP_NO_SINGLE_DEFS);
+ 
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     dump_var_map (dump_file, map);
+ 
+   liveinfo = coalesce_ssa_name (map);
+ 
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       fprintf (dump_file, "After Coalescing:\n");
+       dump_var_map (dump_file, map);
+     }
+   if (!flag_tree_combine_temps)
+     compact_var_map (map, VARMAP_NORMAL);
+ 
+   /* This is the final var list, so assign real variables to the different
+      partitions.  */
+   assign_vars (map);
+ 
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       fprintf (dump_file, "After Root variable replacement:\n");
+       dump_var_map (dump_file, map);
+     }
+ 
+   if (flag_tree_ter)
+     {
+       values = find_replaceable_exprs (map);
+       if (values && dump_file && (dump_flags & TDF_DETAILS))
+ 	dump_replaceable_exprs (dump_file, values);
+     }
+ 
+   if (flag_tree_combine_temps && liveinfo)
+     {
+       coalesce_vars (map, liveinfo);
+       if (dump_file && (dump_flags & TDF_DETAILS))
+ 	{
+ 	  fprintf (dump_file, "After variable memory coalescing:\n");
+ 	  dump_var_map (dump_file, map);
+ 	}
+     }
+ 
+   if (liveinfo)
+     delete_tree_live_info (liveinfo);
+ 
+   rewrite_trees (map, values);
+ 
+   FOR_EACH_BB (bb)
+     {
+       for (phi = phi_nodes (bb); phi; phi = next)
+ 	{
+ 	  next = TREE_CHAIN (phi);
+ 	  remove_phi_node (phi, NULL_TREE, bb);
+ 	}
+     }
  
    if (dump_file && (dump_flags & TDF_DETAILS))
      dump_tree_cfg (dump_file, dump_flags & ~TDF_DETAILS);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]