VirtRegMap: No implicit defs/uses for super registers with subreg liveness tracking.
authorMatthias Braun <matze@braunis.de>
Wed, 10 Dec 2014 01:13:04 +0000 (01:13 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 10 Dec 2014 01:13:04 +0000 (01:13 +0000)
Adding the implicit defs/uses to the superregisters is semantically questionable
but was not dangerous before as the register allocator never assigned the same
register to two overlapping LiveIntervals even when the actually live
subregisters do not overlap. With subregister liveness tracking enabled this
does actually happen and leads to subsequent bugs if we don't stop adding
the superregister defs/uses.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223892 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/VirtRegMap.cpp

index dde55f9dd48f66757a730b51f7328a37850307af..1e78259731bb4ed4a64c43e2e21ff3a91c16f6b0 100644 (file)
@@ -671,6 +671,30 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
         CancelKill = true;
         break;
       }
+
+      // If an instruction writes to a subregister, a new segment starts in the
+      // LiveInterval. In this case adding Kill-Flags is incorrect if no
+      // super registers defs/uses are appended to the instruction which is
+      // what we do when subregister liveness tracking is enabled.
+      if (MRI->tracksSubRegLiveness()) {
+        // Next segment has to be adjacent in the subregister write case.
+        LiveRange::iterator N = std::next(RI);
+        if (N != LI->end() && N->start == RI->end) {
+          // See if we have a partial write operand
+          bool IsFullWrite = false;
+          for (MachineInstr::const_mop_iterator MOp = MI->operands_begin(),
+               MOpE = MI->operands_end(); MOp != MOpE; ++MOp) {
+            if (MOp->isReg() && !MOp->isDef() && MOp->getReg() == Reg
+                && MOp->getSubReg() == 0) {
+              IsFullWrite = true;
+              break;
+            }
+          }
+          if (!IsFullWrite)
+            CancelKill = true;
+        }
+      }
+
       if (CancelKill)
         MI->clearRegisterKills(Reg, nullptr);
       else
index 0d17d43d972dc69e1cb2ac402906a38367d9b633..3d72d204ac4b011d0d1835122c01d5c124071374 100644 (file)
@@ -266,6 +266,7 @@ void VirtRegRewriter::addMBBLiveIns() {
 }
 
 void VirtRegRewriter::rewrite() {
+  bool NoSubRegLiveness = !MRI->tracksSubRegLiveness();
   SmallVector<unsigned, 8> SuperDeads;
   SmallVector<unsigned, 8> SuperDefs;
   SmallVector<unsigned, 8> SuperKills;
@@ -347,7 +348,8 @@ void VirtRegRewriter::rewrite() {
           // A virtual register kill refers to the whole register, so we may
           // 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()))
+          if (NoSubRegLiveness && MO.readsReg()
+              && (MO.isDef() || MO.isKill()))
             SuperKills.push_back(PhysReg);
 
           if (MO.isDef()) {
@@ -358,10 +360,12 @@ void VirtRegRewriter::rewrite() {
             MO.setIsUndef(false);
 
             // Also add implicit defs for the super-register.
-            if (MO.isDead())
-              SuperDeads.push_back(PhysReg);
-            else
-              SuperDefs.push_back(PhysReg);
+            if (NoSubRegLiveness) {
+              if (MO.isDead())
+                SuperDeads.push_back(PhysReg);
+              else
+                SuperDefs.push_back(PhysReg);
+            }
           }
 
           // PhysReg operands cannot have subregister indexes.