Closed
Description
I have played around a bit with F# and decompilers, and in many cases F# generates complicated IL.
e.g.
this
let sample1() =
use fs = File.Create("x.txt")
fs.WriteByte(byte 1)
compiles to
.method public static
void sample1 () cil managed
{
// Method begins at RVA 0x2050
// Code size 48 (0x30)
.maxstack 4
.locals init (
[0] class [mscorlib]System.IO.FileStream fs,
[1] class [FSharp.Core]Microsoft.FSharp.Core.Unit,
[2] class [mscorlib]System.IDisposable
)
IL_0000: nop
IL_0001: ldstr "x.txt"
IL_0006: call class [mscorlib]System.IO.FileStream [mscorlib]System.IO.File::Create(string)
IL_000b: stloc.0
.try
{
IL_000c: ldloc.0
IL_000d: ldc.i4.1
IL_000e: callvirt instance void [mscorlib]System.IO.Stream::WriteByte(uint8)
IL_0013: ldnull
IL_0014: stloc.1
IL_0015: leave.s IL_002d
} // end .try
finally
{
IL_0017: ldloc.0
IL_0018: isinst [mscorlib]System.IDisposable
IL_001d: stloc.2
IL_001e: ldloc.2
IL_001f: brfalse.s IL_002a
IL_0021: ldloc.2
IL_0022: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_0027: ldnull
IL_0028: pop
IL_0029: endfinally
IL_002a: ldnull
IL_002b: pop
IL_002c: endfinally
} // end handler
IL_002d: ldloc.1
IL_002e: pop
IL_002f: ret
} // end of method Program::sample1
Edit:
Opportunities in this this simple program
- ldnull/pop pairs
- typecheck for IDisposable
- second endfinally in try-finally
- ldloc/pop @IL_002d
All these would reduce the size of the method from 0x2f (47) to less than 32 instructions.
32 instructions is the magic upper limit for inlining.
Metadata
Metadata
Assignees
Labels
No labels