From 1465e5cf7a5d32d06a5e57488d65d329a461b7b9 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 1 Oct 2013 15:40:28 -0600 Subject: [PATCH] tree-ssa-threadupdate.c (struct redirection_data): Delete outgoing_edge and intermediate_edge fields. * tree-ssa-threadupdate.c (struct redirection_data): Delete outgoing_edge and intermediate_edge fields. Instead store the path. (redirection_data::hash): Hash on the last edge's destination index. (redirection_data::equal): Check the entire thread path. (lookup_redirectio_data): Corresponding changes. (create_edge_and_update_destination_phis): Likewise. (thread_single_edge): Likewise. From-SVN: r203091 --- gcc/ChangeLog | 10 ++++++ gcc/tree-ssa-threadupdate.c | 61 +++++++++++++++++++++++-------------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 58299d231c0..5738af9f21c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2013-10-01 Jeff Law + + * tree-ssa-threadupdate.c (struct redirection_data): Delete + outgoing_edge and intermediate_edge fields. Instead store the path. + (redirection_data::hash): Hash on the last edge's destination index. + (redirection_data::equal): Check the entire thread path. + (lookup_redirectio_data): Corresponding changes. + (create_edge_and_update_destination_phis): Likewise. + (thread_single_edge): Likewise. + 2013-10-01 Joern Rennecke Diego Novillo diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index ecf9baf5430..2adea1b5119 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -116,14 +116,11 @@ struct redirection_data : typed_free_remove targets a single successor of B. */ basic_block dup_block; - /* An outgoing edge from B. DUP_BLOCK will have OUTGOING_EDGE->dest as - its single successor. */ - edge outgoing_edge; + /* The jump threading path. */ + vec *path; - edge intermediate_edge; - - /* A list of incoming edges which we want to thread to - OUTGOING_EDGE->dest. */ + /* A list of incoming edges which we want to thread to the + same path. */ struct el *incoming_edges; /* hash_table support. */ @@ -133,21 +130,36 @@ struct redirection_data : typed_free_remove static inline int equal (const value_type *, const compare_type *); }; +/* Simple hashing function. For any given incoming edge E, we're going + to be most concerned with the final destination of its jump thread + path. So hash on the block index of the final edge in the path. */ + inline hashval_t redirection_data::hash (const value_type *p) { - edge e = p->outgoing_edge; - return e->dest->index; + vec *path = p->path; + return path->last ()->e->dest->index; } +/* Given two hash table entries, return true if they have the same + jump threading path. */ inline int redirection_data::equal (const value_type *p1, const compare_type *p2) { - edge e1 = p1->outgoing_edge; - edge e2 = p2->outgoing_edge; - edge e3 = p1->intermediate_edge; - edge e4 = p2->intermediate_edge; - return e1 == e2 && e3 == e4; + vec *path1 = p1->path; + vec *path2 = p2->path; + + if (path1->length () != path2->length ()) + return false; + + for (unsigned int i = 1; i < path1->length (); i++) + { + if ((*path1)[i]->type != (*path2)[i]->type + || (*path1)[i]->e != (*path2)[i]->e) + return false; + } + + return true; } /* Data structure of information to pass to hash table traversal routines. */ @@ -259,10 +271,7 @@ lookup_redirection_data (edge e, enum insert_option insert) /* Build a hash table element so we can see if E is already in the table. */ elt = XNEW (struct redirection_data); - /* Right now, if we have a joiner, it is always index 1 into the vector. */ - elt->intermediate_edge - = (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK ? (*path)[1]->e : NULL; - elt->outgoing_edge = path->last ()->e; + elt->path = path; elt->dup_block = NULL; elt->incoming_edges = NULL; @@ -356,7 +365,7 @@ static void create_edge_and_update_destination_phis (struct redirection_data *rd, basic_block bb) { - edge e = make_edge (bb, rd->outgoing_edge->dest, EDGE_FALLTHRU); + edge e = make_edge (bb, rd->path->last ()->e->dest, EDGE_FALLTHRU); rescan_loop_exit (e, true, false); e->probability = REG_BR_PROB_BASE; @@ -364,9 +373,9 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, /* We have to copy path -- which means creating a new vector as well as all the jump_thread_edge entries. */ - if (rd->outgoing_edge->aux) + if (rd->path->last ()->e->aux) { - vec *path = THREAD_PATH (rd->outgoing_edge); + vec *path = THREAD_PATH (rd->path->last ()->e); vec *copy = new vec (); /* Sadly, the elements of the vector are pointers and need to @@ -388,7 +397,7 @@ create_edge_and_update_destination_phis (struct redirection_data *rd, from the duplicate block, then we will need to add a new argument to them. The argument should have the same value as the argument associated with the outgoing edge stored in RD. */ - copy_phi_args (e->dest, rd->outgoing_edge, e); + copy_phi_args (e->dest, rd->path->last ()->e, e); } /* Wire up the outgoing edges from the duplicate block and @@ -787,7 +796,13 @@ thread_single_edge (edge e) if (e->dest == eto->src) update_bb_profile_for_threading (bb, EDGE_FREQUENCY (e), e->count, eto); - rd.outgoing_edge = eto; + vec *npath = new vec (); + jump_thread_edge *x = new jump_thread_edge (e, EDGE_START_JUMP_THREAD); + npath->safe_push (x); + + x = new jump_thread_edge (eto, EDGE_COPY_SRC_BLOCK); + npath->safe_push (x); + rd.path = npath; create_block_for_threading (bb, &rd); remove_ctrl_stmt_and_useless_edges (rd.dup_block, NULL); -- 2.30.2