[m-rev.] diff: Add extra data to the mdprof procedure report

Paul Bone pbone at csse.unimelb.edu.au
Sat Oct 20 23:12:20 AEDT 2012


Add extra data to the procedure report in the form of an extra row of data
in the table for the calls into the procedure from its parent call sites.
Note that since this report shows proc static data parent call sites are
defined as calls to the procedure from other procedures (they may include
mutual recursion).  As this may be a point of confusion this information is
only shown in developer mode.

report.m:
    As above.

    We also count the number of calls into this procedure, including the
    numbers of unique ProcStatic and ProcDynamic structures seen.
    The later is trivially the number of calls into the procedure.

create_report.m:
    Generate this data.

display_report.m:
    Handle the new report data.

display.m:
    So that we only show this table row in developer mode, add a new table
    row type (table_developer_row) that contains the real table row.

html_format.m:
    Handle the new table row type.

diff --git a/deep_profiler/create_report.m b/deep_profiler/create_report.m
index 8ea543f..e09b025 100644
--- a/deep_profiler/create_report.m
+++ b/deep_profiler/create_report.m
@@ -102,6 +102,7 @@
 :- import_module map.
 :- import_module pair.
 :- import_module require.
+:- import_module set.
 :- import_module string.
 :- import_module unit.
 
@@ -837,7 +838,16 @@ create_proc_report(Deep, PSPtr, MaybeProcReport) :-
         ProcCallSiteSummaryRowDatas = list.map(create_call_site_summary(Deep),
             CallSites),
 
-        ProcReport = proc_report(ProcSummaryRowData,
+        deep_lookup_proc_callers(Deep, PSPtr, CallerCSDPtrs0),
+        summarize_callers(Deep, CallerCSDPtrs0, PSPtr, set.init, SeenProcs,
+            0, NumDynamic, zero_own_prof_info, CallersOwn,
+            zero_inherit_prof_info, CallersInherit),
+        NumStatic = set.count(SeenProcs),
+        own_and_inherit_to_perf_row_data(Deep,
+            callers_counts(NumStatic, NumDynamic), CallersOwn,
+            CallersInherit, CallersSummaryRowData),
+
+        ProcReport = proc_report(CallersSummaryRowData, ProcSummaryRowData,
             ProcCallSiteSummaryRowDatas),
         MaybeProcReport = ok(ProcReport)
     ;
@@ -922,6 +932,38 @@ generate_call_site_callee_perf(Deep, CallerPSPtr, PSPtr - CSDPtrs)
         zero_own_prof_info, Own, zero_inherit_prof_info, Desc),
     CalleeProf = call_site_callee_perf(PSPtr, Own, Desc).
 
+:- pred summarize_callers(deep::in, list(call_site_dynamic_ptr)::in,
+    proc_static_ptr::in, set(proc_static_ptr)::in, set(proc_static_ptr)::out,
+    int::in, int::out, own_prof_info::in, own_prof_info::out,
+    inherit_prof_info::in, inherit_prof_info::out) is det.
+
+summarize_callers(Deep, CallerCSDPtrs0, CalleePSPtr, !PSSeen, !NumDynamic,
+        !Own, !Desc) :-
+    (
+        CallerCSDPtrs0 = []
+    ;
+        CallerCSDPtrs0 = [CSDPtr | CallerCSDPtrs],
+
+        deep_lookup_call_site_dynamics(Deep, CSDPtr, CSD),
+        CallerPDPtr = CSD ^ csd_caller,
+        deep_lookup_proc_dynamics(Deep, CallerPDPtr, CallerPD),
+        CallerPSPtr = CallerPD ^ pd_proc_static,
+        ( CallerPSPtr = CalleePSPtr ->
+            % exclude recursive calls.
+            true
+        ;
+            !:NumDynamic = !.NumDynamic + 1,
+            set.insert(CallerPSPtr, !PSSeen),
+            CSDOwn = CSD ^ csd_own_prof,
+            !:Own = add_own_to_own(!.Own, CSDOwn),
+            deep_lookup_csd_desc(Deep, CSDPtr, CSDInherit),
+            !:Desc = add_inherit_to_inherit(!.Desc, CSDInherit)
+        ),
+
+        summarize_callers(Deep, CallerCSDPtrs, CalleePSPtr, !PSSeen,
+            !NumDynamic, !Own, !Desc)
+    ).
+
 :- pred accumulate_csd_prof_info(deep::in, proc_static_ptr::in,
     call_site_dynamic_ptr::in,
     own_prof_info::in, own_prof_info::out,
@@ -1132,7 +1174,7 @@ create_dynamic_procrep_coverage_report(Deep, PDPtr, MaybeReport) :-
 
         % Gather call site information.
         proc_dynamic_paired_call_site_slots(Deep, PDPtr, Slots),
-        foldl(build_dynamic_call_site_cost_and_callee_map(Deep), Slots, 
+        foldl(build_dynamic_call_site_cost_and_callee_map(Deep), Slots,
             map.init, CallSitesMap),
 
         % Gather information about the procedure.
diff --git a/deep_profiler/display.m b/deep_profiler/display.m
index 9261784..e6b28e7 100644
--- a/deep_profiler/display.m
+++ b/deep_profiler/display.m
@@ -139,6 +139,9 @@
     ;       table_separator_row
     ;       table_section_header(
                 tsh_text        :: table_data
+            )
+    ;       table_developer_row(
+                tdr_row         :: table_row
             ).
 
 :- type table_cell
diff --git a/deep_profiler/display_report.m b/deep_profiler/display_report.m
index 757afbf..4483e48 100644
--- a/deep_profiler/display_report.m
+++ b/deep_profiler/display_report.m
@@ -1405,7 +1405,8 @@ scope_to_description(overall) = "overall".
     display::out) is det.
 
 display_report_proc(Deep, Prefs, ProcReport, Display) :-
-    ProcReport = proc_report(ProcSummaryRowData, CallSitePerfs0),
+    ProcReport = proc_report(CallersSummaryRowData, ProcSummaryRowData,
+        CallSitePerfs0),
     ProcDesc = ProcSummaryRowData ^ perf_row_subject,
     RefinedName = ProcDesc ^ pdesc_q_refined_name,
     Title = "Summary of procedure " ++ RefinedName,
@@ -1432,6 +1433,16 @@ display_report_proc(Deep, Prefs, ProcReport, Display) :-
         [SourceHeaderGroup, ProcHeaderGroup] ++ PerfHeaderGroups,
     header_groups_to_header(AllHeaderGroups, NumColumns, Header),
 
+    Fields = Prefs ^ pref_fields,
+    CallersCounts = CallersSummaryRowData ^ perf_row_subject,
+    CallersSummaryText = format("%d static & %d dynamic call sites",
+        [i(CallersCounts ^ cc_static), i(CallersCounts ^ cc_dynamic)]),
+    CallersSummaryCell = table_multi_cell(td_s(CallersSummaryText), 2),
+    perf_table_row(total_columns_meaningful, Fields, CallersSummaryRowData,
+        CallersPerfCells),
+    CallersCells = [CallersSummaryCell] ++ CallersPerfCells,
+    CallersRow = table_row(CallersCells),
+
     % We could make SummaryProcCell a link, but the only link that would make
     % sense (and the link that pre-display versions of the deep profiler
     % generated) point back to this page itself, which is not useful and
@@ -1440,7 +1451,6 @@ display_report_proc(Deep, Prefs, ProcReport, Display) :-
     % SummaryProcCell spans two columns: the ones that contain (1) the context
     % and (2) the callee of each call site in the rows below.
     SummaryProcCell = table_multi_cell(td_s(RefinedName), 2),
-    Fields = Prefs ^ pref_fields,
     perf_table_row(total_columns_meaningful, Fields, ProcSummaryRowData,
         SummaryPerfCells),
     SummaryCells = [SummaryProcCell] ++ SummaryPerfCells,
@@ -1454,7 +1464,12 @@ display_report_proc(Deep, Prefs, ProcReport, Display) :-
         report_proc_call_site(MaybeCurModuleName, ModuleQual, Prefs),
         CallSitePerfs),
     list.condense(CallSiteRowLists, CallSiteRows),
-    AllRows = [SummaryRow, table_separator_row] ++ CallSiteRows,
+    DeveloperRows = map(func(X) = table_developer_row(X),
+        [table_section_header(td_s(
+            "Callers excluding directly-recursive calls")),
+        CallersRow, table_separator_row]),
+    CommonRows = [SummaryRow, table_separator_row] ++ CallSiteRows,
+    AllRows = DeveloperRows ++ CommonRows,
     Table = table(table_class_box_if_pref, NumColumns, yes(Header), AllRows),
     DisplayTable = display_table(Table),
 
diff --git a/deep_profiler/html_format.m b/deep_profiler/html_format.m
index 502f9f7..a01b541 100644
--- a/deep_profiler/html_format.m
+++ b/deep_profiler/html_format.m
@@ -463,6 +463,17 @@ table_row_to_html(FormatInfo, MaybeColClassMap, NumColumns, !StyleControlMap,
         map_join_html_count(table_cell_to_html(FormatInfo, MaybeColClassMap),
             !StyleControlMap, 0, Cells, InnerHTML),
         HTML = wrap_tags("<tr>\n", "</tr>\n", InnerHTML)
+    ;
+        TableRow = table_developer_row(RealTableRow),
+        Developer = FormatInfo ^ fi_pref_developer,
+        (
+            Developer = developer_options_visible,
+            table_row_to_html(FormatInfo, MaybeColClassMap, NumColumns,
+                !StyleControlMap, RealTableRow, HTML)
+        ;
+            Developer = developer_options_invisible,
+            HTML = cord.empty
+        )
     ).
 
 %-----------------------------------------------------------------------------%
diff --git a/deep_profiler/report.m b/deep_profiler/report.m
index a40375d..7986a52 100644
--- a/deep_profiler/report.m
+++ b/deep_profiler/report.m
@@ -375,12 +375,23 @@
 
 :- type proc_report
     --->    proc_report(
-                % The proc description is inside the proc_summary field.
+                % The integer is a count of the number of cliques this
+                % procedure appears in.
+                proc_callers_summary        :: perf_row_data(callers_counts),
 
+                % The proc description is inside the proc_summary field.
                 proc_summary                :: perf_row_data(proc_desc),
                 proc_call_site_summaries    :: list(call_site_perf)
             ).
 
+    % A count of the number of callers.
+    %
+:- type callers_counts
+    --->    callers_counts(
+                cc_static                   :: int,
+                cc_dynamic                  :: int
+            ).
+
 :- type call_site_perf
     --->    call_site_perf(
                 % The csf_summary_perf field contains the description of this
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: Digital signature
URL: <http://lists.mercurylang.org/archives/reviews/attachments/20121020/10b48ae0/attachment.sig>


More information about the reviews mailing list