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