The INLINEASM_BR instruction's a terminator, and the code generator
doesn't allow non-terminator instructions after a terminator. This is an
issue when an INLINEASM_BR defines a physical register. We can't place
the copies of the physical registers into virtual registers in the
fallthrough block because physical registers can't be marked as
"live-in" until after register allocation.
To get around this issue, we introduce a new pseudo-instruction, TCOPY,
that's identical to the COPY instruction, but is a terminator. With it
we're able to copy the physical registers to virtual registers without
needing to place the copies in a fallthrough block:
bb.1: INLINEASM_BR &"" ..., implicit-def $esi, $1:[regdef],... %9:gr32 = TCOPY $esi bb.2: ; predecessors: %bb.1 successors: %bb.3(0x80000000); %bb.3(100.00%) %0:gr32 = COPY %9:gr32 JMP_1 %bb.3
The TCOPY is converted to a normal COPY after register allocation, when
we have live variable information and live-ins are allowed on basic
blocks.
The fast register allocator behaves a bit differently because everything
is spilled before the end of a basic block. Therefore, we allow a store
of a physical register after the INLINEASM_BR when optimizations are
disabled.
Does this save a few getOpcode() calls? The rest of this CL explicitly compares the opcode against COPY_BR? I just worry if this might mess up existing callsites of isCopy when getOpcode() == TargetOpcode::COPY_BR;.