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.