Skip to content

Commit dea4b3e

Browse files
authored
flambda-backend: Don't get the layout of arguments from patterns (#1179)
1 parent 6d3e85b commit dea4b3e

File tree

1 file changed

+57
-47
lines changed

1 file changed

+57
-47
lines changed

lambda/translcore.ml

Lines changed: 57 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -361,11 +361,18 @@ and transl_exp0 ~in_new_scope ~scopes e =
361361
body_layout (event_before ~scopes body (transl_exp ~scopes body))
362362
| Texp_function { arg_label = _; param; cases; partial;
363363
region; curry; warnings; arg_mode; alloc_mode } ->
364+
(* CR ncourant: it would be better if we had [arg_layout] here *)
365+
let arg_layout =
366+
match is_function_type e.exp_env e.exp_type with
367+
| None -> Misc.fatal_error "Translcore.transl_exp0: Type of a function is not a function type"
368+
| Some (arg_type, _) ->
369+
Typeopt.layout e.exp_env arg_type
370+
in
364371
let scopes =
365372
if in_new_scope then scopes
366373
else enter_anonymous_function ~scopes
367374
in
368-
transl_function ~scopes e alloc_mode param arg_mode cases partial warnings region curry
375+
transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry
369376
| Texp_apply({ exp_desc = Texp_ident(path, _, {val_kind = Val_prim p},
370377
Id_prim pmode);
371378
exp_type = prim_type; } as funct, oargs, pos, alloc_mode)
@@ -1072,10 +1079,10 @@ and transl_apply ~scopes
10721079

10731080
and transl_curried_function
10741081
~scopes loc return
1075-
repr ~region ~curry partial warnings (param:Ident.t) cases =
1082+
repr ~region ~curry partial warnings (param:Ident.t) arg_layout cases =
10761083
let max_arity = Lambda.max_arity () in
10771084
let rec loop ~scopes loc return ~arity ~region ~curry
1078-
partial warnings (param:Ident.t) cases =
1085+
partial warnings (param:Ident.t) arg_layout cases =
10791086
match curry, cases with
10801087
More_args {partial_mode},
10811088
[{c_lhs=pat; c_guard=None;
@@ -1091,12 +1098,18 @@ and transl_curried_function
10911098
if Parmatch.inactive ~partial pat
10921099
then
10931100
let partial_mode = transl_alloc_mode partial_mode in
1094-
let layout = layout pat.pat_env pat.pat_type in
10951101
let return_layout = function_return_layout exp_env exp_type in
1102+
let arg_layout' =
1103+
match is_function_type exp_env exp_type with
1104+
| None ->
1105+
Misc.fatal_error "Translcore.transl_curried_function: \
1106+
Type of Texp_function is not function"
1107+
| Some (lhs, _) -> layout exp_env lhs
1108+
in
10961109
let ((fnkind, params, return, region), body) =
10971110
loop ~scopes exp_loc return_layout
10981111
~arity:(arity + 1) ~region:region' ~curry:curry'
1099-
partial' warnings' param' cases'
1112+
partial' warnings' param' arg_layout' cases'
11001113
in
11011114
let fnkind =
11021115
match partial_mode, fnkind with
@@ -1109,8 +1122,8 @@ and transl_curried_function
11091122
assert (nlocal = List.length params);
11101123
Curried {nlocal = nlocal + 1}
11111124
in
1112-
((fnkind, (param, layout) :: params, return, region),
1113-
Matching.for_function ~scopes return_layout loc None (Lvar param, layout)
1125+
((fnkind, (param, arg_layout) :: params, return, region),
1126+
Matching.for_function ~scopes return_layout loc None (Lvar param, arg_layout)
11141127
[pat, body] partial)
11151128
else begin
11161129
begin match partial with
@@ -1123,18 +1136,18 @@ and transl_curried_function
11231136
| Partial -> ()
11241137
end;
11251138
transl_tupled_function ~scopes ~arity ~region ~curry
1126-
loc return repr partial param cases
1139+
loc return repr partial param arg_layout cases
11271140
end
11281141
| curry, cases ->
11291142
transl_tupled_function ~scopes ~arity ~region ~curry
1130-
loc return repr partial param cases
1143+
loc return repr partial param arg_layout cases
11311144
in
11321145
loop ~scopes loc return ~arity:1 ~region ~curry
1133-
partial warnings param cases
1146+
partial warnings param arg_layout cases
11341147

11351148
and transl_tupled_function
11361149
~scopes ~arity ~region ~curry loc return
1137-
repr partial (param:Ident.t) cases =
1150+
repr partial (param:Ident.t) arg_layout cases =
11381151
let partial_mode =
11391152
match curry with
11401153
| More_args {partial_mode} | Final_arg {partial_mode} ->
@@ -1153,21 +1166,13 @@ and transl_tupled_function
11531166
(Matching.flatten_pattern size c_lhs, c_guard, c_rhs))
11541167
cases in
11551168
let kinds =
1156-
(* All the patterns might not share the same types. We must take the
1157-
union of the patterns types *)
1158-
match pats_expr_list with
1159-
| [] -> assert false
1160-
| (pats, _, _) :: cases ->
1161-
let first_case_layouts =
1162-
List.map (fun pat -> layout pat.pat_env pat.pat_type) pats
1163-
in
1164-
List.fold_left
1165-
(fun kinds (pats, _, _) ->
1166-
List.map2 (fun kind pat ->
1167-
layout_union kind
1168-
(layout pat.pat_env pat.pat_type))
1169-
kinds pats)
1170-
first_case_layouts cases
1169+
match arg_layout with
1170+
| Pvalue (Pvariant { consts = []; non_consts = [0, kinds] }) ->
1171+
List.map (fun vk -> Pvalue vk) kinds
1172+
| _ ->
1173+
Misc.fatal_error
1174+
"Translcore.transl_tupled_function: \
1175+
Argument should be a tuple, but couldn't get the kinds"
11711176
in
11721177
let tparams =
11731178
List.map (fun kind -> Ident.create_local "param", kind) kinds
@@ -1181,29 +1186,16 @@ and transl_tupled_function
11811186
((Tupled, tparams, return, region), body)
11821187
with Matching.Cannot_flatten ->
11831188
transl_function0 ~scopes loc ~region ~partial_mode
1184-
return repr partial param cases
1189+
return repr partial param arg_layout cases
11851190
end
11861191
| _ -> transl_function0 ~scopes loc ~region ~partial_mode
1187-
return repr partial param cases
1192+
return repr partial param arg_layout cases
11881193

11891194
and transl_function0
11901195
~scopes loc ~region ~partial_mode return
1191-
repr partial (param:Ident.t) cases =
1192-
let layout =
1193-
match cases with
1194-
| [] ->
1195-
(* With Camlp4, a pattern matching might be empty *)
1196-
Lambda.layout_bottom
1197-
| {c_lhs=pat} :: other_cases ->
1198-
(* All the patterns might not share the same types. We must take the
1199-
union of the patterns types *)
1200-
List.fold_left (fun ly {c_lhs=pat} ->
1201-
Typeopt.layout_union ly
1202-
(layout pat.pat_env pat.pat_type))
1203-
(layout pat.pat_env pat.pat_type) other_cases
1204-
in
1196+
repr partial (param:Ident.t) arg_layout cases =
12051197
let body =
1206-
Matching.for_function ~scopes return loc repr (Lvar param, layout)
1198+
Matching.for_function ~scopes return loc repr (Lvar param, arg_layout)
12071199
(transl_cases ~scopes cases) partial
12081200
in
12091201
let region = region || not (may_allocate_in_region body) in
@@ -1213,17 +1205,17 @@ and transl_function0
12131205
| Alloc_local -> 1
12141206
| Alloc_heap -> 0
12151207
in
1216-
((Curried {nlocal}, [param, layout], return, region), body)
1208+
((Curried {nlocal}, [param, arg_layout], return, region), body)
12171209

1218-
and transl_function ~scopes e alloc_mode param arg_mode cases partial warnings region curry =
1210+
and transl_function ~scopes e alloc_mode param arg_mode arg_layout cases partial warnings region curry =
12191211
let mode = transl_alloc_mode alloc_mode in
12201212
let ((kind, params, return, region), body) =
12211213
event_function ~scopes e
12221214
(function repr ->
12231215
let pl = push_defaults e.exp_loc arg_mode cases partial warnings in
12241216
let return_layout = function_return_layout e.exp_env e.exp_type in
12251217
transl_curried_function ~scopes e.exp_loc return_layout
1226-
repr ~region ~curry partial warnings param pl)
1218+
repr ~region ~curry partial warnings param arg_layout pl)
12271219
in
12281220
let attr = default_function_attribute in
12291221
let loc = of_location ~scopes e.exp_loc in
@@ -1570,13 +1562,31 @@ and transl_letop ~scopes loc env let_ ands param case partial warnings =
15701562
in
15711563
let exp = loop (layout let_.bop_exp.exp_env let_.bop_exp.exp_type) (transl_exp ~scopes let_.bop_exp) ands in
15721564
let func =
1565+
let arg_layout =
1566+
match Typeopt.is_function_type env let_.bop_op_type with
1567+
| None ->
1568+
Misc.fatal_error
1569+
"Translcore.transl_letop: letop should be a function"
1570+
| Some (_, rhs) ->
1571+
match Typeopt.is_function_type env rhs with
1572+
| None ->
1573+
Misc.fatal_error
1574+
"Translcore.transl_letop: letop should have at least two arguments"
1575+
| Some (lhs, _) ->
1576+
match Typeopt.is_function_type env lhs with
1577+
| None ->
1578+
Misc.fatal_error
1579+
"Translcore.transl_letop: letop second argument should be a function"
1580+
| Some (arg_type, _) ->
1581+
Typeopt.layout env arg_type
1582+
in
15731583
let return_layout = layout case.c_rhs.exp_env case.c_rhs.exp_type in
15741584
let curry = More_args { partial_mode = Alloc_mode.global } in
15751585
let (kind, params, return, _region), body =
15761586
event_function ~scopes case.c_rhs
15771587
(function repr ->
15781588
transl_curried_function ~scopes case.c_rhs.exp_loc return_layout
1579-
repr ~region:true ~curry partial warnings param [case])
1589+
repr ~region:true ~curry partial warnings param arg_layout [case])
15801590
in
15811591
let attr = default_function_attribute in
15821592
let loc = of_location ~scopes case.c_rhs.exp_loc in

0 commit comments

Comments
 (0)