aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-iterator.c
diff options
context:
space:
mode:
authorRichard Henderson <rth@gcc.gnu.org>2010-07-26 15:53:50 -0700
committerRichard Henderson <rth@gcc.gnu.org>2010-07-26 15:53:50 -0700
commit8b84c5966fddefd51475d4df0fb2f1a699ba23fe (patch)
tree566634468015c713398a1fcd59ec66da7138545a /gcc/gimple-iterator.c
parentb57c6b13e0d950ba0771b1688cf6e57e3a5beae6 (diff)
downloadgcc-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.c51
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);