+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * gimplify.h (get_initialized_tmp_var): Add allow_ssa parameter
+ default true.
+ (gimplify_arg): Likewise.
+ * gimplify.c (gimplify_expr): Add overload with allow_ssa parameter,
+ re-writing the result to a decl if required.
+ (internal_get_tmp_var): Add allow_ssa parameter
+ and override into_ssa with it.
+ (get_formal_tmp_var): Adjust.
+ (get_initialized_tmp_var): Add allow_ssa parameter.
+ (gimplify_arg): Add allow_ssa parameter and avoid generating
+ SSA names for the result false.
+ (gimplify_call_expr): If the call may return twice do not
+ gimplify parameters into SSA.
+ (prepare_gimple_addressable): Do not allow an SSA name as
+ temporary.
+ (gimplify_modify_expr): Adjust assert. For noreturn calls
+ with a SSA name LHS adjust its def.
+ (gimplify_save_expr): Do not allow an SSA name as save-expr
+ result.
+ (gimplify_one_sizepos): Do not allow an SSA name as a sizepos.
+ (gimplify_body): Init GIMPLE SSA data structures and gimplify
+ into-SSA.
+ (gimplify_scan_omp_clauses): Make sure OMP_CLAUSE_SIZE is not
+ an SSA name. Likewise for OMP_CLAUSE_REDUCTION operands.
+ (gimplify_omp_for): Likewise for OMP_CLAUSE_DECL. Likewise
+ for OMP_FOR_COND, OMP_FOR_INCR and OMP_CLAUSE_LINEAR_STEP.
+ (optimize_target_teams): Do not allow SSA names for clause operands.
+ (gimplify_expr): Likewise for where we mark the result addressable.
+ * passes.def (pass_init_datastructures): Remove.
+ * tree-into-ssa.c (mark_def_sites): Ignore existing SSA names.
+ (rewrite_stmt): Likewise.
+ * tree-inline.c (initialize_cfun): Properly transfer SSA state.
+ (replace_locals_op): Replace SSA names.
+ (copy_gimple_seq_and_replace_locals): Init src_cfun.
+ * gimple-low.c (lower_builtin_setjmp): Deal with SSA.
+ * cgraph.c (release_function_body): Free CFG annotations only
+ when we have a CFG. Simplify.
+ * gimple-fold.c (gimplify_and_update_call_from_tree): Use
+ force_gimple_operand instead of get_initialized_tmp_var.
+ * tree-pass.h (make_pass_init_datastructures): Remove.
+ * tree-ssa.c (execute_init_datastructures): Remove.
+ (pass_data_init_datastructures): Likewise.
+ (class pass_init_datastructures): Likewise.
+ (make_pass_init_datastructures): Likewise.
+ * omp-low.c (create_omp_child_function): Init SSA data structures.
+ (grid_expand_target_grid_body): Likewise.
+ * tree-cfg.c (move_block_to_fn): Double-check the DEF is an SSA
+ name before adding it to names_to_release.
+ (remove_bb): Always release SSA defs.
+ * tree-ssa-ccp.c (get_default_value): Check SSA_NAME_VAR
+ before dereferencing it.
+ * cgraphunit.c (init_lowered_empty_function): Always
+ int SSA data structures.
+ * tree-ssanames.c (release_defs): Remove assert that we are in
+ SSA form.
+ * trans-mem.c (diagnose_tm_1): Handle SSA name function.
+
2016-05-03 Jakub Jelinek <jakub@redhat.com>
Uros Bizjak <ubizjak@gmail.com>
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * cilk.c (cilk_gimplify_call_params_in_spawned_fn): Do not
+ allow call args to gimplify to SSA names.
+
2016-05-03 Marek Polacek <polacek@redhat.com>
* c-common.h (enum c_omp_region_type): Remove stray comma.
fix_parm_expr = &TREE_OPERAND (*expr_p, 1);
if (TREE_CODE (*fix_parm_expr) == CALL_EXPR)
- for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
- gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
- EXPR_LOCATION (*fix_parm_expr));
+ {
+ /* Cilk outlining assumes GENERIC bodies, avoid leaking SSA names
+ via parameters. */
+ for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
+ gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
+ EXPR_LOCATION (*fix_parm_expr), false);
+ }
}
if (fn)
{
if (fn->cfg
- || fn->gimple_df)
+ && loops_for_fn (fn))
{
- if (fn->cfg
- && loops_for_fn (fn))
- {
- fn->curr_properties &= ~PROP_loops;
- loop_optimizer_finalize (fn);
- }
- if (fn->gimple_df)
- {
- delete_tree_ssa (fn);
- delete_tree_cfg_annotations (fn);
- fn->eh = NULL;
- }
- if (fn->cfg)
- {
- gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
- gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
- clear_edges (fn);
- fn->cfg = NULL;
- }
- if (fn->value_histograms)
- free_histograms (fn);
+ fn->curr_properties &= ~PROP_loops;
+ loop_optimizer_finalize (fn);
+ }
+ if (fn->gimple_df)
+ {
+ delete_tree_ssa (fn);
+ fn->eh = NULL;
+ }
+ if (fn->cfg)
+ {
+ gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
+ gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
+ delete_tree_cfg_annotations (fn);
+ clear_edges (fn);
+ fn->cfg = NULL;
}
+ if (fn->value_histograms)
+ free_histograms (fn);
gimple_set_body (decl, NULL);
/* Struct function hangs a lot of data that would leak if we didn't
removed all pointers to it. */
allocate_struct_function (decl, false);
gimple_register_cfg_hooks ();
init_empty_tree_cfg ();
+ init_tree_ssa (cfun);
if (in_ssa)
{
- init_tree_ssa (cfun);
init_ssa_operands (cfun);
cfun->gimple_df->in_ssa_p = true;
cfun->curr_properties |= PROP_ssa;
}
else
{
- tree tmp = get_initialized_tmp_var (expr, &stmts, NULL);
+ tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
new_stmt = gimple_build_assign (lhs, tmp);
i = gsi_last (stmts);
gsi_insert_after_without_update (&i, new_stmt,
passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
FORCED_LABEL (next_label) = 1;
- dest = gimple_call_lhs (stmt);
+ tree orig_dest = dest = gimple_call_lhs (stmt);
+ if (orig_dest && TREE_CODE (orig_dest) == SSA_NAME)
+ dest = create_tmp_reg (TREE_TYPE (orig_dest));
/* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
arg = build_addr (next_label);
g = gimple_build_label (cont_label);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ /* Build orig_dest = dest if necessary. */
+ if (dest != orig_dest)
+ {
+ g = gimple_build_assign (orig_dest, dest);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ }
+
/* Remove the call to __builtin_setjmp. */
gsi_remove (gsi, false);
}
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
static hash_map<tree, tree> *oacc_declare_returns;
+static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ bool (*) (tree), fallback_t, bool);
/* Shorter alias name for the above function for use in gimplify.c
only. */
static tree
internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
- bool is_formal)
+ bool is_formal, bool allow_ssa)
{
tree t, mod;
gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
fb_rvalue);
- if (gimplify_ctxp->into_ssa
+ if (allow_ssa
+ && gimplify_ctxp->into_ssa
&& is_gimple_reg_type (TREE_TYPE (val)))
- t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
+ {
+ t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
+ if (! gimple_in_ssa_p (cfun))
+ {
+ const char *name = get_name (val);
+ if (name)
+ SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
+ }
+ }
else
t = lookup_tmp_var (val, is_formal);
tree
get_formal_tmp_var (tree val, gimple_seq *pre_p)
{
- return internal_get_tmp_var (val, pre_p, NULL, true);
+ return internal_get_tmp_var (val, pre_p, NULL, true, true);
}
/* Return a temporary variable initialized with VAL. PRE_P and POST_P
are as in gimplify_expr. */
tree
-get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p)
+get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
+ bool allow_ssa)
{
- return internal_get_tmp_var (val, pre_p, post_p, false);
+ return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
}
/* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
/* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
Store any side-effects in PRE_P. CALL_LOCATION is the location of
- the CALL_EXPR. */
+ the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
+ gimplified to an SSA name. */
enum gimplify_status
-gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
+gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
+ bool allow_ssa)
{
bool (*test) (tree);
fallback_t fb;
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
post queue which is then appended to the end of PRE_P. */
- return gimplify_expr (arg_p, pre_p, NULL, test, fb);
+ return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
}
/* Don't fold inside offloading or taskreg regions: it can break code by
}
}
+ /* If the call returns twice then after building the CFG the call
+ argument computations will no longer dominate the call because
+ we add an abnormal incoming edge to the call. So do not use SSA
+ vars there. */
+ bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
+
/* Gimplify the function arguments. */
if (nargs > 0)
{
if ((i != 1) || !builtin_va_start_p)
{
t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
- EXPR_LOCATION (*expr_p));
+ EXPR_LOCATION (*expr_p), ! returns_twice);
if (t == GS_ERROR)
ret = GS_ERROR;
{
enum gimplify_status t;
t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
- EXPR_LOCATION (*expr_p));
+ EXPR_LOCATION (*expr_p), ! returns_twice);
if (t == GS_ERROR)
ret = GS_ERROR;
}
expr_p = &TREE_OPERAND (*expr_p, 0);
if (is_gimple_reg (*expr_p))
{
- tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL);
+ /* Do not allow an SSA name as the temporary. */
+ tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
DECL_GIMPLE_REG_P (var) = 0;
*expr_p = var;
}
|| TREE_ADDRESSABLE (TREE_TYPE (*to_p))
|| TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
gimple_call_set_lhs (call_stmt, *to_p);
+ else if (TREE_CODE (*to_p) == SSA_NAME)
+ /* The above is somewhat premature, avoid ICEing later for a
+ SSA name w/o a definition. We may have uses in the GIMPLE IL.
+ ??? This doesn't make it a default-def. */
+ SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
assign = call_stmt;
}
else
if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
{
/* We should have got an SSA name from the start. */
- gcc_assert (TREE_CODE (*to_p) == SSA_NAME);
+ gcc_assert (TREE_CODE (*to_p) == SSA_NAME
+ || ! gimple_in_ssa_p (cfun));
}
gimplify_seq_add_stmt (pre_p, assign);
val = NULL;
}
else
- val = get_initialized_tmp_var (val, pre_p, post_p);
+ /* The temporary may not be an SSA name as later abnormal and EH
+ control flow may invalidate use/def domination. */
+ val = get_initialized_tmp_var (val, pre_p, post_p, false);
TREE_OPERAND (*expr_p, 0) = val;
SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
{
tree type = TREE_TYPE (decl);
if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
- NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
+ NULL, is_gimple_val, fb_rvalue, false)
+ == GS_ERROR)
{
remove = true;
break;
if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
{
if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
- NULL, is_gimple_val, fb_rvalue)
+ NULL, is_gimple_val, fb_rvalue, false)
== GS_ERROR)
{
remove = true;
&& TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
{
OMP_CLAUSE_SIZE (c)
- = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL);
+ = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
+ false);
omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
GOVD_FIRSTPRIVATE | GOVD_SEEN);
}
{
TREE_OPERAND (t, 1)
= get_initialized_tmp_var (TREE_OPERAND (t, 1),
- pre_p, NULL);
+ pre_p, NULL, false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
TREE_OPERAND (t, 1)
= get_initialized_tmp_var (TREE_OPERAND (t, 1),
gimple_seq_empty_p (for_pre_body)
- ? pre_p : &for_pre_body, NULL);
+ ? pre_p : &for_pre_body, NULL,
+ false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
{
gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
? pre_p : &for_pre_body;
- *tp = get_initialized_tmp_var (*tp, seq, NULL);
+ *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = *tp;
var = decl;
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
if (ret == GS_ERROR)
return ret;
gcc_assert (TREE_OPERAND (t, 0) == decl);
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
/* Handle OMP_FOR_INCR. */
}
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
if (c)
{
{
tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
&for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
}
}
}
*p = expr;
gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
- if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue)
+ if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
== GS_ERROR)
{
gimplify_omp_ctxp = target_ctx;
required. */
if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
required. */
if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
required. */
else if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
return ret;
}
+/* Like gimplify_expr but make sure the gimplified result is not itself
+ a SSA name (but a decl if it were). Temporaries required by
+ evaluating *EXPR_P may be still SSA names. */
+
+static enum gimplify_status
+gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool (*gimple_test_f) (tree), fallback_t fallback,
+ bool allow_ssa)
+{
+ bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
+ enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
+ gimple_test_f, fallback);
+ if (! allow_ssa
+ && TREE_CODE (*expr_p) == SSA_NAME)
+ {
+ tree name = *expr_p;
+ if (was_ssa_name_p)
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
+ else
+ {
+ /* Avoid the extra copy if possible. */
+ *expr_p = create_tmp_reg (TREE_TYPE (name));
+ gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
+ release_ssa_name (name);
+ }
+ }
+ return ret;
+}
+
/* Look through TYPE for variable-sized objects and gimplify each such
size that we find. Add to LIST_P any statements generated. */
*expr_p = unshare_expr (expr);
- gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
+ /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
+ if the def vanishes. */
+ gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
}
/* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
timevar_push (TV_TREE_GIMPLIFY);
+ init_tree_ssa (cfun);
+
/* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
gimplification. */
default_rtl_profile ();
gcc_assert (gimplify_ctxp == NULL);
- push_gimplify_context ();
+ push_gimplify_context (true);
if (flag_openacc || flag_openmp)
{
extern vec<gbind *> gimple_bind_expr_stack (void);
extern void gimplify_and_add (tree, gimple_seq *);
extern tree get_formal_tmp_var (tree, gimple_seq *);
-extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *,
+ bool = true);
extern void declare_vars (tree, gimple *, bool);
extern void gimple_add_tmp_var (tree);
extern void gimple_add_tmp_var_fn (struct function *, tree);
extern void gimplify_type_sizes (tree, gimple_seq *);
extern void gimplify_one_sizepos (tree *, gimple_seq *);
extern gbind *gimplify_body (tree, bool);
-extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t);
+extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t,
+ bool = true);
extern void gimplify_function_tree (tree);
extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
gimple_seq *);
it afterward. */
push_struct_function (decl);
cfun->function_end_locus = gimple_location (ctx->stmt);
+ init_tree_ssa (cfun);
pop_cfun ();
}
DECL_INITIAL (kern_fndecl) = fniniblock;
push_struct_function (kern_fndecl);
cfun->function_end_locus = gimple_location (tgt_stmt);
+ init_tree_ssa (cfun);
pop_cfun ();
tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl);
NEXT_PASS (pass_build_ssa_passes);
PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes)
NEXT_PASS (pass_fixup_cfg);
- NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_warn_nonnull_compare);
NEXT_PASS (pass_ubsan);
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/pr30172-1.c: Adjust.
+ * gcc.dg/pr63743.c: Likewise.
+ * gcc.dg/tm/pr51696.c: Likewise.
+ * c-c++-common/tm/safe-1.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-3.c: Likewise.
+ * gcc.dg/plugin/self-assign-test-1.c: XFAIL case that needs CSE.
+ * g++.dg/plugin/self-assign-test-1.C: Likewise.
+ * g++.dg/plugin/self-assign-test-2.C: Likewise.
+
2016-05-03 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/70467
/* tu(); */
(*ps)();
- (*pc)(); /* { dg-error "unsafe function call" } */
- (*pi)(); /* { dg-error "unsafe function call" } */
- (*pu)(); /* { dg-error "unsafe function call" } */
+ (*pc)(); /* { dg-error "unsafe indirect function call" } */
+ (*pi)(); /* { dg-error "unsafe indirect function call" } */
+ (*pu)(); /* { dg-error "unsafe indirect function call" } */
asm(""); /* { dg-error "asm not allowed" } */
asm("" : "=g"(i)); /* { dg-error "asm not allowed" } */
tm();
(*ps)();
- (*pc)(); /* { dg-error "unsafe function call" } */
- (*pi)(); /* { dg-error "unsafe function call" } */
+ (*pc)(); /* { dg-error "unsafe indirect function call" } */
+ (*pi)(); /* { dg-error "unsafe indirect function call" } */
(*pm)();
- (*pu)(); /* { dg-error "unsafe function call" } */
+ (*pu)(); /* { dg-error "unsafe indirect function call" } */
asm(""); /* { dg-error "asm not allowed" } */
asm("" : "=g"(i)); /* { dg-error "asm not allowed" } */
foo = foo; // { dg-warning "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
- bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
+ bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" "" { xfail *-*-* } }
y = x;
x = y;
}
foo = foo; // { dg-bogus "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
- bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
+ bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" "" { xfail *-*-* } }
y = x;
x = y;
}
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-ccp1" } */
+/* { dg-options "-O -fdump-tree-fre1" } */
typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
*f = __builtin_shuffle (*f, *g, n);
}
-/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "ccp1" } } */
-/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "ccp1" } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "ccp1" } } */
+/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "fre1" } } */
+/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "fre1" } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "fre1" } } */
static int y;
struct Bar b_array[5];
- b_array[x+g].b_ = b_array[x+g].b_; /* { dg-warning "self-assignment detected" } */
+ b_array[x+g].b_ = b_array[x+g].b_; /* { dg-warning "self-assignment detected" "" { xfail *-*-* } } */
g = g; /* { dg-warning "assigned to itself" } */
y = y; /* { dg-warning "assigned to itself" } */
bar->b_ = bar->b_; /* { dg-warning "assigned to itself" } */
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, 1.0e\\+0>" "gimple" } } */
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <1.0e\\+0, x>" "gimple" } } */
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, y>" "gimple" } } */
-/* { dg-final { scan-tree-dump "D.* = -y;\n.*COMPLEX_EXPR <D.*, x>" "gimple" } } */
-/* { dg-final { scan-tree-dump "D.* = -x;\n.*COMPLEX_EXPR <y, D.*>" "gimple" } } */
+/* { dg-final { scan-tree-dump " = -y;\n.*COMPLEX_EXPR <\[^,\]*, x>" "gimple" } } */
+/* { dg-final { scan-tree-dump " = -x;\n.*COMPLEX_EXPR <y, " "gimple" } } */
double
libcall_dep (double x, double y)
{
- return x * (x + y);
+ double tem = x + y;
+ return x * tem;
}
/* { dg-final { scan-rtl-dump-times "Swap operands" 1 "expand" } } */
__attribute__((transaction_safe))
static void func () {
listPtr->compare(); /* { dg-error "unsafe indirect function call" } */
- compare(); /* { dg-error "unsafe function call" } */
+ compare(); /* { dg-error "unsafe indirect function call" } */
}
/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "profile" } } */
/* This is part of code checking that n is greater than the divisor so we are sure that it
didn't get optimized out. */
-/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */
+/* { dg-final-use { scan-tree-dump "if \\(_\[0-9\]* \\< n_\[0-9\]*" "optimized"} } */
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
the negated code == 22 compare to code != 22 first. It turns out if
we do that we even generate better code on x86 at least. */
-/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* <" 4 "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* \[<>\]" 4 "forwprop1"} } */
/* PR tree-optimization/64193 */
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre1-details" } */
+/* { dg-options "-O -fdump-tree-fre1" } */
double T,T2,E1[5];
int J;
/* We should remove 15 dead loads and some related stmts, fully propagating
their replacements with exactly 4 loads and 4 stores from/to E remaining. */
-/* { dg-final { scan-tree-dump-times "Removing dead stmt" 19 "fre1" } } */
-/* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */
+/* { dg-final { scan-tree-dump-times "MEM" 8 "fre1" } } */
"atomic transaction", fn);
else
{
- if (!DECL_P (fn) || DECL_NAME (fn))
+ if ((!DECL_P (fn) || DECL_NAME (fn))
+ && TREE_CODE (fn) != SSA_NAME)
error_at (gimple_location (stmt),
"unsafe function call %qE within "
"atomic transaction", fn);
"%<transaction_safe%> function", fn);
else
{
- if (!DECL_P (fn) || DECL_NAME (fn))
+ if ((!DECL_P (fn) || DECL_NAME (fn))
+ && TREE_CODE (fn) != SSA_NAME)
error_at (gimple_location (stmt),
"unsafe function call %qE within "
"%<transaction_safe%> function", fn);
}
else
{
- /* Release SSA definitions if we are in SSA. Note that we
- may be called when not in SSA. For example,
- final_cleanup calls this function via
- cleanup_tree_cfg. */
- if (gimple_in_ssa_p (cfun))
- release_defs (stmt);
-
+ /* Release SSA definitions. */
+ release_defs (stmt);
gsi_remove (&i, true);
}
if (src_cfun->gimple_df)
{
init_tree_ssa (cfun);
- cfun->gimple_df->in_ssa_p = true;
- init_ssa_operands (cfun);
+ cfun->gimple_df->in_ssa_p = src_cfun->gimple_df->in_ssa_p;
+ if (cfun->gimple_df->in_ssa_p)
+ init_ssa_operands (cfun);
}
}
tree *n;
tree expr = *tp;
+ /* For recursive invocations this is no longer the LHS itself. */
+ bool is_lhs = wi->is_lhs;
+ wi->is_lhs = false;
+
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ *tp = remap_ssa_name (*tp, id);
+ *walk_subtrees = 0;
+ if (is_lhs)
+ SSA_NAME_DEF_STMT (*tp) = gsi_stmt (wi->gsi);
+ }
/* Only a local declaration (variable or label). */
- if ((TREE_CODE (expr) == VAR_DECL
- && !TREE_STATIC (expr))
- || TREE_CODE (expr) == LABEL_DECL)
+ else if ((TREE_CODE (expr) == VAR_DECL
+ && !TREE_STATIC (expr))
+ || TREE_CODE (expr) == LABEL_DECL)
{
/* Lookup the declaration. */
n = st->get (expr);
memset (&id, 0, sizeof (id));
id.src_fn = current_function_decl;
id.dst_fn = current_function_decl;
+ id.src_cfun = cfun;
id.decl_map = new hash_map<tree, tree>;
id.debug_map = NULL;
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
{
tree sym = USE_FROM_PTR (use_p);
+ if (TREE_CODE (sym) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (sym));
if (!bitmap_bit_p (kills, DECL_UID (sym)))
set_livein_block (sym, bb);
each def to the set of killed symbols. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
{
+ if (TREE_CODE (def) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (def));
set_def_block (def, bb, false);
bitmap_set_bit (kills, DECL_UID (def));
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
{
tree var = USE_FROM_PTR (use_p);
+ if (TREE_CODE (var) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (var));
SET_USE (use_p, get_reaching_def (var));
}
tree name;
tree tracked_var;
+ if (TREE_CODE (var) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (var));
if (gimple_clobber_p (stmt)
extern gimple_opt_pass *make_pass_cleanup_cfg_post_optimizing (gcc::context
*ctxt);
-extern gimple_opt_pass *make_pass_init_datastructures (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_fixup_cfg (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_backprop (gcc::context *ctxt);
can assume initially that it is UNDEFINED, otherwise we must
consider it VARYING. */
if (!virtual_operand_p (var)
+ && SSA_NAME_VAR (var)
&& TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
val.lattice_val = UNDEFINED;
else
init_ssanames (fn, 0);
}
-/* Do the actions required to initialize internal data structures used
- in tree-ssa optimization passes. */
-
-static unsigned int
-execute_init_datastructures (void)
-{
- /* Allocate hash tables, arrays and other structures. */
- gcc_assert (!cfun->gimple_df);
- init_tree_ssa (cfun);
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_init_datastructures =
-{
- GIMPLE_PASS, /* type */
- "*init_datastructures", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_init_datastructures : public gimple_opt_pass
-{
-public:
- pass_init_datastructures (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_init_datastructures, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *fun)
- {
- /* Do nothing for funcions that was produced already in SSA form. */
- return !(fun->curr_properties & PROP_ssa);
- }
-
- virtual unsigned int execute (function *)
- {
- return execute_init_datastructures ();
- }
-
-}; // class pass_init_datastructures
-
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_init_datastructures (gcc::context *ctxt)
-{
- return new pass_init_datastructures (ctxt);
-}
-
/* Deallocate memory associated with SSA data structures for FNDECL. */
void
tree def;
ssa_op_iter iter;
- /* Make sure that we are in SSA. Otherwise, operand cache may point
- to garbage. */
- gcc_assert (gimple_in_ssa_p (cfun));
-
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
if (TREE_CODE (def) == SSA_NAME)
release_ssa_name (def);