diff options
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 61 |
1 files changed, 59 insertions, 2 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index dfa82aa..e99e102 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -170,6 +170,7 @@ static edge find_taken_edge_computed_goto (basic_block, tree); static edge find_taken_edge_cond_expr (basic_block, tree); static edge find_taken_edge_switch_expr (gswitch *, basic_block, tree); static tree find_case_label_for_value (gswitch *, tree); +static void lower_phi_internal_fn (); void init_empty_tree_cfg_for_function (struct function *fn) @@ -244,6 +245,7 @@ build_gimple_cfg (gimple_seq seq) discriminator_per_locus = new hash_table<locus_discrim_hasher> (13); make_edges (); assign_discriminators (); + lower_phi_internal_fn (); cleanup_dead_labels (); delete discriminator_per_locus; discriminator_per_locus = NULL; @@ -345,6 +347,49 @@ replace_loop_annotate (void) } } +/* Lower internal PHI function from GIMPLE FE. */ + +static void +lower_phi_internal_fn () +{ + basic_block bb, pred = NULL; + gimple_stmt_iterator gsi; + tree lhs; + gphi *phi_node; + gimple *stmt; + + /* 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);) + { + stmt = gsi_stmt (gsi); + if (! gimple_call_internal_p (stmt, IFN_PHI)) + { + gsi_next (&gsi); + continue; + } + + lhs = gimple_call_lhs (stmt); + phi_node = create_phi_node (lhs, bb); + + /* Add arguments to the PHI node. */ + for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i) + { + tree arg = gimple_call_arg (stmt, i); + if (TREE_CODE (arg) == LABEL_DECL) + pred = label_to_block (arg); + else + { + edge e = find_edge (pred, bb); + add_phi_arg (phi_node, arg, e, UNKNOWN_LOCATION); + } + } + + gsi_remove (&gsi, true); + } + } +} static unsigned int execute_build_cfg (void) @@ -3337,6 +3382,11 @@ verify_gimple_call (gcall *stmt) debug_generic_stmt (fn); return true; } + /* FIXME : for passing label as arg in internal fn PHI from GIMPLE FE*/ + else if (gimple_call_internal_fn (stmt) == IFN_PHI) + { + return false; + } } else { @@ -7497,7 +7547,14 @@ dump_function_to_file (tree fndecl, FILE *file, int flags) } current_function_decl = fndecl; - fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : ""); + if (flags & TDF_GIMPLE) + { + print_generic_expr (file, TREE_TYPE (TREE_TYPE (fndecl)), + dump_flags | TDF_SLIM); + fprintf (file, " __GIMPLE ()\n%s (", function_name (fun)); + } + else + fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : ""); arg = DECL_ARGUMENTS (fndecl); while (arg) @@ -7609,7 +7666,7 @@ dump_function_to_file (tree fndecl, FILE *file, int flags) fprintf (file, "}\n"); } - else if (DECL_SAVED_TREE (fndecl) == NULL) + else if (fun->curr_properties & PROP_gimple_any) { /* The function is now in GIMPLE form but the CFG has not been built yet. Emit the single sequence of GIMPLE statements |