aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-31 11:56:53 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-31 11:56:53 -0800
commit2325baf34e144586d71251f31c01c7f2abfdb8b7 (patch)
tree6dec7e37e75040034d443786d4701e62b38a4d6d /tools
parent8aa6919b7acf0b4034735ac7ee597e946fefaf4d (diff)
parenta55c2a24a50a93fcf9035eb2a809d13d3a8d3555 (diff)
Merge branch 'incoming' into asm_js
Conflicts: src/library_browser.js
Diffstat (limited to 'tools')
-rw-r--r--tools/autodebugger.py31
-rw-r--r--tools/autodebugger_js.py47
-rw-r--r--tools/eliminator/eliminator-test-output.js7
-rw-r--r--tools/eliminator/eliminator-test.js14
-rw-r--r--tools/file_packager.py12
-rw-r--r--tools/js-optimizer.js4
-rw-r--r--tools/js_optimizer.py8
-rwxr-xr-xtools/nativize_llvm.py9
-rw-r--r--tools/shared.py9
9 files changed, 120 insertions, 21 deletions
diff --git a/tools/autodebugger.py b/tools/autodebugger.py
index 3631548c..c74e56d2 100644
--- a/tools/autodebugger.py
+++ b/tools/autodebugger.py
@@ -13,6 +13,7 @@ import os, sys, re
ALLOW_POINTERS = False
ALLOW_MISC = True
MEMCPY = False
+MEMCPY2 = False
NO_DLMALLOC = True
POSTAMBLE = '''
@@ -89,12 +90,15 @@ return: ; preds = %entry
POSTAMBLE_NEW = '''
@.emscripten.autodebug.str = private constant [10 x i8] c"AD:%d,%d\\0A\\00", align 1 ; [#uses=1]
+@.emscripten.autodebug.str.2 = private constant [13 x i8] c"AD:%d,%d,%d\\0A\\00", align 1 ; [#uses=1]
@.emscripten.autodebug.str.f = private constant [11 x i8] c"AD:%d,%lf\\0A\\00", align 1 ; [#uses=1]
; [#uses=1]
define void @emscripten_autodebug_i64(i32 %line, i64 %value) {
- %1 = sitofp i64 %value to double
- %2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([11 x i8]* @.emscripten.autodebug.str.f, i32 0, i32 0), i32 %line, double %1) ; [#uses=0]
+ %1 = trunc i64 %value to i32
+ %2 = lshr i64 %value, 32
+ %3 = trunc i64 %2 to i32
+ %4 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([13 x i8]* @.emscripten.autodebug.str.2, i32 0, i32 0), i32 %line, i32 %1, i32 %3) ; [#uses=0]
ret void
}
@@ -142,6 +146,10 @@ if 'declare i32 @printf(' not in data:
; [#uses=1]
declare i32 @printf(i8*, ...)
'''
+ POSTAMBLE_NEW += '''
+; [#uses=1]
+declare i32 @printf(i8*, ...)
+'''
LLVM_STYLE_OLD = '<label>' not in data and 'entry:' in data
@@ -252,20 +260,21 @@ for i in range(len(lines)):
lines_added += 1
continue
if ALLOW_MISC:
- m = re.match(' %(?P<var>[\w_.]+) = (call|mul|add) (nsw )?(?P<type>i64|i32|i16|i8|float|double+) .*', lines[i])
+ # call is risky - return values can be i32 (i8*) (i16)
+ m = re.match(' %(?P<var>[\w_.]+) = (mul|add) (nsw )?(?P<type>i64|i32|i16|i8|float|double+) .*', lines[i])
if m:
index = i+1+lines_added
lines[i] += '\n call void @emscripten_autodebug_%s(i32 %d, %s %%%s)' % (m.group('type'), index, m.group('type'), m.group('var'))
lines_added += 1
continue
- m = re.match(' call void @llvm\.memcpy\.p0i8\.p0i8\.i32\(i8\* %(?P<dst>[\w_.]+), i8\* %(?P<src>[\w_.]+), i32 8, i32 (?P<align>\d+),.*', lines[i])
- if m:
- index = i+1+lines_added
- lines[i] += '\n %%adpretemp%d = bitcast i8* %%%s to i64*' % (index, m.group('src')) + \
- '\n %%adtemp%d = load i64* %%adpretemp%d, align %s' % (index, index, m.group('align')) + \
- '\n call void @emscripten_autodebug_%s(i32 %d, %s %%adtemp%d)' % ('i64', index, 'i64', index)
- lines_added += 3
- continue
+ if MEMCPY2:
+ m = re.match(' call void @llvm\.memcpy\.p0i8\.p0i8\.i32\(i8\* %(?P<dst>[\w_.]+), i8\* %(?P<src>[\w_.]+), i32 8, i32 (?P<align>\d+),.*', lines[i])
+ if m:
+ index = i+1+lines_added
+ lines[i] += '\n %%adtemp%d = load i8* %%%s, align 1' % (index, m.group('src')) + \
+ '\n call void @emscripten_autodebug_i8(i32 %d, i8 %%adtemp%d)' % (index, index)
+ lines_added += 3
+ continue
finally:
if len(pre) > 0:
diff --git a/tools/autodebugger_js.py b/tools/autodebugger_js.py
new file mode 100644
index 00000000..3f8818c6
--- /dev/null
+++ b/tools/autodebugger_js.py
@@ -0,0 +1,47 @@
+'''
+Processes a C source file, adding debugging information.
+
+Similar to autodebugger.py, but runs on .js files.
+'''
+
+import os, sys, re
+
+filename = sys.argv[1]
+func = sys.argv[2]
+
+f = open(filename, 'r')
+data = f.read()
+f.close()
+
+lines = data.split('\n')
+in_func = False
+for i in range(len(lines)):
+ if lines[i].startswith('function '):
+ name = lines[i].split('(')[0].split(' ')[1]
+ args = lines[i].split('(')[1].split(')')[0]
+ lines[i] += ' print("call %s(" + [%s] + ")");' % (name, args)
+ if lines[i].startswith('function ' + func + '('):
+ in_func = True
+ continue
+ elif lines[i].startswith('}'):
+ in_func = False
+ continue
+ if in_func:
+ m = re.match('^ +([$_\w\d \[\]]+) = +([^;]+);$', lines[i])
+ if m and (' if ' not in lines[i-1] or '{' in lines[i-1]) and \
+ (' if ' not in lines[i+1] or '{' in lines[i+1]) and \
+ (' else' not in lines[i-1] or '{' in lines[i-1]) and \
+ (' else' not in lines[i+1] or '{' in lines[i+1]):
+ var = m.groups(1)[0].rstrip().split(' ')[-1]
+ if 'STACKTOP' not in lines[i] and 'stackBase' not in lines[i]:
+ #lines[i] += ''' print("[%4d] %s = " + %s);''' % (i+1, var, var)
+ lines[i] += ''' print("%s = " + %s);''' % (var, var)
+ m = re.match('^ +HEAP.*$', lines[i])
+ if m and lines[i].count(' = ') == 1:
+ left, right = lines[i].split(' = ')
+ lines[i] += ''' print("%s = " + %s);''' % (left, left)
+
+print '\n'.join(lines)
+
+print >> sys.stderr, 'Success.'
+
diff --git a/tools/eliminator/eliminator-test-output.js b/tools/eliminator/eliminator-test-output.js
index 0d60d305..a005a0a5 100644
--- a/tools/eliminator/eliminator-test-output.js
+++ b/tools/eliminator/eliminator-test-output.js
@@ -6148,4 +6148,11 @@ function phi() {
}
var $10;
}
+function intoCond() {
+ var $115 = 22;
+ var $NumWords = __ZN4llvm15BitstreamCursor4ReadEj($117, 32);
+ if (($115 | 0) != 0) {
+ HEAP32[$115 >> 2] = $NumWords;
+ }
+}
diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js
index 3d71c210..13ecab59 100644
--- a/tools/eliminator/eliminator-test.js
+++ b/tools/eliminator/eliminator-test.js
@@ -8847,5 +8847,17 @@ function phi() {
}
var $10;
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm", "phi"]
+function intoCond() {
+ var $115 = 22;
+ var $499 = __ZN4llvm15BitstreamCursor4ReadEj($117, 32);
+ var $NumWords = $499;
+ var $500 = $115;
+ var $501 = ($500 | 0) != 0;
+ if ($501) {
+ var $503 = $NumWords;
+ var $504 = $115;
+ HEAP32[$504 >> 2] = $503;
+ }
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "c", "f", "g", "h", "py", "r", "t", "f2", "f3", "llvm3_1", "_inflate", "_malloc", "_mallocNoU", "asm", "phi", "intoCond"]
diff --git a/tools/file_packager.py b/tools/file_packager.py
index 33082ac2..7e196efd 100644
--- a/tools/file_packager.py
+++ b/tools/file_packager.py
@@ -252,7 +252,17 @@ for file_ in data_files:
filename = file_['name']
if file_['mode'] == 'embed':
# Embed
- code += '''Module['FS_createDataFile']('/%s', '%s', %s, true, true);\n''' % (os.path.dirname(filename), os.path.basename(filename), str(map(ord, open(file_['localname'], 'rb').read())))
+ data = map(ord, open(file_['localname'], 'rb').read())
+ str_data = ''
+ chunk_size = 10240
+ while len(data) > 0:
+ chunk = data[:chunk_size]
+ data = data[chunk_size:]
+ if not str_data:
+ str_data = str(chunk)
+ else:
+ str_data += '.concat(' + str(chunk) + ')'
+ code += '''Module['FS_createDataFile']('/%s', '%s', %s, true, true);\n''' % (os.path.dirname(filename), os.path.basename(filename), str_data)
elif file_['mode'] == 'preload':
# Preload
varname = 'filePreload%d' % counter
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 85a7b214..77c48a23 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1937,6 +1937,10 @@ function eliminate(ast, memSafe, asm) {
} else if (type == 'if') {
if (allowTracking) {
traverseInOrder(node[1]); // can eliminate into condition, but nowhere else
+ if (!callsInvalidated) { // invalidate calls, since we cannot eliminate them into an if that may not execute!
+ invalidateCalls();
+ callsInvalidated = true;
+ }
allowTracking = false;
traverseInOrder(node[2]); // 2 and 3 could be 'parallel', really..
if (node[3]) traverseInOrder(node[3]);
diff --git a/tools/js_optimizer.py b/tools/js_optimizer.py
index 744e068a..b72a2084 100644
--- a/tools/js_optimizer.py
+++ b/tools/js_optimizer.py
@@ -26,7 +26,8 @@ def run_on_chunk(command):
f.close()
return filename
-def run(filename, passes, js_engine, jcache):
+def run_on_js(filename, passes, js_engine, jcache):
+
if jcache: shared.JCache.ensure()
if type(passes) == str:
@@ -144,6 +145,8 @@ def run(filename, passes, js_engine, jcache):
else:
filenames = []
+ for filename in filenames: temp_files.note(filename)
+
filename += '.jo.js'
f = open(filename, 'w')
f.write(pre);
@@ -170,3 +173,6 @@ def run(filename, passes, js_engine, jcache):
return filename
+def run(filename, passes, js_engine, jcache):
+ return temp_files.run_and_clean(lambda: run_on_js(filename, passes, js_engine, jcache))
+
diff --git a/tools/nativize_llvm.py b/tools/nativize_llvm.py
index e76b9a4e..d9558c32 100755
--- a/tools/nativize_llvm.py
+++ b/tools/nativize_llvm.py
@@ -23,9 +23,12 @@ libs = sys.argv[2:] # e.g.: dl for dlopen/dlclose, util for openpty/forkpty
print 'bc => clean bc'
Popen([LLVM_OPT, filename, '-strip-debug', '-o=' + filename + '.clean.bc']).communicate()[0]
print 'bc => s'
-Popen([LLVM_COMPILER, filename + '.clean.bc', '-o=' + filename + '.s']).communicate()[0]
-print 's => o'
-Popen(['as', filename + '.s', '-o', filename + '.o']).communicate()[0]
+for params in [[], ['-march=x86-64']]: # try x86, then x86-64 FIXME
+ print 'params', params
+ Popen([LLVM_COMPILER] + params + [filename + '.clean.bc', '-o=' + filename + '.s']).communicate()[0]
+ print 's => o'
+ Popen(['as', filename + '.s', '-o', filename + '.o']).communicate()[0]
+ if os.path.exists(filename + '.o'): break
print 'o => runnable'
Popen(['g++', path_from_root('system', 'lib', 'debugging.cpp'), filename + '.o', '-o', filename + '.run'] + ['-l' + lib for lib in libs]).communicate()[0]
diff --git a/tools/shared.py b/tools/shared.py
index d850b770..c310afd4 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -328,13 +328,13 @@ except:
try:
PYTHON
except:
- print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"'
+ if DEBUG: print >> sys.stderr, 'PYTHON not defined in ~/.emscripten, using "python"'
PYTHON = 'python'
try:
JAVA
except:
- print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"'
+ if DEBUG: print >> sys.stderr, 'JAVA not defined in ~/.emscripten, using "java"'
JAVA = 'java'
# Additional compiler options
@@ -344,7 +344,7 @@ try:
except:
COMPILER_OPTS = []
# Force a simple, standard target as much as possible: target 32-bit linux, and disable various flags that hint at other platforms
-COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-U__SSE__', '-U__SSE2__', '-U__MMX__',
+COMPILER_OPTS = COMPILER_OPTS + ['-m32', '-U__i386__', '-U__x86_64__', '-U__i386', '-U__x86_64', '-Ui386', '-Ux86_64', '-U__SSE__', '-U__SSE2__', '-U__MMX__',
'-UX87_DOUBLE_ROUNDING', '-UHAVE_GCC_ASM_FOR_X87', '-DEMSCRIPTEN', '-U__STRICT_ANSI__', '-U__CYGWIN__',
'-D__STDC__', '-Xclang', '-triple=i386-pc-linux-gnu', '-D__IEEE_LITTLE_ENDIAN', '-fno-math-errno']
@@ -430,7 +430,7 @@ class TempFiles:
def run_and_clean(self, func):
try:
- func()
+ return func()
finally:
self.clean()
@@ -820,6 +820,7 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)''' % { 'winfix': '' if not WINDOWS e
def llvm_opt(filename, opts):
if type(opts) is int:
opts = Building.pick_llvm_opts(opts)
+ if DEBUG: print >> sys.stderr, 'emcc: LLVM opts:', opts
output = Popen([LLVM_OPT, filename] + opts + ['-o=' + filename + '.opt.bc'], stdout=PIPE).communicate()[0]
assert os.path.exists(filename + '.opt.bc'), 'Failed to run llvm optimizations: ' + output
shutil.move(filename + '.opt.bc', filename)