Skip to content

Commit d764f59

Browse files
PR updates
1 parent 3a25c2e commit d764f59

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

src/passes/GlobalEffects.cpp

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
9494
} else if (auto* callIndirect = curr->dynCast<CallIndirect>()) {
9595
type = callIndirect->heapType;
9696
} else {
97-
assert(false && "Unexpected type of call");
97+
Fatal() << "Unexpected call type";
9898
}
9999

100100
funcInfo.indirectCalledTypes.insert(type);
@@ -123,34 +123,41 @@ using CallGraphNode = std::variant<Function*, HeapType>;
123123
using CallGraph =
124124
std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>;
125125

126+
/* Build a call graph for indirect and direct calls.
127+
128+
key (caller) -> value (callee)
129+
Name -> Name : direct call
130+
Name -> HeapType : indirect call to the given HeapType
131+
HeapType -> Name : The function `callee` has the type `caller`. The
132+
HeapType may essentially 'call' any of its
133+
potential implementations.
134+
HeapType -> HeapType : `callee` is a subtype of `caller`. A call_ref
135+
could target any subtype of the ref, so we need to
136+
aggregate effects of subtypes of the target type.
137+
138+
If we're running in an open world, we only include Name -> Name edges.
139+
*/
126140
CallGraph buildCallGraph(Module& module,
127141
const std::map<Function*, FuncInfo>& funcInfos,
128142
bool closedWorld) {
129143
CallGraph callGraph;
130144

131-
if (!closedWorld) {
132-
for (const auto& [func, info] : funcInfos) {
133-
if (info.calledFunctions.empty()) {
134-
continue;
135-
}
136-
137-
auto& callees = callGraph[func];
138-
for (Name calleeFunction : info.calledFunctions) {
139-
callees.insert(module.getFunction(calleeFunction));
140-
}
141-
}
142-
return callGraph;
143-
}
144-
145145
std::unordered_set<HeapType> allFunctionTypes;
146146
for (const auto& [caller, callerInfo] : funcInfos) {
147+
auto& callees = callGraph[caller];
147148
for (Name calleeFunction : callerInfo.calledFunctions) {
148-
callGraph[caller].insert(module.getFunction(calleeFunction));
149+
callees.insert(module.getFunction(calleeFunction));
150+
}
151+
152+
// In open world, just connect functions. Indirect calls are already handled
153+
// by giving such functions unknown effects.
154+
if (!closedWorld) {
155+
continue;
149156
}
150157

151158
allFunctionTypes.insert(caller->type.getHeapType());
152159
for (HeapType calleeType : callerInfo.indirectCalledTypes) {
153-
callGraph[caller].insert(calleeType);
160+
callees.insert(calleeType);
154161
allFunctionTypes.insert(calleeType);
155162
}
156163
callGraph[caller->type.getHeapType()].insert(caller);
@@ -210,11 +217,7 @@ void propagateEffects(const Module& module,
210217
funcInfos(funcInfos), callGraph(callGraph), module(module) {}
211218

212219
void pushChildren(CallGraphNode node) {
213-
auto callees = callGraph.find(node);
214-
if (callees == callGraph.end()) {
215-
return;
216-
}
217-
for (CallGraphNode callee : callees->second) {
220+
for (CallGraphNode callee : callGraph.at(node)) {
218221
push(callee);
219222
}
220223
}
@@ -249,12 +252,7 @@ void propagateEffects(const Module& module,
249252

250253
std::unordered_set<int> calleeSccs;
251254
for (CallGraphNode caller : cc) {
252-
auto callees = callGraph.find(caller);
253-
if (callees == callGraph.end()) {
254-
continue;
255-
}
256-
257-
for (CallGraphNode callee : callees->second) {
255+
for (CallGraphNode callee : callGraph.at(caller)) {
258256
calleeSccs.insert(funcComponents.at(callee));
259257
}
260258
}

0 commit comments

Comments
 (0)