I added a simple guard elimination pass to the compiler. This should be done very late in the pipeline, since it benefits from load elimination (which we don’t do yet but will do soon). Currently I only eliminate redundant null guards that point directly to an object allocation. Since we are in SSA, and in particular once we do load elimination, this should catch all redundant null checks on locally allocated objects.
The other common case we should optimize for are null checks on the this pointer. This should be pretty straight forward to detect. The this pointer is in context slot 0. In case of inlined method calls the this pointer will be passed in as argument, but since we are in SSA and do copy propagation the direct link to slot 0 in the anchor context will be visible even for such inlined uses of the this pointer.
As a little side note I would like to mention that our null check guards store the object in operand1, and the null constant in operand0. This results from the way we record JVML if statements that have only one operand and check against null. In this case we push a null constant onto the stack and then record it as guard with two operands, which then in turn causes the constant to end up in the left operand. Just a little detail to keep in mind.
I will add some code to the arithmetic optimizer to swap the operands such that the constant is always on the right side. We already to this for arithmetic expressions.