Skip to content

Commit 3311a77

Browse files
Start cleaning up
1 parent e0d287f commit 3311a77

File tree

1 file changed

+22
-44
lines changed

1 file changed

+22
-44
lines changed

src/passes/GlobalEffects.cpp

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
9595
}
9696

9797
funcInfo.indirectCalledTypes.insert(type);
98-
// funcInfo.effects.reset();
9998
} else {
10099
// No call here, but update throwing if we see it. (Only do so,
101100
// however, if we have effects; if we cleared it - see before -
@@ -114,24 +113,6 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
114113
return analysis.map;
115114
}
116115

117-
// std::unordered_map<HeapType, std::unordered_set<Name>>
118-
// typeToFunctionNames(const Module& module) {
119-
// std::unordered_map<HeapType, std::unordered_set<Name>> ret;
120-
121-
// // TODO
122-
// SubTypes s(*const_cast<Module*>(&module));
123-
124-
// for (const auto& func : module.functions) {
125-
// s.iterSubTypes(func->type.getHeapType(), [&ret, &func](HeapType type, int _) {
126-
// std::cout<<"subtype "<< func->type.getHeapType() << " " << type<< "\n";
127-
// ret[type].insert(func->name);
128-
// });
129-
// // ret[func->type.getHeapType()].insert(func->name);
130-
// }
131-
132-
// return ret;
133-
// }
134-
135116
template <typename T>
136117
std::unordered_map<T, std::unordered_set<T>> transitiveClosure2(const std::unordered_map<T, std::unordered_set<T>>& in) {
137118
UniqueNonrepeatingDeferredQueue<std::pair<T, T>> work;
@@ -240,33 +221,26 @@ std::unordered_map<V, std::unordered_set<K>> flip(const std::unordered_map<K, st
240221
return flipped;
241222
}
242223

224+
// std::unordered_map<HeapType, std::unordered_set<Name>>
225+
243226
struct GenerateGlobalEffects : public Pass {
244227
void run(Module* module) override {
245228
// First, we do a scan of each function to see what effects they have,
246229
// including which functions they call directly (so that we can compute
247230
// transitive effects later).
248231
auto funcInfos = analyzeFuncs(*module, getPassOptions());
249232

250-
// Compute the transitive closure of effects. To do so, first construct for
251-
// each function a list of the functions that it is called by (so we need to
252-
// propagate its effects to them), and then we'll construct the closure of
253-
// that.
254-
//
255-
// callers[foo] = [func that calls foo, another func that calls foo, ..]
256-
//
257-
std::unordered_map<Name, std::unordered_set<Name>> callers =
258-
transitiveClosure(*module, funcInfos);
259-
260-
// const auto functionsWithType = typeToFunctionNames(*module);
233+
// Find the 'entry points' of indirect calls Name -> HeapType.
234+
// At the same time, start recording connections for the transitive closure of indirect calls
235+
// HeapType -> HeapType. This will be used to find the set of HeapTypes that are reachable via any sequence of indirect calls from a given function
236+
// (Name -> HeapType)
261237
std::unordered_map<Name, std::unordered_set<HeapType>>
262238
indirectCallersNonTransitive;
263239
std::unordered_map<HeapType, std::unordered_set<HeapType>> indirectCalls;
264240
for (auto& [func, info] : funcInfos) {
265241
auto& set = indirectCallersNonTransitive[func->name];
266242
auto& indirectCallsSet = indirectCalls[func->type.getHeapType()];
267243
for (auto& calledType : info.indirectCalledTypes) {
268-
// if (auto it = functionsWithType.find(calledType);
269-
// it != functionsWithType.end()) {
270244
set.insert(calledType);
271245
indirectCallsSet.insert(calledType);
272246
}
@@ -293,15 +267,18 @@ struct GenerateGlobalEffects : public Pass {
293267
for (const auto& [k, v] : subTypesToAdd) {
294268
auto it = indirectCalls.find(k);
295269

296-
// This is possible but if it happens it means there was no function with this type anyway
297-
// So no effects to include and no harm in forgetting it.
270+
// No need to add this. It wasn't in the map because no function has this
271+
// type, so there are no effects to aggregate and we can forget about it.
298272
if (it == indirectCalls.end()) continue;
299273

300274
it->second.insert(v.begin(), v.end());
301275
}
302276

303277
auto a = transitiveClosure2<HeapType>(indirectCalls);
304278

279+
// Pretend that each subtype is indirect called by its supertype.
280+
// This might not be the case but it's accurate enough since any caller that
281+
// may indirect call a given type may also indirect call its subtype.
305282
for (const auto& [k, v]: indirectCallersNonTransitive) {
306283
for (const auto& x : v) {
307284
auto y = a[x];
@@ -313,16 +290,17 @@ struct GenerateGlobalEffects : public Pass {
313290
}
314291

315292
std::unordered_map<HeapType, std::unordered_set<Name>> flipped = flip(indirectCallersNonTransitive);
316-
// indirectCalls;
317-
318-
// std::cout << "indirectCallers\n";
319-
// for (auto [callee, callers] : indirectCallers) {
320-
// std::cout << callee << "\n";
321-
// for (auto caller : callers) {
322-
// std::cout << "\t" << caller << "\n";
323-
// }
324-
// std::cout << "\n";
325-
// }
293+
294+
// Compute the transitive closure of effects. To do so, first construct for
295+
// each function a list of the functions that it is called by (so we need to
296+
// propagate its effects to them), and then we'll construct the closure of
297+
// that.
298+
//
299+
// callers[foo] = [func that calls foo, another func that calls foo, ..]
300+
//
301+
std::unordered_map<Name, std::unordered_set<Name>> callers =
302+
transitiveClosure(*module, funcInfos);
303+
326304

327305
// Now that we have transitively propagated all static calls, apply that
328306
// information. First, apply infinite recursion: if a function can call

0 commit comments

Comments
 (0)