Simplify header analysis/reasoning by splitting core_io.h into the expected core_read.h/core_write.h (matching core_read.cpp/core_write.cpp).
As noted by MarcoFalke in the review of #16129:
For some reason core_io is the header file for both core_read and core_write...
Also noted by sipa when writing extra code to handle this specific case in contrib/devtools/circular-dependencies.py:
This change makes automated header analysis easier. Also humans will benefit: especially future generations of contributors who joins us with the expectation of normal header naming :-)