aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/llvm/CodeGen/FunctionLoweringInfo.h21
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp19
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();