Mill code is member-dependent at the encoded bit level. In fact, it is even slot-dependent: the exact same add operation encodes differently if it is the first, second, or Nth operation in an instruction (usually, anyway, depending on what operations are supported in the different slots). Because operations that are not present cannot be encoded, the Mill encoding is very dense and compact,
However, Mill code is member-independent at the load-module level. Compiler output does express an abstract form of the program, just as you suggest. That abstract code is then specialized to the concrete binary of the actual Mill member, and the specialized code is than cached back into the load module so that specialization only need be done once per different Mill that will run on.
Typically code is specialized at install-time, although it may be done at load time or (to build ROMs and a few other purposes) as a manual command. Specialization is very fast, because its job is roughly what is done in the backend of a conventional compiler. A few other tools that work with concrete binaries also are bit-level Mill dependent (a debugger for example) so we’ve put the concrete-to-abstract and abstract-to-concrete conversion functions in a library for application use if desired.