Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions src/fsharp/CompilerOptions.fs
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ let setFlag r n =
let SetOptimizeOff(tcConfigB: TcConfigBuilder) =
tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some false }
tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some false }
tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false }
tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some false }
tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 0 }
tcConfigB.doDetuple <- false
tcConfigB.doTLR <- false
Expand All @@ -391,7 +391,7 @@ let SetOptimizeOff(tcConfigB: TcConfigBuilder) =
let SetOptimizeOn(tcConfigB: TcConfigBuilder) =
tcConfigB.optSettings <- { tcConfigB.optSettings with jitOptUser = Some true }
tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some true }
tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true }
tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some true }
tcConfigB.optSettings <- { tcConfigB.optSettings with lambdaInlineThreshold = 6 }
tcConfigB.doDetuple <- true
tcConfigB.doTLR <- true
Expand Down Expand Up @@ -420,7 +420,7 @@ let localoptimizeSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.optSettings <- { tcConfigB.optSettings with localOptUser = Some (switch = OptionSwitch.On) }

let crossOptimizeSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some (switch = OptionSwitch.On) }
tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some (switch = OptionSwitch.On) }

let splittingSwitch (tcConfigB: TcConfigBuilder) switch =
tcConfigB.optSettings <- { tcConfigB.optSettings with abstractBigTargets = switch = OptionSwitch.On }
Expand Down Expand Up @@ -540,7 +540,7 @@ let tagLangVersionValues = "{?|version|latest|preview}"
let PrintOptionInfo (tcConfigB:TcConfigBuilder) =
printfn " jitOptUser . . . . . . : %+A" tcConfigB.optSettings.jitOptUser
printfn " localOptUser . . . . . : %+A" tcConfigB.optSettings.localOptUser
printfn " crossModuleOptUser . . : %+A" tcConfigB.optSettings.crossModuleOptUser
printfn " crossAssemblyOptimizationUser . . : %+A" tcConfigB.optSettings.crossAssemblyOptimizationUser
printfn " lambdaInlineThreshold : %+A" tcConfigB.optSettings.lambdaInlineThreshold
printfn " ignoreSymStoreSeqPts . : %+A" tcConfigB.ignoreSymbolStoreSequencePoints
printfn " doDetuple . . . . . . : %+A" tcConfigB.doDetuple
Expand Down Expand Up @@ -1359,12 +1359,12 @@ let deprecatedFlagsFsc tcConfigB =

CompilerOption
("cross-optimize", tagNone,
OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some true }),
OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some true }),
Some(DeprecatedCommandLineOptionNoDescription("--cross-optimize", rangeCmdArgs)), None)

CompilerOption
("no-cross-optimize", tagNone,
OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossModuleOptUser = Some false }),
OptionUnit (fun _ -> tcConfigB.optSettings <- { tcConfigB.optSettings with crossAssemblyOptimizationUser = Some false }),
Some(DeprecatedCommandLineOptionNoDescription("--no-cross-optimize", rangeCmdArgs)), None)

CompilerOption
Expand Down
213 changes: 179 additions & 34 deletions src/fsharp/Optimizer.fs

Large diffs are not rendered by default.

41 changes: 30 additions & 11 deletions src/fsharp/Optimizer.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,39 @@ open FSharp.Compiler.TypedTreeOps
open FSharp.Compiler.TypedTreePickle

type OptimizationSettings =
{ abstractBigTargets: bool
jitOptUser: bool option
localOptUser: bool option
crossModuleOptUser: bool option
bigTargetSize: int
veryBigExprSize: int
lambdaInlineThreshold: int
reportingPhase: bool
{
abstractBigTargets : bool

jitOptUser : bool option

localOptUser : bool option

debugPointsForPipeRight: bool option

crossAssemblyOptimizationUser : bool option

/// size after which we start chopping methods in two, though only at match targets
bigTargetSize : int

/// size after which we start enforcing splitting sub-expressions to new methods, to avoid hitting .NET IL limitations
veryBigExprSize : int

/// The size after which we don't inline
lambdaInlineThreshold : int

/// For unit testing
reportingPhase : bool

reportNoNeedToTailcall: bool
reportFunctionSizes: bool
reportHasEffect: bool
reportTotalSizes: bool

reportFunctionSizes : bool

reportHasEffect : bool

reportTotalSizes : bool
}


member jitOpt: unit -> bool

member localOpt: unit -> bool
Expand Down
27 changes: 26 additions & 1 deletion src/fsharp/SyntaxTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -760,4 +760,29 @@ let (|ParsedHashDirectiveArguments|) (input: ParsedHashDirectiveArgument list) =
(function
| ParsedHashDirectiveArgument.String (s, _, _) -> s
| ParsedHashDirectiveArgument.SourceIdentifier (_, v, _) -> v)
input
input

let (|SynBinOp|_|) input =
match input with
| SynExpr.App (ExprAtomicFlag.NonAtomic, false, SynExpr.App (ExprAtomicFlag.NonAtomic, true, SynExpr.Ident synId, x1, _m1), x2, _m2) ->
Some (synId, x1, x2)
| _ -> None

let (|SynPipeRight|_|) input =
match input with
| SynBinOp (synId, x1, x2) when synId.idText = "op_PipeRight" -> Some (x1, x2)
| _ -> None

let (|SynPipeRight2|_|) input =
match input with
| SynBinOp (synId, SynExpr.Paren(SynExpr.Tuple(false, [x1a; x1b], _, _), _, _, _), x2)
when synId.idText = "op_PipeRight2" ->
Some (x1a, x1b, x2)
| _ -> None

let (|SynPipeRight3|_|) input =
match input with
| SynBinOp (synId, SynExpr.Paren(SynExpr.Tuple(false, [x1a; x1b; x1c], _, _), _, _, _), x2)
when synId.idText = "op_PipeRight3" ->
Some (x1a, x1b, x1c, x2)
| _ -> None
9 changes: 8 additions & 1 deletion src/fsharp/SyntaxTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -262,4 +262,11 @@ val noInferredTypars: SynValTyparDecls

val synExprContainsError: inpExpr:SynExpr -> bool

val ( |ParsedHashDirectiveArguments| ) : ParsedHashDirectiveArgument list -> string list
val ( |ParsedHashDirectiveArguments| ) : ParsedHashDirectiveArgument list -> string list

val (|SynPipeRight|_|): SynExpr -> (SynExpr * SynExpr) option

val (|SynPipeRight2|_|): SynExpr -> (SynExpr * SynExpr * SynExpr) option

val (|SynPipeRight3|_|): SynExpr -> (SynExpr * SynExpr * SynExpr * SynExpr) option

6 changes: 6 additions & 0 deletions src/fsharp/TcGlobals.fs
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,9 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d

let v_reference_equality_inner_info = makeIntrinsicValRef(fslib_MFHashCompare_nleref, "PhysicalEqualityIntrinsic" , None , None , [vara], mk_rel_sig varaTy)

let v_piperight_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight" , None , None , [vara; varb],([[varaTy];[varaTy --> varbTy]], varbTy))
let v_piperight2_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight2" , None , None , [vara; varb; varc],([[varaTy; varbTy];[varaTy --> (varbTy --> varcTy)]], varcTy))
let v_piperight3_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_PipeRight3" , None , None , [vara; varb; varc; vard],([[varaTy; varbTy; varcTy];[varaTy --> (varbTy --> (varcTy --> vardTy))]], vardTy))
let v_bitwise_or_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseOr" , None , None , [vara], mk_binop_ty varaTy)
let v_bitwise_and_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_BitwiseAnd" , None , None , [vara], mk_binop_ty varaTy)
let v_bitwise_xor_info = makeIntrinsicValRef(fslib_MFOperators_nleref, "op_ExclusiveOr" , None , None , [vara], mk_binop_ty varaTy)
Expand Down Expand Up @@ -1298,6 +1301,9 @@ type public TcGlobals(compilingFslib: bool, ilg:ILGlobals, fslibCcu: CcuThunk, d

member val reference_equality_inner_vref = ValRefForIntrinsic v_reference_equality_inner_info

member val piperight_vref = ValRefForIntrinsic v_piperight_info
member val piperight2_vref = ValRefForIntrinsic v_piperight2_info
member val piperight3_vref = ValRefForIntrinsic v_piperight3_info
member val bitwise_or_vref = ValRefForIntrinsic v_bitwise_or_info
member val bitwise_and_vref = ValRefForIntrinsic v_bitwise_and_info
member val bitwise_xor_vref = ValRefForIntrinsic v_bitwise_xor_info
Expand Down
21 changes: 21 additions & 0 deletions src/fsharp/TypedTreeOps.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7663,6 +7663,27 @@ let (|DelegateInvokeExpr|_|) g expr =
Some(iref, fty, tyargs, f, args, m)
| _ -> None

let (|OpPipeRight|_|) g expr =
match expr with
| Expr.App (Expr.Val (vref, _, _), _, [_; resType], [xExpr; fExpr], m)
when valRefEq g vref g.piperight_vref ->
Some(resType, xExpr, fExpr, m)
| _ -> None

let (|OpPipeRight2|_|) g expr =
match expr with
| Expr.App (Expr.Val (vref, _, _), _, [_; _; resType], [Expr.Op (TOp.Tuple _, _, [arg1; arg2], _); fExpr], m)
when valRefEq g vref g.piperight2_vref ->
Some(resType, arg1, arg2, fExpr, m)
| _ -> None

let (|OpPipeRight3|_|) g expr =
match expr with
| Expr.App (Expr.Val (vref, _, _), _, [_; _; _; resType], [Expr.Op (TOp.Tuple _, _, [arg1; arg2; arg3], _); fExpr], m)
when valRefEq g vref g.piperight3_vref ->
Some(resType, arg1, arg2, arg3, fExpr, m)
| _ -> None

let rec MakeFSharpDelegateInvokeAndTryBetaReduce g (invokeRef, f, fty, tyargs, argsl: Expr list, m) =
match f with
| Expr.Let (bind, body, mlet, _) ->
Expand Down
17 changes: 16 additions & 1 deletion src/fsharp/TypedTreeOps.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -2508,4 +2508,19 @@ val (|ResumableCodeInvoke|_|):
g:TcGlobals ->
expr: Expr ->
(Expr * Expr * Expr list * range * (Expr * Expr list -> Expr)) option


val (|OpPipeRight|_|):
g:TcGlobals ->
expr: Expr ->
(TType * Expr * Expr * range) option

val (|OpPipeRight2|_|):
g:TcGlobals ->
expr: Expr ->
(TType * Expr * Expr * Expr * range) option

val (|OpPipeRight3|_|):
g:TcGlobals ->
expr: Expr ->
(TType * Expr * Expr * Expr * Expr * range) option

30 changes: 30 additions & 0 deletions src/fsharp/service/FSharpParseFileResults.fs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,36 @@ type FSharpParseFileResults(diagnostics: FSharpDiagnostic[], input: ParsedInput,
yield! checkRange e.Range
yield! walkExpr false e

// Always allow breakpoints on input and stages of x |> f1 |> f2 pipelines
| SynPipeRight _ ->
let rec loop e =
seq {
match e with
| SynPipeRight (xExpr, fExpr) ->
yield! checkRange fExpr.Range
yield! walkExpr false fExpr
yield! loop xExpr
| SynPipeRight2 (xExpr1, xExpr2, fExpr) ->
yield! checkRange fExpr.Range
yield! checkRange xExpr1.Range
yield! checkRange xExpr2.Range
yield! walkExpr false xExpr1
yield! walkExpr false xExpr2
yield! walkExpr false fExpr
| SynPipeRight3 (xExpr1, xExpr2, xExpr3, fExpr) ->
yield! checkRange fExpr.Range
yield! checkRange xExpr1.Range
yield! checkRange xExpr2.Range
yield! checkRange xExpr3.Range
yield! walkExpr false xExpr1
yield! walkExpr false xExpr2
yield! walkExpr false xExpr3
yield! walkExpr false fExpr
| _ ->
yield! checkRange e.Range
yield! walkExpr false e
}
yield! loop expr
| SynExpr.NamedIndexedPropertySet (_, e1, e2, _)
| SynExpr.DotSet (e1, _, e2, _)
| SynExpr.Set (e1, e2, _)
Expand Down
3 changes: 2 additions & 1 deletion src/fsharp/symbols/Exprs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,8 @@ module FSharpExprConvert =
// tail recursive
ConvExprLinear cenv env e2 (contF << (fun e2R -> E.Sequential(e1R, e2R)))

| Expr.Sequential (x0, x1, ThenDoSeq, _, _) -> E.Sequential(ConvExpr cenv env x0, ConvExpr cenv env x1)
| Expr.Sequential (x0, x1, ThenDoSeq, _, _) ->
E.Sequential(ConvExpr cenv env x0, ConvExpr cenv env x1) |> contF

| ModuleValueOrMemberUse cenv.g (vref, vFlags, _f, _fty, tyargs, curriedArgs) when (nonNil tyargs || nonNil curriedArgs) && vref.IsMemberOrModuleBinding ->
ConvModuleValueOrMemberUseLinear cenv env (expr, vref, vFlags, tyargs, curriedArgs) contF
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0
// Copyright (c) Microsoft Corporation. All rights reserved.


Expand All @@ -13,7 +13,7 @@
.assembly extern FSharp.Core
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:4:3:0
.ver 5:0:0:0
}
.assembly AsyncExpressionSteppingTest1
{
Expand All @@ -29,20 +29,20 @@
}
.mresource public FSharpSignatureData.AsyncExpressionSteppingTest1
{
// Offset: 0x00000000 Length: 0x0000026C
// Offset: 0x00000000 Length: 0x00000260
}
.mresource public FSharpOptimizationData.AsyncExpressionSteppingTest1
{
// Offset: 0x00000270 Length: 0x000000B1
// Offset: 0x00000268 Length: 0x000000B1
}
.module AsyncExpressionSteppingTest1.dll
// MVID: {5AF5DDAE-6394-B5D4-A745-0383AEDDF55A}
// MVID: {611B0EC4-6394-B5D4-A745-0383C40E1B61}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x02880000
// Image base: 0x06680000


// =============== CLASS MEMBERS DECLARATION ===================
Expand Down Expand Up @@ -83,7 +83,7 @@
// Code size 62 (0x3e)
.maxstack 8
.language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
.line 6,6 : 17,32 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs'
.line 6,6 : 17,32 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest1.fs'
IL_0000: ldstr "hello"
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit>::.ctor(string)
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatLine<class [FSharp.Core]Microsoft.FSharp.Core.Unit>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [mscorlib]System.IO.TextWriter,class [FSharp.Core]Microsoft.FSharp.Core.Unit,class [FSharp.Core]Microsoft.FSharp.Core.Unit>)
Expand Down Expand Up @@ -140,11 +140,12 @@
{
// Code size 18 (0x12)
.maxstack 5
.locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_0,
.locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> 'Pipe #1 input at line 10',
[1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_1)
.line 10,10 : 13,43 ''
.line 10,10 : 13,17 ''
IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> AsyncExpressionSteppingTest1/AsyncExpressionSteppingTest1::f1()
IL_0005: stloc.0
.line 10,10 : 21,43 ''
IL_0006: ldloc.0
IL_0007: stloc.1
IL_0008: ldloc.1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

// Microsoft (R) .NET Framework IL Disassembler. Version 4.6.1055.0
// Microsoft (R) .NET Framework IL Disassembler. Version 4.8.3928.0
// Copyright (c) Microsoft Corporation. All rights reserved.


Expand All @@ -13,7 +13,7 @@
.assembly extern FSharp.Core
{
.publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A ) // .?_....:
.ver 4:4:3:0
.ver 5:0:0:0
}
.assembly AsyncExpressionSteppingTest2
{
Expand All @@ -29,20 +29,20 @@
}
.mresource public FSharpSignatureData.AsyncExpressionSteppingTest2
{
// Offset: 0x00000000 Length: 0x0000026C
// Offset: 0x00000000 Length: 0x00000260
}
.mresource public FSharpOptimizationData.AsyncExpressionSteppingTest2
{
// Offset: 0x00000270 Length: 0x000000B1
// Offset: 0x00000268 Length: 0x000000B1
}
.module AsyncExpressionSteppingTest2.dll
// MVID: {5AF5DDAE-6394-D499-A745-0383AEDDF55A}
// MVID: {611B0EC4-6394-D499-A745-0383C40E1B61}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003 // WINDOWS_CUI
.corflags 0x00000001 // ILONLY
// Image base: 0x04520000
// Image base: 0x06860000


// =============== CLASS MEMBERS DECLARATION ===================
Expand Down Expand Up @@ -80,7 +80,7 @@
// Code size 15 (0xf)
.maxstack 8
.language '{AB4F38C9-B6E6-43BA-BE3B-58080B2CCCE3}', '{994B45C4-E6E9-11D2-903F-00C04FA302A1}', '{5A869D0B-6611-11D3-BD2A-0000F80849BD}'
.line 6,6 : 23,29 'C:\\GitHub\\dsyme\\visualfsharp\\tests\\fsharpqa\\Source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs'
.line 6,6 : 23,29 'C:\\GitHub\\dsyme\\fsharp\\tests\\fsharpqa\\source\\CodeGen\\EmittedIL\\AsyncExpressionStepping\\AsyncExpressionSteppingTest2.fs'
IL_0000: ldarg.0
IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1<int32> AsyncExpressionSteppingTest2/AsyncExpressionSteppingTest2/'f2@6-1'::x
IL_0006: call !!0 [FSharp.Core]Microsoft.FSharp.Core.Operators::op_Dereference<int32>(class [FSharp.Core]Microsoft.FSharp.Core.FSharpRef`1<!!0>)
Expand Down Expand Up @@ -237,11 +237,12 @@
{
// Code size 18 (0x12)
.maxstack 5
.locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_0,
.locals init ([0] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> 'Pipe #1 input at line 11',
[1] class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> V_1)
.line 11,11 : 13,43 ''
.line 11,11 : 13,17 ''
IL_0000: call class [FSharp.Core]Microsoft.FSharp.Control.FSharpAsync`1<class [FSharp.Core]Microsoft.FSharp.Core.Unit> AsyncExpressionSteppingTest2/AsyncExpressionSteppingTest2::f2()
IL_0005: stloc.0
.line 11,11 : 21,43 ''
IL_0006: ldloc.0
IL_0007: stloc.1
IL_0008: ldloc.1
Expand Down
Loading