Hi,

this tidies ssa liveness calculation a bit (related to out-of-ssa).  In 
particular it doesn't make use of var annotations to compress the index 
space from partitions to base variable indices anymore, but instead a 
hashmap built on the fly when we need it.  The basevars itself actually 
aren't needed at all (currently only for checking), only a mapping for 
which ssa names belong to the same base variable.

Regstrapped with the other two patches on x86_64-linux.  Okay for trunk?


Ciao,
Michael.
        * tree-flow.h (struct var_ann_d): Remove base_var_processed and
        base_index members.
        * tree-ssa-live.h (struct _var_map): Remove basevars member.
        (VAR_ANN_BASE_INDEX): Remove.
        * tree-ssa-live.c (var_map_base_init): Use a hash table instead
        of var annotation to compress index space.  Don't deal with above
        removed members.
        (var_map_base_fini): Don't free basevars.
        (init_var_map): Don't clear basevars.

Index: tree-flow.h
===================================================================
*** tree-flow.h.orig    2012-08-01 15:59:27.000000000 +0200
--- tree-flow.h 2012-08-01 15:59:35.000000000 +0200
*************** enum need_phi_state {
*** 178,192 ****
  
  
  struct GTY(()) var_ann_d {
-   /* Used when building base variable structures in a var_map.  */
-   unsigned base_var_processed : 1;
- 
    /* Nonzero if this variable was used after SSA optimizations were
       applied.  We set this when translating out of SSA form.  */
    unsigned used : 1;
- 
-   /* Used by var_map for the base index of ssa base variables.  */
-   unsigned base_index;
  };
  
  
--- 178,186 ----
Index: tree-ssa-live.h
===================================================================
*** tree-ssa-live.h.orig        2012-08-01 15:58:34.000000000 +0200
--- tree-ssa-live.h     2012-08-01 15:59:35.000000000 +0200
*************** along with GCC; see the file COPYING3.
*** 31,43 ****
  /* Used to create the variable mapping when we go out of SSA form.
  
     Mapping from an ssa_name to a partition number is maintained, as well as
!    partition number to back to ssa_name. A partition can also be represented
!    by a non-ssa_name variable.  This allows ssa_names and their partition to
!    be coalesced with live on entry compiler variables, as well as eventually
!    having real compiler variables assigned to each partition as part of the
!    final stage of going of of ssa.
! 
!    Non-ssa_names maintain their partition index in the variable annotation.
  
     This data structure also supports "views", which work on a subset of all
     partitions.  This allows the coalescer to decide what partitions are
--- 31,37 ----
  /* Used to create the variable mapping when we go out of SSA form.
  
     Mapping from an ssa_name to a partition number is maintained, as well as
!    partition number back to ssa_name.
  
     This data structure also supports "views", which work on a subset of all
     partitions.  This allows the coalescer to decide what partitions are
*************** typedef struct _var_map
*** 72,87 ****
  
    /* Map of partitions numbers to base variable table indexes.  */
    int *partition_to_base_index;
- 
-   /* Table of base variable's.  */
-   VEC (tree, heap) *basevars;
  } *var_map;
  
  
- /* Index to the basevar table of a non ssa-name variable.  */
- #define VAR_ANN_BASE_INDEX(ann) (ann->base_index)
- 
- 
  /* Value used to represent no partition number.  */
  #define NO_PARTITION          -1
  
--- 66,74 ----
Index: tree-ssa-live.c
===================================================================
*** tree-ssa-live.c.orig        2012-08-01 15:58:34.000000000 +0200
--- tree-ssa-live.c     2012-08-01 15:59:35.000000000 +0200
*************** static void  verify_live_on_entry (tree_
*** 59,117 ****
  static void
  var_map_base_init (var_map map)
  {
!   int x, num_part, num;
    tree var;
!   var_ann_t ann;
  
-   num = 0;
    num_part = num_var_partitions (map);
  
    /* If a base table already exists, clear it, otherwise create it.  */
!   if (map->partition_to_base_index != NULL)
!     {
!       free (map->partition_to_base_index);
!       VEC_truncate (tree, map->basevars, 0);
!     }
!   else
!     map->basevars = VEC_alloc (tree, heap, MAX (40, (num_part / 10)));
! 
    map->partition_to_base_index = (int *) xmalloc (sizeof (int) * num_part);
  
    /* Build the base variable list, and point partitions at their bases.  */
    for (x = 0; x < num_part; x++)
      {
        var = partition_to_var (map, x);
!       if (TREE_CODE (var) == SSA_NAME)
!        var = SSA_NAME_VAR (var);
!       ann = var_ann (var);
        /* If base variable hasn't been seen, set it up.  */
!       if (!ann->base_var_processed)
!         {
!         ann->base_var_processed = 1;
!         VAR_ANN_BASE_INDEX (ann) = num++;
!         VEC_safe_push (tree, heap, map->basevars, var);
        }
!       map->partition_to_base_index[x] = VAR_ANN_BASE_INDEX (ann);
      }
  
!   map->num_basevars = num;
  
!   /* Now clear the processed bit.  */
!   for (x = 0; x < num; x++)
!     {
!        var = VEC_index (tree, map->basevars, x);
!        var_ann (var)->base_var_processed = 0;
!     }
! 
! #ifdef ENABLE_CHECKING
!   for (x = 0; x < num_part; x++)
!     {
!       tree var2;
!       var = SSA_NAME_VAR (partition_to_var (map, x));
!       var2 = VEC_index (tree, map->basevars, basevar_index (map, x));
!       gcc_assert (var == var2);
!     }
! #endif
  }
  
  
--- 59,107 ----
  static void
  var_map_base_init (var_map map)
  {
!   int x, num_part;
    tree var;
!   htab_t decl_to_index;
!   struct tree_int_map *m, *mapstorage;
  
    num_part = num_var_partitions (map);
+   decl_to_index = htab_create (num_part, tree_decl_map_hash,
+                              tree_int_map_eq, NULL);
+   /* We can have at most num_part entries in the hash tables, so it's
+      enough to allocate so many map elements once, saving some malloc
+      calls.  */
+   mapstorage = m = XNEWVEC (struct tree_int_map, num_part);
  
    /* If a base table already exists, clear it, otherwise create it.  */
!   free (map->partition_to_base_index);
    map->partition_to_base_index = (int *) xmalloc (sizeof (int) * num_part);
  
    /* Build the base variable list, and point partitions at their bases.  */
    for (x = 0; x < num_part; x++)
      {
+       struct tree_int_map **slot;
+       unsigned baseindex;
        var = partition_to_var (map, x);
!       var = SSA_NAME_VAR (var);
        /* If base variable hasn't been seen, set it up.  */
!       m->base.from = var;
!       slot = (struct tree_int_map **) htab_find_slot (decl_to_index, m, 
INSERT);
!       if (!*slot)
!       {
!         baseindex = m - mapstorage;
!         m->to = baseindex;
!         *slot = m;
!         m++;
        }
!       else
!       baseindex = (*slot)->to;
!       map->partition_to_base_index[x] = baseindex;
      }
  
!   map->num_basevars = m - mapstorage;
  
!   free (mapstorage);
!   htab_delete (decl_to_index);
  }
  
  
*************** var_map_base_fini (var_map map)
*** 123,129 ****
    /* Free the basevar info if it is present.  */
    if (map->partition_to_base_index != NULL)
      {
-       VEC_free (tree, heap, map->basevars);
        free (map->partition_to_base_index);
        map->partition_to_base_index = NULL;
        map->num_basevars = 0;
--- 113,118 ----
*************** init_var_map (int size)
*** 145,151 ****
    map->partition_size = size;
    map->num_basevars = 0;
    map->partition_to_base_index = NULL;
-   map->basevars = NULL;
    return map;
  }
  
--- 134,139 ----

Reply via email to