diff options
author | Richard Henderson <rth@gcc.gnu.org> | 2010-07-26 15:53:50 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2010-07-26 15:53:50 -0700 |
commit | 8b84c5966fddefd51475d4df0fb2f1a699ba23fe (patch) | |
tree | 566634468015c713398a1fcd59ec66da7138545a /gcc/gimple-iterator.c | |
parent | b57c6b13e0d950ba0771b1688cf6e57e3a5beae6 (diff) | |
download | gcc-8b84c5966fddefd51475d4df0fb2f1a699ba23fe.zip gcc-8b84c5966fddefd51475d4df0fb2f1a699ba23fe.tar.gz gcc-8b84c5966fddefd51475d4df0fb2f1a699ba23fe.tar.bz2 |
re PR target/44132 (emutls is broken under a range of circumstances.)
PR target/44132
Emulated TLS rewrite.
From-SVN: r162549
Diffstat (limited to 'gcc/gimple-iterator.c')
-rw-r--r-- | gcc/gimple-iterator.c | 51 |
1 files changed, 48 insertions, 3 deletions
diff --git a/gcc/gimple-iterator.c b/gcc/gimple-iterator.c index 1402c0d..064b7fe 100644 --- a/gcc/gimple-iterator.c +++ b/gcc/gimple-iterator.c @@ -65,6 +65,35 @@ update_bb_for_stmts (gimple_seq_node first, basic_block bb) gimple_set_bb (n->stmt, bb); } +/* Set the frequencies for the cgraph_edges for each of the calls + starting at FIRST for their new position within BB. */ + +static void +update_call_edge_frequencies (gimple_seq_node first, basic_block bb) +{ + struct cgraph_node *cfun_node = NULL; + int bb_freq = 0; + gimple_seq_node n; + + for (n = first; n ; n = n->next) + if (is_gimple_call (n->stmt)) + { + struct cgraph_edge *e; + + /* These function calls are expensive enough that we want + to avoid calling them if we never see any calls. */ + if (cfun_node == NULL) + { + cfun_node = cgraph_node (current_function_decl); + bb_freq = (compute_call_stmt_bb_frequency + (current_function_decl, bb)); + } + + e = cgraph_edge (cfun_node, n->stmt); + if (e != NULL) + e->frequency = bb_freq; + } +} /* Insert the sequence delimited by nodes FIRST and LAST before iterator I. M specifies how to update iterator I after insertion @@ -696,11 +725,19 @@ basic_block gsi_insert_on_edge_immediate (edge e, gimple stmt) { gimple_stmt_iterator gsi; + struct gimple_seq_node_d node; basic_block new_bb = NULL; + bool ins_after; gcc_assert (!PENDING_STMT (e)); - if (gimple_find_edge_insert_loc (e, &gsi, &new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb); + + node.stmt = stmt; + node.prev = node.next = NULL; + update_call_edge_frequencies (&node, gsi.bb); + + if (ins_after) gsi_insert_after (&gsi, stmt, GSI_NEW_STMT); else gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); @@ -716,10 +753,14 @@ gsi_insert_seq_on_edge_immediate (edge e, gimple_seq stmts) { gimple_stmt_iterator gsi; basic_block new_bb = NULL; + bool ins_after; gcc_assert (!PENDING_STMT (e)); - if (gimple_find_edge_insert_loc (e, &gsi, &new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, &new_bb); + update_call_edge_frequencies (gimple_seq_first (stmts), gsi.bb); + + if (ins_after) gsi_insert_seq_after (&gsi, stmts, GSI_NEW_STMT); else gsi_insert_seq_before (&gsi, stmts, GSI_NEW_STMT); @@ -758,10 +799,14 @@ gsi_commit_one_edge_insert (edge e, basic_block *new_bb) { gimple_stmt_iterator gsi; gimple_seq seq = PENDING_STMT (e); + bool ins_after; PENDING_STMT (e) = NULL; - if (gimple_find_edge_insert_loc (e, &gsi, new_bb)) + ins_after = gimple_find_edge_insert_loc (e, &gsi, new_bb); + update_call_edge_frequencies (gimple_seq_first (seq), gsi.bb); + + if (ins_after) gsi_insert_seq_after (&gsi, seq, GSI_NEW_STMT); else gsi_insert_seq_before (&gsi, seq, GSI_NEW_STMT); |