LLvm LiveVariables Pass
Functionality
For virtual register:
If there is not any usage after a definition, then the def will be marked as dead.
If there is not any usage after a usage, then the usage will be marked as killed.
Consider the following machine irs before phi-node-elimination
Function Live Ins: $edi in %4
bb.0.entry:
successors: %bb.2(0x30000000), %bb.1(0x50000000); %bb.2(37.50%), %bb.1(62.50%)
liveins: $edi
%4:gr32 = COPY $edi
%7:gr32 = ADD32ri8 %4:gr32(tied-def 0), 2, implicit-def $eflags
%6:gr32 = MOV32ri 2
CMP32ri8 %6:gr32, 0, implicit-def $eflags
JCC_1 %bb.2, 14, implicit $eflags
bb.1.if.then:
; predecessors: %bb.0
successors: %bb.3(0x80000000); %bb.3(100.00%)
%9:gr32 = MOV32ri 1
%10:gr32 = ADD32ri8 %9:gr32(tied-def 0), 1, implicit-def $eflags
JMP_1 %bb.3
bb.2.if.else:
; predecessors: %bb.0
successors: %bb.3(0x80000000); %bb.3(100.00%)
%8:gr32 = ADD32ri8 %4:gr32(tied-def 0), 2, implicit-def $eflags
bb.3.if.end:
; predecessors: %bb.2, %bb.1
%3:gr32 = PHI %8:gr32, %bb.2, %10:gr32, %bb.1
%16:gr32 = ADD32ri8 %3:gr32(tied-def 0), 1, implicit-def $eflags
%15:gr32 = ADD32rr %16:gr32(tied-def 0), %7:gr32, implicit-def $eflags
%13:gr32 = ADD32ri8 %15:gr32(tied-def 0), 1, implicit-def $eflags
$eax = COPY %13:gr32
RET64 implicit $eax
After phi-node-elimination, the sequence will be
Function Live Ins: $edi in %4
bb.0.entry:
successors: %bb.2(0x30000000), %bb.1(0x50000000); %bb.2(37.50%), %bb.1(62.50%)
liveins: $edi
%4:gr32 = COPY killed $edi
%7:gr32 = ADD32ri8 %4:gr32(tied-def 0), 2, implicit-def dead $eflags
%6:gr32 = MOV32ri 2
CMP32ri8 killed %6:gr32, 0, implicit-def $eflags
JCC_1 %bb.2, 14, implicit killed $eflags
bb.1.if.then:
; predecessors: %bb.0
successors: %bb.3(0x80000000); %bb.3(100.00%)
%9:gr32 = MOV32ri 1
%10:gr32 = ADD32ri8 killed %9:gr32(tied-def 0), 1, implicit-def dead $eflags
JMP_1 %bb.3
bb.2.if.else:
; predecessors: %bb.0
successors: %bb.3(0x80000000); %bb.3(100.00%)
%8:gr32 = ADD32ri8 killed %4:gr32(tied-def 0), 2, implicit-def dead $eflags
bb.3.if.end:
; predecessors: %bb.2, %bb.1
%3:gr32 = PHI %8:gr32, %bb.2, %10:gr32, %bb.1
%16:gr32 = ADD32ri8 killed %3:gr32(tied-def 0), 1, implicit-def dead $eflags
%15:gr32 = ADD32rr killed %16:gr32(tied-def 0), killed %7:gr32, implicit-def dead $eflags
%13:gr32 = ADD32ri8 killed %15:gr32(tied-def 0), 1, implicit-def dead $eflags
$eax = COPY killed %13:gr32
RET64 implicit killed $eax
Consider the control flow path1: bb.0->bb.1->bb.3 and the virtual register %4. Although the source %4 of %7:gr32 = ADD32ri8 %4:gr32(tied-def 0), 2, implicit-def dead $eflags is the last usage when path1 is taken. But it will not be the last usage when path2: bb.0->bb.2->bb.3 is taken, so the %4 at %7:gr32 = ADD32ri8 %4:gr32(tied-def 0), 2, implicit-def dead $eflags will not be marked as killed.