Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1316)

Unified Diff: gcc/tree-profile.c

Issue 8336016: Inline 'if' in GC instrumentation (Closed) Base URL: http://git.chromium.org/native_client/nacl-gcc.git@master
Patch Set: rebased Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gcc/tree-profile.c
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 59d37666dbe1740a85e6a28340f3cfde923c0a60..887643b369f92e61f9ea282067120d8a896ed019 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -436,35 +436,85 @@ tree_gen_ior_profiler (histogram_value value, unsigned tag, unsigned base)
static void
tree_gen_thread_suspension_instrumentation (edge e)
{
- static tree tree_suspend_thread_fn = NULL_TREE;
+ static tree suspend_thread_fn = NULL_TREE;
+ static tree thread_suspension_needed_var = NULL_TREE;
+
+ tree tmp_var;
+
+ basic_block bb_if;
+ basic_block bb_call;
+ basic_block bb_dest;
- basic_block bb;
gimple_stmt_iterator gsi;
gimple stmt;
- if (tree_suspend_thread_fn == NULL_TREE)
+ if (suspend_thread_fn == NULL_TREE)
{
- tree type = build_function_type (void_type_node, void_list_node);
- tree id = get_identifier ("__nacl_suspend_thread_if_needed");
- tree decl = build_decl (FUNCTION_DECL, id, type);
+ /* void __nacl_suspend_thread_if_needed (void); */
+
+ suspend_thread_fn = build_decl (
+ FUNCTION_DECL,
+ get_identifier ("__nacl_suspend_thread_if_needed"),
+ build_function_type (void_type_node, void_list_node));
+
+ TREE_PUBLIC (suspend_thread_fn) = 1;
+ DECL_EXTERNAL (suspend_thread_fn) = 1;
+
+ SET_DECL_ASSEMBLER_NAME (
+ suspend_thread_fn,
+ get_identifier ("__nacl_suspend_thread_if_needed"));
- tree libname = get_identifier ("__nacl_suspend_thread_if_needed");
+ /* volatile int __nacl_thread_suspension_needed; */
- TREE_PUBLIC (decl) = 1;
- DECL_EXTERNAL (decl) = 1;
+ thread_suspension_needed_var = build_decl (
+ VAR_DECL,
+ get_identifier ("__nacl_thread_suspension_needed"),
+ integer_type_node);
- SET_DECL_ASSEMBLER_NAME (decl, libname);
+ TREE_STATIC (thread_suspension_needed_var) = 1;
+ TREE_PUBLIC (thread_suspension_needed_var) = 1;
+ DECL_EXTERNAL (thread_suspension_needed_var) = 1;
+ TREE_USED (thread_suspension_needed_var) = 1;
+ TREE_THIS_VOLATILE (thread_suspension_needed_var) = 1;
- tree_suspend_thread_fn = decl;
+ SET_DECL_ASSEMBLER_NAME (
+ thread_suspension_needed_var,
+ get_identifier ("__nacl_thread_suspension_needed"));
}
- bb = split_edge (e);
- gsi = gsi_start_bb (bb);
+ /* tmp = __nacl_thread_suspension_needed;
+ if (tmp)
+ {
+ __nacl_suspend_thread_if_needed ();
+ }
- stmt = gimple_build_call (tree_suspend_thread_fn, 0);
+ Temporary variable is needed to keep SSA happy. */
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- add_abnormal_goto_call_edges (gsi);
+ bb_dest = e->dest;
+
+ bb_if = split_edge (e);
+
+ gsi = gsi_start_bb (bb_if);
+ tmp_var = create_tmp_var (integer_type_node, NULL);
+ stmt = gimple_build_assign (tmp_var, thread_suspension_needed_var);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ stmt = gimple_build_cond (
+ NE_EXPR,
+ tmp_var,
+ build_int_cst (integer_type_node, 0),
+ NULL_TREE,
+ NULL_TREE);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ bb_call = split_edge (single_succ_edge (bb_if));
+
+ gsi = gsi_start_bb (bb_call);
+ stmt = gimple_build_call (suspend_thread_fn, 0);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ remove_edge (single_succ_edge (bb_if));
+ make_edge(bb_if, bb_dest, EDGE_FALSE_VALUE);
+ make_edge(bb_if, bb_call, EDGE_TRUE_VALUE);
}
/* Return 1 if tree-based profiling is in effect, else 0.
@@ -496,20 +546,51 @@ tree_profiling (void)
basic_block bb;
edge e;
edge_iterator ei;
+ edge *edges;
+ int n;
+ int i;
+ /* Force back edges to be marked. */
mark_dfs_back_edges ();
+ /* Instrument edges.
+ Actual instrumentation adds basic blocks and adds/removes edges, thus
+ making iterators unhappy. Build a list of edges to instrument before
+ changing anything. */
+
+ /* Count back edges. */
+ n = 0;
+ FOR_EACH_BB (bb)
+ {
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (e->flags & EDGE_DFS_BACK)
+ ++n;
+ }
+ }
+
+ /* Add function entry edge at pos 0. */
+ ++n;
+ edges = (edge *) alloca (n * sizeof (edge));
+ edges[0] = single_succ_edge (ENTRY_BLOCK_PTR);
+
+ /* Populate back edges. */
+ i = 1;
FOR_EACH_BB (bb)
{
FOR_EACH_EDGE (e, ei, bb->preds)
{
- /* Instrument beginning of the function and back edges. */
- if (e->src == ENTRY_BLOCK_PTR
- || e->flags & EDGE_DFS_BACK)
- tree_gen_thread_suspension_instrumentation (e);
+ if (e->flags & EDGE_DFS_BACK)
+ edges[i++] = e;
}
}
+ /* Instrument edges. */
+ for (i = 0; i < n; ++i)
+ {
+ tree_gen_thread_suspension_instrumentation (edges[i]);
+ }
+
/* HACK: exit if we only need thread suspension instrumentation. */
if (!(profile_arc_flag || flag_test_coverage || flag_branch_probabilities))
return 0;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698