This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
emit-rtl tidy
- From: Alan Modra <amodra at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>, gcc-patches at gcc dot gnu dot org
- Date: Fri, 6 Feb 2015 10:48:26 +1030
- Subject: emit-rtl tidy
- Authentication-results: sourceware.org; auth=none
- References: <20150203135735 dot GJ14796 at bubble dot grove dot modra dot org> <CAGWvnykygYkakPVTASG_UuGM=f7tXPSdnUzS-seMe=gB3EUqhQ at mail dot gmail dot com> <20150204001605 dot GL14796 at bubble dot grove dot modra dot org> <CAGWvnykMMtzV6n54cWsa16u53MiRLE1FNEKScvvagK_wv9qUww at mail dot gmail dot com> <20150205033954 dot GR14796 at bubble dot grove dot modra dot org> <20150205071225 dot GD1746 at tucnak dot redhat dot com> <20150205102901 dot GU14796 at bubble dot grove dot modra dot org>
On Thu, Feb 05, 2015 at 08:59:01PM +1030, Alan Modra wrote:
> Thanks, I'll use it directly now and have a patch in the works to tidy
> m32c.c and rs6000.c.
As threatened, the emit-rtl tidy. Besides adding a couple of
accessors, I've moved x_first_insn and x_last_insn into a struct
sequence_stack. This seemed natural to me, making
get_topmost_sequence possible, and simplifying functions in emit-rtl.c
that need to operate on both the current sequence and any pushed
sequences.
If you look carefully, you'll see I delete some lines in remove_insn:
- if (next)
- SET_PREV_INSN (next) = NULL;
that don't seem to be covered by the loop. That's a deliberate
change. Jan added those lines in rev 160111 and 160121 for apparently
no good reason. See SET_PREV_INSN (next) = prev; a little later in
the function.
Bootstrapped and regression tested powerpc64-linux and x86_64-linux.
I've built an m32c compiler but haven't yet bootstapped it - I'm a
little rusty on setting up a sim environment.
OK when stage1 opens?
* function.h (struct emit_status): Delete x_first_insn, x_last_insn
and sequence_stack. Add seq.
(seq_stack): Delete.
* function.c (prepare_function_start): Don't access x_last_insn.
* emit-rtl.h (get_current_sequence, get_topmost_sequence): New.
(get_insns, set_first_insn, get_last_insn, set_last_insn): Use them.
* emit_rtl.c (start_sequence, push_topmost_sequence,
pop_topmost_sequence, end_sequence, in_sequence_p, init_emit): Use
sequence accessors.
(get_last_insn_anywhere, add_insn_after_nobb, add_insn_before_nobb,
remove_insn): Likewise. Simplify.
* config/m32c/m32c.c (m32c_leaf_function_p): Use push_topmost_sequence
and pop_topmost_sequence.
(m32c_function_needs_enter): Use get_topmost_sequence. Ignore
debug insns.
* config/rs6000/rs6000.c (rs6000_call_aix): Use get_current_sequence.
Index: gcc/function.h
===================================================================
--- gcc/function.h (revision 220462)
+++ gcc/function.h (working copy)
@@ -41,19 +41,17 @@ struct GTY(()) emit_status {
/* Lowest label number in current function. */
int x_first_label_num;
- /* The ends of the doubly-linked chain of rtl for the current function.
- Both are reset to null at the start of rtl generation for the function.
+ /* seq.first and seq.last are the ends of the doubly-linked chain of
+ rtl for the current function. Both are reset to null at the
+ start of rtl generation for the function.
- start_sequence saves both of these on `sequence_stack' and then starts
- a new, nested sequence of insns. */
- rtx_insn *x_first_insn;
- rtx_insn *x_last_insn;
+ start_sequence saves both of these on seq.next and then starts
+ a new, nested sequence of insns.
- /* Stack of pending (incomplete) sequences saved by `start_sequence'.
- Each element describes one pending sequence.
- The main insn-chain is saved in the last element of the chain,
- unless the chain is empty. */
- struct sequence_stack *sequence_stack;
+ seq.next is a stack of pending (incomplete) sequences saved by
+ start_sequence. Each element describes one pending sequence.
+ The main insn-chain is the last element of the chain. */
+ struct sequence_stack seq;
/* INSN_UID for next insn emitted.
Reset to 1 for each function compiled. */
@@ -88,7 +86,6 @@ extern GTY ((length ("crtl->emit.x_reg_rtx_no")))
/* For backward compatibility... eventually these should all go away. */
#define reg_rtx_no (crtl->emit.x_reg_rtx_no)
-#define seq_stack (crtl->emit.sequence_stack)
#define REGNO_POINTER_ALIGN(REGNO) (crtl->emit.regno_pointer_align[REGNO])
Index: gcc/function.c
===================================================================
--- gcc/function.c (revision 220462)
+++ gcc/function.c (working copy)
@@ -4831,7 +4831,7 @@ push_struct_function (tree fndecl)
static void
prepare_function_start (void)
{
- gcc_assert (!crtl->emit.x_last_insn);
+ gcc_assert (!get_last_insn ());
init_temp_slots ();
init_emit ();
init_varasm_status ();
Index: gcc/emit-rtl.h
===================================================================
--- gcc/emit-rtl.h (revision 220462)
+++ gcc/emit-rtl.h (working copy)
@@ -75,12 +75,36 @@ extern int mem_expr_equal_p (const_tree, const_tre
extern bool need_atomic_barrier_p (enum memmodel, bool);
+/* Return the current sequence. */
+
+static inline struct sequence_stack *
+get_current_sequence (void)
+{
+ return &crtl->emit.seq;
+}
+
+/* Return the outermost sequence. */
+
+static inline struct sequence_stack *
+get_topmost_sequence (void)
+{
+ struct sequence_stack *seq, *top;
+
+ seq = get_current_sequence ();
+ do
+ {
+ top = seq;
+ seq = seq->next;
+ } while (seq);
+ return top;
+}
+
/* Return the first insn of the current sequence or current function. */
static inline rtx_insn *
get_insns (void)
{
- return crtl->emit.x_first_insn;
+ return get_current_sequence ()->first;
}
/* Specify a new insn as the first in the chain. */
@@ -89,7 +113,7 @@ static inline void
set_first_insn (rtx_insn *insn)
{
gcc_checking_assert (!insn || !PREV_INSN (insn));
- crtl->emit.x_first_insn = insn;
+ get_current_sequence ()->first = insn;
}
/* Return the last insn emitted in current sequence or current function. */
@@ -97,7 +121,7 @@ set_first_insn (rtx_insn *insn)
static inline rtx_insn *
get_last_insn (void)
{
- return crtl->emit.x_last_insn;
+ return get_current_sequence ()->last;
}
/* Specify a new insn as the last in the chain. */
@@ -106,7 +130,7 @@ static inline void
set_last_insn (rtx_insn *insn)
{
gcc_checking_assert (!insn || !NEXT_INSN (insn));
- crtl->emit.x_last_insn = insn;
+ get_current_sequence ()->last = insn;
}
/* Return a number larger than any instruction's uid in this function. */
Index: gcc/emit-rtl.c
===================================================================
--- gcc/emit-rtl.c (revision 220462)
+++ gcc/emit-rtl.c (working copy)
@@ -3175,12 +3175,10 @@ make_safe_from (rtx x, rtx other)
rtx_insn *
get_last_insn_anywhere (void)
{
- struct sequence_stack *stack;
- if (get_last_insn ())
- return get_last_insn ();
- for (stack = seq_stack; stack; stack = stack->next)
- if (stack->last != 0)
- return stack->last;
+ struct sequence_stack *seq;
+ for (seq = get_current_sequence (); seq; seq = seq->next)
+ if (seq->last != 0)
+ return seq->last;
return 0;
}
@@ -4014,19 +4012,14 @@ add_insn_after_nobb (rtx_insn *insn, rtx_insn *aft
if (next == NULL)
{
- if (get_last_insn () == after)
- set_last_insn (insn);
- else
- {
- struct sequence_stack *stack = seq_stack;
- /* Scan all pending sequences too. */
- for (; stack; stack = stack->next)
- if (after == stack->last)
- {
- stack->last = insn;
- break;
- }
- }
+ struct sequence_stack *seq;
+
+ for (seq = get_current_sequence (); seq; seq = seq->next)
+ if (after == seq->last)
+ {
+ seq->last = insn;
+ break;
+ }
}
}
@@ -4043,21 +4036,16 @@ add_insn_before_nobb (rtx_insn *insn, rtx_insn *be
if (prev == NULL)
{
- if (get_insns () == before)
- set_first_insn (insn);
- else
- {
- struct sequence_stack *stack = seq_stack;
- /* Scan all pending sequences too. */
- for (; stack; stack = stack->next)
- if (before == stack->first)
- {
- stack->first = insn;
- break;
- }
+ struct sequence_stack *seq;
- gcc_assert (stack);
- }
+ for (seq = get_current_sequence (); seq; seq = seq->next)
+ if (before == seq->first)
+ {
+ seq->first = insn;
+ break;
+ }
+
+ gcc_assert (seq);
}
}
@@ -4168,24 +4156,18 @@ remove_insn (rtx uncast_insn)
SET_NEXT_INSN (sequence->insn (sequence->len () - 1)) = next;
}
}
- else if (get_insns () == insn)
- {
- if (next)
- SET_PREV_INSN (next) = NULL;
- set_first_insn (next);
- }
else
{
- struct sequence_stack *stack = seq_stack;
- /* Scan all pending sequences too. */
- for (; stack; stack = stack->next)
- if (insn == stack->first)
+ struct sequence_stack *seq;
+
+ for (seq = get_current_sequence (); seq; seq = seq->next)
+ if (insn == seq->first)
{
- stack->first = next;
+ seq->first = next;
break;
}
- gcc_assert (stack);
+ gcc_assert (seq);
}
if (next)
@@ -4197,20 +4179,18 @@ remove_insn (rtx uncast_insn)
SET_PREV_INSN (sequence->insn (0)) = prev;
}
}
- else if (get_last_insn () == insn)
- set_last_insn (prev);
else
{
- struct sequence_stack *stack = seq_stack;
- /* Scan all pending sequences too. */
- for (; stack; stack = stack->next)
- if (insn == stack->last)
+ struct sequence_stack *seq;
+
+ for (seq = get_current_sequence (); seq; seq = seq->next)
+ if (insn == seq->last)
{
- stack->last = prev;
+ seq->last = prev;
break;
}
- gcc_assert (stack);
+ gcc_assert (seq);
}
/* Fix up basic block boundaries, if necessary. */
@@ -5399,12 +5379,11 @@ start_sequence (void)
else
tem = ggc_alloc<sequence_stack> ();
- tem->next = seq_stack;
+ tem->next = get_current_sequence ()->next;
tem->first = get_insns ();
tem->last = get_last_insn ();
+ get_current_sequence ()->next = tem;
- seq_stack = tem;
-
set_first_insn (0);
set_last_insn (0);
}
@@ -5445,13 +5424,11 @@ push_to_sequence2 (rtx_insn *first, rtx_insn *last
void
push_topmost_sequence (void)
{
- struct sequence_stack *stack, *top = NULL;
+ struct sequence_stack *top;
start_sequence ();
- for (stack = seq_stack; stack; stack = stack->next)
- top = stack;
-
+ top = get_topmost_sequence ();
set_first_insn (top->first);
set_last_insn (top->last);
}
@@ -5462,11 +5439,9 @@ push_topmost_sequence (void)
void
pop_topmost_sequence (void)
{
- struct sequence_stack *stack, *top = NULL;
+ struct sequence_stack *top;
- for (stack = seq_stack; stack; stack = stack->next)
- top = stack;
-
+ top = get_topmost_sequence ();
top->first = get_insns ();
top->last = get_last_insn ();
@@ -5489,11 +5464,11 @@ pop_topmost_sequence (void)
void
end_sequence (void)
{
- struct sequence_stack *tem = seq_stack;
+ struct sequence_stack *tem = get_current_sequence ()->next;
set_first_insn (tem->first);
set_last_insn (tem->last);
- seq_stack = tem->next;
+ get_current_sequence ()->next = tem->next;
memset (tem, 0, sizeof (*tem));
tem->next = free_sequence_stack;
@@ -5505,7 +5480,7 @@ end_sequence (void)
int
in_sequence_p (void)
{
- return seq_stack != 0;
+ return get_current_sequence ()->next != 0;
}
/* Put the various virtual registers into REGNO_REG_RTX. */
@@ -5721,7 +5696,7 @@ init_emit (void)
cur_debug_insn_uid = 1;
reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
first_label_num = label_num;
- seq_stack = NULL;
+ get_current_sequence ()->next = NULL;
/* Init the tables that describe all the pseudo regs. */
Index: gcc/config/m32c/m32c.c
===================================================================
--- gcc/config/m32c/m32c.c (revision 220462)
+++ gcc/config/m32c/m32c.c (working copy)
@@ -4056,24 +4056,11 @@ m32c_encode_section_info (tree decl, rtx rtl, int
static int
m32c_leaf_function_p (void)
{
- rtx_insn *saved_first, *saved_last;
- struct sequence_stack *seq;
int rv;
- saved_first = crtl->emit.x_first_insn;
- saved_last = crtl->emit.x_last_insn;
- for (seq = crtl->emit.sequence_stack; seq && seq->next; seq = seq->next)
- ;
- if (seq)
- {
- crtl->emit.x_first_insn = seq->first;
- crtl->emit.x_last_insn = seq->last;
- }
-
+ push_topmost_sequence ();
rv = leaf_function_p ();
-
- crtl->emit.x_first_insn = saved_first;
- crtl->emit.x_last_insn = saved_last;
+ pop_topmost_sequence ();
return rv;
}
@@ -4084,23 +4071,17 @@ static bool
m32c_function_needs_enter (void)
{
rtx_insn *insn;
- struct sequence_stack *seq;
rtx sp = gen_rtx_REG (Pmode, SP_REGNO);
rtx fb = gen_rtx_REG (Pmode, FB_REGNO);
- insn = get_insns ();
- for (seq = crtl->emit.sequence_stack;
- seq;
- insn = seq->first, seq = seq->next);
-
- while (insn)
- {
- if (reg_mentioned_p (sp, insn))
- return true;
- if (reg_mentioned_p (fb, insn))
- return true;
- insn = NEXT_INSN (insn);
- }
+ for (insn = get_topmost_sequence ()->first; insn; insn = NEXT_INSN (insn))
+ if (NONDEBUG_INSN_P (insn))
+ {
+ if (reg_mentioned_p (sp, insn))
+ return true;
+ if (reg_mentioned_p (fb, insn))
+ return true;
+ }
return false;
}
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c (revision 220463)
+++ gcc/config/rs6000/rs6000.c (working copy)
@@ -33026,7 +33026,7 @@ rs6000_call_aix (rtx value, rtx func_desc, rtx fla
override a static chain value. */
if (!direct_call_p
&& TARGET_POINTERS_TO_NESTED_FUNCTIONS
- && !chain_already_loaded (crtl->emit.sequence_stack->last))
+ && !chain_already_loaded (get_current_sequence ()->next->last))
{
rtx sc_reg = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
rtx func_sc_offset = GEN_INT (2 * GET_MODE_SIZE (Pmode));
--
Alan Modra
Australia Development Lab, IBM