llvm opts in emcc (untested)
This commit is contained in:
Родитель
09f3e4c413
Коммит
9071942043
71
emcc
71
emcc
|
@ -8,12 +8,9 @@ emcc is a drop-in replacement for a compiler like gcc or clang.
|
|||
|
||||
Tell your build system to use this instead of the compiler, linker, ar and
|
||||
ranlib. All the normal build commands will be sent to this script, which
|
||||
will proxy them to the appropriate LLVM build commands, in order to
|
||||
generate proper code for Emscripten to later process.
|
||||
|
||||
For example, compilation will be translated into calls to clang
|
||||
with -emit-llvm, and linking will be translated into calls to llvm-link,
|
||||
and so forth.
|
||||
will proxy them to the appropriate build commands. For example, compilation
|
||||
will be translated into calls to clang with -emit-llvm, and linking will
|
||||
be translated into calls to llvm-link, and so forth.
|
||||
|
||||
Example uses:
|
||||
|
||||
|
@ -77,7 +74,6 @@ emcc can be influenced by a few environment variables:
|
|||
your system headers will be used.
|
||||
|
||||
EMMAKEN_COMPILER - The compiler to be used, if you don't want the default clang.
|
||||
|
||||
'''
|
||||
|
||||
import os, sys, shutil
|
||||
|
@ -117,16 +113,24 @@ Most normal gcc/g++ options will work, for example:
|
|||
|
||||
Options that are modified or new in %s include:
|
||||
-O0 No optimizations (default)
|
||||
-O1 Simple optimizations and no runtime assertions
|
||||
-O1 Simple optimizations, including safe LLVM
|
||||
optimizations, and no runtime assertions
|
||||
-O2 As -O1, plus code flow optimization (relooper)
|
||||
Warning: Compiling with this takes a long time!
|
||||
-O3 As -O2, plus dangerous optimizations that may
|
||||
break things
|
||||
-s OPTION=VALUE JavaScript code generation option
|
||||
passed into the emscripten compiler
|
||||
--typed-arrays <mode> 0: no typed arrays
|
||||
1: parallel typed arrays
|
||||
2: shared (C-like) typed arrays (default)
|
||||
break the generated code! If that happens, try
|
||||
-O2 and then adding dangerous optimizations one
|
||||
by one.
|
||||
-s OPTION=VALUE JavaScript code generation option passed
|
||||
into the emscripten compiler
|
||||
--typed-arrays <mode> 0: No typed arrays
|
||||
1: Parallel typed arrays
|
||||
2: Shared (C-like) typed arrays (default)
|
||||
--llvm-opts <level> 0: No LLVM optimizations
|
||||
1: Safe/portable LLVM optimizations
|
||||
2: Full, unsafe/unportable LLVM optimizations;
|
||||
this will almost certainly break the
|
||||
generated code!
|
||||
|
||||
The target file, if specified (-o <target>), defines what will
|
||||
be generated:
|
||||
|
@ -248,6 +252,7 @@ elif use_compiler:
|
|||
newargs = sys.argv[1:]
|
||||
|
||||
opt_level = 0
|
||||
llvm_opt_level = 0
|
||||
|
||||
for i in range(len(newargs)):
|
||||
if newargs[i].startswith('-O'):
|
||||
|
@ -256,6 +261,8 @@ elif use_compiler:
|
|||
assert 0 <= opt_level <= 3
|
||||
except:
|
||||
raise Exception('Invalid optimization level: ' + newargs[i])
|
||||
if opt_level >= 1:
|
||||
llvm_opt_level = 1
|
||||
newargs[i] = ''
|
||||
newargs = [ arg for arg in newargs if arg is not '' ]
|
||||
|
||||
|
@ -284,22 +291,6 @@ elif use_compiler:
|
|||
|
||||
final_suffix = target.split('.')[-1]
|
||||
|
||||
## Compile
|
||||
|
||||
# First, generate LLVM bitcode TODO: handle |emcc a.cpp b.cpp -c| which generate *two* bitcode files
|
||||
newargs = newargs + ['-emit-llvm', '-c', '-o', target_basename + '.bc']
|
||||
|
||||
if DEBUG: print >> sys.stderr, "Running:", call, ' '.join(newargs)
|
||||
Popen([call] + newargs).communicate()
|
||||
|
||||
# If we were just asked to generate bitcode, stop there
|
||||
if final_suffix in ['o', 'bc']:
|
||||
if final_suffix == 'o':
|
||||
shutil.move(target_basename + '.bc', target_basename + '.o')
|
||||
exit(0)
|
||||
|
||||
## Continue on to create JavaScript
|
||||
|
||||
# Apply optimization level settings
|
||||
if opt_level >= 1:
|
||||
shared.Settings.ASSERTIONS = 0
|
||||
|
@ -315,6 +306,26 @@ elif use_compiler:
|
|||
shared.Settings.DISABLE_EXCEPTION_CATCHING = 1
|
||||
print >> sys.stderr, 'Warning: Applying some potentially unsafe optimizations! (Use -O2 if this fails.)'
|
||||
|
||||
## Compile
|
||||
|
||||
# First, generate LLVM bitcode TODO: handle |emcc a.cpp b.cpp -c| which generate *two* bitcode files
|
||||
newargs = newargs + ['-emit-llvm', '-c', '-o', target_basename + '.bc']
|
||||
|
||||
if DEBUG: print >> sys.stderr, "Running:", call, ' '.join(newargs)
|
||||
Popen([call] + newargs).communicate()
|
||||
|
||||
# Optimize, if asked to
|
||||
if llvm_opt_level > 0:
|
||||
shared.Building.llvm_opt(target_basename + '.bc', 2, safe=llvm_opt_level < 2)
|
||||
|
||||
# If we were just asked to generate bitcode, stop there
|
||||
if final_suffix in ['o', 'bc']:
|
||||
if final_suffix == 'o':
|
||||
shutil.move(target_basename + '.bc', target_basename + '.o')
|
||||
exit(0)
|
||||
|
||||
## Continue on to create JavaScript
|
||||
|
||||
# Apply -s settings in newargs here (after -Ox, so they can override it)
|
||||
|
||||
for change in settings_changes:
|
||||
|
|
|
@ -81,7 +81,8 @@ class RunnerCore(unittest.TestCase):
|
|||
need_post = build_ll_hook(filename)
|
||||
Building.llvm_as(filename)
|
||||
shutil.move(filename + '.o.ll', filename + '.o.ll.pre') # for comparisons later
|
||||
Building.llvm_opts(filename)
|
||||
if Building.LLVM_OPTS:
|
||||
Building.llvm_opts(filename)
|
||||
Building.llvm_dis(filename)
|
||||
if build_ll_hook and need_post:
|
||||
build_ll_hook(filename)
|
||||
|
@ -4958,8 +4959,7 @@ Options that are modified or new in %s include:
|
|||
|
||||
|
||||
# emcc --llvm-opts=x .. ==> pick level of LLVM optimizations (default is 0, to be safe?)
|
||||
# When doing unsafe opts, can we run -Ox on the source, not just at the very end?
|
||||
# In fact we can run safe opts at that time too, now we are a gcc replacement. Removes the entire need for llvm opts only at the end.
|
||||
# We can run safe opts at each emcc invocation, now we are a gcc replacement. Removes the entire need for llvm opts only at the end.
|
||||
# linking - TODO. in particular, test normal project linking, static and dynamic: get_library should not need to be told what to link!
|
||||
# emcc a.cpp b.cpp => one .js
|
||||
# emcc a.cpp b.cpp -c => two .o files
|
||||
|
|
|
@ -196,6 +196,7 @@ class Settings:
|
|||
class Settings2:
|
||||
reset = Settings.reset
|
||||
load_defaults = Settings.load_defaults
|
||||
QUANTUM_SIZE = 4
|
||||
Settings = Settings2
|
||||
|
||||
@classmethod
|
||||
|
@ -203,6 +204,7 @@ class Settings:
|
|||
''' Load the JS settings into Python '''
|
||||
settings = open(path_from_root('src', 'settings.js')).read().replace('var ', 'Settings.').replace('//', '#')
|
||||
exec(settings)
|
||||
Settings.reset()
|
||||
|
||||
# Building
|
||||
|
||||
|
@ -296,7 +298,13 @@ class Building:
|
|||
|
||||
# Optional LLVM optimizations
|
||||
@staticmethod
|
||||
def llvm_opts(filename):
|
||||
def llvm_opt(filename, level, safe=True):
|
||||
output = Popen([LLVM_OPT, filename] + Building.pick_llvm_opts(level, safe) + ['-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)
|
||||
|
||||
@staticmethod
|
||||
def llvm_opts(filename): # deprecated version, only for test runner. TODO: remove
|
||||
if Building.LLVM_OPTS:
|
||||
shutil.move(filename + '.o', filename + '.o.pre')
|
||||
output = Popen([LLVM_OPT, filename + '.o.pre'] + Building.LLVM_OPT_OPTS + ['-o=' + filename + '.o'], stdout=PIPE).communicate()[0]
|
||||
|
@ -371,8 +379,6 @@ class Building:
|
|||
into i64s. In any case, the handpicked ones here should be safe and portable. They are also tuned for
|
||||
things that look useful.
|
||||
'''
|
||||
if not Building.LLVM_OPTS: return # XXX this makes using this independently from the test runner very unpleasant
|
||||
|
||||
opts = []
|
||||
if optimization_level > 0:
|
||||
#opts.append('-disable-inlining') # we prefer to let closure compiler do our inlining
|
||||
|
|
Загрузка…
Ссылка в новой задаче