Permalink
Browse files

Eliminate second loop label

  • Loading branch information...
rossberg committed Aug 24, 2016
1 parent d7f4d02 commit 6e8d71eb2afab1f6b53ba5f53679cc555cb84e1a
Showing with 195 additions and 129 deletions.
  1. +46 −30 ml-proto/README.md
  2. +0 −11 ml-proto/host/parser.mly
  3. +76 −28 ml-proto/test/float_exprs.wast
  4. +34 −27 ml-proto/test/labels.wast
  5. +39 −33 ml-proto/test/stack.wast
View
@@ -115,35 +115,48 @@ offset: offset=<uint>
align: align=(1|2|4|8|...)
cvtop: trunc_s | trunc_u | extend_s | extend_u | ...
+instr:
+ <op>
+ block <name>? <instr>* end
+ loop <name>? <instr>* end
+ if <name1>? <instr>* else <name2>? <instr>* end
+ if <name>? <instr>* end ;; = if <name>? <instr>* else end
+ <expr>
+
+op:
+ unreachable
+ nop
+ drop
+ select
+ br <var>
+ br_if <var>
+ br_table <var>+
+ return
+ call <var>
+ call_indirect <var>
+ get_local <var>
+ set_local <var>
+ tee_local <var>
+ <type>.const <value>
+ <type>.<unop>
+ <type>.<binop>
+ <type>.<testop>
+ <type>.<relop>
+ <type>.<cvtop>/<type>
+ <type>.load((8|16|32)_<sign>)? <offset>? <align>?
+ <type>.store(8|16|32)? <offset>? <align>?
+ current_memory
+ grow_memory <expr>
+
expr:
- ( nop )
- ( block <name>? <expr>* )
- ( loop <name1>? <name2>? <expr>* ) ;; = (block <name1>? (loop <name2>? (block <expr>*)))
- ( select <expr> <expr> <expr> )
- ( if <expr> ( then <name>? <expr>* ) ( else <name>? <expr>* )? )
- ( if <expr1> <expr2> <expr3>? ) ;; = (if <expr1> (then <expr2>) (else <expr3>?))
- ( br <var> <expr>? )
- ( br_if <var> <expr>? <expr> )
- ( br_table <var> <var> <expr>? <expr> )
- ( return <expr>? ) ;; = (br <current_depth> <expr>?)
- ( call <var> <expr>* )
- ( call_import <var> <expr>* )
- ( call_indirect <var> <expr> <expr>* )
- ( get_local <var> )
- ( set_local <var> <expr> )
- ( <type>.load((8|16|32)_<sign>)? <offset>? <align>? <expr> )
- ( <type>.store(8|16|32)? <offset>? <align>? <expr> <expr> )
- ( <type>.const <value> )
- ( <type>.<unop> <expr> )
- ( <type>.<binop> <expr> <expr> )
- ( <type>.<relop> <expr> <expr> )
- ( <type>.<cvtop>/<type> <expr> )
- ( unreachable )
- ( current_memory )
- ( grow_memory <expr> )
-
-func: ( func <name>? <sig> <local>* <expr>* )
- ( func <string> <name>? <sig> <local>* <expr>* ) ;; = (export <string> <N>) (func <name>? <sig> <local>* <expr>*)
+ ( <op> <expr>* ) ;; = <expr>* <op>
+ ( block <name>? <instr>* ) ;; = block <name>? <instr>* end
+ ( loop <name>? <instr>* ) ;; = loop <name>? <instr>* end
+ ( if <expr1> <expr2> <expr3>? ) ;; = <expr1> if <expr2> else <expr3>? end
+ ( if <expr>? ( then <name1>? <instr1>* ) ( else <name2>? <instr2>* )? ) ;; = <expr>? if <name1>? <instr1>* else <name2>? <instr2>* end
+
+func: ( func <name>? <sig> <local>* <instr>* )
+ ( func <string> <name>? <sig> <local>* <instr>* ) ;; = (export <string> <N>) (func <name>? <sig> <local>* <instr>*)
sig: ( type <var> ) | <param>* <result>?
param: ( param <type>* ) | ( param <name> <type> )
result: ( result <type> )
@@ -156,13 +169,16 @@ export: ( export <string> <var> ) | ( export <string> memory)
start: ( start <var> )
table: ( table <nat> <nat>? <elem_type> )
( table <elem_type> ( elem <var>* ) ) ;; = (table <size> <size> <elem_type>) (elem (i32.const 0) <var>*)
-elem: ( elem <expr> <var>* )
+elem: ( elem ( offset <instr> ) <var>* )
+ ( elem <expr> <var>* ) ;; = (elem (offset <expr>) <var>*)
memory: ( memory <nat> <nat>? )
( memory ( data <string>* ) ) ;; = (memory <size> <size>) (data (i32.const 0) <string>*)
-data: ( data <expr> <string>* )
+data: ( data ( offset <instr>* ) <string>* )
+ ( data <expr> <string>* ) ;; = (data (offset <expr>) <var>*)
```
Here, productions marked with respective comments are abbreviation forms for equivalent expansions (see the explanation of the AST below).
+WebAssembly is a stack machine, so all expressions are merely abbreviations of a corresponding post-order sequence of instructions.
Any form of naming via `<name>` and `<var>` (including expression labels) is merely notational convenience of this text format. The actual AST has no names, and all bindings are referred to via ordered numeric indices; consequently, names are immediately resolved in the parser and replaced by indices. Indices can also be used directly in the text format.
View
@@ -235,9 +235,6 @@ bind_var :
labeling :
| /* empty */ %prec LOW { fun c -> anon_label c }
- | labeling1 { $1 }
-;
-labeling1 :
| bind_var { fun c -> bind_label c $1 }
;
@@ -290,10 +287,6 @@ ctrl_instr :
{ fun c -> let c' = $2 c in block ($3 c') }
| LOOP labeling instr_list END
{ fun c -> let c' = $2 c in loop ($3 c') }
- | LOOP labeling1 labeling1 instr_list END
- { let at = at () in
- fun c -> let c' = $2 c in let c'' = $3 c' in
- block [loop ($4 c'') @@ at] }
| IF labeling instr_list END
{ fun c -> let c' = $2 c in if_ ($3 c') [] }
| IF labeling instr_list ELSE labeling instr_list END
@@ -317,10 +310,6 @@ expr1 : /* Sugar */
{ fun c -> let c' = $2 c in [], block ($3 c') }
| LOOP labeling instr_list
{ fun c -> let c' = $2 c in [], loop ($3 c') }
- | LOOP labeling1 labeling1 instr_list
- { let at = at () in
- fun c -> let c' = $2 c in let c'' = $3 c' in
- [], block [loop ($4 c'') @@ at] }
| IF expr expr { fun c -> let c' = anon_label c in $2 c, if_ ($3 c') [] }
| IF expr expr expr
{ fun c -> let c' = anon_label c in $2 c, if_ ($3 c') ($4 c') }
@@ -871,10 +871,15 @@
(func $run (param $n i32) (param $z f32)
(local $i i32)
- (loop $exit $cont
- (f32.store (get_local $i) (f32.div (f32.load (get_local $i)) (get_local $z)))
- (set_local $i (i32.add (get_local $i) (i32.const 4)))
- (br_if $cont (i32.lt_u (get_local $i) (get_local $n)))
+ (block $exit
+ (loop $cont
+ (f32.store
+ (get_local $i)
+ (f32.div (f32.load (get_local $i)) (get_local $z))
+ )
+ (set_local $i (i32.add (get_local $i) (i32.const 4)))
+ (br_if $cont (i32.lt_u (get_local $i) (get_local $n)))
+ )
)
)
(export "run" $run)
@@ -904,10 +909,15 @@
(func $run (param $n i32) (param $z f64)
(local $i i32)
- (loop $exit $cont
- (f64.store (get_local $i) (f64.div (f64.load (get_local $i)) (get_local $z)))
- (set_local $i (i32.add (get_local $i) (i32.const 8)))
- (br_if $cont (i32.lt_u (get_local $i) (get_local $n)))
+ (block $exit
+ (loop $cont
+ (f64.store
+ (get_local $i)
+ (f64.div (f64.load (get_local $i)) (get_local $z))
+ )
+ (set_local $i (i32.add (get_local $i) (i32.const 8)))
+ (br_if $cont (i32.lt_u (get_local $i) (get_local $n)))
+ )
)
)
(export "run" $run)
@@ -1506,23 +1516,42 @@
(local $sum f32)
(local $c f32)
(local $t f32)
- (loop $exit $top
- (set_local $t (f32.sub (f32.sub (tee_local $sum (f32.add (get_local $c) (tee_local $t (f32.sub (f32.load (get_local $p)) (get_local $t))))) (get_local $c)) (get_local $t)))
- (set_local $p (i32.add (get_local $p) (i32.const 4)))
- (set_local $c (get_local $sum))
- (br_if $top (tee_local $n (i32.add (get_local $n) (i32.const -1))))
+ (block $exit
+ (loop $top
+ (set_local $t
+ (f32.sub
+ (f32.sub
+ (tee_local $sum
+ (f32.add
+ (get_local $c)
+ (tee_local $t
+ (f32.sub (f32.load (get_local $p)) (get_local $t))
+ )
+ )
+ )
+ (get_local $c)
+ )
+ (get_local $t)
+ )
+ )
+ (set_local $p (i32.add (get_local $p) (i32.const 4)))
+ (set_local $c (get_local $sum))
+ (br_if $top (tee_local $n (i32.add (get_local $n) (i32.const -1))))
+ )
)
(get_local $sum)
)
(export "f32.kahan_sum" $f32.kahan_sum)
(func $f32.plain_sum (param $p i32) (param $n i32) (result f32)
(local $sum f32)
- (loop $exit $top
- (set_local $sum (f32.add (get_local $sum) (f32.load (get_local $p))))
- (set_local $p (i32.add (get_local $p) (i32.const 4)))
- (set_local $n (i32.add (get_local $n) (i32.const -1)))
- (br_if $top (get_local $n))
+ (block $exit
+ (loop $top
+ (set_local $sum (f32.add (get_local $sum) (f32.load (get_local $p))))
+ (set_local $p (i32.add (get_local $p) (i32.const 4)))
+ (set_local $n (i32.add (get_local $n) (i32.const -1)))
+ (br_if $top (get_local $n))
+ )
)
(get_local $sum)
)
@@ -1540,23 +1569,42 @@
(local $sum f64)
(local $c f64)
(local $t f64)
- (loop $exit $top
- (set_local $t (f64.sub (f64.sub (tee_local $sum (f64.add (get_local $c) (tee_local $t (f64.sub (f64.load (get_local $p)) (get_local $t))))) (get_local $c)) (get_local $t)))
- (set_local $p (i32.add (get_local $p) (i32.const 8)))
- (set_local $c (get_local $sum))
- (br_if $top (tee_local $n (i32.add (get_local $n) (i32.const -1))))
+ (block $exit
+ (loop $top
+ (set_local $t
+ (f64.sub
+ (f64.sub
+ (tee_local $sum
+ (f64.add
+ (get_local $c)
+ (tee_local $t
+ (f64.sub (f64.load (get_local $p)) (get_local $t))
+ )
+ )
+ )
+ (get_local $c)
+ )
+ (get_local $t)
+ )
+ )
+ (set_local $p (i32.add (get_local $p) (i32.const 8)))
+ (set_local $c (get_local $sum))
+ (br_if $top (tee_local $n (i32.add (get_local $n) (i32.const -1))))
+ )
)
(get_local $sum)
)
(export "f64.kahan_sum" $f64.kahan_sum)
(func $f64.plain_sum (param $p i32) (param $n i32) (result f64)
(local $sum f64)
- (loop $exit $top
- (set_local $sum (f64.add (get_local $sum) (f64.load (get_local $p))))
- (set_local $p (i32.add (get_local $p) (i32.const 8)))
- (set_local $n (i32.add (get_local $n) (i32.const -1)))
- (br_if $top (get_local $n))
+ (block $exit
+ (loop $top
+ (set_local $sum (f64.add (get_local $sum) (f64.load (get_local $p))))
+ (set_local $p (i32.add (get_local $p) (i32.const 8)))
+ (set_local $n (i32.add (get_local $n) (i32.const -1)))
+ (br_if $top (get_local $n))
+ )
)
(get_local $sum)
)
View
@@ -9,60 +9,67 @@
(func $loop1 (result i32)
(local $i i32)
(set_local $i (i32.const 0))
- (loop $exit $cont
- (set_local $i (i32.add (get_local $i) (i32.const 1)))
- (if (i32.eq (get_local $i) (i32.const 5))
- (br $exit (get_local $i))
+ (block $exit
+ (loop $cont
+ (set_local $i (i32.add (get_local $i) (i32.const 1)))
+ (if (i32.eq (get_local $i) (i32.const 5))
+ (br $exit (get_local $i))
+ )
+ (br $cont)
)
- (br $cont)
)
)
(func $loop2 (result i32)
(local $i i32)
(set_local $i (i32.const 0))
- (loop $exit $cont
- (set_local $i (i32.add (get_local $i) (i32.const 1)))
- (if (i32.eq (get_local $i) (i32.const 5))
+ (block $exit
+ (loop $cont
+ (set_local $i (i32.add (get_local $i) (i32.const 1)))
+ (if (i32.eq (get_local $i) (i32.const 5))
+ (br $cont)
+ )
+ (if (i32.eq (get_local $i) (i32.const 8))
+ (br $exit (get_local $i))
+ )
+ (set_local $i (i32.add (get_local $i) (i32.const 1)))
(br $cont)
)
- (if (i32.eq (get_local $i) (i32.const 8))
- (br $exit (get_local $i))
- )
- (set_local $i (i32.add (get_local $i) (i32.const 1)))
- (br $cont)
)
)
(func $loop3 (result i32)
(local $i i32)
(set_local $i (i32.const 0))
- (loop $exit $cont
- (set_local $i (i32.add (get_local $i) (i32.const 1)))
- (if (i32.eq (get_local $i) (i32.const 5))
- (br $exit (get_local $i))
+ (block $exit
+ (loop $cont
+ (set_local $i (i32.add (get_local $i) (i32.const 1)))
+ (if (i32.eq (get_local $i) (i32.const 5))
+ (br $exit (get_local $i))
+ )
+ (get_local $i)
)
- (get_local $i)
)
)
(func $loop4 (param $max i32) (result i32)
(local $i i32)
(set_local $i (i32.const 1))
- (loop $exit $cont
- (set_local $i (i32.add (get_local $i) (get_local $i)))
- (if (i32.gt_u (get_local $i) (get_local $max))
- (br $exit (get_local $i))
+ (block $exit
+ (loop $cont
+ (set_local $i (i32.add (get_local $i) (get_local $i)))
+ (if (i32.gt_u (get_local $i) (get_local $max))
+ (br $exit (get_local $i))
+ )
+ (br $cont)
)
- (br $cont)
)
)
(func $loop5 (result i32)
- (i32.add (loop $l0 $l1
- (i32.const 1)
- )
- (i32.const 1)
+ (i32.add
+ (loop $l (i32.const 1))
+ (i32.const 1)
)
)
Oops, something went wrong.

0 comments on commit 6e8d71e

Please sign in to comment.