1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-23 21:13:02 +02:00
llvm-mirror/test/CodeGen/X86/machine-copy-prop.mir
Derek Schuff 9f833b6097 Introduce MachineFunctionProperties and the AllVRegsAllocated property
MachineFunctionProperties represents a set of properties that a MachineFunction
can have at particular points in time. Existing examples of this idea are
MachineRegisterInfo::isSSA() and MachineRegisterInfo::tracksLiveness() which
will eventually be switched to use this mechanism.
This change introduces the AllVRegsAllocated property; i.e. the property that
all virtual registers have been allocated and there are no VReg operands
left.

With this mechanism, passes can declare that they require a particular property
to be set, or that they set or clear properties by implementing e.g.
MachineFunctionPass::getRequiredProperties(). The MachineFunctionPass base class
verifies that the requirements are met, and handles the setting and clearing
based on the delcarations. Passes can also directly query and update the current
properties of the MF if they want to have conditional behavior.

This change annotates the target-independent post-regalloc passes; future
changes will also annotate target-specific ones.

Reviewers: qcolombet, hfinkel

Differential Revision: http://reviews.llvm.org/D18421

llvm-svn: 264593
2016-03-28 17:05:30 +00:00

228 lines
6.4 KiB
YAML

# RUN: llc -march=x86 -run-pass machine-cp -verify-machineinstrs -o /dev/null %s 2>&1 | FileCheck %s
--- |
declare void @foo()
define void @copyprop_remove_kill0() { ret void }
define void @copyprop_remove_kill1() { ret void }
define void @copyprop_remove_kill2() { ret void }
define void @copyprop0() { ret void }
define void @copyprop1() { ret void }
define void @copyprop2() { ret void }
define void @nocopyprop0() { ret void }
define void @nocopyprop1() { ret void }
define void @nocopyprop2() { ret void }
define void @nocopyprop3() { ret void }
define void @nocopyprop4() { ret void }
define void @nocopyprop5() { ret void }
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill0
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rdi
# CHECK-NEXT: NOOP implicit %rdi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop_remove_kill0
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rdi
NOOP implicit killed %rdi
%rdi = COPY %rax
NOOP implicit %rax, implicit %rdi
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill1
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rdi
# CHECK-NEXT: NOOP implicit %edi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop_remove_kill1
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rdi
NOOP implicit killed %edi
%rdi = COPY %rax
NOOP implicit %rax, implicit %rdi
...
---
# The second copy is redundant and will be removed, check that we also remove
# the kill flag of intermediate instructions.
# CHECK-LABEL: name: copyprop_remove_kill2
# CHECK: bb.0:
# CHECK-NEXT: %ax = COPY %di
# CHECK-NEXT: NOOP implicit %rdi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop_remove_kill2
allVRegsAllocated: true
body: |
bb.0:
%ax = COPY %di
NOOP implicit killed %rdi
%di = COPY %ax
NOOP implicit %rax, implicit %rdi
...
---
# The second copy is redundant; the call preserves the source and dest register.
# CHECK-LABEL: name: copyprop0
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rdi
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
# CHECK-NEXT: NOOP implicit %edi
# CHECK-NOT: COPY
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop0
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rdi
CALL64pcrel32 @foo, csr_64_rt_mostregs
NOOP implicit killed %edi
%rdi = COPY %rax
NOOP implicit %rax, implicit %rdi
...
---
# The 2nd copy is redundant; The call preserves the source and dest register.
# CHECK-LABEL: name: copyprop1
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rdi
# CHECK-NEXT: NOOP implicit %rax
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop1
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rdi
NOOP implicit killed %rax
%rax = COPY %rdi
NOOP implicit %rax, implicit %rdi
...
---
# CHECK-LABEL: name: copyprop2
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rdi
# CHECK-NEXT: NOOP implicit %ax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64_rt_mostregs
# CHECK-NOT: %rax = COPY %rdi
# CHECK-NEXT: NOOP implicit %rax, implicit %rdi
name: copyprop2
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rdi
NOOP implicit killed %ax
CALL64pcrel32 @foo, csr_64_rt_mostregs
%rax = COPY %rdi
NOOP implicit %rax, implicit %rdi
...
---
# The second copy is not redundant if the source register (%rax) is clobbered
# even if the dest (%rbp) is not.
# CHECK-LABEL: name: nocopyprop0
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rbp
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
# CHECK-NEXT: %rbp = COPY %rax
# CHECK-NEXT: NOOP implicit %rax, implicit %rbp
name: nocopyprop0
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rbp
CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
%rbp = COPY %rax
NOOP implicit %rax, implicit %rbp
...
---
# The second copy is not redundant if the dest register (%rax) is clobbered
# even if the source (%rbp) is not.
# CHECK-LABEL: name: nocopyprop1
# CHECK: bb.0:
# CHECK-NEXT: %rbp = COPY %rax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
# CHECK-NEXT: %rax = COPY %rbp
# CHECK-NEXT: NOOP implicit %rax, implicit %rbp
name: nocopyprop1
allVRegsAllocated: true
body: |
bb.0:
%rbp = COPY %rax
CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
%rax = COPY %rbp
NOOP implicit %rax, implicit %rbp
...
---
# The second copy is not redundant if the source register (%rax) is clobbered
# even if the dest (%rbp) is not.
# CHECK-LABEL: name: nocopyprop2
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rbp
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
# CHECK-NEXT: %rax = COPY %rbp
# CHECK-NEXT: NOOP implicit %rax, implicit %rbp
name: nocopyprop2
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rbp
CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
%rax = COPY %rbp
NOOP implicit %rax, implicit %rbp
...
---
# The second copy is not redundant if the dest register (%rax) is clobbered
# even if the source (%rbp) is not.
# CHECK-LABEL: name: nocopyprop3
# CHECK: bb.0:
# CHECK-NEXT: %rbp = COPY %rax
# CHECK-NEXT: CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
# CHECK-NEXT: %rbp = COPY %rax
# CHECK-NEXT: NOOP implicit %rax, implicit %rbp
name: nocopyprop3
allVRegsAllocated: true
body: |
bb.0:
%rbp = COPY %rax
CALL64pcrel32 @foo, csr_64, implicit %rax, implicit %rbp
%rbp = COPY %rax
NOOP implicit %rax, implicit %rbp
...
---
# A reserved register may change its value so the 2nd copy is not redundant.
# CHECK-LABEL: name: nocopyprop4
# CHECK: bb.0:
# CHECK-NEXT: %rax = COPY %rip
# CHECK-NEXT: NOOP implicit %rax
# CHECK-NEXT: %rax = COPY %rip
# CHECK-NEXT: NOOP implicit %rax
name: nocopyprop4
allVRegsAllocated: true
body: |
bb.0:
%rax = COPY %rip
NOOP implicit %rax
%rax = COPY %rip
NOOP implicit %rax
...
---
# Writing to a reserved register may have additional effects (slightly illegal
# testcase because writing to %rip like this should make the instruction a jump)
# CHECK-LABEL: name: nocopyprop5
# CHECK: bb.0:
# CHECK-NEXT: %rip = COPY %rax
# CHECK-NEXT: %rip = COPY %rax
name: nocopyprop5
allVRegsAllocated: true
body: |
bb.0:
%rip = COPY %rax
%rip = COPY %rax
...