aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp127
1 files changed, 30 insertions, 97 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp b/contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 0ed1773373a7..281d47c8625f 100644
--- a/contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/contrib/llvm-project/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -662,7 +662,8 @@ public:
const DataLayout &DL)
: F(F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC), DL(DL),
PredInfo(std::make_unique<PredicateInfo>(F, *DT, *AC)),
- SQ(DL, TLI, DT, AC, /*CtxI=*/nullptr, /*UseInstrInfo=*/false) {}
+ SQ(DL, TLI, DT, AC, /*CtxI=*/nullptr, /*UseInstrInfo=*/false,
+ /*CanUseUndef=*/false) {}
bool runGVN();
@@ -800,12 +801,7 @@ private:
Value *findPHIOfOpsLeader(const Expression *, const Instruction *,
const BasicBlock *) const;
- // New instruction creation.
- void handleNewInstruction(Instruction *) {}
-
// Various instruction touch utilities
- template <typename Map, typename KeyType, typename Func>
- void for_each_found(Map &, const KeyType &, Func);
template <typename Map, typename KeyType>
void touchAndErase(Map &, const KeyType &);
void markUsersTouched(Value *);
@@ -834,7 +830,6 @@ private:
BasicBlock *getBlockForValue(Value *V) const;
void deleteExpression(const Expression *E) const;
MemoryUseOrDef *getMemoryAccess(const Instruction *) const;
- MemoryAccess *getDefiningAccess(const MemoryAccess *) const;
MemoryPhi *getMemoryAccess(const BasicBlock *) const;
template <class T, class Range> T *getMinDFSOfRange(const Range &) const;
@@ -1253,6 +1248,7 @@ const UnknownExpression *NewGVN::createUnknownExpression(Instruction *I) const {
const CallExpression *
NewGVN::createCallExpression(CallInst *CI, const MemoryAccess *MA) const {
// FIXME: Add operand bundles for calls.
+ // FIXME: Allow commutative matching for intrinsics.
auto *E =
new (ExpressionAllocator) CallExpression(CI->getNumOperands(), CI, MA);
setBasicExpressionInfo(CI, E);
@@ -1539,90 +1535,39 @@ NewGVN::performSymbolicPredicateInfoEvaluation(Instruction *I) const {
LLVM_DEBUG(dbgs() << "Found predicate info from instruction !\n");
- auto *PWC = dyn_cast<PredicateWithCondition>(PI);
- if (!PWC)
+ const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
+ if (!Constraint)
return nullptr;
- auto *CopyOf = I->getOperand(0);
- auto *Cond = PWC->Condition;
-
- // If this a copy of the condition, it must be either true or false depending
- // on the predicate info type and edge.
- if (CopyOf == Cond) {
- // We should not need to add predicate users because the predicate info is
- // already a use of this operand.
- if (isa<PredicateAssume>(PI))
- return createConstantExpression(ConstantInt::getTrue(Cond->getType()));
- if (auto *PBranch = dyn_cast<PredicateBranch>(PI)) {
- if (PBranch->TrueEdge)
- return createConstantExpression(ConstantInt::getTrue(Cond->getType()));
- return createConstantExpression(ConstantInt::getFalse(Cond->getType()));
- }
- if (auto *PSwitch = dyn_cast<PredicateSwitch>(PI))
- return createConstantExpression(cast<Constant>(PSwitch->CaseValue));
- }
+ CmpInst::Predicate Predicate = Constraint->Predicate;
+ Value *CmpOp0 = I->getOperand(0);
+ Value *CmpOp1 = Constraint->OtherOp;
- // Not a copy of the condition, so see what the predicates tell us about this
- // value. First, though, we check to make sure the value is actually a copy
- // of one of the condition operands. It's possible, in certain cases, for it
- // to be a copy of a predicateinfo copy. In particular, if two branch
- // operations use the same condition, and one branch dominates the other, we
- // will end up with a copy of a copy. This is currently a small deficiency in
- // predicateinfo. What will end up happening here is that we will value
- // number both copies the same anyway.
-
- // Everything below relies on the condition being a comparison.
- auto *Cmp = dyn_cast<CmpInst>(Cond);
- if (!Cmp)
- return nullptr;
+ Value *FirstOp = lookupOperandLeader(CmpOp0);
+ Value *SecondOp = lookupOperandLeader(CmpOp1);
+ Value *AdditionallyUsedValue = CmpOp0;
- if (CopyOf != Cmp->getOperand(0) && CopyOf != Cmp->getOperand(1)) {
- LLVM_DEBUG(dbgs() << "Copy is not of any condition operands!\n");
- return nullptr;
- }
- Value *FirstOp = lookupOperandLeader(Cmp->getOperand(0));
- Value *SecondOp = lookupOperandLeader(Cmp->getOperand(1));
- bool SwappedOps = false;
// Sort the ops.
if (shouldSwapOperands(FirstOp, SecondOp)) {
std::swap(FirstOp, SecondOp);
- SwappedOps = true;
+ Predicate = CmpInst::getSwappedPredicate(Predicate);
+ AdditionallyUsedValue = CmpOp1;
}
- CmpInst::Predicate Predicate =
- SwappedOps ? Cmp->getSwappedPredicate() : Cmp->getPredicate();
-
- if (isa<PredicateAssume>(PI)) {
- // If we assume the operands are equal, then they are equal.
- if (Predicate == CmpInst::ICMP_EQ) {
- addPredicateUsers(PI, I);
- addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
- I);
- return createVariableOrConstant(FirstOp);
- }
+
+ if (Predicate == CmpInst::ICMP_EQ) {
+ addPredicateUsers(PI, I);
+ addAdditionalUsers(AdditionallyUsedValue, I);
+ return createVariableOrConstant(FirstOp);
}
- if (const auto *PBranch = dyn_cast<PredicateBranch>(PI)) {
- // If we are *not* a copy of the comparison, we may equal to the other
- // operand when the predicate implies something about equality of
- // operations. In particular, if the comparison is true/false when the
- // operands are equal, and we are on the right edge, we know this operation
- // is equal to something.
- if ((PBranch->TrueEdge && Predicate == CmpInst::ICMP_EQ) ||
- (!PBranch->TrueEdge && Predicate == CmpInst::ICMP_NE)) {
- addPredicateUsers(PI, I);
- addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
- I);
- return createVariableOrConstant(FirstOp);
- }
- // Handle the special case of floating point.
- if (((PBranch->TrueEdge && Predicate == CmpInst::FCMP_OEQ) ||
- (!PBranch->TrueEdge && Predicate == CmpInst::FCMP_UNE)) &&
- isa<ConstantFP>(FirstOp) && !cast<ConstantFP>(FirstOp)->isZero()) {
- addPredicateUsers(PI, I);
- addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
- I);
- return createConstantExpression(cast<Constant>(FirstOp));
- }
+
+ // Handle the special case of floating point.
+ if (Predicate == CmpInst::FCMP_OEQ && isa<ConstantFP>(FirstOp) &&
+ !cast<ConstantFP>(FirstOp)->isZero()) {
+ addPredicateUsers(PI, I);
+ addAdditionalUsers(AdditionallyUsedValue, I);
+ return createConstantExpression(cast<Constant>(FirstOp));
}
+
return nullptr;
}
@@ -2044,16 +1989,6 @@ NewGVN::performSymbolicEvaluation(Value *V,
return E;
}
-// Look up a container in a map, and then call a function for each thing in the
-// found container.
-template <typename Map, typename KeyType, typename Func>
-void NewGVN::for_each_found(Map &M, const KeyType &Key, Func F) {
- const auto Result = M.find_as(Key);
- if (Result != M.end())
- for (typename Map::mapped_type::value_type Mapped : Result->second)
- F(Mapped);
-}
-
// Look up a container of values/instructions in a map, and touch all the
// instructions in the container. Then erase value from the map.
template <typename Map, typename KeyType>
@@ -2941,8 +2876,7 @@ void NewGVN::cleanupTables() {
}
while (!TempInst.empty()) {
- auto *I = TempInst.back();
- TempInst.pop_back();
+ auto *I = TempInst.pop_back_val();
I->deleteValue();
}
@@ -3437,10 +3371,9 @@ bool NewGVN::runGVN() {
for (auto &B : RPOT) {
auto *Node = DT->getNode(B);
if (Node->getNumChildren() > 1)
- llvm::sort(Node->begin(), Node->end(),
- [&](const DomTreeNode *A, const DomTreeNode *B) {
- return RPOOrdering[A] < RPOOrdering[B];
- });
+ llvm::sort(*Node, [&](const DomTreeNode *A, const DomTreeNode *B) {
+ return RPOOrdering[A] < RPOOrdering[B];
+ });
}
// Now a standard depth first ordering of the domtree is equivalent to RPO.