/* Rewrite a program in Normal form into SSA.
- Copyright (C) 2001-2019 Free Software Foundation, Inc.
+ Copyright (C) 2001-2021 Free Software Foundation, Inc.
Contributed by Diego Novillo <dnovillo@redhat.com>
This file is part of GCC.
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
+#include "attr-fnspec.h"
#define PERCENT(x,y) ((float)(x) * 100.0 / (float)(y))
/* Re-allocate the vector at most once per update/into-SSA. */
if (ver >= len)
- info_for_ssa_name.safe_grow_cleared (num_ssa_names);
+ info_for_ssa_name.safe_grow_cleared (num_ssa_names, true);
/* But allocate infos lazily. */
info = info_for_ssa_name[ver];
if (!blocks_with_phis_to_rewrite)
return;
- bitmap_set_bit (blocks_with_phis_to_rewrite, idx);
-
- n = (unsigned) last_basic_block_for_fn (cfun) + 1;
- if (phis_to_rewrite.length () < n)
- phis_to_rewrite.safe_grow_cleared (n);
+ if (bitmap_set_bit (blocks_with_phis_to_rewrite, idx))
+ {
+ n = (unsigned) last_basic_block_for_fn (cfun) + 1;
+ if (phis_to_rewrite.length () < n)
+ phis_to_rewrite.safe_grow_cleared (n, true);
- phis = phis_to_rewrite[idx];
- phis.reserve (10);
+ phis = phis_to_rewrite[idx];
+ gcc_assert (!phis.exists ());
+ phis.create (10);
+ }
+ else
+ phis = phis_to_rewrite[idx];
phis.safe_push (phi);
phis_to_rewrite[idx] = phis;
unsigned i;
var_info *info;
- timevar_push (TV_TREE_INSERT_PHI_NODES);
-
/* When the gimplifier introduces SSA names it cannot easily avoid
situations where abnormal edges added by CFG construction break
the use-def dominance requirement. For this case rewrite SSA
insert_phi_nodes_for (info->var, idf, false);
BITMAP_FREE (idf);
}
-
- timevar_pop (TV_TREE_INSERT_PHI_NODES);
}
SET_DEF (def_p, name);
register_new_def (DEF_FROM_PTR (def_p), var);
+ /* Do not insert debug stmts if the stmt ends the BB. */
+ if (stmt_ends_bb_p (stmt))
+ continue;
+
tracked_var = target_for_debug_bind (var);
if (tracked_var)
{
void
dump_currdefs (FILE *file)
{
- unsigned i;
- tree var;
-
if (symbols_to_rename.is_empty ())
return;
fprintf (file, "\n\nCurrent reaching definitions\n\n");
- FOR_EACH_VEC_ELT (symbols_to_rename, i, var)
+ for (tree var : symbols_to_rename)
{
common_info *info = get_common_info (var);
fprintf (file, "CURRDEF (");
{
edge e;
edge_iterator ei;
- unsigned i;
FOR_EACH_EDGE (e, ei, bb->succs)
{
- gphi *phi;
vec<gphi *> phis;
if (!bitmap_bit_p (blocks_with_phis_to_rewrite, e->dest->index))
continue;
phis = phis_to_rewrite[e->dest->index];
- FOR_EACH_VEC_ELT (phis, i, phi)
+ for (gphi *phi : phis)
{
tree arg, lhs_sym, reaching_def = NULL;
use_operand_p arg_p;
static void
rewrite_blocks (basic_block entry, enum rewrite_mode what)
{
- /* Rewrite all the basic blocks in the program. */
- timevar_push (TV_TREE_SSA_REWRITE_BLOCKS);
-
block_defs_stack.create (10);
/* Recursively walk the dominator tree rewriting each statement in
}
block_defs_stack.release ();
-
- timevar_pop (TV_TREE_SSA_REWRITE_BLOCKS);
}
class mark_def_dom_walker : public dom_walker
GIMPLE_PASS, /* type */
"ssa", /* name */
OPTGROUP_NONE, /* optinfo_flags */
- TV_TREE_SSA_OTHER, /* tv_id */
+ TV_TREE_INTO_SSA, /* tv_id */
PROP_cfg, /* properties_required */
PROP_ssa, /* properties_provided */
0, /* properties_destroyed */
basic_block bb;
/* Increase the set of variables we can rewrite into SSA form
- by clearing TREE_ADDRESSABLE and setting DECL_GIMPLE_REG_P
- and transform the IL to support this. */
+ by clearing TREE_ADDRESSABLE and transform the IL to support this. */
if (optimize)
execute_update_addresses_taken ();
}
/* Initialize SSA_NAME_POINTS_TO_READONLY_MEMORY. */
- tree fnspec = lookup_attribute ("fn spec",
- TYPE_ATTRIBUTES (TREE_TYPE (fun->decl)));
- if (fnspec)
+ tree fnspec_tree
+ = lookup_attribute ("fn spec",
+ TYPE_ATTRIBUTES (TREE_TYPE (fun->decl)));
+ if (fnspec_tree)
{
- fnspec = TREE_VALUE (TREE_VALUE (fnspec));
- unsigned i = 1;
+ attr_fnspec fnspec (TREE_VALUE (TREE_VALUE (fnspec_tree)));
+ unsigned i = 0;
for (tree arg = DECL_ARGUMENTS (cfun->decl);
arg; arg = DECL_CHAIN (arg), ++i)
{
- if (i >= (unsigned) TREE_STRING_LENGTH (fnspec))
- break;
- if (TREE_STRING_POINTER (fnspec)[i] == 'R'
- || TREE_STRING_POINTER (fnspec)[i] == 'r')
+ if (!fnspec.arg_specified_p (i))
+ break;
+ if (fnspec.arg_readonly_p (i))
{
tree name = ssa_default_def (fun, arg);
if (name)
}
}
-
-/* Do a dominator walk starting at BB processing statements that
- reference symbols in SSA operands. This is very similar to
- mark_def_sites, but the scan handles statements whose operands may
- already be SSA names.
+/* Processing statements in BB that reference symbols in SSA operands.
+ This is very similar to mark_def_sites, but the scan handles
+ statements whose operands may already be SSA names.
If INSERT_PHI_P is true, mark those uses as live in the
corresponding block. This is later used by the PHI placement
that. */
static void
-prepare_block_for_update (basic_block bb, bool insert_phi_p)
+prepare_block_for_update_1 (basic_block bb, bool insert_phi_p)
{
- basic_block son;
edge e;
edge_iterator ei;
}
}
- /* Now visit all the blocks dominated by BB. */
- for (son = first_dom_son (CDI_DOMINATORS, bb);
- son;
- son = next_dom_son (CDI_DOMINATORS, son))
- prepare_block_for_update (son, insert_phi_p);
}
+/* Do a dominator walk starting at BB processing statements that
+ reference symbols in SSA operands. This is very similar to
+ mark_def_sites, but the scan handles statements whose operands may
+ already be SSA names.
+
+ If INSERT_PHI_P is true, mark those uses as live in the
+ corresponding block. This is later used by the PHI placement
+ algorithm to make PHI pruning decisions.
+
+ FIXME. Most of this would be unnecessary if we could associate a
+ symbol to all the SSA names that reference it. But that
+ sounds like it would be expensive to maintain. Still, it
+ would be interesting to see if it makes better sense to do
+ that. */
+static void
+prepare_block_for_update (basic_block bb, bool insert_phi_p)
+{
+ size_t sp = 0;
+ basic_block *worklist;
+
+ /* Allocate the worklist. */
+ worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
+ /* Add the BB to the worklist. */
+ worklist[sp++] = bb;
+
+ while (sp)
+ {
+ basic_block bb;
+ basic_block son;
+
+ /* Pick a block from the worklist. */
+ bb = worklist[--sp];
+
+ prepare_block_for_update_1 (bb, insert_phi_p);
+
+ /* Now add all the blocks dominated by BB to the worklist. */
+ for (son = first_dom_son (CDI_DOMINATORS, bb);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ worklist[sp++] = son;
+ }
+ free (worklist);
+}
/* Helper for prepare_names_to_update. Mark all the use sites for
NAME as interesting. BLOCKS and INSERT_PHI_P are as in
if (blocks_with_phis_to_rewrite)
EXECUTE_IF_SET_IN_BITMAP (blocks_with_phis_to_rewrite, 0, i, bi)
- {
- vec<gphi *> phis = phis_to_rewrite[i];
- phis.release ();
- phis_to_rewrite[i].create (0);
- }
+ phis_to_rewrite[i].release ();
BITMAP_FREE (blocks_with_phis_to_rewrite);
BITMAP_FREE (blocks_to_update);