[m-rev.] For post-commit review: Start using the new dynamic coverage information in the deep profiler.

Paul Bone pbone at csse.unimelb.edu.au
Wed Sep 22 22:53:05 AEST 2010


For post-commit review by Zoltan.

---

Start using the new dynamic coverage information in the deep profiler.

This patch separates the coverage annotated procedure report into two
reports, one with dynamic coverage data and one with static coverage data.
This restores the functionality of the static coverage report since my last
change, and provides access to the dynamic report via new controls only
visible to developers.

deep_profiler/query.m:
    In the cmd data-type:

        Rename deep_cmd_procrep_coverage constructor to
        deep_cmd_static_procrep_coverage.

        Add deep_cmd_procrep_dynamic_coverage.

    In the preferences data-type:

        Add a new field pref_developer_mode which indicates if developer-only
        options are visible or not.

    Add code to parse and print the new command and preference option.

deep_profiler/create_report.m:
    Specialise create_procrep_coverage_report/3 into
    create_{static,dynamic}_coverage_report/4.

    Created a new exported function deep_get_maybe_procrep.  This is useful for
    getting a procedure representation from the deep data-structure in one
    step.

deep_profiler/display.m:
    Add a new display item, display_developer.  This wraps another display
    item but is only displayed when developer mode is active.

deep_profiler/display_report.m:
    Add a control to the main screen that enables or disabled developer mode.
    This control has been placed at the bottom of the screen so that it's out
    of the way.

    Put the developer controls on the main screen into their own list (there's
    only one at the moment).

    For now the coverage-annotated procedure representation link on a (static)
    procedure's page is not a developer option.  Should this be a developer
    option?

    Added a link to the dynamic coverage annotated procedure representation
    report from the dump proc dynamic report.

    Added a link to the clique dump report from the clique report, the dynamic
    coverage annotated procedure representation report can be accessed
    transitively through this link.
    
    Added a link the variable use analysis report and proc static report to the
    procedure report and static coverage annotated procedure representation
    report.

deep_profiler/html_format.m:
    Support the new display_developer item.

    Refactor the item_to_html code for lists.

deep_profiler/profile.m:
    Include a new field in the deep data-structure for storing coverage data
    that is indexed by a proc_static_ptr.  When dynamic coverage information is
    used this field is populated by adding per ProcDynamic data for each static
    procedure.

deep_profiler/startup.m:
    Fill in the per ProcStatic coverage data when the deep profiler starts up.

deep_profiler/measurements.m:
    Create a new data type static_coverage_info which represents per ProcStatic
    coverage information.
    
    Include functions that are used when calculating per ProcStatic coverage
    information from per ProcDynamic coverage information.

deep_profiler/mdprof_cgi.m:
    Remove rarely used command line option rather making it conform to changes
    in query.m.

deep_profiler/old_html_format.m:
deep_profiler/old_query.m:
    Conform to changes in query.m.

deep_profiler/mdprof_test.m:
deep_profiler/mdprof_fb.automatic_parallelism.m:
deep_profiler/recursion_patterns.m:
deep_profiler/var_use_analysis.m:
    Conform to changes in create_report.

deep_profiler/array_util.m:
    Add a new predicate, array_foldl3_from_1 to support propagation of coverage
    information from proc dynamics to proc statics.

Index: deep_profiler/array_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/array_util.m,v
retrieving revision 1.11
diff -u -p -b -r1.11 array_util.m
--- deep_profiler/array_util.m	18 Aug 2008 02:14:51 -0000	1.11
+++ deep_profiler/array_util.m	22 Sep 2010 03:46:03 -0000
@@ -87,6 +87,15 @@
 :- mode array_foldl2(in, in, pred(in, in, in, out, in, out) is det, in,
     in, out, in, out) is det.
 
+    % Performs a foldl3 on all the elements of the given array, starting at
+    % index 1.
+    %
+:- pred array_foldl3_from_1(pred(int, T, U, U, V, V, W, W), array(T), U, U, 
+    V, V, W, W).
+:- mode array_foldl3_from_1(pred(in, in, array_di, array_uo,
+    array_di, array_uo, array_di, array_uo) is det,
+    in, array_di, array_uo, array_di, array_uo, array_di, array_uo) is det.
+
     % Performs the same computation as list.foldl; the only difference is
     % that the accumulator is an array and has an array mode.
     %
@@ -197,6 +206,29 @@ do_array_foldl2(N, Max, P, A, !AccU, !Ac
         true
     ).
 
+%----------------------------------------------------------------------------%
+
+array_foldl3_from_1(P, Array, !A, !B, !C) :-
+    array.max(Array, Max),
+    do_array_foldl3(1, Max, P, Array, !A, !B, !C).
+
+:- pred do_array_foldl3(int, int, pred(int, T, U, U, V, V, W, W), array(T),
+    U, U, V, V, W, W).
+:- mode do_array_foldl3(in, in, pred(in, in, array_di, array_uo, 
+    array_di, array_uo, array_di, array_uo) is det, in,
+    array_di, array_uo, array_di, array_uo, array_di, array_uo) is det.
+
+do_array_foldl3(N, Max, P, Array, !A, !B, !C) :-
+    ( N =< Max ->
+        array.lookup(Array, N, E),
+        P(N, E, !A, !B, !C),
+        do_array_foldl3(N + 1, Max, P, Array, !A, !B, !C)
+    ;
+        true
+    ).
+
+%----------------------------------------------------------------------------%
+
 array_list_foldl(_, [], !Acc).
 array_list_foldl(P, [X | Xs], !Acc) :-
     P(X, !Acc),
Index: deep_profiler/create_report.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/create_report.m,v
retrieving revision 1.23
diff -u -p -b -r1.23 create_report.m
--- deep_profiler/create_report.m	21 Sep 2010 01:09:16 -0000	1.23
+++ deep_profiler/create_report.m	22 Sep 2010 04:51:09 -0000
@@ -16,6 +16,8 @@
 :- module create_report.
 :- interface.
 
+:- import_module mdbcomp.
+:- import_module mdbcomp.program_representation.
 :- import_module measurements.
 :- import_module profile.
 :- import_module query.
@@ -40,11 +42,19 @@
 :- pred create_proc_report(deep::in, proc_static_ptr::in,
     maybe_error(proc_report)::out) is det.
 
-    % Create a procrep coverage report.
+    % Create a static procrep coverage report.
     %
-:- pred create_procrep_coverage_report(deep::in,
+:- pred create_static_procrep_coverage_report(deep::in,
     proc_static_ptr::in, maybe_error(procrep_coverage_info)::out) is det.
     
+    % Create a dynamic procrep coverage report.
+    %
+    % This will fail if dynamic coverage information is not present in the
+    % profile.
+    %
+:- pred create_dynamic_procrep_coverage_report(deep::in,
+    proc_dynamic_ptr::in, maybe_error(procrep_coverage_info)::out) is det.
+    
     % Create a top procs report, from the given data with the specified
     % parameters.
     %
@@ -75,6 +85,13 @@
 :- pred own_and_inherit_to_perf_row_data(deep::in, T::in,
     own_prof_info::in, inherit_prof_info::in, perf_row_data(T)::out) is det.
 
+    % Lookup a procedure representation from the deep structure.
+    %
+    % (Perhaps this should be a new report).
+    %
+:- pred deep_get_maybe_procrep(deep::in, proc_static_ptr::in, 
+    maybe_error(proc_rep)::out) is det.
+
 %----------------------------------------------------------------------------%
 
 :- implementation.
@@ -82,8 +99,6 @@
 :- import_module apply_exclusion.
 :- import_module coverage.
 :- import_module exclude.
-:- import_module mdbcomp.
-:- import_module mdbcomp.program_representation.
 :- import_module measurement_units.
 :- import_module program_representation_utils.
 :- import_module recursion_patterns.
@@ -167,9 +182,15 @@ create_report(Cmd, Deep, Report) :-
             MaybeTopProcsReport),
         Report = report_top_procs(MaybeTopProcsReport)
     ;
-        Cmd = deep_cmd_procrep_coverage(PSPtr),
-        create_procrep_coverage_report(Deep, PSPtr,
-            MaybeProcrepCoverageReport),
+        (
+            Cmd = deep_cmd_static_procrep_coverage(PSPtr),
+            create_static_procrep_coverage_report(Deep, PSPtr,
+                MaybeProcrepCoverageReport)
+        ;
+            Cmd = deep_cmd_dynamic_procrep_coverage(PDPtr),
+            create_dynamic_procrep_coverage_report(Deep, PDPtr,
+                MaybeProcrepCoverageReport)
+        ),
         Report = report_procrep_coverage(MaybeProcrepCoverageReport)
     ;
         Cmd = deep_cmd_proc(PSPtr),
@@ -1117,17 +1138,48 @@ create_proc_caller_cliques(Deep, CalleeP
 % Code to create the coverage annotated procedure representation report.
 %
 
-create_procrep_coverage_report(Deep, PSPtr, MaybeReport) :-
-    deep_get_maybe_progrep(Deep, MaybeProgRep),
+create_static_procrep_coverage_report(Deep, PSPtr, MaybeReport) :-
+    ( valid_proc_static_ptr(Deep, PSPtr) ->
+        deep_lookup_ps_coverage(Deep, PSPtr, StaticCoverage),
+        MaybeCoveragePoints =
+            static_coverage_maybe_get_coverage_points(StaticCoverage),
+        maybe_create_procrep_coverage_report(Deep, PSPtr, MaybeCoveragePoints,
+            MaybeReport)
+    ;
+        PSPtr = proc_static_ptr(PSId),
+        MaybeReport = error(
+            format("Proc static pointer is invalid %d", [i(PSId)]))
+    ).
+
+create_dynamic_procrep_coverage_report(Deep, PDPtr, MaybeReport) :-
+    ( valid_proc_dynamic_ptr(Deep, PDPtr) ->
+        deep_lookup_proc_dynamics(Deep, PDPtr, PD),
+        PSPtr = PD ^ pd_proc_static,
+        MaybeCoveragePoints = PD ^ pd_maybe_coverage_points,
+        maybe_create_procrep_coverage_report(Deep, PSPtr, MaybeCoveragePoints,
+            MaybeReport)
+    ;
+        PDPtr = proc_dynamic_ptr(PDId),
+        MaybeReport = error(
+            format("Proc dynamic pointer is invalid %d", [i(PDId)]))
+    ).
+
+:- pred maybe_create_procrep_coverage_report(deep::in, proc_static_ptr::in,
+    maybe(array(int))::in, maybe_error(procrep_coverage_info)::out) is det.
+
+maybe_create_procrep_coverage_report(_, _, no, error(Error)) :-
+    Error = "No coverage information available".
+maybe_create_procrep_coverage_report(Deep, PSPtr, yes(CoveragePointsArray),
+        MaybeReport) :-
+    deep_lookup_proc_statics(Deep, PSPtr, PS),
+    coverage_point_arrays_to_list(PS ^ ps_coverage_point_infos,
+        CoveragePointsArray, CoveragePoints),
+    deep_get_maybe_procrep(Deep, PSPtr, MaybeProcRep0),
     (
-        MaybeProgRep = error(Error),
+        MaybeProcRep0 = error(Error),
         MaybeReport = error(Error)
     ;
-        MaybeProgRep = ok(ProgRep),
-        ( valid_proc_static_ptr(Deep, PSPtr) ->
-            deep_lookup_proc_statics(Deep, PSPtr, PS),
-            ProcLabel = PS ^ ps_id,
-            ( progrep_search_proc(ProgRep, ProcLabel, ProcRep0) ->
+        MaybeProcRep0 = ok(ProcRep0),
                 % Information about the procedure.
                 deep_lookup_ps_own(Deep, PSPtr, Own),
 
@@ -1136,23 +1188,9 @@ create_procrep_coverage_report(Deep, PSP
                 CallSitesMap = array.foldl(add_ps_own_info_to_map(Deep),
                     CallSitesArray, map.init),
 
-                % Gather information about coverage points.
-                MaybeCoveragePoints = PS ^ ps_maybe_coverage_points,
-                (
-                    MaybeCoveragePoints = yes(CoveragePointsArray),
-                    coverage_point_arrays_to_list(PS ^ ps_coverage_point_infos,
-                        CoveragePointsArray, CoveragePoints),
                     foldl2(add_coverage_point_to_map, 
                         CoveragePoints, map.init, SolnsCoveragePointMap,
-                        map.init, BranchCoveragePointMap)
-                ;
-                    MaybeCoveragePoints = no,
-                    
-                    % No static coverage data available.
-                    % XXX: Try to get dynamic coverage data.
-                    SolnsCoveragePointMap = map.init,
-                    BranchCoveragePointMap = map.init
-                ),
+            map.init, BranchCoveragePointMap),
 
                 procrep_annotate_with_coverage(Own, CallSitesMap,
                     SolnsCoveragePointMap, BranchCoveragePointMap,
@@ -1164,14 +1202,6 @@ create_procrep_coverage_report(Deep, PSP
                     MaybeProcRep = error(Error),
                     MaybeReport = error(Error)
                 )
-            ;
-                MaybeReport =
-                    error("Program Representation doesn't contain procedure: "
-                        ++ string(PSPtr))
-            )
-        ;
-            MaybeReport = error("Invalid proc_static index")
-        )
     ).
 
 :- func add_ps_own_info_to_map(deep, call_site_static_ptr,
@@ -1424,6 +1454,24 @@ own_and_maybe_inherit_to_perf_row_data(D
     RowData = perf_row_data(Subject, Calls, Exits, Fails, Redos, Excps,
         WordSize, SelfPerf, MaybeTotalPerf).
 
+%----------------------------------------------------------------------------%
+
+deep_get_maybe_procrep(Deep, PSPtr, MaybeProcRep) :-
+    deep_get_maybe_progrep(Deep, MaybeProgRep),
+    (
+        MaybeProgRep = ok(ProgRep),
+        deep_lookup_proc_statics(Deep, PSPtr, PS),
+        ProcLabel = PS ^ ps_id,
+        ( progrep_search_proc(ProgRep, ProcLabel, ProcRep) ->
+            MaybeProcRep = ok(ProcRep)
+        ;
+            MaybeProcRep = error("Cannot find procedure representation")
+        )
+    ;
+        MaybeProgRep = error(Error),
+        MaybeProcRep = error(Error)
+    ).
+
 %-----------------------------------------------------------------------------%
 
     % int_per_call(Num, Calls) is the quotient of Nom and Calls, after they've
Index: deep_profiler/display.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/display.m,v
retrieving revision 1.11
diff -u -p -b -r1.11 display.m
--- deep_profiler/display.m	2 Jan 2009 02:59:35 -0000	1.11
+++ deep_profiler/display.m	21 Sep 2010 07:15:41 -0000
@@ -68,6 +68,11 @@
                 % A string to be displayed verbatim.  It should be displayed
                 % with a fixed width font and line breaks should be honoured.
                 string
+            )
+    ;       display_developer(
+                % A display item intended for developers only.  These are
+                % displayed only when in developer mode.
+                display_item
             ).
 
 %-----------------------------------------------------------------------------%
Index: deep_profiler/display_report.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/display_report.m,v
retrieving revision 1.27
diff -u -p -b -r1.27 display_report.m
--- deep_profiler/display_report.m	21 Sep 2010 01:09:16 -0000	1.27
+++ deep_profiler/display_report.m	22 Sep 2010 12:28:58 -0000
@@ -263,6 +263,7 @@ display_report_menu(Deep, Prefs, MenuRep
 
     (
         ShouldDisplayTimes = yes,
+    
         Top100SelfCmd = deep_cmd_top_procs(rank_range(1, 100),
             cost_time, self, overall),
         Top100SelfAndDescCmd = deep_cmd_top_procs(rank_range(1, 100),
@@ -352,22 +353,28 @@ display_report_menu(Deep, Prefs, MenuRep
             "Procedures above 2M words threshold: words, self+descendants.")
     ],
 
-    RecursionTypeFrequenciesCmd = deep_cmd_recursion_types_frequency,
-
-    LinksSummaryReports = [
-        link_base(RecursionTypeFrequenciesCmd, no,
-            "Frequencies of different types of recursion used in the program.")
-    ],
-
     LinkCmds = LinksExploration ++
         LinksTopProcsByLimitTime ++ LinksTopProcsByLimit ++
-        LinksTopProcsByPercentTime ++ LinksTopProcsByPercent ++
-        LinksSummaryReports,
+        LinksTopProcsByPercentTime ++ LinksTopProcsByPercent,
     list.map(make_link, LinkCmds, LinksList),
     Links = display_list(list_class_vertical_bullets,
         yes("You can start exploring the deep profile at the following" ++
             " points."), LinksList),
 
+    %
+    % Produce the developer-only options list.
+    %
+    RecursionTypeFrequenciesCmd = deep_cmd_recursion_types_frequency,
+    
+    LinksDeveloperCmds = [
+        link_base(RecursionTypeFrequenciesCmd, no,
+            "Frequencies of different types of recursion used in the program.")
+    ],
+    list.map(make_link, LinksDeveloperCmds, DeveloperLinksList),
+    DeveloperLinks = display_developer(display_list(list_class_vertical_bullets,
+        yes("Options that are only useful to Mercury developers"), 
+        DeveloperLinksList)),
+
     % Display the table section of the report.
     ProfilingStatistics =
         [("Profile generated for:"      - td_s(ProgramName)),
@@ -386,12 +393,15 @@ display_report_menu(Deep, Prefs, MenuRep
     Rows = list.map(make_labelled_table_row, ProfilingStatistics),
     Table = table(table_class_do_not_box, 2, no, Rows),
 
+    OptionsControls = general_options_controls(deep_cmd_menu, Prefs),
+
     MenuRestartQuitControls = cmds_menu_restart_quit(yes(Prefs)),
 
     % Construct the complete representation of what to display.
     Display = display(yes("Deep profiler menu"),
-        [Links, display_table(Table),
-        display_paragraph_break, MenuRestartQuitControls]).
+        [Links, DeveloperLinks, display_table(Table),
+        display_paragraph_break, MenuRestartQuitControls,
+        display_paragraph_break, OptionsControls]).
 
 %-----------------------------------------------------------------------------%
 %
@@ -1974,7 +1984,7 @@ display_report_procrep_coverage_info(Pre
     string.append_list(list(ProcRepStrings), ProcRepString),
     CoverageInfoItem = display_verbatim(ProcRepString),
 
-    Cmd = deep_cmd_procrep_coverage(PSPtr),
+    Cmd = deep_cmd_static_procrep_coverage(PSPtr),
     ProcReportControls = proc_reports_controls(Prefs, PSPtr, Cmd),
     MenuResetQuitControls = cmds_menu_restart_quit(yes(Prefs)),
     Controls =
@@ -2106,9 +2116,16 @@ display_report_proc_dynamic_dump(_Deep, 
         CoveragePointsItems = []
     ),
 
+    make_link(link_base(deep_cmd_dynamic_procrep_coverage(PDPtr), yes(Prefs),
+            "Dynamic coverage annotated procedure representation"),
+        CoverageAnnotatedProcrepItem),
+    RelatedReportsList = display_list(list_class_horizontal_except_title, 
+        yes("Related reports:"), [CoverageAnnotatedProcrepItem]),
+
     Display = display(yes(Title),
         [MainTableItem, CallSitesTitleItem, CallSitesTableItem] ++
-        CoveragePointsItems).
+        CoveragePointsItems ++
+        [display_paragraph_break, RelatedReportsList]).
 
 :- pred dump_psd_call_site(preferences::in,
     call_site_array_slot::in, list(table_row)::out,
@@ -3770,13 +3787,25 @@ proc_reports_controls(Prefs, Proc, NotCm
     solutions((pred(Control::out) is nondet :-
             (
                 Cmd = deep_cmd_proc(Proc),
-                Label = "Procedure"
+                Label = "Procedure",
+                Developer = no
             ;
-                Cmd = deep_cmd_procrep_coverage(Proc),
-                Label = "Coverage annotated procedure representation"
+                Cmd = deep_cmd_static_procrep_coverage(Proc),
+                Label = "Coverage annotated procedure representation",
+                % XXX: Should this option be considered a developer-only
+                % option?
+                Developer = no
+            ;
+                Cmd = deep_cmd_dump_proc_static(Proc),
+                Label = "Unprocessed proc static data",
+                Developer = yes
+            ;
+                Cmd = deep_cmd_dump_proc_var_use(Proc),
+                Label = "Var use report",
+                Developer = yes
             ),
             Cmd \= NotCmd,
-            make_control(yes(Prefs), Cmd - Label, Control)
+            make_control(yes(Prefs), Cmd, Label, Developer, Control)
         ), ProcReportControls),
     ControlsItem = display_list(list_class_vertical_no_bullets,
         yes("Related procedure reports:"), ProcReportControls).
@@ -3787,13 +3816,19 @@ clique_reports_controls(Perfs, CliquePtr
     solutions((pred(Control::out) is nondet :-
             (
                 Cmd = deep_cmd_clique(CliquePtr),
-                Label = "Clique"
+                Label = "Clique",
+                Developer = no
             ;
                 Cmd = deep_cmd_clique_recursive_costs(CliquePtr),
-                Label = "Clique's recursion information"
+                Label = "Clique's recursion information",
+                Developer = yes
+            ;
+                Cmd = deep_cmd_dump_clique(CliquePtr),
+                Label = "Unprocessed clique data",
+                Developer = yes
             ),
             Cmd \= NotCmd,
-            make_control(yes(Perfs), Cmd - Label, Control)
+            make_control(yes(Perfs), Cmd, Label, Developer, Control)
         ), CliqueReportControls),
     ControlsItem = display_list(list_class_vertical_no_bullets,
         yes("Related clique reports:"), CliqueReportControls).
@@ -4106,10 +4141,30 @@ cmds_menu_restart_quit(MaybePrefs) = Con
         attr_str([], "Restart"), link_class_control)),
     Quit = display_link(deep_link(deep_cmd_quit, MaybePrefs,
         attr_str([], "Quit"), link_class_control)),
-    List = display_list(list_class_horizontal, no,
-        [Menu, Restart, Quit]),
-    ControlsItem = display_list(list_class_vertical_no_bullets,
-        yes("General commands:"), [List]).
+    List = [Menu, Restart, Quit],
+    ControlsItem = display_list(list_class_horizontal_except_title,
+        yes("General commands:"), List).
+
+:- func general_options_controls(cmd, preferences) = display_item.
+
+general_options_controls(Cmd, Prefs) = ControlsItem :-
+    DeveloperMode = Prefs ^ pref_developer_mode,
+    (
+        DeveloperMode = developer_options_visable,
+        DeveloperText = "Disable developer options",
+        DeveloperPrefs = 
+            Prefs ^ pref_developer_mode := developer_options_invisable
+    ;
+        DeveloperMode = developer_options_invisable,
+        DeveloperText = "Enable developer options",
+        DeveloperPrefs = 
+            Prefs ^ pref_developer_mode := developer_options_visable
+    ),
+    DeveloperControl = display_link(deep_link(Cmd, yes(DeveloperPrefs),
+        attr_str([], DeveloperText), link_class_control)),
+    List = [DeveloperControl], 
+    ControlsItem = display_list(list_class_horizontal_except_title,
+        yes("General options:"), List).
 
 %-----------------------------------------------------------------------------%
 %
@@ -4264,12 +4319,19 @@ make_link(link_base(Cmd, MaybePrefs, Lab
     % Make a control from a command and label and optional preferences
     % structure.
     %
-:- pred make_control(maybe(preferences)::in, pair(cmd, string)::in,
+:- pred make_control(maybe(preferences)::in, cmd::in, string::in, bool::in,
     display_item::out) is det.
 
-make_control(MaybePrefs, Cmd - Label, Item) :-
-    Item = display_link(deep_link(Cmd, MaybePrefs, attr_str([], Label),
-        link_class_control)).
+make_control(MaybePrefs, Cmd, Label, Developer, Item) :-
+    Item0 = display_link(deep_link(Cmd, MaybePrefs, attr_str([], Label),
+        link_class_control)),
+    (
+        Developer = yes,
+        Item = display_developer(Item0)
+    ;
+        Developer = no,
+        Item = Item0
+    ).
 
 %-----------------------------------------------------------------------------%
 %
Index: deep_profiler/html_format.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/html_format.m,v
retrieving revision 1.34
diff -u -p -b -r1.34 html_format.m
--- deep_profiler/html_format.m	2 Jan 2009 02:59:35 -0000	1.34
+++ deep_profiler/html_format.m	21 Sep 2010 08:33:01 -0000
@@ -183,61 +183,39 @@ item_to_html(StartTag, EndTag, FormatInf
         HTML = wrap_tags(StartTag, EndTag, TableHTML)
     ;
         Item = display_list(Class, MaybeTitle, Items),
+        DeveloperMode = FormatInfo ^ fi_pref_developer,
         (
-            MaybeTitle = yes(Title),
-            TitleStartTag = "<span id=\"list_title\">",
-            TitleEndTag = "</span>\n",
-            TitleHTML = wrap_tags(TitleStartTag, TitleEndTag,
-                str_to_html(Title)),
-            (
-                Class = list_class_horizontal,
-                PostTitleHTML = empty_html
-            ;
-                ( Class = list_class_horizontal_except_title
-                ; Class = list_class_vertical_bullets
-                ; Class = list_class_vertical_no_bullets
-                ),
-                PostTitleHTML = str_to_html("<br>\n")
+            % If developer only items are invisable and all the items in the
+            % list are developer items, then don't display the list at all.
+            DeveloperMode = developer_options_invisable,
+            not (
+                some [ListItem] (
+                    member(ListItem, Items),
+                    not ListItem = display_developer(_)
             )
+            )
+        ->
+            HTML = empty
         ;
-            MaybeTitle = no,
-            TitleHTML = empty_html,
-            PostTitleHTML = empty_html
-        ),
-        (
-            ( Class = list_class_horizontal
-            ; Class = list_class_horizontal_except_title
-            ),
-            OutsideStartTag = "",
-            OutsideEndTag = "\n",
-            InnerStartTag = "",
-            InnerEndTag = "\n",
-            Separator = str_to_html("")
-        ;
-            Class = list_class_vertical_no_bullets,
-            OutsideStartTag = "",
-            OutsideEndTag = "\n",
-            InnerStartTag = "",
-            InnerEndTag = "\n",
-            Separator = str_to_html("<br>\n")
-        ;
-            Class = list_class_vertical_bullets,
-            OutsideStartTag = "<ul>\n",
-            OutsideEndTag = "</ul>\n",
-            InnerStartTag = "<li>\n",
-            InnerEndTag = "</li>\n",
-            Separator = empty_html
-        ),
-        sep_map_join_html(Separator,
-            item_to_html(InnerStartTag, InnerEndTag, FormatInfo),
-            !StyleControlMap, Items, InnerItemsHTML),
-        ItemsHTML = wrap_tags(OutsideStartTag, OutsideEndTag, InnerItemsHTML),
-        HTML = wrap_tags(StartTag, EndTag,
-            TitleHTML ++ PostTitleHTML ++ ItemsHTML)
+            list_to_html(FormatInfo, !StyleControlMap, Class, MaybeTitle, Items,
+                TableHTML),
+            HTML = wrap_tags(StartTag, EndTag, TableHTML)
+        )
     ;
         Item = display_verbatim(Text),
         HTML = wrap_tags(StartTag, EndTag,
             wrap_tags("<pre>", "</pre>", str_to_html(Text)))
+    ;
+        Item = display_developer(SubItem),
+        DeveloperMode = FormatInfo ^ fi_pref_developer,
+        (
+            DeveloperMode = developer_options_visable,
+            item_to_html(StartTag, EndTag, FormatInfo, !StyleControlMap,
+                SubItem, HTML)
+        ;
+            DeveloperMode = developer_options_invisable,
+            HTML = empty
+        )
     ).
 
 %-----------------------------------------------------------------------------%
@@ -745,6 +723,68 @@ default_style_control_map =
 
 %-----------------------------------------------------------------------------%
 
+    % Transform a list of items into HTML.
+    %
+:- pred list_to_html(format_info::in, 
+    style_control_map::in, style_control_map::out,
+    list_class::in, maybe(string)::in, list(display_item)::in, html::out)
+    is det.
+
+list_to_html(FormatInfo, !StyleControlMap, Class, MaybeTitle, Items, HTML) :-
+    (
+        MaybeTitle = yes(Title),
+        TitleStartTag = "<span id=\"list_title\">",
+        TitleEndTag = "</span>\n",
+        TitleHTML = wrap_tags(TitleStartTag, TitleEndTag,
+            str_to_html(Title)),
+        (
+            Class = list_class_horizontal,
+            PostTitleHTML = empty_html
+        ;
+            ( Class = list_class_horizontal_except_title
+            ; Class = list_class_vertical_bullets
+            ; Class = list_class_vertical_no_bullets
+            ),
+            PostTitleHTML = str_to_html("<br>\n")
+        )
+    ;
+        MaybeTitle = no,
+        TitleHTML = empty_html,
+        PostTitleHTML = empty_html
+    ),
+    (
+        ( Class = list_class_horizontal
+        ; Class = list_class_horizontal_except_title
+        ),
+        OutsideStartTag = "",
+        OutsideEndTag = "\n",
+        InnerStartTag = "",
+        InnerEndTag = "\n",
+        Separator = str_to_html("")
+    ;
+        Class = list_class_vertical_no_bullets,
+        OutsideStartTag = "",
+        OutsideEndTag = "\n",
+        InnerStartTag = "",
+        InnerEndTag = "\n",
+        Separator = str_to_html("<br>\n")
+    ;
+        Class = list_class_vertical_bullets,
+        OutsideStartTag = "<ul>\n",
+        OutsideEndTag = "</ul>\n",
+        InnerStartTag = "<li>\n",
+        InnerEndTag = "</li>\n",
+        Separator = empty_html
+    ),
+    sep_map_join_html(Separator,
+        item_to_html(InnerStartTag, InnerEndTag, FormatInfo),
+        !StyleControlMap, Items, InnerItemsHTML),
+    ItemsHTML = wrap_tags(OutsideStartTag, OutsideEndTag,
+        InnerItemsHTML),
+    HTML = TitleHTML ++ PostTitleHTML ++ ItemsHTML.
+
+%-----------------------------------------------------------------------------%
+
     % Transform a deep link into HTML.
     %
 :- func link_to_html(format_info, deep_link) = html.
@@ -790,6 +830,7 @@ pseudo_link_to_html(_FormatInfo, PseudoL
                 % Information about preferences.
                 fi_pref_colour_scheme   :: colour_column_groups,
                 fi_pref_box             :: box_tables,
+                fi_pref_developer       :: developer_mode,
 
                 % Information about the current HTTP session, which we use
                 % to create links.
@@ -802,6 +843,7 @@ pseudo_link_to_html(_FormatInfo, PseudoL
 
 init_format_info(Deep, Prefs) = FormatInfo :-
     FormatInfo = format_info(Prefs ^ pref_colour, Prefs ^ pref_box,
+        Prefs ^ pref_developer_mode,
         Deep ^ server_name_port, Deep ^ script_name, Deep ^ data_file_name).
 
 %-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_cgi.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/mdprof_cgi.m,v
retrieving revision 1.30
diff -u -p -b -r1.30 mdprof_cgi.m
--- deep_profiler/mdprof_cgi.m	8 Sep 2009 02:37:15 -0000	1.30
+++ deep_profiler/mdprof_cgi.m	21 Sep 2010 06:51:04 -0000
@@ -816,7 +816,6 @@ detach_process(Result, !IO) :-
     ;       localhost
     ;       modules
     ;       proc
-    ;       procrep_coverage
     ;       quit
     ;       root
     ;       record_startup
@@ -854,7 +853,6 @@ long("help",                help).
 long("localhost",           localhost).
 long("modules",             modules).
 long("proc",                proc).
-long("procrep-coverage",    procrep_coverage).
 long("quit",                quit).
 long("root",                root).
 long("record-startup",      record_startup).
@@ -877,7 +875,6 @@ defaults(help,                  bool(no)
 defaults(localhost,             bool(no)).
 defaults(modules,               bool(no)).
 defaults(proc,                  int(0)).
-defaults(procrep_coverage,      int(0)).
 defaults(quit,                  bool(no)).
 defaults(root,                  bool(no)).
 defaults(record_loop,           bool(yes)).
@@ -895,7 +892,6 @@ default_cmd(Options) = Cmd :-
     lookup_bool_option(Options, modules, Modules),
     lookup_int_option(Options, clique, CliqueNum),
     lookup_int_option(Options, proc, ProcProcNum),
-    lookup_int_option(Options, procrep_coverage, ProcrepCoverageProcNum),
     ( Root = yes ->
         Cmd = deep_cmd_root(no)
     ; Modules = yes ->
@@ -904,8 +900,6 @@ default_cmd(Options) = Cmd :-
         Cmd = deep_cmd_clique(clique_ptr(CliqueNum))
     ; ProcProcNum > 0 ->
         Cmd = deep_cmd_proc(proc_static_ptr(ProcProcNum))
-    ; ProcrepCoverageProcNum > 0 ->
-        Cmd = deep_cmd_procrep_coverage(proc_static_ptr(ProcrepCoverageProcNum))
     ; Quit = yes ->
         Cmd = deep_cmd_quit
     ;
Index: deep_profiler/mdprof_fb.automatic_parallelism.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/mdprof_fb.automatic_parallelism.m,v
retrieving revision 1.14
diff -u -p -b -r1.14 mdprof_fb.automatic_parallelism.m
--- deep_profiler/mdprof_fb.automatic_parallelism.m	26 Aug 2010 06:29:27 -0000	1.14
+++ deep_profiler/mdprof_fb.automatic_parallelism.m	21 Sep 2010 05:09:09 -0000
@@ -649,7 +649,7 @@ build_recursive_call_site_cost_map(Deep,
         CallSites = CliqueProc ^ cpr_first_proc_dynamic ^ cpdr_call_sites,
        
         PSPtr = ProcDesc ^ pdesc_ps_ptr,
-        create_procrep_coverage_report(Deep, PSPtr, MaybeCoverageReport),
+        create_static_procrep_coverage_report(Deep, PSPtr, MaybeCoverageReport),
         (
             MaybeCoverageReport = ok(procrep_coverage_info(_, ProcRep)),
             Goal = ProcRep ^ pr_defn ^ pdr_goal,
Index: deep_profiler/mdprof_test.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/mdprof_test.m,v
retrieving revision 1.22
diff -u -p -b -r1.22 mdprof_test.m
--- deep_profiler/mdprof_test.m	26 Aug 2010 06:29:27 -0000	1.22
+++ deep_profiler/mdprof_test.m	21 Sep 2010 06:52:11 -0000
@@ -282,8 +282,8 @@ test_procs(Cur, Max, Options, Pref, Deep
 
 test_procrep_coverages(Cur, Max, Pref, Deep, Options, !IO) :-
     ( Cur =< Max ->
-        try_exec(deep_cmd_procrep_coverage(proc_static_ptr(Cur)), Pref, Deep,
-            HTML, !IO),
+        try_exec(deep_cmd_static_procrep_coverage(proc_static_ptr(Cur)), Pref, 
+            Deep, HTML, !IO),
         write_test_html(Options, "procrep_coverage", Cur, HTML, !IO),
         test_procrep_coverages(Cur + 1, Max, Pref, Deep, Options, !IO)
     ;
Index: deep_profiler/measurements.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/measurements.m,v
retrieving revision 1.20
diff -u -p -b -r1.20 measurements.m
--- deep_profiler/measurements.m	26 Aug 2010 06:29:27 -0000	1.20
+++ deep_profiler/measurements.m	22 Sep 2010 07:14:14 -0000
@@ -17,7 +17,9 @@
 
 :- interface.
 
+:- import_module array.
 :- import_module list.
+:- import_module maybe.
 
 :- import_module mdbcomp.
 :- import_module mdbcomp.feedback.
@@ -143,6 +145,21 @@
 
 %-----------------------------------------------------------------------------%
 
+:- type static_coverage_info.
+
+:- func zero_static_coverage = static_coverage_info.
+
+:- pred add_coverage_arrays(array(int)::in, 
+    static_coverage_info::in, static_coverage_info::out) is det.
+
+:- pred array_to_static_coverage(array(int)::in, static_coverage_info::out) 
+    is det.
+
+:- func static_coverage_maybe_get_coverage_points(static_coverage_info) =
+    maybe(array(int)).
+
+%-----------------------------------------------------------------------------%
+
     % The amount of parallelism either available or exploited.
     %
 :- type parallelism_amount.
@@ -235,10 +252,11 @@
 :- import_module bool.
 :- import_module float.
 :- import_module int.
-:- import_module maybe.
 :- import_module require.
 :- import_module string.
 
+:- import_module array_util.
+
 %----------------------------------------------------------------------------%
 
 :- type own_prof_info
@@ -670,6 +688,32 @@ Cost0 / Denom = Cost :-
 
 %----------------------------------------------------------------------------%
 
+:- type static_coverage_info == maybe(array(int)).
+
+zero_static_coverage = no.
+
+add_coverage_arrays(Array, no, yes(Array)).
+add_coverage_arrays(NewArray, yes(!.Array), yes(!:Array)) :-
+    ( 
+        bounds(NewArray, Min, Max),
+        bounds(!.Array, Min, Max)
+    ->
+        !:Array = copy(!.Array),
+        array_foldl_from_0(
+            (pred(Index::in, E::in, A0::array_di, A::array_uo) is det :-
+                lookup(A0, Index, Value),
+                set(A0, Index, Value + E, A)
+            ), NewArray, !Array)
+    ;
+        error(this_file ++ "Arrays' bounds do not match")
+    ).
+
+array_to_static_coverage(Array, yes(Array)).
+
+static_coverage_maybe_get_coverage_points(MaybeCoverage) = MaybeCoverage.
+
+%----------------------------------------------------------------------------%
+
     % This type can be represented in multiple ways.  A single value expressing
     % the probable value, or a probable value and a measure of
     % deviation/variance.  Or as below three values that can express the
Index: deep_profiler/old_html_format.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/old_html_format.m,v
retrieving revision 1.6
diff -u -p -b -r1.6 old_html_format.m
--- deep_profiler/old_html_format.m	26 Aug 2010 06:29:27 -0000	1.6
+++ deep_profiler/old_html_format.m	21 Sep 2010 06:51:34 -0000
@@ -410,7 +410,8 @@ command_relevant_toggles(deep_cmd_dump_c
 command_relevant_toggles(deep_cmd_dump_clique(_)) = [].
 command_relevant_toggles(deep_cmd_dump_proc_var_use(_)) = [].
 command_relevant_toggles(Cmd) = [] :-
-    ( Cmd = deep_cmd_procrep_coverage(_)
+    ( Cmd = deep_cmd_static_procrep_coverage(_)
+    ; Cmd = deep_cmd_dynamic_procrep_coverage(_)
     ; Cmd = deep_cmd_module_getter_setters(_)
     ; Cmd = deep_cmd_clique_recursive_costs(_)
     ; Cmd = deep_cmd_recursion_types_frequency
Index: deep_profiler/old_query.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/old_query.m,v
retrieving revision 1.6
diff -u -p -b -r1.6 old_query.m
--- deep_profiler/old_query.m	26 Aug 2010 06:29:27 -0000	1.6
+++ deep_profiler/old_query.m	21 Sep 2010 06:55:10 -0000
@@ -139,21 +139,16 @@ old_exec(Cmd, Pref, Deep, HTML, !IO) :-
     ).
 old_exec(deep_cmd_dump_clique(CliquePtr), _Pref, Deep, HTML, !IO) :-
     HTML = generate_clique_debug_page(CliquePtr, Deep).
-old_exec(deep_cmd_procrep_coverage(_), _, _, HTML, !IO) :-
-    HTML = 
-        "old_query.m: deep_cmd_procrep_coverage is unsupported by old_exec\n". 
-old_exec(deep_cmd_dump_proc_var_use(_), _, _, HTML, !IO) :-
-    HTML = 
-        "old_query.m: deep_cmd_dump_proc_var_use is unsupported by old_exec\n".
-old_exec(deep_cmd_module_getter_setters(_), _, _, HTML, !IO) :-
-    HTML = "old_query.m: " ++
-        "deep_cmd_module_getter_setters is unsupported by old_exec\n". 
-old_exec(deep_cmd_clique_recursive_costs(_), _, _, HTML, !IO) :-
-    HTML = "old_query.m: " ++
-        "deep_cmd_clique_recursive_costs is unsupported by old_exec\n".
-old_exec(deep_cmd_recursion_types_frequency, _, _, HTML, !IO) :-
-    HTML = "old_query.m: " ++
-        "deep_cmd_recursion_types_frequency is unsupported by old_exec\n".
+old_exec(Cmd, _, _, HTML, !IO) :-
+    ( Cmd = deep_cmd_static_procrep_coverage(_)
+    ; Cmd = deep_cmd_dynamic_procrep_coverage(_)
+    ; Cmd = deep_cmd_dump_proc_var_use(_)
+    ; Cmd = deep_cmd_module_getter_setters(_)
+    ; Cmd = deep_cmd_clique_recursive_costs(_)
+    ; Cmd = deep_cmd_recursion_types_frequency
+    ),
+    format("old_query.m: %s is unsupported by old_exec\n", [s(string(Cmd))], 
+        HTML).
 
 %-----------------------------------------------------------------------------%
 
Index: deep_profiler/profile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/profile.m,v
retrieving revision 1.30
diff -u -p -b -r1.30 profile.m
--- deep_profiler/profile.m	21 Sep 2010 01:09:16 -0000	1.30
+++ deep_profiler/profile.m	22 Sep 2010 11:53:12 -0000
@@ -119,6 +119,9 @@
                 % Information about modules.
                 module_data             :: map(string, module_data),
 
+                % Static coverage information.
+                maybe_static_coverage   :: maybe(array(static_coverage_info)),
+
                 % If this field is `no', then there is no (readable) contour
                 % exclusion file. If this field is yes(MaybeExcludeFile),
                 % then there are again two possibilities. The normal case is
@@ -367,6 +370,8 @@
     proc_dynamic_ptr::in, compensation_table::out) is det.
 :- pred lookup_csd_comp_table(array(compensation_table)::in,
     call_site_dynamic_ptr::in, compensation_table::out) is det.
+:- pred lookup_ps_coverage(array(static_coverage_info)::in,
+    proc_static_ptr::in, static_coverage_info::out) is det.
 
 :- pred deep_lookup_call_site_dynamics(deep::in, call_site_dynamic_ptr::in,
     call_site_dynamic::out) is det.
@@ -413,6 +418,8 @@
     own_prof_info::out) is det.
 :- pred deep_lookup_css_desc(deep::in, call_site_static_ptr::in,
     inherit_prof_info::out) is det.
+:- pred deep_lookup_ps_coverage(deep::in, proc_static_ptr::in,
+    static_coverage_info::out) is det.
 
 :- pred update_call_site_dynamics(call_site_dynamic_ptr::in,
     call_site_dynamic::in,
@@ -441,6 +448,9 @@
 :- pred update_css_desc(call_site_static_ptr::in, inherit_prof_info::in,
     array(inherit_prof_info)::array_di, array(inherit_prof_info)::array_uo)
     is det.
+:- pred update_ps_coverage(proc_static_ptr::in, static_coverage_info::in,
+    array(static_coverage_info)::array_di, 
+    array(static_coverage_info)::array_uo) is det.
 
 :- pred deep_update_csd_desc(call_site_dynamic_ptr::in, inherit_prof_info::in,
     deep::in, deep::out) is det.
@@ -780,6 +790,14 @@ lookup_csd_comp_table(CSDCompTables, CSD
         error("lookup_csd_comp_table: bounds error")
     ).
 
+lookup_ps_coverage(PSCoverageArrays, PSPtr, PSCoverageArray) :-
+    PSPtr = proc_static_ptr(PSI),
+    ( PSI > 0, array.in_bounds(PSCoverageArrays, PSI) ->
+        array.lookup(PSCoverageArrays, PSI, PSCoverageArray)
+    ;
+        error("lookup_ps_coverage: bounds error")
+    ).
+
 %-----------------------------------------------------------------------------%
 
 deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD) :-
@@ -862,6 +880,16 @@ deep_lookup_css_desc(Deep, CSSPtr, Desc)
     CSSPtr = call_site_static_ptr(CSSI),
     array.lookup(Deep ^ css_desc, CSSI, Desc).
 
+deep_lookup_ps_coverage(Deep, PSPtr, Coverage) :-
+    MaybeCoverageTables = Deep ^ maybe_static_coverage,
+    (
+        MaybeCoverageTables = yes(CoverageTables),
+        lookup_ps_coverage(CoverageTables, PSPtr, Coverage)
+    ;
+        MaybeCoverageTables = no,
+        Coverage = zero_static_coverage
+    ).
+
 %-----------------------------------------------------------------------------%
 
 update_call_site_dynamics(CSDPtr, CSD, CallSiteDynamics0, CallSiteDynamics) :-
@@ -905,6 +933,10 @@ update_css_desc(CSSPtr, Desc, CSSDescs0,
     CSSPtr = call_site_static_ptr(CSSI),
     array.set(CSSDescs0, CSSI, Desc, CSSDescs).
 
+update_ps_coverage(PSPtr, Coverage, !Coverages) :-
+    PSPtr = proc_static_ptr(PSI),
+    array.set(!.Coverages, PSI, Coverage, !:Coverages).
+
 %-----------------------------------------------------------------------------%
 
 deep_update_csd_desc(CSDPtr, CSDDesc, Deep0, Deep) :-
Index: deep_profiler/query.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/query.m,v
retrieving revision 1.36
diff -u -p -b -r1.36 query.m
--- deep_profiler/query.m	26 Aug 2010 06:29:27 -0000	1.36
+++ deep_profiler/query.m	21 Sep 2010 07:29:49 -0000
@@ -119,8 +119,11 @@
                 cmd_tp_incl_desc                :: include_descendants,
                 cmd_tp_scope                    :: measurement_scope
             )
-    ;       deep_cmd_procrep_coverage(
-                cmd_procrep_coverage_proc_id    :: proc_static_ptr
+    ;       deep_cmd_static_procrep_coverage(
+                cmd_static_coverage_ps          :: proc_static_ptr
+            )
+    ;       deep_cmd_dynamic_procrep_coverage(
+                cmd_dynamic_coverage_pd         :: proc_dynamic_ptr
             )
     ;       deep_cmd_module_getter_setters(
                 cmd_mgs_module_name             :: string
@@ -224,7 +227,10 @@
 
                 % Whether we should show modules/procs that haven't been
                 % called.
-                pref_inactive       :: inactive_items
+                pref_inactive       :: inactive_items,
+
+                % Whether to show developer-only options.
+                pref_developer_mode :: developer_mode
             ).
 
 :- type preferences_indication
@@ -318,6 +324,10 @@
                 inactive_modules    :: inactive_status
             ).
 
+:- type developer_mode
+    --->    developer_options_visable
+    ;       developer_options_invisable.
+
 %-----------------------------------------------------------------------------%
 
     % Return "yes" if it is worth displaying times for this profile.
@@ -345,6 +355,7 @@
 :- func default_time_format = time_format.
 :- func default_module_qual = module_qual.
 :- func default_inactive_items = inactive_items.
+:- func default_developer_mode = developer_mode.
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -446,7 +457,8 @@ exec(Cmd, Prefs, Deep, HTMLStr, !IO) :-
             new_exec(Cmd, Prefs, Deep, HTMLStr, !IO)
         )
     ;
-        ( Cmd = deep_cmd_procrep_coverage(_)
+        ( Cmd = deep_cmd_static_procrep_coverage(_)
+        ; Cmd = deep_cmd_dynamic_procrep_coverage(_)
         ; Cmd = deep_cmd_module_getter_setters(_)
         ; Cmd = deep_cmd_dump_proc_var_use(_)
         ; Cmd = deep_cmd_clique_recursive_costs(_)
@@ -525,7 +537,8 @@ default_preferences(Deep) =
         default_contour_exclusion,
         default_time_format,
         default_module_qual,
-        default_inactive_items
+        default_inactive_items,
+        default_developer_mode
     ).
 
 default_fields(Deep) = Fields :-
@@ -556,6 +569,7 @@ default_time_format = scale_by_thousands
 default_module_qual = module_qual_when_diff.
 default_inactive_items =
     inactive_items(inactive_hide, inactive_hide, inactive_hide).
+default_developer_mode = developer_options_invisable.
 
 %-----------------------------------------------------------------------------%
 
@@ -659,10 +673,15 @@ cmd_to_string(Cmd) = CmdStr :-
             c(cmd_separator_char), s(InclDescStr),
             c(cmd_separator_char), s(ScopeStr)])
     ;
-        Cmd = deep_cmd_procrep_coverage(PSPtr),
+        Cmd = deep_cmd_static_procrep_coverage(PSPtr),
         PSPtr = proc_static_ptr(PSI),
         CmdStr = string.format("%s%c%d",
-            [s(cmd_str_procrep_coverage), c(cmd_separator_char), i(PSI)])
+            [s(cmd_str_static_coverage), c(cmd_separator_char), i(PSI)])
+    ;
+        Cmd = deep_cmd_dynamic_procrep_coverage(PDPtr),
+        PDPtr = proc_dynamic_ptr(PDI),
+        CmdStr = string.format("%s%c%d",
+            [s(cmd_str_dynamic_coverage), c(cmd_separator_char), i(PDI)])
     ;
         Cmd = deep_cmd_dump_proc_static(PSPtr),
         PSPtr = proc_static_ptr(PSI),
@@ -700,7 +719,7 @@ cmd_to_string(Cmd) = CmdStr :-
 preferences_to_string(Pref) = PrefStr :-
     Pref = preferences(Fields, Box, Colour, MaybeAncestorLimit,
         ProcStaticsPerRecTypeLimit, SummarizeHoCallSites, Order, Contour,
-        Time, ModuleQual, InactiveItems),
+        Time, ModuleQual, InactiveItems, DeveloperMode),
     (
         MaybeAncestorLimit = yes(AncestorLimit),
         MaybeAncestorLimitStr =
@@ -709,7 +728,7 @@ preferences_to_string(Pref) = PrefStr :-
         MaybeAncestorLimit = no,
         MaybeAncestorLimitStr = "no"
     ),
-    PrefStr = string.format("%s%c%s%c%s%c%s%c%d%c%s%c%s%c%s%c%s%c%s%c%s",
+    PrefStr = string.format("%s%c%s%c%s%c%s%c%d%c%s%c%s%c%s%c%s%c%s%c%s%c%s",
         [s(fields_to_string(Fields)),
         c(pref_separator_char), s(box_to_string(Box)),
         c(pref_separator_char), s(colour_scheme_to_string(Colour)),
@@ -720,7 +739,8 @@ preferences_to_string(Pref) = PrefStr :-
         c(pref_separator_char), s(contour_exclusion_to_string(Contour)),
         c(pref_separator_char), s(time_format_to_string(Time)),
         c(pref_separator_char), s(module_qual_to_string(ModuleQual)),
-        c(pref_separator_char), s(inactive_items_to_string(InactiveItems))
+        c(pref_separator_char), s(inactive_items_to_string(InactiveItems)),
+        c(pref_separator_char), s(developer_mode_to_string(DeveloperMode))
     ]).
 
 :- func string_to_cmd(string, cmd) = cmd.
@@ -813,11 +833,17 @@ string_to_maybe_cmd(QueryString) = Maybe
         Cmd = deep_cmd_top_procs(Limit, CostKind, InclDesc, Scope),
         MaybeCmd = yes(Cmd)
     ;
-        Pieces = [cmd_str_procrep_coverage, PSIStr],
+        Pieces = [cmd_str_static_coverage, PSIStr],
         string.to_int(PSIStr, PSI)
     ->
         PSPtr = proc_static_ptr(PSI),
-        MaybeCmd = yes(deep_cmd_procrep_coverage(PSPtr))
+        MaybeCmd = yes(deep_cmd_static_procrep_coverage(PSPtr))
+    ;
+        Pieces = [cmd_str_dynamic_coverage, PDIStr],
+        string.to_int(PDIStr, PDI)
+    ->
+        PDPtr = proc_dynamic_ptr(PDI),
+        MaybeCmd = yes(deep_cmd_dynamic_procrep_coverage(PDPtr))
     ;
         Pieces = [cmd_str_menu]
     ->
@@ -891,7 +917,7 @@ string_to_maybe_pref(QueryString) = Mayb
         Pieces = [FieldsStr, BoxStr, ColourStr,
             MaybeAncestorLimitStr, ProcStaticsPerRecTypeLimitStr, 
             SummarizeHoCallSitesStr, OrderStr, ContourStr, TimeStr,
-            ModuleQualStr, InactiveItemsStr],
+            ModuleQualStr, InactiveItemsStr, DeveloperModeStr],
         string_to_fields(FieldsStr, Fields),
         string_to_box(BoxStr, Box),
         string_to_colour_scheme(ColourStr, Colour),
@@ -909,11 +935,12 @@ string_to_maybe_pref(QueryString) = Mayb
         string_to_contour_exclusion(ContourStr, Contour),
         string_to_time_format(TimeStr, Time),
         string_to_module_qual(ModuleQualStr, ModuleQual),
-        string_to_inactive_items(InactiveItemsStr, InactiveItems)
+        string_to_inactive_items(InactiveItemsStr, InactiveItems),
+        string_to_developer_mode(DeveloperModeStr, DeveloperMode)
     ->
         Preferences = preferences(Fields, Box, Colour, MaybeAncestorLimit,
             ProcStaticsPerRecTypeLimit, SummarizeHoCallSites, Order, Contour,
-            Time, ModuleQual, InactiveItems),
+            Time, ModuleQual, InactiveItems, DeveloperMode),
         MaybePreferences = yes(Preferences)
     ;
         MaybePreferences = no
@@ -1277,6 +1304,18 @@ string_to_inactive_items("ssh",
 string_to_inactive_items("sss",
     inactive_items(inactive_show, inactive_show, inactive_show)).
 
+:- func developer_mode_to_string(developer_mode) = string.
+
+developer_mode_to_string(DevMode) = String :-
+    string_to_developer_mode(String, DevMode).
+
+:- pred string_to_developer_mode(string, developer_mode).
+:- mode string_to_developer_mode(in, out) is semidet.
+:- mode string_to_developer_mode(out, in) is det.
+
+string_to_developer_mode("dev", developer_options_visable).
+string_to_developer_mode("nodev", developer_options_invisable).
+
 :- func colour_scheme_to_string(colour_column_groups) = string.
 
 colour_scheme_to_string(Scheme) = String :-
@@ -1345,8 +1384,11 @@ cmd_str_module_getter_setters = "module_
 :- func cmd_str_top_procs = string.
 cmd_str_top_procs = "top_procs".
 
-:- func cmd_str_procrep_coverage = string.
-cmd_str_procrep_coverage = "procrep_coverage".
+:- func cmd_str_static_coverage = string.
+cmd_str_static_coverage = "proc_static_coverage".
+
+:- func cmd_str_dynamic_coverage = string.
+cmd_str_dynamic_coverage = "proc_dynamic_coverage".
 
 :- func cmd_str_dump_proc_static = string.
 cmd_str_dump_proc_static = "dump_proc_static".
Index: deep_profiler/recursion_patterns.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/recursion_patterns.m,v
retrieving revision 1.1
diff -u -p -b -r1.1 recursion_patterns.m
--- deep_profiler/recursion_patterns.m	27 Aug 2010 08:27:32 -0000	1.1
+++ deep_profiler/recursion_patterns.m	21 Sep 2010 04:58:05 -0000
@@ -106,7 +106,7 @@ proc_get_recursion_type(Deep, ThisClique
     % TODO: Don't use coverage information here, it's computationally expensive
     % and shouldn't be necessary.  But more importantly it is per proc static
     % and therefore not suitable for calculating the depths of recursion.
-    create_procrep_coverage_report(Deep, PSPtr, MaybeCoverageReport),
+    create_static_procrep_coverage_report(Deep, PSPtr, MaybeCoverageReport),
     (
         MaybeCoverageReport = ok(CoverageReport),
         ProcRep = CoverageReport ^ prci_proc_rep, 
Index: deep_profiler/startup.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/startup.m,v
retrieving revision 1.24
diff -u -p -b -r1.24 startup.m
--- deep_profiler/startup.m	2 Oct 2009 04:37:57 -0000	1.24
+++ deep_profiler/startup.m	22 Sep 2010 11:56:20 -0000
@@ -294,6 +294,17 @@ startup(Machine, ScriptName, DataFileNam
     array.init(NCSSs, zero_inherit_prof_info, CSSDesc0),
     array.init(NPDs, map.init, PDCompTable0),
     array.init(NCSDs, map.init, CSDCompTable0),
+    CoverageDataType = InitStats ^ coverage_data_type, 
+    (
+        CoverageDataType = no_coverage_data,
+        MaybeStaticCoverage0 = no
+    ;
+        ( CoverageDataType = static_coverage_data
+        ; CoverageDataType = dynamic_coverage_data
+        ),
+        array.init(NPSs, zero_static_coverage, StaticCoverage0),
+        MaybeStaticCoverage0 = yes(StaticCoverage0)
+    ),
 
     !:Deep = deep(InitStats, Machine, ScriptName, DataFileName, Root,
         CallSiteDynamics, ProcDynamics, CallSiteStatics, ProcStatics,
@@ -301,7 +312,7 @@ startup(Machine, ScriptName, DataFileNam
         ProcCallers, CallSiteStaticMap, CallSiteCalls,
         PDOwn, PDDesc0, CSDDesc0,
         PSOwn0, PSDesc0, CSSOwn0, CSSDesc0,
-        PDCompTable0, CSDCompTable0, ModuleDataMap,
+        PDCompTable0, CSDCompTable0, ModuleDataMap, MaybeStaticCoverage0, 
         ExcludeFile, MaybeProcRepFile),
 
     array_foldl_from_1(propagate_to_clique, Cliques, !Deep),
@@ -314,8 +325,32 @@ startup(Machine, ScriptName, DataFileNam
 
     maybe_report_msg(MaybeOutputStream,
         "% Summarizing information...\n", !IO),
-    summarize_proc_dynamics(!Deep),
+    (
+        ( CoverageDataType = no_coverage_data
+        ; CoverageDataType = static_coverage_data
+        ),
+        (
+            CoverageDataType = static_coverage_data,
+            maybe_report_msg(MaybeOutputStream,
+                "\t% Summarizing static coverage...\n", !IO),
+            summarize_proc_statics_coverage(!Deep)
+        ;
+            CoverageDataType = no_coverage_data
+        ),
+        maybe_report_msg(MaybeOutputStream,
+            "\t% Summarizing proc dynamics...\n", !IO),
+        summarize_proc_dynamics(!Deep)
+    ;
+        CoverageDataType = dynamic_coverage_data,
+        maybe_report_msg(MaybeOutputStream,
+            "\t% Summarizing proc dynamics with coverage...\n", !IO),
+        summarize_proc_dynamics_with_coverage_data(!Deep)
+    ),
+    maybe_report_msg(MaybeOutputStream,
+        "\t% Summarizing call site dynamics...\n", !IO),
     summarize_call_site_dynamics(!Deep),
+    maybe_report_msg(MaybeOutputStream,
+        "\t% Summarizing modules...\n", !IO),
     summarize_modules(!Deep),
     maybe_report_msg(MaybeOutputStream,
         "% Done.\n", !IO),
@@ -724,6 +759,50 @@ summarize_proc_dynamic(PDOwnArray, PDDes
     update_ps_own(PSPtr, PSOwn, u(PSOwnArray0), PSOwnArray),
     update_ps_desc(PSPtr, PSDesc, u(PSDescArray0), PSDescArray).
 
+:- pred summarize_proc_dynamics_with_coverage_data(deep::in, deep::out) is det.
+
+summarize_proc_dynamics_with_coverage_data(!Deep) :-
+    % These arrays are one based, the +1 here is necessary to allocate the
+    % correect amount of storage.
+    NPS = !.Deep ^ profile_stats ^ num_ps + 1,
+    array_foldl3_from_1(
+        summarize_proc_dynamic_with_coverage(!.Deep ^ pd_own, 
+            !.Deep ^ pd_desc, !.Deep ^ pd_comp_table),
+        !.Deep ^ proc_dynamics,
+        init(NPS, zero_own_prof_info), PSOwnArray,
+        init(NPS, zero_inherit_prof_info), PSDescArray,
+        init(NPS, zero_static_coverage), CoverageArray),
+    !Deep ^ ps_own := PSOwnArray,
+    !Deep ^ ps_desc := PSDescArray,
+    !Deep ^ maybe_static_coverage := yes(CoverageArray).
+
+:- pred summarize_proc_dynamic_with_coverage(array(own_prof_info)::in,
+    array(inherit_prof_info)::in, array(compensation_table)::in,
+    int::in, proc_dynamic::in,
+    array(own_prof_info)::array_di, array(own_prof_info)::array_uo,
+    array(inherit_prof_info)::array_di, array(inherit_prof_info)::array_uo,
+    array(static_coverage_info)::array_di,
+    array(static_coverage_info)::array_uo)
+    is det.
+
+summarize_proc_dynamic_with_coverage(PDOwnArray, PDDescArray, PDCompTableArray,
+        PDI, PD, !PSOwnArray, !PSDescArray, !CoverageArray) :-
+    summarize_proc_dynamic(PDOwnArray, PDDescArray, PDCompTableArray,
+        PDI, PD, !PSOwnArray, !PSDescArray),
+    PSPtr = PD ^ pd_proc_static,
+    MaybeDynamicCoverage = PD ^ pd_maybe_coverage_points,
+    (
+        MaybeDynamicCoverage = yes(DynamicCoverage),
+        some [!StaticCoverage] (
+            lookup_ps_coverage(!.CoverageArray, PSPtr, !:StaticCoverage),
+            add_coverage_arrays(DynamicCoverage, !StaticCoverage),
+            update_ps_coverage(PSPtr, !.StaticCoverage, !CoverageArray)
+        )
+    ;
+        MaybeDynamicCoverage = no,
+        error(this_file ++ "No coverage point array in proc dynamic")
+    ).
+
 %-----------------------------------------------------------------------------%
 
 :- pred summarize_call_site_dynamics(deep::in, deep::out) is det.
@@ -793,6 +872,35 @@ summarize_module_costs(Deep, ModuleData0
     list.foldl2(accumulate_ps_costs(Deep), PSPtrs, Own0, Own, Desc0, Desc),
     ModuleData = module_data(Own, Desc, PSPtrs).
 
+%----------------------------------------------------------------------------%
+
+:- pred summarize_proc_statics_coverage(deep::in, deep::out) is det.
+
+summarize_proc_statics_coverage(!Deep) :-
+    NPS = !.Deep ^ profile_stats ^ num_ps,
+    array_foldl_from_1(
+        summarize_proc_static_coverage,
+        !.Deep ^ proc_statics,
+        init(NPS, zero_static_coverage), CoverageArray),
+    !Deep ^ maybe_static_coverage := yes(CoverageArray).
+
+:- pred summarize_proc_static_coverage(int::in, proc_static::in, 
+    array(static_coverage_info)::array_di,
+    array(static_coverage_info)::array_uo) is det.
+
+summarize_proc_static_coverage(Index, PS, !CoverageArray) :-
+    MaybeCoverage = PS ^ ps_maybe_coverage_points,
+    (
+        MaybeCoverage = yes(Coverage0),
+        array_to_static_coverage(Coverage0, Coverage),
+        array.set(!.CoverageArray, Index, Coverage, !:CoverageArray)
+    ;
+        MaybeCoverage = no,
+        error(this_file ++ "No coverage data in proc static.")
+    ).
+
+%----------------------------------------------------------------------------%
+
 :- pred accumulate_ps_costs(deep::in, proc_static_ptr::in,
     own_prof_info::in, own_prof_info::out,
     inherit_prof_info::in, inherit_prof_info::out) is det.
@@ -999,5 +1107,11 @@ maybe_report_msg(yes(OutputStream), Msg,
 maybe_report_msg(no, _, !IO).
 
 %-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "startup.m".
+
+%-----------------------------------------------------------------------------%
 :- end_module startup.
 %-----------------------------------------------------------------------------%
Index: deep_profiler/var_use_analysis.m
===================================================================
RCS file: /home/mercury1/repository/mercury/deep_profiler/var_use_analysis.m,v
retrieving revision 1.3
diff -u -p -b -r1.3 var_use_analysis.m
--- deep_profiler/var_use_analysis.m	26 Aug 2010 06:29:27 -0000	1.3
+++ deep_profiler/var_use_analysis.m	21 Sep 2010 05:08:39 -0000
@@ -740,7 +740,7 @@ generic_vars_first_use(VarsPred, Deep, P
     create_proc_report(Deep, PSPtr, MaybeProcReport),
     (
         MaybeProcReport = ok(ProcReport),
-        create_procrep_coverage_report(Deep, PSPtr, MaybeProcRepCoverage),
+        create_static_procrep_coverage_report(Deep, PSPtr, MaybeProcRepCoverage),
         (
             MaybeProcRepCoverage = ok(ProcRepCoverageInfo),
             ProcRepCoverageInfo = procrep_coverage_info(_, ProcRep),
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 489 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20100922/7d7f0c46/attachment.sig>


More information about the reviews mailing list