128#define DEBUG_TYPE "newgvn"
130STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
131STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
132STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
133STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
135 "Maximum Number of iterations it took to converge GVN");
136STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
137STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
139 "Number of avoided sorted leader changes");
140STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
141STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
143 "Number of things eliminated using PHI of ops");
145 "Controls which instructions are value numbered");
147 "Controls which instructions we create phi of ops for");
164namespace GVNExpression {
188 TarjanSCC() : Components(1) {}
191 if (Root.lookup(Start) == 0)
196 unsigned ComponentID = ValueToComponent.lookup(V);
199 "Asking for a component for a value we never processed");
200 return Components[ComponentID];
207 unsigned int OurDFS = DFSNum;
208 for (
const auto &
Op :
I->operands()) {
209 if (
auto *InstOp = dyn_cast<Instruction>(
Op)) {
210 if (Root.lookup(
Op) == 0)
212 if (!InComponent.count(
Op))
213 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
220 if (Root.lookup(
I) == OurDFS) {
221 unsigned ComponentID = Components.size();
222 Components.resize(Components.size() + 1);
226 InComponent.insert(
I);
227 ValueToComponent[
I] = ComponentID;
229 while (!
Stack.empty() && Root.lookup(
Stack.back()) >= OurDFS) {
233 InComponent.insert(Member);
234 ValueToComponent[
Member] = ComponentID;
243 unsigned int DFSNum = 1;
293class CongruenceClass {
295 using MemberType =
Value;
300 explicit CongruenceClass(
unsigned ID) :
ID(
ID) {}
301 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
303 :
ID(
ID), RepLeader(Leader), DefiningExpr(E) {}
305 unsigned getID()
const {
return ID; }
312 return empty() && memory_empty();
316 Value *getLeader()
const {
return RepLeader.first; }
317 void setLeader(std::pair<Value *, unsigned int> Leader) {
320 const std::pair<Value *, unsigned int> &getNextLeader()
const {
323 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
324 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
325 if (LeaderPair.second < RepLeader.second) {
326 NextLeader = RepLeader;
327 RepLeader = LeaderPair;
329 }
else if (LeaderPair.second < NextLeader.second) {
330 NextLeader = LeaderPair;
336 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
337 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
338 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
341 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
344 bool empty()
const {
return Members.empty(); }
345 unsigned size()
const {
return Members.size(); }
348 void insert(MemberType *M) { Members.insert(M); }
349 void erase(MemberType *M) { Members.erase(M); }
353 bool memory_empty()
const {
return MemoryMembers.empty(); }
354 unsigned memory_size()
const {
return MemoryMembers.size(); }
356 return MemoryMembers.begin();
359 return MemoryMembers.end();
362 return make_range(memory_begin(), memory_end());
365 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
366 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
369 unsigned getStoreCount()
const {
return StoreCount; }
370 void incStoreCount() { ++StoreCount; }
371 void decStoreCount() {
372 assert(StoreCount != 0 &&
"Store count went negative");
377 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
381 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
387 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
389 Other->RepMemoryAccess))
391 if (DefiningExpr !=
Other->DefiningExpr)
392 if (!DefiningExpr || !
Other->DefiningExpr ||
393 *DefiningExpr != *
Other->DefiningExpr)
396 if (Members.size() !=
Other->Members.size())
407 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
412 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
415 Value *RepStoredValue =
nullptr;
430 MemoryMemberSet MemoryMembers;
449 return E.exactlyEquals(
Other);
455 auto Val =
static_cast<uintptr_t
>(-1);
456 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
457 return reinterpret_cast<const Expression *
>(Val);
461 auto Val =
static_cast<uintptr_t
>(~1U);
462 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
463 return reinterpret_cast<const Expression *
>(Val);
467 return E->getComputedHash();
471 return E.getComputedHash();
475 if (
RHS == getTombstoneKey() ||
RHS == getEmptyKey())
483 if (
LHS == getTombstoneKey() ||
RHS == getTombstoneKey() ||
484 LHS == getEmptyKey() ||
RHS == getEmptyKey())
490 if (
LHS->getComputedHash() !=
RHS->getComputedHash())
514 mutable TarjanSCC SCCFinder;
516 std::unique_ptr<PredicateInfo> PredInfo;
520 unsigned int NumFuncArgs = 0;
531 CongruenceClass *TOPClass =
nullptr;
532 std::vector<CongruenceClass *> CongruenceClasses;
533 unsigned NextCongruenceNum = 0;
568 ExpressionToPhiOfOps;
617 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
620 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
625 ExpressionClassMap ExpressionToClass;
677 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
681 SQ(
DL, TLI, DT, AC, nullptr,
false,
695 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
696 ExprResult(
const ExprResult &) =
delete;
697 ExprResult(ExprResult &&
Other)
699 Other.Expr =
nullptr;
700 Other.ExtraDep =
nullptr;
701 Other.PredDep =
nullptr;
703 ExprResult &operator=(
const ExprResult &
Other) =
delete;
704 ExprResult &operator=(ExprResult &&
Other) =
delete;
706 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
708 operator bool()
const {
return Expr; }
710 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
711 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
712 return {Expr, ExtraDep,
nullptr};
714 static ExprResult some(
const Expression *Expr,
716 return {Expr,
nullptr, PredDep};
720 return {Expr, ExtraDep, PredDep};
731 using ValPair = std::pair<Value *, BasicBlock *>;
735 bool &OriginalOpsConstant)
const;
748 createAggregateValueExpression(
Instruction *)
const;
752 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
755 unsigned LeaderDFS = 0;
762 else if (
auto *
I = dyn_cast<Instruction>(Leader))
763 LeaderDFS = InstrToDFSNum(
I);
765 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
766 CongruenceClasses.emplace_back(result);
771 auto *CC = createCongruenceClass(
nullptr,
nullptr);
772 CC->setMemoryLeader(MA);
776 CongruenceClass *ensureLeaderOfMemoryClass(
MemoryAccess *MA) {
777 auto *CC = getMemoryClass(MA);
778 if (CC->getMemoryLeader() != MA)
779 CC = createMemoryClass(MA);
783 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
784 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
785 CClass->insert(Member);
786 ValueToClass[
Member] = CClass;
790 void initializeCongruenceClasses(
Function &
F);
808 ExprResult performSymbolicEvaluation(
Instruction *,
815 ExprResult performSymbolicCallEvaluation(
Instruction *)
const;
821 ExprResult performSymbolicCmpEvaluation(
Instruction *)
const;
822 ExprResult performSymbolicPredicateInfoEvaluation(
BitCastInst *)
const;
827 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
830 CongruenceClass *, CongruenceClass *);
832 CongruenceClass *, CongruenceClass *);
833 Value *getNextValueLeader(CongruenceClass *)
const;
834 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
836 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
841 unsigned int getRank(
const Value *)
const;
842 bool shouldSwapOperands(
const Value *,
const Value *)
const;
843 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
849 Value *findConditionEquivalence(
Value *)
const;
853 void convertClassToDFSOrdered(
const CongruenceClass &,
857 void convertClassToLoadsAndStores(
const CongruenceClass &,
860 bool eliminateInstructions(
Function &);
868 template <
typename Map,
typename KeyType>
869 void touchAndErase(Map &,
const KeyType &);
870 void markUsersTouched(
Value *);
874 void markValueLeaderChangeTouched(CongruenceClass *CC);
875 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
882 void iterateTouchedInstructions();
885 void cleanupTables();
886 std::pair<unsigned, unsigned> assignDFSNumbers(
BasicBlock *,
unsigned);
887 void updateProcessedCount(
const Value *V);
888 void verifyMemoryCongruency()
const;
889 void verifyIterationSettled(
Function &
F);
890 void verifyStoreExpressions()
const;
897 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
899 unsigned InstrToDFSNum(
const Value *V)
const {
900 assert(isa<Instruction>(V) &&
"This should not be used for MemoryAccesses");
901 return InstrDFS.
lookup(V);
905 return MemoryToDFSNum(MA);
908 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
913 unsigned MemoryToDFSNum(
const Value *MA)
const {
914 assert(isa<MemoryAccess>(MA) &&
915 "This should not be used with instructions");
916 return isa<MemoryUseOrDef>(MA)
917 ? InstrToDFSNum(cast<MemoryUseOrDef>(MA)->getMemoryInst())
933 if (!isa<LoadExpression>(
RHS) && !isa<StoreExpression>(
RHS))
935 return LHS.MemoryExpression::equals(
RHS);
946 if (
const auto *S = dyn_cast<StoreExpression>(&
Other))
956 if (
auto *
RHS = dyn_cast<CallExpression>(&
Other))
990 if (
auto *
I = dyn_cast<Instruction>(V)) {
991 auto *Parent =
I->getParent();
994 Parent = TempToBlock.
lookup(V);
995 assert(Parent &&
"Every fake instruction should have a block");
999 auto *MP = dyn_cast<MemoryPhi>(V);
1000 assert(MP &&
"Should have been an instruction or a MemoryPhi");
1001 return MP->getBlock();
1007void NewGVN::deleteExpression(
const Expression *
E)
const {
1008 assert(isa<BasicExpression>(
E));
1009 auto *BE = cast<BasicExpression>(
E);
1016 if (
auto *BC = dyn_cast<BitCastInst>(V))
1017 if (BC->getType() == BC->getOperand(0)->getType())
1018 return BC->getOperand(0);
1029 return CO && isa<PHINode>(CO);
1036 llvm::sort(Ops, [&](
const ValPair &P1,
const ValPair &P2) {
1037 return BlockInstRange.
lookup(
P1.second).first <
1038 BlockInstRange.
lookup(P2.second).first;
1046 return isa<Constant>(V) || isa<Argument>(V);
1058 bool &OriginalOpsConstant)
const {
1059 unsigned NumOps = PHIOperands.
size();
1060 auto *
E =
new (ExpressionAllocator)
PHIExpression(NumOps, PHIBlock);
1062 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1063 E->setType(PHIOperands.
begin()->first->getType());
1064 E->setOpcode(Instruction::PHI);
1068 auto *BB =
P.second;
1069 if (
auto *PHIOp = dyn_cast<PHINode>(
I))
1072 if (!ReachableEdges.
count({BB, PHIBlock}))
1075 if (ValueToClass.
lookup(
P.first) == TOPClass)
1077 OriginalOpsConstant = OriginalOpsConstant && isa<Constant>(
P.first);
1078 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1079 return lookupOperandLeader(
P.first) !=
I;
1082 return lookupOperandLeader(
P.first);
1090 bool AllConstant =
true;
1091 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I))
1092 E->setType(
GEP->getSourceElementType());
1094 E->setType(
I->getType());
1095 E->setOpcode(
I->getOpcode());
1096 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1101 auto Operand = lookupOperandLeader(O);
1102 AllConstant = AllConstant && isa<Constant>(Operand);
1109const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1118 E->setOpcode(Opcode);
1119 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1125 if (shouldSwapOperands(Arg1, Arg2))
1128 E->op_push_back(lookupOperandLeader(Arg1));
1129 E->op_push_back(lookupOperandLeader(Arg2));
1132 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1133 addAdditionalUsers(Simplified,
I);
1145 return ExprResult::none();
1147 if (
auto *
C = dyn_cast<Constant>(V)) {
1150 <<
" constant " << *
C <<
"\n");
1151 NumGVNOpsSimplified++;
1152 assert(isa<BasicExpression>(
E) &&
1153 "We should always have had a basic expression here");
1154 deleteExpression(
E);
1155 return ExprResult::some(createConstantExpression(
C));
1156 }
else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1159 <<
" variable " << *V <<
"\n");
1160 deleteExpression(
E);
1161 return ExprResult::some(createVariableExpression(V));
1164 CongruenceClass *CC = ValueToClass.
lookup(V);
1166 if (CC->getLeader() && CC->getLeader() !=
I) {
1167 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1169 if (CC->getDefiningExpr()) {
1172 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1173 NumGVNOpsSimplified++;
1174 deleteExpression(
E);
1175 return ExprResult::some(CC->getDefiningExpr(), V);
1179 return ExprResult::none();
1185NewGVN::ExprResult NewGVN::createExpression(
Instruction *
I)
const {
1191 bool AllConstant = setBasicExpressionInfo(
I,
E);
1193 if (
I->isCommutative()) {
1198 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1199 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1200 E->swapOperands(0, 1);
1203 if (
auto *CI = dyn_cast<CmpInst>(
I)) {
1207 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1208 E->swapOperands(0, 1);
1211 E->setOpcode((CI->getOpcode() << 8) |
Predicate);
1213 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1214 "Wrong types on cmp instruction");
1215 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1216 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1219 if (
auto Simplified = checkExprResults(
E,
I, V))
1221 }
else if (isa<SelectInst>(
I)) {
1222 if (isa<Constant>(
E->getOperand(0)) ||
1223 E->getOperand(1) ==
E->getOperand(2)) {
1224 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1225 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1227 E->getOperand(2), Q);
1228 if (
auto Simplified = checkExprResults(
E,
I, V))
1231 }
else if (
I->isBinaryOp()) {
1234 if (
auto Simplified = checkExprResults(
E,
I, V))
1236 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
1239 if (
auto Simplified = checkExprResults(
E,
I, V))
1241 }
else if (
auto *GEPI = dyn_cast<GetElementPtrInst>(
I)) {
1243 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1244 GEPI->getNoWrapFlags(), Q);
1245 if (
auto Simplified = checkExprResults(
E,
I, V))
1247 }
else if (AllConstant) {
1256 for (
Value *Arg :
E->operands())
1257 C.emplace_back(cast<Constant>(Arg));
1260 if (
auto Simplified = checkExprResults(
E,
I, V))
1263 return ExprResult::some(
E);
1267NewGVN::createAggregateValueExpression(
Instruction *
I)
const {
1268 if (
auto *
II = dyn_cast<InsertValueInst>(
I)) {
1269 auto *
E =
new (ExpressionAllocator)
1271 setBasicExpressionInfo(
I,
E);
1272 E->allocateIntOperands(ExpressionAllocator);
1275 }
else if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1276 auto *
E =
new (ExpressionAllocator)
1278 setBasicExpressionInfo(EI,
E);
1279 E->allocateIntOperands(ExpressionAllocator);
1289 return SingletonDeadExpression;
1294 E->setOpcode(
V->getValueID());
1299 if (
auto *
C = dyn_cast<Constant>(V))
1300 return createConstantExpression(
C);
1301 return createVariableExpression(V);
1306 E->setOpcode(
C->getValueID());
1312 E->setOpcode(
I->getOpcode());
1321 setBasicExpressionInfo(CI,
E);
1327 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1328 E->swapOperands(0, 1);
1334bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1336 auto *CC = ValueToClass.
lookup(Inst);
1357 if (DT->
dominates(cast<Instruction>(CC->getLeader()), U))
1359 if (CC->getNextLeader().first &&
1360 DT->
dominates(cast<Instruction>(CC->getNextLeader().first), U))
1363 return Member != CC->getLeader() &&
1364 DT->
dominates(cast<Instruction>(Member), U);
1370Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1371 CongruenceClass *CC = ValueToClass.
lookup(V);
1378 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1385 auto *CC = getMemoryClass(MA);
1386 assert(CC->getMemoryLeader() &&
1387 "Every MemoryAccess should be mapped to a congruence class with a "
1388 "representative memory access");
1389 return CC->getMemoryLeader();
1395bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1396 return getMemoryClass(MA) == TOPClass;
1403 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1404 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1405 E->setType(LoadType);
1409 E->op_push_back(PointerOp);
1419 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1420 auto *
E =
new (ExpressionAllocator)
1422 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1423 E->setType(
SI->getValueOperand()->getType());
1427 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1438 auto *
SI = cast<StoreInst>(
I);
1439 auto *StoreAccess = getMemoryAccess(SI);
1441 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1445 StoreRHS = lookupMemoryLeader(StoreRHS);
1446 if (StoreRHS != StoreAccess->getDefiningAccess())
1447 addMemoryUsers(StoreRHS, StoreAccess);
1449 if (StoreRHS == StoreAccess)
1452 if (
SI->isSimple()) {
1456 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1457 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1463 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1469 if (
auto *LI = dyn_cast<LoadInst>(LastStore->getStoredValue()))
1471 LastStore->getOperand(0)) &&
1472 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1475 deleteExpression(LastStore);
1481 return createStoreExpression(SI, StoreAccess);
1487NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1491 if (
auto *DepSI = dyn_cast<StoreInst>(DepInst)) {
1495 if (LI->
isAtomic() > DepSI->isAtomic() ||
1496 LoadType == DepSI->getValueOperand()->getType())
1500 if (
auto *
C = dyn_cast<Constant>(
1501 lookupOperandLeader(DepSI->getValueOperand()))) {
1504 <<
" to constant " << *Res <<
"\n");
1505 return createConstantExpression(Res);
1509 }
else if (
auto *DepLI = dyn_cast<LoadInst>(DepInst)) {
1511 if (LI->
isAtomic() > DepLI->isAtomic())
1516 if (
auto *
C = dyn_cast<Constant>(lookupOperandLeader(DepLI)))
1517 if (
auto *PossibleConstant =
1520 <<
" to constant " << *PossibleConstant <<
"\n");
1521 return createConstantExpression(PossibleConstant);
1524 }
else if (
auto *DepMI = dyn_cast<MemIntrinsic>(DepInst)) {
1527 if (
auto *PossibleConstant =
1530 <<
" to constant " << *PossibleConstant <<
"\n");
1531 return createConstantExpression(PossibleConstant);
1536 if (
auto *
II = dyn_cast<IntrinsicInst>(DepInst)) {
1537 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1538 auto *LifetimePtr =
II->getOperand(0);
1539 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1548 (LoadPtr != lookupOperandLeader(DepInst) &&
1555 if (isa<AllocaInst>(DepInst)) {
1557 }
else if (
auto *InitVal =
1559 return createConstantExpression(InitVal);
1565 auto *LI = cast<LoadInst>(
I);
1574 if (isa<UndefValue>(LoadAddressLeader))
1581 if (
auto *MD = dyn_cast<MemoryDef>(DefiningAccess)) {
1590 if (
const auto *CoercionResult =
1591 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1592 DefiningInst, DefiningAccess))
1593 return CoercionResult;
1597 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1601 if (
LE->getMemoryLeader() != DefiningAccess)
1602 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1607NewGVN::performSymbolicPredicateInfoEvaluation(
BitCastInst *
I)
const {
1608 auto *PI = PredInfo->getPredicateInfoFor(
I);
1610 return ExprResult::none();
1612 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1614 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1616 return ExprResult::none();
1619 Value *CmpOp0 =
I->getOperand(0);
1620 Value *CmpOp1 = Constraint->OtherOp;
1622 Value *FirstOp = lookupOperandLeader(CmpOp0);
1623 Value *SecondOp = lookupOperandLeader(CmpOp1);
1624 Value *AdditionallyUsedValue = CmpOp0;
1627 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1630 AdditionallyUsedValue = CmpOp1;
1634 return ExprResult::some(createVariableOrConstant(FirstOp),
1635 AdditionallyUsedValue, PI);
1639 !cast<ConstantFP>(FirstOp)->
isZero())
1640 return ExprResult::some(createConstantExpression(cast<Constant>(FirstOp)),
1641 AdditionallyUsedValue, PI);
1643 return ExprResult::none();
1647NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(
Instruction *
I)
const {
1648 auto *CI = cast<CallInst>(
I);
1649 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
1650 if (
auto *ReturnedValue =
II->getReturnedArgOperand())
1651 return ExprResult::some(createVariableOrConstant(ReturnedValue));
1662 return ExprResult::none();
1668 return ExprResult::none();
1671 return ExprResult::some(
1672 createCallExpression(CI, TOPClass->getMemoryLeader()));
1676 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1678 return ExprResult::some(
1679 createCallExpression(CI, TOPClass->getMemoryLeader()));
1681 return ExprResult::none();
1685CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1687 assert(Result &&
"Should have found memory class");
1694 CongruenceClass *NewClass) {
1696 "Every MemoryAccess should be getting mapped to a non-null class");
1700 <<
" with current MemoryAccess leader ");
1704 bool Changed =
false;
1706 if (LookupResult != MemoryAccessToClass.
end()) {
1708 if (OldClass != NewClass) {
1710 if (
auto *MP = dyn_cast<MemoryPhi>(
From)) {
1711 OldClass->memory_erase(MP);
1712 NewClass->memory_insert(MP);
1714 if (OldClass->getMemoryLeader() ==
From) {
1715 if (OldClass->definesNoMemory()) {
1716 OldClass->setMemoryLeader(
nullptr);
1718 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1720 << OldClass->getID() <<
" to "
1721 << *OldClass->getMemoryLeader()
1722 <<
" due to removal of a memory member " << *
From
1724 markMemoryLeaderChangeTouched(OldClass);
1747 auto ICS = InstCycleState.
lookup(
I);
1748 if (ICS == ICS_Unknown) {
1750 auto &
SCC = SCCFinder.getComponentFor(
I);
1752 if (
SCC.size() == 1)
1753 InstCycleState.
insert({
I, ICS_CycleFree});
1758 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1759 for (
const auto *Member : SCC)
1760 if (
auto *MemberPhi = dyn_cast<PHINode>(Member))
1761 InstCycleState.
insert({MemberPhi, ICS});
1764 if (ICS == ICS_Cycle)
1775 bool HasBackedge =
false;
1780 bool OriginalOpsConstant =
true;
1781 auto *
E = cast<PHIExpression>(createPHIExpression(
1782 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1786 bool HasUndef =
false, HasPoison =
false;
1788 if (isa<PoisonValue>(Arg)) {
1792 if (isa<UndefValue>(Arg)) {
1799 if (Filtered.empty()) {
1804 dbgs() <<
"PHI Node " << *
I
1805 <<
" has no non-undef arguments, valuing it as undef\n");
1810 dbgs() <<
"PHI Node " << *
I
1811 <<
" has no non-poison arguments, valuing it as poison\n");
1815 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1816 deleteExpression(
E);
1817 return createDeadExpression();
1819 Value *AllSameValue = *(Filtered.begin());
1837 if (HasPoison || HasUndef) {
1843 if (HasBackedge && !OriginalOpsConstant &&
1844 !isa<UndefValue>(AllSameValue) && !isCycleFree(
I))
1848 if (
auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
1849 if (!someEquivalentDominates(AllSameInst,
I))
1855 if (isa<Instruction>(AllSameValue) &&
1856 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1858 NumGVNPhisAllSame++;
1859 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1861 deleteExpression(
E);
1862 return createVariableOrConstant(AllSameValue);
1868NewGVN::performSymbolicAggrValueEvaluation(
Instruction *
I)
const {
1869 if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1870 auto *WO = dyn_cast<WithOverflowInst>(EI->getAggregateOperand());
1871 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1875 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1876 WO->getLHS(), WO->getRHS(),
I);
1879 return createAggregateValueExpression(
I);
1882NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(
Instruction *
I)
const {
1883 assert(isa<CmpInst>(
I) &&
"Expected a cmp instruction.");
1885 auto *CI = cast<CmpInst>(
I);
1888 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1889 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1890 auto OurPredicate = CI->getPredicate();
1891 if (shouldSwapOperands(Op0, Op1)) {
1893 OurPredicate = CI->getSwappedPredicate();
1900 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1901 if (isa_and_nonnull<PredicateAssume>(CmpPI))
1902 return ExprResult::some(
1907 if (CI->isTrueWhenEqual())
1908 return ExprResult::some(
1910 else if (CI->isFalseWhenEqual())
1911 return ExprResult::some(
1941 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1942 if (
const auto *PBranch = dyn_cast_or_null<PredicateBranch>(PI)) {
1943 if (PI == LastPredInfo)
1948 if (!DT->
dominates(PBranch->To,
I->getParent()))
1955 auto *BranchCond = dyn_cast<CmpInst>(PBranch->Condition);
1958 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1959 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1960 auto BranchPredicate = BranchCond->getPredicate();
1961 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1963 BranchPredicate = BranchCond->getSwappedPredicate();
1965 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1966 if (PBranch->TrueEdge) {
1972 return ExprResult::some(createConstantExpression(
C), PI);
1977 if (BranchPredicate == OurPredicate) {
1979 return ExprResult::some(
1982 }
else if (BranchPredicate ==
1985 return ExprResult::some(
1994 return createExpression(
I);
2006 switch (
I->getOpcode()) {
2007 case Instruction::ExtractValue:
2008 case Instruction::InsertValue:
2009 E = performSymbolicAggrValueEvaluation(
I);
2011 case Instruction::PHI: {
2013 auto *PN = cast<PHINode>(
I);
2014 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
2015 Ops.
push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2018 E = performSymbolicPHIEvaluation(Ops,
I, getBlockForValue(
I));
2020 case Instruction::Call:
2021 return performSymbolicCallEvaluation(
I);
2023 case Instruction::Store:
2024 E = performSymbolicStoreEvaluation(
I);
2026 case Instruction::Load:
2027 E = performSymbolicLoadEvaluation(
I);
2029 case Instruction::BitCast:
2031 if (
I->getType() ==
I->getOperand(0)->getType())
2033 performSymbolicPredicateInfoEvaluation(cast<BitCastInst>(
I)))
2036 case Instruction::AddrSpaceCast:
2037 case Instruction::Freeze:
2038 return createExpression(
I);
2040 case Instruction::ICmp:
2041 case Instruction::FCmp:
2042 return performSymbolicCmpEvaluation(
I);
2044 case Instruction::FNeg:
2045 case Instruction::Add:
2046 case Instruction::FAdd:
2047 case Instruction::Sub:
2048 case Instruction::FSub:
2049 case Instruction::Mul:
2050 case Instruction::FMul:
2051 case Instruction::UDiv:
2052 case Instruction::SDiv:
2053 case Instruction::FDiv:
2054 case Instruction::URem:
2055 case Instruction::SRem:
2056 case Instruction::FRem:
2057 case Instruction::Shl:
2058 case Instruction::LShr:
2059 case Instruction::AShr:
2060 case Instruction::And:
2061 case Instruction::Or:
2062 case Instruction::Xor:
2063 case Instruction::Trunc:
2064 case Instruction::ZExt:
2065 case Instruction::SExt:
2066 case Instruction::FPToUI:
2067 case Instruction::FPToSI:
2068 case Instruction::UIToFP:
2069 case Instruction::SIToFP:
2070 case Instruction::FPTrunc:
2071 case Instruction::FPExt:
2072 case Instruction::PtrToInt:
2073 case Instruction::IntToPtr:
2074 case Instruction::Select:
2075 case Instruction::ExtractElement:
2076 case Instruction::InsertElement:
2077 case Instruction::GetElementPtr:
2078 return createExpression(
I);
2080 case Instruction::ShuffleVector:
2082 return ExprResult::none();
2084 return ExprResult::none();
2086 return ExprResult::some(
E);
2091template <
typename Map,
typename KeyType>
2092void NewGVN::touchAndErase(Map &M,
const KeyType &Key) {
2093 const auto Result =
M.find_as(Key);
2094 if (Result !=
M.end()) {
2095 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2096 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2103 if (isa<Instruction>(To))
2107void NewGVN::addAdditionalUsers(ExprResult &Res,
Instruction *
User)
const {
2108 if (Res.ExtraDep && Res.ExtraDep !=
User)
2109 addAdditionalUsers(Res.ExtraDep,
User);
2110 Res.ExtraDep =
nullptr;
2113 if (
const auto *PBranch = dyn_cast<PredicateBranch>(Res.PredDep))
2114 PredicateToUsers[PBranch->Condition].
insert(
User);
2115 else if (
const auto *PAssume = dyn_cast<PredicateAssume>(Res.PredDep))
2116 PredicateToUsers[PAssume->Condition].
insert(
User);
2118 Res.PredDep =
nullptr;
2121void NewGVN::markUsersTouched(
Value *V) {
2123 for (
auto *
User :
V->users()) {
2124 assert(isa<Instruction>(
User) &&
"Use of value not within an instruction?");
2125 TouchedInstructions.
set(InstrToDFSNum(
User));
2127 touchAndErase(AdditionalUsers, V);
2131 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2132 MemoryToUsers[To].
insert(U);
2135void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2136 TouchedInstructions.
set(MemoryToDFSNum(MA));
2139void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2140 if (isa<MemoryUse>(MA))
2142 for (
const auto *U : MA->
users())
2143 TouchedInstructions.
set(MemoryToDFSNum(U));
2144 touchAndErase(MemoryToUsers, MA);
2148void NewGVN::markPredicateUsersTouched(
Instruction *
I) {
2149 touchAndErase(PredicateToUsers,
I);
2153void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2154 for (
const auto *M : CC->memory())
2155 markMemoryDefTouched(M);
2160void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2161 for (
auto *M : *CC) {
2162 if (
auto *
I = dyn_cast<Instruction>(M))
2163 TouchedInstructions.
set(InstrToDFSNum(
I));
2170template <
class T,
class Range>
2171T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2172 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2173 for (
const auto X : R) {
2174 auto DFSNum = InstrToDFSNum(
X);
2175 if (DFSNum < MinDFS.second)
2176 MinDFS = {
X, DFSNum};
2178 return MinDFS.first;
2184const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2188 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2189 if (CC->getStoreCount() > 0) {
2190 if (
auto *NL = dyn_cast_or_null<StoreInst>(CC->getNextLeader().first))
2191 return getMemoryAccess(NL);
2194 *CC, [&](
const Value *V) {
return isa<StoreInst>(V); }));
2195 return getMemoryAccess(cast<StoreInst>(V));
2197 assert(CC->getStoreCount() == 0);
2201 if (CC->memory_size() == 1)
2202 return *CC->memory_begin();
2203 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2209Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2214 if (CC->size() == 1 || CC == TOPClass) {
2215 return *(CC->begin());
2216 }
else if (CC->getNextLeader().first) {
2217 ++NumGVNAvoidedSortedLeaderChanges;
2218 return CC->getNextLeader().first;
2220 ++NumGVNSortedLeaderChanges;
2224 return getMinDFSOfRange<Value>(*CC);
2237void NewGVN::moveMemoryToNewCongruenceClass(
Instruction *
I,
2239 CongruenceClass *OldClass,
2240 CongruenceClass *NewClass) {
2243 assert((!InstMA || !OldClass->getMemoryLeader() ||
2244 OldClass->getLeader() !=
I ||
2245 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2246 MemoryAccessToClass.
lookup(InstMA)) &&
2247 "Representative MemoryAccess mismatch");
2249 if (!NewClass->getMemoryLeader()) {
2251 assert(NewClass->size() == 1 ||
2252 (isa<StoreInst>(
I) && NewClass->getStoreCount() == 1));
2253 NewClass->setMemoryLeader(InstMA);
2256 << NewClass->getID()
2257 <<
" due to new memory instruction becoming leader\n");
2258 markMemoryLeaderChangeTouched(NewClass);
2260 setMemoryClass(InstMA, NewClass);
2262 if (OldClass->getMemoryLeader() == InstMA) {
2263 if (!OldClass->definesNoMemory()) {
2264 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2266 << OldClass->getID() <<
" to "
2267 << *OldClass->getMemoryLeader()
2268 <<
" due to removal of old leader " << *InstMA <<
"\n");
2269 markMemoryLeaderChangeTouched(OldClass);
2271 OldClass->setMemoryLeader(
nullptr);
2278 CongruenceClass *OldClass,
2279 CongruenceClass *NewClass) {
2280 if (
I == OldClass->getNextLeader().first)
2281 OldClass->resetNextLeader();
2284 NewClass->insert(
I);
2288 if (NewClass->getLeader() !=
I &&
2289 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2290 markValueLeaderChangeTouched(NewClass);
2294 if (
auto *SI = dyn_cast<StoreInst>(
I)) {
2295 OldClass->decStoreCount();
2303 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2306 if (
auto *SE = dyn_cast<StoreExpression>(
E)) {
2307 NewClass->setStoredValue(SE->getStoredValue());
2308 markValueLeaderChangeTouched(NewClass);
2311 << NewClass->getID() <<
" from "
2312 << *NewClass->getLeader() <<
" to " << *SI
2313 <<
" because store joined class\n");
2316 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2320 NewClass->incStoreCount();
2326 auto *InstMA = dyn_cast_or_null<MemoryDef>(getMemoryAccess(
I));
2328 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2329 ValueToClass[
I] = NewClass;
2331 if (OldClass->empty() && OldClass != TOPClass) {
2332 if (OldClass->getDefiningExpr()) {
2333 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2334 <<
" from table\n");
2337 auto Iter = ExpressionToClass.find_as(
2339 if (Iter != ExpressionToClass.end())
2340 ExpressionToClass.erase(Iter);
2341#ifdef EXPENSIVE_CHECKS
2343 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2344 "We erased the expression we just inserted, which should not happen");
2347 }
else if (OldClass->getLeader() ==
I) {
2352 << OldClass->getID() <<
"\n");
2353 ++NumGVNLeaderChanges;
2358 if (OldClass->getStoreCount() == 0) {
2359 if (OldClass->getStoredValue())
2360 OldClass->setStoredValue(
nullptr);
2362 OldClass->setLeader({getNextValueLeader(OldClass),
2363 InstrToDFSNum(getNextValueLeader(OldClass))});
2364 OldClass->resetNextLeader();
2365 markValueLeaderChangeTouched(OldClass);
2371void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2372 touchAndErase(ExpressionToPhiOfOps,
E);
2380 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2381 assert(IClass &&
"Should have found a IClass");
2383 assert(!IClass->isDead() &&
"Found a dead class");
2385 CongruenceClass *EClass =
nullptr;
2386 if (
const auto *VE = dyn_cast<VariableExpression>(
E)) {
2387 EClass = ValueToClass.
lookup(VE->getVariableValue());
2388 }
else if (isa<DeadExpression>(
E)) {
2392 auto lookupResult = ExpressionToClass.try_emplace(
E);
2395 if (lookupResult.second) {
2396 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2397 auto place = lookupResult.first;
2398 place->second = NewClass;
2401 if (
const auto *CE = dyn_cast<ConstantExpression>(
E)) {
2402 NewClass->setLeader({
CE->getConstantValue(), 0});
2403 }
else if (
const auto *SE = dyn_cast<StoreExpression>(
E)) {
2405 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2406 NewClass->setStoredValue(SE->getStoredValue());
2410 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2412 assert(!isa<VariableExpression>(
E) &&
2413 "VariableExpression should have been handled already");
2417 <<
" using expression " << *
E <<
" at "
2418 << NewClass->getID() <<
" and leader "
2419 << *(NewClass->getLeader()));
2420 if (NewClass->getStoredValue())
2422 << *(NewClass->getStoredValue()));
2425 EClass = lookupResult.first->second;
2426 if (isa<ConstantExpression>(
E))
2427 assert((isa<Constant>(EClass->getLeader()) ||
2428 (EClass->getStoredValue() &&
2429 isa<Constant>(EClass->getStoredValue()))) &&
2430 "Any class with a constant expression should have a "
2433 assert(EClass &&
"Somehow don't have an eclass");
2435 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2438 bool ClassChanged = IClass != EClass;
2439 bool LeaderChanged = LeaderChanges.
erase(
I);
2440 if (ClassChanged || LeaderChanged) {
2441 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2444 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2445 markPhiOfOpsChanged(
E);
2448 markUsersTouched(
I);
2450 markMemoryUsersTouched(MA);
2451 if (
auto *CI = dyn_cast<CmpInst>(
I))
2452 markPredicateUsersTouched(CI);
2458 if (ClassChanged && isa<StoreInst>(
I)) {
2459 auto *OldE = ValueToExpression.
lookup(
I);
2462 if (OldE && isa<StoreExpression>(OldE) && *
E != *OldE) {
2466 if (Iter != ExpressionToClass.end())
2467 ExpressionToClass.erase(Iter);
2470 ValueToExpression[
I] =
E;
2477 if (ReachableEdges.
insert({From, To}).second) {
2479 if (ReachableBlocks.
insert(To).second) {
2481 <<
" marked reachable\n");
2482 const auto &InstRange = BlockInstRange.
lookup(To);
2483 TouchedInstructions.
set(InstRange.first, InstRange.second);
2486 <<
" was reachable, but new edge {"
2488 <<
"} to it found\n");
2495 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2500 for (
auto InstNum : RevisitOnReachabilityChange[To])
2501 TouchedInstructions.
set(InstNum);
2510 return isa<Constant>(Result) ?
Result :
nullptr;
2519 Value *CondEvaluated = findConditionEquivalence(
Cond);
2520 if (!CondEvaluated) {
2521 if (
auto *
I = dyn_cast<Instruction>(
Cond)) {
2523 auto Res = performSymbolicEvaluation(
I, Visited);
2524 if (
const auto *CE = dyn_cast_or_null<ConstantExpression>(Res.Expr)) {
2525 CondEvaluated =
CE->getConstantValue();
2526 addAdditionalUsers(Res,
I);
2530 Res.ExtraDep =
nullptr;
2532 }
else if (isa<ConstantInt>(
Cond)) {
2533 CondEvaluated =
Cond;
2537 if (CondEvaluated && (CI = dyn_cast<ConstantInt>(CondEvaluated))) {
2540 <<
" evaluated to true\n");
2541 updateReachableEdge(
B, TrueSucc);
2542 }
else if (CI->
isZero()) {
2544 <<
" evaluated to false\n");
2545 updateReachableEdge(
B, FalseSucc);
2548 updateReachableEdge(
B, TrueSucc);
2549 updateReachableEdge(
B, FalseSucc);
2551 }
else if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
2555 Value *SwitchCond =
SI->getCondition();
2556 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2558 if (CondEvaluated && isa<ConstantInt>(CondEvaluated)) {
2559 auto *CondVal = cast<ConstantInt>(CondEvaluated);
2561 auto Case = *
SI->findCaseValue(CondVal);
2562 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2566 updateReachableEdge(
B,
SI->getDefaultDest());
2570 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2571 updateReachableEdge(
B, TargetBlock);
2574 updateReachableEdge(
B, TargetBlock);
2580 updateReachableEdge(
B, TargetBlock);
2585 auto *MA = getMemoryAccess(TI);
2586 if (MA && !isa<MemoryUse>(MA)) {
2587 auto *CC = ensureLeaderOfMemoryClass(MA);
2588 if (setMemoryClass(MA, CC))
2589 markMemoryUsersTouched(MA);
2596 InstrDFS.
erase(PHITemp);
2599 TempToBlock.
erase(PHITemp);
2610 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2612 TempToBlock[
Op] = BB;
2613 RealToTemp[ExistingValue] =
Op;
2616 for (
auto *U : ExistingValue->
users())
2617 if (
auto *UI = dyn_cast<Instruction>(U))
2624 return isa<BinaryOperator>(
I) || isa<SelectInst>(
I) || isa<CmpInst>(
I) ||
2639 while (!Worklist.
empty()) {
2641 if (!isa<Instruction>(
I))
2644 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2645 if (OISIt != OpSafeForPHIOfOps.
end())
2646 return OISIt->second;
2651 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2655 if (isa<PHINode>(
I) && getBlockForValue(
I) == PHIBlock) {
2656 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2660 auto *OrigI = cast<Instruction>(
I);
2667 if (OrigI->mayReadFromMemory())
2671 for (
auto *
Op : OrigI->operand_values()) {
2672 if (!isa<Instruction>(
Op))
2675 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2676 if (OISIt != OpSafeForPHIOfOps.
end()) {
2677 if (!OISIt->second) {
2678 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2688 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2701 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2703 AllTempInstructions.
insert(TransInst);
2707 TempToBlock.
insert({TransInst, PredBB});
2708 InstrDFS.
insert({TransInst, IDFSNum});
2710 auto Res = performSymbolicEvaluation(TransInst, Visited);
2712 addAdditionalUsers(Res, OrigInst);
2713 InstrDFS.
erase(TransInst);
2714 AllTempInstructions.
erase(TransInst);
2715 TempToBlock.
erase(TransInst);
2717 TempToMemory.
erase(TransInst);
2720 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2722 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2723 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2727 if (
auto *SI = dyn_cast<StoreInst>(FoundVal))
2728 FoundVal =
SI->getValueOperand();
2740 if (!Visited.
insert(
I).second)
2746 if (!isCycleFree(
I))
2752 auto *MemAccess = getMemoryAccess(
I);
2756 if (MemAccess && !isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2757 MemAccess->getDefiningAccess()->
getBlock() ==
I->getParent())
2767 for (
auto *
Op : Ops) {
2768 if (!isa<PHINode>(
Op)) {
2769 auto *ValuePHI = RealToTemp.
lookup(
Op);
2775 OpPHI = cast<PHINode>(
Op);
2776 if (!SamePHIBlock) {
2777 SamePHIBlock = getBlockForValue(OpPHI);
2778 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2781 <<
"PHIs for operands are not all in the same block, aborting\n");
2796 auto *PHIBlock = getBlockForValue(OpPHI);
2797 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2798 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2800 Value *FoundVal =
nullptr;
2804 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2812 TempToMemory.
insert({ValueOp, MemAccess});
2813 bool SafeForPHIOfOps =
true;
2816 auto *OrigOp = &*
Op;
2819 if (isa<PHINode>(
Op)) {
2820 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2821 if (
Op != OrigOp &&
Op !=
I)
2823 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2824 if (getBlockForValue(ValuePHI) == PHIBlock)
2825 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2830 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2837 FoundVal = !SafeForPHIOfOps ? nullptr
2838 : findLeaderForInst(ValueOp, Visited,
2839 MemAccess,
I, PredBB);
2844 if (SafeForPHIOfOps)
2845 for (
auto *Dep : CurrentDeps)
2846 addAdditionalUsers(Dep,
I);
2852 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2854 <<
" because the block is unreachable\n");
2856 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2860 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2863 for (
auto *Dep : Deps)
2864 addAdditionalUsers(Dep,
I);
2866 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2867 if (isa<ConstantExpression>(
E) || isa<VariableExpression>(
E)) {
2870 <<
"Not creating real PHI of ops because it simplified to existing "
2871 "value or constant\n");
2877 for (
auto &O : PHIOps)
2878 addAdditionalUsers(
O.first,
I);
2882 auto *ValuePHI = RealToTemp.
lookup(
I);
2883 bool NewPHI =
false;
2887 addPhiOfOps(ValuePHI, PHIBlock,
I);
2889 NumGVNPHIOfOpsCreated++;
2892 for (
auto PHIOp : PHIOps)
2893 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2895 TempToBlock[ValuePHI] = PHIBlock;
2897 for (
auto PHIOp : PHIOps) {
2898 ValuePHI->setIncomingValue(i, PHIOp.first);
2899 ValuePHI->setIncomingBlock(i, PHIOp.second);
2903 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2904 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2913void NewGVN::initializeCongruenceClasses(
Function &
F) {
2914 NextCongruenceNum = 0;
2924 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2930 for (
auto *DTN :
nodes(DT)) {
2937 if (MemoryBlockDefs)
2938 for (
const auto &Def : *MemoryBlockDefs) {
2939 MemoryAccessToClass[&
Def] = TOPClass;
2940 auto *MD = dyn_cast<MemoryDef>(&Def);
2943 const MemoryPhi *MP = cast<MemoryPhi>(&Def);
2944 TOPClass->memory_insert(MP);
2945 MemoryPhiState.
insert({MP, MPS_TOP});
2948 if (MD && isa<StoreInst>(MD->getMemoryInst()))
2949 TOPClass->incStoreCount();
2955 for (
auto &
I : *BB) {
2956 if (isa<PHINode>(&
I))
2957 for (
auto *U :
I.users())
2958 if (
auto *UInst = dyn_cast<Instruction>(U))
2960 PHINodeUses.
insert(UInst);
2963 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2965 TOPClass->insert(&
I);
2966 ValueToClass[&
I] = TOPClass;
2971 for (
auto &FA :
F.args())
2972 createSingletonCongruenceClass(&FA);
2975void NewGVN::cleanupTables() {
2976 for (CongruenceClass *&CC : CongruenceClasses) {
2977 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2978 << CC->size() <<
" members\n");
2987 AllTempInstructions.
end());
2988 AllTempInstructions.
clear();
2992 for (
auto *
I : TempInst) {
2993 I->dropAllReferences();
2996 while (!TempInst.empty()) {
2997 auto *
I = TempInst.pop_back_val();
3001 ValueToClass.
clear();
3002 ArgRecycler.
clear(ExpressionAllocator);
3003 ExpressionAllocator.
Reset();
3004 CongruenceClasses.clear();
3005 ExpressionToClass.clear();
3006 ValueToExpression.
clear();
3008 AdditionalUsers.
clear();
3009 ExpressionToPhiOfOps.
clear();
3010 TempToBlock.
clear();
3011 TempToMemory.
clear();
3012 PHINodeUses.
clear();
3013 OpSafeForPHIOfOps.
clear();
3014 ReachableBlocks.
clear();
3015 ReachableEdges.
clear();
3017 ProcessedCount.
clear();
3020 InstructionsToErase.
clear();
3022 BlockInstRange.
clear();
3023 TouchedInstructions.
clear();
3024 MemoryAccessToClass.
clear();
3025 PredicateToUsers.
clear();
3026 MemoryToUsers.
clear();
3027 RevisitOnReachabilityChange.
clear();
3028 PredicateSwapChoice.
clear();
3033std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(
BasicBlock *
B,
3035 unsigned End = Start;
3037 InstrDFS[MemPhi] =
End++;
3042 for (
auto &
I : *
B) {
3048 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3050 markInstructionForDeletion(&
I);
3053 if (isa<PHINode>(&
I))
3054 RevisitOnReachabilityChange[
B].set(
End);
3055 InstrDFS[&
I] =
End++;
3062 return std::make_pair(Start,
End);
3065void NewGVN::updateProcessedCount(
const Value *V) {
3067 assert(++ProcessedCount[V] < 100 &&
3068 "Seem to have processed the same Value a lot");
3073void NewGVN::valueNumberMemoryPhi(
MemoryPhi *MP) {
3080 return cast<MemoryAccess>(U) != MP &&
3081 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3082 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3087 if (Filtered.begin() == Filtered.end()) {
3088 if (setMemoryClass(MP, TOPClass))
3089 markMemoryUsersTouched(MP);
3095 auto LookupFunc = [&](
const Use &
U) {
3096 return lookupMemoryLeader(cast<MemoryAccess>(U));
3098 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3099 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3103 const auto *AllSameValue = *MappedBegin;
3105 bool AllEqual = std::all_of(
3106 MappedBegin, MappedEnd,
3107 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3110 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3119 CongruenceClass *CC =
3120 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3121 auto OldState = MemoryPhiState.
lookup(MP);
3122 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3123 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3124 MemoryPhiState[MP] = NewState;
3125 if (setMemoryClass(MP, CC) || OldState != NewState)
3126 markMemoryUsersTouched(MP);
3133 if (!
I->isTerminator()) {
3137 auto Res = performSymbolicEvaluation(
I, Visited);
3138 Symbolized = Res.Expr;
3139 addAdditionalUsers(Res,
I);
3142 if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
3143 !isa<VariableExpression>(Symbolized) && PHINodeUses.
count(
I)) {
3144 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3149 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3150 removePhiOfOps(
I,
Op);
3159 if (Symbolized ==
nullptr)
3160 Symbolized = createUnknownExpression(
I);
3161 performCongruenceFinding(
I, Symbolized);
3166 if (!
I->getType()->isVoidTy()) {
3167 auto *Symbolized = createUnknownExpression(
I);
3168 performCongruenceFinding(
I, Symbolized);
3170 processOutgoingEdges(
I,
I->getParent());
3176bool NewGVN::singleReachablePHIPath(
3179 if (
First == Second)
3192 const auto *EndDef =
First;
3194 if (ChainDef == Second)
3200 auto *MP = cast<MemoryPhi>(EndDef);
3201 auto ReachableOperandPred = [&](
const Use &
U) {
3204 auto FilteredPhiArgs =
3209 return singleReachablePHIPath(Visited, cast<MemoryAccess>(OperandList[0]),
3218void NewGVN::verifyMemoryCongruency()
const {
3221 for (
const auto *CC : CongruenceClasses) {
3222 if (CC == TOPClass || CC->isDead())
3224 if (CC->getStoreCount() != 0) {
3225 assert((CC->getStoredValue() || !isa<StoreInst>(CC->getLeader())) &&
3226 "Any class with a store as a leader should have a "
3227 "representative stored value");
3228 assert(CC->getMemoryLeader() &&
3229 "Any congruence class with a store should have a "
3230 "representative access");
3233 if (CC->getMemoryLeader())
3234 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3235 "Representative MemoryAccess does not appear to be reverse "
3237 for (
const auto *M : CC->memory())
3239 "Memory member does not appear to be reverse mapped properly");
3247 auto ReachableAccessPred =
3248 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3249 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3251 MemoryToDFSNum(Pair.first) == 0)
3253 if (
auto *MemDef = dyn_cast<MemoryDef>(Pair.first))
3258 if (
auto *MemPHI = dyn_cast<MemoryPhi>(Pair.first)) {
3259 for (
const auto &U : MemPHI->incoming_values()) {
3260 if (
auto *
I = dyn_cast<Instruction>(&*U)) {
3272 for (
auto KV : Filtered) {
3273 if (
auto *FirstMUD = dyn_cast<MemoryUseOrDef>(KV.first)) {
3274 auto *SecondMUD = dyn_cast<MemoryUseOrDef>(KV.second->getMemoryLeader());
3275 if (FirstMUD && SecondMUD) {
3277 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3278 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3279 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3280 "The instructions for these memory operations should have "
3281 "been in the same congruence class or reachable through"
3282 "a single argument phi");
3284 }
else if (
auto *FirstMP = dyn_cast<MemoryPhi>(KV.first)) {
3287 auto ReachableOperandPred = [&](
const Use &
U) {
3288 return ReachableEdges.
count(
3289 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3293 auto FilteredPhiArgs =
3296 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3297 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3298 const MemoryDef *MD = cast<MemoryDef>(U);
3299 return ValueToClass.lookup(MD->getMemoryInst());
3302 "All MemoryPhi arguments should be in the same class");
3311void NewGVN::verifyIterationSettled(
Function &
F) {
3321 std::map<const Value *, CongruenceClass> BeforeIteration;
3323 for (
auto &KV : ValueToClass) {
3324 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3326 if (InstrToDFSNum(
I) == 0)
3328 BeforeIteration.insert({KV.first, *KV.second});
3331 TouchedInstructions.
set();
3332 TouchedInstructions.
reset(0);
3333 OpSafeForPHIOfOps.
clear();
3335 iterateTouchedInstructions();
3338 for (
const auto &KV : ValueToClass) {
3339 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3341 if (InstrToDFSNum(
I) == 0)
3345 auto *BeforeCC = &BeforeIteration.
find(KV.first)->second;
3346 auto *AfterCC = KV.second;
3349 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3350 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3351 "Value number changed after main loop completed!");
3352 EqualClasses.
insert({BeforeCC, AfterCC});
3363void NewGVN::verifyStoreExpressions()
const {
3368 std::pair<
const Value *,
3369 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3371 for (
const auto &KV : ExpressionToClass) {
3372 if (
auto *SE = dyn_cast<StoreExpression>(KV.first)) {
3374 auto Res = StoreExpressionSet.insert(
3375 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3376 SE->getStoredValue())});
3377 bool Okay = Res.second;
3382 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3383 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3384 lookupOperandLeader(SE->getStoredValue()));
3385 assert(Okay &&
"Stored expression conflict exists in expression table");
3386 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3387 assert(ValueExpr && ValueExpr->equals(*SE) &&
3388 "StoreExpression in ExpressionToClass is not latest "
3389 "StoreExpression for value");
3398void NewGVN::iterateTouchedInstructions() {
3401 int FirstInstr = TouchedInstructions.
find_first();
3403 if (FirstInstr == -1)
3405 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3406 while (TouchedInstructions.
any()) {
3412 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3416 if (InstrNum == 0) {
3417 TouchedInstructions.
reset(InstrNum);
3421 Value *
V = InstrFromDFSNum(InstrNum);
3422 const BasicBlock *CurrBlock = getBlockForValue(V);
3425 if (CurrBlock != LastBlock) {
3426 LastBlock = CurrBlock;
3427 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3428 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3431 if (!BlockReachable) {
3432 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3435 <<
" because it is unreachable\n");
3440 updateProcessedCount(CurrBlock);
3444 TouchedInstructions.
reset(InstrNum);
3446 if (
auto *MP = dyn_cast<MemoryPhi>(V)) {
3448 valueNumberMemoryPhi(MP);
3449 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
3450 valueNumberInstruction(
I);
3454 updateProcessedCount(V);
3457 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3461bool NewGVN::runGVN() {
3464 bool Changed =
false;
3465 NumFuncArgs =
F.arg_size();
3467 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3471 unsigned ICount = 1;
3483 unsigned Counter = 0;
3484 for (
auto &
B : RPOT) {
3486 assert(
Node &&
"RPO and Dominator tree should have same reachability");
3487 RPOOrdering[
Node] = ++Counter;
3490 for (
auto &
B : RPOT) {
3492 if (
Node->getNumChildren() > 1)
3494 return RPOOrdering[
A] < RPOOrdering[
B];
3501 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3502 BlockInstRange.
insert({
B, BlockRange});
3503 ICount += BlockRange.second - BlockRange.first;
3505 initializeCongruenceClasses(
F);
3507 TouchedInstructions.
resize(ICount);
3511 ExpressionToClass.reserve(ICount);
3514 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3515 TouchedInstructions.
set(InstRange.first, InstRange.second);
3517 <<
" marked reachable\n");
3518 ReachableBlocks.
insert(&
F.getEntryBlock());
3522 iterateTouchedInstructions();
3523 verifyMemoryCongruency();
3524 verifyIterationSettled(
F);
3525 verifyStoreExpressions();
3527 Changed |= eliminateInstructions(
F);
3530 for (
Instruction *ToErase : InstructionsToErase) {
3531 if (!ToErase->use_empty())
3534 assert(ToErase->getParent() &&
3535 "BB containing ToErase deleted unexpectedly!");
3536 ToErase->eraseFromParent();
3538 Changed |= !InstructionsToErase.empty();
3541 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3542 return !ReachableBlocks.
count(&BB);
3547 <<
" is unreachable\n");
3548 deleteInstructionsInBlock(&BB);
3606 return std::tie(DFSIn, DFSOut,
LocalNum, Def, U) <
3617void NewGVN::convertClassToDFSOrdered(
3626 assert(BB &&
"Should have figured out a basic block for value");
3634 if (
auto *SI = dyn_cast<StoreInst>(
D)) {
3635 auto Leader = lookupOperandLeader(SI->getValueOperand());
3637 VDDef.Def.setPointer(Leader);
3639 VDDef.Def.setPointer(
SI->getValueOperand());
3640 VDDef.Def.setInt(
true);
3643 VDDef.Def.setPointer(
D);
3646 "The dense set member should always be an instruction");
3651 if (
auto *PN = RealToTemp.
lookup(Def)) {
3653 dyn_cast_or_null<PHIExpression>(ValueToExpression.
lookup(Def));
3655 VDDef.Def.setInt(
false);
3656 VDDef.Def.setPointer(PN);
3662 unsigned int UseCount = 0;
3664 for (
auto &U :
Def->uses()) {
3665 if (
auto *
I = dyn_cast<Instruction>(
U.getUser())) {
3667 if (InstructionsToErase.count(
I))
3672 if (
auto *
P = dyn_cast<PHINode>(
I)) {
3673 IBlock =
P->getIncomingBlock(U);
3678 IBlock = getBlockForValue(
I);
3684 if (!ReachableBlocks.
contains(IBlock))
3700 ProbablyDead.
insert(Def);
3702 UseCounts[
Def] = UseCount;
3708void NewGVN::convertClassToLoadsAndStores(
3709 const CongruenceClass &
Dense,
3712 if (!isa<LoadInst>(
D) && !isa<StoreInst>(
D))
3720 VD.Def.setPointer(
D);
3723 if (
auto *
I = dyn_cast<Instruction>(
D))
3734 I->replaceAllUsesWith(Repl);
3737void NewGVN::deleteInstructionsInBlock(
BasicBlock *BB) {
3739 ++NumGVNBlocksDeleted;
3743 auto StartPoint = BB->
rbegin();
3751 if (isa<LandingPadInst>(Inst))
3756 ++NumGVNInstrDeleted;
3766void NewGVN::markInstructionForDeletion(
Instruction *
I) {
3768 InstructionsToErase.insert(
I);
3776 markInstructionForDeletion(
I);
3783class ValueDFSStack {
3785 Value *back()
const {
return ValueStack.back(); }
3786 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3788 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3789 ValueStack.emplace_back(V);
3790 DFSStack.emplace_back(DFSIn, DFSOut);
3793 bool empty()
const {
return DFSStack.empty(); }
3795 bool isInScope(
int DFSIn,
int DFSOut)
const {
3798 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3801 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3804 assert(ValueStack.size() == DFSStack.size() &&
3805 "Mismatch between ValueStack and DFSStack");
3807 !DFSStack.empty() &&
3808 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3809 DFSStack.pop_back();
3810 ValueStack.pop_back();
3822CongruenceClass *NewGVN::getClassForExpression(
const Expression *E)
const {
3823 if (
auto *VE = dyn_cast<VariableExpression>(E))
3824 return ValueToClass.lookup(VE->getVariableValue());
3825 else if (isa<DeadExpression>(E))
3827 return ExpressionToClass.lookup(E);
3836 if (
auto *CE = dyn_cast<ConstantExpression>(E))
3837 return CE->getConstantValue();
3838 if (
auto *VE = dyn_cast<VariableExpression>(E)) {
3839 auto *
V = VE->getVariableValue();
3841 return VE->getVariableValue();
3844 auto *CC = getClassForExpression(E);
3848 return CC->getLeader();
3850 for (
auto *Member : *CC) {
3851 auto *MemberInst = dyn_cast<Instruction>(Member);
3852 if (MemberInst == OrigInst)
3857 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3863bool NewGVN::eliminateInstructions(
Function &
F) {
3887 bool AnythingReplaced =
false;
3896 for (
auto &Operand :
PHI->incoming_values())
3897 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3901 <<
" with poison due to it being unreachable\n");
3915 for (
auto &KV : ReachableEdges)
3916 ReachablePredCount[KV.getEnd()]++;
3917 for (
auto &BBPair : RevisitOnReachabilityChange) {
3918 for (
auto InstNum : BBPair.second) {
3919 auto *Inst = InstrFromDFSNum(InstNum);
3920 auto *
PHI = dyn_cast<PHINode>(Inst);
3924 auto *BB = BBPair.first;
3925 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3926 ReplaceUnreachablePHIArgs(
PHI, BB);
3932 for (
auto *CC :
reverse(CongruenceClasses)) {
3933 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3939 if (CC->isDead() || CC->empty())
3942 if (CC == TOPClass) {
3943 for (
auto *M : *CC) {
3944 auto *VTE = ValueToExpression.
lookup(M);
3945 if (VTE && isa<DeadExpression>(VTE))
3946 markInstructionForDeletion(cast<Instruction>(M));
3947 assert((!ReachableBlocks.
count(cast<Instruction>(M)->getParent()) ||
3948 InstructionsToErase.count(cast<Instruction>(M))) &&
3949 "Everything in TOP should be unreachable or dead at this "
3955 assert(CC->getLeader() &&
"We should have had a leader");
3961 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3964 for (
auto *M : *CC) {
3967 if (Member == Leader || !isa<Instruction>(Member) ||
3968 Member->getType()->isVoidTy()) {
3969 MembersLeft.
insert(Member);
3973 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3974 << *Member <<
"\n");
3975 auto *
I = cast<Instruction>(Member);
3976 assert(Leader !=
I &&
"About to accidentally remove our leader");
3977 replaceInstruction(
I, Leader);
3978 AnythingReplaced =
true;
3980 CC->swap(MembersLeft);
3983 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3988 ValueDFSStack EliminationStack;
3992 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3996 for (
auto &VD : DFSOrderedSet) {
3997 int MemberDFSIn = VD.
DFSIn;
3998 int MemberDFSOut = VD.
DFSOut;
4000 bool FromStore = VD.Def.getInt();
4003 if (Def &&
Def->getType()->isVoidTy())
4005 auto *DefInst = dyn_cast_or_null<Instruction>(Def);
4006 if (DefInst && AllTempInstructions.
count(DefInst)) {
4007 auto *PN = cast<PHINode>(DefInst);
4012 AllTempInstructions.
erase(PN);
4013 auto *DefBlock = getBlockForValue(Def);
4017 PN->insertBefore(DefBlock->begin());
4019 NumGVNPHIOfOpsEliminations++;
4022 if (EliminationStack.empty()) {
4026 << EliminationStack.dfs_back().first <<
","
4027 << EliminationStack.dfs_back().second <<
")\n");
4030 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4031 << MemberDFSOut <<
")\n");
4045 bool ShouldPush =
Def && EliminationStack.empty();
4047 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4049 if (OutOfScope || ShouldPush) {
4051 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4052 bool ShouldPush =
Def && EliminationStack.empty();
4054 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4073 auto *DefI = dyn_cast<Instruction>(Def);
4074 if (!EliminationStack.empty() && DefI && !FromStore) {
4075 Value *DominatingLeader = EliminationStack.back();
4076 if (DominatingLeader != Def) {
4084 for (
auto *DVR : DVRUsers)
4085 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4087 markInstructionForDeletion(DefI);
4095 assert(isa<Instruction>(
U->get()) &&
4096 "Current def should have been an instruction");
4097 assert(isa<Instruction>(
U->getUser()) &&
4098 "Current user should have been an instruction");
4104 Instruction *InstUse = cast<Instruction>(
U->getUser());
4105 if (InstructionsToErase.count(InstUse)) {
4106 auto &UseCount = UseCounts[
U->get()];
4107 if (--UseCount == 0) {
4108 ProbablyDead.
insert(cast<Instruction>(
U->get()));
4114 if (EliminationStack.empty())
4117 Value *DominatingLeader = EliminationStack.back();
4120 if (
auto *BC = dyn_cast<BitCastInst>(DominatingLeader)) {
4121 if (BC->getType() == BC->getOperand(0)->getType() &&
4122 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4124 DominatingLeader = BC->getOperand(0);
4129 if (
U->get() == DominatingLeader)
4135 auto *ReplacedInst = cast<Instruction>(
U->get());
4136 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4137 if (!PI || DominatingLeader != PI->OriginalOp)
4141 <<
"Found replacement " << *DominatingLeader <<
" for "
4142 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4143 U->set(DominatingLeader);
4146 auto &LeaderUseCount = UseCounts[DominatingLeader];
4148 if (LeaderUseCount == 0 && isa<Instruction>(DominatingLeader))
4149 ProbablyDead.
erase(cast<Instruction>(DominatingLeader));
4153 auto It = UseCounts.
find(SSACopy);
4154 if (It != UseCounts.
end()) {
4155 unsigned &IIUseCount = It->second;
4156 if (--IIUseCount == 0)
4157 ProbablyDead.
insert(SSACopy);
4161 AnythingReplaced =
true;
4168 for (
auto *
I : ProbablyDead)
4170 markInstructionForDeletion(
I);
4174 for (
auto *Member : *CC)
4175 if (!isa<Instruction>(Member) ||
4176 !InstructionsToErase.count(cast<Instruction>(Member)))
4177 MembersLeft.
insert(Member);
4178 CC->swap(MembersLeft);
4181 if (CC->getStoreCount() > 0) {
4182 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4184 ValueDFSStack EliminationStack;
4185 for (
auto &VD : PossibleDeadStores) {
4186 int MemberDFSIn = VD.
DFSIn;
4187 int MemberDFSOut = VD.
DFSOut;
4189 if (EliminationStack.empty() ||
4190 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4192 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4193 if (EliminationStack.empty()) {
4194 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4199 if (isa<LoadInst>(Member))
4201 assert(!EliminationStack.empty());
4202 Instruction *Leader = cast<Instruction>(EliminationStack.back());
4207 <<
" that is dominated by " << *Leader <<
"\n");
4208 markInstructionForDeletion(Member);
4214 return AnythingReplaced;
4222unsigned int NewGVN::getRank(
const Value *V)
const {
4228 if (isa<ConstantExpr>(V))
4230 if (isa<PoisonValue>(V))
4232 if (isa<UndefValue>(V))
4234 if (isa<Constant>(V))
4236 if (
auto *
A = dyn_cast<Argument>(V))
4237 return 4 +
A->getArgNo();
4241 unsigned Result = InstrToDFSNum(V);
4243 return 5 + NumFuncArgs +
Result;
4250bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4254 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4257bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4259 if (shouldSwapOperands(
A,
B)) {
4260 PredicateSwapChoice[
I] =
B;
4265 if (LookupResult != PredicateSwapChoice.
end()) {
4267 if (SeenPredicate) {
4269 if (SeenPredicate ==
B)
4288 NewGVN(
F, &DT, &AC, &TLI, &AA, &MSSA,
F.getDataLayout())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
This file implements the BitVector class.
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
The header file for the GVN pass that contains expression handling classes.
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
This is the interface for a simple mod/ref and alias analysis over globals.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
This defines the Use class.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Branch Probability Basic Block static false std::string getBlockName(const MachineBasicBlock *BB)
Helper to print the name of a MBB.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static bool alwaysAvailable(Value *V)
static Value * getCopyOf(const Value *V)
static bool isCopyOfPHI(const Value *V, const PHINode *PN)
static bool isCopyOfAPHI(const Value *V)
static bool okayForPHIOfOps(const Instruction *I)
static cl::opt< bool > EnableStoreRefinement("enable-store-refinement", cl::init(false), cl::Hidden)
static bool equalsLoadStoreHelper(const T &LHS, const Expression &RHS)
static cl::opt< bool > EnablePhiOfOps("enable-phi-of-ops", cl::init(true), cl::Hidden)
Currently, the generation "phi of ops" can result in correctness issues.
This file provides the interface for LLVM's Global Value Numbering pass.
This file defines the PointerIntPair class.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
const SmallVectorImpl< MachineOperand > & Cond
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the SparseBitVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
A manager for alias analyses.
A private abstract base class describing the concept of an individual alias analysis implementation.
bool isMustAlias(const MemoryLocation &LocA, const MemoryLocation &LocB)
A trivial helper function to check to see if the specified pointers are must-alias.
bool doesNotAccessMemory(const CallBase *Call)
Checks if the specified call is known to never read or write memory.
bool onlyReadsMemory(const CallBase *Call)
Checks if the specified call is known to only read from non-volatile memory (or not access memory at ...
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Recycle small arrays allocated from a BumpPtrAllocator.
void clear(AllocatorType &Allocator)
Release all the tracked allocations to the allocator.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM_ABI std::optional< AttributeList > intersectWith(LLVMContext &C, AttributeList Other) const
Try to intersect this AttributeList with Other.
LLVM Basic Block Representation.
reverse_iterator rbegin()
InstListType::reverse_iterator reverse_iterator
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This class represents a no-op cast from one type to another.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
bool any() const
any - Returns true if any bit is set.
iterator_range< const_set_bits_iterator > set_bits() const
Allocate memory in an ever growing pool, as if by bump-pointer.
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
void Deallocate(const void *Ptr, size_t Size, size_t)
bool isConvergent() const
Determine if the invoke is convergent.
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantInt * getBool(LLVMContext &Context, bool V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
static CounterState getCounterState(unsigned ID)
static bool isCounterSet(unsigned ID)
static bool shouldExecute(unsigned CounterName)
static void setCounterState(unsigned ID, CounterState State)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Class representing an expression and its matching format.
bool isPresplitCoroutine() const
Determine if the function is presplit coroutine.
~AggregateValueExpression() override
~BasicExpression() override
bool equals(const Expression &Other) const override
~CallExpression() override
bool equals(const Expression &Other) const override
~LoadExpression() override
bool equals(const Expression &Other) const override
~PHIExpression() override
bool equals(const Expression &Other) const override
~StoreExpression() override
Value * getStoredValue() const
static LLVM_ABI std::optional< bool > isImpliedByMatchingCmp(CmpPredicate Pred1, CmpPredicate Pred2)
Determine if Pred1 implies Pred2 is true, false, or if nothing can be inferred about the implication,...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
An instruction for reading from memory.
Value * getPointerOperand()
BasicBlock * getBlock() const
Represents phi nodes for memory accesses.
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
An analysis that produces MemorySSA for a function.
This is the generic walker interface for walkers of MemorySSA.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemoryAccess * getLiveOnEntryDef() const
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
Class that has the common methods + fields of memory uses/defs.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
PreservedAnalyses run(Function &F, AnalysisManager< Function > &AM)
Run the pass over the function.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PointerIntPair - This class implements a pair of a pointer and small integer.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Encapsulates PredicateInfo, including all data associated with memory accesses.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSetIterator< PtrType > const_iterator
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
LLVM_ABI friend const_iterator begin(StringRef path, Style style)
Get begin iterator over path.
LLVM_ABI friend const_iterator end(StringRef path)
Get end iterator over path.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
bool match(Val *V, const Pattern &P)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
std::vector< ExecutorSymbolDef > LookupResult
NodeAddr< DefNode * > Def
LLVM_ABI const_iterator begin(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get begin iterator over path.
LLVM_ABI const_iterator end(StringRef path LLVM_LIFETIME_BOUND)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
SDValue getStoredValue(SDValue Op)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
mapped_iterator< ItTy, FuncTy > map_iterator(ItTy I, FuncTy F)
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
OutputIt copy(R &&Range, OutputIt Out)
iterator_range< df_iterator< T > > depth_first(const T &G)
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
PointerIntPair< Value *, 1, bool > Def
bool operator<(const ValueDFS &Other) const
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
static unsigned getHashValue(const ExactEqualsExpression &E)
static unsigned getHashValue(const Expression *E)
static const Expression * getTombstoneKey()
static bool isEqual(const Expression *LHS, const Expression *RHS)
static const Expression * getEmptyKey()
static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
ExactEqualsExpression(const Expression &E)
hash_code getComputedHash() const
bool operator==(const Expression &Other) const
SimplifyQuery getWithInstruction(const Instruction *I) const