[m-rev.] diff: fix more problems with dummy vars in erlang
Peter Wang
wangp at students.csse.unimelb.edu.au
Mon Jun 4 16:26:25 AEST 2007
Estimated hours taken: 4
Branches: main
Fix more problems with dummy variables in the Erlang backend.
compiler/erl_code_gen.m:
compiler/erl_code_util.m:
When we bind unbound variables to ensure two or more branches of a
conditional statement bind the same sets of variables, don't bother
binding variables which are of dummy types.
compiler/erl_call_gen.m:
Replace dummy variables which appear as input arguments to calls with
`false'. Then we don't need to materialise dummy variables before
calls.
library/io.m:
Uncomment the Erlang implementation of io.read_char_code_2, which was
commented out before because it exposed the above bugs when it was
inlined. Replace it with a better definition.
Index: compiler/erl_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_call_gen.m,v
retrieving revision 1.5
diff -u -r1.5 erl_call_gen.m
--- compiler/erl_call_gen.m 30 May 2007 05:15:04 -0000 1.5
+++ compiler/erl_call_gen.m 4 Jun 2007 06:00:20 -0000
@@ -88,6 +88,16 @@
prog_vars::in, prog_vars::in, maybe(elds_expr)::in,
elds_expr::out) is det.
+ % erl_make_call_replace_dummies(Info, CodeModel, CallTarget,
+ % InputVars, OutputVars, MaybeSuccessExpr, Statement)
+ %
+ % As above, but in the generated call, replace any input variables which
+ % are of dummy types with `false'.
+ %
+:- pred erl_make_call_replace_dummies(erl_gen_info::in, code_model::in,
+ elds_call_target::in, prog_vars::in, prog_vars::in, maybe(elds_expr)::in,
+ elds_expr::out) is det.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -99,6 +109,7 @@
:- import_module libs.compiler_util.
:- import_module int.
+:- import_module map.
:- import_module pair.
%-----------------------------------------------------------------------------%
@@ -119,15 +130,46 @@
ArgVars, CalleeTypes, ArgModes, InputVars, OutputVars),
CallTarget = elds_call_plain(proc(PredId, ProcId)),
- erl_make_call(CodeModel, CallTarget, InputVars, OutputVars,
- MaybeSuccessExpr, DoCall),
- materialise_dummies_before_expr(!.Info, InputVars, DoCall, Statement).
+ erl_make_call_replace_dummies(!.Info, CodeModel, CallTarget,
+ InputVars, OutputVars, MaybeSuccessExpr, Statement).
%-----------------------------------------------------------------------------%
-erl_make_call(CodeModel, CallTarget, InputVars, OutputVars, MaybeSuccessExpr,
- Statement) :-
+erl_make_call(CodeModel, CallTarget, InputVars, OutputVars,
+ MaybeSuccessExpr, Statement) :-
InputExprs = exprs_from_vars(InputVars),
+ erl_make_call_2(CodeModel, CallTarget, InputExprs, OutputVars,
+ MaybeSuccessExpr, Statement).
+
+erl_make_call_replace_dummies(Info, CodeModel, CallTarget,
+ InputVars, OutputVars, MaybeSuccessExpr, Statement) :-
+ erl_gen_info_get_module_info(Info, ModuleInfo),
+ erl_gen_info_get_var_types(Info, VarTypes),
+ InputExprs = list.map(var_to_expr_or_false(ModuleInfo, VarTypes),
+ InputVars),
+ erl_make_call_2(CodeModel, CallTarget, InputExprs, OutputVars,
+ MaybeSuccessExpr, Statement).
+
+:- func var_to_expr_or_false(module_info, vartypes, prog_var) = elds_expr.
+
+var_to_expr_or_false(ModuleInfo, VarTypes, Var) = Expr :-
+ (if
+ % The variable may not be in VarTypes if it did not exist in the
+ % HLDS, i.e. we invented the variable. Those should be kept.
+ map.search(VarTypes, Var, Type),
+ is_dummy_argument_type(ModuleInfo, Type)
+ then
+ Expr = elds_term(elds_false)
+ else
+ Expr = expr_from_var(Var)
+ ).
+
+:- pred erl_make_call_2(code_model::in, elds_call_target::in,
+ list(elds_expr)::in, prog_vars::in, maybe(elds_expr)::in,
+ elds_expr::out) is det.
+
+erl_make_call_2(CodeModel, CallTarget, InputExprs, OutputVars,
+ MaybeSuccessExpr, Statement) :-
(
CodeModel = model_det,
make_det_call(CallTarget, InputExprs, OutputVars, MaybeSuccessExpr,
@@ -267,8 +309,8 @@
determinism_to_code_model(Detism, CallCodeModel),
CallTarget = elds_call_ho(expr_from_var(ClosureVar)),
- erl_make_call(CallCodeModel, CallTarget, InputVars, OutputVars,
- MaybeSuccessExpr, DoCall),
+ erl_make_call_replace_dummies(!.Info, CallCodeModel, CallTarget, InputVars,
+ OutputVars, MaybeSuccessExpr, DoCall),
% The callee function is responsible for materialising dummy output
% variables.
@@ -318,16 +360,11 @@
% of the argument list.
determinism_to_code_model(Detism, CallCodeModel),
CallTarget = elds_call_ho(MethodWrapperVarExpr),
- erl_make_call(CallCodeModel, CallTarget, [TCIVar | CallInputVars],
- CallOutputVars, MaybeSuccessExpr, DoCall),
-
- ExtractAndCall = join_exprs(ExtractBaseTypeclassInfo,
- join_exprs(ExtractMethodWrapper, DoCall)),
+ erl_make_call_replace_dummies(!.Info, CallCodeModel, CallTarget,
+ [TCIVar | CallInputVars], CallOutputVars, MaybeSuccessExpr, DoCall),
- % The callee function is responsible for materialising dummy output
- % variables.
- materialise_dummies_before_expr(!.Info, CallInputVars, ExtractAndCall,
- Statement).
+ Statement = join_exprs(ExtractBaseTypeclassInfo,
+ join_exprs(ExtractMethodWrapper, DoCall)).
%-----------------------------------------------------------------------------%
Index: compiler/erl_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_gen.m,v
retrieving revision 1.7
diff -u -r1.7 erl_code_gen.m
--- compiler/erl_code_gen.m 1 Jun 2007 06:41:23 -0000 1.7
+++ compiler/erl_code_gen.m 4 Jun 2007 06:00:20 -0000
@@ -660,8 +660,7 @@
% bind the same set of variables. This might not be true if the Mercury
% compiler knows that a case calls a procedure which throws an exception.
%
- erl_gen_info_get_module_info(!.Info, ModuleInfo),
- erl_bind_unbound_vars(ModuleInfo, MustBindNonLocals, Goal, InstMap,
+ erl_bind_unbound_vars(!.Info, MustBindNonLocals, Goal, InstMap,
Statement0, Statement),
ELDSCase = elds_case(Pattern, Statement).
@@ -823,9 +822,9 @@
ElseStatement0, !Info),
% Make sure both branches bind the same sets of variables.
- erl_bind_unbound_vars(ModuleInfo, ElseVars, Then, InstMap1,
+ erl_bind_unbound_vars(!.Info, ElseVars, Then, InstMap1,
ThenStatement0, ThenStatement),
- erl_bind_unbound_vars(ModuleInfo, ThenVars, Else, InstMap0,
+ erl_bind_unbound_vars(!.Info, ThenVars, Else, InstMap0,
ElseStatement0, ElseStatement),
IfStatement = elds_case_expr(CondStatement, [TrueCase, FalseCase]),
Index: compiler/erl_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_code_util.m,v
retrieving revision 1.5
diff -u -r1.5 erl_code_util.m
--- compiler/erl_code_util.m 1 Jun 2007 04:25:08 -0000 1.5
+++ compiler/erl_code_util.m 4 Jun 2007 06:00:20 -0000
@@ -124,8 +124,7 @@
:- pred erl_bound_nonlocals_in_goal(module_info::in, instmap::in,
hlds_goal::in, set(prog_var)::out) is det.
- % erl_bind_unbound_vars(ModuleInfo, VarsToBind, Goal, InstMap,
- % !Statement)
+ % erl_bind_unbound_vars(Info, VarsToBind, Goal, InstMap, !Statement)
%
% For any variables in VarsToBind which are not bound in Goal, add
% assignment expressions to !Statement. This is necessary to ensure that
@@ -135,7 +134,9 @@
% variables do not matter since this is only done to appease the
% Erlang compiler.
%
-:- pred erl_bind_unbound_vars(module_info::in, set(prog_var)::in,
+ % Variables of dummy types are not bound.
+ %
+:- pred erl_bind_unbound_vars(erl_gen_info::in, set(prog_var)::in,
hlds_goal::in, instmap::in, elds_expr::in, elds_expr::out) is det.
% erl_create_renaming(Vars, Subst, !Info):
@@ -359,10 +360,13 @@
IsBound = var_is_bound_in_instmap_delta(ModuleInfo, InstMap, InstmapDelta),
BoundNonLocals = set.filter(IsBound, NonLocals).
-erl_bind_unbound_vars(ModuleInfo, VarsToBind, Goal, InstMap,
+erl_bind_unbound_vars(Info, VarsToBind, Goal, InstMap,
Statement0, Statement) :-
+ erl_gen_info_get_module_info(Info, ModuleInfo),
+ erl_gen_info_get_var_types(Info, VarTypes),
erl_bound_nonlocals_in_goal(ModuleInfo, InstMap, Goal, Bound),
- NotBound = set.difference(VarsToBind, Bound),
+ NotBound0 = set.difference(VarsToBind, Bound),
+ NotBound = set.filter(non_dummy_var(ModuleInfo, VarTypes), NotBound0),
(if set.empty(NotBound) then
Statement = Statement0
else
@@ -372,6 +376,12 @@
Statement = join_exprs(elds_block(Assignments), Statement0)
).
+:- pred non_dummy_var(module_info::in, vartypes::in, prog_var::in) is semidet.
+
+non_dummy_var(ModuleInfo, VarTypes, Var) :-
+ map.lookup(VarTypes, Var, Type),
+ not is_dummy_argument_type(ModuleInfo, Type).
+
%-----------------------------------------------------------------------------%
erl_create_renaming(Vars, Subst, !Info) :-
Index: library/io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/io.m,v
retrieving revision 1.386
diff -u -r1.386 io.m
--- library/io.m 31 May 2007 07:28:21 -0000 1.386
+++ library/io.m 4 Jun 2007 06:00:21 -0000
@@ -6744,16 +6744,21 @@
File.ungetc(Byte);
").
-/*
:- pragma foreign_proc("Erlang",
io.read_char_code_2(Stream::in, CharCode::out, _IO0::di, _IO::uo),
[will_not_call_mercury, promise_pure, tabled_for_io,
does_not_affect_liveness],
"
- % XXX this seems pretty horrible
- [CharCode] = io:get_chars('', 1)
+ {'ML_stream', _Id, IoDevice} = Stream,
+ case file:read(IoDevice, 1) of
+ {ok, [C]} ->
+ CharCode = C;
+ eof ->
+ CharCode = -1;
+ {error, _Reason} ->
+ CharCode = -2
+ 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