Mike Stump schrieb:
On May 3, 2012, at 12:50 PM, Georg-Johann Lay wrote:
It's hardly possible to write proper rtx_costs for SET:
1) What should be the cost of (const_int 1) if you don't see the
machine mode? Is it QI, is it HI, is it SI or whatever?
You can choose to see the complete expression in its entirety and
form the cost for it.
(set (reg:DI 1) (const_int 1))
Sorry, for the dumb question, but I still don't get it.
TARGET_RTX_COSTS gets called with x = (const_int 1) and outer = SET
for example. How do I get SET_DEST from that information?
I don't now if lower-subreg.s ever emits such cost requests, but several
passes definitely do.
is a DI mode set of register 1, with the value 1. This can have a
different cost, from the perspective of the cost function from:
(set (reg:SI 1 (const_int 1))
or even
(set (reg:SI 1 (const_int 2))
or
(set (reg:SI 2 (const_int 1))
though, little else in the compiler would help mitigate such
differences. Just return a non-zero value from the cost function.
If you return zero, you are saying that you don't care, or that the
costs compose in a simplistic manner. Try returning 1, and figuring
out the total cost of the entire expression yourself, if the
simplistic answer is wrong.
TARGET_RTX_COSTS does not mention the "0 = don't know" in any way.
There are post-reload passes that mention it in source comments, yes.
2) If the target will be a REG, what is the register class for the
assignment?
Hard register has a class associated with it that can be found with
REGNO_REG_CLASS (REGNO (x)). If the register [...]
Thanks for the detailed explanation.
But again the question was for the case when TARGET_RTX_COSTS is called
with outer = SET and x = (const_int ?).
then, no class has been chosen for it yet, and the register allocator
can choose any valid class it wants for the mode. I suspect you're
better off explaining the average cost (or maybe even the best case
cost), when multiple choices exist. In general, someone else should
check later the true cost of the operation based upon the class and
should be willing to influence the code generated (the class picked),
so what you return for rtx_costs shouldn't matter too much.
rtx_costs are called after reload, so it would be good to know. It
would be good to know if it is a pseudo or hard reg.
HARD_REGISTER_NUM_P (REGNO (x)) will tell you if it is hard. The
inverse of this will tell you if is isn't hard, aka, a pseudo.
And in many places the backend does not know where it is standing.
Is it upon expanding? Prior or after combine? Or split1?
I think the idea is to give the cost of the rtl it asks for.
(set (reg:SI 1) (const_int 0))
should have the same cost, before reload, after reload, during
optimization, just before final, or at expand time.
Just grepped a log from avr-gcc -mlog=rtx_costs but there was
not a single line with outer=pattern.
In some cases like insn-combine where there is a complete pattern,
synthesized from several insns, but just SET_DEST is passed to
rtx_costs hiding informations from the backends in an unnecessary
way; presumably for historical reasons.
There are machines with complex instructions sets like 4-operand
OR and combined OR and SHIFT or similar. Instead of writing
hundreds or thousands of lines in rtx_costs and XEXP TARGET_RTX_COSTS
(effectively rewriting insn-recog.c) it would be straight forward
to attach costs to insns and use recog + insn_attr to get the costs.
I tried that approach (write costs as insn attribute and use recog
to get the costs) in a backend and it works smooth and really helped
to keep the backend clean and maintainable.
3) Likewise, the costs of MEM are peeled of MEM and pass just the
address without any information on the MEM like it's address space.
Cost might highly depend on the address space involved.
Yes, that is why on my machine:
(set (mem) (reg))
has one set of costs, and
(set (reg) (mem))
What hook are we talking about?
TARGET_RTX_COSTS? (not called with outer=PATTERN)
TARGET_MEMORY_MOVE_COST? (uses register classes)
TARGET_ADDRESS_COST (no address space available as MEM was peeled)
has a completely different set of costs. The address space, if it
influences the cost, can be had with:
MEM_ADDR_SPACE (XEXP (x, 0))
or a store, and:
MEM_ADDR_SPACE (XEXP (x, 1))
for a load.
The original PR is because split of mem:HI is fine -- if it reads
from generic. And splitting mem:HI is complete bloat for other
address spaces. Likewise for wider modes like PSI, SI, ...
The you will want to check the mode of the MEM, and address space
involved.
The issue is to *get* the MEM.
To hack around PR52543 for PSImode (there is just one AS that uses
PSImode addresses), I used TARGET_MODE_DEPENDENT_ADDRESS_P, see
respective FIXME in avr.c.
But again no avail to get the AS. AS is attached to the MEM, not
to the address, i.e. XEXP (mem, 0) which is passed to that hook.
Thanks for all your detailed descriptions.
Johann