Example #1
0
static void 
process_replaceable (temp_expr_table_p tab, gimple stmt)
{
  tree var, def, basevar;
  int version;
  ssa_op_iter iter;
  bitmap def_vars, use_vars;

#ifdef ENABLE_CHECKING
  gcc_assert (is_replaceable_p (stmt));
#endif

  def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
  version = SSA_NAME_VERSION (def);
  basevar = SSA_NAME_VAR (def);
  def_vars = BITMAP_ALLOC (NULL);

  bitmap_set_bit (def_vars, DECL_UID (basevar));

  /* Add this expression to the dependency list for each use partition.  */
  FOR_EACH_SSA_TREE_OPERAND (var, stmt, iter, SSA_OP_USE)
    {
      int var_version = SSA_NAME_VERSION (var);

      use_vars = tab->expr_decl_uids[var_version];
      add_dependence (tab, version, var);
      if (use_vars)
        {
	  bitmap_ior_into (def_vars, use_vars);
	  BITMAP_FREE (tab->expr_decl_uids[var_version]);
	}
      else
	bitmap_set_bit (def_vars, DECL_UID (SSA_NAME_VAR (var)));
    }
Example #2
0
void
set_ssa_name_value (tree name, tree value)
{
  if (SSA_NAME_VERSION (name) >= ssa_name_values.length ())
    ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1);
  ssa_name_values[SSA_NAME_VERSION (name)] = value;
}
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);
}
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;
}
void
set_ssa_name_value (tree name, tree value)
{
  if (SSA_NAME_VERSION (name) >= ssa_name_values.length ())
    ssa_name_values.safe_grow_cleared (SSA_NAME_VERSION (name) + 1);
  if (value && TREE_OVERFLOW_P (value))
    value = drop_tree_overflow (value);
  ssa_name_values[SSA_NAME_VERSION (name)] = value;
}
Example #6
0
static tree
get_value (tree name)
{
  tree val;
  if (SSA_NAME_VERSION (name) >= n_copy_of)
    return NULL_TREE;
  val = copy_of[SSA_NAME_VERSION (name)].value;
  if (val && val != name)
    return val;
  return NULL_TREE;
}
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 #8
0
File: sese.c Project: zh9118/gcc
static bool
sese_bad_liveouts_use (sese region, bitmap liveouts, basic_block bb,
		       tree use)
{
  unsigned ver;
  basic_block def_bb;

  if (TREE_CODE (use) != SSA_NAME)
    return false;

  ver = SSA_NAME_VERSION (use);

  /* If it's in liveouts, the variable will get a new PHI node, and
     the debug use will be properly adjusted.  */
  if (bitmap_bit_p (liveouts, ver))
    return false;

  def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));

  if (!def_bb
      || !bb_in_sese_p (def_bb, region)
      || bb_in_sese_p (bb, region))
    return false;

  return true;
}
Example #9
0
static tree
get_last_copy_of (tree var)
{
  tree last;
  int i;

  /* Traverse COPY_OF starting at VAR until we get to the last
     link in the chain.  Since it is possible to have cycles in PHI
     nodes, the copy-of chain may also contain cycles.
     
     To avoid infinite loops and to avoid traversing lengthy copy-of
     chains, we artificially limit the maximum number of chains we are
     willing to traverse.

     The value 5 was taken from a compiler and runtime library
     bootstrap and a mixture of C and C++ code from various sources.
     More than 82% of all copy-of chains were shorter than 5 links.  */
#define LIMIT	5

  last = var;
  for (i = 0; i < LIMIT; i++)
    {
      tree copy = copy_of[SSA_NAME_VERSION (last)].value;
      if (copy == NULL_TREE || copy == last)
	break;
      last = copy;
    }

  /* If we have reached the limit, then we are either in a copy-of
     cycle or the copy-of chain is too long.  In this case, just
     return VAR so that it is not considered a copy of anything.  */
  return (i < LIMIT ? last : var);
}
Example #10
0
static inline bool
set_copy_of_val (tree dest, tree first)
{
  unsigned int dest_ver = SSA_NAME_VERSION (dest);
  tree old_first, old_last, new_last;
  
  /* Set FIRST to be the first link in COPY_OF[DEST].  If that
     changed, return true.  */
  old_first = copy_of[dest_ver].value;
  copy_of[dest_ver].value = first;

  if (old_first != first)
    return true;

  /* If FIRST and OLD_FIRST are the same, we need to check whether the
     copy-of chain starting at FIRST ends in a different variable.  If
     the copy-of chain starting at FIRST ends up in a different
     variable than the last cached value we had for DEST, then return
     true because DEST is now a copy of a different variable.

     This test is necessary because even though the first link in the
     copy-of chain may not have changed, if any of the variables in
     the copy-of chain changed its final value, DEST will now be the
     copy of a different variable, so we have to do another round of
     propagation for everything that depends on DEST.  */
  old_last = cached_last_copy_of[dest_ver];
  new_last = get_last_copy_of (dest);
  cached_last_copy_of[dest_ver] = new_last;

  return (old_last != new_last);
}
Example #11
0
static void
dump_copy_of (FILE *file, tree var)
{
  tree val;

  print_generic_expr (file, var, dump_flags);
  if (TREE_CODE (var) != SSA_NAME)
    return;

  val = copy_of[SSA_NAME_VERSION (var)].value;
  fprintf (file, " copy-of chain: ");
  print_generic_expr (file, var, 0);
  fprintf (file, " ");
  if (!val)
    fprintf (file, "[UNDEFINED]");
  else if (val == var)
    fprintf (file, "[NOT A COPY]");
  else
    {
      fprintf (file, "-> ");
      print_generic_expr (file, val, 0);
      fprintf (file, " ");
      fprintf (file, "[COPY]");
    }
}
Example #12
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;
}
Example #13
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;
}
Example #14
0
static unsigned
get_stmt_uid (tree stmt)
{
  if (TREE_CODE (stmt) == PHI_NODE)
    return SSA_NAME_VERSION (PHI_RESULT (stmt)) + max_stmt_uid;

  return stmt_ann (stmt)->uid;
}
Example #15
0
static unsigned
get_stmt_uid (gimple stmt)
{
  if (gimple_code (stmt) == GIMPLE_PHI)
    return SSA_NAME_VERSION (gimple_phi_result (stmt))
           + gimple_stmt_max_uid (cfun);

  return gimple_uid (stmt);
}
Example #16
0
static void
init_parameter_lattice_values (void)
{
  tree parm, ssa_name;

  for (parm = DECL_ARGUMENTS (cfun->decl); parm ; parm = DECL_CHAIN (parm))
    if (is_complex_reg (parm)
	&& (ssa_name = ssa_default_def (cfun, parm)) != NULL_TREE)
      complex_lattice_values[SSA_NAME_VERSION (ssa_name)] = VARYING;
}
Example #17
0
static void
dump_copy_of (FILE *file, tree var)
{
  tree val;
  sbitmap visited;

  print_generic_expr (file, var, dump_flags);

  if (TREE_CODE (var) != SSA_NAME)
    return;
    
  visited = sbitmap_alloc (num_ssa_names);
  sbitmap_zero (visited);
  SET_BIT (visited, SSA_NAME_VERSION (var));
  
  fprintf (file, " copy-of chain: ");

  val = var;
  print_generic_expr (file, val, 0);
  fprintf (file, " ");
  while (copy_of[SSA_NAME_VERSION (val)].value)
    {
      fprintf (file, "-> ");
      val = copy_of[SSA_NAME_VERSION (val)].value;
      print_generic_expr (file, val, 0);
      fprintf (file, " ");
      if (TEST_BIT (visited, SSA_NAME_VERSION (val)))
        break;
      SET_BIT (visited, SSA_NAME_VERSION (val));
    }

  val = get_copy_of_val (var)->value;
  if (val == NULL_TREE)
    fprintf (file, "[UNDEFINED]");
  else if (val != var)
    fprintf (file, "[COPY]");
  else
    fprintf (file, "[NOT A COPY]");
  
  sbitmap_free (visited);
}
Example #18
0
DEBUG_FUNCTION void
verify_ssaname_freelists (struct function *fun)
{
  if (!gimple_in_ssa_p (fun))
    return;

  bitmap names_in_il = BITMAP_ALLOC (NULL);

  /* Walk the entire IL noting every SSA_NAME we see.  */
  basic_block bb;
  FOR_EACH_BB_FN (bb, fun)
    {
      tree t;
      /* First note the result and arguments of PHI nodes.  */
      for (gphi_iterator gsi = gsi_start_phis (bb);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  gphi *phi = gsi.phi ();
	  t = gimple_phi_result (phi);
	  bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));

	  for (unsigned int i = 0; i < gimple_phi_num_args (phi); i++)
	    {
	      t = gimple_phi_arg_def (phi, i);
	      if (TREE_CODE (t) == SSA_NAME)
		bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));
	    }
	}

      /* Then note the operands of each statement.  */
      for (gimple_stmt_iterator gsi = gsi_start_bb (bb);
	   !gsi_end_p (gsi);
	   gsi_next (&gsi))
	{
	  ssa_op_iter iter;
	  gimple *stmt = gsi_stmt (gsi);
	  FOR_EACH_SSA_TREE_OPERAND (t, stmt, iter, SSA_OP_ALL_OPERANDS)
	    bitmap_set_bit (names_in_il, SSA_NAME_VERSION (t));
	}
    }
Example #19
0
/* qsort comparison function to sort operand entries PA and PB by rank
   so that the sorted array is ordered by rank in decreasing order.  */
static int
sort_by_operand_rank (const void *pa, const void *pb)
{
  const operand_entry_t oea = *(const operand_entry_t *)pa;
  const operand_entry_t oeb = *(const operand_entry_t *)pb;

  /* It's nicer for optimize_expression if constants that are likely
     to fold when added/multiplied//whatever are put next to each
     other.  Since all constants have rank 0, order them by type.  */
  if (oeb->rank == 0 &&  oea->rank == 0)
    return constant_type (oeb->op) - constant_type (oea->op);

  /* Lastly, make sure the versions that are the same go next to each
     other.  We use SSA_NAME_VERSION because it's stable.  */
  if ((oeb->rank - oea->rank == 0)
      && TREE_CODE (oea->op) == SSA_NAME
      && TREE_CODE (oeb->op) == SSA_NAME)
    return SSA_NAME_VERSION (oeb->op) - SSA_NAME_VERSION (oea->op);

  return oeb->rank - oea->rank;
}
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);
}
Example #21
0
static bool
verify_def (basic_block bb, basic_block *definition_block, tree ssa_name,
	    tree stmt, bool is_virtual)
{
  if (verify_ssa_name (ssa_name, is_virtual))
    goto err;

  if (definition_block[SSA_NAME_VERSION (ssa_name)])
    {
      error ("SSA_NAME created in two different blocks %i and %i",
	     definition_block[SSA_NAME_VERSION (ssa_name)]->index, bb->index);
      goto err;
    }

  definition_block[SSA_NAME_VERSION (ssa_name)] = bb;

  if (SSA_NAME_DEF_STMT (ssa_name) != stmt)
    {
      error ("SSA_NAME_DEF_STMT is wrong");
      fprintf (stderr, "Expected definition statement:\n");
      print_generic_stmt (stderr, SSA_NAME_DEF_STMT (ssa_name), TDF_VOPS);
      fprintf (stderr, "\nActual definition statement:\n");
      print_generic_stmt (stderr, stmt, TDF_VOPS);
      goto err;
    }

  return false;

err:
  fprintf (stderr, "while verifying SSA_NAME ");
  print_generic_expr (stderr, ssa_name, 0);
  fprintf (stderr, " in statement\n");
  print_generic_stmt (stderr, stmt, TDF_VOPS);

  return true;
}
Example #22
0
static inline prop_value_t *
get_copy_of_val (tree var)
{
  prop_value_t *val = &copy_of[SSA_NAME_VERSION (var)];

  if (val->value == NULL_TREE
      && !stmt_may_generate_copy (SSA_NAME_DEF_STMT (var)))
    {
      /* If the variable will never generate a useful copy relation,
	 make it its own copy.  */
      val->value = var;
    }

  return val;
}
Example #23
0
static void
output_phi (struct output_block *ob, gimple phi)
{
  unsigned i, len = gimple_phi_num_args (phi);

  streamer_write_record_start (ob, lto_gimple_code_to_tag (GIMPLE_PHI));
  streamer_write_uhwi (ob, SSA_NAME_VERSION (PHI_RESULT (phi)));

  for (i = 0; i < len; i++)
    {
      stream_write_tree (ob, gimple_phi_arg_def (phi, i), true);
      streamer_write_uhwi (ob, gimple_phi_arg_edge (phi, i)->src->index);
      lto_output_location (ob, gimple_phi_arg_location (phi, i));
    }
}
Example #24
0
static inline bool
set_copy_of_val (tree var, tree val)
{
  unsigned int ver = SSA_NAME_VERSION (var);
  tree old;

  /* Set FIRST to be the first link in COPY_OF[DEST].  If that
     changed, return true.  */
  old = copy_of[ver].value;
  copy_of[ver].value = val;

  if (old != val
      || (val && !operand_equal_p (old, val, 0)))
    return true;

  return false;
}
Example #25
0
static void
add_dependence (temp_expr_table_p tab, int version, tree var)
{
  int i;
  bitmap_iterator bi;
  unsigned x;

  i = SSA_NAME_VERSION (var);
  if (version_to_be_replaced_p (tab, i))
    {
      if (!bitmap_empty_p (tab->new_replaceable_dependencies))
        {
	  /* Version will now be killed by a write to any partition the 
	     substituted expression would have been killed by.  */
	  EXECUTE_IF_SET_IN_BITMAP (tab->new_replaceable_dependencies, 0, x, bi)
	    add_to_partition_kill_list (tab, x, version);

	  /* Rather than set partition_dependencies and in_use lists bit by 
	     bit, simply OR in the new_replaceable_dependencies bits.  */
	  if (!tab->partition_dependencies[version])
	    tab->partition_dependencies[version] = BITMAP_ALLOC (NULL);
	  bitmap_ior_into (tab->partition_dependencies[version], 
			   tab->new_replaceable_dependencies);
	  bitmap_ior_into (tab->partition_in_use, 
			   tab->new_replaceable_dependencies);
	  /* It is only necessary to add these once.  */
	  bitmap_clear (tab->new_replaceable_dependencies);
	}
    }
  else
    {
      i = var_to_partition (tab->map, var);
#ifdef ENABLE_CHECKING
      gcc_assert (i != NO_PARTITION);
      gcc_assert (tab->num_in_part[i] != 0);
#endif
      /* Only dependencies on ssa_names which are coalesced with something need
         to be tracked.  Partitions with containing only a single SSA_NAME
	 *cannot* have their value changed.  */
      if (tab->num_in_part[i] > 1)
        {
	  add_to_partition_kill_list (tab, i, version);
	  make_dependent_on_partition (tab, version, i);
	}
    }
}
Example #26
0
File: sese.c Project: zh9118/gcc
static void
sese_build_liveouts_use (sese region, bitmap liveouts, basic_block bb,
			 tree use)
{
  unsigned ver;
  basic_block def_bb;

  if (TREE_CODE (use) != SSA_NAME)
    return;

  ver = SSA_NAME_VERSION (use);
  def_bb = gimple_bb (SSA_NAME_DEF_STMT (use));

  if (!def_bb
      || !bb_in_sese_p (def_bb, region)
      || bb_in_sese_p (bb, region))
    return;

  bitmap_set_bit (liveouts, ver);
}
/* 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;
}
Example #28
0
static complex_lattice_t
find_lattice_value (tree t)
{
  tree real, imag;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      return complex_lattice_values[SSA_NAME_VERSION (t)];

    case COMPLEX_CST:
      real = TREE_REALPART (t);
      imag = TREE_IMAGPART (t);
      break;

    default:
      gcc_unreachable ();
    }

  return find_lattice_value_parts (real, imag);
}
static complex_lattice_t
find_lattice_value (tree t)
{
  tree real, imag;
  int r, i;
  complex_lattice_t ret;

  switch (TREE_CODE (t))
    {
    case SSA_NAME:
      return VEC_index (complex_lattice_t, complex_lattice_values,
			SSA_NAME_VERSION (t));

    case COMPLEX_CST:
      real = TREE_REALPART (t);
      imag = TREE_IMAGPART (t);
      break;

    case COMPLEX_EXPR:
      real = TREE_OPERAND (t, 0);
      imag = TREE_OPERAND (t, 1);
      break;

    default:
      gcc_unreachable ();
    }

  r = some_nonzerop (real);
  i = some_nonzerop (imag);
  ret = r*ONLY_REAL + i*ONLY_IMAG;

  /* ??? On occasion we could do better than mapping 0+0i to real, but we
     certainly don't want to leave it UNINITIALIZED, which eventually gets
     mapped to VARYING.  */
  if (ret == UNINITIALIZED)
    ret = ONLY_REAL;

  return ret;
}
Example #30
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);
    }
}