[llvm] r290816 - NewGVN: Add UnknownExpression and create them for things we can't symbolize. Kill fragile machinery for handling null expressions.
Daniel Berlin via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 2 10:00:54 PST 2017
Author: dannyb
Date: Mon Jan 2 12:00:53 2017
New Revision: 290816
URL: http://llvm.org/viewvc/llvm-project?rev=290816&view=rev
Log:
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
Modified:
llvm/trunk/include/llvm/Transforms/Scalar/GVNExpression.h
llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp
Modified: llvm/trunk/include/llvm/Transforms/Scalar/GVNExpression.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Scalar/GVNExpression.h?rev=290816&r1=290815&r2=290816&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Scalar/GVNExpression.h (original)
+++ llvm/trunk/include/llvm/Transforms/Scalar/GVNExpression.h Mon Jan 2 12:00:53 2017
@@ -36,6 +36,7 @@ enum ExpressionType {
ET_Base,
ET_Constant,
ET_Variable,
+ ET_Unknown,
ET_BasicStart,
ET_Basic,
ET_Call,
@@ -564,6 +565,40 @@ public:
OS << " constant = " << *ConstantValue;
}
};
+
+class UnknownExpression final : public Expression {
+private:
+ Instruction *Inst;
+
+public:
+ static bool classof(const Expression *EB) {
+ return EB->getExpressionType() == ET_Unknown;
+ }
+
+ UnknownExpression(Instruction *I) : Expression(ET_Unknown), Inst(I) {}
+ void operator=(const UnknownExpression &) = delete;
+ UnknownExpression(const UnknownExpression &) = delete;
+ UnknownExpression() = delete;
+
+ Instruction *getInstruction() const { return Inst; }
+ void setInstruction(Instruction *I) { Inst = I; }
+ virtual bool equals(const Expression &Other) const override {
+ const auto &OU = cast<UnknownExpression>(Other);
+ return Inst == OU.Inst;
+ }
+ virtual hash_code getHashValue() const override {
+ return hash_combine(getExpressionType(), Inst);
+ }
+ //
+ // Debugging support
+ //
+ virtual void printInternal(raw_ostream &OS, bool PrintEType) const override {
+ if (PrintEType)
+ OS << "ExpressionTypeUnknown, ";
+ this->Expression::printInternal(OS, false);
+ OS << " inst = " << *Inst;
+ }
+};
}
}
Modified: llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp?rev=290816&r1=290815&r2=290816&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp Mon Jan 2 12:00:53 2017
@@ -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::create
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(Va
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(Inst
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());
}
}
More information about the llvm-commits
mailing list