Hi!

On 2021-03-17T00:24:55+0100, I wrote:
> Now, walking each function backwards (!), [...]

> I've now got a simple 'callback_op', which for '!is_lhs' looks at
> 'get_base_address ([op])', and if that 'var' is contained in the set of
> current candidates (initialized per containg 'bind's, which we enter
> first, even if walking a 'gimple_seq' backwards), removes that 'var' as a
> candidate for such optimization.  (Plus some "details", of couse.)  This
> seems to work fine, as far as I can tell.  :-)

Is something like the attached "[WIP] 'walk_gimple_seq' backward" OK
conceptually?  (For next development stage 1 and with all the TODOs
resolved, of course.)

The 'backward' flag cannot simply be a argument to 'walk_gimple_seq'
etc.: it needs to also be passed to 'walk_gimple_seq_mod' calls triggered
from inside 'walk_gimple_stmt'.  Hence, I've put it into the state
'struct walk_stmt_info'.


Grüße
 Thomas


-----------------
Mentor Graphics (Deutschland) GmbH, Arnulfstrasse 201, 80634 München 
Registergericht München HRB 106955, Geschäftsführer: Thomas Heurung, Frank 
Thürauf
>From 48036d65cea6bb47c7d4eca3b4fea77e058f29e3 Mon Sep 17 00:00:00 2001
From: Thomas Schwinge <tho...@codesourcery.com>
Date: Mon, 15 Mar 2021 17:31:00 +0100
Subject: [PATCH] [WIP] 'walk_gimple_seq' backward

This seems to work -- for the one case where I'm using it...
---
 gcc/doc/gimple.texi |  2 ++
 gcc/gimple-walk.c   | 15 ++++++++++++---
 gcc/gimple-walk.h   |  4 ++++
 3 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi
index 5e0fc2e0dc5..51fe0f2d715 100644
--- a/gcc/doc/gimple.texi
+++ b/gcc/doc/gimple.texi
@@ -2778,4 +2778,6 @@ calling @code{walk_gimple_stmt} on each one.  @code{WI} is as in
 @code{walk_gimple_stmt}.  If @code{walk_gimple_stmt} returns non-@code{NULL}, the walk
 is stopped and the value returned.  Otherwise, all the statements
 are walked and @code{NULL_TREE} returned.
+
+TODO update for forward vs. backward.
 @end deftypefn
diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
index 9a761f32578..dfc2f0b4dbc 100644
--- a/gcc/gimple-walk.c
+++ b/gcc/gimple-walk.c
@@ -32,6 +32,8 @@ along with GCC; see the file COPYING3.  If not see
 /* Walk all the statements in the sequence *PSEQ calling walk_gimple_stmt
    on each one.  WI is as in walk_gimple_stmt.
 
+   TODO update for forward vs. backward.
+
    If walk_gimple_stmt returns non-NULL, the walk is stopped, and the
    value is stored in WI->CALLBACK_RESULT.  Also, the statement that
    produced the value is returned if this statement has not been
@@ -44,9 +46,10 @@ gimple *
 walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
 		     walk_tree_fn callback_op, struct walk_stmt_info *wi)
 {
-  gimple_stmt_iterator gsi;
+  bool forward = !(wi && wi->backward);
 
-  for (gsi = gsi_start (*pseq); !gsi_end_p (gsi); )
+  gimple_stmt_iterator gsi = forward ? gsi_start (*pseq) : gsi_last (*pseq);
+  for (; !gsi_end_p (gsi); )
     {
       tree ret = walk_gimple_stmt (&gsi, callback_stmt, callback_op, wi);
       if (ret)
@@ -60,7 +63,13 @@ walk_gimple_seq_mod (gimple_seq *pseq, walk_stmt_fn callback_stmt,
 	}
 
       if (!wi->removed_stmt)
-	gsi_next (&gsi);
+	{
+	  if (forward)
+	    gsi_next (&gsi);
+	  else //TODO Correct?
+	    gsi_prev (&gsi);
+	  //TODO This could do with some unit testing, to make sure all the corner cases (removing first/last, for example) work correctly.
+	}
     }
 
   if (wi)
diff --git a/gcc/gimple-walk.h b/gcc/gimple-walk.h
index bdc7351f190..9590c63ba18 100644
--- a/gcc/gimple-walk.h
+++ b/gcc/gimple-walk.h
@@ -71,6 +71,10 @@ struct walk_stmt_info
 
   /* True if we've removed the statement that was processed.  */
   BOOL_BITFIELD removed_stmt : 1;
+
+  /*TODO */
+  //TODO Only applicable for 'walk_gimple_seq'.
+  BOOL_BITFIELD backward : 1;
 };
 
 /* Callback for walk_gimple_stmt.  Called for every statement found
-- 
2.17.1

Reply via email to