GenBCode: eliminate unreachable code

The first 4 commits (on MultiChoiceSetting) are reviewed separately in #3939, ignore them here.

Here's some of the changes, but just refer to individual commit messages.

The actual DCE is implemented by the ASM framework. As noted in the commit message, it is slow. I think OK enough if we run it once (which is currently the case. Note that it's enabled even in non-optimized mode). But it will probably be too slow if we apply it multiple times (to clean up after other optimizations). I think we should merge it as-is for now, we can later implement a faster DCE.

I added a new compiler flag `-Yopt` for enabling / disabling optimizations in GenBCode. I think it makes sense for now, we can always decide later how to interpret old flags when the new backend is enabled.

You can now write JUnit tests like:
```
assertSameCode(
  singleMethodInstructions(compiler)("def f: Int = { return 1; 2 }").dropNonOp,
  List(Op(ICONST_1), Op(IRETURN))
```