aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/emconfiguren.py2
-rwxr-xr-xtools/emmaken.py2
-rw-r--r--tools/js-optimizer.js74
-rw-r--r--tools/shared.py16
-rw-r--r--tools/test-js-optimizer-output.js9
-rw-r--r--tools/test-js-optimizer.js7
6 files changed, 103 insertions, 7 deletions
diff --git a/tools/emconfiguren.py b/tools/emconfiguren.py
index abe41564..d549908b 100755
--- a/tools/emconfiguren.py
+++ b/tools/emconfiguren.py
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+raise Exception('emconfiguren is deprecated!')
+
'''
This is a helper script for emmaken.py. See docs in that file for more info.
'''
diff --git a/tools/emmaken.py b/tools/emmaken.py
index a509b940..89785bc5 100755
--- a/tools/emmaken.py
+++ b/tools/emmaken.py
@@ -1,5 +1,7 @@
#!/usr/bin/env python
+raise Exception('emmaken is deprecated!')
+
'''
emmaken - the emscripten make proxy tool
========================================
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index d22de39c..bf971951 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -78,6 +78,7 @@ function traverse(node, pre, post, stack) {
if (stack) len = stack.length;
var result = pre(node, type, stack);
if (result == true) return true;
+ if (typeof result == 'object') node = result; // Continue processing on this node
if (stack && len == stack.length) stack.push(0);
}
for (var i = 0; i < node.length; i++) {
@@ -259,8 +260,74 @@ function removeUnneededLabelSettings(ast) {
});
}
-// Various expression simplifications
-function simplifyExpressions(ast) {
+// Various expression simplifications. Pre run before closure (where we still have metadata), Post run after.
+
+function simplifyExpressionsPre(ast) {
+ // When there is a bunch of math like (((8+5)|0)+12)|0, only the external |0 is needed, one correction is enough.
+ // At each node, ((X|0)+Y)|0 can be transformed into (X+Y): The inner corrections are not needed
+ // TODO: Is the same is true for 0xff, 0xffff?
+
+ function simplifyBitops(ast) {
+ var SAFE_BINARY_OPS = set('+', '-', '*', '/', '%', '|');
+ var ZERO = ['num', 0];
+ var rerun = true;
+ while (rerun) {
+ rerun = false;
+ traverseGenerated(ast, function(node, type, stack) {
+ if (type == 'binary' && node[1] == '|' && (jsonCompare(node[2], ZERO) || jsonCompare(node[3], ZERO))) {
+ stack.push(1); // From here on up, no need for this kind of correction, it's done at the top
+
+ // We might be able to remove this correction
+ for (var i = stack.length-2; i >= 0; i--) {
+ if (stack[i] == 1) {
+ // Great, we can eliminate
+ rerun = true;
+ return jsonCompare(node[2], ZERO) ? node[3] : node[2];
+ } else if (stack[i] == -1) {
+ break; // Too bad, we can't
+ }
+ }
+ } else if ((type == 'binary' && node[1] in SAFE_BINARY_OPS) || type == 'num' || type == 'name') {
+ stack.push(0); // This node is safe in that it does not interfere with this optimization
+ } else {
+ stack.push(-1); // This node is dangerous! Give up if you see this before you see '1'
+ }
+ }, null, []);
+ }
+ }
+
+ // The most common mathop is addition, e.g. in getelementptr done repeatedly. We can join all of those,
+ // by doing (num+num) ==> newnum, and (name+num)+num = name+newnum
+ function joinAdditions(ast) {
+ var rerun = true;
+ while (rerun) {
+ rerun = false;
+ traverseGenerated(ast, function(node, type) {
+ if (type == 'binary' && node[1] == '+') {
+ if (node[2][0] == 'num' && node[3][0] == 'num') {
+ rerun = true;
+ return ['num', node[2][1] + node[3][1]];
+ }
+ for (var i = 2; i <= 3; i++) {
+ var ii = 5-i;
+ for (var j = 2; j <= 3; j++) {
+ if (node[i][0] == 'num' && node[ii][0] == 'binary' && node[ii][1] == '+' && node[ii][j][0] == 'num') {
+ rerun = true;
+ node[ii][j][1] += node[i][1];
+ return node[ii];
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+ simplifyBitops(ast);
+ joinAdditions(ast);
+}
+
+function simplifyExpressionsPost(ast) {
// We often have branchings that are simplified so one end vanishes, and
// we then get
// if (!(x < 5))
@@ -373,7 +440,8 @@ var passes = {
unGlobalize: unGlobalize,
removeAssignsToUndefined: removeAssignsToUndefined,
//removeUnneededLabelSettings: removeUnneededLabelSettings,
- simplifyExpressions: simplifyExpressions,
+ simplifyExpressionsPre: simplifyExpressionsPre,
+ simplifyExpressionsPost: simplifyExpressionsPost,
loopOptimizer: loopOptimizer
};
diff --git a/tools/shared.py b/tools/shared.py
index b61552ba..cecfd4ac 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -28,6 +28,10 @@ DEMANGLER = path_from_root('third_party', 'demangler.py')
NAMESPACER = path_from_root('tools', 'namespacer.py')
EMCC = path_from_root('emcc')
EMXX = path_from_root('em++')
+EMAR = path_from_root('emar')
+EMLD = path_from_root('emld')
+EMRANLIB = path_from_root('emranlib')
+EMLIBTOOL = path_from_root('emlibtool')
EMMAKEN = path_from_root('tools', 'emmaken.py')
AUTODEBUGGER = path_from_root('tools', 'autodebugger.py')
DFE = path_from_root('tools', 'dead_function_eliminator.py')
@@ -217,7 +221,11 @@ class Building:
@staticmethod
def get_building_env():
env = os.environ.copy()
- env['RANLIB'] = env['AR'] = env['CXX'] = env['CC'] = env['LIBTOOL'] = EMMAKEN
+ env['CC'] = EMCC
+ env['CXX'] = EMXX
+ env['AR'] = EMAR
+ env['RANLIB'] = EMRANLIB
+ env['LIBTOOL'] = EMLIBTOOL
env['EMMAKEN_COMPILER'] = Building.COMPILER
env['EMSCRIPTEN_TOOLS'] = path_from_root('tools')
env['CFLAGS'] = env['EMMAKEN_CFLAGS'] = ' '.join(COMPILER_OPTS + Building.COMPILER_TEST_OPTS) # Normal CFLAGS is ignored by some configure's.
@@ -369,6 +377,8 @@ class Building:
if output_processor is not None:
output_processor(open(filename + '.o.js').read())
+ return filename + '.o.js'
+
@staticmethod
def pick_llvm_opts(optimization_level, safe=True):
'''
@@ -472,6 +482,7 @@ class Building:
f = open(filename, 'w')
f.write(output)
f.close()
+ return filename
@staticmethod
def eliminator(filename):
@@ -486,6 +497,7 @@ class Building:
f = open(filename, 'w')
f.write(output)
f.close()
+ return filename
@staticmethod
def closure_compiler(filename):
@@ -502,3 +514,5 @@ class Building:
if 'ERROR' in cc_output:
raise Exception('Error in cc output: ' + cc_output)
+ return filename + '.cc.js'
+
diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js
index fcd2380d..d171c5b5 100644
--- a/tools/test-js-optimizer-output.js
+++ b/tools/test-js-optimizer-output.js
@@ -79,6 +79,11 @@ function ignoreLoopy() {
}
}
function bits() {
- print((($s & 65535) + ((($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) | 0 | 0) % 256 | 0) & 65535);
+ print((($s & 65535) + (($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) % 256 | 0) & 65535);
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits"]
+function maths() {
+ check(17);
+ check(95);
+ __ZN6b2Vec2C1Ev($this1 + 76 | 0);
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths"]
diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js
index e06ebd29..0665462b 100644
--- a/tools/test-js-optimizer.js
+++ b/tools/test-js-optimizer.js
@@ -83,5 +83,10 @@ function ignoreLoopy() {
function bits() { // TODO: optimize this!
print((($s & 65535) + ((($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) | 0 | 0) % 256 | 0) & 65535);
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits"]
+function maths() {
+ check(5+12);
+ check(90+3+2);
+ __ZN6b2Vec2C1Ev(((((((($this1 + 20 | 0 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0);
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths"]