summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorDaniel Berlin <dberlin@dberlin.org>2017-09-30 23:51:04 +0000
committerDaniel Berlin <dberlin@dberlin.org>2017-09-30 23:51:04 +0000
commitde6958ee85bf6ac582c323e38efbcec9d568f222 (patch)
tree42cd115639dd9a8a20af86a10cbcde0fff319f93 /llvm
parent6ae59c599b7d3a00dbdea6b9eab9e270a49d6b1e (diff)
downloadbcm5719-llvm-de6958ee85bf6ac582c323e38efbcec9d568f222.tar.gz
bcm5719-llvm-de6958ee85bf6ac582c323e38efbcec9d568f222.zip
NewGVN: Make OpIsSafeForPhiOfOps non-recursive
llvm-svn: 314609
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/Transforms/Scalar/NewGVN.cpp45
1 files changed, 38 insertions, 7 deletions
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 8e7b1551a16..a16b37745eb 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -2487,8 +2487,7 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst,
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;
@@ -2498,23 +2497,55 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *V, Instruction *OrigInst,
OpSafeForPHIOfOps.insert({V, false});
return false;
}
- for (auto Op : cast<Instruction>(V)->operand_values()) {
+
+ SmallVector<Instruction *, 4> Worklist;
+ auto *OrigI = cast<Instruction>(V);
+ for (auto *Op : OrigI->operand_values()) {
if (!isa<Instruction>(Op))
continue;
- // See if we already know the answer for this node.
- auto OISIt = OpSafeForPHIOfOps.find(Op);
+ // Stop now if we find an unsafe operand.
+ auto OISIt = OpSafeForPHIOfOps.find(OrigI);
if (OISIt != OpSafeForPHIOfOps.end()) {
if (!OISIt->second) {
OpSafeForPHIOfOps.insert({V, false});
return false;
}
+ continue;
}
- if (!Visited.insert(Op).second)
+ Worklist.push_back(cast<Instruction>(Op));
+ }
+
+ 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;
- if (!OpIsSafeForPHIOfOps(Op, OrigInst, PHIBlock, Visited)) {
+ }
+ // PHI in the same block.
+ if (isa<PHINode>(I) && getBlockForValue(I) == PHIBlock) {
+ OpSafeForPHIOfOps.insert({I, false});
OpSafeForPHIOfOps.insert({V, false});
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;
OpenPOWER on IntegriCloud