Patchwork [v2,middle-end] : Introduce TARGET_REJECT_COMBINED_INSN target hook

login
register
mail settings
Submitter Uros Bizjak
Date Aug. 25, 2012, 3:04 p.m.
Message ID <CAFULd4a3KnrWnakDqMRiqtW7Aa-vv-Z3oGfTSK4CJuc39W2n5w@mail.gmail.com>
Download mbox | patch
Permalink /patch/179974/
State New
Headers show

Comments

Uros Bizjak - Aug. 25, 2012, 3:04 p.m.
Hello!

v2 patch differences:
- moves hook description text to target.def
- fixes error path to clear clobbers, as expected by recog_for_combine callers

2012-08-25  Uros Bizjak  <ubizjak@gmail.com>

	* target.def (reject_combined_insn): New target hook.
	* doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
	* doc/tm.texi: Regenerated.
	* combine.c (recog_for_combine): Call targetm.reject_combined_insn
	to allow targets to reject combined insn.

Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.

OK for mainline?

Uros.
Georg-Johann Lay - Aug. 25, 2012, 4:54 p.m.
Uros Bizjak schrieb:
> Hello!
> 
> v2 patch differences:
> - moves hook description text to target.def
> - fixes error path to clear clobbers, as expected by recog_for_combine callers
> 
> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
> 
> 	* target.def (reject_combined_insn): New target hook.
> 	* doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
> 	* doc/tm.texi: Regenerated.
> 	* combine.c (recog_for_combine): Call targetm.reject_combined_insn
> 	to allow targets to reject combined insn.
> 
> Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.
> 
> OK for mainline?

Just a question:

avr.md could use this hook instead of the
combine_pseudo_register_operand predicate in order to reject
hard registers in some insns before register allocation.

Is it valid to use INSN_CODE (insn)?  E.g. compare it against
CODE_FOR_foo for a light-wight detection of the insn in
the backend?

And may recod_data.operands[] et al. be used then?
Or is garbage therein and the backend has to call recog on its own?

The hook documentation could make this clear.

In the case where the answer to the above questions is "no",
i.e. the hook runs prior to recog: Why is this so?

The performance gain is just minimal and sensible INSN_CODE
and recog_data can make it considerably more easy to filter
(u)nwanted insns instead of rewriting parts of recog in the
hook.

Johann
Hans-Peter Nilsson - Aug. 25, 2012, 5:22 p.m.
On Sat, 25 Aug 2012, Uros Bizjak wrote:

> Hello!
>
> v2 patch differences:
> - moves hook description text to target.def
> - fixes error path to clear clobbers, as expected by recog_for_combine callers
>
> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>
> 	* target.def (reject_combined_insn): New target hook.
> 	* doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
> 	* doc/tm.texi: Regenerated.
> 	* combine.c (recog_for_combine): Call targetm.reject_combined_insn
> 	to allow targets to reject combined insn.

Maybe mention that the default is to allow all combinations for
which a pattern match?  And that the reason to disallow them can
be that they're known to result in suboptimal code?  Or other
reasons.

I don't think it should be mentioned that it can be used to stop
invalid code to be generated; that'd just be encouraging
covering up bugs in reload.  (Using it to simplify the port may
be valid.)

brgds, H-P
Uros Bizjak - Aug. 25, 2012, 5:51 p.m.
On Sat, Aug 25, 2012 at 6:54 PM, Georg-Johann Lay <avr@gjlay.de> wrote:

>> Hello!
>>
>> v2 patch differences:
>> - moves hook description text to target.def
>> - fixes error path to clear clobbers, as expected by recog_for_combine
>> callers
>>
>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>
>>         * target.def (reject_combined_insn): New target hook.
>>         * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>         * doc/tm.texi: Regenerated.
>>         * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>         to allow targets to reject combined insn.
>>
>> Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.
>>
>> OK for mainline?

>
> Just a question:
>
> avr.md could use this hook instead of the
> combine_pseudo_register_operand predicate in order to reject
> hard registers in some insns before register allocation.

> Is it valid to use INSN_CODE (insn)?  E.g. compare it against
> CODE_FOR_foo for a light-wight detection of the insn in
> the backend?

No, you have to call recog (note, not recog_memoized) first to get new
INSN_CODE. Note, that clobbers are added to the pattern in
recog_for_combine just before the call to the hook.

> And may recod_data.operands[] et al. be used then?

No, you HAVE to set INSN_CODE of the tested insn and call extract_insn
(insn) in the backend.

> Or is garbage therein and the backend has to call recog on its own?

There is garbage, backend has to do its own call to recog.

> The hook documentation could make this clear.

The hook in fact just receives combined insn, and recog_for_combine
restores insn to original state before exit. Backend can use this insn
as a test site for its (possibly destructive) checks. I agree that the
documentation should say that backend does not need to restore insn to
its original state.

> In the case where the answer to the above questions is "no",
> i.e. the hook runs prior to recog: Why is this so?

Instruction with all its clobbers added to the pattern has not yet
been fully recognized. Backed in free to re-recognize the insn to
obtain its INSN_UID for checks or further processing.

> The performance gain is just minimal and sensible INSN_CODE
> and recog_data can make it considerably more easy to filter
> (u)nwanted insns instead of rewriting parts of recog in the
> hook.

What you are referring to is x86 version of the hook that has to check
for hard register constraints and check passed regs to these
constraints. Where do you see reimplementation of recog?

Uros.
Uros Bizjak - Aug. 25, 2012, 6:21 p.m.
On Sat, Aug 25, 2012 at 7:22 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:

>> v2 patch differences:
>> - moves hook description text to target.def
>> - fixes error path to clear clobbers, as expected by recog_for_combine callers
>>
>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>
>>       * target.def (reject_combined_insn): New target hook.
>>       * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>       * doc/tm.texi: Regenerated.
>>       * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>       to allow targets to reject combined insn.
>
> Maybe mention that the default is to allow all combinations for
> which a pattern match?  And that the reason to disallow them can
> be that they're known to result in suboptimal code?  Or other
> reasons.

Something like this perhaps:

/* Returns true if the combined insn should be rejected
   for some reason.  */
DEFHOOK
(reject_combined_insn,
"Take an instruction in @var{insn} and return @code{true} if the instruction\
 should be rejected as a combination of two or more instructions.  The\
 default is to accept all instructions.",
 bool, (rtx insn),
 hook_bool_rtx_false)

> I don't think it should be mentioned that it can be used to stop
> invalid code to be generated; that'd just be encouraging
> covering up bugs in reload.  (Using it to simplify the port may
> be valid.)

Please note that there is no mention of the specific purpose of this
hook. x86 uses it to counter a specific reload problem, but this is
just hook _implementation_ detail.

Thanks,
Uros.
Georg-Johann Lay - Aug. 25, 2012, 6:25 p.m.
Uros Bizjak schrieb:
> On Sat, Aug 25, 2012 at 6:54 PM, Georg-Johann Lay <avr@gjlay.de> wrote:
> 
>>> Hello!
>>>
>>> v2 patch differences:
>>> - moves hook description text to target.def
>>> - fixes error path to clear clobbers, as expected by recog_for_combine
>>> callers
>>>
>>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>>
>>>         * target.def (reject_combined_insn): New target hook.
>>>         * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>>         * doc/tm.texi: Regenerated.
>>>         * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>>         to allow targets to reject combined insn.
>>>
>>> Bootstrapped and regression tested on x86_64-pc-linux-gnu {,-m32}.
>>>
>>> OK for mainline?
> 
>> Just a question:
>>
>> avr.md could use this hook instead of the
>> combine_pseudo_register_operand predicate in order to reject
>> hard registers in some insns before register allocation.
> 
>> Is it valid to use INSN_CODE (insn)?  E.g. compare it against
>> CODE_FOR_foo for a light-wight detection of the insn in
>> the backend?
> 
> No, you have to call recog (note, not recog_memoized) first to get new
> INSN_CODE. Note, that clobbers are added to the pattern in
> recog_for_combine just before the call to the hook.
> 
>> And may recod_data.operands[] et al. be used then?
> 
> No, you HAVE to set INSN_CODE of the tested insn and call extract_insn
> (insn) in the backend.
> 
>> Or is garbage therein and the backend has to call recog on its own?
> 
> There is garbage, backend has to do its own call to recog.
> 
>> The hook documentation could make this clear.
> 
> The hook in fact just receives combined insn, and recog_for_combine
> restores insn to original state before exit. Backend can use this insn
> as a test site for its (possibly destructive) checks. I agree that the
> documentation should say that backend does not need to restore insn to
> its original state.
> 
>> In the case where the answer to the above questions is "no",
>> i.e. the hook runs prior to recog: Why is this so?
> 
> Instruction with all its clobbers added to the pattern has not yet
> been fully recognized. Backed in free to re-recognize the insn to
> obtain its INSN_UID for checks or further processing.
> 
>> The performance gain is just minimal and sensible INSN_CODE
>> and recog_data can make it considerably more easy to filter
>> (u)nwanted insns instead of rewriting parts of recog in the
>> hook.
> 
> What you are referring to is x86 version of the hook that has to check
> for hard register constraints and check passed regs to these
> constraints. Where do you see reimplementation of recog?

I am thinking of how this new hook could be used in the avr backend.

For some reasons sign/zero source must not be a hard register at
combine time, but combine propagates hard registers into the
input operands.  avr.md disallows that by a predicate:

(define_insn "extendqisi2"
   [(set (match_operand:SI 0 "register_operand" "=r,r")
         (sign_extend:SI
          (match_operand:QI 1 "combine_pseudo_register_operand" "0,*r")))]

With valid data from recog the avr version of the hook would be
something like

if (icode == CODE_FOR_extendqihi2
     || icode == CODE_FOR_extendqipsi2
     || icode == CODE_FOR_extendqisi2
     || ...=
   {
     if (REGNO (recog_data[icode].operands[1]) < FIRST_PSEUDO_REGISTER)
       return true;
   }

without you have to look into the insn anatomy:

if (single_set (insn)
     && (SIGN_EXTEND == GET_CODE (SET_SRC (single_set (insn)))
         || ZERO_EXTEND == GET_CODE (SET_SRC (single_set (insn))))
     && REG_P (XEXP (SET_SRC (single_set (insn)), 0))
     && REGNO (XEXP (SET_SRC (single_set (insn)), 0))
        < FIRST_PSEUDO_REGISTER)
   {
     return true;
   }

for complex patterns this will turn to a recog-like XEXP orgy that
is hard to read and maintain.  Ugly.

BTW: while I typed the lines above I find it more natural to
return "true" for good patterns and "false" for bad patterns
and not vice versa.  But that's just a matter of taste.

Johann
Oleg Endo - Aug. 25, 2012, 6:45 p.m.
On Sat, 2012-08-25 at 20:25 +0200, Georg-Johann Lay wrote:

> BTW: while I typed the lines above I find it more natural to
> return "true" for good patterns and "false" for bad patterns
> and not vice versa.  But that's just a matter of taste.

But then that won't fit with 'reject_combined_insn'.
Reject? -> return 'true' for bad pattern that is to be rejected.
Maybe if the hook was called something like
'legitimate_combined_insn'...

Cheers,
Oleg
Georg-Johann Lay - Aug. 25, 2012, 6:59 p.m.
Oleg Endo schrieb:
> On Sat, 2012-08-25 at 20:25 +0200, Georg-Johann Lay wrote:
> 
>> BTW: while I typed the lines above I find it more natural to
>> return "true" for good patterns and "false" for bad patterns
>> and not vice versa.  But that's just a matter of taste.
> 
> But then that won't fit with 'reject_combined_insn'.
> Reject? -> return 'true' for bad pattern that is to be rejected.
> Maybe if the hook was called something like
> 'legitimate_combined_insn'...

Ya, that would be a reasonable name and fit into already existing
targetm.legitimate_foo namings.

Johann
Ian Taylor - Aug. 25, 2012, 7:40 p.m.
On Sat, Aug 25, 2012 at 11:21 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
> On Sat, Aug 25, 2012 at 7:22 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:
>
>>> v2 patch differences:
>>> - moves hook description text to target.def
>>> - fixes error path to clear clobbers, as expected by recog_for_combine callers
>>>
>>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>>
>>>       * target.def (reject_combined_insn): New target hook.
>>>       * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>>       * doc/tm.texi: Regenerated.
>>>       * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>>       to allow targets to reject combined insn.
>>
>> Maybe mention that the default is to allow all combinations for
>> which a pattern match?  And that the reason to disallow them can
>> be that they're known to result in suboptimal code?  Or other
>> reasons.
>
> Something like this perhaps:
>
> /* Returns true if the combined insn should be rejected
>    for some reason.  */
> DEFHOOK
> (reject_combined_insn,
> "Take an instruction in @var{insn} and return @code{true} if the instruction\
>  should be rejected as a combination of two or more instructions.  The\
>  default is to accept all instructions.",
>  bool, (rtx insn),
>  hook_bool_rtx_false)
>
>> I don't think it should be mentioned that it can be used to stop
>> invalid code to be generated; that'd just be encouraging
>> covering up bugs in reload.  (Using it to simplify the port may
>> be valid.)
>
> Please note that there is no mention of the specific purpose of this
> hook. x86 uses it to counter a specific reload problem, but this is
> just hook _implementation_ detail.


What if we just add a global variable during_combine, and the insn
predicates can check that variable?  Then we wouldn't need a new
target hook, one that seems slightly obscure to me.

My apologies if this was already mentioned, I haven't followed the
thread closely.

Ian
Georg-Johann Lay - Aug. 25, 2012, 9:16 p.m.
Ian Lance Taylor schrieb:
> On Sat, Aug 25, 2012 at 11:21 AM, Uros Bizjak <ubizjak@gmail.com> wrote:
>> On Sat, Aug 25, 2012 at 7:22 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:
>>
>>>> v2 patch differences:
>>>> - moves hook description text to target.def
>>>> - fixes error path to clear clobbers, as expected by recog_for_combine callers
>>>>
>>>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>>>
>>>>       * target.def (reject_combined_insn): New target hook.
>>>>       * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>>>       * doc/tm.texi: Regenerated.
>>>>       * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>>>       to allow targets to reject combined insn.
>>> Maybe mention that the default is to allow all combinations for
>>> which a pattern match?  And that the reason to disallow them can
>>> be that they're known to result in suboptimal code?  Or other
>>> reasons.
>> Something like this perhaps:
>>
>> /* Returns true if the combined insn should be rejected
>>    for some reason.  */
>> DEFHOOK
>> (reject_combined_insn,
>> "Take an instruction in @var{insn} and return @code{true} if the instruction\
>>  should be rejected as a combination of two or more instructions.  The\
>>  default is to accept all instructions.",
>>  bool, (rtx insn),
>>  hook_bool_rtx_false)
>>
>>> I don't think it should be mentioned that it can be used to stop
>>> invalid code to be generated; that'd just be encouraging
>>> covering up bugs in reload.  (Using it to simplify the port may
>>> be valid.)
>> Please note that there is no mention of the specific purpose of this
>> hook. x86 uses it to counter a specific reload problem, but this is
>> just hook _implementation_ detail.
> 
> 
> What if we just add a global variable during_combine, and the insn
> predicates can check that variable?  Then we wouldn't need a new
> target hook, one that seems slightly obscure to me.

Instead of a global variable, more information on passes would be a
good thing.

Currently there is reload_completed or reload_in_progress, but
sometimes similar information is needed for other passes like
IRA, split1 or combine.

A reasonable interface would be

compiler->passes->combine->finished
compiler->passes->split1->in_progress

or similar, but currently such a thing. The only way is by comparing
pass numbers; not nice.

Johann


> My apologies if this was already mentioned, I haven't followed the
> thread closely.
> 
> Ian
Hans-Peter Nilsson - Aug. 25, 2012, 9:21 p.m.
On Sat, 25 Aug 2012, Uros Bizjak wrote:
> On Sat, Aug 25, 2012 at 7:22 PM, Hans-Peter Nilsson <hp@bitrange.com> wrote:
> > Maybe mention that the default is to allow all combinations for
> > which a pattern match?  And that the reason to disallow them can
> > be that they're known to result in suboptimal code?  Or other
> > reasons.
>
> Something like this perhaps:
>
> /* Returns true if the combined insn should be rejected
>    for some reason.  */
> DEFHOOK
> (reject_combined_insn,
> "Take an instruction in @var{insn} and return @code{true} if the instruction\
>  should be rejected as a combination of two or more instructions.  The\
>  default is to accept all instructions.",
>  bool, (rtx insn),
>  hook_bool_rtx_false)

Better.

brgds, H-P
Uros Bizjak - Aug. 26, 2012, 6:11 a.m.
On Sat, Aug 25, 2012 at 9:40 PM, Ian Lance Taylor <iant@google.com> wrote:

>>>> v2 patch differences:
>>>> - moves hook description text to target.def
>>>> - fixes error path to clear clobbers, as expected by recog_for_combine callers
>>>>
>>>> 2012-08-25  Uros Bizjak  <ubizjak@gmail.com>
>>>>
>>>>       * target.def (reject_combined_insn): New target hook.
>>>>       * doc/tm.texi.in (TARGET_REJECT_COMBINED_INSN): New hook.
>>>>       * doc/tm.texi: Regenerated.
>>>>       * combine.c (recog_for_combine): Call targetm.reject_combined_insn
>>>>       to allow targets to reject combined insn.
>>>
>>> Maybe mention that the default is to allow all combinations for
>>> which a pattern match?  And that the reason to disallow them can
>>> be that they're known to result in suboptimal code?  Or other
>>> reasons.
>>
>> Something like this perhaps:
>>
>> /* Returns true if the combined insn should be rejected
>>    for some reason.  */
>> DEFHOOK
>> (reject_combined_insn,
>> "Take an instruction in @var{insn} and return @code{true} if the instruction\
>>  should be rejected as a combination of two or more instructions.  The\
>>  default is to accept all instructions.",
>>  bool, (rtx insn),
>>  hook_bool_rtx_false)
>>
>>> I don't think it should be mentioned that it can be used to stop
>>> invalid code to be generated; that'd just be encouraging
>>> covering up bugs in reload.  (Using it to simplify the port may
>>> be valid.)
>>
>> Please note that there is no mention of the specific purpose of this
>> hook. x86 uses it to counter a specific reload problem, but this is
>> just hook _implementation_ detail.
>
>
> What if we just add a global variable during_combine, and the insn
> predicates can check that variable?  Then we wouldn't need a new
> target hook, one that seems slightly obscure to me.

No, in x86 case we need to look at operand constraints of the insn,
and we need to recognize and analyse the insn. This way, we can avoid
i.e. "ax_reg", "nonimm_ax_reg" and such register constraints.

Uros.
Uros Bizjak - Aug. 26, 2012, 6:35 a.m.
On Sun, Aug 26, 2012 at 8:11 AM, Uros Bizjak <ubizjak@gmail.com> wrote:

>> What if we just add a global variable during_combine, and the insn
>> predicates can check that variable?  Then we wouldn't need a new
>> target hook, one that seems slightly obscure to me.
>
> No, in x86 case we need to look at operand constraints of the insn,
> and we need to recognize and analyse the insn. This way, we can avoid
> i.e. "ax_reg", "nonimm_ax_reg" and such register constraints.

Please also note that with "enabled" attribute, operand constraints
are dynamically changed, so predicate would need to track these
changes (i.e. "*umul<mode><dwi>3_1").

BTW: I found the proposed "legitimate_combined_insn" name much more
descriptive, I will update the patch accordingly.

Uros.

Patch

Index: target.def
===================================================================
--- target.def	(revision 190665)
+++ target.def	(working copy)
@@ -1984,7 +1984,16 @@  DEFHOOK
  const char *, (const_rtx insn),
  default_invalid_within_doloop)
 
+/* Returns true if the combined insn should be rejected
+   for some reason.  */
 DEFHOOK
+(reject_combined_insn,
+"Take an instruction in @var{insn} and return @code{true} if the instruction\
+ should be rejected as a combination of two or more instructions.",
+ bool, (rtx insn),
+ hook_bool_rtx_false)
+
+DEFHOOK
 (valid_dllimport_attribute_p,
 "@var{decl} is a variable or function with @code{__attribute__((dllimport))}\
  specified.  Use this hook if the target needs to add extra validation\
Index: combine.c
===================================================================
--- combine.c	(revision 190665)
+++ combine.c	(working copy)
@@ -10500,11 +10500,13 @@  static int
 recog_for_combine (rtx *pnewpat, rtx insn, rtx *pnotes)
 {
   rtx pat = *pnewpat;
+  rtx pat_without_clobbers;
   int insn_code_number;
   int num_clobbers_to_add = 0;
   int i;
-  rtx notes = 0;
+  rtx notes = NULL_RTX;
   rtx old_notes, old_pat;
+  int old_icode;
 
   /* If PAT is a PARALLEL, check to see if it contains the CLOBBER
      we use to indicate that something didn't match.  If we find such a
@@ -10518,7 +10520,7 @@  recog_for_combine (rtx *pnewpat, rtx insn, rtx *pn
   old_pat = PATTERN (insn);
   old_notes = REG_NOTES (insn);
   PATTERN (insn) = pat;
-  REG_NOTES (insn) = 0;
+  REG_NOTES (insn) = NULL_RTX;
 
   insn_code_number = recog (pat, insn, &num_clobbers_to_add);
   if (dump_file && (dump_flags & TDF_DETAILS))
@@ -10564,6 +10566,9 @@  recog_for_combine (rtx *pnewpat, rtx insn, rtx *pn
 	  print_rtl_single (dump_file, pat);
 	}
     }
+
+  pat_without_clobbers = pat;
+
   PATTERN (insn) = old_pat;
   REG_NOTES (insn) = old_notes;
 
@@ -10605,6 +10610,35 @@  recog_for_combine (rtx *pnewpat, rtx insn, rtx *pn
       pat = newpat;
     }
 
+  if (insn_code_number >= 0
+      && insn_code_number != NOOP_MOVE_INSN_CODE)
+    {
+      old_pat = PATTERN (insn);
+      old_notes = REG_NOTES (insn);
+      old_icode = INSN_CODE (insn);
+      PATTERN (insn) = pat;
+      REG_NOTES (insn) = notes;
+
+      /* Allow targets to reject combined insn.  */
+      if (targetm.reject_combined_insn (insn))
+	{
+	  if (dump_file && (dump_flags & TDF_DETAILS))
+	    fputs ("Instruction not appropriate for target.",
+		   dump_file);
+
+	  /* Callers expect recog_for_combine to strip
+	     clobbers from the pattern on failure.  */
+	  pat = pat_without_clobbers;
+	  notes = NULL_RTX;
+
+	  insn_code_number = -1;
+	}
+
+      PATTERN (insn) = old_pat;
+      REG_NOTES (insn) = old_notes;
+      INSN_CODE (insn) = old_icode;
+    }
+
   *pnewpat = pat;
   *pnotes = notes;
 
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 190665)
+++ doc/tm.texi	(working copy)
@@ -10938,6 +10938,10 @@  By default, the RTL loop optimizer does not use a
 loops containing function calls or branch on table instructions.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_REJECT_COMBINED_INSN (rtx @var{insn})
+Take an instruction in @var{insn} and return @code{true} if the instruction should be rejected as a combination of two or more instructions.
+@end deftypefn
+
 @defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2})
 
 Take a branch insn in @var{branch1} and another in @var{branch2}.
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 190665)
+++ doc/tm.texi.in	(working copy)
@@ -10796,6 +10796,8 @@  By default, the RTL loop optimizer does not use a
 loops containing function calls or branch on table instructions.
 @end deftypefn
 
+@hook TARGET_REJECT_COMBINED_INSN
+
 @defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2})
 
 Take a branch insn in @var{branch1} and another in @var{branch2}.