more precise abstract-values in ASM dataflow-analysis

Before this commit, there was only one catch-all mechanism to
create the abstract values of a custom dataflow analyses (DFAs),
namely via Interpreter.newValue(Type)

That state of affairs leads to imprecission, as can be seen
for example when creating a nullness-tracking analysis
(an instance method should have its this variable initially
tracked as non-null).

This commit adds methods to asm.tree.analysis.Analyzer to
allow overridding what abstract values are of interest for:
  - formal params in a method
  - local vars in a method
  - exception on the operand stack on entry to an
    exception-handling block
improvements to ASM dataflow-analysis
BCodeOpt building block: ConstantFolder

Constant folding comprises:

  - loads that are amenable to shorthand (e.g. ICONST_1) are rewritten

  - stores where the LHS already contains the value
    denoted by the RHS are replaced by DROP instruction

  - binary operations with constant result are left in place,
    but a DROP and a load of the constant-result are inserted
    rigth after them. Successive iterations of the fixpoint will
    reduce code to its final form.

  - conditional jumps, as well as lookup and table switches
    are simplified when their operand is constant.
Level 1 intra-method optimiz: ConstantFolder
BCodeOpt: test constant folding in the presence of NaNs

Tests are added to verify that intra-method optimizations
don't change the meaning of a program that involves operations
on floating-point NaNs.

These tests are the BCodeOpt counterpart to the tests introduced in
commit 497b0cb09a750fe05cf6c7c1cae2e3b960772ec4
BCodeOpt building block: NullnessPropagator

This transformer simplifies bytecode based on information
determined at compile-time about
definitely-null and definitely-non-null
for values held in local-variables and operant-stack slots.

Details in the documentation for
scala.tools.nsc.backend.bcode.NullnessPropagator
Level 1 intra-method optimiz: NullnessPropagator
BCodeOpt: NullnessPropagator takes module load for non-null

The load of a MODULE$ field won't be elided.
However, the non-nullness tracked for that value might lead later on
to control-flow simplification.
BCodeOpt: test constant folding including nullness propagation

A test is added to verify branches are removed when their outcome
can be determined at compile time based on constant-folding and
nullness propagation.

The test is the BCodeOpt counterpart to the jvm test introduced in
commit 69109c0ace5e3ac831c3b0a5635f25317d3b28bf
use-def, def-use chains for byecode-level: ProdConsAnalyzer

As covered in Sec. 8.10 of
  Steven S. Muchnick.
  Advanced compiler design and implementation.
  Morgan Kaufmann Publishers Inc., San Francisco, CA, USA, 1997.
BCodeOpt building block: DisambiguatingAnalyzer

In addition to tracking use-def and def-use chains,
a DisambiguatingAnalyzer goes one step further in that
the sources of value received via formal-params are
more accurately tracked.

Details in the documentation for
scala.tools.nsc.backend.bcode.DisambiguatingAnalyzer
BCodeOpt building block: CopyPropagator

Replaces the last link in a chain of data accesses
(involving local-variables only)
by a direct access to the chain-start.

Details in the documentation for
scala.tools.nsc.backend.bcode.CopyPropagator
Level 1 intra-method optimiz: Copy propagation

CopyPropagator rephrases LOAD instructions to re-use (when possible)
the value stored in a local-var with the lowest index.
That way, copies of that same value in other local-vars
may end up being not read anywhere, thus making the local-vars
holding them candidates for dead-store elimination.
TODO bcode.Util and asm.tree.analysis.Frame
BCodeOpt building block: DeadStoreElimPrim

Perform dead-store elimination for local-vars
holding primitives (dead-store elimination can be performed
more aggresively for primitive values than for reference values).

Details in the documentation for
scala.tools.nsc.backend.bcode.DeadStoreElimPrim
Level 1 intra-method optimiz: Dead Store Elimination, Primitives
BCodeOpt building block: DeadStoreElimRef

Perform dead-store elimination for local-vars
holding references (dead-store elimination can be performed
more aggresively for primitive values than for reference values).

Details in the documentation for
scala.tools.nsc.backend.bcode.DeadStoreElimRef
Level 1 intra-method optimiz: Dead Store Elimination, References
BCodeOpt building block: PushPopCollapser

Back-propagate POP and POP2 instructions to the instructions
producing the values to drop; all while preserving
and side-effects of those instructions.

Details in the documentation for
scala.tools.nsc.backend.bcode.PushPopCollapser
Level 1 intra-method optimiz: PushPopCollapser