* split the `PassContext` into multiple protocols and structs: `Context`, `MutatingContext`, `FunctionPassContext` and `SimplifyContext`
* change how instruction passes work: implement the `simplify` function in conformance to `SILCombineSimplifyable`
* add a mechanism to add a callback for inserted instructions
Dead-end blocks are blocks from which there is no path to the function exit (`return`, `throw` or unwind).
These are blocks which end with an unreachable instruction and blocks from which all paths end in "unreachable" blocks.
Let's lldb's `po` command not print any "internal" properties of the conforming type.
This is useful if the `description` already contains all the information of a type instance.
These sets are _much_ more efficient than `Set<Value>` and `Set<Instruction>` because they bridge to the efficient `NodeSet`.
Insertions/deletions are just bit operations.