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(
const ScalarOptions &Opts,
Function &
F, DominatorTree *DT,
637 AssumptionCache *AC, TargetLibraryInfo *TLI,
AliasAnalysis *AA,
639 : Opts(Opts),
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
642 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
643 SQ(
DL, TLI, DT, AC, nullptr,
false,
651 const Expression *Expr;
653 const PredicateBase *PredDep;
655 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
656 const PredicateBase *PredDep =
nullptr)
657 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
658 ExprResult(
const ExprResult &) =
delete;
659 ExprResult(ExprResult &&
Other)
661 Other.Expr =
nullptr;
662 Other.ExtraDep =
nullptr;
663 Other.PredDep =
nullptr;
665 ExprResult &operator=(
const ExprResult &
Other) =
delete;
666 ExprResult &operator=(ExprResult &&
Other) =
delete;
668 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
670 operator bool()
const {
return Expr; }
672 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
673 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
674 return {Expr, ExtraDep,
nullptr};
676 static ExprResult some(
const Expression *Expr,
677 const PredicateBase *PredDep) {
678 return {Expr,
nullptr, PredDep};
680 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
681 const PredicateBase *PredDep) {
682 return {Expr, ExtraDep, PredDep};
687 ExprResult createExpression(Instruction *)
const;
688 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
689 Instruction *)
const;
693 using ValPair = std::pair<Value *, BasicBlock *>;
696 BasicBlock *,
bool &HasBackEdge,
697 bool &OriginalOpsConstant)
const;
698 const DeadExpression *createDeadExpression()
const;
699 const VariableExpression *createVariableExpression(
Value *)
const;
700 const ConstantExpression *createConstantExpression(Constant *)
const;
701 const Expression *createVariableOrConstant(
Value *V)
const;
702 const UnknownExpression *createUnknownExpression(Instruction *)
const;
703 const StoreExpression *createStoreExpression(StoreInst *,
704 const MemoryAccess *)
const;
705 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
706 const MemoryAccess *)
const;
707 const CallExpression *createCallExpression(CallInst *,
708 const MemoryAccess *)
const;
709 const AggregateValueExpression *
710 createAggregateValueExpression(Instruction *)
const;
711 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
714 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
717 unsigned LeaderDFS = 0;
725 LeaderDFS = InstrToDFSNum(
I);
727 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
728 CongruenceClasses.emplace_back(result);
732 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
733 auto *CC = createCongruenceClass(
nullptr,
nullptr);
734 CC->setMemoryLeader(MA);
738 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
739 auto *CC = getMemoryClass(MA);
740 if (CC->getMemoryLeader() != MA)
741 CC = createMemoryClass(MA);
745 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
746 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
747 CClass->insert(Member);
748 ValueToClass[
Member] = CClass;
752 void initializeCongruenceClasses(
Function &
F);
753 const Expression *makePossiblePHIOfOps(Instruction *,
754 SmallPtrSetImpl<Value *> &);
755 Value *findLeaderForInst(Instruction *ValueOp,
756 SmallPtrSetImpl<Value *> &Visited,
757 MemoryAccess *MemAccess, Instruction *OrigInst,
759 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
760 SmallPtrSetImpl<const Value *> &);
761 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
762 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
765 void valueNumberMemoryPhi(MemoryPhi *);
766 void valueNumberInstruction(Instruction *);
769 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
770 ExprResult performSymbolicEvaluation(Instruction *,
771 SmallPtrSetImpl<Value *> &)
const;
772 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
774 MemoryAccess *)
const;
775 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
776 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
777 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
781 BasicBlock *PHIBlock)
const;
782 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
783 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
784 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
787 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
789 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
790 void performCongruenceFinding(Instruction *,
const Expression *);
791 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
792 CongruenceClass *, CongruenceClass *);
793 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
794 CongruenceClass *, CongruenceClass *);
795 Value *getNextValueLeader(CongruenceClass *)
const;
796 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
797 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
798 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
799 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
800 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
803 unsigned int getRank(
const Value *)
const;
804 bool shouldSwapOperands(
const Value *,
const Value *)
const;
805 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
806 const BitCastInst *
I)
const;
809 void updateReachableEdge(BasicBlock *, BasicBlock *);
810 void processOutgoingEdges(Instruction *, BasicBlock *);
811 Value *findConditionEquivalence(
Value *)
const;
815 void convertClassToDFSOrdered(
const CongruenceClass &,
816 SmallVectorImpl<ValueDFS> &,
817 DenseMap<const Value *, unsigned int> &,
818 SmallPtrSetImpl<Instruction *> &)
const;
819 void convertClassToLoadsAndStores(
const CongruenceClass &,
820 SmallVectorImpl<ValueDFS> &)
const;
822 bool eliminateInstructions(
Function &);
823 void replaceInstruction(Instruction *,
Value *);
824 void markInstructionForDeletion(Instruction *);
825 void deleteInstructionsInBlock(BasicBlock *);
826 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
827 const BasicBlock *)
const;
830 template <
typename Map,
typename KeyType>
831 void touchAndErase(Map &,
const KeyType &);
832 void markUsersTouched(
Value *);
833 void markMemoryUsersTouched(
const MemoryAccess *);
834 void markMemoryDefTouched(
const MemoryAccess *);
835 void markPredicateUsersTouched(Instruction *);
836 void markValueLeaderChangeTouched(CongruenceClass *CC);
837 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
838 void markPhiOfOpsChanged(
const Expression *
E);
839 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
840 void addAdditionalUsers(
Value *To,
Value *User)
const;
841 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
844 void iterateTouchedInstructions();
847 void cleanupTables();
848 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
849 void updateProcessedCount(
const Value *V);
850 void verifyMemoryCongruency()
const;
851 void verifyIterationSettled(
Function &
F);
852 void verifyStoreExpressions()
const;
853 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
854 const MemoryAccess *,
const MemoryAccess *)
const;
856 void deleteExpression(
const Expression *
E)
const;
857 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
858 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
859 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
861 unsigned InstrToDFSNum(
const Value *V)
const {
863 return InstrDFS.
lookup(V);
866 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
867 return MemoryToDFSNum(MA);
870 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
875 unsigned MemoryToDFSNum(
const Value *MA)
const {
877 "This should not be used with instructions");
883 bool isCycleFree(
const Instruction *)
const;
884 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
888 DebugCounter::CounterState StartingVNCounter;
897 return LHS.MemoryExpression::equals(
RHS);
919 return Call->getAttributes()
920 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
940MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
946MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
953 auto *Parent =
I->getParent();
956 Parent = TempToBlock.
lookup(V);
957 assert(Parent &&
"Every fake instruction should have a block");
962 assert(MP &&
"Should have been an instruction or a MemoryPhi");
963 return MP->getBlock();
969void NewGVN::deleteExpression(
const Expression *
E)
const {
973 ExpressionAllocator.Deallocate(
E);
979 if (BC->getType() == BC->getOperand(0)->getType())
980 return BC->getOperand(0);
999 return BlockInstRange.
lookup(
P1.second).first <
1000 BlockInstRange.
lookup(
P2.second).first;
1017 const Instruction *
I,
1018 BasicBlock *PHIBlock,
1020 bool &OriginalOpsConstant)
const {
1025 E->setType(PHIOperands.
begin()->first->getType());
1026 E->setOpcode(Instruction::PHI);
1030 auto *BB =
P.second;
1034 if (!ReachableEdges.
count({BB, PHIBlock}))
1037 if (ValueToClass.
lookup(
P.first) == TOPClass)
1039 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1040 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1041 return lookupOperandLeader(
P.first) !=
I;
1044 return lookupOperandLeader(
P.first);
1052 bool AllConstant =
true;
1054 E->setType(
GEP->getSourceElementType());
1056 E->setType(
I->getType());
1057 E->setOpcode(
I->getOpcode());
1058 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1063 auto Operand = lookupOperandLeader(O);
1071const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1073 Instruction *
I)
const {
1080 E->setOpcode(Opcode);
1081 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1087 if (shouldSwapOperands(Arg1, Arg2))
1090 E->op_push_back(lookupOperandLeader(Arg1));
1091 E->op_push_back(lookupOperandLeader(Arg2));
1094 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1095 addAdditionalUsers(Simplified,
I);
1104NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1107 return ExprResult::none();
1112 <<
" constant " << *
C <<
"\n");
1113 NumGVNOpsSimplified++;
1115 "We should always have had a basic expression here");
1116 deleteExpression(
E);
1117 return ExprResult::some(createConstantExpression(
C));
1121 <<
" variable " << *V <<
"\n");
1122 deleteExpression(
E);
1123 return ExprResult::some(createVariableExpression(V));
1126 CongruenceClass *CC = ValueToClass.
lookup(V);
1128 if (CC->getLeader() && CC->getLeader() !=
I) {
1129 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1131 if (CC->getDefiningExpr()) {
1134 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1135 NumGVNOpsSimplified++;
1136 deleteExpression(
E);
1137 return ExprResult::some(CC->getDefiningExpr(), V);
1141 return ExprResult::none();
1147NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1153 bool AllConstant = setBasicExpressionInfo(
I,
E);
1155 if (
I->isCommutative()) {
1160 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1161 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1162 E->swapOperands(0, 1);
1169 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1170 E->swapOperands(0, 1);
1173 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1175 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1176 "Wrong types on cmp instruction");
1177 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1178 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1181 if (
auto Simplified = checkExprResults(
E,
I, V))
1185 E->getOperand(1) ==
E->getOperand(2)) {
1186 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1187 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1189 E->getOperand(2), FastMathFlags(), Q);
1190 if (
auto Simplified = checkExprResults(
E,
I, V))
1193 }
else if (
I->isBinaryOp()) {
1196 if (
auto Simplified = checkExprResults(
E,
I, V))
1201 if (
auto Simplified = checkExprResults(
E,
I, V))
1205 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1206 GEPI->getNoWrapFlags(), Q);
1207 if (
auto Simplified = checkExprResults(
E,
I, V))
1209 }
else if (AllConstant) {
1218 for (
Value *Arg :
E->operands())
1222 if (
auto Simplified = checkExprResults(
E,
I, V))
1225 return ExprResult::some(
E);
1229NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1231 auto *
E =
new (ExpressionAllocator)
1233 setBasicExpressionInfo(
I,
E);
1234 E->allocateIntOperands(ExpressionAllocator);
1238 auto *
E =
new (ExpressionAllocator)
1240 setBasicExpressionInfo(EI,
E);
1241 E->allocateIntOperands(ExpressionAllocator);
1251 return SingletonDeadExpression;
1262 return createConstantExpression(
C);
1263 return createVariableExpression(V);
1279NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1283 setBasicExpressionInfo(CI,
E);
1289 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1290 E->swapOperands(0, 1);
1296bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1297 const Instruction *U)
const {
1298 auto *CC = ValueToClass.
lookup(Inst);
1321 if (CC->getNextLeader().first &&
1325 return Member != CC->getLeader() &&
1332Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1333 CongruenceClass *CC = ValueToClass.
lookup(V);
1340 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1346const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1347 auto *CC = getMemoryClass(MA);
1348 assert(CC->getMemoryLeader() &&
1349 "Every MemoryAccess should be mapped to a congruence class with a "
1350 "representative memory access");
1351 return CC->getMemoryLeader();
1357bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1358 return getMemoryClass(MA) == TOPClass;
1363 const MemoryAccess *MA)
const {
1365 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1367 E->setType(LoadType);
1371 E->op_push_back(PointerOp);
1380NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1381 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1382 auto *
E =
new (ExpressionAllocator)
1385 E->setType(
SI->getValueOperand()->getType());
1389 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1397const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1401 auto *StoreAccess = getMemoryAccess(SI);
1403 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1404 if (Opts.enable_store_refinement)
1407 StoreRHS = lookupMemoryLeader(StoreRHS);
1408 if (StoreRHS != StoreAccess->getDefiningAccess())
1409 addMemoryUsers(StoreRHS, StoreAccess);
1411 if (StoreRHS == StoreAccess)
1414 if (
SI->isSimple()) {
1418 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1419 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1425 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1433 LastStore->getOperand(0)) &&
1434 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1437 deleteExpression(LastStore);
1443 return createStoreExpression(SI, StoreAccess);
1449NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1450 LoadInst *LI, Instruction *DepInst,
1451 MemoryAccess *DefiningAccess)
const {
1457 if (LI->
isAtomic() > DepSI->isAtomic() ||
1458 LoadType == DepSI->getValueOperand()->getType())
1463 lookupOperandLeader(DepSI->getValueOperand()))) {
1466 <<
" to constant " << *Res <<
"\n");
1467 return createConstantExpression(Res);
1473 if (LI->
isAtomic() > DepLI->isAtomic())
1479 if (
auto *PossibleConstant =
1482 <<
" to constant " << *PossibleConstant <<
"\n");
1483 return createConstantExpression(PossibleConstant);
1489 if (
auto *PossibleConstant =
1492 <<
" to constant " << *PossibleConstant <<
"\n");
1493 return createConstantExpression(PossibleConstant);
1499 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1500 auto *LifetimePtr =
II->getOperand(0);
1501 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1510 (LoadPtr != lookupOperandLeader(DepInst) &&
1519 }
else if (
auto *InitVal =
1521 return createConstantExpression(InitVal);
1526const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1538 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1539 MemoryAccess *DefiningAccess =
1552 if (
const auto *CoercionResult =
1553 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1554 DefiningInst, DefiningAccess))
1555 return CoercionResult;
1559 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1563 if (
LE->getMemoryLeader() != DefiningAccess)
1564 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1569NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1570 auto *PI = PredInfo->getPredicateInfoFor(
I);
1572 return ExprResult::none();
1574 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1576 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1578 return ExprResult::none();
1581 Value *CmpOp0 =
I->getOperand(0);
1582 Value *CmpOp1 = Constraint->OtherOp;
1584 Value *FirstOp = lookupOperandLeader(CmpOp0);
1585 Value *SecondOp = lookupOperandLeader(CmpOp1);
1586 Value *AdditionallyUsedValue = CmpOp0;
1589 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1592 AdditionallyUsedValue = CmpOp1;
1596 return ExprResult::some(createVariableOrConstant(FirstOp),
1597 AdditionallyUsedValue, PI);
1602 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1603 AdditionallyUsedValue, PI);
1605 return ExprResult::none();
1609NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1620 return ExprResult::none();
1626 return ExprResult::none();
1629 return ExprResult::some(
1630 createCallExpression(CI, TOPClass->getMemoryLeader()));
1634 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1636 return ExprResult::some(
1637 createCallExpression(CI, TOPClass->getMemoryLeader()));
1639 return ExprResult::none();
1643CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1645 assert(Result &&
"Should have found memory class");
1651bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1652 CongruenceClass *NewClass) {
1654 "Every MemoryAccess should be getting mapped to a non-null class");
1658 <<
" with current MemoryAccess leader ");
1664 if (LookupResult != MemoryAccessToClass.
end()) {
1666 if (OldClass != NewClass) {
1669 OldClass->memory_erase(MP);
1670 NewClass->memory_insert(MP);
1672 if (OldClass->getMemoryLeader() == From) {
1673 if (OldClass->definesNoMemory()) {
1674 OldClass->setMemoryLeader(
nullptr);
1676 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1678 << OldClass->getID() <<
" to "
1679 << *OldClass->getMemoryLeader()
1680 <<
" due to removal of a memory member " << *From
1682 markMemoryLeaderChangeTouched(OldClass);
1699bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1705 auto ICS = InstCycleState.
lookup(
I);
1706 if (ICS == ICS_Unknown) {
1708 auto &
SCC = SCCFinder.getComponentFor(
I);
1710 if (
SCC.size() == 1)
1711 InstCycleState.
insert({
I, ICS_CycleFree});
1716 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1717 for (
const auto *Member : SCC)
1719 InstCycleState.
insert({MemberPhi, ICS});
1722 if (ICS == ICS_Cycle)
1731 BasicBlock *PHIBlock)
const {
1733 bool HasBackedge =
false;
1738 bool OriginalOpsConstant =
true;
1740 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1744 bool HasUndef =
false, HasPoison =
false;
1746 if (isa<PoisonValue>(Arg)) {
1757 if (Filtered.empty()) {
1762 dbgs() <<
"PHI Node " << *
I
1763 <<
" has no non-undef arguments, valuing it as undef\n");
1768 dbgs() <<
"PHI Node " << *
I
1769 <<
" has no non-poison arguments, valuing it as poison\n");
1773 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1774 deleteExpression(
E);
1775 return createDeadExpression();
1777 Value *AllSameValue = *(Filtered.begin());
1795 if (HasPoison || HasUndef) {
1801 if (HasBackedge && !OriginalOpsConstant &&
1807 if (!someEquivalentDominates(AllSameInst,
I))
1814 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1816 NumGVNPhisAllSame++;
1817 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1819 deleteExpression(
E);
1820 return createVariableOrConstant(AllSameValue);
1826NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1829 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1833 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1834 WO->getLHS(), WO->getRHS(),
I);
1837 return createAggregateValueExpression(
I);
1840NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1846 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1847 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1848 auto OurPredicate = CI->getPredicate();
1849 if (shouldSwapOperands(Op0, Op1)) {
1851 OurPredicate = CI->getSwappedPredicate();
1855 const PredicateBase *LastPredInfo =
nullptr;
1858 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1860 return ExprResult::some(
1865 if (CI->isTrueWhenEqual())
1866 return ExprResult::some(
1868 else if (CI->isFalseWhenEqual())
1869 return ExprResult::some(
1899 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1901 if (PI == LastPredInfo)
1906 if (!DT->
dominates(PBranch->To,
I->getParent()))
1916 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1917 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1918 auto BranchPredicate = BranchCond->getPredicate();
1919 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1921 BranchPredicate = BranchCond->getSwappedPredicate();
1923 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1924 if (PBranch->TrueEdge) {
1930 return ExprResult::some(createConstantExpression(
C), PI);
1935 if (BranchPredicate == OurPredicate) {
1937 return ExprResult::some(
1940 }
else if (BranchPredicate ==
1943 return ExprResult::some(
1952 return createExpression(
I);
1957NewGVN::performSymbolicEvaluation(Instruction *
I,
1958 SmallPtrSetImpl<Value *> &Visited)
const {
1964 switch (
I->getOpcode()) {
1965 case Instruction::ExtractValue:
1966 case Instruction::InsertValue:
1967 E = performSymbolicAggrValueEvaluation(
I);
1969 case Instruction::PHI: {
1972 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
1973 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
1976 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
1978 case Instruction::Call:
1979 return performSymbolicCallEvaluation(
I);
1981 case Instruction::Store:
1982 E = performSymbolicStoreEvaluation(
I);
1984 case Instruction::Load:
1985 E = performSymbolicLoadEvaluation(
I);
1987 case Instruction::BitCast:
1989 if (
I->getType() ==
I->getOperand(0)->getType())
1994 case Instruction::AddrSpaceCast:
1995 case Instruction::Freeze:
1996 return createExpression(
I);
1998 case Instruction::ICmp:
1999 case Instruction::FCmp:
2000 return performSymbolicCmpEvaluation(
I);
2002 case Instruction::FNeg:
2003 case Instruction::Add:
2004 case Instruction::FAdd:
2005 case Instruction::Sub:
2006 case Instruction::FSub:
2007 case Instruction::Mul:
2008 case Instruction::FMul:
2009 case Instruction::UDiv:
2010 case Instruction::SDiv:
2011 case Instruction::FDiv:
2012 case Instruction::URem:
2013 case Instruction::SRem:
2014 case Instruction::FRem:
2015 case Instruction::Shl:
2016 case Instruction::LShr:
2017 case Instruction::AShr:
2018 case Instruction::And:
2019 case Instruction::Or:
2020 case Instruction::Xor:
2021 case Instruction::Trunc:
2022 case Instruction::ZExt:
2023 case Instruction::SExt:
2024 case Instruction::FPToUI:
2025 case Instruction::FPToSI:
2026 case Instruction::UIToFP:
2027 case Instruction::SIToFP:
2028 case Instruction::FPTrunc:
2029 case Instruction::FPExt:
2030 case Instruction::PtrToInt:
2031 case Instruction::PtrToAddr:
2032 case Instruction::IntToPtr:
2033 case Instruction::Select:
2034 case Instruction::ExtractElement:
2035 case Instruction::InsertElement:
2036 case Instruction::GetElementPtr:
2037 return createExpression(
I);
2039 case Instruction::ShuffleVector:
2041 return ExprResult::none();
2043 return ExprResult::none();
2045 return ExprResult::some(
E);
2050template <
typename Map,
typename KeyType>
2051void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2053 if (Result !=
M.end()) {
2054 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2055 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2060void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2061 assert(User && To != User);
2063 AdditionalUsers[To].
insert(User);
2066void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2067 if (Res.ExtraDep && Res.ExtraDep != User)
2068 addAdditionalUsers(Res.ExtraDep, User);
2069 Res.ExtraDep =
nullptr;
2073 PredicateToUsers[PBranch->Condition].
insert(User);
2074 else if (
const auto *PAssume =
2076 PredicateToUsers[PAssume->Condition].
insert(User);
2078 Res.PredDep =
nullptr;
2081void NewGVN::markUsersTouched(
Value *V) {
2083 for (
auto *User :
V->users()) {
2085 TouchedInstructions.
set(InstrToDFSNum(User));
2087 touchAndErase(AdditionalUsers, V);
2090void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2091 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2092 MemoryToUsers[To].
insert(U);
2095void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2096 TouchedInstructions.
set(MemoryToDFSNum(MA));
2099void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2102 for (
const auto *U : MA->
users())
2103 TouchedInstructions.
set(MemoryToDFSNum(U));
2104 touchAndErase(MemoryToUsers, MA);
2108void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2109 touchAndErase(PredicateToUsers,
I);
2113void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2114 for (
const auto *M : CC->memory())
2115 markMemoryDefTouched(M);
2120void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2121 for (
auto *M : *CC) {
2123 TouchedInstructions.
set(InstrToDFSNum(
I));
2130template <
class T,
class Range>
2131T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2132 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2133 for (
const auto X : R) {
2134 auto DFSNum = InstrToDFSNum(
X);
2135 if (DFSNum < MinDFS.second)
2136 MinDFS = {
X, DFSNum};
2138 return MinDFS.first;
2144const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2148 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2149 if (CC->getStoreCount() > 0) {
2151 return getMemoryAccess(NL);
2157 assert(CC->getStoreCount() == 0);
2161 if (CC->memory_size() == 1)
2162 return *CC->memory_begin();
2163 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2169Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2174 if (CC->size() == 1 || CC == TOPClass) {
2175 return *(CC->begin());
2176 }
else if (CC->getNextLeader().first) {
2177 ++NumGVNAvoidedSortedLeaderChanges;
2178 return CC->getNextLeader().first;
2180 ++NumGVNSortedLeaderChanges;
2184 return getMinDFSOfRange<Value>(*CC);
2197void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2198 MemoryAccess *InstMA,
2199 CongruenceClass *OldClass,
2200 CongruenceClass *NewClass) {
2203 assert((!InstMA || !OldClass->getMemoryLeader() ||
2204 OldClass->getLeader() !=
I ||
2205 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2206 MemoryAccessToClass.
lookup(InstMA)) &&
2207 "Representative MemoryAccess mismatch");
2209 if (!NewClass->getMemoryLeader()) {
2211 assert(NewClass->size() == 1 ||
2213 NewClass->setMemoryLeader(InstMA);
2216 << NewClass->getID()
2217 <<
" due to new memory instruction becoming leader\n");
2218 markMemoryLeaderChangeTouched(NewClass);
2220 setMemoryClass(InstMA, NewClass);
2222 if (OldClass->getMemoryLeader() == InstMA) {
2223 if (!OldClass->definesNoMemory()) {
2224 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2226 << OldClass->getID() <<
" to "
2227 << *OldClass->getMemoryLeader()
2228 <<
" due to removal of old leader " << *InstMA <<
"\n");
2229 markMemoryLeaderChangeTouched(OldClass);
2231 OldClass->setMemoryLeader(
nullptr);
2237void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2238 CongruenceClass *OldClass,
2239 CongruenceClass *NewClass) {
2240 if (
I == OldClass->getNextLeader().first)
2241 OldClass->resetNextLeader();
2244 NewClass->insert(
I);
2248 if (NewClass->getLeader() !=
I &&
2249 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2250 markValueLeaderChangeTouched(NewClass);
2255 OldClass->decStoreCount();
2263 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2267 NewClass->setStoredValue(SE->getStoredValue());
2268 markValueLeaderChangeTouched(NewClass);
2271 << NewClass->getID() <<
" from "
2272 << *NewClass->getLeader() <<
" to " << *SI
2273 <<
" because store joined class\n");
2276 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2280 NewClass->incStoreCount();
2288 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2289 ValueToClass[
I] = NewClass;
2291 if (OldClass->empty() && OldClass != TOPClass) {
2292 if (OldClass->getDefiningExpr()) {
2293 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2294 <<
" from table\n");
2297 auto Iter = ExpressionToClass.find_as(
2298 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2299 if (Iter != ExpressionToClass.end())
2300 ExpressionToClass.erase(Iter);
2301#ifdef EXPENSIVE_CHECKS
2303 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2304 "We erased the expression we just inserted, which should not happen");
2307 }
else if (OldClass->getLeader() ==
I) {
2312 << OldClass->getID() <<
"\n");
2313 ++NumGVNLeaderChanges;
2318 if (OldClass->getStoreCount() == 0) {
2319 if (OldClass->getStoredValue())
2320 OldClass->setStoredValue(
nullptr);
2322 OldClass->setLeader({getNextValueLeader(OldClass),
2323 InstrToDFSNum(getNextValueLeader(OldClass))});
2324 OldClass->resetNextLeader();
2325 markValueLeaderChangeTouched(OldClass);
2331void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2332 touchAndErase(ExpressionToPhiOfOps,
E);
2336void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2340 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2341 assert(IClass &&
"Should have found a IClass");
2343 assert(!IClass->isDead() &&
"Found a dead class");
2345 CongruenceClass *EClass =
nullptr;
2347 EClass = ValueToClass.
lookup(VE->getVariableValue());
2352 auto lookupResult = ExpressionToClass.try_emplace(
E);
2355 if (lookupResult.second) {
2356 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2357 auto place = lookupResult.first;
2358 place->second = NewClass;
2362 NewClass->setLeader({
CE->getConstantValue(), 0});
2364 StoreInst *
SI = SE->getStoreInst();
2365 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2366 NewClass->setStoredValue(SE->getStoredValue());
2370 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2373 "VariableExpression should have been handled already");
2377 <<
" using expression " << *
E <<
" at "
2378 << NewClass->getID() <<
" and leader "
2379 << *(NewClass->getLeader()));
2380 if (NewClass->getStoredValue())
2382 << *(NewClass->getStoredValue()));
2385 EClass = lookupResult.first->second;
2388 (EClass->getStoredValue() &&
2390 "Any class with a constant expression should have a "
2393 assert(EClass &&
"Somehow don't have an eclass");
2395 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2398 bool ClassChanged = IClass != EClass;
2399 bool LeaderChanged = LeaderChanges.
erase(
I);
2400 if (ClassChanged || LeaderChanged) {
2401 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2404 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2405 markPhiOfOpsChanged(
E);
2408 markUsersTouched(
I);
2409 if (MemoryAccess *MA = getMemoryAccess(
I))
2410 markMemoryUsersTouched(MA);
2412 markPredicateUsersTouched(CI);
2419 auto *OldE = ValueToExpression.
lookup(
I);
2425 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2426 if (Iter != ExpressionToClass.end())
2427 ExpressionToClass.erase(Iter);
2430 ValueToExpression[
I] =
E;
2435void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2437 if (ReachableEdges.
insert({From, To}).second) {
2439 if (ReachableBlocks.
insert(To).second) {
2441 <<
" marked reachable\n");
2442 const auto &InstRange = BlockInstRange.
lookup(To);
2443 TouchedInstructions.
set(InstRange.first, InstRange.second);
2446 <<
" was reachable, but new edge {"
2448 <<
"} to it found\n");
2454 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2455 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2460 for (
auto InstNum : RevisitOnReachabilityChange[To])
2461 TouchedInstructions.
set(InstNum);
2474void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2479 Value *CondEvaluated = findConditionEquivalence(
Cond);
2480 if (!CondEvaluated) {
2482 SmallPtrSet<Value *, 4> Visited;
2483 auto Res = performSymbolicEvaluation(
I, Visited);
2485 CondEvaluated =
CE->getConstantValue();
2486 addAdditionalUsers(Res,
I);
2490 Res.ExtraDep =
nullptr;
2493 CondEvaluated =
Cond;
2500 <<
" evaluated to true\n");
2501 updateReachableEdge(
B, TrueSucc);
2502 }
else if (CI->
isZero()) {
2504 <<
" evaluated to false\n");
2505 updateReachableEdge(
B, FalseSucc);
2508 updateReachableEdge(
B, TrueSucc);
2509 updateReachableEdge(
B, FalseSucc);
2515 Value *SwitchCond =
SI->getCondition();
2516 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2521 auto Case = *
SI->findCaseValue(CondVal);
2522 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2526 updateReachableEdge(
B,
SI->getDefaultDest());
2530 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2531 updateReachableEdge(
B, TargetBlock);
2533 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2534 updateReachableEdge(
B, TargetBlock);
2540 updateReachableEdge(
B, TargetBlock);
2545 auto *MA = getMemoryAccess(TI);
2547 auto *CC = ensureLeaderOfMemoryClass(MA);
2548 if (setMemoryClass(MA, CC))
2549 markMemoryUsersTouched(MA);
2555void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2556 InstrDFS.
erase(PHITemp);
2559 TempToBlock.
erase(PHITemp);
2568void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2569 Instruction *ExistingValue) {
2570 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2572 TempToBlock[
Op] = BB;
2573 RealToTemp[ExistingValue] =
Op;
2576 for (
auto *U : ExistingValue->
users())
2582 if (!Opts.enable_phi_of_ops)
2595bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2596 SmallPtrSetImpl<const Value *> &Visited) {
2597 SmallVector<Value *, 4> Worklist;
2599 while (!Worklist.
empty()) {
2604 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2605 if (OISIt != OpSafeForPHIOfOps.
end())
2606 return OISIt->second;
2611 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2616 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2627 if (OrigI->mayReadFromMemory())
2631 for (
auto *
Op : OrigI->operand_values()) {
2635 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2636 if (OISIt != OpSafeForPHIOfOps.
end()) {
2637 if (!OISIt->second) {
2638 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2648 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2657Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2658 SmallPtrSetImpl<Value *> &Visited,
2659 MemoryAccess *MemAccess, Instruction *OrigInst,
2660 BasicBlock *PredBB) {
2661 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2663 AllTempInstructions.
insert(TransInst);
2667 TempToBlock.
insert({TransInst, PredBB});
2668 InstrDFS.
insert({TransInst, IDFSNum});
2670 auto Res = performSymbolicEvaluation(TransInst, Visited);
2672 addAdditionalUsers(Res, OrigInst);
2673 InstrDFS.
erase(TransInst);
2674 AllTempInstructions.
erase(TransInst);
2675 TempToBlock.
erase(TransInst);
2677 TempToMemory.
erase(TransInst);
2680 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2682 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2683 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2688 FoundVal =
SI->getValueOperand();
2695NewGVN::makePossiblePHIOfOps(Instruction *
I,
2696 SmallPtrSetImpl<Value *> &Visited) {
2700 if (!Visited.
insert(
I).second)
2706 if (!isCycleFree(
I))
2712 auto *MemAccess = getMemoryAccess(
I);
2716 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2721 SmallPtrSet<const Value *, 10> VisitedOps;
2722 SmallVector<Value *, 4>
Ops(
I->operand_values());
2724 PHINode *OpPHI =
nullptr;
2727 for (
auto *
Op :
Ops) {
2729 auto *ValuePHI = RealToTemp.
lookup(
Op);
2736 if (!SamePHIBlock) {
2737 SamePHIBlock = getBlockForValue(OpPHI);
2738 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2741 <<
"PHIs for operands are not all in the same block, aborting\n");
2755 SmallPtrSet<Value *, 4> Deps;
2756 auto *PHIBlock = getBlockForValue(OpPHI);
2757 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2758 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2760 Value *FoundVal =
nullptr;
2761 SmallPtrSet<Value *, 4> CurrentDeps;
2764 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2772 TempToMemory.
insert({ValueOp, MemAccess});
2773 bool SafeForPHIOfOps =
true;
2776 auto *OrigOp = &*
Op;
2780 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2781 if (
Op != OrigOp &&
Op !=
I)
2783 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2784 if (getBlockForValue(ValuePHI) == PHIBlock)
2785 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2790 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2797 FoundVal = !SafeForPHIOfOps ? nullptr
2798 : findLeaderForInst(ValueOp, Visited,
2799 MemAccess,
I, PredBB);
2804 if (SafeForPHIOfOps)
2805 for (
auto *Dep : CurrentDeps)
2806 addAdditionalUsers(Dep,
I);
2812 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2814 <<
" because the block is unreachable\n");
2816 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2820 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2823 for (
auto *Dep : Deps)
2824 addAdditionalUsers(Dep,
I);
2826 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2830 <<
"Not creating real PHI of ops because it simplified to existing "
2831 "value or constant\n");
2837 for (
auto &O : PHIOps)
2838 addAdditionalUsers(
O.first,
I);
2842 auto *ValuePHI = RealToTemp.
lookup(
I);
2843 bool NewPHI =
false;
2847 addPhiOfOps(ValuePHI, PHIBlock,
I);
2849 NumGVNPHIOfOpsCreated++;
2852 for (
auto PHIOp : PHIOps)
2853 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2855 TempToBlock[ValuePHI] = PHIBlock;
2857 for (
auto PHIOp : PHIOps) {
2858 ValuePHI->setIncomingValue(i, PHIOp.first);
2859 ValuePHI->setIncomingBlock(i, PHIOp.second);
2863 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2864 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2873void NewGVN::initializeCongruenceClasses(
Function &
F) {
2874 NextCongruenceNum = 0;
2884 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2890 for (
auto *DTN :
nodes(DT)) {
2897 if (MemoryBlockDefs)
2898 for (
const auto &Def : *MemoryBlockDefs) {
2899 MemoryAccessToClass[&
Def] = TOPClass;
2904 TOPClass->memory_insert(MP);
2905 MemoryPhiState.
insert({MP, MPS_TOP});
2909 TOPClass->incStoreCount();
2915 for (
auto &
I : *BB) {
2917 for (
auto *U :
I.users())
2920 PHINodeUses.
insert(UInst);
2923 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2925 TOPClass->insert(&
I);
2926 ValueToClass[&
I] = TOPClass;
2931 for (
auto &FA :
F.args())
2932 createSingletonCongruenceClass(&FA);
2935void NewGVN::cleanupTables() {
2936 for (CongruenceClass *&CC : CongruenceClasses) {
2937 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2938 << CC->size() <<
" members\n");
2946 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2947 AllTempInstructions.
end());
2948 AllTempInstructions.
clear();
2952 for (
auto *
I : TempInst) {
2953 I->dropAllReferences();
2956 while (!TempInst.empty()) {
2957 auto *
I = TempInst.pop_back_val();
2961 ValueToClass.
clear();
2962 ArgRecycler.
clear(ExpressionAllocator);
2963 ExpressionAllocator.Reset();
2964 CongruenceClasses.clear();
2965 ExpressionToClass.clear();
2966 ValueToExpression.
clear();
2968 AdditionalUsers.
clear();
2969 ExpressionToPhiOfOps.
clear();
2970 TempToBlock.
clear();
2971 TempToMemory.
clear();
2972 PHINodeUses.
clear();
2973 OpSafeForPHIOfOps.
clear();
2974 ReachableBlocks.
clear();
2975 ReachableEdges.
clear();
2977 ProcessedCount.
clear();
2980 InstructionsToErase.
clear();
2982 BlockInstRange.
clear();
2983 TouchedInstructions.
clear();
2984 MemoryAccessToClass.
clear();
2985 PredicateToUsers.
clear();
2986 MemoryToUsers.
clear();
2987 RevisitOnReachabilityChange.
clear();
2988 PredicateSwapChoice.
clear();
2993std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
2996 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
2997 InstrDFS[MemPhi] =
End++;
3002 for (
auto &
I : *
B) {
3008 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3010 markInstructionForDeletion(&
I);
3014 RevisitOnReachabilityChange[
B].set(
End);
3015 InstrDFS[&
I] =
End++;
3022 return std::make_pair(Start,
End);
3025void NewGVN::updateProcessedCount(
const Value *V) {
3027 assert(++ProcessedCount[V] < 100 &&
3028 "Seem to have processed the same Value a lot");
3033void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3040 return cast<MemoryAccess>(U) != MP &&
3041 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3042 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3047 if (Filtered.begin() == Filtered.end()) {
3048 if (setMemoryClass(MP, TOPClass))
3049 markMemoryUsersTouched(MP);
3055 auto LookupFunc = [&](
const Use &
U) {
3058 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3059 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3063 const auto *AllSameValue = *MappedBegin;
3065 bool AllEqual = std::all_of(
3066 MappedBegin, MappedEnd,
3067 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3070 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3079 CongruenceClass *CC =
3080 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3081 auto OldState = MemoryPhiState.
lookup(MP);
3082 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3083 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3084 MemoryPhiState[MP] = NewState;
3085 if (setMemoryClass(MP, CC) || OldState != NewState)
3086 markMemoryUsersTouched(MP);
3091void NewGVN::valueNumberInstruction(Instruction *
I) {
3093 if (!
I->isTerminator()) {
3095 SmallPtrSet<Value *, 2> Visited;
3097 auto Res = performSymbolicEvaluation(
I, Visited);
3098 Symbolized = Res.Expr;
3099 addAdditionalUsers(Res,
I);
3104 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3109 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3110 removePhiOfOps(
I,
Op);
3119 if (Symbolized ==
nullptr)
3120 Symbolized = createUnknownExpression(
I);
3121 performCongruenceFinding(
I, Symbolized);
3126 if (!
I->getType()->isVoidTy()) {
3127 auto *Symbolized = createUnknownExpression(
I);
3128 performCongruenceFinding(
I, Symbolized);
3130 processOutgoingEdges(
I,
I->getParent());
3136bool NewGVN::singleReachablePHIPath(
3137 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3138 const MemoryAccess *Second)
const {
3139 if (
First == Second)
3152 const auto *EndDef =
First;
3154 if (ChainDef == Second)
3161 auto ReachableOperandPred = [&](
const Use &
U) {
3164 auto FilteredPhiArgs =
3178void NewGVN::verifyMemoryCongruency()
const {
3181 for (
const auto *CC : CongruenceClasses) {
3182 if (CC == TOPClass || CC->isDead())
3184 if (CC->getStoreCount() != 0) {
3186 "Any class with a store as a leader should have a "
3187 "representative stored value");
3188 assert(CC->getMemoryLeader() &&
3189 "Any congruence class with a store should have a "
3190 "representative access");
3193 if (CC->getMemoryLeader())
3194 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3195 "Representative MemoryAccess does not appear to be reverse "
3197 for (
const auto *M : CC->memory())
3199 "Memory member does not appear to be reverse mapped properly");
3207 auto ReachableAccessPred =
3208 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3209 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3211 MemoryToDFSNum(Pair.first) == 0)
3219 for (
const auto &U : MemPHI->incoming_values()) {
3232 for (
auto KV : Filtered) {
3235 if (FirstMUD && SecondMUD) {
3236 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3237 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3238 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3239 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3240 "The instructions for these memory operations should have "
3241 "been in the same congruence class or reachable through"
3242 "a single argument phi");
3247 auto ReachableOperandPred = [&](
const Use &
U) {
3248 return ReachableEdges.
count(
3249 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3253 auto FilteredPhiArgs =
3256 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3257 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3258 const MemoryDef *MD = cast<MemoryDef>(U);
3259 return ValueToClass.lookup(MD->getMemoryInst());
3262 "All MemoryPhi arguments should be in the same class");
3271void NewGVN::verifyIterationSettled(
Function &
F) {
3281 std::map<const Value *, CongruenceClass> BeforeIteration;
3283 for (
auto &KV : ValueToClass) {
3286 if (InstrToDFSNum(
I) == 0)
3288 BeforeIteration.insert({KV.first, *KV.second});
3291 TouchedInstructions.
set();
3292 TouchedInstructions.
reset(0);
3293 OpSafeForPHIOfOps.
clear();
3295 iterateTouchedInstructions();
3296 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3298 for (
const auto &KV : ValueToClass) {
3301 if (InstrToDFSNum(
I) == 0)
3305 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3306 auto *AfterCC = KV.second;
3309 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3310 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3311 "Value number changed after main loop completed!");
3312 EqualClasses.
insert({BeforeCC, AfterCC});
3323void NewGVN::verifyStoreExpressions()
const {
3328 std::pair<
const Value *,
3329 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3331 for (
const auto &KV : ExpressionToClass) {
3334 auto Res = StoreExpressionSet.insert(
3335 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3336 SE->getStoredValue())});
3337 bool Okay = Res.second;
3342 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3343 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3344 lookupOperandLeader(SE->getStoredValue()));
3345 assert(Okay &&
"Stored expression conflict exists in expression table");
3346 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3347 assert(ValueExpr && ValueExpr->equals(*SE) &&
3348 "StoreExpression in ExpressionToClass is not latest "
3349 "StoreExpression for value");
3358void NewGVN::iterateTouchedInstructions() {
3361 int FirstInstr = TouchedInstructions.
find_first();
3363 if (FirstInstr == -1)
3365 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3366 while (TouchedInstructions.
any()) {
3372 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3376 if (InstrNum == 0) {
3377 TouchedInstructions.
reset(InstrNum);
3381 Value *
V = InstrFromDFSNum(InstrNum);
3382 const BasicBlock *CurrBlock = getBlockForValue(V);
3385 if (CurrBlock != LastBlock) {
3386 LastBlock = CurrBlock;
3387 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3388 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3391 if (!BlockReachable) {
3392 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3395 <<
" because it is unreachable\n");
3400 updateProcessedCount(CurrBlock);
3404 TouchedInstructions.
reset(InstrNum);
3408 valueNumberMemoryPhi(MP);
3410 valueNumberInstruction(
I);
3414 updateProcessedCount(V);
3417 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3421bool NewGVN::runGVN() {
3425 NumFuncArgs =
F.arg_size();
3427 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3431 unsigned ICount = 1;
3437 ReversePostOrderTraversal<Function *> RPOT(&
F);
3438 unsigned Counter = 0;
3439 for (BasicBlock *
B : RPOT) {
3441 assert(Node &&
"RPO and Dominator tree should have same reachability");
3442 RPOOrdering[
Node] = ++Counter;
3443 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3444 BlockInstRange.
insert({
B, BlockRange});
3445 ICount += BlockRange.second - BlockRange.first;
3447 initializeCongruenceClasses(
F);
3449 TouchedInstructions.
resize(ICount);
3453 ExpressionToClass.reserve(ICount);
3456 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3457 TouchedInstructions.
set(InstRange.first, InstRange.second);
3459 <<
" marked reachable\n");
3460 ReachableBlocks.
insert(&
F.getEntryBlock());
3464 iterateTouchedInstructions();
3465 verifyMemoryCongruency();
3466 verifyIterationSettled(
F);
3467 verifyStoreExpressions();
3469 Changed |= eliminateInstructions(
F);
3472 for (Instruction *ToErase : InstructionsToErase) {
3473 if (!ToErase->use_empty())
3476 assert(ToErase->getParent() &&
3477 "BB containing ToErase deleted unexpectedly!");
3478 ToErase->eraseFromParent();
3480 Changed |= !InstructionsToErase.empty();
3483 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3484 return !ReachableBlocks.
count(&BB);
3489 <<
" is unreachable\n");
3490 deleteInstructionsInBlock(&BB);
3559void NewGVN::convertClassToDFSOrdered(
3568 assert(BB &&
"Should have figured out a basic block for value");
3577 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3579 VDDef.Def.setPointer(Leader);
3581 VDDef.Def.setPointer(
SI->getValueOperand());
3582 VDDef.Def.setInt(
true);
3585 VDDef.Def.setPointer(
D);
3588 "The dense set member should always be an instruction");
3593 if (
auto *PN = RealToTemp.
lookup(Def)) {
3597 VDDef.Def.setInt(
false);
3598 VDDef.Def.setPointer(PN);
3604 unsigned int UseCount = 0;
3606 for (
auto &U :
Def->uses()) {
3609 if (InstructionsToErase.count(
I))
3615 IBlock =
P->getIncomingBlock(U);
3620 IBlock = getBlockForValue(
I);
3626 if (!ReachableBlocks.
contains(IBlock))
3642 ProbablyDead.
insert(Def);
3644 UseCounts[
Def] = UseCount;
3650void NewGVN::convertClassToLoadsAndStores(
3651 const CongruenceClass &
Dense,
3652 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3662 VD.Def.setPointer(
D);
3676 I->replaceAllUsesWith(Repl);
3679void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3681 ++NumGVNBlocksDeleted;
3685 auto StartPoint = BB->
rbegin();
3698 ++NumGVNInstrDeleted;
3708void NewGVN::markInstructionForDeletion(Instruction *
I) {
3710 InstructionsToErase.insert(
I);
3713void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3718 markInstructionForDeletion(
I);
3725class ValueDFSStack {
3727 Value *
back()
const {
return ValueStack.back(); }
3728 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3730 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3731 ValueStack.emplace_back(V);
3732 DFSStack.emplace_back(DFSIn, DFSOut);
3735 bool empty()
const {
return DFSStack.empty(); }
3737 bool isInScope(
int DFSIn,
int DFSOut)
const {
3740 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3743 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3746 assert(ValueStack.size() == DFSStack.size() &&
3747 "Mismatch between ValueStack and DFSStack");
3749 !DFSStack.empty() &&
3750 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3751 DFSStack.pop_back();
3752 ValueStack.pop_back();
3757 SmallVector<Value *, 8> ValueStack;
3764CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3766 return ValueToClass.lookup(VE->getVariableValue());
3769 return ExpressionToClass.lookup(
E);
3775 const Instruction *OrigInst,
3776 const BasicBlock *BB)
const {
3779 return CE->getConstantValue();
3781 auto *
V = VE->getVariableValue();
3783 return VE->getVariableValue();
3786 auto *CC = getClassForExpression(
E);
3790 return CC->getLeader();
3792 for (
auto *Member : *CC) {
3794 if (MemberInst == OrigInst)
3799 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3805bool NewGVN::eliminateInstructions(
Function &
F) {
3829 bool AnythingReplaced =
false;
3837 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3838 for (
auto &Operand :
PHI->incoming_values())
3839 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3843 <<
" with poison due to it being unreachable\n");
3856 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3857 for (
auto &KV : ReachableEdges)
3858 ReachablePredCount[KV.getEnd()]++;
3859 for (
auto &BBPair : RevisitOnReachabilityChange) {
3860 for (
auto InstNum : BBPair.second) {
3861 auto *Inst = InstrFromDFSNum(InstNum);
3866 auto *BB = BBPair.first;
3867 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3868 ReplaceUnreachablePHIArgs(
PHI, BB);
3873 DenseMap<const Value *, unsigned int> UseCounts;
3874 for (
auto *CC :
reverse(CongruenceClasses)) {
3875 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3880 SmallPtrSet<Instruction *, 8> ProbablyDead;
3881 if (CC->isDead() || CC->empty())
3884 if (CC == TOPClass) {
3885 for (
auto *M : *CC) {
3886 auto *VTE = ValueToExpression.
lookup(M);
3891 "Everything in TOP should be unreachable or dead at this "
3897 assert(CC->getLeader() &&
"We should have had a leader");
3903 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3905 CongruenceClass::MemberSet MembersLeft;
3906 for (
auto *M : *CC) {
3910 Member->getType()->isVoidTy()) {
3911 MembersLeft.
insert(Member);
3915 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3916 << *Member <<
"\n");
3918 assert(Leader !=
I &&
"About to accidentally remove our leader");
3919 replaceInstruction(
I, Leader);
3920 AnythingReplaced =
true;
3922 CC->swap(MembersLeft);
3925 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3930 ValueDFSStack EliminationStack;
3934 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3938 for (
auto &VD : DFSOrderedSet) {
3939 int MemberDFSIn = VD.
DFSIn;
3940 int MemberDFSOut = VD.
DFSOut;
3942 bool FromStore = VD.Def.getInt();
3945 if (Def &&
Def->getType()->isVoidTy())
3948 if (DefInst && AllTempInstructions.
count(DefInst)) {
3954 AllTempInstructions.
erase(PN);
3955 auto *DefBlock = getBlockForValue(Def);
3959 PN->insertBefore(DefBlock->begin());
3961 NumGVNPHIOfOpsEliminations++;
3964 if (EliminationStack.empty()) {
3968 << EliminationStack.dfs_back().first <<
","
3969 << EliminationStack.dfs_back().second <<
")\n");
3972 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
3973 << MemberDFSOut <<
")\n");
3987 bool ShouldPush =
Def && EliminationStack.empty();
3989 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
3991 if (OutOfScope || ShouldPush) {
3993 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
3994 bool ShouldPush =
Def && EliminationStack.empty();
3996 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4016 if (!EliminationStack.empty() && DefI && !FromStore) {
4017 Value *DominatingLeader = EliminationStack.back();
4018 if (DominatingLeader != Def) {
4026 for (
auto *DVR : DVRUsers)
4027 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4029 markInstructionForDeletion(DefI);
4038 "Current def should have been an instruction");
4040 "Current user should have been an instruction");
4047 if (InstructionsToErase.count(InstUse)) {
4048 auto &UseCount = UseCounts[
U->get()];
4049 if (--UseCount == 0) {
4056 if (EliminationStack.empty())
4059 Value *DominatingLeader = EliminationStack.back();
4063 if (BC->getType() == BC->getOperand(0)->getType() &&
4064 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4066 DominatingLeader = BC->getOperand(0);
4071 if (
U->get() == DominatingLeader)
4078 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4079 if (!PI || DominatingLeader != PI->OriginalOp)
4083 <<
"Found replacement " << *DominatingLeader <<
" for "
4084 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4085 U->set(DominatingLeader);
4088 auto &LeaderUseCount = UseCounts[DominatingLeader];
4095 auto It = UseCounts.
find(SSACopy);
4096 if (It != UseCounts.
end()) {
4097 unsigned &IIUseCount = It->second;
4098 if (--IIUseCount == 0)
4099 ProbablyDead.
insert(SSACopy);
4103 AnythingReplaced =
true;
4110 for (
auto *
I : ProbablyDead)
4112 markInstructionForDeletion(
I);
4115 CongruenceClass::MemberSet MembersLeft;
4116 for (
auto *Member : *CC)
4119 MembersLeft.
insert(Member);
4120 CC->swap(MembersLeft);
4123 if (CC->getStoreCount() > 0) {
4124 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4126 ValueDFSStack EliminationStack;
4127 for (
auto &VD : PossibleDeadStores) {
4128 int MemberDFSIn = VD.
DFSIn;
4129 int MemberDFSOut = VD.
DFSOut;
4131 if (EliminationStack.empty() ||
4132 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4134 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4135 if (EliminationStack.empty()) {
4136 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4143 assert(!EliminationStack.empty());
4149 <<
" that is dominated by " << *Leader <<
"\n");
4150 markInstructionForDeletion(Member);
4156 return AnythingReplaced;
4164unsigned int NewGVN::getRank(
const Value *V)
const {
4179 return 4 +
A->getArgNo();
4183 unsigned Result = InstrToDFSNum(V);
4185 return 5 + NumFuncArgs +
Result;
4192bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4196 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4199bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4200 const BitCastInst *
I)
const {
4201 if (shouldSwapOperands(
A,
B)) {
4202 PredicateSwapChoice[
I] =
B;
4207 if (LookupResult != PredicateSwapChoice.
end()) {
4209 if (SeenPredicate) {
4211 if (SeenPredicate ==
B)
4231 NewGVN(Opts,
F, &DT, &AC, &TLI, &
AA, &MSSA,
F.getDataLayout()).runGVN();
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
const ScalarOptions & getScalarOptions(const LLVMContext &C)
bool isa_and_nonnull(const Y &Val)
constexpr auto equal_to(T &&Arg)
Functor variant of std::equal_to that can be used as a UnaryPredicate in functional algorithms like a...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
LLVM_ABI Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, FastMathFlags FMF, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
@ End
Run the machine verifier once, at the end of the pipeline.
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