1919// Function::effects; see more details there.
2020//
2121
22- #include " ir/table-utils.h"
23- #include " ir/subtypes.h"
2422#include " ir/effects.h"
23+ #include " ir/element-utils.h"
2524#include " ir/module-utils.h"
25+ #include " ir/subtypes.h"
26+ #include " ir/table-utils.h"
2627#include " pass.h"
27- #include " ir/element-utils.h"
2828#include " support/unique_deferring_queue.h"
2929#include " wasm.h"
3030
@@ -125,7 +125,8 @@ using CallGraphNode = std::variant<Name, HeapType>;
125125// Then B inherits effects from C and A inherits effects from both B and C.
126126void propagateEffects (
127127 const Module& module ,
128- const std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>& reverseCallGraph,
128+ const std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>&
129+ reverseCallGraph,
129130 std::map<Function*, FuncInfo>& funcInfos) {
130131
131132 using CallGraphEdge = std::pair<CallGraphNode, CallGraphNode>;
@@ -164,8 +165,10 @@ void propagateEffects(
164165 while (!work.empty ()) {
165166 auto [callee, caller] = work.pop ();
166167
167- if (std::get_if<Name>(&callee) == std::get_if<Name>(&caller) && std::holds_alternative<Name>(callee)) {
168- auto & callerEffects = funcInfos.at (module .getFunction (std::get<Name>(caller))).effects ;
168+ if (std::get_if<Name>(&callee) == std::get_if<Name>(&caller) &&
169+ std::holds_alternative<Name>(callee)) {
170+ auto & callerEffects =
171+ funcInfos.at (module .getFunction (std::get<Name>(caller))).effects ;
169172 if (callerEffects) {
170173 callerEffects->trap = true ;
171174 }
@@ -193,15 +196,18 @@ struct GenerateGlobalEffects : public Pass {
193196 analyzeFuncs (*module , getPassOptions ());
194197
195198 // callee : caller
196- std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>> callers;
199+ std::unordered_map<CallGraphNode, std::unordered_set<CallGraphNode>>
200+ callers;
197201
198202 std::unordered_set<HeapType> allIndirectCalledTypes;
199203
200204 std::unordered_set<Name> funcsWithAddress;
201205
202206 auto refFuncs = TableUtils::getFunctionsNeedingElemDeclare (*module );
203207 funcsWithAddress.insert (refFuncs.begin (), refFuncs.end ());
204- ElementUtils::iterAllElementFunctionNames (module , [&funcsWithAddress](Name name) { funcsWithAddress.insert (name); });
208+ ElementUtils::iterAllElementFunctionNames (
209+ module ,
210+ [&funcsWithAddress](Name name) { funcsWithAddress.insert (name); });
205211 for (const auto & export_ : module ->exports ) {
206212 if (export_->kind == ExternalKind::Function) {
207213 // This exported function might flow back to us even in a closed world,
@@ -233,10 +239,10 @@ struct GenerateGlobalEffects : public Pass {
233239 for (auto type : allIndirectCalledTypes) {
234240 subtypes.iterSubTypes (type, [&callers, type](HeapType sub, int _) {
235241 // HeapType -> HeapType
236- // A subtype is a 'callee' of its supertype. Supertypes need to inherit effects from their subtypes
237- // See the example in (TODO)
242+ // A subtype is a 'callee' of its supertype.
243+ // Supertypes need to inherit effects from their subtypes since they may
244+ // be called via a ref to the subtype.
238245 callers[sub].insert (type);
239- // callers[type].insert(sub);
240246 return true ;
241247 });
242248 }
@@ -247,7 +253,7 @@ struct GenerateGlobalEffects : public Pass {
247253 // known.
248254 for (auto & [func, info] : funcInfos) {
249255 func->effects .reset ();
250- if (! info.effects ) {
256+ if (info.effects == UnknownEffects ) {
251257 continue ;
252258 }
253259
0 commit comments