-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Add bit shift intrinsic functions #8569
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
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.
Thanks!
|
||
internal static int RightShiftUnsigned(int operand, int count) | ||
{ | ||
return operand >>> count; |
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 wasn't aware this existed. Always nice to learn something new!
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 good! Can you please add a "fast path" in this block to avoid having to use reflection when this is called?
msbuild/src/Build/Evaluation/Expander.cs
Lines 3826 to 3835 in 60ea2f7
else if (_receiverType == typeof(IntrinsicFunctions)) | |
{ | |
if (string.Equals(_methodMethodName, nameof(IntrinsicFunctions.EnsureTrailingSlash), StringComparison.OrdinalIgnoreCase)) | |
{ | |
if (TryGetArg(args, out string arg0)) | |
{ | |
returnVal = IntrinsicFunctions.EnsureTrailingSlash(arg0); | |
return true; | |
} | |
} |
@rainersigwald, the existing bitwise operations are not on the fast path either. Presumably because they're not expected to be used very often and, while making the first call faster, every such special case |
In the past we've added any method that is known to be called in the wild to the fast path, but haven't required it, and I suspect the bitwise operations were missed, rather than intentionally omitted. |
…se Shouldly because fail messages will show the name of the failing function
I added a "fast path" for each of the bit operator functions:
In |
Make sense. Also, source generators for the win! It should be a fun project to automatically create efficient lookup tables at compile time. |
I have been fantasizing about doing this for several years now! |
I'm looking at the 'Fast Path'
msbuild/src/Build/Evaluation/IntrinsicFunctions.cs Lines 40 to 55 in b84faa7
The msbuild/src/Build/Evaluation/Expander.cs Lines 3893 to 3900 in b84faa7
There are Shouldn't the It seems that currently |
I don't think this really matters. From a style perspective, it is better to have them all look the same, that is, all call the appropriate member of IntrinsicFunctions as you suggest. From the user's perspective, they're equivalent, and if the call isn't inlined, calling '+' directly may even be (negligibly) faster.
There aren't really "ints," "doubles," etc. in MSBuild; everything is just strings. Even things like TryConvertToInt are kinda misleading, as far as I know, because 'value' won't ever be a double or an int; it'll always be a string, and we'll always parse it as such. With that in mind, if you pass Add two ints, they just turn into doubles, get added, and get converted back to a string that looks like an integer, so people generally don't care too much about whether the arithmetic was actually executed with ints or doubles. Since all ints are doubles, though, we do get them in the fast path. |
@Forgind It sounds like the int overloads of Add, Subtract, Multiply, Divide, and Modulo should be removed because they are never used. |
I wouldn't be opposed to that. The only ways I can think of that someone could actually call them is if they use reflection or MSBuildLocator to specifically load our IntrinsicFunctions class then call the int overload...neither feels at all worthwhile to me, since C# programmers don't need a special function to call something built-in. Can you think of any legitimate reason someone might want to use one of those overloads @rainersigwald? |
It might be considered clean up for supporting the source generation @rainersigwald and @ladipro mentioned. 😊 |
@jrdodds I'm not sure of the impact of some of those removals, and it's late enough in the 17.6 release cycle that I'm nervous about removing them. Can you separate them into a different PR that we can think about for a bit longer? Adding the shift operators and the fast paths is in good shape, though. |
…insicFunctions" This reverts commit 66cb9c1.
@rainersigwald This PR has been updated. |
Fixes #8551
Context
The intrinsic functions include functions for bit And, Or, Xor, and Not operators but not for the bit shift operators.
Changes Made
Added functions LeftShift, RightShift, and RightShiftUnsigned. The functions expect values of type
int
(32 bit) which matches the existing bit operator functions.long
(64 bit) is not supported by any of the bit operator intrinsic functions.Testing
Tested on Windows 11 and macOS 12 Monterey.
Added to Expander_Tests.cs and ran unit tests.
Created and ran BitShift.proj project file with the following content:
The project produced the following output (which matched the expected results):
Notes