SI-8601 Don't treat int/long division, or arraylength, as dead-code

`{i, l}div` and `{i, l}rem` throw an `ArithmeticException` if the
divisor is 0.

`arraylength` throws a `NullPointerException` on a null reference.

JVM Spec:
> The only integer operations that can throw an exception are the
> integer divide instructions (idiv and ldiv) and the integer
> remainder instructions (irem and lrem), which throw an
> ArithmeticException if the divisor is zero.

> The Java virtual machine's floating-point operators do not throw
> runtime exceptions

> If the arrayref is null, the arraylength instruction throws a
> NullPointerException.

I checked the other primitives in `ICode` to see if anything else
should be considered as live code.

Pure:

	  // jvm  : {i, l, f, d}neg
	  case class Negation(kind: TypeKind) extends Primitive
	  // jvm  : if{eq, ne, lt, ge, le, gt}, if{null, nonnull}
	  //        if_icmp{eq, ne, lt, ge, le, gt}, if_acmp{eq,ne}
	  case class Test(op: TestOp, kind: TypeKind,  zero: Boolean)  extends Primitive
	  // jvm  : lcmp, {f, d}cmp{l, g}
	  case class Comparison(op: ComparisonOp, kind: TypeKind) extends Primitive

Impure: {i, l}{div, rem}, otherwise pure

	  // jvm  : {i, l, f, d}{add, sub, mul, div, rem}
	  case class Arithmetic(op: ArithmeticOp, kind: TypeKind) extends Primitive

Pure (overflow is silent, NaN.toInt is defined):
	  // jvm  : {i, l}{and, or, xor}
	  case class Logical(op: LogicalOp, kind: TypeKind) extends Primitive

	  // jvm  : {i, l}{shl, ushl, shr}
	  case class Shift(op: ShiftOp, kind: TypeKind) extends Primitive

	  // jvm  : i2{l, f, d}, l2{i, f, d}, f2{i, l, d}, d2{i, l, f}, i2{b, c, s}
	  case class Conversion(src: TypeKind, dst: TypeKind) extends Primitive

Impure! May NPE!

	  // jvm  : arraylength
	  case class ArrayLength(kind: TypeKind) extends Primitive

Pure (we know that StringBuilder.{<init>, append, toString} are pure
and `append` is null safe.)

	  // jvm  : It should call the appropiate 'append' method on StringBuffer
	  case class StringConcat(el: TypeKind) extends Primitive

	  // jvm:  it should create a new StringBuffer
	  case object StartConcat extends Primitive

      // jvm:  convert StringBuffer to a String
	  case object EndConcat extends Primitive
SI-8601 Avoid over-eager optimization of LOAD_FIELD

It can NPE or trigger static class initilization, we can't elimiate
it without changing semantics.

To make sure we don't thwart closure elimination, I've allowed DCE
to eliminate a non-static LOAD_FIELD of a member of a closure class.
It would be more general to track nullity of the reciever (e.g, `this`
or `new Foo` cannot be null), but that would require more
infrastructure in this phase.

I've added a test for closure inlining based on a a suggestion by
@dragos. This actually passes if we remove the (LOAD_FIELD, DROP)
peephole optimization for `closelim` altogether. But I chose to
adapt that optimization (only allow it for non-static, closure
fields), rather then remove it alogether, in the interests of
treading lightly.
Add a test for array load
SI-8601 Don't treat newarray as dead code

Otherwise we lose the side effect of a `NegativeArraySizeException`.
SI-8601 Test that `null.synchronized` NPEs under -optimize

As part of my sweep through the side-effecting byte code instructions.
SI-8601 Test that static LOAD_FIELD is not eliminated

This test fails under 2.11.0, and works now that DCE treats
static loads as useful instructions.
Merge pull request #3765 from retronym/ticket/8601

Reining on over eager optimizations (take 2)