@@ -668,8 +668,23 @@ class NewGVN {
668
668
bool runGVN ();
669
669
670
670
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
+
671
686
// Expression handling.
672
- const Expression * createExpression (Instruction *) const ;
687
+ ExprResult createExpression (Instruction *) const ;
673
688
const Expression *createBinaryExpression (unsigned , Type *, Value *, Value *,
674
689
Instruction *) const ;
675
690
@@ -742,10 +757,9 @@ class NewGVN {
742
757
void valueNumberInstruction (Instruction *);
743
758
744
759
// 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 ;
749
763
const Expression *performSymbolicLoadCoercion (Type *, Value *, LoadInst *,
750
764
Instruction *,
751
765
MemoryAccess *) const ;
@@ -757,7 +771,7 @@ class NewGVN {
757
771
Instruction *I,
758
772
BasicBlock *PHIBlock) const ;
759
773
const Expression *performSymbolicAggrValueEvaluation (Instruction *) const ;
760
- const Expression * performSymbolicCmpEvaluation (Instruction *) const ;
774
+ ExprResult performSymbolicCmpEvaluation (Instruction *) const ;
761
775
const Expression *performSymbolicPredicateInfoEvaluation (Instruction *) const ;
762
776
763
777
// Congruence finding.
@@ -814,6 +828,7 @@ class NewGVN {
814
828
void addPredicateUsers (const PredicateBase *, Instruction *) const ;
815
829
void addMemoryUsers (const MemoryAccess *To, MemoryAccess *U) const ;
816
830
void addAdditionalUsers (Value *To, Value *User) const ;
831
+ void addAdditionalUsers (ExprResult &Res, Value *User) const ;
817
832
818
833
// Main loop of value numbering
819
834
void iterateTouchedInstructions ();
@@ -1052,19 +1067,21 @@ const Expression *NewGVN::createBinaryExpression(unsigned Opcode, Type *T,
1052
1067
E->op_push_back (lookupOperandLeader (Arg2));
1053
1068
1054
1069
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
+ }
1057
1074
return E;
1058
1075
}
1059
1076
1060
1077
// Take a Value returned by simplification of Expression E/Instruction
1061
1078
// I, and see if it resulted in a simpler expression. If so, return
1062
1079
// 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 {
1066
1082
if (!V)
1067
- return nullptr ;
1083
+ return ExprResult::none ();
1084
+
1068
1085
if (auto *C = dyn_cast<Constant>(V)) {
1069
1086
if (I)
1070
1087
LLVM_DEBUG (dbgs () << " Simplified " << *I << " to "
@@ -1073,52 +1090,37 @@ const Expression *NewGVN::checkSimplificationResults(Expression *E,
1073
1090
assert (isa<BasicExpression>(E) &&
1074
1091
" We should always have had a basic expression here" );
1075
1092
deleteExpression (E);
1076
- return createConstantExpression (C);
1093
+ return ExprResult::some ( createConstantExpression (C) );
1077
1094
} else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1078
1095
if (I)
1079
1096
LLVM_DEBUG (dbgs () << " Simplified " << *I << " to "
1080
1097
<< " variable " << *V << " \n " );
1081
1098
deleteExpression (E);
1082
- return createVariableExpression (V);
1099
+ return ExprResult::some ( createVariableExpression (V) );
1083
1100
}
1084
1101
1085
1102
CongruenceClass *CC = ValueToClass.lookup (V);
1086
1103
if (CC) {
1087
1104
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);
1096
1106
}
1097
1107
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
-
1106
1108
if (I)
1107
1109
LLVM_DEBUG (dbgs () << " Simplified " << *I << " to "
1108
1110
<< " expression " << *CC->getDefiningExpr () << " \n " );
1109
1111
NumGVNOpsSimplified++;
1110
1112
deleteExpression (E);
1111
- return CC->getDefiningExpr ();
1113
+ return ExprResult::some ( CC->getDefiningExpr (), V );
1112
1114
}
1113
1115
}
1114
1116
1115
- return nullptr ;
1117
+ return ExprResult::none () ;
1116
1118
}
1117
1119
1118
1120
// Create a value expression from the instruction I, replacing operands with
1119
1121
// their leaders.
1120
1122
1121
- const Expression * NewGVN::createExpression (Instruction *I) const {
1123
+ NewGVN::ExprResult NewGVN::createExpression (Instruction *I) const {
1122
1124
auto *E = new (ExpressionAllocator) BasicExpression (I->getNumOperands ());
1123
1125
1124
1126
bool AllConstant = setBasicExpressionInfo (I, E);
@@ -1149,33 +1151,33 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
1149
1151
E->getOperand (1 )->getType () == I->getOperand (1 )->getType ()));
1150
1152
Value *V =
1151
1153
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 ;
1154
1156
} else if (isa<SelectInst>(I)) {
1155
1157
if (isa<Constant>(E->getOperand (0 )) ||
1156
1158
E->getOperand (1 ) == E->getOperand (2 )) {
1157
1159
assert (E->getOperand (1 )->getType () == I->getOperand (1 )->getType () &&
1158
1160
E->getOperand (2 )->getType () == I->getOperand (2 )->getType ());
1159
1161
Value *V = SimplifySelectInst (E->getOperand (0 ), E->getOperand (1 ),
1160
1162
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 ;
1163
1165
}
1164
1166
} else if (I->isBinaryOp ()) {
1165
1167
Value *V =
1166
1168
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 ;
1169
1171
} else if (auto *CI = dyn_cast<CastInst>(I)) {
1170
1172
Value *V =
1171
1173
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 ;
1174
1176
} else if (isa<GetElementPtrInst>(I)) {
1175
1177
Value *V = SimplifyGEPInst (
1176
1178
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 ;
1179
1181
} else if (AllConstant) {
1180
1182
// We don't bother trying to simplify unless all of the operands
1181
1183
// were constant.
@@ -1189,10 +1191,10 @@ const Expression *NewGVN::createExpression(Instruction *I) const {
1189
1191
C.emplace_back (cast<Constant>(Arg));
1190
1192
1191
1193
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 ;
1194
1196
}
1195
- return E ;
1197
+ return ExprResult::some (E) ;
1196
1198
}
1197
1199
1198
1200
const AggregateValueExpression *
@@ -1778,7 +1780,7 @@ NewGVN::performSymbolicAggrValueEvaluation(Instruction *I) const {
1778
1780
return createAggregateValueExpression (I);
1779
1781
}
1780
1782
1781
- const Expression * NewGVN::performSymbolicCmpEvaluation (Instruction *I) const {
1783
+ NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation (Instruction *I) const {
1782
1784
assert (isa<CmpInst>(I) && " Expected a cmp instruction." );
1783
1785
1784
1786
auto *CI = cast<CmpInst>(I);
@@ -1798,14 +1800,17 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
1798
1800
// of an assume.
1799
1801
auto *CmpPI = PredInfo->getPredicateInfoFor (I);
1800
1802
if (dyn_cast_or_null<PredicateAssume>(CmpPI))
1801
- return createConstantExpression (ConstantInt::getTrue (CI->getType ()));
1803
+ return ExprResult::some (
1804
+ createConstantExpression (ConstantInt::getTrue (CI->getType ())));
1802
1805
1803
1806
if (Op0 == Op1) {
1804
1807
// This condition does not depend on predicates, no need to add users
1805
1808
if (CI->isTrueWhenEqual ())
1806
- return createConstantExpression (ConstantInt::getTrue (CI->getType ()));
1809
+ return ExprResult::some (
1810
+ createConstantExpression (ConstantInt::getTrue (CI->getType ())));
1807
1811
else if (CI->isFalseWhenEqual ())
1808
- return createConstantExpression (ConstantInt::getFalse (CI->getType ()));
1812
+ return ExprResult::some (
1813
+ createConstantExpression (ConstantInt::getFalse (CI->getType ())));
1809
1814
}
1810
1815
1811
1816
// NOTE: Because we are comparing both operands here and below, and using
@@ -1865,30 +1870,30 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
1865
1870
if (CmpInst::isImpliedTrueByMatchingCmp (BranchPredicate,
1866
1871
OurPredicate)) {
1867
1872
addPredicateUsers (PI, I);
1868
- return createConstantExpression (
1869
- ConstantInt::getTrue (CI->getType ()));
1873
+ return ExprResult::some (
1874
+ createConstantExpression ( ConstantInt::getTrue (CI->getType () )));
1870
1875
}
1871
1876
1872
1877
if (CmpInst::isImpliedFalseByMatchingCmp (BranchPredicate,
1873
1878
OurPredicate)) {
1874
1879
addPredicateUsers (PI, I);
1875
- return createConstantExpression (
1876
- ConstantInt::getFalse (CI->getType ()));
1880
+ return ExprResult::some (
1881
+ createConstantExpression ( ConstantInt::getFalse (CI->getType () )));
1877
1882
}
1878
1883
} else {
1879
1884
// Just handle the ne and eq cases, where if we have the same
1880
1885
// operands, we may know something.
1881
1886
if (BranchPredicate == OurPredicate) {
1882
1887
addPredicateUsers (PI, I);
1883
1888
// 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 () )));
1886
1891
} else if (BranchPredicate ==
1887
1892
CmpInst::getInversePredicate (OurPredicate)) {
1888
1893
addPredicateUsers (PI, I);
1889
1894
// 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 () )));
1892
1897
}
1893
1898
}
1894
1899
}
@@ -1899,9 +1904,10 @@ const Expression *NewGVN::performSymbolicCmpEvaluation(Instruction *I) const {
1899
1904
}
1900
1905
1901
1906
// Substitute and symbolize the value before value numbering.
1902
- const Expression *
1907
+ NewGVN::ExprResult
1903
1908
NewGVN::performSymbolicEvaluation (Value *V,
1904
1909
SmallPtrSetImpl<Value *> &Visited) const {
1910
+
1905
1911
const Expression *E = nullptr ;
1906
1912
if (auto *C = dyn_cast<Constant>(V))
1907
1913
E = createConstantExpression (C);
@@ -1937,11 +1943,11 @@ NewGVN::performSymbolicEvaluation(Value *V,
1937
1943
break ;
1938
1944
case Instruction::BitCast:
1939
1945
case Instruction::AddrSpaceCast:
1940
- E = createExpression (I);
1946
+ return createExpression (I);
1941
1947
break ;
1942
1948
case Instruction::ICmp:
1943
1949
case Instruction::FCmp:
1944
- E = performSymbolicCmpEvaluation (I);
1950
+ return performSymbolicCmpEvaluation (I);
1945
1951
break ;
1946
1952
case Instruction::FNeg:
1947
1953
case Instruction::Add:
@@ -1977,16 +1983,16 @@ NewGVN::performSymbolicEvaluation(Value *V,
1977
1983
case Instruction::ExtractElement:
1978
1984
case Instruction::InsertElement:
1979
1985
case Instruction::GetElementPtr:
1980
- E = createExpression (I);
1986
+ return createExpression (I);
1981
1987
break ;
1982
1988
case Instruction::ShuffleVector:
1983
1989
// FIXME: Add support for shufflevector to createExpression.
1984
- return nullptr ;
1990
+ return ExprResult::none () ;
1985
1991
default :
1986
- return nullptr ;
1992
+ return ExprResult::none () ;
1987
1993
}
1988
1994
}
1989
- return E ;
1995
+ return ExprResult::some (E) ;
1990
1996
}
1991
1997
1992
1998
// 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 {
2007
2013
AdditionalUsers[To].insert (User);
2008
2014
}
2009
2015
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
+
2010
2022
void NewGVN::markUsersTouched (Value *V) {
2011
2023
// Now mark the users as touched.
2012
2024
for (auto *User : V->users ()) {
@@ -2414,9 +2426,14 @@ void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *B) {
2414
2426
Value *CondEvaluated = findConditionEquivalence (Cond);
2415
2427
if (!CondEvaluated) {
2416
2428
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 )) {
2419
2431
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 ;
2420
2437
}
2421
2438
} else if (isa<ConstantInt>(Cond)) {
2422
2439
CondEvaluated = Cond;
@@ -2600,7 +2617,9 @@ Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2600
2617
TempToBlock.insert ({TransInst, PredBB});
2601
2618
InstrDFS.insert ({TransInst, IDFSNum});
2602
2619
2603
- const Expression *E = performSymbolicEvaluation (TransInst, Visited);
2620
+ auto Res = performSymbolicEvaluation (TransInst, Visited);
2621
+ const Expression *E = Res.Expr ;
2622
+ addAdditionalUsers (Res, OrigInst);
2604
2623
InstrDFS.erase (TransInst);
2605
2624
AllTempInstructions.erase (TransInst);
2606
2625
TempToBlock.erase (TransInst);
@@ -3027,7 +3046,10 @@ void NewGVN::valueNumberInstruction(Instruction *I) {
3027
3046
const Expression *Symbolized = nullptr ;
3028
3047
SmallPtrSet<Value *, 2 > Visited;
3029
3048
if (DebugCounter::shouldExecute (VNCounter)) {
3030
- Symbolized = performSymbolicEvaluation (I, Visited);
3049
+ auto Res = performSymbolicEvaluation (I, Visited);
3050
+ Symbolized = Res.Expr ;
3051
+ addAdditionalUsers (Res, I);
3052
+
3031
3053
// Make a phi of ops if necessary
3032
3054
if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
3033
3055
!isa<VariableExpression>(Symbolized) && PHINodeUses.count (I)) {
0 commit comments