[erlang-patches] Optimize handling of local fun variables in v3_kernel

Anthony Ramine <>
Thu Jan 10 13:33:03 CET 2013


Le 9 janv. 2013 à 17:32, Björn Gustavsson a écrit :

> The code handles free variables. As far as I can understand, there
> can be no free variables in this case, so you should simplify the code.

You're right and wrong :) There can be no free variables if the Core Erlang
code comes from a current Erlang module, but there can be if the Core Erlang
was handwritten or generated by my EEP37 patch, for example:

module 'foo' ['bar'/1,
	      'module_info'/0,
	      'module_info'/1]
    attributes []
'bar'/1 =
    %% Line 4
    fun (_cor0) ->
	letrec
	    'Bar'/1 =
		%% Line 5
		( fun (_cor4) ->
		      let <Bar> = 'Bar'/1
		      in  case _cor4 of
			    <1> when 'true' ->
				1
			    <N> when 'true' ->
				let <_cor3> =
				    call 'erlang':'*'
					(N, _cor0)
				in  let <_cor1> =
					call 'erlang':'-'
					    (N, 1)
				    in  let <_cor2> =
					    apply Bar
						(_cor1)
					in  call 'erlang':'*'
						(_cor3, _cor2)
			  end
		  -| [{'id',{0,0,'Bar'}}] )
	in  'Bar'/1
'module_info'/0 =
    fun () ->
	call 'erlang':'get_module_info'
	    ('foo')
'module_info'/1 =
    fun (_cor0) ->
	call 'erlang':'get_module_info'
	    ('foo', _cor0)
end

In 'bar'/1, _cor0 is a free variable inside 'Bar'/1; thus free variables need
to be handled to remove the reverse eta conversion in a future-proof way.

The differences between master and my patch when running erlc +to_kernel foo.core
are:

--- foo.kernel.orig	2013-01-10 13:27:28.000000000 +0100
+++ foo.kernel	2013-01-10 13:27:36.000000000 +0100
@@ -5,18 +5,16 @@
 attributes []
 fdef 'bar'/1(_Xcor0) =
   do
-    bif (internal 'make_fun'/4)('-bar/1-anonymous-2-', 2, 0, 0, _Xcor0) >> <_ker2>
+    bif (internal 'make_fun'/4)('-bar/1-Bar/1-0-', 2, 0, 0, _Xcor0) >> <_ker1>
   then
-  <<_ker2>>
+  <<_ker1>>
 fdef 'module_info'/0() =
   enter (remote 'erlang':'get_module_info'/1)('foo')
 fdef 'module_info'/1(_Xcor0) =
   enter (remote 'erlang':'get_module_info'/2)('foo', _Xcor0)
-fdef '-bar/1-anonymous-2-'/2(_ker0, _Xcor0) =
-  enter (local '-bar/1-Bar/1-0-'/2)(_ker0, _Xcor0)
 fdef '-bar/1-Bar/1-0-'/2(_Xcor4, _Xcor0) =
   do
-    bif (internal 'make_fun'/4)('-bar/1-anonymous-1-', 2, 0, 0, _Xcor0) >> <Bar>
+    bif (internal 'make_fun'/4)('-bar/1-Bar/1-0-', 2, 0, 0, _Xcor0) >> <Bar>
   then
   match _Xcor4
     alt
@@ -34,10 +32,8 @@
 	call (Bar)(_Xcor1) >> <_Xcor2>
       then
       do
-	bif (remote 'erlang':'*'/2)(_Xcor3, _Xcor2) >> <_ker1>
+	bif (remote 'erlang':'*'/2)(_Xcor3, _Xcor2) >> <_ker0>
       then
-      <<_ker1>>
+      <<_ker0>>
   end >> <>
-fdef '-bar/1-anonymous-1-'/2(V1, _Xcor0) =
-  enter (local '-bar/1-Bar/1-0-'/2)(V1, _Xcor0)
 end
\ No newline at end of file

Fredrik, I'll fix the failing test cases from trace_local_SUITE and come back to you
when I'm done. Thanks for the feedback.

Regards,

-- 
Anthony Ramine



More information about the erlang-patches mailing list