}
}
+/* Expand a clobber of LHS. If LHS is stored it in a multi-part
+ register, tell the rtl optimizers that its value is no longer
+ needed. */
+
+static void
+expand_clobber (tree lhs)
+{
+ if (DECL_P (lhs))
+ {
+ rtx decl_rtl = DECL_RTL_IF_SET (lhs);
+ if (decl_rtl && REG_P (decl_rtl))
+ {
+ machine_mode decl_mode = GET_MODE (decl_rtl);
+ if (maybe_gt (GET_MODE_SIZE (decl_mode),
+ REGMODE_NATURAL_SIZE (decl_mode)))
+ emit_clobber (decl_rtl);
+ }
+ }
+}
+
/* A subroutine of expand_gimple_stmt, expanding one gimple statement
STMT that doesn't require special handling for outgoing edges. That
is no tailcalls and no GIMPLE_COND. */
if (TREE_CLOBBER_P (rhs))
/* This is a clobber to mark the going out of scope for
this LHS. */
- ;
+ expand_clobber (lhs);
else
expand_assignment (lhs, rhs,
gimple_assign_nontemporal_move_p (
return mem_ref;
}
+/* Add a clobber of variable VAR to the vectorization of STMT.
+ Emit the clobber before *GSI. */
+
+static void
+vect_clobber_variable (gimple *stmt, gimple_stmt_iterator *gsi, tree var)
+{
+ tree clobber = build_clobber (TREE_TYPE (var));
+ gimple *new_stmt = gimple_build_assign (var, clobber);
+ vect_finish_stmt_generation (stmt, new_stmt, gsi);
+}
+
/* Utility functions used by vect_mark_stmts_to_be_vectorized. */
/* Function vect_mark_relevant.
}
if (ratype)
- {
- tree clobber = build_constructor (ratype, NULL);
- TREE_THIS_VOLATILE (clobber) = 1;
- new_stmt = gimple_build_assign (new_temp, clobber);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
- }
+ vect_clobber_variable (stmt, gsi, new_temp);
continue;
}
else if (simd_clone_subparts (vectype) > nunits)
CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE,
gimple_assign_lhs (new_stmt));
}
- tree clobber = build_constructor (ratype, NULL);
- TREE_THIS_VOLATILE (clobber) = 1;
- new_stmt = gimple_build_assign (new_temp, clobber);
- vect_finish_stmt_generation (stmt, new_stmt, gsi);
+ vect_clobber_variable (stmt, gsi, new_temp);
}
else
CONSTRUCTOR_APPEND_ELT (ret_ctor_elts, NULL_TREE, new_temp);
new_stmt
= gimple_build_assign (make_ssa_name (vec_dest), t);
vect_finish_stmt_generation (stmt, new_stmt, gsi);
- tree clobber = build_constructor (ratype, NULL);
- TREE_THIS_VOLATILE (clobber) = 1;
- vect_finish_stmt_generation (stmt,
- gimple_build_assign (new_temp,
- clobber), gsi);
+ vect_clobber_variable (stmt, gsi, new_temp);
}
}
{
tree vec_array;
- /* Combine all the vectors into an array. */
+ /* Get an array into which we can store the individual vectors. */
vec_array = create_vector_array (vectype, vec_num);
+
+ /* Invalidate the current contents of VEC_ARRAY. This should
+ become an RTL clobber too, which prevents the vector registers
+ from being upward-exposed. */
+ vect_clobber_variable (stmt, gsi, vec_array);
+
+ /* Store the individual vectors into the array. */
for (i = 0; i < vec_num; i++)
{
vec_oprnd = dr_chain[i];
gimple_call_set_nothrow (call, true);
new_stmt = call;
vect_finish_stmt_generation (stmt, new_stmt, gsi);
+
+ /* Record that VEC_ARRAY is now dead. */
+ vect_clobber_variable (stmt, gsi, vec_array);
}
else
{
/* Record the mapping between SSA_NAMEs and statements. */
vect_record_grouped_load_vectors (stmt, dr_chain);
+
+ /* Record that VEC_ARRAY is now dead. */
+ vect_clobber_variable (stmt, gsi, vec_array);
}
else
{