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 <[email protected]>
>
> * 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.