summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rwxr-xr-xemscripten.py43
-rw-r--r--src/jsifier.js2
-rw-r--r--src/library_fs.js2
-rw-r--r--src/library_glfw.js8
-rw-r--r--src/library_sdl.js5
-rw-r--r--src/modules.js20
-rw-r--r--tests/cases/caall.ll12
-rw-r--r--tests/cases/i24_mem_ta2.ll10
-rw-r--r--tests/cases/i64toi8star.ll6
-rw-r--r--tests/cases/inttoptr.ll8
-rw-r--r--tests/cases/invokebitcast.ll7
-rw-r--r--tests/cases/phicubed.ll2
-rw-r--r--tests/cases/phientryimplicit.ll36
-rw-r--r--tests/cases/phiself.ll4
-rw-r--r--tests/cases/ptrtoi64.ll14
-rw-r--r--tests/cases/sillybitcast.ll4
-rw-r--r--tests/cases/sillybitcast2.ll35
-rw-r--r--tests/cases/unaligneddouble.ll2
-rwxr-xr-xtests/runner.py5
-rw-r--r--tests/test_benchmark.py208
-rw-r--r--tests/test_core.py75
-rw-r--r--tests/test_other.py5
-rw-r--r--tools/shared.py4
24 files changed, 346 insertions, 172 deletions
diff --git a/AUTHORS b/AUTHORS
index 413b9de1..d71eea47 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -112,3 +112,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Lu Wang <coolwanglu@gmail.com>
* Heidi Pan <heidi.pan@intel.com> (copyright owned by Intel)
* Vasilis Kalintiris <ehostunreach@gmail.com>
+* Adam C. Clifton <adam@hulkamaniac.com>
diff --git a/emscripten.py b/emscripten.py
index 7514b3ca..111c2df4 100755
--- a/emscripten.py
+++ b/emscripten.py
@@ -726,7 +726,6 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
"""
assert(settings['ASM_JS']) # TODO: apply ASM_JS even in -O0 for fastcomp
- assert(settings['RUNNING_JS_OPTS'])
# Overview:
# * Run LLVM backend to emit JS. JS includes function bodies, memory initializer,
@@ -741,9 +740,14 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if DEBUG: shutil.copyfile(infile, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp0.ll'))
+ extra_opt_args = []
+ #if DEBUG: extra_opt_args.append('-time-passes')
+
+ if DEBUG: t = time.time()
+
if DEBUG: logging.debug(' ..1..')
temp1 = temp_files.get('.1.bc').name
- shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), infile, '-pnacl-abi-simplify-preopt', '-o', temp1]))
+ shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), infile, '-pnacl-abi-simplify-preopt', '-o', temp1] + extra_opt_args))
assert os.path.exists(temp1)
if DEBUG:
shutil.copyfile(temp1, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp1.bc'))
@@ -760,19 +764,27 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if DEBUG: logging.debug(' ..3..')
temp3 = temp_files.get('.3.bc').name
- shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp2, '-pnacl-abi-simplify-postopt', '-o', temp3]))
+ shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'opt'), temp2, '-pnacl-abi-simplify-postopt', '-o', temp3] + extra_opt_args))
#'-print-after-all'
assert os.path.exists(temp3)
if DEBUG:
shutil.copyfile(temp3, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp3.bc'))
shared.jsrun.timeout_run(subprocess.Popen([os.path.join(shared.LLVM_ROOT, 'llvm-dis'), 'temp3.bc', '-o', 'temp3.ll']))
+ if DEBUG:
+ logging.debug(' emscript: ir simplification took %s seconds' % (time.time() - t))
+ t = time.time()
+
if DEBUG: logging.debug(' ..4..')
temp4 = temp_files.get('.4.js').name
backend_compiler = os.path.join(shared.LLVM_ROOT, 'llc')
shared.jsrun.timeout_run(subprocess.Popen([backend_compiler, temp3, '-march=js', '-filetype=asm', '-o', temp4], stdout=subprocess.PIPE))
if DEBUG: shutil.copyfile(temp4, os.path.join(shared.CANONICAL_TEMP_DIR, 'temp4.js'))
+ if DEBUG:
+ logging.debug(' emscript: llvm backend took %s seconds' % (time.time() - t))
+ t = time.time()
+
# Split up output
backend_output = open(temp4).read()
#if DEBUG: print >> sys.stderr, backend_output
@@ -801,6 +813,20 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
table_sizes[k] = str(v.count(',')) # undercounts by one, but that is what we want
funcs = re.sub(r"#FM_(\w+)#", lambda m: table_sizes[m.groups(0)[0]], funcs)
+ # fix +float into float.0, if not running js opts
+ if not settings['RUNNING_JS_OPTS']:
+ def fix_dot_zero(m):
+ num = m.group(3)
+ # TODO: handle 0x floats?
+ if num.find('.') < 0:
+ e = num.find('e');
+ if e < 0:
+ num += '.0'
+ else:
+ num = num[:e] + '.0' + num[e:]
+ return m.group(1) + m.group(2) + num
+ funcs = re.sub(r'([(=,+\-*/%] *)\+(-?)((0x)?[0-9a-f]*\.?[0-9]+([eE][-+]?[0-9]+)?)', lambda m: fix_dot_zero(m), funcs)
+
# js compiler
if DEBUG: logging.debug('emscript: js compiler glue')
@@ -836,7 +862,9 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
assert '//FORWARDED_DATA:' in out, 'Did not receive forwarded data in pre output - process failed?'
glue, forwarded_data = out.split('//FORWARDED_DATA:')
- #print >> sys.stderr, out
+ if DEBUG:
+ logging.debug(' emscript: glue took %s seconds' % (time.time() - t))
+ t = time.time()
last_forwarded_json = forwarded_json = json.loads(forwarded_data)
@@ -932,7 +960,10 @@ def emscript_fast(infile, settings, outfile, libraries=[], compiler_engine=None,
if item == '0': return bad if not newline else (bad + '\n')
if item not in metadata['implementedFunctions']:
# this is imported into asm, we must wrap it
- code = item + '(' + coerced_params + ')'
+ call_ident = item
+ if call_ident in metadata['redirects']: call_ident = metadata['redirects'][call_ident]
+ if not call_ident.startswith('_') and not call_ident.startswith('Math_'): call_ident = '_' + call_ident
+ code = call_ident + '(' + coerced_params + ')'
if sig[0] != 'v':
code = 'return ' + shared.JS.make_coercion(code, sig[0], settings)
code += ';'
@@ -1203,6 +1234,8 @@ Runtime.stackRestore = function(top) { asm['stackRestore'](top) };
outfile.close()
+ if DEBUG: logging.debug(' emscript: final python processing took %s seconds' % (time.time() - t))
+
if os.environ.get('EMCC_FAST_COMPILER'):
emscript = emscript_fast
diff --git a/src/jsifier.js b/src/jsifier.js
index b5502741..6b831b04 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1859,7 +1859,7 @@ function JSify(data, functionsOnly, givenFunctions) {
// first row are utilities called from generated code, second are needed from fastLong
['i64Add', 'i64Subtract', 'bitshift64Shl', 'bitshift64Lshr', 'bitshift64Ashr',
'llvm_ctlz_i32', 'llvm_cttz_i32'].forEach(function(func) {
- if (!Functions.libraryFunctions[func] || (phase == 'glue' && func[0] === 'l')) { // TODO: one-by-one in fastcomp glue mode
+ if (!Functions.libraryFunctions[func] || (phase == 'glue' && func[0] === 'l' && !addedLibraryItems[func])) { // TODO: one-by-one in fastcomp glue mode
print(processLibraryFunction(LibraryManager.library[func], func)); // must be first to be close to generated code
Functions.implementedFunctions['_' + func] = LibraryManager.library[func + '__sig'];
Functions.libraryFunctions[func] = phase == 'glue' ? 2 : 1; // XXX
diff --git a/src/library_fs.js b/src/library_fs.js
index 5412185f..1e7856aa 100644
--- a/src/library_fs.js
+++ b/src/library_fs.js
@@ -961,7 +961,7 @@ mergeInto(LibraryManager.library, {
throw new FS.ErrnoError(ERRNO_CODES.EACCES);
}
if (!stream.stream_ops.mmap) {
- throw new FS.errnoError(ERRNO_CODES.ENODEV);
+ throw new FS.ErrnoError(ERRNO_CODES.ENODEV);
}
return stream.stream_ops.mmap(stream, buffer, offset, length, position, prot, flags);
},
diff --git a/src/library_glfw.js b/src/library_glfw.js
index 647d4bb6..17e8956a 100644
--- a/src/library_glfw.js
+++ b/src/library_glfw.js
@@ -120,7 +120,6 @@ var LibraryGLFW = {
if (event.charCode) {
var char = GLFW.getUnicodeChar(event.charCode);
if (char !== null && GLFW.charFunc) {
- event.preventDefault();
Runtime.dynCall('vii', GLFW.charFunc, [event.charCode, 1]);
}
}
@@ -130,13 +129,18 @@ var LibraryGLFW = {
var key = GLFW.DOMToGLFWKeyCode(event.keyCode);
if (key && GLFW.keyFunc) {
GLFW.keys[key] = status;
- event.preventDefault();
Runtime.dynCall('vii', GLFW.keyFunc, [key, status]);
}
},
onKeydown: function(event) {
GLFW.onKeyChanged(event, 1);//GLFW_PRESS
+ // This logic comes directly from the sdl implementation. We cannot
+ // call preventDefault on all keydown events otherwise onKeyPress will
+ // not get called
+ if (event.keyCode === 8 /* backspace */ || event.keyCode === 9 /* tab */) {
+ event.preventDefault();
+ }
},
onKeyup: function(event) {
diff --git a/src/library_sdl.js b/src/library_sdl.js
index 40e5e3ab..2efc1271 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -1247,10 +1247,7 @@ var LibrarySDL = {
return 0;
},
- SDL_LowerBlit__deps: ['SDL_UpperBlit'],
- SDL_LowerBlit: function(src, srcrect, dst, dstrect) {
- return _SDL_UpperBlit(src, srcrect, dst, dstrect);
- },
+ SDL_LowerBlit: 'SDL_UpperBlit',
SDL_FillRect: function(surf, rect, color) {
var surfData = SDL.surfaces[surf];
diff --git a/src/modules.js b/src/modules.js
index b9b8ab5e..3e7405f8 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -429,6 +429,26 @@ var LibraryManager = {
eval(processMacros(preprocess(read(libraries[i]))));
}
+ /*
+ // export code for CallHandlers.h
+ printErr('============================');
+ for (var x in this.library) {
+ var y = this.library[x];
+ if (typeof y === 'string' && x.indexOf('__sig') < 0 && x.indexOf('__postset') < 0 && y.indexOf(' ') < 0) {
+ printErr('DEF_REDIRECT_HANDLER(' + x + ', ' + y + ');');
+ }
+ }
+ printErr('============================');
+ for (var x in this.library) {
+ var y = this.library[x];
+ if (typeof y === 'string' && x.indexOf('__sig') < 0 && x.indexOf('__postset') < 0 && y.indexOf(' ') < 0) {
+ printErr(' SETUP_CALL_HANDLER(' + x + ');');
+ }
+ }
+ printErr('============================');
+ // end export code for CallHandlers.h
+ */
+
this.loaded = true;
},
diff --git a/tests/cases/caall.ll b/tests/cases/caall.ll
index 5b8f7f29..2cc231ec 100644
--- a/tests/cases/caall.ll
+++ b/tests/cases/caall.ll
@@ -1,6 +1,6 @@
; ModuleID = 'tests/hello_world.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
@.str = private unnamed_addr constant [15 x i8] c"hello, world!\0A\00", align 1 ; [#uses=1 type=[15 x i8]*]
@@ -11,14 +11,14 @@ entry:
store i32 0, i32* %retval
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
%call12 = call void (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 10)
- %26 = load void (%class.Object*)** %call12
+ %l26 = load void (i32*)** %call12
ret i32 1
}
-define (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 %x) {
+define void (i32*)** @_ZNSt3__13mapINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFvP6ObjectENS_4lessIS6_EENS4_INS_4pairIKS6_SA_EEEEEixERSE_(i32 %x) {
entry:
- %ret = inttoptr i32 0 to (i32*)**
- ret (i32*)** %ret
+ %ret = inttoptr i32 0 to void (i32*)**
+ ret void (i32*)** %ret
}
; [#uses=1]
diff --git a/tests/cases/i24_mem_ta2.ll b/tests/cases/i24_mem_ta2.ll
index e50014ca..550389fe 100644
--- a/tests/cases/i24_mem_ta2.ll
+++ b/tests/cases/i24_mem_ta2.ll
@@ -1,8 +1,8 @@
; ModuleID = 'tests/hello_world.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
-@.str = private unnamed_addr constant [15 x i8] c".%x.\0A\00", align 1 ; [#uses=1 type=[5 x i8]*]
+@.str = private unnamed_addr constant [6 x i8] c".%x.\0A\00", align 1 ; [#uses=1 type=[5 x i8]*]
define i32 @main() {
entry:
@@ -11,11 +11,11 @@ entry:
%i24 = bitcast i32* %mem to i24*
%load = load i24* %i24, align 4
%load32 = zext i24 %load to i32
- %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32)
+ %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i32 %load32)
%val_24 = trunc i32 4041265344 to i24
store i24 %val_24, i24* %i24, align 4
%load32b = load i32* %mem, align 4
- %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i32 0, i32 0), i32 %load32b)
+ %call2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0), i32 %load32b)
ret i32 1
}
diff --git a/tests/cases/i64toi8star.ll b/tests/cases/i64toi8star.ll
index d4a39340..b2307449 100644
--- a/tests/cases/i64toi8star.ll
+++ b/tests/cases/i64toi8star.ll
@@ -25,8 +25,8 @@ entry:
%retval = alloca i32 ; [#uses=2]
%0 = alloca i32 ; [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
- %5 = call i32 @PyLong_FromVoidPtr(i8* null) nounwind ; [#uses=0]
- %13 = call i32 @PyLong_FromVoidPtr(i8* inttoptr (i64 1 to i8*)) nounwind ; [#uses=0]
- %1 = call i32 bitcast (i32 (i8*)* @puts to i32 (i32*)*)(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
+ %a5 = call i32 @PyLong_FromVoidPtr(i8* null) nounwind ; [#uses=0]
+ %a13 = call i32 @PyLong_FromVoidPtr(i8* inttoptr (i64 1 to i8*)) nounwind ; [#uses=0]
+ %a1 = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
ret i32 0
}
diff --git a/tests/cases/inttoptr.ll b/tests/cases/inttoptr.ll
index b0711672..c1b40a74 100644
--- a/tests/cases/inttoptr.ll
+++ b/tests/cases/inttoptr.ll
@@ -1,6 +1,6 @@
; ModuleID = '/tmp/emscripten/tmp/src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
@.str = private constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
@@ -14,7 +14,7 @@ entry:
%0 = alloca i32 ; [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
%sz.i7 = inttoptr i32 64 to i32* ; [#uses=1 type=i32*]
- store i32 184, i32* %sz.i7, align 8, !tbaa !1610
- %1 = call i32 bitcast (i32 (i8*)* @puts to i32 (i32*)*)(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
+ store i32 184, i32* %sz.i7, align 8
+ %1 = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
ret i32 0
}
diff --git a/tests/cases/invokebitcast.ll b/tests/cases/invokebitcast.ll
index ffb5803f..ec090b0d 100644
--- a/tests/cases/invokebitcast.ll
+++ b/tests/cases/invokebitcast.ll
@@ -1,7 +1,7 @@
; ModuleID = '/dev/shm/tmp/src.cpp.o'
; Just test for compilation here
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-f128:128:128-n8:16:32"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
%struct.CPU_Regs = type { [8 x %union.GenReg32] }
%union.GenReg32 = type { [1 x i32] }
@@ -16,7 +16,8 @@ entry:
%0 = alloca i32 ; [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
%1 = load i32* bitcast (i32* getelementptr inbounds (%struct.CPU_Regs* @cpu_regs, i32 0, i32 0, i32 1, i32 0, i32 0) to i32*), align 2 ; [#uses=1]
- store i16 %1, i16* bitcast (%struct.CPU_Regs* @cpu_regs to i16*), align 2
+ %s = trunc i32 %1 to i16
+ store i16 %s, i16* bitcast (%struct.CPU_Regs* @cpu_regs to i16*), align 2
%2 = call i32 @puts(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
store i32 0, i32* %0, align 4
%3 = load i32* %0, align 4 ; [#uses=1]
diff --git a/tests/cases/phicubed.ll b/tests/cases/phicubed.ll
index a0799997..5fc3208b 100644
--- a/tests/cases/phicubed.ll
+++ b/tests/cases/phicubed.ll
@@ -1,4 +1,6 @@
; ModuleID = '/dev/shm/tmp/src.cpp.o'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
%struct.worker_args = type { i32, %struct.worker_args* }
diff --git a/tests/cases/phientryimplicit.ll b/tests/cases/phientryimplicit.ll
index 8a510f43..b7b17add 100644
--- a/tests/cases/phientryimplicit.ll
+++ b/tests/cases/phientryimplicit.ll
@@ -1,6 +1,6 @@
; ModuleID = 'tests/hello_world.bc'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
; Phi nodes can refer to the entry. And the entry might be unnamed, and doesn't even have a consistent implicit name!
@@ -9,35 +9,35 @@ target triple = "i386-pc-linux-gnu"
; [#uses=0]
define i32 @main() {
%retval = alloca i32, align 4 ; [#uses=1 type=i32*]
- %16 = trunc i32 1 to i1
- br i1 %16, label %17, label %26, !dbg !1269853 ; [debug line = 3920:5]
+ %a16 = trunc i32 1 to i1
+ br i1 %a16, label %L17, label %L26, !dbg !1269853 ; [debug line = 3920:5]
-; <label>:17 ; preds = %1
- %25 = trunc i32 1 to i1
- br label %26
+L17:
+ %a25 = trunc i32 1 to i1
+ br label %L26
-; <label>:26 ; preds = %17, %1
- %27 = phi i1 [ false, %1 ], [ %25, %17 ] ; [#uses=1 type=i1]
+L26:
+ %a27 = phi i1 [ false, %1 ], [ %25, %L17 ] ; [#uses=1 type=i1]
store i32 0, i32* %retval
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
- %cal2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i32 %27) ; make sure %27 is used
+ %cal2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i1 %a27) ; make sure %27 is used
ret i32 1
}
define i32 @main0() {
%retval = alloca i32, align 4 ; [#uses=1 type=i32*]
- %16 = trunc i32 1 to i1
- br i1 %16, label %17, label %26, !dbg !1269853 ; [debug line = 3920:5]
+ %a16 = trunc i32 1 to i1
+ br i1 %a16, label %L17, label %L26, !dbg !1269853 ; [debug line = 3920:5]
-; <label>:17 ; preds = %1
- %25 = trunc i32 1 to i1
- br label %26
+L17:
+ %a25 = trunc i32 1 to i1
+ br label %L26
-; <label>:26 ; preds = %17, %1
- %27 = phi i1 [ false, %0 ], [ %25, %17 ] ; [#uses=1 type=i1]
+L26:
+ %a27 = phi i1 [ false, %0 ], [ %25, %L17 ] ; [#uses=1 type=i1]
store i32 0, i32* %retval
%call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0)) ; [#uses=0 type=i32]
- %cal2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i32 %27) ; make sure %27 is used
+ %cal2 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str, i32 0, i32 0), i1 %a27) ; make sure %27 is used
ret i32 1
}
diff --git a/tests/cases/phiself.ll b/tests/cases/phiself.ll
index 81249799..0a06fcca 100644
--- a/tests/cases/phiself.ll
+++ b/tests/cases/phiself.ll
@@ -1,6 +1,6 @@
; ModuleID = '/tmp/emscripten_temp/src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32-S128"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
@.str = private unnamed_addr constant [7 x i8] c"cheez\0A\00", align 1
@.str1 = private unnamed_addr constant [6 x i8] c"*%d*\0A\00", align 1
diff --git a/tests/cases/ptrtoi64.ll b/tests/cases/ptrtoi64.ll
index 01e466fe..5898f529 100644
--- a/tests/cases/ptrtoi64.ll
+++ b/tests/cases/ptrtoi64.ll
@@ -1,8 +1,8 @@
; pointer to i64, then to i32
; ModuleID = '/tmp/emscripten/tmp/src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
@.str2 = private constant [9 x i8] c"*%d,%d*\0A\00", align 1 ; [#uses=1]
@@ -18,10 +18,10 @@ entry:
%0 = alloca i32 ; [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
%sz.i7 = inttoptr i32 400 to i32* ; [#uses=1 type=i32*]
- %10 = ptrtoint i32* %sz.i7 to i64, !dbg !8557 ; [#uses=1 type=i64] [debug line = 99:3]
- %conv5 = trunc i64 %10 to i32, !dbg !8557 ; [#uses=1 type=i32] [debug line = 99:3]
- %11 = ptrtoint i32* %sz.i7 to i8, !dbg !8557 ; [#uses=1 type=i64] [debug line = 99:3]
- %conv6 = zext i8 %11 to i32, !dbg !8557 ; [#uses=1 type=i32] [debug line = 99:3]
- %55 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %conv5, i32 %conv6) ; [#uses=0]
+ %a10 = ptrtoint i32* %sz.i7 to i64
+ %conv5 = trunc i64 %a10 to i32
+ %a11 = ptrtoint i32* %sz.i7 to i8
+ %conv6 = zext i8 %a11 to i32
+ %a55 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str2, i32 0, i32 0), i32 %conv5, i32 %conv6)
ret i32 0
}
diff --git a/tests/cases/sillybitcast.ll b/tests/cases/sillybitcast.ll
index c5ca4f9a..50a54da9 100644
--- a/tests/cases/sillybitcast.ll
+++ b/tests/cases/sillybitcast.ll
@@ -1,6 +1,6 @@
; ModuleID = '/tmp/emscripten/tmp/src.cpp.o'
-target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
-target triple = "i386-pc-linux-gnu"
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
@.str = private constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
diff --git a/tests/cases/sillybitcast2.ll b/tests/cases/sillybitcast2.ll
new file mode 100644
index 00000000..02cf8615
--- /dev/null
+++ b/tests/cases/sillybitcast2.ll
@@ -0,0 +1,35 @@
+; ModuleID = '/tmp/emscripten/tmp/src.cpp.o'
+target datalayout = "e-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-p:32:32:32-v128:32:32"
+target triple = "le32-unknown-nacl"
+
+@.str = private constant [14 x i8] c"hello, world!\00", align 1 ; [#uses=1]
+
+; [#uses=2]
+define void @"_Z5hellov"() {
+entry:
+ %0 = call i32 bitcast (i32 (i32*)* @puts to i32 (i8*)*)(i8* getelementptr inbounds ([14 x i8]* @.str, i32 0, i32 0)) ; [#uses=0]
+ br label %return
+
+return: ; preds = %entry
+ ret void
+}
+
+; [#uses=1]
+declare i32 @puts(i32*)
+
+; [#uses=0]
+define i32 @main() {
+entry:
+ %retval = alloca i32 ; [#uses=2]
+ %0 = alloca i32 ; [#uses=2]
+ %"alloca point" = bitcast i32 0 to i32 ; [#uses=0]
+ call void @"_Z5hellov"()
+ store i32 0, i32* %0, align 4
+ %1 = load i32* %0, align 4 ; [#uses=1]
+ store i32 %1, i32* %retval, align 4
+ br label %return
+
+return: ; preds = %entry
+ %retval1 = load i32* %retval ; [#uses=1]
+ ret i32 %retval1
+}
diff --git a/tests/cases/unaligneddouble.ll b/tests/cases/unaligneddouble.ll
index 22b92741..e4067831 100644
--- a/tests/cases/unaligneddouble.ll
+++ b/tests/cases/unaligneddouble.ll
@@ -10,7 +10,7 @@ entry:
%retval = alloca i32, align 4 ; [#uses=1 type=i32*]
%doub = alloca double, align 4
store i32 0, i32* %retval
- %0 = bitcast double* %doub to i32
+ %0 = ptrtoint double* %doub to i32
%1 = uitofp i32 %0 to double
store double %1, double* %doub, align 1
store double %1, double* %doub, align 2
diff --git a/tests/runner.py b/tests/runner.py
index 8a5e1129..37e307e9 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -328,7 +328,10 @@ process(sys.argv[1])
os.makedirs(ret)
return ret
- def get_library(self, name, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args=['-j', '2'], cache=True, env_init={}, cache_name_extra='', native=False):
+ def get_library(self, name, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args='help', cache=True, env_init={}, cache_name_extra='', native=False):
+ if make_args == 'help':
+ make_args = ['-j', str(multiprocessing.cpu_count())]
+
build_dir = self.get_build_dir()
output_dir = self.get_dir()
diff --git a/tests/test_benchmark.py b/tests/test_benchmark.py
index 63e0041f..2f4d26fd 100644
--- a/tests/test_benchmark.py
+++ b/tests/test_benchmark.py
@@ -14,6 +14,109 @@ DEFAULT_ARG = '4'
TEST_REPS = 2
+CORE_BENCHMARKS = True # core benchmarks vs full regression suite
+
+class Benchmarker:
+ def __init__(self, name):
+ self.name = name
+
+ def bench(self, args, output_parser=None):
+ self.times = []
+ for i in range(TEST_REPS):
+ start = time.time()
+ output = self.run(args)
+ if not output_parser:
+ curr = time.time()-start
+ else:
+ curr = output_parser(output)
+ self.times.append(curr)
+
+ def display(self, baseline=None):
+ if baseline == self: baseline = None
+ mean = sum(self.times)/len(self.times)
+ squared_times = map(lambda x: x*x, self.times)
+ mean_of_squared = sum(squared_times)/len(self.times)
+ std = math.sqrt(mean_of_squared - mean*mean)
+ sorted_times = self.times[:]
+ sorted_times.sort()
+ median = sum(sorted_times[len(sorted_times)/2 - 1:len(sorted_times)/2 + 1])/2
+
+ print ' %10s: mean: %4.3f (+-%4.3f) secs median: %4.3f range: %4.3f-%4.3f (noise: %4.3f%%) (%d runs)' % (self.name, mean, std, median, min(self.times), max(self.times), 100*std/mean, TEST_REPS),
+
+ if baseline:
+ mean_baseline = sum(baseline.times)/len(baseline.times)
+ final = mean / mean_baseline
+ print ' Relative: %.2f X slower' % final
+ else:
+ print
+
+class NativeBenchmarker(Benchmarker):
+ def __init__(self, name, cc, cxx):
+ self.name = name
+ self.cc = cc
+ self.cxx = cxx
+
+ def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec):
+ self.parent = parent
+ if not native_exec:
+ compiler = self.cxx if filename.endswith('cpp') else self.cc
+ process = Popen([compiler, '-O2', '-fno-math-errno', filename, '-o', filename+'.native'] + shared_args + native_args, stdout=PIPE, stderr=parent.stderr_redirect)
+ output = process.communicate()
+ if process.returncode is not 0:
+ print >> sys.stderr, "Building native executable with command '%s' failed with a return code %d!" % (' '.join([compiler, '-O2', filename, '-o', filename+'.native']), process.returncode)
+ print "Output: " + output[0]
+ else:
+ print '(using clang)'
+ shutil.copyfile(native_exec, filename + '.native')
+ shutil.copymode(native_exec, filename + '.native')
+ self.filename = filename
+
+ def run(self, args):
+ process = Popen([self.filename+'.native'] + args, stdout=PIPE, stderr=PIPE)
+ return process.communicate()[0]
+
+class JSBenchmarker(Benchmarker):
+ def __init__(self, name, engine, extra_args=[]):
+ self.name = name
+ self.engine = engine
+ self.extra_args = extra_args
+
+ def build(self, parent, filename, args, shared_args, emcc_args, native_args, native_exec):
+ self.filename = filename
+
+ open('hardcode.py', 'w').write('''
+def process(filename):
+ js = open(filename).read()
+ replaced = js.replace("run();", "run(%s.concat(Module[\\"arguments\\"]));")
+ assert js != replaced
+ open(filename, 'w').write(replaced)
+import sys
+process(sys.argv[1])
+''' % str(args[:-1]) # do not hardcode in the last argument, the default arg
+)
+
+ try_delete(filename + '.js')
+ output = Popen([PYTHON, EMCC, filename, #'-O3',
+ '-O2', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0',
+ '--memory-init-file', '0', '--js-transform', 'python hardcode.py',
+ '-s', 'TOTAL_MEMORY=128*1024*1024',
+ #'--closure', '1',
+ #'-g',
+ '-o', filename + '.js'] + shared_args + emcc_args + self.extra_args, stdout=PIPE, stderr=PIPE).communicate()
+ assert os.path.exists(filename + '.js'), 'Failed to compile file: ' + output[0]
+
+ def run(self, args):
+ return run_js(self.filename + '.js', engine=self.engine, args=args, stderr=PIPE, full_output=True)
+
+# Benchmarkers
+benchmarkers = [
+ NativeBenchmarker('clang', CLANG_CC, CLANG),
+ NativeBenchmarker('gcc', 'gcc', 'g++'),
+ JSBenchmarker('sm-f32', SPIDERMONKEY_ENGINE, ['-s', 'PRECISE_F32=2']),
+ JSBenchmarker('sm', SPIDERMONKEY_ENGINE),
+ JSBenchmarker('v8', V8_ENGINE)
+]
+
class benchmark(RunnerCore):
save_dir = True
@@ -54,41 +157,6 @@ class benchmark(RunnerCore):
JS_ENGINE = Building.JS_ENGINE_OVERRIDE if Building.JS_ENGINE_OVERRIDE is not None else JS_ENGINES[0]
print 'Benchmarking JS engine: %s' % JS_ENGINE
- def print_stats(self, times, native_times, last=False, reps=TEST_REPS):
- if reps == 0:
- print '(no reps)'
- return
- mean = sum(times)/len(times)
- squared_times = map(lambda x: x*x, times)
- mean_of_squared = sum(squared_times)/len(times)
- std = math.sqrt(mean_of_squared - mean*mean)
- sorted_times = times[:]
- sorted_times.sort()
- median = sum(sorted_times[len(sorted_times)/2 - 1:len(sorted_times)/2 + 1])/2
-
- mean_native = sum(native_times)/len(native_times)
- squared_native_times = map(lambda x: x*x, native_times)
- mean_of_squared_native = sum(squared_native_times)/len(native_times)
- std_native = math.sqrt(mean_of_squared_native - mean_native*mean_native)
- sorted_native_times = native_times[:]
- sorted_native_times.sort()
- median_native = sum(sorted_native_times[len(sorted_native_times)/2 - 1:len(sorted_native_times)/2 + 1])/2
-
- final = mean / mean_native
-
- if last:
- norm = 0
- for i in range(len(times)):
- norm += times[i]/native_times[i]
- norm /= len(times)
- print
- print ' JavaScript: %.3f Native: %.3f Ratio: %.3f Normalized ratio: %.3f' % (mean, mean_native, final, norm)
- return
-
- print
- print ' JavaScript: mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) (%d runs)' % (mean, std, median, min(times), max(times), 100*std/mean, reps)
- print ' Native : mean: %.3f (+-%.3f) secs median: %.3f range: %.3f-%.3f (noise: %3.3f%%) JS is %.2f X slower' % (mean_native, std_native, median_native, min(native_times), max(native_times), 100*std_native/mean_native, final)
-
def do_benchmark(self, name, src, expected_output='FAIL', args=[], emcc_args=[], native_args=[], shared_args=[], force_c=False, reps=TEST_REPS, native_exec=None, output_parser=None, args_processor=None):
args = args or [DEFAULT_ARG]
if args_processor: args = args_processor(args)
@@ -98,68 +166,12 @@ class benchmark(RunnerCore):
f = open(filename, 'w')
f.write(src)
f.close()
- final_filename = os.path.join(dirname, name + '.js')
- open('hardcode.py', 'w').write('''
-def process(filename):
- js = open(filename).read()
- replaced = js.replace("run();", "run(%s.concat(Module[\\"arguments\\"]));")
- assert js != replaced
- open(filename, 'w').write(replaced)
-import sys
-process(sys.argv[1])
-''' % str(args[:-1]) # do not hardcode in the last argument, the default arg
-)
-
- try_delete(final_filename)
- output = Popen([PYTHON, EMCC, filename, #'-O3',
- '-O2', '-s', 'DOUBLE_MODE=0', '-s', 'PRECISE_I64_MATH=0',
- '--memory-init-file', '0', '--js-transform', 'python hardcode.py',
- '-s', 'TOTAL_MEMORY=128*1024*1024',
- '--closure', '1',
- #'-s', 'PRECISE_F32=1',
- #'-g',
- '-o', final_filename] + shared_args + emcc_args, stdout=PIPE, stderr=self.stderr_redirect).communicate()
- assert os.path.exists(final_filename), 'Failed to compile file: ' + output[0]
-
- # Run JS
- times = []
- for i in range(reps):
- start = time.time()
- js_output = run_js(final_filename, engine=JS_ENGINE, args=args, stderr=PIPE, full_output=True)
-
- if i == 0 and 'uccessfully compiled asm.js code' in js_output:
- if 'asm.js link error' not in js_output:
- print "[%s was asm.js'ified]" % name
- if not output_parser:
- curr = time.time()-start
- else:
- curr = output_parser(js_output)
- times.append(curr)
- if i == 0:
- # Sanity check on output
- self.assertContained(expected_output, js_output)
-
- # Run natively
- if not native_exec:
- self.build_native(filename, shared_args + native_args)
- else:
- shutil.copyfile(native_exec, filename + '.native')
- shutil.copymode(native_exec, filename + '.native')
- native_times = []
- for i in range(reps):
- start = time.time()
- native_output = self.run_native(filename, args)
- if i == 0:
- # Sanity check on output
- self.assertContained(expected_output, native_output)
- if not output_parser:
- curr = time.time()-start
- else:
- curr = output_parser(native_output)
- native_times.append(curr)
-
- self.print_stats(times, native_times, reps=reps)
+ print
+ for b in benchmarkers:
+ b.build(self, filename, args, shared_args, emcc_args, native_args, native_exec)
+ b.bench(args, output_parser)
+ b.display(benchmarkers[0])
def test_primes(self):
src = r'''
@@ -402,9 +414,11 @@ process(sys.argv[1])
self.fasta('fasta_float', 'float')
def test_fasta_double(self):
+ if CORE_BENCHMARKS: return
self.fasta('fasta_double', 'double')
def test_fasta_double_full(self):
+ if CORE_BENCHMARKS: return
self.fasta('fasta_double_full', 'double', emcc_args=['-s', 'DOUBLE_MODE=1'])
def test_skinning(self):
@@ -412,10 +426,12 @@ process(sys.argv[1])
self.do_benchmark('skinning', src, 'blah=0.000000')
def test_life(self):
+ if CORE_BENCHMARKS: return
src = open(path_from_root('tests', 'life.c'), 'r').read()
self.do_benchmark('life', src, '''--------------------------------''', shared_args=['-std=c99'], force_c=True)
def test_linpack_double(self):
+ if CORE_BENCHMARKS: return
def output_parser(output):
return 100.0/float(re.search('Unrolled Double Precision +([\d\.]+) Mflops', output).group(1))
self.do_benchmark('linpack_double', open(path_from_root('tests', 'linpack.c')).read(), '''Unrolled Double Precision''', force_c=True, output_parser=output_parser)
diff --git a/tests/test_core.py b/tests/test_core.py
index 9b072b90..862beb8b 100644
--- a/tests/test_core.py
+++ b/tests/test_core.py
@@ -351,6 +351,9 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
}
'''
self.do_run(src, '*4903566027370624, 153236438355333*')
+
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
code = open(os.path.join(self.get_dir(), 'src.cpp.o.js')).read()
assert 'goog.math.Long' not in code, 'i64 precise math should not have been included if not actually used'
@@ -459,6 +462,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
def test_float32_precise(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Settings.PRECISE_F32 = 1
test_path = path_from_root('tests', 'core', 'test_float32_precise')
@@ -1086,36 +1091,48 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
def test_longjmp(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_longjmp2(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp2')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_longjmp3(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp3')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_longjmp4(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp4')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_longjmp_funcptr(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp_funcptr')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_longjmp_repeat(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Settings.MAX_SETJMPS = 1
test_path = path_from_root('tests', 'core', 'test_longjmp_repeat')
@@ -1124,6 +1141,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
def test_longjmp_stacked(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp_stacked')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -1131,12 +1150,16 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_longjmp_exc(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
test_path = path_from_root('tests', 'core', 'test_longjmp_exc')
src, output = (test_path + s for s in ('.in', '.out'))
self.do_run_from_file(src, output)
def test_setjmp_many(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
src = r'''
#include <stdio.h>
#include <setjmp.h>
@@ -1155,6 +1178,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_exceptions(self):
if Settings.QUANTUM_SIZE == 1: return self.skip("we don't support libcxx in q1")
if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.EXCEPTION_DEBUG = 1
@@ -1243,6 +1267,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_exception_2(self):
if self.emcc_args is None: return self.skip('need emcc to add in libcxx properly')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.DISABLE_EXCEPTION_CATCHING = 0
test_path = path_from_root('tests', 'core', 'test_exception_2')
@@ -1251,6 +1276,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output)
def test_white_list_exception(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Settings.DISABLE_EXCEPTION_CATCHING = 2
Settings.EXCEPTION_CATCHING_WHITELIST = ["__Z12somefunctionv"]
Settings.INLINING_LIMIT = 50 # otherwise it is inlined and not identified
@@ -1265,6 +1292,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_uncaught_exception(self):
if self.emcc_args is None: return self.skip('no libcxx inclusion without emcc')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.DISABLE_EXCEPTION_CATCHING = 0
@@ -1303,6 +1331,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run(src, 'success')
def test_typed_exceptions(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Settings.DISABLE_EXCEPTION_CATCHING = 0
Settings.SAFE_HEAP = 0 # Throwing null will cause an ignorable null pointer access.
src = open(path_from_root('tests', 'exceptions', 'typed.cpp'), 'r').read()
@@ -1310,6 +1340,8 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run(src, expected)
def test_multiexception(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Settings.DISABLE_EXCEPTION_CATCHING = 0
test_path = path_from_root('tests', 'core', 'test_multiexception')
@@ -1319,6 +1351,7 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
def test_std_exception(self):
if self.emcc_args is None: return self.skip('requires emcc')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.DISABLE_EXCEPTION_CATCHING = 0
self.emcc_args += ['-s', 'SAFE_HEAP=0']
@@ -1844,12 +1877,9 @@ class T(RunnerCore): # Short name, to make it more fun to use manually on the co
self.do_run_from_file(src, output, [], lambda x, err: x.replace('\n', '*'))
- def test_float_h(self):
- process = Popen([PYTHON, EMCC, path_from_root('tests', 'float+.c')], stdout=PIPE, stderr=PIPE)
- process.communicate()
- assert process.returncode is 0, 'float.h should agree with our system'
-
def test_llvm_used(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('pnacl kills llvm_used')
+
Building.LLVM_OPTS = 3
test_path = path_from_root('tests', 'core', 'test_llvm_used')
@@ -1885,6 +1915,7 @@ def process(filename):
def test_inlinejs(self):
if not self.is_le32(): return self.skip('le32 needed for inline js')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
test_path = path_from_root('tests', 'core', 'test_inlinejs')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -1897,6 +1928,7 @@ def process(filename):
def test_inlinejs2(self):
if not self.is_le32(): return self.skip('le32 needed for inline js')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
test_path = path_from_root('tests', 'core', 'test_inlinejs2')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -2035,6 +2067,8 @@ def process(filename):
''', args=['34962', '26214', '35040'])
def test_indirectbr(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
Building.COMPILER_TEST_OPTS = filter(lambda x: x != '-g', Building.COMPILER_TEST_OPTS)
test_path = path_from_root('tests', 'core', 'test_indirectbr')
@@ -2043,6 +2077,8 @@ def process(filename):
self.do_run_from_file(src, output)
def test_indirectbr_many(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('blockaddr > 255 requires ta2')
test_path = path_from_root('tests', 'core', 'test_indirectbr_many')
@@ -2689,6 +2725,10 @@ The current type of b is: 9
self.do_run(main, 'supp: 54,2\nmain: 56\nsupp see: 543\nmain see: 76\nok.')
def can_dlfcn(self):
+ if os.environ.get('EMCC_FAST_COMPILER') == '1':
+ self.skip('todo in fastcomp')
+ return False
+
if self.emcc_args and '--memory-init-file' in self.emcc_args:
for i in range(len(self.emcc_args)):
if self.emcc_args[i] == '--memory-init-file':
@@ -3067,6 +3107,7 @@ def process(filename):
def test_dlfcn_self(self):
if Settings.USE_TYPED_ARRAYS == 1: return self.skip('Does not work with USE_TYPED_ARRAYS=1')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.DLOPEN_SUPPORT = 1
def post(filename):
@@ -4016,6 +4057,8 @@ def process(filename):
def test_utf32(self):
if self.emcc_args is None: return self.skip('need libc for wcslen()')
if not self.is_le32(): return self.skip('this test uses inline js, which requires le32')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
+
self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.')
self.do_run(open(path_from_root('tests', 'utf32.cpp')).read(), 'OK.', args=['-fshort-wchar'])
@@ -4550,6 +4593,7 @@ return malloc(size);
def test_simd(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2')
if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
test_path = path_from_root('tests', 'core', 'test_simd')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -4558,6 +4602,7 @@ return malloc(size);
def test_simd2(self):
if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
test_path = path_from_root('tests', 'core', 'test_simd2')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -4567,6 +4612,7 @@ return malloc(size);
def test_simd3(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip('needs ta2')
if Settings.ASM_JS: Settings.ASM_JS = 2 # does not validate
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
test_path = path_from_root('tests', 'core', 'test_simd3')
src, output = (test_path + s for s in ('.in', '.out'))
@@ -4593,6 +4639,7 @@ return malloc(size);
def test_lua(self):
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: make this work')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
self.do_run('',
'hello lua world!\n17\n1\n2\n3\n4\n7',
@@ -4610,6 +4657,7 @@ return malloc(size);
def test_freetype(self):
if self.emcc_args is None: return self.skip('requires emcc')
if Settings.QUANTUM_SIZE == 1: return self.skip('TODO: Figure out and try to fix')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
assert 'asm2g' in test_modes
if self.run_name == 'asm2g':
@@ -4742,7 +4790,7 @@ def process(filename):
test()
assert 'asm2g' in test_modes
- if self.run_name == 'asm2g' and not use_cmake:
+ if self.run_name == 'asm2g' and not use_cmake and os.environ.get('EMCC_FAST_COMPILER') != '1':
# Test forced alignment
print >> sys.stderr, 'testing FORCE_ALIGNED_MEMORY'
old = open('src.cpp.o.js').read()
@@ -4755,6 +4803,7 @@ def process(filename):
def test_poppler(self):
if self.emcc_args is None: return self.skip('very slow, we only do this in emcc runs')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.CORRECT_OVERFLOWS = 1
Settings.CORRECT_SIGNS = 1
@@ -4970,11 +5019,12 @@ def process(filename):
shortname = name.replace('.ll', '')
if '' not in shortname: continue
if os.environ.get('EMCC_FAST_COMPILER') == '1' and os.path.basename(shortname) in [
- 'structparam', 'uadd_overflow_ta2', 'extendedprecision', 'issue_39', 'emptystruct', 'phinonexist', 'quotedlabel', 'oob_ta2', # invalid ir
- 'structphiparam', 'callwithstructural_ta2', # pnacl limitation in ExpandStructRegs
+ 'structparam', 'uadd_overflow_ta2', 'extendedprecision', 'issue_39', 'emptystruct', 'phinonexist', 'quotedlabel', 'oob_ta2', 'phientryimplicit', 'phiself', 'invokebitcast', # invalid ir
+ 'structphiparam', 'callwithstructural_ta2', 'callwithstructural64_ta2', 'structinparam', # pnacl limitations in ExpandStructRegs
+ '2xi40', # pnacl limitations in ExpandGetElementPtr
'legalizer_ta2', '514_ta2', # pnacl limitation in not legalizing i104, i96, etc.
- 'longjmp_tiny', 'longjmp_tiny_phi', 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME
- 'sillyfuncast', # TODO very very soon XXX
+ 'longjmp_tiny', 'longjmp_tiny_invoke', 'longjmp_tiny_phi', 'longjmp_tiny_phi2', 'indirectbrphi', 'ptrtoint_blockaddr', 'quoted', # current fastcomp limitations FIXME
+ 'sillyfuncast', 'sillyfuncast2', 'sillybitcast', # TODO very very soon XXX
]: continue
if '_ta2' in shortname and not Settings.USE_TYPED_ARRAYS == 2:
print self.skip('case "%s" only relevant for ta2' % shortname)
@@ -5378,6 +5428,7 @@ def process(filename):
def test_embind(self):
if self.emcc_args is None: return self.skip('requires emcc')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Building.COMPILER_TEST_OPTS += ['--bind']
src = r'''
@@ -5400,6 +5451,7 @@ def process(filename):
def test_embind_2(self):
if self.emcc_args is None: return self.skip('requires emcc')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Building.COMPILER_TEST_OPTS += ['--bind', '--post-js', 'post.js']
open('post.js', 'w').write('''
Module.print('lerp ' + Module.lerp(1, 2, 0.66) + '.');
@@ -5420,6 +5472,7 @@ def process(filename):
def test_scriptaclass(self):
if self.emcc_args is None: return self.skip('requires emcc')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
Settings.EXPORT_BINDINGS = 1
@@ -5909,6 +5962,7 @@ def process(filename):
def test_source_map(self):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip("doesn't pass without typed arrays")
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
if NODE_JS not in JS_ENGINES: return self.skip('sourcemapper requires Node to run')
if '-g' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g')
@@ -5992,6 +6046,7 @@ def process(filename):
if Settings.USE_TYPED_ARRAYS != 2: return self.skip("doesn't pass without typed arrays")
if '-g4' not in Building.COMPILER_TEST_OPTS: Building.COMPILER_TEST_OPTS.append('-g4')
if NODE_JS not in JS_ENGINES: return self.skip('sourcemapper requires Node to run')
+ if os.environ.get('EMCC_FAST_COMPILER') == '1': return self.skip('todo in fastcomp')
src = '''
#include <stdio.h>
diff --git a/tests/test_other.py b/tests/test_other.py
index b10ae13b..46170856 100644
--- a/tests/test_other.py
+++ b/tests/test_other.py
@@ -2150,3 +2150,8 @@ mergeInto(LibraryManager.library, {
Popen([PYTHON, EMCC, path_from_root('tests', 'hello_world.cpp'), '--js-library', 'lib.js']).communicate()
self.assertContained('hello, world!', run_js(os.path.join(self.get_dir(), 'a.out.js')))
+ def test_float_h(self):
+ process = Popen([PYTHON, EMCC, path_from_root('tests', 'float+.c')], stdout=PIPE, stderr=PIPE)
+ out, err = process.communicate()
+ assert process.returncode is 0, 'float.h should agree with our system: ' + out + '\n\n\n' + err
+
diff --git a/tools/shared.py b/tools/shared.py
index 3456ab18..cbeb3eda 100644
--- a/tools/shared.py
+++ b/tools/shared.py
@@ -926,7 +926,7 @@ class Building:
@staticmethod
- def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args=['-j', '2'], cache=None, cache_name=None, copy_project=False, env_init={}, source_dir=None, native=False):
+ def build_library(name, build_dir, output_dir, generated_libs, configure=['sh', './configure'], configure_args=[], make=['make'], make_args='help', cache=None, cache_name=None, copy_project=False, env_init={}, source_dir=None, native=False):
''' Build a library into a .bc file. We build the .bc file once and cache it for all our tests. (We cache in
memory since the test directory is destroyed and recreated for each test. Note that we cache separately
for different compilers).
@@ -934,6 +934,8 @@ class Building:
if type(generated_libs) is not list: generated_libs = [generated_libs]
if source_dir is None: source_dir = path_from_root('tests', name.replace('_native', ''))
+ if make_args == 'help':
+ make_args = ['-j', str(multiprocessing.cpu_count())]
temp_dir = build_dir
if copy_project: