On 10/16/2012 06:36 PM, David Terei wrote:
What is the problem you face? That you want to allow passing a dynamic
number of float or double arguments? I assume you are keeping it fixed
at 6 still but want to allow those 6 to be either 6 floats, 6 doubles
or any other combination. (Long term is anything that can be put in a
xmm* register...)

Correct, Floats and Doubles for now, and later on SSE vectors (128-bits,
xmm*), then AVX (256-bits, ymm*, overlap with xmm*).

Why do you want Cmm liveness on entry? Is it simply to solve the above
so you can generate specialized function types instead of the
universal one the LLVM backend uses?

Yup :)

If so, have you tried just using the most general universal type?
e.g., how badly is the generated code affected if you have all
arguments be Doubles and then do type casts on jumps and function
entries?

I thought about this and may try it yet. On x86-64 at least, we could
just pass the D* registers on jumps and load Fn_Var from Dn_Arg on
function entry, with an appropriate bitcast. Later on, we would pass
only the X16 registers, which hold 128-bit wide vectors, and load F*_Var
and D*_Var from X16*_Arg with bitcasts.

Sadly, I believe this would require platform-specific LLVM-code if we
were ever to support, say, Sparc compilation via LLVM. On Sparc, each
double-precision register can be used as *two* single-precision
registers, so Fn_Var would no longer be loaded from Dn_Arg, but from the
appropriate half of D(n/2)_Arg. I would like to avoid this.

As a side note, it is slightly unfortunate that the LLVM calling
convention spec requires passing SpLim after the R* registers--ideally
the LLVM back end would pass all registers that are always live
first. With the way things currently are, I still have to always pass
all the R* registers even if they aren't used as arguments by the
callee.

This is the original commit I wrote for tracking STG reg liveness:
4384e146640230399b38cd62e8e5df391f72c3a7
This is the one Simon Marlow wrote to do the same but in the new code
gen: c6a61235aa0baf6f9e8a41c5a771ccc7e32c23a5

I'd suggest you look at these commits and they should show you where
to get the information from. (I can't remember anymore sorry).

Thanks for the pointers. I've already rewritten the register allocator,
so I know where the information comes from...it just seems to get lost
when procedures are created. I was hoping there was a function somewhere
that could take a CmmProc and tell me what registers it expected live on
entry, but I don't think such a thing exists. My dumb attempt at writing
such a function is quickly becoming a full abstract interpreter, so I
think my best bet is to change CmmProc to include live register info. If
this turns out to be too painful I may go back to the bitcast idea.

Cheers,
David

On 16 October 2012 03:45, Geoffrey Mainland <[email protected]> wrote:
Hi all,

I'm working on changing GHC's calling convention to support overlapping
register classes. On x86-64 this will mean that a function can receive up to
six Float/Double arguments (any mixture) in registers. Right now only two
Double arguments can be passed in registers on x86-64, even if a function
takes zero Float arguments---the register classes for Floats and Doubles
cannot overlap even though both are passed in xmm* registers.

This is working fine with the native back-end, but I'm not sure how to get
it working with the LLVM back-end. Right now LLVM translates a Cmm procedure
to an LLVM function of a single universal type( that is, all LLVM functions
that the LLVM back-end produces for Cmm procedures have the same type) that
takes all STG registers as arguments. A Cmm procedure call passes all the
STG registers, although the back-end takes advantage of the liveness
information attached to Cmm jumps to pass undefined values for non-live
registers.

Now that register classes can overlap, I need to change this. Since jumps
have liveness information attached, I can simply pass the live registers.
But when translating Cmm procedures, I need to know which registers are live
on entry to the procedure.

The slightly longer-term goal is to add support for passing SSE vectors in
registers. What I'd like to have ideally is the set of live registers *and
their Cmm types* at each procedure entry and jump. I envision having a
single STG register class, say X16, for all 128-bit-wide SSE registers, but
I'd like the Cmm type information when generating LLVM type signatures so I
can generate the appropriate LLVM types---a 128-bit-wide vector of 32-bit
integers does not have the same type as a 128-bit-wide vector of double
precision floats.

I might be able to do without the Cmm type information by inserting
appropriate casts in the generated LLVM code, but I really need the set of
live registers on entry to a Cmm procedure. I don't see how to get this
unfortunately. Any hints?

Thanks,
Geoff

_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc


_______________________________________________
Cvs-ghc mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/cvs-ghc

Reply via email to