@@ -165,7 +165,16 @@ transitiveClosure(const Module& module,
165165 //
166166 // caller => called => called by called
167167 //
168- auto & calledInfo = funcInfos.at (module .getFunction (called));
168+ auto it = funcInfos.find (module .getFunction (called));
169+
170+ // TODO: this should never be missing?
171+ if (it == funcInfos.end ()) {
172+ std::cout << " missing key " << called << " \n " ;
173+ throw (1 );
174+ // assert(false && ("missing key " + called));
175+ }
176+ auto & calledInfo = it->second ;
177+ // auto& calledInfo = funcInfos.at(module.getFunction(called));
169178 for (auto calledByCalled : calledInfo.calledFunctions ) {
170179 if (!callers[calledByCalled].contains (caller)) {
171180 work.push ({caller, calledByCalled});
@@ -179,18 +188,17 @@ transitiveClosure(const Module& module,
179188std::unordered_map<Name, std::unordered_set<Name>> transitiveClosure (
180189 const Module& module ,
181190 const std::unordered_map<Name, std::unordered_set<Name>>& funcInfos) {
182- std::map<Function*, FuncInfo> other;
183- auto _ =
191+ auto transformed =
184192 funcInfos | std::views::transform (
185193 [&](const auto & pair) -> std::pair<Function*, FuncInfo> {
186194 auto & [k, v] = pair;
187195
188- auto & func = module .getFunction (k);
196+ auto * func = module .getFunction (k);
189197 FuncInfo info;
190198 info.calledFunctions = v;
191- return {func-> name , info};
199+ return {func, info};
192200 });
193-
201+ std::map<Function*, FuncInfo> other (transformed. begin (), transformed. end ());
194202 return transitiveClosure (module , other);
195203}
196204
@@ -215,6 +223,7 @@ struct GenerateGlobalEffects : public Pass {
215223 std::unordered_map<Name, std::unordered_set<Name>>
216224 indirectCallersNonTransitive;
217225 for (auto & [func, info] : funcInfos) {
226+ indirectCallersNonTransitive[func->name ];
218227 for (auto & calledType : info.indirectCalledTypes ) {
219228 // auto asdf = functionsWithType.at(calledType);
220229 // auto foo = indirectCallersNonTransitive[func->name];
@@ -226,18 +235,23 @@ struct GenerateGlobalEffects : public Pass {
226235 indirectCallersNonTransitive[func->name ].insert (it->second .begin (),
227236 it->second .end ());
228237 }
229- // indirectCallersNonTransitive[func->name].merge(functionsWithType.at(calledType));
230238 }
231- // for (const auto& name : functionsWitType[])
232- // for ()
233- // info.indirectCalledTypes[func->name]
234239 }
235240
236241 // indirectCallers[foo] = [func that indirect calls something with the same
237242 // type as foo, ..]
238243 const std::unordered_map<Name, std::unordered_set<Name>> indirectCallers =
239244 transitiveClosure (*module , indirectCallersNonTransitive);
240245
246+ std::cout << " indirectCallers\n " ;
247+ for (auto [callee, callers] : indirectCallers) {
248+ std::cout << callee << " \n " ;
249+ for (auto caller : callers) {
250+ std::cout << " \t " << caller << " \n " ;
251+ }
252+ std::cout << " \n " ;
253+ }
254+
241255 // Now that we have transitively propagated all static calls, apply that
242256 // information. First, apply infinite recursion: if a function can call
243257 // itself then it might recurse infinitely, which we consider an effect (a
@@ -303,6 +317,7 @@ struct GenerateGlobalEffects : public Pass {
303317 continue ;
304318 }
305319
320+ std::cout << func->name << " has effects " << *info.effects << " \n " ;
306321 func->effects = std::make_shared<EffectAnalyzer>(*info.effects );
307322 }
308323 }
0 commit comments