@@ -276,9 +276,9 @@ module With_subkind = struct
276
276
| Boxed_int64
277
277
| Boxed_nativeint
278
278
| Tagged_immediate
279
- | Block of
280
- { tag : Tag .t ;
281
- fields : t list
279
+ | Variant of
280
+ { consts : Targetint_31_63.Set .t ;
281
+ non_consts : t list Tag.Scannable.Map .t
282
282
}
283
283
| Float_block of { num_fields : int }
284
284
| Float_array
@@ -300,19 +300,34 @@ module With_subkind = struct
300
300
| Value_array , Value_array
301
301
| Generic_array , Generic_array ->
302
302
true
303
- | ( Block { tag = t1; fields = fields1 },
304
- Block { tag = t2; fields = fields2 } ) ->
305
- Tag. equal t1 t2
306
- && List. length fields1 = List. length fields2
307
- && List. for_all2
308
- (fun d when_used_at -> compatible d ~when_used_at )
309
- fields1 fields2
303
+ | ( Variant { consts = consts1; non_consts = non_consts1 },
304
+ Variant { consts = consts2; non_consts = non_consts2 } ) ->
305
+ if not (Targetint_31_63.Set. equal consts1 consts2)
306
+ then false
307
+ else
308
+ let tags1 = Tag.Scannable.Map. keys non_consts1 in
309
+ let tags2 = Tag.Scannable.Map. keys non_consts2 in
310
+ if not (Tag.Scannable.Set. equal tags1 tags2)
311
+ then false
312
+ else
313
+ let field_lists1 = Tag.Scannable.Map. data non_consts1 in
314
+ let field_lists2 = Tag.Scannable.Map. data non_consts2 in
315
+ assert (List. compare_lengths field_lists1 field_lists2 = 0 );
316
+ List. for_all2
317
+ (fun fields1 fields2 ->
318
+ if List. compare_lengths fields1 fields2 <> 0
319
+ then false
320
+ else
321
+ List. for_all2
322
+ (fun d when_used_at -> compatible d ~when_used_at )
323
+ fields1 fields2)
324
+ field_lists1 field_lists2
310
325
| ( Float_block { num_fields = num_fields1 },
311
326
Float_block { num_fields = num_fields2 } ) ->
312
327
num_fields1 = num_fields2
313
328
(* Subkinds of [Value] may always be used at [Value] (but not the
314
329
converse): *)
315
- | ( ( Block _ | Float_block _ | Float_array | Immediate_array
330
+ | ( ( Variant _ | Float_block _ | Float_array | Immediate_array
316
331
| Value_array | Generic_array | Boxed_float | Boxed_int32
317
332
| Boxed_int64 | Boxed_nativeint | Tagged_immediate ),
318
333
Anything ) ->
@@ -324,7 +339,7 @@ module With_subkind = struct
324
339
true
325
340
(* All other combinations are incompatible: *)
326
341
| ( ( Anything | Boxed_float | Boxed_int32 | Boxed_int64 | Boxed_nativeint
327
- | Tagged_immediate | Block _ | Float_block _ | Float_array
342
+ | Tagged_immediate | Variant _ | Float_block _ | Float_array
328
343
| Immediate_array | Value_array | Generic_array ),
329
344
_ ) ->
330
345
false
@@ -335,7 +350,7 @@ module With_subkind = struct
335
350
let rec print ppf t =
336
351
let colour = Flambda_colours. subkind () in
337
352
match t with
338
- | Anything -> ()
353
+ | Anything -> Format. fprintf ppf " * "
339
354
| Tagged_immediate ->
340
355
Format. fprintf ppf " @<0>%s=tagged_@<1>\u {2115}@<1>\u {1d55a}@<0>%s"
341
356
colour
@@ -356,10 +371,15 @@ module With_subkind = struct
356
371
Format. fprintf ppf " @<0>%s=boxed_@<1>\u {2115}@<1>\u {2115}@<0>%s"
357
372
colour
358
373
(Flambda_colours. normal () )
359
- | Block { tag; fields } ->
360
- Format. fprintf ppf " @<0>%s=Block{%a: %a}@<0>%s" colour Tag. print tag
361
- (Format. pp_print_list ~pp_sep: Format. pp_print_space print)
362
- fields
374
+ | Variant { consts; non_consts } ->
375
+ Format. fprintf ppf
376
+ " @<0>%s=Variant((consts (%a))@ (non_consts (%a)))@<0>%s" colour
377
+ Targetint_31_63.Set. print consts
378
+ (Tag.Scannable.Map. print (fun ppf fields ->
379
+ Format. fprintf ppf " [%a]"
380
+ (Format. pp_print_list ~pp_sep: Format. pp_print_space print)
381
+ fields))
382
+ non_consts
363
383
(Flambda_colours. normal () )
364
384
| Float_block { num_fields } ->
365
385
Format. fprintf ppf " @<0>%s=Float_block(%d)@<0>%s" colour num_fields
@@ -399,7 +419,7 @@ module With_subkind = struct
399
419
match subkind with
400
420
| Anything -> ()
401
421
| Boxed_float | Boxed_int32 | Boxed_int64 | Boxed_nativeint
402
- | Tagged_immediate | Block _ | Float_block _ | Float_array
422
+ | Tagged_immediate | Variant _ | Float_block _ | Float_array
403
423
| Immediate_array | Value_array | Generic_array ->
404
424
Misc. fatal_errorf " Subkind %a is not valid for kind %a" Subkind. print
405
425
subkind print kind));
@@ -448,7 +468,14 @@ module With_subkind = struct
448
468
" Block with fields of non-Value kind (use \
449
469
[Flambda_kind.With_subkind.float_block] for float records)" ;
450
470
let fields = List. map (fun t -> t.subkind) fields in
451
- create value (Block { tag; fields })
471
+ match Tag.Scannable. of_tag tag with
472
+ | Some tag ->
473
+ create value
474
+ (Variant
475
+ { consts = Targetint_31_63.Set. empty;
476
+ non_consts = Tag.Scannable.Map. singleton tag fields
477
+ })
478
+ | None -> Misc. fatal_errorf " Tag %a is not scannable" Tag. print tag
452
479
453
480
let float_block ~num_fields = create value (Float_block { num_fields })
454
481
@@ -468,12 +495,34 @@ module With_subkind = struct
468
495
| Pboxedintval Pint64 -> boxed_int64
469
496
| Pboxedintval Pnativeint -> boxed_nativeint
470
497
| Pintval -> tagged_immediate
471
- | Pblock { tag; fields } ->
472
- (* If we have [Obj.double_array_tag] here, this is always an all-float
473
- block, not an array. *)
474
- if tag = Obj. double_array_tag
475
- then float_block ~num_fields: (List. length fields)
476
- else block (Tag. create_exn tag) (List. map from_lambda fields)
498
+ | Pvariant { consts; non_consts } -> (
499
+ match consts, non_consts with
500
+ | [] , [] -> Misc. fatal_error " [Pvariant] with no constructors at all"
501
+ | [] , [(tag, fields)] when tag = Obj. double_array_tag ->
502
+ (* If we have [Obj.double_array_tag] here, this is always an all-float
503
+ block, not an array. *)
504
+ float_block ~num_fields: (List. length fields)
505
+ | [] , _ :: _ | _ :: _ , [] | _ :: _ , _ :: _ ->
506
+ let consts =
507
+ Targetint_31_63.Set. of_list
508
+ (List. map
509
+ (fun const ->
510
+ Targetint_31_63. int (Targetint_31_63.Imm. of_int const))
511
+ consts)
512
+ in
513
+ let non_consts =
514
+ List. fold_left
515
+ (fun non_consts (tag , fields ) ->
516
+ match Tag.Scannable. create tag with
517
+ | Some tag ->
518
+ Tag.Scannable.Map. add tag
519
+ (List. map (fun vk -> subkind (from_lambda vk)) fields)
520
+ non_consts
521
+ | None ->
522
+ Misc. fatal_errorf " Non-scannable tag %d in [Pvariant]" tag)
523
+ Tag.Scannable.Map. empty non_consts
524
+ in
525
+ create value (Variant { consts; non_consts }))
477
526
| Parrayval Pfloatarray -> float_array
478
527
| Parrayval Pintarray -> immediate_array
479
528
| Parrayval Paddrarray -> value_array
@@ -489,7 +538,7 @@ module With_subkind = struct
489
538
Format. fprintf ppf " @[%a%a@]" print kind Subkind. print subkind
490
539
| ( (Naked_number _ | Region | Rec_info ),
491
540
( Boxed_float | Boxed_int32 | Boxed_int64 | Boxed_nativeint
492
- | Tagged_immediate | Block _ | Float_block _ | Float_array
541
+ | Tagged_immediate | Variant _ | Float_block _ | Float_array
493
542
| Immediate_array | Value_array | Generic_array ) ) ->
494
543
assert false
495
544
(* see [create] *)
@@ -511,7 +560,9 @@ module With_subkind = struct
511
560
match t.subkind with
512
561
| Anything -> false
513
562
| Boxed_float | Boxed_int32 | Boxed_int64 | Boxed_nativeint
514
- | Tagged_immediate | Block _ | Float_block _ | Float_array | Immediate_array
515
- | Value_array | Generic_array ->
563
+ | Tagged_immediate | Variant _ | Float_block _ | Float_array
564
+ | Immediate_array | Value_array | Generic_array ->
516
565
true
566
+
567
+ let erase_subkind t = { t with subkind = Anything }
517
568
end
0 commit comments