summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changes1
-rw-r--r--bytecomp/simplif.ml24
2 files changed, 25 insertions, 0 deletions
diff --git a/Changes b/Changes
index 585fd8387..705fb9201 100644
--- a/Changes
+++ b/Changes
@@ -18,6 +18,7 @@ Compilers:
- Better reporting of compiler version mismatch in .cmi files
* Warning 28 is now enabled by default.
- New option -absname to use absolute paths in error messages
+- Optimize away compile-time beta-redexes, e.g. (fun x y -> e) a b.
Native-code compiler:
- Optimized handling of partially-applied functions (PR#5287)
diff --git a/bytecomp/simplif.ml b/bytecomp/simplif.ml
index 892fbe7ea..1883f7151 100644
--- a/bytecomp/simplif.ml
+++ b/bytecomp/simplif.ml
@@ -272,6 +272,18 @@ let simplify_exits lam =
in
simplif lam
+(* Compile-time beta-reduction of functions immediately applied:
+ Lapply(Lfunction(Curried, params, body), args, loc) ->
+ let paramN = argN in ... let param1 = arg1 in body
+ Lapply(Lfunction(Tupled, params, body), [Lprim(Pmakeblock(args))], loc) ->
+ let paramN = argN in ... let param1 = arg1 in body
+ Assumes |args| = |params|.
+*)
+
+let beta_reduce params body args =
+ List.fold_left2 (fun l param arg -> Llet(Strict, param, arg, l))
+ body params args
+
(* Simplification of lets *)
let simplify_lets lam =
@@ -322,6 +334,12 @@ let simplify_lets lam =
| Lconst cst -> ()
| Lvar v ->
use_var bv v 1
+ | Lapply(Lfunction(Curried, params, body), args, _)
+ when optimize && List.length params = List.length args ->
+ count bv (beta_reduce params body args)
+ | Lapply(Lfunction(Tupled, params, body), [Lprim(Pmakeblock _, args)], _)
+ when optimize && List.length params = List.length args ->
+ count bv (beta_reduce params body args)
| Lapply(l1, ll, _) ->
count bv l1; List.iter (count bv) ll
| Lfunction(kind, params, l) ->
@@ -397,6 +415,12 @@ let simplify_lets lam =
l
end
| Lconst cst as l -> l
+ | Lapply(Lfunction(Curried, params, body), args, _)
+ when optimize && List.length params = List.length args ->
+ simplif (beta_reduce params body args)
+ | Lapply(Lfunction(Tupled, params, body), [Lprim(Pmakeblock _, args)], _)
+ when optimize && List.length params = List.length args ->
+ simplif (beta_reduce params body args)
| Lapply(l1, ll, loc) -> Lapply(simplif l1, List.map simplif ll, loc)
| Lfunction(kind, params, l) -> Lfunction(kind, params, simplif l)
| Llet(str, v, Lvar w, l2) when optimize ->