diff options
-rw-r--r-- | include/llvm/CodeGen/FunctionLoweringInfo.h | 21 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 19 |
2 files changed, 36 insertions, 4 deletions
diff --git a/include/llvm/CodeGen/FunctionLoweringInfo.h b/include/llvm/CodeGen/FunctionLoweringInfo.h index 8b1c852..2d44a8b 100644 --- a/include/llvm/CodeGen/FunctionLoweringInfo.h +++ b/include/llvm/CodeGen/FunctionLoweringInfo.h @@ -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); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 9d3f5bc..d540063 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -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(); |