For qcc progs, relocs may not be necessary (due to lack of structs, arrays, and pointers). ie, the globals read by instructions can never change (entity fields don't count as globals and don't matter anyway), and every global accessed does have a def associated with it (even vector_z).
However, qfcc is a little different:
The def for vector_z is not necessarily written to the progs.
qfcc supports structs, arrays and pointers. While it's possible to create defs for every member, this loses the ability to have data structs higher than 64k.
The code for patching relocs is cleaner than that for using the instructions directly (and thus easier to maintain, possibly faster too).
Yes, relocs take a chunk (16 bytes each), but they allow a lot of flexibility. And there's always gzip
qc progs
is native code, just nobody has built a cpu that uses it. I once asked a cpu designer (unfortunately, I don't remember his name right now) about the feasibility of making a qc cpu and his answer was something like "very feasible". I don't know if anybody else has noticed, but GLSL feels a lot like a cleaned up QuakeC.