Skip to content

Commit 9d4acee

Browse files
authored
Refactor removing module elements (#2489)
This creates utility functions for removing module elements: removing one element by name, and removing multiple elements using a predicate function. And makes other parts of code use it. I think this is a light-handed approach than calling `Module::updateMaps` after removing only a part of module elements. This also fixes a bug in the inlining pass: it didn't call `Module::updateMaps` after removing functions. After this patch callers don't need to additionally call it anyway.
1 parent 86492f7 commit 9d4acee

7 files changed

Lines changed: 74 additions & 106 deletions

File tree

auto_update_tests.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def update_example_tests():
197197
'-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-L' + libdir, '-pthread']
198198
print('build: ', ' '.join(extra))
199199
if src.endswith('.cpp'):
200-
extra += ['-std=c++11']
200+
extra += ['-std=c++14']
201201
print(os.getcwd())
202202
subprocess.check_call(extra)
203203
# Link against the binaryen C library DSO, using rpath
@@ -206,7 +206,7 @@ def update_example_tests():
206206
if os.environ.get('COMPILER_FLAGS'):
207207
for f in os.environ.get('COMPILER_FLAGS').split(' '):
208208
cmd.append(f)
209-
cmd = [os.environ.get('CXX') or 'g++', '-std=c++11'] + cmd
209+
cmd = [os.environ.get('CXX') or 'g++', '-std=c++14'] + cmd
210210
try:
211211
print('link: ', ' '.join(cmd))
212212
subprocess.check_call(cmd)

check.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ def run_gcc_tests():
388388
extra = [shared.NATIVECC, src, '-c', '-o', 'example.o',
389389
'-I' + os.path.join(shared.options.binaryen_root, 'src'), '-g', '-L' + libpath, '-pthread']
390390
if src.endswith('.cpp'):
391-
extra += ['-std=c++11']
391+
extra += ['-std=c++14']
392392
if os.environ.get('COMPILER_FLAGS'):
393393
for f in os.environ.get('COMPILER_FLAGS').split(' '):
394394
extra.append(f)
@@ -402,7 +402,7 @@ def run_gcc_tests():
402402
if os.environ.get('COMPILER_FLAGS'):
403403
for f in os.environ.get('COMPILER_FLAGS').split(' '):
404404
cmd.append(f)
405-
cmd = [shared.NATIVEXX, '-std=c++11'] + cmd
405+
cmd = [shared.NATIVEXX, '-std=c++14'] + cmd
406406
print('link: ', ' '.join(cmd))
407407
subprocess.check_call(cmd)
408408
print('run...', output_file)

src/passes/DuplicateFunctionElimination.cpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,8 @@ struct DuplicateFunctionElimination : public Pass {
8989
// perform replacements
9090
if (replacements.size() > 0) {
9191
// remove the duplicates
92-
auto& v = module->functions;
93-
v.erase(std::remove_if(v.begin(),
94-
v.end(),
95-
[&](const std::unique_ptr<Function>& curr) {
96-
return duplicates.count(curr->name) > 0;
97-
}),
98-
v.end());
99-
module->updateMaps();
92+
module->removeFunctions(
93+
[&](Function* func) { return duplicates.count(func->name) > 0; });
10094
OptUtils::replaceFunctions(runner, *module, replacements);
10195
} else {
10296
break;

src/passes/Inlining.cpp

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -385,23 +385,12 @@ struct Inlining : public Pass {
385385
OptUtils::optimizeAfterInlining(inlinedInto, module, runner);
386386
}
387387
// remove functions that we no longer need after inlining
388-
auto& funcs = module->functions;
389-
funcs.erase(std::remove_if(funcs.begin(),
390-
funcs.end(),
391-
[&](const std::unique_ptr<Function>& curr) {
392-
auto name = curr->name;
393-
auto& info = infos[name];
394-
bool canRemove =
395-
inlinedUses.count(name) &&
396-
inlinedUses[name] == info.calls &&
397-
!info.usedGlobally;
398-
#ifdef INLINING_DEBUG
399-
if (canRemove)
400-
std::cout << "removing " << name << '\n';
401-
#endif
402-
return canRemove;
403-
}),
404-
funcs.end());
388+
module->removeFunctions([&](Function* func) {
389+
auto name = func->name;
390+
auto& info = infos[name];
391+
return inlinedUses.count(name) && inlinedUses[name] == info.calls &&
392+
!info.usedGlobally;
393+
});
405394
// return whether we did any work
406395
return inlinedUses.size() > 0;
407396
}

src/passes/RemoveUnusedModuleElements.cpp

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -211,40 +211,18 @@ struct RemoveUnusedModuleElements : public Pass {
211211
// Compute reachability starting from the root set.
212212
ReachabilityAnalyzer analyzer(module, roots);
213213
// Remove unreachable elements.
214-
{
215-
auto& v = module->functions;
216-
v.erase(std::remove_if(v.begin(),
217-
v.end(),
218-
[&](const std::unique_ptr<Function>& curr) {
219-
return analyzer.reachable.count(ModuleElement(
220-
ModuleElementKind::Function,
221-
curr->name)) == 0;
222-
}),
223-
v.end());
224-
}
225-
{
226-
auto& v = module->globals;
227-
v.erase(std::remove_if(v.begin(),
228-
v.end(),
229-
[&](const std::unique_ptr<Global>& curr) {
230-
return analyzer.reachable.count(
231-
ModuleElement(ModuleElementKind::Global,
232-
curr->name)) == 0;
233-
}),
234-
v.end());
235-
}
236-
{
237-
auto& v = module->events;
238-
v.erase(std::remove_if(v.begin(),
239-
v.end(),
240-
[&](const std::unique_ptr<Event>& curr) {
241-
return analyzer.reachable.count(
242-
ModuleElement(ModuleElementKind::Event,
243-
curr->name)) == 0;
244-
}),
245-
v.end());
246-
}
247-
module->updateMaps();
214+
module->removeFunctions([&](Function* curr) {
215+
return analyzer.reachable.count(
216+
ModuleElement(ModuleElementKind::Function, curr->name)) == 0;
217+
});
218+
module->removeGlobals([&](Global* curr) {
219+
return analyzer.reachable.count(
220+
ModuleElement(ModuleElementKind::Global, curr->name)) == 0;
221+
});
222+
module->removeEvents([&](Event* curr) {
223+
return analyzer.reachable.count(
224+
ModuleElement(ModuleElementKind::Event, curr->name)) == 0;
225+
});
248226
// Handle the memory and table
249227
if (!exportsMemory && !analyzer.usesMemory) {
250228
if (!importsMemory) {
@@ -302,14 +280,8 @@ struct RemoveUnusedModuleElements : public Pass {
302280
call->fullType = canonicalize(call->fullType);
303281
}
304282
// remove no-longer used types
305-
module->functionTypes.erase(
306-
std::remove_if(module->functionTypes.begin(),
307-
module->functionTypes.end(),
308-
[&needed](std::unique_ptr<FunctionType>& type) {
309-
return needed.count(type.get()) == 0;
310-
}),
311-
module->functionTypes.end());
312-
module->updateMaps();
283+
module->removeFunctionTypes(
284+
[&](FunctionType* type) { return needed.count(type) == 0; });
313285
}
314286
};
315287

src/wasm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,12 @@ class Module {
13961396
void removeGlobal(Name name);
13971397
void removeEvent(Name name);
13981398

1399+
void removeFunctionTypes(std::function<bool(FunctionType*)> pred);
1400+
void removeExports(std::function<bool(Export*)> pred);
1401+
void removeFunctions(std::function<bool(Function*)> pred);
1402+
void removeGlobals(std::function<bool(Global*)> pred);
1403+
void removeEvents(std::function<bool(Event*)> pred);
1404+
13991405
void updateMaps();
14001406

14011407
void clearDebugInfo();

src/wasm/wasm.cpp

Lines changed: 42 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,57 +1155,64 @@ Event* Module::addEvent(Event* curr) {
11551155

11561156
void Module::addStart(const Name& s) { start = s; }
11571157

1158-
void Module::removeFunctionType(Name name) {
1159-
for (size_t i = 0; i < functionTypes.size(); i++) {
1160-
if (functionTypes[i]->name == name) {
1161-
functionTypes.erase(functionTypes.begin() + i);
1158+
template<typename Vector, typename Map>
1159+
void removeModuleElement(Vector& v, Map& m, Name name) {
1160+
m.erase(name);
1161+
for (size_t i = 0; i < v.size(); i++) {
1162+
if (v[i]->name == name) {
1163+
v.erase(v.begin() + i);
11621164
break;
11631165
}
11641166
}
1165-
functionTypesMap.erase(name);
11661167
}
11671168

1169+
void Module::removeFunctionType(Name name) {
1170+
removeModuleElement(functionTypes, functionTypesMap, name);
1171+
}
11681172
void Module::removeExport(Name name) {
1169-
for (size_t i = 0; i < exports.size(); i++) {
1170-
if (exports[i]->name == name) {
1171-
exports.erase(exports.begin() + i);
1172-
break;
1173-
}
1174-
}
1175-
exportsMap.erase(name);
1173+
removeModuleElement(exports, exportsMap, name);
11761174
}
1177-
11781175
void Module::removeFunction(Name name) {
1179-
for (size_t i = 0; i < functions.size(); i++) {
1180-
if (functions[i]->name == name) {
1181-
functions.erase(functions.begin() + i);
1182-
break;
1183-
}
1184-
}
1185-
functionsMap.erase(name);
1176+
removeModuleElement(functions, functionsMap, name);
11861177
}
1187-
11881178
void Module::removeGlobal(Name name) {
1189-
for (size_t i = 0; i < globals.size(); i++) {
1190-
if (globals[i]->name == name) {
1191-
globals.erase(globals.begin() + i);
1192-
break;
1193-
}
1194-
}
1195-
globalsMap.erase(name);
1179+
removeModuleElement(globals, globalsMap, name);
11961180
}
1197-
11981181
void Module::removeEvent(Name name) {
1199-
for (size_t i = 0; i < events.size(); i++) {
1200-
if (events[i]->name == name) {
1201-
events.erase(events.begin() + i);
1202-
break;
1182+
removeModuleElement(events, eventsMap, name);
1183+
}
1184+
1185+
template<typename Vector, typename Map, typename Elem>
1186+
void removeModuleElements(Vector& v,
1187+
Map& m,
1188+
std::function<bool(Elem* elem)> pred) {
1189+
for (auto it = m.begin(); it != m.end();) {
1190+
if (pred(it->second)) {
1191+
it = m.erase(it);
1192+
} else {
1193+
it++;
12031194
}
12041195
}
1205-
eventsMap.erase(name);
1196+
v.erase(
1197+
std::remove_if(v.begin(), v.end(), [&](auto& e) { return pred(e.get()); }),
1198+
v.end());
12061199
}
12071200

1208-
// TODO: remove* for other elements
1201+
void Module::removeFunctionTypes(std::function<bool(FunctionType*)> pred) {
1202+
removeModuleElements(functionTypes, functionTypesMap, pred);
1203+
}
1204+
void Module::removeExports(std::function<bool(Export*)> pred) {
1205+
removeModuleElements(exports, exportsMap, pred);
1206+
}
1207+
void Module::removeFunctions(std::function<bool(Function*)> pred) {
1208+
removeModuleElements(functions, functionsMap, pred);
1209+
}
1210+
void Module::removeGlobals(std::function<bool(Global*)> pred) {
1211+
removeModuleElements(globals, globalsMap, pred);
1212+
}
1213+
void Module::removeEvents(std::function<bool(Event*)> pred) {
1214+
removeModuleElements(events, eventsMap, pred);
1215+
}
12091216

12101217
void Module::updateMaps() {
12111218
functionsMap.clear();

0 commit comments

Comments
 (0)