Skip to content

Commit 2b15262

Browse files
committed
Recommit "[NewGVN] Track simplification dependencies for phi-of-ops."
This recommits 4f5da35, including explicit implementations of move a constructor and deleted copy constructors/assignment operators, to fix failures with some compilers. This reverts the revert 74854d0.
1 parent 791930d commit 2b15262

File tree

2 files changed

+220
-69
lines changed

2 files changed

+220
-69
lines changed

llvm/lib/Transforms/Scalar/NewGVN.cpp

Lines changed: 102 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,34 @@ class NewGVN {
668668
bool runGVN();
669669

670670
private:
671+
/// Helper struct return a Expression with an optional extra dependency.
672+
struct ExprResult {
673+
const Expression *Expr;
674+
Value *ExtraDep;
675+
676+
ExprResult(const Expression *Expr, Value *ExtraDep = nullptr)
677+
: Expr(Expr), ExtraDep(ExtraDep) {}
678+
ExprResult(const ExprResult &) = delete;
679+
ExprResult(ExprResult &&Other)
680+
: Expr(Other.Expr), ExtraDep(Other.ExtraDep) {
681+
Other.Expr = nullptr;
682+
Other.ExtraDep = nullptr;
683+
}
684+
ExprResult &operator=(const ExprResult &Other) = delete;
685+
ExprResult &operator=(ExprResult &&Other) = delete;
686+
687+
~ExprResult() { assert(!ExtraDep && "unhandled ExtraDep"); }
688+
689+
operator bool() const { return Expr; }
690+
691+
static ExprResult none() { return {nullptr, nullptr}; }
692+
static ExprResult some(const Expression *Expr, Value *ExtraDep = nullptr) {
693+
return {Expr, ExtraDep};
694+
}
695+
};
696+
671697
// Expression handling.
672-
const Expression *createExpression(Instruction *) const;
698+
ExprResult createExpression(Instruction *) const;
673699
const Expression *createBinaryExpression(unsigned, Type *, Value *, Value *,
674700
Instruction *) const;
675701

@@ -742,10 +768,9 @@ class NewGVN {
742768
void valueNumberInstruction(Instruction *);
743769

744770
// Symbolic evaluation.
745-
const Expression *checkSimplificationResults(Expression *, Instruction *,
746-
Value *) const;
747-
const Expression *performSymbolicEvaluation(Value *,
748-
SmallPtrSetImpl<Value *> &) const;
771+
ExprResult checkExprResults(Expression *, Instruction *, Value *) const;
772+
ExprResult performSymbolicEvaluation(Value *,
773+
SmallPtrSetImpl<Value *> &) const;
749774
const Expression *performSymbolicLoadCoercion(Type *, Value *, LoadInst *,
750775
Instruction *,
751776
MemoryAccess *) const;
@@ -757,7 +782,7 @@ class NewGVN {
757782
Instruction *I,
758783
BasicBlock *PHIBlock) const;
759784
const Expression *performSymbolicAggrValueEvaluation(Instruction *) const;
760-
const Expression *performSymbolicCmpEvaluation(Instruction *) const;
785+
ExprResult performSymbolicCmpEvaluation(Instruction *) const;
761786
const Expression *performSymbolicPredicateInfoEvaluation(Instruction *) const;
762787

763788
// Congruence finding.
@@ -814,6 +839,7 @@ class NewGVN {
814839
void addPredicateUsers(const PredicateBase *, Instruction *) const;
815840
void addMemoryUsers(const MemoryAccess *To, MemoryAccess *U) const;
816841
void addAdditionalUsers(Value *To, Value *User) const;
842+
void addAdditionalUsers(ExprResult &Res, Value *User) const;
817843

818844
// Main loop of value numbering
819845
void iterateTouchedInstructions();
@@ -1052,19 +1078,21 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
10521078
E->op_push_back(lookupOperandLeader(Arg2));
10531079

10541080
Value *V = SimplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ);
1055-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1056-
return SimplifiedE;
1081+
if (auto Simplified = checkExprResults(E, I, V)) {
1082+
addAdditionalUsers(Simplified, I);
1083+
return Simplified.Expr;
1084+
}
10571085
return E;
10581086
}
10591087

10601088
// Take a Value returned by simplification of Expression E/Instruction
10611089
// I, and see if it resulted in a simpler expression. If so, return
10621090
// that expression.
1063-
const Expression *NewGVN::checkSimplificationResults(Expression *E,
1064-
Instruction *I,
1065-
Value *V) const {
1091+
NewGVN::ExprResult NewGVN::checkExprResults(Expression *E, Instruction *I,
1092+
Value *V) const {
10661093
if (!V)
1067-
return nullptr;
1094+
return ExprResult::none();
1095+
10681096
if (auto *C = dyn_cast<Constant>(V)) {
10691097
if (I)
10701098
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
@@ -1073,52 +1101,37 @@ const Expression *NewGVN::checkSimplificationResults(Expression *E,
10731101
assert(isa<BasicExpression>(E) &&
10741102
"We should always have had a basic expression here");
10751103
deleteExpression(E);
1076-
return createConstantExpression(C);
1104+
return ExprResult::some(createConstantExpression(C));
10771105
} else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
10781106
if (I)
10791107
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
10801108
<< " variable " << *V << "\n");
10811109
deleteExpression(E);
1082-
return createVariableExpression(V);
1110+
return ExprResult::some(createVariableExpression(V));
10831111
}
10841112

10851113
CongruenceClass *CC = ValueToClass.lookup(V);
10861114
if (CC) {
10871115
if (CC->getLeader() && CC->getLeader() != I) {
1088-
// If we simplified to something else, we need to communicate
1089-
// that we're users of the value we simplified to.
1090-
if (I != V) {
1091-
// Don't add temporary instructions to the user lists.
1092-
if (!AllTempInstructions.count(I))
1093-
addAdditionalUsers(V, I);
1094-
}
1095-
return createVariableOrConstant(CC->getLeader());
1116+
return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
10961117
}
10971118
if (CC->getDefiningExpr()) {
1098-
// If we simplified to something else, we need to communicate
1099-
// that we're users of the value we simplified to.
1100-
if (I != V) {
1101-
// Don't add temporary instructions to the user lists.
1102-
if (!AllTempInstructions.count(I))
1103-
addAdditionalUsers(V, I);
1104-
}
1105-
11061119
if (I)
11071120
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
11081121
<< " expression " << *CC->getDefiningExpr() << "\n");
11091122
NumGVNOpsSimplified++;
11101123
deleteExpression(E);
1111-
return CC->getDefiningExpr();
1124+
return ExprResult::some(CC->getDefiningExpr(), V);
11121125
}
11131126
}
11141127

1115-
return nullptr;
1128+
return ExprResult::none();
11161129
}
11171130

11181131
// Create a value expression from the instruction I, replacing operands with
11191132
// their leaders.
11201133

1121-
const Expression *NewGVN::createExpression(Instruction *I) const {
1134+
NewGVN::ExprResult NewGVN::createExpression(Instruction *I) const {
11221135
auto *E = new (ExpressionAllocator) BasicExpression(I->getNumOperands());
11231136

11241137
bool AllConstant = setBasicExpressionInfo(I, E);
@@ -1149,33 +1162,33 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
11491162
E->getOperand(1)->getType() == I->getOperand(1)->getType()));
11501163
Value *V =
11511164
SimplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), SQ);
1152-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1153-
return SimplifiedE;
1165+
if (auto Simplified = checkExprResults(E, I, V))
1166+
return Simplified;
11541167
} else if (isa<SelectInst>(I)) {
11551168
if (isa<Constant>(E->getOperand(0)) ||
11561169
E->getOperand(1) == E->getOperand(2)) {
11571170
assert(E->getOperand(1)->getType() == I->getOperand(1)->getType() &&
11581171
E->getOperand(2)->getType() == I->getOperand(2)->getType());
11591172
Value *V = SimplifySelectInst(E->getOperand(0), E->getOperand(1),
11601173
E->getOperand(2), SQ);
1161-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1162-
return SimplifiedE;
1174+
if (auto Simplified = checkExprResults(E, I, V))
1175+
return Simplified;
11631176
}
11641177
} else if (I->isBinaryOp()) {
11651178
Value *V =
11661179
SimplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), SQ);
1167-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1168-
return SimplifiedE;
1180+
if (auto Simplified = checkExprResults(E, I, V))
1181+
return Simplified;
11691182
} else if (auto *CI = dyn_cast<CastInst>(I)) {
11701183
Value *V =
11711184
SimplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), SQ);
1172-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1173-
return SimplifiedE;
1185+
if (auto Simplified = checkExprResults(E, I, V))
1186+
return Simplified;
11741187
} else if (isa<GetElementPtrInst>(I)) {
11751188
Value *V = SimplifyGEPInst(
11761189
E->getType(), ArrayRef<Value *>(E->op_begin(), E->op_end()), SQ);
1177-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1178-
return SimplifiedE;
1190+
if (auto Simplified = checkExprResults(E, I, V))
1191+
return Simplified;
11791192
} else if (AllConstant) {
11801193
// We don't bother trying to simplify unless all of the operands
11811194
// were constant.
@@ -1189,10 +1202,10 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
11891202
C.emplace_back(cast<Constant>(Arg));
11901203

11911204
if (Value *V = ConstantFoldInstOperands(I, C, DL, TLI))
1192-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1193-
return SimplifiedE;
1205+
if (auto Simplified = checkExprResults(E, I, V))
1206+
return Simplified;
11941207
}
1195-
return E;
1208+
return ExprResult::some(E);
11961209
}
11971210

11981211
const AggregateValueExpression *
@@ -1778,7 +1791,7 @@ NewGVN::performSymbolicAggrValueEvaluation(Instruction *I) const {
17781791
return createAggregateValueExpression(I);
17791792
}
17801793

1781-
const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
1794+
NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
17821795
assert(isa<CmpInst>(I) && "Expected a cmp instruction.");
17831796

17841797
auto *CI = cast<CmpInst>(I);
@@ -1798,14 +1811,17 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
17981811
// of an assume.
17991812
auto *CmpPI = PredInfo->getPredicateInfoFor(I);
18001813
if (dyn_cast_or_null<PredicateAssume>(CmpPI))
1801-
return createConstantExpression(ConstantInt::getTrue(CI->getType()));
1814+
return ExprResult::some(
1815+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18021816

18031817
if (Op0 == Op1) {
18041818
// This condition does not depend on predicates, no need to add users
18051819
if (CI->isTrueWhenEqual())
1806-
return createConstantExpression(ConstantInt::getTrue(CI->getType()));
1820+
return ExprResult::some(
1821+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18071822
else if (CI->isFalseWhenEqual())
1808-
return createConstantExpression(ConstantInt::getFalse(CI->getType()));
1823+
return ExprResult::some(
1824+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18091825
}
18101826

18111827
// NOTE: Because we are comparing both operands here and below, and using
@@ -1865,30 +1881,30 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
18651881
if (CmpInst::isImpliedTrueByMatchingCmp(BranchPredicate,
18661882
OurPredicate)) {
18671883
addPredicateUsers(PI, I);
1868-
return createConstantExpression(
1869-
ConstantInt::getTrue(CI->getType()));
1884+
return ExprResult::some(
1885+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18701886
}
18711887

18721888
if (CmpInst::isImpliedFalseByMatchingCmp(BranchPredicate,
18731889
OurPredicate)) {
18741890
addPredicateUsers(PI, I);
1875-
return createConstantExpression(
1876-
ConstantInt::getFalse(CI->getType()));
1891+
return ExprResult::some(
1892+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18771893
}
18781894
} else {
18791895
// Just handle the ne and eq cases, where if we have the same
18801896
// operands, we may know something.
18811897
if (BranchPredicate == OurPredicate) {
18821898
addPredicateUsers(PI, I);
18831899
// Same predicate, same ops,we know it was false, so this is false.
1884-
return createConstantExpression(
1885-
ConstantInt::getFalse(CI->getType()));
1900+
return ExprResult::some(
1901+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18861902
} else if (BranchPredicate ==
18871903
CmpInst::getInversePredicate(OurPredicate)) {
18881904
addPredicateUsers(PI, I);
18891905
// Inverse predicate, we know the other was false, so this is true.
1890-
return createConstantExpression(
1891-
ConstantInt::getTrue(CI->getType()));
1906+
return ExprResult::some(
1907+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18921908
}
18931909
}
18941910
}
@@ -1899,9 +1915,10 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
18991915
}
19001916

19011917
// Substitute and symbolize the value before value numbering.
1902-
const Expression *
1918+
NewGVN::ExprResult
19031919
NewGVN::performSymbolicEvaluation(Value *V,
19041920
SmallPtrSetImpl<Value *> &Visited) const {
1921+
19051922
const Expression *E = nullptr;
19061923
if (auto *C = dyn_cast<Constant>(V))
19071924
E = createConstantExpression(C);
@@ -1937,11 +1954,11 @@ NewGVN::performSymbolicEvaluation(Value *V,
19371954
break;
19381955
case Instruction::BitCast:
19391956
case Instruction::AddrSpaceCast:
1940-
E = createExpression(I);
1957+
return createExpression(I);
19411958
break;
19421959
case Instruction::ICmp:
19431960
case Instruction::FCmp:
1944-
E = performSymbolicCmpEvaluation(I);
1961+
return performSymbolicCmpEvaluation(I);
19451962
break;
19461963
case Instruction::FNeg:
19471964
case Instruction::Add:
@@ -1977,16 +1994,16 @@ NewGVN::performSymbolicEvaluation(Value *V,
19771994
case Instruction::ExtractElement:
19781995
case Instruction::InsertElement:
19791996
case Instruction::GetElementPtr:
1980-
E = createExpression(I);
1997+
return createExpression(I);
19811998
break;
19821999
case Instruction::ShuffleVector:
19832000
// FIXME: Add support for shufflevector to createExpression.
1984-
return nullptr;
2001+
return ExprResult::none();
19852002
default:
1986-
return nullptr;
2003+
return ExprResult::none();
19872004
}
19882005
}
1989-
return E;
2006+
return ExprResult::some(E);
19902007
}
19912008

19922009
// Look up a container of values/instructions in a map, and touch all the
@@ -2007,6 +2024,12 @@ void NewGVN::addAdditionalUsers(Value *To, Value *User) const {
20072024
AdditionalUsers[To].insert(User);
20082025
}
20092026

2027+
void NewGVN::addAdditionalUsers(ExprResult &Res, Value *User) const {
2028+
if (Res.ExtraDep && Res.ExtraDep != User)
2029+
addAdditionalUsers(Res.ExtraDep, User);
2030+
Res.ExtraDep = nullptr;
2031+
}
2032+
20102033
void NewGVN::markUsersTouched(Value *V) {
20112034
// Now mark the users as touched.
20122035
for (auto *User : V->users()) {
@@ -2414,9 +2437,14 @@ void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *B) {
24142437
Value *CondEvaluated = findConditionEquivalence(Cond);
24152438
if (!CondEvaluated) {
24162439
if (auto *I = dyn_cast<Instruction>(Cond)) {
2417-
const Expression *E = createExpression(I);
2418-
if (const auto *CE = dyn_cast<ConstantExpression>(E)) {
2440+
auto Res = createExpression(I);
2441+
if (const auto *CE = dyn_cast<ConstantExpression>(Res.Expr)) {
24192442
CondEvaluated = CE->getConstantValue();
2443+
addAdditionalUsers(Res, I);
2444+
} else {
2445+
// Did not use simplification result, no need to add the extra
2446+
// dependency.
2447+
Res.ExtraDep = nullptr;
24202448
}
24212449
} else if (isa<ConstantInt>(Cond)) {
24222450
CondEvaluated = Cond;
@@ -2600,7 +2628,9 @@ Value *NewGVN::findLeaderForInst(Instruction *TransInst,
26002628
TempToBlock.insert({TransInst, PredBB});
26012629
InstrDFS.insert({TransInst, IDFSNum});
26022630

2603-
const Expression *E = performSymbolicEvaluation(TransInst, Visited);
2631+
auto Res = performSymbolicEvaluation(TransInst, Visited);
2632+
const Expression *E = Res.Expr;
2633+
addAdditionalUsers(Res, OrigInst);
26042634
InstrDFS.erase(TransInst);
26052635
AllTempInstructions.erase(TransInst);
26062636
TempToBlock.erase(TransInst);
@@ -3027,7 +3057,10 @@ void NewGVN::valueNumberInstruction(Instruction *I) {
30273057
const Expression *Symbolized = nullptr;
30283058
SmallPtrSet<Value *, 2> Visited;
30293059
if (DebugCounter::shouldExecute(VNCounter)) {
3030-
Symbolized = performSymbolicEvaluation(I, Visited);
3060+
auto Res = performSymbolicEvaluation(I, Visited);
3061+
Symbolized = Res.Expr;
3062+
addAdditionalUsers(Res, I);
3063+
30313064
// Make a phi of ops if necessary
30323065
if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
30333066
!isa<VariableExpression>(Symbolized) && PHINodeUses.count(I)) {

0 commit comments

Comments
 (0)