On Fri, 18 Dec 2015, Richard Biener wrote: > > The following tries to address the issue that with delayed folding > and the general attempt to do folding on GIMPLE we have "unfolded" > trees up to the point where we go into SSA (as otherwise the > match-and-simplify machinery on GIMPLE can't get to the defs of uses > to match larger expressions). > > The obvious solution is to do folding at gimplification time where > we already process GENERIC bottom-up via recursion. > > Of course that requires a solution for the missing use->def > information in pre-SSA GIMPLE. > > The solution is quite obvious in making the gimplifier use SSA > names for all temporaries it creates when gimplifying expressions. > In fact it can already do this when operating on SSA GIMPLE. > > So the following proof-of-concept patch makes the gimplifier > do that (and it passes a surprisingly large amount of testcases > without issues - most ICEs are for VLAs because we gimplify > sizes to SSA temps which eventually get released). It's also > way cheaper to allocate SSA names compared to decls for each temporary. > Note the prototype doesn't try to use match-and-simplify yet. > > With this in place the gimplifier can be changed to build GIMPLE > stmts with the gimple_build interface (into the appropriate > pre/post sequence) and thus automatically (re-)fold all expressions > (but not across statement border - user vars would stay in non-SSA). > > A final patch would get rid of the into_ssa flag in the gimplifier > context and instead annotate the few places where we can't do > with SSA temps (like for gimplifying COND_EXPRs into control-flow). > After all the gimplifier wouldn't create PHI nodes (we don't have > a CFG). The gimplifier also wouldn't set up SSA operands so this > is only about having SSA_NAME_DEF_STMT ready. > > Any comments?
Updated patch, runs into the copy_bb part during libmpxwrappers build in bootstrap (so libstdc++ build is fine already). Richard. TODO: copy_gimple_seq_and_replace_locals and copy_bb have incomplete or non-existing SSA def handling in non-SSA form 2015-12-18 Richard Biener <rguent...@suse.de> * gimplify.c (gimplify_modify_expr): Adjust assert. (gimplify_body): Gimplify into-SSA. (gimplify_function_tree): Init GIMPLE SSA data structures. (gimplify_one_sizepos): Set into_ssa to false around gimplifying a type/decl size. * 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. (replace_locals_stmt): Remap SSA defs. (copy_gimple_seq_and_replace_locals): Init src_cfun. Index: gcc/gimplify.c =================================================================== --- gcc/gimplify.c (revision 231805) +++ gcc/gimplify.c (working copy) @@ -4841,7 +4841,8 @@ gimplify_modify_expr (tree *expr_p, gimp 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); @@ -11192,7 +11193,12 @@ gimplify_one_sizepos (tree *expr_p, gimp *expr_p = unshare_expr (expr); + /* SSA names in decl/type fields are a bad idea - they'll get reclaimed + if the def vanishes. */ + bool saved_into_ssa = gimplify_ctxp->into_ssa; + gimplify_ctxp->into_ssa = false; gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue); + gimplify_ctxp->into_ssa = saved_into_ssa; } /* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node @@ -11215,7 +11221,7 @@ gimplify_body (tree fndecl, bool do_parm default_rtl_profile (); gcc_assert (gimplify_ctxp == NULL); - push_gimplify_context (); + push_gimplify_context (true); if (flag_openacc || flag_openmp) { @@ -11382,6 +11388,8 @@ gimplify_function_tree (tree fndecl) if necessary. */ cfun->curr_properties |= PROP_gimple_lva; + init_tree_ssa (cfun); + for (parm = DECL_ARGUMENTS (fndecl); parm ; parm = DECL_CHAIN (parm)) { /* Preliminarily mark non-addressed complex variables as eligible Index: gcc/passes.def =================================================================== --- gcc/passes.def (revision 231805) +++ gcc/passes.def (working copy) @@ -54,7 +54,6 @@ along with GCC; see the file COPYING3. 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_ubsan); NEXT_PASS (pass_early_warn_uninitialized); Index: gcc/tree-into-ssa.c =================================================================== --- gcc/tree-into-ssa.c (revision 231805) +++ gcc/tree-into-ssa.c (working copy) @@ -666,6 +666,8 @@ mark_def_sites (basic_block bb, gimple * 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); @@ -676,6 +678,8 @@ mark_def_sites (basic_block bb, gimple * 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)); @@ -1310,6 +1314,8 @@ rewrite_stmt (gimple_stmt_iterator *si) 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)); } @@ -1323,6 +1329,8 @@ rewrite_stmt (gimple_stmt_iterator *si) tree name; tree tracked_var; + if (TREE_CODE (var) == SSA_NAME) + continue; gcc_checking_assert (DECL_P (var)); if (gimple_clobber_p (stmt) Index: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c (revision 231805) +++ gcc/tree-inline.c (working copy) @@ -2078,6 +2078,9 @@ copy_bb (copy_body_data *id, basic_block maybe_duplicate_eh_stmt_fn (cfun, stmt, id->src_cfun, orig_stmt, id->eh_map, id->eh_lp_nr); + /* ??? This is not enough for non-SSA SSA defs. We should + instead fix the stmt copier to directly associate copied + stmts with remapped defs. */ if (gimple_in_ssa_p (cfun) && !is_gimple_debug (stmt)) { ssa_op_iter i; @@ -2443,8 +2446,9 @@ initialize_cfun (tree new_fndecl, tree c 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); } } @@ -5136,6 +5140,7 @@ replace_locals_op (tree *tp, int *walk_s /* Only a local declaration (variable or label). */ if ((TREE_CODE (expr) == VAR_DECL && !TREE_STATIC (expr)) + || TREE_CODE (expr) == SSA_NAME || TREE_CODE (expr) == LABEL_DECL) { /* Lookup the declaration. */ @@ -5227,6 +5232,16 @@ replace_locals_stmt (gimple_stmt_iterato NULL, id)); } + /* ??? Somehow cover all defs. */ + if (tree lhs = gimple_get_lhs (gs)) + { + if (TREE_CODE (lhs) == SSA_NAME) + { + lhs = remap_ssa_name (lhs, id); + SSA_NAME_DEF_STMT (lhs) = gs; + } + } + /* Keep iterating. */ return NULL_TREE; } @@ -5265,6 +5280,7 @@ copy_gimple_seq_and_replace_locals (gimp 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;