128#define DEBUG_TYPE "newgvn"
130STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
131STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
132STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
133STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
135 "Maximum Number of iterations it took to converge GVN");
136STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
137STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
139 "Number of avoided sorted leader changes");
140STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
141STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
143 "Number of things eliminated using PHI of ops");
145 "Controls which instructions are value numbered");
147 "Controls which instructions we create phi of ops for");
188 TarjanSCC() : Components(1) {}
190 void Start(
const Instruction *Start) {
191 if (Root.lookup(Start) == 0)
195 const SmallPtrSetImpl<const Value *> &getComponentFor(
const Value *V)
const {
196 unsigned ComponentID = ValueToComponent.lookup(V);
199 "Asking for a component for a value we never processed");
200 return Components[ComponentID];
204 void FindSCC(
const Instruction *
I) {
207 unsigned int OurDFS = DFSNum;
208 for (
const auto &
Op :
I->operands()) {
210 if (Root.lookup(
Op) == 0)
212 if (!InComponent.count(
Op))
213 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
220 if (Root.lookup(
I) == OurDFS) {
221 unsigned ComponentID = Components.size();
222 Components.resize(Components.size() + 1);
226 InComponent.insert(
I);
227 ValueToComponent[
I] = ComponentID;
229 while (!Stack.empty() && Root.lookup(Stack.back()) >= OurDFS) {
230 auto *
Member = Stack.back();
233 InComponent.insert(Member);
234 ValueToComponent[
Member] = ComponentID;
243 unsigned int DFSNum = 1;
244 SmallPtrSet<const Value *, 8> InComponent;
245 DenseMap<const Value *, unsigned int> Root;
246 SmallVector<const Value *, 8> Stack;
252 DenseMap<const Value *, unsigned> ValueToComponent;
293class CongruenceClass {
295 using MemberType =
Value;
296 using MemberSet = SmallPtrSet<MemberType *, 4>;
297 using MemoryMemberType = MemoryPhi;
298 using MemoryMemberSet = SmallPtrSet<const MemoryMemberType *, 2>;
300 explicit CongruenceClass(
unsigned ID) : ID(ID) {}
301 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
303 : ID(ID), RepLeader(Leader), DefiningExpr(
E) {}
305 unsigned getID()
const {
return ID; }
312 return empty() && memory_empty();
316 Value *getLeader()
const {
return RepLeader.first; }
317 void setLeader(std::pair<Value *, unsigned int> Leader) {
320 const std::pair<Value *, unsigned int> &getNextLeader()
const {
323 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
324 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
325 if (LeaderPair.second < RepLeader.second) {
326 NextLeader = RepLeader;
327 RepLeader = LeaderPair;
329 }
else if (LeaderPair.second < NextLeader.second) {
330 NextLeader = LeaderPair;
336 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
337 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
338 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
341 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
344 bool empty()
const {
return Members.empty(); }
345 unsigned size()
const {
return Members.size(); }
348 void insert(MemberType *M) { Members.insert(M); }
349 void erase(MemberType *M) { Members.erase(M); }
353 bool memory_empty()
const {
return MemoryMembers.empty(); }
354 unsigned memory_size()
const {
return MemoryMembers.size(); }
356 return MemoryMembers.begin();
359 return MemoryMembers.end();
362 return make_range(memory_begin(), memory_end());
365 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
366 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
369 unsigned getStoreCount()
const {
return StoreCount; }
370 void incStoreCount() { ++StoreCount; }
371 void decStoreCount() {
372 assert(StoreCount != 0 &&
"Store count went negative");
377 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
381 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
387 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
389 Other->RepMemoryAccess))
391 if (DefiningExpr !=
Other->DefiningExpr)
392 if (!DefiningExpr || !
Other->DefiningExpr ||
393 *DefiningExpr != *
Other->DefiningExpr)
396 if (Members.size() !=
Other->Members.size())
407 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
412 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
415 Value *RepStoredValue =
nullptr;
419 const MemoryAccess *RepMemoryAccess =
nullptr;
422 const Expression *DefiningExpr =
nullptr;
430 MemoryMemberSet MemoryMembers;
437struct ExactEqualsExpression {
440 explicit ExactEqualsExpression(
const Expression &E) : E(E) {}
442 hash_code getComputedHash()
const {
return E.getComputedHash(); }
445 return E.exactlyEquals(
Other);
452 auto Val =
static_cast<uintptr_t
>(-1);
453 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
454 return reinterpret_cast<const Expression *
>(Val);
458 auto Val =
static_cast<uintptr_t
>(~1U);
459 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
460 return reinterpret_cast<const Expression *
>(Val);
464 return E->getComputedHash();
468 return E.getComputedHash();
487 if (LHS->getComputedHash() != RHS->getComputedHash())
509 mutable TarjanSCC SCCFinder;
511 std::unique_ptr<PredicateInfo> PredInfo;
515 unsigned int NumFuncArgs = 0;
526 CongruenceClass *TOPClass =
nullptr;
527 std::vector<CongruenceClass *> CongruenceClasses;
528 unsigned NextCongruenceNum = 0;
563 ExpressionToPhiOfOps;
612 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
613 DenseMap<const MemoryPhi *, MemoryPhiState> MemoryPhiState;
615 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
616 mutable DenseMap<const Instruction *, InstCycleState> InstCycleState;
619 using ExpressionClassMap = DenseMap<const Expression *, CongruenceClass *>;
620 ExpressionClassMap ExpressionToClass;
627 DeadExpression *SingletonDeadExpression =
nullptr;
630 SmallPtrSet<Value *, 8> LeaderChanges;
633 using BlockEdge = BasicBlockEdge;
634 DenseSet<BlockEdge> ReachableEdges;
635 SmallPtrSet<const BasicBlock *, 8> ReachableBlocks;
646 BitVector TouchedInstructions;
648 DenseMap<const BasicBlock *, std::pair<unsigned, unsigned>> BlockInstRange;
649 mutable DenseMap<const BitCastInst *, const Value *> PredicateSwapChoice;
653 DenseMap<const Value *, unsigned> ProcessedCount;
660 DenseMap<const Value *, unsigned> InstrDFS;
666 SmallPtrSet<Instruction *, 8> InstructionsToErase;
669 NewGVN(Function &
F, DominatorTree *DT, AssumptionCache *AC,
671 const DataLayout &
DL)
672 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
675 std::make_unique<PredicateInfo>(
F, *DT, *AC, ExpressionAllocator)),
676 SQ(
DL, TLI, DT, AC, nullptr,
false,
684 const Expression *Expr;
686 const PredicateBase *PredDep;
688 ExprResult(
const Expression *Expr,
Value *ExtraDep =
nullptr,
689 const PredicateBase *PredDep =
nullptr)
690 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
691 ExprResult(
const ExprResult &) =
delete;
692 ExprResult(ExprResult &&
Other)
694 Other.Expr =
nullptr;
695 Other.ExtraDep =
nullptr;
696 Other.PredDep =
nullptr;
698 ExprResult &operator=(
const ExprResult &
Other) =
delete;
699 ExprResult &operator=(ExprResult &&
Other) =
delete;
701 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
703 operator bool()
const {
return Expr; }
705 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
706 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
707 return {Expr, ExtraDep,
nullptr};
709 static ExprResult some(
const Expression *Expr,
710 const PredicateBase *PredDep) {
711 return {Expr,
nullptr, PredDep};
713 static ExprResult some(
const Expression *Expr,
Value *ExtraDep,
714 const PredicateBase *PredDep) {
715 return {Expr, ExtraDep, PredDep};
720 ExprResult createExpression(Instruction *)
const;
721 const Expression *createBinaryExpression(
unsigned,
Type *,
Value *,
Value *,
722 Instruction *)
const;
726 using ValPair = std::pair<Value *, BasicBlock *>;
729 BasicBlock *,
bool &HasBackEdge,
730 bool &OriginalOpsConstant)
const;
731 const DeadExpression *createDeadExpression()
const;
732 const VariableExpression *createVariableExpression(
Value *)
const;
733 const ConstantExpression *createConstantExpression(Constant *)
const;
734 const Expression *createVariableOrConstant(
Value *V)
const;
735 const UnknownExpression *createUnknownExpression(Instruction *)
const;
736 const StoreExpression *createStoreExpression(StoreInst *,
737 const MemoryAccess *)
const;
738 LoadExpression *createLoadExpression(
Type *,
Value *, LoadInst *,
739 const MemoryAccess *)
const;
740 const CallExpression *createCallExpression(CallInst *,
741 const MemoryAccess *)
const;
742 const AggregateValueExpression *
743 createAggregateValueExpression(Instruction *)
const;
744 bool setBasicExpressionInfo(Instruction *, BasicExpression *)
const;
747 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
750 unsigned LeaderDFS = 0;
758 LeaderDFS = InstrToDFSNum(
I);
760 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
761 CongruenceClasses.emplace_back(result);
765 CongruenceClass *createMemoryClass(MemoryAccess *MA) {
766 auto *CC = createCongruenceClass(
nullptr,
nullptr);
767 CC->setMemoryLeader(MA);
771 CongruenceClass *ensureLeaderOfMemoryClass(MemoryAccess *MA) {
772 auto *CC = getMemoryClass(MA);
773 if (CC->getMemoryLeader() != MA)
774 CC = createMemoryClass(MA);
778 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
779 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
780 CClass->insert(Member);
781 ValueToClass[
Member] = CClass;
785 void initializeCongruenceClasses(Function &
F);
786 const Expression *makePossiblePHIOfOps(Instruction *,
787 SmallPtrSetImpl<Value *> &);
788 Value *findLeaderForInst(Instruction *ValueOp,
789 SmallPtrSetImpl<Value *> &Visited,
790 MemoryAccess *MemAccess, Instruction *OrigInst,
792 bool OpIsSafeForPHIOfOps(
Value *
Op,
const BasicBlock *PHIBlock,
793 SmallPtrSetImpl<const Value *> &);
794 void addPhiOfOps(PHINode *
Op, BasicBlock *BB, Instruction *ExistingValue);
795 void removePhiOfOps(Instruction *
I, PHINode *PHITemp);
798 void valueNumberMemoryPhi(MemoryPhi *);
799 void valueNumberInstruction(Instruction *);
802 ExprResult checkExprResults(Expression *, Instruction *,
Value *)
const;
803 ExprResult performSymbolicEvaluation(Instruction *,
804 SmallPtrSetImpl<Value *> &)
const;
805 const Expression *performSymbolicLoadCoercion(
Type *,
Value *, LoadInst *,
807 MemoryAccess *)
const;
808 const Expression *performSymbolicLoadEvaluation(Instruction *)
const;
809 const Expression *performSymbolicStoreEvaluation(Instruction *)
const;
810 ExprResult performSymbolicCallEvaluation(Instruction *)
const;
814 BasicBlock *PHIBlock)
const;
815 const Expression *performSymbolicAggrValueEvaluation(Instruction *)
const;
816 ExprResult performSymbolicCmpEvaluation(Instruction *)
const;
817 ExprResult performSymbolicPredicateInfoEvaluation(BitCastInst *)
const;
820 bool someEquivalentDominates(
const Instruction *,
const Instruction *)
const;
822 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
823 void performCongruenceFinding(Instruction *,
const Expression *);
824 void moveValueToNewCongruenceClass(Instruction *,
const Expression *,
825 CongruenceClass *, CongruenceClass *);
826 void moveMemoryToNewCongruenceClass(Instruction *, MemoryAccess *,
827 CongruenceClass *, CongruenceClass *);
828 Value *getNextValueLeader(CongruenceClass *)
const;
829 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
830 bool setMemoryClass(
const MemoryAccess *From, CongruenceClass *To);
831 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
832 const MemoryAccess *lookupMemoryLeader(
const MemoryAccess *)
const;
833 bool isMemoryAccessTOP(
const MemoryAccess *)
const;
836 unsigned int getRank(
const Value *)
const;
837 bool shouldSwapOperands(
const Value *,
const Value *)
const;
838 bool shouldSwapOperandsForPredicate(
const Value *,
const Value *,
839 const BitCastInst *
I)
const;
842 void updateReachableEdge(BasicBlock *, BasicBlock *);
843 void processOutgoingEdges(Instruction *, BasicBlock *);
844 Value *findConditionEquivalence(
Value *)
const;
848 void convertClassToDFSOrdered(
const CongruenceClass &,
849 SmallVectorImpl<ValueDFS> &,
850 DenseMap<const Value *, unsigned int> &,
851 SmallPtrSetImpl<Instruction *> &)
const;
852 void convertClassToLoadsAndStores(
const CongruenceClass &,
853 SmallVectorImpl<ValueDFS> &)
const;
855 bool eliminateInstructions(Function &);
856 void replaceInstruction(Instruction *,
Value *);
857 void markInstructionForDeletion(Instruction *);
858 void deleteInstructionsInBlock(BasicBlock *);
859 Value *findPHIOfOpsLeader(
const Expression *,
const Instruction *,
860 const BasicBlock *)
const;
863 template <
typename Map,
typename KeyType>
864 void touchAndErase(Map &,
const KeyType &);
865 void markUsersTouched(
Value *);
866 void markMemoryUsersTouched(
const MemoryAccess *);
867 void markMemoryDefTouched(
const MemoryAccess *);
868 void markPredicateUsersTouched(Instruction *);
869 void markValueLeaderChangeTouched(CongruenceClass *CC);
870 void markMemoryLeaderChangeTouched(CongruenceClass *CC);
871 void markPhiOfOpsChanged(
const Expression *
E);
872 void addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const;
873 void addAdditionalUsers(
Value *To,
Value *User)
const;
874 void addAdditionalUsers(ExprResult &Res, Instruction *User)
const;
877 void iterateTouchedInstructions();
880 void cleanupTables();
881 std::pair<unsigned, unsigned> assignDFSNumbers(BasicBlock *,
unsigned);
882 void updateProcessedCount(
const Value *V);
883 void verifyMemoryCongruency()
const;
884 void verifyIterationSettled(Function &
F);
885 void verifyStoreExpressions()
const;
886 bool singleReachablePHIPath(SmallPtrSet<const MemoryAccess *, 8> &,
887 const MemoryAccess *,
const MemoryAccess *)
const;
889 void deleteExpression(
const Expression *
E)
const;
890 MemoryUseOrDef *getMemoryAccess(
const Instruction *)
const;
891 MemoryPhi *getMemoryAccess(
const BasicBlock *)
const;
892 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
894 unsigned InstrToDFSNum(
const Value *V)
const {
896 return InstrDFS.
lookup(V);
899 unsigned InstrToDFSNum(
const MemoryAccess *MA)
const {
900 return MemoryToDFSNum(MA);
903 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
908 unsigned MemoryToDFSNum(
const Value *MA)
const {
910 "This should not be used with instructions");
916 bool isCycleFree(
const Instruction *)
const;
917 bool isBackedge(BasicBlock *From, BasicBlock *To)
const;
921 DebugCounter::CounterState StartingVNCounter;
930 return LHS.MemoryExpression::equals(
RHS);
952 return Call->getAttributes()
953 .intersectWith(Call->getContext(), RHS->Call->getAttributes())
973MemoryUseOrDef *NewGVN::getMemoryAccess(
const Instruction *
I)
const {
979MemoryPhi *NewGVN::getMemoryAccess(
const BasicBlock *BB)
const {
986 auto *Parent =
I->getParent();
989 Parent = TempToBlock.
lookup(V);
990 assert(Parent &&
"Every fake instruction should have a block");
995 assert(MP &&
"Should have been an instruction or a MemoryPhi");
996 return MP->getBlock();
1002void NewGVN::deleteExpression(
const Expression *
E)
const {
1012 if (BC->getType() == BC->getOperand(0)->getType())
1013 return BC->getOperand(0);
1032 return BlockInstRange.
lookup(
P1.second).first <
1033 BlockInstRange.
lookup(P2.second).first;
1050 const Instruction *
I,
1051 BasicBlock *PHIBlock,
1053 bool &OriginalOpsConstant)
const {
1058 E->setType(PHIOperands.
begin()->first->getType());
1059 E->setOpcode(Instruction::PHI);
1063 auto *BB =
P.second;
1067 if (!ReachableEdges.
count({BB, PHIBlock}))
1070 if (ValueToClass.
lookup(
P.first) == TOPClass)
1072 OriginalOpsConstant = OriginalOpsConstant &&
isa<Constant>(
P.first);
1073 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1074 return lookupOperandLeader(
P.first) !=
I;
1077 return lookupOperandLeader(
P.first);
1085 bool AllConstant =
true;
1087 E->setType(
GEP->getSourceElementType());
1089 E->setType(
I->getType());
1090 E->setOpcode(
I->getOpcode());
1091 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1096 auto Operand = lookupOperandLeader(O);
1104const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1106 Instruction *
I)
const {
1113 E->setOpcode(Opcode);
1114 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1120 if (shouldSwapOperands(Arg1, Arg2))
1123 E->op_push_back(lookupOperandLeader(Arg1));
1124 E->op_push_back(lookupOperandLeader(Arg2));
1127 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1128 addAdditionalUsers(Simplified,
I);
1137NewGVN::ExprResult NewGVN::checkExprResults(
Expression *
E, Instruction *
I,
1140 return ExprResult::none();
1145 <<
" constant " << *
C <<
"\n");
1146 NumGVNOpsSimplified++;
1148 "We should always have had a basic expression here");
1149 deleteExpression(
E);
1150 return ExprResult::some(createConstantExpression(
C));
1154 <<
" variable " << *V <<
"\n");
1155 deleteExpression(
E);
1156 return ExprResult::some(createVariableExpression(V));
1159 CongruenceClass *CC = ValueToClass.
lookup(V);
1161 if (CC->getLeader() && CC->getLeader() !=
I) {
1162 return ExprResult::some(createVariableOrConstant(CC->getLeader()), V);
1164 if (CC->getDefiningExpr()) {
1167 <<
" expression " << *CC->getDefiningExpr() <<
"\n");
1168 NumGVNOpsSimplified++;
1169 deleteExpression(
E);
1170 return ExprResult::some(CC->getDefiningExpr(), V);
1174 return ExprResult::none();
1180NewGVN::ExprResult NewGVN::createExpression(Instruction *
I)
const {
1186 bool AllConstant = setBasicExpressionInfo(
I,
E);
1188 if (
I->isCommutative()) {
1193 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1194 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1195 E->swapOperands(0, 1);
1202 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1203 E->swapOperands(0, 1);
1206 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1208 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1209 "Wrong types on cmp instruction");
1210 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1211 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1214 if (
auto Simplified = checkExprResults(
E,
I, V))
1218 E->getOperand(1) ==
E->getOperand(2)) {
1219 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1220 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1222 E->getOperand(2), Q);
1223 if (
auto Simplified = checkExprResults(
E,
I, V))
1226 }
else if (
I->isBinaryOp()) {
1229 if (
auto Simplified = checkExprResults(
E,
I, V))
1234 if (
auto Simplified = checkExprResults(
E,
I, V))
1238 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1239 GEPI->getNoWrapFlags(), Q);
1240 if (
auto Simplified = checkExprResults(
E,
I, V))
1242 }
else if (AllConstant) {
1251 for (
Value *Arg :
E->operands())
1255 if (
auto Simplified = checkExprResults(
E,
I, V))
1258 return ExprResult::some(
E);
1262NewGVN::createAggregateValueExpression(Instruction *
I)
const {
1264 auto *
E =
new (ExpressionAllocator)
1266 setBasicExpressionInfo(
I,
E);
1267 E->allocateIntOperands(ExpressionAllocator);
1271 auto *
E =
new (ExpressionAllocator)
1273 setBasicExpressionInfo(EI,
E);
1274 E->allocateIntOperands(ExpressionAllocator);
1284 return SingletonDeadExpression;
1295 return createConstantExpression(
C);
1296 return createVariableExpression(V);
1312NewGVN::createCallExpression(CallInst *CI,
const MemoryAccess *MA)
const {
1316 setBasicExpressionInfo(CI,
E);
1322 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1323 E->swapOperands(0, 1);
1329bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1330 const Instruction *U)
const {
1331 auto *CC = ValueToClass.
lookup(Inst);
1354 if (CC->getNextLeader().first &&
1358 return Member != CC->getLeader() &&
1365Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1366 CongruenceClass *CC = ValueToClass.
lookup(V);
1373 return CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
1379const MemoryAccess *NewGVN::lookupMemoryLeader(
const MemoryAccess *MA)
const {
1380 auto *CC = getMemoryClass(MA);
1381 assert(CC->getMemoryLeader() &&
1382 "Every MemoryAccess should be mapped to a congruence class with a "
1383 "representative memory access");
1384 return CC->getMemoryLeader();
1390bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1391 return getMemoryClass(MA) == TOPClass;
1396 const MemoryAccess *MA)
const {
1398 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1400 E->setType(LoadType);
1404 E->op_push_back(PointerOp);
1413NewGVN::createStoreExpression(StoreInst *SI,
const MemoryAccess *MA)
const {
1414 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1415 auto *
E =
new (ExpressionAllocator)
1418 E->setType(
SI->getValueOperand()->getType());
1422 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1430const Expression *NewGVN::performSymbolicStoreEvaluation(Instruction *
I)
const {
1434 auto *StoreAccess = getMemoryAccess(SI);
1436 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1440 StoreRHS = lookupMemoryLeader(StoreRHS);
1441 if (StoreRHS != StoreAccess->getDefiningAccess())
1442 addMemoryUsers(StoreRHS, StoreAccess);
1444 if (StoreRHS == StoreAccess)
1447 if (
SI->isSimple()) {
1451 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1452 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1458 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1466 LastStore->getOperand(0)) &&
1467 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1470 deleteExpression(LastStore);
1476 return createStoreExpression(SI, StoreAccess);
1482NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1483 LoadInst *LI, Instruction *DepInst,
1484 MemoryAccess *DefiningAccess)
const {
1490 if (LI->
isAtomic() > DepSI->isAtomic() ||
1491 LoadType == DepSI->getValueOperand()->getType())
1496 lookupOperandLeader(DepSI->getValueOperand()))) {
1499 <<
" to constant " << *Res <<
"\n");
1500 return createConstantExpression(Res);
1506 if (LI->
isAtomic() > DepLI->isAtomic())
1512 if (
auto *PossibleConstant =
1515 <<
" to constant " << *PossibleConstant <<
"\n");
1516 return createConstantExpression(PossibleConstant);
1522 if (
auto *PossibleConstant =
1525 <<
" to constant " << *PossibleConstant <<
"\n");
1526 return createConstantExpression(PossibleConstant);
1532 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
1533 auto *LifetimePtr =
II->getOperand(0);
1534 if (LoadPtr == lookupOperandLeader(LifetimePtr) ||
1543 (LoadPtr != lookupOperandLeader(DepInst) &&
1552 }
else if (
auto *InitVal =
1554 return createConstantExpression(InitVal);
1559const Expression *NewGVN::performSymbolicLoadEvaluation(Instruction *
I)
const {
1571 MemoryAccess *OriginalAccess = getMemoryAccess(
I);
1572 MemoryAccess *DefiningAccess =
1585 if (
const auto *CoercionResult =
1586 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1587 DefiningInst, DefiningAccess))
1588 return CoercionResult;
1592 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1596 if (
LE->getMemoryLeader() != DefiningAccess)
1597 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1602NewGVN::performSymbolicPredicateInfoEvaluation(BitCastInst *
I)
const {
1603 auto *PI = PredInfo->getPredicateInfoFor(
I);
1605 return ExprResult::none();
1607 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1609 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1611 return ExprResult::none();
1614 Value *CmpOp0 =
I->getOperand(0);
1615 Value *CmpOp1 = Constraint->OtherOp;
1617 Value *FirstOp = lookupOperandLeader(CmpOp0);
1618 Value *SecondOp = lookupOperandLeader(CmpOp1);
1619 Value *AdditionallyUsedValue = CmpOp0;
1622 if (shouldSwapOperandsForPredicate(FirstOp, SecondOp,
I)) {
1625 AdditionallyUsedValue = CmpOp1;
1629 return ExprResult::some(createVariableOrConstant(FirstOp),
1630 AdditionallyUsedValue, PI);
1635 return ExprResult::some(createConstantExpression(
cast<Constant>(FirstOp)),
1636 AdditionallyUsedValue, PI);
1638 return ExprResult::none();
1642NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *
I)
const {
1653 return ExprResult::none();
1659 return ExprResult::none();
1662 return ExprResult::some(
1663 createCallExpression(CI, TOPClass->getMemoryLeader()));
1667 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1669 return ExprResult::some(
1670 createCallExpression(CI, TOPClass->getMemoryLeader()));
1672 return ExprResult::none();
1676CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1678 assert(Result &&
"Should have found memory class");
1684bool NewGVN::setMemoryClass(
const MemoryAccess *From,
1685 CongruenceClass *NewClass) {
1687 "Every MemoryAccess should be getting mapped to a non-null class");
1691 <<
" with current MemoryAccess leader ");
1697 if (LookupResult != MemoryAccessToClass.
end()) {
1699 if (OldClass != NewClass) {
1702 OldClass->memory_erase(MP);
1703 NewClass->memory_insert(MP);
1705 if (OldClass->getMemoryLeader() == From) {
1706 if (OldClass->definesNoMemory()) {
1707 OldClass->setMemoryLeader(
nullptr);
1709 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1711 << OldClass->getID() <<
" to "
1712 << *OldClass->getMemoryLeader()
1713 <<
" due to removal of a memory member " << *From
1715 markMemoryLeaderChangeTouched(OldClass);
1732bool NewGVN::isCycleFree(
const Instruction *
I)
const {
1738 auto ICS = InstCycleState.
lookup(
I);
1739 if (ICS == ICS_Unknown) {
1741 auto &
SCC = SCCFinder.getComponentFor(
I);
1743 if (
SCC.size() == 1)
1744 InstCycleState.
insert({
I, ICS_CycleFree});
1749 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1750 for (
const auto *Member : SCC)
1752 InstCycleState.
insert({MemberPhi, ICS});
1755 if (ICS == ICS_Cycle)
1764 BasicBlock *PHIBlock)
const {
1766 bool HasBackedge =
false;
1771 bool OriginalOpsConstant =
true;
1773 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1777 bool HasUndef =
false, HasPoison =
false;
1779 if (isa<PoisonValue>(Arg)) {
1790 if (Filtered.empty()) {
1795 dbgs() <<
"PHI Node " << *
I
1796 <<
" has no non-undef arguments, valuing it as undef\n");
1801 dbgs() <<
"PHI Node " << *
I
1802 <<
" has no non-poison arguments, valuing it as poison\n");
1806 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1807 deleteExpression(
E);
1808 return createDeadExpression();
1810 Value *AllSameValue = *(Filtered.begin());
1828 if (HasPoison || HasUndef) {
1834 if (HasBackedge && !OriginalOpsConstant &&
1840 if (!someEquivalentDominates(AllSameInst,
I))
1847 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1849 NumGVNPhisAllSame++;
1850 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1852 deleteExpression(
E);
1853 return createVariableOrConstant(AllSameValue);
1859NewGVN::performSymbolicAggrValueEvaluation(Instruction *
I)
const {
1862 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1866 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1867 WO->getLHS(), WO->getRHS(),
I);
1870 return createAggregateValueExpression(
I);
1873NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(Instruction *
I)
const {
1879 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1880 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1881 auto OurPredicate = CI->getPredicate();
1882 if (shouldSwapOperands(Op0, Op1)) {
1884 OurPredicate = CI->getSwappedPredicate();
1888 const PredicateBase *LastPredInfo =
nullptr;
1891 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1893 return ExprResult::some(
1898 if (CI->isTrueWhenEqual())
1899 return ExprResult::some(
1901 else if (CI->isFalseWhenEqual())
1902 return ExprResult::some(
1932 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1934 if (PI == LastPredInfo)
1939 if (!DT->
dominates(PBranch->To,
I->getParent()))
1949 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1950 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1951 auto BranchPredicate = BranchCond->getPredicate();
1952 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1954 BranchPredicate = BranchCond->getSwappedPredicate();
1956 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1957 if (PBranch->TrueEdge) {
1963 return ExprResult::some(createConstantExpression(
C), PI);
1968 if (BranchPredicate == OurPredicate) {
1970 return ExprResult::some(
1973 }
else if (BranchPredicate ==
1976 return ExprResult::some(
1985 return createExpression(
I);
1990NewGVN::performSymbolicEvaluation(Instruction *
I,
1991 SmallPtrSetImpl<Value *> &Visited)
const {
1997 switch (
I->getOpcode()) {
1998 case Instruction::ExtractValue:
1999 case Instruction::InsertValue:
2000 E = performSymbolicAggrValueEvaluation(
I);
2002 case Instruction::PHI: {
2005 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
2006 Ops.push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2009 E = performSymbolicPHIEvaluation(
Ops,
I, getBlockForValue(
I));
2011 case Instruction::Call:
2012 return performSymbolicCallEvaluation(
I);
2014 case Instruction::Store:
2015 E = performSymbolicStoreEvaluation(
I);
2017 case Instruction::Load:
2018 E = performSymbolicLoadEvaluation(
I);
2020 case Instruction::BitCast:
2022 if (
I->getType() ==
I->getOperand(0)->getType())
2027 case Instruction::AddrSpaceCast:
2028 case Instruction::Freeze:
2029 return createExpression(
I);
2031 case Instruction::ICmp:
2032 case Instruction::FCmp:
2033 return performSymbolicCmpEvaluation(
I);
2035 case Instruction::FNeg:
2036 case Instruction::Add:
2037 case Instruction::FAdd:
2038 case Instruction::Sub:
2039 case Instruction::FSub:
2040 case Instruction::Mul:
2041 case Instruction::FMul:
2042 case Instruction::UDiv:
2043 case Instruction::SDiv:
2044 case Instruction::FDiv:
2045 case Instruction::URem:
2046 case Instruction::SRem:
2047 case Instruction::FRem:
2048 case Instruction::Shl:
2049 case Instruction::LShr:
2050 case Instruction::AShr:
2051 case Instruction::And:
2052 case Instruction::Or:
2053 case Instruction::Xor:
2054 case Instruction::Trunc:
2055 case Instruction::ZExt:
2056 case Instruction::SExt:
2057 case Instruction::FPToUI:
2058 case Instruction::FPToSI:
2059 case Instruction::UIToFP:
2060 case Instruction::SIToFP:
2061 case Instruction::FPTrunc:
2062 case Instruction::FPExt:
2063 case Instruction::PtrToInt:
2064 case Instruction::PtrToAddr:
2065 case Instruction::IntToPtr:
2066 case Instruction::Select:
2067 case Instruction::ExtractElement:
2068 case Instruction::InsertElement:
2069 case Instruction::GetElementPtr:
2070 return createExpression(
I);
2072 case Instruction::ShuffleVector:
2074 return ExprResult::none();
2076 return ExprResult::none();
2078 return ExprResult::some(
E);
2083template <
typename Map,
typename KeyType>
2084void NewGVN::touchAndErase(Map &M,
const KeyType &
Key) {
2086 if (Result !=
M.end()) {
2087 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2088 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2093void NewGVN::addAdditionalUsers(
Value *To,
Value *User)
const {
2094 assert(User && To != User);
2096 AdditionalUsers[To].
insert(User);
2099void NewGVN::addAdditionalUsers(ExprResult &Res, Instruction *User)
const {
2100 if (Res.ExtraDep && Res.ExtraDep != User)
2101 addAdditionalUsers(Res.ExtraDep, User);
2102 Res.ExtraDep =
nullptr;
2106 PredicateToUsers[PBranch->Condition].
insert(User);
2108 PredicateToUsers[PAssume->Condition].
insert(User);
2110 Res.PredDep =
nullptr;
2113void NewGVN::markUsersTouched(
Value *V) {
2115 for (
auto *User :
V->users()) {
2117 TouchedInstructions.
set(InstrToDFSNum(User));
2119 touchAndErase(AdditionalUsers, V);
2122void NewGVN::addMemoryUsers(
const MemoryAccess *To, MemoryAccess *U)
const {
2123 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2124 MemoryToUsers[To].
insert(U);
2127void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2128 TouchedInstructions.
set(MemoryToDFSNum(MA));
2131void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2134 for (
const auto *U : MA->
users())
2135 TouchedInstructions.
set(MemoryToDFSNum(U));
2136 touchAndErase(MemoryToUsers, MA);
2140void NewGVN::markPredicateUsersTouched(Instruction *
I) {
2141 touchAndErase(PredicateToUsers,
I);
2145void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *CC) {
2146 for (
const auto *M : CC->memory())
2147 markMemoryDefTouched(M);
2152void NewGVN::markValueLeaderChangeTouched(CongruenceClass *CC) {
2153 for (
auto *M : *CC) {
2155 TouchedInstructions.
set(InstrToDFSNum(
I));
2162template <
class T,
class Range>
2163T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2164 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2165 for (
const auto X : R) {
2166 auto DFSNum = InstrToDFSNum(
X);
2167 if (DFSNum < MinDFS.second)
2168 MinDFS = {
X, DFSNum};
2170 return MinDFS.first;
2176const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *CC)
const {
2180 assert(!CC->definesNoMemory() &&
"Can't get next leader if there is none");
2181 if (CC->getStoreCount() > 0) {
2183 return getMemoryAccess(NL);
2189 assert(CC->getStoreCount() == 0);
2193 if (CC->memory_size() == 1)
2194 return *CC->memory_begin();
2195 return getMinDFSOfRange<const MemoryPhi>(CC->memory());
2201Value *NewGVN::getNextValueLeader(CongruenceClass *CC)
const {
2206 if (CC->size() == 1 || CC == TOPClass) {
2207 return *(CC->begin());
2208 }
else if (CC->getNextLeader().first) {
2209 ++NumGVNAvoidedSortedLeaderChanges;
2210 return CC->getNextLeader().first;
2212 ++NumGVNSortedLeaderChanges;
2216 return getMinDFSOfRange<Value>(*CC);
2229void NewGVN::moveMemoryToNewCongruenceClass(Instruction *
I,
2230 MemoryAccess *InstMA,
2231 CongruenceClass *OldClass,
2232 CongruenceClass *NewClass) {
2235 assert((!InstMA || !OldClass->getMemoryLeader() ||
2236 OldClass->getLeader() !=
I ||
2237 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2238 MemoryAccessToClass.
lookup(InstMA)) &&
2239 "Representative MemoryAccess mismatch");
2241 if (!NewClass->getMemoryLeader()) {
2243 assert(NewClass->size() == 1 ||
2245 NewClass->setMemoryLeader(InstMA);
2248 << NewClass->getID()
2249 <<
" due to new memory instruction becoming leader\n");
2250 markMemoryLeaderChangeTouched(NewClass);
2252 setMemoryClass(InstMA, NewClass);
2254 if (OldClass->getMemoryLeader() == InstMA) {
2255 if (!OldClass->definesNoMemory()) {
2256 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2258 << OldClass->getID() <<
" to "
2259 << *OldClass->getMemoryLeader()
2260 <<
" due to removal of old leader " << *InstMA <<
"\n");
2261 markMemoryLeaderChangeTouched(OldClass);
2263 OldClass->setMemoryLeader(
nullptr);
2269void NewGVN::moveValueToNewCongruenceClass(Instruction *
I,
const Expression *
E,
2270 CongruenceClass *OldClass,
2271 CongruenceClass *NewClass) {
2272 if (
I == OldClass->getNextLeader().first)
2273 OldClass->resetNextLeader();
2276 NewClass->insert(
I);
2280 if (NewClass->getLeader() !=
I &&
2281 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2282 markValueLeaderChangeTouched(NewClass);
2287 OldClass->decStoreCount();
2295 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2299 NewClass->setStoredValue(SE->getStoredValue());
2300 markValueLeaderChangeTouched(NewClass);
2303 << NewClass->getID() <<
" from "
2304 << *NewClass->getLeader() <<
" to " << *SI
2305 <<
" because store joined class\n");
2308 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2312 NewClass->incStoreCount();
2320 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2321 ValueToClass[
I] = NewClass;
2323 if (OldClass->empty() && OldClass != TOPClass) {
2324 if (OldClass->getDefiningExpr()) {
2325 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2326 <<
" from table\n");
2329 auto Iter = ExpressionToClass.find_as(
2330 ExactEqualsExpression(*OldClass->getDefiningExpr()));
2331 if (Iter != ExpressionToClass.end())
2332 ExpressionToClass.erase(Iter);
2333#ifdef EXPENSIVE_CHECKS
2335 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2336 "We erased the expression we just inserted, which should not happen");
2339 }
else if (OldClass->getLeader() ==
I) {
2344 << OldClass->getID() <<
"\n");
2345 ++NumGVNLeaderChanges;
2350 if (OldClass->getStoreCount() == 0) {
2351 if (OldClass->getStoredValue())
2352 OldClass->setStoredValue(
nullptr);
2354 OldClass->setLeader({getNextValueLeader(OldClass),
2355 InstrToDFSNum(getNextValueLeader(OldClass))});
2356 OldClass->resetNextLeader();
2357 markValueLeaderChangeTouched(OldClass);
2363void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2364 touchAndErase(ExpressionToPhiOfOps,
E);
2368void NewGVN::performCongruenceFinding(Instruction *
I,
const Expression *
E) {
2372 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2373 assert(IClass &&
"Should have found a IClass");
2375 assert(!IClass->isDead() &&
"Found a dead class");
2377 CongruenceClass *EClass =
nullptr;
2379 EClass = ValueToClass.
lookup(VE->getVariableValue());
2384 auto lookupResult = ExpressionToClass.try_emplace(
E);
2387 if (lookupResult.second) {
2388 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2389 auto place = lookupResult.first;
2390 place->second = NewClass;
2394 NewClass->setLeader({
CE->getConstantValue(), 0});
2396 StoreInst *
SI = SE->getStoreInst();
2397 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2398 NewClass->setStoredValue(SE->getStoredValue());
2402 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2405 "VariableExpression should have been handled already");
2409 <<
" using expression " << *
E <<
" at "
2410 << NewClass->getID() <<
" and leader "
2411 << *(NewClass->getLeader()));
2412 if (NewClass->getStoredValue())
2414 << *(NewClass->getStoredValue()));
2417 EClass = lookupResult.first->second;
2420 (EClass->getStoredValue() &&
2422 "Any class with a constant expression should have a "
2425 assert(EClass &&
"Somehow don't have an eclass");
2427 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2430 bool ClassChanged = IClass != EClass;
2431 bool LeaderChanged = LeaderChanges.
erase(
I);
2432 if (ClassChanged || LeaderChanged) {
2433 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2436 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2437 markPhiOfOpsChanged(
E);
2440 markUsersTouched(
I);
2441 if (MemoryAccess *MA = getMemoryAccess(
I))
2442 markMemoryUsersTouched(MA);
2444 markPredicateUsersTouched(CI);
2451 auto *OldE = ValueToExpression.
lookup(
I);
2457 auto Iter = ExpressionToClass.find_as(ExactEqualsExpression(*OldE));
2458 if (Iter != ExpressionToClass.end())
2459 ExpressionToClass.erase(Iter);
2462 ValueToExpression[
I] =
E;
2467void NewGVN::updateReachableEdge(BasicBlock *From, BasicBlock *To) {
2469 if (ReachableEdges.
insert({From, To}).second) {
2471 if (ReachableBlocks.
insert(To).second) {
2473 <<
" marked reachable\n");
2474 const auto &InstRange = BlockInstRange.
lookup(To);
2475 TouchedInstructions.
set(InstRange.first, InstRange.second);
2478 <<
" was reachable, but new edge {"
2480 <<
"} to it found\n");
2486 if (MemoryAccess *MemPhi = getMemoryAccess(To))
2487 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2492 for (
auto InstNum : RevisitOnReachabilityChange[To])
2493 TouchedInstructions.
set(InstNum);
2506void NewGVN::processOutgoingEdges(Instruction *TI, BasicBlock *
B) {
2511 Value *CondEvaluated = findConditionEquivalence(
Cond);
2512 if (!CondEvaluated) {
2514 SmallPtrSet<Value *, 4> Visited;
2515 auto Res = performSymbolicEvaluation(
I, Visited);
2517 CondEvaluated =
CE->getConstantValue();
2518 addAdditionalUsers(Res,
I);
2522 Res.ExtraDep =
nullptr;
2525 CondEvaluated =
Cond;
2532 <<
" evaluated to true\n");
2533 updateReachableEdge(
B, TrueSucc);
2534 }
else if (CI->
isZero()) {
2536 <<
" evaluated to false\n");
2537 updateReachableEdge(
B, FalseSucc);
2540 updateReachableEdge(
B, TrueSucc);
2541 updateReachableEdge(
B, FalseSucc);
2547 Value *SwitchCond =
SI->getCondition();
2548 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2553 auto Case = *
SI->findCaseValue(CondVal);
2554 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2558 updateReachableEdge(
B,
SI->getDefaultDest());
2562 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2563 updateReachableEdge(
B, TargetBlock);
2565 for (BasicBlock *TargetBlock :
successors(
SI->getParent()))
2566 updateReachableEdge(
B, TargetBlock);
2572 updateReachableEdge(
B, TargetBlock);
2577 auto *MA = getMemoryAccess(TI);
2579 auto *CC = ensureLeaderOfMemoryClass(MA);
2580 if (setMemoryClass(MA, CC))
2581 markMemoryUsersTouched(MA);
2587void NewGVN::removePhiOfOps(Instruction *
I, PHINode *PHITemp) {
2588 InstrDFS.
erase(PHITemp);
2591 TempToBlock.
erase(PHITemp);
2600void NewGVN::addPhiOfOps(PHINode *
Op, BasicBlock *BB,
2601 Instruction *ExistingValue) {
2602 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2604 TempToBlock[
Op] = BB;
2605 RealToTemp[ExistingValue] =
Op;
2608 for (
auto *U : ExistingValue->
users())
2627bool NewGVN::OpIsSafeForPHIOfOps(
Value *V,
const BasicBlock *PHIBlock,
2628 SmallPtrSetImpl<const Value *> &Visited) {
2631 while (!Worklist.
empty()) {
2636 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2637 if (OISIt != OpSafeForPHIOfOps.
end())
2638 return OISIt->second;
2643 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2648 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2659 if (OrigI->mayReadFromMemory())
2663 for (
auto *
Op : OrigI->operand_values()) {
2667 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2668 if (OISIt != OpSafeForPHIOfOps.
end()) {
2669 if (!OISIt->second) {
2670 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2680 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2689Value *NewGVN::findLeaderForInst(Instruction *TransInst,
2690 SmallPtrSetImpl<Value *> &Visited,
2691 MemoryAccess *MemAccess, Instruction *OrigInst,
2692 BasicBlock *PredBB) {
2693 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2695 AllTempInstructions.
insert(TransInst);
2699 TempToBlock.
insert({TransInst, PredBB});
2700 InstrDFS.
insert({TransInst, IDFSNum});
2702 auto Res = performSymbolicEvaluation(TransInst, Visited);
2704 addAdditionalUsers(Res, OrigInst);
2705 InstrDFS.
erase(TransInst);
2706 AllTempInstructions.
erase(TransInst);
2707 TempToBlock.
erase(TransInst);
2709 TempToMemory.
erase(TransInst);
2712 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2714 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2715 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2720 FoundVal =
SI->getValueOperand();
2727NewGVN::makePossiblePHIOfOps(Instruction *
I,
2728 SmallPtrSetImpl<Value *> &Visited) {
2732 if (!Visited.
insert(
I).second)
2738 if (!isCycleFree(
I))
2744 auto *MemAccess = getMemoryAccess(
I);
2748 if (MemAccess && !
isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2753 SmallPtrSet<const Value *, 10> VisitedOps;
2756 PHINode *OpPHI =
nullptr;
2759 for (
auto *
Op :
Ops) {
2761 auto *ValuePHI = RealToTemp.
lookup(
Op);
2768 if (!SamePHIBlock) {
2769 SamePHIBlock = getBlockForValue(OpPHI);
2770 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2773 <<
"PHIs for operands are not all in the same block, aborting\n");
2787 SmallPtrSet<Value *, 4> Deps;
2788 auto *PHIBlock = getBlockForValue(OpPHI);
2789 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2790 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2792 Value *FoundVal =
nullptr;
2793 SmallPtrSet<Value *, 4> CurrentDeps;
2796 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2804 TempToMemory.
insert({ValueOp, MemAccess});
2805 bool SafeForPHIOfOps =
true;
2808 auto *OrigOp = &*
Op;
2812 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2813 if (
Op != OrigOp &&
Op !=
I)
2815 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2816 if (getBlockForValue(ValuePHI) == PHIBlock)
2817 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2822 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2829 FoundVal = !SafeForPHIOfOps ? nullptr
2830 : findLeaderForInst(ValueOp, Visited,
2831 MemAccess,
I, PredBB);
2836 if (SafeForPHIOfOps)
2837 for (
auto *Dep : CurrentDeps)
2838 addAdditionalUsers(Dep,
I);
2844 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2846 <<
" because the block is unreachable\n");
2848 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2852 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2855 for (
auto *Dep : Deps)
2856 addAdditionalUsers(Dep,
I);
2858 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2862 <<
"Not creating real PHI of ops because it simplified to existing "
2863 "value or constant\n");
2869 for (
auto &O : PHIOps)
2870 addAdditionalUsers(
O.first,
I);
2874 auto *ValuePHI = RealToTemp.
lookup(
I);
2875 bool NewPHI =
false;
2879 addPhiOfOps(ValuePHI, PHIBlock,
I);
2881 NumGVNPHIOfOpsCreated++;
2884 for (
auto PHIOp : PHIOps)
2885 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2887 TempToBlock[ValuePHI] = PHIBlock;
2889 for (
auto PHIOp : PHIOps) {
2890 ValuePHI->setIncomingValue(i, PHIOp.first);
2891 ValuePHI->setIncomingBlock(i, PHIOp.second);
2895 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2896 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2905void NewGVN::initializeCongruenceClasses(Function &
F) {
2906 NextCongruenceNum = 0;
2916 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2922 for (
auto *DTN :
nodes(DT)) {
2929 if (MemoryBlockDefs)
2930 for (
const auto &Def : *MemoryBlockDefs) {
2931 MemoryAccessToClass[&
Def] = TOPClass;
2936 TOPClass->memory_insert(MP);
2937 MemoryPhiState.
insert({MP, MPS_TOP});
2941 TOPClass->incStoreCount();
2947 for (
auto &
I : *BB) {
2949 for (
auto *U :
I.users())
2952 PHINodeUses.
insert(UInst);
2955 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2957 TOPClass->insert(&
I);
2958 ValueToClass[&
I] = TOPClass;
2963 for (
auto &FA :
F.args())
2964 createSingletonCongruenceClass(&FA);
2967void NewGVN::cleanupTables() {
2968 for (CongruenceClass *&CC : CongruenceClasses) {
2969 LLVM_DEBUG(
dbgs() <<
"Congruence class " << CC->getID() <<
" has "
2970 << CC->size() <<
" members\n");
2978 SmallVector<Instruction *, 8> TempInst(AllTempInstructions.
begin(),
2979 AllTempInstructions.
end());
2980 AllTempInstructions.
clear();
2984 for (
auto *
I : TempInst) {
2985 I->dropAllReferences();
2988 while (!TempInst.empty()) {
2989 auto *
I = TempInst.pop_back_val();
2993 ValueToClass.
clear();
2994 ArgRecycler.
clear(ExpressionAllocator);
2995 ExpressionAllocator.
Reset();
2996 CongruenceClasses.clear();
2997 ExpressionToClass.clear();
2998 ValueToExpression.
clear();
3000 AdditionalUsers.
clear();
3001 ExpressionToPhiOfOps.
clear();
3002 TempToBlock.
clear();
3003 TempToMemory.
clear();
3004 PHINodeUses.
clear();
3005 OpSafeForPHIOfOps.
clear();
3006 ReachableBlocks.
clear();
3007 ReachableEdges.
clear();
3009 ProcessedCount.
clear();
3012 InstructionsToErase.
clear();
3014 BlockInstRange.
clear();
3015 TouchedInstructions.
clear();
3016 MemoryAccessToClass.
clear();
3017 PredicateToUsers.
clear();
3018 MemoryToUsers.
clear();
3019 RevisitOnReachabilityChange.
clear();
3020 PredicateSwapChoice.
clear();
3025std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(BasicBlock *
B,
3027 unsigned End =
Start;
3028 if (MemoryAccess *MemPhi = getMemoryAccess(
B)) {
3029 InstrDFS[MemPhi] = End++;
3034 for (
auto &
I : *
B) {
3040 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3042 markInstructionForDeletion(&
I);
3046 RevisitOnReachabilityChange[
B].set(End);
3047 InstrDFS[&
I] = End++;
3054 return std::make_pair(Start, End);
3057void NewGVN::updateProcessedCount(
const Value *V) {
3059 assert(++ProcessedCount[V] < 100 &&
3060 "Seem to have processed the same Value a lot");
3065void NewGVN::valueNumberMemoryPhi(MemoryPhi *MP) {
3072 return cast<MemoryAccess>(U) != MP &&
3073 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3074 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3079 if (Filtered.begin() == Filtered.end()) {
3080 if (setMemoryClass(MP, TOPClass))
3081 markMemoryUsersTouched(MP);
3087 auto LookupFunc = [&](
const Use &
U) {
3090 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3091 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3095 const auto *AllSameValue = *MappedBegin;
3097 bool AllEqual = std::all_of(
3098 MappedBegin, MappedEnd,
3099 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3102 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3111 CongruenceClass *CC =
3112 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3113 auto OldState = MemoryPhiState.
lookup(MP);
3114 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3115 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3116 MemoryPhiState[MP] = NewState;
3117 if (setMemoryClass(MP, CC) || OldState != NewState)
3118 markMemoryUsersTouched(MP);
3123void NewGVN::valueNumberInstruction(Instruction *
I) {
3125 if (!
I->isTerminator()) {
3127 SmallPtrSet<Value *, 2> Visited;
3129 auto Res = performSymbolicEvaluation(
I, Visited);
3130 Symbolized = Res.Expr;
3131 addAdditionalUsers(Res,
I);
3136 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3141 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3142 removePhiOfOps(
I,
Op);
3151 if (Symbolized ==
nullptr)
3152 Symbolized = createUnknownExpression(
I);
3153 performCongruenceFinding(
I, Symbolized);
3158 if (!
I->getType()->isVoidTy()) {
3159 auto *Symbolized = createUnknownExpression(
I);
3160 performCongruenceFinding(
I, Symbolized);
3162 processOutgoingEdges(
I,
I->getParent());
3168bool NewGVN::singleReachablePHIPath(
3169 SmallPtrSet<const MemoryAccess *, 8> &Visited,
const MemoryAccess *
First,
3170 const MemoryAccess *Second)
const {
3171 if (
First == Second)
3184 const auto *EndDef =
First;
3186 if (ChainDef == Second)
3193 auto ReachableOperandPred = [&](
const Use &
U) {
3196 auto FilteredPhiArgs =
3210void NewGVN::verifyMemoryCongruency()
const {
3213 for (
const auto *CC : CongruenceClasses) {
3214 if (CC == TOPClass || CC->isDead())
3216 if (CC->getStoreCount() != 0) {
3218 "Any class with a store as a leader should have a "
3219 "representative stored value");
3220 assert(CC->getMemoryLeader() &&
3221 "Any congruence class with a store should have a "
3222 "representative access");
3225 if (CC->getMemoryLeader())
3226 assert(MemoryAccessToClass.
lookup(CC->getMemoryLeader()) == CC &&
3227 "Representative MemoryAccess does not appear to be reverse "
3229 for (
const auto *M : CC->memory())
3231 "Memory member does not appear to be reverse mapped properly");
3239 auto ReachableAccessPred =
3240 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3241 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3243 MemoryToDFSNum(Pair.first) == 0)
3251 for (
const auto &U : MemPHI->incoming_values()) {
3264 for (
auto KV : Filtered) {
3267 if (FirstMUD && SecondMUD) {
3268 SmallPtrSet<const MemoryAccess *, 8> VisitedMAS;
3269 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3270 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3271 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3272 "The instructions for these memory operations should have "
3273 "been in the same congruence class or reachable through"
3274 "a single argument phi");
3279 auto ReachableOperandPred = [&](
const Use &
U) {
3280 return ReachableEdges.
count(
3281 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3285 auto FilteredPhiArgs =
3288 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3289 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3290 const MemoryDef *MD = cast<MemoryDef>(U);
3291 return ValueToClass.lookup(MD->getMemoryInst());
3294 "All MemoryPhi arguments should be in the same class");
3303void NewGVN::verifyIterationSettled(Function &
F) {
3313 std::map<const Value *, CongruenceClass> BeforeIteration;
3315 for (
auto &KV : ValueToClass) {
3318 if (InstrToDFSNum(
I) == 0)
3320 BeforeIteration.insert({KV.first, *KV.second});
3323 TouchedInstructions.
set();
3324 TouchedInstructions.
reset(0);
3325 OpSafeForPHIOfOps.
clear();
3327 iterateTouchedInstructions();
3328 DenseSet<std::pair<const CongruenceClass *, const CongruenceClass *>>
3330 for (
const auto &KV : ValueToClass) {
3333 if (InstrToDFSNum(
I) == 0)
3337 auto *BeforeCC = &BeforeIteration.find(KV.first)->second;
3338 auto *AfterCC = KV.second;
3341 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3342 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3343 "Value number changed after main loop completed!");
3344 EqualClasses.
insert({BeforeCC, AfterCC});
3355void NewGVN::verifyStoreExpressions()
const {
3360 std::pair<
const Value *,
3361 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3363 for (
const auto &KV : ExpressionToClass) {
3366 auto Res = StoreExpressionSet.insert(
3367 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3368 SE->getStoredValue())});
3369 bool Okay = Res.second;
3374 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3375 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3376 lookupOperandLeader(SE->getStoredValue()));
3377 assert(Okay &&
"Stored expression conflict exists in expression table");
3378 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3379 assert(ValueExpr && ValueExpr->equals(*SE) &&
3380 "StoreExpression in ExpressionToClass is not latest "
3381 "StoreExpression for value");
3390void NewGVN::iterateTouchedInstructions() {
3391 uint64_t Iterations = 0;
3393 int FirstInstr = TouchedInstructions.
find_first();
3395 if (FirstInstr == -1)
3397 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3398 while (TouchedInstructions.
any()) {
3404 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3408 if (InstrNum == 0) {
3409 TouchedInstructions.
reset(InstrNum);
3413 Value *
V = InstrFromDFSNum(InstrNum);
3414 const BasicBlock *CurrBlock = getBlockForValue(V);
3417 if (CurrBlock != LastBlock) {
3418 LastBlock = CurrBlock;
3419 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3420 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3423 if (!BlockReachable) {
3424 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3427 <<
" because it is unreachable\n");
3432 updateProcessedCount(CurrBlock);
3436 TouchedInstructions.
reset(InstrNum);
3440 valueNumberMemoryPhi(MP);
3442 valueNumberInstruction(
I);
3446 updateProcessedCount(V);
3449 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3453bool NewGVN::runGVN() {
3457 NumFuncArgs =
F.arg_size();
3459 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3463 unsigned ICount = 1;
3474 ReversePostOrderTraversal<Function *> RPOT(&
F);
3475 unsigned Counter = 0;
3476 for (
auto &
B : RPOT) {
3478 assert(Node &&
"RPO and Dominator tree should have same reachability");
3479 RPOOrdering[
Node] = ++Counter;
3482 for (
auto &
B : RPOT) {
3484 if (
Node->getNumChildren() > 1)
3486 return RPOOrdering[
A] < RPOOrdering[
B];
3493 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3494 BlockInstRange.
insert({
B, BlockRange});
3495 ICount += BlockRange.second - BlockRange.first;
3497 initializeCongruenceClasses(
F);
3499 TouchedInstructions.
resize(ICount);
3503 ExpressionToClass.reserve(ICount);
3506 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3507 TouchedInstructions.
set(InstRange.first, InstRange.second);
3509 <<
" marked reachable\n");
3510 ReachableBlocks.
insert(&
F.getEntryBlock());
3514 iterateTouchedInstructions();
3515 verifyMemoryCongruency();
3516 verifyIterationSettled(
F);
3517 verifyStoreExpressions();
3519 Changed |= eliminateInstructions(
F);
3522 for (Instruction *ToErase : InstructionsToErase) {
3523 if (!ToErase->use_empty())
3526 assert(ToErase->getParent() &&
3527 "BB containing ToErase deleted unexpectedly!");
3528 ToErase->eraseFromParent();
3530 Changed |= !InstructionsToErase.empty();
3533 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3534 return !ReachableBlocks.
count(&BB);
3539 <<
" is unreachable\n");
3540 deleteInstructionsInBlock(&BB);
3609void NewGVN::convertClassToDFSOrdered(
3618 assert(BB &&
"Should have figured out a basic block for value");
3627 auto Leader = lookupOperandLeader(
SI->getValueOperand());
3629 VDDef.Def.setPointer(Leader);
3631 VDDef.Def.setPointer(
SI->getValueOperand());
3632 VDDef.Def.setInt(
true);
3635 VDDef.Def.setPointer(
D);
3638 "The dense set member should always be an instruction");
3643 if (
auto *PN = RealToTemp.
lookup(Def)) {
3647 VDDef.Def.setInt(
false);
3648 VDDef.Def.setPointer(PN);
3654 unsigned int UseCount = 0;
3656 for (
auto &U :
Def->uses()) {
3659 if (InstructionsToErase.count(
I))
3665 IBlock =
P->getIncomingBlock(U);
3670 IBlock = getBlockForValue(
I);
3676 if (!ReachableBlocks.
contains(IBlock))
3692 ProbablyDead.
insert(Def);
3694 UseCounts[
Def] = UseCount;
3700void NewGVN::convertClassToLoadsAndStores(
3701 const CongruenceClass &
Dense,
3702 SmallVectorImpl<ValueDFS> &LoadsAndStores)
const {
3712 VD.Def.setPointer(
D);
3726 I->replaceAllUsesWith(Repl);
3729void NewGVN::deleteInstructionsInBlock(BasicBlock *BB) {
3731 ++NumGVNBlocksDeleted;
3735 auto StartPoint = BB->
rbegin();
3748 ++NumGVNInstrDeleted;
3758void NewGVN::markInstructionForDeletion(Instruction *
I) {
3760 InstructionsToErase.insert(
I);
3763void NewGVN::replaceInstruction(Instruction *
I,
Value *V) {
3768 markInstructionForDeletion(
I);
3775class ValueDFSStack {
3777 Value *
back()
const {
return ValueStack.back(); }
3778 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3780 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3781 ValueStack.emplace_back(V);
3782 DFSStack.emplace_back(DFSIn, DFSOut);
3785 bool empty()
const {
return DFSStack.empty(); }
3787 bool isInScope(
int DFSIn,
int DFSOut)
const {
3790 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3793 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3796 assert(ValueStack.size() == DFSStack.size() &&
3797 "Mismatch between ValueStack and DFSStack");
3799 !DFSStack.empty() &&
3800 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3801 DFSStack.pop_back();
3802 ValueStack.pop_back();
3807 SmallVector<Value *, 8> ValueStack;
3814CongruenceClass *NewGVN::getClassForExpression(
const Expression *
E)
const {
3816 return ValueToClass.lookup(VE->getVariableValue());
3819 return ExpressionToClass.lookup(
E);
3825 const Instruction *OrigInst,
3826 const BasicBlock *BB)
const {
3829 return CE->getConstantValue();
3831 auto *
V = VE->getVariableValue();
3833 return VE->getVariableValue();
3836 auto *CC = getClassForExpression(
E);
3840 return CC->getLeader();
3842 for (
auto *Member : *CC) {
3844 if (MemberInst == OrigInst)
3849 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3855bool NewGVN::eliminateInstructions(Function &
F) {
3879 bool AnythingReplaced =
false;
3887 auto ReplaceUnreachablePHIArgs = [&](PHINode *
PHI,
BasicBlock *BB) {
3888 for (
auto &Operand :
PHI->incoming_values())
3889 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3893 <<
" with poison due to it being unreachable\n");
3906 DenseMap<const BasicBlock *, unsigned> ReachablePredCount;
3907 for (
auto &KV : ReachableEdges)
3908 ReachablePredCount[KV.getEnd()]++;
3909 for (
auto &BBPair : RevisitOnReachabilityChange) {
3910 for (
auto InstNum : BBPair.second) {
3911 auto *Inst = InstrFromDFSNum(InstNum);
3916 auto *BB = BBPair.first;
3917 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3918 ReplaceUnreachablePHIArgs(
PHI, BB);
3923 DenseMap<const Value *, unsigned int> UseCounts;
3924 for (
auto *CC :
reverse(CongruenceClasses)) {
3925 LLVM_DEBUG(
dbgs() <<
"Eliminating in congruence class " << CC->getID()
3930 SmallPtrSet<Instruction *, 8> ProbablyDead;
3931 if (CC->isDead() || CC->empty())
3934 if (CC == TOPClass) {
3935 for (
auto *M : *CC) {
3936 auto *VTE = ValueToExpression.
lookup(M);
3941 "Everything in TOP should be unreachable or dead at this "
3947 assert(CC->getLeader() &&
"We should have had a leader");
3953 CC->getStoredValue() ? CC->getStoredValue() : CC->getLeader();
3955 CongruenceClass::MemberSet MembersLeft;
3956 for (
auto *M : *CC) {
3960 Member->getType()->isVoidTy()) {
3961 MembersLeft.
insert(Member);
3965 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3966 << *Member <<
"\n");
3968 assert(Leader !=
I &&
"About to accidentally remove our leader");
3969 replaceInstruction(
I, Leader);
3970 AnythingReplaced =
true;
3972 CC->swap(MembersLeft);
3975 if (CC->size() != 1 || RealToTemp.
count(Leader)) {
3980 ValueDFSStack EliminationStack;
3984 convertClassToDFSOrdered(*CC, DFSOrderedSet, UseCounts, ProbablyDead);
3988 for (
auto &VD : DFSOrderedSet) {
3989 int MemberDFSIn = VD.
DFSIn;
3990 int MemberDFSOut = VD.
DFSOut;
3992 bool FromStore = VD.Def.getInt();
3995 if (Def &&
Def->getType()->isVoidTy())
3998 if (DefInst && AllTempInstructions.
count(DefInst)) {
4004 AllTempInstructions.
erase(PN);
4005 auto *DefBlock = getBlockForValue(Def);
4009 PN->insertBefore(DefBlock->begin());
4011 NumGVNPHIOfOpsEliminations++;
4014 if (EliminationStack.empty()) {
4018 << EliminationStack.dfs_back().first <<
","
4019 << EliminationStack.dfs_back().second <<
")\n");
4022 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4023 << MemberDFSOut <<
")\n");
4037 bool ShouldPush =
Def && EliminationStack.empty();
4039 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4041 if (OutOfScope || ShouldPush) {
4043 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4044 bool ShouldPush =
Def && EliminationStack.empty();
4046 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4066 if (!EliminationStack.empty() && DefI && !FromStore) {
4067 Value *DominatingLeader = EliminationStack.back();
4068 if (DominatingLeader != Def) {
4076 for (
auto *DVR : DVRUsers)
4077 DVR->replaceVariableLocationOp(DefI, DominatingLeader);
4079 markInstructionForDeletion(DefI);
4088 "Current def should have been an instruction");
4090 "Current user should have been an instruction");
4097 if (InstructionsToErase.count(InstUse)) {
4098 auto &UseCount = UseCounts[
U->get()];
4099 if (--UseCount == 0) {
4106 if (EliminationStack.empty())
4109 Value *DominatingLeader = EliminationStack.back();
4113 if (BC->getType() == BC->getOperand(0)->getType() &&
4114 PredInfo->getPredicateInfoFor(DominatingLeader)) {
4116 DominatingLeader = BC->getOperand(0);
4121 if (
U->get() == DominatingLeader)
4128 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4129 if (!PI || DominatingLeader != PI->OriginalOp)
4133 <<
"Found replacement " << *DominatingLeader <<
" for "
4134 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4135 U->set(DominatingLeader);
4138 auto &LeaderUseCount = UseCounts[DominatingLeader];
4145 auto It = UseCounts.
find(SSACopy);
4146 if (It != UseCounts.
end()) {
4147 unsigned &IIUseCount = It->second;
4148 if (--IIUseCount == 0)
4149 ProbablyDead.
insert(SSACopy);
4153 AnythingReplaced =
true;
4160 for (
auto *
I : ProbablyDead)
4162 markInstructionForDeletion(
I);
4165 CongruenceClass::MemberSet MembersLeft;
4166 for (
auto *Member : *CC)
4169 MembersLeft.
insert(Member);
4170 CC->swap(MembersLeft);
4173 if (CC->getStoreCount() > 0) {
4174 convertClassToLoadsAndStores(*CC, PossibleDeadStores);
4176 ValueDFSStack EliminationStack;
4177 for (
auto &VD : PossibleDeadStores) {
4178 int MemberDFSIn = VD.
DFSIn;
4179 int MemberDFSOut = VD.
DFSOut;
4181 if (EliminationStack.empty() ||
4182 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4184 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4185 if (EliminationStack.empty()) {
4186 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4193 assert(!EliminationStack.empty());
4199 <<
" that is dominated by " << *Leader <<
"\n");
4200 markInstructionForDeletion(Member);
4206 return AnythingReplaced;
4214unsigned int NewGVN::getRank(
const Value *V)
const {
4229 return 4 +
A->getArgNo();
4233 unsigned Result = InstrToDFSNum(V);
4235 return 5 + NumFuncArgs +
Result;
4242bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4246 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4249bool NewGVN::shouldSwapOperandsForPredicate(
const Value *
A,
const Value *
B,
4250 const BitCastInst *
I)
const {
4251 if (shouldSwapOperands(
A,
B)) {
4252 PredicateSwapChoice[
I] =
B;
4257 if (LookupResult != PredicateSwapChoice.
end()) {
4259 if (SeenPredicate) {
4261 if (SeenPredicate ==
B)
4280 NewGVN(
F, &DT, &AC, &TLI, &
AA, &MSSA,
F.getDataLayout())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Unify divergent function exit nodes
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file defines the BumpPtrAllocator interface.
This file implements the BitVector class.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
early cse Early CSE w MemorySSA
The header file for the GVN pass that contains expression handling classes.
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
This is the interface for a simple mod/ref and alias analysis over globals.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
This defines the Use class.
static bool lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
Branch Probability Basic Block static false std::string getBlockName(const MachineBasicBlock *BB)
Helper to print the name of a MBB.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static bool alwaysAvailable(Value *V)
static Value * getCopyOf(const Value *V)
static bool isCopyOfPHI(const Value *V, const PHINode *PN)
static bool isCopyOfAPHI(const Value *V)
static bool okayForPHIOfOps(const Instruction *I)
static cl::opt< bool > EnableStoreRefinement("enable-store-refinement", cl::init(false), cl::Hidden)
static bool equalsLoadStoreHelper(const T &LHS, const Expression &RHS)
static cl::opt< bool > EnablePhiOfOps("enable-phi-of-ops", cl::init(true), cl::Hidden)
Currently, the generation "phi of ops" can result in correctness issues.
This file provides the interface for LLVM's Global Value Numbering pass.
This file defines the PointerIntPair class.
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
const SmallVectorImpl< MachineOperand > & Cond
bool isDead(const MachineInstr &MI, const MachineRegisterInfo &MRI)
This file defines generic set operations that may be used on set's of different types,...
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the SparseBitVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
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
size - 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 if the block is well formed or null if the block is not well forme...
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
bool any() const
any - Returns true if any bit is set.
iterator_range< const_set_bits_iterator > set_bits() const
void Reset()
Deallocate all but the current slab and reset the current pointer to the beginning of it,...
void Deallocate(const void *Ptr, size_t Size, size_t)
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(unsigned ID)
static bool isCounterSet(unsigned ID)
static bool shouldExecute(unsigned CounterName)
static void setCounterState(unsigned ID, CounterState State)
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
unsigned getDFSNumIn() const
getDFSNumIn/getDFSNumOut - These return the DFS visitation order for nodes in the dominator tree.
unsigned getDFSNumOut() const
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getRootNode()
getRootNode - This returns the entry node for the CFG of the function.
void updateDFSNumbers() const
updateDFSNumbers - Assign In and Out numbers to the nodes while walking dominator tree in dfs order.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Class representing an expression and its matching format.
bool isPresplitCoroutine() const
Determine if the function is presplit coroutine.
~AggregateValueExpression() override
~BasicExpression() override
void allocateOperands(RecyclerType &Recycler, BumpPtrAllocator &Allocator)
bool equals(const Expression &Other) const override
~CallExpression() override
void setOpcode(unsigned opcode)
bool equals(const Expression &Other) const override
~LoadExpression() override
bool equals(const Expression &Other) const override
~PHIExpression() override
bool equals(const Expression &Other) const override
~StoreExpression() override
Value * getStoredValue() const
static LLVM_ABI std::optional< bool > isImpliedByMatchingCmp(CmpPredicate Pred1, CmpPredicate Pred2)
Determine if Pred1 implies Pred2 is true, false, or if nothing can be inferred about the implication,...
LLVM_ABI bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
Value * getPointerOperand()
BasicBlock * getBlock() const
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
An analysis that produces MemorySSA for a function.
This is the generic walker interface for walkers of MemorySSA.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Encapsulates MemorySSA, including all data associated with memory accesses.
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
const DefsList * getBlockDefs(const BasicBlock *BB) const
Return the list of MemoryDef's and MemoryPhi's for a given basic block.
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
PreservedAnalyses run(Function &F, AnalysisManager< Function > &AM)
Run the pass over the function.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PointerIntPair - This class implements a pair of a pointer and small integer.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
SmallPtrSetIterator< PtrType > const_iterator
bool erase(PtrType Ptr)
Remove pointer from the set.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool isPointerTy() const
True if this is an instance of PointerType.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
unsigned getNumOperands() const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
std::pair< iterator, bool > insert(const ValueT &V)
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
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...
Constant * getConstantValueForLoad(Constant *SrcVal, unsigned Offset, Type *LoadTy, const DataLayout &DL)
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...
Constant * getConstantMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, const DataLayout &DL)
int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
@ CE
Windows NT (Windows on ARM)
initializer< Ty > init(const Ty &Val)
std::vector< std::optional< ExecutorSymbolDef > > LookupResult
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI Instruction & back() const
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Value * simplifyGEPInst(Type *SrcTy, Value *Ptr, ArrayRef< Value * > Indices, GEPNoWrapFlags NW, const SimplifyQuery &Q)
Given operands for a GetElementPtrInst, fold the result or return null.
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
SDValue getStoredValue(SDValue Op)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
mapped_iterator< ItTy, FuncTy > map_iterator(ItTy I, FuncTy F)
bool set_is_subset(const S1Ty &S1, const S2Ty &S2)
set_is_subset(A, B) - Return true iff A in B
bool isa_and_nonnull(const Y &Val)
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
DomTreeNodeBase< BasicBlock > DomTreeNode
auto dyn_cast_or_null(const Y &Val)
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
OutputIt transform(R &&Range, OutputIt d_first, UnaryFunction F)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
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...
BumpPtrAllocatorImpl BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
iterator_range< df_iterator< T > > depth_first(const T &G)
bool all_equal(std::initializer_list< T > Values)
Returns true if all Values in the initializer lists are equal or the list.
LLVM_ABI Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
LLVM_ABI bool isGuaranteedNotToBePoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Returns true if V cannot be poison, but may be undef.
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 Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
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 const Expression * getTombstoneKey()
static bool isEqual(const Expression *LHS, const Expression *RHS)
static const Expression * getEmptyKey()
static bool isEqual(const ExactEqualsExpression &LHS, const Expression *RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
SimplifyQuery getWithInstruction(const Instruction *I) const