[m-rev.] diff: fix a bug with switches

Julien Fischer juliensf at csse.unimelb.edu.au
Fri Aug 4 15:49:32 AEST 2006


(This is pending a bootcheck)

Estimated hours taken: 6
Branches: main, release

Fix a bug reported by Peter Hawkins.  The problem occurred with switches with
multiple arms that shared code.   Switch detection expands such arms by making
copies of the shared code.  Requantification then renames the variables in
these copies apart, but the new variables are not being entered into the RTTI
varmaps.   This leads to an assertion failure.

compiler/quantification.m:
 	Update the RTTI varmaps after renaming apart.  Failing to add any
 	freshly introduced variables into the RTTI varmaps makes them
 	inconsistent.

compiler/add_clause.m:
compiler/add_pragma.m:
compiler/cse_detection.m:
compiler/equiv_type_hlds.m:
compiler/follow_code.m:
compiler/hlds_clauses.m:
compiler/hlds_pred.m:
compiler/hlds_rtti.m:
compiler/lambda.m:
compiler/mode_constraints.m:
compiler/pd_util.m:
compiler/polymorphism.m:
compiler/saved_vars.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/tupling.m:
compiler/unify_proc.m:
compiler/unneeded_code.m:
compiler/unused_args.m:
 	Conform to the above change.

 	Minor formatting fixes.

tests/valid/Mmakefile:
tests/valid/hawkins_switch_bug.m:
 	Test case for the above.

Julien.

Index: compiler/add_clause.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/add_clause.m,v
retrieving revision 1.26
diff -u -r1.26 add_clause.m
--- compiler/add_clause.m	27 Jul 2006 05:00:56 -0000	1.26
+++ compiler/add_clause.m	4 Aug 2006 05:19:08 -0000
@@ -62,6 +62,7 @@
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_out.
  :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
  :- import_module hlds.pred_table.
  :- import_module hlds.make_hlds.add_pragma.
  :- import_module hlds.make_hlds.add_pred.
@@ -523,8 +524,13 @@
          finish_goals(Context, FinalSVarMap, [HeadGoal, BodyGoal], Goal0,
              !.SInfo),
          qual_info_get_var_types(!.QualInfo, VarTypes0),
+        %
+        % The RTTI varmaps here are just a dummy value because the real
+        % ones are not introduced until typechecking and polymorphism.
+        %
+        rtti_varmaps_init(EmptyRttiVarmaps),
          implicitly_quantify_clause_body(HeadVars, Warnings, Goal0, Goal,
-            !VarSet, VarTypes0, VarTypes),
+            !VarSet, VarTypes0, VarTypes, EmptyRttiVarmaps, _),
          qual_info_set_var_types(VarTypes, !QualInfo)
      ).

Index: compiler/add_pragma.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/add_pragma.m,v
retrieving revision 1.42
diff -u -r1.42 add_pragma.m
--- compiler/add_pragma.m	29 Jul 2006 12:28:27 -0000	1.42
+++ compiler/add_pragma.m	3 Aug 2006 07:29:02 -0000
@@ -2547,8 +2547,10 @@
          HldsGoal0 = call_foreign_proc(Attributes, PredId, ProcId, ForeignArgs,
              ExtraArgs, MaybeTraceRuntimeCond, PragmaImpl) - GoalInfo,
          map.init(EmptyVarTypes),
+        rtti_varmaps_init(EmptyRttiVarmaps),
          implicitly_quantify_clause_body(HeadVars, _Warnings,
-            HldsGoal0, HldsGoal, VarSet0, VarSet, EmptyVarTypes, _),
+            HldsGoal0, HldsGoal, VarSet0, VarSet, EmptyVarTypes, _,
+            EmptyRttiVarmaps, _),
          NewClause = clause([ProcId], HldsGoal, foreign_language(NewLang),
              Context),
          (
Index: compiler/cse_detection.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/cse_detection.m,v
retrieving revision 1.101
diff -u -r1.101 cse_detection.m
--- compiler/cse_detection.m	31 Jul 2006 08:31:32 -0000	1.101
+++ compiler/cse_detection.m	3 Aug 2006 06:42:11 -0000
@@ -193,11 +193,12 @@
          Redo = yes,

          % ModuleInfo should not be changed by detect_cse_in_goal.
-        CseInfo = cse_info(VarSet1, VarTypes1, RttiVarMaps, _),
+        CseInfo = cse_info(VarSet1, VarTypes1, RttiVarMaps1, _),
          proc_info_get_headvars(ProcInfo0, HeadVars),

          implicitly_quantify_clause_body(HeadVars, _Warnings,
-            Goal1, Goal, VarSet1, VarSet, VarTypes1, VarTypes),
+            Goal1, Goal, VarSet1, VarSet, VarTypes1, VarTypes,
+            RttiVarMaps1, RttiVarMaps),

          proc_info_set_goal(Goal, ProcInfo0, ProcInfo1),
          proc_info_set_varset(VarSet, ProcInfo1, ProcInfo2),
Index: compiler/equiv_type_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/equiv_type_hlds.m,v
retrieving revision 1.35
diff -u -r1.35 equiv_type_hlds.m
--- compiler/equiv_type_hlds.m	31 Jul 2006 08:31:36 -0000	1.35
+++ compiler/equiv_type_hlds.m	3 Aug 2006 03:45:34 -0000
@@ -289,41 +289,44 @@

  replace_in_pred(EqvMap, PredId, !ModuleInfo, !Cache) :-
      some [!PredInfo, !EquivTypeInfo] (
-    module_info_get_name(!.ModuleInfo, ModuleName),
-    module_info_pred_info(!.ModuleInfo, PredId, !:PredInfo),
-    module_info_get_maybe_recompilation_info(!.ModuleInfo, MaybeRecompInfo0),
-
-    PredName = pred_info_name(!.PredInfo),
-    equiv_type.maybe_record_expanded_items(ModuleName,
-        qualified(ModuleName, PredName), MaybeRecompInfo0, !:EquivTypeInfo),
-
-    pred_info_get_arg_types(!.PredInfo, ArgTVarSet0, ExistQVars, ArgTypes0),
-    equiv_type.replace_in_type_list(EqvMap, ArgTypes0, ArgTypes,
-        _, ArgTVarSet0, ArgTVarSet1, !EquivTypeInfo),
-
-    % The constraint_proofs aren't used after polymorphism,
-    % so they don't need to be processed.
-    pred_info_get_class_context(!.PredInfo, ClassContext0),
-    equiv_type.replace_in_prog_constraints(EqvMap, ClassContext0,
-        ClassContext, ArgTVarSet1, ArgTVarSet, !EquivTypeInfo),
-    pred_info_set_class_context(ClassContext, !PredInfo),
+        module_info_get_name(!.ModuleInfo, ModuleName),
+        module_info_pred_info(!.ModuleInfo, PredId, !:PredInfo),
+        module_info_get_maybe_recompilation_info(!.ModuleInfo,
+            MaybeRecompInfo0),
+
+        PredName = pred_info_name(!.PredInfo),
+        equiv_type.maybe_record_expanded_items(ModuleName,
+            qualified(ModuleName, PredName), MaybeRecompInfo0,
+                !:EquivTypeInfo),
+
+        pred_info_get_arg_types(!.PredInfo, ArgTVarSet0, ExistQVars,
+            ArgTypes0),
+        equiv_type.replace_in_type_list(EqvMap, ArgTypes0, ArgTypes,
+            _, ArgTVarSet0, ArgTVarSet1, !EquivTypeInfo),
+
+        % The constraint_proofs aren't used after polymorphism,
+        % so they don't need to be processed.
+        pred_info_get_class_context(!.PredInfo, ClassContext0),
+        equiv_type.replace_in_prog_constraints(EqvMap, ClassContext0,
+            ClassContext, ArgTVarSet1, ArgTVarSet, !EquivTypeInfo),
+        pred_info_set_class_context(ClassContext, !PredInfo),
          pred_info_set_arg_types(ArgTVarSet, ExistQVars, ArgTypes, !PredInfo),

-    ItemId = item_id(pred_or_func_to_item_type(
-        pred_info_is_pred_or_func(!.PredInfo)),
-        item_name(qualified(pred_info_module(!.PredInfo), PredName),
-            pred_info_orig_arity(!.PredInfo))),
-    equiv_type.finish_recording_expanded_items(ItemId,
-        !.EquivTypeInfo, MaybeRecompInfo0, MaybeRecompInfo),
-    module_info_set_maybe_recompilation_info(MaybeRecompInfo, !ModuleInfo),
+        ItemId = item_id(pred_or_func_to_item_type(
+            pred_info_is_pred_or_func(!.PredInfo)),
+            item_name(qualified(pred_info_module(!.PredInfo), PredName),
+                pred_info_orig_arity(!.PredInfo))),
+        equiv_type.finish_recording_expanded_items(ItemId,
+            !.EquivTypeInfo, MaybeRecompInfo0, MaybeRecompInfo),
+        module_info_set_maybe_recompilation_info(MaybeRecompInfo, !ModuleInfo),

          pred_info_get_procedures(!.PredInfo, Procs0),
-    map.map_foldl(
-        replace_in_proc(EqvMap), Procs0, Procs,
-            {!.ModuleInfo, !.PredInfo, !.Cache},
-            {!:ModuleInfo, !:PredInfo, !:Cache}),
-        pred_info_set_procedures(Procs, !PredInfo),
-        module_info_set_pred_info(PredId, !.PredInfo, !ModuleInfo)
+        map.map_foldl(
+            replace_in_proc(EqvMap), Procs0, Procs,
+                {!.ModuleInfo, !.PredInfo, !.Cache},
+                {!:ModuleInfo, !:PredInfo, !:Cache}),
+            pred_info_set_procedures(Procs, !PredInfo),
+            module_info_set_pred_info(PredId, !.PredInfo, !ModuleInfo)
      ).

  :- pred replace_in_proc(eqv_map::in, proc_id::in,
Index: compiler/follow_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/follow_code.m,v
retrieving revision 1.85
diff -u -r1.85 follow_code.m
--- compiler/follow_code.m	31 Jul 2006 08:31:37 -0000	1.85
+++ compiler/follow_code.m	3 Aug 2006 07:47:53 -0000
@@ -79,6 +79,7 @@
      proc_info_get_goal(!.ProcInfo, Goal0),
      proc_info_get_varset(!.ProcInfo, Varset0),
      proc_info_get_vartypes(!.ProcInfo, VarTypes0),
+    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
      (
          move_follow_code_in_goal(Goal0, Goal1, Flags, no, Res),
          % Did the goal change?
@@ -88,7 +89,7 @@
          % and the non-atomic instmap deltas.
          proc_info_get_headvars(!.ProcInfo, HeadVars),
          implicitly_quantify_clause_body(HeadVars, _Warnings, Goal1, Goal2,
-            Varset0, Varset, VarTypes0, VarTypes),
+            Varset0, Varset, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
          proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InstMap0),
          proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
          recompute_instmap_delta(no, Goal2, Goal, VarTypes, InstVarSet,
@@ -96,11 +97,13 @@
      ;
          Goal = Goal0,
          Varset = Varset0,
-        VarTypes = VarTypes0
+        VarTypes = VarTypes0,
+        RttiVarMaps = RttiVarMaps0
      ),
      proc_info_set_goal(Goal, !ProcInfo),
      proc_info_set_varset(Varset, !ProcInfo),
-    proc_info_set_vartypes(VarTypes, !ProcInfo).
+    proc_info_set_vartypes(VarTypes, !ProcInfo),
+    proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo).

  %-----------------------------------------------------------------------------%
  %-----------------------------------------------------------------------------%
Index: compiler/hlds_clauses.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_clauses.m,v
retrieving revision 1.4
diff -u -r1.4 hlds_clauses.m
--- compiler/hlds_clauses.m	31 Jul 2006 08:31:40 -0000	1.4
+++ compiler/hlds_clauses.m	3 Aug 2006 06:43:29 -0000
@@ -104,14 +104,16 @@
      % This partial map holds the types specified by any explicit
      % type qualifiers in the clauses.
      %
-:- pred clauses_info_get_explicit_vartypes(clauses_info::in, vartypes::out) is det.
+:- pred clauses_info_get_explicit_vartypes(clauses_info::in, vartypes::out)
+    is det.

      % This map contains the types of all the variables, as inferred
      % by typecheck.m.
      %
  :- pred clauses_info_get_vartypes(clauses_info::in, vartypes::out) is det.

-:- pred clauses_info_get_rtti_varmaps(clauses_info::in, rtti_varmaps::out) is det.
+:- pred clauses_info_get_rtti_varmaps(clauses_info::in, rtti_varmaps::out)
+    is det.

  :- pred clauses_info_get_headvars(clauses_info::in, list(prog_var)::out) is det.

@@ -166,6 +168,7 @@
              ).

  %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%

  :- implementation.

Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.202
diff -u -r1.202 hlds_pred.m
--- compiler/hlds_pred.m	31 Jul 2006 08:31:41 -0000	1.202
+++ compiler/hlds_pred.m	3 Aug 2006 07:45:29 -0000
@@ -1681,7 +1681,8 @@
      maybe(list(is_live))::out) is det.
  :- pred proc_info_get_declared_determinism(proc_info::in,
      maybe(determinism)::out) is det.
-:- pred proc_info_get_inferred_determinism(proc_info::in, determinism::out) is det.
+:- pred proc_info_get_inferred_determinism(proc_info::in, determinism::out)
+    is det.
  :- pred proc_info_get_goal(proc_info::in, hlds_goal::out) is det.
  :- pred proc_info_get_can_process(proc_info::in, bool::out) is det.
  :- pred proc_info_get_rtti_varmaps(proc_info::in, rtti_varmaps::out) is det.
Index: compiler/hlds_rtti.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_rtti.m,v
retrieving revision 1.6
diff -u -r1.6 hlds_rtti.m
--- compiler/hlds_rtti.m	31 Jul 2006 08:31:41 -0000	1.6
+++ compiler/hlds_rtti.m	4 Aug 2006 05:15:56 -0000
@@ -305,6 +305,7 @@
      bool::in, vartypes::in, rtti_varmaps::in, set(prog_var)::out) is det.

  %-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%

  :- implementation.

Index: compiler/lambda.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/lambda.m,v
retrieving revision 1.117
diff -u -r1.117 lambda.m
--- compiler/lambda.m	31 Jul 2006 08:31:44 -0000	1.117
+++ compiler/lambda.m	3 Aug 2006 07:51:20 -0000
@@ -187,18 +187,20 @@
          PredName, !.ModuleInfo, MustRecomputeNonLocals0),
      process_goal(Goal0, Goal1, Info0, Info1),
      Info1 = lambda_info(VarSet1, VarTypes1, Constraints, TypeVarSet,
-        _, RttiVarMaps, _, _, _, !:ModuleInfo, MustRecomputeNonLocals),
+        _, RttiVarMaps1, _, _, _, !:ModuleInfo, MustRecomputeNonLocals),

      % Check if we need to requantify.
      (
          MustRecomputeNonLocals = yes,
          implicitly_quantify_clause_body(HeadVars, _Warnings,
-            Goal1, Goal, VarSet1, VarSet, VarTypes1, VarTypes)
+            Goal1, Goal, VarSet1, VarSet, VarTypes1, VarTypes,
+            RttiVarMaps1, RttiVarMaps)
      ;
          MustRecomputeNonLocals = no,
          Goal = Goal1,
          VarSet = VarSet1,
-        VarTypes = VarTypes1
+        VarTypes = VarTypes1,
+        RttiVarMaps = RttiVarMaps1
      ),

      % Set the new values of the fields in proc_info and pred_info.
Index: compiler/mode_constraints.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_constraints.m,v
retrieving revision 1.31
diff -u -r1.31 mode_constraints.m
--- compiler/mode_constraints.m	31 Jul 2006 08:31:54 -0000	1.31
+++ compiler/mode_constraints.m	3 Aug 2006 06:46:24 -0000
@@ -55,6 +55,7 @@
  :- import_module hlds.hlds_data.
  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
  :- import_module hlds.inst_graph.
  :- import_module hlds.passes_aux.
  :- import_module hlds.quantification.
@@ -186,8 +187,7 @@
      ).

  dump_abstract_constraints(ModuleInfo, ConstraintVarset, ModeConstraints,
-    !IO) :-
-
+        !IO) :-
      hlds_module.module_info_get_name(ModuleInfo, ModuleName),
      CreateDirectories = yes,
      parse_tree.modules.module_name_to_file_name(ModuleName,
@@ -218,37 +218,41 @@

  correct_nonlocals_in_pred(PredId, !ModuleInfo) :-
      module_info_pred_info(!.ModuleInfo, PredId, PredInfo0),
-    some [!ClausesInfo, !Varset, !Vartypes, !Clauses, !Goals] (
+    some [!ClausesInfo, !Varset, !Vartypes, !Clauses, !Goals, !RttiVarMaps] (
          pred_info_clauses_info(PredInfo0, !:ClausesInfo),
          clauses_info_clauses_only(!.ClausesInfo, !:Clauses),
          clauses_info_get_headvars(!.ClausesInfo, Headvars),
          clauses_info_get_varset(!.ClausesInfo, !:Varset),
          clauses_info_get_vartypes(!.ClausesInfo, !:Vartypes),
+        clauses_info_get_rtti_varmaps(!.ClausesInfo, !:RttiVarMaps),
          !:Goals = list.map(func(X) = clause_body(X), !.Clauses),
-        list.map_foldl2(correct_nonlocals_in_clause_body(Headvars), !Goals,
-            !Varset, !Vartypes),
+        list.map_foldl3(correct_nonlocals_in_clause_body(Headvars), !Goals,
+            !Varset, !Vartypes, !RttiVarMaps),
          !:Clauses = list.map_corresponding(
              func(Clause, Goal) = 'clause_body :='(Clause, Goal),
              !.Clauses, !.Goals),
          clauses_info_set_clauses(!.Clauses, !ClausesInfo),
          clauses_info_set_varset(!.Varset, !ClausesInfo),
          clauses_info_set_vartypes(!.Vartypes, !ClausesInfo),
+        clauses_info_set_rtti_varmaps(!.RttiVarMaps, !ClausesInfo),
          pred_info_set_clauses_info(!.ClausesInfo, PredInfo0, PredInfo)
      ),
      module_info_set_pred_info(PredId, PredInfo, !ModuleInfo).

-    % correct_nonlocals_in_clause_body(Headvars, !Goals, !Varset, !Vartypes)
+    % correct_nonlocals_in_clause_body(Headvars, !Goals, !Varset, !Vartypes,
+    %   RttiVarMaps)
      % requantifies the clause body Goal. This is to ensure that no variable
      % appears in the nonlocal set of a goal that doesn't also appear
      % in that goal.
      %
  :- pred correct_nonlocals_in_clause_body(list(prog_var)::in,
      hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
-    vartypes::in, vartypes::out) is det.
+    vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.

-correct_nonlocals_in_clause_body(Headvars, !Goals, !Varset, !Vartypes) :-
-        implicitly_quantify_clause_body(Headvars, Warnings, !Goals, !Varset,
-            !Vartypes),
+correct_nonlocals_in_clause_body(Headvars, !Goals, !Varset, !Vartypes,
+        !RttiVarMaps) :-
+    implicitly_quantify_clause_body(Headvars, Warnings, !Goals, !Varset,
+        !Vartypes, !RttiVarMaps),
      (   Warnings = []
      ;
          Warnings = [_|_],
Index: compiler/pd_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/pd_util.m,v
retrieving revision 1.53
diff -u -r1.53 pd_util.m
--- compiler/pd_util.m	27 Jul 2006 05:01:18 -0000	1.53
+++ compiler/pd_util.m	3 Aug 2006 07:53:23 -0000
@@ -762,14 +762,18 @@
  %-----------------------------------------------------------------------------%

  requantify_goal(NonLocals, Goal0, Goal, !PDInfo) :-
-    pd_info_get_proc_info(!.PDInfo, ProcInfo0),
-    proc_info_get_varset(ProcInfo0, VarSet0),
-    proc_info_get_vartypes(ProcInfo0, VarTypes0),
-    implicitly_quantify_goal(NonLocals, _, Goal0, Goal,
-        VarSet0, VarSet, VarTypes0, VarTypes),
-    proc_info_set_varset(VarSet, ProcInfo0, ProcInfo1),
-    proc_info_set_vartypes(VarTypes, ProcInfo1, ProcInfo),
-    pd_info_set_proc_info(ProcInfo, !PDInfo).
+    some [!ProcInfo] (
+        pd_info_get_proc_info(!.PDInfo, !:ProcInfo),
+        proc_info_get_varset(!.ProcInfo, VarSet0),
+        proc_info_get_vartypes(!.ProcInfo, VarTypes0),
+        proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
+        implicitly_quantify_goal(NonLocals, _, Goal0, Goal, VarSet0, VarSet,
+            VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
+        proc_info_set_varset(VarSet, !ProcInfo),
+        proc_info_set_vartypes(VarTypes, !ProcInfo),
+        proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo),
+        pd_info_set_proc_info(!.ProcInfo, !PDInfo)
+    ).

  recompute_instmap_delta(Goal0, Goal, !PDInfo) :-
      pd_info_get_module_info(!.PDInfo, ModuleInfo0),
Index: compiler/polymorphism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/polymorphism.m,v
retrieving revision 1.301
diff -u -r1.301 polymorphism.m
--- compiler/polymorphism.m	27 Jul 2006 05:01:18 -0000	1.301
+++ compiler/polymorphism.m	3 Aug 2006 07:38:29 -0000
@@ -1941,10 +1941,12 @@
      ;
          poly_info_get_varset(!.Info, VarSet0),
          poly_info_get_var_types(!.Info, VarTypes0),
+        poly_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
          set.list_to_set(HeadVars, OutsideVars),
          implicitly_quantify_goal(OutsideVars, _Warnings, Goal0, Goal,
-            VarSet0, VarSet, VarTypes0, VarTypes),
-        poly_info_set_varset_and_types(VarSet, VarTypes, !Info)
+            VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
+        poly_info_set_varset_and_types(VarSet, VarTypes, !Info),
+        poly_info_set_rtti_varmaps(RttiVarMaps, !Info)
      ).

      % If the lambda goal we are processing is polymorphically typed, we may
@@ -1963,8 +1965,8 @@

  fixup_lambda_quantification(ArgVars, LambdaVars, ExistQVars, !Goal,
          NewOutsideVars, !Info) :-
-    poly_info_get_rtti_varmaps(!.Info, RttiVarMaps),
-    ( rtti_varmaps_no_tvars(RttiVarMaps) ->
+    poly_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
+    ( rtti_varmaps_no_tvars(RttiVarMaps0) ->
          set.init(NewOutsideVars)
      ;
          poly_info_get_varset(!.Info, VarSet0),
@@ -1973,12 +1975,13 @@
          goal_info_get_nonlocals(GoalInfo0, NonLocals),
          set.insert_list(NonLocals, ArgVars, NonLocalsPlusArgs0),
          set.insert_list(NonLocalsPlusArgs0, LambdaVars, NonLocalsPlusArgs),
-        goal_util.extra_nonlocal_typeinfos(RttiVarMaps, VarTypes0,
+        goal_util.extra_nonlocal_typeinfos(RttiVarMaps0, VarTypes0,
              ExistQVars, NonLocalsPlusArgs, NewOutsideVars),
          set.union(NonLocals, NewOutsideVars, OutsideVars),
          implicitly_quantify_goal(OutsideVars, _Warnings, !Goal,
-            VarSet0, VarSet, VarTypes0, VarTypes),
-        poly_info_set_varset_and_types(VarSet, VarTypes, !Info)
+            VarSet0, VarSet, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
+        poly_info_set_varset_and_types(VarSet, VarTypes, !Info),
+        poly_info_set_rtti_varmaps(RttiVarMaps, !Info)
      ).

  %-----------------------------------------------------------------------------%
Index: compiler/quantification.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/quantification.m,v
retrieving revision 1.106
diff -u -r1.106 quantification.m
--- compiler/quantification.m	27 Jul 2006 05:01:22 -0000	1.106
+++ compiler/quantification.m	4 Aug 2006 05:44:00 -0000
@@ -5,10 +5,10 @@
  % This file may only be copied under the terms of the GNU General
  % Public License - see the file COPYING in the Mercury distribution.
  %-----------------------------------------------------------------------------%
-
+%
  % File: quantification.m.
  % Main authors: fjh, conway.
-
+%
  % Make implicit quantification explicit, and rename apart variables with the
  % same name that appear in distinct scopes. For the rules on implicit
  % quantification, see the Mercury language reference manual.
@@ -27,7 +27,7 @@
  % know is "Does this goal bind any of its nonlocal variables?".  So, rather
  % than storing a list of the variables which _are_ existentially quantified in
  % the goal_info, we store the set of variables which are _not_ quantified.
-
+%
  %-----------------------------------------------------------------------------%

  :- module hlds.quantification.
@@ -35,6 +35,7 @@

  :- import_module hlds.hlds_goal.
  :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
  :- import_module parse_tree.prog_data.

  :- import_module list.
@@ -71,24 +72,25 @@
  :- pred implicitly_quantify_clause_body(nonlocals_to_recompute::in,
      list(prog_var)::in, list(quant_warning)::out,
      hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
-    vartypes::in, vartypes::out) is det.
+    vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.

      % As above, with `ordinary_nonlocals' passed as the first argument.
      %
  :- pred implicitly_quantify_clause_body(list(prog_var)::in,
      list(quant_warning)::out, hlds_goal::in, hlds_goal::out,
-    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out) is det.
+    prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
+    rtti_varmaps::in, rtti_varmaps::out) is det.

  :- pred implicitly_quantify_goal(nonlocals_to_recompute::in,
      set(prog_var)::in, list(quant_warning)::out,
      hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
-    vartypes::in, vartypes::out) is det.
+    vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.

      % As above, with `ordinary_nonlocals' passed as the first argument.
      %
  :- pred implicitly_quantify_goal(set(prog_var)::in, list(quant_warning)::out,
      hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
-    vartypes::in, vartypes::out) is det.
+    vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.

  :- pred requantify_proc(nonlocals_to_recompute::in,
      proc_info::in, proc_info::out) is det.
@@ -134,8 +136,8 @@

      % The `outside vars', `lambda outside vars', and `quant vars'
      % fields are inputs; the `nonlocals' field is output; and
-    % the `seen so far', the varset, the types, and the warnings fields
-    % are threaded (i.e. both input and output).
+    % the `seen so far', the varset, the types, rtti_varmaps, and the
+    % warnings fields are threaded (i.e. both input and output).
      % We use the convention that the input fields are callee save,
      % and the outputs are caller save.
      % The nonlocals_to_recompute field is constant.
@@ -150,7 +152,8 @@
                  seen                    :: set_of_var,
                  varset                  :: prog_varset,
                  vartypes                :: vartypes,
-                warnings                :: list(quant_warning)
+                warnings                :: list(quant_warning),
+                rtti_varmaps            :: rtti_varmaps
              ).

      % Until we have user-specified pretty printing in the debugger,
@@ -195,15 +198,15 @@
  %-----------------------------------------------------------------------------%

  implicitly_quantify_clause_body(HeadVars, Warnings,
-        !Goal, !Varset, !VarTypes) :-
+        !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
      implicitly_quantify_clause_body(ordinary_nonlocals, HeadVars, Warnings,
-        !Goal, !Varset, !VarTypes).
+        !Goal, !Varset, !VarTypes, !RttiVarMaps).

  implicitly_quantify_clause_body(RecomputeNonLocals, HeadVars, Warnings,
-        !Goal, !Varset, !VarTypes) :-
+        !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
      list_to_set(HeadVars, OutsideVars),
      implicitly_quantify_goal(RecomputeNonLocals, OutsideVars, Warnings,
-        !Goal, !Varset, !VarTypes).
+        !Goal, !Varset, !VarTypes, !RttiVarMaps).

  requantify_proc(ProcInfo0, ProcInfo) :-
      requantify_proc(ordinary_nonlocals, ProcInfo0, ProcInfo).
@@ -213,20 +216,24 @@
      proc_info_get_varset(!.ProcInfo, Varset0),
      proc_info_get_vartypes(!.ProcInfo, VarTypes0),
      proc_info_get_goal(!.ProcInfo, Goal0),
+    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarmaps0),
      implicitly_quantify_clause_body(RecomputeNonLocals, HeadVars, _,
-        Goal0, Goal, Varset0, Varset, VarTypes0, VarTypes),
+        Goal0, Goal, Varset0, Varset, VarTypes0, VarTypes,
+        RttiVarmaps0, RttiVarmaps),
      proc_info_set_varset(Varset, !ProcInfo),
      proc_info_set_vartypes(VarTypes, !ProcInfo),
-    proc_info_set_goal(Goal, !ProcInfo).
+    proc_info_set_goal(Goal, !ProcInfo),
+    proc_info_set_rtti_varmaps(RttiVarmaps, !ProcInfo).

-implicitly_quantify_goal(OutsideVars, Warnings, !Goal, !Varset, !VarTypes) :-
+implicitly_quantify_goal(OutsideVars, Warnings, !Goal, !Varset, !VarTypes, 
+        !RttiVarMaps) :-
      implicitly_quantify_goal(ordinary_nonlocals, OutsideVars, Warnings,
-        !Goal, !Varset, !VarTypes).
+        !Goal, !Varset, !VarTypes, !RttiVarMaps).

  implicitly_quantify_goal(RecomputeNonLocals, OutsideVars, Warnings,
-        !Goal, !Varset, !VarTypes) :-
+        !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
      implicitly_quantify_goal_2(ordinary_nonlocals, OutsideVars, Warnings,
-        !Goal, !Varset, !VarTypes),
+        !Goal, !Varset, !VarTypes, !RttiVarMaps),
      (
          RecomputeNonLocals = code_gen_nonlocals,

@@ -235,7 +242,7 @@
          goal_contains_reconstruction(!.Goal)
      ->
          implicitly_quantify_goal_2(code_gen_nonlocals, OutsideVars, _,
-            !Goal, !Varset, !VarTypes)
+            !Goal, !Varset, !VarTypes, !RttiVarMaps)
      ;
          true
      ).
@@ -243,16 +250,18 @@
  :- pred implicitly_quantify_goal_2(nonlocals_to_recompute::in,
      set(prog_var)::in, list(quant_warning)::out,
      hlds_goal::in, hlds_goal::out, prog_varset::in, prog_varset::out,
-    vartypes::in, vartypes::out) is det.
+    vartypes::in, vartypes::out, rtti_varmaps::in, rtti_varmaps::out) is det.

  implicitly_quantify_goal_2(RecomputeNonLocals, OutsideVars0, Warnings,
-        !Goal, !Varset, !VarTypes) :-
+        !Goal, !Varset, !VarTypes, !RttiVarMaps) :-
      OutsideVars = set_to_bitset(OutsideVars0),
-    init(RecomputeNonLocals, OutsideVars, !.Varset, !.VarTypes, QuantInfo0),
+    init(RecomputeNonLocals, OutsideVars, !.Varset, !.VarTypes, !.RttiVarMaps,
+        QuantInfo0),
      implicitly_quantify_goal(!Goal, QuantInfo0, QuantInfo),
      get_varset(QuantInfo, !:Varset),
      get_vartypes(QuantInfo, !:VarTypes),
      get_warnings(QuantInfo, Warnings0),
+    get_rtti_varmaps(QuantInfo, !:RttiVarMaps),
      list.reverse(Warnings0, Warnings).

  :- pred implicitly_quantify_goal(hlds_goal::in, hlds_goal::out,
@@ -273,7 +282,17 @@
          intersect(SeenVars, LocalVars, RenameVars),
          \+ empty(RenameVars)
      ->
-        rename_apart(RenameVars, _, Goal1 - GoalInfo0, Goal - GoalInfo1, !Info)
+        rename_apart(RenameVars, RenameMap,
+            Goal1 - GoalInfo0, Goal - GoalInfo1, !Info),
+        %
+        % Make sure that the information in the RTTI varmaps is updated
+        % to reflect any new variables that we may have just introduced.
+        %
+        some [!RttiVarMaps] (
+            get_rtti_varmaps(!.Info, !:RttiVarMaps),
+            map.foldl(rtti_var_info_duplicate, RenameMap, !RttiVarMaps),
+            set_rtti_varmaps(!.RttiVarMaps, !Info)
+        )
      ;
          Goal = Goal1,
          GoalInfo1 = GoalInfo0
@@ -1370,12 +1389,14 @@
  %-----------------------------------------------------------------------------%

  :- pred init(nonlocals_to_recompute::in, set_of_var::in,
-    prog_varset::in, vartypes::in, quant_info::out) is det.
+    prog_varset::in, vartypes::in, rtti_varmaps::in, quant_info::out) is det.

-init(RecomputeNonLocals, OutsideVars, Varset, VarTypes, QuantInfo) :-
+init(RecomputeNonLocals, OutsideVars, Varset, VarTypes, RttiVarMaps,
+        QuantInfo) :-
      OverlapWarnings = [],
      QuantInfo = quant_info(RecomputeNonLocals, OutsideVars, QuantVars,
-        LambdaOutsideVars, NonLocals, Seen, Varset, VarTypes, OverlapWarnings),
+        LambdaOutsideVars, NonLocals, Seen, Varset, VarTypes, OverlapWarnings,
+        RttiVarMaps),
      init(QuantVars),
      init(NonLocals),
      init(LambdaOutsideVars),
@@ -1391,6 +1412,7 @@
  :- pred get_varset(quant_info::in, prog_varset::out) is det.
  :- pred get_vartypes(quant_info::in, vartypes::out) is det.
  :- pred get_warnings(quant_info::in, list(quant_warning)::out) is det.
+:- pred get_rtti_varmaps(quant_info::in, rtti_varmaps::out) is det.

  :- pred set_outside(set_of_var::in,
      quant_info::in, quant_info::out) is det.
@@ -1408,6 +1430,8 @@
      quant_info::in, quant_info::out) is det.
  :- pred set_warnings(list(quant_warning)::in,
      quant_info::in, quant_info::out) is det.
+:- pred set_rtti_varmaps(rtti_varmaps::in,
+    quant_info::in, quant_info::out) is det.

  get_nonlocals_to_recompute(Q, Q ^ nonlocals_to_recompute).
  get_outside(Q, Q ^ outside).
@@ -1418,6 +1442,7 @@
  get_varset(Q, Q ^ varset).
  get_vartypes(Q, Q ^ vartypes).
  get_warnings(Q, Q ^ warnings).
+get_rtti_varmaps(Q, Q ^ rtti_varmaps).

  set_outside(Outside, Q, Q ^ outside := Outside).
  set_quant_vars(QuantVars, Q, Q ^ quant_vars := QuantVars).
@@ -1427,6 +1452,7 @@
  set_varset(Varset, Q, Q ^ varset := Varset).
  set_vartypes(VarTypes, Q, Q ^ vartypes := VarTypes).
  set_warnings(Warnings, Q, Q ^ warnings := Warnings).
+set_rtti_varmaps(RttiVarMaps, Q, Q ^ rtti_varmaps := RttiVarMaps).

  %-----------------------------------------------------------------------------%

Index: compiler/saved_vars.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/saved_vars.m,v
retrieving revision 1.68
diff -u -r1.68 saved_vars.m
--- compiler/saved_vars.m	31 Jul 2006 08:31:59 -0000	1.68
+++ compiler/saved_vars.m	3 Aug 2006 07:49:52 -0000
@@ -85,14 +85,14 @@

      saved_vars_in_goal(Goal0, Goal1, SlotInfo0, SlotInfo),

-    final_slot_info(Varset1, VarTypes1, RttiVarMaps, SlotInfo),
+    final_slot_info(Varset1, VarTypes1, RttiVarMaps1, SlotInfo),
      proc_info_get_headvars(!.ProcInfo, HeadVars),

      % hlds_out.write_goal(Goal1, !.ModuleInfo, Varset1, 0, "\n"),

      % Recompute the nonlocals for each goal.
      implicitly_quantify_clause_body(HeadVars, _Warnings, Goal1, Goal2,
-        Varset1, Varset, VarTypes1, VarTypes),
+        Varset1, Varset, VarTypes1, VarTypes, RttiVarMaps1, RttiVarMaps),
      proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InstMap0),
      proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
      recompute_instmap_delta(no, Goal2, Goal, VarTypes,
Index: compiler/simplify.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/simplify.m,v
retrieving revision 1.182
diff -u -r1.182 simplify.m
--- compiler/simplify.m	31 Jul 2006 08:31:59 -0000	1.182
+++ compiler/simplify.m	4 Aug 2006 05:42:46 -0000
@@ -469,14 +469,17 @@
      simplify_goal(Goal0, Goal1, !Info, !IO),
      simplify_info_get_varset(!.Info, VarSet0),
      simplify_info_get_var_types(!.Info, VarTypes0),
+    simplify_info_get_rtti_varmaps(!.Info, RttiVarMaps0),
      ( simplify_info_requantify(!.Info) ->
          Goal1 = _ - GoalInfo1,
          goal_info_get_nonlocals(GoalInfo1, NonLocals),
          implicitly_quantify_goal(NonLocals, _, Goal1, Goal2,
-            VarSet0, VarSet1, VarTypes0, VarTypes1),
+            VarSet0, VarSet1, VarTypes0, VarTypes1,
+            RttiVarMaps0, RttiVarMaps1),

          simplify_info_set_varset(VarSet1, !Info),
          simplify_info_set_var_types(VarTypes1, !Info),
+        simplify_info_set_rtti_varmaps(RttiVarMaps1, !Info),

          % Always recompute instmap_deltas for atomic goals - this is safer
          % in the case where unused variables should no longer be included
@@ -502,12 +505,14 @@
          simplify_info_get_varset(!.Info, VarSet2),
          simplify_info_get_var_types(!.Info, VarTypes2),
          simplify_info_get_det_info(!.Info, DetInfo2),
+        simplify_info_get_rtti_varmaps(!.Info, RttiVarMaps2),
          det_info_get_pred_id(DetInfo2, PredId),
          det_info_get_proc_id(DetInfo2, ProcId),
          module_info_pred_proc_info(ModuleInfo2, PredId, ProcId,
              PredInfo, ProcInfo0),
          proc_info_set_vartypes(VarTypes2, ProcInfo0, ProcInfo1),
-        proc_info_set_varset(VarSet2, ProcInfo1, ProcInfo),
+        proc_info_set_varset(VarSet2, ProcInfo1, ProcInfo2),
+        proc_info_set_rtti_varmaps(RttiVarMaps2, ProcInfo2, ProcInfo),
          module_info_set_pred_proc_info(PredId, ProcId,
              PredInfo, ProcInfo, ModuleInfo2, ModuleInfo3),
          simplify_info_set_module_info(ModuleInfo3, !Info),
Index: compiler/size_prof.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/size_prof.m,v
retrieving revision 1.42
diff -u -r1.42 size_prof.m
--- compiler/size_prof.m	31 Jul 2006 08:32:00 -0000	1.42
+++ compiler/size_prof.m	3 Aug 2006 07:56:07 -0000
@@ -245,21 +245,21 @@
      proc_info_get_varset(!.ProcInfo, VarSet0),
      proc_info_get_vartypes(!.ProcInfo, VarTypes0),
      proc_info_get_initial_instmap(!.ProcInfo, !.ModuleInfo, InstMap0),
-    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps),
+    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
      % The with_types are needed to avoid a combinatorial explosion
      % of ambiguity in the type checker.
-    TypeCtorMap0 = map.init `with_type` type_ctor_map,
-    TypeInfoMap0 = map.init `with_type` type_info_map,
-    RevTypeCtorMap0 = map.init `with_type` rev_type_ctor_map,
-    RevTypeInfoMap0 = map.init `with_type` rev_type_info_map,
-    TargetTypeInfoMap0 = map.init `with_type` type_info_map,
-    KnownSizeMap0 = map.init `with_type` known_size_map,
+    TypeCtorMap0 = map.init : type_ctor_map,
+    TypeInfoMap0 = map.init : type_info_map,
+    RevTypeCtorMap0 = map.init : rev_type_ctor_map,
+    RevTypeInfoMap0 = map.init : rev_type_info_map,
+    TargetTypeInfoMap0 = map.init : type_info_map,
+    KnownSizeMap0 = map.init : known_size_map,
      Info0 = size_prof_info(TypeCtorMap0, TypeInfoMap0,
          RevTypeCtorMap0, RevTypeInfoMap0, TargetTypeInfoMap0,
-        KnownSizeMap0, VarSet0, VarTypes0, Transform, RttiVarMaps,
+        KnownSizeMap0, VarSet0, VarTypes0, Transform, RttiVarMaps0,
          !.ModuleInfo),
-    rtti_varmaps_tvars(RttiVarMaps, TVars),
-    list.foldl(record_typeinfo_in_type_info_varmap(RttiVarMaps), TVars,
+    rtti_varmaps_tvars(RttiVarMaps0, TVars),
+    list.foldl(record_typeinfo_in_type_info_varmap(RttiVarMaps0), TVars,
          Info0, Info1),
      process_goal(Goal0, Goal1, Info1, Info),

@@ -268,12 +268,14 @@
      proc_info_get_headvars(!.ProcInfo, HeadVars),
      proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
      implicitly_quantify_clause_body(HeadVars, _Warnings, Goal1, Goal2,
-        Info ^ varset, VarSet, Info ^ vartypes, VarTypes),
+        Info ^ varset, VarSet, Info ^ vartypes, VarTypes,
+        Info ^ rtti_varmaps, RttiVarMaps),
      recompute_instmap_delta(no, Goal2, Goal, VarTypes, InstVarSet,
          InstMap0, !ModuleInfo),
      proc_info_set_goal(Goal, !ProcInfo),
      proc_info_set_varset(VarSet, !ProcInfo),
-    proc_info_set_vartypes(VarTypes, !ProcInfo).
+    proc_info_set_vartypes(VarTypes, !ProcInfo),
+    proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo).

  :- pred process_goal(hlds_goal::in, hlds_goal::out, info::in, info::out)
      is det.
Index: compiler/tupling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/tupling.m,v
retrieving revision 1.26
diff -u -r1.26 tupling.m
--- compiler/tupling.m	31 Jul 2006 08:32:07 -0000	1.26
+++ compiler/tupling.m	3 Aug 2006 08:09:43 -0000
@@ -108,6 +108,7 @@
  :- import_module hlds.hlds_llds.
  :- import_module hlds.hlds_out.
  :- import_module hlds.hlds_pred.
+:- import_module hlds.hlds_rtti.
  :- import_module hlds.instmap.
  :- import_module hlds.quantification.
  :- import_module libs.compiler_util.
@@ -1653,11 +1654,14 @@
              proc_info_get_goal(!.ProcInfo, Goal0),
              proc_info_get_vartypes(!.ProcInfo, VarTypes0),
              proc_info_get_varset(!.ProcInfo, VarSet0),
+            proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
              fix_calls_in_goal(Goal0, Goal, VarSet0, VarSet,
-                VarTypes0, VarTypes, TransformMap),
+                VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps,
+                TransformMap),
              proc_info_set_goal(Goal, !ProcInfo),
              proc_info_set_varset(VarSet, !ProcInfo),
              proc_info_set_vartypes(VarTypes, !ProcInfo),
+            proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo),
              requantify_proc(!ProcInfo),
              recompute_instmap_delta_proc(yes, !ProcInfo, !ModuleInfo),
              module_info_set_pred_proc_info(PredId, ProcId,
@@ -1668,16 +1672,18 @@
  %-----------------------------------------------------------------------------%

  :- pred fix_calls_in_goal(hlds_goal::in, hlds_goal::out, prog_varset::in,
-    prog_varset::out, vartypes::in, vartypes::out, transform_map::in)
+    prog_varset::out, vartypes::in, vartypes::out,
+    rtti_varmaps::in, rtti_varmaps::out, transform_map::in)
      is det.

-fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, _TransformMap) :-
+fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, !_, _) :-
      Goal = call_foreign_proc(_, _, _, _, _, _, _).

-fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, _TransformMap) :-
+fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, !_, _) :-
      Goal = generic_call(_, _, _, _).

-fix_calls_in_goal(Goal0 - GoalInfo0, Goal, !VarSet, !VarTypes, TransformMap) :-
+fix_calls_in_goal(Goal0 - GoalInfo0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap) :-
      Goal0 = plain_call(CalledPredId0, CalledProcId0, Args0, Builtin,
          _Context, _SymName),
      (
@@ -1703,65 +1709,78 @@
          conj_list_to_goal([ConstructGoal, CallGoal], GoalInfo0, Goal1),
          RequantifyVars = set.from_list([CellVar | Args0]),
          implicitly_quantify_goal(RequantifyVars, _, Goal1, Goal,
-            !VarSet, !VarTypes)
+            !VarSet, !VarTypes, !RttiVarMaps)
      ;
          Goal = Goal0 - GoalInfo0
      ).

-fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, _TransformMap) :-
+fix_calls_in_goal(Goal - GoalInfo, Goal - GoalInfo, !_, !_, !_, _) :-
      Goal = unify(_, _, _, _, _).

  fix_calls_in_goal(negation(Goal0) - GoalInfo, negation(Goal) - GoalInfo,
-        !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, TransformMap).
+        !VarSet, !VarTypes, !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap).

  fix_calls_in_goal(scope(Reason, Goal0) - GoalInfo,
          scope(Reason, Goal) - GoalInfo,
-        !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, TransformMap).
+        !VarSet, !VarTypes, !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap).

  fix_calls_in_goal(conj(ConjType, Goals0) - GoalInfo,
-        conj(ConjType, Goals) - GoalInfo, !VarSet, !VarTypes, TransformMap) :-
+        conj(ConjType, Goals) - GoalInfo, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap) :-
      (
          ConjType = plain_conj,
-        fix_calls_in_conj(Goals0, Goals, !VarSet, !VarTypes, TransformMap)
+        fix_calls_in_conj(Goals0, Goals, !VarSet, !VarTypes, !RttiVarMaps,
+            TransformMap)
      ;
          ConjType = parallel_conj,
          % XXX: I am not sure whether parallel conjunctions should be treated
          % with fix_calls_in_goal or fix_calls_in_goal_list.  At any rate,
          % this is untested.
-        fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes, TransformMap)
+        fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes,
+            !RttiVarMaps, TransformMap)
      ).

  fix_calls_in_goal(disj(Goals0) - GoalInfo, disj(Goals) - GoalInfo,
-        !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes, TransformMap).
+        !VarSet, !VarTypes, !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes,
+        !RttiVarMaps, TransformMap).

  fix_calls_in_goal(switch(Var, CanFail, Cases0) - GoalInfo,
          switch(Var, CanFail, Cases) - GoalInfo,
-        !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_cases(Cases0, Cases, !VarSet, !VarTypes, TransformMap).
+        !VarSet, !VarTypes, !RttiVarMaps, TransformMap) :-
+    fix_calls_in_cases(Cases0, Cases, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap).

  fix_calls_in_goal(if_then_else(Vars, Cond0, Then0, Else0) - GoalInfo,
          if_then_else(Vars, Cond, Then, Else) - GoalInfo,
-        !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_goal(Cond0, Cond, !VarSet, !VarTypes, TransformMap),
-    fix_calls_in_goal(Then0, Then, !VarSet, !VarTypes, TransformMap),
-    fix_calls_in_goal(Else0, Else, !VarSet, !VarTypes, TransformMap).
+        !VarSet, !VarTypes, !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal(Cond0, Cond, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
+    fix_calls_in_goal(Then0, Then, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
+    fix_calls_in_goal(Else0, Else, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap).

-fix_calls_in_goal(shorthand(_) - _, _, !VarSet, !VarTypes, _TransformMap) :-
+fix_calls_in_goal(shorthand(_) - _, _, _, _, _, _, _, _, _) :-
      unexpected(this_file, "fix_calls_in_goal: unexpected shorthand").

  %-----------------------------------------------------------------------------%

  :- pred fix_calls_in_conj(hlds_goals::in, hlds_goals::out,
      prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
-    transform_map::in) is det.
+    rtti_varmaps::in, rtti_varmaps::out, transform_map::in) is det.

-fix_calls_in_conj([], [], !VarSet, !VarTypes, _).
-fix_calls_in_conj([Goal0 | Goals0], Goals, !VarSet, !VarTypes, TransformMap) :-
-    fix_calls_in_goal(Goal0, Goal1, !VarSet, !VarTypes, TransformMap),
-    fix_calls_in_conj(Goals0, Goals1, !VarSet, !VarTypes, TransformMap),
+fix_calls_in_conj([], [], !VarSet, !VarTypes, !RttiVarMaps, _).
+fix_calls_in_conj([Goal0 | Goals0], Goals, !VarSet, !VarTypes, 
+        !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal(Goal0, Goal1, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
+    fix_calls_in_conj(Goals0, Goals1, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
      ( Goal1 = conj(plain_conj, ConjGoals) - _ ->
          Goals = ConjGoals ++ Goals1
      ;
@@ -1770,25 +1789,29 @@

  :- pred fix_calls_in_goal_list(hlds_goals::in, hlds_goals::out,
      prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
-    transform_map::in) is det.
+    rtti_varmaps::in, rtti_varmaps::out, transform_map::in) is det.

-fix_calls_in_goal_list([], [], !VarSet, !VarTypes, _TransformMap).
+fix_calls_in_goal_list([], [], !VarSet, !VarTypes, !RttiVarMaps, _).
  fix_calls_in_goal_list([Goal0 | Goals0], [Goal | Goals], !VarSet, !VarTypes,
-        TransformMap) :-
-    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, TransformMap),
-    fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes, TransformMap).
+        !RttiVarMaps, TransformMap) :-
+    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
+    fix_calls_in_goal_list(Goals0, Goals, !VarSet, !VarTypes,
+        !RttiVarMaps, TransformMap).

  :- pred fix_calls_in_cases(list(case)::in, list(case)::out,
      prog_varset::in, prog_varset::out, vartypes::in, vartypes::out,
-    transform_map::in) is det.
+    rtti_varmaps::in, rtti_varmaps::out, transform_map::in) is det.

-fix_calls_in_cases([], [], !VarSet, !VarTypes, _TransformMap).
+fix_calls_in_cases([], [], !VarSet, !VarTypes, !RttiVarMaps, _).
  fix_calls_in_cases([Case0 | Cases0], [Case | Cases], !VarSet, !VarTypes,
-        TransformMap) :-
+        !RttiVarMaps, TransformMap) :-
      Case0 = case(Functor, Goal0),
-    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, TransformMap),
+    fix_calls_in_goal(Goal0, Goal, !VarSet, !VarTypes, !RttiVarMaps,
+        TransformMap),
      Case = case(Functor, Goal),
-    fix_calls_in_cases(Cases0, Cases, !VarSet, !VarTypes, TransformMap).
+    fix_calls_in_cases(Cases0, Cases, !VarSet, !VarTypes,
+        !RttiVarMaps, TransformMap).

  %-----------------------------------------------------------------------------%

Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.168
diff -u -r1.168 unify_proc.m
--- compiler/unify_proc.m	31 Jul 2006 08:32:10 -0000	1.168
+++ compiler/unify_proc.m	3 Aug 2006 06:49:13 -0000
@@ -1204,10 +1204,12 @@
  quantify_clause_body(HeadVars, Goal0, Context, Clause, !Info) :-
      info_get_varset(!.Info, Varset0),
      info_get_types(!.Info, Types0),
+    info_get_rtti_varmaps(!.Info, RttiVarMaps0),
      implicitly_quantify_clause_body(HeadVars, _Warnings, Goal0, Goal,
-        Varset0, Varset, Types0, Types),
+        Varset0, Varset, Types0, Types, RttiVarMaps0, RttiVarMaps),
      info_set_varset(Varset, !Info),
      info_set_types(Types, !Info),
+    info_set_rtti_varmaps(RttiVarMaps, !Info),
      Clause = clause([], Goal, mercury, Context).

  %-----------------------------------------------------------------------------%
@@ -1980,6 +1982,8 @@
      unify_proc_info::in, unify_proc_info::out) is det.
  :- pred info_set_types(vartypes::in,
      unify_proc_info::in, unify_proc_info::out) is det.
+:- pred info_set_rtti_varmaps(rtti_varmaps::in,
+    unify_proc_info::in, unify_proc_info::out) is det.

  %-----------------------------------------------------------------------------%

@@ -2018,6 +2022,7 @@

  info_set_varset(VarSet, UPI, UPI ^ varset := VarSet).
  info_set_types(Types, UPI, UPI ^ vartypes := Types).
+info_set_rtti_varmaps(RttiVarMaps, UPI, UPI ^ rtti_varmaps := RttiVarMaps).

  %-----------------------------------------------------------------------------%

Index: compiler/unneeded_code.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unneeded_code.m,v
retrieving revision 1.35
diff -u -r1.35 unneeded_code.m
--- compiler/unneeded_code.m	31 Jul 2006 08:32:10 -0000	1.35
+++ compiler/unneeded_code.m	3 Aug 2006 08:12:51 -0000
@@ -243,11 +243,13 @@
      proc_info_get_goal(!.ProcInfo, Goal0),
      proc_info_get_varset(!.ProcInfo, Varset0),
      proc_info_get_vartypes(!.ProcInfo, VarTypes0),
+    proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
      implicitly_quantify_clause_body(HeadVars, _Warnings, Goal0, Goal,
-        Varset0, Varset, VarTypes0, VarTypes),
+        Varset0, Varset, VarTypes0, VarTypes, RttiVarMaps0, RttiVarMaps),
      proc_info_set_goal(Goal, !ProcInfo),
      proc_info_set_varset(Varset, !ProcInfo),
-    proc_info_set_vartypes(VarTypes, !ProcInfo).
+    proc_info_set_vartypes(VarTypes, !ProcInfo),
+    proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo).

  % The source-to-source transform operates in two phases.
  %
@@ -296,10 +298,9 @@
      instmap.apply_instmap_delta(InitInstMap, InstMapDelta, FinalInstMap),
      proc_info_instantiated_head_vars(!.ModuleInfo, !.ProcInfo, NeededVarsList),
      map.init(WhereNeededMap0),
-    NeededEverywhere =
-        (pred(Var::in, NeededMap0::in, NeededMap::out) is det :-
-            map.det_insert(NeededMap0, Var, everywhere, NeededMap)
-        ),
+    NeededEverywhere = (pred(Var::in, NeededMap0::in, NeededMap::out) is det :-
+        map.det_insert(NeededMap0, Var, everywhere, NeededMap)
+    ),
      list.foldl(NeededEverywhere, NeededVarsList,
          WhereNeededMap0, WhereNeededMap1),
      module_info_get_globals(!.ModuleInfo, Globals),
@@ -319,13 +320,16 @@
              % the nonlocal vars and the non-atomic instmap deltas.
          proc_info_get_headvars(!.ProcInfo, HeadVars),
          proc_info_get_inst_varset(!.ProcInfo, InstVarSet),
+        proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
          implicitly_quantify_clause_body(HeadVars, _Warnings,
-            Goal2, Goal3, Varset0, Varset, VarTypes0, VarTypes),
+            Goal2, Goal3, Varset0, Varset, VarTypes0, VarTypes,
+            RttiVarMaps0, RttiVarMaps),
          recompute_instmap_delta(no, Goal3, Goal, VarTypes, InstVarSet,
              InitInstMap, !ModuleInfo),
          proc_info_set_goal(Goal, !ProcInfo),
          proc_info_set_varset(Varset, !ProcInfo),
          proc_info_set_vartypes(VarTypes, !ProcInfo),
+        proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo),
          process_proc(!ProcInfo, !ModuleInfo, _),
          Successful = yes
      ;
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.130
diff -u -r1.130 unused_args.m
--- compiler/unused_args.m	31 Jul 2006 08:32:11 -0000	1.130
+++ compiler/unused_args.m	3 Aug 2006 08:15:31 -0000
@@ -1219,15 +1219,17 @@
      % The varset should probably be fixed up, but it shouldn't make
      % too much difference.
      proc_info_get_varset(!.OldProc, VarSet0),
+    proc_info_get_rtti_varmaps(!.OldProc, RttiVarMaps0),
      remove_listof_elements(1, UnusedArgs, HeadVars, NewHeadVars),
      GoalExpr = plain_call(NewPredId, NewProcId, NewHeadVars,
          not_builtin, no, qualified(PredModule, PredName)),
      Goal1 = GoalExpr - GoalInfo1,
      implicitly_quantify_goal(NonLocals, _, Goal1, Goal, VarSet0, VarSet,
-        VarTypes1, VarTypes),
+        VarTypes1, VarTypes, RttiVarMaps0, RttiVarMaps),
      proc_info_set_goal(Goal, !OldProc),
      proc_info_set_varset(VarSet, !OldProc),
-    proc_info_set_vartypes(VarTypes, !OldProc).
+    proc_info_set_vartypes(VarTypes, !OldProc),
+    proc_info_set_rtti_varmaps(RttiVarMaps, !OldProc).

      % Create a pred_info for an imported pred with a pragma unused_args
      % in the .opt file.
@@ -1387,11 +1389,14 @@
              Changed = yes,
              % If anything has changed, rerun quantification.
              set.list_to_set(HeadVars, NonLocals),
+            proc_info_get_rtti_varmaps(!.ProcInfo, RttiVarMaps0),
              implicitly_quantify_goal(NonLocals, _, !Goal,
-                VarSet1, VarSet, VarTypes1, VarTypes),
+                VarSet1, VarSet, VarTypes1, VarTypes,
+                RttiVarMaps0, RttiVarMaps),
              proc_info_set_goal(!.Goal, !ProcInfo),
              proc_info_set_varset(VarSet, !ProcInfo),
-            proc_info_set_vartypes(VarTypes, !ProcInfo)
+            proc_info_set_vartypes(VarTypes, !ProcInfo),
+            proc_info_set_rtti_varmaps(RttiVarMaps, !ProcInfo)
          ;
              Changed = no
          ),
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.177
diff -u -r1.177 Mmakefile
--- tests/valid/Mmakefile	29 Jul 2006 12:28:28 -0000	1.177
+++ tests/valid/Mmakefile	4 Aug 2006 05:24:31 -0000
@@ -87,6 +87,7 @@
  	func_default_modes \
  	func_in_head \
  	func_int_bug_main \
+	hawkins_switch_bug \
  	headvar_not_found \
  	higher_order \
  	higher_order2 \
Index: tests/valid/hawkins_switch_bug.m
===================================================================
RCS file: tests/valid/hawkins_switch_bug.m
diff -N tests/valid/hawkins_switch_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/hawkins_switch_bug.m	4 Aug 2006 05:26:15 -0000
@@ -0,0 +1,41 @@
+% The predicate foo caused the following assertion failure in 
+% rotd-2006-08-03:
+%
+% Uncaught Mercury exception:
+% Software Error: equiv_type_hlds.m: Unexpected: replace_in_goal_expr:
+% info not found
+%
+% The problem was that when switch detection copied the bodies of the
+% arms for Kind = b and Kind = c, it requantified the goals.  The
+% requantification introduced some new variables but the entries in the
+% RTTI varmaps were not updated at the same time.  The fix was to make
+% sure that when quantification might introduce new variables, the RTTI
+% varmaps are updated.
+%
+% The following test case was supplied by Peter Hawkins.
+
+:- module hawkins_switch_bug.
+:- interface.
+
+:- import_module int.
+:- import_module map.
+:- import_module set.
+
+:- type kind ---> a ; b ; c.
+:- pred foo(kind::in, map(int, set(int))::in) is det.
+
+:- implementation.
+
+foo(Kind, B) :-
+    (
+        Kind = a
+    ;
+        ( Kind = b
+        ; Kind = c
+        ),
+        ( if map.search(B, 0, PDeps0) then
+            _PDeps = PDeps0
+          else
+            _PDeps = set.init : set(int)
+        )
+    ).

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