Skip to content
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

Units of measure can affect compiled form of integral ranges #17046

Open
brianrourkeboll opened this issue Apr 15, 2024 · 2 comments
Open

Units of measure can affect compiled form of integral ranges #17046

brianrourkeboll opened this issue Apr 15, 2024 · 2 comments
Labels
Area-Compiler-Optimization The F# optimizer, release code gen etc. Feature Improvement
Milestone

Comments

@brianrourkeboll
Copy link
Contributor

When looking into #17025, I found that the presence of units of measure can affect the compiled form of the range (..) and range-step (.. ..) operators. This applies to their use in bare for-loops as well as in computed collections.

When start and finish (for (..)) and start, step, and finish (for (.. ..)) are all literal values, local variables, or parameter values, the compiled form with units of measure is the same as it is without units of measure.

But when any of start, step, or finish is a function call, method call, property access, etc., the compiled form with units of measure diverges from the compiled form without units of measure.

That is, these pairs are compiled identically (as expected):

for n in 1..1..10 do ignore (float n ** float n)
for n in 1<m>..1<m>..10<m> do ignore (float n ** float n)
[1..1..10]
[1<m>..1<m>..10<m>]
[|1..1..10|]
[|1<m>..1<m>..10<m>|]

But these pairs are compiled differently:

let f1 g = for n in g ()..1..10 do ignore (float n ** float n)
let f2 g = for n in g ()..1<m>..10<m> do ignore (float n ** float n)
let f3 g = [g ()..1..10]
let f4 g = [g ()..1<m>..10<m>]
let f5 g = [|g ()..1..10|]
let f6 g = [|g ()..1<m>..10<m>|]

This divergence is happening in the compiler somewhere before for-loops or computed collections are optimized, which means that neither the longstanding optimization for integer for-loops over ranges with a step of 1 or -1 nor the new optimizations introduced in #16650 are applied in certain scenarios when units of measure are involved.

I don't believe that this should be the case. Ideally, the presence of units of measure should not affect the compiled form of these constructs.

@T-Gro
Copy link
Member

T-Gro commented Apr 29, 2024

This was fixed by #17048 right?

@brianrourkeboll
Copy link
Contributor Author

This was fixed by #17048 right?

No. This is actually a longstanding difference that also affects the older optimizations (see the second SharpLab link from above).

@abonie abonie added Area-Compiler-Optimization The F# optimizer, release code gen etc. Feature Improvement and removed Needs-Triage labels Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compiler-Optimization The F# optimizer, release code gen etc. Feature Improvement
Projects
Status: New
Development

No branches or pull requests

3 participants