Skip to content

Commit 1b591a0

Browse files
committed
add eliminator mode for asm
1 parent b707c2c commit 1b591a0

6 files changed

Lines changed: 37 additions & 5 deletions

File tree

emcc

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,12 @@ try:
11661166
if DEBUG: save_intermediate('pretty')
11671167

11681168
def get_eliminate():
1169-
return 'eliminate' if not shared.Settings.ALLOW_MEMORY_GROWTH else 'eliminateMemSafe'
1169+
if shared.Settings.ASM_JS:
1170+
return 'eliminateAsm'
1171+
elif shared.Settings.ALLOW_MEMORY_GROWTH:
1172+
return 'eliminateMemSafe'
1173+
else:
1174+
return 'eliminate'
11701175

11711176
js_optimizer_queue += [get_eliminate()]
11721177

tests/runner.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8531,6 +8531,8 @@ def test_js_optimizer(self):
85318531
['eliminate']),
85328532
(path_from_root('tools', 'eliminator', 'safe-eliminator-test.js'), open(path_from_root('tools', 'eliminator', 'safe-eliminator-test-output.js')).read(),
85338533
['eliminateMemSafe']),
8534+
(path_from_root('tools', 'eliminator', 'asm-eliminator-test.js'), open(path_from_root('tools', 'eliminator', 'asm-eliminator-test-output.js')).read(),
8535+
['eliminateAsm']),
85348536
]:
85358537
output = Popen([NODE_JS, path_from_root('tools', 'js-optimizer.js'), input] + passes, stdin=PIPE, stdout=PIPE).communicate()[0]
85368538
self.assertIdentical(expected, output.replace('\r\n', '\n').replace('\n\n', '\n'))
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
function asm(x, y) {
2+
x = +x;
3+
y = y | 0;
4+
var a = 0;
5+
a = cheez(y + ~~x | 0) | 0;
6+
fleefl(a * a | 0, a | 0);
7+
}
8+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function asm(x, y) {
2+
x = +x;
3+
y = y|0;
4+
var a = 0, b = +0, c = 0;
5+
var label = 0;
6+
a = cheez((y+~~x)|0)|0;
7+
b = a*a;
8+
fleefl(b|0, a|0);
9+
}
10+
// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm"]
11+

tools/eliminator/eliminator-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8828,7 +8828,7 @@ function _mallocNoU($bytes) {
88288828
return $mem_0;
88298829
return null;
88308830
}
8831-
function asm(x, y) {
8831+
function asm(x, y) { // asm-style code, without special asm requested so will not be fully optimized
88328832
x = +x;
88338833
y = y|0;
88348834
var a = 0, b = +0, c = 0;

tools/js-optimizer.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,7 +1408,7 @@ var NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS = set('name', 'num', 'string', 'binar
14081408
var IGNORABLE_ELIMINATOR_SCAN_NODES = set('num', 'toplevel', 'string', 'break', 'continue', 'dot'); // dot can only be STRING_TABLE.*
14091409
var ABORTING_ELIMINATOR_SCAN_NODES = set('new', 'object', 'function', 'defun', 'switch', 'for', 'while', 'array', 'throw'); // we could handle some of these, TODO, but nontrivial (e.g. for while, the condition is hit multiple times after the body)
14101410

1411-
function eliminate(ast, memSafe) {
1411+
function eliminate(ast, memSafe, asm) {
14121412
// Find variables that have a single use, and if they can be eliminated, do so
14131413
traverseGeneratedFunctions(ast, function(func, type) {
14141414
//printErr('eliminate in ' + func[1]);
@@ -1426,6 +1426,7 @@ function eliminate(ast, memSafe) {
14261426
locals[func[2][i]] = true;
14271427
}
14281428
}
1429+
var defaultDefs = asm ? -1 : 0; // in asm.js we have an extra formal def which we can ignore
14291430
// examine body and note locals
14301431
traverse(func, function(node, type) {
14311432
if (type === 'var') {
@@ -1435,7 +1436,7 @@ function eliminate(ast, memSafe) {
14351436
var name = node1i[0];
14361437
var value = node1i[1];
14371438
if (value) {
1438-
if (!definitions[name]) definitions[name] = 0;
1439+
if (!(name in definitions)) definitions[name] = defaultDefs;
14391440
definitions[name]++;
14401441
if (!values[name]) values[name] = value;
14411442
}
@@ -1450,7 +1451,7 @@ function eliminate(ast, memSafe) {
14501451
var target = node[2];
14511452
if (target[0] == 'name') {
14521453
var name = target[1];
1453-
if (!definitions[name]) definitions[name] = 0;
1454+
if (!(name in definitions)) definitions[name] = defaultDefs;
14541455
definitions[name]++;
14551456
if (!uses[name]) uses[name] = 0;
14561457
if (!values[name]) values[name] = node[3];
@@ -1872,6 +1873,10 @@ function eliminateMemSafe(ast) {
18721873
eliminate(ast, true);
18731874
}
18741875

1876+
function eliminateAsm(ast) {
1877+
eliminate(ast, false, true);
1878+
}
1879+
18751880
// Passes table
18761881

18771882
var compress = false, printMetadata = true;
@@ -1891,6 +1896,7 @@ var passes = {
18911896
registerize: registerize,
18921897
eliminate: eliminate,
18931898
eliminateMemSafe: eliminateMemSafe,
1899+
eliminateAsm: eliminateAsm,
18941900
compress: function() { compress = true; },
18951901
noPrintMetadata: function() { printMetadata = false; }
18961902
};

0 commit comments

Comments
 (0)