RE: [PATCH, Mips] Compact branch/delay slot optimization.
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.
> -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.
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