diff options
| author | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-10-05 00:01:48 +0000 |
|---|---|---|
| committer | Jakob Stoklund Olesen <stoklund@2pi.dk> | 2011-10-05 00:01:48 +0000 |
| commit | d5d39bb098b548ee371c6a6281ba7363763b26af (patch) | |
| tree | fc547bcd36a2045e6bc3866b6a246fa9bbcbf37c /llvm/lib/CodeGen | |
| parent | 9d5bda9be150500db82055e8aeb20efc0c235425 (diff) | |
| download | bcm5719-llvm-d5d39bb098b548ee371c6a6281ba7363763b26af.tar.gz bcm5719-llvm-d5d39bb098b548ee371c6a6281ba7363763b26af.zip | |
Also add <imp-use,kill> flags for redefined super-registers.
For example:
%vreg10:dsub_0<def,undef> = COPY %vreg1
%vreg10:dsub_1<def> = COPY %vreg2
is rewritten as:
%D2<def> = COPY %D0, %Q1<imp-def>
%D3<def> = COPY %D1, %Q1<imp-use,kill>, %Q1<imp-def>
The first COPY doesn't care about the previous value of %Q1, so it
doesn't read that register.
The second COPY is a partial redefinition of %Q1, so it implicitly kills
and redefines that register.
This makes it possible to recognize instructions that can harmlessly
clobber the full super-register. The write and don't read the
super-register.
llvm-svn: 141139
Diffstat (limited to 'llvm/lib/CodeGen')
| -rw-r--r-- | llvm/lib/CodeGen/VirtRegMap.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp index e9f89c5b4b4..8a1cdc01c49 100644 --- a/llvm/lib/CodeGen/VirtRegMap.cpp +++ b/llvm/lib/CodeGen/VirtRegMap.cpp @@ -285,14 +285,24 @@ void VirtRegMap::rewrite(SlotIndexes *Indexes) { // Preserve semantics of sub-register operands. if (MO.getSubReg()) { // A virtual register kill refers to the whole register, so we may - // have to add <imp-use,kill> operands for the super-register. - if (MO.isUse()) { - if (MO.isKill() && !MO.isUndef()) - SuperKills.push_back(PhysReg); - } else if (MO.isDead()) - SuperDeads.push_back(PhysReg); - else - SuperDefs.push_back(PhysReg); + // have to add <imp-use,kill> operands for the super-register. A + // partial redef always kills and redefines the super-register. + if (MO.readsReg() && (MO.isDef() || MO.isKill())) + SuperKills.push_back(PhysReg); + + if (MO.isDef()) { + // The <def,undef> flag only makes sense for sub-register defs, and + // we are substituting a full physreg. An <imp-use,kill> operand + // from the SuperKills list will represent the partial read of the + // super-register. + MO.setIsUndef(false); + + // Also add implicit defs for the super-register. + if (MO.isDead()) + SuperDeads.push_back(PhysReg); + else + SuperDefs.push_back(PhysReg); + } // PhysReg operands cannot have subregister indexes. PhysReg = TRI->getSubReg(PhysReg, MO.getSubReg()); |

