[m-rev.] diff: optimise single outputs in erlang backend
Peter Wang
wangp at students.csse.unimelb.edu.au
Mon Jul 9 14:50:54 AEST 2007
Branches: main
Change the calling convention on the Erlang backend so that model_det
predicates/functions which have a single output variable directly return the
value of that variable, instead of a 1-tuple containing that value.
This change makes the compiler built with the Erlang backend, compiled to
native code, about 4% faster at compiling middle_rec.m.
compiler/elds.m:
Add helper function tuple_or_single_expr.
compiler/erl_call_gen.m:
Change the calling convention in make_det_call.
compiler/erl_code_gen.m:
Change the calling convention in erl_gen_proc_body.
Update the code generated for simplified unify/compare predicates
for the new calling convention.
compiler/erl_rtti.m:
Change the calling convention for method wrappers and unify/compare
wrappers.
compiler/erl_unify_gen.m:
Conform to the new calling convention when making closures.
library/erlang_rtti_implementation.m:
library/exception.m:
Conform to the new calling convention in hand-written code.
Index: compiler/elds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/elds.m,v
retrieving revision 1.13
diff -u -r1.13 elds.m
--- compiler/elds.m 19 Jun 2007 01:10:52 -0000 1.13
+++ compiler/elds.m 9 Jul 2007 03:00:16 -0000
@@ -352,6 +352,12 @@
:- func elds_clause_arity(elds_clause) = arity.
+ % tuple_or_single_expr(List)
+ % If List contains exactly one expression, return that expression.
+ % Otherwise return a tuple of the expressions in List.
+ %
+:- func tuple_or_single_expr(list(elds_expr)) = elds_expr.
+
%
% make_enum_alternative(F)
%
@@ -444,6 +450,13 @@
elds_clause_arity(elds_clause(Args, _Expr)) = list.length(Args).
+tuple_or_single_expr(List) =
+ ( List = [SingleExpr] ->
+ SingleExpr
+ ;
+ elds_term(elds_tuple(List))
+ ).
+
make_enum_alternative(F) = elds_tuple([elds_term(elds_atom(unqualified(F)))]).
%-----------------------------------------------------------------------------%
Index: compiler/erl_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_call_gen.m,v
retrieving revision 1.8
diff -u -r1.8 erl_call_gen.m
--- compiler/erl_call_gen.m 2 Jul 2007 05:30:28 -0000 1.8
+++ compiler/erl_call_gen.m 9 Jul 2007 03:00:16 -0000
@@ -206,7 +206,7 @@
)
;
OutputVars = [_ | _],
- UnpackTerm = elds_term(elds_tuple(elds.exprs_from_vars(OutputVars))),
+ UnpackTerm = tuple_or_single_expr(exprs_from_vars(OutputVars)),
(if
MaybeSuccessExpr = yes(UnpackTerm)
then
@@ -627,17 +627,20 @@
OutputVarsNames = list.map(foreign_arg_name, OutputForeignArgs),
ForeignCodeExpr = elds_foreign_code(ForeignCode),
- OutputTuple = elds_term(elds_tuple(
- exprs_from_fixed_vars(OutputVarsNames))),
% Create the inner lambda function.
(
CodeModel = model_det,
%
% <ForeignCodeExpr>,
+ % SingleOutput
+ % or
+ % <ForeignCodeExpr>,
% {Outputs, ...}
%
- InnerFunStatement = join_exprs(ForeignCodeExpr, OutputTuple)
+ OutputExpr = tuple_or_single_expr(
+ exprs_from_fixed_vars(OutputVarsNames)),
+ InnerFunStatement = join_exprs(ForeignCodeExpr, OutputExpr)
;
CodeModel = model_semi,
%
@@ -648,6 +651,8 @@
% end
%
InnerFunStatement = join_exprs(ForeignCodeExpr, MaybePlaceOutputs),
+ OutputTuple = elds_term(elds_tuple(
+ exprs_from_fixed_vars(OutputVarsNames))),
MaybePlaceOutputs = elds_case_expr(SuccessInd, [OnTrue, OnFalse]),
SuccessInd = elds_term(elds_fixed_name_var("SUCCESS_INDICATOR")),
OnTrue = elds_case(elds_true, OutputTuple),
Index: compiler/erl_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_gen.m,v
retrieving revision 1.18
diff -u -r1.18 erl_code_gen.m
--- compiler/erl_code_gen.m 3 Jul 2007 04:48:28 -0000 1.18
+++ compiler/erl_code_gen.m 9 Jul 2007 03:00:16 -0000
@@ -278,11 +278,11 @@
% '__Compare__'(X, Y) ->
% case X =:= Y of
- % true -> {{'='}};
+ % true -> {'='};
% false ->
% case X < Y of
- % true -> {{'<'}};
- % false -> {{'>'}};
+ % true -> {'<'};
+ % false -> {'>'};
% end
% end.
%
@@ -290,23 +290,18 @@
ClauseExpr = elds_case_expr(CondEq, [IsEq, IsNotEq]),
CondEq = elds_binop((=:=), XExpr, YExpr),
- IsEq = elds_case(elds_true, enum_in_tuple("=")),
+ IsEq = elds_case(elds_true, elds_term(make_enum_alternative("="))),
IsNotEq = elds_case(elds_false, elds_case_expr(CondLt, [IsLt, IsGt])),
CondLt = elds_binop((<), XExpr, YExpr),
- IsLt = elds_case(elds_true, enum_in_tuple("<")),
- IsGt = elds_case(elds_false, enum_in_tuple(">")),
+ IsLt = elds_case(elds_true, elds_term(make_enum_alternative("<"))),
+ IsGt = elds_case(elds_false, elds_term(make_enum_alternative(">"))),
erl_gen_info_get_varset(Info, ProcVarSet),
erl_gen_info_get_env_vars(Info, EnvVarNames),
ProcDefn = elds_defn(proc(PredId, ProcId), ProcVarSet,
body_defined_here(Clause), EnvVarNames).
-:- func enum_in_tuple(string) = elds_expr.
-
-enum_in_tuple(X) =
- elds_term(elds_tuple([elds_term(make_enum_alternative(X))])).
-
%-----------------------------------------------------------------------------%
%
% Code for handling individual procedures
@@ -381,9 +376,18 @@
erl_gen_info_get_output_vars(!.Info, OutputVars),
OutputVarsExprs = exprs_from_vars(OutputVars),
(
- ( CodeModel = model_det
- ; CodeModel = model_semi
- ),
+ CodeModel = model_det,
+ InputVarsTerms = terms_from_vars(InputVars),
+ %
+ % On success, the procedure returns either:
+ % - the single output variable, or
+ % - a tuple of its output variables if there are zero or two or more
+ % output variables.
+ %
+ SuccessExpr = tuple_or_single_expr(OutputVarsExprs),
+ InstMap = InstMap0
+ ;
+ CodeModel = model_semi,
InputVarsTerms = terms_from_vars(InputVars),
%
% On success, the procedure returns a tuple of its output variables.
Index: compiler/erl_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_rtti.m,v
retrieving revision 1.13
diff -u -r1.13 erl_rtti.m
--- compiler/erl_rtti.m 14 Jun 2007 04:43:50 -0000 1.13
+++ compiler/erl_rtti.m 9 Jul 2007 03:00:16 -0000
@@ -318,11 +318,16 @@
determinism_to_code_model(Detism, CodeModel),
WrapperOutputVarsExprs = exprs_from_vars(WrapperOutputVars),
(
- ( CodeModel = model_det
- ; CodeModel = model_semi
- ),
+ CodeModel = model_det,
AllWrapperInputVars = [TCIVar | WrapperInputVars],
- % On success we return a tuple of the output arguments of the call.
+ % On success we either return a tuple of the output variables of the
+ % call, or if there is exactly one output variable, just that output
+ % variable.
+ SuccessExpr0 = tuple_or_single_expr(WrapperOutputVarsExprs)
+ ;
+ CodeModel = model_semi,
+ AllWrapperInputVars = [TCIVar | WrapperInputVars],
+ % On success we return a tuple of the output variables of the call.
SuccessExpr0 = elds_term(elds_tuple(WrapperOutputVarsExprs))
;
CodeModel = model_non,
@@ -675,9 +680,13 @@
determinism_to_code_model(Detism, CodeModel),
WrapperOutputVarsExprs = exprs_from_vars(WrapperOutputVars),
(
- ( CodeModel = model_det
- ; CodeModel = model_semi
- ),
+ CodeModel = model_det,
+ % On success we either return a tuple of the output variables of the
+ % call, or if there is exactly one output variable, just that output
+ % variable.
+ SuccessExpr0 = tuple_or_single_expr(WrapperOutputVarsExprs)
+ ;
+ CodeModel = model_semi,
% On success we return a tuple of the output arguments of the call.
SuccessExpr0 = elds_term(elds_tuple(WrapperOutputVarsExprs))
;
Index: compiler/erl_unify_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_unify_gen.m,v
retrieving revision 1.7
diff -u -r1.7 erl_unify_gen.m
--- compiler/erl_unify_gen.m 14 Jun 2007 03:52:48 -0000 1.7
+++ compiler/erl_unify_gen.m 9 Jul 2007 03:00:16 -0000
@@ -363,9 +363,11 @@
OutputVarsInclDummyExprs = exprs_from_vars(OutputVarsInclDummy),
(
- ( CodeModel = model_det
- ; CodeModel = model_semi
- ),
+ CodeModel = model_det,
+ ClosureInputArgs = InputExtraVars,
+ SuccessExpr0 = tuple_or_single_expr(OutputVarsInclDummyExprs)
+ ;
+ CodeModel = model_semi,
ClosureInputArgs = InputExtraVars,
SuccessExpr0 = elds_term(elds_tuple(OutputVarsInclDummyExprs))
;
Index: library/erlang_rtti_implementation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/erlang_rtti_implementation.m,v
retrieving revision 1.11
diff -u -r1.11 erlang_rtti_implementation.m
--- library/erlang_rtti_implementation.m 5 Jul 2007 02:53:49 -0000 1.11
+++ library/erlang_rtti_implementation.m 9 Jul 2007 03:00:16 -0000
@@ -1060,39 +1060,39 @@
result_call_4(Pred::in, Res::out, X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(X, Y)
+ Res = Pred(X, Y)
").
:- pragma foreign_proc("Erlang",
result_call_5(Pred::in, Res::out, A::in, X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(A, X, Y)
+ Res = Pred(A, X, Y)
").
:- pragma foreign_proc("Erlang",
result_call_6(Pred::in, Res::out, A::in, B::in, X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(A, B, X, Y)
+ Res = Pred(A, B, X, Y)
").
:- pragma foreign_proc("Erlang",
result_call_7(Pred::in, Res::out, A::in, B::in, C::in, X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(A, B, C, X, Y)
+ Res = Pred(A, B, C, X, Y)
").
:- pragma foreign_proc("Erlang",
result_call_8(Pred::in, Res::out, A::in, B::in, C::in, D::in, X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(A, B, C, D, X, Y)
+ Res = Pred(A, B, C, D, X, Y)
").
:- pragma foreign_proc("Erlang",
result_call_9(Pred::in, Res::out, A::in, B::in, C::in, D::in, E::in,
X::in, Y::in),
[will_not_call_mercury, promise_pure, thread_safe],
"
- {Res} = Pred(A, B, C, D, E, X, Y)
+ Res = Pred(A, B, C, D, E, X, Y)
").
%-----------------------------------------------------------------------------%
Index: library/exception.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/exception.m,v
retrieving revision 1.126
diff -u -r1.126 exception.m
--- library/exception.m 6 Jun 2007 01:26:26 -0000 1.126
+++ library/exception.m 9 Jul 2007 03:00:16 -0000
@@ -1401,7 +1401,7 @@
catch_impl(Pred::pred(out) is det, Handler::in(handler), T::out),
[will_not_call_mercury, promise_pure],
"
- {T} = try
+ T = try
Pred()
catch
throw: {'ML_exception', Excp} ->
@@ -1421,11 +1421,11 @@
Handler(Excp)
end
of
- {T} ->
- SUCCESS_INDICATOR = true;
- _ ->
+ fail ->
SUCCESS_INDICATOR = false,
- T = null
+ T = null;
+ T ->
+ SUCCESS_INDICATOR = true
end
").
@@ -1444,7 +1444,7 @@
Pred(Succeed)
catch
throw: {'ML_exception', Excp} ->
- {Result} = Handler(Excp),
+ Result = Handler(Excp),
Succeed(Result)
end.
@@ -1453,7 +1453,7 @@
Pred(Succeed)
catch
throw: {'ML_exception', Excp} ->
- {Result} = Handler(Excp),
+ Result = Handler(Excp),
Succeed(Result)
end.
").
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list