void
set_ssa_name_value (tree name, tree value)
{
  if (SSA_NAME_VERSION (name) >= VEC_length (tree, ssa_name_values))
    VEC_safe_grow_cleared (tree, heap, ssa_name_values,
			   SSA_NAME_VERSION (name) + 1);
  VEC_replace (tree, ssa_name_values, SSA_NAME_VERSION (name), value);
}
예제 #2
0
static void
init_parameter_lattice_values (void)
{
  tree parm, ssa_name;

  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = TREE_CHAIN (parm))
    if (is_complex_reg (parm)
	&& var_ann (parm) != NULL
	&& (ssa_name = gimple_default_def (cfun, parm)) != NULL_TREE)
      VEC_replace (complex_lattice_t, complex_lattice_values,
		   SSA_NAME_VERSION (ssa_name), VARYING);
}
예제 #3
0
static void
streamer_tree_cache_add_to_node_array (struct streamer_tree_cache_d *cache,
				       unsigned ix, tree t)
{
  /* Make sure we're either replacing an old element or
     appending consecutively.  */
  gcc_assert (ix <= VEC_length (tree, cache->nodes));

  if (ix == VEC_length (tree, cache->nodes))
    VEC_safe_push (tree, heap, cache->nodes, t);
  else
    VEC_replace (tree, cache->nodes, ix, 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;
}
예제 #5
0
static void
cfg_blocks_add (basic_block bb)
{
    /* APPLE LOCAL begin mainline */
    bool head = false;

    gcc_assert (bb != ENTRY_BLOCK_PTR && bb != EXIT_BLOCK_PTR);
    gcc_assert (!TEST_BIT (bb_in_list, bb->index));

    if (cfg_blocks_empty_p ())
    {
        cfg_blocks_tail = cfg_blocks_head = 0;
        cfg_blocks_num = 1;
    }
    else
    {
        cfg_blocks_num++;
        if (cfg_blocks_num > VEC_length (basic_block, cfg_blocks))
        {
            /* We have to grow the array now.  Adjust to queue to occupy
               the full space of the original array.  We do not need to
               initialize the newly allocated portion of the array
               because we keep track of CFG_BLOCKS_HEAD and
               CFG_BLOCKS_HEAD.  */
            cfg_blocks_tail = VEC_length (basic_block, cfg_blocks);
            cfg_blocks_head = 0;
            VEC_safe_grow (basic_block, heap, cfg_blocks, 2 * cfg_blocks_tail);
        }
        /* Minor optimization: we prefer to see blocks with more
        predecessors later, because there is more of a chance that
         the incoming edges will be executable.  */
        else if (EDGE_COUNT (bb->preds)
                 >= EDGE_COUNT (VEC_index (basic_block, cfg_blocks,
                                           cfg_blocks_head)->preds))
            cfg_blocks_tail = ((cfg_blocks_tail + 1)
                               % VEC_length (basic_block, cfg_blocks));
        else
        {
            if (cfg_blocks_head == 0)
                cfg_blocks_head = VEC_length (basic_block, cfg_blocks);
            --cfg_blocks_head;
            head = true;
        }
    }

    VEC_replace (basic_block, cfg_blocks,
                 head ? cfg_blocks_head : cfg_blocks_tail,
                 bb);
    /* APPLE LOCAL end mainline */
    SET_BIT (bb_in_list, bb->index);
}
예제 #6
0
파일: fwprop.c 프로젝트: rgmabs19357/gcc
static void
process_defs (df_ref *def_rec, int top_flag)
{
  df_ref def;
  while ((def = *def_rec++) != NULL)
    {
      df_ref curr_def = VEC_index (df_ref, reg_defs, DF_REF_REGNO (def));
      unsigned int dregno;

      if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) != top_flag)
	continue;

      dregno = DF_REF_REGNO (def);
      if (curr_def)
	VEC_safe_push (df_ref, heap, reg_defs_stack, curr_def);
      else
	{
	  /* Do not store anything if "transitioning" from NULL to NULL.  But
             otherwise, push a special entry on the stack to tell the
	     leave_block callback that the entry in reg_defs was NULL.  */
	  if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS)
	    ;
	  else
	    VEC_safe_push (df_ref, heap, reg_defs_stack, def);
	}

      if (DF_REF_FLAGS (def) & DF_MD_GEN_FLAGS)
	{
	  bitmap_set_bit (local_md, dregno);
	  VEC_replace (df_ref, reg_defs, dregno, NULL);
	}
      else
	{
	  bitmap_clear_bit (local_md, dregno);
	  VEC_replace (df_ref, reg_defs, dregno, def);
	}
    }
}
예제 #7
0
파일: fwprop.c 프로젝트: rgmabs19357/gcc
static void
process_uses (df_ref *use_rec, int top_flag)
{
  df_ref use;
  while ((use = *use_rec++) != NULL)
    if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == top_flag)
      {
        unsigned int uregno = DF_REF_REGNO (use);
        if (VEC_index (df_ref, reg_defs, uregno)
	    && !bitmap_bit_p (local_md, uregno)
	    && bitmap_bit_p (local_lr, uregno))
	  VEC_replace (df_ref, use_def_ref, DF_REF_ID (use),
		       VEC_index (df_ref, reg_defs, uregno));
      }
}
예제 #8
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;
}
예제 #9
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)
{
  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;
}
예제 #10
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);

      VEC_replace (tree, 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.  */
      SSA_NAME_VAR (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 (tree, gc, FREE_SSANAMES (cfun), var);
    }
}