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/graph_traversal.h"
@@ -47,8 +48,55 @@ struct FuncInfo {
4748 std::unordered_set<HeapType> indirectCalledTypes;
4849};
4950
51+ std::unordered_set<Function*> getAddressedFuncs (Module& module ) {
52+ struct AddressedFuncsWalker
53+ : PostWalker<AddressedFuncsWalker,
54+ UnifiedExpressionVisitor<AddressedFuncsWalker>> {
55+ const Module& module ;
56+ std::unordered_set<Function*>& addressedFuncs;
57+
58+ AddressedFuncsWalker (const Module& module ,
59+ std::unordered_set<Function*>& addressedFuncs)
60+ : module (module ), addressedFuncs(addressedFuncs) {}
61+
62+ void visitExpression (Expression* curr) {
63+ if (auto * refFunc = curr->dynCast <RefFunc>()) {
64+ addressedFuncs.insert (module .getFunction (refFunc->func ));
65+ }
66+ }
67+ };
68+
69+ std::unordered_set<Function*> addressedFuncs;
70+ AddressedFuncsWalker walker (module , addressedFuncs);
71+ walker.walkModule (&module );
72+
73+ ModuleUtils::iterImportedFunctions (
74+ module , [&addressedFuncs, &module ](Function* import ) {
75+ addressedFuncs.insert (module .getFunction (import ->name ));
76+ });
77+
78+ for (const auto & export_ : module .exports ) {
79+ if (export_->kind != ExternalKind::Function) {
80+ continue ;
81+ }
82+
83+ // TODO: internal or external? I think internal
84+ // This might be why we failed to lookup the function earlier
85+ // Maybe we can use Function* after all
86+ addressedFuncs.insert (module .getFunction (*export_->getInternalName ()));
87+ }
88+
89+ ElementUtils::iterAllElementFunctionNames (
90+ &module , [&addressedFuncs, &module ](Name func) {
91+ addressedFuncs.insert (module .getFunction (func));
92+ });
93+
94+ return addressedFuncs;
95+ }
96+
5097std::map<Function*, FuncInfo> analyzeFuncs (Module& module ,
5198 const PassOptions& passOptions) {
99+ std::unordered_set<Name> addressedFuncs;
52100 ModuleUtils::ParallelFunctionAnalysis<FuncInfo> analysis (
53101 module , [&](Function* func, FuncInfo& funcInfo) {
54102 if (func->imported ()) {
@@ -79,10 +127,14 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
79127 const PassOptions& options;
80128 FuncInfo& funcInfo;
81129
130+ std::unordered_set<Name>& addressedFuncs;
131+
82132 CallScanner (Module& wasm,
83133 const PassOptions& options,
84- FuncInfo& funcInfo)
85- : wasm(wasm), options(options), funcInfo(funcInfo) {}
134+ FuncInfo& funcInfo,
135+ std::unordered_set<Name>& addressedFuncs)
136+ : wasm(wasm), options(options), funcInfo(funcInfo),
137+ addressedFuncs (addressedFuncs) {}
86138
87139 void visitExpression (Expression* curr) {
88140 ShallowEffectAnalyzer effects (options, wasm, curr);
@@ -115,7 +167,7 @@ std::map<Function*, FuncInfo> analyzeFuncs(Module& module,
115167 }
116168 }
117169 };
118- CallScanner scanner (module , passOptions, funcInfo);
170+ CallScanner scanner (module , passOptions, funcInfo, addressedFuncs );
119171 scanner.walkFunction(func);
120172 }
121173 });
@@ -147,6 +199,7 @@ using CallGraph =
147199
148200CallGraph buildCallGraph (const Module& module ,
149201 const std::map<Function*, FuncInfo>& funcInfos,
202+ const std::unordered_set<Function*> addressedFuncs,
150203 bool closedWorld) {
151204 CallGraph callGraph;
152205 if (!closedWorld) {
@@ -182,7 +235,9 @@ CallGraph buildCallGraph(const Module& module,
182235 }
183236
184237 // Type -> Function
185- callGraph[caller->type .getHeapType ()].insert (caller);
238+ if (addressedFuncs.contains (caller)) {
239+ callGraph[caller->type .getHeapType ()].insert (caller);
240+ }
186241 }
187242
188243 // Type -> Type
@@ -343,11 +398,12 @@ void copyEffectsToFunctions(const std::map<Function*, FuncInfo>& funcInfos) {
343398
344399struct GenerateGlobalEffects : public Pass {
345400 void run (Module* module ) override {
346- std::map<Function*, FuncInfo> funcInfos =
347- analyzeFuncs (*module , getPassOptions ());
401+ auto funcInfos = analyzeFuncs (*module , getPassOptions ());
402+
403+ auto addressedFuncs = getAddressedFuncs (*module );
348404
349- auto callGraph =
350- buildCallGraph ( *module , funcInfos, getPassOptions ().closedWorld );
405+ auto callGraph = buildCallGraph (
406+ *module , funcInfos, addressedFuncs , getPassOptions ().closedWorld );
351407
352408 propagateEffects (*module , getPassOptions (), funcInfos, callGraph);
353409
0 commit comments