Re: Determining live registers on Cmm procedure entry?
Geoffrey Mainland <[email protected]>
| Newsgroups | gmane.comp.lang.haskell.cvs.ghc |
|---|---|
| Message-ID | <[email protected]> |
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