126#define DEBUG_TYPE "newgvn"
128STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
129STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
130STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
131STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
133 "Maximum Number of iterations it took to converge GVN");
134STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
135STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
137 "Number of avoided sorted leader changes");
138STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
139STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
141 "Number of things eliminated using PHI of ops");
143 "Controls which instructions are value numbered");
145 "Controls which instructions we create phi of ops for");
180 TarjanSCC() : Components(1) {}
182 void Start(
const Instruction *Start) {
183 if (Root.lookup(Start) == 0)
187 const SmallPtrSetImpl<const Value *> &getComponentFor(
const Value *V)
const {
188 unsigned ComponentID = ValueToComponent.lookup(V);
191 "Asking for a component for a value we never processed");
192 return Components[ComponentID];
196 void FindSCC(
const Instruction *
I) {
199 unsigned int OurDFS = DFSNum;
200 for (
const auto &
Op :
I->operands()) {
202 if (Root.lookup(
Op) == 0)
204 if (!InComponent.count(
Op))
205 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
212 if (Root.lookup(
I) == OurDFS) {
213 unsigned ComponentID = Components.size();
214 Components.resize(Components.size() + 1);
218 InComponent.insert(
I);
219 ValueToComponent[
I] = ComponentID;
221 while (!Stack.empty() && Root.lookup(Stack.back()) >= OurDFS) {
222 auto *
Member = Stack.back();
225 InComponent.insert(Member);
226 ValueToComponent[
Member] = ComponentID;
235 unsigned int DFSNum = 1;
236 SmallPtrSet<const Value *, 8> InComponent;
237 DenseMap<const Value *, unsigned int> Root;
238 SmallVector<const Value *, 8> Stack;
244 DenseMap<const Value *, unsigned> ValueToComponent;
285class CongruenceClass {
287 using MemberType =
Value;
288 using MemberSet = SmallPtrSet<MemberType *, 4>;
289 using MemoryMemberType = MemoryPhi;
290 using MemoryMemberSet = SmallPtrSet<const MemoryMemberType *, 2>;
292 explicit CongruenceClass(
unsigned ID) : ID(ID) {}
293 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
295 : ID(ID), RepLeader(Leader), DefiningExpr(
E) {}
297 unsigned getID()
const {
return ID; }
304 return empty() && memory_empty();
308 Value *getLeader()
const {
return RepLeader.first; }
309 void setLeader(std::pair<Value *, unsigned int> Leader) {
310 RepLeader = std::move(Leader);
312 const std::pair<Value *, unsigned int> &getNextLeader()
const {
315 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
316 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
317 if (LeaderPair.second < RepLeader.second) {
318 NextLeader = RepLeader;
319 RepLeader = std::move(LeaderPair);
321 }
else if (LeaderPair.second < NextLeader.second) {
322 NextLeader = std::move(LeaderPair);
328 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
329 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
330 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
333 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
336 bool empty()
const {
return Members.empty(); }
337 unsigned size()
const {
return Members.size(); }
340 void insert(MemberType *M) { Members.insert(M); }
341 void erase(MemberType *M) { Members.erase(M); }
345 bool memory_empty()
const {
return MemoryMembers.empty(); }
346 unsigned memory_size()
const {
return MemoryMembers.size(); }
348 return MemoryMembers.begin();
351 return MemoryMembers.end();
354 return make_range(memory_begin(), memory_end());
357 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
358 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
361 unsigned getStoreCount()
const {
return StoreCount; }
362 void incStoreCount() { ++StoreCount; }
363 void decStoreCount() {
364 assert(StoreCount != 0 &&
"Store count went negative");
369 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
373 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
379 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
381 Other->RepMemoryAccess))
383 if (DefiningExpr !=
Other->DefiningExpr)
384 if (!DefiningExpr || !
Other->DefiningExpr ||
385 *DefiningExpr != *
Other->DefiningExpr)
388 if (Members.size() !=
Other->Members.size())
399 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
404 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
407 Value *RepStoredValue =
nullptr;
411 const MemoryAccess *RepMemoryAccess =
nullptr;
414 const Expression *DefiningExpr =
nullptr;
422 MemoryMemberSet MemoryMembers;
429struct ExactEqualsExpression {
432 explicit ExactEqualsExpression(
const Expression &E) : E(E) {}
434 hash_code getComputedHash()
const {
return E.getComputedHash(); }
437 return E.exactlyEquals(
Other);
444 return E->getComputedHash();
448 return E.getComputedHash();
462 if (LHS->getComputedHash() != RHS->getComputedHash())
484 mutable TarjanSCC SCCFinder;
486 std::unique_ptr<PredicateInfo> PredInfo;
490 unsigned int NumFuncArgs = 0;
501 CongruenceClass *TOPClass =
nullptr;
502 std::vector<CongruenceClass *> CongruenceClasses;
503 unsigned NextCongruenceNum = 0;
538 ExpressionToPhiOfOps;
587 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
588 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
590 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
591 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
594 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
595 ExpressionClassMap ExpressionToClass;
602 DeadExpression *SingletonDeadExpression =
nullptr;
605 SmallPtrSet<Value *, 8> LeaderChanges;
608 using BlockEdge = BasicBlockEdge;
609 DenseSet<BlockEdge> ReachableEdges;
610 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
621 BitVector TouchedInstructions;
623 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
624 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
628 DenseMap<const Value *, unsigned> ProcessedCount;
635 DenseMap<const Value *, unsigned> InstrDFS;
641 SmallPtrSet<Instruction *, 8> InstructionsToErase;
644 NewGVN(
Function &
F, DominatorTree *DT, AssumptionCache *AC,
646 const DataLayout &
DL)
647 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
650 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
651 SQ(
DL, TLI, DT, AC, nullptr,
false,
659 const Expression *Expr;
661 const PredicateBase *PredDep;
663 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
664 const PredicateBase *PredDep =
nullptr)
665 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
666 ExprResult(
const ExprResult &) =
delete;
667 ExprResult(ExprResult &&
Other)
669 Other.Expr =
nullptr;
670 Other.ExtraDep =
nullptr;
671 Other.PredDep =
nullptr;
673 ExprResult &operator=(
const ExprResult &
Other) =
delete;
674 ExprResult &operator=(ExprResult &&
Other) =
delete;
676 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
678 operator bool()
const {
return Expr; }
680 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
681 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
682 return {Expr, ExtraDep,
nullptr};
684 static ExprResult some(
const Expression *Expr,
685 const PredicateBase *PredDep) {
686 return {Expr,
nullptr, PredDep};
688 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
689 const PredicateBase *PredDep) {
690 return {Expr, ExtraDep, PredDep};
695 ExprResult createExpression(Instruction *)
const;
696 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
697 Instruction *)
const;
701 using ValPair = std::pair<Value *, BasicBlock *>;
704 BasicBlock *,
bool &HasBackEdge,
705 bool &OriginalOpsConstant)
const;
706 const DeadExpression *createDeadExpression()
const;
707 const VariableExpression *createVariableExpression(
Value *)
const;
708 const ConstantExpression *createConstantExpression(Constant *)
const;
709 const Expression *createVariableOrConstant(
Value *V)
const;
710 const UnknownExpression *createUnknownExpression(Instruction *)
const;
711 const StoreExpression *createStoreExpression(StoreInst *,
712 const MemoryAccess *)
const;
713 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
714 const MemoryAccess *)
const;
715 const CallExpression *createCallExpression(CallInst *,
716 const MemoryAccess *)
const;
717 const AggregateValueExpression *
718 createAggregateValueExpression(Instruction *)
const;
719 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
722 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
725 unsigned LeaderDFS = 0;
733 LeaderDFS = InstrToDFSNum(
I);
735 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
736 CongruenceClasses.emplace_back(result);
740 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
741 auto *CC = createCongruenceClass(
nullptr,
nullptr);
742 CC->setMemoryLeader(MA);
746 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
747 auto *CC = getMemoryClass(MA);
748 if (CC->getMemoryLeader() != MA)
749 CC = createMemoryClass(MA);
753 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
754 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
755 CClass->insert(Member);
756 ValueToClass[
Member] = CClass;
760 void initializeCongruenceClasses(
Function &
F);
761 const Expression *makePossiblePHIOfOps(Instruction *,
762 SmallPtrSetImpl<Value *> &);
763 Value *findLeaderForInst(Instruction *ValueOp,
764 SmallPtrSetImpl<Value *> &Visited,
765 MemoryAccess *MemAccess, Instruction *OrigInst,
767 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
768 SmallPtrSetImpl<const Value *> &);
769 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
770 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
773 void valueNumberMemoryPhi(MemoryPhi *);
774 void valueNumberInstruction(Instruction *);
777 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
778 ExprResult performSymbolicEvaluation(Instruction *,
779 SmallPtrSetImpl<Value *> &)
const;
780 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
782 MemoryAccess *)
const;
783 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
784 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
785 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
789 BasicBlock *PHIBlock)
const;
790 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
791 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
792 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
795 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
797 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
798 void performCongruenceFinding(Instruction *,
const Expression *);
799 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
800 CongruenceClass *, CongruenceClass *);
801 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
802 CongruenceClass *, CongruenceClass *);
803 Value *getNextValueLeader(CongruenceClass *)
const;
804 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
805 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
806 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
807 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
808 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
811 unsigned int getRank(
const Value *)
const;
812 bool shouldSwapOperands(
const Value *,
const Value *)
const;
813 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
814 const BitCastInst *
I)
const;
817 void updateReachableEdge(BasicBlock *, BasicBlock *);
818 void processOutgoingEdges(Instruction *, BasicBlock *);
819 Value *findConditionEquivalence(
Value *)
const;
823 void convertClassToDFSOrdered(
const CongruenceClass &,
824 SmallVectorImpl<ValueDFS> &,
825 DenseMap<const Value *, unsigned int> &,
826 SmallPtrSetImpl<Instruction *> &)
const;
827 void convertClassToLoadsAndStores(
const CongruenceClass &,
828 SmallVectorImpl<ValueDFS> &)
const;
830 bool eliminateInstructions(
Function &);
831 void replaceInstruction(Instruction *,
Value *);
832 void markInstructionForDeletion(Instruction *);
833 void deleteInstructionsInBlock(BasicBlock *);
834 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
835 const BasicBlock *)
const;
838 template <
typename Map,
typename KeyType>
839 void touchAndErase(Map &,
const KeyType &);
840 void markUsersTouched(
Value *);
841 void markMemoryUsersTouched(
const MemoryAccess *);
842 void markMemoryDefTouched(
const MemoryAccess *);
843 void markPredicateUsersTouched(Instruction *);
844 void markValueLeaderChangeTouched(CongruenceClass *CC);
845 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
846 void markPhiOfOpsChanged(
const Expression *
E);
847 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
848 void addAdditionalUsers(
Value *To,
Value *User)
const;
849 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
852 void iterateTouchedInstructions();
855 void cleanupTables();
856 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
857 void updateProcessedCount(
const Value *V);
858 void verifyMemoryCongruency()
const;
859 void verifyIterationSettled(
Function &
F);
860 void verifyStoreExpressions()
const;
861 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
862 const MemoryAccess *,
const MemoryAccess *)
const;
864 void deleteExpression(
const Expression *
E)
const;
865 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
866 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
867 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
869 unsigned InstrToDFSNum(
const Value *V)
const {
871 return InstrDFS.
lookup(V);
874 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
875 return MemoryToDFSNum(MA);
878 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
883 unsigned MemoryToDFSNum(
const Value *MA)
const {
885 "This should not be used with instructions");
891 bool isCycleFree(
const Instruction *)
const;
892 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
896 DebugCounter::CounterState StartingVNCounter;
905 return LHS.MemoryExpression::equals(
RHS);
927 return Call->getAttributes()
928 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
948MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
954MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
961 auto *Parent =
I->getParent();
964 Parent = TempToBlock.
lookup(V);
965 assert(Parent &&
"Every fake instruction should have a block");
970 assert(MP &&
"Should have been an instruction or a MemoryPhi");
971 return MP->getBlock();
977void NewGVN::deleteExpression(
const Expression *
E)
const {
981 ExpressionAllocator.Deallocate(
E);
987 if (BC->getType() == BC->getOperand(0)->getType())
988 return BC->getOperand(0);
1007 return BlockInstRange.
lookup(
P1.second).first <
1008 BlockInstRange.
lookup(
P2.second).first;
1025 const Instruction *
I,
1026 BasicBlock *PHIBlock,
1028 bool &OriginalOpsConstant)
const {
1033 E->setType(PHIOperands.
begin()->first->getType());
1034 E->setOpcode(Instruction::PHI);
1038 auto *BB =
P.second;
1042 if (!ReachableEdges.
count({BB, PHIBlock}))
1045 if (ValueToClass.
lookup(
P.first) == TOPClass)
1047 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1048 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1049 return lookupOperandLeader(
P.first) !=
I;
1052 return lookupOperandLeader(
P.first);
1060 bool AllConstant =
true;
1062 E->setType(
GEP->getSourceElementType());
1064 E->setType(
I->getType());
1065 E->setOpcode(
I->getOpcode());
1066 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1071 auto Operand = lookupOperandLeader(O);
1079const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1081 Instruction *
I)
const {
1088 E->setOpcode(Opcode);
1089 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1095 if (shouldSwapOperands(Arg1, Arg2))
1098 E->op_push_back(lookupOperandLeader(Arg1));
1099 E->op_push_back(lookupOperandLeader(Arg2));
1102 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1103 addAdditionalUsers(Simplified,
I);
1112NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1115 return ExprResult::none();
1120 <<
" constant " << *
C <<
"\n");
1121 NumGVNOpsSimplified++;
1123 "We should always have had a basic expression here");
1124 deleteExpression(
E);
1125 return ExprResult::some(createConstantExpression(
C));
1129 <<
" variable " << *V <<
"\n");
1130 deleteExpression(
E);
1131 return ExprResult::some(createVariableExpression(V));
1134 CongruenceClass *CC = ValueToClass.
lookup(V);
1136 if (CC->getLeader() && CC->getLeader() !=
I) {
1137 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1139 if (CC->getDefiningExpr()) {
1142 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1143 NumGVNOpsSimplified++;
1144 deleteExpression(
E);
1145 return ExprResult::some(CC->getDefiningExpr(), V);
1149 return ExprResult::none();
1155NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1161 bool AllConstant = setBasicExpressionInfo(
I,
E);
1163 if (
I->isCommutative()) {
1168 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1169 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1170 E->swapOperands(0, 1);
1177 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1178 E->swapOperands(0, 1);
1181 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1183 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1184 "Wrong types on cmp instruction");
1185 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1186 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1189 if (
auto Simplified = checkExprResults(
E,
I, V))
1193 E->getOperand(1) ==
E->getOperand(2)) {
1194 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1195 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1197 E->getOperand(2), FastMathFlags(), Q);
1198 if (
auto Simplified = checkExprResults(
E,
I, V))
1201 }
else if (
I->isBinaryOp()) {
1204 if (
auto Simplified = checkExprResults(
E,
I, V))
1209 if (
auto Simplified = checkExprResults(
E,
I, V))
1213 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1214 GEPI->getNoWrapFlags(), Q);
1215 if (
auto Simplified = checkExprResults(
E,
I, V))
1217 }
else if (AllConstant) {
1226 for (
Value *Arg :
E->operands())
1230 if (
auto Simplified = checkExprResults(
E,
I, V))
1233 return ExprResult::some(
E);
1237NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1239 auto *
E =
new (ExpressionAllocator)
1241 setBasicExpressionInfo(
I,
E);
1242 E->allocateIntOperands(ExpressionAllocator);
1246 auto *
E =
new (ExpressionAllocator)
1248 setBasicExpressionInfo(EI,
E);
1249 E->allocateIntOperands(ExpressionAllocator);
1259 return SingletonDeadExpression;
1270 return createConstantExpression(
C);
1271 return createVariableExpression(V);
1287NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1291 setBasicExpressionInfo(CI,
E);
1297 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1298 E->swapOperands(0, 1);
1304bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1305 const Instruction *U)
const {
1306 auto *CC = ValueToClass.
lookup(Inst);
1329 if (CC->getNextLeader().first &&
1333 return Member != CC->getLeader() &&
1340Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1341 CongruenceClass *CC = ValueToClass.
lookup(V);
1348 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1354const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1355 auto *CC = getMemoryClass(MA);
1356 assert(CC->getMemoryLeader() &&
1357 "Every MemoryAccess should be mapped to a congruence class with a "
1358 "representative memory access");
1359 return CC->getMemoryLeader();
1365bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1366 return getMemoryClass(MA) == TOPClass;
1371 const MemoryAccess *MA)
const {
1373 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1375 E->setType(LoadType);
1379 E->op_push_back(PointerOp);
1388NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1389 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1390 auto *
E =
new (ExpressionAllocator)
1393 E->setType(
SI->getValueOperand()->getType());
1397 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1405const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1409 auto *StoreAccess = getMemoryAccess(SI);
1411 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1415 StoreRHS = lookupMemoryLeader(StoreRHS);
1416 if (StoreRHS != StoreAccess->getDefiningAccess())
1417 addMemoryUsers(StoreRHS, StoreAccess);
1419 if (StoreRHS == StoreAccess)
1422 if (
SI->isSimple()) {
1426 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1427 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1433 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1441 LastStore->getOperand(0)) &&
1442 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1445 deleteExpression(LastStore);
1451 return createStoreExpression(SI, StoreAccess);
1457NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1458 LoadInst *LI, Instruction *DepInst,
1459 MemoryAccess *DefiningAccess)
const {
1465 if (LI->
isAtomic() > DepSI->isAtomic() ||
1466 LoadType == DepSI->getValueOperand()->getType())
1471 lookupOperandLeader(DepSI->getValueOperand()))) {
1474 <<
" to constant " << *Res <<
"\n");
1475 return createConstantExpression(Res);
1481 if (LI->
isAtomic() > DepLI->isAtomic())
1487 if (
auto *PossibleConstant =
1490 <<
" to constant " << *PossibleConstant <<
"\n");
1491 return createConstantExpression(PossibleConstant);
1497 if (
auto *PossibleConstant =
1500 <<
" to constant " << *PossibleConstant <<
"\n");
1501 return createConstantExpression(PossibleConstant);
1507 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1508 auto *LifetimePtr =
II->getOperand(0);
1509 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1518 (LoadPtr != lookupOperandLeader(DepInst) &&
1527 }
else if (
auto *InitVal =
1529 return createConstantExpression(InitVal);
1534const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1546 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1547 MemoryAccess *DefiningAccess =
1560 if (
const auto *CoercionResult =
1561 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1562 DefiningInst, DefiningAccess))
1563 return CoercionResult;
1567 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1571 if (
LE->getMemoryLeader() != DefiningAccess)
1572 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1577NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1578 auto *PI = PredInfo->getPredicateInfoFor(
I);
1580 return ExprResult::none();
1582 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1584 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1586 return ExprResult::none();
1589 Value *CmpOp0 =
I->getOperand(0);
1590 Value *CmpOp1 = Constraint->OtherOp;
1592 Value *FirstOp = lookupOperandLeader(CmpOp0);
1593 Value *SecondOp = lookupOperandLeader(CmpOp1);
1594 Value *AdditionallyUsedValue = CmpOp0;
1597 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1600 AdditionallyUsedValue = CmpOp1;
1604 return ExprResult::some(createVariableOrConstant(FirstOp),
1605 AdditionallyUsedValue, PI);
1610 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1611 AdditionallyUsedValue, PI);
1613 return ExprResult::none();
1617NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1628 return ExprResult::none();
1634 return ExprResult::none();
1637 return ExprResult::some(
1638 createCallExpression(CI, TOPClass->getMemoryLeader()));
1642 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1644 return ExprResult::some(
1645 createCallExpression(CI, TOPClass->getMemoryLeader()));
1647 return ExprResult::none();
1651CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1653 assert(Result &&
"Should have found memory class");
1659bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1660 CongruenceClass *NewClass) {
1662 "Every MemoryAccess should be getting mapped to a non-null class");
1666 <<
" with current MemoryAccess leader ");
1672 if (LookupResult != MemoryAccessToClass.
end()) {
1674 if (OldClass != NewClass) {
1677 OldClass->memory_erase(MP);
1678 NewClass->memory_insert(MP);
1680 if (OldClass->getMemoryLeader() == From) {
1681 if (OldClass->definesNoMemory()) {
1682 OldClass->setMemoryLeader(
nullptr);
1684 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1686 << OldClass->getID() <<
" to "
1687 << *OldClass->getMemoryLeader()
1688 <<
" due to removal of a memory member " << *From
1690 markMemoryLeaderChangeTouched(OldClass);
1707bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1713 auto ICS = InstCycleState.
lookup(
I);
1714 if (ICS == ICS_Unknown) {
1716 auto &
SCC = SCCFinder.getComponentFor(
I);
1718 if (
SCC.size() == 1)
1719 InstCycleState.
insert({
I, ICS_CycleFree});
1724 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1725 for (
const auto *Member : SCC)
1727 InstCycleState.
insert({MemberPhi, ICS});
1730 if (ICS == ICS_Cycle)
1739 BasicBlock *PHIBlock)
const {
1741 bool HasBackedge =
false;
1746 bool OriginalOpsConstant =
true;
1748 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1752 bool HasUndef =
false, HasPoison =
false;
1754 if (isa<PoisonValue>(Arg)) {
1765 if (Filtered.empty()) {
1770 dbgs() <<
"PHI Node " << *
I
1771 <<
" has no non-undef arguments, valuing it as undef\n");
1776 dbgs() <<
"PHI Node " << *
I
1777 <<
" has no non-poison arguments, valuing it as poison\n");
1781 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1782 deleteExpression(
E);
1783 return createDeadExpression();
1785 Value *AllSameValue = *(Filtered.begin());
1803 if (HasPoison || HasUndef) {
1809 if (HasBackedge && !OriginalOpsConstant &&
1815 if (!someEquivalentDominates(AllSameInst,
I))
1822 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1824 NumGVNPhisAllSame++;
1825 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1827 deleteExpression(
E);
1828 return createVariableOrConstant(AllSameValue);
1834NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1837 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1841 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1842 WO->getLHS(), WO->getRHS(),
I);
1845 return createAggregateValueExpression(
I);
1848NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1854 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1855 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1856 auto OurPredicate = CI->getPredicate();
1857 if (shouldSwapOperands(Op0, Op1)) {
1859 OurPredicate = CI->getSwappedPredicate();
1863 const PredicateBase *LastPredInfo =
nullptr;
1866 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1868 return ExprResult::some(
1873 if (CI->isTrueWhenEqual())
1874 return ExprResult::some(
1876 else if (CI->isFalseWhenEqual())
1877 return ExprResult::some(
1907 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1909 if (PI == LastPredInfo)
1914 if (!DT->
dominates(PBranch->To,
I->getParent()))
1924 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1925 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1926 auto BranchPredicate = BranchCond->getPredicate();
1927 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1929 BranchPredicate = BranchCond->getSwappedPredicate();
1931 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1932 if (PBranch->TrueEdge) {
1938 return ExprResult::some(createConstantExpression(
C), PI);
1943 if (BranchPredicate == OurPredicate) {
1945 return ExprResult::some(
1948 }
else if (BranchPredicate ==
1951 return ExprResult::some(
1960 return createExpression(
I);
1965NewGVN::performSymbolicEvaluation(Instruction *
I,
1966 SmallPtrSetImpl<Value *> &Visited)
const {
1972 switch (
I->getOpcode()) {
1973 case Instruction::ExtractValue:
1974 case Instruction::InsertValue:
1975 E = performSymbolicAggrValueEvaluation(
I);
1977 case Instruction::PHI: {
1980 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1981 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1984 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
1986 case Instruction::Call:
1987 return performSymbolicCallEvaluation(
I);
1989 case Instruction::Store:
1990 E = performSymbolicStoreEvaluation(
I);
1992 case Instruction::Load:
1993 E = performSymbolicLoadEvaluation(
I);
1995 case Instruction::BitCast:
1997 if (
I->getType() ==
I->getOperand(0)->getType())
2002 case Instruction::AddrSpaceCast:
2003 case Instruction::Freeze:
2004 return createExpression(
I);
2006 case Instruction::ICmp:
2007 case Instruction::FCmp:
2008 return performSymbolicCmpEvaluation(
I);
2010 case Instruction::FNeg:
2011 case Instruction::Add:
2012 case Instruction::FAdd:
2013 case Instruction::Sub:
2014 case Instruction::FSub:
2015 case Instruction::Mul:
2016 case Instruction::FMul:
2017 case Instruction::UDiv:
2018 case Instruction::SDiv:
2019 case Instruction::FDiv:
2020 case Instruction::URem:
2021 case Instruction::SRem:
2022 case Instruction::FRem:
2023 case Instruction::Shl:
2024 case Instruction::LShr:
2025 case Instruction::AShr:
2026 case Instruction::And:
2027 case Instruction::Or:
2028 case Instruction::Xor:
2029 case Instruction::Trunc:
2030 case Instruction::ZExt:
2031 case Instruction::SExt:
2032 case Instruction::FPToUI:
2033 case Instruction::FPToSI:
2034 case Instruction::UIToFP:
2035 case Instruction::SIToFP:
2036 case Instruction::FPTrunc:
2037 case Instruction::FPExt:
2038 case Instruction::PtrToInt:
2039 case Instruction::PtrToAddr:
2040 case Instruction::IntToPtr:
2041 case Instruction::Select:
2042 case Instruction::ExtractElement:
2043 case Instruction::InsertElement:
2044 case Instruction::GetElementPtr:
2045 return createExpression(
I);
2047 case Instruction::ShuffleVector:
2049 return ExprResult::none();
2051 return ExprResult::none();
2053 return ExprResult::some(
E);
2058template <
typename Map,
typename KeyType>
2059void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2061 if (Result !=
M.end()) {
2062 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2063 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2068void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2069 assert(User && To != User);
2071 AdditionalUsers[To].
insert(User);
2074void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2075 if (Res.ExtraDep && Res.ExtraDep != User)
2076 addAdditionalUsers(Res.ExtraDep, User);
2077 Res.ExtraDep =
nullptr;
2081 PredicateToUsers[PBranch->Condition].
insert(User);
2082 else if (
const auto *PAssume =
2084 PredicateToUsers[PAssume->Condition].
insert(User);
2086 Res.PredDep =
nullptr;
2089void NewGVN::markUsersTouched(
Value *V) {
2091 for (
auto *User :
V->users()) {
2093 TouchedInstructions.
set(InstrToDFSNum(User));
2095 touchAndErase(AdditionalUsers, V);
2098void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2099 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2100 MemoryToUsers[To].
insert(U);
2103void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2104 TouchedInstructions.
set(MemoryToDFSNum(MA));
2107void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2110 for (
const auto *U : MA->
users())
2111 TouchedInstructions.
set(MemoryToDFSNum(U));
2112 touchAndErase(MemoryToUsers, MA);
2116void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2117 touchAndErase(PredicateToUsers,
I);
2121void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2122 for (
const auto *M : CC->memory())
2123 markMemoryDefTouched(M);
2128void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2129 for (
auto *M : *CC) {
2131 TouchedInstructions.
set(InstrToDFSNum(
I));
2138template <
class T,
class Range>
2139T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2140 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2141 for (
const auto X : R) {
2142 auto DFSNum = InstrToDFSNum(
X);
2143 if (DFSNum < MinDFS.second)
2144 MinDFS = {
X, DFSNum};
2146 return MinDFS.first;
2152const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2156 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2157 if (CC->getStoreCount() > 0) {
2159 return getMemoryAccess(NL);
2165 assert(CC->getStoreCount() == 0);
2169 if (CC->memory_size() == 1)
2170 return *CC->memory_begin();
2171 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2177Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2182 if (CC->size() == 1 || CC == TOPClass) {
2183 return *(CC->begin());
2184 }
else if (CC->getNextLeader().first) {
2185 ++NumGVNAvoidedSortedLeaderChanges;
2186 return CC->getNextLeader().first;
2188 ++NumGVNSortedLeaderChanges;
2192 return getMinDFSOfRange<Value>(*CC);
2205void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2206 MemoryAccess *InstMA,
2207 CongruenceClass *OldClass,
2208 CongruenceClass *NewClass) {
2211 assert((!InstMA || !OldClass->getMemoryLeader() ||
2212 OldClass->getLeader() !=
I ||
2213 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2214 MemoryAccessToClass.
lookup(InstMA)) &&
2215 "Representative MemoryAccess mismatch");
2217 if (!NewClass->getMemoryLeader()) {
2219 assert(NewClass->size() == 1 ||
2221 NewClass->setMemoryLeader(InstMA);
2224 << NewClass->getID()
2225 <<
" due to new memory instruction becoming leader\n");
2226 markMemoryLeaderChangeTouched(NewClass);
2228 setMemoryClass(InstMA, NewClass);
2230 if (OldClass->getMemoryLeader() == InstMA) {
2231 if (!OldClass->definesNoMemory()) {
2232 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2234 << OldClass->getID() <<
" to "
2235 << *OldClass->getMemoryLeader()
2236 <<
" due to removal of old leader " << *InstMA <<
"\n");
2237 markMemoryLeaderChangeTouched(OldClass);
2239 OldClass->setMemoryLeader(
nullptr);
2245void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2246 CongruenceClass *OldClass,
2247 CongruenceClass *NewClass) {
2248 if (
I == OldClass->getNextLeader().first)
2249 OldClass->resetNextLeader();
2252 NewClass->insert(
I);
2256 if (NewClass->getLeader() !=
I &&
2257 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2258 markValueLeaderChangeTouched(NewClass);
2263 OldClass->decStoreCount();
2271 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2275 NewClass->setStoredValue(SE->getStoredValue());
2276 markValueLeaderChangeTouched(NewClass);
2279 << NewClass->getID() <<
" from "
2280 << *NewClass->getLeader() <<
" to " << *SI
2281 <<
" because store joined class\n");
2284 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2288 NewClass->incStoreCount();
2296 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2297 ValueToClass[
I] = NewClass;
2299 if (OldClass->empty() && OldClass != TOPClass) {
2300 if (OldClass->getDefiningExpr()) {
2301 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2302 <<
" from table\n");
2305 auto Iter = ExpressionToClass.find_as(
2306 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2307 if (Iter != ExpressionToClass.end())
2308 ExpressionToClass.erase(Iter);
2309#ifdef EXPENSIVE_CHECKS
2311 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2312 "We erased the expression we just inserted, which should not happen");
2315 }
else if (OldClass->getLeader() ==
I) {
2320 << OldClass->getID() <<
"\n");
2321 ++NumGVNLeaderChanges;
2326 if (OldClass->getStoreCount() == 0) {
2327 if (OldClass->getStoredValue())
2328 OldClass->setStoredValue(
nullptr);
2330 OldClass->setLeader({getNextValueLeader(OldClass),
2331 InstrToDFSNum(getNextValueLeader(OldClass))});
2332 OldClass->resetNextLeader();
2333 markValueLeaderChangeTouched(OldClass);
2339void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2340 touchAndErase(ExpressionToPhiOfOps,
E);
2344void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2348 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2349 assert(IClass &&
"Should have found a IClass");
2351 assert(!IClass->isDead() &&
"Found a dead class");
2353 CongruenceClass *EClass =
nullptr;
2355 EClass = ValueToClass.
lookup(VE->getVariableValue());
2360 auto lookupResult = ExpressionToClass.try_emplace(
E);
2363 if (lookupResult.second) {
2364 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2365 auto place = lookupResult.first;
2366 place->second = NewClass;
2370 NewClass->setLeader({
CE->getConstantValue(), 0});
2372 StoreInst *
SI = SE->getStoreInst();
2373 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2374 NewClass->setStoredValue(SE->getStoredValue());
2378 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2381 "VariableExpression should have been handled already");
2385 <<
" using expression " << *
E <<
" at "
2386 << NewClass->getID() <<
" and leader "
2387 << *(NewClass->getLeader()));
2388 if (NewClass->getStoredValue())
2390 << *(NewClass->getStoredValue()));
2393 EClass = lookupResult.first->second;
2396 (EClass->getStoredValue() &&
2398 "Any class with a constant expression should have a "
2401 assert(EClass &&
"Somehow don't have an eclass");
2403 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2406 bool ClassChanged = IClass != EClass;
2407 bool LeaderChanged = LeaderChanges.
erase(
I);
2408 if (ClassChanged || LeaderChanged) {
2409 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2412 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2413 markPhiOfOpsChanged(
E);
2416 markUsersTouched(
I);
2417 if (MemoryAccess *MA = getMemoryAccess(
I))
2418 markMemoryUsersTouched(MA);
2420 markPredicateUsersTouched(CI);
2427 auto *OldE = ValueToExpression.
lookup(
I);
2433 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2434 if (Iter != ExpressionToClass.end())
2435 ExpressionToClass.erase(Iter);
2438 ValueToExpression[
I] =
E;
2443void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2445 if (ReachableEdges.
insert({From, To}).second) {
2447 if (ReachableBlocks.
insert(To).second) {
2449 <<
" marked reachable\n");
2450 const auto &InstRange = BlockInstRange.
lookup(To);
2451 TouchedInstructions.
set(InstRange.first, InstRange.second);
2454 <<
" was reachable, but new edge {"
2456 <<
"} to it found\n");
2462 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2463 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2468 for (
auto InstNum : RevisitOnReachabilityChange[To])
2469 TouchedInstructions.
set(InstNum);
2482void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2487 Value *CondEvaluated = findConditionEquivalence(
Cond);
2488 if (!CondEvaluated) {
2490 SmallPtrSet<Value *, 4> Visited;
2491 auto Res = performSymbolicEvaluation(
I, Visited);
2493 CondEvaluated =
CE->getConstantValue();
2494 addAdditionalUsers(Res,
I);
2498 Res.ExtraDep =
nullptr;
2501 CondEvaluated =
Cond;
2508 <<
" evaluated to true\n");
2509 updateReachableEdge(
B, TrueSucc);
2510 }
else if (CI->
isZero()) {
2512 <<
" evaluated to false\n");
2513 updateReachableEdge(
B, FalseSucc);
2516 updateReachableEdge(
B, TrueSucc);
2517 updateReachableEdge(
B, FalseSucc);
2523 Value *SwitchCond =
SI->getCondition();
2524 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2529 auto Case = *
SI->findCaseValue(CondVal);
2530 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2534 updateReachableEdge(
B,
SI->getDefaultDest());
2538 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2539 updateReachableEdge(
B, TargetBlock);
2541 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2542 updateReachableEdge(
B, TargetBlock);
2548 updateReachableEdge(
B, TargetBlock);
2553 auto *MA = getMemoryAccess(TI);
2555 auto *CC = ensureLeaderOfMemoryClass(MA);
2556 if (setMemoryClass(MA, CC))
2557 markMemoryUsersTouched(MA);
2563void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2564 InstrDFS.
erase(PHITemp);
2567 TempToBlock.
erase(PHITemp);
2576void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2577 Instruction *ExistingValue) {
2578 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2580 TempToBlock[
Op] = BB;
2581 RealToTemp[ExistingValue] =
Op;
2584 for (
auto *U : ExistingValue->
users())
2603bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2604 SmallPtrSetImpl<const Value *> &Visited) {
2605 SmallVector<Value *, 4> Worklist;
2607 while (!Worklist.
empty()) {
2612 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2613 if (OISIt != OpSafeForPHIOfOps.
end())
2614 return OISIt->second;
2619 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2624 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2635 if (OrigI->mayReadFromMemory())
2639 for (
auto *
Op : OrigI->operand_values()) {
2643 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2644 if (OISIt != OpSafeForPHIOfOps.
end()) {
2645 if (!OISIt->second) {
2646 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2656 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2665Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2666 SmallPtrSetImpl<Value *> &Visited,
2667 MemoryAccess *MemAccess, Instruction *OrigInst,
2668 BasicBlock *PredBB) {
2669 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2671 AllTempInstructions.
insert(TransInst);
2675 TempToBlock.
insert({TransInst, PredBB});
2676 InstrDFS.
insert({TransInst, IDFSNum});
2678 auto Res = performSymbolicEvaluation(TransInst, Visited);
2680 addAdditionalUsers(Res, OrigInst);
2681 InstrDFS.
erase(TransInst);
2682 AllTempInstructions.
erase(TransInst);
2683 TempToBlock.
erase(TransInst);
2685 TempToMemory.
erase(TransInst);
2688 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2690 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2691 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2696 FoundVal =
SI->getValueOperand();
2703NewGVN::makePossiblePHIOfOps(Instruction *
I,
2704 SmallPtrSetImpl<Value *> &Visited) {
2708 if (!Visited.
insert(
I).second)
2714 if (!isCycleFree(
I))
2720 auto *MemAccess = getMemoryAccess(
I);
2724 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2729 SmallPtrSet<const Value *, 10> VisitedOps;
2730 SmallVector<Value *, 4>
Ops(
I->operand_values());
2732 PHINode *OpPHI =
nullptr;
2735 for (
auto *
Op :
Ops) {
2737 auto *ValuePHI = RealToTemp.
lookup(
Op);
2744 if (!SamePHIBlock) {
2745 SamePHIBlock = getBlockForValue(OpPHI);
2746 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2749 <<
"PHIs for operands are not all in the same block, aborting\n");
2763 SmallPtrSet<Value *, 4> Deps;
2764 auto *PHIBlock = getBlockForValue(OpPHI);
2765 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2766 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2768 Value *FoundVal =
nullptr;
2769 SmallPtrSet<Value *, 4> CurrentDeps;
2772 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2780 TempToMemory.
insert({ValueOp, MemAccess});
2781 bool SafeForPHIOfOps =
true;
2784 auto *OrigOp = &*
Op;
2788 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2789 if (
Op != OrigOp &&
Op !=
I)
2791 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2792 if (getBlockForValue(ValuePHI) == PHIBlock)
2793 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2798 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2805 FoundVal = !SafeForPHIOfOps ? nullptr
2806 : findLeaderForInst(ValueOp, Visited,
2807 MemAccess,
I, PredBB);
2812 if (SafeForPHIOfOps)
2813 for (
auto *Dep : CurrentDeps)
2814 addAdditionalUsers(Dep,
I);
2820 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2822 <<
" because the block is unreachable\n");
2824 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2828 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2831 for (
auto *Dep : Deps)
2832 addAdditionalUsers(Dep,
I);
2834 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2838 <<
"Not creating real PHI of ops because it simplified to existing "
2839 "value or constant\n");
2845 for (
auto &O : PHIOps)
2846 addAdditionalUsers(
O.first,
I);
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
2881void NewGVN::initializeCongruenceClasses(
Function &
F) {
2882 NextCongruenceNum = 0;
2892 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2898 for (
auto *DTN :
nodes(DT)) {
2905 if (MemoryBlockDefs)
2906 for (
const auto &Def : *MemoryBlockDefs) {
2907 MemoryAccessToClass[&
Def] = TOPClass;
2912 TOPClass->memory_insert(MP);
2913 MemoryPhiState.
insert({MP, MPS_TOP});
2917 TOPClass->incStoreCount();
2923 for (
auto &
I : *BB) {
2925 for (
auto *U :
I.users())
2928 PHINodeUses.
insert(UInst);
2931 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2933 TOPClass->insert(&
I);
2934 ValueToClass[&
I] = TOPClass;
2939 for (
auto &FA :
F.args())
2940 createSingletonCongruenceClass(&FA);
2943void NewGVN::cleanupTables() {
2944 for (CongruenceClass *&CC : CongruenceClasses) {
2945 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2946 << CC->size() <<
" members\n");
2954 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2955 AllTempInstructions.
end());
2956 AllTempInstructions.
clear();
2960 for (
auto *
I : TempInst) {
2961 I->dropAllReferences();
2964 while (!TempInst.empty()) {
2965 auto *
I = TempInst.pop_back_val();
2969 ValueToClass.
clear();
2970 ArgRecycler.
clear(ExpressionAllocator);
2971 ExpressionAllocator.Reset();
2972 CongruenceClasses.clear();
2973 ExpressionToClass.clear();
2974 ValueToExpression.
clear();
2976 AdditionalUsers.
clear();
2977 ExpressionToPhiOfOps.
clear();
2978 TempToBlock.
clear();
2979 TempToMemory.
clear();
2980 PHINodeUses.
clear();
2981 OpSafeForPHIOfOps.
clear();
2982 ReachableBlocks.
clear();
2983 ReachableEdges.
clear();
2985 ProcessedCount.
clear();
2988 InstructionsToErase.
clear();
2990 BlockInstRange.
clear();
2991 TouchedInstructions.
clear();
2992 MemoryAccessToClass.
clear();
2993 PredicateToUsers.
clear();
2994 MemoryToUsers.
clear();
2995 RevisitOnReachabilityChange.
clear();
2996 PredicateSwapChoice.
clear();
3001std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
3003 unsigned End =
Start;
3004 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
3005 InstrDFS[MemPhi] = End++;
3010 for (
auto &
I : *
B) {
3016 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3018 markInstructionForDeletion(&
I);
3022 RevisitOnReachabilityChange[
B].set(End);
3023 InstrDFS[&
I] = End++;
3030 return std::make_pair(Start, End);
3033void NewGVN::updateProcessedCount(
const Value *V) {
3035 assert(++ProcessedCount[V] < 100 &&
3036 "Seem to have processed the same Value a lot");
3041void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3048 return cast<MemoryAccess>(U) != MP &&
3049 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3050 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3055 if (Filtered.begin() == Filtered.end()) {
3056 if (setMemoryClass(MP, TOPClass))
3057 markMemoryUsersTouched(MP);
3063 auto LookupFunc = [&](
const Use &
U) {
3066 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3067 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3071 const auto *AllSameValue = *MappedBegin;
3073 bool AllEqual = std::all_of(
3074 MappedBegin, MappedEnd,
3075 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3078 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3087 CongruenceClass *CC =
3088 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3089 auto OldState = MemoryPhiState.
lookup(MP);
3090 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3091 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3092 MemoryPhiState[MP] = NewState;
3093 if (setMemoryClass(MP, CC) || OldState != NewState)
3094 markMemoryUsersTouched(MP);
3099void NewGVN::valueNumberInstruction(Instruction *
I) {
3101 if (!
I->isTerminator()) {
3103 SmallPtrSet<Value *, 2> Visited;
3105 auto Res = performSymbolicEvaluation(
I, Visited);
3106 Symbolized = Res.Expr;
3107 addAdditionalUsers(Res,
I);
3112 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3117 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3118 removePhiOfOps(
I,
Op);
3127 if (Symbolized ==
nullptr)
3128 Symbolized = createUnknownExpression(
I);
3129 performCongruenceFinding(
I, Symbolized);
3134 if (!
I->getType()->isVoidTy()) {
3135 auto *Symbolized = createUnknownExpression(
I);
3136 performCongruenceFinding(
I, Symbolized);
3138 processOutgoingEdges(
I,
I->getParent());
3144bool NewGVN::singleReachablePHIPath(
3145 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3146 const MemoryAccess *Second)
const {
3147 if (
First == Second)
3160 const auto *EndDef =
First;
3162 if (ChainDef == Second)
3169 auto ReachableOperandPred = [&](
const Use &
U) {
3172 auto FilteredPhiArgs =
3186void NewGVN::verifyMemoryCongruency()
const {
3189 for (
const auto *CC : CongruenceClasses) {
3190 if (CC == TOPClass || CC->isDead())
3192 if (CC->getStoreCount() != 0) {
3194 "Any class with a store as a leader should have a "
3195 "representative stored value");
3196 assert(CC->getMemoryLeader() &&
3197 "Any congruence class with a store should have a "
3198 "representative access");
3201 if (CC->getMemoryLeader())
3202 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3203 "Representative MemoryAccess does not appear to be reverse "
3205 for (
const auto *M : CC->memory())
3207 "Memory member does not appear to be reverse mapped properly");
3215 auto ReachableAccessPred =
3216 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3217 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3219 MemoryToDFSNum(Pair.first) == 0)
3227 for (
const auto &U : MemPHI->incoming_values()) {
3240 for (
auto KV : Filtered) {
3243 if (FirstMUD && SecondMUD) {
3244 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3245 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3246 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3247 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3248 "The instructions for these memory operations should have "
3249 "been in the same congruence class or reachable through"
3250 "a single argument phi");
3255 auto ReachableOperandPred = [&](
const Use &
U) {
3256 return ReachableEdges.
count(
3257 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3261 auto FilteredPhiArgs =
3264 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3265 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3266 const MemoryDef *MD = cast<MemoryDef>(U);
3267 return ValueToClass.lookup(MD->getMemoryInst());
3270 "All MemoryPhi arguments should be in the same class");
3279void NewGVN::verifyIterationSettled(
Function &
F) {
3289 std::map<const Value *, CongruenceClass> BeforeIteration;
3291 for (
auto &KV : ValueToClass) {
3294 if (InstrToDFSNum(
I) == 0)
3296 BeforeIteration.insert({KV.first, *KV.second});
3299 TouchedInstructions.
set();
3300 TouchedInstructions.
reset(0);
3301 OpSafeForPHIOfOps.
clear();
3303 iterateTouchedInstructions();
3304 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3306 for (
const auto &KV : ValueToClass) {
3309 if (InstrToDFSNum(
I) == 0)
3313 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3314 auto *AfterCC = KV.second;
3317 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3318 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3319 "Value number changed after main loop completed!");
3320 EqualClasses.
insert({BeforeCC, AfterCC});
3331void NewGVN::verifyStoreExpressions()
const {
3336 std::pair<
const Value *,
3337 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3339 for (
const auto &KV : ExpressionToClass) {
3342 auto Res = StoreExpressionSet.insert(
3343 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3344 SE->getStoredValue())});
3345 bool Okay = Res.second;
3350 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3351 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3352 lookupOperandLeader(SE->getStoredValue()));
3353 assert(Okay &&
"Stored expression conflict exists in expression table");
3354 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3355 assert(ValueExpr && ValueExpr->equals(*SE) &&
3356 "StoreExpression in ExpressionToClass is not latest "
3357 "StoreExpression for value");
3366void NewGVN::iterateTouchedInstructions() {
3369 int FirstInstr = TouchedInstructions.
find_first();
3371 if (FirstInstr == -1)
3373 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3374 while (TouchedInstructions.
any()) {
3380 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3384 if (InstrNum == 0) {
3385 TouchedInstructions.
reset(InstrNum);
3389 Value *
V = InstrFromDFSNum(InstrNum);
3390 const BasicBlock *CurrBlock = getBlockForValue(V);
3393 if (CurrBlock != LastBlock) {
3394 LastBlock = CurrBlock;
3395 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3396 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3399 if (!BlockReachable) {
3400 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3403 <<
" because it is unreachable\n");
3408 updateProcessedCount(CurrBlock);
3412 TouchedInstructions.
reset(InstrNum);
3416 valueNumberMemoryPhi(MP);
3418 valueNumberInstruction(
I);
3422 updateProcessedCount(V);
3425 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3429bool NewGVN::runGVN() {
3433 NumFuncArgs =
F.arg_size();
3435 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3439 unsigned ICount = 1;
3445 ReversePostOrderTraversal<Function *> RPOT(&
F);
3446 unsigned Counter = 0;
3447 for (BasicBlock *
B : RPOT) {
3449 assert(Node &&
"RPO and Dominator tree should have same reachability");
3450 RPOOrdering[
Node] = ++Counter;
3451 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3452 BlockInstRange.
insert({
B, BlockRange});
3453 ICount += BlockRange.second - BlockRange.first;
3455 initializeCongruenceClasses(
F);
3457 TouchedInstructions.
resize(ICount);
3461 ExpressionToClass.reserve(ICount);
3464 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3465 TouchedInstructions.
set(InstRange.first, InstRange.second);
3467 <<
" marked reachable\n");
3468 ReachableBlocks.
insert(&
F.getEntryBlock());
3472 iterateTouchedInstructions();
3473 verifyMemoryCongruency();
3474 verifyIterationSettled(
F);
3475 verifyStoreExpressions();
3477 Changed |= eliminateInstructions(
F);
3480 for (Instruction *ToErase : InstructionsToErase) {
3481 if (!ToErase->use_empty())
3484 assert(ToErase->getParent() &&
3485 "BB containing ToErase deleted unexpectedly!");
3486 ToErase->eraseFromParent();
3488 Changed |= !InstructionsToErase.empty();
3491 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3492 return !ReachableBlocks.
count(&BB);
3497 <<
" is unreachable\n");
3498 deleteInstructionsInBlock(&BB);
3567void NewGVN::convertClassToDFSOrdered(
3576 assert(BB &&
"Should have figured out a basic block for value");
3585 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3587 VDDef.Def.setPointer(Leader);
3589 VDDef.Def.setPointer(
SI->getValueOperand());
3590 VDDef.Def.setInt(
true);
3593 VDDef.Def.setPointer(
D);
3596 "The dense set member should always be an instruction");
3601 if (
auto *PN = RealToTemp.
lookup(Def)) {
3605 VDDef.Def.setInt(
false);
3606 VDDef.Def.setPointer(PN);
3612 unsigned int UseCount = 0;
3614 for (
auto &U :
Def->uses()) {
3617 if (InstructionsToErase.count(
I))
3623 IBlock =
P->getIncomingBlock(U);
3628 IBlock = getBlockForValue(
I);
3634 if (!ReachableBlocks.
contains(IBlock))
3650 ProbablyDead.
insert(Def);
3652 UseCounts[
Def] = UseCount;
3658void NewGVN::convertClassToLoadsAndStores(
3659 const CongruenceClass &
Dense,
3660 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3670 VD.Def.setPointer(
D);
3684 I->replaceAllUsesWith(Repl);
3687void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3689 ++NumGVNBlocksDeleted;
3693 auto StartPoint = BB->
rbegin();
3706 ++NumGVNInstrDeleted;
3716void NewGVN::markInstructionForDeletion(Instruction *
I) {
3718 InstructionsToErase.insert(
I);
3721void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3726 markInstructionForDeletion(
I);
3733class ValueDFSStack {
3735 Value *
back()
const {
return ValueStack.back(); }
3736 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3738 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3739 ValueStack.emplace_back(V);
3740 DFSStack.emplace_back(DFSIn, DFSOut);
3743 bool empty()
const {
return DFSStack.empty(); }
3745 bool isInScope(
int DFSIn,
int DFSOut)
const {
3748 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3751 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3754 assert(ValueStack.size() == DFSStack.size() &&
3755 "Mismatch between ValueStack and DFSStack");
3757 !DFSStack.empty() &&
3758 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3759 DFSStack.pop_back();
3760 ValueStack.pop_back();
3765 SmallVector<Value *, 8> ValueStack;
3772CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3774 return ValueToClass.lookup(VE->getVariableValue());
3777 return ExpressionToClass.lookup(
E);
3783 const Instruction *OrigInst,
3784 const BasicBlock *BB)
const {
3787 return CE->getConstantValue();
3789 auto *
V = VE->getVariableValue();
3791 return VE->getVariableValue();
3794 auto *CC = getClassForExpression(
E);
3798 return CC->getLeader();
3800 for (
auto *Member : *CC) {
3802 if (MemberInst == OrigInst)
3807 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3813bool NewGVN::eliminateInstructions(
Function &
F) {
3837 bool AnythingReplaced =
false;
3845 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3846 for (
auto &Operand :
PHI->incoming_values())
3847 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3851 <<
" with poison due to it being unreachable\n");
3864 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3865 for (
auto &KV : ReachableEdges)
3866 ReachablePredCount[KV.getEnd()]++;
3867 for (
auto &BBPair : RevisitOnReachabilityChange) {
3868 for (
auto InstNum : BBPair.second) {
3869 auto *Inst = InstrFromDFSNum(InstNum);
3874 auto *BB = BBPair.first;
3875 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3876 ReplaceUnreachablePHIArgs(
PHI, BB);
3881 DenseMap<const Value *, unsigned int> UseCounts;
3882 for (
auto *CC :
reverse(CongruenceClasses)) {
3883 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3888 SmallPtrSet<Instruction *, 8> ProbablyDead;
3889 if (CC->isDead() || CC->empty())
3892 if (CC == TOPClass) {
3893 for (
auto *M : *CC) {
3894 auto *VTE = ValueToExpression.
lookup(M);
3899 "Everything in TOP should be unreachable or dead at this "
3905 assert(CC->getLeader() &&
"We should have had a leader");
3911 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3913 CongruenceClass::MemberSet MembersLeft;
3914 for (
auto *M : *CC) {
3918 Member->getType()->isVoidTy()) {
3919 MembersLeft.
insert(Member);
3923 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3924 << *Member <<
"\n");
3926 assert(Leader !=
I &&
"About to accidentally remove our leader");
3927 replaceInstruction(
I, Leader);
3928 AnythingReplaced =
true;
3930 CC->swap(MembersLeft);
3933 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3938 ValueDFSStack EliminationStack;
3942 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3946 for (
auto &VD : DFSOrderedSet) {
3947 int MemberDFSIn = VD.
DFSIn;
3948 int MemberDFSOut = VD.
DFSOut;
3950 bool FromStore = VD.Def.getInt();
3953 if (Def &&
Def->getType()->isVoidTy())
3956 if (DefInst && AllTempInstructions.
count(DefInst)) {
3962 AllTempInstructions.
erase(PN);
3963 auto *DefBlock = getBlockForValue(Def);
3967 PN->insertBefore(DefBlock->begin());
3969 NumGVNPHIOfOpsEliminations++;
3972 if (EliminationStack.empty()) {
3976 << EliminationStack.dfs_back().first <<
","
3977 << EliminationStack.dfs_back().second <<
")\n");
3980 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
3981 << MemberDFSOut <<
")\n");
3995 bool ShouldPush =
Def && EliminationStack.empty();
3997 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
3999 if (OutOfScope || ShouldPush) {
4001 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4002 bool ShouldPush =
Def && EliminationStack.empty();
4004 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4024 if (!EliminationStack.empty() && DefI && !FromStore) {
4025 Value *DominatingLeader = EliminationStack.back();
4026 if (DominatingLeader != Def) {
4034 for (
auto *DVR : DVRUsers)
4035 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4037 markInstructionForDeletion(DefI);
4046 "Current def should have been an instruction");
4048 "Current user should have been an instruction");
4055 if (InstructionsToErase.count(InstUse)) {
4056 auto &UseCount = UseCounts[
U->get()];
4057 if (--UseCount == 0) {
4064 if (EliminationStack.empty())
4067 Value *DominatingLeader = EliminationStack.back();
4071 if (BC->getType() == BC->getOperand(0)->getType() &&
4072 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4074 DominatingLeader = BC->getOperand(0);
4079 if (
U->get() == DominatingLeader)
4086 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4087 if (!PI || DominatingLeader != PI->OriginalOp)
4091 <<
"Found replacement " << *DominatingLeader <<
" for "
4092 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4093 U->set(DominatingLeader);
4096 auto &LeaderUseCount = UseCounts[DominatingLeader];
4103 auto It = UseCounts.
find(SSACopy);
4104 if (It != UseCounts.
end()) {
4105 unsigned &IIUseCount = It->second;
4106 if (--IIUseCount == 0)
4107 ProbablyDead.
insert(SSACopy);
4111 AnythingReplaced =
true;
4118 for (
auto *
I : ProbablyDead)
4120 markInstructionForDeletion(
I);
4123 CongruenceClass::MemberSet MembersLeft;
4124 for (
auto *Member : *CC)
4127 MembersLeft.
insert(Member);
4128 CC->swap(MembersLeft);
4131 if (CC->getStoreCount() > 0) {
4132 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4134 ValueDFSStack EliminationStack;
4135 for (
auto &VD : PossibleDeadStores) {
4136 int MemberDFSIn = VD.
DFSIn;
4137 int MemberDFSOut = VD.
DFSOut;
4139 if (EliminationStack.empty() ||
4140 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4142 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4143 if (EliminationStack.empty()) {
4144 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4151 assert(!EliminationStack.empty());
4157 <<
" that is dominated by " << *Leader <<
"\n");
4158 markInstructionForDeletion(Member);
4164 return AnythingReplaced;
4172unsigned int NewGVN::getRank(
const Value *V)
const {
4187 return 4 +
A->getArgNo();
4191 unsigned Result = InstrToDFSNum(V);
4193 return 5 + NumFuncArgs +
Result;
4200bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4204 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4207bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4208 const BitCastInst *
I)
const {
4209 if (shouldSwapOperands(
A,
B)) {
4210 PredicateSwapChoice[
I] =
B;
4215 if (LookupResult != PredicateSwapChoice.
end()) {
4217 if (SeenPredicate) {
4219 if (SeenPredicate ==
B)
4238 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< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
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, GsymDataExtractor &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)
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
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; assumes that the block is well-formed.
BitVector & reset()
Reset all bits in the bitvector.
int find_first() const
Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
void clear()
Removes all bits from the bitvector.
BitVector & set()
Set all bits in the bitvector.
bool any() const
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
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.
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.
DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
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
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
LLVM_ABI 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(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
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.
@ BasicBlock
Various leaf nodes.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
LLVM_ABI 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...
LLVM_ABI Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
LLVM_ABI 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...
LLVM_ABI Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
LLVM_ABI 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< ExecutorAddr > > 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.
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)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
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.
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 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 bool isEqual(const Expression *LHS, const Expression *RHS)
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