Add a mechanism for invalidating the LiveOutInfo of a PHI, and use it whenever
authorCameron Zwarich <zwarich@apple.com>
Thu, 24 Feb 2011 10:00:16 +0000 (10:00 +0000)
committerCameron Zwarich <zwarich@apple.com>
Thu, 24 Feb 2011 10:00:16 +0000 (10:00 +0000)
a block is visited before all of its predecessors.

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

include/llvm/CodeGen/FunctionLoweringInfo.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp

index 8b1c852e4f2674ff630640a4bb7e0c0767354dde..2d44a8beed4a2afe46fa7650ea33e5c229779a79 100644 (file)
@@ -101,9 +101,11 @@ public:
 #endif
 
   struct LiveOutInfo {
-    unsigned NumSignBits;
+    unsigned NumSignBits : 31;
+    bool IsValid : 1;
     APInt KnownOne, KnownZero;
-    LiveOutInfo() : NumSignBits(0), KnownOne(1, 0), KnownZero(1, 0) {}
+    LiveOutInfo() : NumSignBits(0), IsValid(true), KnownOne(1, 0),
+                    KnownZero(1, 0) {}
   };
 
   /// VisitedBBs - The set of basic blocks visited thus far by instruction
@@ -149,7 +151,12 @@ public:
   const LiveOutInfo *GetLiveOutRegInfo(unsigned Reg) {
     if (!LiveOutRegInfo.inBounds(Reg))
       return NULL;
-    return &LiveOutRegInfo[Reg];
+
+    const LiveOutInfo *LOI = &LiveOutRegInfo[Reg];
+    if (!LOI->IsValid)
+      return NULL;
+
+    return LOI;
   }
 
   /// AddLiveOutRegInfo - Adds LiveOutInfo for a register.
@@ -166,6 +173,14 @@ public:
     LOI.KnownZero = KnownZero;
   }
 
+  /// InvalidatePHILiveOutRegInfo - Invalidates a PHI's LiveOutInfo, to be
+  /// called when a block is visited before all of its predecessors.
+  void InvalidatePHILiveOutRegInfo(const PHINode *PN) {
+    unsigned Reg = ValueMap[PN];
+    LiveOutRegInfo.grow(Reg);
+    LiveOutRegInfo[Reg].IsValid = false;
+  }
+
   /// setByValArgumentFrameIndex - Record frame index for the byval
   /// argument.
   void setByValArgumentFrameIndex(const Argument *A, int FI);
index 9d3f5bc7e3bcc9879960a4e0a52791f4288a5c75..d540063083523a3e63cca7c1d92d3707df48e9f3 100644 (file)
@@ -832,8 +832,25 @@ void SelectionDAGISel::SelectAllBasicBlocks(const Function &Fn) {
     CheckLineNumbers(LLVMBB);
 #endif
 
-    if (OptLevel != CodeGenOpt::None)
+    if (OptLevel != CodeGenOpt::None) {
+      bool AllPredsVisited = true;
+      for (const_pred_iterator PI = pred_begin(LLVMBB), PE = pred_end(LLVMBB);
+           PI != PE; ++PI) {
+        if (!FuncInfo->VisitedBBs.count(*PI)) {
+          AllPredsVisited = false;
+          break;
+        }
+      }
+
+      if (!AllPredsVisited) {
+        for (BasicBlock::const_iterator I = LLVMBB->begin(), E = LLVMBB->end();
+             I != E && isa<PHINode>(I); ++I) {
+          FuncInfo->InvalidatePHILiveOutRegInfo(cast<PHINode>(I));
+        }
+      }
+
       FuncInfo->VisitedBBs.insert(LLVMBB);
+    }
 
     FuncInfo->MBB = FuncInfo->MBBMap[LLVMBB];
     FuncInfo->InsertPt = FuncInfo->MBB->getFirstNonPHI();