Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add initial support for using lld rather than s2wasm in the wasm backend #5313

Closed
wants to merge 2 commits into from

Conversation

Projects
None yet
3 participants
@sbc100
Copy link
Collaborator

sbc100 commented Jun 15, 2017

This path is currently experimental and is activated by setting EMCC_WASM_BACKEND=2.

This change does 3 things:

  • Support for setting WASM_BACKEND=2, and checking lld version support
  • Support for building wasm_compiler_rt libararies as .o archives in addition to current .s archives
  • Support for using lld to produce the final wasm file, rather than s2wasm + wasm-as.

@sbc100 sbc100 requested review from dschuff and jgravelle-google Jun 15, 2017

emcc.py Outdated
@@ -479,8 +480,9 @@ def filter_emscripten_options(argv):
# but then, we don't care about bitcode outputs anyhow, below, so
# skipping to exit(ret) is fine
if target.endswith('.js'):
shutil.copyfile(target, target[:-3])
target = target[:-3]
bare_target = os.path.splitext(target)[0]

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

we have a utility for that, unsuffixed

emcc.py Outdated
@@ -1444,10 +1454,11 @@ def get_final():
with ToolchainProfiler.profile_block('post-link'):
if DEBUG:
logging.debug('saving intermediate processing steps to %s', shared.get_emscripten_temp_dir())
if not LEAVE_INPUTS_RAW: save_intermediate('basebc', 'bc')
if not LEAVE_INPUTS_RAW and not shared.Settings.WASM_BACKEND:
save_intermediate('basebc', 'bc')

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

shouldn't this be if using obj files?

emcc.py Outdated

# Optimize, if asked to
if not LEAVE_INPUTS_RAW:
if not LEAVE_INPUTS_RAW and not shared.Settings.WASM_BACKEND:

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

ditto, looks like this would disable lto for the wasm backend (when not using wasm object files)

emcc.py Outdated
@@ -1525,10 +1536,14 @@ def get_final():

if shared.Settings.WASM_BACKEND:
# we also received wast and wasm at this stage
temp_basename = final[:-3]
temp_basename = os.path.splitext(final)[0]

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

unsuffixed

@@ -395,9 +384,9 @@ def create_module(function_table_sigs, metadata, settings,


def write_output_file(outfile, post, module):
for i in range(len(module)): # do this loop carefully to save memory

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

i think this loop intentionally did not leave a variable with chunk contents alive. here, the new variable chunk survives. maybe this mattered a long time ago but not now, though, but we should verify

@@ -333,7 +331,10 @@ def get_clang_version():
return actual_clang_version

def check_clang_version():
expected = '.'.join(map(str, EXPECTED_LLVM_VERSION))

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

is EXPECTED_LLVM_VERSION not used anywhere else? i think it might be, maybe in the tests? I could be wrong.

@@ -903,14 +905,18 @@ def set_logging():

# Target choice.
ASM_JS_TARGET = 'asmjs-unknown-emscripten'
WASM_TARGET = 'wasm32-unknown-unknown'
WASM_TARGET = 'wasm32-unknown-unknown-elf'
WASM_OBJ_TARGET = 'wasm32-unknown-unknown-wasm'

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

this surprises me - a different triple just for the feature of using wasm object files?

return in_temp(lib_filename)
output = in_temp(lib_filename)
if shared.get_llvm_target() == shared.WASM_OBJ_TARGET:
shared.Building.emar('cr', output, o_s)

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

they could be linked using lld, instead of an archive? we specifically only use an archive for libc++ i believe, and this would change that. however, I don't remember all the details of why we do that atm.

elif not Building.is_ar(absolute_path_f):
if get_llvm_target() == WASM_OBJ_TARGET:
if Building.is_wasm(f):
actual_files.append(f)

This comment has been minimized.

@kripken

kripken Jun 15, 2017

Member

no else? perhaps it should throw an error?

@sbc100 sbc100 force-pushed the lld branch 3 times, most recently from d745c53 to af6fdd5 Jun 21, 2017

@sbc100 sbc100 force-pushed the lld branch 3 times, most recently from 1c2cfb6 to 78ac896 Jul 7, 2017

@sbc100 sbc100 changed the title WIP: Add a wasm backend mode that uses lld rather than s2wasm Add initial support for using lld rather than s2wasm in the wasm backend Jul 12, 2017

@sbc100

This comment has been minimized.

Copy link
Collaborator Author

sbc100 commented Jul 12, 2017

This change is not much more focused. PTAL.

@@ -398,6 +398,12 @@ def check_fastcomp():
print >> sys.stderr, '==========================================================================='
return False

if Settings.WASM_BACKEND == 2:
if subprocess.call([LLVM_LLD, '-flavor', 'wasm', '--version'], stdout=PIPE, stderr=PIPE) != 0:
logging.critical('WASM_BACKEND=2 but lld not build with wasm support:')

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Typo: build -> built

compiler_rt_lib = shared.Cache.get('libwasm_compiler_rt.a', wasm_rt_fail('libwasm_compiler_rt.a'), 'a')
libc_rt_lib = shared.Cache.get('libwasm_libc_rt.a', wasm_rt_fail('libwasm_libc_rt.a'), 'a')

args = [shared.LLVM_LLD, '-flavor', 'wasm', temp_o] #, '--strip-debug']

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Remove commented out code



def create_lld_args(temp_o, output):
def wasm_rt_fail(archive_file):

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Might as well combine this with the one in create_s2wasm_args and promote them to top-level functions

return metadata


def archive_intermediate(filename, output_name):

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Yay helper functions


import pprint

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Imports should be at the top of the file

wast = basename + '.wast'
build_wasm_lld(temp_files, infile, wasm_file, settings, DEBUG)
wasm_dis(wasm_file, wast)
sending = []

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

Why initialize these here?

if shared.Settings.WASM_BACKEND == 2:
basename = shared.unsuffixed(outfile.name)
wasm_file = basename + '.wasm'
wast = basename + '.wast'

This comment has been minimized.

@jgravelle-google

jgravelle-google Jul 12, 2017

Collaborator

I feel like this should be wast_file to match wasm_file

@kripken
Copy link
Member

kripken left a comment

Please document the meaning of Settings.WASM_BACKEND mode 2, in src/settings.js

def build_wasm(temp_files, infile, outfile, settings, DEBUG):
with temp_files.get_file('.wb.s') as temp_s:
backend_args = create_backend_args_wasm(infile, temp_s, settings)
def wasm_dis(wasm_file, wast_file):

This comment has been minimized.

@kripken

kripken Jul 12, 2017

Member

this should probably be in tools/shared.py, we have a bunch of utility functions there like llvm_opt etc. that call the various llvm tools, so this could fit alongside them

shared.Cache.get('wasm_compiler_rt.a', lambda: create_wasm_compiler_rt('wasm_compiler_rt.a'), extension='a')
shared.Cache.get('wasm_libc_rt.a', lambda: create_wasm_libc_rt('wasm_libc_rt.a'), extension='a')
if shared.Settings.WASM_BACKEND == 2:
shared.Cache.get('libwasm_compiler_rt.a', lambda: create_wasm_compiler_rt('libwasm_compiler_rt.a'), extension='a')

This comment has been minimized.

@kripken

kripken Jul 12, 2017

Member

is this just because the lib prefix is necessary for lld? if the contents are identical, could we just always call it the lib* name?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.