@@ -258,7 +258,7 @@ let (|SeqToArray|_|) g expr =
258
258
259
259
module List =
260
260
/// Makes an expression that will build a list from an integral range.
261
- let mkFromIntegralRange tcVal ( g : TcGlobals ) amap m overallElemTy overallSeqExpr start step finish =
261
+ let mkFromIntegralRange tcVal ( g : TcGlobals ) amap m rangeTy overallElemTy rangeExpr start step finish body =
262
262
let collectorTy = g.mk_ ListCollector_ ty overallElemTy
263
263
264
264
/// let collector = ListCollector () in
@@ -267,15 +267,24 @@ module List =
267
267
let mkListInit mkLoop =
268
268
mkCompGenLetMutableIn m " collector" collectorTy ( mkDefault ( m, collectorTy)) ( fun ( _ , collector ) ->
269
269
let reader = InfoReader ( g, amap)
270
- let loop = mkLoop ( fun _idxVar loopVar -> mkCallCollectorAdd tcVal g reader m collector loopVar)
270
+
271
+ let loop =
272
+ mkLoop ( fun _idxVar loopVar ->
273
+ let body =
274
+ body
275
+ |> Option.map ( fun ( loopVal , body ) -> mkInvisibleLet m loopVal loopVar body)
276
+ |> Option.defaultValue loopVar
277
+
278
+ mkCallCollectorAdd tcVal g reader m collector body)
279
+
271
280
let close = mkCallCollectorClose tcVal g reader m collector
272
281
mkSequential m loop close
273
282
)
274
283
275
284
mkOptimizedRangeLoop
276
285
g
277
286
( m, m, m, DebugPointAtWhile.No)
278
- ( overallElemTy , overallSeqExpr )
287
+ ( rangeTy , rangeExpr )
279
288
( start, step, finish)
280
289
( fun count mkLoop ->
281
290
match count with
@@ -301,7 +310,7 @@ module Array =
301
310
| NoCheckOvf
302
311
303
312
/// Makes an expression that will build an array from an integral range.
304
- let mkFromIntegralRange g m overallElemTy overallSeqExpr start step finish =
313
+ let mkFromIntegralRange g m rangeTy ilTy overallElemTy rangeExpr start step finish body =
305
314
let arrayTy = mkArrayType g overallElemTy
306
315
307
316
let convToNativeInt ovf expr =
@@ -324,21 +333,21 @@ module Array =
324
333
else
325
334
expr
326
335
327
- let ilTy , ilBasicTy =
328
- let ty = stripMeasuresFromTy g overallElemTy
329
-
330
- if typeEquiv g ty g.int32 _ ty then g.ilg.typ _ Int32 , DT _ I4
331
- elif typeEquiv g ty g.int64 _ ty then g.ilg.typ _ Int64 , DT _ I8
332
- elif typeEquiv g ty g.uint64 _ ty then g.ilg.typ _ UInt64 , DT _ U8
333
- elif typeEquiv g ty g.uint32 _ ty then g.ilg.typ _ UInt32 , DT _ U4
334
- elif typeEquiv g ty g.nativeint _ ty then g.ilg.typ _ IntPtr , DT _ I
335
- elif typeEquiv g ty g.unativeint _ ty then g.ilg.typ _ UIntPtr , DT _ U
336
- elif typeEquiv g ty g.int16 _ ty then g.ilg.typ _ Int16 , DT _ I2
337
- elif typeEquiv g ty g.uint16 _ ty then g.ilg.typ _ UInt16 , DT _ U2
338
- elif typeEquiv g ty g.sbyte _ ty then g.ilg.typ _ SByte , DT _ I1
339
- elif typeEquiv g ty g.byte _ ty then g.ilg.typ _ Byte , DT _ U1
340
- elif typeEquiv g ty g.char _ ty then g.ilg.typ _ Char , DT _ U2
341
- else error ( InternalError ( $ " Unable to find IL type for integral type '{overallElemTy}'. " , m ) )
336
+ let stelem =
337
+ if ilTy = g.ilg.typ _ Int32 then I _ stelem DT _ I4
338
+ elif ilTy = g.ilg.typ _ Int64 then I _ stelem DT _ I8
339
+ elif ilTy = g.ilg.typ _ UInt64 then I _ stelem DT _ U8
340
+ elif ilTy = g.ilg.typ _ UInt32 then I _ stelem DT _ U4
341
+ elif ilTy = g.ilg.typ _ IntPtr then I _ stelem DT _ I
342
+ elif ilTy = g.ilg.typ _ UIntPtr then I _ stelem DT _ U
343
+ elif ilTy = g.ilg.typ _ Int16 then I _ stelem DT _ I2
344
+ elif ilTy = g.ilg.typ _ UInt16 then I _ stelem DT _ U2
345
+ elif ilTy = g.ilg.typ _ SByte then I _ stelem DT _ I1
346
+ elif ilTy = g.ilg.typ _ Byte then I _ stelem DT _ U1
347
+ elif ilTy = g.ilg.typ _ Char then I _ stelem DT _ U2
348
+ elif ilTy = g.ilg.typ _ Double then I _ stelem DT _ R8
349
+ elif ilTy = g.ilg.typ _ Single then I _ stelem DT _ R4
350
+ else I _ stelem _ any ( ILArrayShape.SingleDimensional , ilTy )
342
351
343
352
/// (# "newarr !0" type ('T) count : 'T array #)
344
353
let mkNewArray count =
@@ -356,13 +365,21 @@ module Array =
356
365
/// array
357
366
let mkArrayInit count mkLoop =
358
367
mkCompGenLetIn m " array" arrayTy ( mkNewArray count) ( fun ( _ , array ) ->
359
- let loop = mkLoop ( fun idxVar loopVar -> mkAsmExpr ([ I_ stelem ilBasicTy], [], [ array; convToNativeInt NoCheckOvf idxVar; loopVar], [], m))
368
+ let loop =
369
+ mkLoop ( fun idxVar loopVar ->
370
+ let body =
371
+ body
372
+ |> Option.map ( fun ( loopVal , body ) -> mkInvisibleLet m loopVal loopVar body)
373
+ |> Option.defaultValue loopVar
374
+
375
+ mkAsmExpr ([ stelem], [], [ array; convToNativeInt NoCheckOvf idxVar; body], [], m))
376
+
360
377
mkSequential m loop array)
361
378
362
379
mkOptimizedRangeLoop
363
380
g
364
381
( m, m, m, DebugPointAtWhile.No)
365
- ( overallElemTy , overallSeqExpr )
382
+ ( rangeTy , rangeExpr )
366
383
( start, step, finish)
367
384
( fun count mkLoop ->
368
385
match count with
@@ -399,7 +416,64 @@ module Array =
399
416
)
400
417
)
401
418
402
- let LowerComputedListOrArrayExpr tcVal ( g : TcGlobals ) amap overallExpr =
419
+ /// f (); …; Seq.singleton x
420
+ ///
421
+ /// E.g., in [for x in … do f (); …; yield x]
422
+ [<return : Struct>]
423
+ let (| SimpleSequential | _ |) g expr =
424
+ let rec loop expr cont =
425
+ match expr with
426
+ | Expr.Sequential ( expr1, DebugPoints ( ValApp g g.seq_ singleton_ vref (_, [ body], _), debug), kind, m) ->
427
+ ValueSome ( cont ( expr1, debug body, kind, m))
428
+
429
+ | Expr.Sequential ( expr1, body, kind, m) ->
430
+ loop body ( cont >> fun body -> Expr.Sequential ( expr1, body, kind, m))
431
+
432
+ | _ -> ValueNone
433
+
434
+ loop expr Expr.Sequential
435
+
436
+ /// The representation used for
437
+ ///
438
+ /// for … in … -> …
439
+ ///
440
+ /// and
441
+ ///
442
+ /// for … in … do yield …
443
+ [<return : Struct>]
444
+ let (| SeqMap | _ |) g expr =
445
+ match expr with
446
+ | ValApp g g.seq_ map_ vref ([ ty1; ty2], [ Expr.Lambda ( valParams = [ loopVal]; bodyExpr = body) as mapping; input], _) ->
447
+ ValueSome ( ty1, ty2, input, mapping, loopVal, body)
448
+ | _ -> ValueNone
449
+
450
+ /// The representation used for
451
+ ///
452
+ /// for … in … do f (); …; yield …
453
+ [<return : Struct>]
454
+ let (| SeqCollectSingle | _ |) g expr =
455
+ match expr with
456
+ | ValApp g g.seq_ collect_ vref ([ ty1; _; ty2], [ Expr.Lambda ( valParams = [ loopVal]; bodyExpr = SimpleSequential g body) as mapping; input], _) ->
457
+ ValueSome ( ty1, ty2, input, mapping, loopVal, body)
458
+ | _ -> ValueNone
459
+
460
+ /// for … in … -> …
461
+ /// for … in … do yield …
462
+ /// for … in … do f (); …; yield …
463
+ [<return : Struct>]
464
+ let (| SimpleMapping | _ |) g expr =
465
+ match expr with
466
+ // for … in … -> …
467
+ // for … in … do yield …
468
+ | ValApp g g.seq_ delay_ vref (_, [ Expr.Lambda ( bodyExpr = SeqMap g ( ty1, ty2, input, mapping, loopVal, body))], _)
469
+
470
+ // for … in … do f (); …; yield …
471
+ | ValApp g g.seq_ delay_ vref (_, [ Expr.Lambda ( bodyExpr = SeqCollectSingle g ( ty1, ty2, input, mapping, loopVal, body))], _) ->
472
+ ValueSome ( ty1, ty2, input, mapping, loopVal, body)
473
+
474
+ | _ -> ValueNone
475
+
476
+ let LowerComputedListOrArrayExpr tcVal ( g : TcGlobals ) amap ilTyForTy overallExpr =
403
477
// If ListCollector is in FSharp.Core then this optimization kicks in
404
478
if g.ListCollector_ tcr.CanDeref then
405
479
match overallExpr with
@@ -408,8 +482,17 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr =
408
482
match overallSeqExpr with
409
483
// [start..finish]
410
484
// [start..step..finish]
411
- | IntegralRange g (_, ( start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops ->
412
- Some ( List.mkFromIntegralRange tcVal g amap m overallElemTy overallSeqExpr start step finish)
485
+ | IntegralRange g ( rangeTy, ( start, step, finish)) when
486
+ g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops
487
+ ->
488
+ Some ( List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy overallSeqExpr start step finish None)
489
+
490
+ // [for … in start..finish -> …]
491
+ // [for … in start..step..finish -> …]
492
+ | SimpleMapping g (_, _, rangeExpr & IntegralRange g ( rangeTy, ( start, step, finish)), _, loopVal, body) when
493
+ g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops
494
+ ->
495
+ Some ( List.mkFromIntegralRange tcVal g amap m rangeTy overallElemTy rangeExpr start step finish ( Some ( loopVal, body)))
413
496
414
497
// [(* Anything more complex. *)]
415
498
| _ ->
@@ -421,8 +504,17 @@ let LowerComputedListOrArrayExpr tcVal (g: TcGlobals) amap overallExpr =
421
504
match overallSeqExpr with
422
505
// [|start..finish|]
423
506
// [|start..step..finish|]
424
- | IntegralRange g (_, ( start, step, finish)) when g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops ->
425
- Some ( Array.mkFromIntegralRange g m overallElemTy overallSeqExpr start step finish)
507
+ | IntegralRange g ( rangeTy, ( start, step, finish)) when
508
+ g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops
509
+ ->
510
+ Some ( Array.mkFromIntegralRange g m rangeTy ( ilTyForTy overallElemTy) overallElemTy overallSeqExpr start step finish None)
511
+
512
+ // [|for … in start..finish -> …|]
513
+ // [|for … in start..step..finish -> …|]
514
+ | SimpleMapping g (_, _, rangeExpr & IntegralRange g ( rangeTy, ( start, step, finish)), _, loopVal, body) when
515
+ g.langVersion.SupportsFeature LanguageFeature.LowerIntegralRangesToFastLoops
516
+ ->
517
+ Some ( Array.mkFromIntegralRange g m rangeTy ( ilTyForTy overallElemTy) overallElemTy rangeExpr start step finish ( Some ( loopVal, body)))
426
518
427
519
// [|(* Anything more complex. *)|]
428
520
| _ ->
0 commit comments