SmallPtrSetImpl<Value *> &Visited,
MemoryAccess *MemAccess, Instruction *OrigInst,
BasicBlock *PredBB);
-
- bool OpIsSafeForPHIOfOps(Value *Op, Instruction *OrigInst,
- const BasicBlock *PHIBlock,
+ bool OpIsSafeForPHIOfOpsHelper(Value *V, const BasicBlock *PHIBlock,
+ SmallPtrSetImpl<const Value *> &Visited,
+ SmallVectorImpl<Instruction *> &Worklist);
+ bool OpIsSafeForPHIOfOps(Value *Op, const BasicBlock *PHIBlock,
SmallPtrSetImpl<const Value *> &);
void addPhiOfOps(PHINode *Op, BasicBlock *BB, Instruction *ExistingValue);
void removePhiOfOps(Instruction *I, PHINode *PHITemp);
isa<LoadInst>(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<const Value *> &Visited) {
+bool NewGVN::OpIsSafeForPHIOfOpsHelper(
+ Value *V, const BasicBlock *PHIBlock,
+ SmallPtrSetImpl<const Value *> &Visited,
+ SmallVectorImpl<Instruction *> &Worklist) {
+
if (!isa<Instruction>(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;
return false;
}
- SmallVector<Instruction *, 4> Worklist;
auto *OrigI = cast<Instruction>(V);
for (auto *Op : OrigI->operand_values()) {
if (!isa<Instruction>(Op))
}
continue;
}
+ if (!Visited.insert(Op).second)
+ continue;
Worklist.push_back(cast<Instruction>(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<const Value *> &Visited) {
+ SmallVector<Instruction *, 4> 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<PHINode>(I) && getBlockForValue(I) == PHIBlock) {
- OpSafeForPHIOfOps.insert({I, false});
- OpSafeForPHIOfOps.insert({V, false});
+ if (!OpIsSafeForPHIOfOpsHelper(I, PHIBlock, Visited, Worklist))
return false;
- }
- for (auto *Op : cast<Instruction>(I)->operand_values()) {
- if (!isa<Instruction>(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<Instruction>(Op));
- }
}
OpSafeForPHIOfOps.insert({V, true});
return true;
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