public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Filip Kastl <pheeck@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc(refs/users/pheeck/heads/sccp)] norecursive tarjan v2; seems to work Date: Sun, 24 Jul 2022 11:51:54 +0000 (GMT) [thread overview] Message-ID: <20220724115154.A42F73858C39@sourceware.org> (raw) https://gcc.gnu.org/g:47bb91efdb7673f9fba6efd7056cfe4c8eefc867 commit 47bb91efdb7673f9fba6efd7056cfe4c8eefc867 Author: Filip Kastl <filip.kastl@gmail.com> Date: Sun Jul 24 13:50:46 2022 +0200 norecursive tarjan v2; seems to work Diff: --- gcc/sccp.cc | 113 ++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 37 deletions(-) diff --git a/gcc/sccp.cc b/gcc/sccp.cc index d33f0337e8c..c0bb98f9f79 100644 --- a/gcc/sccp.cc +++ b/gcc/sccp.cc @@ -58,24 +58,22 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "gimple-fold.h" +enum vstate +{ + unvisited, + vopen, /* Open and closed vertices are on stack. */ + closed, + in_scc +}; + struct vertex { - bool visited; - bool is_on_stack; + vstate state; unsigned index; unsigned lowlink; gphi* stmt; }; -static unsigned -min (unsigned x, unsigned y) -{ - if (x < y) - return x; - else - return y; -} - static void tarjan_set_using (gimple* stmt) { @@ -159,8 +157,7 @@ tarjan_phis_to_vertices (vec<gphi *> phis) for (gphi *phi : phis) { vertex v; - v.visited = false; - v.is_on_stack = false; + v.state = unvisited; v.index = 0; v.lowlink = 0; v.stmt = phi; @@ -175,6 +172,7 @@ tarjan_compute_sccs (vec<gphi *> phis) { vec<vec<gphi *>> sccs = vNULL; vec<unsigned> worklist = vNULL; + vec<unsigned> stack = vNULL; unsigned curr_index = 0; vec<vertex> vs = tarjan_phis_to_vertices (phis); @@ -198,68 +196,109 @@ tarjan_compute_sccs (vec<gphi *> phis) while (!worklist.is_empty ()) { unsigned i = worklist.pop(); + gphi *phi = vs[i].stmt; - if (!vs[i].visited) + if (vs[i].state == unvisited) { - gphi *phi = vs[i].stmt; + vs[i].state = vopen; /* Assign index to this vertex. */ vs[i].index = curr_index; vs[i].lowlink = curr_index; curr_index++; - /* Put this vertex back on worklist. */ + /* Put vertex on stack and also on worklist to be closed later. */ + stack.safe_push (i); worklist.safe_push (i); - /* Put not yet visited children of vertex on worklist and update - lowlink of this vertex according to lowlinks of children on stack. */ + /* Put unvisited neighbors of vertex on worklist and update + lowlink of this vertex according to indices of neighbors on + stack. */ unsigned j; for (j = 0; j < gimple_phi_num_args (phi); j++) { - tree op_ssa = gimple_phi_arg_def (phi, i); + tree op_ssa = gimple_phi_arg_def (phi, j); gimple *op_stmt = SSA_NAME_DEF_STMT (op_ssa); /* Skip any operand that isn't a vertex we're using. */ if (!tarjan_is_using (op_stmt)) continue; - + gphi *op_phi = dyn_cast<gphi *> (op_stmt); if (op_phi == NULL) /* Only PHI functions have the 'using' flags set. */ gcc_unreachable (); unsigned op_i = tarjan_phinum (op_phi); - if (!vs[op_i].visited) + switch (vs[op_i].state) { + case unvisited: worklist.safe_push (op_i); - } - else if (vs[op_i].is_on_stack) - { - vs[i].lowlink = min (vs[i].lowlink, vs[op_i].index); + break; + case vopen: + case closed: + vs[i].lowlink = std::min (vs[i].lowlink, vs[op_i].index); + break; + case in_scc: + /* Ignore these edges. */ + break; } } } - else if (vs[i].is_on_stack) // TODO This check is redundant + else if (vs[i].state == vopen) { - vec<gphi *> scc = vNULL; - - /* Put vertex back on stack/worklist. */ - worklist.safe_push (i); + vs[i].state = closed; - /* Pop scc from stack/worklist. */ + /* Update lowlink of this vertex according to lowlinks of children + of this vertex (in terms of DFS tree). */ unsigned j; - do + for (j = 0; j < gimple_phi_num_args (phi); j++) { - j = worklist.pop(); - scc.safe_push (vs[j].stmt); - vs[j].is_on_stack = false; + tree op_ssa = gimple_phi_arg_def (phi, j); // TODO Same code + // twice (iterator?) + gimple *op_stmt = SSA_NAME_DEF_STMT (op_ssa); + + /* Skip any operand that isn't a vertex we're using. */ + if (!tarjan_is_using (op_stmt)) + continue; + + gphi *op_phi = dyn_cast<gphi *> (op_stmt); + if (op_phi == NULL) + /* Only PHI functions have the 'using' flags set. */ + gcc_unreachable (); + + unsigned op_i = tarjan_phinum (op_phi); + if (vs[op_i].state == closed) + { + vs[i].lowlink = std::min (vs[i].lowlink, vs[op_i].lowlink); + } } - while (vs[j].lowlink != vs[j].index); - sccs.safe_push (scc); + /* If this is the root of an scc, pop it from stack. */ + if (vs[i].lowlink == vs[i].index) + { + vec<gphi *> scc = vNULL; + + unsigned j; + do + { + j = stack.pop(); + scc.safe_push (vs[j].stmt); + vs[j].state = in_scc; + } + while (j != i); + + sccs.safe_push (scc); + } } } + // DEBUG + if (!stack.is_empty ()) + { + gcc_unreachable(); + } + /* Clear PHI functions' 'using' flags. */ for (vertex v : vs) {
next reply other threads:[~2022-07-24 11:51 UTC|newest] Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top 2022-07-24 11:51 Filip Kastl [this message] 2023-02-15 10:13 Filip Kastl
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20220724115154.A42F73858C39@sourceware.org \ --to=pheeck@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).