123 using namespace llvm;
127 #define DEBUG_TYPE "newgvn" 129 STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
130 STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
131 STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
132 STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
134 "Maximum Number of iterations it took to converge GVN");
135 STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
136 STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
137 STATISTIC(NumGVNAvoidedSortedLeaderChanges,
138 "Number of avoided sorted leader changes");
139 STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
140 STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
142 "Number of things eliminated using PHI of ops");
144 "Controls which instructions are value numbered");
146 "Controls which instructions we create phi of ops for");
163 namespace GVNExpression {
187 TarjanSCC() : Components(1) {}
190 if (Root.lookup(Start) == 0)
195 unsigned ComponentID = ValueToComponent.lookup(V);
198 "Asking for a component for a value we never processed");
199 return Components[ComponentID];
206 unsigned int OurDFS = DFSNum;
208 if (
auto *InstOp = dyn_cast<Instruction>(
Op)) {
209 if (Root.lookup(
Op) == 0)
211 if (!InComponent.count(
Op))
212 Root[I] = std::min(Root.lookup(I), Root.lookup(
Op));
219 if (Root.lookup(I) == OurDFS) {
220 unsigned ComponentID = Components.size();
221 Components.resize(Components.size() + 1);
222 auto &Component = Components.back();
225 InComponent.insert(I);
226 ValueToComponent[
I] = ComponentID;
228 while (!Stack.empty() && Root.lookup(Stack.back()) >= OurDFS) {
229 auto *Member = Stack.back();
231 Component.insert(Member);
232 InComponent.insert(Member);
233 ValueToComponent[Member] = ComponentID;
242 unsigned int DFSNum = 1;
292 class CongruenceClass {
294 using MemberType =
Value;
299 explicit CongruenceClass(
unsigned ID) : ID(ID) {}
301 : ID(ID), RepLeader(Leader), DefiningExpr(E) {}
303 unsigned getID()
const {
return ID; }
307 bool isDead()
const {
310 return empty() && memory_empty();
314 Value *getLeader()
const {
return RepLeader; }
315 void setLeader(
Value *Leader) { RepLeader = Leader; }
316 const std::pair<Value *, unsigned int> &getNextLeader()
const {
319 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
320 void addPossibleNextLeader(std::pair<Value *, unsigned int> LeaderPair) {
321 if (LeaderPair.second < NextLeader.second)
322 NextLeader = LeaderPair;
325 Value *getStoredValue()
const {
return RepStoredValue; }
326 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
327 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
328 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
331 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
334 bool empty()
const {
return Members.empty(); }
335 unsigned size()
const {
return Members.size(); }
336 MemberSet::const_iterator
begin()
const {
return Members.
begin(); }
337 MemberSet::const_iterator
end()
const {
return Members.
end(); }
338 void insert(MemberType *M) { Members.insert(M); }
339 void erase(MemberType *M) { Members.erase(M); }
340 void swap(MemberSet &Other) { Members.swap(Other); }
343 bool memory_empty()
const {
return MemoryMembers.empty(); }
344 unsigned memory_size()
const {
return MemoryMembers.size(); }
345 MemoryMemberSet::const_iterator memory_begin()
const {
346 return MemoryMembers.begin();
348 MemoryMemberSet::const_iterator memory_end()
const {
349 return MemoryMembers.end();
352 return make_range(memory_begin(), memory_end());
355 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
356 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
359 unsigned getStoreCount()
const {
return StoreCount; }
360 void incStoreCount() { ++StoreCount; }
361 void decStoreCount() {
362 assert(StoreCount != 0 &&
"Store count went negative");
367 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
371 bool isEquivalentTo(
const CongruenceClass *Other)
const {
377 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
378 std::tie(Other->StoreCount, Other->RepLeader, Other->RepStoredValue,
379 Other->RepMemoryAccess))
381 if (DefiningExpr != Other->DefiningExpr)
382 if (!DefiningExpr || !Other->DefiningExpr ||
383 *DefiningExpr != *Other->DefiningExpr)
386 if (Members.size() != Other->Members.size())
390 [&](
const Value *V) {
return Other->Members.count(V); });
397 Value *RepLeader =
nullptr;
401 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0U};
404 Value *RepStoredValue =
nullptr;
419 MemoryMemberSet MemoryMembers;
444 auto Val =
static_cast<uintptr_t
>(-1);
445 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
446 return reinterpret_cast<const Expression *
>(Val);
450 auto Val =
static_cast<uintptr_t
>(~1U);
451 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
452 return reinterpret_cast<const Expression *
>(Val);
464 if (RHS == getTombstoneKey() || RHS == getEmptyKey())
472 if (LHS == getTombstoneKey() || RHS == getTombstoneKey() ||
473 LHS == getEmptyKey() || RHS == getEmptyKey())
497 std::unique_ptr<PredicateInfo> PredInfo;
503 mutable TarjanSCC SCCFinder;
507 unsigned int NumFuncArgs;
518 CongruenceClass *TOPClass;
519 std::vector<CongruenceClass *> CongruenceClasses;
520 unsigned NextCongruenceNum;
551 ExpressionToPhiOfOps;
600 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
603 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
608 ExpressionClassMap ExpressionToClass;
659 :
F(F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), DL(DL),
660 PredInfo(make_unique<PredicateInfo>(F, *DT, *AC)),
661 SQ(DL, TLI, DT, AC,
nullptr,
false) {}
673 using ValPair = std::pair<Value *, BasicBlock *>;
677 bool &OriginalOpsConstant)
const;
690 createAggregateValueExpression(
Instruction *)
const;
694 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
695 auto *result =
new CongruenceClass(NextCongruenceNum++, Leader, E);
696 CongruenceClasses.emplace_back(result);
701 auto *CC = createCongruenceClass(
nullptr,
nullptr);
702 CC->setMemoryLeader(MA);
706 CongruenceClass *ensureLeaderOfMemoryClass(
MemoryAccess *MA) {
707 auto *CC = getMemoryClass(MA);
708 if (CC->getMemoryLeader() != MA)
709 CC = createMemoryClass(MA);
713 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
714 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
715 CClass->insert(Member);
716 ValueToClass[Member] = CClass;
720 void initializeCongruenceClasses(
Function &F);
761 CongruenceClass *getClassForExpression(
const Expression *E)
const;
764 CongruenceClass *, CongruenceClass *);
766 CongruenceClass *, CongruenceClass *);
767 Value *getNextValueLeader(CongruenceClass *)
const;
768 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
770 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
775 unsigned int getRank(
const Value *)
const;
776 bool shouldSwapOperands(
const Value *,
const Value *)
const;
781 Value *findConditionEquivalence(
Value *)
const;
785 void convertClassToDFSOrdered(
const CongruenceClass &,
789 void convertClassToLoadsAndStores(
const CongruenceClass &,
792 bool eliminateInstructions(
Function &);
803 template <
typename Map,
typename KeyType,
typename Func>
804 void for_each_found(Map &,
const KeyType &, Func);
805 template <
typename Map,
typename KeyType>
806 void touchAndErase(Map &,
const KeyType &);
807 void markUsersTouched(
Value *);
811 void markValueLeaderChangeTouched(CongruenceClass *CC);
812 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
813 void markPhiOfOpsChanged(
const Expression *E);
819 void iterateTouchedInstructions();
822 void cleanupTables();
823 std::pair<unsigned, unsigned> assignDFSNumbers(
BasicBlock *,
unsigned);
824 void updateProcessedCount(
const Value *V);
825 void verifyMemoryCongruency()
const;
826 void verifyIterationSettled(
Function &F);
827 void verifyStoreExpressions()
const;
831 void deleteExpression(
const Expression *E)
const;
835 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
837 unsigned InstrToDFSNum(
const Value *V)
const {
838 assert(isa<Instruction>(V) &&
"This should not be used for MemoryAccesses");
839 return InstrDFS.
lookup(V);
843 return MemoryToDFSNum(MA);
846 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
851 unsigned MemoryToDFSNum(
const Value *MA)
const {
852 assert(isa<MemoryAccess>(MA) &&
853 "This should not be used with instructions");
854 return isa<MemoryUseOrDef>(MA)
855 ? InstrToDFSNum(cast<MemoryUseOrDef>(MA)->getMemoryInst())
864 int64_t StartingVNCounter;
869 template <
typename T>
871 if (!isa<LoadExpression>(RHS) && !isa<StoreExpression>(RHS))
873 return LHS.MemoryExpression::equals(RHS);
884 if (
const auto *S = dyn_cast<StoreExpression>(&Other))
885 if (getStoredValue() != S->getStoredValue())
893 RPOOrdering.lookup(DT->getNode(From)) >=
894 RPOOrdering.lookup(DT->getNode(To));
905 auto *Result = MSSA->getMemoryAccess(I);
906 return Result ? Result : TempToMemory.lookup(I);
911 return MSSA->getMemoryAccess(BB);
916 if (
auto *I = dyn_cast<Instruction>(V)) {
920 Parent = TempToBlock.lookup(V);
921 assert(Parent &&
"Every fake instruction should have a block");
926 assert(MP &&
"Should have been an instruction or a MemoryPhi");
927 return MP->getBlock();
933 void NewGVN::deleteExpression(
const Expression *
E)
const {
934 assert(isa<BasicExpression>(E));
935 auto *BE = cast<BasicExpression>(
E);
937 ExpressionAllocator.Deallocate(E);
942 if (
auto *II = dyn_cast<IntrinsicInst>(V))
944 return II->getOperand(0);
955 return CO && isa<PHINode>(CO);
962 llvm::sort(Ops, [&](
const ValPair &P1,
const ValPair &P2) {
963 return BlockInstRange.lookup(P1.second).first <
964 BlockInstRange.lookup(P2.second).first;
972 return isa<Constant>(V) || isa<Argument>(V);
984 bool &OriginalOpsConstant)
const {
985 unsigned NumOps = PHIOperands.
size();
986 auto *E =
new (ExpressionAllocator)
PHIExpression(NumOps, PHIBlock);
988 E->allocateOperands(ArgRecycler, ExpressionAllocator);
989 E->setType(PHIOperands.
begin()->first->getType());
995 if (
auto *PHIOp = dyn_cast<PHINode>(I))
998 if (!ReachableEdges.count({BB, PHIBlock}))
1001 if (ValueToClass.lookup(P.first) == TOPClass)
1003 OriginalOpsConstant = OriginalOpsConstant && isa<Constant>(P.first);
1004 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1005 return lookupOperandLeader(P.first) !=
I;
1008 [&](
const ValPair &
P) ->
Value * {
1009 return lookupOperandLeader(P.first);
1017 bool AllConstant =
true;
1018 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(I))
1028 auto Operand = lookupOperandLeader(
O);
1029 AllConstant = AllConstant && isa<Constant>(Operand);
1036 const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1049 if (shouldSwapOperands(Arg1, Arg2))
1056 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1069 if (
auto *
C = dyn_cast<Constant>(V)) {
1072 <<
" constant " << *
C <<
"\n");
1073 NumGVNOpsSimplified++;
1074 assert(isa<BasicExpression>(E) &&
1075 "We should always have had a basic expression here");
1076 deleteExpression(E);
1077 return createConstantExpression(
C);
1078 }
else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1081 <<
" variable " << *V <<
"\n");
1082 deleteExpression(E);
1083 return createVariableExpression(V);
1086 CongruenceClass *CC = ValueToClass.lookup(V);
1088 if (CC->getLeader() && CC->getLeader() !=
I) {
1093 if (!AllTempInstructions.count(I))
1094 addAdditionalUsers(V, I);
1096 return createVariableOrConstant(CC->getLeader());
1098 if (CC->getDefiningExpr()) {
1103 if (!AllTempInstructions.count(I))
1104 addAdditionalUsers(V, I);
1109 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1110 NumGVNOpsSimplified++;
1111 deleteExpression(E);
1112 return CC->getDefiningExpr();
1125 bool AllConstant = setBasicExpressionInfo(I, E);
1133 if (shouldSwapOperands(E->getOperand(0), E->getOperand(1)))
1134 E->swapOperands(0, 1);
1137 if (
auto *CI = dyn_cast<CmpInst>(I)) {
1141 if (shouldSwapOperands(E->getOperand(0), E->getOperand(1))) {
1142 E->swapOperands(0, 1);
1145 E->
setOpcode((CI->getOpcode() << 8) | Predicate);
1148 "Wrong types on cmp instruction");
1153 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1155 }
else if (isa<SelectInst>(I)) {
1156 if (isa<Constant>(E->getOperand(0)) ||
1157 E->getOperand(1) == E->getOperand(2)) {
1161 E->getOperand(2), SQ);
1162 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1168 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1170 }
else if (
auto *BI = dyn_cast<BitCastInst>(I)) {
1173 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1175 }
else if (isa<GetElementPtrInst>(I)) {
1178 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1180 }
else if (AllConstant) {
1193 if (
const Expression *SimplifiedE = checkSimplificationResults(E, I, V))
1200 NewGVN::createAggregateValueExpression(
Instruction *I)
const {
1201 if (
auto *II = dyn_cast<InsertValueInst>(I)) {
1202 auto *E =
new (ExpressionAllocator)
1204 setBasicExpressionInfo(I, E);
1205 E->allocateIntOperands(ExpressionAllocator);
1208 }
else if (
auto *EI = dyn_cast<ExtractValueInst>(I)) {
1209 auto *E =
new (ExpressionAllocator)
1211 setBasicExpressionInfo(EI, E);
1212 E->allocateIntOperands(ExpressionAllocator);
1222 return SingletonDeadExpression;
1232 if (
auto *
C = dyn_cast<Constant>(V))
1233 return createConstantExpression(
C);
1234 return createVariableExpression(V);
1254 setBasicExpressionInfo(CI, E);
1259 bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1261 auto *CC = ValueToClass.lookup(Inst);
1282 if (DT->dominates(cast<Instruction>(CC->getLeader()), U))
1284 if (CC->getNextLeader().first &&
1285 DT->dominates(cast<Instruction>(CC->getNextLeader().first), U))
1288 return Member != CC->getLeader() &&
1289 DT->dominates(cast<Instruction>(Member), U);
1295 Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1296 CongruenceClass *CC = ValueToClass.lookup(V);
1303 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1310 auto *CC = getMemoryClass(MA);
1311 assert(CC->getMemoryLeader() &&
1312 "Every MemoryAccess should be mapped to a congruence class with a " 1313 "representative memory access");
1314 return CC->getMemoryLeader();
1320 bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1321 return getMemoryClass(MA) == TOPClass;
1328 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1329 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1330 E->setType(LoadType);
1334 E->op_push_back(PointerOp);
1347 auto *E =
new (ExpressionAllocator)
1365 auto *SI = cast<StoreInst>(
I);
1366 auto *StoreAccess = getMemoryAccess(SI);
1368 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1370 StoreRHS = MSSAWalker->getClobberingMemoryAccess(StoreAccess);
1372 StoreRHS = lookupMemoryLeader(StoreRHS);
1373 if (StoreRHS != StoreAccess->getDefiningAccess())
1374 addMemoryUsers(StoreRHS, StoreAccess);
1376 if (StoreRHS == StoreAccess)
1377 StoreRHS = MSSA->getLiveOnEntryDef();
1383 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1384 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1390 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1396 if (
auto *LI = dyn_cast<LoadInst>(LastStore->getStoredValue()))
1398 LastStore->getOperand(0)) &&
1399 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1402 deleteExpression(LastStore);
1408 return createStoreExpression(SI, StoreAccess);
1414 NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1418 if (
auto *DepSI = dyn_cast<StoreInst>(DepInst)) {
1422 if (LI->
isAtomic() > DepSI->isAtomic() ||
1423 LoadType == DepSI->getValueOperand()->getType())
1427 if (
auto *C = dyn_cast<Constant>(
1428 lookupOperandLeader(DepSI->getValueOperand()))) {
1430 <<
" to constant " << *C <<
"\n");
1431 return createConstantExpression(
1435 }
else if (
auto *DepLI = dyn_cast<LoadInst>(DepInst)) {
1437 if (LI->
isAtomic() > DepLI->isAtomic())
1442 if (
auto *C = dyn_cast<Constant>(lookupOperandLeader(DepLI)))
1443 if (
auto *PossibleConstant =
1446 <<
" to constant " << *PossibleConstant <<
"\n");
1447 return createConstantExpression(PossibleConstant);
1450 }
else if (
auto *DepMI = dyn_cast<MemIntrinsic>(DepInst)) {
1453 if (
auto *PossibleConstant =
1456 <<
" to constant " << *PossibleConstant <<
"\n");
1457 return createConstantExpression(PossibleConstant);
1464 if (LoadPtr != lookupOperandLeader(DepInst) &&
1465 !AA->isMustAlias(LoadPtr, DepInst))
1476 else if (
auto *II = dyn_cast<IntrinsicInst>(DepInst)) {
1490 auto *LI = cast<LoadInst>(
I);
1499 if (isa<UndefValue>(LoadAddressLeader))
1503 MSSAWalker->getClobberingMemoryAccess(OriginalAccess);
1505 if (!MSSA->isLiveOnEntryDef(DefiningAccess)) {
1506 if (
auto *MD = dyn_cast<MemoryDef>(DefiningAccess)) {
1509 if (!ReachableBlocks.count(DefiningInst->
getParent()))
1515 if (
const auto *CoercionResult =
1516 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1517 DefiningInst, DefiningAccess))
1518 return CoercionResult;
1522 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1526 if (
LE->getMemoryLeader() != DefiningAccess)
1527 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1532 NewGVN::performSymbolicPredicateInfoEvaluation(
Instruction *I)
const {
1533 auto *PI = PredInfo->getPredicateInfoFor(I);
1537 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1544 auto *Cond = PWC->Condition;
1548 if (CopyOf == Cond) {
1551 if (isa<PredicateAssume>(PI))
1553 if (
auto *PBranch = dyn_cast<PredicateBranch>(PI)) {
1554 if (PBranch->TrueEdge)
1558 if (
auto *PSwitch = dyn_cast<PredicateSwitch>(PI))
1559 return createConstantExpression(cast<Constant>(PSwitch->CaseValue));
1576 if (CopyOf != Cmp->getOperand(0) && CopyOf != Cmp->getOperand(1)) {
1577 LLVM_DEBUG(
dbgs() <<
"Copy is not of any condition operands!\n");
1580 Value *FirstOp = lookupOperandLeader(Cmp->getOperand(0));
1581 Value *SecondOp = lookupOperandLeader(Cmp->getOperand(1));
1582 bool SwappedOps =
false;
1584 if (shouldSwapOperands(FirstOp, SecondOp)) {
1589 SwappedOps ? Cmp->getSwappedPredicate() : Cmp->getPredicate();
1591 if (isa<PredicateAssume>(PI)) {
1594 addPredicateUsers(PI, I);
1595 addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
1597 return createVariableOrConstant(FirstOp);
1600 if (
const auto *PBranch = dyn_cast<PredicateBranch>(PI)) {
1608 addPredicateUsers(PI, I);
1609 addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
1611 return createVariableOrConstant(FirstOp);
1616 isa<ConstantFP>(FirstOp) && !cast<ConstantFP>(FirstOp)->isZero()) {
1617 addPredicateUsers(PI, I);
1618 addAdditionalUsers(SwappedOps ? Cmp->getOperand(1) : Cmp->getOperand(0),
1620 return createConstantExpression(cast<Constant>(FirstOp));
1628 auto *CI = cast<CallInst>(
I);
1629 if (
auto *II = dyn_cast<IntrinsicInst>(I)) {
1631 if (
auto *ReturnedValue = II->getReturnedArgOperand()) {
1633 if (
const auto *Result = performSymbolicPredicateInfoEvaluation(I))
1635 return createVariableOrConstant(ReturnedValue);
1638 if (AA->doesNotAccessMemory(CI)) {
1639 return createCallExpression(CI, TOPClass->getMemoryLeader());
1640 }
else if (AA->onlyReadsMemory(CI)) {
1641 MemoryAccess *DefiningAccess = MSSAWalker->getClobberingMemoryAccess(CI);
1642 return createCallExpression(CI, DefiningAccess);
1648 CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1649 auto *Result = MemoryAccessToClass.lookup(MA);
1650 assert(Result &&
"Should have found memory class");
1657 CongruenceClass *NewClass) {
1659 "Every MemoryAccess should be getting mapped to a non-null class");
1663 <<
" with current MemoryAccess leader ");
1666 auto LookupResult = MemoryAccessToClass.find(From);
1667 bool Changed =
false;
1669 if (LookupResult != MemoryAccessToClass.end()) {
1670 auto *OldClass = LookupResult->second;
1671 if (OldClass != NewClass) {
1673 if (
auto *MP = dyn_cast<MemoryPhi>(From)) {
1674 OldClass->memory_erase(MP);
1675 NewClass->memory_insert(MP);
1677 if (OldClass->getMemoryLeader() ==
From) {
1678 if (OldClass->definesNoMemory()) {
1679 OldClass->setMemoryLeader(
nullptr);
1681 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1683 << OldClass->getID() <<
" to " 1684 << *OldClass->getMemoryLeader()
1685 <<
" due to removal of a memory member " << *From
1687 markMemoryLeaderChangeTouched(OldClass);
1692 LookupResult->second = NewClass;
1704 bool NewGVN::isCycleFree(
const Instruction *I)
const {
1710 auto ICS = InstCycleState.lookup(I);
1711 if (ICS == ICS_Unknown) {
1713 auto &SCC = SCCFinder.getComponentFor(I);
1715 if (SCC.size() == 1)
1716 InstCycleState.insert({I, ICS_CycleFree});
1721 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1722 for (
auto *Member : SCC)
1723 if (
auto *MemberPhi = dyn_cast<PHINode>(Member))
1724 InstCycleState.insert({MemberPhi, ICS});
1727 if (ICS == ICS_Cycle)
1738 bool HasBackedge =
false;
1743 bool OriginalOpsConstant =
true;
1744 auto *E = cast<PHIExpression>(createPHIExpression(
1745 PHIOps, I, PHIBlock, HasBackedge, OriginalOpsConstant));
1749 bool HasUndef =
false;
1751 if (isa<UndefValue>(
Arg)) {
1758 if (
empty(Filtered)) {
1763 dbgs() <<
"PHI Node " << *I
1764 <<
" has no non-undef arguments, valuing it as undef\n");
1768 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *I <<
" are live\n");
1769 deleteExpression(E);
1770 return createDeadExpression();
1772 Value *AllSameValue = *(Filtered.begin());
1791 if (HasBackedge && !OriginalOpsConstant &&
1792 !isa<UndefValue>(AllSameValue) && !isCycleFree(I))
1796 if (
auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
1797 if (!someEquivalentDominates(AllSameInst, I))
1803 if (isa<Instruction>(AllSameValue) &&
1804 InstrToDFSNum(AllSameValue) > InstrToDFSNum(I))
1806 NumGVNPhisAllSame++;
1807 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *I <<
" to " << *AllSameValue
1809 deleteExpression(E);
1810 return createVariableOrConstant(AllSameValue);
1816 NewGVN::performSymbolicAggrValueEvaluation(
Instruction *I)
const {
1817 if (
auto *EI = dyn_cast<ExtractValueInst>(I)) {
1819 if (II && EI->getNumIndices() == 1 && *EI->idx_begin() == 0) {
1820 unsigned Opcode = 0;
1824 switch (II->getIntrinsicID()) {
1831 Opcode = Instruction::Sub;
1835 Opcode = Instruction::Mul;
1844 assert(II->getNumArgOperands() == 2 &&
1845 "Expect two args for recognised intrinsics.");
1846 return createBinaryExpression(Opcode, EI->getType(),
1847 II->getArgOperand(0),
1848 II->getArgOperand(1),
I);
1853 return createAggregateValueExpression(I);
1857 assert(isa<CmpInst>(I) &&
"Expected a cmp instruction.");
1859 auto *CI = cast<CmpInst>(
I);
1862 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1863 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1864 auto OurPredicate = CI->getPredicate();
1865 if (shouldSwapOperands(Op0, Op1)) {
1867 OurPredicate = CI->getSwappedPredicate();
1874 auto *CmpPI = PredInfo->getPredicateInfoFor(I);
1875 if (dyn_cast_or_null<PredicateAssume>(CmpPI))
1880 if (CI->isTrueWhenEqual())
1882 else if (CI->isFalseWhenEqual())
1912 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1913 if (
const auto *PBranch = dyn_cast_or_null<PredicateBranch>(PI)) {
1914 if (PI == LastPredInfo)
1919 if (!DT->dominates(PBranch->To, getBlockForValue(I)))
1929 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1930 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1932 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1934 BranchPredicate = BranchCond->getSwappedPredicate();
1936 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1937 if (PBranch->TrueEdge) {
1942 addPredicateUsers(PI, I);
1943 return createConstantExpression(
1949 addPredicateUsers(PI, I);
1950 return createConstantExpression(
1956 if (BranchPredicate == OurPredicate) {
1957 addPredicateUsers(PI, I);
1959 return createConstantExpression(
1961 }
else if (BranchPredicate ==
1963 addPredicateUsers(PI, I);
1965 return createConstantExpression(
1973 return createExpression(I);
1978 NewGVN::performSymbolicEvaluation(
Value *V,
1981 if (
auto *C = dyn_cast<Constant>(V))
1982 E = createConstantExpression(C);
1983 else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1984 E = createVariableExpression(V);
1989 auto *I = cast<Instruction>(V);
1991 case Instruction::ExtractValue:
1992 case Instruction::InsertValue:
1993 E = performSymbolicAggrValueEvaluation(I);
1995 case Instruction::PHI: {
1997 auto *PN = cast<PHINode>(
I);
1998 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1999 Ops.
push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2002 E = performSymbolicPHIEvaluation(Ops, I, getBlockForValue(I));
2005 E = performSymbolicCallEvaluation(I);
2008 E = performSymbolicStoreEvaluation(I);
2011 E = performSymbolicLoadEvaluation(I);
2013 case Instruction::BitCast:
2014 E = createExpression(I);
2016 case Instruction::ICmp:
2017 case Instruction::FCmp:
2018 E = performSymbolicCmpEvaluation(I);
2021 case Instruction::FAdd:
2022 case Instruction::Sub:
2023 case Instruction::FSub:
2024 case Instruction::Mul:
2025 case Instruction::FMul:
2026 case Instruction::UDiv:
2027 case Instruction::SDiv:
2028 case Instruction::FDiv:
2029 case Instruction::URem:
2030 case Instruction::SRem:
2031 case Instruction::FRem:
2032 case Instruction::Shl:
2033 case Instruction::LShr:
2034 case Instruction::AShr:
2035 case Instruction::And:
2036 case Instruction::Or:
2037 case Instruction::Xor:
2038 case Instruction::Trunc:
2039 case Instruction::ZExt:
2040 case Instruction::SExt:
2041 case Instruction::FPToUI:
2042 case Instruction::FPToSI:
2043 case Instruction::UIToFP:
2044 case Instruction::SIToFP:
2045 case Instruction::FPTrunc:
2046 case Instruction::FPExt:
2047 case Instruction::PtrToInt:
2048 case Instruction::IntToPtr:
2050 case Instruction::ExtractElement:
2051 case Instruction::InsertElement:
2052 case Instruction::ShuffleVector:
2053 case Instruction::GetElementPtr:
2054 E = createExpression(I);
2065 template <
typename Map,
typename KeyType,
typename Func>
2066 void NewGVN::for_each_found(Map &M,
const KeyType &
Key, Func
F) {
2067 const auto Result = M.find_as(Key);
2068 if (Result != M.end())
2069 for (
typename Map::mapped_type::value_type Mapped : Result->second)
2075 template <
typename Map,
typename KeyType>
2076 void NewGVN::touchAndErase(Map &M,
const KeyType &Key) {
2077 const auto Result = M.find_as(Key);
2078 if (Result != M.end()) {
2079 for (
const typename Map::mapped_type::value_type Mapped : Result->second)
2080 TouchedInstructions.set(InstrToDFSNum(Mapped));
2086 assert(User && To != User);
2087 if (isa<Instruction>(To))
2088 AdditionalUsers[To].insert(User);
2091 void NewGVN::markUsersTouched(
Value *V) {
2093 for (
auto *User : V->
users()) {
2094 assert(isa<Instruction>(User) &&
"Use of value not within an instruction?");
2095 TouchedInstructions.set(InstrToDFSNum(User));
2097 touchAndErase(AdditionalUsers, V);
2101 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2102 MemoryToUsers[To].insert(U);
2105 void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2106 TouchedInstructions.set(MemoryToDFSNum(MA));
2109 void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2110 if (isa<MemoryUse>(MA))
2112 for (
auto U : MA->
users())
2113 TouchedInstructions.set(MemoryToDFSNum(U));
2114 touchAndErase(MemoryToUsers, MA);
2120 if (AllTempInstructions.count(I))
2123 if (
auto *PBranch = dyn_cast<PredicateBranch>(PB))
2124 PredicateToUsers[PBranch->Condition].insert(I);
2125 else if (
auto *PAssume = dyn_cast<PredicateBranch>(PB))
2126 PredicateToUsers[PAssume->Condition].insert(I);
2130 void NewGVN::markPredicateUsersTouched(
Instruction *I) {
2131 touchAndErase(PredicateToUsers, I);
2135 void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2136 for (
auto M : CC->memory())
2137 markMemoryDefTouched(M);
2142 void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2143 for (
auto M : *CC) {
2144 if (
auto *I = dyn_cast<Instruction>(M))
2145 TouchedInstructions.set(InstrToDFSNum(I));
2146 LeaderChanges.insert(M);
2152 template <
class T,
class Range>
2153 T *NewGVN::getMinDFSOfRange(
const Range &
R)
const {
2154 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0U};
2155 for (
const auto X : R) {
2156 auto DFSNum = InstrToDFSNum(
X);
2157 if (DFSNum < MinDFS.second)
2158 MinDFS = {
X, DFSNum};
2160 return MinDFS.first;
2166 const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2170 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2171 if (CC->getStoreCount() > 0) {
2172 if (
auto *NL = dyn_cast_or_null<StoreInst>(CC->getNextLeader().first))
2173 return getMemoryAccess(NL);
2176 *CC, [&](
const Value *V) {
return isa<StoreInst>(V); }));
2177 return getMemoryAccess(cast<StoreInst>(V));
2179 assert(CC->getStoreCount() == 0);
2183 if (CC->memory_size() == 1)
2184 return *CC->memory_begin();
2185 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2191 Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2196 if (CC->size() == 1 || CC == TOPClass) {
2197 return *(CC->begin());
2198 }
else if (CC->getNextLeader().first) {
2199 ++NumGVNAvoidedSortedLeaderChanges;
2200 return CC->getNextLeader().first;
2202 ++NumGVNSortedLeaderChanges;
2206 return getMinDFSOfRange<Value>(*CC);
2219 void NewGVN::moveMemoryToNewCongruenceClass(
Instruction *I,
2221 CongruenceClass *OldClass,
2222 CongruenceClass *NewClass) {
2225 assert((!InstMA || !OldClass->getMemoryLeader() ||
2226 OldClass->getLeader() != I ||
2227 MemoryAccessToClass.lookup(OldClass->getMemoryLeader()) ==
2228 MemoryAccessToClass.lookup(InstMA)) &&
2229 "Representative MemoryAccess mismatch");
2231 if (!NewClass->getMemoryLeader()) {
2233 assert(NewClass->size() == 1 ||
2234 (isa<StoreInst>(
I) && NewClass->getStoreCount() == 1));
2235 NewClass->setMemoryLeader(InstMA);
2238 << NewClass->getID()
2239 <<
" due to new memory instruction becoming leader\n");
2240 markMemoryLeaderChangeTouched(NewClass);
2242 setMemoryClass(InstMA, NewClass);
2244 if (OldClass->getMemoryLeader() == InstMA) {
2245 if (!OldClass->definesNoMemory()) {
2246 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2248 << OldClass->getID() <<
" to " 2249 << *OldClass->getMemoryLeader()
2250 <<
" due to removal of old leader " << *InstMA <<
"\n");
2251 markMemoryLeaderChangeTouched(OldClass);
2253 OldClass->setMemoryLeader(
nullptr);
2260 CongruenceClass *OldClass,
2261 CongruenceClass *NewClass) {
2262 if (I == OldClass->getNextLeader().first)
2263 OldClass->resetNextLeader();
2266 NewClass->insert(I);
2268 if (NewClass->getLeader() !=
I)
2269 NewClass->addPossibleNextLeader({I, InstrToDFSNum(I)});
2271 if (
auto *SI = dyn_cast<StoreInst>(I)) {
2272 OldClass->decStoreCount();
2280 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2283 if (
auto *SE = dyn_cast<StoreExpression>(E)) {
2284 NewClass->setStoredValue(SE->getStoredValue());
2285 markValueLeaderChangeTouched(NewClass);
2288 << NewClass->getID() <<
" from " 2289 << *NewClass->getLeader() <<
" to " << *SI
2290 <<
" because store joined class\n");
2293 NewClass->setLeader(SI);
2297 NewClass->incStoreCount();
2303 auto *InstMA = dyn_cast_or_null<MemoryDef>(getMemoryAccess(I));
2305 moveMemoryToNewCongruenceClass(I, InstMA, OldClass, NewClass);
2306 ValueToClass[
I] = NewClass;
2308 if (OldClass->empty() && OldClass != TOPClass) {
2309 if (OldClass->getDefiningExpr()) {
2310 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2311 <<
" from table\n");
2314 auto Iter = ExpressionToClass.find_as(
2316 if (Iter != ExpressionToClass.end())
2317 ExpressionToClass.erase(Iter);
2318 #ifdef EXPENSIVE_CHECKS 2320 (*OldClass->getDefiningExpr() != *E || ExpressionToClass.lookup(E)) &&
2321 "We erased the expression we just inserted, which should not happen");
2324 }
else if (OldClass->getLeader() ==
I) {
2329 << OldClass->getID() <<
"\n");
2330 ++NumGVNLeaderChanges;
2335 if (OldClass->getStoreCount() == 0) {
2336 if (OldClass->getStoredValue())
2337 OldClass->setStoredValue(
nullptr);
2339 OldClass->setLeader(getNextValueLeader(OldClass));
2340 OldClass->resetNextLeader();
2341 markValueLeaderChangeTouched(OldClass);
2347 void NewGVN::markPhiOfOpsChanged(
const Expression *E) {
2348 touchAndErase(ExpressionToPhiOfOps, E);
2356 CongruenceClass *IClass = ValueToClass.lookup(I);
2357 assert(IClass &&
"Should have found a IClass");
2359 assert(!IClass->isDead() &&
"Found a dead class");
2361 CongruenceClass *EClass =
nullptr;
2362 if (
const auto *VE = dyn_cast<VariableExpression>(E)) {
2363 EClass = ValueToClass.lookup(VE->getVariableValue());
2364 }
else if (isa<DeadExpression>(E)) {
2368 auto lookupResult = ExpressionToClass.insert({
E,
nullptr});
2371 if (lookupResult.second) {
2372 CongruenceClass *NewClass = createCongruenceClass(
nullptr, E);
2373 auto place = lookupResult.first;
2374 place->second = NewClass;
2377 if (
const auto *CE = dyn_cast<ConstantExpression>(E)) {
2378 NewClass->setLeader(CE->getConstantValue());
2379 }
else if (
const auto *SE = dyn_cast<StoreExpression>(E)) {
2381 NewClass->setLeader(SI);
2382 NewClass->setStoredValue(SE->getStoredValue());
2386 NewClass->setLeader(I);
2388 assert(!isa<VariableExpression>(E) &&
2389 "VariableExpression should have been handled already");
2393 <<
" using expression " << *E <<
" at " 2394 << NewClass->getID() <<
" and leader " 2395 << *(NewClass->getLeader()));
2396 if (NewClass->getStoredValue())
2398 << *(NewClass->getStoredValue()));
2401 EClass = lookupResult.first->second;
2402 if (isa<ConstantExpression>(E))
2403 assert((isa<Constant>(EClass->getLeader()) ||
2404 (EClass->getStoredValue() &&
2405 isa<Constant>(EClass->getStoredValue()))) &&
2406 "Any class with a constant expression should have a " 2409 assert(EClass &&
"Somehow don't have an eclass");
2411 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2414 bool ClassChanged = IClass != EClass;
2415 bool LeaderChanged = LeaderChanges.erase(I);
2416 if (ClassChanged || LeaderChanged) {
2417 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression " 2420 moveValueToNewCongruenceClass(I, E, IClass, EClass);
2421 markPhiOfOpsChanged(E);
2424 markUsersTouched(I);
2426 markMemoryUsersTouched(MA);
2427 if (
auto *CI = dyn_cast<CmpInst>(I))
2428 markPredicateUsersTouched(CI);
2434 if (ClassChanged && isa<StoreInst>(I)) {
2435 auto *OldE = ValueToExpression.lookup(I);
2438 if (OldE && isa<StoreExpression>(OldE) && *E != *OldE) {
2442 if (Iter != ExpressionToClass.end())
2443 ExpressionToClass.erase(Iter);
2446 ValueToExpression[
I] =
E;
2453 if (ReachableEdges.insert({From, To}).second) {
2455 if (ReachableBlocks.insert(To).second) {
2457 <<
" marked reachable\n");
2458 const auto &InstRange = BlockInstRange.lookup(To);
2459 TouchedInstructions.set(InstRange.first, InstRange.second);
2462 <<
" was reachable, but new edge {" 2464 <<
"} to it found\n");
2471 TouchedInstructions.set(InstrToDFSNum(MemPhi));
2476 for (
auto InstNum : RevisitOnReachabilityChange[To])
2477 TouchedInstructions.set(InstNum);
2484 Value *NewGVN::findConditionEquivalence(
Value *Cond)
const {
2485 auto Result = lookupOperandLeader(Cond);
2486 return isa<Constant>(Result) ? Result :
nullptr;
2493 if ((BR = dyn_cast<BranchInst>(TI)) && BR->
isConditional()) {
2495 Value *CondEvaluated = findConditionEquivalence(Cond);
2496 if (!CondEvaluated) {
2497 if (
auto *I = dyn_cast<Instruction>(Cond)) {
2499 if (
const auto *CE = dyn_cast<ConstantExpression>(E)) {
2500 CondEvaluated = CE->getConstantValue();
2502 }
else if (isa<ConstantInt>(Cond)) {
2503 CondEvaluated = Cond;
2509 if (CondEvaluated && (CI = dyn_cast<ConstantInt>(CondEvaluated))) {
2512 <<
" evaluated to true\n");
2513 updateReachableEdge(B, TrueSucc);
2514 }
else if (CI->
isZero()) {
2516 <<
" evaluated to false\n");
2517 updateReachableEdge(B, FalseSucc);
2520 updateReachableEdge(B, TrueSucc);
2521 updateReachableEdge(B, FalseSucc);
2523 }
else if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
2530 Value *SwitchCond = SI->getCondition();
2531 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2533 if (CondEvaluated && isa<ConstantInt>(CondEvaluated)) {
2534 auto *CondVal = cast<ConstantInt>(CondEvaluated);
2536 auto Case = *SI->findCaseValue(CondVal);
2537 if (Case.getCaseSuccessor() == SI->getDefaultDest()) {
2541 updateReachableEdge(B, SI->getDefaultDest());
2545 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2546 updateReachableEdge(B, TargetBlock);
2550 ++SwitchEdges[TargetBlock];
2551 updateReachableEdge(B, TargetBlock);
2559 updateReachableEdge(B, TargetBlock);
2565 auto *MA = getMemoryAccess(TI);
2566 if (MA && !isa<MemoryUse>(MA)) {
2567 auto *CC = ensureLeaderOfMemoryClass(MA);
2568 if (setMemoryClass(MA, CC))
2569 markMemoryUsersTouched(MA);
2576 InstrDFS.erase(PHITemp);
2579 TempToBlock.erase(PHITemp);
2580 RealToTemp.erase(I);
2590 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2591 AllTempInstructions.insert(Op);
2592 TempToBlock[
Op] = BB;
2593 RealToTemp[ExistingValue] =
Op;
2596 for (
auto *U : ExistingValue->
users())
2597 if (
auto *UI = dyn_cast<Instruction>(U))
2598 PHINodeUses.insert(UI);
2604 return isa<BinaryOperator>(
I) || isa<SelectInst>(I) || isa<CmpInst>(
I) ||
2608 bool NewGVN::OpIsSafeForPHIOfOpsHelper(
2613 if (!isa<Instruction>(V))
2615 auto OISIt = OpSafeForPHIOfOps.find(V);
2616 if (OISIt != OpSafeForPHIOfOps.end())
2617 return OISIt->second;
2621 if (DT->properlyDominates(getBlockForValue(V), PHIBlock)) {
2622 OpSafeForPHIOfOps.insert({V,
true});
2626 if (isa<PHINode>(V) && getBlockForValue(V) == PHIBlock) {
2627 OpSafeForPHIOfOps.insert({V,
false});
2631 auto *OrigI = cast<Instruction>(V);
2633 if (!isa<Instruction>(Op))
2636 auto OISIt = OpSafeForPHIOfOps.find(OrigI);
2637 if (OISIt != OpSafeForPHIOfOps.end()) {
2638 if (!OISIt->second) {
2639 OpSafeForPHIOfOps.insert({V,
false});
2644 if (!Visited.
insert(Op).second)
2646 Worklist.
push_back(cast<Instruction>(Op));
2658 bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2661 if (!OpIsSafeForPHIOfOpsHelper(V, PHIBlock, Visited, Worklist))
2663 while (!Worklist.
empty()) {
2665 if (!OpIsSafeForPHIOfOpsHelper(I, PHIBlock, Visited, Worklist))
2668 OpSafeForPHIOfOps.insert({V,
true});
2681 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2683 AllTempInstructions.insert(TransInst);
2687 TempToBlock.insert({TransInst, PredBB});
2688 InstrDFS.insert({TransInst, IDFSNum});
2690 const Expression *E = performSymbolicEvaluation(TransInst, Visited);
2691 InstrDFS.erase(TransInst);
2692 AllTempInstructions.erase(TransInst);
2693 TempToBlock.erase(TransInst);
2695 TempToMemory.erase(TransInst);
2698 auto *FoundVal = findPHIOfOpsLeader(E, OrigInst, PredBB);
2700 ExpressionToPhiOfOps[
E].insert(OrigInst);
2701 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2705 if (
auto *SI = dyn_cast<StoreInst>(FoundVal))
2718 if (!Visited.
insert(I).second)
2724 if (!isCycleFree(I))
2731 auto *MemAccess = getMemoryAccess(I);
2735 if (MemAccess && !isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2746 for (
auto *Op : Ops) {
2747 if (!isa<PHINode>(Op)) {
2748 auto *ValuePHI = RealToTemp.lookup(Op);
2754 OpPHI = cast<PHINode>(
Op);
2755 if (!SamePHIBlock) {
2756 SamePHIBlock = getBlockForValue(OpPHI);
2757 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2760 <<
"PHIs for operands are not all in the same block, aborting\n");
2775 auto *PHIBlock = getBlockForValue(OpPHI);
2776 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(I));
2777 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2779 Value *FoundVal =
nullptr;
2783 if (ReachableEdges.count({PredBB, PHIBlock})) {
2788 TempToMemory.insert({ValueOp, MemAccess});
2789 bool SafeForPHIOfOps =
true;
2791 for (
auto &Op : ValueOp->
operands()) {
2792 auto *OrigOp = &*
Op;
2795 if (isa<PHINode>(Op)) {
2797 if (Op != OrigOp && Op != I)
2799 }
else if (
auto *ValuePHI = RealToTemp.lookup(Op)) {
2800 if (getBlockForValue(ValuePHI) == PHIBlock)
2806 (Op != OrigOp || OpIsSafeForPHIOfOps(Op, PHIBlock, VisitedOps));
2813 FoundVal = !SafeForPHIOfOps ? nullptr
2814 : findLeaderForInst(ValueOp, Visited,
2815 MemAccess, I, PredBB);
2820 if (SafeForPHIOfOps)
2821 for (
auto Dep : CurrentDeps)
2822 addAdditionalUsers(Dep, I);
2828 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block " 2830 <<
" because the block is unreachable\n");
2832 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(I));
2836 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in " 2839 for (
auto Dep : Deps)
2840 addAdditionalUsers(Dep, I);
2842 auto *E = performSymbolicPHIEvaluation(PHIOps, I, PHIBlock);
2843 if (isa<ConstantExpression>(E) || isa<VariableExpression>(E)) {
2846 <<
"Not creating real PHI of ops because it simplified to existing " 2847 "value or constant\n");
2850 auto *ValuePHI = RealToTemp.lookup(I);
2851 bool NewPHI =
false;
2855 addPhiOfOps(ValuePHI, PHIBlock, I);
2857 NumGVNPHIOfOpsCreated++;
2860 for (
auto PHIOp : PHIOps)
2861 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2863 TempToBlock[ValuePHI] = PHIBlock;
2865 for (
auto PHIOp : PHIOps) {
2866 ValuePHI->setIncomingValue(i, PHIOp.first);
2867 ValuePHI->setIncomingBlock(i, PHIOp.second);
2871 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(I));
2872 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *I
2881 void NewGVN::initializeCongruenceClasses(
Function &F) {
2882 NextCongruenceNum = 0;
2892 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2893 TOPClass->setMemoryLeader(MSSA->getLiveOnEntryDef());
2895 MemoryAccessToClass[MSSA->getLiveOnEntryDef()] =
2896 createMemoryClass(MSSA->getLiveOnEntryDef());
2898 for (
auto DTN :
nodes(DT)) {
2904 auto *MemoryBlockDefs = MSSA->getBlockDefs(BB);
2905 if (MemoryBlockDefs)
2906 for (
const auto &
Def : *MemoryBlockDefs) {
2907 MemoryAccessToClass[&
Def] = TOPClass;
2912 TOPClass->memory_insert(MP);
2913 MemoryPhiState.insert({MP, MPS_TOP});
2916 if (MD && isa<StoreInst>(MD->getMemoryInst()))
2917 TOPClass->incStoreCount();
2923 for (
auto &I : *BB) {
2924 if (isa<PHINode>(&I))
2925 for (
auto *U : I.
users())
2926 if (
auto *UInst = dyn_cast<Instruction>(U))
2928 PHINodeUses.insert(UInst);
2933 TOPClass->insert(&I);
2934 ValueToClass[&
I] = TOPClass;
2939 for (
auto &FA : F.
args())
2940 createSingletonCongruenceClass(&FA);
2943 void NewGVN::cleanupTables() {
2944 for (
unsigned i = 0, e = CongruenceClasses.size(); i != e; ++i) {
2946 <<
" has " << CongruenceClasses[i]->
size()
2950 delete CongruenceClasses[i];
2951 CongruenceClasses[i] =
nullptr;
2956 AllTempInstructions.end());
2957 AllTempInstructions.
clear();
2961 for (
auto *I : TempInst) {
2965 while (!TempInst.empty()) {
2966 auto *I = TempInst.back();
2967 TempInst.pop_back();
2971 ValueToClass.clear();
2972 ArgRecycler.clear(ExpressionAllocator);
2973 ExpressionAllocator.Reset();
2974 CongruenceClasses.clear();
2975 ExpressionToClass.clear();
2976 ValueToExpression.clear();
2978 AdditionalUsers.clear();
2979 ExpressionToPhiOfOps.clear();
2980 TempToBlock.clear();
2981 TempToMemory.clear();
2982 PHINodeUses.clear();
2983 OpSafeForPHIOfOps.clear();
2984 ReachableBlocks.clear();
2985 ReachableEdges.clear();
2987 ProcessedCount.clear();
2990 InstructionsToErase.clear();
2992 BlockInstRange.clear();
2993 TouchedInstructions.clear();
2994 MemoryAccessToClass.clear();
2995 PredicateToUsers.clear();
2996 MemoryToUsers.clear();
2997 RevisitOnReachabilityChange.clear();
3002 std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(
BasicBlock *B,
3004 unsigned End = Start;
3006 InstrDFS[MemPhi] = End++;
3007 DFSToInstr.emplace_back(MemPhi);
3011 for (
auto &I : *B) {
3017 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " << I <<
"\n");
3018 markInstructionForDeletion(&I);
3021 if (isa<PHINode>(&I))
3022 RevisitOnReachabilityChange[
B].set(End);
3023 InstrDFS[&
I] = End++;
3024 DFSToInstr.emplace_back(&I);
3030 return std::make_pair(Start, End);
3033 void NewGVN::updateProcessedCount(
const Value *V) {
3035 if (ProcessedCount.count(V) == 0) {
3036 ProcessedCount.insert({V, 1});
3038 ++ProcessedCount[V];
3039 assert(ProcessedCount[V] < 100 &&
3040 "Seem to have processed the same Value a lot");
3046 void NewGVN::valueNumberMemoryPhi(
MemoryPhi *MP) {
3053 return cast<MemoryAccess>(U) != MP &&
3054 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3055 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3060 if (Filtered.begin() == Filtered.end()) {
3061 if (setMemoryClass(MP, TOPClass))
3062 markMemoryUsersTouched(MP);
3068 auto LookupFunc = [&](
const Use &U) {
3069 return lookupMemoryLeader(cast<MemoryAccess>(U));
3071 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3072 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3076 const auto *AllSameValue = *MappedBegin;
3079 MappedBegin, MappedEnd,
3080 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3083 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3092 CongruenceClass *CC =
3093 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3094 auto OldState = MemoryPhiState.lookup(MP);
3095 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3096 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3097 MemoryPhiState[MP] = NewState;
3098 if (setMemoryClass(MP, CC) || OldState != NewState)
3099 markMemoryUsersTouched(MP);
3104 void NewGVN::valueNumberInstruction(
Instruction *I) {
3110 Symbolized = performSymbolicEvaluation(I, Visited);
3112 if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
3113 !isa<VariableExpression>(Symbolized) && PHINodeUses.count(I)) {
3114 auto *PHIE = makePossiblePHIOfOps(I, Visited);
3119 }
else if (
auto *Op = RealToTemp.lookup(I)) {
3120 removePhiOfOps(I, Op);
3129 if (Symbolized ==
nullptr)
3130 Symbolized = createUnknownExpression(I);
3131 performCongruenceFinding(I, Symbolized);
3137 auto *Symbolized = createUnknownExpression(I);
3138 performCongruenceFinding(I, Symbolized);
3140 processOutgoingEdges(I, I->
getParent());
3146 bool NewGVN::singleReachablePHIPath(
3149 if (First == Second)
3151 if (MSSA->isLiveOnEntryDef(First))
3159 if (Visited.
count(First))
3163 const auto *EndDef = First;
3165 if (ChainDef == Second)
3167 if (MSSA->isLiveOnEntryDef(ChainDef))
3171 auto *MP = cast<MemoryPhi>(EndDef);
3172 auto ReachableOperandPred = [&](
const Use &U) {
3175 auto FilteredPhiArgs =
3178 llvm::copy(FilteredPhiArgs, std::back_inserter(OperandList));
3181 return singleReachablePHIPath(Visited, cast<MemoryAccess>(OperandList[0]),
3190 void NewGVN::verifyMemoryCongruency()
const {
3193 for (
const auto *CC : CongruenceClasses) {
3194 if (CC == TOPClass || CC->isDead())
3196 if (CC->getStoreCount() != 0) {
3197 assert((CC->getStoredValue() || !isa<StoreInst>(CC->getLeader())) &&
3198 "Any class with a store as a leader should have a " 3199 "representative stored value");
3200 assert(CC->getMemoryLeader() &&
3201 "Any congruence class with a store should have a " 3202 "representative access");
3205 if (CC->getMemoryLeader())
3206 assert(MemoryAccessToClass.lookup(CC->getMemoryLeader()) == CC &&
3207 "Representative MemoryAccess does not appear to be reverse " 3209 for (
auto M : CC->memory())
3210 assert(MemoryAccessToClass.lookup(M) == CC &&
3211 "Memory member does not appear to be reverse mapped properly");
3219 auto ReachableAccessPred =
3220 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3221 bool Result = ReachableBlocks.count(Pair.first->getBlock());
3222 if (!Result || MSSA->isLiveOnEntryDef(Pair.first) ||
3223 MemoryToDFSNum(Pair.first) == 0)
3225 if (
auto *MemDef = dyn_cast<MemoryDef>(Pair.first))
3230 if (
auto *MemPHI = dyn_cast<MemoryPhi>(Pair.first)) {
3231 for (
auto &U : MemPHI->incoming_values()) {
3232 if (
auto *I = dyn_cast<Instruction>(&*U)) {
3244 for (
auto KV : Filtered) {
3245 if (
auto *FirstMUD = dyn_cast<MemoryUseOrDef>(KV.first)) {
3247 if (FirstMUD && SecondMUD) {
3249 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3250 ValueToClass.lookup(FirstMUD->getMemoryInst()) ==
3251 ValueToClass.lookup(SecondMUD->getMemoryInst())) &&
3252 "The instructions for these memory operations should have " 3253 "been in the same congruence class or reachable through" 3254 "a single argument phi");
3256 }
else if (
auto *FirstMP = dyn_cast<MemoryPhi>(KV.first)) {
3259 auto ReachableOperandPred = [&](
const Use &U) {
3260 return ReachableEdges.count(
3261 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3266 auto FilteredPhiArgs =
3270 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3271 const MemoryDef *MD = cast<MemoryDef>(U);
3275 "All MemoryPhi arguments should be in the same class");
3284 void NewGVN::verifyIterationSettled(
Function &F) {
3294 std::map<const Value *, CongruenceClass> BeforeIteration;
3296 for (
auto &KV : ValueToClass) {
3297 if (
auto *I = dyn_cast<Instruction>(KV.first))
3299 if (InstrToDFSNum(I) == 0)
3301 BeforeIteration.insert({KV.first, *KV.second});
3304 TouchedInstructions.set();
3305 TouchedInstructions.reset(0);
3306 iterateTouchedInstructions();
3309 for (
const auto &KV : ValueToClass) {
3310 if (
auto *I = dyn_cast<Instruction>(KV.first))
3312 if (InstrToDFSNum(I) == 0)
3316 auto *BeforeCC = &BeforeIteration.
find(KV.first)->second;
3317 auto *AfterCC = KV.second;
3320 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3321 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3322 "Value number changed after main loop completed!");
3323 EqualClasses.
insert({BeforeCC, AfterCC});
3334 void NewGVN::verifyStoreExpressions()
const {
3339 std::pair<
const Value *,
3340 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3342 for (
const auto &KV : ExpressionToClass) {
3343 if (
auto *SE = dyn_cast<StoreExpression>(KV.first)) {
3345 auto Res = StoreExpressionSet.insert(
3346 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3347 SE->getStoredValue())});
3348 bool Okay = Res.second;
3353 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3354 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3355 lookupOperandLeader(SE->getStoredValue()));
3356 assert(Okay &&
"Stored expression conflict exists in expression table");
3357 auto *ValueExpr = ValueToExpression.lookup(SE->getStoreInst());
3358 assert(ValueExpr && ValueExpr->equals(*SE) &&
3359 "StoreExpression in ExpressionToClass is not latest " 3360 "StoreExpression for value");
3369 void NewGVN::iterateTouchedInstructions() {
3370 unsigned int Iterations = 0;
3372 int FirstInstr = TouchedInstructions.find_first();
3374 if (FirstInstr == -1)
3376 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3377 while (TouchedInstructions.any()) {
3383 for (
unsigned InstrNum : TouchedInstructions.set_bits()) {
3387 if (InstrNum == 0) {
3388 TouchedInstructions.reset(InstrNum);
3392 Value *V = InstrFromDFSNum(InstrNum);
3393 const BasicBlock *CurrBlock = getBlockForValue(V);
3396 if (CurrBlock != LastBlock) {
3397 LastBlock = CurrBlock;
3398 bool BlockReachable = ReachableBlocks.count(CurrBlock);
3399 const auto &CurrInstRange = BlockInstRange.lookup(CurrBlock);
3402 if (!BlockReachable) {
3403 TouchedInstructions.reset(CurrInstRange.first, CurrInstRange.second);
3406 <<
" because it is unreachable\n");
3409 updateProcessedCount(CurrBlock);
3413 TouchedInstructions.reset(InstrNum);
3415 if (
auto *MP = dyn_cast<MemoryPhi>(V)) {
3417 valueNumberMemoryPhi(MP);
3418 }
else if (
auto *I = dyn_cast<Instruction>(V)) {
3419 valueNumberInstruction(I);
3423 updateProcessedCount(V);
3426 NumGVNMaxIterations =
std::max(NumGVNMaxIterations.getValue(), Iterations);
3430 bool NewGVN::runGVN() {
3433 bool Changed =
false;
3435 MSSAWalker = MSSA->getWalker();
3436 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3440 unsigned ICount = 1;
3442 DFSToInstr.emplace_back(
nullptr);
3452 unsigned Counter = 0;
3453 for (
auto &B : RPOT) {
3454 auto *Node = DT->getNode(B);
3455 assert(Node &&
"RPO and Dominator tree should have same reachability");
3456 RPOOrdering[Node] = ++Counter;
3459 for (
auto &B : RPOT) {
3460 auto *Node = DT->getNode(B);
3461 if (Node->getChildren().size() > 1)
3464 return RPOOrdering[
A] < RPOOrdering[
B];
3471 const auto &BlockRange = assignDFSNumbers(B, ICount);
3472 BlockInstRange.insert({
B, BlockRange});
3473 ICount += BlockRange.second - BlockRange.first;
3475 initializeCongruenceClasses(F);
3477 TouchedInstructions.resize(ICount);
3481 ExpressionToClass.reserve(ICount);
3484 const auto &InstRange = BlockInstRange.lookup(&F.
getEntryBlock());
3485 TouchedInstructions.set(InstRange.first, InstRange.second);
3487 <<
" marked reachable\n");
3490 iterateTouchedInstructions();
3491 verifyMemoryCongruency();
3492 verifyIterationSettled(F);
3493 verifyStoreExpressions();
3495 Changed |= eliminateInstructions(F);
3498 for (
Instruction *ToErase : InstructionsToErase) {
3499 if (!ToErase->use_empty())
3502 assert(ToErase->getParent() &&
3503 "BB containing ToErase deleted unexpectedly!");
3504 ToErase->eraseFromParent();
3506 Changed |= !InstructionsToErase.empty();
3509 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3510 return !ReachableBlocks.count(&BB);
3515 <<
" is unreachable\n");
3516 deleteInstructionsInBlock(&BB);
3574 return std::tie(DFSIn, DFSOut, LocalNum, Def, U) <
3585 void NewGVN::convertClassToDFSOrdered(
3589 for (
auto D : Dense) {
3594 assert(BB &&
"Should have figured out a basic block for value");
3602 if (
auto *SI = dyn_cast<StoreInst>(
D)) {
3614 "The dense set member should always be an instruction");
3619 if (
auto *PN = RealToTemp.lookup(Def)) {
3621 dyn_cast_or_null<PHIExpression>(ValueToExpression.lookup(Def));
3630 unsigned int UseCount = 0;
3632 for (
auto &U : Def->
uses()) {
3633 if (
auto *I = dyn_cast<Instruction>(U.getUser())) {
3635 if (InstructionsToErase.count(I))
3640 if (
auto *
P = dyn_cast<PHINode>(I)) {
3641 IBlock =
P->getIncomingBlock(U);
3644 VDUse.
LocalNum = InstrDFS.size() + 1;
3646 IBlock = getBlockForValue(I);
3652 if (ReachableBlocks.count(IBlock) == 0)
3668 ProbablyDead.
insert(Def);
3670 UseCounts[
Def] = UseCount;
3676 void NewGVN::convertClassToLoadsAndStores(
3677 const CongruenceClass &Dense,
3679 for (
auto D : Dense) {
3680 if (!isa<LoadInst>(
D) && !isa<StoreInst>(
D))
3691 if (
auto *I = dyn_cast<Instruction>(
D))
3705 void NewGVN::deleteInstructionsInBlock(
BasicBlock *BB) {
3707 ++NumGVNBlocksDeleted;
3711 auto StartPoint = BB->
rbegin();
3719 if (isa<LandingPadInst>(Inst))
3723 ++NumGVNInstrDeleted;
3732 void NewGVN::markInstructionForDeletion(
Instruction *I) {
3734 InstructionsToErase.insert(I);
3738 LLVM_DEBUG(
dbgs() <<
"Replacing " << *I <<
" with " << *V <<
"\n");
3742 markInstructionForDeletion(I);
3749 class ValueDFSStack {
3751 Value *back()
const {
return ValueStack.back(); }
3752 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3754 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3755 ValueStack.emplace_back(V);
3756 DFSStack.emplace_back(DFSIn, DFSOut);
3759 bool empty()
const {
return DFSStack.empty(); }
3761 bool isInScope(
int DFSIn,
int DFSOut)
const {
3764 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3767 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3770 assert(ValueStack.size() == DFSStack.size() &&
3771 "Mismatch between ValueStack and DFSStack");
3773 !DFSStack.empty() &&
3774 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3775 DFSStack.pop_back();
3776 ValueStack.pop_back();
3788 CongruenceClass *NewGVN::getClassForExpression(
const Expression *E)
const {
3789 if (
auto *VE = dyn_cast<VariableExpression>(E))
3790 return ValueToClass.lookup(VE->getVariableValue());
3791 else if (isa<DeadExpression>(E))
3793 return ExpressionToClass.lookup(E);
3802 if (
auto *CE = dyn_cast<ConstantExpression>(E))
3803 return CE->getConstantValue();
3804 if (
auto *VE = dyn_cast<VariableExpression>(E)) {
3805 auto *V = VE->getVariableValue();
3807 return VE->getVariableValue();
3810 auto *CC = getClassForExpression(E);
3814 return CC->getLeader();
3816 for (
auto Member : *CC) {
3818 if (MemberInst == OrigInst)
3823 if (DT->dominates(getBlockForValue(MemberInst), BB))
3829 bool NewGVN::eliminateInstructions(
Function &F) {
3853 bool AnythingReplaced =
false;
3857 DT->updateDFSNumbers();
3863 if (!ReachableEdges.count({PHI->getIncomingBlock(Operand), BB})) {
3867 <<
" with undef due to it being unreachable\n");
3881 for (
auto &KV : ReachableEdges)
3882 ReachablePredCount[KV.getEnd()]++;
3883 for (
auto &BBPair : RevisitOnReachabilityChange) {
3884 for (
auto InstNum : BBPair.second) {
3885 auto *Inst = InstrFromDFSNum(InstNum);
3887 PHI = PHI ? PHI : dyn_cast_or_null<PHINode>(RealToTemp.lookup(Inst));
3890 auto *BB = BBPair.first;
3891 if (ReachablePredCount.
lookup(BB) != PHI->getNumIncomingValues())
3892 ReplaceUnreachablePHIArgs(PHI, BB);
3898 for (
auto *CC :
reverse(CongruenceClasses)) {
3899 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3905 if (CC->isDead() || CC->empty())
3908 if (CC == TOPClass) {
3909 for (
auto M : *CC) {
3910 auto *VTE = ValueToExpression.lookup(M);
3911 if (VTE && isa<DeadExpression>(VTE))
3912 markInstructionForDeletion(cast<Instruction>(M));
3913 assert((!ReachableBlocks.count(cast<Instruction>(M)->getParent()) ||
3914 InstructionsToErase.count(cast<Instruction>(M))) &&
3915 "Everything in TOP should be unreachable or dead at this " 3921 assert(CC->getLeader() &&
"We should have had a leader");
3927 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3930 for (
auto M : *CC) {
3933 if (Member == Leader || !isa<Instruction>(Member) ||
3935 MembersLeft.
insert(Member);
3938 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for " 3939 << *Member <<
"\n");
3940 auto *I = cast<Instruction>(Member);
3941 assert(Leader != I &&
"About to accidentally remove our leader");
3942 replaceInstruction(I, Leader);
3943 AnythingReplaced =
true;
3945 CC->swap(MembersLeft);
3948 if (CC->size() != 1 || RealToTemp.count(Leader)) {
3953 ValueDFSStack EliminationStack;
3957 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3961 for (
auto &VD : DFSOrderedSet) {
3962 int MemberDFSIn = VD.DFSIn;
3963 int MemberDFSOut = VD.DFSOut;
3965 bool FromStore = VD.Def.getInt();
3970 auto *DefInst = dyn_cast_or_null<Instruction>(
Def);
3971 if (DefInst && AllTempInstructions.count(DefInst)) {
3972 auto *PN = cast<PHINode>(DefInst);
3977 AllTempInstructions.erase(PN);
3978 auto *DefBlock = getBlockForValue(Def);
3982 PN->insertBefore(&DefBlock->front());
3984 NumGVNPHIOfOpsEliminations++;
3987 if (EliminationStack.empty()) {
3991 << EliminationStack.dfs_back().first <<
"," 3992 << EliminationStack.dfs_back().second <<
")\n");
3995 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
"," 3996 << MemberDFSOut <<
")\n");
4010 bool ShouldPush = Def && EliminationStack.empty();
4012 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4014 if (OutOfScope || ShouldPush) {
4016 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4017 bool ShouldPush = Def && EliminationStack.empty();
4019 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4038 if (!EliminationStack.empty() && Def != EliminationStack.back() &&
4039 isa<Instruction>(
Def) && !FromStore)
4040 markInstructionForDeletion(cast<Instruction>(Def));
4046 assert(isa<Instruction>(U->get()) &&
4047 "Current def should have been an instruction");
4048 assert(isa<Instruction>(U->getUser()) &&
4049 "Current user should have been an instruction");
4055 Instruction *InstUse = cast<Instruction>(U->getUser());
4056 if (InstructionsToErase.count(InstUse)) {
4057 auto &UseCount = UseCounts[U->get()];
4058 if (--UseCount == 0) {
4059 ProbablyDead.
insert(cast<Instruction>(U->get()));
4065 if (EliminationStack.empty())
4068 Value *DominatingLeader = EliminationStack.back();
4073 DominatingLeader = II->getOperand(0);
4076 if (U->get() == DominatingLeader)
4079 <<
"Found replacement " << *DominatingLeader <<
" for " 4080 << *U->get() <<
" in " << *(U->getUser()) <<
"\n");
4085 auto *ReplacedInst = cast<Instruction>(U->get());
4086 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4087 if (!PI || DominatingLeader != PI->OriginalOp)
4089 U->set(DominatingLeader);
4092 auto &LeaderUseCount = UseCounts[DominatingLeader];
4094 if (LeaderUseCount == 0 && isa<Instruction>(DominatingLeader))
4095 ProbablyDead.
erase(cast<Instruction>(DominatingLeader));
4099 unsigned &IIUseCount = UseCounts[II];
4100 if (--IIUseCount == 0)
4104 AnythingReplaced =
true;
4111 for (
auto *I : ProbablyDead)
4113 markInstructionForDeletion(I);
4117 for (
auto *Member : *CC)
4118 if (!isa<Instruction>(Member) ||
4119 !InstructionsToErase.count(cast<Instruction>(Member)))
4120 MembersLeft.
insert(Member);
4121 CC->swap(MembersLeft);
4124 if (CC->getStoreCount() > 0) {
4125 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4127 ValueDFSStack EliminationStack;
4128 for (
auto &VD : PossibleDeadStores) {
4129 int MemberDFSIn = VD.DFSIn;
4130 int MemberDFSOut = VD.DFSOut;
4131 Instruction *Member = cast<Instruction>(VD.Def.getPointer());
4132 if (EliminationStack.empty() ||
4133 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4135 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4136 if (EliminationStack.empty()) {
4137 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4142 if (isa<LoadInst>(Member))
4144 assert(!EliminationStack.empty());
4145 Instruction *Leader = cast<Instruction>(EliminationStack.back());
4150 <<
" that is dominated by " << *Leader <<
"\n");
4151 markInstructionForDeletion(Member);
4157 return AnythingReplaced;
4165 unsigned int NewGVN::getRank(
const Value *V)
const {
4169 if (isa<ConstantExpr>(V))
4171 if (isa<UndefValue>(V))
4173 if (isa<Constant>(V))
4175 else if (
auto *A = dyn_cast<Argument>(V))
4176 return 3 + A->getArgNo();
4180 unsigned Result = InstrToDFSNum(V);
4182 return 4 + NumFuncArgs + Result;
4189 bool NewGVN::shouldSwapOperands(
const Value *A,
const Value *B)
const {
4193 return std::make_pair(getRank(A), A) > std::make_pair(getRank(B), B);
4224 if (skipFunction(F))
4226 return NewGVN(F, &getAnalysis<DominatorTreeWrapperPass>().getDomTree(),
4227 &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
4228 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(),
4229 &getAnalysis<AAResultsWrapperPass>().getAAResults(),
4230 &getAnalysis<MemorySSAWrapperPass>().getMSSA(),
Legacy wrapper pass to provide the GlobalsAAResult object.
void initializeNewGVNLegacyPassPass(PassRegistry &)
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A parsed version of the target data layout string in and methods for querying it. ...
const_iterator end(StringRef path)
Get end iterator over path.
static ConstantInt * getFalse(LLVMContext &Context)
This class is the base class for the comparison instructions.
void setInt(IntType IntVal)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
iterator_range< use_iterator > uses()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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...
~BasicExpression() override
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
unsigned getValueID() const
Return an ID for the concrete type of this object.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
void dropAllReferences()
Drop all references to operands.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
static bool equalsLoadStoreHelper(const T &LHS, const Expression &RHS)
This class represents lattice values for constants.
bool isAtomic() const
Return true if this instruction has an AtomicOrdering of unordered or higher.
static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS)
This is the interface for a simple mod/ref and alias analysis over globals.
BasicBlock * getSuccessor(unsigned Idx) const
Return the specified successor. This instruction must be a terminator.
static bool okayForPHIOfOps(const Instruction *I)
Implements a dense probed hash-table based set.
void push_back(const T &Elt)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
This class represents a function call, abstracting a target machine's calling convention.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
Represents a read-write access to memory, whether it is a must-alias, or a may-alias.
bool isTerminator() const
1 1 1 0 True if unordered or not equal
Recycle small arrays allocated from a BumpPtrAllocator.
void deleteValue()
Delete a pointer to a generic Value.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
BasicBlock * getSuccessor(unsigned i) const
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
An instruction for reading from memory.
reverse_iterator rbegin()
Value * getCondition() const
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 defines the Use class.
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
const Value * DoPHITranslation(const BasicBlock *CurBB, const BasicBlock *PredBB) const
Translate PHI node to its predecessor from the given basic block.
ExactEqualsExpression(const Expression &E)
LLVMContext & getContext() const
Get the context in which this basic block lives.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2)
Determine if Pred1 implies Pred2 is false when two compares have matching operands.
hash_code getComputedHash() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Legacy analysis pass which computes MemorySSA.
void setPointer(PointerTy PtrVal)
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.
~AggregateValueExpression() override
void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE, etc.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Value * SimplifyGEPInst(Type *SrcTy, ArrayRef< Value *> Ops, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
A Use represents the edge between a Value definition and its users.
PointerType * getPointerTo(unsigned AddrSpace=0) const
Return a pointer to the current type.
hash_code getComputedHash() const
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...
Constant * getConstantStoreValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Encapsulates MemorySSA, including all data associated with memory accesses.
static bool isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2)
Determine if Pred1 implies Pred2 is true when two compares have matching operands.
PointerIntPair< Value *, 1, bool > Def
friend const_iterator begin(StringRef path, Style style)
Get begin iterator over path.
bool equals(const Expression &Other) const override
This file provides an implementation of debug counters.
static unsigned getHashValue(const ExactEqualsExpression &E)
auto reverse(ContainerTy &&C, typename std::enable_if< has_rbegin< ContainerTy >::value >::type *=nullptr) -> decltype(make_range(C.rbegin(), C.rend()))
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
Value * SimplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
Type * getType() const
All values are typed, get the type of this value.
static int getID(struct InternalInstruction *insn, const void *miiArg)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static bool isCounterSet(unsigned ID)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
This is the generic walker interface for walkers of MemorySSA.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static const Expression * getEmptyKey()
unsigned getNumSuccessors() const
Return the number of successors that this instruction has.
Value * getOperand(unsigned i) const
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...
bool isVoidTy() const
Return true if this is 'void'.
const BasicBlock & getEntryBlock() const
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree...
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
friend const_iterator end(StringRef path)
Get end iterator over path.
Value * SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
Control flow instructions. These all have token chains.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Allocate memory in an ever growing pool, as if by bump-pointer.
Conditional or Unconditional Branch instruction.
bool is_splat(R &&Range)
Wrapper function around std::equal to detect if all elements in a container are same.
static void setCounterValue(unsigned ID, int64_t Count)
size_t size() const
size - Get the array size.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
Value * getIncomingValueForBlock(const BasicBlock *BB) const
Constant * getConstantLoadValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
mapped_iterator< ItTy, FuncTy > map_iterator(ItTy I, FuncTy F)
A manager for alias analyses.
std::pair< iterator, bool > insert(const ValueT &V)
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
static int64_t getCounterValue(unsigned ID)
Value * SimplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
Represent the analysis usage information of a pass.
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Analysis pass providing a never-invalidated alias analysis result.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This file provides the interface for LLVM's Global Value Numbering pass.
FunctionPass class - This class is used to implement most global optimizations.
Value * getPointerOperand()
unsigned getDFSNumOut() const
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
static bool shouldExecute(unsigned CounterName)
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static const Expression * getTombstoneKey()
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static bool isCopyOfAPHI(const Value *V)
void sort(IteratorTy Start, IteratorTy End)
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
A function analysis which provides an AssumptionCache.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
This is the shared class of boolean and integer constants.
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
void setOpcode(unsigned opcode)
BlockVerifier::State From
bool erase(PtrType Ptr)
erase - If the set contains the specified pointer, remove it and return true, otherwise return false...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Provides information about what library functions are available for the current target.
An analysis that produces MemorySSA for a function.
LLVM_NODISCARD T pop_back_val()
PreservedAnalyses run(Function &F, AnalysisManager< Function > &AM)
Run the pass over the function.
BasicBlock * getBlock() const
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
bool isConditional() const
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
static ConstantInt * getTrue(LLVMContext &Context)
bool isCommutative() const
Return true if the instruction is commutative:
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
A range adaptor for a pair of iterators.
static bool alwaysAvailable(Value *V)
Class that has the common methods + fields of memory uses/defs.
iterator_range< user_iterator > users()
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
An opaque object representing a hash code.
bool isMallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates uninitialized memory (such ...
Instruction * getMemoryInst() const
Get the instruction that this MemoryUse represents.
bool operator<(const ValueDFS &Other) const
amdgpu Simplify well known AMD library false Value Value * Arg
Predicate getPredicate() const
Return the predicate for this instruction.
iterator_range< typename GraphTraits< GraphType >::nodes_iterator > nodes(const GraphType &G)
static Value * getCopyOf(const Value *V)
unsigned getAlignment() const
Return the alignment of the access that is being performed.
void emplace_back(ArgTypes &&... Args)
LLVM_NODISCARD bool empty() const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
bool isCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI, bool LookThroughBitCast=false)
Tests if a value is a call or invoke to a library function that allocates zero-filled memory (such as...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
iterator find(const_arg_type_t< ValueT > V)
~LoadExpression() override
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
~CallExpression() override
iterator_range< value_op_iterator > operand_values()
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant *> Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands...
void preserve()
Mark an analysis as preserved.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
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...
static std::string getBlockName(const BasicBlock *B)
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...
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
~StoreExpression() override
Analysis pass providing the TargetLibraryInfo.
iterator_range< df_iterator< T > > depth_first(const T &G)
Value * SimplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool equals(const Expression &Other) const override
static bool isEqual(const Expression *LHS, const Expression *RHS)
static bool isCopyOfPHI(const Value *V, const PHINode *PN)
0 0 0 1 True if ordered and equal
Module * getParent()
Get the module that this global value is contained inside of...
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
~PHIExpression() override
Value * getOperand(unsigned N) const
The header file for the GVN pass that contains expression handling classes.
bool wouldInstructionBeTriviallyDead(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...
static cl::opt< bool > EnableStoreRefinement("enable-store-refinement", cl::init(false), cl::Hidden)
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
FunctionPass * createNewGVNPass()
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
A container for analyses that lazily runs them and caches their results.
Legacy analysis pass which computes a DominatorTree.
unsigned getOpcode() const
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
Represents phi nodes for memory accesses.
static unsigned getHashValue(const Expression *E)
virtual bool exactlyEquals(const Expression &Other) const
op_range incoming_values()
OutputIt copy(R &&Range, OutputIt Out)
void op_push_back(Value *Arg)
Value * getPointerOperand()
DEBUG_COUNTER(VNCounter, "newgvn-vn", "Controls which instructions are value numbered")
static IntegerType * getInt8Ty(LLVMContext &C)
INITIALIZE_PASS_BEGIN(NewGVNLegacyPass, "newgvn", "Global Value Numbering", false, false) INITIALIZE_PASS_END(NewGVNLegacyPass
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator)
iterator_range< arg_iterator > args()
A wrapper class for inspecting calls to intrinsic functions.
const BasicBlock * getParent() const
bool operator==(const Expression &Other) const