Branch Pruning

Branch Pruning

IonMonkey poster

SpiderMonkey

Currently Firefox has a JavaScript engine which has 4 evaluation methods: an interpreter, a baseline JIT compiler, an optimizing JIT compiler, and an AOT compiler. All compilers are method compilers. We used to have a Tracing JIT compiler, but we removed it early in 2012.

Libraries

  • ECMAScript standard library
  • JQuery
  • React

Motivation

  • Remove unused/unlikely branches.
  • Use content code as guard.
  • Improve (Alias / Escape) Analysis results.

Libraries

        // ES6, 22.1.5.2.1
        function ArrayIteratorNext() {
          if (!IsObject(this) || !IsArrayIterator(this)) {
            return callFunction(CallArrayIteratorMethodIfWrapped,
                                this, "ArrayIteratorNext");
          }
          var result = { value: undefined, done: false };
          …
          return result;
        }
      

Branch Pruning

Bailouts

Bailouts

Bailouts

Bailouts

Acceptable, If and only if:

  • Low Frequency
  • Temporary

We would need some heuristics.

Analysis

  • Unreachable
    • Ignore backedges
  • Should Bailout
    • Not entry/OSR block
    • Predecessor is hot.
    • Has some alias set.
    • Number of dominated instructions / blocks.
    • A return is cheaper than a bailout.

Hit Counters

Removed Uses

Remove Blocks

Results

  • Improve other optimizations:
    • for-of (Scalar Replacement)
    • underscore uniq function (LICM)
  • Reduce generated code (~23%)