@@ -90,6 +90,11 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
9090 // Note the direct call.
9191 funcInfo.calledFunctions .insert (call->target );
9292 } else if (effects.calls ) {
93+ if (!options.closedWorld ) {
94+ funcInfo.effects = UnknownEffects;
95+ return ;
96+ }
97+
9398 HeapType type;
9499 if (auto * callRef = curr->dynCast <CallRef>()) {
95100 type = callRef->target ->type .getHeapType ();
@@ -118,6 +123,36 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
118123 return std::move (analysis.map );
119124}
120125
126+ // Funcs that can be the target of a virtual call
127+ // These are either:
128+ // - Part of an (elem declare ...) or (elem ...) directive
129+ // - Exported, since they may flow back to us from the host
130+ std::unordered_set<Name> getFuncsWithAddress (Module& module ) {
131+ std::unordered_set<Name> funcsWithAddress;
132+ for (const auto & fun : module .functions ) {
133+ funcsWithAddress.insert (fun->name );
134+ }
135+ return funcsWithAddress;
136+
137+ // {
138+ // auto refFuncs = TableUtils::getFunctionsNeedingElemDeclare(module);
139+ // funcsWithAddress.insert(refFuncs.begin(), refFuncs.end());
140+ // }
141+
142+ // ElementUtils::iterAllElementFunctionNames(
143+ // &module,
144+ // [&funcsWithAddress](Name name) { funcsWithAddress.insert(name); });
145+ // for (const auto& export_ : module.exports) {
146+ // if (export_->kind == ExternalKind::Function) {
147+ // // This exported function might flow back to us even in a closed world,
148+ // // so it's essentially addressed.
149+ // funcsWithAddress.insert(export_->name);
150+ // }
151+ // }
152+
153+ // return funcsWithAddress;
154+ }
155+
121156using CallGraphNode = std::variant<Name, HeapType>;
122157
123158// Build a call graph for indirect and direct calls.
@@ -126,27 +161,20 @@ using CallGraphNode = std::variant<Name, HeapType>;
126161// Name -> HeapType : callee is a potential target of a virtual call with this HeapType
127162// HeapType -> Name : callee is indirectly called by caller
128163// HeapType -> HeapType : callee is a subtype of caller
164+
165+ // TODO: only track indirect calls in closed world
129166std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>> buildReverseCallGraph (Module& module , const std::map<Function*, FuncInfo> funcInfos) {
130167 // callee : caller
131168 std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>
132169 callers;
133170
134171 std::unordered_set<HeapType> allIndirectCalledTypes;
135172
136- std::unordered_set<Name> funcsWithAddress;
137-
138- auto refFuncs = TableUtils::getFunctionsNeedingElemDeclare (module );
139- funcsWithAddress.insert (refFuncs.begin (), refFuncs.end ());
140- ElementUtils::iterAllElementFunctionNames (
141- &module ,
142- [&funcsWithAddress](Name name) { funcsWithAddress.insert (name); });
143- for (const auto & export_ : module .exports ) {
144- if (export_->kind == ExternalKind::Function) {
145- // This exported function might flow back to us even in a closed world,
146- // so it's essentially addressed.
147- funcsWithAddress.insert (export_->name );
148- }
149- }
173+ // Funcs that can be the target of a virtual call
174+ // These are either:
175+ // - Part of an (elem declare ...) or (elem ...) directive
176+ // - Exported, since they may flow back to us from the host
177+ std::unordered_set<Name> funcsWithAddress = getFuncsWithAddress (module );
150178
151179 for (const auto & [func, info] : funcInfos) {
152180 // Name -> Name for direct calls
@@ -263,6 +291,15 @@ struct GenerateGlobalEffects : public Pass {
263291 std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>
264292 callers = buildReverseCallGraph (*module , funcInfos);
265293
294+ // for (const auto& [callee, callers] : callers) {
295+ // for (const auto& caller : callers) {
296+ // const auto* calleeName = std::get_if<Name>(&callee);
297+ // const auto* callerName = std::get_if<Name>(&caller);
298+ // if (!calleeName || !callerName) continue;
299+ // std::cout<<*calleeName<<"\t\t->\t\t"<<*callerName<<"\n";
300+ // }
301+ // }
302+
266303 propagateEffects (*module , callers, funcInfos);
267304
268305 // Generate the final data, starting from a blank slate where nothing is
0 commit comments