Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.75
diff -u -r1.75 ml_call_gen.m
--- compiler/ml_call_gen.m	1 Dec 2006 15:04:07 -0000	1.75
+++ compiler/ml_call_gen.m	21 Dec 2006 12:54:33 -0000
@@ -107,7 +107,7 @@
     % Generate the appropriate MLDS type for a continuation function
     % for a nondet procedure whose output arguments have the specified types.
     %
-    % WARNING: this does not fill in the maybe_gc_trace_code for the function
+    % WARNING: this does not fill in the gc_statement for the function
     % parameters. It is the caller's responsibility to fill these in properly
     % if needed.
     %
@@ -184,16 +184,16 @@
 
     % Insert the `closure_arg' parameter.
     %
-    % The GC_TraceCode for `closure_arg' here is wrong, but it doesn't matter,
+    % The GCStatement for `closure_arg' here is wrong, but it doesn't matter,
     % since `closure_arg' is only part of a type (a function parameter in the
     % function type). We won't use the GC tracing code generated here, since
     % we don't generate any actual local variable or parameter for
     % `closure_arg'.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     ClosureArgType = mlds_generic_type,
     ClosureArg =
         mlds_argument(entity_data(var(mlds_var_name("closure_arg", no))),
-            ClosureArgType, GC_TraceCode),
+            ClosureArgType, GCStatement),
     Params0 = mlds_func_params(ArgParams0, RetParam),
     Params = mlds_func_params([ClosureArg | ArgParams0], RetParam),
     Signature = mlds_get_func_signature(Params),
@@ -249,9 +249,9 @@
     FuncVarName = mlds_var_name(string.format("func_%d", [i(ConvVarNum)]), no),
     % The function address is always a pointer to code,
     % not to the heap, so the GC doesn't need to trace it.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     FuncVarDecl = ml_gen_mlds_var_decl(var(FuncVarName),
-        FuncType, GC_TraceCode, mlds_make_context(Context)),
+        FuncType, GCStatement, mlds_make_context(Context)),
     ml_gen_var_lval(!.Info, FuncVarName, FuncType, FuncVarLval),
     AssignFuncVar = ml_gen_assign(FuncVarLval, FuncRval, Context),
     FuncVarRval = lval(FuncVarLval),
@@ -513,7 +513,7 @@
         % Create a new continuation function that just copies the outputs
         % to locals and then calls the original current continuation.
         %
-        % Note that ml_gen_cont_params does not fill in the maybe_gc_trace_code
+        % Note that ml_gen_cont_params does not fill in the gc_statement
         % for the parameters. This is OK, because the parameters of the
         % continuation function will not be live across any heap allocations or
         % procedure calls.
@@ -561,9 +561,9 @@
     % requires knowing the HLDS types, but here we only have the MLDS types.
     % So here we just leave it blank. The caller of ml_gen_cont_param has the
     % reponsibility of fillling this in properly if needed.
-    Maybe_GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     Argument =
-        mlds_argument(entity_data(var(ArgName)), Type, Maybe_GC_TraceCode),
+        mlds_argument(entity_data(var(ArgName)), Type, GCStatement),
     ml_gen_cont_params_2(Types, ArgNum + 1, Arguments).
 
 :- pred ml_gen_copy_args_to_locals(ml_gen_info::in, list(mlds_lval)::in,
@@ -823,7 +823,7 @@
         % type variable from the callee, not from the caller,
         % and we can't generate type_infos for type variables
         % from the callee.  Hence we need to call the version of
-        % ml_gen_maybe_gc_trace_code which takes two types:
+        % ml_gen_gc_statement which takes two types:
         % the CalleeType is used to determine the type for the
         % temporary variable declaration, but the CallerType is
         % used to construct the type_info.
@@ -847,10 +847,10 @@
             )
         ;
             ForClosureWrapper = no,
-            ml_gen_maybe_gc_trace_code(ArgVarName, CalleeType, CallerType,
-                Context, GC_TraceCode, !Info),
+            ml_gen_gc_statement(ArgVarName, CalleeType, CallerType,
+                Context, GC_Statements, !Info),
             ArgVarDecl = ml_gen_mlds_var_decl(var(ArgVarName), MLDS_CalleeType,
-                GC_TraceCode, mlds_make_context(Context))
+                GC_Statements, mlds_make_context(Context))
         ),
         ConvDecls = [ArgVarDecl],
 
Index: compiler/ml_closure_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_closure_gen.m,v
retrieving revision 1.47
diff -u -r1.47 ml_closure_gen.m
--- compiler/ml_closure_gen.m	4 Oct 2006 07:14:47 -0000	1.47
+++ compiler/ml_closure_gen.m	21 Dec 2006 12:54:33 -0000
@@ -713,7 +713,7 @@
     % function to when it calls the wrapped function, and garbage collection
     % can't occur in that time, since there are no allocations (only an
     % assignment to `closure_arg' and some unbox operations).
-    WrapperArgs1 = list.map(arg_delete_gc_trace_code, WrapperArgs0),
+    WrapperArgs1 = list.map(arg_delete_gc_statement, WrapperArgs0),
 
     % then insert the `closure_arg' parameter, if needed.
     ( ClosureKind = special_pred ->
@@ -723,11 +723,11 @@
         ClosureArgType = mlds_generic_type,
         ClosureArgName = mlds_var_name("closure_arg", no),
         ClosureArgDeclType = list.det_head(ml_make_boxed_types(1)),
-        gen_closure_gc_trace_code(ClosureArgName, ClosureArgDeclType,
+        gen_closure_gc_statement(ClosureArgName, ClosureArgDeclType,
             ClosureKind, WrapperArgTypes, Purity, PredOrFunc,
-            Context, ClosureArgGCTraceCode, !Info),
+            Context, ClosureArgGCStatement, !Info),
         ClosureArg = mlds_argument(entity_data(var(ClosureArgName)),
-            ClosureArgType, ClosureArgGCTraceCode),
+            ClosureArgType, ClosureArgGCStatement),
         MaybeClosureA = yes({ClosureArgType, ClosureArgName}),
         WrapperArgs = [ClosureArg | WrapperArgs1]
     ),
@@ -759,16 +759,16 @@
         % If we were to generate GC tracing code for the closure
         % pointer, it would look like this:
         %   ClosureDeclType = list.det_head(ml_make_boxed_types(1)),
-        %   gen_closure_gc_trace_code(ClosureName, ClosureDeclType,
+        %   gen_closure_gc_statement(ClosureName, ClosureDeclType,
         %       ClosureKind, WrapperArgTypes, Purity,
-        %       PredOrFunc, Context, ClosureGCTraceCode),
+        %       PredOrFunc, Context, ClosureGCStatement),
         % But we don't need any GC tracing code for the closure pointer,
         % because it won't be live across an allocation, and because
         % (unlike the closure_arg parameter) it isn't referenced from
         % the GC tracing for other variables.
-        ClosureGCTraceCode = no,
+        ClosureGCStatement = gc_no_stmt,
         ClosureDecl = ml_gen_mlds_var_decl(var(ClosureName),
-            ClosureType, ClosureGCTraceCode, MLDS_Context),
+            ClosureType, ClosureGCStatement, MLDS_Context),
         ml_gen_var_lval(!.Info, ClosureName, ClosureType, ClosureLval),
         ml_gen_var_lval(!.Info, ClosureArgName1, ClosureArgType1,
             ClosureArgLval),
@@ -903,23 +903,23 @@
     WrapperFuncType = mlds_func_type(WrapperParams),
     ml_gen_info_add_extra_defn(WrapperFunc, !Info).
 
-:- func arg_delete_gc_trace_code(mlds_argument) = mlds_argument.
+:- func arg_delete_gc_statement(mlds_argument) = mlds_argument.
 
-arg_delete_gc_trace_code(Argument0) = Argument :-
-    Argument0 = mlds_argument(Name, Type, _GCTraceCode),
-    Argument = mlds_argument(Name, Type, no).
+arg_delete_gc_statement(Argument0) = Argument :-
+    Argument0 = mlds_argument(Name, Type, _GCStatement),
+    Argument = mlds_argument(Name, Type, gc_no_stmt).
 
-    % Generate the GC tracing code for `closure_arg' or `closure'
+    % Generate the GC trace code for `closure_arg' or `closure'
     % (see ml_gen_closure_wrapper above).
     %
-:- pred gen_closure_gc_trace_code(mlds_var_name::in, mer_type::in,
+:- pred gen_closure_gc_statement(mlds_var_name::in, mer_type::in,
     closure_kind::in, list(mer_type)::in, purity::in, pred_or_func::in,
-    prog_context::in, mlds_maybe_gc_trace_code::out,
+    prog_context::in, mlds_gc_statement::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-gen_closure_gc_trace_code(ClosureName, ClosureDeclType,
+gen_closure_gc_statement(ClosureName, ClosureDeclType,
         ClosureKind, WrapperArgTypes, Purity, PredOrFunc,
-        Context, ClosureGCTraceCode, !Info) :-
+        Context, ClosureGCStatement, !Info) :-
     % We can't use WrapperArgTypes here, because we don't have type_infos
     % for the type variables in WrapperArgTypes; those type variables come from
     % the callee. But when copying closures, we don't care what the types of
@@ -936,10 +936,10 @@
         ClosureActualType = sample_typeclass_info_type
     ;
         ClosureKind = special_pred,
-        unexpected(this_file, "gen_closure_gc_trace_code: special_pred")
+        unexpected(this_file, "gen_closure_gc_statement: special_pred")
     ),
-    ml_gen_maybe_gc_trace_code(ClosureName, ClosureDeclType,
-        ClosureActualType, Context, ClosureGCTraceCode, !Info).
+    ml_gen_gc_statement(ClosureName, ClosureDeclType,
+        ClosureActualType, Context, ClosureGCStatement, !Info).
 
 :- pred ml_gen_wrapper_func(ml_label_func::in, mlds_func_params::in,
     prog_context::in, statement::in, mlds_defn::out,
@@ -1073,8 +1073,12 @@
     % This type is really `const MR_Closure_Layout *', but there's no easy
     % way to represent that in the MLDS; using MR_Box instead works fine.
     ClosureLayoutPtrType = mlds_generic_type,
+    % We use 'gc_initialiser' for the garbage collection code as it is code to
+    % initialise local variables used during garbage collection and must
+    % run before variables are traced.
     ClosureLayoutPtrDecl = ml_gen_mlds_var_decl(var(ClosureLayoutPtrName),
-        ClosureLayoutPtrType, yes(ClosureLayoutPtrGCInit), MLDS_Context),
+        ClosureLayoutPtrType, gc_initialiser(ClosureLayoutPtrGCInit),
+        MLDS_Context),
     ml_gen_var_lval(!.Info, ClosureLayoutPtrName, ClosureLayoutPtrType,
         ClosureLayoutPtrLval),
 
@@ -1082,8 +1086,11 @@
     % This type is really MR_TypeInfoParams, but there's no easy way to
     % represent that in the MLDS; using MR_Box instead works fine.
     TypeParamsType = mlds_generic_type,
+    % We use 'gc_initialiser' for the garbage collection code as it is code to
+    % initialise local variables used during garbage collection and must
+    % run before variables are traced.
     TypeParamsDecl = ml_gen_mlds_var_decl(var(TypeParamsName),
-        TypeParamsType, yes(TypeParamsGCInit), MLDS_Context),
+        TypeParamsType, gc_initialiser(TypeParamsGCInit), MLDS_Context),
     ml_gen_var_lval(!.Info, TypeParamsName, TypeParamsType, TypeParamsLval),
     (
         ClosureKind = higher_order_proc_closure,
@@ -1176,13 +1183,17 @@
     TypeInfoType = mercury_type_to_mlds_type(ModuleInfo, TypeInfoMercuryType),
     ml_gen_var_lval(!.Info, TypeInfoName, TypeInfoType, TypeInfoLval),
     TypeInfoDecl = ml_gen_mlds_var_decl(var(TypeInfoName), TypeInfoType,
-        no_initializer, no, MLDS_Context),
+        no_initializer, gc_no_stmt, MLDS_Context),
 
-    ml_gen_maybe_gc_trace_code_with_typeinfo(VarName, Type,
-        lval(TypeInfoLval), Context, MaybeGCTraceCode0, !Info),
+    ml_gen_gc_statement_with_typeinfo(VarName, Type,
+        lval(TypeInfoLval), Context, GCStatement0, !Info),
 
     (
-        MaybeGCTraceCode0 = yes(CallTraceFuncCode),
+        (
+            GCStatement0 = gc_trace_code(CallTraceFuncCode)
+        ;
+            GCStatement0 = gc_initialiser(CallTraceFuncCode)
+        ),
         MakeTypeInfoCode = atomic(inline_target_code(ml_target_c, [
             raw_target_code("{\n", []),
             raw_target_code("MR_MemoryList allocated_mem = NULL;\n", []),
@@ -1206,14 +1217,14 @@
             CallTraceFuncCode,
             statement(DeallocateCode, MLDS_Context)
         ]),
-        MaybeGCTraceCode = yes(statement(GCTraceCode, MLDS_Context))
+        GCStatement = gc_trace_code(statement(GCTraceCode, MLDS_Context))
     ;
-        MaybeGCTraceCode0 = no,
-        MaybeGCTraceCode = MaybeGCTraceCode0
+        GCStatement0 = gc_no_stmt,
+        GCStatement = GCStatement0
     ),
     LocalVarDefn = ml_gen_mlds_var_decl(var(VarName),
         mercury_type_to_mlds_type(ModuleInfo, Type),
-        MaybeGCTraceCode, MLDS_Context).
+        GCStatement, MLDS_Context).
 
 :- pred ml_gen_closure_field_lvals(mlds_lval::in, int::in, int::in, int::in,
     list(mlds_lval)::out, ml_gen_info::in, ml_gen_info::out) is det.
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.191
diff -u -r1.191 ml_code_gen.m
--- compiler/ml_code_gen.m	1 Dec 2006 15:04:07 -0000	1.191
+++ compiler/ml_code_gen.m	21 Dec 2006 12:54:38 -0000
@@ -1292,10 +1292,10 @@
 
 tabling_name_and_init_to_defn(ProcLabel, MLDS_Context, Constness, Id,
         Initializer) = Defn :-
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     MLDS_Type = mlds_tabling_type(Id),
     Flags = tabling_data_decl_flags(Constness),
-    DefnBody = mlds_data(MLDS_Type, Initializer, GC_TraceCode),
+    DefnBody = mlds_data(MLDS_Type, Initializer, GCStatement),
     Name = entity_data(mlds_tabling_ref(ProcLabel, Id)),
     Defn = mlds_defn(Name, MLDS_Context, Flags, DefnBody).
 
@@ -2143,10 +2143,10 @@
     LocalVarName = mlds_var_name(
         string.append("local_", OutputVarNameStr), MaybeNum),
     ml_gen_type(!.Info, Type, MLDS_Type),
-    ml_gen_maybe_gc_trace_code(LocalVarName, Type, Context, GC_TraceCode,
+    ml_gen_gc_statement(LocalVarName, Type, Context, GCStatement,
         !Info),
     LocalVarDefn = ml_gen_mlds_var_decl(var(LocalVarName), MLDS_Type,
-        GC_TraceCode, mlds_make_context(Context)),
+        GCStatement, mlds_make_context(Context)),
 
     % Generate code to assign from the local var to the output var.
     ml_gen_var(!.Info, OutputVar, OutputVarLval),
@@ -2164,7 +2164,7 @@
 :- func ml_gen_commit_var_decl(mlds_context, mlds_var_name) = mlds_defn.
 
 ml_gen_commit_var_decl(Context, VarName) =
-    ml_gen_mlds_var_decl(var(VarName), mlds_commit_type, no, Context).
+    ml_gen_mlds_var_decl(var(VarName), mlds_commit_type, gc_no_stmt, Context).
 
     % Generate MLDS code for the different kinds of HLDS goals.
     %
@@ -2656,7 +2656,7 @@
         SuccessIndicatorDecl = ml_gen_mlds_var_decl(
             var(SuccessIndicatorVarName),
             mlds_native_bool_type,
-            no_initializer, no, MLDSContext),
+            no_initializer, gc_no_stmt, MLDSContext),
         SuccessIndicatorLval = var(qual(MLDSModuleName, module_qual,
             SuccessIndicatorVarName), mlds_native_bool_type),
         SuccessIndicatorStatement = ml_gen_assign(SucceededLval,
@@ -2871,9 +2871,9 @@
     % XXX Accurate GC is not supported for IL foreign code;
     % this would only be useful if interfacing to
     % IL when compiling to C, which is not yet supported.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     Defn = ml_gen_mlds_var_decl(var(NonMangledVarName), MLDSType,
-        Initializer, GC_TraceCode, MLDSContext).
+        Initializer, GCStatement, MLDSContext).
 
     % For ordinary (not model_non) pragma c_proc,
     % we generate code of the following form:
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.119
diff -u -r1.119 ml_code_util.m
--- compiler/ml_code_util.m	1 Dec 2006 15:04:07 -0000	1.119
+++ compiler/ml_code_util.m	21 Dec 2006 12:54:41 -0000
@@ -272,14 +272,14 @@
     % and the code to trace it for accurate GC (if needed).
     %
 :- func ml_gen_mlds_var_decl(mlds_data_name, mlds_type,
-    maybe(statement), mlds_context) = mlds_defn.
+    mlds_gc_statement, mlds_context) = mlds_defn.
 
     % Generate a declaration for an MLDS variable, given its MLDS type
     % and initializer, and given the code to trace it for accurate GC
     % (if needed).
     %
 :- func ml_gen_mlds_var_decl(mlds_data_name, mlds_type, mlds_initializer,
-    maybe(statement), mlds_context) = mlds_defn.
+    mlds_gc_statement, mlds_context) = mlds_defn.
 
     % Generate declaration flags for a local variable.
     %
@@ -456,17 +456,17 @@
 % Code to handle accurate GC
 %
 
-    % ml_gen_maybe_gc_trace_code(Var, Type, Context, Code):
+    % ml_gen_gc_statement(Var, Type, Context, Code):
     %
     % If accurate GC is enabled, and the specified variable might contain
     % pointers, generate code to call `private_builtin.gc_trace' to trace
     % the variable.
     %
-:- pred ml_gen_maybe_gc_trace_code(mlds_var_name::in, mer_type::in,
-    prog_context::in, maybe(statement)::out,
+:- pred ml_gen_gc_statement(mlds_var_name::in, mer_type::in,
+    prog_context::in, mlds_gc_statement::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-    % ml_gen_maybe_gc_trace_code(Var, DeclType, ActualType, Context, Code):
+    % ml_gen_gc_statement(Var, DeclType, ActualType, Context, Code):
     %
     % This is the same as the //4 version (above), except that it takes two
     % type arguments, rather than one. The first (DeclType) is the type that
@@ -484,23 +484,23 @@
     % doesn't (e.g. because DeclType may be a boxed float). So we need to pass
     % both.
     %
-:- pred ml_gen_maybe_gc_trace_code(mlds_var_name::in,
-    mer_type::in, mer_type::in, prog_context::in, maybe(statement)::out,
-    ml_gen_info::in, ml_gen_info::out) is det.
+:- pred ml_gen_gc_statement(mlds_var_name::in,
+    mer_type::in, mer_type::in, prog_context::in,
+    mlds_gc_statement::out, ml_gen_info::in, ml_gen_info::out) is det.
 
-    % ml_gen_maybe_gc_trace_code_with_typeinfo(Var, DeclType, TypeInfoRval,
+    % ml_gen_gc_statement_with_typeinfo(Var, DeclType, TypeInfoRval,
     %   Context, Code):
     %
-    % This is the same as ml_gen_maybe_gc_trace_code//5, except that rather
+    % This is the same as ml_gen_gc_statement//5, except that rather
     % than passing ActualType, the caller constructs the type-info itself,
     % and just passes the rval for it to this routine.
     %
     % This is used by ml_closure_gen.m to generate GC tracing code
     % for the the local variables in closure wrapper functions.
     %
-:- pred ml_gen_maybe_gc_trace_code_with_typeinfo(mlds_var_name::in,
-    mer_type::in, mlds_rval::in, prog_context::in, maybe(statement)::out,
-    ml_gen_info::in, ml_gen_info::out) is det.
+:- pred ml_gen_gc_statement_with_typeinfo(mlds_var_name::in,
+    mer_type::in, mlds_rval::in, prog_context::in,
+    mlds_gc_statement::out, ml_gen_info::in, ml_gen_info::out) is det.
 
 %-----------------------------------------------------------------------------%
 %
@@ -1099,7 +1099,7 @@
             \+ is_dummy_argument_type(ModuleInfo, ResultType)
         ->
             pred_args_to_func_args(FuncArgs0, FuncArgs, RetArg),
-            RetArg = mlds_argument(_RetArgName, RetTypePtr, _GC_TraceCode),
+            RetArg = mlds_argument(_RetArgName, RetTypePtr, _GCStatement),
             ( RetTypePtr = mlds_ptr_type(RetType) ->
                 RetTypes = [RetType]
             ;
@@ -1131,8 +1131,8 @@
         ContName = entity_data(var(mlds_var_name("cont", no))),
         % The cont variable always points to code, not to the heap,
         % so the GC never needs to trace it.
-        ContGCTraceCode = no,
-        ContArg = mlds_argument(ContName, ContType, ContGCTraceCode),
+        ContGCStatement = gc_no_stmt,
+        ContArg = mlds_argument(ContName, ContType, ContGCStatement),
         ContEnvType = mlds_generic_env_ptr_type,
         ContEnvName = entity_data(var(mlds_var_name("cont_env_ptr", no))),
         % The cont_env_ptr always points to the stack, since continuation
@@ -1140,9 +1140,9 @@
         % put_nondet_env_on_heap is true, which won't be the case when doing
         % our own GC -- this is enforced in handle_options.m).
         % So the GC doesn't need to trace it.
-        ContEnvGCTraceCode = no,
+        ContEnvGCStatement = gc_no_stmt,
         ContEnvArg = mlds_argument(ContEnvName, ContEnvType,
-            ContEnvGCTraceCode),
+            ContEnvGCStatement),
         globals.lookup_bool_option(Globals, gcc_nested_functions,
             NestedFunctions),
         (
@@ -1226,15 +1226,15 @@
         !.MaybeInfo = yes(Info0),
         % XXX We should fill in this Context properly.
         term.context_init(Context),
-        ml_gen_maybe_gc_trace_code(Var, Type, Context, Maybe_GC_TraceCode,
+        ml_gen_gc_statement(Var, Type, Context, GCStatement,
             Info0, Info),
         !:MaybeInfo = yes(Info)
     ;
         !.MaybeInfo = no,
-        Maybe_GC_TraceCode = no,
+        GCStatement = gc_no_stmt,
         !:MaybeInfo = no
     ),
-    FuncArg = mlds_argument(Name, MLDS_ArgType, Maybe_GC_TraceCode).
+    FuncArg = mlds_argument(Name, MLDS_ArgType, GCStatement).
 
 ml_is_output_det_function(ModuleInfo, PredId, ProcId, RetArgVar) :-
     module_info_pred_proc_info(ModuleInfo, PredId, ProcId, PredInfo, ProcInfo),
@@ -1489,19 +1489,19 @@
 
 ml_gen_var_decl(VarName, Type, Context, Defn, !Info) :-
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
-    ml_gen_maybe_gc_trace_code(VarName, Type, Context, GC_TraceCode, !Info),
+    ml_gen_gc_statement(VarName, Type, Context, GCStatement, !Info),
     Defn = ml_gen_mlds_var_decl(var(VarName),
         mercury_type_to_mlds_type(ModuleInfo, Type),
-        GC_TraceCode, mlds_make_context(Context)).
+        GCStatement, mlds_make_context(Context)).
 
-ml_gen_mlds_var_decl(DataName, MLDS_Type, GC_TraceCode, Context) =
-    ml_gen_mlds_var_decl(DataName, MLDS_Type, no_initializer, GC_TraceCode,
+ml_gen_mlds_var_decl(DataName, MLDS_Type, GCStatement, Context) =
+    ml_gen_mlds_var_decl(DataName, MLDS_Type, no_initializer, GCStatement,
         Context).
 
-ml_gen_mlds_var_decl(DataName, MLDS_Type, Initializer, GC_TraceCode, Context) =
+ml_gen_mlds_var_decl(DataName, MLDS_Type, Initializer, GCStatement, Context) =
         MLDS_Defn :-
     Name = entity_data(DataName),
-    Defn = mlds_data(MLDS_Type, Initializer, GC_TraceCode),
+    Defn = mlds_data(MLDS_Type, Initializer, GCStatement),
     DeclFlags = ml_gen_local_var_decl_flags,
     MLDS_Defn = mlds_defn(Name, Context, DeclFlags, Defn).
 
@@ -1511,8 +1511,8 @@
     % The GC never needs to trace static constants,
     % because they can never point into the heap
     % (only to other static constants).
-    GC_TraceCode = no,
-    Defn = mlds_data(ConstType, Initializer, GC_TraceCode),
+    GCStatement = gc_no_stmt,
+    Defn = mlds_data(ConstType, Initializer, GCStatement),
     DeclFlags = mlds.set_access(ml_static_const_decl_flags, Access),
     MLDS_Context = mlds_make_context(Context),
     MLDS_Defn = mlds_defn(Name, MLDS_Context, DeclFlags, Defn).
@@ -1655,7 +1655,7 @@
 
 ml_gen_succeeded_var_decl(Context) =
     ml_gen_mlds_var_decl(var(mlds_var_name("succeeded", no)),
-        mlds_native_bool_type, no, Context).
+        mlds_native_bool_type, gc_no_stmt, Context).
 
 ml_success_lval(Info, SucceededLval) :-
     ml_gen_var_lval(Info, mlds_var_name("succeeded", no),
@@ -1680,7 +1680,7 @@
 
 ml_gen_cond_var_decl(CondVar, Context) =
     ml_gen_mlds_var_decl(var(ml_gen_cond_var_name(CondVar)),
-        mlds_native_bool_type, no, Context).
+        mlds_native_bool_type, gc_no_stmt, Context).
 
 ml_cond_var_lval(Info, CondVar, CondVarLval) :-
     ml_gen_var_lval(Info, ml_gen_cond_var_name(CondVar),
@@ -1790,7 +1790,7 @@
     % All we do is change the call rvals to be the input variables, and the
     % func rval to be the input variable for the continuation.
     %
-    % Note that ml_gen_cont_params does not fill in the gc_trace_code
+    % Note that ml_gen_cont_params does not fill in the gc_statement
     % for the parameters. This is OK, because the parameters will not be used
     % again after the call. (Also currently this is only used for IL, for which
     % GC is the .NET CLR implementation's problem, not ours.)
@@ -1811,9 +1811,9 @@
     PassedContVarName = mlds_var_name("passed_cont", no),
     % The passed_cont variable always points to code, not to heap,
     % so the GC never needs to trace it.
-    PassedContGCTraceCode = no,
+    PassedContGCStatement = gc_no_stmt,
     PassedContArg = mlds_argument(entity_data(var(PassedContVarName)),
-        InnerFuncArgType, PassedContGCTraceCode),
+        InnerFuncArgType, PassedContGCStatement),
     InnerFuncRval = lval(var(qual(MLDS_Module, module_qual,
         PassedContVarName), InnerFuncArgType)),
     InnerFuncParams = mlds_func_params([PassedContArg | InnerArgs0], Rets),
@@ -1859,7 +1859,7 @@
     ml_gen_var_lval(Info, mlds_var_name("env_ptr", no),
         mlds_unknown_type, EnvPtrLval).
 
-ml_declare_env_ptr_arg(mlds_argument(Name, Type, GC_TraceCode)) :-
+ml_declare_env_ptr_arg(mlds_argument(Name, Type, GCStatement)) :-
     Name = entity_data(var(mlds_var_name("env_ptr_arg", no))),
     Type = mlds_generic_env_ptr_type,
     % The env_ptr_arg always points to the stack, since continuation
@@ -1867,40 +1867,40 @@
     % put_nondet_env_on_heap is true, which won't be the case when
     % doing our own GC -- this is enforced in handle_options.m).
     % So the GC doesn't need to trace it.
-    GC_TraceCode = no.
+    GCStatement = gc_no_stmt.
 
 %-----------------------------------------------------------------------------%
 %
 % Code to handle accurate GC
 %
 
-ml_gen_maybe_gc_trace_code(VarName, Type, Context, Maybe_GC_TraceCode,
+ml_gen_gc_statement(VarName, Type, Context, GCStatement,
         !Info) :-
-    ml_gen_maybe_gc_trace_code(VarName, Type, Type, Context,
-        Maybe_GC_TraceCode, !Info).
+    ml_gen_gc_statement(VarName, Type, Type, Context,
+        GCStatement, !Info).
 
-ml_gen_maybe_gc_trace_code(VarName, DeclType, ActualType, Context,
-        Maybe_GC_TraceCode, !Info) :-
+ml_gen_gc_statement(VarName, DeclType, ActualType, Context,
+        GCStatement, !Info) :-
     HowToGetTypeInfo = construct_from_type(ActualType),
-    ml_gen_maybe_gc_trace_code_2(VarName, DeclType, HowToGetTypeInfo,
-        Context, Maybe_GC_TraceCode, !Info).
+    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo,
+        Context, GCStatement, !Info).
 
-ml_gen_maybe_gc_trace_code_with_typeinfo(VarName, DeclType, TypeInfoRval,
-        Context, Maybe_GC_TraceCode, !Info) :-
+ml_gen_gc_statement_with_typeinfo(VarName, DeclType, TypeInfoRval,
+        Context, GCStatement, !Info) :-
     HowToGetTypeInfo = already_provided(TypeInfoRval),
-    ml_gen_maybe_gc_trace_code_2(VarName, DeclType, HowToGetTypeInfo,
-        Context, Maybe_GC_TraceCode, !Info).
+    ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo,
+        Context, GCStatement, !Info).
 
 :- type how_to_get_type_info
     --->    construct_from_type(mer_type)
     ;       already_provided(mlds_rval).
 
-:- pred ml_gen_maybe_gc_trace_code_2(mlds_var_name::in, mer_type::in,
-    how_to_get_type_info::in, prog_context::in, maybe(statement)::out,
-    ml_gen_info::in, ml_gen_info::out) is det.
+:- pred ml_gen_gc_statement_2(mlds_var_name::in, mer_type::in,
+    how_to_get_type_info::in, prog_context::in,
+    mlds_gc_statement::out, ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_maybe_gc_trace_code_2(VarName, DeclType, HowToGetTypeInfo, Context,
-        Maybe_GC_TraceCode, !Info) :-
+ml_gen_gc_statement_2(VarName, DeclType, HowToGetTypeInfo, Context,
+        GCStatement, !Info) :-
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
     module_info_get_globals(ModuleInfo, Globals),
     globals.get_gc_method(Globals, GC),
@@ -1929,9 +1929,9 @@
             ml_gen_trace_var(!.Info, VarName, DeclType, TypeInfoRval,
                 Context, GC_TraceCode)
         ),
-        Maybe_GC_TraceCode = yes(GC_TraceCode)
+        GCStatement = gc_trace_code(GC_TraceCode)
     ;
-        Maybe_GC_TraceCode = no
+        GCStatement = gc_no_stmt
     ).
 
     % Return `yes' if the type needs to be traced by the accurate garbage
@@ -2080,7 +2080,7 @@
             map.lookup(VarTypes, Var, LocalVarType),
             MLDS_Defn = ml_gen_mlds_var_decl(var(LocalVarName),
                 mercury_type_to_mlds_type(ModuleInfo, LocalVarType),
-                no, MLDS_Context)
+                gc_no_stmt, MLDS_Context)
         ),
     set.to_sorted_list(NonLocals, NonLocalVarList),
     MLDS_NonLocalVarDecls = list.map(GenLocalVarDecl, NonLocalVarList),
@@ -2301,10 +2301,10 @@
         Initializer = init_array(NullPointers),
         % This is used for the type_infos allocated during tracing,
         % and we don't need to trace them.
-        MaybeGCTraceCode = no,
+        GCStatement = gc_no_stmt,
         Context = !.Fixup ^ context,
         VarDecl = ml_gen_mlds_var_decl(var(VarName), VarType, Initializer,
-            MaybeGCTraceCode, Context),
+            GCStatement, Context),
         !:Fixup = !.Fixup ^ next_id := NextId,
         !:Fixup= !.Fixup ^ locals := !.Fixup ^ locals ++ [VarDecl],
 
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.87
diff -u -r1.87 ml_elim_nested.m
--- compiler/ml_elim_nested.m	1 Dec 2006 15:04:08 -0000	1.87
+++ compiler/ml_elim_nested.m	21 Dec 2006 12:54:44 -0000
@@ -523,8 +523,8 @@
         Params0 = mlds_func_params(Arguments0, RetValues),
         ml_maybe_add_args(Arguments0, FuncBody0, ModuleName,
             Context, ElimInfo0, ElimInfo1),
-        flatten_arguments(Arguments0, Arguments1, ElimInfo1, ElimInfo2),
-        flatten_statement(FuncBody0, FuncBody1, ElimInfo2, ElimInfo),
+        flatten_statement(FuncBody0, FuncBody1, ElimInfo1, ElimInfo2),
+        fixup_gc_statements(ElimInfo2, ElimInfo),
         elim_info_finish(ElimInfo, NestedFuncs0, Locals),
 
         % Split the locals that we need to process into local variables
@@ -589,7 +589,7 @@
                 % functions, or (for accurate GC) may contain pointers,
                 % then we need to copy them to local variables in the
                 % environment structure.
-                ml_maybe_copy_args(Arguments1, FuncBody0, ElimInfo,
+                ml_maybe_copy_args(Arguments0, FuncBody0, ElimInfo,
                     EnvTypeName, EnvPtrTypeName, Context,
                     _ArgsToCopy, CodeToCopyArgs),
 
@@ -639,10 +639,10 @@
             % annotation on the arguments anymore. We delete them here, because
             % otherwise the `#if 0 ... #endif' blocks output for the
             % annotations clutter up the generated C files.
-            Arguments = list.map(strip_gc_trace_code, Arguments1)
+            Arguments = list.map(strip_gc_statement, Arguments0)
         ;
             Action = hoist_nested_funcs,
-            Arguments = Arguments1
+            Arguments = Arguments0
         ),
         Params = mlds_func_params(Arguments, RetValues),
         DefnBody = mlds_function(PredProcId, Params,
@@ -654,11 +654,11 @@
         Defns = [Defn0]
     ).
 
-:- func strip_gc_trace_code(mlds_argument) = mlds_argument.
+:- func strip_gc_statement(mlds_argument) = mlds_argument.
 
-strip_gc_trace_code(Argument0) = Argument :-
-    Argument0 = mlds_argument(Name, Type, _MaybeGCTraceCode),
-    Argument = mlds_argument(Name, Type, no).
+strip_gc_statement(Argument0) = Argument :-
+    Argument0 = mlds_argument(Name, Type, _GCStatement),
+    Argument = mlds_argument(Name, Type, gc_no_stmt).
 
     % Add any arguments which are used in nested functions
     % to the local_data field in the elim_info.
@@ -670,12 +670,12 @@
 ml_maybe_add_args([], _, _, _, !Info).
 ml_maybe_add_args([Arg|Args], FuncBody, ModuleName, Context, !Info) :-
     (
-        Arg = mlds_argument(entity_data(var(VarName)), _Type, GC_TraceCode),
-        ml_should_add_local_data(!.Info, var(VarName), GC_TraceCode,
+        Arg = mlds_argument(entity_data(var(VarName)), _Type, GCStatement),
+        ml_should_add_local_data(!.Info, var(VarName), GCStatement,
             [], [FuncBody])
     ->
         ml_conv_arg_to_var(Context, Arg, ArgToCopy),
-        elim_info_add_and_flatten_local_data(ArgToCopy, !Info)
+        elim_info_add_local_data(ArgToCopy, !Info)
     ;
         true
     ),
@@ -696,8 +696,8 @@
     ModuleName = elim_info_get_module_name(ElimInfo),
     (
         Arg = mlds_argument(entity_data(var(VarName)), FieldType,
-            GC_TraceCode),
-        ml_should_add_local_data(ElimInfo, var(VarName), GC_TraceCode,
+            GCStatement),
+        ml_should_add_local_data(ElimInfo, var(VarName), GCStatement,
             [], [FuncBody])
     ->
         ml_conv_arg_to_var(Context, Arg, ArgToCopy),
@@ -809,21 +809,23 @@
     Fields0 = list.map(convert_local_to_field, LocalVars),
 
     % Extract the GC tracing code from the fields.
-    list.map2(extract_gc_trace_code, Fields0, Fields1, GC_TraceStatements0),
-    GC_TraceStatements = list.condense(GC_TraceStatements0),
+    list.map3(extract_gc_statements, Fields0, Fields1,
+        GC_InitStatements,GC_TraceStatements),
+    list.append(GC_InitStatements,GC_TraceStatements,GC_Statements0),
+    GC_Statements = list.condense(GC_Statements0),
 
     ( Action = chain_gc_stack_frames ->
-        ml_chain_stack_frames(Fields1, GC_TraceStatements, EnvTypeName,
+        ml_chain_stack_frames(Fields1, GC_Statements, EnvTypeName,
             Context, FuncName, ModuleName, Globals, Fields, EnvInitializer,
             LinkStackChain, GCTraceFuncDefns),
-        GC_TraceEnv = no
+        GCStatementEnv = gc_no_stmt
     ;
         (
-            GC_TraceStatements = [],
-            GC_TraceEnv = no
+            GC_Statements = [],
+            GCStatementEnv = gc_no_stmt
         ;
-            GC_TraceStatements = [_ | _],
-            GC_TraceEnv = yes(ml_block([], GC_TraceStatements, Context))
+            GC_Statements = [_ | _],
+            GCStatementEnv = gc_trace_code(ml_block([], GC_Statements, Context))
         ),
         Fields = Fields1,
         EnvInitializer = no_initializer,
@@ -846,7 +848,7 @@
     EnvVarName = mlds_var_name(env_name_base(Action), no),
     EnvVarEntityName = entity_data(var(EnvVarName)),
     EnvVarFlags = ml_gen_local_var_decl_flags,
-    EnvVarDefnBody = mlds_data(EnvTypeName, EnvInitializer, GC_TraceEnv),
+    EnvVarDefnBody = mlds_data(EnvTypeName, EnvInitializer, GCStatementEnv),
     EnvVarDecl = mlds_defn(EnvVarEntityName, Context, EnvVarFlags,
         EnvVarDefnBody),
 
@@ -919,14 +921,14 @@
     PrevFieldName = entity_data(var(mlds_var_name("prev", no))),
     PrevFieldFlags = ml_gen_public_field_decl_flags,
     PrevFieldType = ml_stack_chain_type,
-    PrevFieldDefnBody = mlds_data(PrevFieldType, no_initializer, no),
+    PrevFieldDefnBody = mlds_data(PrevFieldType, no_initializer, gc_no_stmt),
     PrevFieldDecl = mlds_defn(PrevFieldName, Context, PrevFieldFlags,
         PrevFieldDefnBody),
 
     TraceFieldName = entity_data(var(mlds_var_name("trace", no))),
     TraceFieldFlags = ml_gen_public_field_decl_flags,
     TraceFieldType = mlds_func_type(GCTraceFuncParams),
-    TraceFieldDefnBody = mlds_data(TraceFieldType, no_initializer, no),
+    TraceFieldDefnBody = mlds_data(TraceFieldType, no_initializer, gc_no_stmt),
     TraceFieldDecl = mlds_defn(TraceFieldName, Context, TraceFieldFlags,
         TraceFieldDefnBody),
 
@@ -972,7 +974,7 @@
     % Compute the signature of the GC tracing function
     ArgName = entity_data(var(mlds_var_name("this_frame", no))),
     ArgType = mlds_generic_type,
-    Argument = mlds_argument(ArgName, ArgType, no),
+    Argument = mlds_argument(ArgName, ArgType, gc_no_stmt),
     FuncParams = mlds_func_params([Argument], []),
     Signature = mlds_get_func_signature(FuncParams),
 
@@ -1027,16 +1029,22 @@
     MLDS_DeclFlags = init_decl_flags(Access, PerInstance,
         Virtuality, Finality, Constness, Abstractness).
 
-:- pred extract_gc_trace_code(mlds_defn::in, mlds_defn::out,
-    statements::out) is det.
+:- pred extract_gc_statements(mlds_defn::in, mlds_defn::out,
+    statements::out, statements::out) is det.
 
-extract_gc_trace_code(mlds_defn(Name, Context, Flags, Body0),
-        mlds_defn(Name, Context, Flags, Body), GCTraceStmts) :-
-    ( Body0 = mlds_data(Type, Init, yes(GCTraceStmt)) ->
-        Body = mlds_data(Type, Init, no),
+extract_gc_statements(mlds_defn(Name, Context, Flags, Body0),
+        mlds_defn(Name, Context, Flags, Body), GCInitStmts, GCTraceStmts) :-
+    ( Body0 = mlds_data(Type, Init, gc_trace_code(GCTraceStmt)) ->
+        Body = mlds_data(Type, Init, gc_no_stmt),
+        GCInitStmts = [],
         GCTraceStmts = [GCTraceStmt]
+    ; Body0 = mlds_data(Type, Init, gc_initialiser(GCInitStmt)) ->
+        Body = mlds_data(Type, Init, gc_no_stmt),
+        GCInitStmts = [GCInitStmt],
+        GCTraceStmts = []
     ;
         Body = Body0,
+        GCInitStmts = [],
         GCTraceStmts = []
     ).
 
@@ -1157,9 +1165,9 @@
     EnvPtrVarType = ml_make_env_ptr_type(Globals, EnvTypeName),
     % The env_ptr never needs to be traced by the GC, since the environment
     % that it points to will always be on the stack, not into the heap.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     EnvPtrVarDefnBody = mlds_data(EnvPtrVarType, no_initializer,
-        GC_TraceCode),
+        GCStatement),
     EnvPtrVarDecl = mlds_defn(EnvPtrVarEntityName, Context,
         EnvPtrVarFlags, EnvPtrVarDefnBody),
 
@@ -1183,9 +1191,9 @@
     mlds_defn::out) is det.
 
 ml_conv_arg_to_var(Context, Arg, LocalVar) :-
-    Arg = mlds_argument(Name, Type, GC_TraceCode),
+    Arg = mlds_argument(Name, Type, GCStatement),
     Flags = ml_gen_local_var_decl_flags,
-    DefnBody = mlds_data(Type, no_initializer, GC_TraceCode),
+    DefnBody = mlds_data(Type, no_initializer, GCStatement),
     LocalVar = mlds_defn(Name, Context, Flags, DefnBody).
 
     % Return the declaration flags appropriate for an environment struct
@@ -1311,10 +1319,9 @@
 
 %-----------------------------------------------------------------------------%
 
-% flatten_arguments:
-% flatten_argument:
 % flatten_function_body:
 % flatten_maybe_statement:
+% flatten_gc_statement:
 % flatten_statements:
 % flatten_statement:
 %   Recursively process the statement(s), calling fixup_var on every
@@ -1325,20 +1332,6 @@
 %   Also, for Action = chain_gc_stack_frames, add code to save and
 %   restore the stack chain pointer at any `try_commit' statements.
 
-:- pred flatten_arguments(mlds_arguments::in, mlds_arguments::out,
-    elim_info::in, elim_info::out) is det.
-
-flatten_arguments(!Arguments, !Info) :-
-    list.map_foldl(flatten_argument, !Arguments, !Info).
-
-:- pred flatten_argument(mlds_argument::in, mlds_argument::out,
-    elim_info::in, elim_info::out) is det.
-
-flatten_argument(Argument0, Argument, !Info) :-
-    Argument0 = mlds_argument(Name, Type, MaybeGCTraceCode0),
-    flatten_maybe_statement(MaybeGCTraceCode0, MaybeGCTraceCode, !Info),
-    Argument = mlds_argument(Name, Type, MaybeGCTraceCode).
-
 :- pred flatten_function_body(mlds_function_body::in, mlds_function_body::out,
     elim_info::in, elim_info::out) is det.
 
@@ -1355,6 +1348,17 @@
 flatten_maybe_statement(yes(Statement0), yes(Statement), !Info) :-
     flatten_statement(Statement0, Statement, !Info).
 
+:- pred flatten_gc_statement(mlds_gc_statement::in,
+    mlds_gc_statement::out, elim_info::in, elim_info::out) is det.
+
+flatten_gc_statement(gc_no_stmt, gc_no_stmt, !Info).
+flatten_gc_statement(gc_trace_code(Statement0), gc_trace_code(Statement),
+        !Info) :-
+    flatten_statement(Statement0, Statement, !Info).
+flatten_gc_statement(gc_initialiser(Statement0), gc_initialiser(Statement),
+        !Info) :-
+    flatten_statement(Statement0, Statement, !Info).
+
 :- pred flatten_statements(statements::in, statements::out,
     elim_info::in, elim_info::out) is det.
 
@@ -1574,7 +1578,7 @@
         ),
         InitStatements = []
     ;
-        DefnBody0 = mlds_data(Type, Init0, MaybeGCTraceCode0),
+        DefnBody0 = mlds_data(Type, Init0, GCStatement0),
         % For local variable definitions, if they are referenced by any nested
         % functions, then strip them out and store them in the elim_info.
         (
@@ -1584,7 +1588,7 @@
             % the testing burden), we do the same for the other back-ends too.
             ml_decl_is_static_const(Defn0)
         ->
-            elim_info_add_and_flatten_local_data(Defn0, !Info),
+            elim_info_add_local_data(Defn0, !Info),
             Defns = [],
             InitStatements = []
         ;
@@ -1592,7 +1596,7 @@
             Name = entity_data(DataName),
             DataName = var(VarName),
             ml_should_add_local_data(!.Info,
-                DataName, MaybeGCTraceCode0,
+                DataName, GCStatement0,
                 FollowingDefns, FollowingStatements)
         ->
             % We need to strip out the initializer (if any) and convert it
@@ -1603,7 +1607,7 @@
                 % work, because it doesn't handle the case when initializers in
                 % FollowingDefns reference this variable
                 Init1 = no_initializer,
-                DefnBody1 = mlds_data(Type, Init1, MaybeGCTraceCode0),
+                DefnBody1 = mlds_data(Type, Init1, GCStatement0),
                 Defn1 = mlds_defn(Name, Context, Flags0, DefnBody1),
                 VarLval = var(qual(!.Info ^ module_name, module_qual, VarName),
                     Type),
@@ -1613,13 +1617,11 @@
                 Defn1 = Defn0,
                 InitStatements = []
             ),
-            elim_info_add_and_flatten_local_data(Defn1, !Info),
+            elim_info_add_local_data(Defn1, !Info),
             Defns = []
         ;
             fixup_initializer(Init0, Init, !Info),
-            flatten_maybe_statement(MaybeGCTraceCode0, MaybeGCTraceCode,
-                !Info),
-            DefnBody = mlds_data(Type, Init, MaybeGCTraceCode),
+            DefnBody = mlds_data(Type, Init, GCStatement0),
             Defn = mlds_defn(Name, Context, Flags0, DefnBody),
             Defns = [Defn],
             InitStatements = []
@@ -1642,15 +1644,19 @@
     % top level (if it's a static const).
     %
 :- pred ml_should_add_local_data(elim_info::in, mlds_data_name::in,
-    mlds_maybe_gc_trace_code::in, mlds_defns::in, statements::in)
+    mlds_gc_statement::in, mlds_defns::in, statements::in)
     is semidet.
 
-ml_should_add_local_data(Info, DataName, MaybeGCTraceCode,
+ml_should_add_local_data(Info, DataName, GCStatement,
         FollowingDefns, FollowingStatements) :-
     Action = Info ^ action,
     (
         Action = chain_gc_stack_frames,
-        MaybeGCTraceCode = yes(_)
+        (
+            GCStatement = gc_trace_code(_)
+        ;
+            GCStatement = gc_initialiser(_)
+        )
     ;
         Action = hoist_nested_funcs,
         ml_need_to_hoist(Info ^ module_name, DataName,
@@ -1665,9 +1671,9 @@
     % the last part of that is tricky, and for the Java and IL back-ends we
     % need to hoist out all static constants anyway, so to keep things simple
     % we do the same for the C back-end to, i.e. we always hoist all static
-    % %constants.
+    % constants.
     %
-    % XXX Do we need to check for references from the GC_TraceCode
+    % XXX Do we need to check for references from the GCStatement
     % fields here?
     %
 :- pred ml_need_to_hoist(mlds_module_name::in, mlds_data_name::in,
@@ -1690,32 +1696,6 @@
         initializer_contains_var(Initializer, QualDataName)
     ).
 
-    % Add the variable definition to the local_data field of the elim_info,
-    % fix up any references inside the GC tracing code, and then update
-    % the GC tracing code in the local_data.
-    %
-    % Note that we need to add the variable definition to the local_data
-    % *before* we fix up the GC tracing code, otherwise references to the
-    % variable itself in the GC tracing code won't get fixed.
-    %
-:- pred elim_info_add_and_flatten_local_data(mlds_defn::in,
-    elim_info::in, elim_info::out) is det.
-
-elim_info_add_and_flatten_local_data(Defn0, !Info) :-
-    (
-        Defn0 = mlds_defn(Name, Context, Flags, DefnBody0),
-        DefnBody0 = mlds_data(Type, Init, MaybeGCTraceCode0)
-    ->
-        elim_info_add_local_data(Defn0, !Info),
-        flatten_maybe_statement(MaybeGCTraceCode0, MaybeGCTraceCode, !Info),
-        DefnBody = mlds_data(Type, Init, MaybeGCTraceCode),
-        Defn = mlds_defn(Name, Context, Flags, DefnBody),
-        elim_info_remove_local_data(Defn0, !Info),
-        elim_info_add_local_data(Defn, !Info)
-    ;
-        elim_info_add_local_data(Defn0, !Info)
-    ).
-
 %-----------------------------------------------------------------------------%
 
 % fixup_initializer:
@@ -1863,6 +1843,38 @@
 fixup_lval(var(Var0, VarType), VarLval, !Info) :-
     fixup_var(Var0, VarType, VarLval, !Info).
 
+% fixup_gc_statements:
+%   Process the trace code in the locals that have been hoisted
+%   to the stack frame structure so that the code correctly refers to any
+%   variables that have been pulled out.
+%   It assumes the locals don't actually change during the process.
+%   I think this should be safe. (schmidt)
+
+:- pred fixup_gc_statements(elim_info::in, elim_info::out) is det.
+
+fixup_gc_statements(!Info) :-
+    Locals = elim_info_get_local_data(!.Info),
+    fixup_gc_statements_defns(Locals, !Info).
+
+:- pred fixup_gc_statements_defns(mlds_defns::in,
+    elim_info::in, elim_info::out) is det.
+
+fixup_gc_statements_defns([], !Info).
+fixup_gc_statements_defns([ Defn0 | Defns ], !Info) :-
+    (
+        Defn0 = mlds_defn(Name, Context, Flags, DefnBody0),
+        DefnBody0 = mlds_data(Type, Init, GCStatement0)
+    ->
+        flatten_gc_statement(GCStatement0, GCStatement, !Info),
+        DefnBody = mlds_data(Type, Init, GCStatement),
+        Defn = mlds_defn(Name, Context, Flags, DefnBody),
+        elim_info_remove_local_data(Defn0, !Info),
+        elim_info_add_local_data(Defn, !Info)
+    ;
+        true
+    ),
+    fixup_gc_statements_defns(Defns, !Info).
+
 %-----------------------------------------------------------------------------%
 
     % Change up any references to local vars in the containing function
@@ -2311,8 +2323,8 @@
     Initializer = no_initializer,
     % The saved stack chain never needs to be traced by the GC,
     % since it will always point to the stack, not into the heap.
-    GCTraceCode = no,
-    DefnBody = mlds_data(Type, Initializer, GCTraceCode),
+    GCStatement = gc_no_stmt,
+    DefnBody = mlds_data(Type, Initializer, GCStatement),
     Defn = mlds_defn(Name, Context, Flags, DefnBody).
 
     % Generate a statement to save the stack chain pointer:
Index: compiler/ml_optimize.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_optimize.m,v
retrieving revision 1.46
diff -u -r1.46 ml_optimize.m
--- compiler/ml_optimize.m	1 Dec 2006 15:04:08 -0000	1.46
+++ compiler/ml_optimize.m	21 Dec 2006 12:54:46 -0000
@@ -317,7 +317,7 @@
     unexpected(this_file, "generate_assign_args: length mismatch").
 generate_assign_args(OptInfo, [Arg | Args], [ArgRval | ArgRvals],
         Statements, TempDefns) :-
-    Arg = mlds_argument(Name, Type, _ArgGCTraceCode),
+    Arg = mlds_argument(Name, Type, _ArgGCStatement),
     (
         % Extract the variable name.
         Name = entity_data(var(VarName))
@@ -356,9 +356,9 @@
             Initializer = no_initializer,
             % We don't need to trace the temporary variables for GC, since they
             % are not live across a call or a heap allocation.
-            GC_TraceCode = no,
+            GCStatement = gc_no_stmt,
             TempDefn = ml_gen_mlds_var_decl(var(TempName), Type, Initializer,
-                GC_TraceCode, OptInfo ^ context),
+                GCStatement, OptInfo ^ context),
             TempInitStatement = statement(
                 atomic(assign(var(QualTempName, Type), ArgRval)),
                 OptInfo ^ context),
@@ -640,9 +640,9 @@
     Defn0 = mlds_defn(Name, Context, Flags, DefnBody0),
     (
         Name = entity_data(var(VarName)),
-        DefnBody0 = mlds_data(Type, _OldInitializer, GC_TraceCode)
+        DefnBody0 = mlds_data(Type, _OldInitializer, GCStatement)
     ->
-        DefnBody = mlds_data(Type, init_obj(Rval), GC_TraceCode),
+        DefnBody = mlds_data(Type, init_obj(Rval), GCStatement),
         Defn = mlds_defn(Name, Context, Flags, DefnBody),
         Defns = Defns0
     ;
@@ -724,7 +724,7 @@
     % Check if this definition is a local variable definition...
     Name = entity_data(var(VarName)),
     Flags = ml_gen_local_var_decl_flags,
-    DefnBody = mlds_data(_Type, Initializer, _MaybeGCTraceCode),
+    DefnBody = mlds_data(_Type, Initializer, _GCStatement),
 
     % ... with a known initial value.
     QualVarName = qual(OptInfo ^ module_name, module_qual, VarName),
@@ -909,9 +909,9 @@
 eliminate_var_in_defn(Defn0, Defn, !VarElimInfo) :-
     Defn0 = mlds_defn(Name, Context, Flags, DefnBody0),
     (
-        DefnBody0 = mlds_data(Type, Initializer0, MaybeGCTraceCode),
+        DefnBody0 = mlds_data(Type, Initializer0, GCStatement),
         eliminate_var_in_initializer(Initializer0, Initializer, !VarElimInfo),
-        DefnBody = mlds_data(Type, Initializer, MaybeGCTraceCode)
+        DefnBody = mlds_data(Type, Initializer, GCStatement)
     ;
         DefnBody0 = mlds_class(_),
         % We assume that nested classes don't refer to local variables
Index: compiler/ml_string_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_string_switch.m,v
retrieving revision 1.29
diff -u -r1.29 ml_string_switch.m
--- compiler/ml_string_switch.m	1 Dec 2006 15:04:08 -0000	1.29
+++ compiler/ml_string_switch.m	21 Dec 2006 12:54:46 -0000
@@ -66,9 +66,9 @@
     SlotVarName = mlds_var_name(
         string.format("slot_%d", [i(SlotVarSeq)]), no),
     SlotVarType = mlds_native_int_type,
-    SlotVarGCTraceCode = no, % never need to trace ints
+    SlotVarGCStatement = gc_no_stmt, % never need to trace ints
     SlotVarDefn = ml_gen_mlds_var_decl(var(SlotVarName), SlotVarType,
-        SlotVarGCTraceCode, MLDS_Context),
+        SlotVarGCStatement, MLDS_Context),
     ml_gen_var_lval(!.Info, SlotVarName, SlotVarType, SlotVarLval),
 
     ml_gen_info_new_cond_var(StringVarSeq, !Info),
@@ -78,9 +78,9 @@
     % This variable always points to an element of the string_table array,
     % which are all static constants; it can never point into the heap.
     % So the GC never needs to trace it
-    StringVarGCTraceCode = no,
+    StringVarGCStatement = gc_no_stmt,
     StringVarDefn = ml_gen_mlds_var_decl(var(StringVarName),
-        StringVarType, StringVarGCTraceCode, MLDS_Context),
+        StringVarType, StringVarGCStatement, MLDS_Context),
     ml_gen_var_lval(!.Info, StringVarName, StringVarType, StringVarLval),
 
     % Generate new labels.
Index: compiler/ml_type_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_type_gen.m,v
retrieving revision 1.62
diff -u -r1.62 ml_type_gen.m
--- compiler/ml_type_gen.m	1 Dec 2006 15:04:08 -0000	1.62
+++ compiler/ml_type_gen.m	21 Dec 2006 12:54:47 -0000
@@ -225,7 +225,7 @@
     mlds_defn(entity_data(var(mlds_var_name("value", no))),
         mlds_make_context(Context),
         ml_gen_member_decl_flags,
-        mlds_data(mlds_native_int_type, no_initializer, no)).
+        mlds_data(mlds_native_int_type, no_initializer, gc_no_stmt)).
 
 :- func ml_gen_enum_constant(prog_context, cons_tag_values, constructor)
     = mlds_defn.
@@ -250,7 +250,7 @@
     MLDS_Defn = mlds_defn(entity_data(var(mlds_var_name(UnqualifiedName, no))),
         mlds_make_context(Context),
         ml_gen_enum_constant_decl_flags,
-        mlds_data(mlds_native_int_type, init_obj(ConstValue), no)).
+        mlds_data(mlds_native_int_type, init_obj(ConstValue), gc_no_stmt)).
 
 %-----------------------------------------------------------------------------%
 %
@@ -433,7 +433,7 @@
     mlds_defn(entity_data(var(mlds_var_name(Name, no))),
         mlds_make_context(Context),
         ml_gen_member_decl_flags,
-        mlds_data(mlds_native_int_type, no_initializer, no)).
+        mlds_data(mlds_native_int_type, no_initializer, gc_no_stmt)).
 
 :- func ml_gen_tag_constant(prog_context, cons_tag_values, constructor)
     = mlds_defns.
@@ -453,7 +453,7 @@
             entity_data(var(mlds_var_name(UnqualifiedName, no))),
             mlds_make_context(Context),
             ml_gen_enum_constant_decl_flags,
-            mlds_data(mlds_native_int_type, init_obj(ConstValue), no)),
+            mlds_data(mlds_native_int_type, init_obj(ConstValue), gc_no_stmt)),
         MLDS_Defns = [MLDS_Defn]
     ;
         MLDS_Defns = []
@@ -789,8 +789,8 @@
 :- func make_arg(mlds_defn) = mlds_argument is det.
 
 make_arg(mlds_defn(Name, _Context, _Flags, Defn)) = Arg :-
-    ( Defn = mlds_data(Type, _Init, GC_TraceCode) ->
-        Arg = mlds_argument(Name, Type, GC_TraceCode)
+    ( Defn = mlds_data(Type, _Init, GCStatement) ->
+        Arg = mlds_argument(Name, Type, GCStatement)
     ;
         unexpected(this_file, "make_arg: non-data member")
     ).
@@ -803,7 +803,7 @@
 gen_init_field(Target, BaseClassId, ClassType, ClassQualifier, Member) =
         Statement :-
     Member = mlds_defn(EntityName, Context, _Flags, Defn),
-    ( Defn = mlds_data(Type0, _Init, _GC_TraceCode) ->
+    ( Defn = mlds_data(Type0, _Init, _GCStatement) ->
         Type = Type0
     ;
         unexpected(this_file, "gen_init_field: non-data member")
@@ -911,8 +911,8 @@
 ml_gen_mlds_field_decl(DataName, MLDS_Type, Context) = MLDS_Defn :-
     Name = entity_data(DataName),
     % We only need GC tracing code for top-level variables, not for fields
-    GC_TraceCode = no,
-    Defn = mlds_data(MLDS_Type, no_initializer, GC_TraceCode),
+    GCStatement = gc_no_stmt,
+    Defn = mlds_data(MLDS_Type, no_initializer, GCStatement),
     DeclFlags = ml_gen_public_field_decl_flags,
     MLDS_Defn = mlds_defn(Name, Context, DeclFlags, Defn).
 
Index: compiler/ml_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/ml_util.m,v
retrieving revision 1.54
diff -u -r1.54 ml_util.m
--- compiler/ml_util.m	1 Dec 2006 15:04:09 -0000	1.54
+++ compiler/ml_util.m	21 Dec 2006 12:54:48 -0000
@@ -555,8 +555,8 @@
 :- pred defn_body_contains_var(mlds_entity_defn::in, mlds_data::in)
     is semidet.
 
-    % XXX Should we include variables in the GC_TraceCode field here?
-defn_body_contains_var(mlds_data(_Type, Initializer, _GC_TraceCode), Name) :-
+    % XXX Should we include variables in the GCStatement field here?
+defn_body_contains_var(mlds_data(_Type, Initializer, _GCStatement), Name) :-
     initializer_contains_var(Initializer, Name).
 defn_body_contains_var(mlds_function(_PredProcId, _Params, FunctionBody,
         _Attrs, _EnvVarNames), Name) :-
Index: compiler/mlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds.m,v
retrieving revision 1.143
diff -u -r1.143 mlds.m
--- compiler/mlds.m	1 Dec 2006 15:04:09 -0000	1.143
+++ compiler/mlds.m	21 Dec 2006 12:54:53 -0000
@@ -563,8 +563,9 @@
                 mlds_type,
                 mlds_initializer,
                 % If accurate GC is enabled, we associate with each variable
-                % the code needed to trace that variable when doing GC.
-                mlds_maybe_gc_trace_code
+                % the code needed to initialise or trace that variable when
+                % doing GC (in the compiler-generated gc trace functions).
+                mlds_gc_statement
             )
     ;       mlds_function(
                 % Represents functions.
@@ -583,12 +584,20 @@
             ).
 
     % If accurate GC is enabled, we associate with each variable
-    % (including function parameters) the code needed to trace that
-    % variable when doing GC.
-    % `no' here indicates that no GC tracing code is needed,
-    % e.g. because accurate GC isn't enabled, or because the
-    % variable can never contain pointers to objects on the heap.
-:- type mlds_maybe_gc_trace_code == maybe(statement).
+    % (including function parameters) the code needed to initialise
+    % or trace that variable when doing GC (in the GC trace function).
+    % `gc_no_stmt' here indicates that no code is needed (e.g. because
+    % accurate GC isn't enabled, or because the variable can never
+    % contain pointers to objects on the heap).
+    % 'gc_trace_code' indicates that GC tracing code is required for the
+    % variable.
+    % 'gc_initialiser' indicates that the variable is a compiler-generated
+    % variable that needs to be initialised before tracing the other
+    % variables for the predicate (used when generating closures).
+:- type mlds_gc_statement
+    ---> gc_trace_code(statement)
+    ;    gc_initialiser(statement)
+    ;    gc_no_stmt.
 
     % It is possible for the function to be defined externally
     % (i.e. the original Mercury procedure was declared `:- external').
@@ -619,8 +628,8 @@
     --->    mlds_argument(
                 mlds_entity_name,          % Argument name.
                 mlds_type,                 % Argument type.
-                mlds_maybe_gc_trace_code   % GC tracing code for this argument,
-                                           % if needed.
+                mlds_gc_statement          % code for GC necessitated
+                                           % by this argument.
             ).
 
 :- type mlds_arg_types == list(mlds_type).
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.204
diff -u -r1.204 mlds_to_c.m
--- compiler/mlds_to_c.m	1 Dec 2006 15:04:09 -0000	1.204
+++ compiler/mlds_to_c.m	21 Dec 2006 12:54:57 -0000
@@ -977,11 +977,11 @@
 
     % Declare local variables corresponding to any foreign_type parameters.
     IsCForeignType = (pred(Arg::in) is semidet :-
-        Arg = mlds_argument(_Name, Type, _GCTraceCode),
+        Arg = mlds_argument(_Name, Type, _GCStatement),
         Type = mlds_foreign_type(c(_))
     ),
     IsCForeignTypePtr = (pred(Arg::in) is semidet :-
-        Arg = mlds_argument(_Name, Type, _GCTraceCode),
+        Arg = mlds_argument(_Name, Type, _GCStatement),
         Type = mlds_ptr_type(mlds_foreign_type(c(_)))
     ),
     CForeignTypeInputs = list.filter(IsCForeignType, Parameters),
@@ -1070,7 +1070,7 @@
     io::di, io::uo) is det.
 
 mlds_output_pragma_input_arg(ModuleName, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     QualName = qual(ModuleName, module_qual, Name),
     BoxedQualName = qual(ModuleName, module_qual, boxed_name(Name)),
     io.write_string("\tMR_MAYBE_BOX_FOREIGN_TYPE(", !IO),
@@ -1085,7 +1085,7 @@
     io::di, io::uo) is det.
 
 mlds_output_pragma_output_arg(ModuleName, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     QualName = qual(ModuleName, module_qual, Name),
     BoxedQualName = qual(ModuleName, module_qual, boxed_name(Name)),
     io.write_string("\tMR_MAYBE_UNBOX_FOREIGN_TYPE(", !IO),
@@ -1100,7 +1100,7 @@
     mlds_argument::in, io::di, io::uo) is det.
 
 mlds_output_pragma_export_input_defns(ModuleName, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     io.write_string("\t", !IO),
     mlds_output_data_decl_ho(mlds_output_type_prefix, mlds_output_type_suffix,
         qual(ModuleName, module_qual, boxed_name(Name)), Type, !IO),
@@ -1110,7 +1110,7 @@
     mlds_argument::in, io::di, io::uo) is det.
 
 mlds_output_pragma_export_output_defns(ModuleName, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     io.write_string("\t", !IO),
     mlds_output_data_decl_ho(mlds_output_type_prefix, mlds_output_type_suffix,
         qual(ModuleName, module_qual, boxed_name(Name)), pointed_to_type(Type),
@@ -1151,7 +1151,7 @@
     io::di, io::uo) is det.
 
 mlds_output_pragma_export_arg(ModuleName, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     ( Type = mlds_foreign_type(c(_)) ->
         % This is a foreign_type input. Pass in the already-boxed value.
         BoxedName = boxed_name(Name),
@@ -1188,7 +1188,7 @@
     ),
     (
         ReturnArg = mlds_argument(_ReturnArgName,
-            mlds_ptr_type(ReturnArgType0), _GC_TraceCode)
+            mlds_ptr_type(ReturnArgType0), _GCStatement)
     ->
         ReturnArgType = ReturnArgType0
     ;
@@ -1315,7 +1315,7 @@
 mlds_type_contains_type(mlds_ptr_type(Type), Type).
 mlds_type_contains_type(mlds_func_type(Parameters), Type) :-
     Parameters = mlds_func_params(Arguments, RetTypes),
-    ( list.member(mlds_argument(_Name, Type, _GC_TraceCode), Arguments)
+    ( list.member(mlds_argument(_Name, Type, _GCStatement), Arguments)
     ; list.member(Type, RetTypes)
     ).
 
@@ -1364,7 +1364,7 @@
 
 mlds_output_decl_body(Indent, Name, Context, DefnBody, !IO) :-
     (
-        DefnBody = mlds_data(Type, Initializer, _GC_TraceCode),
+        DefnBody = mlds_data(Type, Initializer, _GCStatement),
         mlds_output_data_decl(Name, Type, initializer_array_size(Initializer),
             !IO)
     ;
@@ -1383,9 +1383,9 @@
 
 mlds_output_defn_body(Indent, Name, Context, DefnBody, !IO) :-
     (
-        DefnBody = mlds_data(Type, Initializer, Maybe_GC_TraceCode),
+        DefnBody = mlds_data(Type, Initializer, GCStatement),
         mlds_output_data_defn(Name, Type, Initializer, !IO),
-        mlds_output_maybe_gc_trace_code(Indent, Name, Maybe_GC_TraceCode, "",
+        mlds_output_gc_statement(Indent, Name, GCStatement, "",
             !IO)
     ;
         DefnBody = mlds_function(MaybePredProcId, Signature,
@@ -1397,22 +1397,28 @@
         mlds_output_class(Indent, Name, Context, ClassDefn, !IO)
     ).
 
-:- pred mlds_output_maybe_gc_trace_code(indent::in,
-    mlds_qualified_entity_name::in, maybe(statement)::in,
+:- pred mlds_output_gc_statement(indent::in,
+    mlds_qualified_entity_name::in, mlds_gc_statement::in,
     string::in, io::di, io::uo) is det.
 
-mlds_output_maybe_gc_trace_code(Indent, Name, Maybe_GC_TraceCode, MaybeNewLine,
+mlds_output_gc_statement(Indent, Name, GCStatement, MaybeNewLine,
         !IO) :-
     (
-        Maybe_GC_TraceCode = no
+        GCStatement = gc_no_stmt
     ;
-        Maybe_GC_TraceCode = yes(GC_TraceCode),
+        (
+            GCStatement = gc_trace_code(Statement),
+            Label = "#if 0 /* GC trace code */\n"
+        ;
+            GCStatement = gc_initialiser(Statement),
+            Label = "#if 0 /* GC initialiser */\n"
+        ),
         io.write_string(MaybeNewLine, !IO),
-        io.write_string("#if 0 /* GC trace code */\n", !IO),
+        io.write_string(Label, !IO),
         % XXX This value for FuncInfo is bogus. However, this output is only
         % for debugging anyway, so it doesn't really matter.
         FuncInfo = func_info(Name, mlds_func_signature([], [])),
-        mlds_output_statement(Indent, FuncInfo, GC_TraceCode, !IO),
+        mlds_output_statement(Indent, FuncInfo, Statement, !IO),
         io.write_string("#endif\n", !IO)
     ).
 
@@ -1528,10 +1534,10 @@
     Type = ClassId,
     % We only need GC tracing code for top-level variables,
     % not for base classes.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
     MLDS_Defn = mlds_defn(entity_data(var(BaseName)), Context,
         ml_gen_public_field_decl_flags,
-        mlds_data(Type, no_initializer, GC_TraceCode)),
+        mlds_data(Type, no_initializer, GCStatement)),
     BaseNum = BaseNum0 + 1.
 
     % Output the definitions of the enumeration constants
@@ -1564,7 +1570,7 @@
 
 mlds_output_enum_constant(Indent, EnumModuleName, Defn, !IO) :-
     Defn = mlds_defn(Name, Context, _Flags, DefnBody),
-    ( DefnBody = mlds_data(Type, Initializer, _GC_TraceCode) ->
+    ( DefnBody = mlds_data(Type, Initializer, _GCStatement) ->
         mlds_indent(Context, Indent, !IO),
         mlds_output_fully_qualified_name(
             qual(EnumModuleName, type_qual, Name), !IO),
@@ -1801,11 +1807,11 @@
 
 mlds_output_param(OutputPrefix, OutputSuffix, Indent, ModuleName, Context,
         Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, Maybe_GC_TraceCode),
+    Arg = mlds_argument(Name, Type, GCStatement),
     QualName = qual(ModuleName, module_qual, Name),
     mlds_indent(Context, Indent, !IO),
     mlds_output_data_decl_ho(OutputPrefix, OutputSuffix, QualName, Type, !IO),
-    mlds_output_maybe_gc_trace_code(Indent, QualName, Maybe_GC_TraceCode,
+    mlds_output_gc_statement(Indent, QualName, GCStatement,
         "\n", !IO).
 
 :- pred mlds_output_func_type_prefix(mlds_func_params::in, io::di, io::uo)
@@ -1851,7 +1857,7 @@
 
 :- pred mlds_output_param_type(mlds_argument::in, io::di, io::uo) is det.
 
-mlds_output_param_type(mlds_argument(_Name, Type, _GC_TraceCode), !IO) :-
+mlds_output_param_type(mlds_argument(_Name, Type, _GCStatement), !IO) :-
     mlds_output_type(Type, !IO).
 
 %-----------------------------------------------------------------------------%
Index: compiler/mlds_to_gcc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_gcc.m,v
retrieving revision 1.125
diff -u -r1.125 mlds_to_gcc.m
--- compiler/mlds_to_gcc.m	1 Dec 2006 15:04:09 -0000	1.125
+++ compiler/mlds_to_gcc.m	21 Dec 2006 12:55:02 -0000
@@ -804,7 +804,7 @@
 
 gen_defn_body(Name, Context, Flags, DefnBody, GlobalInfo0, GlobalInfo) -->
 	(
-		{ DefnBody = mlds_data(Type, Initializer, _GC_TraceCode) },
+		{ DefnBody = mlds_data(Type, Initializer, _GCStatement) },
 		{ LocalVars = map__init },
 		{ LabelTable = map__init },
 		{ DefnInfo = defn_info(GlobalInfo0, Name, LocalVars,
@@ -844,7 +844,7 @@
 
 build_local_defn_body(Name, DefnInfo, _Context, Flags, DefnBody, GCC_Defn) -->
 	(
-		{ DefnBody = mlds_data(Type, Initializer, _GC_TraceCode) },
+		{ DefnBody = mlds_data(Type, Initializer, _GCStatement) },
 		build_local_data_defn(Name, Flags, Type,
 			Initializer, DefnInfo, GCC_Defn)
 	;
@@ -871,7 +871,7 @@
 build_field_defn_body(Name, _Context, Flags, DefnBody, GlobalInfo,
 		GCC_Defn) -->
 	(
-		{ DefnBody = mlds_data(Type, Initializer, _GC_TraceCode) },
+		{ DefnBody = mlds_data(Type, Initializer, _GCStatement) },
 		build_field_data_defn(Name, Type, Initializer, GlobalInfo,
 			GCC_Defn),
 		add_field_decl_flags(Flags, GCC_Defn)
@@ -1395,11 +1395,11 @@
 	Type = ClassId,
 	% We only need GC tracing code for top-level variables,
 	% not for base classes.
-	GC_TraceCode = no,
+	GCStatement = gc_no_stmt,
 	MLDS_Defn = mlds_defn(
 		entity_data(var(mlds_var_name(BaseName, no))), Context,
 		ml_gen_public_field_decl_flags,
-		mlds_data(Type, no_initializer, GC_TraceCode)),
+		mlds_data(Type, no_initializer, GCStatement)),
 	BaseNum = BaseNum0 + 1.
 
 /***********
@@ -1702,7 +1702,7 @@
 		ParamTypes, ParamDecls, SymbolTable) -->
 	build_param_types_and_decls(Args, ModuleName, GlobalInfo,
 		ParamTypes0, ParamDecls0, SymbolTable0),
-	{ Arg = mlds_argument(ArgName, Type, _GC_TraceCode) },
+	{ Arg = mlds_argument(ArgName, Type, _Statement) },
 	build_type(Type, GlobalInfo, GCC_Type),
 	( { ArgName = entity_data(var(ArgVarName)) } ->
 		{ GCC_ArgVarName = ml_var_name_to_string(ArgVarName) },
Index: compiler/mlds_to_il.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_il.m,v
retrieving revision 1.174
diff -u -r1.174 mlds_to_il.m
--- compiler/mlds_to_il.m	1 Dec 2006 15:04:10 -0000	1.174
+++ compiler/mlds_to_il.m	21 Dec 2006 12:55:07 -0000
@@ -417,9 +417,9 @@
 rename_defn(mlds_defn(Name, Context, Flags, Entity0))
         = mlds_defn(Name, Context, Flags, Entity) :-
     (
-        Entity0 = mlds_data(Type, Initializer, GC_TraceCode),
+        Entity0 = mlds_data(Type, Initializer, GCStatement),
         Entity = mlds_data(Type, rename_initializer(Initializer),
-            rename_maybe_statement(GC_TraceCode))
+            rename_gc_statement(GCStatement))
     ;
         Entity0 = mlds_function(MaybePredProcId, Params, FunctionBody0,
             Attributes, EnvVarNames),
@@ -446,6 +446,14 @@
 rename_maybe_statement(no) = no.
 rename_maybe_statement(yes(Stmt)) = yes(rename_statement(Stmt)).
 
+:- func rename_gc_statement(mlds_gc_statement) = mlds_gc_statement.
+
+rename_gc_statement(gc_no_stmt) = gc_no_stmt.
+rename_gc_statement(gc_trace_code(Stmt))
+    = gc_trace_code(rename_statement(Stmt)).
+rename_gc_statement(gc_initialiser(Stmt))
+    = gc_initialiser(rename_statement(Stmt)).
+
 :- func rename_statement(statement) = statement.
 
 rename_statement(statement(block(Defns, Stmts), Context))
@@ -954,7 +962,7 @@
 
 generate_method(ClassName, _, mlds_defn(Name, Context, Flags, Entity),
         ClassMember, !Info) :-
-    Entity = mlds_data(Type, DataInitializer, _GC_TraceCode),
+    Entity = mlds_data(Type, DataInitializer, _GCStatement),
 
     FieldName = entity_name_to_ilds_id(Name),
 
@@ -1369,9 +1377,9 @@
             % We don't need to worry about tracing variables for
             % accurate GC in the IL back-end -- the .NET runtime
             % system itself provides accurate GC.
-            GC_TraceCode = no,
+            GCStatement = gc_no_stmt,
             RV = ml_gen_mlds_var_decl(
-                var(VN), RT, no_initializer, GC_TraceCode,
+                var(VN), RT, no_initializer, GCStatement,
                 Context),
             Lval = var(qual(ModuleName, module_qual, VN), RT)
         ), RetTypes, ReturnVars, 0, _),
@@ -1386,7 +1394,7 @@
     ),
     ArgTypes = mlds_get_arg_types(Inputs),
     ArgRvals = list.map(
-        (func(mlds_argument(EntName, Type, _GC_TraceCode)) =
+        (func(mlds_argument(EntName, Type, _GCStatement)) =
                 lval(var(VarName, Type)) :-
             VarName = EntNameToVarName(EntName)
         ), Inputs),
@@ -1442,7 +1450,7 @@
         !Tree, !Info) :-
     (
         Name = entity_data(DataName),
-        Entity = mlds_data(MLDSType, Initializer, _GC_TraceCode)
+        Entity = mlds_data(MLDSType, Initializer, _GCStatement)
     ->
         ( Initializer = no_initializer ->
             true
@@ -2987,7 +2995,7 @@
 
 :- func mlds_arg_to_il_arg(mlds_argument) = pair(ilds.id, mlds_type).
 
-mlds_arg_to_il_arg(mlds_argument(EntityName, Type, _GC_TraceCode)) =
+mlds_arg_to_il_arg(mlds_argument(EntityName, Type, _GCStatement)) =
         Id - Type :-
     mangle_entity_name(EntityName, Id).
 
@@ -3038,7 +3046,7 @@
     = ilds.param.
 
 input_param_to_ilds_type(DataRep, _ModuleName, Arg) = ILType - yes(Id) :-
-    Arg = mlds_argument(EntityName, MldsType, _GC_TraceCode),
+    Arg = mlds_argument(EntityName, MldsType, _GCStatement),
     mangle_entity_name(EntityName, Id),
     ILType = mlds_type_to_ilds_type(DataRep, MldsType).
 
@@ -3793,7 +3801,7 @@
     Defn = mlds_defn(Name, _Context, _DeclFlags, Entity),
     (
         Name = entity_data(DataName),
-        Entity = mlds_data(MLDSType0, _Initializer, _GC_TraceCode)
+        Entity = mlds_data(MLDSType0, _Initializer, _GCStatement)
     ->
         mangle_dataname(DataName, MangledDataName),
         mangle_mlds_var(qual(ModuleName, module_qual,
Index: compiler/mlds_to_java.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_java.m,v
retrieving revision 1.87
diff -u -r1.87 mlds_to_java.m
--- compiler/mlds_to_java.m	1 Dec 2006 15:04:10 -0000	1.87
+++ compiler/mlds_to_java.m	21 Dec 2006 12:55:11 -0000
@@ -599,7 +599,7 @@
     ;
         Body = body_external
     ).
-method_ptrs_in_entity_defn(mlds_data(_Type, Initializer, _GC_TraceCode),
+method_ptrs_in_entity_defn(mlds_data(_Type, Initializer, _GCStatement),
         !CodeAddrs) :-
     method_ptrs_in_initializer(Initializer, !CodeAddrs).
 method_ptrs_in_entity_defn(mlds_class(ClassDefn), !CodeAddrs) :-
@@ -889,7 +889,7 @@
     % It will have the return type java.lang.Object
     MethodArgVariable = mlds_var_name("args", no),
     MethodArgType = mlds_argument(entity_data(var(MethodArgVariable)),
-        mlds_array_type(mlds_generic_type), no),
+        mlds_array_type(mlds_generic_type), gc_no_stmt),
     MethodRetType = mlds_generic_type,
     MethodArgs = [MethodArgType],
     MethodRets = [MethodRetType],
@@ -914,8 +914,8 @@
     ReturnEntityName = entity_data(var(ReturnVarName)),
 
     ReturnDecFlags = ml_gen_local_var_decl_flags,
-    GCTraceCode = no,  % The Java back-end does its own garbage collection.
-    ReturnEntityDefn = mlds_data(ReturnVarType, no_initializer, GCTraceCode),
+    GCStatement = gc_no_stmt,  % The Java back-end does its own GC.
+    ReturnEntityDefn = mlds_data(ReturnVarType, no_initializer, GCStatement),
     ReturnVarDefn = mlds_defn(ReturnEntityName, Context, ReturnDecFlags,
         ReturnEntityDefn),
     MethodDefns = [ReturnVarDefn],
@@ -1386,7 +1386,7 @@
 output_enum_constant(Indent, ModuleInfo, EnumModuleName, Defn, !IO) :-
     Defn = mlds_defn(Name, _Context, _Flags, DefnBody),
     (
-        DefnBody = mlds_data(Type, Initializer, _GC_TraceCode)
+        DefnBody = mlds_data(Type, Initializer, _GCStatement)
     ->
         indent_line(Indent, !IO),
         io.write_string("public static final int ", !IO),
@@ -1651,7 +1651,7 @@
     mlds_argument::in, io::di, io::uo) is det.
 
 output_param(Indent, _ModuleName, Context, Arg, !IO) :-
-    Arg = mlds_argument(Name, Type, _GC_TraceCode),
+    Arg = mlds_argument(Name, Type, _GCStatement),
     indent_line(Context, Indent, !IO),
     output_type(Type, !IO),
     io.write_char(' ', !IO),
Index: compiler/mlds_to_managed.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/mlds_to_managed.m,v
retrieving revision 1.37
diff -u -r1.37 mlds_to_managed.m
--- compiler/mlds_to_managed.m	1 Dec 2006 15:04:11 -0000	1.37
+++ compiler/mlds_to_managed.m	21 Dec 2006 12:55:12 -0000
@@ -692,7 +692,7 @@
 write_defn_decl(Lang, Defn, !IO) :-
     Defn = mlds_defn(Name, _Context, _Flags, DefnBody),
     (
-        DefnBody = mlds_data(Type, _Initializer, _GC_TraceCode),
+        DefnBody = mlds_data(Type, _Initializer, _GCStatement),
         Name = entity_data(var(VarName))
     ->
         write_parameter_type(Lang, Type, !IO),
@@ -716,7 +716,7 @@
     mlds_argument::in, io::di, io::uo) is det.
 
 write_input_arg_as_foreign_type(Lang, Arg, !IO) :-
-    Arg = mlds_argument(EntityName, Type, _GC_TraceCode),
+    Arg = mlds_argument(EntityName, Type, _GCStatement),
     get_il_data_rep(DataRep, !IO),
     write_il_type_as_foreign_type(Lang, mlds_type_to_ilds_type(DataRep, Type),
         !IO),
Index: compiler/rtti_to_mlds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/rtti_to_mlds.m,v
retrieving revision 1.77
diff -u -r1.77 rtti_to_mlds.m
--- compiler/rtti_to_mlds.m	1 Dec 2006 15:04:19 -0000	1.77
+++ compiler/rtti_to_mlds.m	21 Dec 2006 12:55:14 -0000
@@ -150,11 +150,11 @@
 
     % The GC never needs to trace these definitions, because they are static
     % constants, and can point only to other static constants, not to the heap.
-    GC_TraceCode = no,
+    GCStatement = gc_no_stmt,
 
     % Generate the declaration body, i.e. the type and the initializer
     MLDS_Type = mlds_rtti_type(item_type(RttiId)),
-    DefnBody = mlds_data(MLDS_Type, Initializer, GC_TraceCode),
+    DefnBody = mlds_data(MLDS_Type, Initializer, GCStatement),
     MLDS_Defn = mlds_defn(Name, MLDS_Context, Flags, DefnBody).
 
     % Return the declaration flags appropriate for an rtti_data.
