Uros Bizjak wrote:
> Hello!
> 
> This patch introduces TARGET_REJECT_COMBINED_INSN target hook, so
> targets are able to reject combinations of two or more insns. The hook
> is called from recog_for_combine, so it is the target that has the
> final say on the combined insn.

Hi,

great place for a hook, it was missing, IMO.

Just a note:  Wouldn't it be good to have a hook that may transform
a pattern to a new one and return that to combine?

Your reject_combined_insn would be a special case, e.g. return
NULL_RTX.

Sometimes recog_for_combine fails (resp. recog fails) because
recog_for_combine does not try all possible transformations and
therefore recog then fails because there is no combine pattern.

However, there may be a pattern that does exactly the same thing
but is written down differently.  The backend then could try to
canonicalize the pattern before it goes into recog.

An other question is:

I always wondered if it is possible to transform code like

(set (reg:SI 0)
     (ior:SI (reg SI:1)
             (reg SI:2)))

or more complicated, combined patterns to a different pattern
if there is some additional knowledge.

For example, a backend may have an insn that can do the
combined operation efficiently, but only if reg2 is a
boolean value (0 or 1).

Currently you will have to write a combine pattern like


(set (reg:SI 0)
     (ior:SI (reg SI:1)
             (and:SI (reg SI:2)
                     (const_int 0))))

and/or

(set (reg:SI 0)
     (ior:SI (reg SI:1)
             (zero_extract:SI (reg:SI 2)
                              (const_int 1)
                              (const_int x)))))

and/or

(set (reg:SI 0)
     (ior:SI (reg SI:1)
             (and:SI (lshiftrt:SI (reg SI:2)
                                  (const_int x))
                     (const_int 1))))

You can imagine that it is really tedious to write
down all these patterns and describe their rtx_costs.

If the targed had a way to say "this transformation is
okay under the condition X" that would be great.

combine collects many information on the values like
ranges and set/unset bits, but that information cannot
be used for matching/rejecting on the insn level,
e.g. in an insn predicate or insn condition.

A Hook would do this:

- If the pattern is to be rejected, return NULL_RTX.

- If the pattern is fine, return it (recog will run on it).

- If the target can make use of additional information,
  it might return the origonal pattern or reject it.
  Here again, recog runs on the pattern (provided the hook
  returned non-NULL).

- The hook may canonicalize the pattern and cook a new one.
  In that case the backend is responsible for a correct
  transformation.  Also in this case recog runs on the
  returned pattern.

Another use case could be to fold away an UNSPEC.

>From the hook perspective, it's no additional work:
Just call the hook from recog_for_combine, receive the
pattern back from the backend, check for NULL_RTX and
then run recog.

Thanks,

Johann


> This target hook will be used in a follow-up x86 patch that rejects
> instructions where hard registers don't fit into operand register
> constraint.
> 
> 2012-08-23  Uros Bizjak  <ubiz...@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.
> 
> OK for mainline?
> 
> Uros.

Reply via email to