2222#include < ranges>
2323
2424#include " ir/effects.h"
25+ #include " ir/element-utils.h"
2526#include " ir/module-utils.h"
2627#include " pass.h"
2728#include " support/strongly_connected_components.h"
@@ -46,8 +47,55 @@ struct FuncInfo {
4647 std::unordered_set<HeapType> indirectCalledTypes;
4748};
4849
50+ std::unordered_set<Function*> getAddressedFuncs (Module& module ) {
51+ struct AddressedFuncsWalker
52+ : PostWalker<AddressedFuncsWalker,
53+ UnifiedExpressionVisitor<AddressedFuncsWalker>> {
54+ const Module& module ;
55+ std::unordered_set<Function*>& addressedFuncs;
56+
57+ AddressedFuncsWalker (const Module& module ,
58+ std::unordered_set<Function*>& addressedFuncs)
59+ : module (module ), addressedFuncs(addressedFuncs) {}
60+
61+ void visitExpression (Expression* curr) {
62+ if (auto * refFunc = curr->dynCast <RefFunc>()) {
63+ addressedFuncs.insert (module .getFunction (refFunc->func ));
64+ }
65+ }
66+ };
67+
68+ std::unordered_set<Function*> addressedFuncs;
69+ AddressedFuncsWalker walker (module , addressedFuncs);
70+ walker.walkModule (&module );
71+
72+ ModuleUtils::iterImportedFunctions (
73+ module , [&addressedFuncs, &module ](Function* import ) {
74+ addressedFuncs.insert (module .getFunction (import ->name ));
75+ });
76+
77+ for (const auto & export_ : module .exports ) {
78+ if (export_->kind != ExternalKind::Function) {
79+ continue ;
80+ }
81+
82+ // TODO: internal or external? I think internal
83+ // This might be why we failed to lookup the function earlier
84+ // Maybe we can use Function* after all
85+ addressedFuncs.insert (module .getFunction (*export_->getInternalName ()));
86+ }
87+
88+ ElementUtils::iterAllElementFunctionNames (
89+ &module , [&addressedFuncs, &module ](Name func) {
90+ addressedFuncs.insert (module .getFunction (func));
91+ });
92+
93+ return addressedFuncs;
94+ }
95+
4996std::map<Function*, FuncInfo> analyzeFuncs (Module& module ,
5097 const PassOptions& passOptions) {
98+ std::unordered_set<Name> addressedFuncs;
5199 ModuleUtils::ParallelFunctionAnalysis<FuncInfo> analysis (
52100 module , [&](Function* func, FuncInfo& funcInfo) {
53101 if (func->imported ()) {
@@ -78,10 +126,14 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
78126 const PassOptions& options;
79127 FuncInfo& funcInfo;
80128
129+ std::unordered_set<Name>& addressedFuncs;
130+
81131 CallScanner (Module& wasm,
82132 const PassOptions& options,
83- FuncInfo& funcInfo)
84- : wasm(wasm), options(options), funcInfo(funcInfo) {}
133+ FuncInfo& funcInfo,
134+ std::unordered_set<Name>& addressedFuncs)
135+ : wasm(wasm), options(options), funcInfo(funcInfo),
136+ addressedFuncs (addressedFuncs) {}
85137
86138 void visitExpression (Expression* curr) {
87139 ShallowEffectAnalyzer effects (options, wasm, curr);
@@ -114,7 +166,7 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
114166 }
115167 }
116168 };
117- CallScanner scanner (module , passOptions, funcInfo);
169+ CallScanner scanner (module , passOptions, funcInfo, addressedFuncs );
118170 scanner.walkFunction(func);
119171 }
120172 });
@@ -146,6 +198,7 @@ using CallGraph =
146198
147199CallGraph buildCallGraph (const Module& module ,
148200 const std::map<Function*, FuncInfo>& funcInfos,
201+ const std::unordered_set<Function*> addressedFuncs,
149202 bool closedWorld) {
150203 CallGraph callGraph;
151204
@@ -170,7 +223,9 @@ CallGraph buildCallGraph(const Module& module,
170223 }
171224
172225 // Type -> Function
173- callGraph[caller->type .getHeapType ()].insert (caller);
226+ if (addressedFuncs.contains (caller)) {
227+ callGraph[caller->type .getHeapType ()].insert (caller);
228+ }
174229 }
175230
176231 // Type -> Type
@@ -325,11 +380,12 @@ void copyEffectsToFunctions(const std::map<Function*, FuncInfo>& funcInfos) {
325380
326381struct GenerateGlobalEffects : public Pass {
327382 void run (Module* module ) override {
328- std::map<Function*, FuncInfo> funcInfos =
329- analyzeFuncs (*module , getPassOptions ());
383+ auto funcInfos = analyzeFuncs (*module , getPassOptions ());
384+
385+ auto addressedFuncs = getAddressedFuncs (*module );
330386
331- auto callGraph =
332- buildCallGraph ( *module , funcInfos, getPassOptions ().closedWorld );
387+ auto callGraph = buildCallGraph (
388+ *module , funcInfos, addressedFuncs , getPassOptions ().closedWorld );
333389
334390 propagateEffects (*module , getPassOptions (), funcInfos, callGraph);
335391
0 commit comments