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");
182 TarjanSCC() : Components(1) {}
184 void Start(
const Instruction *Start) {
185 if (Root.lookup(Start) == 0)
189 const SmallPtrSetImpl<const Value *> &getComponentFor(
const Value *V)
const {
190 unsigned ComponentID = ValueToComponent.lookup(V);
193 "Asking for a component for a value we never processed");
194 return Components[ComponentID];
198 void FindSCC(
const Instruction *
I) {
201 unsigned int OurDFS = DFSNum;
202 for (
const auto &
Op :
I->operands()) {
204 if (Root.lookup(
Op) == 0)
206 if (!InComponent.count(
Op))
207 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
214 if (Root.lookup(
I) == OurDFS) {
215 unsigned ComponentID = Components.size();
216 Components.resize(Components.size() + 1);
220 InComponent.insert(
I);
221 ValueToComponent[
I] = ComponentID;
223 while (!Stack.empty() && Root.lookup(Stack.back()) >= OurDFS) {
224 auto *
Member = Stack.back();
227 InComponent.insert(Member);
228 ValueToComponent[
Member] = ComponentID;
237 unsigned int DFSNum = 1;
238 SmallPtrSet<const Value *, 8> InComponent;
239 DenseMap<const Value *, unsigned int> Root;
240 SmallVector<const Value *, 8> Stack;
246 DenseMap<const Value *, unsigned> ValueToComponent;
287class CongruenceClass {
289 using MemberType =
Value;
290 using MemberSet = SmallPtrSet<MemberType *, 4>;
291 using MemoryMemberType = MemoryPhi;
292 using MemoryMemberSet = SmallPtrSet<const MemoryMemberType *, 2>;
294 explicit CongruenceClass(
unsigned ID) : ID(ID) {}
295 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
297 : ID(ID), RepLeader(Leader), DefiningExpr(
E) {}
299 unsigned getID()
const {
return ID; }
306 return empty() && memory_empty();
310 Value *getLeader()
const {
return RepLeader.first; }
311 void setLeader(std::pair<Value *, unsigned int> Leader) {
314 const std::pair<Value *, unsigned int> &getNextLeader()
const {
317 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
318 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
319 if (LeaderPair.second < RepLeader.second) {
320 NextLeader = RepLeader;
321 RepLeader = LeaderPair;
323 }
else if (LeaderPair.second < NextLeader.second) {
324 NextLeader = LeaderPair;
330 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
331 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
332 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
335 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
338 bool empty()
const {
return Members.empty(); }
339 unsigned size()
const {
return Members.size(); }
342 void insert(MemberType *M) { Members.insert(M); }
343 void erase(MemberType *M) { Members.erase(M); }
347 bool memory_empty()
const {
return MemoryMembers.empty(); }
348 unsigned memory_size()
const {
return MemoryMembers.size(); }
350 return MemoryMembers.begin();
353 return MemoryMembers.end();
356 return make_range(memory_begin(), memory_end());
359 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
360 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
363 unsigned getStoreCount()
const {
return StoreCount; }
364 void incStoreCount() { ++StoreCount; }
365 void decStoreCount() {
366 assert(StoreCount != 0 &&
"Store count went negative");
371 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
375 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
381 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
383 Other->RepMemoryAccess))
385 if (DefiningExpr !=
Other->DefiningExpr)
386 if (!DefiningExpr || !
Other->DefiningExpr ||
387 *DefiningExpr != *
Other->DefiningExpr)
390 if (Members.size() !=
Other->Members.size())
401 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
406 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
409 Value *RepStoredValue =
nullptr;
413 const MemoryAccess *RepMemoryAccess =
nullptr;
416 const Expression *DefiningExpr =
nullptr;
424 MemoryMemberSet MemoryMembers;
431struct ExactEqualsExpression {
434 explicit ExactEqualsExpression(
const Expression &E) : E(E) {}
436 hash_code getComputedHash()
const {
return E.getComputedHash(); }
439 return E.exactlyEquals(
Other);
446 auto Val =
static_cast<uintptr_t
>(-1);
447 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
448 return reinterpret_cast<const Expression *
>(Val);
452 auto Val =
static_cast<uintptr_t
>(~1U);
453 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
454 return reinterpret_cast<const Expression *
>(Val);
458 return E->getComputedHash();
462 return E.getComputedHash();
481 if (LHS->getComputedHash() != RHS->getComputedHash())
503 mutable TarjanSCC SCCFinder;
505 std::unique_ptr<PredicateInfo> PredInfo;
509 unsigned int NumFuncArgs = 0;
520 CongruenceClass *TOPClass =
nullptr;
521 std::vector<CongruenceClass *> CongruenceClasses;
522 unsigned NextCongruenceNum = 0;
557 ExpressionToPhiOfOps;
606 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
607 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
609 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
610 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
613 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
614 ExpressionClassMap ExpressionToClass;
621 DeadExpression *SingletonDeadExpression =
nullptr;
624 SmallPtrSet<Value *, 8> LeaderChanges;
627 using BlockEdge = BasicBlockEdge;
628 DenseSet<BlockEdge> ReachableEdges;
629 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
640 BitVector TouchedInstructions;
642 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
643 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
647 DenseMap<const Value *, unsigned> ProcessedCount;
654 DenseMap<const Value *, unsigned> InstrDFS;
660 SmallPtrSet<Instruction *, 8> InstructionsToErase;
663 NewGVN(Function &
F, DominatorTree *DT, AssumptionCache *AC,
665 const DataLayout &
DL)
666 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
669 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
670 SQ(
DL, TLI, DT, AC, nullptr,
false,
678 const Expression *Expr;
680 const PredicateBase *PredDep;
682 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
683 const PredicateBase *PredDep =
nullptr)
684 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
685 ExprResult(
const ExprResult &) =
delete;
686 ExprResult(ExprResult &&
Other)
688 Other.Expr =
nullptr;
689 Other.ExtraDep =
nullptr;
690 Other.PredDep =
nullptr;
692 ExprResult &operator=(
const ExprResult &
Other) =
delete;
693 ExprResult &operator=(ExprResult &&
Other) =
delete;
695 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
697 operator bool()
const {
return Expr; }
699 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
700 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
701 return {Expr, ExtraDep,
nullptr};
703 static ExprResult some(
const Expression *Expr,
704 const PredicateBase *PredDep) {
705 return {Expr,
nullptr, PredDep};
707 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
708 const PredicateBase *PredDep) {
709 return {Expr, ExtraDep, PredDep};
714 ExprResult createExpression(Instruction *)
const;
715 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
716 Instruction *)
const;
720 using ValPair = std::pair<Value *, BasicBlock *>;
723 BasicBlock *,
bool &HasBackEdge,
724 bool &OriginalOpsConstant)
const;
725 const DeadExpression *createDeadExpression()
const;
726 const VariableExpression *createVariableExpression(
Value *)
const;
727 const ConstantExpression *createConstantExpression(Constant *)
const;
728 const Expression *createVariableOrConstant(
Value *V)
const;
729 const UnknownExpression *createUnknownExpression(Instruction *)
const;
730 const StoreExpression *createStoreExpression(StoreInst *,
731 const MemoryAccess *)
const;
732 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
733 const MemoryAccess *)
const;
734 const CallExpression *createCallExpression(CallInst *,
735 const MemoryAccess *)
const;
736 const AggregateValueExpression *
737 createAggregateValueExpression(Instruction *)
const;
738 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
741 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
744 unsigned LeaderDFS = 0;
752 LeaderDFS = InstrToDFSNum(
I);
754 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
755 CongruenceClasses.emplace_back(result);
759 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
760 auto *CC = createCongruenceClass(
nullptr,
nullptr);
761 CC->setMemoryLeader(MA);
765 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
766 auto *CC = getMemoryClass(MA);
767 if (CC->getMemoryLeader() != MA)
768 CC = createMemoryClass(MA);
772 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
773 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
774 CClass->insert(Member);
775 ValueToClass[
Member] = CClass;
779 void initializeCongruenceClasses(Function &
F);
780 const Expression *makePossiblePHIOfOps(Instruction *,
781 SmallPtrSetImpl<Value *> &);
782 Value *findLeaderForInst(Instruction *ValueOp,
783 SmallPtrSetImpl<Value *> &Visited,
784 MemoryAccess *MemAccess, Instruction *OrigInst,
786 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
787 SmallPtrSetImpl<const Value *> &);
788 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
789 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
792 void valueNumberMemoryPhi(MemoryPhi *);
793 void valueNumberInstruction(Instruction *);
796 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
797 ExprResult performSymbolicEvaluation(Instruction *,
798 SmallPtrSetImpl<Value *> &)
const;
799 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
801 MemoryAccess *)
const;
802 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
803 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
804 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
808 BasicBlock *PHIBlock)
const;
809 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
810 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
811 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
814 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
816 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
817 void performCongruenceFinding(Instruction *,
const Expression *);
818 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
819 CongruenceClass *, CongruenceClass *);
820 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
821 CongruenceClass *, CongruenceClass *);
822 Value *getNextValueLeader(CongruenceClass *)
const;
823 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
824 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
825 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
826 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
827 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
830 unsigned int getRank(
const Value *)
const;
831 bool shouldSwapOperands(
const Value *,
const Value *)
const;
832 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
833 const BitCastInst *
I)
const;
836 void updateReachableEdge(BasicBlock *, BasicBlock *);
837 void processOutgoingEdges(Instruction *, BasicBlock *);
838 Value *findConditionEquivalence(
Value *)
const;
842 void convertClassToDFSOrdered(
const CongruenceClass &,
843 SmallVectorImpl<ValueDFS> &,
844 DenseMap<const Value *, unsigned int> &,
845 SmallPtrSetImpl<Instruction *> &)
const;
846 void convertClassToLoadsAndStores(
const CongruenceClass &,
847 SmallVectorImpl<ValueDFS> &)
const;
849 bool eliminateInstructions(Function &);
850 void replaceInstruction(Instruction *,
Value *);
851 void markInstructionForDeletion(Instruction *);
852 void deleteInstructionsInBlock(BasicBlock *);
853 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
854 const BasicBlock *)
const;
857 template <
typename Map,
typename KeyType>
858 void touchAndErase(Map &,
const KeyType &);
859 void markUsersTouched(
Value *);
860 void markMemoryUsersTouched(
const MemoryAccess *);
861 void markMemoryDefTouched(
const MemoryAccess *);
862 void markPredicateUsersTouched(Instruction *);
863 void markValueLeaderChangeTouched(CongruenceClass *CC);
864 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
865 void markPhiOfOpsChanged(
const Expression *
E);
866 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
867 void addAdditionalUsers(
Value *To,
Value *User)
const;
868 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
871 void iterateTouchedInstructions();
874 void cleanupTables();
875 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
876 void updateProcessedCount(
const Value *V);
877 void verifyMemoryCongruency()
const;
878 void verifyIterationSettled(Function &
F);
879 void verifyStoreExpressions()
const;
880 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
881 const MemoryAccess *,
const MemoryAccess *)
const;
883 void deleteExpression(
const Expression *
E)
const;
884 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
885 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
886 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
888 unsigned InstrToDFSNum(
const Value *V)
const {
890 return InstrDFS.
lookup(V);
893 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
894 return MemoryToDFSNum(MA);
897 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
902 unsigned MemoryToDFSNum(
const Value *MA)
const {
904 "This should not be used with instructions");
910 bool isCycleFree(
const Instruction *)
const;
911 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
915 DebugCounter::CounterState StartingVNCounter;
924 return LHS.MemoryExpression::equals(
RHS);
946 return Call->getAttributes()
947 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
967MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
973MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
980 auto *Parent =
I->getParent();
983 Parent = TempToBlock.
lookup(V);
984 assert(Parent &&
"Every fake instruction should have a block");
989 assert(MP &&
"Should have been an instruction or a MemoryPhi");
990 return MP->getBlock();
996void NewGVN::deleteExpression(
const Expression *
E)
const {
1000 ExpressionAllocator.Deallocate(
E);
1006 if (BC->getType() == BC->getOperand(0)->getType())
1007 return BC->getOperand(0);
1026 return BlockInstRange.
lookup(
P1.second).first <
1027 BlockInstRange.
lookup(
P2.second).first;
1044 const Instruction *
I,
1045 BasicBlock *PHIBlock,
1047 bool &OriginalOpsConstant)
const {
1052 E->setType(PHIOperands.
begin()->first->getType());
1053 E->setOpcode(Instruction::PHI);
1057 auto *BB =
P.second;
1061 if (!ReachableEdges.
count({BB, PHIBlock}))
1064 if (ValueToClass.
lookup(
P.first) == TOPClass)
1066 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1067 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1068 return lookupOperandLeader(
P.first) !=
I;
1071 return lookupOperandLeader(
P.first);
1079 bool AllConstant =
true;
1081 E->setType(
GEP->getSourceElementType());
1083 E->setType(
I->getType());
1084 E->setOpcode(
I->getOpcode());
1085 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1090 auto Operand = lookupOperandLeader(O);
1098const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1100 Instruction *
I)
const {
1107 E->setOpcode(Opcode);
1108 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1114 if (shouldSwapOperands(Arg1, Arg2))
1117 E->op_push_back(lookupOperandLeader(Arg1));
1118 E->op_push_back(lookupOperandLeader(Arg2));
1121 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1122 addAdditionalUsers(Simplified,
I);
1131NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1134 return ExprResult::none();
1139 <<
" constant " << *
C <<
"\n");
1140 NumGVNOpsSimplified++;
1142 "We should always have had a basic expression here");
1143 deleteExpression(
E);
1144 return ExprResult::some(createConstantExpression(
C));
1148 <<
" variable " << *V <<
"\n");
1149 deleteExpression(
E);
1150 return ExprResult::some(createVariableExpression(V));
1153 CongruenceClass *CC = ValueToClass.
lookup(V);
1155 if (CC->getLeader() && CC->getLeader() !=
I) {
1156 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1158 if (CC->getDefiningExpr()) {
1161 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1162 NumGVNOpsSimplified++;
1163 deleteExpression(
E);
1164 return ExprResult::some(CC->getDefiningExpr(), V);
1168 return ExprResult::none();
1174NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1180 bool AllConstant = setBasicExpressionInfo(
I,
E);
1182 if (
I->isCommutative()) {
1187 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1188 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1189 E->swapOperands(0, 1);
1196 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1197 E->swapOperands(0, 1);
1200 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1202 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1203 "Wrong types on cmp instruction");
1204 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1205 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1208 if (
auto Simplified = checkExprResults(
E,
I, V))
1212 E->getOperand(1) ==
E->getOperand(2)) {
1213 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1214 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1216 E->getOperand(2), Q);
1217 if (
auto Simplified = checkExprResults(
E,
I, V))
1220 }
else if (
I->isBinaryOp()) {
1223 if (
auto Simplified = checkExprResults(
E,
I, V))
1228 if (
auto Simplified = checkExprResults(
E,
I, V))
1232 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1233 GEPI->getNoWrapFlags(), Q);
1234 if (
auto Simplified = checkExprResults(
E,
I, V))
1236 }
else if (AllConstant) {
1245 for (
Value *Arg :
E->operands())
1249 if (
auto Simplified = checkExprResults(
E,
I, V))
1252 return ExprResult::some(
E);
1256NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1258 auto *
E =
new (ExpressionAllocator)
1260 setBasicExpressionInfo(
I,
E);
1261 E->allocateIntOperands(ExpressionAllocator);
1265 auto *
E =
new (ExpressionAllocator)
1267 setBasicExpressionInfo(EI,
E);
1268 E->allocateIntOperands(ExpressionAllocator);
1278 return SingletonDeadExpression;
1289 return createConstantExpression(
C);
1290 return createVariableExpression(V);
1306NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1310 setBasicExpressionInfo(CI,
E);
1316 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1317 E->swapOperands(0, 1);
1323bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1324 const Instruction *U)
const {
1325 auto *CC = ValueToClass.
lookup(Inst);
1348 if (CC->getNextLeader().first &&
1352 return Member != CC->getLeader() &&
1359Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1360 CongruenceClass *CC = ValueToClass.
lookup(V);
1367 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1373const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1374 auto *CC = getMemoryClass(MA);
1375 assert(CC->getMemoryLeader() &&
1376 "Every MemoryAccess should be mapped to a congruence class with a "
1377 "representative memory access");
1378 return CC->getMemoryLeader();
1384bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1385 return getMemoryClass(MA) == TOPClass;
1390 const MemoryAccess *MA)
const {
1392 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1394 E->setType(LoadType);
1398 E->op_push_back(PointerOp);
1407NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1408 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1409 auto *
E =
new (ExpressionAllocator)
1412 E->setType(
SI->getValueOperand()->getType());
1416 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1424const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1428 auto *StoreAccess = getMemoryAccess(SI);
1430 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1434 StoreRHS = lookupMemoryLeader(StoreRHS);
1435 if (StoreRHS != StoreAccess->getDefiningAccess())
1436 addMemoryUsers(StoreRHS, StoreAccess);
1438 if (StoreRHS == StoreAccess)
1441 if (
SI->isSimple()) {
1445 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1446 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1452 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1460 LastStore->getOperand(0)) &&
1461 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1464 deleteExpression(LastStore);
1470 return createStoreExpression(SI, StoreAccess);
1476NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1477 LoadInst *LI, Instruction *DepInst,
1478 MemoryAccess *DefiningAccess)
const {
1484 if (LI->
isAtomic() > DepSI->isAtomic() ||
1485 LoadType == DepSI->getValueOperand()->getType())
1490 lookupOperandLeader(DepSI->getValueOperand()))) {
1493 <<
" to constant " << *Res <<
"\n");
1494 return createConstantExpression(Res);
1500 if (LI->
isAtomic() > DepLI->isAtomic())
1506 if (
auto *PossibleConstant =
1509 <<
" to constant " << *PossibleConstant <<
"\n");
1510 return createConstantExpression(PossibleConstant);
1516 if (
auto *PossibleConstant =
1519 <<
" to constant " << *PossibleConstant <<
"\n");
1520 return createConstantExpression(PossibleConstant);
1526 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1527 auto *LifetimePtr =
II->getOperand(0);
1528 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1537 (LoadPtr != lookupOperandLeader(DepInst) &&
1546 }
else if (
auto *InitVal =
1548 return createConstantExpression(InitVal);
1553const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1565 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1566 MemoryAccess *DefiningAccess =
1579 if (
const auto *CoercionResult =
1580 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1581 DefiningInst, DefiningAccess))
1582 return CoercionResult;
1586 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1590 if (
LE->getMemoryLeader() != DefiningAccess)
1591 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1596NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1597 auto *PI = PredInfo->getPredicateInfoFor(
I);
1599 return ExprResult::none();
1601 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1603 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1605 return ExprResult::none();
1608 Value *CmpOp0 =
I->getOperand(0);
1609 Value *CmpOp1 = Constraint->OtherOp;
1611 Value *FirstOp = lookupOperandLeader(CmpOp0);
1612 Value *SecondOp = lookupOperandLeader(CmpOp1);
1613 Value *AdditionallyUsedValue = CmpOp0;
1616 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1619 AdditionallyUsedValue = CmpOp1;
1623 return ExprResult::some(createVariableOrConstant(FirstOp),
1624 AdditionallyUsedValue, PI);
1629 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1630 AdditionallyUsedValue, PI);
1632 return ExprResult::none();
1636NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1647 return ExprResult::none();
1653 return ExprResult::none();
1656 return ExprResult::some(
1657 createCallExpression(CI, TOPClass->getMemoryLeader()));
1661 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1663 return ExprResult::some(
1664 createCallExpression(CI, TOPClass->getMemoryLeader()));
1666 return ExprResult::none();
1670CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1672 assert(Result &&
"Should have found memory class");
1678bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1679 CongruenceClass *NewClass) {
1681 "Every MemoryAccess should be getting mapped to a non-null class");
1685 <<
" with current MemoryAccess leader ");
1691 if (LookupResult != MemoryAccessToClass.
end()) {
1693 if (OldClass != NewClass) {
1696 OldClass->memory_erase(MP);
1697 NewClass->memory_insert(MP);
1699 if (OldClass->getMemoryLeader() == From) {
1700 if (OldClass->definesNoMemory()) {
1701 OldClass->setMemoryLeader(
nullptr);
1703 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1705 << OldClass->getID() <<
" to "
1706 << *OldClass->getMemoryLeader()
1707 <<
" due to removal of a memory member " << *From
1709 markMemoryLeaderChangeTouched(OldClass);
1726bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1732 auto ICS = InstCycleState.
lookup(
I);
1733 if (ICS == ICS_Unknown) {
1735 auto &
SCC = SCCFinder.getComponentFor(
I);
1737 if (
SCC.size() == 1)
1738 InstCycleState.
insert({
I, ICS_CycleFree});
1743 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1744 for (
const auto *Member : SCC)
1746 InstCycleState.
insert({MemberPhi, ICS});
1749 if (ICS == ICS_Cycle)
1758 BasicBlock *PHIBlock)
const {
1760 bool HasBackedge =
false;
1765 bool OriginalOpsConstant =
true;
1767 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1771 bool HasUndef =
false, HasPoison =
false;
1773 if (isa<PoisonValue>(Arg)) {
1784 if (Filtered.empty()) {
1789 dbgs() <<
"PHI Node " << *
I
1790 <<
" has no non-undef arguments, valuing it as undef\n");
1795 dbgs() <<
"PHI Node " << *
I
1796 <<
" has no non-poison arguments, valuing it as poison\n");
1800 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1801 deleteExpression(
E);
1802 return createDeadExpression();
1804 Value *AllSameValue = *(Filtered.begin());
1822 if (HasPoison || HasUndef) {
1828 if (HasBackedge && !OriginalOpsConstant &&
1834 if (!someEquivalentDominates(AllSameInst,
I))
1841 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1843 NumGVNPhisAllSame++;
1844 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1846 deleteExpression(
E);
1847 return createVariableOrConstant(AllSameValue);
1853NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1856 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1860 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1861 WO->getLHS(), WO->getRHS(),
I);
1864 return createAggregateValueExpression(
I);
1867NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1873 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1874 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1875 auto OurPredicate = CI->getPredicate();
1876 if (shouldSwapOperands(Op0, Op1)) {
1878 OurPredicate = CI->getSwappedPredicate();
1882 const PredicateBase *LastPredInfo =
nullptr;
1885 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1887 return ExprResult::some(
1892 if (CI->isTrueWhenEqual())
1893 return ExprResult::some(
1895 else if (CI->isFalseWhenEqual())
1896 return ExprResult::some(
1926 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1928 if (PI == LastPredInfo)
1933 if (!DT->
dominates(PBranch->To,
I->getParent()))
1943 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1944 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1945 auto BranchPredicate = BranchCond->getPredicate();
1946 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1948 BranchPredicate = BranchCond->getSwappedPredicate();
1950 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1951 if (PBranch->TrueEdge) {
1957 return ExprResult::some(createConstantExpression(
C), PI);
1962 if (BranchPredicate == OurPredicate) {
1964 return ExprResult::some(
1967 }
else if (BranchPredicate ==
1970 return ExprResult::some(
1979 return createExpression(
I);
1984NewGVN::performSymbolicEvaluation(Instruction *
I,
1985 SmallPtrSetImpl<Value *> &Visited)
const {
1991 switch (
I->getOpcode()) {
1992 case Instruction::ExtractValue:
1993 case Instruction::InsertValue:
1994 E = performSymbolicAggrValueEvaluation(
I);
1996 case Instruction::PHI: {
1999 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
2000 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2003 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
2005 case Instruction::Call:
2006 return performSymbolicCallEvaluation(
I);
2008 case Instruction::Store:
2009 E = performSymbolicStoreEvaluation(
I);
2011 case Instruction::Load:
2012 E = performSymbolicLoadEvaluation(
I);
2014 case Instruction::BitCast:
2016 if (
I->getType() ==
I->getOperand(0)->getType())
2021 case Instruction::AddrSpaceCast:
2022 case Instruction::Freeze:
2023 return createExpression(
I);
2025 case Instruction::ICmp:
2026 case Instruction::FCmp:
2027 return performSymbolicCmpEvaluation(
I);
2029 case Instruction::FNeg:
2030 case Instruction::Add:
2031 case Instruction::FAdd:
2032 case Instruction::Sub:
2033 case Instruction::FSub:
2034 case Instruction::Mul:
2035 case Instruction::FMul:
2036 case Instruction::UDiv:
2037 case Instruction::SDiv:
2038 case Instruction::FDiv:
2039 case Instruction::URem:
2040 case Instruction::SRem:
2041 case Instruction::FRem:
2042 case Instruction::Shl:
2043 case Instruction::LShr:
2044 case Instruction::AShr:
2045 case Instruction::And:
2046 case Instruction::Or:
2047 case Instruction::Xor:
2048 case Instruction::Trunc:
2049 case Instruction::ZExt:
2050 case Instruction::SExt:
2051 case Instruction::FPToUI:
2052 case Instruction::FPToSI:
2053 case Instruction::UIToFP:
2054 case Instruction::SIToFP:
2055 case Instruction::FPTrunc:
2056 case Instruction::FPExt:
2057 case Instruction::PtrToInt:
2058 case Instruction::PtrToAddr:
2059 case Instruction::IntToPtr:
2060 case Instruction::Select:
2061 case Instruction::ExtractElement:
2062 case Instruction::InsertElement:
2063 case Instruction::GetElementPtr:
2064 return createExpression(
I);
2066 case Instruction::ShuffleVector:
2068 return ExprResult::none();
2070 return ExprResult::none();
2072 return ExprResult::some(
E);
2077template <
typename Map,
typename KeyType>
2078void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2080 if (Result !=
M.end()) {
2081 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2082 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2087void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2088 assert(User && To != User);
2090 AdditionalUsers[To].
insert(User);
2093void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2094 if (Res.ExtraDep && Res.ExtraDep != User)
2095 addAdditionalUsers(Res.ExtraDep, User);
2096 Res.ExtraDep =
nullptr;
2100 PredicateToUsers[PBranch->Condition].
insert(User);
2101 else if (
const auto *PAssume =
2103 PredicateToUsers[PAssume->Condition].
insert(User);
2105 Res.PredDep =
nullptr;
2108void NewGVN::markUsersTouched(
Value *V) {
2110 for (
auto *User :
V->users()) {
2112 TouchedInstructions.
set(InstrToDFSNum(User));
2114 touchAndErase(AdditionalUsers, V);
2117void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2118 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2119 MemoryToUsers[To].
insert(U);
2122void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2123 TouchedInstructions.
set(MemoryToDFSNum(MA));
2126void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2129 for (
const auto *U : MA->
users())
2130 TouchedInstructions.
set(MemoryToDFSNum(U));
2131 touchAndErase(MemoryToUsers, MA);
2135void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2136 touchAndErase(PredicateToUsers,
I);
2140void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2141 for (
const auto *M : CC->memory())
2142 markMemoryDefTouched(M);
2147void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2148 for (
auto *M : *CC) {
2150 TouchedInstructions.
set(InstrToDFSNum(
I));
2157template <
class T,
class Range>
2158T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2159 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2160 for (
const auto X : R) {
2161 auto DFSNum = InstrToDFSNum(
X);
2162 if (DFSNum < MinDFS.second)
2163 MinDFS = {
X, DFSNum};
2165 return MinDFS.first;
2171const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2175 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2176 if (CC->getStoreCount() > 0) {
2178 return getMemoryAccess(NL);
2184 assert(CC->getStoreCount() == 0);
2188 if (CC->memory_size() == 1)
2189 return *CC->memory_begin();
2190 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2196Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2201 if (CC->size() == 1 || CC == TOPClass) {
2202 return *(CC->begin());
2203 }
else if (CC->getNextLeader().first) {
2204 ++NumGVNAvoidedSortedLeaderChanges;
2205 return CC->getNextLeader().first;
2207 ++NumGVNSortedLeaderChanges;
2211 return getMinDFSOfRange<Value>(*CC);
2224void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2225 MemoryAccess *InstMA,
2226 CongruenceClass *OldClass,
2227 CongruenceClass *NewClass) {
2230 assert((!InstMA || !OldClass->getMemoryLeader() ||
2231 OldClass->getLeader() !=
I ||
2232 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2233 MemoryAccessToClass.
lookup(InstMA)) &&
2234 "Representative MemoryAccess mismatch");
2236 if (!NewClass->getMemoryLeader()) {
2238 assert(NewClass->size() == 1 ||
2240 NewClass->setMemoryLeader(InstMA);
2243 << NewClass->getID()
2244 <<
" due to new memory instruction becoming leader\n");
2245 markMemoryLeaderChangeTouched(NewClass);
2247 setMemoryClass(InstMA, NewClass);
2249 if (OldClass->getMemoryLeader() == InstMA) {
2250 if (!OldClass->definesNoMemory()) {
2251 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2253 << OldClass->getID() <<
" to "
2254 << *OldClass->getMemoryLeader()
2255 <<
" due to removal of old leader " << *InstMA <<
"\n");
2256 markMemoryLeaderChangeTouched(OldClass);
2258 OldClass->setMemoryLeader(
nullptr);
2264void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2265 CongruenceClass *OldClass,
2266 CongruenceClass *NewClass) {
2267 if (
I == OldClass->getNextLeader().first)
2268 OldClass->resetNextLeader();
2271 NewClass->insert(
I);
2275 if (NewClass->getLeader() !=
I &&
2276 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2277 markValueLeaderChangeTouched(NewClass);
2282 OldClass->decStoreCount();
2290 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2294 NewClass->setStoredValue(SE->getStoredValue());
2295 markValueLeaderChangeTouched(NewClass);
2298 << NewClass->getID() <<
" from "
2299 << *NewClass->getLeader() <<
" to " << *SI
2300 <<
" because store joined class\n");
2303 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2307 NewClass->incStoreCount();
2315 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2316 ValueToClass[
I] = NewClass;
2318 if (OldClass->empty() && OldClass != TOPClass) {
2319 if (OldClass->getDefiningExpr()) {
2320 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2321 <<
" from table\n");
2324 auto Iter = ExpressionToClass.find_as(
2325 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2326 if (Iter != ExpressionToClass.end())
2327 ExpressionToClass.erase(Iter);
2328#ifdef EXPENSIVE_CHECKS
2330 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2331 "We erased the expression we just inserted, which should not happen");
2334 }
else if (OldClass->getLeader() ==
I) {
2339 << OldClass->getID() <<
"\n");
2340 ++NumGVNLeaderChanges;
2345 if (OldClass->getStoreCount() == 0) {
2346 if (OldClass->getStoredValue())
2347 OldClass->setStoredValue(
nullptr);
2349 OldClass->setLeader({getNextValueLeader(OldClass),
2350 InstrToDFSNum(getNextValueLeader(OldClass))});
2351 OldClass->resetNextLeader();
2352 markValueLeaderChangeTouched(OldClass);
2358void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2359 touchAndErase(ExpressionToPhiOfOps,
E);
2363void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2367 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2368 assert(IClass &&
"Should have found a IClass");
2370 assert(!IClass->isDead() &&
"Found a dead class");
2372 CongruenceClass *EClass =
nullptr;
2374 EClass = ValueToClass.
lookup(VE->getVariableValue());
2379 auto lookupResult = ExpressionToClass.try_emplace(
E);
2382 if (lookupResult.second) {
2383 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2384 auto place = lookupResult.first;
2385 place->second = NewClass;
2389 NewClass->setLeader({
CE->getConstantValue(), 0});
2391 StoreInst *
SI = SE->getStoreInst();
2392 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2393 NewClass->setStoredValue(SE->getStoredValue());
2397 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2400 "VariableExpression should have been handled already");
2404 <<
" using expression " << *
E <<
" at "
2405 << NewClass->getID() <<
" and leader "
2406 << *(NewClass->getLeader()));
2407 if (NewClass->getStoredValue())
2409 << *(NewClass->getStoredValue()));
2412 EClass = lookupResult.first->second;
2415 (EClass->getStoredValue() &&
2417 "Any class with a constant expression should have a "
2420 assert(EClass &&
"Somehow don't have an eclass");
2422 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2425 bool ClassChanged = IClass != EClass;
2426 bool LeaderChanged = LeaderChanges.
erase(
I);
2427 if (ClassChanged || LeaderChanged) {
2428 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2431 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2432 markPhiOfOpsChanged(
E);
2435 markUsersTouched(
I);
2436 if (MemoryAccess *MA = getMemoryAccess(
I))
2437 markMemoryUsersTouched(MA);
2439 markPredicateUsersTouched(CI);
2446 auto *OldE = ValueToExpression.
lookup(
I);
2452 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2453 if (Iter != ExpressionToClass.end())
2454 ExpressionToClass.erase(Iter);
2457 ValueToExpression[
I] =
E;
2462void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2464 if (ReachableEdges.
insert({From, To}).second) {
2466 if (ReachableBlocks.
insert(To).second) {
2468 <<
" marked reachable\n");
2469 const auto &InstRange = BlockInstRange.
lookup(To);
2470 TouchedInstructions.
set(InstRange.first, InstRange.second);
2473 <<
" was reachable, but new edge {"
2475 <<
"} to it found\n");
2481 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2482 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2487 for (
auto InstNum : RevisitOnReachabilityChange[To])
2488 TouchedInstructions.
set(InstNum);
2501void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2506 Value *CondEvaluated = findConditionEquivalence(
Cond);
2507 if (!CondEvaluated) {
2509 SmallPtrSet<Value *, 4> Visited;
2510 auto Res = performSymbolicEvaluation(
I, Visited);
2512 CondEvaluated =
CE->getConstantValue();
2513 addAdditionalUsers(Res,
I);
2517 Res.ExtraDep =
nullptr;
2520 CondEvaluated =
Cond;
2527 <<
" evaluated to true\n");
2528 updateReachableEdge(
B, TrueSucc);
2529 }
else if (CI->
isZero()) {
2531 <<
" evaluated to false\n");
2532 updateReachableEdge(
B, FalseSucc);
2535 updateReachableEdge(
B, TrueSucc);
2536 updateReachableEdge(
B, FalseSucc);
2542 Value *SwitchCond =
SI->getCondition();
2543 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2548 auto Case = *
SI->findCaseValue(CondVal);
2549 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2553 updateReachableEdge(
B,
SI->getDefaultDest());
2557 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2558 updateReachableEdge(
B, TargetBlock);
2560 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2561 updateReachableEdge(
B, TargetBlock);
2567 updateReachableEdge(
B, TargetBlock);
2572 auto *MA = getMemoryAccess(TI);
2574 auto *CC = ensureLeaderOfMemoryClass(MA);
2575 if (setMemoryClass(MA, CC))
2576 markMemoryUsersTouched(MA);
2582void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2583 InstrDFS.
erase(PHITemp);
2586 TempToBlock.
erase(PHITemp);
2595void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2596 Instruction *ExistingValue) {
2597 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2599 TempToBlock[
Op] = BB;
2600 RealToTemp[ExistingValue] =
Op;
2603 for (
auto *U : ExistingValue->
users())
2622bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2623 SmallPtrSetImpl<const Value *> &Visited) {
2624 SmallVector<Value *, 4> Worklist;
2626 while (!Worklist.
empty()) {
2631 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2632 if (OISIt != OpSafeForPHIOfOps.
end())
2633 return OISIt->second;
2638 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2643 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2654 if (OrigI->mayReadFromMemory())
2658 for (
auto *
Op : OrigI->operand_values()) {
2662 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2663 if (OISIt != OpSafeForPHIOfOps.
end()) {
2664 if (!OISIt->second) {
2665 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2675 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2684Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2685 SmallPtrSetImpl<Value *> &Visited,
2686 MemoryAccess *MemAccess, Instruction *OrigInst,
2687 BasicBlock *PredBB) {
2688 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2690 AllTempInstructions.
insert(TransInst);
2694 TempToBlock.
insert({TransInst, PredBB});
2695 InstrDFS.
insert({TransInst, IDFSNum});
2697 auto Res = performSymbolicEvaluation(TransInst, Visited);
2699 addAdditionalUsers(Res, OrigInst);
2700 InstrDFS.
erase(TransInst);
2701 AllTempInstructions.
erase(TransInst);
2702 TempToBlock.
erase(TransInst);
2704 TempToMemory.
erase(TransInst);
2707 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2709 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2710 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2715 FoundVal =
SI->getValueOperand();
2722NewGVN::makePossiblePHIOfOps(Instruction *
I,
2723 SmallPtrSetImpl<Value *> &Visited) {
2727 if (!Visited.
insert(
I).second)
2733 if (!isCycleFree(
I))
2739 auto *MemAccess = getMemoryAccess(
I);
2743 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2748 SmallPtrSet<const Value *, 10> VisitedOps;
2749 SmallVector<Value *, 4>
Ops(
I->operand_values());
2751 PHINode *OpPHI =
nullptr;
2754 for (
auto *
Op :
Ops) {
2756 auto *ValuePHI = RealToTemp.
lookup(
Op);
2763 if (!SamePHIBlock) {
2764 SamePHIBlock = getBlockForValue(OpPHI);
2765 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2768 <<
"PHIs for operands are not all in the same block, aborting\n");
2782 SmallPtrSet<Value *, 4> Deps;
2783 auto *PHIBlock = getBlockForValue(OpPHI);
2784 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2785 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2787 Value *FoundVal =
nullptr;
2788 SmallPtrSet<Value *, 4> CurrentDeps;
2791 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2799 TempToMemory.
insert({ValueOp, MemAccess});
2800 bool SafeForPHIOfOps =
true;
2803 auto *OrigOp = &*
Op;
2807 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2808 if (
Op != OrigOp &&
Op !=
I)
2810 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2811 if (getBlockForValue(ValuePHI) == PHIBlock)
2812 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2817 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2824 FoundVal = !SafeForPHIOfOps ? nullptr
2825 : findLeaderForInst(ValueOp, Visited,
2826 MemAccess,
I, PredBB);
2831 if (SafeForPHIOfOps)
2832 for (
auto *Dep : CurrentDeps)
2833 addAdditionalUsers(Dep,
I);
2839 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2841 <<
" because the block is unreachable\n");
2843 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2847 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2850 for (
auto *Dep : Deps)
2851 addAdditionalUsers(Dep,
I);
2853 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2857 <<
"Not creating real PHI of ops because it simplified to existing "
2858 "value or constant\n");
2864 for (
auto &O : PHIOps)
2865 addAdditionalUsers(
O.first,
I);
2869 auto *ValuePHI = RealToTemp.
lookup(
I);
2870 bool NewPHI =
false;
2874 addPhiOfOps(ValuePHI, PHIBlock,
I);
2876 NumGVNPHIOfOpsCreated++;
2879 for (
auto PHIOp : PHIOps)
2880 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2882 TempToBlock[ValuePHI] = PHIBlock;
2884 for (
auto PHIOp : PHIOps) {
2885 ValuePHI->setIncomingValue(i, PHIOp.first);
2886 ValuePHI->setIncomingBlock(i, PHIOp.second);
2890 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2891 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2900void NewGVN::initializeCongruenceClasses(Function &
F) {
2901 NextCongruenceNum = 0;
2911 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2917 for (
auto *DTN :
nodes(DT)) {
2924 if (MemoryBlockDefs)
2925 for (
const auto &Def : *MemoryBlockDefs) {
2926 MemoryAccessToClass[&
Def] = TOPClass;
2931 TOPClass->memory_insert(MP);
2932 MemoryPhiState.
insert({MP, MPS_TOP});
2936 TOPClass->incStoreCount();
2942 for (
auto &
I : *BB) {
2944 for (
auto *U :
I.users())
2947 PHINodeUses.
insert(UInst);
2950 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2952 TOPClass->insert(&
I);
2953 ValueToClass[&
I] = TOPClass;
2958 for (
auto &FA :
F.args())
2959 createSingletonCongruenceClass(&FA);
2962void NewGVN::cleanupTables() {
2963 for (CongruenceClass *&CC : CongruenceClasses) {
2964 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2965 << CC->size() <<
" members\n");
2973 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2974 AllTempInstructions.
end());
2975 AllTempInstructions.
clear();
2979 for (
auto *
I : TempInst) {
2980 I->dropAllReferences();
2983 while (!TempInst.empty()) {
2984 auto *
I = TempInst.pop_back_val();
2988 ValueToClass.
clear();
2989 ArgRecycler.
clear(ExpressionAllocator);
2990 ExpressionAllocator.Reset();
2991 CongruenceClasses.clear();
2992 ExpressionToClass.clear();
2993 ValueToExpression.
clear();
2995 AdditionalUsers.
clear();
2996 ExpressionToPhiOfOps.
clear();
2997 TempToBlock.
clear();
2998 TempToMemory.
clear();
2999 PHINodeUses.
clear();
3000 OpSafeForPHIOfOps.
clear();
3001 ReachableBlocks.
clear();
3002 ReachableEdges.
clear();
3004 ProcessedCount.
clear();
3007 InstructionsToErase.
clear();
3009 BlockInstRange.
clear();
3010 TouchedInstructions.
clear();
3011 MemoryAccessToClass.
clear();
3012 PredicateToUsers.
clear();
3013 MemoryToUsers.
clear();
3014 RevisitOnReachabilityChange.
clear();
3015 PredicateSwapChoice.
clear();
3020std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
3022 unsigned End =
Start;
3023 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
3024 InstrDFS[MemPhi] = End++;
3029 for (
auto &
I : *
B) {
3035 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3037 markInstructionForDeletion(&
I);
3041 RevisitOnReachabilityChange[
B].set(End);
3042 InstrDFS[&
I] = End++;
3049 return std::make_pair(Start, End);
3052void NewGVN::updateProcessedCount(
const Value *V) {
3054 assert(++ProcessedCount[V] < 100 &&
3055 "Seem to have processed the same Value a lot");
3060void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3067 return cast<MemoryAccess>(U) != MP &&
3068 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3069 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3074 if (Filtered.begin() == Filtered.end()) {
3075 if (setMemoryClass(MP, TOPClass))
3076 markMemoryUsersTouched(MP);
3082 auto LookupFunc = [&](
const Use &
U) {
3085 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3086 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3090 const auto *AllSameValue = *MappedBegin;
3092 bool AllEqual = std::all_of(
3093 MappedBegin, MappedEnd,
3094 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3097 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3106 CongruenceClass *CC =
3107 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3108 auto OldState = MemoryPhiState.
lookup(MP);
3109 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3110 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3111 MemoryPhiState[MP] = NewState;
3112 if (setMemoryClass(MP, CC) || OldState != NewState)
3113 markMemoryUsersTouched(MP);
3118void NewGVN::valueNumberInstruction(Instruction *
I) {
3120 if (!
I->isTerminator()) {
3122 SmallPtrSet<Value *, 2> Visited;
3124 auto Res = performSymbolicEvaluation(
I, Visited);
3125 Symbolized = Res.Expr;
3126 addAdditionalUsers(Res,
I);
3131 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3136 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3137 removePhiOfOps(
I,
Op);
3146 if (Symbolized ==
nullptr)
3147 Symbolized = createUnknownExpression(
I);
3148 performCongruenceFinding(
I, Symbolized);
3153 if (!
I->getType()->isVoidTy()) {
3154 auto *Symbolized = createUnknownExpression(
I);
3155 performCongruenceFinding(
I, Symbolized);
3157 processOutgoingEdges(
I,
I->getParent());
3163bool NewGVN::singleReachablePHIPath(
3164 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3165 const MemoryAccess *Second)
const {
3166 if (
First == Second)
3179 const auto *EndDef =
First;
3181 if (ChainDef == Second)
3188 auto ReachableOperandPred = [&](
const Use &
U) {
3191 auto FilteredPhiArgs =
3205void NewGVN::verifyMemoryCongruency()
const {
3208 for (
const auto *CC : CongruenceClasses) {
3209 if (CC == TOPClass || CC->isDead())
3211 if (CC->getStoreCount() != 0) {
3213 "Any class with a store as a leader should have a "
3214 "representative stored value");
3215 assert(CC->getMemoryLeader() &&
3216 "Any congruence class with a store should have a "
3217 "representative access");
3220 if (CC->getMemoryLeader())
3221 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3222 "Representative MemoryAccess does not appear to be reverse "
3224 for (
const auto *M : CC->memory())
3226 "Memory member does not appear to be reverse mapped properly");
3234 auto ReachableAccessPred =
3235 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3236 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3238 MemoryToDFSNum(Pair.first) == 0)
3246 for (
const auto &U : MemPHI->incoming_values()) {
3259 for (
auto KV : Filtered) {
3262 if (FirstMUD && SecondMUD) {
3263 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3264 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3265 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3266 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3267 "The instructions for these memory operations should have "
3268 "been in the same congruence class or reachable through"
3269 "a single argument phi");
3274 auto ReachableOperandPred = [&](
const Use &
U) {
3275 return ReachableEdges.
count(
3276 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3280 auto FilteredPhiArgs =
3283 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3284 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3285 const MemoryDef *MD = cast<MemoryDef>(U);
3286 return ValueToClass.lookup(MD->getMemoryInst());
3289 "All MemoryPhi arguments should be in the same class");
3298void NewGVN::verifyIterationSettled(Function &
F) {
3308 std::map<const Value *, CongruenceClass> BeforeIteration;
3310 for (
auto &KV : ValueToClass) {
3313 if (InstrToDFSNum(
I) == 0)
3315 BeforeIteration.insert({KV.first, *KV.second});
3318 TouchedInstructions.
set();
3319 TouchedInstructions.
reset(0);
3320 OpSafeForPHIOfOps.
clear();
3322 iterateTouchedInstructions();
3323 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3325 for (
const auto &KV : ValueToClass) {
3328 if (InstrToDFSNum(
I) == 0)
3332 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3333 auto *AfterCC = KV.second;
3336 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3337 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3338 "Value number changed after main loop completed!");
3339 EqualClasses.
insert({BeforeCC, AfterCC});
3350void NewGVN::verifyStoreExpressions()
const {
3355 std::pair<
const Value *,
3356 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3358 for (
const auto &KV : ExpressionToClass) {
3361 auto Res = StoreExpressionSet.insert(
3362 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3363 SE->getStoredValue())});
3364 bool Okay = Res.second;
3369 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3370 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3371 lookupOperandLeader(SE->getStoredValue()));
3372 assert(Okay &&
"Stored expression conflict exists in expression table");
3373 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3374 assert(ValueExpr && ValueExpr->equals(*SE) &&
3375 "StoreExpression in ExpressionToClass is not latest "
3376 "StoreExpression for value");
3385void NewGVN::iterateTouchedInstructions() {
3386 uint64_t Iterations = 0;
3388 int FirstInstr = TouchedInstructions.
find_first();
3390 if (FirstInstr == -1)
3392 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3393 while (TouchedInstructions.
any()) {
3399 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3403 if (InstrNum == 0) {
3404 TouchedInstructions.
reset(InstrNum);
3408 Value *
V = InstrFromDFSNum(InstrNum);
3409 const BasicBlock *CurrBlock = getBlockForValue(V);
3412 if (CurrBlock != LastBlock) {
3413 LastBlock = CurrBlock;
3414 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3415 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3418 if (!BlockReachable) {
3419 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3422 <<
" because it is unreachable\n");
3427 updateProcessedCount(CurrBlock);
3431 TouchedInstructions.
reset(InstrNum);
3435 valueNumberMemoryPhi(MP);
3437 valueNumberInstruction(
I);
3441 updateProcessedCount(V);
3444 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3448bool NewGVN::runGVN() {
3452 NumFuncArgs =
F.arg_size();
3454 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3458 unsigned ICount = 1;
3469 ReversePostOrderTraversal<Function *> RPOT(&
F);
3470 unsigned Counter = 0;
3471 for (
auto &
B : RPOT) {
3473 assert(Node &&
"RPO and Dominator tree should have same reachability");
3474 RPOOrdering[
Node] = ++Counter;
3479 for (
auto &
B : RPOT) {
3484 while (!
Node->isLeaf()) {
3489 return RPOOrdering[
A] < RPOOrdering[
B];
3492 Node->addChild(Child);
3498 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3499 BlockInstRange.
insert({
B, BlockRange});
3500 ICount += BlockRange.second - BlockRange.first;
3502 initializeCongruenceClasses(
F);
3504 TouchedInstructions.
resize(ICount);
3508 ExpressionToClass.reserve(ICount);
3511 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3512 TouchedInstructions.
set(InstRange.first, InstRange.second);
3514 <<
" marked reachable\n");
3515 ReachableBlocks.
insert(&
F.getEntryBlock());
3519 iterateTouchedInstructions();
3520 verifyMemoryCongruency();
3521 verifyIterationSettled(
F);
3522 verifyStoreExpressions();
3524 Changed |= eliminateInstructions(
F);
3527 for (Instruction *ToErase : InstructionsToErase) {
3528 if (!ToErase->use_empty())
3531 assert(ToErase->getParent() &&
3532 "BB containing ToErase deleted unexpectedly!");
3533 ToErase->eraseFromParent();
3535 Changed |= !InstructionsToErase.empty();
3538 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3539 return !ReachableBlocks.
count(&BB);
3544 <<
" is unreachable\n");
3545 deleteInstructionsInBlock(&BB);
3614void NewGVN::convertClassToDFSOrdered(
3623 assert(BB &&
"Should have figured out a basic block for value");
3632 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3634 VDDef.Def.setPointer(Leader);
3636 VDDef.Def.setPointer(
SI->getValueOperand());
3637 VDDef.Def.setInt(
true);
3640 VDDef.Def.setPointer(
D);
3643 "The dense set member should always be an instruction");
3648 if (
auto *PN = RealToTemp.
lookup(Def)) {
3652 VDDef.Def.setInt(
false);
3653 VDDef.Def.setPointer(PN);
3659 unsigned int UseCount = 0;
3661 for (
auto &U :
Def->uses()) {
3664 if (InstructionsToErase.count(
I))
3670 IBlock =
P->getIncomingBlock(U);
3675 IBlock = getBlockForValue(
I);
3681 if (!ReachableBlocks.
contains(IBlock))
3697 ProbablyDead.
insert(Def);
3699 UseCounts[
Def] = UseCount;
3705void NewGVN::convertClassToLoadsAndStores(
3706 const CongruenceClass &
Dense,
3707 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3717 VD.Def.setPointer(
D);
3731 I->replaceAllUsesWith(Repl);
3734void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3736 ++NumGVNBlocksDeleted;
3740 auto StartPoint = BB->
rbegin();
3753 ++NumGVNInstrDeleted;
3763void NewGVN::markInstructionForDeletion(Instruction *
I) {
3765 InstructionsToErase.insert(
I);
3768void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3773 markInstructionForDeletion(
I);
3780class ValueDFSStack {
3782 Value *
back()
const {
return ValueStack.back(); }
3783 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3785 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3786 ValueStack.emplace_back(V);
3787 DFSStack.emplace_back(DFSIn, DFSOut);
3790 bool empty()
const {
return DFSStack.empty(); }
3792 bool isInScope(
int DFSIn,
int DFSOut)
const {
3795 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3798 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3801 assert(ValueStack.size() == DFSStack.size() &&
3802 "Mismatch between ValueStack and DFSStack");
3804 !DFSStack.empty() &&
3805 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3806 DFSStack.pop_back();
3807 ValueStack.pop_back();
3812 SmallVector<Value *, 8> ValueStack;
3819CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3821 return ValueToClass.lookup(VE->getVariableValue());
3824 return ExpressionToClass.lookup(
E);
3830 const Instruction *OrigInst,
3831 const BasicBlock *BB)
const {
3834 return CE->getConstantValue();
3836 auto *
V = VE->getVariableValue();
3838 return VE->getVariableValue();
3841 auto *CC = getClassForExpression(
E);
3845 return CC->getLeader();
3847 for (
auto *Member : *CC) {
3849 if (MemberInst == OrigInst)
3854 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3860bool NewGVN::eliminateInstructions(Function &
F) {
3884 bool AnythingReplaced =
false;
3892 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3893 for (
auto &Operand :
PHI->incoming_values())
3894 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3898 <<
" with poison due to it being unreachable\n");
3911 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3912 for (
auto &KV : ReachableEdges)
3913 ReachablePredCount[KV.getEnd()]++;
3914 for (
auto &BBPair : RevisitOnReachabilityChange) {
3915 for (
auto InstNum : BBPair.second) {
3916 auto *Inst = InstrFromDFSNum(InstNum);
3921 auto *BB = BBPair.first;
3922 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3923 ReplaceUnreachablePHIArgs(
PHI, BB);
3928 DenseMap<const Value *, unsigned int> UseCounts;
3929 for (
auto *CC :
reverse(CongruenceClasses)) {
3930 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3935 SmallPtrSet<Instruction *, 8> ProbablyDead;
3936 if (CC->isDead() || CC->empty())
3939 if (CC == TOPClass) {
3940 for (
auto *M : *CC) {
3941 auto *VTE = ValueToExpression.
lookup(M);
3946 "Everything in TOP should be unreachable or dead at this "
3952 assert(CC->getLeader() &&
"We should have had a leader");
3958 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3960 CongruenceClass::MemberSet MembersLeft;
3961 for (
auto *M : *CC) {
3965 Member->getType()->isVoidTy()) {
3966 MembersLeft.
insert(Member);
3970 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3971 << *Member <<
"\n");
3973 assert(Leader !=
I &&
"About to accidentally remove our leader");
3974 replaceInstruction(
I, Leader);
3975 AnythingReplaced =
true;
3977 CC->swap(MembersLeft);
3980 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3985 ValueDFSStack EliminationStack;
3989 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3993 for (
auto &VD : DFSOrderedSet) {
3994 int MemberDFSIn = VD.
DFSIn;
3995 int MemberDFSOut = VD.
DFSOut;
3997 bool FromStore = VD.Def.getInt();
4000 if (Def &&
Def->getType()->isVoidTy())
4003 if (DefInst && AllTempInstructions.
count(DefInst)) {
4009 AllTempInstructions.
erase(PN);
4010 auto *DefBlock = getBlockForValue(Def);
4014 PN->insertBefore(DefBlock->begin());
4016 NumGVNPHIOfOpsEliminations++;
4019 if (EliminationStack.empty()) {
4023 << EliminationStack.dfs_back().first <<
","
4024 << EliminationStack.dfs_back().second <<
")\n");
4027 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4028 << MemberDFSOut <<
")\n");
4042 bool ShouldPush =
Def && EliminationStack.empty();
4044 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4046 if (OutOfScope || ShouldPush) {
4048 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4049 bool ShouldPush =
Def && EliminationStack.empty();
4051 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4071 if (!EliminationStack.empty() && DefI && !FromStore) {
4072 Value *DominatingLeader = EliminationStack.back();
4073 if (DominatingLeader != Def) {
4081 for (
auto *DVR : DVRUsers)
4082 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4084 markInstructionForDeletion(DefI);
4093 "Current def should have been an instruction");
4095 "Current user should have been an instruction");
4102 if (InstructionsToErase.count(InstUse)) {
4103 auto &UseCount = UseCounts[
U->get()];
4104 if (--UseCount == 0) {
4111 if (EliminationStack.empty())
4114 Value *DominatingLeader = EliminationStack.back();
4118 if (BC->getType() == BC->getOperand(0)->getType() &&
4119 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4121 DominatingLeader = BC->getOperand(0);
4126 if (
U->get() == DominatingLeader)
4133 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4134 if (!PI || DominatingLeader != PI->OriginalOp)
4138 <<
"Found replacement " << *DominatingLeader <<
" for "
4139 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4140 U->set(DominatingLeader);
4143 auto &LeaderUseCount = UseCounts[DominatingLeader];
4150 auto It = UseCounts.
find(SSACopy);
4151 if (It != UseCounts.
end()) {
4152 unsigned &IIUseCount = It->second;
4153 if (--IIUseCount == 0)
4154 ProbablyDead.
insert(SSACopy);
4158 AnythingReplaced =
true;
4165 for (
auto *
I : ProbablyDead)
4167 markInstructionForDeletion(
I);
4170 CongruenceClass::MemberSet MembersLeft;
4171 for (
auto *Member : *CC)
4174 MembersLeft.
insert(Member);
4175 CC->swap(MembersLeft);
4178 if (CC->getStoreCount() > 0) {
4179 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4181 ValueDFSStack EliminationStack;
4182 for (
auto &VD : PossibleDeadStores) {
4183 int MemberDFSIn = VD.
DFSIn;
4184 int MemberDFSOut = VD.
DFSOut;
4186 if (EliminationStack.empty() ||
4187 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4189 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4190 if (EliminationStack.empty()) {
4191 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4198 assert(!EliminationStack.empty());
4204 <<
" that is dominated by " << *Leader <<
"\n");
4205 markInstructionForDeletion(Member);
4211 return AnythingReplaced;
4219unsigned int NewGVN::getRank(
const Value *V)
const {
4234 return 4 +
A->getArgNo();
4238 unsigned Result = InstrToDFSNum(V);
4240 return 5 + NumFuncArgs +
Result;
4247bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4251 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4254bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4255 const BitCastInst *
I)
const {
4256 if (shouldSwapOperands(
A,
B)) {
4257 PredicateSwapChoice[
I] =
B;
4262 if (LookupResult != PredicateSwapChoice.
end()) {
4264 if (SeenPredicate) {
4266 if (SeenPredicate ==
B)
4285 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
Function Alias Analysis false
This file defines the BumpPtrAllocator interface.
This file implements the BitVector class.
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")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-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.
early cse Early CSE w MemorySSA
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.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
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)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
A manager for alias analyses.
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.
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 Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
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...
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
bool isConvergent() const
Determine if the invoke is convergent.
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,...
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)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
static CounterState getCounterState(CounterInfo &Info)
static void setCounterState(CounterInfo &Info, CounterState State)
static bool shouldExecute(CounterInfo &Counter)
static bool isCounterSet(CounterInfo &Info)
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
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator)
~BasicExpression() override
bool equals(const Expression &Other) const override
~CallExpression() override
void setOpcode(unsigned opcode)
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.
Value * getPointerOperand()
BasicBlock * getBlock() const
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.
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.
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)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
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()
std::pair< iterator, bool > insert(const 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.
const ParentTy * getParent() const
self_iterator getIterator()
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.
Abstract Attribute helper functions.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
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< std::optional< ExecutorSymbolDef > > LookupResult
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI Instruction & back() const
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr 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.
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
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
bool isa_and_nonnull(const Y &Val)
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &Val)
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...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ 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
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
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.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
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)
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...
SimplifyQuery getWithInstruction(const Instruction *I) const