[PATCH, middle-end]: Introduce TARGET_REJECT_COMBINED_INSN target hook

Oleg Endo oleg.endo@t-online.de
Thu Aug 23 18:27:00 GMT 2012


Hello,

On Thu, 2012-08-23 at 19:52 +0200, Georg-Johann Lay wrote:
> 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?

As far as I understand that's what the splits during combine are for.
However, I always get surprised when combine would actually take the
split and continue trying combinations with the insns that came out from
the split, and when it won't.  Sometimes it works, sometimes it doesn't.
Very often I have to resort to insn_and_split, which is similar, but not
the same ... 

> 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.

Do you mean something like already existing CANONICALIZE_COMPARISON
macro?  If so, then probably one would have to match/transform the
patterns in C, which is not 'very nice', IMHO.  Maybe relaxing the
combine-splitting (not insn_and_split, just define_split) would be
better for this?
In any case, if combine doesn't try out all the combinations, then
something would have to do that in the backend and everything is back to
square one, except that every backend (sooner or later) will have some
kind of half-combine-half-recog implementation in it, won't it?

> 
> 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.

I think in this case one could define a predicate for those and then
re-use it in multiple patterns.

As for the costs, it would really be nice if it was possible to just
say: "If this pattern is matched, the total cost is X", instead of
partially re-implementing/describing the patterns in C in the rtx_costs
function.  I was already thinking of using recog functions in the
rtx_costs function, but I'm not sure whether it is the right thing to
do.
I think one of the prime examples that would benefit from those things
are patterns to implement instructions such as bit-tests with constants
(on SH: tst #imm8,R0), where the basic pattern is simply:

(define_insn "tstsi_t"
  [(set (reg:SI T_REG)
	(eq:SI (and:SI (match_operand:SI 0 "logical_operand" "%z,r")
		       (match_operand:SI 1 "logical_operand" "K08,r"))
	       (const_int 0)))]

.. but then 9 variations are required to make it really work under
various circumstances.

Cheers,
Oleg



More information about the Gcc-patches mailing list