Maybe the middle end should only have one pointer type, but with at least two attributes, one to tell the debugger to auto-dereference, one to mark those pointers that cannot point to null. This might enable more optimization.
That would certainly be my recommendation. It would also get rid of the TYPE_REFERENCE_TO field in types, which would save space. We originally had at most one POINTER_TYPE and at most one REFERENCE_TYPE pointing at each type. But that changed with code (partly mine) that allowed for a sort of "variant" of pointers, so that they could have a different mode and a "deref aliases all" flag. Added the suggested flags would just be an extension of this, would eliminate the question of "what's the difference between POINTER_TYPE and REFERENCE_TYPE" once and for all, and would simplify some code. Because build_reference_type would still exist, front end changes would be minimized.