127#define DEBUG_TYPE "newgvn"
129STATISTIC(NumGVNInstrDeleted,
"Number of instructions deleted");
130STATISTIC(NumGVNBlocksDeleted,
"Number of blocks deleted");
131STATISTIC(NumGVNOpsSimplified,
"Number of Expressions simplified");
132STATISTIC(NumGVNPhisAllSame,
"Number of PHIs whos arguments are all the same");
134 "Maximum Number of iterations it took to converge GVN");
135STATISTIC(NumGVNLeaderChanges,
"Number of leader changes");
136STATISTIC(NumGVNSortedLeaderChanges,
"Number of sorted leader changes");
138 "Number of avoided sorted leader changes");
139STATISTIC(NumGVNDeadStores,
"Number of redundant/dead stores eliminated");
140STATISTIC(NumGVNPHIOfOpsCreated,
"Number of PHI of ops created");
142 "Number of things eliminated using PHI of ops");
144 "Controls which instructions are value numbered");
146 "Controls which instructions we create phi of ops for");
163namespace GVNExpression {
187 TarjanSCC() : Components(1) {}
190 if (Root.lookup(Start) == 0)
195 unsigned ComponentID = ValueToComponent.lookup(V);
198 "Asking for a component for a value we never processed");
199 return Components[ComponentID];
206 unsigned int OurDFS = DFSNum;
207 for (
const auto &
Op :
I->operands()) {
208 if (
auto *InstOp = dyn_cast<Instruction>(
Op)) {
209 if (Root.lookup(
Op) == 0)
211 if (!InComponent.count(
Op))
212 Root[
I] = std::min(Root.lookup(
I), Root.lookup(
Op));
219 if (Root.lookup(
I) == OurDFS) {
220 unsigned ComponentID = Components.size();
221 Components.resize(Components.size() + 1);
225 InComponent.insert(
I);
226 ValueToComponent[
I] = ComponentID;
228 while (!
Stack.empty() && Root.lookup(
Stack.back()) >= OurDFS) {
232 InComponent.insert(Member);
233 ValueToComponent[
Member] = ComponentID;
242 unsigned int DFSNum = 1;
292class CongruenceClass {
294 using MemberType =
Value;
299 explicit CongruenceClass(
unsigned ID) :
ID(
ID) {}
300 CongruenceClass(
unsigned ID, std::pair<Value *, unsigned int> Leader,
302 :
ID(
ID), RepLeader(Leader), DefiningExpr(E) {}
304 unsigned getID()
const {
return ID; }
311 return empty() && memory_empty();
315 Value *getLeader()
const {
return RepLeader.first; }
316 void setLeader(std::pair<Value *, unsigned int> Leader) {
319 const std::pair<Value *, unsigned int> &getNextLeader()
const {
322 void resetNextLeader() { NextLeader = {
nullptr, ~0}; }
323 bool addPossibleLeader(std::pair<Value *, unsigned int> LeaderPair) {
324 if (LeaderPair.second < RepLeader.second) {
325 NextLeader = RepLeader;
326 RepLeader = LeaderPair;
328 }
else if (LeaderPair.second < NextLeader.second) {
329 NextLeader = LeaderPair;
335 void setStoredValue(
Value *Leader) { RepStoredValue = Leader; }
336 const MemoryAccess *getMemoryLeader()
const {
return RepMemoryAccess; }
337 void setMemoryLeader(
const MemoryAccess *Leader) { RepMemoryAccess = Leader; }
340 const Expression *getDefiningExpr()
const {
return DefiningExpr; }
343 bool empty()
const {
return Members.empty(); }
344 unsigned size()
const {
return Members.size(); }
347 void insert(MemberType *M) { Members.insert(M); }
348 void erase(MemberType *M) { Members.erase(M); }
352 bool memory_empty()
const {
return MemoryMembers.empty(); }
353 unsigned memory_size()
const {
return MemoryMembers.size(); }
355 return MemoryMembers.begin();
358 return MemoryMembers.end();
361 return make_range(memory_begin(), memory_end());
364 void memory_insert(
const MemoryMemberType *M) { MemoryMembers.insert(M); }
365 void memory_erase(
const MemoryMemberType *M) { MemoryMembers.erase(M); }
368 unsigned getStoreCount()
const {
return StoreCount; }
369 void incStoreCount() { ++StoreCount; }
370 void decStoreCount() {
371 assert(StoreCount != 0 &&
"Store count went negative");
376 bool definesNoMemory()
const {
return StoreCount == 0 && memory_empty(); }
380 bool isEquivalentTo(
const CongruenceClass *
Other)
const {
386 if (std::tie(StoreCount, RepLeader, RepStoredValue, RepMemoryAccess) !=
388 Other->RepMemoryAccess))
390 if (DefiningExpr !=
Other->DefiningExpr)
391 if (!DefiningExpr || !
Other->DefiningExpr ||
392 *DefiningExpr != *
Other->DefiningExpr)
395 if (Members.size() !=
Other->Members.size())
406 std::pair<Value *, unsigned int> RepLeader = {
nullptr, ~0
U};
411 std::pair<Value *, unsigned int> NextLeader = {
nullptr, ~0
U};
414 Value *RepStoredValue =
nullptr;
429 MemoryMemberSet MemoryMembers;
448 return E.exactlyEquals(
Other);
454 auto Val =
static_cast<uintptr_t
>(-1);
455 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
456 return reinterpret_cast<const Expression *
>(Val);
460 auto Val =
static_cast<uintptr_t
>(~1U);
461 Val <<= PointerLikeTypeTraits<const Expression *>::NumLowBitsAvailable;
462 return reinterpret_cast<const Expression *
>(Val);
466 return E->getComputedHash();
470 return E.getComputedHash();
474 if (
RHS == getTombstoneKey() ||
RHS == getEmptyKey())
482 if (
LHS == getTombstoneKey() ||
RHS == getTombstoneKey() ||
483 LHS == getEmptyKey() ||
RHS == getEmptyKey())
489 if (
LHS->getComputedHash() !=
RHS->getComputedHash())
508 std::unique_ptr<PredicateInfo> PredInfo;
514 mutable TarjanSCC SCCFinder;
518 unsigned int NumFuncArgs = 0;
529 CongruenceClass *TOPClass =
nullptr;
530 std::vector<CongruenceClass *> CongruenceClasses;
531 unsigned NextCongruenceNum = 0;
566 ExpressionToPhiOfOps;
615 enum MemoryPhiState { MPS_Invalid, MPS_TOP, MPS_Equivalent, MPS_Unique };
618 enum InstCycleState { ICS_Unknown, ICS_CycleFree, ICS_Cycle };
623 ExpressionClassMap ExpressionToClass;
675 :
F(
F), DT(DT), TLI(TLI), AA(AA), MSSA(MSSA), AC(AC),
DL(
DL),
677 SQ(
DL, TLI, DT, AC, nullptr,
false,
691 : Expr(Expr), ExtraDep(ExtraDep), PredDep(PredDep) {}
692 ExprResult(
const ExprResult &) =
delete;
693 ExprResult(ExprResult &&
Other)
695 Other.Expr =
nullptr;
696 Other.ExtraDep =
nullptr;
697 Other.PredDep =
nullptr;
699 ExprResult &operator=(
const ExprResult &
Other) =
delete;
700 ExprResult &operator=(ExprResult &&
Other) =
delete;
702 ~ExprResult() {
assert(!ExtraDep &&
"unhandled ExtraDep"); }
704 operator bool()
const {
return Expr; }
706 static ExprResult
none() {
return {
nullptr,
nullptr,
nullptr}; }
707 static ExprResult some(
const Expression *Expr,
Value *ExtraDep =
nullptr) {
708 return {Expr, ExtraDep,
nullptr};
710 static ExprResult some(
const Expression *Expr,
712 return {Expr,
nullptr, PredDep};
716 return {Expr, ExtraDep, PredDep};
727 using ValPair = std::pair<Value *, BasicBlock *>;
731 bool &OriginalOpsConstant)
const;
744 createAggregateValueExpression(
Instruction *)
const;
748 CongruenceClass *createCongruenceClass(
Value *Leader,
const Expression *
E) {
751 unsigned LeaderDFS = 0;
758 else if (
auto *
I = dyn_cast<Instruction>(Leader))
759 LeaderDFS = InstrToDFSNum(
I);
761 new CongruenceClass(NextCongruenceNum++, {Leader, LeaderDFS},
E);
762 CongruenceClasses.emplace_back(result);
767 auto *
CC = createCongruenceClass(
nullptr,
nullptr);
768 CC->setMemoryLeader(MA);
772 CongruenceClass *ensureLeaderOfMemoryClass(
MemoryAccess *MA) {
773 auto *
CC = getMemoryClass(MA);
774 if (
CC->getMemoryLeader() != MA)
775 CC = createMemoryClass(MA);
779 CongruenceClass *createSingletonCongruenceClass(
Value *Member) {
780 CongruenceClass *CClass = createCongruenceClass(Member,
nullptr);
781 CClass->insert(Member);
782 ValueToClass[
Member] = CClass;
786 void initializeCongruenceClasses(
Function &
F);
804 ExprResult performSymbolicEvaluation(
Instruction *,
811 ExprResult performSymbolicCallEvaluation(
Instruction *)
const;
817 ExprResult performSymbolicCmpEvaluation(
Instruction *)
const;
818 ExprResult performSymbolicPredicateInfoEvaluation(
IntrinsicInst *)
const;
823 CongruenceClass *getClassForExpression(
const Expression *
E)
const;
826 CongruenceClass *, CongruenceClass *);
828 CongruenceClass *, CongruenceClass *);
829 Value *getNextValueLeader(CongruenceClass *)
const;
830 const MemoryAccess *getNextMemoryLeader(CongruenceClass *)
const;
832 CongruenceClass *getMemoryClass(
const MemoryAccess *MA)
const;
837 unsigned int getRank(
const Value *)
const;
838 bool shouldSwapOperands(
const Value *,
const Value *)
const;
839 bool shouldSwapOperandsForIntrinsic(
const Value *,
const Value *,
845 Value *findConditionEquivalence(
Value *)
const;
849 void convertClassToDFSOrdered(
const CongruenceClass &,
853 void convertClassToLoadsAndStores(
const CongruenceClass &,
856 bool eliminateInstructions(
Function &);
864 template <
typename Map,
typename KeyType>
865 void touchAndErase(Map &,
const KeyType &);
866 void markUsersTouched(
Value *);
870 void markValueLeaderChangeTouched(CongruenceClass *
CC);
871 void markMemoryLeaderChangeTouched(CongruenceClass *
CC);
878 void iterateTouchedInstructions();
881 void cleanupTables();
882 std::pair<unsigned, unsigned> assignDFSNumbers(
BasicBlock *,
unsigned);
883 void updateProcessedCount(
const Value *V);
884 void verifyMemoryCongruency()
const;
885 void verifyIterationSettled(
Function &
F);
886 void verifyStoreExpressions()
const;
893 template <
class T,
class Range>
T *getMinDFSOfRange(
const Range &)
const;
895 unsigned InstrToDFSNum(
const Value *V)
const {
896 assert(isa<Instruction>(V) &&
"This should not be used for MemoryAccesses");
897 return InstrDFS.
lookup(V);
901 return MemoryToDFSNum(MA);
904 Value *InstrFromDFSNum(
unsigned DFSNum) {
return DFSToInstr[DFSNum]; }
909 unsigned MemoryToDFSNum(
const Value *MA)
const {
910 assert(isa<MemoryAccess>(MA) &&
911 "This should not be used with instructions");
912 return isa<MemoryUseOrDef>(MA)
913 ? InstrToDFSNum(cast<MemoryUseOrDef>(MA)->getMemoryInst())
929 if (!isa<LoadExpression>(
RHS) && !isa<StoreExpression>(
RHS))
931 return LHS.MemoryExpression::equals(
RHS);
942 if (
const auto *S = dyn_cast<StoreExpression>(&
Other))
952 if (
auto *
RHS = dyn_cast<CallExpression>(&
Other))
986 if (
auto *
I = dyn_cast<Instruction>(V)) {
987 auto *Parent =
I->getParent();
990 Parent = TempToBlock.
lookup(V);
991 assert(Parent &&
"Every fake instruction should have a block");
995 auto *MP = dyn_cast<MemoryPhi>(V);
996 assert(MP &&
"Should have been an instruction or a MemoryPhi");
997 return MP->getBlock();
1003void NewGVN::deleteExpression(
const Expression *
E)
const {
1004 assert(isa<BasicExpression>(
E));
1005 auto *BE = cast<BasicExpression>(
E);
1012 if (
auto *
II = dyn_cast<IntrinsicInst>(V))
1013 if (
II->getIntrinsicID() == Intrinsic::ssa_copy)
1014 return II->getOperand(0);
1025 return CO && isa<PHINode>(CO);
1032 llvm::sort(Ops, [&](
const ValPair &P1,
const ValPair &P2) {
1033 return BlockInstRange.
lookup(P1.second).first <
1034 BlockInstRange.
lookup(P2.second).first;
1042 return isa<Constant>(V) || isa<Argument>(V);
1054 bool &OriginalOpsConstant)
const {
1055 unsigned NumOps = PHIOperands.
size();
1056 auto *
E =
new (ExpressionAllocator)
PHIExpression(NumOps, PHIBlock);
1058 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1059 E->setType(PHIOperands.
begin()->first->getType());
1060 E->setOpcode(Instruction::PHI);
1064 auto *BB =
P.second;
1065 if (
auto *PHIOp = dyn_cast<PHINode>(
I))
1068 if (!ReachableEdges.
count({BB, PHIBlock}))
1071 if (ValueToClass.
lookup(
P.first) == TOPClass)
1073 OriginalOpsConstant = OriginalOpsConstant && isa<Constant>(
P.first);
1074 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1075 return lookupOperandLeader(
P.first) !=
I;
1077 std::transform(Filtered.begin(), Filtered.end(),
op_inserter(
E),
1078 [&](
const ValPair &
P) ->
Value * {
1079 return lookupOperandLeader(
P.first);
1087 bool AllConstant =
true;
1088 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I))
1089 E->setType(
GEP->getSourceElementType());
1091 E->setType(
I->getType());
1092 E->setOpcode(
I->getOpcode());
1093 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1098 auto Operand = lookupOperandLeader(O);
1099 AllConstant = AllConstant && isa<Constant>(Operand);
1106const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1115 E->setOpcode(Opcode);
1116 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1122 if (shouldSwapOperands(Arg1, Arg2))
1125 E->op_push_back(lookupOperandLeader(Arg1));
1126 E->op_push_back(lookupOperandLeader(Arg2));
1129 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1130 addAdditionalUsers(Simplified,
I);
1142 return ExprResult::none();
1144 if (
auto *
C = dyn_cast<Constant>(V)) {
1147 <<
" constant " << *
C <<
"\n");
1148 NumGVNOpsSimplified++;
1149 assert(isa<BasicExpression>(
E) &&
1150 "We should always have had a basic expression here");
1151 deleteExpression(
E);
1152 return ExprResult::some(createConstantExpression(
C));
1153 }
else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1156 <<
" variable " << *V <<
"\n");
1157 deleteExpression(
E);
1158 return ExprResult::some(createVariableExpression(V));
1161 CongruenceClass *
CC = ValueToClass.
lookup(V);
1163 if (
CC->getLeader() &&
CC->getLeader() !=
I) {
1164 return ExprResult::some(createVariableOrConstant(
CC->getLeader()), V);
1166 if (
CC->getDefiningExpr()) {
1169 <<
" expression " << *
CC->getDefiningExpr() <<
"\n");
1170 NumGVNOpsSimplified++;
1171 deleteExpression(
E);
1172 return ExprResult::some(
CC->getDefiningExpr(), V);
1176 return ExprResult::none();
1182NewGVN::ExprResult NewGVN::createExpression(
Instruction *
I)
const {
1188 bool AllConstant = setBasicExpressionInfo(
I,
E);
1190 if (
I->isCommutative()) {
1195 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1196 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1197 E->swapOperands(0, 1);
1200 if (
auto *CI = dyn_cast<CmpInst>(
I)) {
1204 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1205 E->swapOperands(0, 1);
1208 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1210 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1211 "Wrong types on cmp instruction");
1212 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1213 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1216 if (
auto Simplified = checkExprResults(
E,
I, V))
1218 }
else if (isa<SelectInst>(
I)) {
1219 if (isa<Constant>(
E->getOperand(0)) ||
1220 E->getOperand(1) ==
E->getOperand(2)) {
1221 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1222 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1224 E->getOperand(2), Q);
1225 if (
auto Simplified = checkExprResults(
E,
I, V))
1228 }
else if (
I->isBinaryOp()) {
1231 if (
auto Simplified = checkExprResults(
E,
I, V))
1233 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
1236 if (
auto Simplified = checkExprResults(
E,
I, V))
1238 }
else if (
auto *GEPI = dyn_cast<GetElementPtrInst>(
I)) {
1240 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1241 GEPI->getNoWrapFlags(), Q);
1242 if (
auto Simplified = checkExprResults(
E,
I, V))
1244 }
else if (AllConstant) {
1253 for (
Value *Arg :
E->operands())
1254 C.emplace_back(cast<Constant>(Arg));
1257 if (
auto Simplified = checkExprResults(
E,
I, V))
1260 return ExprResult::some(
E);
1264NewGVN::createAggregateValueExpression(
Instruction *
I)
const {
1265 if (
auto *
II = dyn_cast<InsertValueInst>(
I)) {
1266 auto *
E =
new (ExpressionAllocator)
1268 setBasicExpressionInfo(
I,
E);
1269 E->allocateIntOperands(ExpressionAllocator);
1272 }
else if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1273 auto *
E =
new (ExpressionAllocator)
1275 setBasicExpressionInfo(EI,
E);
1276 E->allocateIntOperands(ExpressionAllocator);
1286 return SingletonDeadExpression;
1291 E->setOpcode(
V->getValueID());
1296 if (
auto *
C = dyn_cast<Constant>(V))
1297 return createConstantExpression(
C);
1298 return createVariableExpression(V);
1303 E->setOpcode(
C->getValueID());
1309 E->setOpcode(
I->getOpcode());
1318 setBasicExpressionInfo(CI,
E);
1324 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1325 E->swapOperands(0, 1);
1331bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1333 auto *
CC = ValueToClass.
lookup(Inst);
1354 if (DT->
dominates(cast<Instruction>(
CC->getLeader()), U))
1356 if (
CC->getNextLeader().first &&
1357 DT->
dominates(cast<Instruction>(
CC->getNextLeader().first), U))
1360 return Member !=
CC->getLeader() &&
1361 DT->
dominates(cast<Instruction>(Member), U);
1367Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1368 CongruenceClass *
CC = ValueToClass.
lookup(V);
1375 return CC->getStoredValue() ?
CC->getStoredValue() :
CC->getLeader();
1382 auto *
CC = getMemoryClass(MA);
1384 "Every MemoryAccess should be mapped to a congruence class with a "
1385 "representative memory access");
1386 return CC->getMemoryLeader();
1392bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1393 return getMemoryClass(MA) == TOPClass;
1400 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1401 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1402 E->setType(LoadType);
1406 E->op_push_back(PointerOp);
1416 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1417 auto *
E =
new (ExpressionAllocator)
1419 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1420 E->setType(
SI->getValueOperand()->getType());
1424 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1435 auto *
SI = cast<StoreInst>(
I);
1436 auto *StoreAccess = getMemoryAccess(SI);
1438 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1442 StoreRHS = lookupMemoryLeader(StoreRHS);
1443 if (StoreRHS != StoreAccess->getDefiningAccess())
1444 addMemoryUsers(StoreRHS, StoreAccess);
1446 if (StoreRHS == StoreAccess)
1449 if (
SI->isSimple()) {
1453 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1454 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1460 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1466 if (
auto *LI = dyn_cast<LoadInst>(LastStore->getStoredValue()))
1468 LastStore->getOperand(0)) &&
1469 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1472 deleteExpression(LastStore);
1478 return createStoreExpression(SI, StoreAccess);
1484NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1488 if (
auto *DepSI = dyn_cast<StoreInst>(DepInst)) {
1492 if (LI->
isAtomic() > DepSI->isAtomic() ||
1493 LoadType == DepSI->getValueOperand()->getType())
1497 if (
auto *
C = dyn_cast<Constant>(
1498 lookupOperandLeader(DepSI->getValueOperand()))) {
1501 <<
" to constant " << *Res <<
"\n");
1502 return createConstantExpression(Res);
1506 }
else if (
auto *DepLI = dyn_cast<LoadInst>(DepInst)) {
1508 if (LI->
isAtomic() > DepLI->isAtomic())
1513 if (
auto *
C = dyn_cast<Constant>(lookupOperandLeader(DepLI)))
1514 if (
auto *PossibleConstant =
1517 <<
" to constant " << *PossibleConstant <<
"\n");
1518 return createConstantExpression(PossibleConstant);
1521 }
else if (
auto *DepMI = dyn_cast<MemIntrinsic>(DepInst)) {
1524 if (
auto *PossibleConstant =
1527 <<
" to constant " << *PossibleConstant <<
"\n");
1528 return createConstantExpression(PossibleConstant);
1535 if (LoadPtr != lookupOperandLeader(DepInst) &&
1542 if (isa<AllocaInst>(DepInst)) {
1547 else if (
auto *
II = dyn_cast<IntrinsicInst>(DepInst)) {
1548 if (
II->getIntrinsicID() == Intrinsic::lifetime_start)
1550 }
else if (
auto *InitVal =
1552 return createConstantExpression(InitVal);
1558 auto *LI = cast<LoadInst>(
I);
1567 if (isa<UndefValue>(LoadAddressLeader))
1574 if (
auto *MD = dyn_cast<MemoryDef>(DefiningAccess)) {
1583 if (
const auto *CoercionResult =
1584 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1585 DefiningInst, DefiningAccess))
1586 return CoercionResult;
1590 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1594 if (
LE->getMemoryLeader() != DefiningAccess)
1595 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1600NewGVN::performSymbolicPredicateInfoEvaluation(
IntrinsicInst *
I)
const {
1601 auto *PI = PredInfo->getPredicateInfoFor(
I);
1603 return ExprResult::none();
1605 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1607 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1609 return ExprResult::none();
1612 Value *CmpOp0 =
I->getOperand(0);
1613 Value *CmpOp1 = Constraint->OtherOp;
1615 Value *FirstOp = lookupOperandLeader(CmpOp0);
1616 Value *SecondOp = lookupOperandLeader(CmpOp1);
1617 Value *AdditionallyUsedValue = CmpOp0;
1620 if (shouldSwapOperandsForIntrinsic(FirstOp, SecondOp,
I)) {
1623 AdditionallyUsedValue = CmpOp1;
1627 return ExprResult::some(createVariableOrConstant(FirstOp),
1628 AdditionallyUsedValue, PI);
1632 !cast<ConstantFP>(FirstOp)->
isZero())
1633 return ExprResult::some(createConstantExpression(cast<Constant>(FirstOp)),
1634 AdditionallyUsedValue, PI);
1636 return ExprResult::none();
1640NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(
Instruction *
I)
const {
1641 auto *CI = cast<CallInst>(
I);
1642 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
1644 if (
auto *ReturnedValue =
II->getReturnedArgOperand()) {
1645 if (
II->getIntrinsicID() == Intrinsic::ssa_copy)
1646 if (
auto Res = performSymbolicPredicateInfoEvaluation(
II))
1648 return ExprResult::some(createVariableOrConstant(ReturnedValue));
1660 return ExprResult::none();
1666 return ExprResult::none();
1669 return ExprResult::some(
1670 createCallExpression(CI, TOPClass->getMemoryLeader()));
1674 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1676 return ExprResult::some(
1677 createCallExpression(CI, TOPClass->getMemoryLeader()));
1679 return ExprResult::none();
1683CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1685 assert(Result &&
"Should have found memory class");
1692 CongruenceClass *NewClass) {
1694 "Every MemoryAccess should be getting mapped to a non-null class");
1698 <<
" with current MemoryAccess leader ");
1702 bool Changed =
false;
1704 if (LookupResult != MemoryAccessToClass.
end()) {
1706 if (OldClass != NewClass) {
1708 if (
auto *MP = dyn_cast<MemoryPhi>(
From)) {
1709 OldClass->memory_erase(MP);
1710 NewClass->memory_insert(MP);
1712 if (OldClass->getMemoryLeader() ==
From) {
1713 if (OldClass->definesNoMemory()) {
1714 OldClass->setMemoryLeader(
nullptr);
1716 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1718 << OldClass->getID() <<
" to "
1719 << *OldClass->getMemoryLeader()
1720 <<
" due to removal of a memory member " << *
From
1722 markMemoryLeaderChangeTouched(OldClass);
1745 auto ICS = InstCycleState.
lookup(
I);
1746 if (ICS == ICS_Unknown) {
1748 auto &
SCC = SCCFinder.getComponentFor(
I);
1750 if (
SCC.size() == 1)
1751 InstCycleState.
insert({
I, ICS_CycleFree});
1756 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1757 for (
const auto *Member : SCC)
1758 if (
auto *MemberPhi = dyn_cast<PHINode>(Member))
1759 InstCycleState.
insert({MemberPhi, ICS});
1762 if (ICS == ICS_Cycle)
1773 bool HasBackedge =
false;
1778 bool OriginalOpsConstant =
true;
1779 auto *
E = cast<PHIExpression>(createPHIExpression(
1780 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1784 bool HasUndef =
false, HasPoison =
false;
1786 if (isa<PoisonValue>(Arg)) {
1790 if (isa<UndefValue>(Arg)) {
1797 if (Filtered.empty()) {
1802 dbgs() <<
"PHI Node " << *
I
1803 <<
" has no non-undef arguments, valuing it as undef\n");
1808 dbgs() <<
"PHI Node " << *
I
1809 <<
" has no non-poison arguments, valuing it as poison\n");
1813 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1814 deleteExpression(
E);
1815 return createDeadExpression();
1817 Value *AllSameValue = *(Filtered.begin());
1835 if (HasPoison || HasUndef) {
1841 if (HasBackedge && !OriginalOpsConstant &&
1842 !isa<UndefValue>(AllSameValue) && !isCycleFree(
I))
1846 if (
auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
1847 if (!someEquivalentDominates(AllSameInst,
I))
1853 if (isa<Instruction>(AllSameValue) &&
1854 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1856 NumGVNPhisAllSame++;
1857 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1859 deleteExpression(
E);
1860 return createVariableOrConstant(AllSameValue);
1866NewGVN::performSymbolicAggrValueEvaluation(
Instruction *
I)
const {
1867 if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1868 auto *WO = dyn_cast<WithOverflowInst>(EI->getAggregateOperand());
1869 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1873 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1874 WO->getLHS(), WO->getRHS(),
I);
1877 return createAggregateValueExpression(
I);
1880NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(
Instruction *
I)
const {
1881 assert(isa<CmpInst>(
I) &&
"Expected a cmp instruction.");
1883 auto *CI = cast<CmpInst>(
I);
1886 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1887 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1888 auto OurPredicate = CI->getPredicate();
1889 if (shouldSwapOperands(Op0, Op1)) {
1891 OurPredicate = CI->getSwappedPredicate();
1898 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1899 if (isa_and_nonnull<PredicateAssume>(CmpPI))
1900 return ExprResult::some(
1905 if (CI->isTrueWhenEqual())
1906 return ExprResult::some(
1908 else if (CI->isFalseWhenEqual())
1909 return ExprResult::some(
1939 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1940 if (
const auto *PBranch = dyn_cast_or_null<PredicateBranch>(PI)) {
1941 if (PI == LastPredInfo)
1946 if (!DT->
dominates(PBranch->To,
I->getParent()))
1953 auto *BranchCond = dyn_cast<CmpInst>(PBranch->Condition);
1956 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1957 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1958 auto BranchPredicate = BranchCond->getPredicate();
1959 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1961 BranchPredicate = BranchCond->getSwappedPredicate();
1963 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1964 if (PBranch->TrueEdge) {
1969 return ExprResult::some(
1976 return ExprResult::some(
1983 if (BranchPredicate == OurPredicate) {
1985 return ExprResult::some(
1988 }
else if (BranchPredicate ==
1991 return ExprResult::some(
2000 return createExpression(
I);
2012 switch (
I->getOpcode()) {
2013 case Instruction::ExtractValue:
2014 case Instruction::InsertValue:
2015 E = performSymbolicAggrValueEvaluation(
I);
2017 case Instruction::PHI: {
2019 auto *PN = cast<PHINode>(
I);
2020 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
2021 Ops.
push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2024 E = performSymbolicPHIEvaluation(Ops,
I, getBlockForValue(
I));
2026 case Instruction::Call:
2027 return performSymbolicCallEvaluation(
I);
2029 case Instruction::Store:
2030 E = performSymbolicStoreEvaluation(
I);
2032 case Instruction::Load:
2033 E = performSymbolicLoadEvaluation(
I);
2035 case Instruction::BitCast:
2036 case Instruction::AddrSpaceCast:
2037 case Instruction::Freeze:
2038 return createExpression(
I);
2040 case Instruction::ICmp:
2041 case Instruction::FCmp:
2042 return performSymbolicCmpEvaluation(
I);
2044 case Instruction::FNeg:
2045 case Instruction::Add:
2046 case Instruction::FAdd:
2047 case Instruction::Sub:
2048 case Instruction::FSub:
2049 case Instruction::Mul:
2050 case Instruction::FMul:
2051 case Instruction::UDiv:
2052 case Instruction::SDiv:
2053 case Instruction::FDiv:
2054 case Instruction::URem:
2055 case Instruction::SRem:
2056 case Instruction::FRem:
2057 case Instruction::Shl:
2058 case Instruction::LShr:
2059 case Instruction::AShr:
2060 case Instruction::And:
2061 case Instruction::Or:
2062 case Instruction::Xor:
2063 case Instruction::Trunc:
2064 case Instruction::ZExt:
2065 case Instruction::SExt:
2066 case Instruction::FPToUI:
2067 case Instruction::FPToSI:
2068 case Instruction::UIToFP:
2069 case Instruction::SIToFP:
2070 case Instruction::FPTrunc:
2071 case Instruction::FPExt:
2072 case Instruction::PtrToInt:
2073 case Instruction::IntToPtr:
2074 case Instruction::Select:
2075 case Instruction::ExtractElement:
2076 case Instruction::InsertElement:
2077 case Instruction::GetElementPtr:
2078 return createExpression(
I);
2080 case Instruction::ShuffleVector:
2082 return ExprResult::none();
2084 return ExprResult::none();
2086 return ExprResult::some(
E);
2091template <
typename Map,
typename KeyType>
2092void NewGVN::touchAndErase(Map &M,
const KeyType &Key) {
2093 const auto Result =
M.find_as(Key);
2094 if (Result !=
M.end()) {
2095 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2096 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2103 if (isa<Instruction>(To))
2107void NewGVN::addAdditionalUsers(ExprResult &Res,
Instruction *
User)
const {
2108 if (Res.ExtraDep && Res.ExtraDep !=
User)
2109 addAdditionalUsers(Res.ExtraDep,
User);
2110 Res.ExtraDep =
nullptr;
2113 if (
const auto *PBranch = dyn_cast<PredicateBranch>(Res.PredDep))
2114 PredicateToUsers[PBranch->Condition].
insert(
User);
2115 else if (
const auto *PAssume = dyn_cast<PredicateAssume>(Res.PredDep))
2116 PredicateToUsers[PAssume->Condition].
insert(
User);
2118 Res.PredDep =
nullptr;
2121void NewGVN::markUsersTouched(
Value *V) {
2123 for (
auto *
User :
V->users()) {
2124 assert(isa<Instruction>(
User) &&
"Use of value not within an instruction?");
2125 TouchedInstructions.
set(InstrToDFSNum(
User));
2127 touchAndErase(AdditionalUsers, V);
2131 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2132 MemoryToUsers[To].
insert(U);
2135void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2136 TouchedInstructions.
set(MemoryToDFSNum(MA));
2139void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2140 if (isa<MemoryUse>(MA))
2142 for (
const auto *U : MA->
users())
2143 TouchedInstructions.
set(MemoryToDFSNum(U));
2144 touchAndErase(MemoryToUsers, MA);
2148void NewGVN::markPredicateUsersTouched(
Instruction *
I) {
2149 touchAndErase(PredicateToUsers,
I);
2153void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *
CC) {
2154 for (
const auto *M :
CC->memory())
2155 markMemoryDefTouched(M);
2160void NewGVN::markValueLeaderChangeTouched(CongruenceClass *
CC) {
2161 for (
auto *M : *
CC) {
2162 if (
auto *
I = dyn_cast<Instruction>(M))
2163 TouchedInstructions.
set(InstrToDFSNum(
I));
2170template <
class T,
class Range>
2171T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2172 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2173 for (
const auto X : R) {
2174 auto DFSNum = InstrToDFSNum(
X);
2175 if (DFSNum < MinDFS.second)
2176 MinDFS = {
X, DFSNum};
2178 return MinDFS.first;
2184const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *
CC)
const {
2188 assert(!
CC->definesNoMemory() &&
"Can't get next leader if there is none");
2189 if (
CC->getStoreCount() > 0) {
2190 if (
auto *NL = dyn_cast_or_null<StoreInst>(
CC->getNextLeader().first))
2191 return getMemoryAccess(NL);
2194 *
CC, [&](
const Value *V) {
return isa<StoreInst>(V); }));
2195 return getMemoryAccess(cast<StoreInst>(V));
2201 if (
CC->memory_size() == 1)
2202 return *
CC->memory_begin();
2203 return getMinDFSOfRange<const MemoryPhi>(
CC->memory());
2209Value *NewGVN::getNextValueLeader(CongruenceClass *
CC)
const {
2214 if (
CC->size() == 1 ||
CC == TOPClass) {
2215 return *(
CC->begin());
2216 }
else if (
CC->getNextLeader().first) {
2217 ++NumGVNAvoidedSortedLeaderChanges;
2218 return CC->getNextLeader().first;
2220 ++NumGVNSortedLeaderChanges;
2224 return getMinDFSOfRange<Value>(*
CC);
2237void NewGVN::moveMemoryToNewCongruenceClass(
Instruction *
I,
2239 CongruenceClass *OldClass,
2240 CongruenceClass *NewClass) {
2243 assert((!InstMA || !OldClass->getMemoryLeader() ||
2244 OldClass->getLeader() !=
I ||
2245 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2246 MemoryAccessToClass.
lookup(InstMA)) &&
2247 "Representative MemoryAccess mismatch");
2249 if (!NewClass->getMemoryLeader()) {
2251 assert(NewClass->size() == 1 ||
2252 (isa<StoreInst>(
I) && NewClass->getStoreCount() == 1));
2253 NewClass->setMemoryLeader(InstMA);
2256 << NewClass->getID()
2257 <<
" due to new memory instruction becoming leader\n");
2258 markMemoryLeaderChangeTouched(NewClass);
2260 setMemoryClass(InstMA, NewClass);
2262 if (OldClass->getMemoryLeader() == InstMA) {
2263 if (!OldClass->definesNoMemory()) {
2264 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2266 << OldClass->getID() <<
" to "
2267 << *OldClass->getMemoryLeader()
2268 <<
" due to removal of old leader " << *InstMA <<
"\n");
2269 markMemoryLeaderChangeTouched(OldClass);
2271 OldClass->setMemoryLeader(
nullptr);
2278 CongruenceClass *OldClass,
2279 CongruenceClass *NewClass) {
2280 if (
I == OldClass->getNextLeader().first)
2281 OldClass->resetNextLeader();
2284 NewClass->insert(
I);
2288 if (NewClass->getLeader() !=
I &&
2289 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2290 markValueLeaderChangeTouched(NewClass);
2294 if (
auto *SI = dyn_cast<StoreInst>(
I)) {
2295 OldClass->decStoreCount();
2303 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2306 if (
auto *SE = dyn_cast<StoreExpression>(
E)) {
2307 NewClass->setStoredValue(SE->getStoredValue());
2308 markValueLeaderChangeTouched(NewClass);
2311 << NewClass->getID() <<
" from "
2312 << *NewClass->getLeader() <<
" to " << *SI
2313 <<
" because store joined class\n");
2316 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2320 NewClass->incStoreCount();
2326 auto *InstMA = dyn_cast_or_null<MemoryDef>(getMemoryAccess(
I));
2328 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2329 ValueToClass[
I] = NewClass;
2331 if (OldClass->empty() && OldClass != TOPClass) {
2332 if (OldClass->getDefiningExpr()) {
2333 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2334 <<
" from table\n");
2337 auto Iter = ExpressionToClass.find_as(
2339 if (Iter != ExpressionToClass.end())
2340 ExpressionToClass.erase(Iter);
2341#ifdef EXPENSIVE_CHECKS
2343 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2344 "We erased the expression we just inserted, which should not happen");
2347 }
else if (OldClass->getLeader() ==
I) {
2352 << OldClass->getID() <<
"\n");
2353 ++NumGVNLeaderChanges;
2358 if (OldClass->getStoreCount() == 0) {
2359 if (OldClass->getStoredValue())
2360 OldClass->setStoredValue(
nullptr);
2362 OldClass->setLeader({getNextValueLeader(OldClass),
2363 InstrToDFSNum(getNextValueLeader(OldClass))});
2364 OldClass->resetNextLeader();
2365 markValueLeaderChangeTouched(OldClass);
2371void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2372 touchAndErase(ExpressionToPhiOfOps,
E);
2380 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2381 assert(IClass &&
"Should have found a IClass");
2383 assert(!IClass->isDead() &&
"Found a dead class");
2385 CongruenceClass *EClass =
nullptr;
2386 if (
const auto *VE = dyn_cast<VariableExpression>(
E)) {
2387 EClass = ValueToClass.
lookup(VE->getVariableValue());
2388 }
else if (isa<DeadExpression>(
E)) {
2392 auto lookupResult = ExpressionToClass.insert({
E,
nullptr});
2395 if (lookupResult.second) {
2396 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2397 auto place = lookupResult.first;
2398 place->second = NewClass;
2401 if (
const auto *CE = dyn_cast<ConstantExpression>(
E)) {
2402 NewClass->setLeader({
CE->getConstantValue(), 0});
2403 }
else if (
const auto *SE = dyn_cast<StoreExpression>(
E)) {
2405 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2406 NewClass->setStoredValue(SE->getStoredValue());
2410 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2412 assert(!isa<VariableExpression>(
E) &&
2413 "VariableExpression should have been handled already");
2417 <<
" using expression " << *
E <<
" at "
2418 << NewClass->getID() <<
" and leader "
2419 << *(NewClass->getLeader()));
2420 if (NewClass->getStoredValue())
2422 << *(NewClass->getStoredValue()));
2425 EClass = lookupResult.first->second;
2426 if (isa<ConstantExpression>(
E))
2427 assert((isa<Constant>(EClass->getLeader()) ||
2428 (EClass->getStoredValue() &&
2429 isa<Constant>(EClass->getStoredValue()))) &&
2430 "Any class with a constant expression should have a "
2433 assert(EClass &&
"Somehow don't have an eclass");
2435 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2438 bool ClassChanged = IClass != EClass;
2439 bool LeaderChanged = LeaderChanges.
erase(
I);
2440 if (ClassChanged || LeaderChanged) {
2441 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2444 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2445 markPhiOfOpsChanged(
E);
2448 markUsersTouched(
I);
2450 markMemoryUsersTouched(MA);
2451 if (
auto *CI = dyn_cast<CmpInst>(
I))
2452 markPredicateUsersTouched(CI);
2458 if (ClassChanged && isa<StoreInst>(
I)) {
2459 auto *OldE = ValueToExpression.
lookup(
I);
2462 if (OldE && isa<StoreExpression>(OldE) && *
E != *OldE) {
2466 if (Iter != ExpressionToClass.end())
2467 ExpressionToClass.erase(Iter);
2470 ValueToExpression[
I] =
E;
2477 if (ReachableEdges.
insert({From, To}).second) {
2479 if (ReachableBlocks.
insert(To).second) {
2481 <<
" marked reachable\n");
2482 const auto &InstRange = BlockInstRange.
lookup(To);
2483 TouchedInstructions.
set(InstRange.first, InstRange.second);
2486 <<
" was reachable, but new edge {"
2488 <<
"} to it found\n");
2495 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2500 for (
auto InstNum : RevisitOnReachabilityChange[To])
2501 TouchedInstructions.
set(InstNum);
2510 return isa<Constant>(Result) ?
Result :
nullptr;
2519 Value *CondEvaluated = findConditionEquivalence(
Cond);
2520 if (!CondEvaluated) {
2521 if (
auto *
I = dyn_cast<Instruction>(
Cond)) {
2523 auto Res = performSymbolicEvaluation(
I, Visited);
2524 if (
const auto *CE = dyn_cast_or_null<ConstantExpression>(Res.Expr)) {
2525 CondEvaluated =
CE->getConstantValue();
2526 addAdditionalUsers(Res,
I);
2530 Res.ExtraDep =
nullptr;
2532 }
else if (isa<ConstantInt>(
Cond)) {
2533 CondEvaluated =
Cond;
2537 if (CondEvaluated && (CI = dyn_cast<ConstantInt>(CondEvaluated))) {
2540 <<
" evaluated to true\n");
2541 updateReachableEdge(
B, TrueSucc);
2542 }
else if (CI->
isZero()) {
2544 <<
" evaluated to false\n");
2545 updateReachableEdge(
B, FalseSucc);
2548 updateReachableEdge(
B, TrueSucc);
2549 updateReachableEdge(
B, FalseSucc);
2551 }
else if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
2555 Value *SwitchCond =
SI->getCondition();
2556 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2558 if (CondEvaluated && isa<ConstantInt>(CondEvaluated)) {
2559 auto *CondVal = cast<ConstantInt>(CondEvaluated);
2561 auto Case = *
SI->findCaseValue(CondVal);
2562 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2566 updateReachableEdge(
B,
SI->getDefaultDest());
2570 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2571 updateReachableEdge(
B, TargetBlock);
2574 updateReachableEdge(
B, TargetBlock);
2580 updateReachableEdge(
B, TargetBlock);
2585 auto *MA = getMemoryAccess(TI);
2586 if (MA && !isa<MemoryUse>(MA)) {
2587 auto *
CC = ensureLeaderOfMemoryClass(MA);
2588 if (setMemoryClass(MA,
CC))
2589 markMemoryUsersTouched(MA);
2596 InstrDFS.
erase(PHITemp);
2599 TempToBlock.
erase(PHITemp);
2610 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2612 TempToBlock[
Op] = BB;
2613 RealToTemp[ExistingValue] =
Op;
2616 for (
auto *U : ExistingValue->
users())
2617 if (
auto *UI = dyn_cast<Instruction>(U))
2624 return isa<BinaryOperator>(
I) || isa<SelectInst>(
I) || isa<CmpInst>(
I) ||
2639 while (!Worklist.
empty()) {
2641 if (!isa<Instruction>(
I))
2644 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2645 if (OISIt != OpSafeForPHIOfOps.
end())
2646 return OISIt->second;
2651 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2655 if (isa<PHINode>(
I) && getBlockForValue(
I) == PHIBlock) {
2656 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2660 auto *OrigI = cast<Instruction>(
I);
2667 if (OrigI->mayReadFromMemory())
2671 for (
auto *
Op : OrigI->operand_values()) {
2672 if (!isa<Instruction>(
Op))
2675 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2676 if (OISIt != OpSafeForPHIOfOps.
end()) {
2677 if (!OISIt->second) {
2678 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2688 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2701 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2703 AllTempInstructions.
insert(TransInst);
2707 TempToBlock.
insert({TransInst, PredBB});
2708 InstrDFS.
insert({TransInst, IDFSNum});
2710 auto Res = performSymbolicEvaluation(TransInst, Visited);
2712 addAdditionalUsers(Res, OrigInst);
2713 InstrDFS.
erase(TransInst);
2714 AllTempInstructions.
erase(TransInst);
2715 TempToBlock.
erase(TransInst);
2717 TempToMemory.
erase(TransInst);
2720 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2722 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2723 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2727 if (
auto *SI = dyn_cast<StoreInst>(FoundVal))
2728 FoundVal =
SI->getValueOperand();
2740 if (!Visited.
insert(
I).second)
2746 if (!isCycleFree(
I))
2753 auto *MemAccess = getMemoryAccess(
I);
2757 if (MemAccess && !isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2758 MemAccess->getDefiningAccess()->
getBlock() ==
I->getParent())
2768 for (
auto *
Op : Ops) {
2769 if (!isa<PHINode>(
Op)) {
2770 auto *ValuePHI = RealToTemp.
lookup(
Op);
2776 OpPHI = cast<PHINode>(
Op);
2777 if (!SamePHIBlock) {
2778 SamePHIBlock = getBlockForValue(OpPHI);
2779 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2782 <<
"PHIs for operands are not all in the same block, aborting\n");
2797 auto *PHIBlock = getBlockForValue(OpPHI);
2798 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2799 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2801 Value *FoundVal =
nullptr;
2805 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2813 TempToMemory.
insert({ValueOp, MemAccess});
2814 bool SafeForPHIOfOps =
true;
2817 auto *OrigOp = &*
Op;
2820 if (isa<PHINode>(
Op)) {
2821 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2822 if (
Op != OrigOp &&
Op !=
I)
2824 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2825 if (getBlockForValue(ValuePHI) == PHIBlock)
2826 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2831 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2838 FoundVal = !SafeForPHIOfOps ? nullptr
2839 : findLeaderForInst(ValueOp, Visited,
2840 MemAccess,
I, PredBB);
2845 if (SafeForPHIOfOps)
2846 for (
auto *Dep : CurrentDeps)
2847 addAdditionalUsers(Dep,
I);
2853 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2855 <<
" because the block is unreachable\n");
2857 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2861 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2864 for (
auto *Dep : Deps)
2865 addAdditionalUsers(Dep,
I);
2867 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2868 if (isa<ConstantExpression>(
E) || isa<VariableExpression>(
E)) {
2871 <<
"Not creating real PHI of ops because it simplified to existing "
2872 "value or constant\n");
2878 for (
auto &O : PHIOps)
2879 addAdditionalUsers(
O.first,
I);
2883 auto *ValuePHI = RealToTemp.
lookup(
I);
2884 bool NewPHI =
false;
2888 addPhiOfOps(ValuePHI, PHIBlock,
I);
2890 NumGVNPHIOfOpsCreated++;
2893 for (
auto PHIOp : PHIOps)
2894 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2896 TempToBlock[ValuePHI] = PHIBlock;
2898 for (
auto PHIOp : PHIOps) {
2899 ValuePHI->setIncomingValue(i, PHIOp.first);
2900 ValuePHI->setIncomingBlock(i, PHIOp.second);
2904 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2905 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2914void NewGVN::initializeCongruenceClasses(
Function &
F) {
2915 NextCongruenceNum = 0;
2925 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2931 for (
auto *DTN :
nodes(DT)) {
2938 if (MemoryBlockDefs)
2939 for (
const auto &Def : *MemoryBlockDefs) {
2940 MemoryAccessToClass[&
Def] = TOPClass;
2941 auto *MD = dyn_cast<MemoryDef>(&Def);
2944 const MemoryPhi *MP = cast<MemoryPhi>(&Def);
2945 TOPClass->memory_insert(MP);
2946 MemoryPhiState.
insert({MP, MPS_TOP});
2949 if (MD && isa<StoreInst>(MD->getMemoryInst()))
2950 TOPClass->incStoreCount();
2956 for (
auto &
I : *BB) {
2957 if (isa<PHINode>(&
I))
2958 for (
auto *U :
I.users())
2959 if (
auto *UInst = dyn_cast<Instruction>(U))
2961 PHINodeUses.
insert(UInst);
2964 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2966 TOPClass->insert(&
I);
2967 ValueToClass[&
I] = TOPClass;
2972 for (
auto &FA :
F.args())
2973 createSingletonCongruenceClass(&FA);
2976void NewGVN::cleanupTables() {
2977 for (CongruenceClass *&
CC : CongruenceClasses) {
2979 <<
CC->size() <<
" members\n");
2988 AllTempInstructions.
end());
2989 AllTempInstructions.
clear();
2993 for (
auto *
I : TempInst) {
2994 I->dropAllReferences();
2997 while (!TempInst.empty()) {
2998 auto *
I = TempInst.pop_back_val();
3002 ValueToClass.
clear();
3003 ArgRecycler.
clear(ExpressionAllocator);
3004 ExpressionAllocator.
Reset();
3005 CongruenceClasses.clear();
3006 ExpressionToClass.clear();
3007 ValueToExpression.
clear();
3009 AdditionalUsers.
clear();
3010 ExpressionToPhiOfOps.
clear();
3011 TempToBlock.
clear();
3012 TempToMemory.
clear();
3013 PHINodeUses.
clear();
3014 OpSafeForPHIOfOps.
clear();
3015 ReachableBlocks.
clear();
3016 ReachableEdges.
clear();
3018 ProcessedCount.
clear();
3021 InstructionsToErase.
clear();
3023 BlockInstRange.
clear();
3024 TouchedInstructions.
clear();
3025 MemoryAccessToClass.
clear();
3026 PredicateToUsers.
clear();
3027 MemoryToUsers.
clear();
3028 RevisitOnReachabilityChange.
clear();
3029 IntrinsicInstPred.
clear();
3034std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(
BasicBlock *
B,
3036 unsigned End = Start;
3038 InstrDFS[MemPhi] =
End++;
3043 for (
auto &
I : *
B) {
3049 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3050 markInstructionForDeletion(&
I);
3053 if (isa<PHINode>(&
I))
3054 RevisitOnReachabilityChange[
B].set(
End);
3055 InstrDFS[&
I] =
End++;
3062 return std::make_pair(Start,
End);
3065void NewGVN::updateProcessedCount(
const Value *V) {
3067 if (ProcessedCount.
count(V) == 0) {
3068 ProcessedCount.
insert({
V, 1});
3070 ++ProcessedCount[
V];
3071 assert(ProcessedCount[V] < 100 &&
3072 "Seem to have processed the same Value a lot");
3078void NewGVN::valueNumberMemoryPhi(
MemoryPhi *MP) {
3085 return cast<MemoryAccess>(U) != MP &&
3086 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3087 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3092 if (Filtered.begin() == Filtered.end()) {
3093 if (setMemoryClass(MP, TOPClass))
3094 markMemoryUsersTouched(MP);
3100 auto LookupFunc = [&](
const Use &
U) {
3101 return lookupMemoryLeader(cast<MemoryAccess>(U));
3103 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3104 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3108 const auto *AllSameValue = *MappedBegin;
3110 bool AllEqual = std::all_of(
3111 MappedBegin, MappedEnd,
3112 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3115 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3124 CongruenceClass *
CC =
3125 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3126 auto OldState = MemoryPhiState.
lookup(MP);
3127 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3128 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3129 MemoryPhiState[MP] = NewState;
3130 if (setMemoryClass(MP,
CC) || OldState != NewState)
3131 markMemoryUsersTouched(MP);
3138 if (!
I->isTerminator()) {
3142 auto Res = performSymbolicEvaluation(
I, Visited);
3143 Symbolized = Res.Expr;
3144 addAdditionalUsers(Res,
I);
3147 if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
3148 !isa<VariableExpression>(Symbolized) && PHINodeUses.
count(
I)) {
3149 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3154 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3155 removePhiOfOps(
I,
Op);
3164 if (Symbolized ==
nullptr)
3165 Symbolized = createUnknownExpression(
I);
3166 performCongruenceFinding(
I, Symbolized);
3171 if (!
I->getType()->isVoidTy()) {
3172 auto *Symbolized = createUnknownExpression(
I);
3173 performCongruenceFinding(
I, Symbolized);
3175 processOutgoingEdges(
I,
I->getParent());
3181bool NewGVN::singleReachablePHIPath(
3184 if (
First == Second)
3197 const auto *EndDef =
First;
3199 if (ChainDef == Second)
3205 auto *MP = cast<MemoryPhi>(EndDef);
3206 auto ReachableOperandPred = [&](
const Use &
U) {
3209 auto FilteredPhiArgs =
3212 llvm::copy(FilteredPhiArgs, std::back_inserter(OperandList));
3215 return singleReachablePHIPath(Visited, cast<MemoryAccess>(OperandList[0]),
3224void NewGVN::verifyMemoryCongruency()
const {
3227 for (
const auto *
CC : CongruenceClasses) {
3228 if (
CC == TOPClass ||
CC->isDead())
3230 if (
CC->getStoreCount() != 0) {
3231 assert((
CC->getStoredValue() || !isa<StoreInst>(
CC->getLeader())) &&
3232 "Any class with a store as a leader should have a "
3233 "representative stored value");
3235 "Any congruence class with a store should have a "
3236 "representative access");
3239 if (
CC->getMemoryLeader())
3241 "Representative MemoryAccess does not appear to be reverse "
3243 for (
const auto *M :
CC->memory())
3245 "Memory member does not appear to be reverse mapped properly");
3253 auto ReachableAccessPred =
3254 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3255 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3257 MemoryToDFSNum(Pair.first) == 0)
3259 if (
auto *MemDef = dyn_cast<MemoryDef>(Pair.first))
3264 if (
auto *MemPHI = dyn_cast<MemoryPhi>(Pair.first)) {
3265 for (
const auto &U : MemPHI->incoming_values()) {
3266 if (
auto *
I = dyn_cast<Instruction>(&*U)) {
3278 for (
auto KV : Filtered) {
3279 if (
auto *FirstMUD = dyn_cast<MemoryUseOrDef>(KV.first)) {
3280 auto *SecondMUD = dyn_cast<MemoryUseOrDef>(KV.second->getMemoryLeader());
3281 if (FirstMUD && SecondMUD) {
3283 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3284 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3285 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3286 "The instructions for these memory operations should have "
3287 "been in the same congruence class or reachable through"
3288 "a single argument phi");
3290 }
else if (
auto *FirstMP = dyn_cast<MemoryPhi>(KV.first)) {
3293 auto ReachableOperandPred = [&](
const Use &
U) {
3294 return ReachableEdges.
count(
3295 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3299 auto FilteredPhiArgs =
3302 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3303 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3304 const MemoryDef *MD = cast<MemoryDef>(U);
3305 return ValueToClass.lookup(MD->getMemoryInst());
3308 "All MemoryPhi arguments should be in the same class");
3317void NewGVN::verifyIterationSettled(
Function &
F) {
3327 std::map<const Value *, CongruenceClass> BeforeIteration;
3329 for (
auto &KV : ValueToClass) {
3330 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3332 if (InstrToDFSNum(
I) == 0)
3334 BeforeIteration.insert({KV.first, *KV.second});
3337 TouchedInstructions.
set();
3338 TouchedInstructions.
reset(0);
3339 OpSafeForPHIOfOps.
clear();
3341 iterateTouchedInstructions();
3344 for (
const auto &KV : ValueToClass) {
3345 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3347 if (InstrToDFSNum(
I) == 0)
3351 auto *BeforeCC = &BeforeIteration.
find(KV.first)->second;
3352 auto *AfterCC = KV.second;
3355 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3356 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3357 "Value number changed after main loop completed!");
3358 EqualClasses.
insert({BeforeCC, AfterCC});
3369void NewGVN::verifyStoreExpressions()
const {
3374 std::pair<
const Value *,
3375 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3377 for (
const auto &KV : ExpressionToClass) {
3378 if (
auto *SE = dyn_cast<StoreExpression>(KV.first)) {
3380 auto Res = StoreExpressionSet.insert(
3381 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3382 SE->getStoredValue())});
3383 bool Okay = Res.second;
3388 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3389 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3390 lookupOperandLeader(SE->getStoredValue()));
3391 assert(Okay &&
"Stored expression conflict exists in expression table");
3392 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3393 assert(ValueExpr && ValueExpr->equals(*SE) &&
3394 "StoreExpression in ExpressionToClass is not latest "
3395 "StoreExpression for value");
3404void NewGVN::iterateTouchedInstructions() {
3407 int FirstInstr = TouchedInstructions.
find_first();
3409 if (FirstInstr == -1)
3411 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3412 while (TouchedInstructions.
any()) {
3418 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3422 if (InstrNum == 0) {
3423 TouchedInstructions.
reset(InstrNum);
3427 Value *
V = InstrFromDFSNum(InstrNum);
3428 const BasicBlock *CurrBlock = getBlockForValue(V);
3431 if (CurrBlock != LastBlock) {
3432 LastBlock = CurrBlock;
3433 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3434 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3437 if (!BlockReachable) {
3438 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3441 <<
" because it is unreachable\n");
3446 updateProcessedCount(CurrBlock);
3450 TouchedInstructions.
reset(InstrNum);
3452 if (
auto *MP = dyn_cast<MemoryPhi>(V)) {
3454 valueNumberMemoryPhi(MP);
3455 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
3456 valueNumberInstruction(
I);
3460 updateProcessedCount(V);
3463 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3467bool NewGVN::runGVN() {
3470 bool Changed =
false;
3471 NumFuncArgs =
F.arg_size();
3473 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3477 unsigned ICount = 1;
3489 unsigned Counter = 0;
3490 for (
auto &
B : RPOT) {
3492 assert(
Node &&
"RPO and Dominator tree should have same reachability");
3493 RPOOrdering[
Node] = ++Counter;
3496 for (
auto &
B : RPOT) {
3498 if (
Node->getNumChildren() > 1)
3500 return RPOOrdering[
A] < RPOOrdering[
B];
3507 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3508 BlockInstRange.
insert({
B, BlockRange});
3509 ICount += BlockRange.second - BlockRange.first;
3511 initializeCongruenceClasses(
F);
3513 TouchedInstructions.
resize(ICount);
3517 ExpressionToClass.reserve(ICount);
3520 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3521 TouchedInstructions.
set(InstRange.first, InstRange.second);
3523 <<
" marked reachable\n");
3524 ReachableBlocks.
insert(&
F.getEntryBlock());
3528 iterateTouchedInstructions();
3529 verifyMemoryCongruency();
3530 verifyIterationSettled(
F);
3531 verifyStoreExpressions();
3533 Changed |= eliminateInstructions(
F);
3536 for (
Instruction *ToErase : InstructionsToErase) {
3537 if (!ToErase->use_empty())
3540 assert(ToErase->getParent() &&
3541 "BB containing ToErase deleted unexpectedly!");
3542 ToErase->eraseFromParent();
3544 Changed |= !InstructionsToErase.empty();
3547 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3548 return !ReachableBlocks.
count(&BB);
3553 <<
" is unreachable\n");
3554 deleteInstructionsInBlock(&BB);
3612 return std::tie(DFSIn, DFSOut,
LocalNum, Def, U) <
3623void NewGVN::convertClassToDFSOrdered(
3632 assert(BB &&
"Should have figured out a basic block for value");
3640 if (
auto *SI = dyn_cast<StoreInst>(
D)) {
3641 auto Leader = lookupOperandLeader(SI->getValueOperand());
3643 VDDef.
Def.setPointer(Leader);
3645 VDDef.
Def.setPointer(
SI->getValueOperand());
3646 VDDef.
Def.setInt(
true);
3649 VDDef.
Def.setPointer(
D);
3652 "The dense set member should always be an instruction");
3657 if (
auto *PN = RealToTemp.
lookup(Def)) {
3659 dyn_cast_or_null<PHIExpression>(ValueToExpression.
lookup(Def));
3661 VDDef.
Def.setInt(
false);
3662 VDDef.
Def.setPointer(PN);
3668 unsigned int UseCount = 0;
3670 for (
auto &U :
Def->uses()) {
3671 if (
auto *
I = dyn_cast<Instruction>(
U.getUser())) {
3673 if (InstructionsToErase.count(
I))
3678 if (
auto *
P = dyn_cast<PHINode>(
I)) {
3679 IBlock =
P->getIncomingBlock(U);
3684 IBlock = getBlockForValue(
I);
3690 if (!ReachableBlocks.
contains(IBlock))
3706 ProbablyDead.
insert(Def);
3708 UseCounts[
Def] = UseCount;
3714void NewGVN::convertClassToLoadsAndStores(
3715 const CongruenceClass &
Dense,
3718 if (!isa<LoadInst>(
D) && !isa<StoreInst>(
D))
3726 VD.
Def.setPointer(
D);
3729 if (
auto *
I = dyn_cast<Instruction>(
D))
3740 I->replaceAllUsesWith(Repl);
3743void NewGVN::deleteInstructionsInBlock(
BasicBlock *BB) {
3745 ++NumGVNBlocksDeleted;
3749 auto StartPoint = BB->
rbegin();
3757 if (isa<LandingPadInst>(Inst))
3762 ++NumGVNInstrDeleted;
3772void NewGVN::markInstructionForDeletion(
Instruction *
I) {
3774 InstructionsToErase.insert(
I);
3782 markInstructionForDeletion(
I);
3789class ValueDFSStack {
3791 Value *back()
const {
return ValueStack.back(); }
3792 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3794 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3795 ValueStack.emplace_back(V);
3796 DFSStack.emplace_back(DFSIn, DFSOut);
3799 bool empty()
const {
return DFSStack.empty(); }
3801 bool isInScope(
int DFSIn,
int DFSOut)
const {
3804 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3807 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3810 assert(ValueStack.size() == DFSStack.size() &&
3811 "Mismatch between ValueStack and DFSStack");
3813 !DFSStack.empty() &&
3814 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3815 DFSStack.pop_back();
3816 ValueStack.pop_back();
3828CongruenceClass *NewGVN::getClassForExpression(
const Expression *E)
const {
3829 if (
auto *VE = dyn_cast<VariableExpression>(E))
3830 return ValueToClass.lookup(VE->getVariableValue());
3831 else if (isa<DeadExpression>(E))
3833 return ExpressionToClass.lookup(E);
3842 if (
auto *CE = dyn_cast<ConstantExpression>(E))
3843 return CE->getConstantValue();
3844 if (
auto *VE = dyn_cast<VariableExpression>(E)) {
3845 auto *
V = VE->getVariableValue();
3847 return VE->getVariableValue();
3850 auto *
CC = getClassForExpression(E);
3854 return CC->getLeader();
3856 for (
auto *Member : *
CC) {
3857 auto *MemberInst = dyn_cast<Instruction>(Member);
3858 if (MemberInst == OrigInst)
3863 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3869bool NewGVN::eliminateInstructions(
Function &
F) {
3893 bool AnythingReplaced =
false;
3902 for (
auto &Operand :
PHI->incoming_values())
3903 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3907 <<
" with poison due to it being unreachable\n");
3921 for (
auto &KV : ReachableEdges)
3922 ReachablePredCount[KV.getEnd()]++;
3923 for (
auto &BBPair : RevisitOnReachabilityChange) {
3924 for (
auto InstNum : BBPair.second) {
3925 auto *Inst = InstrFromDFSNum(InstNum);
3926 auto *
PHI = dyn_cast<PHINode>(Inst);
3930 auto *BB = BBPair.first;
3931 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3932 ReplaceUnreachablePHIArgs(
PHI, BB);
3938 for (
auto *
CC :
reverse(CongruenceClasses)) {
3945 if (
CC->isDead() ||
CC->empty())
3948 if (
CC == TOPClass) {
3949 for (
auto *M : *
CC) {
3950 auto *VTE = ValueToExpression.
lookup(M);
3951 if (VTE && isa<DeadExpression>(VTE))
3952 markInstructionForDeletion(cast<Instruction>(M));
3953 assert((!ReachableBlocks.
count(cast<Instruction>(M)->getParent()) ||
3954 InstructionsToErase.count(cast<Instruction>(M))) &&
3955 "Everything in TOP should be unreachable or dead at this "
3961 assert(
CC->getLeader() &&
"We should have had a leader");
3967 CC->getStoredValue() ?
CC->getStoredValue() :
CC->getLeader();
3970 for (
auto *M : *
CC) {
3973 if (Member == Leader || !isa<Instruction>(Member) ||
3974 Member->getType()->isVoidTy()) {
3975 MembersLeft.
insert(Member);
3979 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3980 << *Member <<
"\n");
3981 auto *
I = cast<Instruction>(Member);
3982 assert(Leader !=
I &&
"About to accidentally remove our leader");
3983 replaceInstruction(
I, Leader);
3984 AnythingReplaced =
true;
3986 CC->swap(MembersLeft);
3989 if (
CC->size() != 1 || RealToTemp.
count(Leader)) {
3994 ValueDFSStack EliminationStack;
3998 convertClassToDFSOrdered(*
CC, DFSOrderedSet, UseCounts, ProbablyDead);
4002 for (
auto &VD : DFSOrderedSet) {
4003 int MemberDFSIn = VD.
DFSIn;
4004 int MemberDFSOut = VD.
DFSOut;
4006 bool FromStore = VD.
Def.getInt();
4009 if (Def &&
Def->getType()->isVoidTy())
4011 auto *DefInst = dyn_cast_or_null<Instruction>(Def);
4012 if (DefInst && AllTempInstructions.
count(DefInst)) {
4013 auto *PN = cast<PHINode>(DefInst);
4018 AllTempInstructions.
erase(PN);
4019 auto *DefBlock = getBlockForValue(Def);
4023 PN->insertBefore(&DefBlock->front());
4025 NumGVNPHIOfOpsEliminations++;
4028 if (EliminationStack.empty()) {
4032 << EliminationStack.dfs_back().first <<
","
4033 << EliminationStack.dfs_back().second <<
")\n");
4036 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4037 << MemberDFSOut <<
")\n");
4051 bool ShouldPush =
Def && EliminationStack.empty();
4053 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4055 if (OutOfScope || ShouldPush) {
4057 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4058 bool ShouldPush =
Def && EliminationStack.empty();
4060 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4079 auto *DefI = dyn_cast<Instruction>(Def);
4080 if (!EliminationStack.empty() && DefI && !FromStore) {
4081 Value *DominatingLeader = EliminationStack.back();
4082 if (DominatingLeader != Def) {
4085 if (!
match(DefI, m_Intrinsic<Intrinsic::ssa_copy>()))
4088 markInstructionForDeletion(DefI);
4096 assert(isa<Instruction>(
U->get()) &&
4097 "Current def should have been an instruction");
4098 assert(isa<Instruction>(
U->getUser()) &&
4099 "Current user should have been an instruction");
4105 Instruction *InstUse = cast<Instruction>(
U->getUser());
4106 if (InstructionsToErase.count(InstUse)) {
4107 auto &UseCount = UseCounts[
U->get()];
4108 if (--UseCount == 0) {
4109 ProbablyDead.
insert(cast<Instruction>(
U->get()));
4115 if (EliminationStack.empty())
4118 Value *DominatingLeader = EliminationStack.back();
4120 auto *
II = dyn_cast<IntrinsicInst>(DominatingLeader);
4121 bool isSSACopy =
II &&
II->getIntrinsicID() == Intrinsic::ssa_copy;
4123 DominatingLeader =
II->getOperand(0);
4126 if (
U->get() == DominatingLeader)
4132 auto *ReplacedInst = cast<Instruction>(
U->get());
4133 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4134 if (!PI || DominatingLeader != PI->OriginalOp)
4138 <<
"Found replacement " << *DominatingLeader <<
" for "
4139 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4140 U->set(DominatingLeader);
4143 auto &LeaderUseCount = UseCounts[DominatingLeader];
4145 if (LeaderUseCount == 0 && isa<Instruction>(DominatingLeader))
4146 ProbablyDead.
erase(cast<Instruction>(DominatingLeader));
4150 auto It = UseCounts.
find(
II);
4151 if (It != UseCounts.
end()) {
4152 unsigned &IIUseCount = It->second;
4153 if (--IIUseCount == 0)
4158 AnythingReplaced =
true;
4165 for (
auto *
I : ProbablyDead)
4167 markInstructionForDeletion(
I);
4171 for (
auto *Member : *
CC)
4172 if (!isa<Instruction>(Member) ||
4173 !InstructionsToErase.count(cast<Instruction>(Member)))
4174 MembersLeft.
insert(Member);
4175 CC->swap(MembersLeft);
4178 if (
CC->getStoreCount() > 0) {
4179 convertClassToLoadsAndStores(*
CC, PossibleDeadStores);
4181 ValueDFSStack EliminationStack;
4182 for (
auto &VD : PossibleDeadStores) {
4183 int MemberDFSIn = VD.
DFSIn;
4184 int MemberDFSOut = VD.
DFSOut;
4186 if (EliminationStack.empty() ||
4187 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4189 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4190 if (EliminationStack.empty()) {
4191 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4196 if (isa<LoadInst>(Member))
4198 assert(!EliminationStack.empty());
4199 Instruction *Leader = cast<Instruction>(EliminationStack.back());
4204 <<
" that is dominated by " << *Leader <<
"\n");
4205 markInstructionForDeletion(Member);
4211 return AnythingReplaced;
4219unsigned int NewGVN::getRank(
const Value *V)
const {
4225 if (isa<ConstantExpr>(V))
4227 if (isa<PoisonValue>(V))
4229 if (isa<UndefValue>(V))
4231 if (isa<Constant>(V))
4233 if (
auto *
A = dyn_cast<Argument>(V))
4234 return 4 +
A->getArgNo();
4238 unsigned Result = InstrToDFSNum(V);
4240 return 5 + NumFuncArgs +
Result;
4247bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4251 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4254bool NewGVN::shouldSwapOperandsForIntrinsic(
const Value *
A,
const Value *
B,
4257 if (shouldSwapOperands(
A,
B)) {
4258 if (LookupResult == IntrinsicInstPred.
end())
4265 if (LookupResult != IntrinsicInstPred.
end()) {
4267 if (SeenPredicate) {
4268 if (SeenPredicate ==
B)
4287 NewGVN(
F, &DT, &AC, &TLI, &AA, &MSSA,
F.getDataLayout())
Unify divergent function exit nodes
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
This file implements the BitVector class.
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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")
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.
std::optional< std::vector< StOtherPiece > > Other
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
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.
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
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.
std::optional< AttributeList > intersectWith(LLVMContext &C, AttributeList Other) const
Try to intersect this AttributeList with Other.
LLVM Basic Block Representation.
reverse_iterator rbegin()
InstListType::reverse_iterator reverse_iterator
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
Allocate memory in an ever growing pool, as if by bump-pointer.
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.
AttributeList getAttributes() const
Return the attributes for this call.
This class represents a function call, abstracting a target machine's calling convention.
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,...
static bool isImpliedTrueByMatchingCmp(Predicate Pred1, Predicate Pred2)
Determine if Pred1 implies Pred2 is true when two compares have matching operands.
static bool isImpliedFalseByMatchingCmp(Predicate Pred1, Predicate Pred2)
Determine if Pred1 implies Pred2 is false when two compares have matching operands.
This is the shared class of boolean and integer constants.
bool isOne() const
This is just a convenience method to make client code smaller for a common case.
static ConstantInt * getTrue(LLVMContext &Context)
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getFalse(LLVMContext &Context)
This is an important base class in LLVM.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
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.
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
bool equals(const Expression &Other) const override
~CallExpression() override
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
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
bool isCommutative() const LLVM_READONLY
Return true if the instruction is commutative:
bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
const Function * getFunction() const
Return the function this instruction belongs to.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Value * getPointerOperand()
BasicBlock * getBlock() const
Represents phi nodes for memory accesses.
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.
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.
Class that has the common methods + fields of memory uses/defs.
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
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 PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Encapsulates PredicateInfo, including all data associated with memory accesses.
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.
void 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.
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)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
static 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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVMContext & getContext() const
All values hold a context through their type.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< 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.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
friend const_iterator begin(StringRef path, Style style)
Get begin iterator over path.
friend const_iterator end(StringRef path)
Get end iterator over path.
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.
@ C
The default llvm calling convention, compatible with C.
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< ExecutorSymbolDef > LookupResult
NodeAddr< DefNode * > Def
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const_iterator end(StringRef path)
Get end iterator over path.
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.
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.
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.
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
Value * simplifyCastInst(unsigned CastOpc, Value *Op, Type *Ty, const SimplifyQuery &Q)
Given operands for a CastInst, fold the result or return null.
void erase(Container &C, ValueType V)
Wrapper function to remove a value from a container:
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
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)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
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.
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...
Constant * ConstantFoldInstOperands(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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
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
OutputIt copy(R &&Range, OutputIt Out)
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.
Value * simplifyCmpInst(CmpPredicate Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, fold the result or return null.
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.
Value * simplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal, const SimplifyQuery &Q)
Given operands for a SelectInst, fold the result or return null.
iterator_range< def_chain_iterator< T, true > > optimized_def_chain(T MA)
Implement std::hash so that hash_code can be used in STL containers.
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...
ExactEqualsExpression(const Expression &E)
hash_code getComputedHash() const
bool operator==(const Expression &Other) const
SimplifyQuery getWithInstruction(const Instruction *I) const