[m-rev.] for post-commit review: break up mdprog_feedback

Zoltan Somogyi zs at csse.unimelb.edu.au
Mon Sep 26 15:36:50 AEST 2011


The concept has been discussed and approved, and the details are trivial.
The only thing I am seeking feedback on are the texts of the two help
messages.

Zoltan.

Replace mdprof_feedback, which currently does two jobs, with
mdprof_create_feedback and mdprof_report_feedback, which do one job each.

deep_profiler/mdprof_feedback.m:
	Remove this module.

deep_profiler/mdprof_create_feedback.m:
deep_profiler/mdprof_report_feedback.m:
	Add these two modules. mdprof_create_feedback.m contains most of the
	code originally in mdprof_feedback.m, while mdprof_report_feedback.m
	contains only the code needed for printing out reports.m

deep_profiler/autopar_reports.m:
	Move here some code that would otherwise hav to duplicated in
	mdprof_create_feedback.m and mdprof_report_feedback.m.

	Keep private the previously exported predicates that are not needed
	outside this module after the above move.

deep_profiler/Mmakefile:
	Replace references to the deleted module with references to the new
	modules.

doc/user_guide.texi:
	Update the only reference to mdprof_feedback in this directory.

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/extra
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/extra
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/doc
cvs diff: Diffing boehm_gc/libatomic_ops/src
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/armcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops/tests
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/tests
cvs diff: Diffing boehm_gc/m4
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
cvs diff: Diffing compiler/notes
cvs diff: Diffing deep_profiler
Index: deep_profiler/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/Mmakefile,v
retrieving revision 1.40
diff -u -b -r1.40 Mmakefile
--- deep_profiler/Mmakefile	27 Jan 2011 02:53:46 -0000	1.40
+++ deep_profiler/Mmakefile	26 Sep 2011 04:50:06 -0000
@@ -38,7 +38,8 @@
 	mdprof_cgi \
 	mdprof_test \
 	mdprof_dump \
-	mdprof_feedback \
+	mdprof_create_feedback \
+	mdprof_report_feedback \
 	mdprof_procrep
 
 # Always compile the deep profiler, even if it is not enabled.
@@ -135,8 +136,10 @@
 mdprof_test:		$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
 mdprof_dump:		$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
 mdprof_dump:		$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
-mdprof_feedback:	$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
-mdprof_feedback:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
+mdprof_create_feedback:	$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_create_feedback:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
+mdprof_report_feedback:	$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
+mdprof_report_feedback:	$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
 mdprof_procrep:		$(RUNTIME_DIR)/lib$(RT_LIB_NAME).$A
 mdprof_procrep:		$(LIBRARY_DIR)/lib$(STD_LIB_NAME).$A
 # XXX Should also depend on $(BOEHM_GC_DIR)/libgc(_prof).$A, but only
@@ -146,7 +149,8 @@
 $(cs_subdir)mdprof_cgi_init.c:		$(UTIL_DIR)/mkinit
 $(cs_subdir)mdprof_test_init.c:		$(UTIL_DIR)/mkinit
 $(cs_subdir)mdprof_dump_init.c:		$(UTIL_DIR)/mkinit
-$(cs_subdir)mdprof_feedback_init.c: 	$(UTIL_DIR)/mkinit
+$(cs_subdir)mdprof_create_feedback_init.c: 	$(UTIL_DIR)/mkinit
+$(cs_subdir)mdprof_report_feedback_init.c: 	$(UTIL_DIR)/mkinit
 $(cs_subdir)mdprof_procrep_init.c:	$(UTIL_DIR)/mkinit
 
 #-----------------------------------------------------------------------------#
@@ -171,7 +175,8 @@
 	$(mdprof_cgi.ms) \
 	$(mdprof_test.ms) \
 	$(mdprof_dump.ms) \
-	$(mdprof_feedback.ms) \
+	$(mdprof_create_feedback.ms) \
+	$(mdprof_report_feedback.ms) \
 	$(mdprof_procrep.ms)
 
 .deep_tags: $(MTAGS) $(DEEP_MS) \
@@ -191,8 +196,12 @@
 
 .PHONY: dates
 dates:
-	touch $(mdprof_cgi.dates) $(mdprof_test.dates) $(mdprof_dump.dates) \
-		$(mdprof_feedback.dates) $(mdprof_procrep.dates)
+	touch 	$(mdprof_cgi.dates) \
+		$(mdprof_test.dates) \
+		$(mdprof_dump.dates) \
+		$(mdprof_create_feedback.dates) \
+		$(mdprof_report_feedback.dates) \
+		$(mdprof_procrep.dates)
 
 #-----------------------------------------------------------------------------#
 
@@ -200,12 +209,14 @@
 os: $(mdprof_cgi.os) $(os_subdir)mdprof_cgi_init.o
 os: $(mdprof_test.os) $(os_subdir)mdprof_test_init.o
 os: $(mdprof_dump.os) $(os_subdir)mdprof_dump_init.o
-os: $(mdprof_feedback.os) $(os_subdir)mdprof_feedback_init.o
+os: $(mdprof_create_feedback.os) $(os_subdir)mdprof_create_feedback_init.o
+os: $(mdprof_report_feedback.os) $(os_subdir)mdprof_report_feedback_init.o
 os: $(mdprof_procrep.os) $(os_subdir)mdprof_procrep_init.o
 cs: $(mdprof_cgi.cs) $(cs_subdir)mdprof_cgi_init.c
 cs: $(mdprof_test.cs) $(cs_subdir)mdprof_test_init.c
 cs: $(mdprof_dump.cs) $(cs_subdir)mdprof_dump_init.c
-cs: $(mdprof_feedback.cs) $(cs_subdir)mdprof_feedback_init.c
+cs: $(mdprof_create_feedback.cs) $(cs_subdir)mdprof_create_feedback_init.c
+cs: $(mdprof_report_feedback.cs) $(cs_subdir)mdprof_report_feedback_init.c
 cs: $(mdprof_procrep.cs) $(cs_subdir)mdprof_procrep_init.c
 
 #-----------------------------------------------------------------------------#
@@ -228,7 +239,8 @@
 # by different paths.
 
 .PHONY: install_cgi_progs
-install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test mdprof_feedback
+install_cgi_progs: mdprof_cgi mdprof_dump mdprof_test \
+	mdprof_create_feedback mdprof_report_feedback
 	# $(INSTALL_CGI_DIR) is likely to be writeable only by root or
 	# the www system administrator, which is why we don't consider a
 	# failure of this action to be an error. If the command fails,
@@ -262,8 +274,10 @@
 		$(INSTALL_MERC_BIN_DIR)/mdprof_test
 	cp `vpath_find mdprof_dump$(EXT_FOR_EXE)` \
 		$(INSTALL_MERC_BIN_DIR)/mdprof_dump
-	cp `vpath_find mdprof_feedback$(EXT_FOR_EXE)` \
-		$(INSTALL_MERC_BIN_DIR)/mdprof_feedback
+	cp `vpath_find mdprof_create_feedback$(EXT_FOR_EXE)` \
+		$(INSTALL_MERC_BIN_DIR)/mdprof_create_feedback
+	cp `vpath_find mdprof_report_feedback$(EXT_FOR_EXE)` \
+		$(INSTALL_MERC_BIN_DIR)/mdprof_report_feedback
 
 uninstall:
 	# We try to uninstall mdprof_cgi, but failure to do so is not an
Index: deep_profiler/autopar_reports.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/deep_profiler/autopar_reports.m,v
retrieving revision 1.2
diff -u -b -r1.2 autopar_reports.m
--- deep_profiler/autopar_reports.m	16 Apr 2011 03:13:04 -0000	1.2
+++ deep_profiler/autopar_reports.m	26 Sep 2011 05:25:33 -0000
@@ -21,17 +21,11 @@
 :- import_module mdbcomp.feedback.automatic_parallelism.
 :- import_module mdbcomp.program_representation.
 
-:- import_module assoc_list.
 :- import_module cord.
-:- import_module pair.
-
-:- pred create_feedback_autopar_report(candidate_par_conjunctions_params::in,
-    assoc_list(string_proc_label, candidate_par_conjunctions_proc)::in,
-    string::out) is det.
+:- import_module io.
 
-:- pred create_candidate_parallel_conj_proc_report(
-    pair(string_proc_label, candidate_par_conjunctions_proc)::in,
-    cord(string)::out) is det.
+:- pred print_feedback_report(string::in, feedback_info::in, io::di, io::uo)
+    is det.
 
 :- pred create_candidate_parallel_conj_report(var_table::in,
     candidate_par_conjunction(pard_goal)::in, cord(string)::out) is det.
@@ -51,6 +45,7 @@
 :- import_module int.
 :- import_module list.
 :- import_module maybe.
+:- import_module pair.
 :- import_module require.
 :- import_module set.
 :- import_module std_util.
@@ -58,6 +53,32 @@
 
 %----------------------------------------------------------------------------%
 
+print_feedback_report(ProgName, Feedback, !IO) :-
+    get_all_feedback_data(Feedback, AllFeedback),
+    list.map(create_feedback_report, AllFeedback, Reports),
+    ReportStr = string.append_list(Reports),
+    io.format("Feedback report for %s:\n\n%s", [s(ProgName), s(ReportStr)],
+        !IO).
+
+:- pred create_feedback_report(feedback_data::in, string::out) is det.
+
+create_feedback_report(FeedbackData, Report) :-
+    (
+        FeedbackData = feedback_data_calls_above_threshold_sorted(_, _, _),
+        Report =
+            "  feedback_data_calls_above_threshold_sorted is not supported\n"
+    ;
+        FeedbackData = feedback_data_candidate_parallel_conjunctions(
+            Parameters, Conjs),
+        create_feedback_autopar_report(Parameters, Conjs, Report)
+    ).
+
+%----------------------------------------------------------------------------%
+
+:- pred create_feedback_autopar_report(candidate_par_conjunctions_params::in,
+    assoc_list(string_proc_label, candidate_par_conjunctions_proc)::in,
+    string::out) is det.
+
 create_feedback_autopar_report(Parameters, ProcConjs, Report) :-
     NumProcConjs = length(ProcConjs),
     foldl(count_conjunctions_in_procs, ProcConjs, 0, NumConjs),
@@ -124,18 +145,26 @@
 :- pred count_conjunctions_in_procs(
     pair(T, candidate_par_conjunctions_proc)::in, int::in, int::out) is det.
 
-count_conjunctions_in_procs(_ -
-        candidate_par_conjunctions_proc(_VarTable, _Pushes, Conjs), !NumConjs) :-
+count_conjunctions_in_procs(_ - Cands, !NumConjs) :-
+    Cands = candidate_par_conjunctions_proc(_VarTable, _Pushes, Conjs),
     !:NumConjs = !.NumConjs + length(Conjs).
 
 :- pred best_par_algorithm_string(best_par_algorithm::in, string::out) is det.
 
-best_par_algorithm_string(bpa_greedy, "greedy").
-best_par_algorithm_string(bpa_complete_branches(N),
-    format("complete-branches(%d)", [i(N)])).
-best_par_algorithm_string(bpa_complete_size(N),
-    format("complete-size(%d)", [i(N)])).
-best_par_algorithm_string(bpa_complete, "complete").
+best_par_algorithm_string(Alg, Str) :-
+    (
+        Alg = bpa_greedy,
+        Str = "greedy"
+    ;
+        Alg = bpa_complete_branches(N),
+        Str = string.format("complete-branches(%d)", [i(N)])
+    ;
+        Alg = bpa_complete_size(N),
+        Str = string.format("complete-size(%d)", [i(N)])
+    ;
+        Alg = bpa_complete,
+        Str = "complete"
+    ).
 
 create_candidate_parallel_conj_proc_report(Proc - CandidateParConjunctionProc,
         Report) :-
@@ -145,9 +174,7 @@
     list.map(create_push_goal_report, PushGoals, PushGoalReports),
     list.map(create_candidate_parallel_conj_report(VarTable),
         CandidateParConjunctions, CandidateParConjunctionReports),
-    Header = string.format(
-        "    %s\n",
-        [s(ProcString)]),
+    Header = string.format("    %s\n", [s(ProcString)]),
     Report = cord.singleton(Header) ++
         cord_list_to_cord(PushGoalReports) ++
         cord.singleton("\n") ++
@@ -166,6 +193,10 @@
     TailPushGoalStrs = list.map(FormatPushedGoals, PushedGoalPathStrs),
     Report = cord.from_list([HeadPushGoalStr | TailPushGoalStrs]).
 
+:- pred create_candidate_parallel_conj_proc_report(
+    pair(string_proc_label, candidate_par_conjunctions_proc)::in,
+    cord(string)::out) is det.
+
 create_candidate_parallel_conj_report(VarTable, CandidateParConjunction,
         Report) :-
     CandidateParConjunction = candidate_par_conjunction(GoalPathString,
@@ -188,9 +219,7 @@
     TimeSaving = parallel_exec_metrics_get_time_saving(ParExecMetrics),
     TotalDeadTime = FirstConjDeadTime + FutureDeadTime,
 
-    string.format(
-        "      Path: %s\n",
-        [s(GoalPathString)], Header1Str),
+    string.format("      Path: %s\n", [s(GoalPathString)], Header1Str),
     Header1 = cord.singleton(Header1Str),
 
     (
Index: deep_profiler/mdprof_create_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_create_feedback.m
diff -N deep_profiler/mdprof_create_feedback.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ deep_profiler/mdprof_create_feedback.m	26 Sep 2011 05:21:39 -0000
@@ -0,0 +1,722 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2006-2011 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: mdprof_create_feedback.m.
+% Author: tannier, pbone.
+%
+% This module contains code for generating feedback files that tell the
+% compiler things such as which conjunctions can be profitably parallelised.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mdprof_create_feedback.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module conf.
+:- import_module mdbcomp.
+:- import_module mdbcomp.feedback.
+:- import_module mdbcomp.feedback.automatic_parallelism.
+:- import_module mdprof_fb.
+:- import_module mdprof_fb.automatic_parallelism.
+:- import_module mdprof_fb.automatic_parallelism.autopar_search_callgraph.
+:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
+:- import_module message.
+:- import_module profile.
+:- import_module startup.
+
+:- import_module bool.
+:- import_module char.
+:- import_module cord.
+:- import_module float.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module parsing_utils.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+%
+% This section contains the main predicate as well as code to read the deep
+% profiling data and display usage and version messages to the user.
+%
+
+main(!IO) :-
+    io.progname_base("mdprof_create_feedback", ProgName, !IO),
+    io.command_line_arguments(Args0, !IO),
+    getopt.process_options(option_ops_multi(short, long, defaults),
+        Args0, Args, MaybeOptions),
+    io.stderr_stream(Stderr, !IO),
+    (
+        MaybeOptions = ok(Options0),
+        post_process_options(ProgName, Options0, Options, !IO),
+        lookup_bool_option(Options, help, Help),
+        lookup_bool_option(Options, version, Version),
+        ( Version = yes ->
+            write_version_message(ProgName, !IO)
+        ; Help = yes ->
+            write_help_message(ProgName, !IO)
+        ;
+            (
+                Args = [InputFileName, OutputFileName],
+                get_feedback_requests(ProgName, Options, FoundError,
+                    RequestedFeedbackInfo, !IO),
+                (
+                    FoundError = have_not_found_error,
+                    generate_requested_feedback(ProgName, Options,
+                        InputFileName, OutputFileName, RequestedFeedbackInfo,
+                        !IO)
+                ;
+                    FoundError = found_error
+                    % The error message have already been printed.
+                )
+            ;
+                ( Args = []
+                ; Args = [_]
+                ; Args = [_, _, _ | _]
+                ),
+                write_help_message(ProgName, !IO),
+                io.set_exit_status(1, !IO)
+            )
+        )
+    ;
+        MaybeOptions = error(Msg),
+        io.format(Stderr, "%s: error parsing options: %s\n",
+            [s(ProgName), s(Msg)], !IO),
+        write_help_message(ProgName, !IO),
+        io.set_exit_status(1, !IO)
+    ).
+
+:- pred generate_requested_feedback(string::in, option_table(option)::in,
+    string::in, string::in, requested_feedback_info::in, io::di, io::uo)
+    is det.
+
+generate_requested_feedback(ProgName, Options, InputFileName, OutputFileName,
+        RequestedFeedbackInfo, !IO) :-
+    io.stderr_stream(Stderr, !IO),
+    RequestedFeedbackInfo = requested_feedback_info(MaybeParallelize),
+    (
+        MaybeParallelize = yes(_),
+        lookup_bool_option(Options, debug_read_profile, DebugReadProfile),
+        lookup_bool_option(Options, report, Report),
+        read_deep_file(InputFileName, DebugReadProfile, MaybeDeep, !IO),
+        (
+            MaybeDeep = ok(Deep),
+            ProfileProgName = Deep ^ profile_stats ^ prs_program_name,
+            feedback.read_or_create(OutputFileName, ProfileProgName,
+                FeedbackReadResult, !IO),
+            (
+                FeedbackReadResult = ok(Feedback0),
+                process_deep_to_feedback(RequestedFeedbackInfo,
+                    Deep, Messages, Feedback0, Feedback),
+                (
+                    Report = yes,
+                    print_feedback_report(ProfileProgName, Feedback, !IO)
+                ;
+                    Report = no
+                ),
+                write_feedback_file(OutputFileName, ProfileProgName,
+                    Feedback, WriteResult, !IO),
+                (
+                    WriteResult = ok
+                ;
+                    ( WriteResult = open_error(Error)
+                    ; WriteResult = write_error(Error)
+                    ),
+                    io.error_message(Error, ErrorMessage),
+                    io.format(Stderr, "%s: %s: %s\n",
+                        [s(ProgName), s(OutputFileName), s(ErrorMessage)],
+                        !IO),
+                    io.set_exit_status(1, !IO)
+                ),
+                lookup_int_option(Options, verbosity, VerbosityLevel),
+                set_verbosity_level(VerbosityLevel, !IO),
+                write_out_messages(Stderr, Messages, !IO)
+            ;
+                FeedbackReadResult = error(FeedbackReadError),
+                feedback.read_error_message_string(OutputFileName,
+                    FeedbackReadError, Message),
+                io.write_string(Stderr, Message, !IO),
+                io.set_exit_status(1, !IO)
+            )
+        ;
+            MaybeDeep = error(Error),
+            io.set_exit_status(1, !IO),
+            io.format(Stderr, "%s: error reading %s: %s\n",
+                [s(ProgName), s(InputFileName), s(Error)], !IO)
+        )
+    ;
+        MaybeParallelize = no,
+        io.format(Stderr, "%s: options do not request any form of feedback\n",
+            [s(ProgName)], !IO)
+    ).
+
+:- func help_message(string) = string.
+
+help_message(ProgName) = HelpMessage :-
+    FormatStr =
+"Usage: %s [<options>] <profdatafile> <feedbackfile>
+    This command generates feedback information from profiling data.
+
+    The first argument must name a deep profiling data file such as Deep.data.
+    The second argument should be the name of the file into which this command
+    should put the feedback information it generates.
+
+    You may specify the following general options:
+
+    -h --help       Generate this help message.
+    -V --version    Report the program's version number.
+    -v --verbosity  <0-4>
+                    Generate messages.  The higher the argument, the more
+                    verbose the program becomes.  2 is recommended and the
+                    default.
+    --debug-read-profile
+                    Generate debugging messages when reading the deep profile
+                    and creating the deep structure.
+    --no-report     Suppress the report about the feedback information in the
+                    file that is usually displayed after any processing has
+                    been done.
+
+    The following options select sets of feedback information useful
+    for particular compiler optimizations:
+
+    --implicit-parallelism
+                Generate information that the compiler can use for automatic
+                parallelization.
+    --desired-parallelism <value>
+                The amount of desired parallelism for implicit parallelism,
+                which must be a floating point number above 1.0.
+                Note: This option is currently ignored.
+    --implicit-parallelism-intermodule-var-use
+                Assume that the compiler will be able to push signals and waits
+                for futures across module boundaries.
+    --ipar-sparking-cost <value>
+                The cost of creating a spark, measured in the deep profiler's
+                call sequence counts.
+    --ipar-sparking-delay <value>
+                The time taken from the time a spark is created until the spark
+                is executed by another processor, assuming that there is a free
+                processor.
+    --ipar-barrier-cost <value>
+                The cost of executing the barrier code at the end of each
+                parallel conjunct.
+    --ipar-future-signal-cost <value>
+                The cost of the signal() call for the producer of a shared
+                variable, measured in the profiler's call sequence counts.
+    --ipar-future-wait-cost <value>
+                The cost of the wait() call for the consumer of a shared
+                variable, measured in the profiler's call sequence counts.
+    --ipar-context-wakeup-delay <value>
+                The time taken for a context to resume execution after being
+                placed on the run queue.  This is used to estimate the impact
+                of blocking of a context's execution, it is measured in the
+                profiler's call sequence counts.
+    --ipar-clique-cost-threshold <value>
+                The cost threshold for cliques to be considered for implicit
+                parallelism, measured on the profiler's call sequence counts.
+    --ipar-call-site-cost-threshold <value>
+                The cost of a call site to be considered for parallelism
+                against another call site.
+    --no-ipar-dep-conjs
+                Disable parallelisation of dependent conjunctions.
+    --ipar-speedup-alg <alg>
+                Choose the algorithm that is used to estimate the speedup for
+                dependent calculations.  The available algorithms are:
+                    overlap: Compute the overlap between dependent
+                      conjunctions.
+                    num_vars: Use the number of shared variables as a proxy for
+                      the amount of overlap available.
+                    naive: Ignore dependencies.
+                The default is overlap.
+    --ipar-speedup-threshold <value>
+                The threshold that a speedup ratio must meet before the
+                feedback tool will accept a parallelization. It must be
+                a floating point number, which must be at least 1.0.
+                If it is e.g. 1.02, then the feedback tool will ignore
+                parallelizations that promise less than a 2%% local speedup.
+    --ipar-best-par-alg <alg>
+                Select which algorithm to use to find the best way to
+                parallelise a conjunction.  The available algorithms are:
+                    greedy: A greedy algorithm with a linear time complexity.
+                    complete: A complete algorithm with a branch and bound
+                      search. This can be slow for problems larger than 50
+                      conjuncts, since it has an exponential complexity.
+                    complete-size(N): As above exept that it takes a single
+                      parameter, N.  If a conjunction has more than N
+                      conjuncts, then the greedy algorithm will be used.
+                    complete-branches(N): The same as the complete algorithm,
+                      except that it allows at most N branches to be created
+                      during the search.  Once N branches have been created,
+                      a greedy search is used on each open branch.
+                The default is complete-branches(1000).
+
+    The following options select specific types of feedback information
+    and parameterise them:
+
+    --candidate-parallel-conjunctions
+                Produce a list of candidate parallel conjunctions for implicit
+                parallelism.  This option uses the implicit parallelism
+                settings above.
+
+",
+    HelpMessage = string.format(FormatStr, [s(ProgName)]).
+
+:- pred write_help_message(string::in, io::di, io::uo) is det.
+
+write_help_message(ProgName, !IO) :-
+    io.write_string(help_message(ProgName), !IO).
+
+:- pred write_version_message(string::in, io::di, io::uo) is det.
+
+write_version_message(ProgName, !IO) :-
+    library.version(Version),
+    io.format("%s: Mercury deep profiler\n%s\n",
+        [s(ProgName), s(Version)], !IO).
+
+    % Read a deep profiling data file.
+    %
+:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
+    io::di, io::uo) is det.
+
+read_deep_file(Input, Debug, MaybeDeep, !IO) :-
+    server_name_port(Machine, !IO),
+    script_name(ScriptName, !IO),
+    (
+        Debug = yes,
+        io.stdout_stream(Stdout, !IO),
+        MaybeOutput = yes(Stdout)
+    ;
+        Debug = no,
+        MaybeOutput = no
+    ),
+    read_and_startup_default_deep_options(Machine, ScriptName, Input, no,
+        MaybeOutput, [], MaybeDeep, !IO).
+
+%----------------------------------------------------------------------------%
+%
+% This section describes and processes command line options. Individual
+% feedback information can be requested by the user, as well as options named
+% after optimizations that may imply one or more feedback inforemation types,
+% which that optimization uses.
+%
+
+    % Command line options.
+    %
+:- type option
+    --->    help
+    ;       version
+    ;       verbosity
+    ;       debug_read_profile
+    ;       report
+
+            % A list of candidate parallel conjunctions is produced for the new
+            % implicit parallelism implementation.
+    ;       candidate_parallel_conjunctions
+
+            % Provide suitable feedback information for implicit parallelism
+    ;       implicit_parallelism
+    ;       desired_parallelism
+    ;       ipar_intermodule_var_use
+    ;       ipar_sparking_cost
+    ;       ipar_sparking_delay
+    ;       ipar_barrier_cost
+    ;       ipar_future_signal_cost
+    ;       ipar_future_wait_cost
+    ;       ipar_context_wakeup_delay
+    ;       ipar_clique_cost_threshold
+    ;       ipar_call_site_cost_threshold
+    ;       ipar_speedup_threshold
+    ;       ipar_dep_conjs
+    ;       ipar_speedup_alg
+    ;       ipar_best_par_alg.
+
+% TODO: Introduce an option to disable parallelisation of dependent
+% conjunctions, or switch to the simple calculations for independent
+% conjunctions.
+
+:- pred short(char::in, option::out) is semidet.
+
+short('h',  help).
+short('v',  verbosity).
+short('V',  version).
+
+:- pred long(string::in, option::out) is semidet.
+
+long("help",
+    help).
+long("verbosity",
+    verbosity).
+long("version",
+    version).
+long("debug-read-profile",
+    debug_read_profile).
+long("report",
+    report).
+long("candidate-parallel-conjunctions",
+    candidate_parallel_conjunctions).
+long("implicit-parallelism",
+    implicit_parallelism).
+long("desired-parallelism",
+    desired_parallelism).
+long("implicit-parallelism-intermodule-var-use",
+    ipar_intermodule_var_use).
+long("ipar-intermodule-var-use",
+    ipar_intermodule_var_use).
+long("implicit-parallelism-sparking-cost",
+    ipar_sparking_cost).
+long("ipar-sparking-cost",
+    ipar_sparking_cost).
+long("implicit-parallelism-sparking-delay",
+    ipar_sparking_delay).
+long("ipar-sparking-delay",
+    ipar_sparking_delay).
+long("implicit-parallelism-future-signal-cost",
+    ipar_future_signal_cost).
+long("ipar-future-signal-cost",
+    ipar_future_signal_cost).
+long("implicit-parallelism-barrier-cost",
+    ipar_barrier_cost).
+long("ipar-barrier-cost",
+    ipar_barrier_cost).
+long("implicit-parallelism-future-wait-cost",
+    ipar_future_wait_cost).
+long("ipar-future-wait-cost",
+    ipar_future_wait_cost).
+long("implicit-parallelism-context-wakeup-delay",
+    ipar_context_wakeup_delay).
+long("ipar-context-wakeup-delay",
+    ipar_context_wakeup_delay).
+long("implicit-parallelism-clique-cost-threshold",
+    ipar_clique_cost_threshold).
+long("ipar-clique-cost-threshold",
+    ipar_clique_cost_threshold).
+long("implicit-parallelism-call-site-cost-threshold",
+    ipar_call_site_cost_threshold).
+long("ipar-call-site-cost-threshold",
+    ipar_call_site_cost_threshold).
+long("implicit-parallelism-dependant-conjunctions",
+    ipar_dep_conjs).
+long("ipar-dep-conjs",
+    ipar_dep_conjs).
+long("implicit-parallelism-dependant-conjunctions-algorithm",
+    ipar_speedup_alg).
+long("ipar-speedup-alg",
+    ipar_speedup_alg).
+long("implicit-parallelism-speedup-threshold",
+    ipar_speedup_threshold).
+long("ipar-speedup-threshold",
+    ipar_speedup_threshold).
+long("implicit-parallelism-best-parallelisation-algorithm",
+    ipar_best_par_alg).
+long("ipar-best-par-alg",
+    ipar_best_par_alg).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(help,                              bool(no)).
+defaults(verbosity,                         int(2)).
+defaults(version,                           bool(no)).
+defaults(debug_read_profile,                bool(no)).
+defaults(report,                            bool(yes)).
+
+defaults(candidate_parallel_conjunctions,   bool(no)).
+
+defaults(implicit_parallelism,              bool(no)).
+defaults(desired_parallelism,               string("8.0")).
+% XXX: These values have been chosen arbitrarily; we should set them
+% based on measurements.
+defaults(ipar_intermodule_var_use,          bool(no)).
+defaults(ipar_sparking_cost,                int(100)).
+defaults(ipar_sparking_delay,               int(1000)).
+defaults(ipar_barrier_cost,                 int(100)).
+defaults(ipar_future_signal_cost,           int(100)).
+defaults(ipar_future_wait_cost,             int(200)).
+defaults(ipar_context_wakeup_delay,         int(1000)).
+defaults(ipar_clique_cost_threshold,        int(2000)).
+defaults(ipar_call_site_cost_threshold,     int(2000)).
+defaults(ipar_dep_conjs,                    bool(yes)).
+defaults(ipar_speedup_threshold,            string("1.01")).
+defaults(ipar_speedup_alg,                  string("overlap")).
+defaults(ipar_best_par_alg,                 string("complete-branches(1000)")).
+
+:- pred construct_measure(string::in, stat_measure::out) is semidet.
+
+construct_measure("mean",       stat_mean).
+construct_measure("median",     stat_median).
+
+:- pred post_process_options(string::in,
+    option_table(option)::in, option_table(option)::out,
+    io::di, io::uo) is det.
+
+post_process_options(ProgName, !Options, !IO) :-
+    lookup_int_option(!.Options, verbosity, VerbosityLevel),
+    io.stderr_stream(Stderr, !IO),
+    ( VerbosityLevel < 0 ->
+        io.format(Stderr,
+            "%s: warning: verbosity level should not be negative.\n",
+            [s(ProgName)], !IO),
+        set_option(verbosity, int(0), !Options)
+    ; VerbosityLevel > 4 ->
+        io.format(Stderr,
+            "%s: warning: verbosity level should not exceed 4.\n",
+            [s(ProgName)], !IO),
+        set_option(verbosity, int(4), !Options)
+    ;
+        true
+    ),
+    lookup_bool_option(!.Options, implicit_parallelism, ImplicitParallelism),
+    (
+        ImplicitParallelism = yes,
+        set_option(candidate_parallel_conjunctions, bool(yes), !Options)
+    ;
+        ImplicitParallelism = no
+    ).
+
+    % This type defines the set of feedback_types that are to be calculated and
+    % put into the feedback info file. They should correspond with the values
+    % of feedback_type.
+    %
+:- type requested_feedback_info
+    --->    requested_feedback_info(
+                rfi_parallel    :: maybe(candidate_par_conjunctions_params)
+            ).
+
+:- type maybe_found_error
+    --->    have_not_found_error
+    ;       found_error.
+
+    % Check all the command line options, and return a representation
+    % of the user's request.
+    %
+:- pred get_feedback_requests(string::in, option_table(option)::in,
+    maybe_found_error::out, requested_feedback_info::out,
+    io::di, io::uo) is det.
+
+get_feedback_requests(ProgName, Options, !:Error, Requested, !IO) :-
+    io.stderr_stream(Stderr, !IO),
+    !:Error = have_not_found_error,
+    % For each feedback type, determine if it is requested, and fill in the
+    % field in the RequestedFeedbackInfo structure.
+    lookup_bool_option(Options, candidate_parallel_conjunctions,
+        CandidateParallelConjunctions),
+    (
+        CandidateParallelConjunctions = yes,
+        lookup_string_option(Options, desired_parallelism,
+            DesiredParallelismStr),
+        ( string.to_float(DesiredParallelismStr, DesiredParallelismPrime) ->
+            DesiredParallelism = DesiredParallelismPrime,
+            ( DesiredParallelism > 1.0 ->
+                true
+            ;
+                io.format(Stderr,
+                    "%s: error: desired parallelism level should be > 1.\n",
+                    [s(ProgName)], !IO),
+                !:Error = found_error
+            )
+        ;
+            io.format(Stderr,
+                "%s: error: desired parallelism level should be a number.\n",
+                [s(ProgName)], !IO),
+            !:Error = found_error,
+            DesiredParallelism = 1.0        % dummy value
+        ),
+        lookup_string_option(Options, ipar_speedup_threshold,
+            SpeedupThresholdStr),
+        ( string.to_float(SpeedupThresholdStr, SpeedupThresholdPrime) ->
+            SpeedupThreshold = SpeedupThresholdPrime,
+            ( SpeedupThreshold >= 1.0 ->
+                true
+            ;
+                io.format(Stderr,
+                    "%s: error: speedup threshold should be >= 1.\n",
+                    [s(ProgName)], !IO),
+                !:Error = found_error
+            )
+        ;
+            io.format(Stderr,
+                "%s: error: speedup threshold should be a number.\n",
+                [s(ProgName)], !IO),
+            !:Error = found_error,
+            SpeedupThreshold = 1.0        % dummy value
+        ),
+        lookup_bool_option(Options, ipar_intermodule_var_use,
+            IntermoduleVarUse),
+        lookup_int_option(Options, ipar_sparking_cost, SparkingCost),
+        lookup_int_option(Options, ipar_sparking_delay, SparkingDelay),
+        lookup_int_option(Options, ipar_barrier_cost, BarrierCost),
+        lookup_int_option(Options, ipar_future_signal_cost, FutureSignalCost),
+        lookup_int_option(Options, ipar_future_wait_cost, FutureWaitCost),
+        lookup_int_option(Options, ipar_context_wakeup_delay,
+            ContextWakeupDelay),
+        lookup_int_option(Options, ipar_clique_cost_threshold,
+            CPCCliqueThreshold),
+        lookup_int_option(Options, ipar_call_site_cost_threshold,
+            CPCCallSiteThreshold),
+        lookup_bool_option(Options, ipar_dep_conjs, AllowDepConjs),
+        lookup_string_option(Options, ipar_speedup_alg, SpeedupAlgString),
+        (
+            parse_parallelise_dep_conjs_string(AllowDepConjs,
+                SpeedupAlgString, SpeedupAlgPrime)
+        ->
+            SpeedupAlg = SpeedupAlgPrime
+        ;
+            io.format(Stderr,
+                "%s: error: %s is not a speedup estimate algorithm.\n",
+                [s(ProgName), s(SpeedupAlgString)], !IO),
+            !:Error = found_error,
+            SpeedupAlg = do_not_parallelise_dep_conjs    % dummy value
+        ),
+        lookup_string_option(Options, ipar_best_par_alg, BestParAlgStr),
+        parse_best_par_algorithm(BestParAlgStr, MaybeBestParAlg),
+        (
+            MaybeBestParAlg = ok(BestParAlg)
+        ;
+            MaybeBestParAlg = error(MaybeMessage, _Line, _Col),
+            (
+                MaybeMessage = yes(Message),
+                io.format(Stderr,
+                    "%s: error: %s is not a best parallelisation " ++
+                        "algorithm: %s.\n",
+                    [s(ProgName), s(BestParAlgStr), s(Message)], !IO)
+            ;
+                MaybeMessage = no,
+                io.format(Stderr,
+                    "%s: error: %s is not a best parallelisation algorithm.\n",
+                    [s(ProgName), s(BestParAlgStr)], !IO)
+            ),
+            !:Error = found_error,
+            BestParAlg = bpa_greedy    % dummy value
+        ),
+        AutoParOpts =
+            candidate_par_conjunctions_params(DesiredParallelism,
+                IntermoduleVarUse,
+                SparkingCost,
+                SparkingDelay,
+                BarrierCost,
+                FutureSignalCost,
+                FutureWaitCost,
+                ContextWakeupDelay,
+                CPCCliqueThreshold,
+                CPCCallSiteThreshold,
+                SpeedupThreshold,
+                SpeedupAlg,
+                BestParAlg),
+        MaybeAutoParOpts = yes(AutoParOpts)
+    ;
+        CandidateParallelConjunctions = no,
+        MaybeAutoParOpts = no
+    ),
+    Requested = requested_feedback_info(MaybeAutoParOpts).
+
+:- pred parse_best_par_algorithm(string::in,
+    parse_result(best_par_algorithm)::out) is det.
+
+parse_best_par_algorithm(String, Result) :-
+    promise_equivalent_solutions [Result] (
+        parse(String, best_par_algorithm_parser, Result)
+    ).
+
+:- pred best_par_algorithm_parser(src::in, best_par_algorithm::out,
+    ps::in, ps::out) is semidet.
+
+best_par_algorithm_parser(Src, Algorithm, !PS) :-
+    whitespace(Src, _, !PS),
+    (
+        keyword(idchars, "greedy", Src, _, !PS)
+    ->
+        Algorithm = bpa_greedy
+    ;
+        keyword(idchars, "complete-branches", Src, _, !PS),
+        brackets("(", ")", int_literal, Src, N, !PS),
+        N >= 0
+    ->
+        Algorithm = bpa_complete_branches(N)
+    ;
+        keyword(idchars, "complete-size", Src, _, !PS),
+        brackets("(", ")", int_literal, Src, N, !PS),
+        N >= 0
+    ->
+        Algorithm = bpa_complete_size(N)
+    ;
+        keyword(idchars, "complete", Src, _, !PS),
+        Algorithm = bpa_complete
+    ),
+    eof(Src, _, !PS).
+
+:- func idchars = string.
+
+idchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".
+
+:- pred parse_parallelise_dep_conjs_string(bool::in, string::in,
+    parallelise_dep_conjs::out) is semidet.
+
+parse_parallelise_dep_conjs_string(no, _, do_not_parallelise_dep_conjs).
+parse_parallelise_dep_conjs_string(yes, "naive",
+    parallelise_dep_conjs(estimate_speedup_naively)).
+parse_parallelise_dep_conjs_string(yes, "num_vars",
+    parallelise_dep_conjs(estimate_speedup_by_num_vars)).
+parse_parallelise_dep_conjs_string(yes, "overlap",
+    parallelise_dep_conjs(estimate_speedup_by_overlap)).
+
+    % Adjust command line options when one option implies other options.
+    %
+:- pred option_implies(option::in, option::in, bool::in,
+    option_table(option)::in, option_table(option)::out) is det.
+
+option_implies(Option, ImpliedOption, ImpliedValue, !Options) :-
+    ( lookup_bool_option(!.Options, Option, yes) ->
+        set_option(ImpliedOption, bool(ImpliedValue), !Options)
+    ;
+        true
+    ).
+
+    % Set the value of an option in the option table.
+    %
+:- pred set_option(option::in, option_data::in,
+    option_table(option)::in, option_table(option)::out) is det.
+
+set_option(Option, Value, !Options) :-
+    map.set(Option, Value, !Options).
+
+%----------------------------------------------------------------------------%
+
+    % process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages,
+    %   !Feedback)
+    %
+    % Process a deep profiling structure and update the feedback information
+    % according to the RequestedFeedbackInfo parameter.
+    %
+:- pred process_deep_to_feedback(requested_feedback_info::in, deep::in,
+    cord(message)::out, feedback_info::in, feedback_info::out) is det.
+
+process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages, !Feedback) :-
+    RequestedFeedbackInfo = requested_feedback_info(MaybeAutoParOpts),
+    (
+        MaybeAutoParOpts = yes(AutoParOpts),
+        candidate_parallel_conjunctions(AutoParOpts, Deep, Messages, !Feedback)
+    ;
+        MaybeAutoParOpts = no,
+        Messages = cord.empty
+    ).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_create_feedback.
+%-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_feedback.m
diff -N deep_profiler/mdprof_feedback.m
--- deep_profiler/mdprof_feedback.m	11 Jul 2011 19:47:25 -0000	1.41
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,770 +0,0 @@
-%-----------------------------------------------------------------------------%
-% vim: ft=mercury ts=4 sw=4 et
-%-----------------------------------------------------------------------------%
-% Copyright (C) 2006-2011 The University of Melbourne.
-% This file may only be copied under the terms of the GNU General
-% Public License - see the file COPYING in the Mercury distribution.
-%-----------------------------------------------------------------------------%
-%
-% File: mdprof_feedback.m.
-% Author: tannier, pbone.
-%
-% This module contains code for generating feedback files that tell the
-% compiler things such as which conjunctions can be profitably parallelised.
-%
-%-----------------------------------------------------------------------------%
-
-:- module mdprof_feedback.
-:- interface.
-
-:- import_module io.
-
-%-----------------------------------------------------------------------------%
-
-:- pred main(io::di, io::uo) is det.
-
-%-----------------------------------------------------------------------------%
-%-----------------------------------------------------------------------------%
-
-:- implementation.
-
-:- import_module conf.
-:- import_module mdbcomp.
-:- import_module mdbcomp.feedback.
-:- import_module mdbcomp.feedback.automatic_parallelism.
-:- import_module mdprof_fb.
-:- import_module mdprof_fb.automatic_parallelism.
-:- import_module mdprof_fb.automatic_parallelism.autopar_search_callgraph.
-:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
-:- import_module message.
-:- import_module profile.
-:- import_module startup.
-
-:- import_module bool.
-:- import_module char.
-:- import_module cord.
-:- import_module float.
-:- import_module getopt.
-:- import_module int.
-:- import_module library.
-:- import_module list.
-:- import_module map.
-:- import_module maybe.
-:- import_module parsing_utils.
-:- import_module require.
-:- import_module string.
-
-%-----------------------------------------------------------------------------%
-%
-% This section contains the main predicate as well as code to read the deep
-% profiling data and display usage and version messages to the user.
-%
-
-main(!IO) :-
-    io.progname_base("mdprof_feedback", ProgName, !IO),
-    io.command_line_arguments(Args0, !IO),
-    getopt.process_options(option_ops_multi(short, long, defaults),
-        Args0, Args, MaybeOptions),
-    io.stderr_stream(Stderr, !IO),
-    (
-        MaybeOptions = ok(Options0),
-        post_process_options(ProgName, Options0, Options, !IO),
-        lookup_bool_option(Options, help, Help),
-        lookup_bool_option(Options, version, Version),
-        (
-            Version = yes
-        ->
-            write_version_message(ProgName, !IO)
-        ;
-            Help = yes
-        ->
-            write_help_message(ProgName, !IO)
-        ;
-            (
-                Args = [OutputFileName],
-                feedback.read_feedback_file(OutputFileName, FeedbackReadResult,
-                    !IO),
-                (
-                    FeedbackReadResult = ok(Feedback),
-                    ProfileProgName = get_feedback_program_name(Feedback),
-                    print_feedback_report(ProfileProgName, Feedback, !IO)
-                ;
-                    FeedbackReadResult = error(FeedbackReadError),
-                    feedback.read_error_message_string(OutputFileName,
-                        FeedbackReadError, Message),
-                    io.format(Stderr, "%s: %s\n",
-                        [s(ProgName), s(Message)], !IO),
-                    io.set_exit_status(1, !IO)
-                )
-            ;
-                Args = [InputFileName, OutputFileName],
-                get_feedback_requests(ProgName, Options, FoundError,
-                    RequestedFeedbackInfo, !IO),
-                (
-                    FoundError = have_not_found_error,
-                    generate_requested_feedback(ProgName, Options,
-                        InputFileName, OutputFileName, RequestedFeedbackInfo,
-                        !IO)
-                ;
-                    FoundError = found_error
-                    % The error message have already been printed.
-                )
-            ;
-                ( Args = []
-                ; Args = [_, _, _ | _]
-                ),
-                write_help_message(ProgName, !IO),
-                io.set_exit_status(1, !IO)
-            )
-        )
-    ;
-        MaybeOptions = error(Msg),
-        io.format(Stderr, "%s: error parsing options: %s\n",
-            [s(ProgName), s(Msg)], !IO),
-        write_help_message(ProgName, !IO),
-        io.set_exit_status(1, !IO)
-    ).
-
-:- pred generate_requested_feedback(string::in, option_table(option)::in,
-    string::in, string::in, requested_feedback_info::in, io::di, io::uo) is det.
-
-generate_requested_feedback(ProgName, Options, InputFileName, OutputFileName,
-        RequestedFeedbackInfo, !IO) :-
-    io.stderr_stream(Stderr, !IO),
-    RequestedFeedbackInfo = requested_feedback_info(MaybeParallelize),
-    (
-        MaybeParallelize = yes(_),
-        lookup_bool_option(Options, debug_read_profile, DebugReadProfile),
-        lookup_bool_option(Options, report, Report),
-        read_deep_file(InputFileName, DebugReadProfile, MaybeDeep, !IO),
-        (
-            MaybeDeep = ok(Deep),
-            ProfileProgName = Deep ^ profile_stats ^ prs_program_name,
-            feedback.read_or_create(OutputFileName, ProfileProgName,
-                FeedbackReadResult, !IO),
-            (
-                FeedbackReadResult = ok(Feedback0),
-                process_deep_to_feedback(RequestedFeedbackInfo,
-                    Deep, Messages, Feedback0, Feedback),
-                (
-                    Report = yes,
-                    print_feedback_report(ProfileProgName, Feedback, !IO)
-                ;
-                    Report = no
-                ),
-                write_feedback_file(OutputFileName, ProfileProgName,
-                    Feedback, WriteResult, !IO),
-                (
-                    WriteResult = ok
-                ;
-                    ( WriteResult = open_error(Error)
-                    ; WriteResult = write_error(Error)
-                    ),
-                    io.error_message(Error, ErrorMessage),
-                    io.format(Stderr, "%s: %s: %s\n",
-                        [s(ProgName), s(OutputFileName), s(ErrorMessage)],
-                        !IO),
-                    io.set_exit_status(1, !IO)
-                ),
-                lookup_int_option(Options, verbosity, VerbosityLevel),
-                set_verbosity_level(VerbosityLevel, !IO),
-                write_out_messages(Stderr, Messages, !IO)
-            ;
-                FeedbackReadResult = error(FeedbackReadError),
-                feedback.read_error_message_string(OutputFileName,
-                    FeedbackReadError, Message),
-                io.write_string(Stderr, Message, !IO),
-                io.set_exit_status(1, !IO)
-            )
-        ;
-            MaybeDeep = error(Error),
-            io.set_exit_status(1, !IO),
-            io.format(Stderr, "%s: error reading %s: %s\n",
-                [s(ProgName), s(InputFileName), s(Error)], !IO)
-        )
-    ;
-        MaybeParallelize = no,
-        io.format(Stderr, "%s: options do not request any form of feedback\n",
-            [s(ProgName)], !IO)
-    ).
-
-:- pred print_feedback_report(string::in, feedback_info::in, io::di, io::uo)
-    is det.
-
-print_feedback_report(ProgName, Feedback, !IO) :-
-    get_all_feedback_data(Feedback, AllFeedback),
-    map(create_feedback_report, AllFeedback, Reports),
-    ReportStr = string.append_list(Reports),
-    io.format("Feedback report for %s:\n\n%s", [s(ProgName), s(ReportStr)],
-        !IO).
-
-:- pred create_feedback_report(feedback_data::in, string::out) is det.
-
-create_feedback_report(feedback_data_calls_above_threshold_sorted(_, _, _),
-        Report) :-
-   Report = "  feedback_data_calls_above_threshold_sorted is not supported\n".
-create_feedback_report(feedback_data_candidate_parallel_conjunctions(
-        Parameters, Conjs), Report) :-
-    create_feedback_autopar_report(Parameters, Conjs, Report).
-
-:- func help_message(string) = string.
-
-help_message(ProgName) = format(
-"Usage: %s [<options>] <input> <output>
-       %s <output>
-       %s --help
-       %s --version
-
-    The first form of this command generates feedback information from
-    profiling data.  The second form prints a report of the feedback data and
-    does not modify it.  The third and forth forms print this help message and
-    version information respectively.
-
-    <input> must name a deep profiling data file.
-    <output> is the name of the file to be generated by this program.
-
-    You may specify the following general options:
-
-    -h --help       Generate this help message.
-    -V --version    Report the program's version number.
-    -v --verbosity  <0-4>
-                    Generate messages.  The higher the argument, the more
-                    verbose the program becomes.  2 is recommended and the
-                    default.
-    --debug-read-profile
-                    Generate debugging messages when reading the deep profile
-                    and creating the deep structure.
-    --no-report     Suppress the report about the feedback information in the
-                    file that is usually displayed after any processing has
-                    been done.
-
-    The following options select sets of feedback information useful
-    for particular compiler optimizations:
-
-    --implicit-parallelism
-                Generate information that the compiler can use for automatic
-                parallelization.
-    --desired-parallelism <value>
-                The amount of desired parallelism for implicit parallelism,
-                which must be a floating point number above 1.0.
-                Note: This option is currently ignored.
-    --implicit-parallelism-intermodule-var-use
-                Assume that the compiler will be able to push signals and waits
-                for futures across module boundaries.
-    --ipar-sparking-cost <value>
-                The cost of creating a spark, measured in the deep profiler's
-                call sequence counts.
-    --ipar-sparking-delay <value>
-                The time taken from the time a spark is created until the spark
-                is executed by another processor, assuming that there is a free
-                processor.
-    --ipar-barrier-cost <value>
-                The cost of executing the barrier code at the end of each
-                parallel conjunct.
-    --ipar-future-signal-cost <value>
-                The cost of the signal() call for the producer of a shared
-                variable, measured in the profiler's call sequence counts.
-    --ipar-future-wait-cost <value>
-                The cost of the wait() call for the consumer of a shared
-                variable, measured in the profiler's call sequence counts.
-    --ipar-context-wakeup-delay <value>
-                The time taken for a context to resume execution after being
-                placed on the run queue.  This is used to estimate the impact
-                of blocking of a context's execution, it is measured in the
-                profiler's call sequence counts.
-    --ipar-clique-cost-threshold <value>
-                The cost threshold for cliques to be considered for implicit
-                parallelism, measured on the profiler's call sequence counts.
-    --ipar-call-site-cost-threshold <value>
-                The cost of a call site to be considered for parallelism
-                against another call site.
-    --no-ipar-dep-conjs
-                Disable parallelisation of dependent conjunctions.
-    --ipar-speedup-alg <alg>
-                Choose the algorithm that is used to estimate the speedup for
-                dependent calculations.  The available algorithms are:
-                    overlap: Compute the overlap between dependent
-                      conjunctions.
-                    num_vars: Use the number of shared variables as a proxy for
-                      the amount of overlap available.
-                    naive: Ignore dependencies.
-                The default is overlap.
-    --ipar-speedup-threshold <value>
-                The threshold that a speedup ratio must meet before the
-                feedback tool will accept a parallelization. It must be
-                a floating point number, which must be at least 1.0.
-                If it is e.g. 1.02, then the feedback tool will ignore
-                parallelizations that promise less than a 2%% local speedup.
-    --ipar-best-par-alg <alg>
-                Select which algorithm to use to find the best way to
-                parallelise a conjunction.  The available algorithms are:
-                    greedy: A greedy algorithm with a linear time complexity.
-                    complete: A complete algorithm with a branch and bound
-                      search. This can be slow for problems larger than 50
-                      conjuncts, since it has an exponential complexity.
-                    complete-size(N): As above exept that it takes a single
-                      parameter, N.  If a conjunction has more than N
-                      conjuncts, then the greedy algorithm will be used.
-                    complete-branches(N): The same as the complete algorithm,
-                      except that it allows at most N branches to be created
-                      during the search.  Once N branches have been created,
-                      a greedy search is used on each open branch.
-                The default is complete-branches(1000).
-
-    The following options select specific types of feedback information
-    and parameterise them:
-
-    --candidate-parallel-conjunctions
-                Produce a list of candidate parallel conjunctions for implicit
-                parallelism.  This option uses the implicit parallelism
-                settings above.
-
-",
-    % This is obviously redundant but by spelling it out we allow the compiler
-    % to check that the format string and arguments make sense.
-    [s(ProgName), s(ProgName), s(ProgName), s(ProgName)]).
-
-:- pred write_help_message(string::in, io::di, io::uo) is det.
-
-write_help_message(ProgName, !IO) :-
-    io.write_string(help_message(ProgName), !IO).
-
-:- pred write_version_message(string::in, io::di, io::uo) is det.
-
-write_version_message(ProgName, !IO) :-
-    library.version(Version),
-    io.write_string(ProgName, !IO),
-    io.write_string(": Mercury deep profiler", !IO),
-    io.nl(!IO),
-    io.write_string(Version, !IO),
-    io.nl(!IO).
-
-    % Read a deep profiling data file.
-    %
-:- pred read_deep_file(string::in, bool::in, maybe_error(deep)::out,
-    io::di, io::uo) is det.
-
-read_deep_file(Input, Debug, MaybeDeep, !IO) :-
-    server_name_port(Machine, !IO),
-    script_name(ScriptName, !IO),
-    (
-        Debug = yes,
-        io.stdout_stream(Stdout, !IO),
-        MaybeOutput = yes(Stdout)
-    ;
-        Debug = no,
-        MaybeOutput = no
-    ),
-    read_and_startup_default_deep_options(Machine, ScriptName, Input, no,
-        MaybeOutput, [], MaybeDeep, !IO).
-
-%----------------------------------------------------------------------------%
-%
-% This section describes and processes command line options. Individual
-% feedback information can be requested by the user, as well as options named
-% after optimizations that may imply one or more feedback inforemation types,
-% which that optimization uses.
-%
-
-    % Command line options.
-    %
-:- type option
-    --->    help
-    ;       version
-    ;       verbosity
-    ;       debug_read_profile
-    ;       report
-
-            % A list of candidate parallel conjunctions is produced for the new
-            % implicit parallelism implementation.
-    ;       candidate_parallel_conjunctions
-
-            % Provide suitable feedback information for implicit parallelism
-    ;       implicit_parallelism
-    ;       desired_parallelism
-    ;       ipar_intermodule_var_use
-    ;       ipar_sparking_cost
-    ;       ipar_sparking_delay
-    ;       ipar_barrier_cost
-    ;       ipar_future_signal_cost
-    ;       ipar_future_wait_cost
-    ;       ipar_context_wakeup_delay
-    ;       ipar_clique_cost_threshold
-    ;       ipar_call_site_cost_threshold
-    ;       ipar_speedup_threshold
-    ;       ipar_dep_conjs
-    ;       ipar_speedup_alg
-    ;       ipar_best_par_alg.
-
-% TODO: Introduce an option to disable parallelisation of dependent
-% conjunctions, or switch to the simple calculations for independent
-% conjunctions.
-
-:- pred short(char::in, option::out) is semidet.
-
-short('h',  help).
-short('v',  verbosity).
-short('V',  version).
-
-:- pred long(string::in, option::out) is semidet.
-
-long("help",
-    help).
-long("verbosity",
-    verbosity).
-long("version",
-    version).
-long("debug-read-profile",
-    debug_read_profile).
-long("report",
-    report).
-long("candidate-parallel-conjunctions",
-    candidate_parallel_conjunctions).
-long("implicit-parallelism",
-    implicit_parallelism).
-long("desired-parallelism",
-    desired_parallelism).
-long("implicit-parallelism-intermodule-var-use",
-    ipar_intermodule_var_use).
-long("ipar-intermodule-var-use",
-    ipar_intermodule_var_use).
-long("implicit-parallelism-sparking-cost",
-    ipar_sparking_cost).
-long("ipar-sparking-cost",
-    ipar_sparking_cost).
-long("implicit-parallelism-sparking-delay",
-    ipar_sparking_delay).
-long("ipar-sparking-delay",
-    ipar_sparking_delay).
-long("implicit-parallelism-future-signal-cost",
-    ipar_future_signal_cost).
-long("ipar-future-signal-cost",
-    ipar_future_signal_cost).
-long("implicit-parallelism-barrier-cost",
-    ipar_barrier_cost).
-long("ipar-barrier-cost",
-    ipar_barrier_cost).
-long("implicit-parallelism-future-wait-cost",
-    ipar_future_wait_cost).
-long("ipar-future-wait-cost",
-    ipar_future_wait_cost).
-long("implicit-parallelism-context-wakeup-delay",
-    ipar_context_wakeup_delay).
-long("ipar-context-wakeup-delay",
-    ipar_context_wakeup_delay).
-long("implicit-parallelism-clique-cost-threshold",
-    ipar_clique_cost_threshold).
-long("ipar-clique-cost-threshold",
-    ipar_clique_cost_threshold).
-long("implicit-parallelism-call-site-cost-threshold",
-    ipar_call_site_cost_threshold).
-long("ipar-call-site-cost-threshold",
-    ipar_call_site_cost_threshold).
-long("implicit-parallelism-dependant-conjunctions",
-    ipar_dep_conjs).
-long("ipar-dep-conjs",
-    ipar_dep_conjs).
-long("implicit-parallelism-dependant-conjunctions-algorithm",
-    ipar_speedup_alg).
-long("ipar-speedup-alg",
-    ipar_speedup_alg).
-long("implicit-parallelism-speedup-threshold",
-    ipar_speedup_threshold).
-long("ipar-speedup-threshold",
-    ipar_speedup_threshold).
-long("implicit-parallelism-best-parallelisation-algorithm",
-    ipar_best_par_alg).
-long("ipar-best-par-alg",
-    ipar_best_par_alg).
-
-:- pred defaults(option::out, option_data::out) is multi.
-
-defaults(help,                              bool(no)).
-defaults(verbosity,                         int(2)).
-defaults(version,                           bool(no)).
-defaults(debug_read_profile,                bool(no)).
-defaults(report,                            bool(yes)).
-
-defaults(candidate_parallel_conjunctions,   bool(no)).
-
-defaults(implicit_parallelism,              bool(no)).
-defaults(desired_parallelism,               string("8.0")).
-% XXX: These values have been chosen arbitrarily; we should set them
-% based on measurements.
-defaults(ipar_intermodule_var_use,          bool(no)).
-defaults(ipar_sparking_cost,                int(100)).
-defaults(ipar_sparking_delay,               int(1000)).
-defaults(ipar_barrier_cost,                 int(100)).
-defaults(ipar_future_signal_cost,           int(100)).
-defaults(ipar_future_wait_cost,             int(200)).
-defaults(ipar_context_wakeup_delay,         int(1000)).
-defaults(ipar_clique_cost_threshold,        int(2000)).
-defaults(ipar_call_site_cost_threshold,     int(2000)).
-defaults(ipar_dep_conjs,                    bool(yes)).
-defaults(ipar_speedup_threshold,            string("1.01")).
-defaults(ipar_speedup_alg,                  string("overlap")).
-defaults(ipar_best_par_alg,                 string("complete-branches(1000)")).
-
-:- pred construct_measure(string::in, stat_measure::out) is semidet.
-
-construct_measure("mean",       stat_mean).
-construct_measure("median",     stat_median).
-
-:- pred post_process_options(string::in,
-    option_table(option)::in, option_table(option)::out,
-    io::di, io::uo) is det.
-
-post_process_options(ProgName, !Options, !IO) :-
-    lookup_int_option(!.Options, verbosity, VerbosityLevel),
-    io.stderr_stream(Stderr, !IO),
-    ( VerbosityLevel < 0 ->
-        io.format(Stderr,
-            "%s: warning: verbosity level should not be negative.\n",
-            [s(ProgName)], !IO),
-        set_option(verbosity, int(0), !Options)
-    ; VerbosityLevel > 4 ->
-        io.format(Stderr,
-            "%s: warning: verbosity level should not exceed 4.\n",
-            [s(ProgName)], !IO),
-        set_option(verbosity, int(4), !Options)
-    ;
-        true
-    ),
-    lookup_bool_option(!.Options, implicit_parallelism, ImplicitParallelism),
-    (
-        ImplicitParallelism = yes,
-        set_option(candidate_parallel_conjunctions, bool(yes), !Options)
-    ;
-        ImplicitParallelism = no
-    ).
-
-    % This type defines the set of feedback_types that are to be calculated and
-    % put into the feedback info file. They should correspond with the values
-    % of feedback_type.
-    %
-:- type requested_feedback_info
-    --->    requested_feedback_info(
-                rfi_parallel    :: maybe(candidate_par_conjunctions_params)
-            ).
-
-:- type maybe_found_error
-    --->    have_not_found_error
-    ;       found_error.
-
-    % Check all the command line options, and return a representation
-    % of the user's request.
-    %
-:- pred get_feedback_requests(string::in, option_table(option)::in,
-    maybe_found_error::out, requested_feedback_info::out,
-    io::di, io::uo) is det.
-
-get_feedback_requests(ProgName, Options, !:Error, Requested, !IO) :-
-    io.stderr_stream(Stderr, !IO),
-    !:Error = have_not_found_error,
-    % For each feedback type, determine if it is requested, and fill in the
-    % field in the RequestedFeedbackInfo structure.
-    lookup_bool_option(Options, candidate_parallel_conjunctions,
-        CandidateParallelConjunctions),
-    (
-        CandidateParallelConjunctions = yes,
-        lookup_string_option(Options, desired_parallelism,
-            DesiredParallelismStr),
-        ( string.to_float(DesiredParallelismStr, DesiredParallelismPrime) ->
-            DesiredParallelism = DesiredParallelismPrime,
-            ( DesiredParallelism > 1.0 ->
-                true
-            ;
-                io.format(Stderr,
-                    "%s: error: desired parallelism level should be > 1.\n",
-                    [s(ProgName)], !IO),
-                !:Error = found_error
-            )
-        ;
-            io.format(Stderr,
-                "%s: error: desired parallelism level should be a number.\n",
-                [s(ProgName)], !IO),
-            !:Error = found_error,
-            DesiredParallelism = 1.0        % dummy value
-        ),
-        lookup_string_option(Options, ipar_speedup_threshold,
-            SpeedupThresholdStr),
-        ( string.to_float(SpeedupThresholdStr, SpeedupThresholdPrime) ->
-            SpeedupThreshold = SpeedupThresholdPrime,
-            ( SpeedupThreshold >= 1.0 ->
-                true
-            ;
-                io.format(Stderr,
-                    "%s: error: speedup threshold should be >= 1.\n",
-                    [s(ProgName)], !IO),
-                !:Error = found_error
-            )
-        ;
-            io.format(Stderr,
-                "%s: error: speedup threshold should be a number.\n",
-                [s(ProgName)], !IO),
-            !:Error = found_error,
-            SpeedupThreshold = 1.0        % dummy value
-        ),
-        lookup_bool_option(Options, ipar_intermodule_var_use,
-            IntermoduleVarUse),
-        lookup_int_option(Options, ipar_sparking_cost, SparkingCost),
-        lookup_int_option(Options, ipar_sparking_delay, SparkingDelay),
-        lookup_int_option(Options, ipar_barrier_cost, BarrierCost),
-        lookup_int_option(Options, ipar_future_signal_cost, FutureSignalCost),
-        lookup_int_option(Options, ipar_future_wait_cost, FutureWaitCost),
-        lookup_int_option(Options, ipar_context_wakeup_delay,
-            ContextWakeupDelay),
-        lookup_int_option(Options, ipar_clique_cost_threshold,
-            CPCCliqueThreshold),
-        lookup_int_option(Options, ipar_call_site_cost_threshold,
-            CPCCallSiteThreshold),
-        lookup_bool_option(Options, ipar_dep_conjs, AllowDepConjs),
-        lookup_string_option(Options, ipar_speedup_alg, SpeedupAlgString),
-        (
-            parse_parallelise_dep_conjs_string(AllowDepConjs,
-                SpeedupAlgString, SpeedupAlgPrime)
-        ->
-            SpeedupAlg = SpeedupAlgPrime
-        ;
-            io.format(Stderr,
-                "%s: error: %s is not a speedup estimate algorithm.\n",
-                [s(ProgName), s(SpeedupAlgString)], !IO),
-            !:Error = found_error,
-            SpeedupAlg = do_not_parallelise_dep_conjs    % dummy value
-        ),
-        lookup_string_option(Options, ipar_best_par_alg, BestParAlgStr),
-        parse_best_par_algorithm(BestParAlgStr, MaybeBestParAlg),
-        (
-            MaybeBestParAlg = ok(BestParAlg)
-        ;
-            MaybeBestParAlg = error(MaybeMessage, _Line, _Col),
-            (
-                MaybeMessage = yes(Message),
-                io.format(Stderr,
-                    "%s: error: %s is not a best parallelisation " ++
-                        "algorithm: %s.\n",
-                    [s(ProgName), s(BestParAlgStr), s(Message)], !IO)
-            ;
-                MaybeMessage = no,
-                io.format(Stderr,
-                    "%s: error: %s is not a best parallelisation algorithm.\n",
-                    [s(ProgName), s(BestParAlgStr)], !IO)
-            ),
-            !:Error = found_error,
-            BestParAlg = bpa_greedy    % dummy value
-        ),
-        AutoParOpts =
-            candidate_par_conjunctions_params(DesiredParallelism,
-                IntermoduleVarUse,
-                SparkingCost,
-                SparkingDelay,
-                BarrierCost,
-                FutureSignalCost,
-                FutureWaitCost,
-                ContextWakeupDelay,
-                CPCCliqueThreshold,
-                CPCCallSiteThreshold,
-                SpeedupThreshold,
-                SpeedupAlg,
-                BestParAlg),
-        MaybeAutoParOpts = yes(AutoParOpts)
-    ;
-        CandidateParallelConjunctions = no,
-        MaybeAutoParOpts = no
-    ),
-    Requested = requested_feedback_info(MaybeAutoParOpts).
-
-:- pred parse_best_par_algorithm(string::in,
-    parse_result(best_par_algorithm)::out) is det.
-
-parse_best_par_algorithm(String, Result) :-
-    promise_equivalent_solutions [Result] (
-        parse(String, best_par_algorithm_parser, Result)
-    ).
-
-:- pred best_par_algorithm_parser(src::in, best_par_algorithm::out,
-    ps::in, ps::out) is semidet.
-
-best_par_algorithm_parser(Src, Algorithm, !PS) :-
-    whitespace(Src, _, !PS),
-    (
-        keyword(idchars, "greedy", Src, _, !PS)
-    ->
-        Algorithm = bpa_greedy
-    ;
-        keyword(idchars, "complete-branches", Src, _, !PS),
-        brackets("(", ")", int_literal, Src, N, !PS),
-        N >= 0
-    ->
-        Algorithm = bpa_complete_branches(N)
-    ;
-        keyword(idchars, "complete-size", Src, _, !PS),
-        brackets("(", ")", int_literal, Src, N, !PS),
-        N >= 0
-    ->
-        Algorithm = bpa_complete_size(N)
-    ;
-        keyword(idchars, "complete", Src, _, !PS),
-        Algorithm = bpa_complete
-    ),
-    eof(Src, _, !PS).
-
-:- func idchars = string.
-
-idchars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_".
-
-:- pred parse_parallelise_dep_conjs_string(bool::in, string::in,
-    parallelise_dep_conjs::out) is semidet.
-
-parse_parallelise_dep_conjs_string(no, _, do_not_parallelise_dep_conjs).
-parse_parallelise_dep_conjs_string(yes, "naive",
-    parallelise_dep_conjs(estimate_speedup_naively)).
-parse_parallelise_dep_conjs_string(yes, "num_vars",
-    parallelise_dep_conjs(estimate_speedup_by_num_vars)).
-parse_parallelise_dep_conjs_string(yes, "overlap",
-    parallelise_dep_conjs(estimate_speedup_by_overlap)).
-
-    % Adjust command line options when one option implies other options.
-    %
-:- pred option_implies(option::in, option::in, bool::in,
-    option_table(option)::in, option_table(option)::out) is det.
-
-option_implies(Option, ImpliedOption, ImpliedValue, !Options) :-
-    ( lookup_bool_option(!.Options, Option, yes) ->
-        set_option(ImpliedOption, bool(ImpliedValue), !Options)
-    ;
-        true
-    ).
-
-    % Set the value of an option in the option table.
-    %
-:- pred set_option(option::in, option_data::in,
-    option_table(option)::in, option_table(option)::out) is det.
-
-set_option(Option, Value, !Options) :-
-    map.set(Option, Value, !Options).
-
-%----------------------------------------------------------------------------%
-
-    % process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages,
-    %   !Feedback)
-    %
-    % Process a deep profiling structure and update the feedback information
-    % according to the RequestedFeedbackInfo parameter.
-    %
-:- pred process_deep_to_feedback(requested_feedback_info::in, deep::in,
-    cord(message)::out, feedback_info::in, feedback_info::out) is det.
-
-process_deep_to_feedback(RequestedFeedbackInfo, Deep, Messages, !Feedback) :-
-    RequestedFeedbackInfo = requested_feedback_info(MaybeAutoParOpts),
-    (
-        MaybeAutoParOpts = yes(AutoParOpts),
-        candidate_parallel_conjunctions(AutoParOpts, Deep, Messages, !Feedback)
-    ;
-        MaybeAutoParOpts = no,
-        Messages = cord.empty
-    ).
-
-%-----------------------------------------------------------------------------%
-:- end_module mdprof_feedback.
-%-----------------------------------------------------------------------------%
Index: deep_profiler/mdprof_report_feedback.m
===================================================================
RCS file: deep_profiler/mdprof_report_feedback.m
diff -N deep_profiler/mdprof_report_feedback.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ deep_profiler/mdprof_report_feedback.m	26 Sep 2011 05:21:54 -0000
@@ -0,0 +1,199 @@
+%-----------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%-----------------------------------------------------------------------------%
+% Copyright (C) 2011 The University of Melbourne.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%-----------------------------------------------------------------------------%
+%
+% File: mdprof_report_feedback.m.
+% Author: pbone.
+%
+% This module contains code for showing the contents of feedback files
+% in a human-readable form.
+%
+%-----------------------------------------------------------------------------%
+
+:- module mdprof_report_feedback.
+:- interface.
+
+:- import_module io.
+
+%-----------------------------------------------------------------------------%
+
+:- pred main(io::di, io::uo) is det.
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.feedback.
+:- import_module mdbcomp.feedback.automatic_parallelism.
+:- import_module mdprof_fb.
+:- import_module mdprof_fb.automatic_parallelism.
+:- import_module mdprof_fb.automatic_parallelism.autopar_reports.
+
+:- import_module bool.
+:- import_module char.
+:- import_module getopt.
+:- import_module int.
+:- import_module library.
+:- import_module list.
+:- import_module map.
+:- import_module string.
+
+%-----------------------------------------------------------------------------%
+
+main(!IO) :-
+    io.progname_base("mdprof_report_feedback", ProgName, !IO),
+    io.command_line_arguments(Args0, !IO),
+    getopt.process_options(option_ops_multi(short, long, defaults),
+        Args0, Args, MaybeOptions),
+    io.stderr_stream(Stderr, !IO),
+    (
+        MaybeOptions = ok(Options0),
+        post_process_options(ProgName, Options0, Options, !IO),
+        lookup_bool_option(Options, help, Help),
+        lookup_bool_option(Options, version, Version),
+        ( Version = yes ->
+            write_version_message(ProgName, !IO)
+        ; Help = yes ->
+            write_help_message(ProgName, !IO)
+        ;
+            (
+                Args = [FeedbackFileName],
+                feedback.read_feedback_file(FeedbackFileName,
+                    FeedbackReadResult, !IO),
+                (
+                    FeedbackReadResult = ok(Feedback),
+                    ProfileProgName = get_feedback_program_name(Feedback),
+                    print_feedback_report(ProfileProgName, Feedback, !IO)
+                ;
+                    FeedbackReadResult = error(FeedbackReadError),
+                    feedback.read_error_message_string(FeedbackFileName,
+                        FeedbackReadError, Message),
+                    io.format(Stderr, "%s: %s\n",
+                        [s(ProgName), s(Message)], !IO),
+                    io.set_exit_status(1, !IO)
+                )
+            ;
+                ( Args = []
+                ; Args = [_, _ | _]
+                ),
+                write_help_message(ProgName, !IO),
+                io.set_exit_status(1, !IO)
+            )
+        )
+    ;
+        MaybeOptions = error(Msg),
+        io.format(Stderr, "%s: error parsing options: %s\n",
+            [s(ProgName), s(Msg)], !IO),
+        write_help_message(ProgName, !IO),
+        io.set_exit_status(1, !IO)
+    ).
+
+:- func help_message(string) = string.
+
+help_message(ProgName) = HelpMessage :-
+    FormatStr = 
+"Usage: %s [options] <feedbackfile>
+    This command outputs a report that shows the contents of the named
+    feedback file in a human-readable form.
+
+    You may specify the following general options:
+
+    -h --help       Generate this help message.
+    -V --version    Report the program's version number.
+    -v --verbosity  <0-4>
+                    Generate messages. The higher the argument, the more
+                    verbose the program becomes. 2 is recommended, and
+                    is the default.
+",
+    HelpMessage = string.format(FormatStr, [s(ProgName)]).
+
+:- pred write_help_message(string::in, io::di, io::uo) is det.
+
+write_help_message(ProgName, !IO) :-
+    io.write_string(help_message(ProgName), !IO).
+
+:- pred write_version_message(string::in, io::di, io::uo) is det.
+
+write_version_message(ProgName, !IO) :-
+    library.version(Version),
+    io.write_string(ProgName, !IO),
+    io.write_string(": Mercury deep profiler", !IO),
+    io.nl(!IO),
+    io.write_string(Version, !IO),
+    io.nl(!IO).
+
+%----------------------------------------------------------------------------%
+%
+% This section describes and processes command line options. Individual
+% feedback information can be requested by the user, as well as options named
+% after optimizations that may imply one or more feedback inforemation types,
+% which that optimization uses.
+%
+
+    % Command line options.
+    %
+:- type option
+    --->    help
+    ;       version
+    ;       verbosity.
+
+% TODO: Introduce an option to disable parallelisation of dependent
+% conjunctions, or switch to the simple calculations for independent
+% conjunctions.
+
+:- pred short(char::in, option::out) is semidet.
+
+short('h',  help).
+short('v',  verbosity).
+short('V',  version).
+
+:- pred long(string::in, option::out) is semidet.
+
+long("help",        help).
+long("verbosity",   verbosity).
+long("version",     version).
+
+:- pred defaults(option::out, option_data::out) is multi.
+
+defaults(help,      bool(no)).
+defaults(verbosity, int(2)).
+defaults(version,   bool(no)).
+
+:- pred post_process_options(string::in,
+    option_table(option)::in, option_table(option)::out,
+    io::di, io::uo) is det.
+
+post_process_options(ProgName, !Options, !IO) :-
+    lookup_int_option(!.Options, verbosity, VerbosityLevel),
+    io.stderr_stream(Stderr, !IO),
+    ( VerbosityLevel < 0 ->
+        io.format(Stderr,
+            "%s: warning: verbosity level should not be negative.\n",
+            [s(ProgName)], !IO),
+        set_option(verbosity, int(0), !Options)
+    ; VerbosityLevel > 4 ->
+        io.format(Stderr,
+            "%s: warning: verbosity level should not exceed 4.\n",
+            [s(ProgName)], !IO),
+        set_option(verbosity, int(4), !Options)
+    ;
+        true
+    ).
+
+    % Set the value of an option in the option table.
+    %
+:- pred set_option(option::in, option_data::in,
+    option_table(option)::in, option_table(option)::out) is det.
+
+set_option(Option, Value, !Options) :-
+    map.set(Option, Value, !Options).
+
+%-----------------------------------------------------------------------------%
+:- end_module mdprof_report_feedback.
+%-----------------------------------------------------------------------------%
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.636
diff -u -b -r1.636 user_guide.texi
--- doc/user_guide.texi	15 Sep 2011 18:00:35 -0000	1.636
+++ doc/user_guide.texi	26 Sep 2011 05:26:58 -0000
@@ -9511,7 +9511,7 @@
 @findex --implicit-parallelism
 Introduce parallel conjunctions where it could be worthwhile (implicit
 parallelism) using deep profiling feedback information generated by
-mdprof_feedback. The profiling feedback file can be specified using the
+mdprof_create_feedback. The profiling feedback file can be specified using the
 --feedback-file option.
 
 @sp 1
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/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_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
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/monte
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
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/appengine
cvs diff: Diffing samples/appengine/war
cvs diff: Diffing samples/appengine/war/WEB-INF
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/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/lazy_list
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/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
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