This PR implements the last piece to make CIR catch up upstream CodeGen on dynamic_cast support. It ports an upstream optimization "exact cast" to CIR.
The basic idea of exact cast is when dynamic_cast to a final class, we don't have to call into the runtime -- we could just check if the dynamic type of the source object is exactly the destination type by quickly comparing the vtable pointers. To give a concrete example of this optimization:
struct Base { virtual ~Base(); };
struct Derived final : Base {};
Derived *test(Base *src) { return dynamic_cast<Derived *>(src); }
Without the optimization, we have to call the runtime function __dynamic_cast to do the heavy and slow type check. After enabling the optimization, we could quickly carry out the runtime type check by inline checking whether the vtable ptr of src points to the vtable of Derived.
This PR also fixes a bug in existing dynamic_cast CIRGen code. The bug mistakenly removes the insertion point after emitting a call to bad_cast, causing the CIRGen of any follow up statements to crash.
This PR implements the last piece to make CIR catch up upstream CodeGen on
dynamic_cast
support. It ports an upstream optimization "exact cast" to CIR.The basic idea of exact cast is when
dynamic_cast
to a final class, we don't have to call into the runtime -- we could just check if the dynamic type of the source object is exactly the destination type by quickly comparing the vtable pointers. To give a concrete example of this optimization:Without the optimization, we have to call the runtime function
__dynamic_cast
to do the heavy and slow type check. After enabling the optimization, we could quickly carry out the runtime type check by inline checking whether the vtable ptr ofsrc
points to the vtable ofDerived
.This PR also fixes a bug in existing dynamic_cast CIRGen code. The bug mistakenly removes the insertion point after emitting a call to bad_cast, causing the CIRGen of any follow up statements to crash.