dblaikie added inline comments.

================
Comment at: clang/lib/AST/Interp/Floating.h:27-29
+  template <unsigned ReprBits> struct Repr;
+  template <> struct Repr<32> { using Type = float; };
+  template <> struct Repr<64> { using Type = double; };
----------------
tbaeder wrote:
> dblaikie wrote:
> > jcranmer-intel wrote:
> > > aaron.ballman wrote:
> > > > tbaeder wrote:
> > > > > aaron.ballman wrote:
> > > > > > tbaeder wrote:
> > > > > > > jcranmer-intel wrote:
> > > > > > > > tbaeder wrote:
> > > > > > > > > jcranmer-intel wrote:
> > > > > > > > > > aaron.ballman wrote:
> > > > > > > > > > > Er, how will this extend to `long double` where the 
> > > > > > > > > > > number of bits is rather more difficult?
> > > > > > > > > > Or `half` and `bfloat`, which are both 16-bit 
> > > > > > > > > > floating-point types?
> > > > > > > > > I have spent some time with this today and tried to simply 
> > > > > > > > > always use `APFloat` instead of a primitive type. 
> > > > > > > > > Unfortunately that doesn't work because what we put on the 
> > > > > > > > > stack is not the `Floating` (or `Integral`), but the 
> > > > > > > > > underlying primitive type. So even if we do the final math 
> > > > > > > > > (in `::add`, etc) via `APFloat`, we need something we can 
> > > > > > > > > serialize to `char[]` so we can put it on the stack. Do you 
> > > > > > > > > think that would work?
> > > > > > > > I don't know enough about the structure of the bytecode 
> > > > > > > > interpreter here to say for sure, but this smells to me like 
> > > > > > > > you're baking in an assumption that every primitive target type 
> > > > > > > > has a corresponding primitive type on the host. This assumption 
> > > > > > > > just doesn't hold when it comes to floating point (only two of 
> > > > > > > > the seven types, `float` and `double`, are generally portable, 
> > > > > > > > and even then, there be dragons in some corner cases).
> > > > > > > > 
> > > > > > > > If you do need to continue down this route, there are two 
> > > > > > > > requirements that should be upheld:
> > > > > > > > * The representation shouldn't assume that the underlying 
> > > > > > > > primitive type exists on host (bfloat16 and float128 are better 
> > > > > > > > test cases here).
> > > > > > > > * Conversion to/from host primitive types shouldn't be easy to 
> > > > > > > > accidentally do.
> > > > > > > > 
> > > > > > > > (Worth repeating again that bit size is insufficient to 
> > > > > > > > distinguish floating point types: `bfloat` and `half` are both 
> > > > > > > > 16-bit, PPC `long double` and IEEE 754 quad precision are both 
> > > > > > > > 128-bit, and x86 `long double` is 80 bits stored as 96 bits on 
> > > > > > > > 32-bit and 128 bits on 64-bit.)
> > > > > > > Well, is there a way to convert an APFloat to a char[] that would 
> > > > > > > work instead of going to float/double and storing that? The only 
> > > > > > > thing I see in the docs is `convertToHexString()` (and the docs 
> > > > > > > don't mention whether the conversion is lossy). If not, do you 
> > > > > > > think adding such a conversion to `APFloat` and its various 
> > > > > > > implementations is the better way forward?
> > > > > > Let's avoid serializing the floats to strings so that we can parse 
> > > > > > the string to turn it back into a float later; that's going to have 
> > > > > > poor performance even if we do get all the corner cases correct 
> > > > > > regarding things like rounding, etc.
> > > > > > 
> > > > > > `APFloat` does not have any sort of serialization functionality 
> > > > > > beyond through strings representing the value. I think you'd have 
> > > > > > to invent such an interface.
> > > > > Do you know who I might talk to regrading such an interface, both the 
> > > > > implementation as well as general feasibility?
> > > > I think there may be at least two ways to do this: use an `APFloat` and 
> > > > put the serialization interfaces there, or use an `APValue` and put the 
> > > > serialization interfaces there.
> > > > 
> > > > Because `APFloat` is an ADT in LLVM, I think it should probably go up 
> > > > on Discourse for broader discussion. @chandlerc is still listed as the 
> > > > code owner for ADTs but he's not been active in quite some time. 
> > > > Instead, I would recommend talking to @dblaikie (he's got a good eye 
> > > > for ADT work in general) and @foad, @RKSimon, and @sepavloff as folks 
> > > > who have recently been touching `APFloat`.
> > > > 
> > > > `APValue` is a Clang-specific class, and it already has some amount of 
> > > > serialization support, it seems 
> > > > (https://github.com/llvm/llvm-project/blob/main/clang/include/clang/AST/APValue.h#L54).
> > > >  From a quick look, it seems we're already using `APValue` in a 
> > > > reasonable number of places in the interpreter, so it might make sense 
> > > > to use this object consistently to represent all values in the new 
> > > > interpreter?
> > > Going through `APInt` is already possible in `APFloat`, and that might 
> > > have some methods to go to char arrays.
> > Yeah - IR gets serialized APFloats somehow (maybe through some layers of 
> > indirection) so I'd suggest looking at how, say, a global float named 
> > constant gets lowered to bitcode to see how that APFloat is serialized.
> > 
> > If that's not enough of a pointer for you/others to find something helpful, 
> > I can look further to see what I can find (I got some of the way - a small 
> > example with just `extern const float v; const float v = 3.14;` and 
> > breaking on APFloat's ctor immediately finds the APFLoat being constructed 
> > from that literal - then I looked at llvm::GlobalVariable's ctor, which 
> > does break on the creation of `v`, but didn't continue further to figure 
> > out how the parsed value gets into the IR constant)
> So, I think this is implemented in `emitGlobalConstantFP()`: 
> https://github.com/llvm/llvm-project/blob/main/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp#L3206.
>  I now wonder how to implement this, since the number of chunks isn't fixed. 
> And all this seems rather costly given that we'd have to do this every time 
> we access a floating point value on the stack.
That looks like the lowering to assembly - I meant the lowering to LLVM IR 
bitcode, though perhaps it's similarly complicated.

As for variable length - I expect the strings encoding had variable length too, 
but either relied on null termination or a length prefix. The APFloat 
serialization could use a length prefix encoding to specify how many bytes to 
read/decode (I guess LLVM IR bitcode does something like that - though I think 
the bitcode records always encode their length, so it might be implicit).


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D134859/new/

https://reviews.llvm.org/D134859

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to