Skip to content

Commit 07860ff

Browse files
authored
[NFC] Add comments to RemoveUnusedModuleElements + renamings (#7750)
Followup to recent investigation, summarizing the reasons for the current separation of classes in that pass. Also rename methods for clarity.
1 parent fa18bdd commit 07860ff

File tree

1 file changed

+42
-32
lines changed

1 file changed

+42
-32
lines changed

src/passes/RemoveUnusedModuleElements.cpp

Lines changed: 42 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -66,28 +66,38 @@ using ModuleElement = std::pair<ModuleElementKind, Name>;
6666
// Information from an indirect call: the name of the table, and the heap type.
6767
using IndirectCall = std::pair<Name, HeapType>;
6868

69-
// Visit or walk an expression to find what things are referenced.
70-
struct ReferenceFinder
71-
: public PostWalker<ReferenceFinder,
72-
UnifiedExpressionVisitor<ReferenceFinder>> {
73-
// Our findings are placed in these data structures, which the user of this
74-
// code can then process. We mark both uses and references, and also note
75-
// uses of specific things that require special handling, like refFuncs.
69+
// Visit or walk an expression to find important things. We note them on data
70+
// structures that the caller can then process.
71+
//
72+
// We could in theory merge this class in with Analyzer, allowing us to
73+
// directly apply our findings - that is, rather than add to a data structure,
74+
// then the caller iterates on it and calls a method on them all, we could call
75+
// that method as we go. However, separating the classes is simpler as we need
76+
// different handling in different cases (when scanning for references vs when
77+
// scanning normally, see below).
78+
//
79+
// In theory we could parallelize this class, processing all functions in
80+
// advance, rather than as we go (single-threaded). However, this turns out not
81+
// to be faster in practice (perhaps because the single-threaded approach uses
82+
// less memory).
83+
struct Noter : public PostWalker<Noter, UnifiedExpressionVisitor<Noter>> {
84+
// We mark both uses and references, and also note specific things that
85+
// require special handling, like refFuncs.
7686
std::vector<ModuleElement> used, referenced;
7787
std::vector<HeapType> callRefTypes;
7888
std::vector<Name> refFuncs;
7989
std::vector<StructField> structFields;
8090
std::vector<IndirectCall> indirectCalls;
8191

82-
// Add an item to the output data structures.
92+
// Note an item on our output data structures.
8393
void use(ModuleElement element) { used.push_back(element); }
8494
void reference(ModuleElement element) { referenced.push_back(element); }
85-
void useCallRef(HeapType type) { callRefTypes.push_back(type); }
86-
void useRefFunc(Name refFunc) { refFuncs.push_back(refFunc); }
87-
void useStructField(StructField structField) {
95+
void noteCallRef(HeapType type) { callRefTypes.push_back(type); }
96+
void noteRefFunc(Name refFunc) { refFuncs.push_back(refFunc); }
97+
void noteStructField(StructField structField) {
8898
structFields.push_back(structField);
8999
}
90-
void useIndirectCall(Name table, HeapType type) {
100+
void noteIndirectCall(Name table, HeapType type) {
91101
indirectCalls.push_back({table, type});
92102
}
93103

@@ -154,12 +164,12 @@ struct ReferenceFinder
154164
// We refer to the table, but may not use all parts of it, that depends on
155165
// the heap type we call with.
156166
reference({ModuleElementKind::Table, curr->table});
157-
useIndirectCall(curr->table, curr->heapType);
167+
noteIndirectCall(curr->table, curr->heapType);
158168
// Note a possible call of a function reference as well, as something might
159169
// be written into the table during runtime. With precise tracking of what
160170
// is written into the table we could do better here; we could also see
161171
// which tables are immutable. TODO
162-
useCallRef(curr->heapType);
172+
noteCallRef(curr->heapType);
163173
}
164174

165175
void visitCallRef(CallRef* curr) {
@@ -168,17 +178,17 @@ struct ReferenceFinder
168178
return;
169179
}
170180

171-
useCallRef(curr->target->type.getHeapType());
181+
noteCallRef(curr->target->type.getHeapType());
172182
}
173183

174-
void visitRefFunc(RefFunc* curr) { useRefFunc(curr->func); }
184+
void visitRefFunc(RefFunc* curr) { noteRefFunc(curr->func); }
175185

176186
void visitStructGet(StructGet* curr) {
177187
if (curr->ref->type == Type::unreachable || curr->ref->type.isNull()) {
178188
return;
179189
}
180190
auto type = curr->ref->type.getHeapType();
181-
useStructField(StructField{type, curr->index});
191+
noteStructField(StructField{type, curr->index});
182192
}
183193
};
184194

@@ -276,25 +286,25 @@ struct Analyzer {
276286

277287
// Find references in this expression, and apply them. Anything found here
278288
// is used.
279-
ReferenceFinder finder;
280-
finder.setModule(module);
281-
finder.visit(curr);
282-
for (auto element : finder.used) {
289+
Noter noter;
290+
noter.setModule(module);
291+
noter.visit(curr);
292+
for (auto element : noter.used) {
283293
use(element);
284294
}
285-
for (auto element : finder.referenced) {
295+
for (auto element : noter.referenced) {
286296
reference(element);
287297
}
288-
for (auto type : finder.callRefTypes) {
298+
for (auto type : noter.callRefTypes) {
289299
useCallRefType(type);
290300
}
291-
for (auto func : finder.refFuncs) {
301+
for (auto func : noter.refFuncs) {
292302
useRefFunc(func);
293303
}
294-
for (auto structField : finder.structFields) {
304+
for (auto structField : noter.structFields) {
295305
useStructField(structField);
296306
}
297-
for (auto call : finder.indirectCalls) {
307+
for (auto call : noter.indirectCalls) {
298308
useIndirectCall(call);
299309
}
300310

@@ -604,18 +614,18 @@ struct Analyzer {
604614
// here).
605615
void addReferences(Expression* curr) {
606616
// Find references anywhere in this expression so we can apply them.
607-
ReferenceFinder finder;
608-
finder.setModule(module);
609-
finder.walk(curr);
617+
Noter noter;
618+
noter.setModule(module);
619+
noter.walk(curr);
610620

611-
for (auto element : finder.used) {
621+
for (auto element : noter.used) {
612622
reference(element);
613623
}
614-
for (auto element : finder.referenced) {
624+
for (auto element : noter.referenced) {
615625
reference(element);
616626
}
617627

618-
for (auto func : finder.refFuncs) {
628+
for (auto func : noter.refFuncs) {
619629
// If a function ends up referenced but not used then later down we will
620630
// empty it out by replacing its body with an unreachable, which always
621631
// validates. For that reason all we need to do here is mark the function

0 commit comments

Comments
 (0)