Example #1
0
/* Return SSA names that are unused to GGC memory and compact the SSA
   version namespace.  This is used to keep footprint of compiler during
   interprocedural optimization.  */
static unsigned int
release_dead_ssa_names (void)
{
  unsigned i, j;
  int n = vec_safe_length (FREE_SSANAMES (cfun));

  /* Now release the freelist.  */
  vec_free (FREE_SSANAMES (cfun));

  /* And compact the SSA number space.  We make sure to not change the
     relative order of SSA versions.  */
  for (i = 1, j = 1; i < cfun->gimple_df->ssa_names->length (); ++i)
    {
      tree name = ssa_name (i);
      if (name)
	{
	  if (i != j)
	    {
	      SSA_NAME_VERSION (name) = j;
	      (*cfun->gimple_df->ssa_names)[j] = name;
	    }
	  j++;
	}
    }
  cfun->gimple_df->ssa_names->truncate (j);

  statistics_counter_event (cfun, "SSA names released", n);
  statistics_counter_event (cfun, "SSA name holes removed", i - j);
  if (dump_file)
    fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n",
	     n, n * 100.0 / num_ssa_names, i - j);
  return 0;
}
/* Return SSA names that are unused to GGC memory.  This is used to keep
   footprint of compiler during interprocedural optimization.
   As a side effect the SSA_NAME_VERSION number reuse is reduced
   so this function should not be used too often.  */
static unsigned int
release_dead_ssa_names (void)
{
    tree t, next;
    int n = 0;
    referenced_var_iterator rvi;

    /* Current defs point to various dead SSA names that in turn points to dead
       statements so bunch of dead memory is held from releasing.  */
    FOR_EACH_REFERENCED_VAR (t, rvi)
    set_current_def (t, NULL);
    /* Now release the freelist.  */
    for (t = FREE_SSANAMES (cfun); t; t = next)
    {
        next = TREE_CHAIN (t);
        /* Dangling pointers might make GGC to still see dead SSA names, so it is
        important to unlink the list and avoid GGC from seeing all subsequent
        SSA names.  In longer run we want to have all dangling pointers here
         removed (since they usually go through dead statements that consume
         considerable amounts of memory).  */
        TREE_CHAIN (t) = NULL_TREE;
        n++;
    }
    FREE_SSANAMES (cfun) = NULL;

    /* Cgraph edges has been invalidated and point to dead statement.  We need to
       remove them now and will rebuild it before next IPA pass.  */
    cgraph_node_remove_callees (cgraph_node (current_function_decl));

    if (dump_file)
        fprintf (dump_file, "Released %i names, %.2f%%\n", n, n * 100.0 / num_ssa_names);
    return 0;
}
Example #3
0
/* Return SSA names that are unused to GGC memory.  This is used to keep
   footprint of compiler during interprocedural optimization.
   As a side effect the SSA_NAME_VERSION number reuse is reduced
   so this function should not be used too often.  */
static unsigned int
release_dead_ssa_names (void)
{
  tree t, next;
  int n = 0;
  referenced_var_iterator rvi;

  /* Current defs point to various dead SSA names that in turn point to
     eventually dead variables so a bunch of memory is held live.  */
  FOR_EACH_REFERENCED_VAR (t, rvi)
    set_current_def (t, NULL);
  /* Now release the freelist.  */
  for (t = FREE_SSANAMES (cfun); t; t = next)
    {
      next = TREE_CHAIN (t);
      /* Dangling pointers might make GGC to still see dead SSA names, so it is
 	 important to unlink the list and avoid GGC from seeing all subsequent
	 SSA names.  In longer run we want to have all dangling pointers here
	 removed (since they usually go through dead statements that consume
	 considerable amounts of memory).  */
      TREE_CHAIN (t) = NULL_TREE;
      n++;
    }
  FREE_SSANAMES (cfun) = NULL;

  statistics_counter_event (cfun, "SSA names released", n);
  if (dump_file)
    fprintf (dump_file, "Released %i names, %.2f%%\n",
	     n, n * 100.0 / num_ssa_names);
  return 0;
}
Example #4
0
tree
make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
{
  tree t;
  use_operand_p imm;

  gcc_assert (TREE_CODE (var) == VAR_DECL
	      || TREE_CODE (var) == PARM_DECL
	      || TREE_CODE (var) == RESULT_DECL
	      || (TYPE_P (var) && is_gimple_reg_type (var)));

  /* If our free list has an element, then use it.  */
  if (!vec_safe_is_empty (FREE_SSANAMES (fn)))
    {
      t = FREE_SSANAMES (fn)->pop ();
      if (GATHER_STATISTICS)
	ssa_name_nodes_reused++;

      /* The node was cleared out when we put it on the free list, so
	 there is no need to do so again here.  */
      gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
      (*SSANAMES (fn))[SSA_NAME_VERSION (t)] = t;
    }
  else
    {
      t = make_node (SSA_NAME);
      SSA_NAME_VERSION (t) = SSANAMES (fn)->length ();
      vec_safe_push (SSANAMES (fn), t);
      if (GATHER_STATISTICS)
	ssa_name_nodes_created++;
    }

  if (TYPE_P (var))
    {
      TREE_TYPE (t) = var;
      SET_SSA_NAME_VAR_OR_IDENTIFIER (t, NULL_TREE);
    }
  else
    {
      TREE_TYPE (t) = TREE_TYPE (var);
      SET_SSA_NAME_VAR_OR_IDENTIFIER (t, var);
    }
  SSA_NAME_DEF_STMT (t) = stmt;
  if (POINTER_TYPE_P (TREE_TYPE (t)))
    SSA_NAME_PTR_INFO (t) = NULL;
  else
    SSA_NAME_RANGE_INFO (t) = NULL;

  SSA_NAME_IN_FREE_LIST (t) = 0;
  SSA_NAME_IS_DEFAULT_DEF (t) = 0;
  imm = &(SSA_NAME_IMM_USE_NODE (t));
  imm->use = NULL;
  imm->prev = imm;
  imm->next = imm;
  imm->loc.ssa_name = t;

  return t;
}
tree
make_ssa_name (tree var, tree stmt)
{
    tree t;
    use_operand_p imm;

    gcc_assert (DECL_P (var)
                || TREE_CODE (var) == INDIRECT_REF);

    gcc_assert (!stmt
                || EXPR_P (stmt) || GIMPLE_STMT_P (stmt)
                || TREE_CODE (stmt) == PHI_NODE);

    /* If our free list has an element, then use it.  */
    if (FREE_SSANAMES (cfun))
    {
        t = FREE_SSANAMES (cfun);
        FREE_SSANAMES (cfun) = TREE_CHAIN (FREE_SSANAMES (cfun));
#ifdef GATHER_STATISTICS
        ssa_name_nodes_reused++;
#endif

        /* The node was cleared out when we put it on the free list, so
        there is no need to do so again here.  */
        gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
        VEC_replace (tree, SSANAMES (cfun), SSA_NAME_VERSION (t), t);
    }
    else
    {
        t = make_node (SSA_NAME);
        SSA_NAME_VERSION (t) = num_ssa_names;
        VEC_safe_push (tree, gc, SSANAMES (cfun), t);
#ifdef GATHER_STATISTICS
        ssa_name_nodes_created++;
#endif
    }

    TREE_TYPE (t) = TREE_TYPE (var);
    SSA_NAME_VAR (t) = var;
    SSA_NAME_DEF_STMT (t) = stmt;
    SSA_NAME_PTR_INFO (t) = NULL;
    SSA_NAME_IN_FREE_LIST (t) = 0;
    SSA_NAME_IS_DEFAULT_DEF (t) = 0;
    imm = &(SSA_NAME_IMM_USE_NODE (t));
    imm->use = NULL;
    imm->prev = imm;
    imm->next = imm;
    imm->stmt = t;

    return t;
}
Example #6
0
void
fini_ssanames (struct function *fn)
{
  vec_free (SSANAMES (fn));
  vec_free (FREE_SSANAMES (fn));
  vec_free (FREE_SSANAMES_QUEUE (fn));
}
Example #7
0
tree
make_ssa_name_fn (struct function *fn, tree var, gimple stmt)
{
  tree t;
  use_operand_p imm;

  gcc_assert (DECL_P (var));

  /* If our free list has an element, then use it.  */
  if (FREE_SSANAMES (fn))
    {
      t = FREE_SSANAMES (fn);
      FREE_SSANAMES (fn) = TREE_CHAIN (FREE_SSANAMES (fn));
#ifdef GATHER_STATISTICS
      ssa_name_nodes_reused++;
#endif

      /* The node was cleared out when we put it on the free list, so
	 there is no need to do so again here.  */
      gcc_assert (ssa_name (SSA_NAME_VERSION (t)) == NULL);
      VEC_replace (tree, SSANAMES (fn), SSA_NAME_VERSION (t), t);
    }
  else
    {
      t = make_node (SSA_NAME);
      SSA_NAME_VERSION (t) = VEC_length (tree, SSANAMES (fn));
      VEC_safe_push (tree, gc, SSANAMES (fn), t);
#ifdef GATHER_STATISTICS
      ssa_name_nodes_created++;
#endif
    }

  TREE_TYPE (t) = TREE_TYPE (var);
  SSA_NAME_VAR (t) = var;
  SSA_NAME_DEF_STMT (t) = stmt;
  SSA_NAME_PTR_INFO (t) = NULL;
  SSA_NAME_IN_FREE_LIST (t) = 0;
  SSA_NAME_IS_DEFAULT_DEF (t) = 0;
  imm = &(SSA_NAME_IMM_USE_NODE (t));
  imm->use = NULL;
  imm->prev = imm;
  imm->next = imm;
  imm->loc.ssa_name = t;

  return t;
}
/* Return SSA names that are unused to GGC memory and compact the SSA
   version namespace.  This is used to keep footprint of compiler during
   interprocedural optimization.  */
static unsigned int
release_dead_ssa_names (void)
{
  tree t;
  unsigned i, j;
  int n = VEC_length (tree, FREE_SSANAMES (cfun));
  referenced_var_iterator rvi;

  /* Current defs point to various dead SSA names that in turn point to
     eventually dead variables so a bunch of memory is held live.  */
  FOR_EACH_REFERENCED_VAR (cfun, t, rvi)
    set_current_def (t, NULL);

  /* Now release the freelist.  */
  VEC_free (tree, gc, FREE_SSANAMES (cfun));
  FREE_SSANAMES (cfun) = NULL;

  /* And compact the SSA number space.  We make sure to not change the
     relative order of SSA versions.  */
  for (i = 1, j = 1; i < VEC_length (tree, cfun->gimple_df->ssa_names); ++i)
    {
      tree name = ssa_name (i);
      if (name)
	{
	  if (i != j)
	    {
	      SSA_NAME_VERSION (name) = j;
	      VEC_replace (tree, cfun->gimple_df->ssa_names, j, name);
	    }
	  j++;
	}
    }
  VEC_truncate (tree, cfun->gimple_df->ssa_names, j);

  statistics_counter_event (cfun, "SSA names released", n);
  statistics_counter_event (cfun, "SSA name holes removed", i - j);
  if (dump_file)
    fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n",
	     n, n * 100.0 / num_ssa_names, i - j);
  return 0;
}
void
init_ssanames (void)
{
    SSANAMES (cfun) = VEC_alloc (tree, gc, 50);

    /* Version 0 is special, so reserve the first slot in the table.  Though
       currently unused, we may use version 0 in alias analysis as part of
       the heuristics used to group aliases when the alias sets are too
       large.

       We use VEC_quick_push here because we know that SSA_NAMES has at
       least 50 elements reserved in it.  */
    VEC_quick_push (tree, SSANAMES (cfun), NULL_TREE);
    FREE_SSANAMES (cfun) = NULL;
}
void
init_ssanames (struct function *fn, int size)
{
  if (size < 50)
    size = 50;

  SSANAMES (fn) = VEC_alloc (tree, gc, size);

  /* Version 0 is special, so reserve the first slot in the table.  Though
     currently unused, we may use version 0 in alias analysis as part of
     the heuristics used to group aliases when the alias sets are too
     large.

     We use VEC_quick_push here because we know that SSA_NAMES has at
     least 50 elements reserved in it.  */
  VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
  FREE_SSANAMES (fn) = NULL;

  SYMS_TO_RENAME (fn) = BITMAP_GGC_ALLOC ();
}
Example #11
0
void
init_ssanames (struct function *fn, int size)
{
  if (size < 50)
    size = 50;

  vec_alloc (SSANAMES (fn), size);

  /* Version 0 is special, so reserve the first slot in the table.  Though
     currently unused, we may use version 0 in alias analysis as part of
     the heuristics used to group aliases when the alias sets are too
     large.

     We use vec::quick_push here because we know that SSA_NAMES has at
     least 50 elements reserved in it.  */
  SSANAMES (fn)->quick_push (NULL_TREE);
  FREE_SSANAMES (fn) = NULL;

  fn->gimple_df->ssa_renaming_needed = 0;
  fn->gimple_df->rename_vops = 0;
}
Example #12
0
void
fini_ssanames (void)
{
  vec_free (SSANAMES (cfun));
  vec_free (FREE_SSANAMES (cfun));
}
Example #13
0
void
release_ssa_name (tree var)
{
  if (!var)
    return;

  /* Never release the default definition for a symbol.  It's a
     special SSA name that should always exist once it's created.  */
  if (SSA_NAME_IS_DEFAULT_DEF (var))
    return;

  /* If VAR has been registered for SSA updating, don't remove it.
     After update_ssa has run, the name will be released.  */
  if (name_registered_for_update_p (var))
    {
      release_ssa_name_after_update_ssa (var);
      return;
    }

  /* release_ssa_name can be called multiple times on a single SSA_NAME.
     However, it should only end up on our free list one time.   We
     keep a status bit in the SSA_NAME node itself to indicate it has
     been put on the free list.

     Note that once on the freelist you can not reference the SSA_NAME's
     defining statement.  */
  if (! SSA_NAME_IN_FREE_LIST (var))
    {
      tree saved_ssa_name_var = SSA_NAME_VAR (var);
      int saved_ssa_name_version = SSA_NAME_VERSION (var);
      use_operand_p imm = &(SSA_NAME_IMM_USE_NODE (var));

      if (MAY_HAVE_DEBUG_STMTS)
	insert_debug_temp_for_var_def (NULL, var);

#ifdef ENABLE_CHECKING
      verify_imm_links (stderr, var);
#endif
      while (imm->next != imm)
	delink_imm_use (imm->next);

      (*SSANAMES (cfun))[SSA_NAME_VERSION (var)] = NULL_TREE;
      memset (var, 0, tree_size (var));

      imm->prev = imm;
      imm->next = imm;
      imm->loc.ssa_name = var;

      /* First put back the right tree node so that the tree checking
	 macros do not complain.  */
      TREE_SET_CODE (var, SSA_NAME);

      /* Restore the version number.  */
      SSA_NAME_VERSION (var) = saved_ssa_name_version;

      /* Hopefully this can go away once we have the new incremental
         SSA updating code installed.  */
      SET_SSA_NAME_VAR_OR_IDENTIFIER (var, saved_ssa_name_var);

      /* Note this SSA_NAME is now in the first list.  */
      SSA_NAME_IN_FREE_LIST (var) = 1;

      /* And finally put it on the free list.  */
      vec_safe_push (FREE_SSANAMES (cfun), var);
    }
}
void
fini_ssanames (void)
{
  VEC_free (tree, gc, SSANAMES (cfun));
  VEC_free (tree, gc, FREE_SSANAMES (cfun));
}