Пример #1
0
void
fini_ssa_operands (struct function *fn)
{
  struct ssa_operand_memory_d *ptr;

  if (!--n_initialized)
    {
      build_uses.release ();
      build_vdef = NULL_TREE;
      build_vuse = NULL_TREE;
    }

  gimple_ssa_operands (fn)->free_uses = NULL;

  while ((ptr = gimple_ssa_operands (fn)->operand_memory) != NULL)
    {
      gimple_ssa_operands (fn)->operand_memory
	= gimple_ssa_operands (fn)->operand_memory->next;
      ggc_free (ptr);
    }

  gimple_ssa_operands (fn)->ops_active = false;

  if (!n_initialized)
    bitmap_obstack_release (&operands_bitmap_obstack);

  fn->gimple_df->vop = NULL_TREE;
}
Пример #2
0
static inline void
finalize_ssa_uses (struct function *fn, gimple *stmt)
{
  unsigned new_i;
  struct use_optype_d new_list;
  use_optype_p old_ops, ptr, last;

  /* Pre-pend the VUSE we may have built.  */
  if (build_vuse != NULL_TREE)
    {
      tree oldvuse = gimple_vuse (stmt);
      if (oldvuse
	  && TREE_CODE (oldvuse) == SSA_NAME)
	oldvuse = SSA_NAME_VAR (oldvuse);
      if (oldvuse != (build_vuse != NULL_TREE
		      ? build_vuse : build_vdef))
	gimple_set_vuse (stmt, NULL_TREE);
      build_uses.safe_insert (0, gimple_vuse_ptr (stmt));
    }

  new_list.next = NULL;
  last = &new_list;

  old_ops = gimple_use_ops (stmt);

  /* Clear a no longer necessary VUSE.  */
  if (build_vuse == NULL_TREE
      && gimple_vuse (stmt) != NULL_TREE)
    gimple_set_vuse (stmt, NULL_TREE);

  /* If there is anything in the old list, free it.  */
  if (old_ops)
    {
      for (ptr = old_ops; ptr->next; ptr = ptr->next)
	delink_imm_use (USE_OP_PTR (ptr));
      delink_imm_use (USE_OP_PTR (ptr));
      ptr->next = gimple_ssa_operands (fn)->free_uses;
      gimple_ssa_operands (fn)->free_uses = old_ops;
    }

  /* If we added a VUSE, make sure to set the operand if it is not already
     present and mark it for renaming.  */
  if (build_vuse != NULL_TREE
      && gimple_vuse (stmt) == NULL_TREE)
    {
      gimple_set_vuse (stmt, gimple_vop (fn));
      fn->gimple_df->rename_vops = 1;
      fn->gimple_df->ssa_renaming_needed = 1;
    }

  /* Now create nodes for all the new nodes.  */
  for (new_i = 0; new_i < build_uses.length (); new_i++)
    {
      tree *op = build_uses[new_i];
      last = add_use_op (fn, stmt, op, last);
    }

  /* Now set the stmt's operands.  */
  gimple_set_use_ops (stmt, new_list.next);
}
void
free_stmt_operands (gimple stmt)
{
  def_optype_p defs = gimple_def_ops (stmt), last_def;
  use_optype_p uses = gimple_use_ops (stmt), last_use;

  if (defs)
    {
      for (last_def = defs; last_def->next; last_def = last_def->next)
	continue;
      last_def->next = gimple_ssa_operands (cfun)->free_defs;
      gimple_ssa_operands (cfun)->free_defs = defs;
      gimple_set_def_ops (stmt, NULL);
    }

  if (uses)
    {
      for (last_use = uses; last_use->next; last_use = last_use->next)
	delink_imm_use (USE_OP_PTR (last_use));
      delink_imm_use (USE_OP_PTR (last_use));
      last_use->next = gimple_ssa_operands (cfun)->free_uses;
      gimple_ssa_operands (cfun)->free_uses = uses;
      gimple_set_use_ops (stmt, NULL);
    }

  if (gimple_has_mem_ops (stmt))
    {
      gimple_set_vuse (stmt, NULL_TREE);
      gimple_set_vdef (stmt, NULL_TREE);
    }
}
static inline void
finalize_ssa_uses (gimple stmt)
{
  unsigned new_i;
  struct use_optype_d new_list;
  use_optype_p old_ops, ptr, last;

  /* Pre-pend the VUSE we may have built.  */
  if (build_vuse != NULL_TREE)
    {
      tree oldvuse = gimple_vuse (stmt);
      if (oldvuse
	  && TREE_CODE (oldvuse) == SSA_NAME)
	oldvuse = SSA_NAME_VAR (oldvuse);
      if (oldvuse != (build_vuse != NULL_TREE
		      ? build_vuse : build_vdef))
	gimple_set_vuse (stmt, NULL_TREE);
      VEC_safe_insert (tree, heap, build_uses, 0, (tree)gimple_vuse_ptr (stmt));
    }

  new_list.next = NULL;
  last = &new_list;

  old_ops = gimple_use_ops (stmt);

  /* Clear a no longer necessary VUSE.  */
  if (build_vuse == NULL_TREE
      && gimple_vuse (stmt) != NULL_TREE)
    gimple_set_vuse (stmt, NULL_TREE);

  /* If there is anything in the old list, free it.  */
  if (old_ops)
    {
      for (ptr = old_ops; ptr; ptr = ptr->next)
	delink_imm_use (USE_OP_PTR (ptr));
      old_ops->next = gimple_ssa_operands (cfun)->free_uses;
      gimple_ssa_operands (cfun)->free_uses = old_ops;
    }

  /* If we added a VUSE, make sure to set the operand if it is not already
     present and mark it for renaming.  */
  if (build_vuse != NULL_TREE
      && gimple_vuse (stmt) == NULL_TREE)
    {
      gimple_set_vuse (stmt, gimple_vop (cfun));
      mark_sym_for_renaming (gimple_vop (cfun));
    }

  /* Now create nodes for all the new nodes.  */
  for (new_i = 0; new_i < VEC_length (tree, build_uses); new_i++)
    last = add_use_op (stmt,
		       (tree *) VEC_index (tree, build_uses, new_i),
		       last);

  /* Now set the stmt's operands.  */
  gimple_set_use_ops (stmt, new_list.next);
}
Пример #5
0
static inline struct use_optype_d *
alloc_use (struct function *fn)
{
  struct use_optype_d *ret;
  if (gimple_ssa_operands (fn)->free_uses)
    {
      ret = gimple_ssa_operands (fn)->free_uses;
      gimple_ssa_operands (fn)->free_uses
	= gimple_ssa_operands (fn)->free_uses->next;
    }
  else
    ret = (struct use_optype_d *)
          ssa_operand_alloc (fn, sizeof (struct use_optype_d));
  return ret;
}
static inline struct def_optype_d *
alloc_def (void)
{
  struct def_optype_d *ret;
  if (gimple_ssa_operands (cfun)->free_defs)
    {
      ret = gimple_ssa_operands (cfun)->free_defs;
      gimple_ssa_operands (cfun)->free_defs
	= gimple_ssa_operands (cfun)->free_defs->next;
    }
  else
    ret = (struct def_optype_d *)
	  ssa_operand_alloc (sizeof (struct def_optype_d));
  return ret;
}
Пример #7
0
bool
ssa_operands_active (struct function *fun)
{
  if (fun == NULL)
    return false;

  return fun->gimple_df && gimple_ssa_operands (fun)->ops_active;
}
Пример #8
0
void
init_ssa_operands (struct function *fn)
{
  if (!n_initialized++)
    {
      build_uses.create (10);
      build_vuse = NULL_TREE;
      build_vdef = NULL_TREE;
      bitmap_obstack_initialize (&operands_bitmap_obstack);
    }

  gcc_assert (gimple_ssa_operands (fn)->operand_memory == NULL);
  gimple_ssa_operands (fn)->operand_memory_index
     = gimple_ssa_operands (fn)->ssa_operand_mem_size;
  gimple_ssa_operands (fn)->ops_active = true;
  gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_INIT;
  create_vop_var (fn);
}
void
init_ssa_operands (void)
{
  if (!n_initialized++)
    {
      build_defs = VEC_alloc (tree, heap, 5);
      build_uses = VEC_alloc (tree, heap, 10);
      build_vuse = NULL_TREE;
      build_vdef = NULL_TREE;
      bitmap_obstack_initialize (&operands_bitmap_obstack);
    }

  gcc_assert (gimple_ssa_operands (cfun)->operand_memory == NULL);
  gimple_ssa_operands (cfun)->operand_memory_index
     = gimple_ssa_operands (cfun)->ssa_operand_mem_size;
  gimple_ssa_operands (cfun)->ops_active = true;
  memset (&clobber_stats, 0, sizeof (clobber_stats));
  gimple_ssa_operands (cfun)->ssa_operand_mem_size = OP_SIZE_INIT;
  create_vop_var ();
}
bool
ssa_operands_active (void)
{
  /* This function may be invoked from contexts where CFUN is NULL
     (IPA passes), return false for now.  FIXME: operands may be
     active in each individual function, maybe this function should
     take CFUN as a parameter.  */
  if (cfun == NULL)
    return false;

  return cfun->gimple_df && gimple_ssa_operands (cfun)->ops_active;
}
void
fini_ssa_operands (void)
{
  struct ssa_operand_memory_d *ptr;

  if (!--n_initialized)
    {
      VEC_free (tree, heap, build_defs);
      VEC_free (tree, heap, build_uses);
      build_vdef = NULL_TREE;
      build_vuse = NULL_TREE;
    }

  gimple_ssa_operands (cfun)->free_defs = NULL;
  gimple_ssa_operands (cfun)->free_uses = NULL;

  while ((ptr = gimple_ssa_operands (cfun)->operand_memory) != NULL)
    {
      gimple_ssa_operands (cfun)->operand_memory
	= gimple_ssa_operands (cfun)->operand_memory->next;
      ggc_free (ptr);
    }

  gimple_ssa_operands (cfun)->ops_active = false;

  if (!n_initialized)
    bitmap_obstack_release (&operands_bitmap_obstack);

  cfun->gimple_df->vop = NULL_TREE;

  if (dump_file && (dump_flags & TDF_STATS))
    {
      fprintf (dump_file, "Original clobbered vars:           %d\n",
	       clobber_stats.clobbered_vars);
      fprintf (dump_file, "Static write clobbers avoided:     %d\n",
	       clobber_stats.static_write_clobbers_avoided);
      fprintf (dump_file, "Static read clobbers avoided:      %d\n",
	       clobber_stats.static_read_clobbers_avoided);
      fprintf (dump_file, "Unescapable clobbers avoided:      %d\n",
	       clobber_stats.unescapable_clobbers_avoided);
      fprintf (dump_file, "Original read-only clobbers:       %d\n",
	       clobber_stats.readonly_clobbers);
      fprintf (dump_file, "Static read-only clobbers avoided: %d\n",
	       clobber_stats.static_readonly_clobbers_avoided);
    }
}
Пример #12
0
static inline void *
ssa_operand_alloc (struct function *fn, unsigned size)
{
  char *ptr;

  gcc_assert (size == sizeof (struct use_optype_d));

  if (gimple_ssa_operands (fn)->operand_memory_index + size
      >= gimple_ssa_operands (fn)->ssa_operand_mem_size)
    {
      struct ssa_operand_memory_d *ptr;

      switch (gimple_ssa_operands (fn)->ssa_operand_mem_size)
	{
	case OP_SIZE_INIT:
	  gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_1;
	  break;
	case OP_SIZE_1:
	  gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_2;
	  break;
	case OP_SIZE_2:
	case OP_SIZE_3:
	  gimple_ssa_operands (fn)->ssa_operand_mem_size = OP_SIZE_3;
	  break;
	default:
	  gcc_unreachable ();
	}


      ptr = (ssa_operand_memory_d *) ggc_internal_alloc
	(sizeof (void *) + gimple_ssa_operands (fn)->ssa_operand_mem_size);

      ptr->next = gimple_ssa_operands (fn)->operand_memory;
      gimple_ssa_operands (fn)->operand_memory = ptr;
      gimple_ssa_operands (fn)->operand_memory_index = 0;
    }

  ptr = &(gimple_ssa_operands (fn)->operand_memory
	  ->mem[gimple_ssa_operands (fn)->operand_memory_index]);
  gimple_ssa_operands (fn)->operand_memory_index += size;
  return ptr;
}
static inline void
finalize_ssa_defs (gimple stmt)
{
  unsigned new_i;
  struct def_optype_d new_list;
  def_optype_p old_ops, last;
  unsigned int num = VEC_length (tree, build_defs);

  /* There should only be a single real definition per assignment.  */
  gcc_assert ((stmt && gimple_code (stmt) != GIMPLE_ASSIGN) || num <= 1);

  /* Pre-pend the vdef we may have built.  */
  if (build_vdef != NULL_TREE)
    {
      tree oldvdef = gimple_vdef (stmt);
      if (oldvdef
	  && TREE_CODE (oldvdef) == SSA_NAME)
	oldvdef = SSA_NAME_VAR (oldvdef);
      if (oldvdef != build_vdef)
	gimple_set_vdef (stmt, build_vdef);
      VEC_safe_insert (tree, heap, build_defs, 0, (tree)gimple_vdef_ptr (stmt));
      ++num;
    }

  new_list.next = NULL;
  last = &new_list;

  old_ops = gimple_def_ops (stmt);

  new_i = 0;

  /* Clear and unlink a no longer necessary VDEF.  */
  if (build_vdef == NULL_TREE
      && gimple_vdef (stmt) != NULL_TREE)
    {
      if (TREE_CODE (gimple_vdef (stmt)) == SSA_NAME)
	{
	  unlink_stmt_vdef (stmt);
	  release_ssa_name (gimple_vdef (stmt));
	}
      gimple_set_vdef (stmt, NULL_TREE);
    }

  /* If we have a non-SSA_NAME VDEF, mark it for renaming.  */
  if (gimple_vdef (stmt)
      && TREE_CODE (gimple_vdef (stmt)) != SSA_NAME)
    mark_sym_for_renaming (gimple_vdef (stmt));

  /* Check for the common case of 1 def that hasn't changed.  */
  if (old_ops && old_ops->next == NULL && num == 1
      && (tree *) VEC_index (tree, build_defs, 0) == DEF_OP_PTR (old_ops))
    return;

  /* If there is anything in the old list, free it.  */
  if (old_ops)
    {
      old_ops->next = gimple_ssa_operands (cfun)->free_defs;
      gimple_ssa_operands (cfun)->free_defs = old_ops;
    }

  /* If there is anything remaining in the build_defs list, simply emit it.  */
  for ( ; new_i < num; new_i++)
    last = add_def_op ((tree *) VEC_index (tree, build_defs, new_i), last);

  /* Now set the stmt's operands.  */
  gimple_set_def_ops (stmt, new_list.next);
}