[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