From 9d89f00c5e6b00b452a5aebf78c1c8ddc3f917bd Mon Sep 17 00:00:00 2001 From: Daniel Berlin Date: Fri, 6 Oct 2017 01:33:06 +0000 Subject: [PATCH] NewGVN: Factor out duplicate parts of OpIsSafeForPHIOfOps git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315040 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/NewGVN.cpp | 76 +++++++++++++------------------- 1 file changed, 31 insertions(+), 45 deletions(-) diff --git a/lib/Transforms/Scalar/NewGVN.cpp b/lib/Transforms/Scalar/NewGVN.cpp index 8eb60194c29..2d909e9c729 100644 --- a/lib/Transforms/Scalar/NewGVN.cpp +++ b/lib/Transforms/Scalar/NewGVN.cpp @@ -640,9 +640,10 @@ private: SmallPtrSetImpl &Visited, MemoryAccess *MemAccess, Instruction *OrigInst, BasicBlock *PredBB); - - bool OpIsSafeForPHIOfOps(Value *Op, Instruction *OrigInst, - const BasicBlock *PHIBlock, + bool OpIsSafeForPHIOfOpsHelper(Value *V, const BasicBlock *PHIBlock, + SmallPtrSetImpl &Visited, + SmallVectorImpl &Worklist); + bool OpIsSafeForPHIOfOps(Value *Op, const BasicBlock *PHIBlock, SmallPtrSetImpl &); void addPhiOfOps(PHINode *Op, BasicBlock *BB, Instruction *ExistingValue); void removePhiOfOps(Instruction *I, PHINode *PHITemp); @@ -2505,22 +2506,19 @@ static bool okayForPHIOfOps(const Instruction *I) { isa(I); } -// Return true if this operand will be safe to use for phi of ops. -// -// The reason some operands are unsafe is that we are not trying to recursively -// translate everything back through phi nodes. We actually expect some lookups -// of expressions to fail. In particular, a lookup where the expression cannot -// exist in the predecessor. This is true even if the expression, as shown, can -// be determined to be constant. -bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst, - const BasicBlock *PHIBlock, - SmallPtrSetImpl &Visited) { +bool NewGVN::OpIsSafeForPHIOfOpsHelper( + Value *V, const BasicBlock *PHIBlock, + SmallPtrSetImpl &Visited, + SmallVectorImpl &Worklist) { + if (!isa(V)) return true; auto OISIt = OpSafeForPHIOfOps.find(V); if (OISIt != OpSafeForPHIOfOps.end()) return OISIt->second; + // Keep walking until we either dominate the phi block, or hit a phi, or run + // out of things to check. if (DT->properlyDominates(getBlockForValue(V), PHIBlock)) { OpSafeForPHIOfOps.insert({V, true}); return true; @@ -2531,7 +2529,6 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst, return false; } - SmallVector Worklist; auto *OrigI = cast(V); for (auto *Op : OrigI->operand_values()) { if (!isa(Op)) @@ -2545,40 +2542,29 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst, } continue; } + if (!Visited.insert(Op).second) + continue; Worklist.push_back(cast(Op)); } + return true; +} +// Return true if this operand will be safe to use for phi of ops. +// +// The reason some operands are unsafe is that we are not trying to recursively +// translate everything back through phi nodes. We actually expect some lookups +// of expressions to fail. In particular, a lookup where the expression cannot +// exist in the predecessor. This is true even if the expression, as shown, can +// be determined to be constant. +bool NewGVN::OpIsSafeForPHIOfOps(Value *V, const BasicBlock *PHIBlock, + SmallPtrSetImpl &Visited) { + SmallVector Worklist; + if (!OpIsSafeForPHIOfOpsHelper(V, PHIBlock, Visited, Worklist)) + return false; while (!Worklist.empty()) { auto *I = Worklist.pop_back_val(); - // Keep walking until we either dominate the phi block, or hit a phi, or run - // out of things to check. - // - if (DT->properlyDominates(getBlockForValue(I), PHIBlock)) { - OpSafeForPHIOfOps.insert({I, true}); - continue; - } - // PHI in the same block. - if (isa(I) && getBlockForValue(I) == PHIBlock) { - OpSafeForPHIOfOps.insert({I, false}); - OpSafeForPHIOfOps.insert({V, false}); + if (!OpIsSafeForPHIOfOpsHelper(I, PHIBlock, Visited, Worklist)) return false; - } - for (auto *Op : cast(I)->operand_values()) { - if (!isa(Op)) - continue; - // See if we already know the answer for this node. - auto OISIt = OpSafeForPHIOfOps.find(Op); - if (OISIt != OpSafeForPHIOfOps.end()) { - if (!OISIt->second) { - OpSafeForPHIOfOps.insert({V, false}); - return false; - } - continue; - } - if (!Visited.insert(Op).second) - continue; - Worklist.push_back(cast(Op)); - } } OpSafeForPHIOfOps.insert({V, true}); return true; @@ -2697,9 +2683,9 @@ NewGVN::makePossiblePHIOfOps(Instruction *I, Op = ValuePHI->getIncomingValue(PredNum); } // If we phi-translated the op, it must be safe. - SafeForPHIOfOps = SafeForPHIOfOps && - (Op != OrigOp || - OpIsSafeForPHIOfOps(Op, I, PHIBlock, VisitedOps)); + SafeForPHIOfOps = + SafeForPHIOfOps && + (Op != OrigOp || OpIsSafeForPHIOfOps(Op, PHIBlock, VisitedOps)); } // FIXME: For those things that are not safe we could generate // expressions all the way down, and see if this comes out to a -- 2.40.0