@@ -397,7 +397,7 @@ let direct_approx (info : Info.t) x =
397
397
y
398
398
| _ -> None
399
399
400
- let rec the_shape_of info x =
400
+ let rec the_shape_of ~ pure info x =
401
401
let rec loop info x acc : Shape.t =
402
402
get_approx
403
403
info
@@ -407,9 +407,10 @@ let rec the_shape_of info x =
407
407
| None -> (
408
408
match info.info_defs.(Var. idx x) with
409
409
| Expr (Block (_ , a , _ , Immutable)) ->
410
- Shape. Block (List. map ~f: (the_shape_of info) (Array. to_list a))
410
+ Shape. Block (List. map ~f: (the_shape_of ~pure info) (Array. to_list a))
411
411
| Expr (Closure (l , _ )) ->
412
- Shape. Function { arity = List. length l; pure = false ; res = Top " unk" }
412
+ let pure = Code.Var.Set. mem x pure in
413
+ Shape. Function { arity = List. length l; pure; res = Top " unk" }
413
414
| Expr (Special (Alias_prim name )) -> (
414
415
try
415
416
let arity = Primitive. arity name in
@@ -429,7 +430,22 @@ let rec the_shape_of info x =
429
430
| Shape. Block _ | Shape. Top _ -> Shape. Top " apply2" )
430
431
| _ -> Shape. Top " other" ))
431
432
(Top " init" )
432
- (fun _u _v -> Shape. Top " merge" )
433
+ (fun u v ->
434
+ let rec merge (u : Shape.t ) (v : Shape.t ) =
435
+ match u, v with
436
+ | ( Function { arity = a1; pure = p1; res = r1 }
437
+ , Function { arity = a2; pure = p2; res = r2 } ) ->
438
+ if a1 = a2
439
+ then Shape. Function { arity = a1; pure = p1 && p2; res = merge r1 r2 }
440
+ else Shape. Top " merge"
441
+ | Block b1 , Block b2 ->
442
+ if List. length b1 = List. length b2
443
+ then Block (List. map2 b1 b2 ~f: merge)
444
+ else Top " merge block"
445
+ | (Top _ as a ), _ | _ , (Top _ as a ) -> a
446
+ | Function _ , Block _ | Block _ , Function _ -> Shape. Top " merge block/fun"
447
+ in
448
+ merge u v)
433
449
x
434
450
in
435
451
loop info x []
0 commit comments