Skip to content

Commit

Permalink
Omit asserts if condition can be proven statically (#685)
Browse files Browse the repository at this point in the history
  • Loading branch information
dcodeIO committed Jul 2, 2019
1 parent 316b2d4 commit d68c266
Show file tree
Hide file tree
Showing 44 changed files with 3,944 additions and 7,593 deletions.
46 changes: 46 additions & 0 deletions src/builtins.ts
Expand Up @@ -2090,6 +2090,52 @@ export function compileCall(
let type = compiler.currentType;
compiler.currentType = type.nonNullableType;

// if the assertion can be proven statically, omit it
if (getExpressionId(arg0 = module.precomputeExpression(arg0)) == ExpressionId.Const) {
switch (getExpressionType(arg0)) {
case NativeType.I32: {
if (getConstValueI32(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.I64: {
if (getConstValueI64Low(arg0) != 0 || getConstValueI64High(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.F32: {
if (getConstValueF32(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
case NativeType.F64: {
if (getConstValueF64(arg0) != 0) {
if (contextualType == Type.void) {
compiler.currentType = Type.void;
return module.nop();
}
return arg0;
}
break;
}
}
}

// return ifTrueish if assertions are disabled
if (compiler.options.noAssert) {
if (contextualType == Type.void) { // simplify if dropped anyway
Expand Down
6 changes: 2 additions & 4 deletions tests/compiler/assert.optimized.wat
@@ -1,10 +1,8 @@
(module
(type $FUNCSIG$v (func))
(memory $0 1)
(data (i32.const 8) "\12\00\00\00\01\00\00\00\01\00\00\00\12\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s")
(data (i32.const 48) "\18\00\00\00\01\00\00\00\01\00\00\00\18\00\00\00m\00u\00s\00t\00 \00b\00e\00 \00t\00r\00u\00e")
(memory $0 0)
(export "memory" (memory $0))
(func $start (; 0 ;) (type $FUNCSIG$v)
(func $null (; 0 ;) (type $FUNCSIG$v)
nop
)
)
108 changes: 2 additions & 106 deletions tests/compiler/assert.untouched.wat
@@ -1,113 +1,9 @@
(module
(type $FUNCSIG$viiii (func (param i32 i32 i32 i32)))
(type $FUNCSIG$v (func))
(import "env" "abort" (func $~lib/builtins/abort (param i32 i32 i32 i32)))
(memory $0 1)
(data (i32.const 8) "\12\00\00\00\01\00\00\00\01\00\00\00\12\00\00\00a\00s\00s\00e\00r\00t\00.\00t\00s\00")
(data (i32.const 48) "\18\00\00\00\01\00\00\00\01\00\00\00\18\00\00\00m\00u\00s\00t\00 \00b\00e\00 \00t\00r\00u\00e\00")
(memory $0 0)
(table $0 1 funcref)
(elem (i32.const 0) $null)
(export "memory" (memory $0))
(start $start)
(func $start:assert (; 1 ;) (type $FUNCSIG$v)
(local $0 i32)
i32.const 1
i32.eqz
if
i32.const 0
i32.const 24
i32.const 1
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
i32.eqz
if
i32.const 0
i32.const 24
i32.const 2
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
i32.const 0
i32.gt_u
i32.eqz
if
i32.const 0
i32.const 24
i32.const 3
i32.const 0
call $~lib/builtins/abort
unreachable
end
f64.const 0.5
f64.const 0
f64.eq
if
i32.const 0
i32.const 24
i32.const 4
i32.const 0
call $~lib/builtins/abort
unreachable
end
f64.const 0.5
f64.const 0.4
f64.gt
i32.eqz
if
i32.const 0
i32.const 24
i32.const 5
i32.const 0
call $~lib/builtins/abort
unreachable
end
i64.const 4294967296
i64.eqz
if
i32.const 0
i32.const 24
i32.const 6
i32.const 0
call $~lib/builtins/abort
unreachable
end
i64.const 4294967296
i64.const 1
i64.gt_s
i32.eqz
if
i32.const 0
i32.const 24
i32.const 7
i32.const 0
call $~lib/builtins/abort
unreachable
end
i32.const 1
local.tee $0
if (result i32)
local.get $0
else
i32.const 64
i32.const 24
i32.const 10
i32.const 5
call $~lib/builtins/abort
unreachable
end
i32.eqz
if
unreachable
end
)
(func $start (; 2 ;) (type $FUNCSIG$v)
call $start:assert
)
(func $null (; 3 ;) (type $FUNCSIG$v)
(func $null (; 0 ;) (type $FUNCSIG$v)
)
)

0 comments on commit d68c266

Please sign in to comment.