Files
mercury/compiler/dependency_graph.m
Zoltan Somogyi dea4368f7d Make each SCC in the dependency graph a set, not a list.
This is to make the data type follow the inherent semantics of SCCs
more closely, and enforce the invariant that a procedure can appear
in the SCC only once.

Also, rename the list of SCCs from "dependency_ordering", which does
not give a clue about *which way* the SCCs are ordered, to "bottom_up_sccs",
which does.

compiler/dependency_graph.m:
    Make the changes described above.

    Document why we reverse the list generated by digraph.atsort.

library/digraph.m:
    Document the order in which digraph.atsort returns the list of SCCs.

    Note that the last step of atsort is to reverse the list, which
    its caller in compiler/dependency_graph.m will then immediately
    re-reverse.

    Document the order in which digraph.tsort and digraph.dfs return
    a list of items.

    Give some variables more meaningful names, and make the argument order
    of some predicates conform to our conventions.

compiler/hlds_out_module.m:
    Add code to print out the dependency info in the module_info, if asked.

doc/user_guide.texi:
    Document the dump string option that asks for this.

compiler/hlds_dependency_graph.m:
    Make the same changes for hlds_dependency_info as dependency_graph.m
    did to just plain dependency_info.

compiler/hlds_pred.m:
    Make the scc type expand to a set, not a list, of pred_proc_ids.

compiler/dep_par_conj.m:
compiler/stratify.m:
    Conform to the changes above, and simplify some code.

compiler/closure_analysis.m:
compiler/ctgc.util.m:
compiler/deep_profiling.m:
compiler/deforest.m:
compiler/exception_analysis.m:
compiler/goal_util.m:
compiler/granularity.m:
compiler/inlining.m:
compiler/lco.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mode_constraints.m:
compiler/rbmm.interproc_region_lifetime.m:
compiler/rbmm.points_to_analysis.m:
compiler/structure_reuse.indirect.m:
compiler/structure_sharing.analysis.m:
compiler/tabling_analysis.m:
compiler/term_constr_build.m:
compiler/term_constr_data.m:
compiler/term_constr_errors.m:
compiler/term_constr_fixpoint.m:
compiler/term_constr_main.m:
compiler/term_constr_pass2.m:
compiler/term_constr_util.m:
compiler/term_errors.m:
compiler/term_pass1.m:
compiler/term_pass2.m:
compiler/term_util.m:
compiler/termination.m:
compiler/trailing_analysis.m:
compiler/tupling.m:
    Conform to the changes above.
2017-02-19 16:08:48 +11:00

103 lines
4.1 KiB
Mathematica

%-----------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------%
% Copyright (C) 2017 The Mercury Team.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------%
%
% File: dependency_graph.m.
%
% These are generic types and predicates for managing a dependency graph.
% hlds_dependency_graph.m uses it, and if we need an mlds_dependency_graph.m,
% that would use it too.
%
% A dependency_graph records which entities depend on which other entities.
% (For hlds_dependency_graph.m, the entities are HLDS procedures.)
% It is defined as a digraph R where the presence of an edge x -> y means that
% the definition of x depends on the definition of y.
%
% The reason why we build the dependency graph is because from it,
% we can compute the list of the SCCs (strongly-connected components)
% of this graph. This list of SCCs is the bottom_up_dependency_sccs, the other
% component in a dependency_graph itself.
%
%-----------------------------------------------------------------------%
:- module libs.dependency_graph.
:- interface.
:- import_module digraph.
:- import_module list.
:- import_module set.
%-----------------------------------------------------------------------%
% A dependency_info contains a dependency_graph and a dependency_ordering.
% Calling make_dependency_info on a graph fills in the dependency_ordering.
%
:- type dependency_info(T).
:- type dependency_graph(T) == digraph(T).
:- type dependency_graph_key(T) == digraph_key(T).
% A dependency ordering gives the list of SCCs of the analysed entities.
% (For hlds_dependency_graph.m, this will be all the predicates or all
% the procedure of the module being compiled.)
%
% The list is in ascending order: the lowest SCC is first,
% the highest SCC is last.
%
:- type bottom_up_dependency_sccs(T) == list(set(T)).
%-----------------------------------------------------------------------%
:- func make_dependency_info(digraph(T)) = dependency_info(T).
%-----------------------------------------------------------------------%
:- func dependency_info_get_graph(dependency_info(T))
= dependency_graph(T).
:- func dependency_info_get_bottom_up_sccs(dependency_info(T))
= bottom_up_dependency_sccs(T).
% This function does the same job as dependency_info_get_ordering,
% except that it condenses all the nodes into a single list.
% This is useful when the caller wants to process entities bottom up,
% but the SCC boundaries are not relevant.
%
:- func dependency_info_get_condensed_bottom_up_sccs(dependency_info(T))
= list(T).
%-----------------------------------------------------------------------%
%-----------------------------------------------------------------------%
:- implementation.
%-----------------------------------------------------------------------%
:- type dependency_info(T)
---> dependency_info(
dep_graph :: dependency_graph(T),
dep_bottom_up_sccs :: bottom_up_dependency_sccs(T)
).
make_dependency_info(Graph) = dependency_info(Graph, BottomUpOrdering) :-
% digraph.atsort puts the cliques of parents before the cliques
% of their children. This is a top down order.
digraph.atsort(Graph, TopDownOrdering),
list.reverse(TopDownOrdering, BottomUpOrdering).
%-----------------------------------------------------------------------%
dependency_info_get_graph(DepInfo) = DepInfo ^ dep_graph.
dependency_info_get_bottom_up_sccs(DepInfo) = DepInfo ^ dep_bottom_up_sccs.
dependency_info_get_condensed_bottom_up_sccs(DepInfo) = CondensedOrder :-
ListOfSets = dependency_info_get_bottom_up_sccs(DepInfo),
list.map(set.to_sorted_list, ListOfSets, ListOfLists),
list.condense(ListOfLists, CondensedOrder).
%-----------------------------------------------------------------------%
%-----------------------------------------------------------------------%