Rework dead block removal using the algorithm from Muchnick (Fig 18.1). [reviewed by lydia]

Our existing algorithm would fail to remove unreachable loops containing 2 or
more blocks.  The Muchnick algorithm will remove all unreachable blocks.  As a
slight improvement on the basic algorithm, it was observed that one pass will
always suffice.  Unreachable block elimination does not have to be iterated
within itself.  (Iteration in combination with other optimizations may still be
profitable, however.)

Also, we skip the removal of DefExprs when deleting the contents of a block.  In
some cases, a variable whose declaration appeared in a dead block was used later
in a block that was not eliminated.  This may not still be true, but removing
the declarations in a separate passe (deadVariableElimination) contains a
verification that all uses of a variable are gone before its declaration is
eliminated.

[tested on std]


git-svn-id: http://svn.code.sf.net/p/chapel/code/trunk@21849 3a8e244f-b0f2-452b-bcba-4c88e055c3ca