aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/exec_llvm.py7
-rw-r--r--tools/nativize_llvm.py31
-rw-r--r--tools/shared.py12
3 files changed, 40 insertions, 10 deletions
diff --git a/tools/exec_llvm.py b/tools/exec_llvm.py
index 1b1bba1b..5cf55e46 100755
--- a/tools/exec_llvm.py
+++ b/tools/exec_llvm.py
@@ -26,11 +26,8 @@ it runs
python $(EMSCRIPTEN_TOOLS)/exec_llvm.py THE_FILE PARAMS
An alternative solution to this problem is to compile
-the .ll into native code. This can be done as follows:
-
- * Use llc to generate x86 asm
- * Use as to generate an object file
- * Use g++ to link it to an executable
+the .ll into native code, see nativize_llvm.py. That is
+useful when this fails.
'''
import os, sys
diff --git a/tools/nativize_llvm.py b/tools/nativize_llvm.py
new file mode 100644
index 00000000..de78dce2
--- /dev/null
+++ b/tools/nativize_llvm.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+
+'''
+Small utility to build some llvm bitcode into native code. Useful when lli (called
+from exec_llvm) fails for some reason.
+
+ * Use llc to generate x86 asm
+ * Use as to generate an object file
+ * Use g++ to link it to an executable
+'''
+
+import os, sys
+from subprocess import Popen, PIPE, STDOUT
+
+__rootpath__ = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+def path_from_root(*pathelems):
+ return os.path.join(__rootpath__, *pathelems)
+exec(open(path_from_root('tools', 'shared.py'), 'r').read())
+
+filename = sys.argv[1]
+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]
+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 f20fc75c..81c7fcf8 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -440,9 +440,9 @@ class Building:
# @param opt Either an integer, in which case it is the optimization level (-O1, -O2, etc.), or a list of raw
# optimization passes passed to llvm opt
@staticmethod
- def llvm_opt(filename, opts, safe=True):
+ def llvm_opt(filename, opts):
if type(opts) is int:
- opts = Building.pick_llvm_opts(opts, safe)
+ opts = Building.pick_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)
@@ -528,7 +528,7 @@ class Building:
return filename + '.o.js'
@staticmethod
- def pick_llvm_opts(optimization_level, safe=True):
+ def pick_llvm_opts(optimization_level):
'''
It may be safe to use nonportable optimizations (like -OX) if we remove the platform info from the .ll
(which we do in do_ll_opts) - but even there we have issues (even in TA2) with instruction combining
@@ -539,14 +539,16 @@ class Building:
llvm-as < /dev/null | opt -std-compile-opts -disable-output -debug-pass=Arguments
'''
+ safe = Settings.USE_TYPED_ARRAYS != 2 or Settings.BUILD_AS_SHARED_LIB or Settings.LINKABLE
+ print 'LLVM opts, safe?', safe
opts = []
if optimization_level > 0:
- #opts.append('-disable-inlining') # we prefer to let closure compiler do our inlining
if not safe:
+ opts.append('-disable-inlining') # we prefer to let closure compiler do our inlining, to avoid overly aggressive inlining
#opts.append('-O%d' % optimization_level)
opts.append('-std-compile-opts')
opts.append('-std-link-opts')
- print 'Unsafe:', opts,
+ print 'Unsafe:', opts
else:
allow_nonportable = not safe
optimize_size = True