RE: [PATCH, Mips] Compact branch/delay slot optimization.

2015-11-11 Thread Simon Dardis
Committed as r230160.

Thanks,
Simon

> -Original Message-
> From: Moore, Catherine [mailto:catherine_mo...@mentor.com]
> Sent: 28 October 2015 14:00
> To: Simon Dardis; Matthew Fortune
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH, Mips] Compact branch/delay slot optimization.
> 
> 
> 
> > -Original Message-
> > From: Simon Dardis [mailto:simon.dar...@imgtec.com]
> > Sent: Tuesday, October 06, 2015 10:00 AM
> > To: Moore, Catherine; Matthew Fortune
> > Cc: gcc-patches@gcc.gnu.org
> > Subject: RE: [PATCH, Mips] Compact branch/delay slot optimization.
> >
> > Hello,
> >
> > I'd like to resubmit the previous patch as it failed to check if the
> > branch inside the sequence had a compact form.
> >
> > Thanks,
> > Simon
> >
> > gcc/
> > * config/mips/mips.c: (mips_breakable_sequence_p): New function.
> >   (mips_break_sequence): New function.
> >   (mips_reorg_process_insns) Use them. Use compact branches in
> > selected
> >   situations.
> >
> > gcc/testsuite/
> > * gcc.target/mips/split-ds-sequence.c: Test for the above.
> 
> Hi Simon,
> This patch looks okay with the exception of one stylistic change.
> Please change all instances of :
> +mips_breakable_sequence_p (rtx_insn * insn)
> To:
> +mips_breakable_sequence_p (rtx_insn *insn)
> Okay, with those changes.
> Thanks,
> Catherine
> 
> 
> >
> > Index: config/mips/mips.c
> >
> ==
> > =
> > --- config/mips/mips.c  (revision 228282)
> > +++ config/mips/mips.c  (working copy)
> > @@ -16973,6 +16973,34 @@
> >}
> >  }
> >
> > +/* A SEQUENCE is breakable iff the branch inside it has a compact form
> > +   and the target has compact branches.  */
> > +
> > +static bool
> > +mips_breakable_sequence_p (rtx_insn * insn) {
> > +  return (insn && GET_CODE (PATTERN (insn)) == SEQUENCE
> > + && TARGET_CB_MAYBE
> > + && get_attr_compact_form (SEQ_BEGIN (insn)) !=
> > COMPACT_FORM_NEVER);
> > +}
> > +
> > +/* Remove a SEQUENCE and replace it with the delay slot instruction
> > +   followed by the branch and return the instruction in the delay slot.
> > +   Return the first of the two new instructions.
> > +   Subroutine of mips_reorg_process_insns.  */
> > +
> > +static rtx_insn *
> > +mips_break_sequence (rtx_insn * insn) {
> > +  rtx_insn * before = PREV_INSN (insn);
> > +  rtx_insn * branch = SEQ_BEGIN (insn);
> > +  rtx_insn * ds = SEQ_END (insn);
> > +  remove_insn (insn);
> > +  add_insn_after (ds, before, NULL);
> > +  add_insn_after (branch, ds, NULL);
> > +  return ds;
> > +}
> > +
> >  /* Go through the instruction stream and insert nops where necessary.
> > Also delete any high-part relocations whose partnering low parts
> > are now all dead.  See if the whole function can then be put into
> > @@ -17065,6 +17093,68 @@
> > {
> >   if (GET_CODE (PATTERN (insn)) == SEQUENCE)
> > {
> > + rtx_insn * next_active = next_active_insn (insn);
> > + /* Undo delay slots to avoid bubbles if the next instruction can
> > +be placed in a forbidden slot or the cost of adding an
> > +explicit NOP in a forbidden slot is OK and if the SEQUENCE is
> > +safely breakable.  */
> > + if (TARGET_CB_MAYBE
> > + && mips_breakable_sequence_p (insn)
> > + && INSN_P (SEQ_BEGIN (insn))
> > + && INSN_P (SEQ_END (insn))
> > + && ((next_active
> > +  && INSN_P (next_active)
> > +  && GET_CODE (PATTERN (next_active)) != SEQUENCE
> > +  && get_attr_can_delay (next_active) ==
> > CAN_DELAY_YES)
> > + || !optimize_size))
> > +   {
> > + /* To hide a potential pipeline bubble, if we scan backwards
> > +from the current SEQUENCE and find that there is a load
> > +of a value that is used in the CTI and there are no
> > +dependencies between the CTI and instruction in the
> > delay
> > +slot, break the sequence so the load delay is hidden.  */
> > + HARD_REG_SET uses;
> > + CLEAR_HARD_REG_SET (uses);
> > +  

RE: [PATCH, Mips] Compact branch/delay slot optimization.

2015-10-28 Thread Moore, Catherine


> -Original Message-
> From: Simon Dardis [mailto:simon.dar...@imgtec.com]
> Sent: Tuesday, October 06, 2015 10:00 AM
> To: Moore, Catherine; Matthew Fortune
> Cc: gcc-patches@gcc.gnu.org
> Subject: RE: [PATCH, Mips] Compact branch/delay slot optimization.
> 
> Hello,
> 
> I'd like to resubmit the previous patch as it failed to check if the branch 
> inside
> the sequence had a compact form.
> 
> Thanks,
> Simon
> 
> gcc/
> * config/mips/mips.c: (mips_breakable_sequence_p): New function.
>   (mips_break_sequence): New function.
>   (mips_reorg_process_insns) Use them. Use compact branches in
> selected
>   situations.
> 
> gcc/testsuite/
> * gcc.target/mips/split-ds-sequence.c: Test for the above.

Hi Simon,
This patch looks okay with the exception of one stylistic change.
Please change all instances of :
+mips_breakable_sequence_p (rtx_insn * insn)
To:
+mips_breakable_sequence_p (rtx_insn *insn)
Okay, with those changes.
Thanks,
Catherine


> 
> Index: config/mips/mips.c
> ==
> =
> --- config/mips/mips.c(revision 228282)
> +++ config/mips/mips.c(working copy)
> @@ -16973,6 +16973,34 @@
>}
>  }
> 
> +/* A SEQUENCE is breakable iff the branch inside it has a compact form
> +   and the target has compact branches.  */
> +
> +static bool
> +mips_breakable_sequence_p (rtx_insn * insn)
> +{
> +  return (insn && GET_CODE (PATTERN (insn)) == SEQUENCE
> +   && TARGET_CB_MAYBE
> +   && get_attr_compact_form (SEQ_BEGIN (insn)) !=
> COMPACT_FORM_NEVER);
> +}
> +
> +/* Remove a SEQUENCE and replace it with the delay slot instruction
> +   followed by the branch and return the instruction in the delay slot.
> +   Return the first of the two new instructions.
> +   Subroutine of mips_reorg_process_insns.  */
> +
> +static rtx_insn *
> +mips_break_sequence (rtx_insn * insn)
> +{
> +  rtx_insn * before = PREV_INSN (insn);
> +  rtx_insn * branch = SEQ_BEGIN (insn);
> +  rtx_insn * ds = SEQ_END (insn);
> +  remove_insn (insn);
> +  add_insn_after (ds, before, NULL);
> +  add_insn_after (branch, ds, NULL);
> +  return ds;
> +}
> +
>  /* Go through the instruction stream and insert nops where necessary.
> Also delete any high-part relocations whose partnering low parts
> are now all dead.  See if the whole function can then be put into
> @@ -17065,6 +17093,68 @@
>   {
> if (GET_CODE (PATTERN (insn)) == SEQUENCE)
>   {
> +   rtx_insn * next_active = next_active_insn (insn);
> +   /* Undo delay slots to avoid bubbles if the next instruction can
> +  be placed in a forbidden slot or the cost of adding an
> +  explicit NOP in a forbidden slot is OK and if the SEQUENCE is
> +  safely breakable.  */
> +   if (TARGET_CB_MAYBE
> +   && mips_breakable_sequence_p (insn)
> +   && INSN_P (SEQ_BEGIN (insn))
> +   && INSN_P (SEQ_END (insn))
> +   && ((next_active
> +&& INSN_P (next_active)
> +&& GET_CODE (PATTERN (next_active)) != SEQUENCE
> +&& get_attr_can_delay (next_active) ==
> CAN_DELAY_YES)
> +   || !optimize_size))
> + {
> +   /* To hide a potential pipeline bubble, if we scan backwards
> +  from the current SEQUENCE and find that there is a load
> +  of a value that is used in the CTI and there are no
> +  dependencies between the CTI and instruction in the
> delay
> +  slot, break the sequence so the load delay is hidden.  */
> +   HARD_REG_SET uses;
> +   CLEAR_HARD_REG_SET (uses);
> +   note_uses ( (SEQ_BEGIN (insn)),
> record_hard_reg_uses,
> +  );
> +   HARD_REG_SET delay_sets;
> +   CLEAR_HARD_REG_SET (delay_sets);
> +   note_stores (PATTERN (SEQ_END (insn)),
> record_hard_reg_sets,
> +_sets);
> +
> +   rtx prev = prev_active_insn (insn);
> +   if (prev
> +   && GET_CODE (PATTERN (prev)) == SET
> +   && MEM_P (SET_SRC (PATTERN (prev
> + {
> +   HARD_REG_SET sets;
> +   CLEAR_HARD_REG_SET (sets);
> +   note_stores (PATTERN (prev), record_hard_reg_sets,
> +);
> +
&g

RE: [PATCH, Mips] Compact branch/delay slot optimization.

2015-10-06 Thread Simon Dardis
Hello,

I'd like to resubmit the previous patch as it failed to check if the branch 
inside the sequence had a compact form.

Thanks,
Simon

gcc/
* config/mips/mips.c: (mips_breakable_sequence_p): New function.
  (mips_break_sequence): New function. 
  (mips_reorg_process_insns) Use them. Use compact branches in selected
  situations.

gcc/testsuite/
* gcc.target/mips/split-ds-sequence.c: Test for the above.

Index: config/mips/mips.c
===
--- config/mips/mips.c  (revision 228282)
+++ config/mips/mips.c  (working copy)
@@ -16973,6 +16973,34 @@
   }
 }
 
+/* A SEQUENCE is breakable iff the branch inside it has a compact form
+   and the target has compact branches.  */
+
+static bool
+mips_breakable_sequence_p (rtx_insn * insn)
+{
+  return (insn && GET_CODE (PATTERN (insn)) == SEQUENCE
+ && TARGET_CB_MAYBE
+ && get_attr_compact_form (SEQ_BEGIN (insn)) != COMPACT_FORM_NEVER);
+}
+
+/* Remove a SEQUENCE and replace it with the delay slot instruction
+   followed by the branch and return the instruction in the delay slot.
+   Return the first of the two new instructions.
+   Subroutine of mips_reorg_process_insns.  */
+
+static rtx_insn *
+mips_break_sequence (rtx_insn * insn)
+{
+  rtx_insn * before = PREV_INSN (insn);
+  rtx_insn * branch = SEQ_BEGIN (insn);
+  rtx_insn * ds = SEQ_END (insn);
+  remove_insn (insn);
+  add_insn_after (ds, before, NULL);
+  add_insn_after (branch, ds, NULL);
+  return ds;
+}
+
 /* Go through the instruction stream and insert nops where necessary.
Also delete any high-part relocations whose partnering low parts
are now all dead.  See if the whole function can then be put into
@@ -17065,6 +17093,68 @@
{
  if (GET_CODE (PATTERN (insn)) == SEQUENCE)
{
+ rtx_insn * next_active = next_active_insn (insn);
+ /* Undo delay slots to avoid bubbles if the next instruction can
+be placed in a forbidden slot or the cost of adding an
+explicit NOP in a forbidden slot is OK and if the SEQUENCE is
+safely breakable.  */
+ if (TARGET_CB_MAYBE
+ && mips_breakable_sequence_p (insn)
+ && INSN_P (SEQ_BEGIN (insn))
+ && INSN_P (SEQ_END (insn))
+ && ((next_active
+  && INSN_P (next_active)
+  && GET_CODE (PATTERN (next_active)) != SEQUENCE
+  && get_attr_can_delay (next_active) == CAN_DELAY_YES)
+ || !optimize_size))
+   {
+ /* To hide a potential pipeline bubble, if we scan backwards
+from the current SEQUENCE and find that there is a load
+of a value that is used in the CTI and there are no
+dependencies between the CTI and instruction in the delay
+slot, break the sequence so the load delay is hidden.  */
+ HARD_REG_SET uses;
+ CLEAR_HARD_REG_SET (uses);
+ note_uses ( (SEQ_BEGIN (insn)), record_hard_reg_uses,
+);
+ HARD_REG_SET delay_sets;
+ CLEAR_HARD_REG_SET (delay_sets);
+ note_stores (PATTERN (SEQ_END (insn)), record_hard_reg_sets,
+  _sets);
+
+ rtx prev = prev_active_insn (insn);
+ if (prev
+ && GET_CODE (PATTERN (prev)) == SET
+ && MEM_P (SET_SRC (PATTERN (prev
+   {
+ HARD_REG_SET sets;
+ CLEAR_HARD_REG_SET (sets);
+ note_stores (PATTERN (prev), record_hard_reg_sets,
+  );
+
+ /* Re-order if safe.  */
+ if (!hard_reg_set_intersect_p (delay_sets, uses)
+ && hard_reg_set_intersect_p (uses, sets))
+   {
+ next_insn = mips_break_sequence (insn);
+ /* Need to process the hazards of the newly
+introduced instructions.  */
+ continue;
+   }
+   }
+
+ /* If we find an orphaned high-part relocation in a delay
+slot then we can convert to a compact branch and get
+the orphaned high part deleted.  */
+ if (mips_orphaned_high_part_p (, SEQ_END (insn)))
+   {
+ next_insn = mips_break_sequence (insn);
+ /* Need to process the hazards of the newly
+introduced instructions.  */
+ continue;
+   }
+   }
+
  /* If we find an orphaned high-part relocation in a