diff --git a/asmcomp/amd64/proc.ml b/asmcomp/amd64/proc.ml index a3aa9cfcb..f044afe59 100644 --- a/asmcomp/amd64/proc.ml +++ b/asmcomp/amd64/proc.ml @@ -76,6 +76,8 @@ let masm = Linux's dynamic loader also destroys r10. *) +let max_arguments_for_tailcalls = 10 + let int_reg_name = match Config.ccomp_type with | "msvc" -> diff --git a/asmcomp/arm/proc.ml b/asmcomp/arm/proc.ml index 9c088751e..a62c470ac 100644 --- a/asmcomp/arm/proc.ml +++ b/asmcomp/arm/proc.ml @@ -180,6 +180,8 @@ let not_supported ofs = fatal_error "Proc.loc_results: cannot call" remaining args on stack. Return values in r0...r7 or d0...d15. *) +let max_arguments_for_tailcalls = 8 + let single_regs arg = Array.map (fun arg -> [| arg |]) arg let ensure_single_regs res = Array.map (function diff --git a/asmcomp/arm64/proc.ml b/asmcomp/arm64/proc.ml index 6522a8489..eaf6a1353 100644 --- a/asmcomp/arm64/proc.ml +++ b/asmcomp/arm64/proc.ml @@ -140,6 +140,8 @@ let not_supported ofs = fatal_error "Proc.loc_results: cannot call" remaining args on stack. Return values in r0...r15 or d0...d15. *) +let max_arguments_for_tailcalls = 16 + let loc_arguments arg = calling_conventions 0 15 100 115 outgoing arg let loc_parameters arg = diff --git a/asmcomp/i386/proc.ml b/asmcomp/i386/proc.ml index de6c8d9ad..d1890012d 100644 --- a/asmcomp/i386/proc.ml +++ b/asmcomp/i386/proc.ml @@ -139,6 +139,9 @@ let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported ofs = fatal_error "Proc.loc_results: cannot call" +(* Six arguments in integer registers plus eight in global memory. *) +let max_arguments_for_tailcalls = 14 + let loc_arguments arg = calling_conventions 0 5 100 99 outgoing arg let loc_parameters arg = diff --git a/asmcomp/power/proc.ml b/asmcomp/power/proc.ml index e97fc00e0..419c29567 100644 --- a/asmcomp/power/proc.ml +++ b/asmcomp/power/proc.ml @@ -174,6 +174,8 @@ let ensure_single_regs res = | _ -> failwith "Proc.ensure_single_regs") res +let max_arguments_for_tailcalls = 8 + let loc_arguments arg = let (loc, ofs) = calling_conventions 0 7 100 112 outgoing 0 false (single_regs arg) diff --git a/asmcomp/proc.mli b/asmcomp/proc.mli index c7bca639a..5ecfd382d 100644 --- a/asmcomp/proc.mli +++ b/asmcomp/proc.mli @@ -37,6 +37,14 @@ val loc_external_arguments: Reg.t array array -> Reg.t array array * int val loc_external_results: Reg.t array -> Reg.t array val loc_exn_bucket: Reg.t +(* The maximum number of arguments of an OCaml to OCaml function call for + which it is guaranteed there will be no arguments passed on the stack. + (Above this limit, tail call optimization may be disabled.) + N.B. The values for this parameter in the backends currently assume + that no unboxed floats are passed using the OCaml calling conventions. +*) +val max_arguments_for_tailcalls : int + (* Maximal register pressures for pre-spilling *) val safe_register_pressure: Mach.operation -> int val max_register_pressure: Mach.operation -> int array diff --git a/asmcomp/s390x/proc.ml b/asmcomp/s390x/proc.ml index 5f1e44bb2..8c5312e21 100644 --- a/asmcomp/s390x/proc.ml +++ b/asmcomp/s390x/proc.ml @@ -125,6 +125,8 @@ let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported ofs = fatal_error "Proc.loc_results: cannot call" +let max_arguments_for_tailcalls = 5 + let loc_arguments arg = calling_conventions 0 4 100 103 outgoing 0 arg let loc_parameters arg = diff --git a/asmcomp/sparc/proc.ml b/asmcomp/sparc/proc.ml index f34a98729..7c296c044 100644 --- a/asmcomp/sparc/proc.ml +++ b/asmcomp/sparc/proc.ml @@ -133,6 +133,8 @@ let incoming ofs = Incoming ofs let outgoing ofs = Outgoing ofs let not_supported ofs = fatal_error "Proc.loc_results: cannot call" +let max_arguments_for_tailcalls = 10 + let loc_arguments arg = calling_conventions 6 15 100 105 outgoing arg let loc_parameters arg = diff --git a/driver/optmain.ml b/driver/optmain.ml index 2e48453b4..22f09ca81 100644 --- a/driver/optmain.ml +++ b/driver/optmain.ml @@ -26,9 +26,9 @@ module Backend = struct let size_int = Arch.size_int let big_endian = Arch.big_endian - (* CR mshinwell: this needs tying through to [Proc], although it may - necessitate the introduction of a new field in that module. *) - let max_sensible_number_of_arguments = 9 + let max_sensible_number_of_arguments = + (* The "-1" is to allow for a potential closure environment parameter. *) + Proc.max_arguments_for_tailcalls - 1 end let backend = (module Backend : Backend_intf.S)