-
Notifications
You must be signed in to change notification settings - Fork 825
Optimize in FCS #3784
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
Optimize in FCS #3784
Conversation
what's that outFile? |
/cc @kjnilsson probably also interesting for fez |
Looks fantastic. |
@forki Impressive. I took a very quick glance and it look totally feasible. I thought this would need much more work. |
@dsyme what we need is to flag the optimizer for creating ilasm statements. These are hard to translate back in fable |
@forki IMO we just need to add the missing ILAsm conversions in Exprs.fs. |
Yes that would be awesome
Am 26.11.2017 18:09 schrieb "ncave" <notifications@github.com>:
… @forki <https://github.com/forki> IMO we just need to add the missing
ILAsm conversions in Exprs.fs.
I added a few here
<ncave/FSharp.Compiler.Service@8518748>
as a test, let me know if you want me to submit them to your PR.
Here is a test REPL so you can try them live:
https://ncave.github.io/fable-repl-test
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3784 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADgNC_0YZ5Z8KJ4S9sDLj9nnULD1Korks5s6ZsrgaJpZM4QAm4R>
.
|
So is this already working? Will it be merged? Or can we make a custom build for Fable? I used the Fable.FCS package in the past for that, we could reuse it now 😄 |
@alfonsogarciacaro All good questions idk the answer to. But you can definitely go ahead with a custom build if you want to try it. It's unfortunate that there are no FCS build artefacts for netstandard. |
@alfonsogarciacaro Just FYI if you are custom building the FCS for netstandard, you may have to fix the embedded resource name in the .fsproj a little bit like that:
|
@alfonsogarciacaro There are still a few more ILAsm that need to be properly translated before it can pass all Fable tests, (e.g. I_box, I_call). |
@ncave Thanks a lot for the info! Hmm, I don't remember doing anything in particular last time I did a custom build, but it was FCS repo (which I'm much more familiarized with) not this one. Would it be possible to create a branch with these changes on your FCS fork? |
Dude, do you have any idea how much time I spent to make the FCS build a
nuget from here? ;-)
I just rebased and will try to grab the package from appveyor and update
the fable pr. Then you can test it out. Ok?
Am 29.11.2017 07:18 schrieb "Alfonso Garcia-Caro" <notifications@github.com
…:
@ncave <https://github.com/ncave> Thanks a lot for the info! Hmm, I don't
remember doing anything in particular last time I did a custom build, but
it was FCS repo (which I'm much more familiarized with) not this one. Would
it be possible to create a branch with these changes on your FCS fork?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3784 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADgNETtQz7xkDcvEes87NbOELLq2nNvks5s7PcXgaJpZM4QAm4R>
.
|
Sounds like a plan! Awesome, thank you @forki 👏 🎉 |
Not a problem, but let me add the missing ILAsm translations first. |
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.
This looks a very promising FCS feature. I don't see any outright errors - but we need to add testing.
-
Please find all the places where test assembly contents and also apply optimizations
-
Please check if we have a test that gets the assembly contents for FSharp.Core - I did do that manually but I don't think it's automated - ideally we would add this test and also get the optimized TAST for FSHarp.Core - that is an excellent stress test
src/fsharp/vs/service.fs
Outdated
|
||
member info.AssemblyContents = FSharpAssemblyContents(info.TypedImplementionFiles) | ||
|
||
member info.OptimizedAssemblyContents = |
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.
Please change to GetOptimizedAssemblyContents()
since it involves potentially very long computation (e.g. we don't want it triggering in the debugger when looking at one of these objects)
src/fsharp/vs/service.fs
Outdated
|
||
member info.OptimizedAssemblyContents = | ||
let tcGlobals, thisCcu, tcImports, mimpls = info.TypedImplementionFiles | ||
let outfile = null |
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.
What is outfile
used for and can we pass in a correct (or at least non-null) value here?
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.
Request adding tests etc. per comment above
This is really good - I believe the typeof inversion is the only one I'm concerned about now |
review fixes
more targeted replacements
@dsyme Thanks for the review, here are the changes since:
|
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.
One last set of additions please - can you also expand/multiply out your tests to include instantiations of the basic operators at the full matrix of primitive types? byte, sbyte, ..., UInt64, double, single, decimal, ... We may as well pin the whole lot down now and get everything under test?
added more tests
added even more tests
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 spotted a few cases where the tree being returned was inaccurate
This is extremely close to being done - I looked through everything else and it looked good.
tests/service/ExprTests.fs
Outdated
"let testSByteToSByteOperator(e1) = Operators.ToSByte<Microsoft.FSharp.Core.sbyte> (e1) @ (42,45--42,53)"; | ||
"let testSByteToInt16Operator(e1) = Operators.ToInt16<Microsoft.FSharp.Core.sbyte> (e1) @ (43,45--43,53)"; | ||
"let testSByteToUInt16Operator(e1) = Operators.ToUInt16<Microsoft.FSharp.Core.sbyte> (e1) @ (44,45--44,54)"; | ||
"let testSByteToIntOperator(e1) = e1 @ (45,45--45,51)"; |
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'm a little concerned about this - it looks like the code being returned wouldn't pass type checking. This will be because it's a no-op conversion
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.
There are quite a lot of cases of this. See comment further above in ConvExprPrim for the root cause
src/fsharp/symbols/Exprs.fs
Outdated
|
||
| TOp.ILAsm([ AI_ceq ], _), _, [arg1;arg2] -> | ||
| TOp.ILAsm([ ], _), _, [arg] -> | ||
ConvExprPrim cenv env arg |
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.
This case is used for no-op conversions like sbyte --> int32.
I think in this case you strictly speaking need to insert an appropriately-typed conversion operator in the F# expression based on the type of arg
and the type of expr
BTW ConvExprPrim is getting kind of huge and maybe should be chopped into ConvExprPrim and ConvOpExprPrim
tests/service/ExprTests.fs
Outdated
"let testByteToUInt64Checked(e1) = Checked.ToUInt64<Microsoft.FSharp.Core.byte> (e1) @ (37,43--37,60)"; | ||
"let testByteToIntPtrChecked(e1) = Checked.ToIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (38,43--38,63)"; | ||
"let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (39,43--39,64)"; | ||
"let testByteToByteOperator(e1) = O |
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.
let testInt64ToCharOperator(e1) = Operators.ToUInt16<Microsoft.FSharp.Core.int64> (e1)
This looks wrong. I think the IL instruction sequence is ambiguous and needs to be disamiguated by the type of expr
in ConvExprPrim
tests/service/ExprTests.fs
Outdated
"let testByteToUInt64Checked(e1) = Checked.ToUInt64<Microsoft.FSharp.Core.byte> (e1) @ (37,43--37,60)"; | ||
"let testByteToIntPtrChecked(e1) = Checked.ToIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (38,43--38,63)"; | ||
"let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (39,43--39,64)"; | ||
"let testByteToByteOperator(e1) = O |
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.
Here's another char
one where we've ended up with ToUInt16
(see comment below)
tests/service/ExprTests.fs
Outdated
"let testByteToUInt64Checked(e1) = Checked.ToUInt64<Microsoft.FSharp.Core.byte> (e1) @ (37,43--37,60)"; | ||
"let testByteToIntPtrChecked(e1) = Checked.ToIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (38,43--38,63)"; | ||
"let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (39,43--39,64)"; | ||
"let testByteToByteOperator(e1) = O |
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.
another char --> UInt16 mistake (See comment below)
tests/service/ExprTests.fs
Outdated
"let testByteToUInt64Checked(e1) = Checked.ToUInt64<Microsoft.FSharp.Core.byte> (e1) @ (37,43--37,60)"; | ||
"let testByteToIntPtrChecked(e1) = Checked.ToIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (38,43--38,63)"; | ||
"let testByteToUIntPtrChecked(e1) = Checked.ToUIntPtr<Microsoft.FSharp.Core.byte> (e1) @ (39,43--39,64)"; | ||
"let testByteToByteOperator(e1) = O |
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.
another char/UInt16 mistake (See comment below)
review fixes
The changes are good, thank you! Just a few warnings left I think:
|
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.
A few warnings to remove, but approved - great work on testing and thank you for going the extra distance to make this a robust feature of FCS
I was just sitting here and merging the PRs that went to my fork. Lol
Am 14.02.2018 17:43 schrieb "ncave" <notifications@github.com>:
… @dsyme <https://github.com/dsyme> Thank you for reviewing so thoroughly,
the end result is always so much better for it.
And thank you @forki <https://github.com/forki> for coming up with this
original idea and blazing the trail.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#3784 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AADgNNDSqMogn_v2gDPUePU3tNQfrmzoks5tUw0fgaJpZM4QAm4R>
.
|
fixed warnings
@forki you can offer this as a service to some repos 😉 |
Awesome! This makes me happy |
This is great! Thank you all for your work! 😃 Please take a cookie as thanks 🍪 ! |
"member M2(__) (unitVar1) = __.compiledAsInstanceMethod(()) @ (56,21--56,47)"; | ||
"member SM1(unitVar0) = Operators.op_Addition<Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int,Microsoft.FSharp.Core.int> (compiledAsStaticField,ClassWithImplicitConstructor.compiledAsGenericStaticMethod<Microsoft.FSharp.Core.int> (compiledAsStaticField)) @ (57,26--57,101)"; | ||
"member SM2(unitVar0) = ClassWithImplicitConstructor.compiledAsStaticMethod (()) @ (58,26--58,50)"; | ||
#if NO_PROJECTCRACKER // proxy for COMPILER |
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.
@ncave Do you recall why this was needed? I don't think it's either NO_PROJECTCRACKER nor COMPILER. I'm hitting cases where this test is now failing and I'm not sure what I've 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.
@dsyme This just means the output of FSharp.LanguageService
is slightly different than FCS
, and accounts for that.
These two projects reference FCS
:
fcs/FSharp.Compiler.Service.Tests.netcore/FSharp.Compiler.Service.Tests.netcore.fsproj
fcs/FSharp.Compiler.Service.Tests/FSharp.Compiler.Service.Tests.fsproj
but vsintegration/tests/unittests/VisualFSharp.UnitTests.fsproj
references FSharp.LanguageService
, so a symbol defined in VisualFSharp.UnitTests.fsproj
is used to branch the output.
I don't know what is the error, perhaps the output is now the same? (if so, then there is no need to branch it anymore).
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.
FSharp.LanguageService
I think you mean FSharp.Compiler.Private
being used from VisualFSharp.UnitTests.fsproj
In #4368 I'm now always seeing the output in the NO_PROJECTCRACKER
branch even from the two FCS test projects. I don't particularly understand why though or what's changed. Don't worry about it for now - let's see if CI passes
In Fable we use the FCS to get parsed files:
https://github.com/fable-compiler/Fable/blob/03bc8e46f0fc94c70d2ae89d533784d10cf84d58/src/dotnet/dotnet-fable/StateUtil.fs#L107
/cc @ncave @alfonsogarciacaro
Corresponding FABLE PR: fable-compiler/Fable#1197