diff options
author | Daniel Berlin <dberlin@dberlin.org> | 2017-01-02 18:00:53 +0000 |
---|---|---|
committer | Daniel Berlin <dberlin@dberlin.org> | 2017-01-02 18:00:53 +0000 |
commit | 02c6b176e75c650ed1e312541035cb7c086d4da1 (patch) | |
tree | 72df17cc31351c4b28180462069e654ec93ad66b /llvm/lib/Transforms | |
parent | 589cecc6e9ef0f2ab8b54512b97244587f74596a (diff) | |
download | bcm5719-llvm-02c6b176e75c650ed1e312541035cb7c086d4da1.tar.gz bcm5719-llvm-02c6b176e75c650ed1e312541035cb7c086d4da1.zip |
NewGVN: Add UnknownExpression and create them for things we can't symbolize. Kill fragile machinery for handling null expressions.
Summary:
This avoids the very fragile code for null expressions. We could also use a denseset that tracks which things have null expressions instead, but that seems pretty fragile and premature optimization.
This resolves a number of infinite loop cases, test reductions coming.
Reviewers: davide
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D28193
llvm-svn: 290816
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/NewGVN.cpp | 38 |
1 files changed, 19 insertions, 19 deletions
diff --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp index 294b0e26fe8..dee61b77412 100644 --- a/llvm/lib/Transforms/Scalar/NewGVN.cpp +++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp @@ -262,6 +262,7 @@ private: const VariableExpression *createVariableExpression(Value *); const ConstantExpression *createConstantExpression(Constant *); const Expression *createVariableOrConstant(Value *V, const BasicBlock *B); + const UnknownExpression *createUnknownExpression(Instruction *); const StoreExpression *createStoreExpression(StoreInst *, MemoryAccess *, const BasicBlock *); LoadExpression *createLoadExpression(Type *, Value *, LoadInst *, @@ -640,6 +641,12 @@ const ConstantExpression *NewGVN::createConstantExpression(Constant *C) { return E; } +const UnknownExpression *NewGVN::createUnknownExpression(Instruction *I) { + auto *E = new (ExpressionAllocator) UnknownExpression(I); + E->setOpcode(I->getOpcode()); + return E; +} + const CallExpression *NewGVN::createCallExpression(CallInst *CI, MemoryAccess *HV, const BasicBlock *B) { @@ -1012,24 +1019,7 @@ void NewGVN::performCongruenceFinding(Value *V, const Expression *E) { assert(!VClass->Dead && "Found a dead class"); CongruenceClass *EClass; - // Expressions we can't symbolize are always in their own unique - // congruence class. FIXME: This is hard to perfect. Long term, we should try - // to create expressions for everything. We should add UnknownExpression(Inst) - // or something to avoid wasting time creating real ones. Then the existing - // logic will just work. - if (E == nullptr) { - // We may have already made a unique class. - // Test whether we are still in the initial class, or we have found a class - if (VClass == InitialClass || VClass->RepLeader != V) { - CongruenceClass *NewClass = createCongruenceClass(V, nullptr); - // We should always be adding the member in the below code. - EClass = NewClass; - DEBUG(dbgs() << "Created new congruence class for " << *V - << " due to nullptr expression\n"); - } else { - EClass = VClass; - } - } else if (const auto *VE = dyn_cast<VariableExpression>(E)) { + if (const auto *VE = dyn_cast<VariableExpression>(E)) { EClass = ValueToClass[VE->getVariableValue()]; } else { auto lookupResult = ExpressionToClass.insert({E, nullptr}); @@ -1392,9 +1382,19 @@ void NewGVN::valueNumberInstruction(Instruction *I) { return; } if (!I->isTerminator()) { - const Expression *Symbolized = performSymbolicEvaluation(I, I->getParent()); + const auto *Symbolized = performSymbolicEvaluation(I, I->getParent()); + // If we couldn't come up with a symbolic expression, use the unknown + // expression + if (Symbolized == nullptr) + Symbolized = createUnknownExpression(I); performCongruenceFinding(I, Symbolized); } else { + // Handle terminators that return values. All of them produce values we + // don't currently understand. + if (!I->getType()->isVoidTy()){ + auto *Symbolized = createUnknownExpression(I); + performCongruenceFinding(I, Symbolized); + } processOutgoingEdges(dyn_cast<TerminatorInst>(I), I->getParent()); } } |