<p dir="ltr">I think Geoffrey's suggestion is workable, but I wouldn't like it so much. The difficulty is that if you aren't aware of it, it's possible to build up a large system that you discover is unworkable the first time you try to compile it. </p>
<p dir="ltr">In that sense it's not too different from Template Haskell staging restrictions, which IIRC exist to deal with exactly this problem. </p>
<p dir="ltr">As the necessity of compile-time constants has shown up at least twice, a more principled solution is worth investigating. </p>
<p dir="ltr">In the meantime, a horrible hack would be something like:</p>
<p dir="ltr"> newtype CStatic v = CStatic ExpQ<br>
instance Num a => Num ( CStatic a) where<br>
fromInteger x = [| x |]</p>
<p dir="ltr">and then the value could be spliced at the call site. Staging restrictions would ensure it's available at compile time. I guess the instance decl needs Lift too. </p>
<p dir="ltr">Downsides are general hideous-ness, misleading error messages, and the necessity for compiling with template haskell. But you'd get an error if s value isn't a compile-time constant. (Please don't put this in ghc, but it's not so bad as a separate lib).</p>
<p dir="ltr">John L.</p>
<div class="gmail_quote">On Sep 19, 2013 3:44 PM, "Geoffrey Mainland" <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If you pass a constant, unboxed value to a primop, I assume GHC won't<br>
ever bind the argument to a value. So although we have no way to enforce<br>
"static const argument" in the type system, if this is a valuable (and<br>
experts-only?) operation, I'm not sure it matters that much if the user<br>
gets an error at code-generation time complaining about non-const arguments.<br>
<br>
Another way to look at it: if we wait until someone enhances the type<br>
system to support the notion of static arguments, we will likely never<br>
have a bit shuffle primitive.<br>
<br>
The other option would be to fall back on a different implementation if<br>
we saw a non-constant argument. I think that would actually be worse<br>
than erroring out, but I'm sure others would disagree.<br>
<br>
Geoff<br>
<br>
On 09/19/2013 11:42 AM, Carter Schonwald wrote:<br>
> tldr; we can't express / expose the LLVM shuffleVector intrinsic in a<br>
> type safe way that will correctly interact with the static argument<br>
> requirement for associated code generation.<br>
><br>
><br>
><br>
><br>
> On Thu, Sep 19, 2013 at 12:40 AM, Carter Schonwald<br>
> <<a href="mailto:carter.schonwald@gmail.com">carter.schonwald@gmail.com</a> <mailto:<a href="mailto:carter.schonwald@gmail.com">carter.schonwald@gmail.com</a>>> wrote:<br>
><br>
> yup, i hit a gap in what we can currently express in haskell<br>
> types. We don't have a way of expressing static data! I actually<br>
> put ticket on trac noting<br>
> this. <a href="http://ghc.haskell.org/trac/ghc/ticket/8107" target="_blank">http://ghc.haskell.org/trac/ghc/ticket/8107</a><br>
> (note that when i was initially writing the ticket, i incorrectly<br>
> thought the int# arg to ghc's prefetch was the locality level<br>
> rather than a byte offset)<br>
><br>
> Currently GHC has no way of expressing "this argument needs to be<br>
> a static compile/codegen time constant" in surface haskell or<br>
> core! This means we could at best provide a suite of special cased<br>
> operations. (eg: we could provide the inter-lane shuffle for<br>
> swapping halves of YMM registers, and the miniature analogue for<br>
> XMM), but that would really be missing the point: being able to<br>
> write complex algorithms that can work completely in registers!<br>
><br>
> the vast majority of the simd shuffle operations have certain<br>
> arguments that need to be compile time static values that are used<br>
> in the actual code generation. The llvm data model doesn't express<br>
> this constraint. This invariant failure was also hit internally<br>
> recently via a bug in how GHC generated code for llvm's<br>
> memcopy! <a href="http://ghc.haskell.org/trac/ghc/ticket/8131" target="_blank">http://ghc.haskell.org/trac/ghc/ticket/8131</a><br>
><br>
> If we could express llvm'sshuffleVector<br>
> <<a href="http://llvm.org/docs/LangRef.html#shufflevector-instruction" target="_blank">http://llvm.org/docs/LangRef.html#shufflevector-instruction</a>><br>
> intrinsic in a type safe way, then we could express any of them. I<br>
> would be over the moon if we could expose an operation like<br>
> shuffleVector, but I dont' think GHC currently can express it in a<br>
> type safe way that won't make LLVM vomit.<br>
><br>
> I want simd shuffle, but i don't see how to give the fully general<br>
> shuffle operations in type safe ways with ghc currently. We need<br>
> to add support for some notion of static data first! If theres a<br>
> way, i'm all for it, but I don't see such a way.<br>
><br>
> I hope that answers your question. that seems to be a deep enough<br>
> issue that theres no way to resolve it with simple engineering in<br>
> the next few weeks.<br>
><br>
> -Carter<br>
><br>
><br>
><br>
><br>
> On Wed, Sep 18, 2013 at 9:41 PM, Geoffrey Mainland<br>
> <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>> wrote:<br>
><br>
> On 09/18/2013 04:49 PM, Carter Schonwald wrote:<br>
> > I've some thoughts on how to have a better solution, but<br>
> they are<br>
> > feasible only on a time scale suitable for 7.10, and not for<br>
> 7.8.<br>
> ><br>
> > a hacky solution we could do for 7.8 perhaps is have a<br>
> warning that<br>
> > works as follows:<br>
> ><br>
> > either<br>
> > a)<br>
> > throw a warning on functions that use the SIMD primops, if that<br>
> > function is being exported by a module, and that function<br>
> isn't marked<br>
> > NOINLINE ? Theres probably a few subtleties to it, and this<br>
> is just a<br>
> > naive idea<br>
> That wouldn't inform the consumers of a module. And for a<br>
> library like<br>
> vector, we definitely want to export unfoldings for code that<br>
> contains<br>
> SIMD primops. That's the only way to get good code out of the<br>
> library!<br>
> > b) somehow put both the -fllvm and -fasm core for inlineable<br>
> functions<br>
> > in the .hi file? (this one prevents the most problems, but<br>
> is probably<br>
> > the most complex work around we could do).<br>
> The problem being that there *is* no -fasm code...because the NCG<br>
> doesn't support SIMD operations. Unless we added a mechanism<br>
> to have two<br>
> completely different, but simultaneous, definitions for a<br>
> function, one<br>
> for -fasm and one for -fllvm. But that would be a lot of work and<br>
> couldn't be done for 7.8.<br>
> ><br>
> ><br>
> > its worth noting that the LLVM simd in 7.8, either way,<br>
> won't support<br>
> > simd shuffles, which will seriously curtail its general utility,<br>
> > either way.<br>
><br>
> You told me you would send me example use cases, type<br>
> signatures, etc.<br>
> Did I miss an email? If this is very important to you, was there a<br>
> particular difficulty you had implementing these primops?<br>
><br>
> > On Wed, Sep 18, 2013 at 4:22 PM, Simon Marlow<br>
> <<a href="mailto:marlowsd@gmail.com">marlowsd@gmail.com</a> <mailto:<a href="mailto:marlowsd@gmail.com">marlowsd@gmail.com</a>><br>
> > <mailto:<a href="mailto:marlowsd@gmail.com">marlowsd@gmail.com</a> <mailto:<a href="mailto:marlowsd@gmail.com">marlowsd@gmail.com</a>>>> wrote:<br>
> ><br>
> > On 18/09/13 20:01, Geoffrey Mainland wrote:<br>
> ><br>
> > We did discuss this, but you may not have been present.<br>
> ><br>
> > If LLVM-only primops show up in a non-LLVM codegen,<br>
> a "sorry"<br>
> > error is<br>
> > reported telling the user that they need to compile with<br>
> > "-fllvm". Yes,<br>
> > this is not a fantastic solution. Options I see:<br>
> ><br>
> > 1) Live with the error message.<br>
> > 2) Remove all SIMD support until the NCG catches up.<br>
> > 3) Figure out a mechanism that avoids inlining any<br>
> code containing<br>
> > LLVM-only primops when we're not using the LLVM back<br>
> end.<br>
> ><br>
> > Maybe you can think of another solution?<br>
> ><br>
> ><br>
> > Those are the three unsatisfactory solutions that I know<br>
> of. Even<br>
> > if we did (3), the user still wants to know when that is<br>
> happening<br>
> > because they're getting less good code, so you'd want a<br>
> warning.<br>
> ><br>
> > One thing we might try to do is automatically enable<br>
> -fllvm when<br>
> > the compilation would otherwise fail. If LLVM isn't<br>
> installed and<br>
> > the compilation still fails, it's no worse than failing<br>
> to compile<br>
> > the module with the sorry error.<br>
> ><br>
> > Simon<br>
> ><br>
> ><br>
> ><br>
> > Geoff<br>
> ><br>
> > On 09/18/2013 02:54 PM, Simon Marlow wrote:<br>
> ><br>
> > This is slightly problematic. What if we have a<br>
> wonderful<br>
> > SIMD-enabled vector library that we compile with<br>
> -fllvm,<br>
> > and then use<br>
> > it in a program that isn't compiled with -fllvm,<br>
> and some<br>
> > of the<br>
> > wonderful SIMD-enabled functions get inlined?<br>
> Presumably<br>
> > we get a<br>
> > panic in the NCG.<br>
> ><br>
> > Did we discuss this before? I have vague<br>
> memories, but<br>
> > don't remember<br>
> > what the outcome was.<br>
> ><br>
> > Cheers,<br>
> > Simon<br>
> ><br>
> > On 12/09/13 03:10, Geoffrey Mainland wrote:<br>
> ><br>
> > We support compiling some code with -fllvm<br>
> and some<br>
> > not in the same<br>
> > executable. Otherwise how could users of the<br>
> Haskell<br>
> > Platform link their<br>
> > -fllvm-compiled code with<br>
> native-codegen-compiled<br>
> > libraries like<br>
> > base, etc.?<br>
> ><br>
> > In other words, the LLVM and native back<br>
> ends use the<br>
> > same calling<br>
> > convention. With my SIMD work, they still<br>
> use the same<br>
> > calling<br>
> > conventions, but the native codegen can<br>
> never generate<br>
> > code that uses<br>
> > SIMD instructions.<br>
> ><br>
> > Geoff<br>
> ><br>
> > On 09/11/2013 10:03 PM, Johan Tibell wrote:<br>
> ><br>
> > OK. But that doesn't create a problem<br>
> for the code<br>
> > we output with the<br>
> > LLVM backend, no? Or do we support<br>
> compiling some<br>
> > code with -fllvm and<br>
> > some not in the same executable?<br>
> ><br>
> ><br>
> > On Wed, Sep 11, 2013 at 6:56 PM,<br>
> Geoffrey Mainland<br>
> > <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>>>> wrote:<br>
> ><br>
> > We definitely have interop between the<br>
> > native codegen and the LLVM<br>
> > back<br>
> > end now. Otherwise anyone who<br>
> wanted to use<br>
> > the LLVM back end<br>
> > would have<br>
> > to build GHC themselves. Interop<br>
> means that<br>
> > users can install the<br>
> > Haskell Platform and still use<br>
> -fllvm when<br>
> > it makes a performance<br>
> > difference.<br>
> ><br>
> > Geoff<br>
> ><br>
> > On 09/11/2013 07:59 PM, Johan<br>
> Tibell wrote:<br>
> > > Do nothing different than you're<br>
> doing for<br>
> > 7.8, we can sort<br>
> > it out<br>
> > > later. Just put a comment on the<br>
> primops<br>
> > saying they're<br>
> > LLVM-only. See<br>
> > > e.g.<br>
> > ><br>
> > ><br>
> > ><br>
> ><br>
> ><br>
> <a href="https://github.com/ghc/ghc/blob/master/compiler/prelude/primops.txt.pp#L181" target="_blank">https://github.com/ghc/ghc/blob/master/compiler/prelude/primops.txt.pp#L181</a><br>
> > ><br>
> > > for an example how to add docs<br>
> to primops.<br>
> > ><br>
> > > I don't think we need interop<br>
> between the<br>
> > native and the LLVM<br>
> > > backends. We don't have that now<br>
> do we<br>
> > (i.e. they use different<br>
> > > calling conventions).<br>
> > ><br>
> > ><br>
> > ><br>
> > > On Wed, Sep 11, 2013 at 4:51 PM,<br>
> Geoffrey<br>
> > Mainland<br>
> > > <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>>>>><br>
> > wrote:<br>
> > ><br>
> > > On 09/11/2013 07:44 PM,<br>
> Johan Tibell<br>
> > wrote:<br>
> > > > On Wed, Sep 11, 2013 at<br>
> 4:40 PM,<br>
> > Geoffrey Mainland<br>
> > > <<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>><br>
> > <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a><br>
> <mailto:<a href="mailto:mainland@apeiron.net">mainland@apeiron.net</a>>>>>><br>
> > wrote:<br>
> > > > > Do you mean we need a<br>
> reasonable<br>
> > emulation of the SIMD<br>
> > primops for<br>
> > > > > the native codegen?<br>
> > > ><br>
> > > > Yes. Reasonable in the<br>
> sense that it<br>
> > computes the right<br>
> > result.<br>
> > > I can<br>
> > > > see that some code might<br>
> still want<br>
> > to #ifdef (if the<br>
> > fallback isn't<br>
> > > > fast enough).<br>
> > ><br>
> > > Two implications of this<br>
> requirement:<br>
> > ><br>
> > > 1) There will not be SIMD in<br>
> 7.8. I<br>
> > just don't have the<br>
> > time. In fact,<br>
> > > what SIMD support is there<br>
> already<br>
> > will have to be<br>
> > removed if we<br>
> > > cannot<br>
> > > live with LLVM-only SIMD<br>
> primops.<br>
> > ><br>
> > > 2) If we also require<br>
> interop between<br>
> > the LLVM back-end and<br>
> > the native<br>
> > > codegen, then we cannot pass<br>
> any SIMD<br>
> > vectors in<br>
> > registers---they all<br>
> > > must be passed on the stack.<br>
> > ><br>
> > > My plan, as discussed with<br>
> Simon PJ,<br>
> > is to not support SIMD<br>
> > primops at<br>
> > > all with the native codegen.<br>
> If there<br>
> > is a strong feeling<br>
> > that<br>
> > > this *is<br>
> > > not* the way to go, the I<br>
> need to know<br>
> > ASAP.<br>
> > ><br>
> > > Geoff<br>
> > ><br>
> > ><br>
> > ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
> ><br>
><br>
><br>
><br>
<br>
_______________________________________________<br>
ghc-devs mailing list<br>
<a href="mailto:ghc-devs@haskell.org">ghc-devs@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/ghc-devs" target="_blank">http://www.haskell.org/mailman/listinfo/ghc-devs</a><br>
</blockquote></div>