-
Notifications
You must be signed in to change notification settings - Fork 239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support vector types in math ops, fixes #45 #47
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look great, thanks! I just had a couple comments on things that stuck out to me.
Also, build_ptr_to_int
and the reverse seem to follow the same pattern we're implementing here? So, I think it's probably fine to add those changes as well
src/builder.rs
Outdated
@@ -254,305 +254,305 @@ impl Builder { | |||
// TODO: Possibly make this generic over sign via struct metadata or subtypes | |||
// SubType: <I: IntSubType>(&self, lhs: &IntValue<I>, rhs: &IntValue<I>, name: &str) -> IntValue<I> { | |||
// if I::sign() == Unsigned { LLVMBuildUDiv() } else { LLVMBuildSDiv() } | |||
pub fn build_int_unsigned_div(&self, lhs: &IntValue, rhs: &IntValue, name: &str) -> IntValue { | |||
pub fn build_int_unsigned_div<T: IntMathValue>(&self, lhs: &T, rhs: &T, name: &str) -> T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The references here are artifacts of a time when *Value
s and *Type
s weren't Copy
. Since you're touching this code, I would greatly appreciate if you could change this and the other methods you modified to take ownership of lhs/rhs trait types.
IE, the signature should be ..., lhs: T, rhs: T, ...
Thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth going through and changing all methods to take ownership, or would you rather I just changed the ones I touched?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just the ones you have touched - I have to look at the remainder on a case by case basis.
src/builder.rs
Outdated
} | ||
|
||
// SubType: <F>(&self, op, lhs: &FloatValue<F>, rhs: &FloatValue<F>, name) -> IntValue<bool> { ? | ||
pub fn build_float_compare(&self, op: FloatPredicate, lhs: &FloatValue, rhs: &FloatValue, name: &str) -> IntValue { | ||
pub fn build_float_compare<T: FloatMathValue>(&self, op: FloatPredicate, lhs: &T, rhs: &T, name: &str) -> <<T::BaseType as FloatMathType>::ConvType as IntMathType>::ValueType { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the issue with build_int_compare
and build_float_compare
returning T
and <<T::BaseType as FloatMathType>::ConvType as IntMathType>::ValueType
(man is that ugly) respectively is that the return type is actually IntValue<bool>
or VecValue<IntValue<bool>>
.
This will be rendered incorrect once subtypes are implemented. IE input of IntValue<32bit>
will return IntValue<32bit>
when it should be IntValue<bool>
I think the way we might need to work around this with subtypes is to add more associated types to go from IntValue<X>
-> IntValue<bool>
& VecValue<IntValue<X>>
-> Vec<IntValue<bool>>
(and likewise for floats) somehow
...so I think this is fine as is, unless you can think of a good way to do that here. I would greatly appreciate adding another comment under the subtype comment either describing the above or pasting the URL to this comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, there's possibly a similar problem with functions like build_int_cast
, if the Type
types are also going to have subtypes.
There's currently an RFC being worked on for generic associated types, which I think would allow us to do something like <<T::BaseType as FloatMathType>::ConvType<bool> as IntMathType>::ValueType
(notice how ConvType
has a generic parameter with the type of integer to 'return') - a similar thing would also work for BaseType
for the cast functions. But yeah, it's pretty ugly.
c4a65ae
to
9fd5cd1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These changes look good to me as is.
That said, would you be willing to write up some tests for the vector math operations? No need for ExecutionEngine type stuff, but it'd be great to have confirmation the API is accepting Vector types as expected (since current tests just use int/floats) and would greatly help with the future subtype refactoring that we planned.
@TheDan64 Yeah, for sure. I was hoping to include tests with the original PR but wasn't actually able to get LLVM to link (Windows ugh). I've managed to get that working in the meantime (since I needed it for the project I've started working on anyway) so I should be able to get those tests in soon :) |
@TheDan64 Tests done :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, thanks for all the help! Will merge this to master now and get the version branches rebased later today
This PR introduces the ability for math functions to take and return vector values in a type-safe way, as discussed in #45. Please note that I'm pretty new to Rust in general, so there are possibly some things here that can be done better :)
Description
The PR primarily introduces two new traits,
FloatMathValue
andIntMathValue
, which are implemented byFloatValue
/VectorValue
andIntValue
/VectorValue
respectively. Applicable methods on theBuilder
have been adjusted to take and return a type that implements these traits - meaning, for example, if you callbuild_float_add
with a vector as the LHS, you must pass a vector for the RHS and you will get a vector back. Since there's no sub-type support yet we can't ensure the passed vectors are actually composed of integers or floats, however I assume this will be a part of 0.2.0.There are some more complicated statements that require both a value and a target type, such as
build_float_to_signed_int
(which takes a floating point and new integer type, and returns an integer). LLVM allows us to pass in a vector as the value here, but also requires in that case that we pass in a vector type - in order to support this, the PR addsFloatMathType
andIntMathType
traits and associated types to navigate between value -> type -> converted type -> value. This means we can ensure the target type is valid (i.e is a vector when the input value is a vector, or an int type otherwise in thebuild_float_to_signed_int
case), at the cost of some long type paths inbuilder.rs
.Note: this PR doesn't implement vector support for functions like
build_ptr_to_int
, although LLVM does support vectors for these functions, since I didn't want to complicate the PR too much. I can add these in if it makes sense though.Breaking Changes
As per one of the requested changes, all math functions now take ownership of their input types/values instead of taking references.
How This Has Been Tested
Due to some weird
llvm-sys
linking issues on my computer, I haven't actually been able to run the test suite (so we'll see if the CI passes :)). However, this PR is entirely type changes and shouldn't affect anything during runtime. Both the tests, the example, and my own personal project compile fine without any changes.Checklist