Several reasons. First, emacs has grown over time. Thousands of people have contributed, and not all of the code is of identical quality. Like all things which grow over time, the final shape was not planned out in detail from the beginning.
Second, emacs is more than a little bit influenced by image-based systems such as the Lisp Machine, Smalltalk, etc. In these systems, there is no separation between typing out a function into a source file and defining that function for immediate use. In these systems you might save a set of functions to a file in order to send them to someone else, but that file isn't needed for the functions you've defined to exist, even through a shutdown and reboot of the machine. Emacs does however live on systems that don't work that way, so it does have canonical source files. Once you've loaded a source file, however, you can call the functions they contain without reference to where they came from. To a first approximation you could rename all of the files to randomized names and emacs wouldn't care.
On the other hand, not all files are actually loaded all of the time. If you don't use feature X, then the source files for feature X don't get loaded. If you did mangle all of the file names, then loading optional features would often fail unless you knew the new filenames.
The result is that once it's running emacs doesn't care much about how functions are organized into files, but it is frequently necessary to know that filename in order to load the stuff you need. One makes reorganizing things easier, the other makes it harder.
On the other hand, it's not quite so dire as that. These days we mostly require
packages, rather than load
specific files. That makes refactoring them easier again! Maybe we just need people to dive in an propose patches.
To address your specific questions about subr.el, I don't think that it's part of any package. It literally is just a collection of functions that always need to be available. Moving them around shouldn't be hard at all. There are probably some details of the early-stage loading process that need to be kept in mind (gotta define things before you use them, for instance), but otherwise it should be pretty straight-forward.