Hi, I tried out the new soft-float support from the mainline. Overall, it looks very nice and pretty clean. It is now extremely easy to add the soft-float support for your target. Just do not call addRegisterClass() for your FP types and they will be expanded into libcalls. But there are several minor things that would be still nice to have: a) It is not possible to express that: - f32 and f64 are both illegal and therefore are mapped to integers - but only f64 is emulated on the target and there are no f32 arithmetic libcalls available (which is the case on our target) To make it possible, f32 should be always promoted first to f64 and then an f64 operation should be applied. I see a small problem here with the current code, since f32 should be promoted to the illegal type f64. It might require some special-case handling eventually. For example, what should be the result getTypeToTransformTo(f32)? On the one hand, it is f64. On the other hand it is illegal. b) LLVM currently uses hard-wired library function names for FP libcalls (and ALL other libcalls as well). It would be nice if they would be customizable, since some targets (e.g. some embedded systems) have some existing naming conventions that are to be followed and cannot be changed. For example, on our embedded target all libcalls for soft-float and some integer operations have very target-specific names for historical reasons. TargetLowering class specific for a target could be extended to handle that and this would require only minor changes. c) LLVM libcalls currently pass their parameters on stack. But on some embedded systems FP support routines expect parameters on specific registers. At the moment, SelectionDAGLegalize::ExpandLibCall() explicitly uses CallingConv::C, but it could be made customizable by introducing a special libcall calling convention or even better by allowing the target specific lowering of libcalls. Actually it can be combined with the solution for (b). In this case target-specific lowering can take care about names of libcalls and also how they handle their parameters and return values. d) Would it be possible with current implementation of soft-float support to map f32/f64 to integer types smaller than i32, e.g. to i16? I have the impression that it is not necessarily the case, since it would require that f64 is split into 4 parts. This question is more about a theoretical possibility. At the moment my embedded target supports i32 registers. But some embedded systems are still only 16bit, which means that they would need something like this. I'm wondering, how easy or difficult would it be to support such a mapping to any integer type? My impression is that (b) and (c) are very easy to implement, but (a) and (d) could be more chellenging. Evan, I guess you are the most qualified person to judge about this, since you implemented the new soft-float support. What do you think about these extension proposals? -Roman --- Roman Levenstein <romixlev at gmail.com> wrote:> > Date: Tue, 19 Dec 2006 22:13:08 +0100 > From: Roman Levenstein <romixlev at yahoo.com> > To: Chris Lattner <sabre at nondot.org> > Subject: Re: Soft-float > > Hi Chris, > > > BTW, in mainline CVS, the LLVM legalizer now supports expanding > > floating point types to integer types and inserting GCC-style > > libcalls for soft-float. Please ask on the mailing list if you > > have any questions, > > Oh, nice to know! Thanks for this info! Actually didn't have too much > > time for LLVM hacking recently, since I had a lot of business trips. > But > just last week I got a working version of soft-floats using both > approaches: a simple post code selection pass and my legalizer-based > solution. The second one was much more complex to implement, noy very > "clean" and affected many different places of the CodeGen. I haven't > done any performance comparisions yet to see if legalizer-based > approach really brings any significant wins. > > I'll have a look at the mainline and compare it to my implementation > to see the differences between them. I'll also try to formulate some > questions and report about my experiences while changing the LLVM > legalizer to support it. > > -Roman > >__________________________________________________ Do You Yahoo!? Tired of spam? Yahoo! Mail has the best spam protection around http://mail.yahoo.com
On Wed, 20 Dec 2006, Roman Levenstein wrote:> Overall, it looks very nice and pretty clean. It is now extremely easy > to add the soft-float support for your target. Just do not call > addRegisterClass() for your FP types and they will be expanded into > libcalls.Great.> a) It is not possible to express that: > - f32 and f64 are both illegal and therefore are mapped to integers > - but only f64 is emulated on the target and there are no f32 > arithmetic libcalls available (which is the case on our target) > > To make it possible, f32 should be always promoted first to f64 and > then an f64 operation should be applied.Ok. This shouldn't be the default behavior (because it will generate significantly less efficient code for targets that have both) but we should support this.> I see a small problem here with the current code, since f32 should be > promoted to the illegal type f64. It might require some special-case > handling eventually. For example, what should be the result > getTypeToTransformTo(f32)? On the one hand, it is f64. On the other > hand it is illegal.I think getTypeToTransformTo(f32) should return f64. That would be recursively expanded to i64, then to 2x i32 if needed. I haven't looked at the mechanics required to get this working, but it shouldn't be too ugly.> b) LLVM currently uses hard-wired library function names for > FP libcalls (and ALL other libcalls as well). It would be nice if > they would be customizable, since some targets (e.g. some embedded > systems) have some existing naming conventions that are to be followed > and cannot be changed. For example, on our embedded target all libcalls > for soft-float and some integer operations have very target-specific > names for historical reasons. > > TargetLowering class specific for a target could be extended to handle > that and this would require only minor changes.Yes, TargetLowering would be a natural place to put this. Patches welcome :)> c) LLVM libcalls currently pass their parameters on stack. But on some > embedded systems FP support routines expect parameters on specific > registers. > At the moment, SelectionDAGLegalize::ExpandLibCall() explicitly uses > CallingConv::C, but it could be made customizable by introducing a > special libcall calling convention or even better by allowing the > target specific lowering of libcalls. Actually it can be combined with > the solution for (b). In this case target-specific lowering can take > care about names of libcalls and also how they handle their parameters > and return values.Yep, TargetLowering can have a pair for each libcall: a function name and a calling convention to use. Patches welcome :)> d) Would it be possible with current implementation of soft-float > support to map f32/f64 to integer types smaller than i32, e.g. to i16? > I have the impression that it is not necessarily the case, since it > would require that f64 is split into 4 parts.Yes, this should be fine.> This question is more about a theoretical possibility. At the moment > my embedded target supports i32 registers. But some embedded systems > are still only 16bit, which means that they would need something like > this. > I'm wondering, how easy or difficult would it be to support such a > mapping to any integer type?It should be transparently handled by the framework. Basically, you'd get: f32 -> f64 -> i64 -> 2x i32 -> 4x i16 If you don't add a register class for i32 or i64, but you do have one for i16, legalize will already 'expand' them for you. Note that we don't have any 16-bit targets in CVS, so there may be minor bugs, but the framework is all there. Duraid was working on a 16-bit port at one point (and reported a few bugs, which were fixed) but it was never contributed. -Chris -- http://nondot.org/sabre/ http://llvm.org/
> >> d) Would it be possible with current implementation of soft-float >> support to map f32/f64 to integer types smaller than i32, e.g. to >> i16? >> I have the impression that it is not necessarily the case, since it >> would require that f64 is split into 4 parts. > > Yes, this should be fine. > >> This question is more about a theoretical possibility. At the >> moment >> my embedded target supports i32 registers. But some embedded systems >> are still only 16bit, which means that they would need something like >> this. >> I'm wondering, how easy or difficult would it be to support such a >> mapping to any integer type? > > It should be transparently handled by the framework. Basically, you'd > get: > > f32 -> f64 -> i64 -> 2x i32 -> 4x i16 > > If you don't add a register class for i32 or i64, but you do have > one for > i16, legalize will already 'expand' them for you. >This will probably require a slightly more extensive patch to legalizer. The current mechanism assumes either 1->1 or 1->2 expansion. It also assumes the result of expansion are of legal types. That means, you will have to either 1) modify ExpandOp() to handle cases which need to be recursively expanded or 2) modify it to return a vector of SDOperand's. Solution one is what I would pursue. It's not done simply because there isn't a need for it right now. :-) Evan> > -Chris > > -- > http://nondot.org/sabre/ > http://llvm.org/ > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev