summaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c335
1 files changed, 234 insertions, 101 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index b6b6d6e12e..bfaaede0c3 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1,5 +1,5 @@
/* Tree inlining.
- Copyright (C) 2001-2016 Free Software Foundation, Inc.
+ Copyright (C) 2001-2017 Free Software Foundation, Inc.
Contributed by Alexandre Oliva <aoliva@redhat.com>
This file is part of GCC.
@@ -163,7 +163,7 @@ insert_debug_decl_map (copy_body_data *id, tree key, tree value)
return;
gcc_assert (TREE_CODE (key) == PARM_DECL);
- gcc_assert (TREE_CODE (value) == VAR_DECL);
+ gcc_assert (VAR_P (value));
if (!id->debug_map)
id->debug_map = new hash_map<tree, tree>;
@@ -214,7 +214,7 @@ remap_ssa_name (tree name, copy_body_data *id)
def_temp = gimple_build_debug_source_bind (vexpr, val, NULL);
DECL_ARTIFICIAL (vexpr) = 1;
TREE_TYPE (vexpr) = TREE_TYPE (name);
- DECL_MODE (vexpr) = DECL_MODE (SSA_NAME_VAR (name));
+ SET_DECL_MODE (vexpr, DECL_MODE (SSA_NAME_VAR (name)));
gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
return vexpr;
@@ -228,7 +228,7 @@ remap_ssa_name (tree name, copy_body_data *id)
var = SSA_NAME_VAR (name);
if (!var
|| (!SSA_NAME_IS_DEFAULT_DEF (name)
- && TREE_CODE (var) == VAR_DECL
+ && VAR_P (var)
&& !VAR_DECL_IS_VIRTUAL_OPERAND (var)
&& DECL_ARTIFICIAL (var)
&& DECL_IGNORED_P (var)
@@ -244,6 +244,7 @@ remap_ssa_name (tree name, copy_body_data *id)
/* At least IPA points-to info can be directly transferred. */
if (id->src_cfun->gimple_df
&& id->src_cfun->gimple_df->ipa_pta
+ && POINTER_TYPE_P (TREE_TYPE (name))
&& (pi = SSA_NAME_PTR_INFO (name))
&& !pi->pt.anything)
{
@@ -263,7 +264,7 @@ remap_ssa_name (tree name, copy_body_data *id)
Replace the SSA name representing RESULT_DECL by variable during
inlining: this saves us from need to introduce PHI node in a case
return value is just partly initialized. */
- if ((TREE_CODE (new_tree) == VAR_DECL || TREE_CODE (new_tree) == PARM_DECL)
+ if ((VAR_P (new_tree) || TREE_CODE (new_tree) == PARM_DECL)
&& (!SSA_NAME_VAR (name)
|| TREE_CODE (SSA_NAME_VAR (name)) != RESULT_DECL
|| !id->transform_return_to_modify))
@@ -276,6 +277,7 @@ remap_ssa_name (tree name, copy_body_data *id)
/* At least IPA points-to info can be directly transferred. */
if (id->src_cfun->gimple_df
&& id->src_cfun->gimple_df->ipa_pta
+ && POINTER_TYPE_P (TREE_TYPE (name))
&& (pi = SSA_NAME_PTR_INFO (name))
&& !pi->pt.anything)
{
@@ -367,7 +369,20 @@ remap_decl (tree decl, copy_body_data *id)
/* Remap types, if necessary. */
TREE_TYPE (t) = remap_type (TREE_TYPE (t), id);
if (TREE_CODE (t) == TYPE_DECL)
- DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id);
+ {
+ DECL_ORIGINAL_TYPE (t) = remap_type (DECL_ORIGINAL_TYPE (t), id);
+
+ /* Preserve the invariant that DECL_ORIGINAL_TYPE != TREE_TYPE,
+ which is enforced in gen_typedef_die when DECL_ABSTRACT_ORIGIN
+ is not set on the TYPE_DECL, for example in LTO mode. */
+ if (DECL_ORIGINAL_TYPE (t) == TREE_TYPE (t))
+ {
+ tree x = build_variant_type_copy (TREE_TYPE (t));
+ TYPE_STUB_DECL (x) = TYPE_STUB_DECL (TREE_TYPE (t));
+ TYPE_NAME (x) = TYPE_NAME (TREE_TYPE (t));
+ DECL_ORIGINAL_TYPE (t) = x;
+ }
+ }
/* Remap sizes as necessary. */
walk_tree (&DECL_SIZE (t), copy_tree_body_r, id, NULL);
@@ -592,8 +607,7 @@ can_be_nonlocal (tree decl, copy_body_data *id)
/* Local static vars must be non-local or we get multiple declaration
problems. */
- if (TREE_CODE (decl) == VAR_DECL
- && !auto_var_in_fn_p (decl, id->src_fn))
+ if (VAR_P (decl) && !auto_var_in_fn_p (decl, id->src_fn))
return true;
return false;
@@ -615,9 +629,7 @@ remap_decls (tree decls, vec<tree, va_gc> **nonlocalized_list,
{
/* We need to add this variable to the local decls as otherwise
nothing else will do so. */
- if (TREE_CODE (old_var) == VAR_DECL
- && ! DECL_EXTERNAL (old_var)
- && cfun)
+ if (VAR_P (old_var) && ! DECL_EXTERNAL (old_var) && cfun)
add_local_decl (cfun, old_var);
if ((!optimize || debug_info_level > DINFO_LEVEL_TERSE)
&& !DECL_IGNORED_P (old_var)
@@ -649,8 +661,7 @@ remap_decls (tree decls, vec<tree, va_gc> **nonlocalized_list,
new_decls = new_var;
/* Also copy value-expressions. */
- if (TREE_CODE (new_var) == VAR_DECL
- && DECL_HAS_VALUE_EXPR_P (new_var))
+ if (VAR_P (new_var) && DECL_HAS_VALUE_EXPR_P (new_var))
{
tree tem = DECL_VALUE_EXPR (new_var);
bool old_regimplify = id->regimplify;
@@ -863,10 +874,16 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
copy_body_data *id = (copy_body_data *) wi_p->info;
tree fn = id->src_fn;
+ /* For recursive invocations this is no longer the LHS itself. */
+ bool is_lhs = wi_p->is_lhs;
+ wi_p->is_lhs = false;
+
if (TREE_CODE (*tp) == SSA_NAME)
{
*tp = remap_ssa_name (*tp, id);
*walk_subtrees = 0;
+ if (is_lhs)
+ SSA_NAME_DEF_STMT (*tp) = wi_p->stmt;
return NULL;
}
else if (auto_var_in_fn_p (*tp, fn))
@@ -1623,11 +1640,19 @@ remap_gimple_stmt (gimple *stmt, copy_body_data *id)
gimple_call_set_tail (call_stmt, false);
if (gimple_call_from_thunk_p (call_stmt))
gimple_call_set_from_thunk (call_stmt, false);
- if (gimple_call_internal_p (call_stmt)
- && IN_RANGE (gimple_call_internal_fn (call_stmt),
- IFN_GOMP_SIMD_ORDERED_START,
- IFN_GOMP_SIMD_ORDERED_END))
- DECL_STRUCT_FUNCTION (id->dst_fn)->has_simduid_loops = true;
+ if (gimple_call_internal_p (call_stmt))
+ switch (gimple_call_internal_fn (call_stmt))
+ {
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ case IFN_GOMP_SIMD_ORDERED_START:
+ case IFN_GOMP_SIMD_ORDERED_END:
+ DECL_STRUCT_FUNCTION (id->dst_fn)->has_simduid_loops = true;
+ break;
+ default:
+ break;
+ }
}
/* Remap the region numbers for __builtin_eh_{pointer,filter},
@@ -1835,7 +1860,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
call_stmt = dyn_cast <gcall *> (stmt);
if (call_stmt
&& gimple_call_va_arg_pack_p (call_stmt)
- && id->call_stmt)
+ && id->call_stmt
+ && ! gimple_call_va_arg_pack_p (id->call_stmt))
{
/* __builtin_va_arg_pack () should be replaced by
all arguments corresponding to ... in the caller. */
@@ -1915,7 +1941,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
&& id->call_stmt
&& (decl = gimple_call_fndecl (stmt))
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN)
+ && DECL_FUNCTION_CODE (decl) == BUILT_IN_VA_ARG_PACK_LEN
+ && ! gimple_call_va_arg_pack_p (id->call_stmt))
{
/* __builtin_va_arg_pack_len () should be replaced by
the number of anonymous arguments. */
@@ -2057,7 +2084,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
&& id->dst_node->definition
&& (fn = gimple_call_fndecl (stmt)) != NULL)
{
- struct cgraph_node *dest = cgraph_node::get (fn);
+ struct cgraph_node *dest = cgraph_node::get_create (fn);
/* We have missing edge in the callgraph. This can happen
when previous inlining turned an indirect call into a
@@ -2095,16 +2122,6 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt,
id->eh_map, id->eh_lp_nr);
- if (gimple_in_ssa_p (cfun) && !is_gimple_debug (stmt))
- {
- ssa_op_iter i;
- tree def;
-
- FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
- if (TREE_CODE (def) == SSA_NAME)
- SSA_NAME_DEF_STMT (def) = stmt;
- }
-
gsi_next (&copy_gsi);
}
while (!gsi_end_p (copy_gsi));
@@ -2327,50 +2344,60 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
if (!virtual_operand_p (res))
{
walk_tree (&new_res, copy_tree_body_r, id, NULL);
- new_phi = create_phi_node (new_res, new_bb);
- FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
+ if (EDGE_COUNT (new_bb->preds) == 0)
{
- edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
- tree arg;
- tree new_arg;
- edge_iterator ei2;
- location_t locus;
-
- /* When doing partial cloning, we allow PHIs on the entry block
- as long as all the arguments are the same. Find any input
- edge to see argument to copy. */
- if (!old_edge)
- FOR_EACH_EDGE (old_edge, ei2, bb->preds)
- if (!old_edge->src->aux)
- break;
-
- arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
- new_arg = arg;
- walk_tree (&new_arg, copy_tree_body_r, id, NULL);
- gcc_assert (new_arg);
- /* With return slot optimization we can end up with
- non-gimple (foo *)&this->m, fix that here. */
- if (TREE_CODE (new_arg) != SSA_NAME
- && TREE_CODE (new_arg) != FUNCTION_DECL
- && !is_gimple_val (new_arg))
- {
- gimple_seq stmts = NULL;
- new_arg = force_gimple_operand (new_arg, &stmts, true, NULL);
- gsi_insert_seq_on_edge (new_edge, stmts);
- inserted = true;
- }
- locus = gimple_phi_arg_location_from_edge (phi, old_edge);
- if (LOCATION_BLOCK (locus))
+ /* Technically we'd want a SSA_DEFAULT_DEF here... */
+ SSA_NAME_DEF_STMT (new_res) = gimple_build_nop ();
+ }
+ else
+ {
+ new_phi = create_phi_node (new_res, new_bb);
+ FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
{
- tree *n;
- n = id->decl_map->get (LOCATION_BLOCK (locus));
- gcc_assert (n);
- locus = set_block (locus, *n);
- }
- else
- locus = LOCATION_LOCUS (locus);
+ edge old_edge = find_edge ((basic_block) new_edge->src->aux,
+ bb);
+ tree arg;
+ tree new_arg;
+ edge_iterator ei2;
+ location_t locus;
+
+ /* When doing partial cloning, we allow PHIs on the entry
+ block as long as all the arguments are the same.
+ Find any input edge to see argument to copy. */
+ if (!old_edge)
+ FOR_EACH_EDGE (old_edge, ei2, bb->preds)
+ if (!old_edge->src->aux)
+ break;
+
+ arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
+ new_arg = arg;
+ walk_tree (&new_arg, copy_tree_body_r, id, NULL);
+ gcc_assert (new_arg);
+ /* With return slot optimization we can end up with
+ non-gimple (foo *)&this->m, fix that here. */
+ if (TREE_CODE (new_arg) != SSA_NAME
+ && TREE_CODE (new_arg) != FUNCTION_DECL
+ && !is_gimple_val (new_arg))
+ {
+ gimple_seq stmts = NULL;
+ new_arg = force_gimple_operand (new_arg, &stmts, true,
+ NULL);
+ gsi_insert_seq_on_edge (new_edge, stmts);
+ inserted = true;
+ }
+ locus = gimple_phi_arg_location_from_edge (phi, old_edge);
+ if (LOCATION_BLOCK (locus))
+ {
+ tree *n;
+ n = id->decl_map->get (LOCATION_BLOCK (locus));
+ gcc_assert (n);
+ locus = set_block (locus, *n);
+ }
+ else
+ locus = LOCATION_LOCUS (locus);
- add_phi_arg (new_phi, new_arg, new_edge, locus);
+ add_phi_arg (new_phi, new_arg, new_edge, locus);
+ }
}
}
}
@@ -2460,8 +2487,9 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
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);
}
}
@@ -2856,12 +2884,10 @@ copy_debug_stmt (gdebug *stmt, copy_body_data *id)
if (TREE_CODE (t) == PARM_DECL && id->debug_map
&& (n = id->debug_map->get (t)))
{
- gcc_assert (TREE_CODE (*n) == VAR_DECL);
+ gcc_assert (VAR_P (*n));
t = *n;
}
- else if (TREE_CODE (t) == VAR_DECL
- && !is_global_var (t)
- && !id->decl_map->get (t))
+ else if (VAR_P (t) && !is_global_var (t) && !id->decl_map->get (t))
/* T is a non-localized variable. */;
else
walk_tree (&t, remap_gimple_op_r, &wi, NULL);
@@ -3257,8 +3283,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple *stmt,
for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
{
tree *varp = id->decl_map->get (p);
- if (varp
- && TREE_CODE (*varp) == VAR_DECL)
+ if (varp && VAR_P (*varp))
{
tree def = (gimple_in_ssa_p (cfun) && is_gimple_reg (p)
? ssa_default_def (id->src_cfun, p) : NULL);
@@ -3567,7 +3592,7 @@ inline_forbidden_p_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p,
RAM instead of 256MB. Don't do so for alloca calls emitted for
VLA objects as those can't cause unbounded growth (they're always
wrapped inside stack_save/stack_restore regions. */
- if (gimple_alloca_call_p (stmt)
+ if (gimple_maybe_alloca_call_p (stmt)
&& !gimple_call_alloca_for_var_p (as_a <gcall *> (stmt))
&& !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
{
@@ -3944,6 +3969,10 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
return weights->div_mod_cost;
return 1;
+ /* Bit-field insertion needs several shift and mask operations. */
+ case BIT_INSERT_EXPR:
+ return 3;
+
default:
/* We expect a copy assignment with no operator. */
gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS);
@@ -4273,7 +4302,7 @@ add_local_variables (struct function *callee, struct function *caller,
tree new_var = remap_decl (var, id);
/* Remap debug-expressions. */
- if (TREE_CODE (new_var) == VAR_DECL
+ if (VAR_P (new_var)
&& DECL_HAS_DEBUG_EXPR_P (var)
&& new_var != var)
{
@@ -4301,7 +4330,7 @@ reset_debug_binding (copy_body_data *id, tree srcvar, gimple_seq *bindings)
if (!remappedvarp)
return;
- if (TREE_CODE (*remappedvarp) != VAR_DECL)
+ if (!VAR_P (*remappedvarp))
return;
if (*remappedvarp == id->retvar || *remappedvarp == id->retbnd)
@@ -4365,6 +4394,12 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
bool purge_dead_abnormal_edges;
gcall *call_stmt;
unsigned int i;
+ unsigned int prop_mask, src_properties;
+ struct function *dst_cfun;
+ tree simduid;
+ use_operand_p use;
+ gimple *simtenter_stmt = NULL;
+ vec<tree> *simtvars_save;
/* The gimplifier uses input_location in too many places, such as
internal_get_tmp_var (). */
@@ -4453,6 +4488,45 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
}
goto egress;
}
+ id->src_node = cg_edge->callee;
+
+ /* If callee is thunk, all we need is to adjust the THIS pointer
+ and redirect to function being thunked. */
+ if (id->src_node->thunk.thunk_p)
+ {
+ cgraph_edge *edge;
+ tree virtual_offset = NULL;
+ int freq = cg_edge->frequency;
+ gcov_type count = cg_edge->count;
+ tree op;
+ gimple_stmt_iterator iter = gsi_for_stmt (stmt);
+
+ cg_edge->remove ();
+ edge = id->src_node->callees->clone (id->dst_node, call_stmt,
+ gimple_uid (stmt),
+ REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
+ true);
+ edge->frequency = freq;
+ edge->count = count;
+ if (id->src_node->thunk.virtual_offset_p)
+ virtual_offset = size_int (id->src_node->thunk.virtual_value);
+ op = create_tmp_reg_fn (cfun, TREE_TYPE (gimple_call_arg (stmt, 0)),
+ NULL);
+ gsi_insert_before (&iter, gimple_build_assign (op,
+ gimple_call_arg (stmt, 0)),
+ GSI_NEW_STMT);
+ gcc_assert (id->src_node->thunk.this_adjusting);
+ op = thunk_adjust (&iter, op, 1, id->src_node->thunk.fixed_offset,
+ virtual_offset);
+
+ gimple_call_set_arg (stmt, 0, op);
+ gimple_call_set_fndecl (stmt, edge->callee->decl);
+ update_stmt (stmt);
+ id->src_node->remove ();
+ expand_call_inline (bb, stmt, id);
+ maybe_remove_unused_call_args (cfun, stmt);
+ return true;
+ }
fn = cg_edge->callee->decl;
cg_edge->callee->get_untransformed_body ();
@@ -4526,17 +4600,29 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
/* Record the function we are about to inline. */
id->src_fn = fn;
- id->src_node = cg_edge->callee;
id->src_cfun = DECL_STRUCT_FUNCTION (fn);
- id->call_stmt = stmt;
+ id->call_stmt = call_stmt;
+
+ /* When inlining into an OpenMP SIMD-on-SIMT loop, arrange for new automatic
+ variables to be added to IFN_GOMP_SIMT_ENTER argument list. */
+ dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn);
+ simtvars_save = id->dst_simt_vars;
+ if (!(dst_cfun->curr_properties & PROP_gimple_lomp_dev)
+ && (simduid = bb->loop_father->simduid) != NULL_TREE
+ && (simduid = ssa_default_def (dst_cfun, simduid)) != NULL_TREE
+ && single_imm_use (simduid, &use, &simtenter_stmt)
+ && is_gimple_call (simtenter_stmt)
+ && gimple_call_internal_p (simtenter_stmt, IFN_GOMP_SIMT_ENTER))
+ vec_alloc (id->dst_simt_vars, 0);
+ else
+ id->dst_simt_vars = NULL;
/* If the src function contains an IFN_VA_ARG, then so will the dst
- function after inlining. */
- if ((id->src_cfun->curr_properties & PROP_gimple_lva) == 0)
- {
- struct function *dst_cfun = DECL_STRUCT_FUNCTION (id->dst_fn);
- dst_cfun->curr_properties &= ~PROP_gimple_lva;
- }
+ function after inlining. Likewise for IFN_GOMP_USE_SIMT. */
+ prop_mask = PROP_gimple_lva | PROP_gimple_lomp_dev;
+ src_properties = id->src_cfun->curr_properties & prop_mask;
+ if (src_properties != prop_mask)
+ dst_cfun->curr_properties &= src_properties | ~prop_mask;
gcc_assert (!id->src_cfun->after_inlining);
@@ -4670,6 +4756,27 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
if (cfun->gimple_df)
pt_solution_reset (&cfun->gimple_df->escaped);
+ /* Add new automatic variables to IFN_GOMP_SIMT_ENTER arguments. */
+ if (id->dst_simt_vars && id->dst_simt_vars->length () > 0)
+ {
+ size_t nargs = gimple_call_num_args (simtenter_stmt);
+ vec<tree> *vars = id->dst_simt_vars;
+ auto_vec<tree> newargs (nargs + vars->length ());
+ for (size_t i = 0; i < nargs; i++)
+ newargs.quick_push (gimple_call_arg (simtenter_stmt, i));
+ for (tree *pvar = vars->begin (); pvar != vars->end (); pvar++)
+ {
+ tree ptrtype = build_pointer_type (TREE_TYPE (*pvar));
+ newargs.quick_push (build1 (ADDR_EXPR, ptrtype, *pvar));
+ }
+ gcall *g = gimple_build_call_internal_vec (IFN_GOMP_SIMT_ENTER, newargs);
+ gimple_call_set_lhs (g, gimple_call_lhs (simtenter_stmt));
+ gimple_stmt_iterator gsi = gsi_for_stmt (simtenter_stmt);
+ gsi_replace (&gsi, g, false);
+ }
+ vec_free (id->dst_simt_vars);
+ id->dst_simt_vars = simtvars_save;
+
/* Clean up. */
if (id->debug_map)
{
@@ -4711,7 +4818,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
{
tree name = gimple_call_lhs (stmt);
tree var = SSA_NAME_VAR (name);
- tree def = ssa_default_def (cfun, var);
+ tree def = var ? ssa_default_def (cfun, var) : NULL;
if (def)
{
@@ -4722,6 +4829,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
}
else
{
+ if (!var)
+ {
+ var = create_tmp_reg_fn (cfun, TREE_TYPE (name), NULL);
+ SET_SSA_NAME_VAR_OR_IDENTIFIER (name, var);
+ }
/* Otherwise make this variable undefined. */
gsi_remove (&stmt_gsi, true);
set_ssa_default_def (cfun, var, name);
@@ -5123,10 +5235,20 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
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 ((VAR_P (expr) && !TREE_STATIC (expr))
+ || TREE_CODE (expr) == LABEL_DECL)
{
/* Lookup the declaration. */
n = st->get (expr);
@@ -5266,6 +5388,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
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;
@@ -5344,7 +5467,7 @@ declare_inline_vars (tree block, tree vars)
but now it will be in the TO_FN. PARM_TO_VAR means enable PARM_DECL to
VAR_DECL translation. */
-static tree
+tree
copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy)
{
/* Don't generate debug information for the copy if we wouldn't have
@@ -5377,9 +5500,19 @@ copy_decl_for_dup_finish (copy_body_data *id, tree decl, tree copy)
function. */
;
else
- /* Ordinary automatic local variables are now in the scope of the
- new function. */
- DECL_CONTEXT (copy) = id->dst_fn;
+ {
+ /* Ordinary automatic local variables are now in the scope of the
+ new function. */
+ DECL_CONTEXT (copy) = id->dst_fn;
+ if (VAR_P (copy) && id->dst_simt_vars && !is_gimple_reg (copy))
+ {
+ if (!lookup_attribute ("omp simt private", DECL_ATTRIBUTES (copy)))
+ DECL_ATTRIBUTES (copy)
+ = tree_cons (get_identifier ("omp simt private"), NULL,
+ DECL_ATTRIBUTES (copy));
+ id->dst_simt_vars->safe_push (copy);
+ }
+ }
return copy;
}
@@ -5968,7 +6101,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
ddecl = make_node (DEBUG_EXPR_DECL);
DECL_ARTIFICIAL (ddecl) = 1;
TREE_TYPE (ddecl) = TREE_TYPE (parm);
- DECL_MODE (ddecl) = DECL_MODE (parm);
+ SET_DECL_MODE (ddecl, DECL_MODE (parm));
vec_safe_push (*debug_args, DECL_ORIGIN (parm));
vec_safe_push (*debug_args, ddecl);
}
@@ -6000,7 +6133,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
parm = (**debug_args)[i];
DECL_ARTIFICIAL (vexpr) = 1;
TREE_TYPE (vexpr) = TREE_TYPE (parm);
- DECL_MODE (vexpr) = DECL_MODE (parm);
+ SET_DECL_MODE (vexpr, DECL_MODE (parm));
def_temp = gimple_build_debug_bind (var, vexpr, NULL);
gsi_insert_before (&cgsi, def_temp, GSI_NEW_STMT);
def_temp = gimple_build_debug_source_bind (vexpr, parm, NULL);