[m-dev.] for review: retry across I/O
Fergus Henderson
fjh at cs.mu.OZ.AU
Tue Nov 7 17:35:20 AEDT 2000
On 06-Nov-2000, Zoltan Somogyi <zs at cs.mu.OZ.AU> wrote:
> Add tabling of I/O actions for the debugger.
>
> compiler/options.m:
> Add a new option, --trace-table-io, that enables the tabling of I/O
> actions, and another, --trace-table-io-states, that governs whether the
> tabling includes the I/O state variables themselves. (You want to table
> these variables iff they contain meaningful information that is not
> stored in global variables.) These options are for developers only
> for now.
...
> compiler/table_gen.m:
> If a procedure has a pair of I/O state args and is defined using pragma
> C code that has the tabled_for_io marker, then perform I/O tabling on
> it and mark it as tabled.
Shouldn't that be done only if the --trace-table-io option is specified?
(I haven't looked at the code yet. Maybe it's just the log message that
is incomplete.)
> library/io.m:
> Mark the relevant procedures with the tabled_for_io feature.
>
> Standardize the formatting of predicates defined by pragma C codes.
>
> library/table_builtin.m:
> Define the predicates that perform I/O tabling, to which calls are
> inserted in I/O tabled predicates. These depend on knowing what the
> maximum MR_Unsigned value is.
>
> configure.in:
> runtime/mercury_conf.h.in:
> Detect the proper value of two new macros, MR_{INTEGER,UNSIGNED}_MAX.
The maximum MR_Unsigned value is `((MR_Unsigned) -1)' or `(~ (MR_Unsigned) 0)'.
For any unsigned type T, the C standard guarantees that `((T) -1)'
and `(~ (T) 0)' both evaluate to the maximum value of that type.
So you don't need to autoconf that.
It's not worth autoconfing MR_INTEGER_MAX if we don't use it.
> +++ compiler/hlds_out.m 2000/11/06 01:49:32
> @@ -2917,6 +2922,10 @@
> io__write_string("% address is not taken\n")
> ),
>
> + io__write_string("% eval method: "),
> + hlds_out__write_eval_method(EvalMethod),
> + io__write_string("\n"),
I think it would be better to write out the eval method iff the eval
method is not `normal'. This would reduce the verbosity of the HLDS
dump in the usual case, and is similar to what we currently do for the
head_type_params, type class constraint proofs, and Aditi indexes.
> +++ compiler/hlds_pred.m 2000/11/06 01:49:32
> @@ -1505,6 +1505,18 @@
> + % If the procedure has a pair of io:state arguments, return the index
> + % of those arguments.
...
> +:- pred proc_info_has_io_state_args(module_info::in, proc_info::in,
> + int::out, int::out) is semidet.
What do you mean by "the index"? Does the first argument have index
zero or one? If there are inserted type_info and typeclass_info args,
do they get counted? The documentation should explain this in more detail.
I suggest s/io:state/io__state/g
> + % The first output argument gives the index of the
> + % input state, the second the output state.
> + % Note that the automatically constructed unify, index and compare
> + % procedures for the io:state type are not counted as having io:state
> + % args, since they do not fall into the scheme of one input and one
> + % output arg. Since they should never be called, this should not
> + % matter.
If the idea is that this pred is supposed to only succeed if there is
an input mode io__state argument and an output mode io__state argument,
then you should say so in the first sentence:
% If the procedure has a pair of io:state arguments, one with
% an input mode and one with an output mode, return the index of
% those arguments.
> +proc_info_has_io_state_args(ModuleInfo, ProcInfo, InArgNum, OutArgNum) :-
> + proc_info_headvars(ProcInfo, HeadVars),
> + proc_info_argmodes(ProcInfo, ArgModes),
> + assoc_list__from_corresponding_lists(HeadVars, ArgModes,
> + HeadVarsModes),
> + proc_info_vartypes(ProcInfo, VarTypes),
> + proc_info_has_io_state_args_2(HeadVarsModes, ModuleInfo, VarTypes,
> + 1, no, no, MaybeIn, MaybeOut),
> + ( MaybeIn = yes(In), MaybeOut = yes(Out) ->
> + InArgNum = In,
> + OutArgNum = Out
> + ; MaybeIn = no, MaybeOut = no ->
> + fail
> + ;
> + % We must be processing the automatically generated index
> + % procedure for the io_state type. Since this predicate
> + % should never be called, any transformation meant for
> + % procedures with io:states would be inappropriate.
> + fail
> + ).
The comment there is wrong. It's quite possible to write procedures
that have only one `io__state' argument, and such procedures can
be called. There's even one in the Mercury compiler itself:
`typecheck_info_init' in typecheck.m.
It's also possible to write predicates that have two io__state
arguments but both have mode `out'. E.g.
main(IO0, _IO) -->
nasty_fail(IO0, IO0).
:- mode nasty_fail(in, in) is erroneous.
nasty_fail(_, _) :- throw("ouch").
> +:- pred proc_info_has_io_state_args_2(assoc_list(prog_var, mode)::in,
> + module_info::in, map(prog_var, type)::in,
> + int::in, maybe(int)::in, maybe(int)::in,
> + maybe(int)::out, maybe(int)::out) is det.
> +
> +proc_info_has_io_state_args_2([], _, _, _,
> + MaybeIn, MaybeOut, MaybeIn, MaybeOut).
> +proc_info_has_io_state_args_2([Var - Mode | VarModes], ModuleInfo, VarTypes,
> + ArgNum, MaybeIn0, MaybeOut0, MaybeIn, MaybeOut) :-
> + (
> + map__lookup(VarTypes, Var, VarType),
> + type_to_type_id(VarType, TypeCtor, []),
> + type_util__type_id_module(ModuleInfo, TypeCtor,
> + unqualified("io")),
> + type_util__type_id_name(ModuleInfo, TypeCtor, "state"),
> + type_util__type_id_arity(ModuleInfo, TypeCtor, 0)
You should use `type_util__type_is_io_state' instead of the five lines
above.
> + ->
> + ( mode_is_fully_input(ModuleInfo, Mode) ->
> + ( MaybeIn0 = no ->
> + MaybeIn1 = yes(ArgNum),
> + MaybeOut1 = MaybeOut0
> + ;
> + % We must be processing the automatically
> + % generated unification or comparison procedure
> + % for the io_state type. Since these predicates
> + % should never be called, any transformation
> + % meant for procedures with io:states would
> + % be inappropriate. We therefore effectively
> + % forget both io:state arguments.
The comment there is wrong too, see above.
> + MaybeIn1 = no,
> + MaybeOut1 = MaybeOut0
> + )
> + ; mode_is_fully_output(ModuleInfo, Mode) ->
> + require(unify(MaybeOut0, no),
> + "proc_info_has_io_state_args_2: two io:state outputs"),
That will call error/1 for the test case I gave above.
> + MaybeOut1 = yes(ArgNum),
> + MaybeIn1 = MaybeIn0
> + ;
> + error("proc_info_has_io_state_args_2: bad io:state mode")
It should not be an error to write code which declares an io__state argument
to have mode `any'. For example, the following should be legal:
main(IO0, _IO) -->
another_nasty_fail(IO0, IO0).
:- mode another_nasty_fail(in(any), in(any)) is erroneous.
another_nasty_fail(_, _) :- throw("ouch").
[... to be continued]
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list