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) {
312 RepLeader = std::move(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 = std::move(LeaderPair);
323 }
else if (LeaderPair.second < NextLeader.second) {
324 NextLeader = std::move(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 return E->getComputedHash();
450 return E.getComputedHash();
464 if (LHS->getComputedHash() != RHS->getComputedHash())
486 mutable TarjanSCC SCCFinder;
488 std::unique_ptr<PredicateInfo> PredInfo;
492 unsigned int NumFuncArgs = 0;
503 CongruenceClass *TOPClass =
nullptr;
504 std::vector<CongruenceClass *> CongruenceClasses;
505 unsigned NextCongruenceNum = 0;
540 ExpressionToPhiOfOps;
589 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
590 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
592 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
593 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
596 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
597 ExpressionClassMap ExpressionToClass;
604 DeadExpression *SingletonDeadExpression =
nullptr;
607 SmallPtrSet<Value *, 8> LeaderChanges;
610 using BlockEdge = BasicBlockEdge;
611 DenseSet<BlockEdge> ReachableEdges;
612 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
623 BitVector TouchedInstructions;
625 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
626 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
630 DenseMap<const Value *, unsigned> ProcessedCount;
637 DenseMap<const Value *, unsigned> InstrDFS;
643 SmallPtrSet<Instruction *, 8> InstructionsToErase;
646 NewGVN(Function &
F, DominatorTree *DT, AssumptionCache *AC,
648 const DataLayout &
DL)
649 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
652 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
653 SQ(
DL, TLI, DT, AC, nullptr,
false,
661 const Expression *Expr;
663 const PredicateBase *PredDep;
665 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
666 const PredicateBase *PredDep =
nullptr)
667 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
668 ExprResult(
const ExprResult &) =
delete;
669 ExprResult(ExprResult &&
Other)
671 Other.Expr =
nullptr;
672 Other.ExtraDep =
nullptr;
673 Other.PredDep =
nullptr;
675 ExprResult &operator=(
const ExprResult &
Other) =
delete;
676 ExprResult &operator=(ExprResult &&
Other) =
delete;
678 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
680 operator bool()
const {
return Expr; }
682 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
683 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
684 return {Expr, ExtraDep,
nullptr};
686 static ExprResult some(
const Expression *Expr,
687 const PredicateBase *PredDep) {
688 return {Expr,
nullptr, PredDep};
690 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
691 const PredicateBase *PredDep) {
692 return {Expr, ExtraDep, PredDep};
697 ExprResult createExpression(Instruction *)
const;
698 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
699 Instruction *)
const;
703 using ValPair = std::pair<Value *, BasicBlock *>;
706 BasicBlock *,
bool &HasBackEdge,
707 bool &OriginalOpsConstant)
const;
708 const DeadExpression *createDeadExpression()
const;
709 const VariableExpression *createVariableExpression(
Value *)
const;
710 const ConstantExpression *createConstantExpression(Constant *)
const;
711 const Expression *createVariableOrConstant(
Value *V)
const;
712 const UnknownExpression *createUnknownExpression(Instruction *)
const;
713 const StoreExpression *createStoreExpression(StoreInst *,
714 const MemoryAccess *)
const;
715 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
716 const MemoryAccess *)
const;
717 const CallExpression *createCallExpression(CallInst *,
718 const MemoryAccess *)
const;
719 const AggregateValueExpression *
720 createAggregateValueExpression(Instruction *)
const;
721 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
724 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
727 unsigned LeaderDFS = 0;
735 LeaderDFS = InstrToDFSNum(
I);
737 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
738 CongruenceClasses.emplace_back(result);
742 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
743 auto *CC = createCongruenceClass(
nullptr,
nullptr);
744 CC->setMemoryLeader(MA);
748 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
749 auto *CC = getMemoryClass(MA);
750 if (CC->getMemoryLeader() != MA)
751 CC = createMemoryClass(MA);
755 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
756 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
757 CClass->insert(Member);
758 ValueToClass[
Member] = CClass;
762 void initializeCongruenceClasses(Function &
F);
763 const Expression *makePossiblePHIOfOps(Instruction *,
764 SmallPtrSetImpl<Value *> &);
765 Value *findLeaderForInst(Instruction *ValueOp,
766 SmallPtrSetImpl<Value *> &Visited,
767 MemoryAccess *MemAccess, Instruction *OrigInst,
769 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
770 SmallPtrSetImpl<const Value *> &);
771 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
772 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
775 void valueNumberMemoryPhi(MemoryPhi *);
776 void valueNumberInstruction(Instruction *);
779 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
780 ExprResult performSymbolicEvaluation(Instruction *,
781 SmallPtrSetImpl<Value *> &)
const;
782 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
784 MemoryAccess *)
const;
785 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
786 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
787 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
791 BasicBlock *PHIBlock)
const;
792 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
793 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
794 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
797 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
799 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
800 void performCongruenceFinding(Instruction *,
const Expression *);
801 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
802 CongruenceClass *, CongruenceClass *);
803 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
804 CongruenceClass *, CongruenceClass *);
805 Value *getNextValueLeader(CongruenceClass *)
const;
806 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
807 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
808 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
809 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
810 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
813 unsigned int getRank(
const Value *)
const;
814 bool shouldSwapOperands(
const Value *,
const Value *)
const;
815 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
816 const BitCastInst *
I)
const;
819 void updateReachableEdge(BasicBlock *, BasicBlock *);
820 void processOutgoingEdges(Instruction *, BasicBlock *);
821 Value *findConditionEquivalence(
Value *)
const;
825 void convertClassToDFSOrdered(
const CongruenceClass &,
826 SmallVectorImpl<ValueDFS> &,
827 DenseMap<const Value *, unsigned int> &,
828 SmallPtrSetImpl<Instruction *> &)
const;
829 void convertClassToLoadsAndStores(
const CongruenceClass &,
830 SmallVectorImpl<ValueDFS> &)
const;
832 bool eliminateInstructions(Function &);
833 void replaceInstruction(Instruction *,
Value *);
834 void markInstructionForDeletion(Instruction *);
835 void deleteInstructionsInBlock(BasicBlock *);
836 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
837 const BasicBlock *)
const;
840 template <
typename Map,
typename KeyType>
841 void touchAndErase(Map &,
const KeyType &);
842 void markUsersTouched(
Value *);
843 void markMemoryUsersTouched(
const MemoryAccess *);
844 void markMemoryDefTouched(
const MemoryAccess *);
845 void markPredicateUsersTouched(Instruction *);
846 void markValueLeaderChangeTouched(CongruenceClass *CC);
847 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
848 void markPhiOfOpsChanged(
const Expression *
E);
849 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
850 void addAdditionalUsers(
Value *To,
Value *User)
const;
851 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
854 void iterateTouchedInstructions();
857 void cleanupTables();
858 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
859 void updateProcessedCount(
const Value *V);
860 void verifyMemoryCongruency()
const;
861 void verifyIterationSettled(Function &
F);
862 void verifyStoreExpressions()
const;
863 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
864 const MemoryAccess *,
const MemoryAccess *)
const;
866 void deleteExpression(
const Expression *
E)
const;
867 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
868 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
869 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
871 unsigned InstrToDFSNum(
const Value *V)
const {
873 return InstrDFS.
lookup(V);
876 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
877 return MemoryToDFSNum(MA);
880 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
885 unsigned MemoryToDFSNum(
const Value *MA)
const {
887 "This should not be used with instructions");
893 bool isCycleFree(
const Instruction *)
const;
894 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
898 DebugCounter::CounterState StartingVNCounter;
907 return LHS.MemoryExpression::equals(
RHS);
929 return Call->getAttributes()
930 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
950MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
956MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
963 auto *Parent =
I->getParent();
966 Parent = TempToBlock.
lookup(V);
967 assert(Parent &&
"Every fake instruction should have a block");
972 assert(MP &&
"Should have been an instruction or a MemoryPhi");
973 return MP->getBlock();
979void NewGVN::deleteExpression(
const Expression *
E)
const {
983 ExpressionAllocator.Deallocate(
E);
989 if (BC->getType() == BC->getOperand(0)->getType())
990 return BC->getOperand(0);
1009 return BlockInstRange.
lookup(
P1.second).first <
1010 BlockInstRange.
lookup(
P2.second).first;
1027 const Instruction *
I,
1028 BasicBlock *PHIBlock,
1030 bool &OriginalOpsConstant)
const {
1035 E->setType(PHIOperands.
begin()->first->getType());
1036 E->setOpcode(Instruction::PHI);
1040 auto *BB =
P.second;
1044 if (!ReachableEdges.
count({BB, PHIBlock}))
1047 if (ValueToClass.
lookup(
P.first) == TOPClass)
1049 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1050 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1051 return lookupOperandLeader(
P.first) !=
I;
1054 return lookupOperandLeader(
P.first);
1062 bool AllConstant =
true;
1064 E->setType(
GEP->getSourceElementType());
1066 E->setType(
I->getType());
1067 E->setOpcode(
I->getOpcode());
1068 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1073 auto Operand = lookupOperandLeader(O);
1081const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1083 Instruction *
I)
const {
1090 E->setOpcode(Opcode);
1091 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1097 if (shouldSwapOperands(Arg1, Arg2))
1100 E->op_push_back(lookupOperandLeader(Arg1));
1101 E->op_push_back(lookupOperandLeader(Arg2));
1104 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1105 addAdditionalUsers(Simplified,
I);
1114NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1117 return ExprResult::none();
1122 <<
" constant " << *
C <<
"\n");
1123 NumGVNOpsSimplified++;
1125 "We should always have had a basic expression here");
1126 deleteExpression(
E);
1127 return ExprResult::some(createConstantExpression(
C));
1131 <<
" variable " << *V <<
"\n");
1132 deleteExpression(
E);
1133 return ExprResult::some(createVariableExpression(V));
1136 CongruenceClass *CC = ValueToClass.
lookup(V);
1138 if (CC->getLeader() && CC->getLeader() !=
I) {
1139 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1141 if (CC->getDefiningExpr()) {
1144 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1145 NumGVNOpsSimplified++;
1146 deleteExpression(
E);
1147 return ExprResult::some(CC->getDefiningExpr(), V);
1151 return ExprResult::none();
1157NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1163 bool AllConstant = setBasicExpressionInfo(
I,
E);
1165 if (
I->isCommutative()) {
1170 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1171 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1172 E->swapOperands(0, 1);
1179 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1180 E->swapOperands(0, 1);
1183 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1185 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1186 "Wrong types on cmp instruction");
1187 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1188 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1191 if (
auto Simplified = checkExprResults(
E,
I, V))
1195 E->getOperand(1) ==
E->getOperand(2)) {
1196 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1197 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1199 E->getOperand(2), FastMathFlags(), Q);
1200 if (
auto Simplified = checkExprResults(
E,
I, V))
1203 }
else if (
I->isBinaryOp()) {
1206 if (
auto Simplified = checkExprResults(
E,
I, V))
1211 if (
auto Simplified = checkExprResults(
E,
I, V))
1215 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1216 GEPI->getNoWrapFlags(), Q);
1217 if (
auto Simplified = checkExprResults(
E,
I, V))
1219 }
else if (AllConstant) {
1228 for (
Value *Arg :
E->operands())
1232 if (
auto Simplified = checkExprResults(
E,
I, V))
1235 return ExprResult::some(
E);
1239NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1241 auto *
E =
new (ExpressionAllocator)
1243 setBasicExpressionInfo(
I,
E);
1244 E->allocateIntOperands(ExpressionAllocator);
1248 auto *
E =
new (ExpressionAllocator)
1250 setBasicExpressionInfo(EI,
E);
1251 E->allocateIntOperands(ExpressionAllocator);
1261 return SingletonDeadExpression;
1272 return createConstantExpression(
C);
1273 return createVariableExpression(V);
1289NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1293 setBasicExpressionInfo(CI,
E);
1299 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1300 E->swapOperands(0, 1);
1306bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1307 const Instruction *U)
const {
1308 auto *CC = ValueToClass.
lookup(Inst);
1331 if (CC->getNextLeader().first &&
1335 return Member != CC->getLeader() &&
1342Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1343 CongruenceClass *CC = ValueToClass.
lookup(V);
1350 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1356const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1357 auto *CC = getMemoryClass(MA);
1358 assert(CC->getMemoryLeader() &&
1359 "Every MemoryAccess should be mapped to a congruence class with a "
1360 "representative memory access");
1361 return CC->getMemoryLeader();
1367bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1368 return getMemoryClass(MA) == TOPClass;
1373 const MemoryAccess *MA)
const {
1375 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1377 E->setType(LoadType);
1381 E->op_push_back(PointerOp);
1390NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1391 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1392 auto *
E =
new (ExpressionAllocator)
1395 E->setType(
SI->getValueOperand()->getType());
1399 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1407const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1411 auto *StoreAccess = getMemoryAccess(SI);
1413 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1417 StoreRHS = lookupMemoryLeader(StoreRHS);
1418 if (StoreRHS != StoreAccess->getDefiningAccess())
1419 addMemoryUsers(StoreRHS, StoreAccess);
1421 if (StoreRHS == StoreAccess)
1424 if (
SI->isSimple()) {
1428 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1429 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1435 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1443 LastStore->getOperand(0)) &&
1444 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1447 deleteExpression(LastStore);
1453 return createStoreExpression(SI, StoreAccess);
1459NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1460 LoadInst *LI, Instruction *DepInst,
1461 MemoryAccess *DefiningAccess)
const {
1467 if (LI->
isAtomic() > DepSI->isAtomic() ||
1468 LoadType == DepSI->getValueOperand()->getType())
1473 lookupOperandLeader(DepSI->getValueOperand()))) {
1476 <<
" to constant " << *Res <<
"\n");
1477 return createConstantExpression(Res);
1483 if (LI->
isAtomic() > DepLI->isAtomic())
1489 if (
auto *PossibleConstant =
1492 <<
" to constant " << *PossibleConstant <<
"\n");
1493 return createConstantExpression(PossibleConstant);
1499 if (
auto *PossibleConstant =
1502 <<
" to constant " << *PossibleConstant <<
"\n");
1503 return createConstantExpression(PossibleConstant);
1509 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1510 auto *LifetimePtr =
II->getOperand(0);
1511 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1520 (LoadPtr != lookupOperandLeader(DepInst) &&
1529 }
else if (
auto *InitVal =
1531 return createConstantExpression(InitVal);
1536const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1548 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1549 MemoryAccess *DefiningAccess =
1562 if (
const auto *CoercionResult =
1563 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1564 DefiningInst, DefiningAccess))
1565 return CoercionResult;
1569 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1573 if (
LE->getMemoryLeader() != DefiningAccess)
1574 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1579NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1580 auto *PI = PredInfo->getPredicateInfoFor(
I);
1582 return ExprResult::none();
1584 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1586 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1588 return ExprResult::none();
1591 Value *CmpOp0 =
I->getOperand(0);
1592 Value *CmpOp1 = Constraint->OtherOp;
1594 Value *FirstOp = lookupOperandLeader(CmpOp0);
1595 Value *SecondOp = lookupOperandLeader(CmpOp1);
1596 Value *AdditionallyUsedValue = CmpOp0;
1599 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1602 AdditionallyUsedValue = CmpOp1;
1606 return ExprResult::some(createVariableOrConstant(FirstOp),
1607 AdditionallyUsedValue, PI);
1612 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1613 AdditionallyUsedValue, PI);
1615 return ExprResult::none();
1619NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1630 return ExprResult::none();
1636 return ExprResult::none();
1639 return ExprResult::some(
1640 createCallExpression(CI, TOPClass->getMemoryLeader()));
1644 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1646 return ExprResult::some(
1647 createCallExpression(CI, TOPClass->getMemoryLeader()));
1649 return ExprResult::none();
1653CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1655 assert(Result &&
"Should have found memory class");
1661bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1662 CongruenceClass *NewClass) {
1664 "Every MemoryAccess should be getting mapped to a non-null class");
1668 <<
" with current MemoryAccess leader ");
1674 if (LookupResult != MemoryAccessToClass.
end()) {
1676 if (OldClass != NewClass) {
1679 OldClass->memory_erase(MP);
1680 NewClass->memory_insert(MP);
1682 if (OldClass->getMemoryLeader() == From) {
1683 if (OldClass->definesNoMemory()) {
1684 OldClass->setMemoryLeader(
nullptr);
1686 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1688 << OldClass->getID() <<
" to "
1689 << *OldClass->getMemoryLeader()
1690 <<
" due to removal of a memory member " << *From
1692 markMemoryLeaderChangeTouched(OldClass);
1709bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1715 auto ICS = InstCycleState.
lookup(
I);
1716 if (ICS == ICS_Unknown) {
1718 auto &
SCC = SCCFinder.getComponentFor(
I);
1720 if (
SCC.size() == 1)
1721 InstCycleState.
insert({
I, ICS_CycleFree});
1726 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1727 for (
const auto *Member : SCC)
1729 InstCycleState.
insert({MemberPhi, ICS});
1732 if (ICS == ICS_Cycle)
1741 BasicBlock *PHIBlock)
const {
1743 bool HasBackedge =
false;
1748 bool OriginalOpsConstant =
true;
1750 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1754 bool HasUndef =
false, HasPoison =
false;
1756 if (isa<PoisonValue>(Arg)) {
1767 if (Filtered.empty()) {
1772 dbgs() <<
"PHI Node " << *
I
1773 <<
" has no non-undef arguments, valuing it as undef\n");
1778 dbgs() <<
"PHI Node " << *
I
1779 <<
" has no non-poison arguments, valuing it as poison\n");
1783 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1784 deleteExpression(
E);
1785 return createDeadExpression();
1787 Value *AllSameValue = *(Filtered.begin());
1805 if (HasPoison || HasUndef) {
1811 if (HasBackedge && !OriginalOpsConstant &&
1817 if (!someEquivalentDominates(AllSameInst,
I))
1824 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1826 NumGVNPhisAllSame++;
1827 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1829 deleteExpression(
E);
1830 return createVariableOrConstant(AllSameValue);
1836NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1839 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1843 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1844 WO->getLHS(), WO->getRHS(),
I);
1847 return createAggregateValueExpression(
I);
1850NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1856 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1857 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1858 auto OurPredicate = CI->getPredicate();
1859 if (shouldSwapOperands(Op0, Op1)) {
1861 OurPredicate = CI->getSwappedPredicate();
1865 const PredicateBase *LastPredInfo =
nullptr;
1868 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1870 return ExprResult::some(
1875 if (CI->isTrueWhenEqual())
1876 return ExprResult::some(
1878 else if (CI->isFalseWhenEqual())
1879 return ExprResult::some(
1909 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1911 if (PI == LastPredInfo)
1916 if (!DT->
dominates(PBranch->To,
I->getParent()))
1926 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1927 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1928 auto BranchPredicate = BranchCond->getPredicate();
1929 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1931 BranchPredicate = BranchCond->getSwappedPredicate();
1933 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1934 if (PBranch->TrueEdge) {
1940 return ExprResult::some(createConstantExpression(
C), PI);
1945 if (BranchPredicate == OurPredicate) {
1947 return ExprResult::some(
1950 }
else if (BranchPredicate ==
1953 return ExprResult::some(
1962 return createExpression(
I);
1967NewGVN::performSymbolicEvaluation(Instruction *
I,
1968 SmallPtrSetImpl<Value *> &Visited)
const {
1974 switch (
I->getOpcode()) {
1975 case Instruction::ExtractValue:
1976 case Instruction::InsertValue:
1977 E = performSymbolicAggrValueEvaluation(
I);
1979 case Instruction::PHI: {
1982 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1983 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1986 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
1988 case Instruction::Call:
1989 return performSymbolicCallEvaluation(
I);
1991 case Instruction::Store:
1992 E = performSymbolicStoreEvaluation(
I);
1994 case Instruction::Load:
1995 E = performSymbolicLoadEvaluation(
I);
1997 case Instruction::BitCast:
1999 if (
I->getType() ==
I->getOperand(0)->getType())
2004 case Instruction::AddrSpaceCast:
2005 case Instruction::Freeze:
2006 return createExpression(
I);
2008 case Instruction::ICmp:
2009 case Instruction::FCmp:
2010 return performSymbolicCmpEvaluation(
I);
2012 case Instruction::FNeg:
2013 case Instruction::Add:
2014 case Instruction::FAdd:
2015 case Instruction::Sub:
2016 case Instruction::FSub:
2017 case Instruction::Mul:
2018 case Instruction::FMul:
2019 case Instruction::UDiv:
2020 case Instruction::SDiv:
2021 case Instruction::FDiv:
2022 case Instruction::URem:
2023 case Instruction::SRem:
2024 case Instruction::FRem:
2025 case Instruction::Shl:
2026 case Instruction::LShr:
2027 case Instruction::AShr:
2028 case Instruction::And:
2029 case Instruction::Or:
2030 case Instruction::Xor:
2031 case Instruction::Trunc:
2032 case Instruction::ZExt:
2033 case Instruction::SExt:
2034 case Instruction::FPToUI:
2035 case Instruction::FPToSI:
2036 case Instruction::UIToFP:
2037 case Instruction::SIToFP:
2038 case Instruction::FPTrunc:
2039 case Instruction::FPExt:
2040 case Instruction::PtrToInt:
2041 case Instruction::PtrToAddr:
2042 case Instruction::IntToPtr:
2043 case Instruction::Select:
2044 case Instruction::ExtractElement:
2045 case Instruction::InsertElement:
2046 case Instruction::GetElementPtr:
2047 return createExpression(
I);
2049 case Instruction::ShuffleVector:
2051 return ExprResult::none();
2053 return ExprResult::none();
2055 return ExprResult::some(
E);
2060template <
typename Map,
typename KeyType>
2061void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2063 if (Result !=
M.end()) {
2064 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2065 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2070void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2071 assert(User && To != User);
2073 AdditionalUsers[To].
insert(User);
2076void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2077 if (Res.ExtraDep && Res.ExtraDep != User)
2078 addAdditionalUsers(Res.ExtraDep, User);
2079 Res.ExtraDep =
nullptr;
2083 PredicateToUsers[PBranch->Condition].
insert(User);
2084 else if (
const auto *PAssume =
2086 PredicateToUsers[PAssume->Condition].
insert(User);
2088 Res.PredDep =
nullptr;
2091void NewGVN::markUsersTouched(
Value *V) {
2093 for (
auto *User :
V->users()) {
2095 TouchedInstructions.
set(InstrToDFSNum(User));
2097 touchAndErase(AdditionalUsers, V);
2100void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2101 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2102 MemoryToUsers[To].
insert(U);
2105void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2106 TouchedInstructions.
set(MemoryToDFSNum(MA));
2109void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2112 for (
const auto *U : MA->
users())
2113 TouchedInstructions.
set(MemoryToDFSNum(U));
2114 touchAndErase(MemoryToUsers, MA);
2118void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2119 touchAndErase(PredicateToUsers,
I);
2123void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2124 for (
const auto *M : CC->memory())
2125 markMemoryDefTouched(M);
2130void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2131 for (
auto *M : *CC) {
2133 TouchedInstructions.
set(InstrToDFSNum(
I));
2140template <
class T,
class Range>
2141T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2142 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2143 for (
const auto X : R) {
2144 auto DFSNum = InstrToDFSNum(
X);
2145 if (DFSNum < MinDFS.second)
2146 MinDFS = {
X, DFSNum};
2148 return MinDFS.first;
2154const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2158 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2159 if (CC->getStoreCount() > 0) {
2161 return getMemoryAccess(NL);
2167 assert(CC->getStoreCount() == 0);
2171 if (CC->memory_size() == 1)
2172 return *CC->memory_begin();
2173 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2179Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2184 if (CC->size() == 1 || CC == TOPClass) {
2185 return *(CC->begin());
2186 }
else if (CC->getNextLeader().first) {
2187 ++NumGVNAvoidedSortedLeaderChanges;
2188 return CC->getNextLeader().first;
2190 ++NumGVNSortedLeaderChanges;
2194 return getMinDFSOfRange<Value>(*CC);
2207void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2208 MemoryAccess *InstMA,
2209 CongruenceClass *OldClass,
2210 CongruenceClass *NewClass) {
2213 assert((!InstMA || !OldClass->getMemoryLeader() ||
2214 OldClass->getLeader() !=
I ||
2215 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2216 MemoryAccessToClass.
lookup(InstMA)) &&
2217 "Representative MemoryAccess mismatch");
2219 if (!NewClass->getMemoryLeader()) {
2221 assert(NewClass->size() == 1 ||
2223 NewClass->setMemoryLeader(InstMA);
2226 << NewClass->getID()
2227 <<
" due to new memory instruction becoming leader\n");
2228 markMemoryLeaderChangeTouched(NewClass);
2230 setMemoryClass(InstMA, NewClass);
2232 if (OldClass->getMemoryLeader() == InstMA) {
2233 if (!OldClass->definesNoMemory()) {
2234 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2236 << OldClass->getID() <<
" to "
2237 << *OldClass->getMemoryLeader()
2238 <<
" due to removal of old leader " << *InstMA <<
"\n");
2239 markMemoryLeaderChangeTouched(OldClass);
2241 OldClass->setMemoryLeader(
nullptr);
2247void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2248 CongruenceClass *OldClass,
2249 CongruenceClass *NewClass) {
2250 if (
I == OldClass->getNextLeader().first)
2251 OldClass->resetNextLeader();
2254 NewClass->insert(
I);
2258 if (NewClass->getLeader() !=
I &&
2259 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2260 markValueLeaderChangeTouched(NewClass);
2265 OldClass->decStoreCount();
2273 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2277 NewClass->setStoredValue(SE->getStoredValue());
2278 markValueLeaderChangeTouched(NewClass);
2281 << NewClass->getID() <<
" from "
2282 << *NewClass->getLeader() <<
" to " << *SI
2283 <<
" because store joined class\n");
2286 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2290 NewClass->incStoreCount();
2298 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2299 ValueToClass[
I] = NewClass;
2301 if (OldClass->empty() && OldClass != TOPClass) {
2302 if (OldClass->getDefiningExpr()) {
2303 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2304 <<
" from table\n");
2307 auto Iter = ExpressionToClass.find_as(
2308 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2309 if (Iter != ExpressionToClass.end())
2310 ExpressionToClass.erase(Iter);
2311#ifdef EXPENSIVE_CHECKS
2313 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2314 "We erased the expression we just inserted, which should not happen");
2317 }
else if (OldClass->getLeader() ==
I) {
2322 << OldClass->getID() <<
"\n");
2323 ++NumGVNLeaderChanges;
2328 if (OldClass->getStoreCount() == 0) {
2329 if (OldClass->getStoredValue())
2330 OldClass->setStoredValue(
nullptr);
2332 OldClass->setLeader({getNextValueLeader(OldClass),
2333 InstrToDFSNum(getNextValueLeader(OldClass))});
2334 OldClass->resetNextLeader();
2335 markValueLeaderChangeTouched(OldClass);
2341void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2342 touchAndErase(ExpressionToPhiOfOps,
E);
2346void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2350 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2351 assert(IClass &&
"Should have found a IClass");
2353 assert(!IClass->isDead() &&
"Found a dead class");
2355 CongruenceClass *EClass =
nullptr;
2357 EClass = ValueToClass.
lookup(VE->getVariableValue());
2362 auto lookupResult = ExpressionToClass.try_emplace(
E);
2365 if (lookupResult.second) {
2366 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2367 auto place = lookupResult.first;
2368 place->second = NewClass;
2372 NewClass->setLeader({
CE->getConstantValue(), 0});
2374 StoreInst *
SI = SE->getStoreInst();
2375 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2376 NewClass->setStoredValue(SE->getStoredValue());
2380 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2383 "VariableExpression should have been handled already");
2387 <<
" using expression " << *
E <<
" at "
2388 << NewClass->getID() <<
" and leader "
2389 << *(NewClass->getLeader()));
2390 if (NewClass->getStoredValue())
2392 << *(NewClass->getStoredValue()));
2395 EClass = lookupResult.first->second;
2398 (EClass->getStoredValue() &&
2400 "Any class with a constant expression should have a "
2403 assert(EClass &&
"Somehow don't have an eclass");
2405 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2408 bool ClassChanged = IClass != EClass;
2409 bool LeaderChanged = LeaderChanges.
erase(
I);
2410 if (ClassChanged || LeaderChanged) {
2411 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2414 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2415 markPhiOfOpsChanged(
E);
2418 markUsersTouched(
I);
2419 if (MemoryAccess *MA = getMemoryAccess(
I))
2420 markMemoryUsersTouched(MA);
2422 markPredicateUsersTouched(CI);
2429 auto *OldE = ValueToExpression.
lookup(
I);
2435 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2436 if (Iter != ExpressionToClass.end())
2437 ExpressionToClass.erase(Iter);
2440 ValueToExpression[
I] =
E;
2445void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2447 if (ReachableEdges.
insert({From, To}).second) {
2449 if (ReachableBlocks.
insert(To).second) {
2451 <<
" marked reachable\n");
2452 const auto &InstRange = BlockInstRange.
lookup(To);
2453 TouchedInstructions.
set(InstRange.first, InstRange.second);
2456 <<
" was reachable, but new edge {"
2458 <<
"} to it found\n");
2464 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2465 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2470 for (
auto InstNum : RevisitOnReachabilityChange[To])
2471 TouchedInstructions.
set(InstNum);
2484void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2489 Value *CondEvaluated = findConditionEquivalence(
Cond);
2490 if (!CondEvaluated) {
2492 SmallPtrSet<Value *, 4> Visited;
2493 auto Res = performSymbolicEvaluation(
I, Visited);
2495 CondEvaluated =
CE->getConstantValue();
2496 addAdditionalUsers(Res,
I);
2500 Res.ExtraDep =
nullptr;
2503 CondEvaluated =
Cond;
2510 <<
" evaluated to true\n");
2511 updateReachableEdge(
B, TrueSucc);
2512 }
else if (CI->
isZero()) {
2514 <<
" evaluated to false\n");
2515 updateReachableEdge(
B, FalseSucc);
2518 updateReachableEdge(
B, TrueSucc);
2519 updateReachableEdge(
B, FalseSucc);
2525 Value *SwitchCond =
SI->getCondition();
2526 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2531 auto Case = *
SI->findCaseValue(CondVal);
2532 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2536 updateReachableEdge(
B,
SI->getDefaultDest());
2540 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2541 updateReachableEdge(
B, TargetBlock);
2543 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2544 updateReachableEdge(
B, TargetBlock);
2550 updateReachableEdge(
B, TargetBlock);
2555 auto *MA = getMemoryAccess(TI);
2557 auto *CC = ensureLeaderOfMemoryClass(MA);
2558 if (setMemoryClass(MA, CC))
2559 markMemoryUsersTouched(MA);
2565void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2566 InstrDFS.
erase(PHITemp);
2569 TempToBlock.
erase(PHITemp);
2578void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2579 Instruction *ExistingValue) {
2580 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2582 TempToBlock[
Op] = BB;
2583 RealToTemp[ExistingValue] =
Op;
2586 for (
auto *U : ExistingValue->
users())
2605bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2606 SmallPtrSetImpl<const Value *> &Visited) {
2607 SmallVector<Value *, 4> Worklist;
2609 while (!Worklist.
empty()) {
2614 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2615 if (OISIt != OpSafeForPHIOfOps.
end())
2616 return OISIt->second;
2621 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2626 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2637 if (OrigI->mayReadFromMemory())
2641 for (
auto *
Op : OrigI->operand_values()) {
2645 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2646 if (OISIt != OpSafeForPHIOfOps.
end()) {
2647 if (!OISIt->second) {
2648 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2658 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2667Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2668 SmallPtrSetImpl<Value *> &Visited,
2669 MemoryAccess *MemAccess, Instruction *OrigInst,
2670 BasicBlock *PredBB) {
2671 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2673 AllTempInstructions.
insert(TransInst);
2677 TempToBlock.
insert({TransInst, PredBB});
2678 InstrDFS.
insert({TransInst, IDFSNum});
2680 auto Res = performSymbolicEvaluation(TransInst, Visited);
2682 addAdditionalUsers(Res, OrigInst);
2683 InstrDFS.
erase(TransInst);
2684 AllTempInstructions.
erase(TransInst);
2685 TempToBlock.
erase(TransInst);
2687 TempToMemory.
erase(TransInst);
2690 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2692 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2693 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2698 FoundVal =
SI->getValueOperand();
2705NewGVN::makePossiblePHIOfOps(Instruction *
I,
2706 SmallPtrSetImpl<Value *> &Visited) {
2710 if (!Visited.
insert(
I).second)
2716 if (!isCycleFree(
I))
2722 auto *MemAccess = getMemoryAccess(
I);
2726 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2731 SmallPtrSet<const Value *, 10> VisitedOps;
2732 SmallVector<Value *, 4>
Ops(
I->operand_values());
2734 PHINode *OpPHI =
nullptr;
2737 for (
auto *
Op :
Ops) {
2739 auto *ValuePHI = RealToTemp.
lookup(
Op);
2746 if (!SamePHIBlock) {
2747 SamePHIBlock = getBlockForValue(OpPHI);
2748 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2751 <<
"PHIs for operands are not all in the same block, aborting\n");
2765 SmallPtrSet<Value *, 4> Deps;
2766 auto *PHIBlock = getBlockForValue(OpPHI);
2767 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2768 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2770 Value *FoundVal =
nullptr;
2771 SmallPtrSet<Value *, 4> CurrentDeps;
2774 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2782 TempToMemory.
insert({ValueOp, MemAccess});
2783 bool SafeForPHIOfOps =
true;
2786 auto *OrigOp = &*
Op;
2790 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2791 if (
Op != OrigOp &&
Op !=
I)
2793 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2794 if (getBlockForValue(ValuePHI) == PHIBlock)
2795 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2800 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2807 FoundVal = !SafeForPHIOfOps ? nullptr
2808 : findLeaderForInst(ValueOp, Visited,
2809 MemAccess,
I, PredBB);
2814 if (SafeForPHIOfOps)
2815 for (
auto *Dep : CurrentDeps)
2816 addAdditionalUsers(Dep,
I);
2822 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2824 <<
" because the block is unreachable\n");
2826 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2830 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2833 for (
auto *Dep : Deps)
2834 addAdditionalUsers(Dep,
I);
2836 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2840 <<
"Not creating real PHI of ops because it simplified to existing "
2841 "value or constant\n");
2847 for (
auto &O : PHIOps)
2848 addAdditionalUsers(
O.first,
I);
2852 auto *ValuePHI = RealToTemp.
lookup(
I);
2853 bool NewPHI =
false;
2857 addPhiOfOps(ValuePHI, PHIBlock,
I);
2859 NumGVNPHIOfOpsCreated++;
2862 for (
auto PHIOp : PHIOps)
2863 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2865 TempToBlock[ValuePHI] = PHIBlock;
2867 for (
auto PHIOp : PHIOps) {
2868 ValuePHI->setIncomingValue(i, PHIOp.first);
2869 ValuePHI->setIncomingBlock(i, PHIOp.second);
2873 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2874 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2883void NewGVN::initializeCongruenceClasses(Function &
F) {
2884 NextCongruenceNum = 0;
2894 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2900 for (
auto *DTN :
nodes(DT)) {
2907 if (MemoryBlockDefs)
2908 for (
const auto &Def : *MemoryBlockDefs) {
2909 MemoryAccessToClass[&
Def] = TOPClass;
2914 TOPClass->memory_insert(MP);
2915 MemoryPhiState.
insert({MP, MPS_TOP});
2919 TOPClass->incStoreCount();
2925 for (
auto &
I : *BB) {
2927 for (
auto *U :
I.users())
2930 PHINodeUses.
insert(UInst);
2933 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2935 TOPClass->insert(&
I);
2936 ValueToClass[&
I] = TOPClass;
2941 for (
auto &FA :
F.args())
2942 createSingletonCongruenceClass(&FA);
2945void NewGVN::cleanupTables() {
2946 for (CongruenceClass *&CC : CongruenceClasses) {
2947 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2948 << CC->size() <<
" members\n");
2956 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2957 AllTempInstructions.
end());
2958 AllTempInstructions.
clear();
2962 for (
auto *
I : TempInst) {
2963 I->dropAllReferences();
2966 while (!TempInst.empty()) {
2967 auto *
I = TempInst.pop_back_val();
2971 ValueToClass.
clear();
2972 ArgRecycler.
clear(ExpressionAllocator);
2973 ExpressionAllocator.Reset();
2974 CongruenceClasses.clear();
2975 ExpressionToClass.clear();
2976 ValueToExpression.
clear();
2978 AdditionalUsers.
clear();
2979 ExpressionToPhiOfOps.
clear();
2980 TempToBlock.
clear();
2981 TempToMemory.
clear();
2982 PHINodeUses.
clear();
2983 OpSafeForPHIOfOps.
clear();
2984 ReachableBlocks.
clear();
2985 ReachableEdges.
clear();
2987 ProcessedCount.
clear();
2990 InstructionsToErase.
clear();
2992 BlockInstRange.
clear();
2993 TouchedInstructions.
clear();
2994 MemoryAccessToClass.
clear();
2995 PredicateToUsers.
clear();
2996 MemoryToUsers.
clear();
2997 RevisitOnReachabilityChange.
clear();
2998 PredicateSwapChoice.
clear();
3003std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
3005 unsigned End =
Start;
3006 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
3007 InstrDFS[MemPhi] = End++;
3012 for (
auto &
I : *
B) {
3018 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3020 markInstructionForDeletion(&
I);
3024 RevisitOnReachabilityChange[
B].set(End);
3025 InstrDFS[&
I] = End++;
3032 return std::make_pair(Start, End);
3035void NewGVN::updateProcessedCount(
const Value *V) {
3037 assert(++ProcessedCount[V] < 100 &&
3038 "Seem to have processed the same Value a lot");
3043void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3050 return cast<MemoryAccess>(U) != MP &&
3051 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3052 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3057 if (Filtered.begin() == Filtered.end()) {
3058 if (setMemoryClass(MP, TOPClass))
3059 markMemoryUsersTouched(MP);
3065 auto LookupFunc = [&](
const Use &
U) {
3068 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3069 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3073 const auto *AllSameValue = *MappedBegin;
3075 bool AllEqual = std::all_of(
3076 MappedBegin, MappedEnd,
3077 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3080 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3089 CongruenceClass *CC =
3090 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3091 auto OldState = MemoryPhiState.
lookup(MP);
3092 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3093 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3094 MemoryPhiState[MP] = NewState;
3095 if (setMemoryClass(MP, CC) || OldState != NewState)
3096 markMemoryUsersTouched(MP);
3101void NewGVN::valueNumberInstruction(Instruction *
I) {
3103 if (!
I->isTerminator()) {
3105 SmallPtrSet<Value *, 2> Visited;
3107 auto Res = performSymbolicEvaluation(
I, Visited);
3108 Symbolized = Res.Expr;
3109 addAdditionalUsers(Res,
I);
3114 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3119 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3120 removePhiOfOps(
I,
Op);
3129 if (Symbolized ==
nullptr)
3130 Symbolized = createUnknownExpression(
I);
3131 performCongruenceFinding(
I, Symbolized);
3136 if (!
I->getType()->isVoidTy()) {
3137 auto *Symbolized = createUnknownExpression(
I);
3138 performCongruenceFinding(
I, Symbolized);
3140 processOutgoingEdges(
I,
I->getParent());
3146bool NewGVN::singleReachablePHIPath(
3147 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3148 const MemoryAccess *Second)
const {
3149 if (
First == Second)
3162 const auto *EndDef =
First;
3164 if (ChainDef == Second)
3171 auto ReachableOperandPred = [&](
const Use &
U) {
3174 auto FilteredPhiArgs =
3188void NewGVN::verifyMemoryCongruency()
const {
3191 for (
const auto *CC : CongruenceClasses) {
3192 if (CC == TOPClass || CC->isDead())
3194 if (CC->getStoreCount() != 0) {
3196 "Any class with a store as a leader should have a "
3197 "representative stored value");
3198 assert(CC->getMemoryLeader() &&
3199 "Any congruence class with a store should have a "
3200 "representative access");
3203 if (CC->getMemoryLeader())
3204 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3205 "Representative MemoryAccess does not appear to be reverse "
3207 for (
const auto *M : CC->memory())
3209 "Memory member does not appear to be reverse mapped properly");
3217 auto ReachableAccessPred =
3218 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3219 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3221 MemoryToDFSNum(Pair.first) == 0)
3229 for (
const auto &U : MemPHI->incoming_values()) {
3242 for (
auto KV : Filtered) {
3245 if (FirstMUD && SecondMUD) {
3246 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3247 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3248 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3249 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3250 "The instructions for these memory operations should have "
3251 "been in the same congruence class or reachable through"
3252 "a single argument phi");
3257 auto ReachableOperandPred = [&](
const Use &
U) {
3258 return ReachableEdges.
count(
3259 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3263 auto FilteredPhiArgs =
3266 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3267 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3268 const MemoryDef *MD = cast<MemoryDef>(U);
3269 return ValueToClass.lookup(MD->getMemoryInst());
3272 "All MemoryPhi arguments should be in the same class");
3281void NewGVN::verifyIterationSettled(Function &
F) {
3291 std::map<const Value *, CongruenceClass> BeforeIteration;
3293 for (
auto &KV : ValueToClass) {
3296 if (InstrToDFSNum(
I) == 0)
3298 BeforeIteration.insert({KV.first, *KV.second});
3301 TouchedInstructions.
set();
3302 TouchedInstructions.
reset(0);
3303 OpSafeForPHIOfOps.
clear();
3305 iterateTouchedInstructions();
3306 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3308 for (
const auto &KV : ValueToClass) {
3311 if (InstrToDFSNum(
I) == 0)
3315 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3316 auto *AfterCC = KV.second;
3319 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3320 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3321 "Value number changed after main loop completed!");
3322 EqualClasses.
insert({BeforeCC, AfterCC});
3333void NewGVN::verifyStoreExpressions()
const {
3338 std::pair<
const Value *,
3339 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3341 for (
const auto &KV : ExpressionToClass) {
3344 auto Res = StoreExpressionSet.insert(
3345 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3346 SE->getStoredValue())});
3347 bool Okay = Res.second;
3352 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3353 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3354 lookupOperandLeader(SE->getStoredValue()));
3355 assert(Okay &&
"Stored expression conflict exists in expression table");
3356 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3357 assert(ValueExpr && ValueExpr->equals(*SE) &&
3358 "StoreExpression in ExpressionToClass is not latest "
3359 "StoreExpression for value");
3368void NewGVN::iterateTouchedInstructions() {
3369 uint64_t Iterations = 0;
3371 int FirstInstr = TouchedInstructions.
find_first();
3373 if (FirstInstr == -1)
3375 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3376 while (TouchedInstructions.
any()) {
3382 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3386 if (InstrNum == 0) {
3387 TouchedInstructions.
reset(InstrNum);
3391 Value *
V = InstrFromDFSNum(InstrNum);
3392 const BasicBlock *CurrBlock = getBlockForValue(V);
3395 if (CurrBlock != LastBlock) {
3396 LastBlock = CurrBlock;
3397 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3398 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3401 if (!BlockReachable) {
3402 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3405 <<
" because it is unreachable\n");
3410 updateProcessedCount(CurrBlock);
3414 TouchedInstructions.
reset(InstrNum);
3418 valueNumberMemoryPhi(MP);
3420 valueNumberInstruction(
I);
3424 updateProcessedCount(V);
3427 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3431bool NewGVN::runGVN() {
3435 NumFuncArgs =
F.arg_size();
3437 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3441 unsigned ICount = 1;
3452 ReversePostOrderTraversal<Function *> RPOT(&
F);
3453 unsigned Counter = 0;
3454 for (
auto &
B : RPOT) {
3456 assert(Node &&
"RPO and Dominator tree should have same reachability");
3457 RPOOrdering[
Node] = ++Counter;
3462 for (
auto &
B : RPOT) {
3467 while (!
Node->isLeaf()) {
3472 return RPOOrdering[
A] < RPOOrdering[
B];
3475 Node->addChild(Child);
3481 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3482 BlockInstRange.
insert({
B, BlockRange});
3483 ICount += BlockRange.second - BlockRange.first;
3485 initializeCongruenceClasses(
F);
3487 TouchedInstructions.
resize(ICount);
3491 ExpressionToClass.reserve(ICount);
3494 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3495 TouchedInstructions.
set(InstRange.first, InstRange.second);
3497 <<
" marked reachable\n");
3498 ReachableBlocks.
insert(&
F.getEntryBlock());
3502 iterateTouchedInstructions();
3503 verifyMemoryCongruency();
3504 verifyIterationSettled(
F);
3505 verifyStoreExpressions();
3507 Changed |= eliminateInstructions(
F);
3510 for (Instruction *ToErase : InstructionsToErase) {
3511 if (!ToErase->use_empty())
3514 assert(ToErase->getParent() &&
3515 "BB containing ToErase deleted unexpectedly!");
3516 ToErase->eraseFromParent();
3518 Changed |= !InstructionsToErase.empty();
3521 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3522 return !ReachableBlocks.
count(&BB);
3527 <<
" is unreachable\n");
3528 deleteInstructionsInBlock(&BB);
3597void NewGVN::convertClassToDFSOrdered(
3606 assert(BB &&
"Should have figured out a basic block for value");
3615 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3617 VDDef.Def.setPointer(Leader);
3619 VDDef.Def.setPointer(
SI->getValueOperand());
3620 VDDef.Def.setInt(
true);
3623 VDDef.Def.setPointer(
D);
3626 "The dense set member should always be an instruction");
3631 if (
auto *PN = RealToTemp.
lookup(Def)) {
3635 VDDef.Def.setInt(
false);
3636 VDDef.Def.setPointer(PN);
3642 unsigned int UseCount = 0;
3644 for (
auto &U :
Def->uses()) {
3647 if (InstructionsToErase.count(
I))
3653 IBlock =
P->getIncomingBlock(U);
3658 IBlock = getBlockForValue(
I);
3664 if (!ReachableBlocks.
contains(IBlock))
3680 ProbablyDead.
insert(Def);
3682 UseCounts[
Def] = UseCount;
3688void NewGVN::convertClassToLoadsAndStores(
3689 const CongruenceClass &
Dense,
3690 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3700 VD.Def.setPointer(
D);
3714 I->replaceAllUsesWith(Repl);
3717void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3719 ++NumGVNBlocksDeleted;
3723 auto StartPoint = BB->
rbegin();
3736 ++NumGVNInstrDeleted;
3746void NewGVN::markInstructionForDeletion(Instruction *
I) {
3748 InstructionsToErase.insert(
I);
3751void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3756 markInstructionForDeletion(
I);
3763class ValueDFSStack {
3765 Value *
back()
const {
return ValueStack.back(); }
3766 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3768 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3769 ValueStack.emplace_back(V);
3770 DFSStack.emplace_back(DFSIn, DFSOut);
3773 bool empty()
const {
return DFSStack.empty(); }
3775 bool isInScope(
int DFSIn,
int DFSOut)
const {
3778 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3781 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3784 assert(ValueStack.size() == DFSStack.size() &&
3785 "Mismatch between ValueStack and DFSStack");
3787 !DFSStack.empty() &&
3788 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3789 DFSStack.pop_back();
3790 ValueStack.pop_back();
3795 SmallVector<Value *, 8> ValueStack;
3802CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3804 return ValueToClass.lookup(VE->getVariableValue());
3807 return ExpressionToClass.lookup(
E);
3813 const Instruction *OrigInst,
3814 const BasicBlock *BB)
const {
3817 return CE->getConstantValue();
3819 auto *
V = VE->getVariableValue();
3821 return VE->getVariableValue();
3824 auto *CC = getClassForExpression(
E);
3828 return CC->getLeader();
3830 for (
auto *Member : *CC) {
3832 if (MemberInst == OrigInst)
3837 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3843bool NewGVN::eliminateInstructions(Function &
F) {
3867 bool AnythingReplaced =
false;
3875 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3876 for (
auto &Operand :
PHI->incoming_values())
3877 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3881 <<
" with poison due to it being unreachable\n");
3894 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3895 for (
auto &KV : ReachableEdges)
3896 ReachablePredCount[KV.getEnd()]++;
3897 for (
auto &BBPair : RevisitOnReachabilityChange) {
3898 for (
auto InstNum : BBPair.second) {
3899 auto *Inst = InstrFromDFSNum(InstNum);
3904 auto *BB = BBPair.first;
3905 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3906 ReplaceUnreachablePHIArgs(
PHI, BB);
3911 DenseMap<const Value *, unsigned int> UseCounts;
3912 for (
auto *CC :
reverse(CongruenceClasses)) {
3913 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3918 SmallPtrSet<Instruction *, 8> ProbablyDead;
3919 if (CC->isDead() || CC->empty())
3922 if (CC == TOPClass) {
3923 for (
auto *M : *CC) {
3924 auto *VTE = ValueToExpression.
lookup(M);
3929 "Everything in TOP should be unreachable or dead at this "
3935 assert(CC->getLeader() &&
"We should have had a leader");
3941 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3943 CongruenceClass::MemberSet MembersLeft;
3944 for (
auto *M : *CC) {
3948 Member->getType()->isVoidTy()) {
3949 MembersLeft.
insert(Member);
3953 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3954 << *Member <<
"\n");
3956 assert(Leader !=
I &&
"About to accidentally remove our leader");
3957 replaceInstruction(
I, Leader);
3958 AnythingReplaced =
true;
3960 CC->swap(MembersLeft);
3963 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3968 ValueDFSStack EliminationStack;
3972 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3976 for (
auto &VD : DFSOrderedSet) {
3977 int MemberDFSIn = VD.
DFSIn;
3978 int MemberDFSOut = VD.
DFSOut;
3980 bool FromStore = VD.Def.getInt();
3983 if (Def &&
Def->getType()->isVoidTy())
3986 if (DefInst && AllTempInstructions.
count(DefInst)) {
3992 AllTempInstructions.
erase(PN);
3993 auto *DefBlock = getBlockForValue(Def);
3997 PN->insertBefore(DefBlock->begin());
3999 NumGVNPHIOfOpsEliminations++;
4002 if (EliminationStack.empty()) {
4006 << EliminationStack.dfs_back().first <<
","
4007 << EliminationStack.dfs_back().second <<
")\n");
4010 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4011 << MemberDFSOut <<
")\n");
4025 bool ShouldPush =
Def && EliminationStack.empty();
4027 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4029 if (OutOfScope || ShouldPush) {
4031 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4032 bool ShouldPush =
Def && EliminationStack.empty();
4034 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4054 if (!EliminationStack.empty() && DefI && !FromStore) {
4055 Value *DominatingLeader = EliminationStack.back();
4056 if (DominatingLeader != Def) {
4064 for (
auto *DVR : DVRUsers)
4065 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4067 markInstructionForDeletion(DefI);
4076 "Current def should have been an instruction");
4078 "Current user should have been an instruction");
4085 if (InstructionsToErase.count(InstUse)) {
4086 auto &UseCount = UseCounts[
U->get()];
4087 if (--UseCount == 0) {
4094 if (EliminationStack.empty())
4097 Value *DominatingLeader = EliminationStack.back();
4101 if (BC->getType() == BC->getOperand(0)->getType() &&
4102 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4104 DominatingLeader = BC->getOperand(0);
4109 if (
U->get() == DominatingLeader)
4116 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4117 if (!PI || DominatingLeader != PI->OriginalOp)
4121 <<
"Found replacement " << *DominatingLeader <<
" for "
4122 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4123 U->set(DominatingLeader);
4126 auto &LeaderUseCount = UseCounts[DominatingLeader];
4133 auto It = UseCounts.
find(SSACopy);
4134 if (It != UseCounts.
end()) {
4135 unsigned &IIUseCount = It->second;
4136 if (--IIUseCount == 0)
4137 ProbablyDead.
insert(SSACopy);
4141 AnythingReplaced =
true;
4148 for (
auto *
I : ProbablyDead)
4150 markInstructionForDeletion(
I);
4153 CongruenceClass::MemberSet MembersLeft;
4154 for (
auto *Member : *CC)
4157 MembersLeft.
insert(Member);
4158 CC->swap(MembersLeft);
4161 if (CC->getStoreCount() > 0) {
4162 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4164 ValueDFSStack EliminationStack;
4165 for (
auto &VD : PossibleDeadStores) {
4166 int MemberDFSIn = VD.
DFSIn;
4167 int MemberDFSOut = VD.
DFSOut;
4169 if (EliminationStack.empty() ||
4170 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4172 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4173 if (EliminationStack.empty()) {
4174 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4181 assert(!EliminationStack.empty());
4187 <<
" that is dominated by " << *Leader <<
"\n");
4188 markInstructionForDeletion(Member);
4194 return AnythingReplaced;
4202unsigned int NewGVN::getRank(
const Value *V)
const {
4217 return 4 +
A->getArgNo();
4221 unsigned Result = InstrToDFSNum(V);
4223 return 5 + NumFuncArgs +
Result;
4230bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4234 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4237bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4238 const BitCastInst *
I)
const {
4239 if (shouldSwapOperands(
A,
B)) {
4240 PredicateSwapChoice[
I] =
B;
4245 if (LookupResult != PredicateSwapChoice.
end()) {
4247 if (SeenPredicate) {
4249 if (SeenPredicate ==
B)
4268 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, 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.
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.
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(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)
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.
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.
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.
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 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