[m-rev.] for review: fix bug with impure lambda expressions

Julien Fischer juliensf at cs.mu.OZ.AU
Thu Aug 11 14:36:51 AEST 2005


On Thu, 11 Aug 2005, Zoltan Somogyi wrote:

> On 10-Aug-2005, Julien Fischer <juliensf at cs.mu.OZ.AU> wrote:
> > +    % Partition the lists of arguments and variables into lists
> > +    % of non-output and output arguments and variables.
> > +    %
> > + :- pred partition_args_and_lambda_vars(
> > +    module_info::in, list(prog_term)::in,
> > +    list(prog_var)::in, list(mode)::in,
> > +    list(prog_term)::out, list(prog_term)::out,
> > +    list(prog_var)::out, list(prog_var)::out) is semidet.
> > +
> > +partition_args_and_lambda_vars(_, [], [], [], [], [], [], []).
> > +partition_args_and_lambda_vars(ModuleInfo, [ Arg | Args ],
> > +            [ LambdaVar | LambdaVars ],
> > +            [Mode | Modes], InputArgs, OutputArgs,
> > +            InputLambdaVars, OutputLambdaVars) :-
> > +        partition_args_and_lambda_vars(ModuleInfo, Args, LambdaVars, Modes,
> > +            InputArgs0, OutputArgs0, InputLambdaVars0, OutputLambdaVars0),
> > +        ( mode_is_output(ModuleInfo, Mode) ->
> > +            InputArgs        = InputArgs0,
> > +            OutputArgs       = [Arg | OutputArgs0],
> > +            InputLambdaVars  = InputLambdaVars0,
> > +            OutputLambdaVars = [ LambdaVar | OutputLambdaVars0 ]
> > +        ;
> > +            InputArgs        = [ Arg | InputArgs0],
> > +            OutputArgs       = OutputArgs0,
> > +            InputLambdaVars  = [ LambdaVar | InputLambdaVars0 ],
> > +            OutputLambdaVars = OutputLambdaVars0
> > +        ).
>
> arg_info.m already contains a bunch of predicates that do similar jobs.
> Use one of them if possible. If not, move this predicate to arg_info.m.
> Otherwise, the diff looks fine.
>

Actually, the above code is incorrect.  It doesn't take account of the
situation where one of the modes is undefined (which can happen at this
stage of compilation).  The relative diff of the fix is below.
(I'll make the relevant changes to the log message.)

I don't think the predicates in arg_info.m are all that related; in
particular most of the code there is used in later stages of
compilation.  It doesn't seem to need to deal with the possibility of
undefined modes.  Unless you feel strongly that this test belongs in
arg_info.m, I'm going to leave it here.


diff -u compiler/superhomogeneous.m compiler/superhomogeneous.m
--- compiler/superhomogeneous.m	10 Aug 2005 08:34:08 -0000
+++ compiler/superhomogeneous.m	10 Aug 2005 15:12:32 -0000
@@ -893,16 +893,30 @@
             InputLambdaVars, OutputLambdaVars) :-
         partition_args_and_lambda_vars(ModuleInfo, Args, LambdaVars, Modes,
             InputArgs0, OutputArgs0, InputLambdaVars0, OutputLambdaVars0),
-        ( mode_is_output(ModuleInfo, Mode) ->
-            InputArgs        = InputArgs0,
-            OutputArgs       = [Arg | OutputArgs0],
-            InputLambdaVars  = InputLambdaVars0,
-            OutputLambdaVars = [ LambdaVar | OutputLambdaVars0 ]
-        ;
+        %
+        % Calling mode_is_output/2 directly will cause the compiler to
+        % abort if the mode is undefined, so we first check for this.
+        % If the mode is undefined, it doesn't really matter which
+        % partitions we place the arguements/lambda vars into because
+        % mode analysis will fail anyway.
+        %
+        ( mode_is_undefined(ModuleInfo, Mode) ->
             InputArgs        = [ Arg | InputArgs0],
             OutputArgs       = OutputArgs0,
             InputLambdaVars  = [ LambdaVar | InputLambdaVars0 ],
             OutputLambdaVars = OutputLambdaVars0
+        ;
+            ( mode_is_output(ModuleInfo, Mode) ->
+                InputArgs        = InputArgs0,
+                OutputArgs       = [Arg | OutputArgs0],
+                InputLambdaVars  = InputLambdaVars0,
+                OutputLambdaVars = [ LambdaVar | OutputLambdaVars0 ]
+            ;
+                InputArgs        = [ Arg | InputArgs0],
+                OutputArgs       = OutputArgs0,
+                InputLambdaVars  = [ LambdaVar | InputLambdaVars0 ],
+                OutputLambdaVars = OutputLambdaVars0
+            )
         ).

 :- pred check_expr_purity(purity::in, prog_context::in,
only in patch2:
unchanged:
--- compiler/mode_util.m	31 May 2005 06:55:30 -0000	1.166
+++ compiler/mode_util.m	10 Aug 2005 14:47:08 -0000
@@ -51,6 +51,10 @@
 	% a mode is considered unused if both initial and final insts are free
 :- pred mode_is_unused(module_info::in, (mode)::in) is semidet.

+	% Succeeds iff the given mode is undefined.
+	%
+:- pred mode_is_undefined(module_info::in, (mode)::in) is semidet.
+
 	% mode_to_arg_mode converts a mode (and corresponding type) to
 	% an arg_mode.  A mode is a high-level notion, the normal
 	% Mercury language mode.  An `arg_mode' is a low-level notion
@@ -226,6 +230,9 @@
 	inst_is_free(ModuleInfo, InitialInst),
 	inst_is_free(ModuleInfo, FinalInst).

+mode_is_undefined(ModuleInfo, Mode) :-
+	not mode_get_insts_semidet(ModuleInfo, Mode, _, _).
+
 %-----------------------------------------------------------------------------%

 modes_to_arg_modes(ModuleInfo, Modes, Types, ArgModes) :-
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list