Specifying / modeling copying semantics in more detail

Dear All,

I’ve had a lot of progress on my 6502 family target, but I’ve hit a bit of a stumbling block wherein some passes inadvertently cause malformed final instruction listings. It’s not necessarily llvm’s fault, though. An example:

%a = COPY %w04
asl_a_16_once %a, %n_flag<imp-def,dead>, %z_flag<imp-def,dead>, %c_flag, %a<imp-use,kill>
%w02 = COPY %a
%w00 = COPY %w06
%w00<def,tied1> = rol_dp_16_once %w00<kill,tied0>, %n_flag<imp-def,dead>, %z_flag<imp-def,dead>, %c_flag<imp-def,dead>, %c_flag<imp-use,kill>
%a = COPY %w02

The MachineCopyPropagation pass eliminates the copy to %w02 on the third line because it thinks that %w00 and %w06 can be copied directly. This ends up with the A register being clobbered in the final listing by the store from %w06 to %w00. %w00 through %w1f form a register class (called dp16) of memory locations that while they are not really registers, can be used as such in a lot of situations. However, they are not directly copyable. They require a move to a hardware register and then a store to another dp16 register. Example:

lda %w06

sta %w00

-or-

ldx %w06

stx %w00

-or-

ldy %w06
sty %w06

In short, the A, X, and Y registers are the only practical conduit through which one can copy dp16 “registers”. One possible fix to the machine instruction listing would be to put the copy from %w06 to %w00 above the first three lines, thus allowing the value in A to not get clobbered. Another would be to custom expand COPY instructions and take note of which physical registers are in use (in this case use X or Y as the copying conduit). But at the core of the problem is that I’m not sure if the dp16 registers should really form a register class if it’s going to produce these kinds of situations. I’m often wondering what exactly the implications of forming a register class are. Here it seems to be that register classes are directly copyable, but there might be more connotations to it. I don’t see how to model that these registers are not directly copyable, and need an intermediate register (A, X, or Y as mentioned above). Note: [A, X, Y] are directly copyable among one another. Is there anyway to intercept deletions and additions of COPY instructions so that they correctly mark Use / Def information. I can’t really do this at the instruction selection step because COPY opcodes can be inserted and deleted by any MachineFunction pass, and at the Post Regalloc Pseudo Expansion pass it’s too late fix this problem. Should I create a new pass to run after Post Regalloc to correct my Machine Functions? That seems like a last ditch effort at fixing the problem though, and I’d rather resolve it through some other means if possible. Any input would be much appreciated.

Thank You,

~Dave Waggoner / MathOnNapkins