126#define DEBUG_TYPE "newgvn"
128STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
129STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
130STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
131STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
133 "Maximum Number of iterations it took to converge GVN");
134STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
135STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
137 "Number of avoided sorted leader changes");
138STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
139STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
141 "Number of things eliminated using PHI of ops");
143 "Controls which instructions are value numbered");
145 "Controls which instructions we create phi of ops for");
171 TarjanSCC() : Components(1) {}
173 void Start(
const Instruction *Start) {
174 if (Root.lookup(Start) == 0)
178 const SmallPtrSetImpl<const Value *> &getComponentFor(
const Value *V)
const {
179 unsigned ComponentID = ValueToComponent.lookup(V);
182 "Asking for a component for a value we never processed");
183 return Components[ComponentID];
187 void FindSCC(
const Instruction *
I) {
190 unsigned int OurDFS = DFSNum;
191 for (
const auto &
Op :
I->operands()) {
193 if (Root.lookup(
Op) == 0)
195 if (!InComponent.count(
Op))
196 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
203 if (Root.lookup(
I) == OurDFS) {
204 unsigned ComponentID = Components.size();
205 Components.resize(Components.size() + 1);
209 InComponent.insert(
I);
210 ValueToComponent[
I] = ComponentID;
212 while (!Stack.empty() && Root.lookup(Stack.back()) >= OurDFS) {
213 auto *
Member = Stack.back();
216 InComponent.insert(Member);
217 ValueToComponent[
Member] = ComponentID;
226 unsigned int DFSNum = 1;
227 SmallPtrSet<const Value *, 8> InComponent;
228 DenseMap<const Value *, unsigned int> Root;
229 SmallVector<const Value *, 8> Stack;
235 DenseMap<const Value *, unsigned> ValueToComponent;
276class CongruenceClass {
278 using MemberType =
Value;
279 using MemberSet = SmallPtrSet<MemberType *, 4>;
280 using MemoryMemberType = MemoryPhi;
281 using MemoryMemberSet = SmallPtrSet<const MemoryMemberType *, 2>;
283 explicit CongruenceClass(
unsigned ID) : ID(ID) {}
284 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
286 : ID(ID), RepLeader(Leader), DefiningExpr(
E) {}
288 unsigned getID()
const {
return ID; }
295 return empty() && memory_empty();
299 Value *getLeader()
const {
return RepLeader.first; }
300 void setLeader(std::pair<Value *, unsigned int> Leader) {
301 RepLeader = std::move(Leader);
303 const std::pair<Value *, unsigned int> &getNextLeader()
const {
306 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
307 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
308 if (LeaderPair.second < RepLeader.second) {
309 NextLeader = RepLeader;
310 RepLeader = std::move(LeaderPair);
312 }
else if (LeaderPair.second < NextLeader.second) {
313 NextLeader = std::move(LeaderPair);
319 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
320 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
321 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
324 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
327 bool empty()
const {
return Members.empty(); }
328 unsigned size()
const {
return Members.size(); }
331 void insert(MemberType *M) { Members.insert(M); }
332 void erase(MemberType *M) { Members.erase(M); }
336 bool memory_empty()
const {
return MemoryMembers.empty(); }
337 unsigned memory_size()
const {
return MemoryMembers.size(); }
339 return MemoryMembers.begin();
342 return MemoryMembers.end();
345 return make_range(memory_begin(), memory_end());
348 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
349 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
352 unsigned getStoreCount()
const {
return StoreCount; }
353 void incStoreCount() { ++StoreCount; }
354 void decStoreCount() {
355 assert(StoreCount != 0 &&
"Store count went negative");
360 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
364 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
370 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
372 Other->RepMemoryAccess))
374 if (DefiningExpr !=
Other->DefiningExpr)
375 if (!DefiningExpr || !
Other->DefiningExpr ||
376 *DefiningExpr != *
Other->DefiningExpr)
379 if (Members.size() !=
Other->Members.size())
390 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
395 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
398 Value *RepStoredValue =
nullptr;
402 const MemoryAccess *RepMemoryAccess =
nullptr;
405 const Expression *DefiningExpr =
nullptr;
413 MemoryMemberSet MemoryMembers;
420struct ExactEqualsExpression {
423 explicit ExactEqualsExpression(
const Expression &E) : E(E) {}
425 hash_code getComputedHash()
const {
return E.getComputedHash(); }
428 return E.exactlyEquals(
Other);
435 return E->getComputedHash();
439 return E.getComputedHash();
453 if (LHS->getComputedHash() != RHS->getComputedHash())
462 const ScalarOptions &Opts;
476 mutable TarjanSCC SCCFinder;
478 std::unique_ptr<PredicateInfo> PredInfo;
482 unsigned int NumFuncArgs = 0;
493 CongruenceClass *TOPClass =
nullptr;
494 std::vector<CongruenceClass *> CongruenceClasses;
495 unsigned NextCongruenceNum = 0;
530 ExpressionToPhiOfOps;
579 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
580 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
582 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
583 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
586 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
587 ExpressionClassMap ExpressionToClass;
594 DeadExpression *SingletonDeadExpression =
nullptr;
597 SmallPtrSet<Value *, 8> LeaderChanges;
600 using BlockEdge = BasicBlockEdge;
601 DenseSet<BlockEdge> ReachableEdges;
602 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
613 BitVector TouchedInstructions;
615 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
616 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
620 DenseMap<const Value *, unsigned> ProcessedCount;
627 DenseMap<const Value *, unsigned> InstrDFS;
633 SmallPtrSet<Instruction *, 8> InstructionsToErase;
636 NewGVN(
Function &
F, DominatorTree *DT, AssumptionCache *AC,
638 const DataLayout &
DL)
639 : Opts(ScalarOptions::
Global),
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA),
643 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
644 SQ(
DL, TLI, DT, AC, nullptr,
false,
652 const Expression *Expr;
654 const PredicateBase *PredDep;
656 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
657 const PredicateBase *PredDep =
nullptr)
658 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
659 ExprResult(
const ExprResult &) =
delete;
660 ExprResult(ExprResult &&
Other)
662 Other.Expr =
nullptr;
663 Other.ExtraDep =
nullptr;
664 Other.PredDep =
nullptr;
666 ExprResult &operator=(
const ExprResult &
Other) =
delete;
667 ExprResult &operator=(ExprResult &&
Other) =
delete;
669 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
671 operator bool()
const {
return Expr; }
673 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
674 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
675 return {Expr, ExtraDep,
nullptr};
677 static ExprResult some(
const Expression *Expr,
678 const PredicateBase *PredDep) {
679 return {Expr,
nullptr, PredDep};
681 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
682 const PredicateBase *PredDep) {
683 return {Expr, ExtraDep, PredDep};
688 ExprResult createExpression(Instruction *)
const;
689 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
690 Instruction *)
const;
694 using ValPair = std::pair<Value *, BasicBlock *>;
697 BasicBlock *,
bool &HasBackEdge,
698 bool &OriginalOpsConstant)
const;
699 const DeadExpression *createDeadExpression()
const;
700 const VariableExpression *createVariableExpression(
Value *)
const;
701 const ConstantExpression *createConstantExpression(Constant *)
const;
702 const Expression *createVariableOrConstant(
Value *V)
const;
703 const UnknownExpression *createUnknownExpression(Instruction *)
const;
704 const StoreExpression *createStoreExpression(StoreInst *,
705 const MemoryAccess *)
const;
706 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
707 const MemoryAccess *)
const;
708 const CallExpression *createCallExpression(CallInst *,
709 const MemoryAccess *)
const;
710 const AggregateValueExpression *
711 createAggregateValueExpression(Instruction *)
const;
712 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
715 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
718 unsigned LeaderDFS = 0;
726 LeaderDFS = InstrToDFSNum(
I);
728 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
729 CongruenceClasses.emplace_back(result);
733 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
734 auto *CC = createCongruenceClass(
nullptr,
nullptr);
735 CC->setMemoryLeader(MA);
739 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
740 auto *CC = getMemoryClass(MA);
741 if (CC->getMemoryLeader() != MA)
742 CC = createMemoryClass(MA);
746 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
747 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
748 CClass->insert(Member);
749 ValueToClass[
Member] = CClass;
753 void initializeCongruenceClasses(
Function &
F);
754 const Expression *makePossiblePHIOfOps(Instruction *,
755 SmallPtrSetImpl<Value *> &);
756 Value *findLeaderForInst(Instruction *ValueOp,
757 SmallPtrSetImpl<Value *> &Visited,
758 MemoryAccess *MemAccess, Instruction *OrigInst,
760 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
761 SmallPtrSetImpl<const Value *> &);
762 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
763 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
766 void valueNumberMemoryPhi(MemoryPhi *);
767 void valueNumberInstruction(Instruction *);
770 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
771 ExprResult performSymbolicEvaluation(Instruction *,
772 SmallPtrSetImpl<Value *> &)
const;
773 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
775 MemoryAccess *)
const;
776 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
777 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
778 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
782 BasicBlock *PHIBlock)
const;
783 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
784 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
785 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
788 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
790 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
791 void performCongruenceFinding(Instruction *,
const Expression *);
792 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
793 CongruenceClass *, CongruenceClass *);
794 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
795 CongruenceClass *, CongruenceClass *);
796 Value *getNextValueLeader(CongruenceClass *)
const;
797 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
798 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
799 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
800 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
801 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
804 unsigned int getRank(
const Value *)
const;
805 bool shouldSwapOperands(
const Value *,
const Value *)
const;
806 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
807 const BitCastInst *
I)
const;
810 void updateReachableEdge(BasicBlock *, BasicBlock *);
811 void processOutgoingEdges(Instruction *, BasicBlock *);
812 Value *findConditionEquivalence(
Value *)
const;
816 void convertClassToDFSOrdered(
const CongruenceClass &,
817 SmallVectorImpl<ValueDFS> &,
818 DenseMap<const Value *, unsigned int> &,
819 SmallPtrSetImpl<Instruction *> &)
const;
820 void convertClassToLoadsAndStores(
const CongruenceClass &,
821 SmallVectorImpl<ValueDFS> &)
const;
823 bool eliminateInstructions(
Function &);
824 void replaceInstruction(Instruction *,
Value *);
825 void markInstructionForDeletion(Instruction *);
826 void deleteInstructionsInBlock(BasicBlock *);
827 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
828 const BasicBlock *)
const;
831 template <
typename Map,
typename KeyType>
832 void touchAndErase(Map &,
const KeyType &);
833 void markUsersTouched(
Value *);
834 void markMemoryUsersTouched(
const MemoryAccess *);
835 void markMemoryDefTouched(
const MemoryAccess *);
836 void markPredicateUsersTouched(Instruction *);
837 void markValueLeaderChangeTouched(CongruenceClass *CC);
838 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
839 void markPhiOfOpsChanged(
const Expression *
E);
840 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
841 void addAdditionalUsers(
Value *To,
Value *User)
const;
842 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
845 void iterateTouchedInstructions();
848 void cleanupTables();
849 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
850 void updateProcessedCount(
const Value *V);
851 void verifyMemoryCongruency()
const;
852 void verifyIterationSettled(
Function &
F);
853 void verifyStoreExpressions()
const;
854 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
855 const MemoryAccess *,
const MemoryAccess *)
const;
857 void deleteExpression(
const Expression *
E)
const;
858 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
859 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
860 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
862 unsigned InstrToDFSNum(
const Value *V)
const {
864 return InstrDFS.
lookup(V);
867 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
868 return MemoryToDFSNum(MA);
871 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
876 unsigned MemoryToDFSNum(
const Value *MA)
const {
878 "This should not be used with instructions");
884 bool isCycleFree(
const Instruction *)
const;
885 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
889 DebugCounter::CounterState StartingVNCounter;
898 return LHS.MemoryExpression::equals(
RHS);
920 return Call->getAttributes()
921 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
941MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
947MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
954 auto *Parent =
I->getParent();
957 Parent = TempToBlock.
lookup(V);
958 assert(Parent &&
"Every fake instruction should have a block");
963 assert(MP &&
"Should have been an instruction or a MemoryPhi");
964 return MP->getBlock();
970void NewGVN::deleteExpression(
const Expression *
E)
const {
974 ExpressionAllocator.Deallocate(
E);
980 if (BC->getType() == BC->getOperand(0)->getType())
981 return BC->getOperand(0);
1000 return BlockInstRange.
lookup(
P1.second).first <
1001 BlockInstRange.
lookup(
P2.second).first;
1018 const Instruction *
I,
1019 BasicBlock *PHIBlock,
1021 bool &OriginalOpsConstant)
const {
1026 E->setType(PHIOperands.
begin()->first->getType());
1027 E->setOpcode(Instruction::PHI);
1031 auto *BB =
P.second;
1035 if (!ReachableEdges.
count({BB, PHIBlock}))
1038 if (ValueToClass.
lookup(
P.first) == TOPClass)
1040 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1041 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1042 return lookupOperandLeader(
P.first) !=
I;
1045 return lookupOperandLeader(
P.first);
1053 bool AllConstant =
true;
1055 E->setType(
GEP->getSourceElementType());
1057 E->setType(
I->getType());
1058 E->setOpcode(
I->getOpcode());
1059 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1064 auto Operand = lookupOperandLeader(O);
1072const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1074 Instruction *
I)
const {
1081 E->setOpcode(Opcode);
1082 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1088 if (shouldSwapOperands(Arg1, Arg2))
1091 E->op_push_back(lookupOperandLeader(Arg1));
1092 E->op_push_back(lookupOperandLeader(Arg2));
1095 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1096 addAdditionalUsers(Simplified,
I);
1105NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1108 return ExprResult::none();
1113 <<
" constant " << *
C <<
"\n");
1114 NumGVNOpsSimplified++;
1116 "We should always have had a basic expression here");
1117 deleteExpression(
E);
1118 return ExprResult::some(createConstantExpression(
C));
1122 <<
" variable " << *V <<
"\n");
1123 deleteExpression(
E);
1124 return ExprResult::some(createVariableExpression(V));
1127 CongruenceClass *CC = ValueToClass.
lookup(V);
1129 if (CC->getLeader() && CC->getLeader() !=
I) {
1130 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1132 if (CC->getDefiningExpr()) {
1135 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1136 NumGVNOpsSimplified++;
1137 deleteExpression(
E);
1138 return ExprResult::some(CC->getDefiningExpr(), V);
1142 return ExprResult::none();
1148NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1154 bool AllConstant = setBasicExpressionInfo(
I,
E);
1156 if (
I->isCommutative()) {
1161 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1162 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1163 E->swapOperands(0, 1);
1170 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1171 E->swapOperands(0, 1);
1174 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1176 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1177 "Wrong types on cmp instruction");
1178 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1179 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1182 if (
auto Simplified = checkExprResults(
E,
I, V))
1186 E->getOperand(1) ==
E->getOperand(2)) {
1187 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1188 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1190 E->getOperand(2), FastMathFlags(), Q);
1191 if (
auto Simplified = checkExprResults(
E,
I, V))
1194 }
else if (
I->isBinaryOp()) {
1197 if (
auto Simplified = checkExprResults(
E,
I, V))
1202 if (
auto Simplified = checkExprResults(
E,
I, V))
1206 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1207 GEPI->getNoWrapFlags(), Q);
1208 if (
auto Simplified = checkExprResults(
E,
I, V))
1210 }
else if (AllConstant) {
1219 for (
Value *Arg :
E->operands())
1223 if (
auto Simplified = checkExprResults(
E,
I, V))
1226 return ExprResult::some(
E);
1230NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1232 auto *
E =
new (ExpressionAllocator)
1234 setBasicExpressionInfo(
I,
E);
1235 E->allocateIntOperands(ExpressionAllocator);
1239 auto *
E =
new (ExpressionAllocator)
1241 setBasicExpressionInfo(EI,
E);
1242 E->allocateIntOperands(ExpressionAllocator);
1252 return SingletonDeadExpression;
1263 return createConstantExpression(
C);
1264 return createVariableExpression(V);
1280NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1284 setBasicExpressionInfo(CI,
E);
1290 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1291 E->swapOperands(0, 1);
1297bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1298 const Instruction *U)
const {
1299 auto *CC = ValueToClass.
lookup(Inst);
1322 if (CC->getNextLeader().first &&
1326 return Member != CC->getLeader() &&
1333Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1334 CongruenceClass *CC = ValueToClass.
lookup(V);
1341 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1347const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1348 auto *CC = getMemoryClass(MA);
1349 assert(CC->getMemoryLeader() &&
1350 "Every MemoryAccess should be mapped to a congruence class with a "
1351 "representative memory access");
1352 return CC->getMemoryLeader();
1358bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1359 return getMemoryClass(MA) == TOPClass;
1364 const MemoryAccess *MA)
const {
1366 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1368 E->setType(LoadType);
1372 E->op_push_back(PointerOp);
1381NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1382 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1383 auto *
E =
new (ExpressionAllocator)
1386 E->setType(
SI->getValueOperand()->getType());
1390 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1398const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1402 auto *StoreAccess = getMemoryAccess(SI);
1404 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1405 if (Opts.enable_store_refinement)
1408 StoreRHS = lookupMemoryLeader(StoreRHS);
1409 if (StoreRHS != StoreAccess->getDefiningAccess())
1410 addMemoryUsers(StoreRHS, StoreAccess);
1412 if (StoreRHS == StoreAccess)
1415 if (
SI->isSimple()) {
1419 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1420 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1426 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1434 LastStore->getOperand(0)) &&
1435 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1438 deleteExpression(LastStore);
1444 return createStoreExpression(SI, StoreAccess);
1450NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1451 LoadInst *LI, Instruction *DepInst,
1452 MemoryAccess *DefiningAccess)
const {
1458 if (LI->
isAtomic() > DepSI->isAtomic() ||
1459 LoadType == DepSI->getValueOperand()->getType())
1464 lookupOperandLeader(DepSI->getValueOperand()))) {
1467 <<
" to constant " << *Res <<
"\n");
1468 return createConstantExpression(Res);
1474 if (LI->
isAtomic() > DepLI->isAtomic())
1480 if (
auto *PossibleConstant =
1483 <<
" to constant " << *PossibleConstant <<
"\n");
1484 return createConstantExpression(PossibleConstant);
1490 if (
auto *PossibleConstant =
1493 <<
" to constant " << *PossibleConstant <<
"\n");
1494 return createConstantExpression(PossibleConstant);
1500 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1501 auto *LifetimePtr =
II->getOperand(0);
1502 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1511 (LoadPtr != lookupOperandLeader(DepInst) &&
1520 }
else if (
auto *InitVal =
1522 return createConstantExpression(InitVal);
1527const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1539 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1540 MemoryAccess *DefiningAccess =
1553 if (
const auto *CoercionResult =
1554 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1555 DefiningInst, DefiningAccess))
1556 return CoercionResult;
1560 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1564 if (
LE->getMemoryLeader() != DefiningAccess)
1565 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1570NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1571 auto *PI = PredInfo->getPredicateInfoFor(
I);
1573 return ExprResult::none();
1575 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1577 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1579 return ExprResult::none();
1582 Value *CmpOp0 =
I->getOperand(0);
1583 Value *CmpOp1 = Constraint->OtherOp;
1585 Value *FirstOp = lookupOperandLeader(CmpOp0);
1586 Value *SecondOp = lookupOperandLeader(CmpOp1);
1587 Value *AdditionallyUsedValue = CmpOp0;
1590 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1593 AdditionallyUsedValue = CmpOp1;
1597 return ExprResult::some(createVariableOrConstant(FirstOp),
1598 AdditionallyUsedValue, PI);
1603 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1604 AdditionallyUsedValue, PI);
1606 return ExprResult::none();
1610NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1621 return ExprResult::none();
1627 return ExprResult::none();
1630 return ExprResult::some(
1631 createCallExpression(CI, TOPClass->getMemoryLeader()));
1635 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1637 return ExprResult::some(
1638 createCallExpression(CI, TOPClass->getMemoryLeader()));
1640 return ExprResult::none();
1644CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1646 assert(Result &&
"Should have found memory class");
1652bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1653 CongruenceClass *NewClass) {
1655 "Every MemoryAccess should be getting mapped to a non-null class");
1659 <<
" with current MemoryAccess leader ");
1665 if (LookupResult != MemoryAccessToClass.
end()) {
1667 if (OldClass != NewClass) {
1670 OldClass->memory_erase(MP);
1671 NewClass->memory_insert(MP);
1673 if (OldClass->getMemoryLeader() == From) {
1674 if (OldClass->definesNoMemory()) {
1675 OldClass->setMemoryLeader(
nullptr);
1677 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1679 << OldClass->getID() <<
" to "
1680 << *OldClass->getMemoryLeader()
1681 <<
" due to removal of a memory member " << *From
1683 markMemoryLeaderChangeTouched(OldClass);
1700bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1706 auto ICS = InstCycleState.
lookup(
I);
1707 if (ICS == ICS_Unknown) {
1709 auto &
SCC = SCCFinder.getComponentFor(
I);
1711 if (
SCC.size() == 1)
1712 InstCycleState.
insert({
I, ICS_CycleFree});
1717 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1718 for (
const auto *Member : SCC)
1720 InstCycleState.
insert({MemberPhi, ICS});
1723 if (ICS == ICS_Cycle)
1732 BasicBlock *PHIBlock)
const {
1734 bool HasBackedge =
false;
1739 bool OriginalOpsConstant =
true;
1741 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1745 bool HasUndef =
false, HasPoison =
false;
1747 if (isa<PoisonValue>(Arg)) {
1758 if (Filtered.empty()) {
1763 dbgs() <<
"PHI Node " << *
I
1764 <<
" has no non-undef arguments, valuing it as undef\n");
1769 dbgs() <<
"PHI Node " << *
I
1770 <<
" has no non-poison arguments, valuing it as poison\n");
1774 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1775 deleteExpression(
E);
1776 return createDeadExpression();
1778 Value *AllSameValue = *(Filtered.begin());
1796 if (HasPoison || HasUndef) {
1802 if (HasBackedge && !OriginalOpsConstant &&
1808 if (!someEquivalentDominates(AllSameInst,
I))
1815 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1817 NumGVNPhisAllSame++;
1818 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1820 deleteExpression(
E);
1821 return createVariableOrConstant(AllSameValue);
1827NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1830 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1834 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1835 WO->getLHS(), WO->getRHS(),
I);
1838 return createAggregateValueExpression(
I);
1841NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1847 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1848 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1849 auto OurPredicate = CI->getPredicate();
1850 if (shouldSwapOperands(Op0, Op1)) {
1852 OurPredicate = CI->getSwappedPredicate();
1856 const PredicateBase *LastPredInfo =
nullptr;
1859 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1861 return ExprResult::some(
1866 if (CI->isTrueWhenEqual())
1867 return ExprResult::some(
1869 else if (CI->isFalseWhenEqual())
1870 return ExprResult::some(
1900 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1902 if (PI == LastPredInfo)
1907 if (!DT->
dominates(PBranch->To,
I->getParent()))
1917 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1918 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1919 auto BranchPredicate = BranchCond->getPredicate();
1920 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1922 BranchPredicate = BranchCond->getSwappedPredicate();
1924 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1925 if (PBranch->TrueEdge) {
1931 return ExprResult::some(createConstantExpression(
C), PI);
1936 if (BranchPredicate == OurPredicate) {
1938 return ExprResult::some(
1941 }
else if (BranchPredicate ==
1944 return ExprResult::some(
1953 return createExpression(
I);
1958NewGVN::performSymbolicEvaluation(Instruction *
I,
1959 SmallPtrSetImpl<Value *> &Visited)
const {
1965 switch (
I->getOpcode()) {
1966 case Instruction::ExtractValue:
1967 case Instruction::InsertValue:
1968 E = performSymbolicAggrValueEvaluation(
I);
1970 case Instruction::PHI: {
1973 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1974 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1977 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
1979 case Instruction::Call:
1980 return performSymbolicCallEvaluation(
I);
1982 case Instruction::Store:
1983 E = performSymbolicStoreEvaluation(
I);
1985 case Instruction::Load:
1986 E = performSymbolicLoadEvaluation(
I);
1988 case Instruction::BitCast:
1990 if (
I->getType() ==
I->getOperand(0)->getType())
1995 case Instruction::AddrSpaceCast:
1996 case Instruction::Freeze:
1997 return createExpression(
I);
1999 case Instruction::ICmp:
2000 case Instruction::FCmp:
2001 return performSymbolicCmpEvaluation(
I);
2003 case Instruction::FNeg:
2004 case Instruction::Add:
2005 case Instruction::FAdd:
2006 case Instruction::Sub:
2007 case Instruction::FSub:
2008 case Instruction::Mul:
2009 case Instruction::FMul:
2010 case Instruction::UDiv:
2011 case Instruction::SDiv:
2012 case Instruction::FDiv:
2013 case Instruction::URem:
2014 case Instruction::SRem:
2015 case Instruction::FRem:
2016 case Instruction::Shl:
2017 case Instruction::LShr:
2018 case Instruction::AShr:
2019 case Instruction::And:
2020 case Instruction::Or:
2021 case Instruction::Xor:
2022 case Instruction::Trunc:
2023 case Instruction::ZExt:
2024 case Instruction::SExt:
2025 case Instruction::FPToUI:
2026 case Instruction::FPToSI:
2027 case Instruction::UIToFP:
2028 case Instruction::SIToFP:
2029 case Instruction::FPTrunc:
2030 case Instruction::FPExt:
2031 case Instruction::PtrToInt:
2032 case Instruction::PtrToAddr:
2033 case Instruction::IntToPtr:
2034 case Instruction::Select:
2035 case Instruction::ExtractElement:
2036 case Instruction::InsertElement:
2037 case Instruction::GetElementPtr:
2038 return createExpression(
I);
2040 case Instruction::ShuffleVector:
2042 return ExprResult::none();
2044 return ExprResult::none();
2046 return ExprResult::some(
E);
2051template <
typename Map,
typename KeyType>
2052void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2054 if (Result !=
M.end()) {
2055 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2056 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2061void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2062 assert(User && To != User);
2064 AdditionalUsers[To].
insert(User);
2067void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2068 if (Res.ExtraDep && Res.ExtraDep != User)
2069 addAdditionalUsers(Res.ExtraDep, User);
2070 Res.ExtraDep =
nullptr;
2074 PredicateToUsers[PBranch->Condition].
insert(User);
2075 else if (
const auto *PAssume =
2077 PredicateToUsers[PAssume->Condition].
insert(User);
2079 Res.PredDep =
nullptr;
2082void NewGVN::markUsersTouched(
Value *V) {
2084 for (
auto *User :
V->users()) {
2086 TouchedInstructions.
set(InstrToDFSNum(User));
2088 touchAndErase(AdditionalUsers, V);
2091void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2092 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2093 MemoryToUsers[To].
insert(U);
2096void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2097 TouchedInstructions.
set(MemoryToDFSNum(MA));
2100void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2103 for (
const auto *U : MA->
users())
2104 TouchedInstructions.
set(MemoryToDFSNum(U));
2105 touchAndErase(MemoryToUsers, MA);
2109void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2110 touchAndErase(PredicateToUsers,
I);
2114void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2115 for (
const auto *M : CC->memory())
2116 markMemoryDefTouched(M);
2121void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2122 for (
auto *M : *CC) {
2124 TouchedInstructions.
set(InstrToDFSNum(
I));
2131template <
class T,
class Range>
2132T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2133 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2134 for (
const auto X : R) {
2135 auto DFSNum = InstrToDFSNum(
X);
2136 if (DFSNum < MinDFS.second)
2137 MinDFS = {
X, DFSNum};
2139 return MinDFS.first;
2145const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2149 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2150 if (CC->getStoreCount() > 0) {
2152 return getMemoryAccess(NL);
2158 assert(CC->getStoreCount() == 0);
2162 if (CC->memory_size() == 1)
2163 return *CC->memory_begin();
2164 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2170Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2175 if (CC->size() == 1 || CC == TOPClass) {
2176 return *(CC->begin());
2177 }
else if (CC->getNextLeader().first) {
2178 ++NumGVNAvoidedSortedLeaderChanges;
2179 return CC->getNextLeader().first;
2181 ++NumGVNSortedLeaderChanges;
2185 return getMinDFSOfRange<Value>(*CC);
2198void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2199 MemoryAccess *InstMA,
2200 CongruenceClass *OldClass,
2201 CongruenceClass *NewClass) {
2204 assert((!InstMA || !OldClass->getMemoryLeader() ||
2205 OldClass->getLeader() !=
I ||
2206 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2207 MemoryAccessToClass.
lookup(InstMA)) &&
2208 "Representative MemoryAccess mismatch");
2210 if (!NewClass->getMemoryLeader()) {
2212 assert(NewClass->size() == 1 ||
2214 NewClass->setMemoryLeader(InstMA);
2217 << NewClass->getID()
2218 <<
" due to new memory instruction becoming leader\n");
2219 markMemoryLeaderChangeTouched(NewClass);
2221 setMemoryClass(InstMA, NewClass);
2223 if (OldClass->getMemoryLeader() == InstMA) {
2224 if (!OldClass->definesNoMemory()) {
2225 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2227 << OldClass->getID() <<
" to "
2228 << *OldClass->getMemoryLeader()
2229 <<
" due to removal of old leader " << *InstMA <<
"\n");
2230 markMemoryLeaderChangeTouched(OldClass);
2232 OldClass->setMemoryLeader(
nullptr);
2238void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2239 CongruenceClass *OldClass,
2240 CongruenceClass *NewClass) {
2241 if (
I == OldClass->getNextLeader().first)
2242 OldClass->resetNextLeader();
2245 NewClass->insert(
I);
2249 if (NewClass->getLeader() !=
I &&
2250 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2251 markValueLeaderChangeTouched(NewClass);
2256 OldClass->decStoreCount();
2264 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2268 NewClass->setStoredValue(SE->getStoredValue());
2269 markValueLeaderChangeTouched(NewClass);
2272 << NewClass->getID() <<
" from "
2273 << *NewClass->getLeader() <<
" to " << *SI
2274 <<
" because store joined class\n");
2277 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2281 NewClass->incStoreCount();
2289 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2290 ValueToClass[
I] = NewClass;
2292 if (OldClass->empty() && OldClass != TOPClass) {
2293 if (OldClass->getDefiningExpr()) {
2294 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2295 <<
" from table\n");
2298 auto Iter = ExpressionToClass.find_as(
2299 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2300 if (Iter != ExpressionToClass.end())
2301 ExpressionToClass.erase(Iter);
2302#ifdef EXPENSIVE_CHECKS
2304 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2305 "We erased the expression we just inserted, which should not happen");
2308 }
else if (OldClass->getLeader() ==
I) {
2313 << OldClass->getID() <<
"\n");
2314 ++NumGVNLeaderChanges;
2319 if (OldClass->getStoreCount() == 0) {
2320 if (OldClass->getStoredValue())
2321 OldClass->setStoredValue(
nullptr);
2323 OldClass->setLeader({getNextValueLeader(OldClass),
2324 InstrToDFSNum(getNextValueLeader(OldClass))});
2325 OldClass->resetNextLeader();
2326 markValueLeaderChangeTouched(OldClass);
2332void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2333 touchAndErase(ExpressionToPhiOfOps,
E);
2337void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2341 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2342 assert(IClass &&
"Should have found a IClass");
2344 assert(!IClass->isDead() &&
"Found a dead class");
2346 CongruenceClass *EClass =
nullptr;
2348 EClass = ValueToClass.
lookup(VE->getVariableValue());
2353 auto lookupResult = ExpressionToClass.try_emplace(
E);
2356 if (lookupResult.second) {
2357 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2358 auto place = lookupResult.first;
2359 place->second = NewClass;
2363 NewClass->setLeader({
CE->getConstantValue(), 0});
2365 StoreInst *
SI = SE->getStoreInst();
2366 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2367 NewClass->setStoredValue(SE->getStoredValue());
2371 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2374 "VariableExpression should have been handled already");
2378 <<
" using expression " << *
E <<
" at "
2379 << NewClass->getID() <<
" and leader "
2380 << *(NewClass->getLeader()));
2381 if (NewClass->getStoredValue())
2383 << *(NewClass->getStoredValue()));
2386 EClass = lookupResult.first->second;
2389 (EClass->getStoredValue() &&
2391 "Any class with a constant expression should have a "
2394 assert(EClass &&
"Somehow don't have an eclass");
2396 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2399 bool ClassChanged = IClass != EClass;
2400 bool LeaderChanged = LeaderChanges.
erase(
I);
2401 if (ClassChanged || LeaderChanged) {
2402 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2405 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2406 markPhiOfOpsChanged(
E);
2409 markUsersTouched(
I);
2410 if (MemoryAccess *MA = getMemoryAccess(
I))
2411 markMemoryUsersTouched(MA);
2413 markPredicateUsersTouched(CI);
2420 auto *OldE = ValueToExpression.
lookup(
I);
2426 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2427 if (Iter != ExpressionToClass.end())
2428 ExpressionToClass.erase(Iter);
2431 ValueToExpression[
I] =
E;
2436void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2438 if (ReachableEdges.
insert({From, To}).second) {
2440 if (ReachableBlocks.
insert(To).second) {
2442 <<
" marked reachable\n");
2443 const auto &InstRange = BlockInstRange.
lookup(To);
2444 TouchedInstructions.
set(InstRange.first, InstRange.second);
2447 <<
" was reachable, but new edge {"
2449 <<
"} to it found\n");
2455 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2456 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2461 for (
auto InstNum : RevisitOnReachabilityChange[To])
2462 TouchedInstructions.
set(InstNum);
2475void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2480 Value *CondEvaluated = findConditionEquivalence(
Cond);
2481 if (!CondEvaluated) {
2483 SmallPtrSet<Value *, 4> Visited;
2484 auto Res = performSymbolicEvaluation(
I, Visited);
2486 CondEvaluated =
CE->getConstantValue();
2487 addAdditionalUsers(Res,
I);
2491 Res.ExtraDep =
nullptr;
2494 CondEvaluated =
Cond;
2501 <<
" evaluated to true\n");
2502 updateReachableEdge(
B, TrueSucc);
2503 }
else if (CI->
isZero()) {
2505 <<
" evaluated to false\n");
2506 updateReachableEdge(
B, FalseSucc);
2509 updateReachableEdge(
B, TrueSucc);
2510 updateReachableEdge(
B, FalseSucc);
2516 Value *SwitchCond =
SI->getCondition();
2517 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2522 auto Case = *
SI->findCaseValue(CondVal);
2523 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2527 updateReachableEdge(
B,
SI->getDefaultDest());
2531 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2532 updateReachableEdge(
B, TargetBlock);
2534 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2535 updateReachableEdge(
B, TargetBlock);
2541 updateReachableEdge(
B, TargetBlock);
2546 auto *MA = getMemoryAccess(TI);
2548 auto *CC = ensureLeaderOfMemoryClass(MA);
2549 if (setMemoryClass(MA, CC))
2550 markMemoryUsersTouched(MA);
2556void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2557 InstrDFS.
erase(PHITemp);
2560 TempToBlock.
erase(PHITemp);
2569void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2570 Instruction *ExistingValue) {
2571 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2573 TempToBlock[
Op] = BB;
2574 RealToTemp[ExistingValue] =
Op;
2577 for (
auto *U : ExistingValue->
users())
2583 if (!Opts.enable_phi_of_ops)
2596bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2597 SmallPtrSetImpl<const Value *> &Visited) {
2598 SmallVector<Value *, 4> Worklist;
2600 while (!Worklist.
empty()) {
2605 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2606 if (OISIt != OpSafeForPHIOfOps.
end())
2607 return OISIt->second;
2612 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2617 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2628 if (OrigI->mayReadFromMemory())
2632 for (
auto *
Op : OrigI->operand_values()) {
2636 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2637 if (OISIt != OpSafeForPHIOfOps.
end()) {
2638 if (!OISIt->second) {
2639 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2649 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2658Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2659 SmallPtrSetImpl<Value *> &Visited,
2660 MemoryAccess *MemAccess, Instruction *OrigInst,
2661 BasicBlock *PredBB) {
2662 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2664 AllTempInstructions.
insert(TransInst);
2668 TempToBlock.
insert({TransInst, PredBB});
2669 InstrDFS.
insert({TransInst, IDFSNum});
2671 auto Res = performSymbolicEvaluation(TransInst, Visited);
2673 addAdditionalUsers(Res, OrigInst);
2674 InstrDFS.
erase(TransInst);
2675 AllTempInstructions.
erase(TransInst);
2676 TempToBlock.
erase(TransInst);
2678 TempToMemory.
erase(TransInst);
2681 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2683 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2684 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2689 FoundVal =
SI->getValueOperand();
2696NewGVN::makePossiblePHIOfOps(Instruction *
I,
2697 SmallPtrSetImpl<Value *> &Visited) {
2701 if (!Visited.
insert(
I).second)
2707 if (!isCycleFree(
I))
2713 auto *MemAccess = getMemoryAccess(
I);
2717 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2722 SmallPtrSet<const Value *, 10> VisitedOps;
2723 SmallVector<Value *, 4>
Ops(
I->operand_values());
2725 PHINode *OpPHI =
nullptr;
2728 for (
auto *
Op :
Ops) {
2730 auto *ValuePHI = RealToTemp.
lookup(
Op);
2737 if (!SamePHIBlock) {
2738 SamePHIBlock = getBlockForValue(OpPHI);
2739 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2742 <<
"PHIs for operands are not all in the same block, aborting\n");
2756 SmallPtrSet<Value *, 4> Deps;
2757 auto *PHIBlock = getBlockForValue(OpPHI);
2758 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2759 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2761 Value *FoundVal =
nullptr;
2762 SmallPtrSet<Value *, 4> CurrentDeps;
2765 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2773 TempToMemory.
insert({ValueOp, MemAccess});
2774 bool SafeForPHIOfOps =
true;
2777 auto *OrigOp = &*
Op;
2781 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2782 if (
Op != OrigOp &&
Op !=
I)
2784 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2785 if (getBlockForValue(ValuePHI) == PHIBlock)
2786 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2791 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2798 FoundVal = !SafeForPHIOfOps ? nullptr
2799 : findLeaderForInst(ValueOp, Visited,
2800 MemAccess,
I, PredBB);
2805 if (SafeForPHIOfOps)
2806 for (
auto *Dep : CurrentDeps)
2807 addAdditionalUsers(Dep,
I);
2813 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2815 <<
" because the block is unreachable\n");
2817 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2821 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2824 for (
auto *Dep : Deps)
2825 addAdditionalUsers(Dep,
I);
2827 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2831 <<
"Not creating real PHI of ops because it simplified to existing "
2832 "value or constant\n");
2838 for (
auto &O : PHIOps)
2839 addAdditionalUsers(
O.first,
I);
2843 auto *ValuePHI = RealToTemp.
lookup(
I);
2844 bool NewPHI =
false;
2848 addPhiOfOps(ValuePHI, PHIBlock,
I);
2850 NumGVNPHIOfOpsCreated++;
2853 for (
auto PHIOp : PHIOps)
2854 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2856 TempToBlock[ValuePHI] = PHIBlock;
2858 for (
auto PHIOp : PHIOps) {
2859 ValuePHI->setIncomingValue(i, PHIOp.first);
2860 ValuePHI->setIncomingBlock(i, PHIOp.second);
2864 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2865 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2874void NewGVN::initializeCongruenceClasses(
Function &
F) {
2875 NextCongruenceNum = 0;
2885 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2891 for (
auto *DTN :
nodes(DT)) {
2898 if (MemoryBlockDefs)
2899 for (
const auto &Def : *MemoryBlockDefs) {
2900 MemoryAccessToClass[&
Def] = TOPClass;
2905 TOPClass->memory_insert(MP);
2906 MemoryPhiState.
insert({MP, MPS_TOP});
2910 TOPClass->incStoreCount();
2916 for (
auto &
I : *BB) {
2918 for (
auto *U :
I.users())
2921 PHINodeUses.
insert(UInst);
2924 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2926 TOPClass->insert(&
I);
2927 ValueToClass[&
I] = TOPClass;
2932 for (
auto &FA :
F.args())
2933 createSingletonCongruenceClass(&FA);
2936void NewGVN::cleanupTables() {
2937 for (CongruenceClass *&CC : CongruenceClasses) {
2938 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2939 << CC->size() <<
" members\n");
2947 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2948 AllTempInstructions.
end());
2949 AllTempInstructions.
clear();
2953 for (
auto *
I : TempInst) {
2954 I->dropAllReferences();
2957 while (!TempInst.empty()) {
2958 auto *
I = TempInst.pop_back_val();
2962 ValueToClass.
clear();
2963 ArgRecycler.
clear(ExpressionAllocator);
2964 ExpressionAllocator.Reset();
2965 CongruenceClasses.clear();
2966 ExpressionToClass.clear();
2967 ValueToExpression.
clear();
2969 AdditionalUsers.
clear();
2970 ExpressionToPhiOfOps.
clear();
2971 TempToBlock.
clear();
2972 TempToMemory.
clear();
2973 PHINodeUses.
clear();
2974 OpSafeForPHIOfOps.
clear();
2975 ReachableBlocks.
clear();
2976 ReachableEdges.
clear();
2978 ProcessedCount.
clear();
2981 InstructionsToErase.
clear();
2983 BlockInstRange.
clear();
2984 TouchedInstructions.
clear();
2985 MemoryAccessToClass.
clear();
2986 PredicateToUsers.
clear();
2987 MemoryToUsers.
clear();
2988 RevisitOnReachabilityChange.
clear();
2989 PredicateSwapChoice.
clear();
2994std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
2996 unsigned End =
Start;
2997 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
2998 InstrDFS[MemPhi] = End++;
3003 for (
auto &
I : *
B) {
3009 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3011 markInstructionForDeletion(&
I);
3015 RevisitOnReachabilityChange[
B].set(End);
3016 InstrDFS[&
I] = End++;
3023 return std::make_pair(Start, End);
3026void NewGVN::updateProcessedCount(
const Value *V) {
3028 assert(++ProcessedCount[V] < 100 &&
3029 "Seem to have processed the same Value a lot");
3034void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3041 return cast<MemoryAccess>(U) != MP &&
3042 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3043 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3048 if (Filtered.begin() == Filtered.end()) {
3049 if (setMemoryClass(MP, TOPClass))
3050 markMemoryUsersTouched(MP);
3056 auto LookupFunc = [&](
const Use &
U) {
3059 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3060 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3064 const auto *AllSameValue = *MappedBegin;
3066 bool AllEqual = std::all_of(
3067 MappedBegin, MappedEnd,
3068 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3071 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3080 CongruenceClass *CC =
3081 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3082 auto OldState = MemoryPhiState.
lookup(MP);
3083 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3084 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3085 MemoryPhiState[MP] = NewState;
3086 if (setMemoryClass(MP, CC) || OldState != NewState)
3087 markMemoryUsersTouched(MP);
3092void NewGVN::valueNumberInstruction(Instruction *
I) {
3094 if (!
I->isTerminator()) {
3096 SmallPtrSet<Value *, 2> Visited;
3098 auto Res = performSymbolicEvaluation(
I, Visited);
3099 Symbolized = Res.Expr;
3100 addAdditionalUsers(Res,
I);
3105 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3110 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3111 removePhiOfOps(
I,
Op);
3120 if (Symbolized ==
nullptr)
3121 Symbolized = createUnknownExpression(
I);
3122 performCongruenceFinding(
I, Symbolized);
3127 if (!
I->getType()->isVoidTy()) {
3128 auto *Symbolized = createUnknownExpression(
I);
3129 performCongruenceFinding(
I, Symbolized);
3131 processOutgoingEdges(
I,
I->getParent());
3137bool NewGVN::singleReachablePHIPath(
3138 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3139 const MemoryAccess *Second)
const {
3140 if (
First == Second)
3153 const auto *EndDef =
First;
3155 if (ChainDef == Second)
3162 auto ReachableOperandPred = [&](
const Use &
U) {
3165 auto FilteredPhiArgs =
3179void NewGVN::verifyMemoryCongruency()
const {
3182 for (
const auto *CC : CongruenceClasses) {
3183 if (CC == TOPClass || CC->isDead())
3185 if (CC->getStoreCount() != 0) {
3187 "Any class with a store as a leader should have a "
3188 "representative stored value");
3189 assert(CC->getMemoryLeader() &&
3190 "Any congruence class with a store should have a "
3191 "representative access");
3194 if (CC->getMemoryLeader())
3195 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3196 "Representative MemoryAccess does not appear to be reverse "
3198 for (
const auto *M : CC->memory())
3200 "Memory member does not appear to be reverse mapped properly");
3208 auto ReachableAccessPred =
3209 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3210 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3212 MemoryToDFSNum(Pair.first) == 0)
3220 for (
const auto &U : MemPHI->incoming_values()) {
3233 for (
auto KV : Filtered) {
3236 if (FirstMUD && SecondMUD) {
3237 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3238 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3239 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3240 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3241 "The instructions for these memory operations should have "
3242 "been in the same congruence class or reachable through"
3243 "a single argument phi");
3248 auto ReachableOperandPred = [&](
const Use &
U) {
3249 return ReachableEdges.
count(
3250 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3254 auto FilteredPhiArgs =
3257 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3258 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3259 const MemoryDef *MD = cast<MemoryDef>(U);
3260 return ValueToClass.lookup(MD->getMemoryInst());
3263 "All MemoryPhi arguments should be in the same class");
3272void NewGVN::verifyIterationSettled(
Function &
F) {
3282 std::map<const Value *, CongruenceClass> BeforeIteration;
3284 for (
auto &KV : ValueToClass) {
3287 if (InstrToDFSNum(
I) == 0)
3289 BeforeIteration.insert({KV.first, *KV.second});
3292 TouchedInstructions.
set();
3293 TouchedInstructions.
reset(0);
3294 OpSafeForPHIOfOps.
clear();
3296 iterateTouchedInstructions();
3297 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3299 for (
const auto &KV : ValueToClass) {
3302 if (InstrToDFSNum(
I) == 0)
3306 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3307 auto *AfterCC = KV.second;
3310 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3311 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3312 "Value number changed after main loop completed!");
3313 EqualClasses.
insert({BeforeCC, AfterCC});
3324void NewGVN::verifyStoreExpressions()
const {
3329 std::pair<
const Value *,
3330 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3332 for (
const auto &KV : ExpressionToClass) {
3335 auto Res = StoreExpressionSet.insert(
3336 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3337 SE->getStoredValue())});
3338 bool Okay = Res.second;
3343 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3344 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3345 lookupOperandLeader(SE->getStoredValue()));
3346 assert(Okay &&
"Stored expression conflict exists in expression table");
3347 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3348 assert(ValueExpr && ValueExpr->equals(*SE) &&
3349 "StoreExpression in ExpressionToClass is not latest "
3350 "StoreExpression for value");
3359void NewGVN::iterateTouchedInstructions() {
3362 int FirstInstr = TouchedInstructions.
find_first();
3364 if (FirstInstr == -1)
3366 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3367 while (TouchedInstructions.
any()) {
3373 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3377 if (InstrNum == 0) {
3378 TouchedInstructions.
reset(InstrNum);
3382 Value *
V = InstrFromDFSNum(InstrNum);
3383 const BasicBlock *CurrBlock = getBlockForValue(V);
3386 if (CurrBlock != LastBlock) {
3387 LastBlock = CurrBlock;
3388 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3389 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3392 if (!BlockReachable) {
3393 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3396 <<
" because it is unreachable\n");
3401 updateProcessedCount(CurrBlock);
3405 TouchedInstructions.
reset(InstrNum);
3409 valueNumberMemoryPhi(MP);
3411 valueNumberInstruction(
I);
3415 updateProcessedCount(V);
3418 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3422bool NewGVN::runGVN() {
3426 NumFuncArgs =
F.arg_size();
3428 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3432 unsigned ICount = 1;
3438 ReversePostOrderTraversal<Function *> RPOT(&
F);
3439 unsigned Counter = 0;
3440 for (BasicBlock *
B : RPOT) {
3442 assert(Node &&
"RPO and Dominator tree should have same reachability");
3443 RPOOrdering[
Node] = ++Counter;
3444 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3445 BlockInstRange.
insert({
B, BlockRange});
3446 ICount += BlockRange.second - BlockRange.first;
3448 initializeCongruenceClasses(
F);
3450 TouchedInstructions.
resize(ICount);
3454 ExpressionToClass.reserve(ICount);
3457 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3458 TouchedInstructions.
set(InstRange.first, InstRange.second);
3460 <<
" marked reachable\n");
3461 ReachableBlocks.
insert(&
F.getEntryBlock());
3465 iterateTouchedInstructions();
3466 verifyMemoryCongruency();
3467 verifyIterationSettled(
F);
3468 verifyStoreExpressions();
3470 Changed |= eliminateInstructions(
F);
3473 for (Instruction *ToErase : InstructionsToErase) {
3474 if (!ToErase->use_empty())
3477 assert(ToErase->getParent() &&
3478 "BB containing ToErase deleted unexpectedly!");
3479 ToErase->eraseFromParent();
3481 Changed |= !InstructionsToErase.empty();
3484 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3485 return !ReachableBlocks.
count(&BB);
3490 <<
" is unreachable\n");
3491 deleteInstructionsInBlock(&BB);
3560void NewGVN::convertClassToDFSOrdered(
3569 assert(BB &&
"Should have figured out a basic block for value");
3578 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3580 VDDef.Def.setPointer(Leader);
3582 VDDef.Def.setPointer(
SI->getValueOperand());
3583 VDDef.Def.setInt(
true);
3586 VDDef.Def.setPointer(
D);
3589 "The dense set member should always be an instruction");
3594 if (
auto *PN = RealToTemp.
lookup(Def)) {
3598 VDDef.Def.setInt(
false);
3599 VDDef.Def.setPointer(PN);
3605 unsigned int UseCount = 0;
3607 for (
auto &U :
Def->uses()) {
3610 if (InstructionsToErase.count(
I))
3616 IBlock =
P->getIncomingBlock(U);
3621 IBlock = getBlockForValue(
I);
3627 if (!ReachableBlocks.
contains(IBlock))
3643 ProbablyDead.
insert(Def);
3645 UseCounts[
Def] = UseCount;
3651void NewGVN::convertClassToLoadsAndStores(
3652 const CongruenceClass &
Dense,
3653 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3663 VD.Def.setPointer(
D);
3677 I->replaceAllUsesWith(Repl);
3680void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3682 ++NumGVNBlocksDeleted;
3686 auto StartPoint = BB->
rbegin();
3699 ++NumGVNInstrDeleted;
3709void NewGVN::markInstructionForDeletion(Instruction *
I) {
3711 InstructionsToErase.insert(
I);
3714void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3719 markInstructionForDeletion(
I);
3726class ValueDFSStack {
3728 Value *
back()
const {
return ValueStack.back(); }
3729 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3731 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3732 ValueStack.emplace_back(V);
3733 DFSStack.emplace_back(DFSIn, DFSOut);
3736 bool empty()
const {
return DFSStack.empty(); }
3738 bool isInScope(
int DFSIn,
int DFSOut)
const {
3741 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3744 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3747 assert(ValueStack.size() == DFSStack.size() &&
3748 "Mismatch between ValueStack and DFSStack");
3750 !DFSStack.empty() &&
3751 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3752 DFSStack.pop_back();
3753 ValueStack.pop_back();
3758 SmallVector<Value *, 8> ValueStack;
3765CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3767 return ValueToClass.lookup(VE->getVariableValue());
3770 return ExpressionToClass.lookup(
E);
3776 const Instruction *OrigInst,
3777 const BasicBlock *BB)
const {
3780 return CE->getConstantValue();
3782 auto *
V = VE->getVariableValue();
3784 return VE->getVariableValue();
3787 auto *CC = getClassForExpression(
E);
3791 return CC->getLeader();
3793 for (
auto *Member : *CC) {
3795 if (MemberInst == OrigInst)
3800 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3806bool NewGVN::eliminateInstructions(
Function &
F) {
3830 bool AnythingReplaced =
false;
3838 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3839 for (
auto &Operand :
PHI->incoming_values())
3840 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3844 <<
" with poison due to it being unreachable\n");
3857 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3858 for (
auto &KV : ReachableEdges)
3859 ReachablePredCount[KV.getEnd()]++;
3860 for (
auto &BBPair : RevisitOnReachabilityChange) {
3861 for (
auto InstNum : BBPair.second) {
3862 auto *Inst = InstrFromDFSNum(InstNum);
3867 auto *BB = BBPair.first;
3868 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3869 ReplaceUnreachablePHIArgs(
PHI, BB);
3874 DenseMap<const Value *, unsigned int> UseCounts;
3875 for (
auto *CC :
reverse(CongruenceClasses)) {
3876 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3881 SmallPtrSet<Instruction *, 8> ProbablyDead;
3882 if (CC->isDead() || CC->empty())
3885 if (CC == TOPClass) {
3886 for (
auto *M : *CC) {
3887 auto *VTE = ValueToExpression.
lookup(M);
3892 "Everything in TOP should be unreachable or dead at this "
3898 assert(CC->getLeader() &&
"We should have had a leader");
3904 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3906 CongruenceClass::MemberSet MembersLeft;
3907 for (
auto *M : *CC) {
3911 Member->getType()->isVoidTy()) {
3912 MembersLeft.
insert(Member);
3916 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3917 << *Member <<
"\n");
3919 assert(Leader !=
I &&
"About to accidentally remove our leader");
3920 replaceInstruction(
I, Leader);
3921 AnythingReplaced =
true;
3923 CC->swap(MembersLeft);
3926 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3931 ValueDFSStack EliminationStack;
3935 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3939 for (
auto &VD : DFSOrderedSet) {
3940 int MemberDFSIn = VD.
DFSIn;
3941 int MemberDFSOut = VD.
DFSOut;
3943 bool FromStore = VD.Def.getInt();
3946 if (Def &&
Def->getType()->isVoidTy())
3949 if (DefInst && AllTempInstructions.
count(DefInst)) {
3955 AllTempInstructions.
erase(PN);
3956 auto *DefBlock = getBlockForValue(Def);
3960 PN->insertBefore(DefBlock->begin());
3962 NumGVNPHIOfOpsEliminations++;
3965 if (EliminationStack.empty()) {
3969 << EliminationStack.dfs_back().first <<
","
3970 << EliminationStack.dfs_back().second <<
")\n");
3973 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
3974 << MemberDFSOut <<
")\n");
3988 bool ShouldPush =
Def && EliminationStack.empty();
3990 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
3992 if (OutOfScope || ShouldPush) {
3994 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
3995 bool ShouldPush =
Def && EliminationStack.empty();
3997 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4017 if (!EliminationStack.empty() && DefI && !FromStore) {
4018 Value *DominatingLeader = EliminationStack.back();
4019 if (DominatingLeader != Def) {
4027 for (
auto *DVR : DVRUsers)
4028 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4030 markInstructionForDeletion(DefI);
4039 "Current def should have been an instruction");
4041 "Current user should have been an instruction");
4048 if (InstructionsToErase.count(InstUse)) {
4049 auto &UseCount = UseCounts[
U->get()];
4050 if (--UseCount == 0) {
4057 if (EliminationStack.empty())
4060 Value *DominatingLeader = EliminationStack.back();
4064 if (BC->getType() == BC->getOperand(0)->getType() &&
4065 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4067 DominatingLeader = BC->getOperand(0);
4072 if (
U->get() == DominatingLeader)
4079 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4080 if (!PI || DominatingLeader != PI->OriginalOp)
4084 <<
"Found replacement " << *DominatingLeader <<
" for "
4085 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4086 U->set(DominatingLeader);
4089 auto &LeaderUseCount = UseCounts[DominatingLeader];
4096 auto It = UseCounts.
find(SSACopy);
4097 if (It != UseCounts.
end()) {
4098 unsigned &IIUseCount = It->second;
4099 if (--IIUseCount == 0)
4100 ProbablyDead.
insert(SSACopy);
4104 AnythingReplaced =
true;
4111 for (
auto *
I : ProbablyDead)
4113 markInstructionForDeletion(
I);
4116 CongruenceClass::MemberSet MembersLeft;
4117 for (
auto *Member : *CC)
4120 MembersLeft.
insert(Member);
4121 CC->swap(MembersLeft);
4124 if (CC->getStoreCount() > 0) {
4125 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4127 ValueDFSStack EliminationStack;
4128 for (
auto &VD : PossibleDeadStores) {
4129 int MemberDFSIn = VD.
DFSIn;
4130 int MemberDFSOut = VD.
DFSOut;
4132 if (EliminationStack.empty() ||
4133 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4135 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4136 if (EliminationStack.empty()) {
4137 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4144 assert(!EliminationStack.empty());
4150 <<
" that is dominated by " << *Leader <<
"\n");
4151 markInstructionForDeletion(Member);
4157 return AnythingReplaced;
4165unsigned int NewGVN::getRank(
const Value *V)
const {
4180 return 4 +
A->getArgNo();
4184 unsigned Result = InstrToDFSNum(V);
4186 return 5 + NumFuncArgs +
Result;
4193bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4197 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4200bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4201 const BitCastInst *
I)
const {
4202 if (shouldSwapOperands(
A,
B)) {
4203 PredicateSwapChoice[
I] =
B;
4208 if (LookupResult != PredicateSwapChoice.
end()) {
4210 if (SeenPredicate) {
4212 if (SeenPredicate ==
B)
4231 NewGVN(
F, &DT, &AC, &TLI, &
AA, &MSSA,
F.getDataLayout())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file defines the BumpPtrAllocator interface.
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
early cse Early CSE w MemorySSA
The header file for the GVN pass that contains expression handling classes.
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
This is the interface for a simple mod/ref and alias analysis over globals.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
This defines the Use class.
static bool lookup(const GsymReader &GR, GsymDataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Branch Probability Basic Block static false std::string getBlockName(const MachineBasicBlock *BB)
Helper to print the name of a MBB.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static bool alwaysAvailable(Value *V)
static Value * getCopyOf(const Value *V)
static bool isCopyOfPHI(const Value *V, const PHINode *PN)
static bool isCopyOfAPHI(const Value *V)
static bool equalsLoadStoreHelper(const T &LHS, const Expression &RHS)
static bool okayForPHIOfOps(const ScalarOptions &Opts, const Instruction *I)
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)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
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.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Class representing an expression and its matching format.
bool isPresplitCoroutine() const
Determine if the function is presplit coroutine.
~AggregateValueExpression() override
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator)
~BasicExpression() override
bool equals(const Expression &Other) const override
~CallExpression() override
void setOpcode(unsigned opcode)
bool equals(const Expression &Other) const override
~LoadExpression() override
bool equals(const Expression &Other) const override
~PHIExpression() override
bool equals(const Expression &Other) const override
~StoreExpression() override
Value * getStoredValue() const
static LLVM_ABI std::optional< bool > isImpliedByMatchingCmp(CmpPredicate Pred1, CmpPredicate Pred2)
Determine if Pred1 implies Pred2 is true, false, or if nothing can be inferred about the implication,...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
iterator_range< user_iterator > users()
Value * getPointerOperand()
BasicBlock * getBlock() const
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
An analysis that produces MemorySSA for a function.
This is the generic walker interface for walkers of MemorySSA.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
LLVM_ABI MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
MemoryAccess * getLiveOnEntryDef() const
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
LLVM_ABI PreservedAnalyses run(Function &F, AnalysisManager< Function > &AM)
Run the pass over the function.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PointerIntPair - This class implements a pair of a pointer and small integer.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSetIterator< PtrType > const_iterator
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
std::pair< iterator, bool > insert(const ValueT &V)
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
@ BasicBlock
Various leaf nodes.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
auto m_Value()
Match an arbitrary value and ignore it.
brc_match< Cond_t, match_bind< BasicBlock >, match_bind< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
LLVM_ABI int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
LLVM_ABI Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
LLVM_ABI int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
LLVM_ABI Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
LLVM_ABI int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
@ CE
Windows NT (Windows on ARM)
std::vector< std::optional< ExecutorAddr > > LookupResult
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI Instruction & back() const
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
SDValue getStoredValue(SDValue Op)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
mapped_iterator< ItTy, FuncTy > map_iterator(ItTy I, FuncTy F)
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
bool isa_and_nonnull(const Y &Val)
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
@ Global
Append to llvm.global_dtors.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
AAResults AliasAnalysis
Temporary typedef for legacy code that uses a generic AliasAnalysis pointer or reference.
LLVM_ABI void findDbgUsers(Value *V, SmallVectorImpl< DbgVariableRecord * > &DbgVariableRecords)
Finds the debug info records describing a value.
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
PointerIntPair< Value *, 1, bool > Def
bool operator<(const ValueDFS &Other) const
DOTGraphTraits - Template class that can be specialized to customize how graphs are converted to 'dot...
static unsigned getHashValue(const ExactEqualsExpression &E)
static unsigned getHashValue(const Expression *E)
static bool isEqual(const Expression *LHS, const Expression *RHS)
static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
SimplifyQuery getWithInstruction(const Instruction *I) const