aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-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
16 files changed, 275 insertions, 158 deletions
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.L