34
35:- module(calls_to,
36 [cleanup_calls_to/0,
37 collect_calls_to/2,
38 calls_to/1,
39 calls_to/3,
40 calls_to/4,
41 calls_to_hook/4
42 ]). 43
44:- use_module(library(apply)). 45:- use_module(library(solution_sequences)). 46:- use_module(library(option)). 47:- use_module(library(lists)). 48:- use_module(library(codewalk)). 49:- use_module(library(location_utils)). 50:- use_module(library(option_utils)). 51:- use_module(library(compact_goal)). 52:- use_module(library(compilation_module)). 53
54:- init_expansors. 55
56:- dynamic
57 calls_to_public/2,
58 calls_to_exported/2,
59 calls_to_initialization/2,
60 calls_to_assertion/4,
61 calls_to_declaration/2,
62 calls_to_clause/3,
63 calls_to_predid/4. 64
65:- multifile
66 calls_to_hook/4. 67
68cleanup_calls_to :-
69 retractall(calls_to_public(_, _)),
70 retractall(calls_to_exported(_, _)),
71 retractall(calls_to_initialization(_, _)),
72 retractall(calls_to_assertion(_, _, _, _)),
73 retractall(calls_to_declaration(_, _)),
74 retractall(calls_to_clause(_, _, _)),
75 retractall(calls_to_predid(_, _, _, _)).
76
77caller_ptr('<initialization>', _, '<initialization>') :- !.
78caller_ptr('<assertion>'(AH), _, '<assertion>'(AH) ) :- !.
79caller_ptr('<declaration>', _, '<declaration>' ) :- !.
80caller_ptr(_, clause(Ptr), clause(Ptr) ) :- !.
81caller_ptr(M:H, _, M:H).
82
83record_calls_to(Type, Caller, Head, M, From) :-
84 ( memberchk(Type, [use, lit])
85 ->caller_ptr(Caller, From, Ptr),
86 record_calls_to(Ptr, M, Head)
87 ; true
88 ).
89
90record_calls_to('<public>', M, Head) :- assertz(calls_to_public( Head, M)).
91record_calls_to('<exported>', M, Head) :- assertz(calls_to_exported( Head, M)).
92record_calls_to('<initialization>', M, Head) :- assertz(calls_to_initialization( Head, M)).
93record_calls_to('<assertion>'(AM:AH), M, Head) :- assertz(calls_to_assertion(AH, AM, Head, M)).
94record_calls_to('<declaration>', M, Head) :- assertz(calls_to_declaration( Head, M)).
95record_calls_to(clause(Ref), M, Head) :- assertz(calls_to_clause(Ref, Head, M)).
96record_calls_to(CM:CH, M, Head) :- assertz(calls_to_predid(CH, CM, Head, M)).
97
98calls_to('<public>'(M:H) ) :- calls_to_public(H, M).
99calls_to('<exported>'(M:H) ) :- calls_to_exported(H, M).
100calls_to('<initialization>' ) :- once(calls_to_initialization(_, _)).
101calls_to('<assertion>'(AM:AH)) :- distinct(AH:AM, calls_to_assertion(AH, AM, _, _)).
102calls_to('<declaration>' ) :- once(calls_to_declaration(_, _)).
103calls_to(clause(Ref) ) :- distinct(Ref, calls_to_clause(Ref, _, _)).
104calls_to(CM:CH ) :- distinct(CM:CH, calls_to_predid(CH, CM, _, _)).
105
106calls_to(CRef, M, Head) :- calls_to(CRef, c, M, Head).
107
108calls_to('<initialization>', _, M, Head) :- calls_to_initialization( Head, M).
109calls_to('<assertion>'(AM:AH), _, M, Head) :- calls_to_assertion(AH, AM, Head, M).
110calls_to('<declaration>', _, M, Head) :- calls_to_declaration( Head, M).
111calls_to(clause(Ref), _, M, Head) :- calls_to_clause(Ref, Head, M).
112calls_to(CM:CH, W, M, Head) :- calls_to_predid(W, CH, CM, Head, M).
113
114calls_to_predid(c, CH, CM, Head, M) :- calls_to_predid(CH, CM, Head, M).
115calls_to_predid(w, CH, CM, Head, M) :-
116 clause(calls_to:calls_to_predid(CH, CM, _, _), _, Ref),
117 clause(calls_to:calls_to_predid( _, _, Head, M), _, Ref).
118
119cu_caller_hook(Caller, Head, CM, Type, Goal, _, From) :-
120 callable(Head),
121 nonvar(CM),
122 predicate_property(CM:Head, implementation_module(M)),
123 ( Type \= lit
124 ->compact_goal(Goal, Comp),
125 record_location_goal(Head, M, Type, CM, Comp, From)
126 ; Caller = '<assertion>'(A:H),
127 member(Goal, [ foreign_props:fimport(_),
128 foreign_props:fimport(_, _),
129 foreign_props:tgen(_)
130 ])
131 ->( A \= CM
132 ->record_calls_to('<exported>', A, H)
133 ; record_calls_to('<public>', A, H)
134 )
135 ; true
136 ),
137 record_calls_to(Type, Caller, Head, CM, From),
138 ( M \= CM
139 ->record_calls_to('<exported>', M, Head)
140 ; true
141 ).
142
143:- public collect_unused/4. 144collect_unused(M, MGoal, Caller, From) :-
145 record_location_meta(MGoal, M, From, all_call_refs, cu_caller_hook(Caller)).
146
147:- public record_head_deps/2. 148record_head_deps(Head, From) :-
149 forall(calls_to_hook(Head, From, C, Called),
150 ( predicate_property(C:Called, implementation_module(M)),
151 record_calls_to(Head, C, Called),
152 ( C \= M
153 ->record_calls_to('<exported>', M, Called)
154 ; true
155 )
156 )).
157
158collect_calls_to(Options1, MFileD) :-
159 foldl(select_option_default,
160 [method(Method1)-clause],
161 Options1, Options2),
162 ( \+ memberchk(Method1, [prolog, clause]) 163 ->Method = clause,
164 print_message(
165 warning,
166 format("Method `~w' not supported yet, using `~w' instead",
167 [Method1, Method]))
168 ; Method = Method1
169 ),
170 option(module(M), Options1, M),
171 merge_options(Options2,
172 [source(false), 173 method(Method),
174 on_trace(collect_unused(M)),
175 on_head(record_head_deps)
176 ], Options),
177 option_module_files(Options, MFileD),
178 walk_code([module_files(MFileD)|Options])