Downcast IR node: utility for dead code elimination

Downcast IR node

I want to propose a new IR node that would make my life MUCH easier while building the dead code eliminator / dead field pruner.

case class Downcast(child: IR, typ: Type) extends IR

where typ is a subtype of child.typ.

Why?

The field pruner / dead code eliminator does a downwards and upwards pass on a BaseIR. The downward pass builds up dependencies and calculates the minimal types required of each child node, and the upstream pass uses these types to rebuild any value IR nodes to change refs / types / eliminate unused code.

This may also let us do better optimizations.

Performance

When we have virtual/physical types, this node should be free – it changes the virtual type of an IR node while keeping the physical type the same.