Clear out asm assignments in minimal runtime metadce (#10725)

Before this, if X was never used (via metadce), we would still have

 X = asm['X']

After this that doesn't exist.

Closure can do this (but doesn't always), so this mostly helps
non-closure builds.
This commit is contained in:
Alon Zakai 2020-03-19 10:34:25 -07:00 коммит произвёл GitHub
Родитель 29cb8336bb
Коммит 96a4a90562
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
8 изменённых файлов: 80 добавлений и 12 удалений

Просмотреть файл

@ -2,9 +2,9 @@
"a.html": 588,
"a.html.gz": 386,
"a.js": 24518,
"a.js.gz": 9119,
"a.js.gz": 9124,
"a.mem": 3168,
"a.mem.gz": 2711,
"total": 28274,
"total_gz": 12216
"total_gz": 12221
}

Просмотреть файл

@ -2,9 +2,9 @@
"a.html": 588,
"a.html.gz": 386,
"a.js": 24013,
"a.js.gz": 8955,
"a.js.gz": 8962,
"a.mem": 3168,
"a.mem.gz": 2711,
"total": 27769,
"total_gz": 12052
"total_gz": 12059
}

Просмотреть файл

@ -2,9 +2,9 @@
"a.html": 697,
"a.html.gz": 437,
"a.js": 2026,
"a.js.gz": 911,
"a.js.gz": 913,
"a.mem": 6,
"a.mem.gz": 32,
"total": 2729,
"total_gz": 1380
"total_gz": 1382
}

Просмотреть файл

@ -1,6 +1,6 @@
{
"a.html": 20054,
"a.html.gz": 8394,
"total": 20054,
"total_gz": 8394
"a.html": 20051,
"a.html.gz": 8371,
"total": 20051,
"total_gz": 8371
}

Просмотреть файл

@ -0,0 +1,22 @@
var name;
var asmLibraryArg = {
"save1": 1,
"save2": 2
};
WebAssembly.instantiate(Module["wasm"], imports).then(function(output) {
asm = output.instance.exports;
expD1 = asm["expD1"];
expD2 = asm["expD2"];
expD3 = asm["expD3"];
initRuntime(asm);
ready();
});
expD1;
Module["expD2"];
asm["expD3"];

Просмотреть файл

@ -0,0 +1,20 @@
var name;
var asmLibraryArg = { 'save1': 1, 'number': 33, 'name': name, 'func': function() {}, 'save2': 2 };
// exports gotten directly in the minimal runtime style
WebAssembly.instantiate(Module["wasm"], imports).then(function(output) {
asm = output.instance.exports;
expD1 = asm['expD1'];
expD2 = asm['expD2'];
expD3 = asm['expD3'];
expD4 = asm['expD4'];
initRuntime(asm);
ready();
});
// add uses for some of them, leave *4 as non-roots
expD1;
Module['expD2'];
asm['expD3'];
// EXTRA_INFO: { "unused": ["emcc$import$number", "emcc$import$name", "emcc$import$func", "emcc$export$expD4", "emcc$export$expI4"] }

2
tests/test_other.py поставляемый
Просмотреть файл

@ -2171,6 +2171,8 @@ int f() {
['emitDCEGraph', 'noPrint']),
(path_from_root('tests', 'optimizer', 'emitDCEGraph5.js'), open(path_from_root('tests', 'optimizer', 'emitDCEGraph5-output.js')).read(),
['emitDCEGraph', 'noPrint']),
(path_from_root('tests', 'optimizer', 'minimal-runtime-applyDCEGraphRemovals.js'), open(path_from_root('tests', 'optimizer', 'minimal-runtime-applyDCEGraphRemovals-output.js')).read(),
['applyDCEGraphRemovals']),
(path_from_root('tests', 'optimizer', 'applyDCEGraphRemovals.js'), open(path_from_root('tests', 'optimizer', 'applyDCEGraphRemovals-output.js')).read(),
['applyDCEGraphRemovals']),
(path_from_root('tests', 'optimizer', 'applyImportAndExportNameChanges.js'), open(path_from_root('tests', 'optimizer', 'applyImportAndExportNameChanges-output.js')).read(),

Просмотреть файл

@ -112,12 +112,19 @@ function nullify(node) {
node.raw = 'null';
}
function undefinedify(node) {
// This converts the node into something that terser will ignore in a var
// declaration, that is, it is a way to get rid of initial values.
function convertToNothingInVarInit(node) {
node.type = 'Literal';
node.value = undefined;
node.raw = 'undefined';
}
function convertToNull(node) {
node.type = 'Identifier';
node.name = 'null';
}
function setLiteralValue(item, value) {
item.value = value;
item.raw = "'" + value + "'";
@ -851,7 +858,24 @@ function applyDCEGraphRemovals(ast) {
var value = node.right;
if ((full in unused) &&
(isAsmUse(value) || !hasSideEffects(value))) {
undefinedify(node);
// This will be in a var init, and we just remove that value.
convertToNothingInVarInit(node);
}
}
} else if (node.type === 'ExpressionStatement') {
var expr = node.expression;
// In the minimal runtime code pattern we have just
// x = asm['x']
// and never in a var.
if (expr.operator === '=' &&
expr.left.type === 'Identifier' &&
isAsmUse(expr.right)) {
var name = expr.left.name;
if (name === getAsmOrModuleUseName(expr.right)) {
var full = 'emcc$export$' + name;
if (full in unused) {
emptyOut(node);
}
}
}
}