[m-rev.] diff: update compiler mutable documentation

Julien Fischer juliensf at csse.unimelb.edu.au
Tue Aug 15 17:22:04 AEST 2006


Estimated hours taken: 1
Branches: main

Add new documentation for the implementation of mutables.

compiler/prog_mutable.m:
 	Provide an up-to-date description of the source-to-source
 	transformation used to implement mutables.

compiler/prog_io.m:
 	Delete the old description of the transformation.  (This hadn't
 	been maintained and was quite out-of-date.)

 	Minor documentation update caused by the removal of the mutable
 	`thread_safe' attribute.

compiler/make_hlds_passes.m:
 	Add a pointer to the new documentation in prog_mutable.m.

Julien.

Index: compiler/make_hlds_passes.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/make_hlds_passes.m,v
retrieving revision 1.47
diff -u -r1.47 make_hlds_passes.m
--- compiler/make_hlds_passes.m	14 Aug 2006 09:09:18 -0000	1.47
+++ compiler/make_hlds_passes.m	15 Aug 2006 06:45:38 -0000
@@ -1189,6 +1189,10 @@
      ).
  add_item_clause(Item, !Status, Context, !ModuleInfo, !QualInfo, !IO) :-
      Item = mutable(Name, Type, InitTerm, Inst, MutAttrs, MutVarset),
+    %
+    % The transformation here is documented in the comments at the
+    % beginning of prog_mutable.m.
+    %
      ( status_defined_in_this_module(!.Status, yes) ->
          module_info_get_name(!.ModuleInfo, ModuleName),
          varset.new_named_var(varset.init, "X", X, ProgVarSet0),
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.267
diff -u -r1.267 prog_io.m
--- compiler/prog_io.m	14 Aug 2006 09:09:19 -0000	1.267
+++ compiler/prog_io.m	15 Aug 2006 07:14:37 -0000
@@ -1777,52 +1777,11 @@
      ).

  %-----------------------------------------------------------------------------%
-
-% Mutable declaration syntax:
-%
-% :- mutable(name, type, value, inst, <attribute_list>).
-% (The list of attributes at the end is optional.)
-%
-% e.g.:
-%
-% :- mutable(counter, int, 0, ground, [thread_safe]).
-%
-% This is converted into the following:
  %
-% :- semipure pred get_counter(int::out(ground)) is det.
-% :- pragma foreign_proc("C",
-%   get_counter(X::out(ground)),
-%   [promise_semipure, will_not_call_mercury, thread_safe],
-%   "X = mutable_counter;").
+% Mutable declarations
  %
-% :- impure pred set_counter(int::in(ground)) is det.
-% :- pragma foreign_proc("C",
-%   set_counter(X::in(ground)),
-%   [will_not_call_mercury, thread_safe],
-%   "MR_trail_current_value(&mutable_counter);
-%    mutable_counter = X;").
+% See prog_mutable.m for implementation details.
  %
-% :- pragma foreign_decl("C", "extern MR_Word mutable_counter;").
-% :- pragma foreign_code("C", "MR_Word mutable_counter;");
-%
-% :- import_module io.
-% :- initialise initialise_counter.
-% :- impure pred initialise_mutable_counter(io::di, io::uo) is det.
-%
-% initialise_mutable_counter(!IO) :-
-%   impure set_counter(0).
-%
-% If the `thread_safe' attribute is specified in <attribute_list>
-% then foreign_procs are created that have the thread_safe attribute
-% set.  If the `untrailed' attribute is specified in <attribute_list>
-% then the code for trailing the mutable variable in the set predicate
-% is omitted
-
-% NOTE: we must attach the varset to the mutable item because if the
-% initial value is non-ground, then the initial value will be a variable
-% and the mutable initialisation predicate will contain references to it.
-% Ignoring the varset may lead to later compiler passes attempting to reuse
-% this variable when fresh variables are allocated.

  :- pred parse_mutable_decl(module_name::in, varset::in, list(term)::in,
      maybe1(item)::out) is semidet.
@@ -1834,6 +1793,9 @@
      term.coerce(ValueTerm, Value),
      varset.coerce(Varset, ProgVarset),
      parse_mutable_inst(InstTerm, InstResult),
+    %
+    % The list of attributes is optional.
+    %
      (
          OptMutAttrsTerm = [],
          MutAttrsResult = ok1(default_mutable_attributes)
@@ -1847,6 +1809,12 @@
          InstResult = ok1(Inst),
          MutAttrsResult = ok1(MutAttrs)
      ->
+        % We *must* attach the varset to the mutable item because if the
+        % initial value is non-ground, then the initial value will be a
+        % variable and the mutable initialisation predicate will contain
+        % references to it.  Ignoring the varset may lead to later compiler
+        % passes attempting to reuse this variable when fresh variables are
+        % allocated.
          Result = ok1(mutable(Name, Type, Value, Inst, MutAttrs, ProgVarset))
      ;
          Errors = get_any_errors1(NameResult) ++ get_any_errors1(TypeResult) ++
@@ -1906,9 +1874,9 @@
          map_parser(parse_mutable_attr, MutAttrTerms, MaybeAttrList),
          MaybeAttrList = ok1(CollectedMutAttrs)
      ->
-        % We check for trailed/untrailed and thread_safe/not_thread_safe
-        % conflicts here and deal with conflicting foreign_name attributes in
-        % make_hlds_passes.m.
+        % We check for trailed/untrailed, constant/trailed and
+        % constant/attach_to_io_state conflicts here and deal with
+        % conflicting foreign_name attributes in make_hlds_passes.m.
          %
          (
              list.member(Conflict1 - Conflict2, ConflictingAttributes),
Index: compiler/prog_mutable.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/prog_mutable.m,v
retrieving revision 1.13
diff -u -r1.13 prog_mutable.m
--- compiler/prog_mutable.m	14 Aug 2006 09:09:19 -0000	1.13
+++ compiler/prog_mutable.m	15 Aug 2006 07:09:51 -0000
@@ -8,9 +8,117 @@
  %
  % File: prog_mutable.m.
  % Main authors: rafe, juliensf.
+%
+% This module defines utility predicates for dealing with mutable
+% declarations.  It also contains a description of the source-to-source
+% transformation used for implementing mutables.
+%
+%-----------------------------------------------------------------------------%
+%
+% Mutables are implemented as a source-to-source transformation on the
+% parse tree.  The basic transformation is as follows:
+%
+%   :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [attributes]).
+% 
+% ===>
+% 
+%   :- pragma foreign_decl("C", "extern <CType> mutable_<varname>;").
+%   :- pragma foreign_code("C", "<CType> mutable_<varname>;");
+%
+% NOTES: 
+%
+%        * The name of the C global corresponding to mutable_<varname> may be
+%          mangled.
+%
+%        * <CType> is chosen on a backend-specific basis.  If the value stored
+%          in the mutable is always boxed it is `MR_Word' otherwise it may
+%          be some native type, `MR_Integer', `MR_Float' etc.
+%
+%   :- initialise initialise_mutable_<varname>/0.
+%
+%   :- impure pred initialise_mutable_<varname> is det.
+% 
+%   initialise_mutable_<varname> :-
+%       impure set_<varname>(<initval>).
+% 
+%   :- semipure pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%   :- pragma foreign_proc("C",
+%       get_<varname>(X::out(<varinst>)),
+%       [promise_semipure, will_not_call_mercury],
+%   "
+%       X = mutable_<varname>;
+%   ");
+% 
+%   :- impure pred set_<varname>(<vartype>::in(<varinst>)) is det.
+%   :- pragma foreign_proc("C",
+%       set_<varname>(X::in(<varinst>)),
+%       [will_not_call_mercury],
+%   "
+%       MR_trail_current_value(&mutable_<varname>);
+%       mutable_<varname> = X; 
+%   ").
+%
+% NOTE: mutables *are* trailed by default.  The `untrailed' attribute just
+%       causes the call to MR_trail_current_value to be omitted.
+%
+% If the `attach_to_io_state' attribute is specified we also generate:
+%
+%   :- pred get_varname(<vartype>::out(<varinst>), io::di, io::uo) is det.
+%   :- pred set_varname(<vartype>::in(<varinst>),  io::di, io::uo) is det.
+%
+%   :- pragma foreign_proc("C",
+%       get_varname(X::out(<varinst), IO0::di, IO::uo),
+%       [promise_pure, will_not_call_mercury, tabled_for_io],
+%   "
+%       X = mutable_<varname>;
+%       IO = IO0;
+%   ").
+% 
+%   :- pragma foreign_proc("C",
+%       set_varname(X::in(<varinst>), IO0::di, IO::uo),
+%       [promise_pure, will_not_call_mercury, tabled_for_io],
+%   "
+%       mutable_<varname> = X;
+%       IO = IO0;
+%   ").
+% 
+% NOTE: we could implement the above in terms of the impure get and set
+%       predicates.  The reason we don't is so that we can use I/O 
+%       tabling.
+%       XXX If tabling of impure actions is ever implemented we should\
+%           revisit this.
+% 
+% For constant mutables (those with the `constant' attribute), the 
+% transformation is a little different:
+%
+%   :- mutable(<varname>, <vartype>, <initvalue>, <varinst>, [constant]).
+%
+% ===>
+%
+%   (The declarations for the global are as above.)
+%
+%   :- pred get_<varname>(<vartype>::out(<varinst>)) is det.
+%   :- pragma foreign_proc("C",
+%       get_<varname>(X::out(<varinst>)),
+%       [will_not_call_mercury, promise_pure, thread_safe],
+%   "
+%       X = mutable_<varname>;
+%   ").
  % 
-% Utility predicates for dealing with mutable declarations.
+% In order to initialise constant mutables we generate the following:
+%
+%   :- impure pred secret_initialization_only_set_<varname>(
+%       <vartype>::in(<varinst>)) is det.
  % 
+%   :- pragma foreign_proc("C",
+%       secret_initialization_only_set_<varname>(X::in(<varinst>)),
+%       [will_not_call_mercury],
+%   "
+%       mutable_<varname> = X;
+%   ").
+%
+%   :- initialise secret_initialization_only_set_<varname>/0.
+%
  %-----------------------------------------------------------------------------%

  :- module parse_tree.prog_mutable.
@@ -68,7 +176,7 @@
      % the init predicate needs to do two things: execute arbitrary Mercury code
      % (call functions etc) to generate the initial (and for constant mutables,
      % also final) value of the mutable, and then store this value in persistent
-    % storage. However, even we could create an item that contains both
+    % storage. However, even if we could create an item that contains both
      % Mercury code and backend (e.g. C) code (which is currently not possible),
      % this would require the second part to be a foreign_proc goal. Such goals
      % include a reference to the predicate they implement. That predicate

--------------------------------------------------------------------------
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