https://gcc.gnu.org/g:49278dd284fab03788b4e69ba385261ecf6bb05b

commit 49278dd284fab03788b4e69ba385261ecf6bb05b
Author: Richard Sandiford <richard.sandif...@arm.com>
Date:   Fri May 16 13:24:01 2025 +0100

    Make end_sequence return the insn sequence
    
    The start_sequence/end_sequence interface was a big improvement over
    the previous state, but one slightly awkward thing about it is that
    you have to call get_insns before end_sequence in order to get the
    insn sequence itself:
    
       To get the contents of the sequence just made, you must call
       `get_insns' *before* calling here.
    
    We therefore have quite a lot of code like this:
    
      insns = get_insns ();
      end_sequence ();
      return insns;
    
    It would seem simpler to write:
    
      return end_sequence ();
    
    instead.
    
    I can see three main potential objections to this:
    
    (1) It isn't obvious whether ending the sequence would return the first
        or the last instruction.  But although some code reads *both* the
        first and the last instruction, I can't think of a specific case
        where code would want *only* the last instruction.  All the emit
        functions take the first instruction rather than the last.
    
    (2) The "end" in end_sequence might imply the C++ meaning of an exclusive
        endpoint iterator.  But for an insn sequence, the exclusive endpoint
        is always the null pointer, so it would never need to be returned.
        That said, we could rename the function to something like
        "finish_sequence" or "complete_sequence" if this is an issue.
    
    (3) There might have been an intention that start_sequence/end_sequence
        could in future reclaim memory for unwanted sequences, and so an
        explicit get_insns was used to indicate that the caller does want
        the sequence.
    
        But that sort of memory reclaimation has never been added,
        and now that the codebase is C++, it would be easier to handle
        using RAII.  I think reclaiming memory would be difficult to do in
        any case, since some code records the individual instructions that
        they emit, rather than using get_insns.
    
    gcc/
            * rtl.h (end_sequence): Return the sequence.
            * emit-rtl.cc (end_sequence): Likewise.
    
    (cherry picked from commit 84269eeecf3c31a7f6be1f210f5e6c38d0c01e31)

Diff:
---
 gcc/emit-rtl.cc | 14 ++++++++------
 gcc/rtl.h       |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index 3e2c4309dee6..d86fb23b29a6 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -5722,22 +5722,22 @@ pop_topmost_sequence (void)
   end_sequence ();
 }
 
-/* After emitting to a sequence, restore previous saved state.
-
-   To get the contents of the sequence just made, you must call
-   `get_insns' *before* calling here.
+/* After emitting to a sequence, restore the previous saved state and return
+   the start of the completed sequence.
 
    If the compiler might have deferred popping arguments while
    generating this sequence, and this sequence will not be immediately
    inserted into the instruction stream, use do_pending_stack_adjust
-   before calling get_insns.  That will ensure that the deferred
+   before calling this function.  That will ensure that the deferred
    pops are inserted into this sequence, and not into some random
    location in the instruction stream.  See INHIBIT_DEFER_POP for more
    information about deferred popping of arguments.  */
 
-void
+rtx_insn *
 end_sequence (void)
 {
+  rtx_insn *insns = get_insns ();
+
   struct sequence_stack *tem = get_current_sequence ()->next;
 
   set_first_insn (tem->first);
@@ -5747,6 +5747,8 @@ end_sequence (void)
   memset (tem, 0, sizeof (*tem));
   tem->next = free_sequence_stack;
   free_sequence_stack = tem;
+
+  return insns;
 }
 
 /* Return true if currently emitting into a sequence.  */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 3b676c468805..62f01a1def04 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -3304,7 +3304,7 @@ extern rtx_insn *get_last_nonnote_insn (void);
 extern void start_sequence (void);
 extern void push_to_sequence (rtx_insn *);
 extern void push_to_sequence2 (rtx_insn *, rtx_insn *);
-extern void end_sequence (void);
+extern rtx_insn *end_sequence (void);
 #if TARGET_SUPPORTS_WIDE_INT == 0
 extern double_int rtx_to_double_int (const_rtx);
 #endif

Reply via email to