@@ -373,60 +373,70 @@ module Array =
373
373
else any ilTy
374
374
375
375
/// Makes the equivalent of an inlined call to Array.map.
376
- let mkMap g m ( mBody , _spFor , _spIn , mFor , mIn , spInWhile ) srcArray srcIlTy destIlTy overallElemTy loopVal body =
377
- let len = mkLdlen g mIn srcArray
378
- let arrayTy = mkArrayType g overallElemTy
379
-
380
- /// (# "newarr !0" type ('T) count : 'T array #)
381
- let array =
382
- mkAsmExpr
383
- (
384
- [ I_ newarr ( ILArrayShape.SingleDimensional, destIlTy)],
385
- [],
386
- [ len],
387
- [ arrayTy],
388
- m
389
- )
390
-
391
- let ldelem = mkIlInstr g I_ ldelem ( fun ilTy -> I_ ldelem_ any ( ILArrayShape.SingleDimensional, ilTy)) srcIlTy
392
- let stelem = mkIlInstr g I_ stelem ( fun ilTy -> I_ stelem_ any ( ILArrayShape.SingleDimensional, ilTy)) destIlTy
393
-
394
- let mapping =
395
- mkCompGenLetIn m ( nameof array) arrayTy array ( fun ( _ , array ) ->
396
- mkCompGenLetMutableIn mFor " i" g.int32_ ty ( mkTypedZero g mIn g.int32_ ty) ( fun ( iVal , i ) ->
397
- let body =
398
- // Rebind the loop val to pull directly from the source array.
399
- let body = mkInvisibleLet mBody loopVal ( mkAsmExpr ([ ldelem], [], [ srcArray; i], [ loopVal.val_ type], mBody)) body
400
-
401
- // destArray[i] <- body srcArray[i]
402
- let setArrSubI = mkAsmExpr ([ stelem], [], [ array; i; body], [], mIn)
403
-
404
- // i <- i + 1
405
- let incrI = mkValSet mIn ( mkLocalValRef iVal) ( mkAsmExpr ([ AI_ add], [], [ i; mkTypedOne g mIn g.int32_ ty], [ g.int32_ ty], mIn))
406
-
407
- mkSequential mIn setArrSubI incrI
408
-
409
- let guard = mkILAsmClt g mFor i ( mkLdlen g mFor array)
376
+ let mkMap g m ( mBody , _spFor , _spIn , mFor , mIn , spInWhile ) srcArray srcIlTy destIlTy overallElemTy ( loopVal : Val ) body =
377
+ mkCompGenLetIn m ( nameof srcArray) ( tyOfExpr g srcArray) srcArray ( fun ( _ , srcArray ) ->
378
+ let len = mkLdlen g mIn srcArray
379
+ let arrayTy = mkArrayType g overallElemTy
380
+
381
+ /// (# "newarr !0" type ('T) count : 'T array #)
382
+ let array =
383
+ mkAsmExpr
384
+ (
385
+ [ I_ newarr ( ILArrayShape.SingleDimensional, destIlTy)],
386
+ [],
387
+ [ len],
388
+ [ arrayTy],
389
+ m
390
+ )
410
391
411
- let loop =
412
- mkWhile
413
- g
414
- (
415
- spInWhile,
416
- NoSpecialWhileLoopMarker,
417
- guard,
418
- body,
419
- mIn
420
- )
392
+ let ldelem = mkIlInstr g I_ ldelem ( fun ilTy -> I_ ldelem_ any ( ILArrayShape.SingleDimensional, ilTy)) srcIlTy
393
+ let stelem = mkIlInstr g I_ stelem ( fun ilTy -> I_ stelem_ any ( ILArrayShape.SingleDimensional, ilTy)) destIlTy
421
394
422
- // while i < array.Length do <body> done
423
- // array
424
- mkSequential m loop array
395
+ let mapping =
396
+ mkCompGenLetIn m ( nameof array) arrayTy array ( fun ( _ , array ) ->
397
+ mkCompGenLetMutableIn mFor " i" g.int32_ ty ( mkTypedZero g mIn g.int32_ ty) ( fun ( iVal , i ) ->
398
+ let body =
399
+ // If the loop val is used in the loop body,
400
+ // rebind it to pull directly from the source array.
401
+ // Otherwise, don't bother reading from the source array at all.
402
+ let body =
403
+ let freeLocals = ( freeInExpr CollectLocals body) .FreeLocals
404
+
405
+ if freeLocals.Contains loopVal then
406
+ mkInvisibleLet mBody loopVal ( mkAsmExpr ([ ldelem], [], [ srcArray; i], [ loopVal.val_ type], mBody)) body
407
+ else
408
+ body
409
+
410
+ // destArray[i] <- body srcArray[i]
411
+ let setArrSubI = mkAsmExpr ([ stelem], [], [ array; i; body], [], mIn)
412
+
413
+ // i <- i + 1
414
+ let incrI = mkValSet mIn ( mkLocalValRef iVal) ( mkAsmExpr ([ AI_ add], [], [ i; mkTypedOne g mIn g.int32_ ty], [ g.int32_ ty], mIn))
415
+
416
+ mkSequential mIn setArrSubI incrI
417
+
418
+ let guard = mkILAsmClt g mFor i ( mkLdlen g mFor array)
419
+
420
+ let loop =
421
+ mkWhile
422
+ g
423
+ (
424
+ spInWhile,
425
+ NoSpecialWhileLoopMarker,
426
+ guard,
427
+ body,
428
+ mIn
429
+ )
430
+
431
+ // while i < array.Length do <body> done
432
+ // array
433
+ mkSequential m loop array
434
+ )
425
435
)
426
- )
427
436
428
- // Add a debug point at the `for`, before anything gets evaluated.
429
- Expr.DebugPoint ( DebugPointAtLeafExpr.Yes mFor, mapping)
437
+ // Add a debug point at the `for`, before anything gets evaluated.
438
+ Expr.DebugPoint ( DebugPointAtLeafExpr.Yes mFor, mapping)
439
+ )
430
440
431
441
/// Whether to check for overflow when converting a value to a native int.
432
442
[<NoEquality; NoComparison>]
@@ -558,6 +568,9 @@ let (|SingleYield|_|) g expr : Expr voption =
558
568
| Expr.Sequential ( expr1, DebugPoints ( body, debug), kind, m) ->
559
569
loop body ( cont << fun body -> Expr.Sequential ( expr1, debug body, kind, m))
560
570
571
+ | Expr.Match ( debugPoint, mInput, decision, [| TTarget ( boundVals, DebugPoints ( SeqSingleton g body, debug), isStateVarFlags)|], mFull, exprType) ->
572
+ ValueSome ( cont ( Expr.Match ( debugPoint, mInput, decision, [| TTarget ( boundVals, debug body, isStateVarFlags)|], mFull, exprType)))
573
+
561
574
| SeqSingleton g body ->
562
575
ValueSome ( cont body)
563
576
0 commit comments