[m-rev.] diff: misc cleanups of program representation code

Zoltan Somogyi zs at csse.unimelb.edu.au
Fri Sep 26 18:30:08 AEST 2008


Cleanups of code I read as part of reviewing Paul's last change. This is not
the post-commit review itself.

deep_profiler/program_representation_utils.m:
	Convert a couple of semidet predicates into functions returning bool,
	so we could check that every case is covered.

	Fix departures from our style guide.

	Add XXXs for unclear documentation.

deep_profiler/report.m:
	Add some documentation.

mdbcomp/program_representation.m:
	Add a utility function.

Zoltan.

cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
Index: deep_profiler/program_representation_utils.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/program_representation_utils.m,v
retrieving revision 1.5
diff -u -b -r1.5 program_representation_utils.m
--- deep_profiler/program_representation_utils.m	25 Sep 2008 13:44:50 -0000	1.5
+++ deep_profiler/program_representation_utils.m	26 Sep 2008 08:29:05 -0000
@@ -12,7 +12,7 @@
 % Utilities for working with the program representation structures in the
 % mdbcomp library.  This file is not part of the mdbcomp library, since it
 % contains routines only used by the deep profiling tools.  Code here should be
-% moved into the mdbcomp.program_representation.m module if it's to be used by
+% moved into the mdbcomp.program_representation.m module if it is to be used by
 % other tools.
 %
 %-----------------------------------------------------------------------------%
@@ -33,17 +33,16 @@
 
 %----------------------------------------------------------------------------%
 
-    % Ugly-print a module to a string representation.  A cord of strings is
-    % returned rather than a string, since this reduces the cost of string
-    % concatenations.
+    % Ugly-print a module to a string representation. We return a cord of
+    % strings is returned rather than a string, since this reduces the cost
+    % of string concatenations.
     %
 :- pred print_module_to_strings(module_rep::in, cord(string)::out) is det.
 
     % Print a procedure to a string representation.
     %
-:- pred print_proc_to_strings(proc_rep(GoalAnn), cord(string)) <=
-    (goal_annotation(GoalAnn)).
-:- mode print_proc_to_strings(in, out) is det.
+:- pred print_proc_to_strings(proc_rep(GoalAnn)::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
 
 %----------------------------------------------------------------------------%
 
@@ -52,7 +51,7 @@
             % above.
             %
         pred print_goal_annotation_to_strings(T::in, cord(string)::out) is det
-    ].
+].
 
     % A goal with no particular annotation has empty strings printed for goal
     % annotations.
@@ -61,7 +60,7 @@
 
 %----------------------------------------------------------------------------%
 
-    % Search a program representation for the given procedure and return it's
+    % Search a program representation for the given procedure and return its
     % procedure representation if found, otherwise fail.
     %
 :- pred progrep_search_proc(prog_rep::in, string_proc_label::in, proc_rep::out)
@@ -95,13 +94,21 @@
 
 print_module_to_strings(ModuleRep, Strings) :-
     ModuleRep = module_rep(ModuleName, _StringTable, ProcReps),
-    map.foldl((pred(_::in, Proc::in, Str0::in, Str::out) is det :-
-            print_proc_to_strings(Proc, Str1),
-            Str = Str0 ++ Str1
-        ), ProcReps, cord.empty, ProcStrings),
+    map.foldl(accumulate_print_proc_to_strings, ProcReps,
+        cord.empty, ProcStrings),
     Strings = cord.cons(string.format("Module %s\n", [s(ModuleName)]), 
         ProcStrings).
 
+    % Print a procedure to a string representation.
+    %
+:- pred accumulate_print_proc_to_strings(string_proc_label::in,
+    proc_rep(GoalAnn)::in, cord(string)::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
+
+accumulate_print_proc_to_strings(_, Proc, !Strings) :-
+    print_proc_to_strings(Proc, ProcStrings),
+    !:Strings = !.Strings ++ ProcStrings.
+
 print_proc_to_strings(ProcRep, Strings) :-
     ProcRep = proc_rep(ProcLabel, ProcDefnRep),
     ProcDefnRep = proc_defn_rep(ArgVarReps, GoalRep, VarTable, Detism),
@@ -138,9 +145,8 @@
 
 %-----------------------------------------------------------------------------%
 
-:- pred print_goal_to_strings(var_table, int, goal_rep(GoalAnn), cord(string))
-    <= goal_annotation(GoalAnn).
-:- mode print_goal_to_strings(in, in, in, out) is det.
+:- pred print_goal_to_strings(var_table::in, int::in, goal_rep(GoalAnn)::in,
+    cord(string)::out) is det <= goal_annotation(GoalAnn).
 
 print_goal_to_strings(VarTable, Indent, GoalRep, Strings) :-
     GoalRep = goal_rep(GoalExprRep, DetismRep, GoalAnnotation),
@@ -148,8 +154,7 @@
     print_goal_annotation_to_strings(GoalAnnotation, GoalAnnotationString),
     (
         GoalExprRep = conj_rep(ConjGoalReps),
-        print_conj_to_strings(VarTable, Indent, ConjGoalReps,
-            Strings)
+        print_conj_to_strings(VarTable, Indent, ConjGoalReps, Strings)
     ;
         GoalExprRep = disj_rep(DisjGoalReps),
         print_disj_to_strings(VarTable, Indent, DisjGoalReps, no, DisjString),
@@ -201,9 +206,9 @@
             DetismRep, AtomicGoalRep, Strings)
     ).
 
-:- pred print_conj_to_strings(var_table, int, list(goal_rep(GoalAnn)),
-    cord(string)) <= goal_annotation(GoalAnn).
-:- mode print_conj_to_strings(in, in, in, out) is det.
+:- pred print_conj_to_strings(var_table::in, int::in,
+    list(goal_rep(GoalAnn))::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
 
 print_conj_to_strings(VarTable, Indent, GoalReps, Strings) :-
     (
@@ -214,9 +219,9 @@
         print_conj_2_to_strings(VarTable, Indent, GoalReps, Strings)
     ).
 
-:- pred print_conj_2_to_strings(var_table, int, list(goal_rep(GoalAnn)), 
-    cord(string)) <= goal_annotation(GoalAnn).
-:- mode print_conj_2_to_strings(in, in, in, out) is det.
+:- pred print_conj_2_to_strings(var_table::in, int::in,
+    list(goal_rep(GoalAnn))::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
 
 print_conj_2_to_strings(_, _Indent, [], cord.empty).
 print_conj_2_to_strings(VarTable, Indent, [GoalRep | GoalReps], Strings) :-
@@ -229,12 +234,13 @@
     print_conj_2_to_strings(VarTable, Indent, GoalReps, ConjString),
     Strings = GoalString ++ ConjString.
 
-:- pred print_disj_to_strings(var_table, int, list(goal_rep(GoalAnn)), bool,
-    cord(string)) <= goal_annotation(GoalAnn).
-:- mode print_disj_to_strings(in, in, in, in, out) is det.
+:- pred print_disj_to_strings(var_table::in, int::in,
+    list(goal_rep(GoalAnn))::in, bool::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
 
 print_disj_to_strings(_, _Indent, [], _PrintSemi, cord.empty).
-print_disj_to_strings(VarTable, Indent, [GoalRep | GoalReps], PrintSemi, Strings) :-
+print_disj_to_strings(VarTable, Indent, [GoalRep | GoalReps], PrintSemi,
+        Strings) :-
     (
         PrintSemi = no,
         DelimString = cord.empty
@@ -246,12 +252,13 @@
     print_disj_to_strings(VarTable, Indent, GoalReps, yes, DisjString),
     Strings = DelimString ++ GoalString ++ DisjString.
 
-:- pred print_switch_to_strings(var_table, int, list(case_rep(GoalAnn)), bool,
-    cord(string)) <= goal_annotation(GoalAnn).
-:- mode print_switch_to_strings(in, in, in, in, out) is det.
+:- pred print_switch_to_strings(var_table::in, int::in,
+    list(case_rep(GoalAnn))::in, bool::in, cord(string)::out) is det
+    <= goal_annotation(GoalAnn).
 
 print_switch_to_strings(_, _Indent, [], _PrintSemi, cord.empty).
-print_switch_to_strings(VarTable, Indent, [CaseRep | CaseReps], PrintSemi, Strings) :-
+print_switch_to_strings(VarTable, Indent, [CaseRep | CaseReps], PrintSemi,
+        Strings) :-
     (
         PrintSemi = no,
         DelimString = cord.empty
@@ -392,7 +399,8 @@
 print_args_2_to_strings(_,        [],                 _,      cord.empty).
 print_args_2_to_strings(VarTable, [VarRep | VarReps], Prefix, Strings) :-
     lookup_var_name(VarTable, VarRep, VarName),
-    print_args_2_to_strings(VarTable, VarReps, cord.singleton(", "), ArgsString),
+    print_args_2_to_strings(VarTable, VarReps, cord.singleton(", "),
+        ArgsString),
     Strings = Prefix ++ cord.cons(VarName, ArgsString).
 
 :- pred print_maybe_args_to_strings(var_table::in, list(maybe(var_rep))::in, 
@@ -412,7 +420,8 @@
     cord(string)::in, cord(string)::out) is det.
 
 print_maybe_args_2_to_strings(_, [], _, cord.empty).
-print_maybe_args_2_to_strings(VarTable, [MaybeVarRep | MaybeVarReps], Prefix, Strings) :-
+print_maybe_args_2_to_strings(VarTable, [MaybeVarRep | MaybeVarReps], Prefix,
+        Strings) :-
     (
         MaybeVarRep = no,
         VarName = "_"
@@ -473,7 +482,7 @@
 
 :- instance goal_annotation(unit) where [
         pred(print_goal_annotation_to_strings/2) is print_unit_to_strings
-    ].
+].
 
 :- pred print_unit_to_strings(unit::in, cord(string)::out) is det.
 
@@ -532,15 +541,15 @@
         ;
             Coverage = coverage_known(Calls, Exits)
         ),
-        CoverageReference =
-            coverage_reference_info(CallSites, SolnsCoveragePoints, 
-                BranchCoveragePoints),
+        CoverageReference = coverage_reference_info(CallSites,
+            SolnsCoveragePoints, BranchCoveragePoints),
         goal_annotate_coverage(CoverageReference, empty_goal_path, Coverage, _,
             !GoalRep),
         !:ProcDefn = !.ProcDefn ^ pdr_goal := !.GoalRep,
         !:ProcRep = !.ProcRep ^ pr_defn := !.ProcDefn
     ).
 
+    % XXX with arbitrary what?
     % These maps are keyed by goal_path, which is a structure with arbitrary,
     % comparing these structures is less efficient than comparing simple
     % structures like the alternative goal_path_string, however, that involves
@@ -557,12 +566,14 @@
 
     % Try to get coverage information from:
     %   + Port counts if this is an atomic goal.
-    %   + A solution count from a coverage point after the goal
+    %   + A solution count from a coverage point after the goal.
     %   + If the goal is in a conjunction and it is not the first conjunct, try
     %     to get the solution count of the previous goal.
     %
     % This does not check for branch entry counts.
     %
+    % XXX I don't understand what exactly the above is trying to say. -zs
+    %
 :- pred get_coverage_information(coverage_reference_info::in,
     goal_expr_rep(T)::in, goal_path::in, detism_rep::in,
     coverage_info::in, coverage_info::out) is det.
@@ -584,14 +595,14 @@
     ->
         ( 
             map.search(Info ^ cri_call_sites, GoalPath, CallSite), 
-            % Callback call sites measure the port counts when mercury is
+            % Callback call sites measure the port counts when Mercury is
             % re-entered, not the number of calls made from this call site.
             CallSite ^ csf_kind \= callback_and_no_info
         ->
             Summary = CallSite ^ csf_summary_perf,
-            % Entry due to redo is not counted at the point before the
-            % goal, it's represented when the number of exists is greater
-            % than the number of calls,  This won't work with nondet code
+            % Entry due to redo is not counted at the point before the goal,
+            % it is represented when the number of exists is greater than
+            % the number of calls. XXX This won't work with nondet code,
             % which should be fixed in the future.
             Calls = Summary ^ perf_row_calls,
             Exits = Summary ^ perf_row_exits, 
@@ -679,15 +690,14 @@
     ),
     propagate_coverage(Detism, GoalPath, !Coverage),
     Goal = goal_rep(GoalExpr, Detism, !.Coverage),
-    trace [ compile_time(flag("debug_coverage_propagation")), io(!IO) ] (
+    trace [compile_time(flag("debug_coverage_propagation")), io(!IO)] (
         io.write_string("goal_annotate_coverage: done\n", !IO),
         io.format("\tGoalPath: %s\n\tDetism %s\n\tCoverage; %s\n", 
             [s(goal_path_to_string(GoalPath)), 
              s(string(Detism)), 
              s(string(!.Coverage))], !IO)
     ),
-    trace [ compile_time(not flag("no_coverage_propagation_assertions")) ]
-    (
+    trace [compile_time(not flag("no_coverage_propagation_assertions"))] (
         require(check_coverage_complete(!.Coverage, GoalExpr),
             string.format("check_coverage_complete failed\n" ++ 
                 "\tCoverage: %s\n\tGoalPath: %s\n",
@@ -720,7 +730,6 @@
     % The empty conjunction is equivalent to 'true' which is deterministic,
     ConjGoalPath = goal_path_add_at_end(GoalPath, step_conj(ConjunctNum)),
     propagate_det_coverage(ConjGoalPath, !Coverage).
-
 conj_annotate_coverage_2(Info, GoalPath, ConjunctNum, !Coverage, 
         [Conj0 | Conjs0], [Conj | Conjs]) :-
     split_coverage(!.Coverage, CoverageBefore0, CoverageAfter0),
@@ -763,7 +772,6 @@
     list(goal_rep)::in, list(goal_rep(coverage_info))::out) is det.
 
 disj_annotate_coverage_2(_, _, _, _, _, [], []).
-
 disj_annotate_coverage_2(Info, GoalPath, DisjNum, Solutions, CoverageBefore0,
         [Disj0 | Disjs0], [Disj | Disjs]) :-
     DisjGoalPath = goal_path_add_at_end(GoalPath, step_disj(DisjNum)),
@@ -818,13 +826,15 @@
         !:Coverage = SwitchCoverage
     ),
 
-    trace [ compile_time(flag("debug_coverage_propagation")), io(!IO) ]
-        io.format("Switch: Coverage0: %s\n", [s(string(Coverage0))], !IO),
-    trace [ compile_time(not flag("no_coverage_propagation_assertions")) ]
+    trace [compile_time(flag("debug_coverage_propagation")), io(!IO)] (
+        io.format("Switch: Coverage0: %s\n", [s(string(Coverage0))], !IO)
+    ),
+    trace [compile_time(not flag("no_coverage_propagation_assertions"))] (
         require(check_switch_coverage(CanFail, Cases, !.Coverage),
         string.format("check_switch_coverage failed\n\t" ++ 
                 "CanFail: %s\n\tCases: %s\n\tCoverage: %s\n",
-            [s(string(CanFail)), s(string(Cases)), s(string(!.Coverage))])).
+            [s(string(CanFail)), s(string(Cases)), s(string(!.Coverage))]))
+    ).
 
     % switch_annotate_coverage_2(Info, Detism, GoalPath, CaseNum, 
     %   !CoverageSum, SwitchCoverage, !Cases),
@@ -845,11 +855,9 @@
     list(case_rep(unit))::in, list(case_rep(coverage_info))::out) is det.
 
 switch_annotate_coverage_2(_, _, _, _, !CoverageSum, _, [], []).
-
-switch_annotate_coverage_2(Info, CanFail, GoalPath, CaseNum, 
-        !CoverageSum, SwitchCoverage, [ Case0 | Cases0 ], [ Case | Cases ]) :-
-    CaseGoalPath = goal_path_add_at_end(GoalPath, 
-        step_switch(CaseNum, no)),
+switch_annotate_coverage_2(Info, CanFail, GoalPath, CaseNum, !CoverageSum,
+        SwitchCoverage, [ Case0 | Cases0 ], [ Case | Cases ]) :-
+    CaseGoalPath = goal_path_add_at_end(GoalPath, step_switch(CaseNum, no)),
     
     % If this is the last case in the switch, then it's coverage information
     % may be computed from the coverage of other cases and the coverage of the
@@ -858,7 +866,6 @@
     %
     % If we can't calculate it's coverage information then try to retrieve the
     % information from a coverage point associated with the switch branch.
-    %
     (
         Cases0 = [],
         CanFail = switch_can_not_fail
@@ -955,9 +962,7 @@
     % Step 2:
     %   Lookup coverage information for the then and else goals.  Set the
     %   coverage before the then and else goals.
-    (
-        coverage_count_after(CondCoverage, CountAfterCond)
-    ->
+    ( coverage_count_after(CondCoverage, CountAfterCond) ->
         ThenCoverage0 = coverage_known_before(CountAfterCond)
     ;
         get_branch_coverage(Info, ThenGoalPath, ThenCoverage0)
@@ -1006,15 +1011,17 @@
     ),
     !:Coverage = merge_coverage(CoverageBefore, CoverageAfter),
 
-    trace [ compile_time(not flag("no_coverage_propagation_assertions")) ]
-    require(check_ite_coverage(!.Coverage, CondCoverage, ThenCoverage,
+    trace [compile_time(not flag("no_coverage_propagation_assertions"))] (
+        require(
+            check_ite_coverage(!.Coverage, CondCoverage, ThenCoverage,
             ElseCoverage, CondDetism), 
         string.format("check_ite_coverage/4 failed\n" ++ 
                 "\tWhole: %s\n\tCond: %s\n\tThen: %s\n\tElse: %s\n" ++ 
                 "\tGoalPath: %s\n",
             [s(string(!.Coverage)), s(string(CondCoverage)),
                 s(string(ThenCoverage)), s(string(ElseCoverage)),
-                s(goal_path_to_string(GoalPath))])).
+                    s(goal_path_to_string(GoalPath))]))
+    ).
 
 :- pred not_unify(T::in, T::in) is semidet.
 
@@ -1027,9 +1034,7 @@
     coverage_info::out(coverage_before)) is det.
 
 get_branch_coverage(Info, GoalPath, Coverage) :-
-    ( 
-        map.search(Info ^ cri_branch_coverage_points, GoalPath, CP)
-    ->
+    ( map.search(Info ^ cri_branch_coverage_points, GoalPath, CP) ->
         CP = coverage_point(Count, _, _),
         Coverage = coverage_known_before(Count)
     ;
@@ -1058,9 +1063,10 @@
         CoverageBefore = CoverageBefore2
     ),
     Coverage = merge_coverage(CoverageBefore, CoverageAfter0),
-    trace [compile_time(flag("debug_coverage_propagation")), io(!IO) ]
+    trace [compile_time(flag("debug_coverage_propagation")), io(!IO)] (
         io.format("Negation: setting negation coverage: %s\n",
-            [s(string(Coverage))], !IO).
+            [s(string(Coverage))], !IO)
+    ).
         
 :- pred scope_annotate_coverage(coverage_reference_info::in, goal_path::in,
     maybe_cut::in, coverage_info::in, coverage_info::out,
@@ -1116,51 +1122,105 @@
     is semidet.
 
 check_coverage_regarding_detism(Coverage, Detism) :-
+    detism_coverage_ok(Coverage, Detism) = yes.
+
+:- func detism_coverage_ok(coverage_info, detism_rep) = bool.
+
+detism_coverage_ok(Coverage, Detism) = OK :-
+    (
     ( Detism = det_rep
     ; Detism = cc_multidet_rep
     ),
-    ( Coverage = coverage_known(Count, Count)
-    ; Coverage = coverage_known_det(_)
+        (
+            ( Coverage = coverage_known_det(_)
     ; Coverage = coverage_unknown
-    ).
-check_coverage_regarding_detism(Coverage, Detism) :-
+            ),
+            OK = yes
+        ;
+            Coverage = coverage_known(Entry, Exit),
+            ( Entry = Exit ->
+                OK = yes
+            ;
+                OK = no
+            )
+        ;
+            ( Coverage = coverage_known_before(_)
+            ; Coverage = coverage_known_after(_)
+            ),
+            % If you known coverage at one of these points, you can compute
+            % the coverage at the other point.
+            OK = no
+        )
+    ;
     ( Detism = semidet_rep
     ; Detism = cc_nondet_rep
     ),
     (
-        Coverage = coverage_known(Entry, Exit),
-        Entry >= Exit
-    ; Coverage = coverage_known_before(_)
+            ( Coverage = coverage_known_before(_)
     ; Coverage = coverage_known_after(_)
     ; Coverage = coverage_known_det(_)
     ; Coverage = coverage_unknown
-    ).
-check_coverage_regarding_detism(Coverage, multidet_rep) :-
-    (
+            ),
+            OK = yes
+        ;
         Coverage = coverage_known(Entry, Exit),
-        Entry =< Exit
-    ; Coverage = coverage_known_before(_)
+            ( Entry >= Exit ->
+                OK = yes
+            ;
+                OK = no
+            )
+        )
+    ;
+        Detism = multidet_rep,
+        (
+            ( Coverage = coverage_known_before(_)
     ; Coverage = coverage_known_after(_)
     ; Coverage = coverage_known_det(_)
     ; Coverage = coverage_unknown
-    ).
-check_coverage_regarding_detism(Coverage, Detism) :-
+            ),
+            OK = yes
+        ;
+            Coverage = coverage_known(Entry, Exit),
+            ( Entry =< Exit ->
+                OK = yes
+            ;
+                OK = no
+            )
+        )
+    ;
+        Detism = nondet_rep,
+        OK = yes
+    ;
     ( Detism = erroneous_rep
     ; Detism = failure_rep
     ),
-    ( Coverage = coverage_known(_, 0)
-    % This probably wont occur, but might
-    ; Coverage = coverage_known_det(0)
-    ; Coverage = coverage_known_before(_)
-    ; Coverage = coverage_known_after(0)
-    % This shouldn't occur, we should infer at least coverage_known_after(0)
-    ; Coverage = coverage_unknown
+        (
+            % The coverage_known_dert case probably won't occur, but it might.
+            ( Coverage = coverage_known(_, Exit)
+            ; Coverage = coverage_known_det(Exit)
+            ; Coverage = coverage_known_after(Exit)
+            ),
+            ( Exit = 0 ->
+                OK = yes
+            ;
+                OK = no
+            )
+        ;
+            Coverage = coverage_known_before(_),
+            OK = yes
+        ;
+            Coverage = coverage_unknown,
+            % This shouldn't occur, we should infer at least
+            % coverage_known_after(0).
+            OK = yes
+        )
     ).
-check_coverage_regarding_detism(_Coverage, nondet_rep).
 
     % Check that the coverages over the switch make sense.  This works only for
     % deterministic switches.
     % 
+    % XXX What does "make sense" mean?
+    %
 :- pred check_switch_coverage(switch_can_fail_rep::in,
     list(case_rep(coverage_info))::in, coverage_info::in) is semidet.
 
@@ -1268,48 +1328,57 @@
 %    ),
 %    goal_expr_is_trivial(GoalExpr).
 
-:- pred goal_is_trivial(goal_rep(T)::in) is semidet.
+:- func goal_is_trivial(goal_rep(T)) = bool.
 
-goal_is_trivial(Goal) :-
+goal_is_trivial(Goal) = IsTrivial:-
     GoalExpr = Goal ^ goal_expr_rep,
-    goal_expr_is_trivial(GoalExpr).
-
-:- pred goal_expr_is_trivial(goal_expr_rep(T)::in) is semidet.
+    IsTrivial = goal_expr_is_trivial(GoalExpr).
 
-goal_expr_is_trivial(conj_rep(Conjs)) :-
-    list.all_true(goal_is_trivial, Conjs). 
+:- func goal_expr_is_trivial(goal_expr_rep(T)) = bool.
 
-goal_expr_is_trivial(disj_rep(Disjs)) :-
-    list.all_true(goal_is_trivial, Disjs).
-
-goal_expr_is_trivial(switch_rep(_, _, Cases)) :-
-    list.all_true((pred(Case::in) is semidet :-
-        Case = case_rep(_, _, Goal),
-        goal_is_trivial(Goal)), Cases).
-
-goal_expr_is_trivial(ite_rep(Cond, Then, Else)) :-
-    goal_is_trivial(Cond),
-    goal_is_trivial(Then),
-    goal_is_trivial(Else).
-
-goal_expr_is_trivial(negation_rep(SubGoal)) :-
-    goal_is_trivial(SubGoal).
-
-goal_expr_is_trivial(scope_rep(SubGoal, _)) :-
-    goal_is_trivial(SubGoal).
-
-goal_expr_is_trivial(atomic_goal_rep(_, _, _, AtomicGoal)) :-
-    ( AtomicGoal = unify_construct_rep(_, _, _)
-    ; AtomicGoal = unify_deconstruct_rep(_, _, _)
-    ; AtomicGoal = partial_deconstruct_rep(_, _, _)
-    ; AtomicGoal = partial_construct_rep(_, _, _)
-    ; AtomicGoal = unify_assign_rep(_, _)
-    ; AtomicGoal = cast_rep(_, _)
-    ; AtomicGoal = unify_simple_test_rep(_, _)
-    % Built-in calls are probably cheap enough to consider to be trivial.
-    ; AtomicGoal = builtin_call_rep(_, _, _)
-    ; AtomicGoal = pragma_foreign_code_rep(_)
-    ; AtomicGoal = event_call_rep(_, _) 
+goal_expr_is_trivial(GoalRep) = IsTrivial :-
+    (
+        (
+            GoalRep = conj_rep(SubGoalReps)
+        ;
+            GoalRep = disj_rep(SubGoalReps)
+        ;
+            GoalRep = switch_rep(_, _, CaseReps),
+            SubGoalReps = list.map(project_case_rep_goal, CaseReps)
+        ;
+            GoalRep = ite_rep(CondRep, ThenRep, ElseRep),
+            SubGoalReps = [CondRep, ThenRep, ElseRep]
+        ),
+        SubGoalIsTrivials = list.map(goal_is_trivial, SubGoalReps),
+        bool.and_list(SubGoalIsTrivials, IsTrivial)
+    ;
+        ( GoalRep = negation_rep(SubGoalRep)
+        ; GoalRep = scope_rep(SubGoalRep, _)
+        ),
+        IsTrivial = goal_is_trivial(SubGoalRep)
+    ;
+        GoalRep = atomic_goal_rep(_, _, _, AtomicGoalRep),
+        (
+            ( AtomicGoalRep = plain_call_rep(_, _, _)
+            ; AtomicGoalRep = higher_order_call_rep(_, _)
+            ; AtomicGoalRep = method_call_rep(_, _, _)
+            ),
+            IsTrivial = no
+        ;
+            ( AtomicGoalRep = unify_construct_rep(_, _, _)
+            ; AtomicGoalRep = unify_deconstruct_rep(_, _, _)
+            ; AtomicGoalRep = partial_deconstruct_rep(_, _, _)
+            ; AtomicGoalRep = partial_construct_rep(_, _, _)
+            ; AtomicGoalRep = unify_assign_rep(_, _)
+            ; AtomicGoalRep = cast_rep(_, _)
+            ; AtomicGoalRep = unify_simple_test_rep(_, _)
+            % Built-in calls are cheap enough to consider to be trivial.
+            ; AtomicGoalRep = builtin_call_rep(_, _, _)
+            ; AtomicGoalRep = pragma_foreign_code_rep(_)
+            ; AtomicGoalRep = event_call_rep(_, _)
+            ),
+            IsTrivial = yes
+        )
     ).
 
 %----------------------------------------------------------------------------%
@@ -1334,6 +1403,7 @@
 coverage_count_after(coverage_known_det(Count), Count).
 
     % The coverage before a det goal should always equal the coverage after.
+    %
 :- pred propagate_det_coverage(goal_path::in, 
     coverage_info::in, coverage_info::out) is det.
 
@@ -1344,10 +1414,12 @@
         !.Coverage = coverage_known_det(_)
     ;
         !.Coverage = coverage_known(Before, After),
-        trace [compile_time(not flag("no_coverage_propagation_assertions"))]
+        trace [compile_time(not flag("no_coverage_propagation_assertions"))] (
             require(unify(Before, After), 
                 format("Coverage before /= after for a det goal: %s, GP: %s",
-                    [s(string(!.Coverage)), s(goal_path_to_string(GoalPath))])),
+                    [s(string(!.Coverage)),
+                    s(goal_path_to_string(GoalPath))]))
+        ),
             !:Coverage = coverage_known_det(Before)
         ;
         ( !.Coverage = coverage_known_before(Coverage)
@@ -1371,7 +1443,8 @@
     % to calculate coverage for trivial goals.
     (
         ( Detism = det_rep
-        ; Detism = cc_multidet_rep ),
+        ; Detism = cc_multidet_rep
+        ),
         propagate_det_coverage(GoalPath, !Coverage)
     ;
         Detism = semidet_rep
Index: deep_profiler/report.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/report.m,v
retrieving revision 1.10
diff -u -b -r1.10 report.m
--- deep_profiler/report.m	25 Sep 2008 03:47:03 -0000	1.10
+++ deep_profiler/report.m	26 Sep 2008 07:48:18 -0000
@@ -210,10 +210,12 @@
     ;       coverage_known_det(int)
                 % Coverage is known both before and after the goal, and the
                 % coverage is the same before as it is after.
-
     ;       coverage_known(int, int)
+            % Coverage is known both before and after the goal.
     ;       coverage_known_before(int)
+            % Coverage is known only before the goal.
     ;       coverage_known_after(int).
+            % Coverage is known only before after goal.
 
 :- type proc_callers_report
     --->    proc_callers_report(
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_glut
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/posix/samples
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
Index: mdbcomp/program_representation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/mdbcomp/program_representation.m,v
retrieving revision 1.39
diff -u -b -r1.39 program_representation.m
--- mdbcomp/program_representation.m	21 Sep 2008 12:05:06 -0000	1.39
+++ mdbcomp/program_representation.m	26 Sep 2008 08:13:53 -0000
@@ -163,40 +163,36 @@
 
 :- type goal_expr_rep(GoalAnnotation)
     --->    conj_rep(
-                list(goal_rep(GoalAnnotation))
                     % The conjuncts in the original order.
+                list(goal_rep(GoalAnnotation))
             )
     ;       disj_rep(
-                list(goal_rep(GoalAnnotation))
                     % The disjuncts in the original order.
+                list(goal_rep(GoalAnnotation))
             )
     ;       switch_rep(
-                var_rep,            
                     % The variable being switched on.
+                var_rep,
                 
-                switch_can_fail_rep,
                     % Completeness of the switch.
+                switch_can_fail_rep,
 
-                list(case_rep(GoalAnnotation))
                     % The switch arms in the original order.
+                list(case_rep(GoalAnnotation))
             )
     ;       ite_rep(
+                % The condition, the then branch and the else branch.
                 goal_rep(GoalAnnotation),
-                    % Condition.
-                
                 goal_rep(GoalAnnotation),
-                    % Then branch.
-                
                 goal_rep(GoalAnnotation)
-                    % Else branch.
             )
     ;       negation_rep(
-                goal_rep(GoalAnnotation)
                     % The negated goal.
+                goal_rep(GoalAnnotation)
             )
     ;       scope_rep(
-                goal_rep(GoalAnnotation),
                     % The quantified goal.
+                goal_rep(GoalAnnotation),
                 
                 maybe_cut
             )
@@ -210,20 +206,23 @@
 
 :- type case_rep(GoalAnnotation)
     --->    case_rep(
-                cons_id_arity_rep,  
                     % The name and arity of the first function symbol for which
                     % this switch arm is applicable.
+                cr_main_cons_id     :: cons_id_arity_rep,
                 
-                list(cons_id_arity_rep),
                     % The names and arities of any other function symbols for
                     % this switch arm.
+                cr_other_cons_ids   :: list(cons_id_arity_rep),
                 
-                goal_rep(GoalAnnotation)
                     % The code of the switch arm.
+                cr_case_goal        :: goal_rep(GoalAnnotation)
             ).
 
 :- type case_rep == case_rep(unit).
 
+:- func project_case_rep_goal(case_rep(GoalAnnotation)) =
+    goal_rep(GoalAnnotation).
+
 :- type switch_can_fail_rep
     --->    switch_can_fail
     ;       switch_can_not_fail.
@@ -617,13 +616,14 @@
 
 :- type coverage_point_info
     --->    coverage_point_info(
-                goal_path,
-                    % Identifies the goal that this coverage point is near.  If
-                    % cp_type is cp_type_branch_arm the coverage point is
+                % Identifies the goal that this coverage point is near.
+                % If cp_type is cp_type_branch_arm, the coverage point is
                     % immediately before this goal, otherwise it is immediately
                     % after.
-                cp_type
+                goal_path,
+
                     % The type of this coverage point.
+                cp_type
             ).
 
 % This enumeration specifies the type of coverage point.  A branch arm is an
@@ -633,7 +633,6 @@
     --->    cp_type_coverage_after
     ;       cp_type_branch_arm.
 
-
     % Gives the value in C for this coverage point type.
     %
 :- pred coverage_point_type_c_value(cp_type::in, string::out) is det.
@@ -919,6 +918,10 @@
 
 %-----------------------------------------------------------------------------%
 
+project_case_rep_goal(Case) = Case ^ cr_case_goal.
+
+%-----------------------------------------------------------------------------%
+
 var_num_rep_byte(byte, 0).
 var_num_rep_byte(short, 1).
 
@@ -1383,7 +1386,8 @@
     ).
 
 :- pred read_cases(var_num_rep::in, bytecode::in, string_table::in,
-    read_proc_rep_info::in, list(case_rep(unit))::out, int::in, int::out) is semidet.
+    read_proc_rep_info::in, list(case_rep(unit))::out, int::in, int::out)
+    is semidet.
 
 read_cases(VarNumRep, ByteCode, StringTable, Info, Cases, !Pos) :-
     read_length(ByteCode, Len, !Pos),
@@ -1703,7 +1707,6 @@
     }
 ").
 
-
 %-----------------------------------------------------------------------------%
 
 %
@@ -1713,7 +1716,8 @@
 
 coverage_point_type_c_value(cp_type_coverage_after, 
     "MR_cp_type_coverage_after").
-coverage_point_type_c_value(cp_type_branch_arm, "MR_cp_type_branch_arm").
+coverage_point_type_c_value(cp_type_branch_arm,
+    "MR_cp_type_branch_arm").
 
 :- pragma foreign_enum("C", cp_type/0,
     [
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/standalone_c
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
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