tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

baseline-opt.js (4005B)


      1 // Point-testing various optimizations in the wasm baseline compiler.
      2 
      3 // Boolean optimization for control (bug 1286816).
      4 //
      5 // These optimizations combine a test (a comparison or Eqz) with an
      6 // immediately following conditional branch (BrIf, If, and Select), to
      7 // avoid generating a boolean value that is then tested with a
      8 // compare-to-zero.
      9 //
     10 // On AngryBots as of November 2016, 84% of all test instructions
     11 // (measured statically) are optimized by this method.
     12 
     13 function testEqzBrIf(value, type, untaken, taken, expected) {
     14    var f = wasmEvalText(`(module
     15 		   (func (result i32)
     16 		    (local ${type})
     17 		    (local i32)
     18 		    (local.set 0 (${type}.const ${value}))
     19 		    (local.set 1 (i32.const ${taken}))
     20 		    (block $b
     21 		     (br_if $b (${type}.eqz (local.get 0)))
     22 		     (local.set 1 (i32.const ${untaken})))
     23 		    (local.get 1))
     24 		   (export "f" (func 0)))`).exports["f"];
     25    assertEq(f(), expected);
     26 }
     27 
     28 ["i32", "i64"].forEach(t => testEqzBrIf(0, t, 37, 42, 42)); // Taken
     29 ["i32", "i64"].forEach(t => testEqzBrIf(1, t, 37, 42, 37)); // Untaken
     30 
     31 function testCmpBrIf(value, type, untaken, taken, expected) {
     32    var f = wasmEvalText(`(module
     33 		   (func (result i32)
     34 		    (local ${type})
     35 		    (local i32)
     36 		    (local.set 1 (i32.const ${taken}))
     37 		    (block $b
     38 		     (br_if $b (${type}.eq (local.get 0) (${type}.const ${value})))
     39 		     (local.set 1 (i32.const ${untaken})))
     40 		    (local.get 1))
     41 		   (export "f" (func 0)))`).exports["f"];
     42    assertEq(f(), expected);
     43 }
     44 
     45 ["i32", "i64", "f32", "f64"].forEach(t => testCmpBrIf(0, t, 37, 42, 42)); // Branch taken
     46 ["i32", "i64", "f32", "f64"].forEach(t => testCmpBrIf(1, t, 37, 42, 37)); // Branch untaken
     47 
     48 function testEqzSelect(value, type, iftrue, iffalse, expected) {
     49    var f = wasmEvalText(`(module
     50 		   (func (result i32)
     51 		    (local ${type})
     52 		    (local.set 0 (${type}.const ${value}))
     53 		    (select (i32.const ${iftrue})
     54 		            (i32.const ${iffalse})
     55 		            (${type}.eqz (local.get 0))))
     56 		   (export "f" (func 0)))`).exports["f"];
     57    assertEq(f(), expected);
     58 }
     59 
     60 ["i32", "i64"].forEach(t => testEqzSelect(0, t, 42, 37, 42)); // Select first
     61 ["i32", "i64"].forEach(t => testEqzSelect(1, t, 42, 37, 37)); // Select second
     62 
     63 function testCmpSelect(value, type, iftrue, iffalse, expected) {
     64    var f = wasmEvalText(`(module
     65 		   (func (result i32)
     66 		    (local ${type})
     67 		    (select (i32.const ${iftrue})
     68 		            (i32.const ${iffalse})
     69 		            (${type}.eq (local.get 0) (${type}.const ${value}))))
     70 		   (export "f" (func 0)))`).exports["f"];
     71    assertEq(f(), expected);
     72 }
     73 
     74 ["i32", "i64", "f32", "f64"].forEach(t => testCmpSelect(0, t, 42, 37, 42)); // Select first
     75 ["i32", "i64", "f32", "f64"].forEach(t => testCmpSelect(1, t, 42, 37, 37)); // Select second
     76 
     77 function testEqzIf(value, type, trueBranch, falseBranch, expected) {
     78    var f = wasmEvalText(`(module
     79 		   (func (result i32)
     80 		    (local ${type})
     81 		    (local i32)
     82 		    (local.set 0 (${type}.const ${value}))
     83 		    (if (${type}.eqz (local.get 0))
     84 			(then (local.set 1 (i32.const ${trueBranch})))
     85 		        (else (local.set 1 (i32.const ${falseBranch}))))
     86 		    (local.get 1))
     87 		   (export "f" (func 0)))`).exports["f"];
     88    assertEq(f(), expected);
     89 }
     90 
     91 ["i32", "i64"].forEach(t => testEqzIf(0, t, 42, 37, 42)); // Taken
     92 ["i32", "i64"].forEach(t => testEqzIf(1, t, 42, 37, 37)); // Untaken
     93 
     94 function testCmpIf(value, type, trueBranch, falseBranch, expected) {
     95    var f = wasmEvalText(`(module
     96 		   (func (result i32)
     97 		    (local ${type})
     98 		    (local i32)
     99 		    (if (${type}.eq (local.get 0) (${type}.const ${value}))
    100 			(then (local.set 1 (i32.const ${trueBranch})))
    101 		        (else (local.set 1 (i32.const ${falseBranch}))))
    102 		    (local.get 1))
    103 		   (export "f" (func 0)))`).exports["f"];
    104    assertEq(f(), expected);
    105 }
    106 
    107 ["i32", "i64", "f32", "f64"].forEach(t => testCmpIf(0, t, 42, 37, 42)); // Taken
    108 ["i32", "i64", "f32", "f64"].forEach(t => testCmpIf(1, t, 42, 37, 37)); // Untaken