diff --git a/gcc/ccmp.cc b/gcc/ccmp.cc index 45629abadbe0428a337f0420bec20bf0e98961d8..4f739dfda50490d7d9788a5a29eee7ae5910ef80 100644 --- a/gcc/ccmp.cc +++ b/gcc/ccmp.cc @@ -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); diff --git a/gcc/cfgexpand.cc b/gcc/cfgexpand.cc index 58d68ec1caa543ea518393f727b8cf35172d8ac7..ea08810df04575cbe518ea94f97f22631b758b9a 100644 --- a/gcc/cfgexpand.cc +++ b/gcc/cfgexpand.cc @@ -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; @@ -4414,7 +4415,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>; @@ -5388,7 +5389,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; @@ -5964,7 +5971,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; diff --git a/gcc/expr.cc b/gcc/expr.cc index 70f2ecec99839e6247ed7601e0bff67e7aa38ba4..5578e3d9e993ed1cba789be4e2bdac6a01c3d817 100644 --- a/gcc/expr.cc +++ b/gcc/expr.cc @@ -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; @@ -11355,11 +11359,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); diff --git a/gcc/tree-outof-ssa.cc b/gcc/tree-outof-ssa.cc index 3df8054a729942bdb22eae94c4dac508a4ee590f..e51d5e0403aa9c76e4f5254e04004867ffdfd229 100644 --- a/gcc/tree-outof-ssa.cc +++ b/gcc/tree-outof-ssa.cc @@ -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;