aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r--gcc/tree-cfg.c61
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