@@ -100,7 +100,7 @@ ccmp_candidate_p (gimple *g, bool outer = false)
tree_code tcode;
basic_block bb;
- if (!g)
+ if (!g || !is_gimple_assign (g))
return false;
tcode = gimple_assign_rhs_code (g);
@@ -138,7 +138,7 @@ get_compare_parts (tree t, int *up, rtx_code *rcode,
{
tree_code code;
gimple *g = get_gimple_for_ssa_name (t);
- if (g)
+ if (g && is_gimple_assign (g))
{
*up = TYPE_UNSIGNED (TREE_TYPE (gimple_assign_rhs1 (g)));
code = gimple_assign_rhs_code (g);
@@ -2848,6 +2848,7 @@ expand_call_stmt (gcall *stmt)
if (builtin_p
&& TREE_CODE (arg) == SSA_NAME
&& (def = get_gimple_for_ssa_name (arg))
+ && is_gimple_assign (def)
&& gimple_assign_rhs_code (def) == ADDR_EXPR)
arg = gimple_assign_rhs1 (def);
CALL_EXPR_ARG (exp, i) = arg;
@@ -4408,7 +4409,7 @@ avoid_deep_ter_for_debug (gimple *stmt, int depth)
gimple *g = get_gimple_for_ssa_name (use);
if (g == NULL)
continue;
- if (depth > 6 && !stmt_ends_bb_p (g))
+ if ((depth > 6 || !is_gimple_assign (g)) && !stmt_ends_bb_p (g))
{
if (deep_ter_debug_map == NULL)
deep_ter_debug_map = new hash_map<tree, tree>;
@@ -5382,7 +5383,13 @@ expand_debug_expr (tree exp)
t = *slot;
}
if (t == NULL_TREE)
- t = gimple_assign_rhs_to_tree (g);
+ {
+ if (is_gimple_assign (g))
+ t = gimple_assign_rhs_to_tree (g);
+ else
+ /* expand_debug_expr doesn't handle CALL_EXPR right now. */
+ return NULL;
+ }
op0 = expand_debug_expr (t);
if (!op0)
return NULL;
@@ -5958,7 +5965,8 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls)
/* Look for SSA names that have their last use here (TERed
names always have only one real use). */
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
- if ((def = get_gimple_for_ssa_name (op)))
+ if ((def = get_gimple_for_ssa_name (op))
+ && is_gimple_assign (def))
{
imm_use_iterator imm_iter;
use_operand_p use_p;
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3. If not see
#include "rtx-vector-builder.h"
#include "tree-pretty-print.h"
#include "flags.h"
+#include "internal-fn.h"
/* If this is nonzero, we do not bother generating VOLATILE
@@ -3827,6 +3828,7 @@ get_def_for_expr (tree name, enum tree_code code)
def_stmt = get_gimple_for_ssa_name (name);
if (!def_stmt
+ || !is_gimple_assign (def_stmt)
|| gimple_assign_rhs_code (def_stmt) != code)
return NULL;
@@ -3847,6 +3849,7 @@ get_def_for_expr_class (tree name, enum tree_code_class tclass)
def_stmt = get_gimple_for_ssa_name (name);
if (!def_stmt
+ || !is_gimple_assign (def_stmt)
|| TREE_CODE_CLASS (gimple_assign_rhs_code (def_stmt)) != tclass)
return NULL;
@@ -5695,6 +5698,7 @@ optimize_bitfield_assignment_op (poly_uint64 pbitsize,
srcstmt = get_gimple_for_ssa_name (src);
if (!srcstmt
+ || !is_gimple_assign (srcstmt)
|| TREE_CODE_CLASS (gimple_assign_rhs_code (srcstmt)) != tcc_binary)
return false;
@@ -11320,11 +11324,24 @@ expand_expr_real_1 (tree exp, rtx target, machine_mode tmode,
&& !SSA_NAME_IS_DEFAULT_DEF (exp)
&& (optimize || !SSA_NAME_VAR (exp)
|| DECL_IGNORED_P (SSA_NAME_VAR (exp)))
+ && is_gimple_assign (SSA_NAME_DEF_STMT (exp))
&& stmt_is_replaceable_p (SSA_NAME_DEF_STMT (exp)))
g = SSA_NAME_DEF_STMT (exp);
- if (g)
+ if (safe_is_a <gassign *> (g))
return expand_expr_real_gassign (as_a<gassign *> (g), target, tmode,
modifier, alt_rtl, inner_reference_p);
+ else if (safe_is_a <gcall *> (g))
+ {
+ /* ??? internal call expansion doesn't follow the usual API
+ of returning the destination RTX and being passed a desired
+ target. */
+ rtx dest = gen_reg_rtx (TYPE_MODE (TREE_TYPE (exp)));
+ tree tmplhs = make_tree (TREE_TYPE (exp), dest);
+ gimple_call_set_lhs (g, tmplhs);
+ expand_internal_call (as_a <gcall *> (g));
+ gimple_call_set_lhs (g, exp);
+ return dest;
+ }
ssa_name = exp;
decl_rtl = get_rtx_for_ssa_name (ssa_name);
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-ssa-coalesce.h"
#include "tree-outof-ssa.h"
#include "dojump.h"
+#include "internal-fn.h"
/* FIXME: A lot of code here deals with expanding to RTL. All that code
should be in cfgexpand.cc. */
@@ -60,8 +61,11 @@ ssa_is_replaceable_p (gimple *stmt)
tree def;
gimple *use_stmt;
- /* Only consider modify stmts. */
- if (!is_gimple_assign (stmt))
+ /* Only consider modify stmts and direct internal fn calls. */
+ if (!is_gimple_assign (stmt)
+ && (!is_gimple_call (stmt)
+ || !gimple_call_internal_p (stmt)
+ || !direct_internal_fn_p (gimple_call_internal_fn (stmt))))
return false;
/* If the statement may throw an exception, it cannot be replaced. */
@@ -92,14 +96,11 @@ ssa_is_replaceable_p (gimple *stmt)
/* An assignment with a register variable on the RHS is not
replaceable. */
- if (gimple_assign_rhs_code (stmt) == VAR_DECL
+ if (is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) == VAR_DECL
&& DECL_HARD_REGISTER (gimple_assign_rhs1 (stmt)))
return false;
- /* No function calls can be replaced. */
- if (is_gimple_call (stmt))
- return false;
-
/* Leave any stmt with volatile operands alone as well. */
if (gimple_has_volatile_ops (stmt))
return false;