]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - opencl/llvm.git/commitdiff
LiveIntervalAnalysis: Mark subregister defs as undef when we determined they are...
authorMatthias Braun <matze@braunis.de>
Wed, 21 Jan 2015 22:55:13 +0000 (22:55 +0000)
committerMatthias Braun <matze@braunis.de>
Wed, 21 Jan 2015 22:55:13 +0000 (22:55 +0000)
This was not necessary before as this case can only be detected when the
liveness analysis is at subregister level.

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

include/llvm/CodeGen/MachineInstr.h
lib/CodeGen/LiveIntervalAnalysis.cpp
lib/CodeGen/MachineInstr.cpp

index bcf1f5caaa8c6c3c5c3c8850dd3791ca5059c0ac..945ee0f5d734e004c06a549ca620afff22c04ca8 100644 (file)
@@ -1048,6 +1048,11 @@ public:
   bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo,
                        bool AddIfNotFound = false);
 
+  /// Mark all subregister defs of register @p Reg with the undef flag.
+  /// This function is used when we determined to have a subregister def in an
+  /// otherwise undefined super register.
+  void addRegisterDefReadUndef(unsigned Reg);
+
   /// addRegisterDefined - We have determined MI defines a register. Make sure
   /// there is an operand defining Reg.
   void addRegisterDefined(unsigned Reg,
index c03773f80370bb8f6261c98926bba48764764ca7..16b30ff2c2958ff52a7a43074bd49ad2125b6234 100644 (file)
@@ -448,23 +448,34 @@ bool LiveIntervals::computeDeadValues(LiveInterval &LI,
   for (auto VNI : LI.valnos) {
     if (VNI->isUnused())
       continue;
-    LiveRange::iterator I = LI.FindSegmentContaining(VNI->def);
+    SlotIndex Def = VNI->def;
+    LiveRange::iterator I = LI.FindSegmentContaining(Def);
     assert(I != LI.end() && "Missing segment for VNI");
-    if (I->end != VNI->def.getDeadSlot())
+
+    // Is the register live before? Otherwise we may have to add a read-undef
+    // flag for subregister defs.
+    if (MRI->tracksSubRegLiveness()) {
+      if ((I == LI.begin() || std::prev(I)->end < Def) && !VNI->isPHIDef()) {
+        MachineInstr *MI = getInstructionFromIndex(Def);
+        MI->addRegisterDefReadUndef(LI.reg);
+      }
+    }
+
+    if (I->end != Def.getDeadSlot())
       continue;
     if (VNI->isPHIDef()) {
       // This is a dead PHI. Remove it.
       VNI->markUnused();
       LI.removeSegment(I);
-      DEBUG(dbgs() << "Dead PHI at " << VNI->def << " may separate interval\n");
+      DEBUG(dbgs() << "Dead PHI at " << Def << " may separate interval\n");
       PHIRemoved = true;
     } else {
       // This is a dead def. Make sure the instruction knows.
-      MachineInstr *MI = getInstructionFromIndex(VNI->def);
+      MachineInstr *MI = getInstructionFromIndex(Def);
       assert(MI && "No instruction defining live value");
       MI->addRegisterDead(LI.reg, TRI);
       if (dead && MI->allDefsAreDead()) {
-        DEBUG(dbgs() << "All defs dead: " << VNI->def << '\t' << *MI);
+        DEBUG(dbgs() << "All defs dead: " << Def << '\t' << *MI);
         dead->push_back(MI);
       }
     }
index 968ec2c68e8c9df50865c7f455d401c22efdd26d..470d6cbdb0546b62a706c7c349464fee385c6f49 100644 (file)
@@ -1889,6 +1889,14 @@ bool MachineInstr::addRegisterDead(unsigned Reg,
   return true;
 }
 
+void MachineInstr::addRegisterDefReadUndef(unsigned Reg) {
+  for (MachineOperand &MO : operands()) {
+    if (!MO.isReg() || !MO.isDef() || MO.getReg() != Reg || MO.getSubReg() == 0)
+      continue;
+    MO.setIsUndef();
+  }
+}
+
 void MachineInstr::addRegisterDefined(unsigned Reg,
                                       const TargetRegisterInfo *RegInfo) {
   if (TargetRegisterInfo::isPhysicalRegister(Reg)) {