Commit 7bad0bf4 authored by Camil Staps's avatar Camil Staps 🍃

Optimize wasm interpreter (about 30% on nfib): move instructions that use a...

Optimize wasm interpreter (about 30% on nfib): move instructions that use a call instruction to an outer loop, because in the SpiderMonkey register allocator calls cause early splits of live ranges
parent 276a9fe6
Pipeline #24226 failed with stages
in 11 minutes and 19 seconds
......@@ -75,12 +75,32 @@ collect_instructions :: !Options ![Target] -> [String]
collect_instructions {instructions_order=Nothing} _ = abort "no abc instructions order specified\n"
collect_instructions {debug_instructions,instructions_order=Just instrs_order} is =
header ++
reverse [block_start i \\ i <- is_with_illegal_block] ++
[ "(loop $abc-loop-outer"
, "(block $abc-gc-outer"
] ++
[ "(block $instr_"+++hd i.instrs \\ i <- reverse slow_instrs] ++
[ "(loop $abc-loop"
, "(block $abc-gc"
] ++
[ "(block $instr_"+++hd i.instrs \\ i <- reverse fast_instrs] ++
switch ++
flatten [block_body i \\ i <- is_with_illegal_block] ++
flatten [block_body {i & stmts=map (optimize fast_opt_options) i.stmts} \\ i <- fast_instrs] ++
gc_block "abc-loop" ++
flatten [block_body {i & stmts=map (optimize slow_opt_options) i.stmts} \\ i <- slow_instrs] ++
gc_block "abc-loop-outer" ++
footer
where
is_with_illegal_block = is ++ [end_instruction (instr_unimplemented (begin_instruction "illegal" start))]
all_instructions = [end_instruction (instr_unimplemented (begin_instruction "illegal" start)):is]
(slow_instrs,fast_instrs) = partition (\i->any (any (\e->e=:(Ecall _ _)) o subexpressions) i.stmts) [] [] all_instructions
where
partition p yes no [x:xs]
| p x
= partition p [x:yes] no xs
= partition p yes [x:no] xs
partition _ yes no [] = (yes,no)
fast_opt_options = {rename_labels=[]}
slow_opt_options = {rename_labels=[("abc-loop","abc-loop-outer"),("abc-gc","abc-gc-outer")]}
header =
[ "(module"
......@@ -125,27 +145,24 @@ where
[ "(local $vw"+++toString i+++" i32)" \\ i <- [0..maxList [i.temp_vars.tv_i32 \\ i <- is]] ] ++
[ "(local $vq"+++toString i+++" i64)" \\ i <- [0..maxList [i.temp_vars.tv_i64 \\ i <- is]] ] ++
[ "(local $vd"+++toString i+++" f64)" \\ i <- [0..maxList [i.temp_vars.tv_f64 \\ i <- is]] ] ++
[ "(local.set $"+++v+++" (global.get $g-"+++v+++"))" \\ v <- rt_vars ] ++
[ "(loop $abc-loop"
, "(block $abc-gc"
]
footer =
[ ")" // block abc-gc
[ "(local.set $"+++v+++" (global.get $g-"+++v+++"))" \\ v <- rt_vars ]
gc_block loop_label =
[ ") ;; gc"
, "(call $clean_gc (local.get $asp))"
, "(if (i32.le_s (global.get $g-hp-free) (local.get $hp-free))"
, "\t(then (call $clean_out_of_memory) (unreachable)))"
, "(local.set $hp (global.get $g-hp))"
, "(local.set $hp-free (global.get $g-hp-free))"
, "(br $abc-loop)"
, ")" // loop abc-loop
, "(unreachable)"
, ")" // func
, ")" // module
, "(br $"+++loop_label+++")"
, ") ;; loop"
]
footer =
[ "(unreachable)"
, ") ;; func"
, ") ;; module"
]
block_start t = "(block $instr_"+++hd t.instrs
block_body t = [")":head ++ [toString (optimize s) \\ s <- reverse t.stmts]]
block_body t = [")":head ++ [toString s \\ s <- reverse t.stmts]]
where
head = reverse [";; "+++i \\ i <- t.instrs]
......
......@@ -86,6 +86,8 @@ instance wasm_literal Int, Char
| Ivar !Variable
| Iref !Type !Type !Int !Ex // load or store
subexpressions :: !Ex -> [Ex]
class type a :: !a -> Type
type2 :: !a !a -> Type | type a
......@@ -93,4 +95,8 @@ instance type Ex, Variable
instance toString Ex
optimize :: !Ex -> Ex
:: OptimizationSettings =
{ rename_labels :: ![(String,String)]
}
optimize :: !OptimizationSettings !Ex -> Ex
......@@ -51,6 +51,66 @@ where
wasm_repr c = toString (toInt c)
is_zero c = c == '\0'
subexpressions :: !Ex -> [Ex]
subexpressions e = case e of
Eunreachable -> [e]
Ereturn e` -> [e:subexpressions e`]
Eblock -> [e]
Eloop -> [e]
Ebr _ -> [e]
Ebr_local _ -> [e]
Ebr_if l e` -> [e:subexpressions e`]
Eend -> [e]
Eif c -> [e:subexpressions c]
Ethen -> [e]
Eelse -> [e]
Ecall l args -> [e:[s \\ a <- args, s <- subexpressions a]]
Eselect e1 e2 c -> [e:[s \\ e <- [e1,e2,c], s <- subexpressions e]]
Etee _ v -> [e:subexpressions v]
Eset _ v -> [e:subexpressions v]
Eget _ -> [e]
Eload _ _ _ _ a -> [e:subexpressions a]
Estore _ _ _ a v -> [e:subexpressions a++subexpressions v]
Econst _ _ -> [e]
Eadd _ a b -> [e:subexpressions a++subexpressions b]
Esub _ a b -> [e:subexpressions a++subexpressions b]
Emul _ a b -> [e:subexpressions a++subexpressions b]
Ediv _ _ a b -> [e:subexpressions a++subexpressions b]
Erem _ _ a b -> [e:subexpressions a++subexpressions b]
Eeq _ a b -> [e:subexpressions a++subexpressions b]
Ene _ a b -> [e:subexpressions a++subexpressions b]
Elt _ _ a b -> [e:subexpressions a++subexpressions b]
Egt _ _ a b -> [e:subexpressions a++subexpressions b]
Ele _ _ a b -> [e:subexpressions a++subexpressions b]
Ege _ _ a b -> [e:subexpressions a++subexpressions b]
Eeqz _ e` -> [e:subexpressions e`]
Eand _ a b -> [e:subexpressions a++subexpressions b]
Eor _ a b -> [e:subexpressions a++subexpressions b]
Exor _ a b -> [e:subexpressions a++subexpressions b]
Eshl _ a b -> [e:subexpressions a++subexpressions b]
Eshr _ _ a b -> [e:subexpressions a++subexpressions b]
Eabs _ e` -> [e:subexpressions e`]
Efloor _ e` -> [e:subexpressions e`]
Eneg _ e` -> [e:subexpressions e`]
Esqrt _ e` -> [e:subexpressions e`]
Ewrap to fr e` -> [e:subexpressions e`]
Eextend to fr e` -> [e:subexpressions e`]
Ereinterpret to fr e` -> [e:subexpressions e`]
Etrunc to fr e` -> [e:subexpressions e`]
Econvert to fr e` -> [e:subexpressions e`]
Ivar _ -> [e]
Iref _ _ _ a -> [e:subexpressions a]
instance type Ex
where
type e = case e of
......@@ -201,66 +261,68 @@ where
F64 -> "."+++op+++" "
_ -> "."+++op+++if sig "_s" "_u"
optimize :: !Ex -> Ex
optimize e = case e of
optimize :: !OptimizationSettings !Ex -> Ex
optimize set e = case e of
Eunreachable -> e
Ereturn e -> Ereturn (optimize e)
Ereturn e -> Ereturn (optimize set e)
Eblock -> e
Eloop -> e
Ebr _ -> e
Ebr l -> case [new \\ (old,new) <- set.rename_labels | old==l] of
[new:_] -> Ebr new
[] -> e
Ebr_local _ -> e
Ebr_if l e -> Ebr_if l (optimize e)
Ebr_if l e -> Ebr_if l (optimize set e)
Eend -> e
Eif e -> Eif (optimize e)
Eif e -> Eif (optimize set e)
Ethen -> e
Eelse -> e
Ecall l args -> Ecall l [optimize a \\ a <- args]
Eselect e1 e2 c -> Eselect (optimize e1) (optimize e2) (optimize c)
Ecall l args -> Ecall l [optimize set a \\ a <- args]
Eselect e1 e2 c -> Eselect (optimize set e1) (optimize set e2) (optimize set c)
Etee v e -> Etee v (optimize e)
Eset v e -> Eset v (optimize e)
Etee v e -> Etee v (optimize set e)
Eset v e -> Eset v (optimize set e)
Eget _ -> e
Eload t1 t2 signed o a -> Eload t1 t2 signed o (optimize a)
Estore t1 t2 o a e -> Estore t1 t2 o (optimize a) (optimize e)
Eload t1 t2 signed o a -> Eload t1 t2 signed o (optimize set a)
Estore t1 t2 o a e -> Estore t1 t2 o (optimize set a) (optimize set e)
Econst _ _ -> e
Eadd t a b -> Eadd t (optimize a) (optimize b)
Esub t a b -> Esub t (optimize a) (optimize b)
Emul t a b -> Emul t (optimize a) (optimize b)
Ediv t signed a b -> Ediv t signed (optimize a) (optimize b)
Erem t signed a b -> Erem t signed (optimize a) (optimize b)
Eeq t a b -> Eeq t (optimize a) (optimize b)
Ene t a b -> Ene t (optimize a) (optimize b)
Elt t signed a b -> Elt t signed (optimize a) (optimize b)
Egt t signed a b -> Egt t signed (optimize a) (optimize b)
Ele t signed a b -> Ele t signed (optimize a) (optimize b)
Ege t signed a b -> Ege t signed (optimize a) (optimize b)
Eeqz t e -> Eeqz t (optimize e)
Eand t a b -> Eand t (optimize a) (optimize b)
Eor t a b -> Eor t (optimize a) (optimize b)
Exor t a b -> Exor t (optimize a) (optimize b)
Eshl t a b -> Eshl t (optimize a) (optimize b)
Eshr t signed a b -> Eshr t signed (optimize a) (optimize b)
Eabs t e -> Eabs t (optimize e)
Efloor t e -> Efloor t (optimize e)
Eneg t e -> Eneg t (optimize e)
Esqrt t e -> Esqrt t (optimize e)
Ewrap to fr e -> case optimize e of
Eadd t a b -> Eadd t (optimize set a) (optimize set b)
Esub t a b -> Esub t (optimize set a) (optimize set b)
Emul t a b -> Emul t (optimize set a) (optimize set b)
Ediv t signed a b -> Ediv t signed (optimize set a) (optimize set b)
Erem t signed a b -> Erem t signed (optimize set a) (optimize set b)
Eeq t a b -> Eeq t (optimize set a) (optimize set b)
Ene t a b -> Ene t (optimize set a) (optimize set b)
Elt t signed a b -> Elt t signed (optimize set a) (optimize set b)
Egt t signed a b -> Egt t signed (optimize set a) (optimize set b)
Ele t signed a b -> Ele t signed (optimize set a) (optimize set b)
Ege t signed a b -> Ege t signed (optimize set a) (optimize set b)
Eeqz t e -> Eeqz t (optimize set e)
Eand t a b -> Eand t (optimize set a) (optimize set b)
Eor t a b -> Eor t (optimize set a) (optimize set b)
Exor t a b -> Exor t (optimize set a) (optimize set b)
Eshl t a b -> Eshl t (optimize set a) (optimize set b)
Eshr t signed a b -> Eshr t signed (optimize set a) (optimize set b)
Eabs t e -> Eabs t (optimize set e)
Efloor t e -> Efloor t (optimize set e)
Eneg t e -> Eneg t (optimize set e)
Esqrt t e -> Esqrt t (optimize set e)
Ewrap to fr e -> case optimize set e of
Eload ltype stype signed o a | fr==ltype
-> Eload to stype signed o a
e
-> Ewrap to fr e
Eextend to fr e -> Eextend to fr (optimize e)
Ereinterpret to fr e -> Ereinterpret to fr (optimize e)
Etrunc to fr e -> Etrunc to fr (optimize e)
Econvert to fr e -> Econvert to fr (optimize e)
Eextend to fr e -> Eextend to fr (optimize set e)
Ereinterpret to fr e -> Ereinterpret to fr (optimize set e)
Etrunc to fr e -> Etrunc to fr (optimize set e)
Econvert to fr e -> Econvert to fr (optimize set e)
Ivar _ -> e
Iref t1 t2 o a -> Eload t1 t2 DontCare o (optimize a)
Iref t1 t2 o a -> Eload t1 t2 DontCare o (optimize set a)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment