/* Rewrite a program in Normal form into SSA.
- Copyright (C) 2001-2020 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];
{
n = (unsigned) last_basic_block_for_fn (cfun) + 1;
if (phis_to_rewrite.length () < n)
- phis_to_rewrite.safe_grow_cleared (n);
+ phis_to_rewrite.safe_grow_cleared (n, true);
phis = phis_to_rewrite[idx];
gcc_assert (!phis.exists ());
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)
{
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