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