Skip to content

Commit 4f5da35

Browse files
committed
[NewGVN] Track simplification dependencies for phi-of-ops.
If we are using a simplified value, we need to add an extra dependency this value , because changes to the class of the simplified value may require us to invalidate any decision based on that value. This is done by adding such values as additional users, however the current code does not excludes temporary instructions. At the moment, this means that we miss those dependencies for phi-of-ops, because they are temporary instructions at this point. We instead need to add the extra dependencies to the root instruction of the phi-of-ops. This patch pushes the responsibility of adding extra users to the callers of createExpression & performSymbolicEvaluation. At those points, it is clearer which real instruction to pick. Alternatively we could either pass the 'real' instruction as additional argument or use another map, but I think the approach in the patch makes things a bit easier to follow. Fixes PR35074. Reviewed By: asbirlea Differential Revision: https://reviews.llvm.org/D99987
1 parent ab15417 commit 4f5da35

File tree

2 files changed

+209
-69
lines changed

2 files changed

+209
-69
lines changed

llvm/lib/Transforms/Scalar/NewGVN.cpp

Lines changed: 91 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -668,8 +668,23 @@ 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() { assert(!ExtraDep && "unhandled ExtraDep"); }
677+
678+
operator bool() const { return Expr; }
679+
680+
static ExprResult none() { return {nullptr, nullptr}; }
681+
static ExprResult some(const Expression *Expr, Value *ExtraDep = nullptr) {
682+
return {Expr, ExtraDep};
683+
}
684+
};
685+
671686
// Expression handling.
672-
const Expression *createExpression(Instruction *) const;
687+
ExprResult createExpression(Instruction *) const;
673688
const Expression *createBinaryExpression(unsigned, Type *, Value *, Value *,
674689
Instruction *) const;
675690

@@ -742,10 +757,9 @@ class NewGVN {
742757
void valueNumberInstruction(Instruction *);
743758

744759
// Symbolic evaluation.
745-
const Expression *checkSimplificationResults(Expression *, Instruction *,
746-
Value *) const;
747-
const Expression *performSymbolicEvaluation(Value *,
748-
SmallPtrSetImpl<Value *> &) const;
760+
ExprResult checkExprResults(Expression *, Instruction *, Value *) const;
761+
ExprResult performSymbolicEvaluation(Value *,
762+
SmallPtrSetImpl<Value *> &) const;
749763
const Expression *performSymbolicLoadCoercion(Type *, Value *, LoadInst *,
750764
Instruction *,
751765
MemoryAccess *) const;
@@ -757,7 +771,7 @@ class NewGVN {
757771
Instruction *I,
758772
BasicBlock *PHIBlock) const;
759773
const Expression *performSymbolicAggrValueEvaluation(Instruction *) const;
760-
const Expression *performSymbolicCmpEvaluation(Instruction *) const;
774+
ExprResult performSymbolicCmpEvaluation(Instruction *) const;
761775
const Expression *performSymbolicPredicateInfoEvaluation(Instruction *) const;
762776

763777
// Congruence finding.
@@ -814,6 +828,7 @@ class NewGVN {
814828
void addPredicateUsers(const PredicateBase *, Instruction *) const;
815829
void addMemoryUsers(const MemoryAccess *To, MemoryAccess *U) const;
816830
void addAdditionalUsers(Value *To, Value *User) const;
831+
void addAdditionalUsers(ExprResult &Res, Value *User) const;
817832

818833
// Main loop of value numbering
819834
void iterateTouchedInstructions();
@@ -1052,19 +1067,21 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
10521067
E->op_push_back(lookupOperandLeader(Arg2));
10531068

10541069
Value *V = SimplifyBinOp(Opcode, E->getOperand(0), E->getOperand(1), SQ);
1055-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1056-
return SimplifiedE;
1070+
if (auto Simplified = checkExprResults(E, I, V)) {
1071+
addAdditionalUsers(Simplified, I);
1072+
return Simplified.Expr;
1073+
}
10571074
return E;
10581075
}
10591076

10601077
// Take a Value returned by simplification of Expression E/Instruction
10611078
// I, and see if it resulted in a simpler expression. If so, return
10621079
// that expression.
1063-
const Expression *NewGVN::checkSimplificationResults(Expression *E,
1064-
Instruction *I,
1065-
Value *V) const {
1080+
NewGVN::ExprResult NewGVN::checkExprResults(Expression *E, Instruction *I,
1081+
Value *V) const {
10661082
if (!V)
1067-
return nullptr;
1083+
return ExprResult::none();
1084+
10681085
if (auto *C = dyn_cast<Constant>(V)) {
10691086
if (I)
10701087
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
@@ -1073,52 +1090,37 @@ const Expression *NewGVN::checkSimplificationResults(Expression *E,
10731090
assert(isa<BasicExpression>(E) &&
10741091
"We should always have had a basic expression here");
10751092
deleteExpression(E);
1076-
return createConstantExpression(C);
1093+
return ExprResult::some(createConstantExpression(C));
10771094
} else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
10781095
if (I)
10791096
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
10801097
<< " variable " << *V << "\n");
10811098
deleteExpression(E);
1082-
return createVariableExpression(V);
1099+
return ExprResult::some(createVariableExpression(V));
10831100
}
10841101

10851102
CongruenceClass *CC = ValueToClass.lookup(V);
10861103
if (CC) {
10871104
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());
1105+
return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
10961106
}
10971107
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-
11061108
if (I)
11071109
LLVM_DEBUG(dbgs() << "Simplified " << *I << " to "
11081110
<< " expression " << *CC->getDefiningExpr() << "\n");
11091111
NumGVNOpsSimplified++;
11101112
deleteExpression(E);
1111-
return CC->getDefiningExpr();
1113+
return ExprResult::some(CC->getDefiningExpr(), V);
11121114
}
11131115
}
11141116

1115-
return nullptr;
1117+
return ExprResult::none();
11161118
}
11171119

11181120
// Create a value expression from the instruction I, replacing operands with
11191121
// their leaders.
11201122

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

11241126
bool AllConstant = setBasicExpressionInfo(I, E);
@@ -1149,33 +1151,33 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
11491151
E->getOperand(1)->getType() == I->getOperand(1)->getType()));
11501152
Value *V =
11511153
SimplifyCmpInst(Predicate, E->getOperand(0), E->getOperand(1), SQ);
1152-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1153-
return SimplifiedE;
1154+
if (auto Simplified = checkExprResults(E, I, V))
1155+
return Simplified;
11541156
} else if (isa<SelectInst>(I)) {
11551157
if (isa<Constant>(E->getOperand(0)) ||
11561158
E->getOperand(1) == E->getOperand(2)) {
11571159
assert(E->getOperand(1)->getType() == I->getOperand(1)->getType() &&
11581160
E->getOperand(2)->getType() == I->getOperand(2)->getType());
11591161
Value *V = SimplifySelectInst(E->getOperand(0), E->getOperand(1),
11601162
E->getOperand(2), SQ);
1161-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1162-
return SimplifiedE;
1163+
if (auto Simplified = checkExprResults(E, I, V))
1164+
return Simplified;
11631165
}
11641166
} else if (I->isBinaryOp()) {
11651167
Value *V =
11661168
SimplifyBinOp(E->getOpcode(), E->getOperand(0), E->getOperand(1), SQ);
1167-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1168-
return SimplifiedE;
1169+
if (auto Simplified = checkExprResults(E, I, V))
1170+
return Simplified;
11691171
} else if (auto *CI = dyn_cast<CastInst>(I)) {
11701172
Value *V =
11711173
SimplifyCastInst(CI->getOpcode(), E->getOperand(0), CI->getType(), SQ);
1172-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1173-
return SimplifiedE;
1174+
if (auto Simplified = checkExprResults(E, I, V))
1175+
return Simplified;
11741176
} else if (isa<GetElementPtrInst>(I)) {
11751177
Value *V = SimplifyGEPInst(
11761178
E->getType(), ArrayRef<Value *>(E->op_begin(), E->op_end()), SQ);
1177-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1178-
return SimplifiedE;
1179+
if (auto Simplified = checkExprResults(E, I, V))
1180+
return Simplified;
11791181
} else if (AllConstant) {
11801182
// We don't bother trying to simplify unless all of the operands
11811183
// were constant.
@@ -1189,10 +1191,10 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
11891191
C.emplace_back(cast<Constant>(Arg));
11901192

11911193
if (Value *V = ConstantFoldInstOperands(I, C, DL, TLI))
1192-
if (const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1193-
return SimplifiedE;
1194+
if (auto Simplified = checkExprResults(E, I, V))
1195+
return Simplified;
11941196
}
1195-
return E;
1197+
return ExprResult::some(E);
11961198
}
11971199

11981200
const AggregateValueExpression *
@@ -1778,7 +1780,7 @@ NewGVN::performSymbolicAggrValueEvaluation(Instruction *I) const {
17781780
return createAggregateValueExpression(I);
17791781
}
17801782

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

17841786
auto *CI = cast<CmpInst>(I);
@@ -1798,14 +1800,17 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
17981800
// of an assume.
17991801
auto *CmpPI = PredInfo->getPredicateInfoFor(I);
18001802
if (dyn_cast_or_null<PredicateAssume>(CmpPI))
1801-
return createConstantExpression(ConstantInt::getTrue(CI->getType()));
1803+
return ExprResult::some(
1804+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18021805

18031806
if (Op0 == Op1) {
18041807
// This condition does not depend on predicates, no need to add users
18051808
if (CI->isTrueWhenEqual())
1806-
return createConstantExpression(ConstantInt::getTrue(CI->getType()));
1809+
return ExprResult::some(
1810+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18071811
else if (CI->isFalseWhenEqual())
1808-
return createConstantExpression(ConstantInt::getFalse(CI->getType()));
1812+
return ExprResult::some(
1813+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18091814
}
18101815

18111816
// NOTE: Because we are comparing both operands here and below, and using
@@ -1865,30 +1870,30 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
18651870
if (CmpInst::isImpliedTrueByMatchingCmp(BranchPredicate,
18661871
OurPredicate)) {
18671872
addPredicateUsers(PI, I);
1868-
return createConstantExpression(
1869-
ConstantInt::getTrue(CI->getType()));
1873+
return ExprResult::some(
1874+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18701875
}
18711876

18721877
if (CmpInst::isImpliedFalseByMatchingCmp(BranchPredicate,
18731878
OurPredicate)) {
18741879
addPredicateUsers(PI, I);
1875-
return createConstantExpression(
1876-
ConstantInt::getFalse(CI->getType()));
1880+
return ExprResult::some(
1881+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18771882
}
18781883
} else {
18791884
// Just handle the ne and eq cases, where if we have the same
18801885
// operands, we may know something.
18811886
if (BranchPredicate == OurPredicate) {
18821887
addPredicateUsers(PI, I);
18831888
// Same predicate, same ops,we know it was false, so this is false.
1884-
return createConstantExpression(
1885-
ConstantInt::getFalse(CI->getType()));
1889+
return ExprResult::some(
1890+
createConstantExpression(ConstantInt::getFalse(CI->getType())));
18861891
} else if (BranchPredicate ==
18871892
CmpInst::getInversePredicate(OurPredicate)) {
18881893
addPredicateUsers(PI, I);
18891894
// Inverse predicate, we know the other was false, so this is true.
1890-
return createConstantExpression(
1891-
ConstantInt::getTrue(CI->getType()));
1895+
return ExprResult::some(
1896+
createConstantExpression(ConstantInt::getTrue(CI->getType())));
18921897
}
18931898
}
18941899
}
@@ -1899,9 +1904,10 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
18991904
}
19001905

19011906
// Substitute and symbolize the value before value numbering.
1902-
const Expression *
1907+
NewGVN::ExprResult
19031908
NewGVN::performSymbolicEvaluation(Value *V,
19041909
SmallPtrSetImpl<Value *> &Visited) const {
1910+
19051911
const Expression *E = nullptr;
19061912
if (auto *C = dyn_cast<Constant>(V))
19071913
E = createConstantExpression(C);
@@ -1937,11 +1943,11 @@ NewGVN::performSymbolicEvaluation(Value *V,
19371943
break;
19381944
case Instruction::BitCast:
19391945
case Instruction::AddrSpaceCast:
1940-
E = createExpression(I);
1946+
return createExpression(I);
19411947
break;
19421948
case Instruction::ICmp:
19431949
case Instruction::FCmp:
1944-
E = performSymbolicCmpEvaluation(I);
1950+
return performSymbolicCmpEvaluation(I);
19451951
break;
19461952
case Instruction::FNeg:
19471953
case Instruction::Add:
@@ -1977,16 +1983,16 @@ NewGVN::performSymbolicEvaluation(Value *V,
19771983
case Instruction::ExtractElement:
19781984
case Instruction::InsertElement:
19791985
case Instruction::GetElementPtr:
1980-
E = createExpression(I);
1986+
return createExpression(I);
19811987
break;
19821988
case Instruction::ShuffleVector:
19831989
// FIXME: Add support for shufflevector to createExpression.
1984-
return nullptr;
1990+
return ExprResult::none();
19851991
default:
1986-
return nullptr;
1992+
return ExprResult::none();
19871993
}
19881994
}
1989-
return E;
1995+
return ExprResult::some(E);
19901996
}
19911997

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

2016+
void NewGVN::addAdditionalUsers(ExprResult &Res, Value *User) const {
2017+
if (Res.ExtraDep && Res.ExtraDep != User)
2018+
addAdditionalUsers(Res.ExtraDep, User);
2019+
Res.ExtraDep = nullptr;
2020+
}
2021+
20102022
void NewGVN::markUsersTouched(Value *V) {
20112023
// Now mark the users as touched.
20122024
for (auto *User : V->users()) {
@@ -2414,9 +2426,14 @@ void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *B) {
24142426
Value *CondEvaluated = findConditionEquivalence(Cond);
24152427
if (!CondEvaluated) {
24162428
if (auto *I = dyn_cast<Instruction>(Cond)) {
2417-
const Expression *E = createExpression(I);
2418-
if (const auto *CE = dyn_cast<ConstantExpression>(E)) {
2429+
auto Res = createExpression(I);
2430+
if (const auto *CE = dyn_cast<ConstantExpression>(Res.Expr)) {
24192431
CondEvaluated = CE->getConstantValue();
2432+
addAdditionalUsers(Res, I);
2433+
} else {
2434+
// Did not use simplification result, no need to add the extra
2435+
// dependency.
2436+
Res.ExtraDep = nullptr;
24202437
}
24212438
} else if (isa<ConstantInt>(Cond)) {
24222439
CondEvaluated = Cond;
@@ -2600,7 +2617,9 @@ Value *NewGVN::findLeaderForInst(Instruction *TransInst,
26002617
TempToBlock.insert({TransInst, PredBB});
26012618
InstrDFS.insert({TransInst, IDFSNum});
26022619

2603-
const Expression *E = performSymbolicEvaluation(TransInst, Visited);
2620+
auto Res = performSymbolicEvaluation(TransInst, Visited);
2621+
const Expression *E = Res.Expr;
2622+
addAdditionalUsers(Res, OrigInst);
26042623
InstrDFS.erase(TransInst);
26052624
AllTempInstructions.erase(TransInst);
26062625
TempToBlock.erase(TransInst);
@@ -3027,7 +3046,10 @@ void NewGVN::valueNumberInstruction(Instruction *I) {
30273046
const Expression *Symbolized = nullptr;
30283047
SmallPtrSet<Value *, 2> Visited;
30293048
if (DebugCounter::shouldExecute(VNCounter)) {
3030-
Symbolized = performSymbolicEvaluation(I, Visited);
3049+
auto Res = performSymbolicEvaluation(I, Visited);
3050+
Symbolized = Res.Expr;
3051+
addAdditionalUsers(Res, I);
3052+
30313053
// Make a phi of ops if necessary
30323054
if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
30333055
!isa<VariableExpression>(Symbolized) && PHINodeUses.count(I)) {

0 commit comments

Comments
 (0)