diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 1a55b9a..17c1eb5 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -66,6 +66,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple-pretty-print.h" #include "tree-ssa.h" #include "pass_manager.h" +#include "tree-ssanames.h" +#include "gimple-ssa.h" /* We need to walk over decls with incomplete struct/union/enum types after parsing the whole translation unit. @@ -1666,7 +1668,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, location_t here = c_parser_peek_token (parser)->location; bool gimple_body_p = false; opt_pass *pass = NULL; - bool startwith_p; + bool startwith_p = false; if (static_assert_ok && c_parser_next_token_is_keyword (parser, RID_STATIC_ASSERT)) @@ -1723,7 +1725,6 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, if (kw_token->keyword == RID_GIMPLE) { gimple_body_p = true; - startwith_p = false; c_parser_consume_token (parser); c_parser_gimple_pass_list (parser, &pass, &startwith_p); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, @@ -18145,7 +18146,7 @@ c_parser_parse_gimple_body (c_parser *parser) location_t loc1 = c_parser_peek_token (parser)->location; seq = NULL; body = NULL; - + init_tree_ssa (cfun); return_p = c_parser_gimple_compound_statement (parser, &seq); if (!return_p) @@ -18173,7 +18174,6 @@ c_parser_parse_gimple_body (c_parser *parser) cfun->curr_properties = PROP_gimple_any; if (flag_gdebug) debug_gimple_seq (seq); - init_tree_ssa (cfun); return; } @@ -18361,7 +18361,7 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq) gcall *call_stmt; /* Gimplify internal functions. */ - tree arg; + tree arg = NULL_TREE; vec vargs = vNULL; if (c_parser_next_token_is (parser, CPP_OPEN_PAREN)) @@ -18386,7 +18386,29 @@ c_parser_gimple_expression (c_parser *parser, gimple_seq *seq) } else { - arg = c_parser_gimple_unary_expression (parser).value; + /* Parse ssa names */ + tree id; + char *var_name, *var_version, *token; + const char *ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + token = new char [strlen (ssa_token)]; + strcpy (token, ssa_token); + var_name = strtok (token, "_"); + id = get_identifier (var_name); + if (lookup_name (id)) + { + unsigned int version; + var_version = strtok (NULL, "_"); + version = atoi (var_version); + if (var_version && version) + { + arg = NULL_TREE; + if (version < num_ssa_names) + arg = ssa_name (version); + if (!arg) + arg = make_ssa_name_fn (cfun, lookup_name (id), gimple_build_nop (), version); + c_parser_consume_token (parser); + } + } vargs.safe_push (arg); } } @@ -18481,7 +18503,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode) sp--; \ } while (0) stack[0].loc = c_parser_peek_token (parser)->location; - stack[0].expr = c_parser_cast_expression (parser, NULL); + stack[0].expr = c_parser_gimple_unary_expression (parser); stack[0].prec = PREC_NONE; sp = 0; enum c_parser_prec oprec; @@ -18601,7 +18623,7 @@ c_parser_gimple_binary_expression (c_parser *parser, enum tree_code *subcode) } sp++; stack[sp].loc = binary_loc; - stack[sp].expr = c_parser_cast_expression (parser, NULL); + stack[sp].expr = c_parser_gimple_unary_expression (parser); stack[sp].prec = oprec; stack[sp].op = *subcode; out: @@ -18618,6 +18640,34 @@ static c_expr c_parser_gimple_unary_expression (c_parser *parser) { struct c_expr ret, op; + /* Parse ssa names */ + if (TREE_CODE (c_parser_peek_token (parser)->value) == IDENTIFIER_NODE + && !lookup_name (c_parser_peek_token (parser)->value)) + { + tree id; + char *var_name, *var_version, *token; + const char *ssa_token = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value); + token = new char [strlen (ssa_token)]; + strcpy (token, ssa_token); + var_name = strtok (token, "_"); + id = get_identifier (var_name); + if (lookup_name (id)) + { + var_version = strtok (NULL, "_"); + unsigned int version; + version = atoi (var_version); + if (var_version && version) + { + ret.value = NULL_TREE; + if (version < num_ssa_names) + ret.value = ssa_name (version); + if (!ret.value) + ret.value = make_ssa_name_fn (cfun, lookup_name (id), gimple_build_nop (), version); + c_parser_consume_token (parser); + } + } + return ret; + } location_t op_loc = c_parser_peek_token (parser)->location; location_t exp_loc; location_t finish; @@ -18868,7 +18918,7 @@ c_parser_gimple_pass_list_params (c_parser *parser, opt_pass **pass) if (c_parser_next_token_is (parser, CPP_STRING)) { - const char *name = TREE_STRING_POINTER(c_parser_peek_token (parser)->value); + const char *name = TREE_STRING_POINTER (c_parser_peek_token (parser)->value); c_parser_consume_token (parser); new_pass = g->get_passes ()->get_pass_by_name (name); diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8842cec..288e983 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -347,6 +347,7 @@ replace_loop_annotate (void) } /* Lower internal PHI function from GIMPLE FE */ + static void lower_phi_internal_fn () { @@ -356,8 +357,8 @@ lower_phi_internal_fn () gphi *phi_node; gimple *stmt; int len, capacity; - /* After edge creation, handle __PHI function from GIMPLE FE */ + /* After edge creation, handle __PHI function from GIMPLE FE */ FOR_EACH_BB_FN (bb, cfun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -368,12 +369,10 @@ lower_phi_internal_fn () if (gimple_call_internal_p (stmt) && gimple_call_internal_fn (stmt) == IFN_PHI) { - gsi_remove (&gsi, true); + gsi_remove (&gsi, true); int i; lhs = gimple_call_lhs (stmt); - phi_node = create_phi_node (lhs, bb); - for (i = 0; i < gimple_call_num_args (stmt); ++i) { tree arg = gimple_call_arg (stmt, i); @@ -7625,7 +7624,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags) for (ix = 1; ix < num_ssa_names; ++ix) { tree name = ssa_name (ix); - if (!virtual_operand_p (name)) + if (name && !SSA_NAME_VAR (name)) { fprintf (file, " "); print_generic_expr (file, TREE_TYPE (name), flags); diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 71150ac..b183b05 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1386,7 +1386,8 @@ rewrite_add_phi_arguments (basic_block bb) /* If we have pre-existing PHI its args may be different vars than existing vars */ argvar = gimple_phi_arg_def (phi, e->dest_idx); - gcc_assert (!argvar || TREE_CODE (argvar) != SSA_NAME); + if (TREE_CODE (argvar) == SSA_NAME) + continue; if (!argvar) argvar = SSA_NAME_VAR (res); currdef = get_reaching_def (argvar); diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index 91a8f97..c85eda2 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -255,7 +255,7 @@ flush_ssaname_freelist (void) used without a preceding definition). */ tree -make_ssa_name_fn (struct function *fn, tree var, gimple *stmt) +make_ssa_name_fn (struct function *fn, tree var, gimple *stmt, int version) { tree t; use_operand_p imm; @@ -265,8 +265,17 @@ make_ssa_name_fn (struct function *fn, tree var, gimple *stmt) || TREE_CODE (var) == RESULT_DECL || (TYPE_P (var) && is_gimple_reg_type (var))); + if (version != 0) + { + t = make_node (SSA_NAME); + SSA_NAME_VERSION (t) = version; + vec_safe_grow_cleared (SSANAMES (fn), version + 1); + gcc_assert ((*SSANAMES (fn))[version] == NULL); + (*SSANAMES (fn))[version] = t; + ssa_name_nodes_created++; + } /* If our free list has an element, then use it. */ - if (!vec_safe_is_empty (FREE_SSANAMES (fn))) + else if (!vec_safe_is_empty (FREE_SSANAMES (fn))) { t = FREE_SSANAMES (fn)->pop (); ssa_name_nodes_reused++; diff --git a/gcc/tree-ssanames.h b/gcc/tree-ssanames.h index c81b1a1..0034ae0 100644 --- a/gcc/tree-ssanames.h +++ b/gcc/tree-ssanames.h @@ -79,7 +79,7 @@ extern bool ssa_name_has_boolean_range (tree); extern void init_ssanames (struct function *, int); extern void fini_ssanames (struct function *); extern void ssanames_print_statistics (void); -extern tree make_ssa_name_fn (struct function *, tree, gimple *); +extern tree make_ssa_name_fn (struct function *, tree, gimple *, int version = 0); extern void release_ssa_name_fn (struct function *, tree); extern bool get_ptr_info_alignment (struct ptr_info_def *, unsigned int *, unsigned int *);