/* Miscellaneous SSA utility functions.
- Copyright (C) 2001-2019 Free Software Foundation, Inc.
+ Copyright (C) 2001-2021 Free Software Foundation, Inc.
This file is part of GCC.
err = true;
}
+ if ((e->flags & EDGE_ABNORMAL) && TREE_CODE (op) != SSA_NAME)
+ {
+ error ("PHI argument on abnormal edge is not SSA_NAME");
+ err = true;
+ }
+
if (TREE_CODE (op) == SSA_NAME)
{
err = verify_ssa_name (op, virtual_operand_p (gimple_phi_result (phi)));
# pragma GCC diagnostic pop
#endif
-/* Initialize global DFA and SSA structures. */
+/* Initialize global DFA and SSA structures.
+ If SIZE is non-zero allocated ssa names array of a given size. */
void
-init_tree_ssa (struct function *fn)
+init_tree_ssa (struct function *fn, int size)
{
fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
pt_solution_reset (&fn->gimple_df->escaped);
- init_ssanames (fn, 0);
+ init_ssanames (fn, size);
}
/* Deallocate memory associated with SSA data structures for FNDECL. */
&& known_gt (wi::to_poly_offset (TYPE_SIZE_UNIT (TREE_TYPE (decl))),
mem_ref_offset (lhs))
&& multiple_of_p (sizetype, TREE_OPERAND (lhs, 1),
- TYPE_SIZE_UNIT (TREE_TYPE (lhs))))
+ TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
+ && known_ge (wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (decl))),
+ wi::to_poly_offset (TYPE_SIZE (TREE_TYPE (lhs)))))
{
poly_uint64 lhs_bits, nelts;
if (poly_int_tree_p (TYPE_SIZE (TREE_TYPE (lhs)), &lhs_bits)
&& multiple_p (lhs_bits,
tree_to_uhwi
(TYPE_SIZE (TREE_TYPE (TREE_TYPE (decl)))),
- &nelts))
+ &nelts)
+ && valid_vector_subparts_p (nelts))
{
if (known_eq (nelts, 1u))
return false;
return true;
}
-/* When possible, clear TREE_ADDRESSABLE bit or set DECL_GIMPLE_REG_P bit and
- mark the variable VAR for conversion into SSA. Return true when updating
+/* When possible, clear TREE_ADDRESSABLE bit, set or clear DECL_NOT_GIMPLE_REG_P
+ and mark the variable VAR for conversion into SSA. Return true when updating
stmts is required. */
static void
|| bitmap_bit_p (addresses_taken, DECL_UID (var)))
return;
- if (TREE_ADDRESSABLE (var)
- /* Do not change TREE_ADDRESSABLE if we need to preserve var as
- a non-register. Otherwise we are confused and forget to
- add virtual operands for it. */
- && (!is_gimple_reg_type (TREE_TYPE (var))
- || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
- || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
- || !bitmap_bit_p (not_reg_needs, DECL_UID (var))))
+ bool maybe_reg = false;
+ if (TREE_ADDRESSABLE (var))
{
TREE_ADDRESSABLE (var) = 0;
- /* If we cleared TREE_ADDRESSABLE make sure DECL_GIMPLE_REG_P
- is unset if we cannot rewrite the var into SSA. */
- if ((TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE
- || TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE)
- && bitmap_bit_p (not_reg_needs, DECL_UID (var)))
- DECL_GIMPLE_REG_P (var) = 0;
- if (is_gimple_reg (var))
- bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
+ maybe_reg = true;
if (dump_file)
{
fprintf (dump_file, "No longer having address taken: ");
}
}
- if (!DECL_GIMPLE_REG_P (var)
- && !bitmap_bit_p (not_reg_needs, DECL_UID (var))
- && (TREE_CODE (TREE_TYPE (var)) == COMPLEX_TYPE
- || TREE_CODE (TREE_TYPE (var)) == VECTOR_TYPE)
- && !TREE_THIS_VOLATILE (var)
- && (!VAR_P (var) || !DECL_HARD_REGISTER (var)))
+ /* For register type decls if we do not have any partial defs
+ we cannot express in SSA form mark them as DECL_NOT_GIMPLE_REG_P
+ as to avoid SSA rewrite. For the others go ahead and mark
+ them for renaming. */
+ if (is_gimple_reg_type (TREE_TYPE (var)))
{
- DECL_GIMPLE_REG_P (var) = 1;
- bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
- if (dump_file)
+ if (bitmap_bit_p (not_reg_needs, DECL_UID (var)))
{
- fprintf (dump_file, "Now a gimple register: ");
- print_generic_expr (dump_file, var);
- fprintf (dump_file, "\n");
+ DECL_NOT_GIMPLE_REG_P (var) = 1;
+ if (dump_file)
+ {
+ fprintf (dump_file, "Has partial defs: ");
+ print_generic_expr (dump_file, var);
+ fprintf (dump_file, "\n");
+ }
+ }
+ else if (DECL_NOT_GIMPLE_REG_P (var))
+ {
+ maybe_reg = true;
+ DECL_NOT_GIMPLE_REG_P (var) = 0;
+ }
+ if (maybe_reg && is_gimple_reg (var))
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Now a gimple register: ");
+ print_generic_expr (dump_file, var);
+ fprintf (dump_file, "\n");
+ }
+ bitmap_set_bit (suitable_for_renaming, DECL_UID (var));
}
}
}
return false;
}
-/* Compute TREE_ADDRESSABLE and DECL_GIMPLE_REG_P for local variables. */
+/* Compute TREE_ADDRESSABLE and whether we have unhandled partial defs
+ for local variables. */
void
execute_update_addresses_taken (void)
&& bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
&& VECTOR_TYPE_P (TREE_TYPE (sym))
&& TYPE_MODE (TREE_TYPE (sym)) != BLKmode
+ /* If it is a full replacement we can do better below. */
+ && maybe_ne (wi::to_poly_offset
+ (TYPE_SIZE_UNIT (TREE_TYPE (lhs))),
+ wi::to_poly_offset
+ (TYPE_SIZE_UNIT (TREE_TYPE (sym))))
&& known_ge (mem_ref_offset (lhs), 0)
&& known_gt (wi::to_poly_offset
(TYPE_SIZE_UNIT (TREE_TYPE (sym))),
(TYPE_SIZE (TREE_TYPE
(TREE_TYPE (sym)))),
&nelts)
- && maybe_ne (nelts, 1u))
+ && maybe_ne (nelts, 1u)
+ && valid_vector_subparts_p (nelts))
temtype = build_vector_type (temtype, nelts);
tree tem = make_ssa_name (temtype);
gimple *pun
/* In ASAN_MARK (UNPOISON, &b, ...) the variable
is uninitialized. Avoid dependencies on
previous out of scope value. */
- tree clobber
- = build_constructor (TREE_TYPE (var), NULL);
- TREE_THIS_VOLATILE (clobber) = 1;
+ tree clobber = build_clobber (TREE_TYPE (var));
gimple *g = gimple_build_assign (var, clobber);
gsi_replace (&gsi, g, GSI_SAME_STMT);
}