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 auto Val =
static_cast<uintptr_t
>(-1);
447 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
448 return reinterpret_cast<const Expression *
>(Val);
452 return E->getComputedHash();
456 return E.getComputedHash();
474 if (LHS->getComputedHash() != RHS->getComputedHash())
496 mutable TarjanSCC SCCFinder;
498 std::unique_ptr<PredicateInfo> PredInfo;
502 unsigned int NumFuncArgs = 0;
513 CongruenceClass *TOPClass =
nullptr;
514 std::vector<CongruenceClass *> CongruenceClasses;
515 unsigned NextCongruenceNum = 0;
550 ExpressionToPhiOfOps;
599 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
600 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
602 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
603 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
606 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
607 ExpressionClassMap ExpressionToClass;
614 DeadExpression *SingletonDeadExpression =
nullptr;
617 SmallPtrSet<Value *, 8> LeaderChanges;
620 using BlockEdge = BasicBlockEdge;
621 DenseSet<BlockEdge> ReachableEdges;
622 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
633 BitVector TouchedInstructions;
635 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
636 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
640 DenseMap<const Value *, unsigned> ProcessedCount;
647 DenseMap<const Value *, unsigned> InstrDFS;
653 SmallPtrSet<Instruction *, 8> InstructionsToErase;
656 NewGVN(Function &
F, DominatorTree *DT, AssumptionCache *AC,
658 const DataLayout &
DL)
659 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
662 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
663 SQ(
DL, TLI, DT, AC, nullptr,
false,
671 const Expression *Expr;
673 const PredicateBase *PredDep;
675 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
676 const PredicateBase *PredDep =
nullptr)
677 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
678 ExprResult(
const ExprResult &) =
delete;
679 ExprResult(ExprResult &&
Other)
681 Other.Expr =
nullptr;
682 Other.ExtraDep =
nullptr;
683 Other.PredDep =
nullptr;
685 ExprResult &operator=(
const ExprResult &
Other) =
delete;
686 ExprResult &operator=(ExprResult &&
Other) =
delete;
688 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
690 operator bool()
const {
return Expr; }
692 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
693 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
694 return {Expr, ExtraDep,
nullptr};
696 static ExprResult some(
const Expression *Expr,
697 const PredicateBase *PredDep) {
698 return {Expr,
nullptr, PredDep};
700 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
701 const PredicateBase *PredDep) {
702 return {Expr, ExtraDep, PredDep};
707 ExprResult createExpression(Instruction *)
const;
708 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
709 Instruction *)
const;
713 using ValPair = std::pair<Value *, BasicBlock *>;
716 BasicBlock *,
bool &HasBackEdge,
717 bool &OriginalOpsConstant)
const;
718 const DeadExpression *createDeadExpression()
const;
719 const VariableExpression *createVariableExpression(
Value *)
const;
720 const ConstantExpression *createConstantExpression(Constant *)
const;
721 const Expression *createVariableOrConstant(
Value *V)
const;
722 const UnknownExpression *createUnknownExpression(Instruction *)
const;
723 const StoreExpression *createStoreExpression(StoreInst *,
724 const MemoryAccess *)
const;
725 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
726 const MemoryAccess *)
const;
727 const CallExpression *createCallExpression(CallInst *,
728 const MemoryAccess *)
const;
729 const AggregateValueExpression *
730 createAggregateValueExpression(Instruction *)
const;
731 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
734 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
737 unsigned LeaderDFS = 0;
745 LeaderDFS = InstrToDFSNum(
I);
747 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
748 CongruenceClasses.emplace_back(result);
752 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
753 auto *CC = createCongruenceClass(
nullptr,
nullptr);
754 CC->setMemoryLeader(MA);
758 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
759 auto *CC = getMemoryClass(MA);
760 if (CC->getMemoryLeader() != MA)
761 CC = createMemoryClass(MA);
765 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
766 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
767 CClass->insert(Member);
768 ValueToClass[
Member] = CClass;
772 void initializeCongruenceClasses(Function &
F);
773 const Expression *makePossiblePHIOfOps(Instruction *,
774 SmallPtrSetImpl<Value *> &);
775 Value *findLeaderForInst(Instruction *ValueOp,
776 SmallPtrSetImpl<Value *> &Visited,
777 MemoryAccess *MemAccess, Instruction *OrigInst,
779 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
780 SmallPtrSetImpl<const Value *> &);
781 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
782 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
785 void valueNumberMemoryPhi(MemoryPhi *);
786 void valueNumberInstruction(Instruction *);
789 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
790 ExprResult performSymbolicEvaluation(Instruction *,
791 SmallPtrSetImpl<Value *> &)
const;
792 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
794 MemoryAccess *)
const;
795 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
796 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
797 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
801 BasicBlock *PHIBlock)
const;
802 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
803 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
804 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
807 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
809 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
810 void performCongruenceFinding(Instruction *,
const Expression *);
811 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
812 CongruenceClass *, CongruenceClass *);
813 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
814 CongruenceClass *, CongruenceClass *);
815 Value *getNextValueLeader(CongruenceClass *)
const;
816 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
817 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
818 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
819 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
820 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
823 unsigned int getRank(
const Value *)
const;
824 bool shouldSwapOperands(
const Value *,
const Value *)
const;
825 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
826 const BitCastInst *
I)
const;
829 void updateReachableEdge(BasicBlock *, BasicBlock *);
830 void processOutgoingEdges(Instruction *, BasicBlock *);
831 Value *findConditionEquivalence(
Value *)
const;
835 void convertClassToDFSOrdered(
const CongruenceClass &,
836 SmallVectorImpl<ValueDFS> &,
837 DenseMap<const Value *, unsigned int> &,
838 SmallPtrSetImpl<Instruction *> &)
const;
839 void convertClassToLoadsAndStores(
const CongruenceClass &,
840 SmallVectorImpl<ValueDFS> &)
const;
842 bool eliminateInstructions(Function &);
843 void replaceInstruction(Instruction *,
Value *);
844 void markInstructionForDeletion(Instruction *);
845 void deleteInstructionsInBlock(BasicBlock *);
846 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
847 const BasicBlock *)
const;
850 template <
typename Map,
typename KeyType>
851 void touchAndErase(Map &,
const KeyType &);
852 void markUsersTouched(
Value *);
853 void markMemoryUsersTouched(
const MemoryAccess *);
854 void markMemoryDefTouched(
const MemoryAccess *);
855 void markPredicateUsersTouched(Instruction *);
856 void markValueLeaderChangeTouched(CongruenceClass *CC);
857 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
858 void markPhiOfOpsChanged(
const Expression *
E);
859 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
860 void addAdditionalUsers(
Value *To,
Value *User)
const;
861 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
864 void iterateTouchedInstructions();
867 void cleanupTables();
868 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
869 void updateProcessedCount(
const Value *V);
870 void verifyMemoryCongruency()
const;
871 void verifyIterationSettled(Function &
F);
872 void verifyStoreExpressions()
const;
873 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
874 const MemoryAccess *,
const MemoryAccess *)
const;
876 void deleteExpression(
const Expression *
E)
const;
877 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
878 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
879 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
881 unsigned InstrToDFSNum(
const Value *V)
const {
883 return InstrDFS.
lookup(V);
886 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
887 return MemoryToDFSNum(MA);
890 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
895 unsigned MemoryToDFSNum(
const Value *MA)
const {
897 "This should not be used with instructions");
903 bool isCycleFree(
const Instruction *)
const;
904 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
908 DebugCounter::CounterState StartingVNCounter;
917 return LHS.MemoryExpression::equals(
RHS);
939 return Call->getAttributes()
940 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
960MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
966MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
973 auto *Parent =
I->getParent();
976 Parent = TempToBlock.
lookup(V);
977 assert(Parent &&
"Every fake instruction should have a block");
982 assert(MP &&
"Should have been an instruction or a MemoryPhi");
983 return MP->getBlock();
989void NewGVN::deleteExpression(
const Expression *
E)
const {
993 ExpressionAllocator.Deallocate(
E);
999 if (BC->getType() == BC->getOperand(0)->getType())
1000 return BC->getOperand(0);
1019 return BlockInstRange.
lookup(
P1.second).first <
1020 BlockInstRange.
lookup(
P2.second).first;
1037 const Instruction *
I,
1038 BasicBlock *PHIBlock,
1040 bool &OriginalOpsConstant)
const {
1045 E->setType(PHIOperands.
begin()->first->getType());
1046 E->setOpcode(Instruction::PHI);
1050 auto *BB =
P.second;
1054 if (!ReachableEdges.
count({BB, PHIBlock}))
1057 if (ValueToClass.
lookup(
P.first) == TOPClass)
1059 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1060 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1061 return lookupOperandLeader(
P.first) !=
I;
1064 return lookupOperandLeader(
P.first);
1072 bool AllConstant =
true;
1074 E->setType(
GEP->getSourceElementType());
1076 E->setType(
I->getType());
1077 E->setOpcode(
I->getOpcode());
1078 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1083 auto Operand = lookupOperandLeader(O);
1091const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1093 Instruction *
I)
const {
1100 E->setOpcode(Opcode);
1101 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1107 if (shouldSwapOperands(Arg1, Arg2))
1110 E->op_push_back(lookupOperandLeader(Arg1));
1111 E->op_push_back(lookupOperandLeader(Arg2));
1114 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1115 addAdditionalUsers(Simplified,
I);
1124NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1127 return ExprResult::none();
1132 <<
" constant " << *
C <<
"\n");
1133 NumGVNOpsSimplified++;
1135 "We should always have had a basic expression here");
1136 deleteExpression(
E);
1137 return ExprResult::some(createConstantExpression(
C));
1141 <<
" variable " << *V <<
"\n");
1142 deleteExpression(
E);
1143 return ExprResult::some(createVariableExpression(V));
1146 CongruenceClass *CC = ValueToClass.
lookup(V);
1148 if (CC->getLeader() && CC->getLeader() !=
I) {
1149 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1151 if (CC->getDefiningExpr()) {
1154 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1155 NumGVNOpsSimplified++;
1156 deleteExpression(
E);
1157 return ExprResult::some(CC->getDefiningExpr(), V);
1161 return ExprResult::none();
1167NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1173 bool AllConstant = setBasicExpressionInfo(
I,
E);
1175 if (
I->isCommutative()) {
1180 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1181 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1182 E->swapOperands(0, 1);
1189 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1190 E->swapOperands(0, 1);
1193 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1195 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1196 "Wrong types on cmp instruction");
1197 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1198 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1201 if (
auto Simplified = checkExprResults(
E,
I, V))
1205 E->getOperand(1) ==
E->getOperand(2)) {
1206 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1207 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1209 E->getOperand(2), FastMathFlags(), Q);
1210 if (
auto Simplified = checkExprResults(
E,
I, V))
1213 }
else if (
I->isBinaryOp()) {
1216 if (
auto Simplified = checkExprResults(
E,
I, V))
1221 if (
auto Simplified = checkExprResults(
E,
I, V))
1225 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1226 GEPI->getNoWrapFlags(), Q);
1227 if (
auto Simplified = checkExprResults(
E,
I, V))
1229 }
else if (AllConstant) {
1238 for (
Value *Arg :
E->operands())
1242 if (
auto Simplified = checkExprResults(
E,
I, V))
1245 return ExprResult::some(
E);
1249NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1251 auto *
E =
new (ExpressionAllocator)
1253 setBasicExpressionInfo(
I,
E);
1254 E->allocateIntOperands(ExpressionAllocator);
1258 auto *
E =
new (ExpressionAllocator)
1260 setBasicExpressionInfo(EI,
E);
1261 E->allocateIntOperands(ExpressionAllocator);
1271 return SingletonDeadExpression;
1282 return createConstantExpression(
C);
1283 return createVariableExpression(V);
1299NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1303 setBasicExpressionInfo(CI,
E);
1309 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1310 E->swapOperands(0, 1);
1316bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1317 const Instruction *U)
const {
1318 auto *CC = ValueToClass.
lookup(Inst);
1341 if (CC->getNextLeader().first &&
1345 return Member != CC->getLeader() &&
1352Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1353 CongruenceClass *CC = ValueToClass.
lookup(V);
1360 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1366const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1367 auto *CC = getMemoryClass(MA);
1368 assert(CC->getMemoryLeader() &&
1369 "Every MemoryAccess should be mapped to a congruence class with a "
1370 "representative memory access");
1371 return CC->getMemoryLeader();
1377bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1378 return getMemoryClass(MA) == TOPClass;
1383 const MemoryAccess *MA)
const {
1385 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1387 E->setType(LoadType);
1391 E->op_push_back(PointerOp);
1400NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1401 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1402 auto *
E =
new (ExpressionAllocator)
1405 E->setType(
SI->getValueOperand()->getType());
1409 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1417const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1421 auto *StoreAccess = getMemoryAccess(SI);
1423 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1427 StoreRHS = lookupMemoryLeader(StoreRHS);
1428 if (StoreRHS != StoreAccess->getDefiningAccess())
1429 addMemoryUsers(StoreRHS, StoreAccess);
1431 if (StoreRHS == StoreAccess)
1434 if (
SI->isSimple()) {
1438 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1439 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1445 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1453 LastStore->getOperand(0)) &&
1454 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1457 deleteExpression(LastStore);
1463 return createStoreExpression(SI, StoreAccess);
1469NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1470 LoadInst *LI, Instruction *DepInst,
1471 MemoryAccess *DefiningAccess)
const {
1477 if (LI->
isAtomic() > DepSI->isAtomic() ||
1478 LoadType == DepSI->getValueOperand()->getType())
1483 lookupOperandLeader(DepSI->getValueOperand()))) {
1486 <<
" to constant " << *Res <<
"\n");
1487 return createConstantExpression(Res);
1493 if (LI->
isAtomic() > DepLI->isAtomic())
1499 if (
auto *PossibleConstant =
1502 <<
" to constant " << *PossibleConstant <<
"\n");
1503 return createConstantExpression(PossibleConstant);
1509 if (
auto *PossibleConstant =
1512 <<
" to constant " << *PossibleConstant <<
"\n");
1513 return createConstantExpression(PossibleConstant);
1519 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1520 auto *LifetimePtr =
II->getOperand(0);
1521 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1530 (LoadPtr != lookupOperandLeader(DepInst) &&
1539 }
else if (
auto *InitVal =
1541 return createConstantExpression(InitVal);
1546const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1558 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1559 MemoryAccess *DefiningAccess =
1572 if (
const auto *CoercionResult =
1573 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1574 DefiningInst, DefiningAccess))
1575 return CoercionResult;
1579 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1583 if (
LE->getMemoryLeader() != DefiningAccess)
1584 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1589NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1590 auto *PI = PredInfo->getPredicateInfoFor(
I);
1592 return ExprResult::none();
1594 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1596 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1598 return ExprResult::none();
1601 Value *CmpOp0 =
I->getOperand(0);
1602 Value *CmpOp1 = Constraint->OtherOp;
1604 Value *FirstOp = lookupOperandLeader(CmpOp0);
1605 Value *SecondOp = lookupOperandLeader(CmpOp1);
1606 Value *AdditionallyUsedValue = CmpOp0;
1609 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1612 AdditionallyUsedValue = CmpOp1;
1616 return ExprResult::some(createVariableOrConstant(FirstOp),
1617 AdditionallyUsedValue, PI);
1622 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1623 AdditionallyUsedValue, PI);
1625 return ExprResult::none();
1629NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1640 return ExprResult::none();
1646 return ExprResult::none();
1649 return ExprResult::some(
1650 createCallExpression(CI, TOPClass->getMemoryLeader()));
1654 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1656 return ExprResult::some(
1657 createCallExpression(CI, TOPClass->getMemoryLeader()));
1659 return ExprResult::none();
1663CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1665 assert(Result &&
"Should have found memory class");
1671bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1672 CongruenceClass *NewClass) {
1674 "Every MemoryAccess should be getting mapped to a non-null class");
1678 <<
" with current MemoryAccess leader ");
1684 if (LookupResult != MemoryAccessToClass.
end()) {
1686 if (OldClass != NewClass) {
1689 OldClass->memory_erase(MP);
1690 NewClass->memory_insert(MP);
1692 if (OldClass->getMemoryLeader() == From) {
1693 if (OldClass->definesNoMemory()) {
1694 OldClass->setMemoryLeader(
nullptr);
1696 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1698 << OldClass->getID() <<
" to "
1699 << *OldClass->getMemoryLeader()
1700 <<
" due to removal of a memory member " << *From
1702 markMemoryLeaderChangeTouched(OldClass);
1719bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1725 auto ICS = InstCycleState.
lookup(
I);
1726 if (ICS == ICS_Unknown) {
1728 auto &
SCC = SCCFinder.getComponentFor(
I);
1730 if (
SCC.size() == 1)
1731 InstCycleState.
insert({
I, ICS_CycleFree});
1736 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1737 for (
const auto *Member : SCC)
1739 InstCycleState.
insert({MemberPhi, ICS});
1742 if (ICS == ICS_Cycle)
1751 BasicBlock *PHIBlock)
const {
1753 bool HasBackedge =
false;
1758 bool OriginalOpsConstant =
true;
1760 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1764 bool HasUndef =
false, HasPoison =
false;
1766 if (isa<PoisonValue>(Arg)) {
1777 if (Filtered.empty()) {
1782 dbgs() <<
"PHI Node " << *
I
1783 <<
" has no non-undef arguments, valuing it as undef\n");
1788 dbgs() <<
"PHI Node " << *
I
1789 <<
" has no non-poison arguments, valuing it as poison\n");
1793 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1794 deleteExpression(
E);
1795 return createDeadExpression();
1797 Value *AllSameValue = *(Filtered.begin());
1815 if (HasPoison || HasUndef) {
1821 if (HasBackedge && !OriginalOpsConstant &&
1827 if (!someEquivalentDominates(AllSameInst,
I))
1834 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1836 NumGVNPhisAllSame++;
1837 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1839 deleteExpression(
E);
1840 return createVariableOrConstant(AllSameValue);
1846NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1849 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1853 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1854 WO->getLHS(), WO->getRHS(),
I);
1857 return createAggregateValueExpression(
I);
1860NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1866 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1867 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1868 auto OurPredicate = CI->getPredicate();
1869 if (shouldSwapOperands(Op0, Op1)) {
1871 OurPredicate = CI->getSwappedPredicate();
1875 const PredicateBase *LastPredInfo =
nullptr;
1878 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1880 return ExprResult::some(
1885 if (CI->isTrueWhenEqual())
1886 return ExprResult::some(
1888 else if (CI->isFalseWhenEqual())
1889 return ExprResult::some(
1919 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1921 if (PI == LastPredInfo)
1926 if (!DT->
dominates(PBranch->To,
I->getParent()))
1936 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1937 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1938 auto BranchPredicate = BranchCond->getPredicate();
1939 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1941 BranchPredicate = BranchCond->getSwappedPredicate();
1943 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1944 if (PBranch->TrueEdge) {
1950 return ExprResult::some(createConstantExpression(
C), PI);
1955 if (BranchPredicate == OurPredicate) {
1957 return ExprResult::some(
1960 }
else if (BranchPredicate ==
1963 return ExprResult::some(
1972 return createExpression(
I);
1977NewGVN::performSymbolicEvaluation(Instruction *
I,
1978 SmallPtrSetImpl<Value *> &Visited)
const {
1984 switch (
I->getOpcode()) {
1985 case Instruction::ExtractValue:
1986 case Instruction::InsertValue:
1987 E = performSymbolicAggrValueEvaluation(
I);
1989 case Instruction::PHI: {
1992 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1993 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1996 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
1998 case Instruction::Call:
1999 return performSymbolicCallEvaluation(
I);
2001 case Instruction::Store:
2002 E = performSymbolicStoreEvaluation(
I);
2004 case Instruction::Load:
2005 E = performSymbolicLoadEvaluation(
I);
2007 case Instruction::BitCast:
2009 if (
I->getType() ==
I->getOperand(0)->getType())
2014 case Instruction::AddrSpaceCast:
2015 case Instruction::Freeze:
2016 return createExpression(
I);
2018 case Instruction::ICmp:
2019 case Instruction::FCmp:
2020 return performSymbolicCmpEvaluation(
I);
2022 case Instruction::FNeg:
2023 case Instruction::Add:
2024 case Instruction::FAdd:
2025 case Instruction::Sub:
2026 case Instruction::FSub:
2027 case Instruction::Mul:
2028 case Instruction::FMul:
2029 case Instruction::UDiv:
2030 case Instruction::SDiv:
2031 case Instruction::FDiv:
2032 case Instruction::URem:
2033 case Instruction::SRem:
2034 case Instruction::FRem:
2035 case Instruction::Shl:
2036 case Instruction::LShr:
2037 case Instruction::AShr:
2038 case Instruction::And:
2039 case Instruction::Or:
2040 case Instruction::Xor:
2041 case Instruction::Trunc:
2042 case Instruction::ZExt:
2043 case Instruction::SExt:
2044 case Instruction::FPToUI:
2045 case Instruction::FPToSI:
2046 case Instruction::UIToFP:
2047 case Instruction::SIToFP:
2048 case Instruction::FPTrunc:
2049 case Instruction::FPExt:
2050 case Instruction::PtrToInt:
2051 case Instruction::PtrToAddr:
2052 case Instruction::IntToPtr:
2053 case Instruction::Select:
2054 case Instruction::ExtractElement:
2055 case Instruction::InsertElement:
2056 case Instruction::GetElementPtr:
2057 return createExpression(
I);
2059 case Instruction::ShuffleVector:
2061 return ExprResult::none();
2063 return ExprResult::none();
2065 return ExprResult::some(
E);
2070template <
typename Map,
typename KeyType>
2071void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2073 if (Result !=
M.end()) {
2074 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2075 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2080void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2081 assert(User && To != User);
2083 AdditionalUsers[To].
insert(User);
2086void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2087 if (Res.ExtraDep && Res.ExtraDep != User)
2088 addAdditionalUsers(Res.ExtraDep, User);
2089 Res.ExtraDep =
nullptr;
2093 PredicateToUsers[PBranch->Condition].
insert(User);
2094 else if (
const auto *PAssume =
2096 PredicateToUsers[PAssume->Condition].
insert(User);
2098 Res.PredDep =
nullptr;
2101void NewGVN::markUsersTouched(
Value *V) {
2103 for (
auto *User :
V->users()) {
2105 TouchedInstructions.
set(InstrToDFSNum(User));
2107 touchAndErase(AdditionalUsers, V);
2110void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2111 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2112 MemoryToUsers[To].
insert(U);
2115void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2116 TouchedInstructions.
set(MemoryToDFSNum(MA));
2119void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2122 for (
const auto *U : MA->
users())
2123 TouchedInstructions.
set(MemoryToDFSNum(U));
2124 touchAndErase(MemoryToUsers, MA);
2128void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2129 touchAndErase(PredicateToUsers,
I);
2133void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2134 for (
const auto *M : CC->memory())
2135 markMemoryDefTouched(M);
2140void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2141 for (
auto *M : *CC) {
2143 TouchedInstructions.
set(InstrToDFSNum(
I));
2150template <
class T,
class Range>
2151T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2152 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2153 for (
const auto X : R) {
2154 auto DFSNum = InstrToDFSNum(
X);
2155 if (DFSNum < MinDFS.second)
2156 MinDFS = {
X, DFSNum};
2158 return MinDFS.first;
2164const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2168 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2169 if (CC->getStoreCount() > 0) {
2171 return getMemoryAccess(NL);
2177 assert(CC->getStoreCount() == 0);
2181 if (CC->memory_size() == 1)
2182 return *CC->memory_begin();
2183 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2189Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2194 if (CC->size() == 1 || CC == TOPClass) {
2195 return *(CC->begin());
2196 }
else if (CC->getNextLeader().first) {
2197 ++NumGVNAvoidedSortedLeaderChanges;
2198 return CC->getNextLeader().first;
2200 ++NumGVNSortedLeaderChanges;
2204 return getMinDFSOfRange<Value>(*CC);
2217void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2218 MemoryAccess *InstMA,
2219 CongruenceClass *OldClass,
2220 CongruenceClass *NewClass) {
2223 assert((!InstMA || !OldClass->getMemoryLeader() ||
2224 OldClass->getLeader() !=
I ||
2225 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2226 MemoryAccessToClass.
lookup(InstMA)) &&
2227 "Representative MemoryAccess mismatch");
2229 if (!NewClass->getMemoryLeader()) {
2231 assert(NewClass->size() == 1 ||
2233 NewClass->setMemoryLeader(InstMA);
2236 << NewClass->getID()
2237 <<
" due to new memory instruction becoming leader\n");
2238 markMemoryLeaderChangeTouched(NewClass);
2240 setMemoryClass(InstMA, NewClass);
2242 if (OldClass->getMemoryLeader() == InstMA) {
2243 if (!OldClass->definesNoMemory()) {
2244 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2246 << OldClass->getID() <<
" to "
2247 << *OldClass->getMemoryLeader()
2248 <<
" due to removal of old leader " << *InstMA <<
"\n");
2249 markMemoryLeaderChangeTouched(OldClass);
2251 OldClass->setMemoryLeader(
nullptr);
2257void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2258 CongruenceClass *OldClass,
2259 CongruenceClass *NewClass) {
2260 if (
I == OldClass->getNextLeader().first)
2261 OldClass->resetNextLeader();
2264 NewClass->insert(
I);
2268 if (NewClass->getLeader() !=
I &&
2269 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2270 markValueLeaderChangeTouched(NewClass);
2275 OldClass->decStoreCount();
2283 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2287 NewClass->setStoredValue(SE->getStoredValue());
2288 markValueLeaderChangeTouched(NewClass);
2291 << NewClass->getID() <<
" from "
2292 << *NewClass->getLeader() <<
" to " << *SI
2293 <<
" because store joined class\n");
2296 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2300 NewClass->incStoreCount();
2308 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2309 ValueToClass[
I] = NewClass;
2311 if (OldClass->empty() && OldClass != TOPClass) {
2312 if (OldClass->getDefiningExpr()) {
2313 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2314 <<
" from table\n");
2317 auto Iter = ExpressionToClass.find_as(
2318 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2319 if (Iter != ExpressionToClass.end())
2320 ExpressionToClass.erase(Iter);
2321#ifdef EXPENSIVE_CHECKS
2323 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2324 "We erased the expression we just inserted, which should not happen");
2327 }
else if (OldClass->getLeader() ==
I) {
2332 << OldClass->getID() <<
"\n");
2333 ++NumGVNLeaderChanges;
2338 if (OldClass->getStoreCount() == 0) {
2339 if (OldClass->getStoredValue())
2340 OldClass->setStoredValue(
nullptr);
2342 OldClass->setLeader({getNextValueLeader(OldClass),
2343 InstrToDFSNum(getNextValueLeader(OldClass))});
2344 OldClass->resetNextLeader();
2345 markValueLeaderChangeTouched(OldClass);
2351void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2352 touchAndErase(ExpressionToPhiOfOps,
E);
2356void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2360 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2361 assert(IClass &&
"Should have found a IClass");
2363 assert(!IClass->isDead() &&
"Found a dead class");
2365 CongruenceClass *EClass =
nullptr;
2367 EClass = ValueToClass.
lookup(VE->getVariableValue());
2372 auto lookupResult = ExpressionToClass.try_emplace(
E);
2375 if (lookupResult.second) {
2376 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2377 auto place = lookupResult.first;
2378 place->second = NewClass;
2382 NewClass->setLeader({
CE->getConstantValue(), 0});
2384 StoreInst *
SI = SE->getStoreInst();
2385 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2386 NewClass->setStoredValue(SE->getStoredValue());
2390 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2393 "VariableExpression should have been handled already");
2397 <<
" using expression " << *
E <<
" at "
2398 << NewClass->getID() <<
" and leader "
2399 << *(NewClass->getLeader()));
2400 if (NewClass->getStoredValue())
2402 << *(NewClass->getStoredValue()));
2405 EClass = lookupResult.first->second;
2408 (EClass->getStoredValue() &&
2410 "Any class with a constant expression should have a "
2413 assert(EClass &&
"Somehow don't have an eclass");
2415 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2418 bool ClassChanged = IClass != EClass;
2419 bool LeaderChanged = LeaderChanges.
erase(
I);
2420 if (ClassChanged || LeaderChanged) {
2421 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2424 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2425 markPhiOfOpsChanged(
E);
2428 markUsersTouched(
I);
2429 if (MemoryAccess *MA = getMemoryAccess(
I))
2430 markMemoryUsersTouched(MA);
2432 markPredicateUsersTouched(CI);
2439 auto *OldE = ValueToExpression.
lookup(
I);
2445 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2446 if (Iter != ExpressionToClass.end())
2447 ExpressionToClass.erase(Iter);
2450 ValueToExpression[
I] =
E;
2455void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2457 if (ReachableEdges.
insert({From, To}).second) {
2459 if (ReachableBlocks.
insert(To).second) {
2461 <<
" marked reachable\n");
2462 const auto &InstRange = BlockInstRange.
lookup(To);
2463 TouchedInstructions.
set(InstRange.first, InstRange.second);
2466 <<
" was reachable, but new edge {"
2468 <<
"} to it found\n");
2474 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2475 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2480 for (
auto InstNum : RevisitOnReachabilityChange[To])
2481 TouchedInstructions.
set(InstNum);
2494void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2499 Value *CondEvaluated = findConditionEquivalence(
Cond);
2500 if (!CondEvaluated) {
2502 SmallPtrSet<Value *, 4> Visited;
2503 auto Res = performSymbolicEvaluation(
I, Visited);
2505 CondEvaluated =
CE->getConstantValue();
2506 addAdditionalUsers(Res,
I);
2510 Res.ExtraDep =
nullptr;
2513 CondEvaluated =
Cond;
2520 <<
" evaluated to true\n");
2521 updateReachableEdge(
B, TrueSucc);
2522 }
else if (CI->
isZero()) {
2524 <<
" evaluated to false\n");
2525 updateReachableEdge(
B, FalseSucc);
2528 updateReachableEdge(
B, TrueSucc);
2529 updateReachableEdge(
B, FalseSucc);
2535 Value *SwitchCond =
SI->getCondition();
2536 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2541 auto Case = *
SI->findCaseValue(CondVal);
2542 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2546 updateReachableEdge(
B,
SI->getDefaultDest());
2550 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2551 updateReachableEdge(
B, TargetBlock);
2553 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2554 updateReachableEdge(
B, TargetBlock);
2560 updateReachableEdge(
B, TargetBlock);
2565 auto *MA = getMemoryAccess(TI);
2567 auto *CC = ensureLeaderOfMemoryClass(MA);
2568 if (setMemoryClass(MA, CC))
2569 markMemoryUsersTouched(MA);
2575void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2576 InstrDFS.
erase(PHITemp);
2579 TempToBlock.
erase(PHITemp);
2588void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2589 Instruction *ExistingValue) {
2590 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2592 TempToBlock[
Op] = BB;
2593 RealToTemp[ExistingValue] =
Op;
2596 for (
auto *U : ExistingValue->
users())
2615bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2616 SmallPtrSetImpl<const Value *> &Visited) {
2617 SmallVector<Value *, 4> Worklist;
2619 while (!Worklist.
empty()) {
2624 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2625 if (OISIt != OpSafeForPHIOfOps.
end())
2626 return OISIt->second;
2631 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2636 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2647 if (OrigI->mayReadFromMemory())
2651 for (
auto *
Op : OrigI->operand_values()) {
2655 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2656 if (OISIt != OpSafeForPHIOfOps.
end()) {
2657 if (!OISIt->second) {
2658 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2668 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2677Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2678 SmallPtrSetImpl<Value *> &Visited,
2679 MemoryAccess *MemAccess, Instruction *OrigInst,
2680 BasicBlock *PredBB) {
2681 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2683 AllTempInstructions.
insert(TransInst);
2687 TempToBlock.
insert({TransInst, PredBB});
2688 InstrDFS.
insert({TransInst, IDFSNum});
2690 auto Res = performSymbolicEvaluation(TransInst, Visited);
2692 addAdditionalUsers(Res, OrigInst);
2693 InstrDFS.
erase(TransInst);
2694 AllTempInstructions.
erase(TransInst);
2695 TempToBlock.
erase(TransInst);
2697 TempToMemory.
erase(TransInst);
2700 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2702 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2703 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2708 FoundVal =
SI->getValueOperand();
2715NewGVN::makePossiblePHIOfOps(Instruction *
I,
2716 SmallPtrSetImpl<Value *> &Visited) {
2720 if (!Visited.
insert(
I).second)
2726 if (!isCycleFree(
I))
2732 auto *MemAccess = getMemoryAccess(
I);
2736 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2741 SmallPtrSet<const Value *, 10> VisitedOps;
2742 SmallVector<Value *, 4>
Ops(
I->operand_values());
2744 PHINode *OpPHI =
nullptr;
2747 for (
auto *
Op :
Ops) {
2749 auto *ValuePHI = RealToTemp.
lookup(
Op);
2756 if (!SamePHIBlock) {
2757 SamePHIBlock = getBlockForValue(OpPHI);
2758 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2761 <<
"PHIs for operands are not all in the same block, aborting\n");
2775 SmallPtrSet<Value *, 4> Deps;
2776 auto *PHIBlock = getBlockForValue(OpPHI);
2777 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2778 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2780 Value *FoundVal =
nullptr;
2781 SmallPtrSet<Value *, 4> CurrentDeps;
2784 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2792 TempToMemory.
insert({ValueOp, MemAccess});
2793 bool SafeForPHIOfOps =
true;
2796 auto *OrigOp = &*
Op;
2800 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2801 if (
Op != OrigOp &&
Op !=
I)
2803 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2804 if (getBlockForValue(ValuePHI) == PHIBlock)
2805 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2810 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2817 FoundVal = !SafeForPHIOfOps ? nullptr
2818 : findLeaderForInst(ValueOp, Visited,
2819 MemAccess,
I, PredBB);
2824 if (SafeForPHIOfOps)
2825 for (
auto *Dep : CurrentDeps)
2826 addAdditionalUsers(Dep,
I);
2832 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2834 <<
" because the block is unreachable\n");
2836 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2840 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2843 for (
auto *Dep : Deps)
2844 addAdditionalUsers(Dep,
I);
2846 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2850 <<
"Not creating real PHI of ops because it simplified to existing "
2851 "value or constant\n");
2857 for (
auto &O : PHIOps)
2858 addAdditionalUsers(
O.first,
I);
2862 auto *ValuePHI = RealToTemp.
lookup(
I);
2863 bool NewPHI =
false;
2867 addPhiOfOps(ValuePHI, PHIBlock,
I);
2869 NumGVNPHIOfOpsCreated++;
2872 for (
auto PHIOp : PHIOps)
2873 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2875 TempToBlock[ValuePHI] = PHIBlock;
2877 for (
auto PHIOp : PHIOps) {
2878 ValuePHI->setIncomingValue(i, PHIOp.first);
2879 ValuePHI->setIncomingBlock(i, PHIOp.second);
2883 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2884 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2893void NewGVN::initializeCongruenceClasses(Function &
F) {
2894 NextCongruenceNum = 0;
2904 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2910 for (
auto *DTN :
nodes(DT)) {
2917 if (MemoryBlockDefs)
2918 for (
const auto &Def : *MemoryBlockDefs) {
2919 MemoryAccessToClass[&
Def] = TOPClass;
2924 TOPClass->memory_insert(MP);
2925 MemoryPhiState.
insert({MP, MPS_TOP});
2929 TOPClass->incStoreCount();
2935 for (
auto &
I : *BB) {
2937 for (
auto *U :
I.users())
2940 PHINodeUses.
insert(UInst);
2943 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2945 TOPClass->insert(&
I);
2946 ValueToClass[&
I] = TOPClass;
2951 for (
auto &FA :
F.args())
2952 createSingletonCongruenceClass(&FA);
2955void NewGVN::cleanupTables() {
2956 for (CongruenceClass *&CC : CongruenceClasses) {
2957 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2958 << CC->size() <<
" members\n");
2966 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2967 AllTempInstructions.
end());
2968 AllTempInstructions.
clear();
2972 for (
auto *
I : TempInst) {
2973 I->dropAllReferences();
2976 while (!TempInst.empty()) {
2977 auto *
I = TempInst.pop_back_val();
2981 ValueToClass.
clear();
2982 ArgRecycler.
clear(ExpressionAllocator);
2983 ExpressionAllocator.Reset();
2984 CongruenceClasses.clear();
2985 ExpressionToClass.clear();
2986 ValueToExpression.
clear();
2988 AdditionalUsers.
clear();
2989 ExpressionToPhiOfOps.
clear();
2990 TempToBlock.
clear();
2991 TempToMemory.
clear();
2992 PHINodeUses.
clear();
2993 OpSafeForPHIOfOps.
clear();
2994 ReachableBlocks.
clear();
2995 ReachableEdges.
clear();
2997 ProcessedCount.
clear();
3000 InstructionsToErase.
clear();
3002 BlockInstRange.
clear();
3003 TouchedInstructions.
clear();
3004 MemoryAccessToClass.
clear();
3005 PredicateToUsers.
clear();
3006 MemoryToUsers.
clear();
3007 RevisitOnReachabilityChange.
clear();
3008 PredicateSwapChoice.
clear();
3013std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
3015 unsigned End =
Start;
3016 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
3017 InstrDFS[MemPhi] = End++;
3022 for (
auto &
I : *
B) {
3028 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3030 markInstructionForDeletion(&
I);
3034 RevisitOnReachabilityChange[
B].set(End);
3035 InstrDFS[&
I] = End++;
3042 return std::make_pair(Start, End);
3045void NewGVN::updateProcessedCount(
const Value *V) {
3047 assert(++ProcessedCount[V] < 100 &&
3048 "Seem to have processed the same Value a lot");
3053void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3060 return cast<MemoryAccess>(U) != MP &&
3061 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3062 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3067 if (Filtered.begin() == Filtered.end()) {
3068 if (setMemoryClass(MP, TOPClass))
3069 markMemoryUsersTouched(MP);
3075 auto LookupFunc = [&](
const Use &
U) {
3078 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3079 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3083 const auto *AllSameValue = *MappedBegin;
3085 bool AllEqual = std::all_of(
3086 MappedBegin, MappedEnd,
3087 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3090 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3099 CongruenceClass *CC =
3100 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3101 auto OldState = MemoryPhiState.
lookup(MP);
3102 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3103 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3104 MemoryPhiState[MP] = NewState;
3105 if (setMemoryClass(MP, CC) || OldState != NewState)
3106 markMemoryUsersTouched(MP);
3111void NewGVN::valueNumberInstruction(Instruction *
I) {
3113 if (!
I->isTerminator()) {
3115 SmallPtrSet<Value *, 2> Visited;
3117 auto Res = performSymbolicEvaluation(
I, Visited);
3118 Symbolized = Res.Expr;
3119 addAdditionalUsers(Res,
I);
3124 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3129 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3130 removePhiOfOps(
I,
Op);
3139 if (Symbolized ==
nullptr)
3140 Symbolized = createUnknownExpression(
I);
3141 performCongruenceFinding(
I, Symbolized);
3146 if (!
I->getType()->isVoidTy()) {
3147 auto *Symbolized = createUnknownExpression(
I);
3148 performCongruenceFinding(
I, Symbolized);
3150 processOutgoingEdges(
I,
I->getParent());
3156bool NewGVN::singleReachablePHIPath(
3157 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3158 const MemoryAccess *Second)
const {
3159 if (
First == Second)
3172 const auto *EndDef =
First;
3174 if (ChainDef == Second)
3181 auto ReachableOperandPred = [&](
const Use &
U) {
3184 auto FilteredPhiArgs =
3198void NewGVN::verifyMemoryCongruency()
const {
3201 for (
const auto *CC : CongruenceClasses) {
3202 if (CC == TOPClass || CC->isDead())
3204 if (CC->getStoreCount() != 0) {
3206 "Any class with a store as a leader should have a "
3207 "representative stored value");
3208 assert(CC->getMemoryLeader() &&
3209 "Any congruence class with a store should have a "
3210 "representative access");
3213 if (CC->getMemoryLeader())
3214 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3215 "Representative MemoryAccess does not appear to be reverse "
3217 for (
const auto *M : CC->memory())
3219 "Memory member does not appear to be reverse mapped properly");
3227 auto ReachableAccessPred =
3228 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3229 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3231 MemoryToDFSNum(Pair.first) == 0)
3239 for (
const auto &U : MemPHI->incoming_values()) {
3252 for (
auto KV : Filtered) {
3255 if (FirstMUD && SecondMUD) {
3256 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3257 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3258 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3259 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3260 "The instructions for these memory operations should have "
3261 "been in the same congruence class or reachable through"
3262 "a single argument phi");
3267 auto ReachableOperandPred = [&](
const Use &
U) {
3268 return ReachableEdges.
count(
3269 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3273 auto FilteredPhiArgs =
3276 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3277 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3278 const MemoryDef *MD = cast<MemoryDef>(U);
3279 return ValueToClass.lookup(MD->getMemoryInst());
3282 "All MemoryPhi arguments should be in the same class");
3291void NewGVN::verifyIterationSettled(Function &
F) {
3301 std::map<const Value *, CongruenceClass> BeforeIteration;
3303 for (
auto &KV : ValueToClass) {
3306 if (InstrToDFSNum(
I) == 0)
3308 BeforeIteration.insert({KV.first, *KV.second});
3311 TouchedInstructions.
set();
3312 TouchedInstructions.
reset(0);
3313 OpSafeForPHIOfOps.
clear();
3315 iterateTouchedInstructions();
3316 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3318 for (
const auto &KV : ValueToClass) {
3321 if (InstrToDFSNum(
I) == 0)
3325 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3326 auto *AfterCC = KV.second;
3329 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3330 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3331 "Value number changed after main loop completed!");
3332 EqualClasses.
insert({BeforeCC, AfterCC});
3343void NewGVN::verifyStoreExpressions()
const {
3348 std::pair<
const Value *,
3349 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3351 for (
const auto &KV : ExpressionToClass) {
3354 auto Res = StoreExpressionSet.insert(
3355 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3356 SE->getStoredValue())});
3357 bool Okay = Res.second;
3362 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3363 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3364 lookupOperandLeader(SE->getStoredValue()));
3365 assert(Okay &&
"Stored expression conflict exists in expression table");
3366 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3367 assert(ValueExpr && ValueExpr->equals(*SE) &&
3368 "StoreExpression in ExpressionToClass is not latest "
3369 "StoreExpression for value");
3378void NewGVN::iterateTouchedInstructions() {
3379 uint64_t Iterations = 0;
3381 int FirstInstr = TouchedInstructions.
find_first();
3383 if (FirstInstr == -1)
3385 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3386 while (TouchedInstructions.
any()) {
3392 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3396 if (InstrNum == 0) {
3397 TouchedInstructions.
reset(InstrNum);
3401 Value *
V = InstrFromDFSNum(InstrNum);
3402 const BasicBlock *CurrBlock = getBlockForValue(V);
3405 if (CurrBlock != LastBlock) {
3406 LastBlock = CurrBlock;
3407 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3408 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3411 if (!BlockReachable) {
3412 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3415 <<
" because it is unreachable\n");
3420 updateProcessedCount(CurrBlock);
3424 TouchedInstructions.
reset(InstrNum);
3428 valueNumberMemoryPhi(MP);
3430 valueNumberInstruction(
I);
3434 updateProcessedCount(V);
3437 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3441bool NewGVN::runGVN() {
3445 NumFuncArgs =
F.arg_size();
3447 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3451 unsigned ICount = 1;
3462 ReversePostOrderTraversal<Function *> RPOT(&
F);
3463 unsigned Counter = 0;
3464 for (
auto &
B : RPOT) {
3466 assert(Node &&
"RPO and Dominator tree should have same reachability");
3467 RPOOrdering[
Node] = ++Counter;
3472 for (
auto &
B : RPOT) {
3477 while (!
Node->isLeaf()) {
3482 return RPOOrdering[
A] < RPOOrdering[
B];
3485 Node->addChild(Child);
3491 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3492 BlockInstRange.
insert({
B, BlockRange});
3493 ICount += BlockRange.second - BlockRange.first;
3495 initializeCongruenceClasses(
F);
3497 TouchedInstructions.
resize(ICount);
3501 ExpressionToClass.reserve(ICount);
3504 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3505 TouchedInstructions.
set(InstRange.first, InstRange.second);
3507 <<
" marked reachable\n");
3508 ReachableBlocks.
insert(&
F.getEntryBlock());
3512 iterateTouchedInstructions();
3513 verifyMemoryCongruency();
3514 verifyIterationSettled(
F);
3515 verifyStoreExpressions();
3517 Changed |= eliminateInstructions(
F);
3520 for (Instruction *ToErase : InstructionsToErase) {
3521 if (!ToErase->use_empty())
3524 assert(ToErase->getParent() &&
3525 "BB containing ToErase deleted unexpectedly!");
3526 ToErase->eraseFromParent();
3528 Changed |= !InstructionsToErase.empty();
3531 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3532 return !ReachableBlocks.
count(&BB);
3537 <<
" is unreachable\n");
3538 deleteInstructionsInBlock(&BB);
3607void NewGVN::convertClassToDFSOrdered(
3616 assert(BB &&
"Should have figured out a basic block for value");
3625 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3627 VDDef.Def.setPointer(Leader);
3629 VDDef.Def.setPointer(
SI->getValueOperand());
3630 VDDef.Def.setInt(
true);
3633 VDDef.Def.setPointer(
D);
3636 "The dense set member should always be an instruction");
3641 if (
auto *PN = RealToTemp.
lookup(Def)) {
3645 VDDef.Def.setInt(
false);
3646 VDDef.Def.setPointer(PN);
3652 unsigned int UseCount = 0;
3654 for (
auto &U :
Def->uses()) {
3657 if (InstructionsToErase.count(
I))
3663 IBlock =
P->getIncomingBlock(U);
3668 IBlock = getBlockForValue(
I);
3674 if (!ReachableBlocks.
contains(IBlock))
3690 ProbablyDead.
insert(Def);
3692 UseCounts[
Def] = UseCount;
3698void NewGVN::convertClassToLoadsAndStores(
3699 const CongruenceClass &
Dense,
3700 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3710 VD.Def.setPointer(
D);
3724 I->replaceAllUsesWith(Repl);
3727void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3729 ++NumGVNBlocksDeleted;
3733 auto StartPoint = BB->
rbegin();
3746 ++NumGVNInstrDeleted;
3756void NewGVN::markInstructionForDeletion(Instruction *
I) {
3758 InstructionsToErase.insert(
I);
3761void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3766 markInstructionForDeletion(
I);
3773class ValueDFSStack {
3775 Value *
back()
const {
return ValueStack.back(); }
3776 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3778 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3779 ValueStack.emplace_back(V);
3780 DFSStack.emplace_back(DFSIn, DFSOut);
3783 bool empty()
const {
return DFSStack.empty(); }
3785 bool isInScope(
int DFSIn,
int DFSOut)
const {
3788 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3791 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3794 assert(ValueStack.size() == DFSStack.size() &&
3795 "Mismatch between ValueStack and DFSStack");
3797 !DFSStack.empty() &&
3798 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3799 DFSStack.pop_back();
3800 ValueStack.pop_back();
3805 SmallVector<Value *, 8> ValueStack;
3812CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3814 return ValueToClass.lookup(VE->getVariableValue());
3817 return ExpressionToClass.lookup(
E);
3823 const Instruction *OrigInst,
3824 const BasicBlock *BB)
const {
3827 return CE->getConstantValue();
3829 auto *
V = VE->getVariableValue();
3831 return VE->getVariableValue();
3834 auto *CC = getClassForExpression(
E);
3838 return CC->getLeader();
3840 for (
auto *Member : *CC) {
3842 if (MemberInst == OrigInst)
3847 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3853bool NewGVN::eliminateInstructions(Function &
F) {
3877 bool AnythingReplaced =
false;
3885 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3886 for (
auto &Operand :
PHI->incoming_values())
3887 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3891 <<
" with poison due to it being unreachable\n");
3904 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3905 for (
auto &KV : ReachableEdges)
3906 ReachablePredCount[KV.getEnd()]++;
3907 for (
auto &BBPair : RevisitOnReachabilityChange) {
3908 for (
auto InstNum : BBPair.second) {
3909 auto *Inst = InstrFromDFSNum(InstNum);
3914 auto *BB = BBPair.first;
3915 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3916 ReplaceUnreachablePHIArgs(
PHI, BB);
3921 DenseMap<const Value *, unsigned int> UseCounts;
3922 for (
auto *CC :
reverse(CongruenceClasses)) {
3923 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3928 SmallPtrSet<Instruction *, 8> ProbablyDead;
3929 if (CC->isDead() || CC->empty())
3932 if (CC == TOPClass) {
3933 for (
auto *M : *CC) {
3934 auto *VTE = ValueToExpression.
lookup(M);
3939 "Everything in TOP should be unreachable or dead at this "
3945 assert(CC->getLeader() &&
"We should have had a leader");
3951 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3953 CongruenceClass::MemberSet MembersLeft;
3954 for (
auto *M : *CC) {
3958 Member->getType()->isVoidTy()) {
3959 MembersLeft.
insert(Member);
3963 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3964 << *Member <<
"\n");
3966 assert(Leader !=
I &&
"About to accidentally remove our leader");
3967 replaceInstruction(
I, Leader);
3968 AnythingReplaced =
true;
3970 CC->swap(MembersLeft);
3973 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3978 ValueDFSStack EliminationStack;
3982 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3986 for (
auto &VD : DFSOrderedSet) {
3987 int MemberDFSIn = VD.
DFSIn;
3988 int MemberDFSOut = VD.
DFSOut;
3990 bool FromStore = VD.Def.getInt();
3993 if (Def &&
Def->getType()->isVoidTy())
3996 if (DefInst && AllTempInstructions.
count(DefInst)) {
4002 AllTempInstructions.
erase(PN);
4003 auto *DefBlock = getBlockForValue(Def);
4007 PN->insertBefore(DefBlock->begin());
4009 NumGVNPHIOfOpsEliminations++;
4012 if (EliminationStack.empty()) {
4016 << EliminationStack.dfs_back().first <<
","
4017 << EliminationStack.dfs_back().second <<
")\n");
4020 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4021 << MemberDFSOut <<
")\n");
4035 bool ShouldPush =
Def && EliminationStack.empty();
4037 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4039 if (OutOfScope || ShouldPush) {
4041 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4042 bool ShouldPush =
Def && EliminationStack.empty();
4044 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4064 if (!EliminationStack.empty() && DefI && !FromStore) {
4065 Value *DominatingLeader = EliminationStack.back();
4066 if (DominatingLeader != Def) {
4074 for (
auto *DVR : DVRUsers)
4075 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4077 markInstructionForDeletion(DefI);
4086 "Current def should have been an instruction");
4088 "Current user should have been an instruction");
4095 if (InstructionsToErase.count(InstUse)) {
4096 auto &UseCount = UseCounts[
U->get()];
4097 if (--UseCount == 0) {
4104 if (EliminationStack.empty())
4107 Value *DominatingLeader = EliminationStack.back();
4111 if (BC->getType() == BC->getOperand(0)->getType() &&
4112 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4114 DominatingLeader = BC->getOperand(0);
4119 if (
U->get() == DominatingLeader)
4126 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4127 if (!PI || DominatingLeader != PI->OriginalOp)
4131 <<
"Found replacement " << *DominatingLeader <<
" for "
4132 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4133 U->set(DominatingLeader);
4136 auto &LeaderUseCount = UseCounts[DominatingLeader];
4143 auto It = UseCounts.
find(SSACopy);
4144 if (It != UseCounts.
end()) {
4145 unsigned &IIUseCount = It->second;
4146 if (--IIUseCount == 0)
4147 ProbablyDead.
insert(SSACopy);
4151 AnythingReplaced =
true;
4158 for (
auto *
I : ProbablyDead)
4160 markInstructionForDeletion(
I);
4163 CongruenceClass::MemberSet MembersLeft;
4164 for (
auto *Member : *CC)
4167 MembersLeft.
insert(Member);
4168 CC->swap(MembersLeft);
4171 if (CC->getStoreCount() > 0) {
4172 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4174 ValueDFSStack EliminationStack;
4175 for (
auto &VD : PossibleDeadStores) {
4176 int MemberDFSIn = VD.
DFSIn;
4177 int MemberDFSOut = VD.
DFSOut;
4179 if (EliminationStack.empty() ||
4180 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4182 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4183 if (EliminationStack.empty()) {
4184 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4191 assert(!EliminationStack.empty());
4197 <<
" that is dominated by " << *Leader <<
"\n");
4198 markInstructionForDeletion(Member);
4204 return AnythingReplaced;
4212unsigned int NewGVN::getRank(
const Value *V)
const {
4227 return 4 +
A->getArgNo();
4231 unsigned Result = InstrToDFSNum(V);
4233 return 5 + NumFuncArgs +
Result;
4240bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4244 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4247bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4248 const BitCastInst *
I)
const {
4249 if (shouldSwapOperands(
A,
B)) {
4250 PredicateSwapChoice[
I] =
B;
4255 if (LookupResult != PredicateSwapChoice.
end()) {
4257 if (SeenPredicate) {
4259 if (SeenPredicate ==
B)
4278 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 const Expression * getEmptyKey()
static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
SimplifyQuery getWithInstruction(const Instruction *I) const