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; }
308 bool isDead()
const {
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))
974 if (
auto *
I = dyn_cast<Instruction>(V)) {
975 auto *Parent =
I->getParent();
978 Parent = TempToBlock.
lookup(V);
979 assert(Parent &&
"Every fake instruction should have a block");
983 auto *MP = dyn_cast<MemoryPhi>(V);
984 assert(MP &&
"Should have been an instruction or a MemoryPhi");
985 return MP->getBlock();
991void NewGVN::deleteExpression(
const Expression *
E)
const {
992 assert(isa<BasicExpression>(
E));
993 auto *BE = cast<BasicExpression>(
E);
1000 if (
auto *
II = dyn_cast<IntrinsicInst>(V))
1001 if (
II->getIntrinsicID() == Intrinsic::ssa_copy)
1002 return II->getOperand(0);
1013 return CO && isa<PHINode>(CO);
1020 llvm::sort(Ops, [&](
const ValPair &P1,
const ValPair &P2) {
1021 return BlockInstRange.
lookup(P1.second).first <
1022 BlockInstRange.
lookup(P2.second).first;
1030 return isa<Constant>(V) || isa<Argument>(V);
1042 bool &OriginalOpsConstant)
const {
1043 unsigned NumOps = PHIOperands.
size();
1044 auto *
E =
new (ExpressionAllocator)
PHIExpression(NumOps, PHIBlock);
1046 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1047 E->setType(PHIOperands.
begin()->first->getType());
1048 E->setOpcode(Instruction::PHI);
1052 auto *BB =
P.second;
1053 if (
auto *PHIOp = dyn_cast<PHINode>(
I))
1056 if (!ReachableEdges.
count({BB, PHIBlock}))
1059 if (ValueToClass.
lookup(
P.first) == TOPClass)
1061 OriginalOpsConstant = OriginalOpsConstant && isa<Constant>(
P.first);
1062 HasBackedge = HasBackedge || isBackedge(BB, PHIBlock);
1063 return lookupOperandLeader(
P.first) !=
I;
1065 std::transform(Filtered.begin(), Filtered.end(),
op_inserter(
E),
1066 [&](
const ValPair &
P) ->
Value * {
1067 return lookupOperandLeader(
P.first);
1075 bool AllConstant =
true;
1076 if (
auto *
GEP = dyn_cast<GetElementPtrInst>(
I))
1077 E->setType(
GEP->getSourceElementType());
1079 E->setType(
I->getType());
1080 E->setOpcode(
I->getOpcode());
1081 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1086 auto Operand = lookupOperandLeader(O);
1087 AllConstant = AllConstant && isa<Constant>(Operand);
1094const Expression *NewGVN::createBinaryExpression(
unsigned Opcode,
Type *
T,
1103 E->setOpcode(Opcode);
1104 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1110 if (shouldSwapOperands(Arg1, Arg2))
1113 E->op_push_back(lookupOperandLeader(Arg1));
1114 E->op_push_back(lookupOperandLeader(Arg2));
1117 if (
auto Simplified = checkExprResults(
E,
I, V)) {
1118 addAdditionalUsers(Simplified,
I);
1130 return ExprResult::none();
1132 if (
auto *
C = dyn_cast<Constant>(V)) {
1135 <<
" constant " << *
C <<
"\n");
1136 NumGVNOpsSimplified++;
1137 assert(isa<BasicExpression>(
E) &&
1138 "We should always have had a basic expression here");
1139 deleteExpression(
E);
1140 return ExprResult::some(createConstantExpression(
C));
1141 }
else if (isa<Argument>(V) || isa<GlobalVariable>(V)) {
1144 <<
" variable " << *V <<
"\n");
1145 deleteExpression(
E);
1146 return ExprResult::some(createVariableExpression(V));
1149 CongruenceClass *
CC = ValueToClass.
lookup(V);
1151 if (
CC->getLeader() &&
CC->getLeader() !=
I) {
1152 return ExprResult::some(createVariableOrConstant(
CC->getLeader()), V);
1154 if (
CC->getDefiningExpr()) {
1157 <<
" expression " << *
CC->getDefiningExpr() <<
"\n");
1158 NumGVNOpsSimplified++;
1159 deleteExpression(
E);
1160 return ExprResult::some(
CC->getDefiningExpr(), V);
1164 return ExprResult::none();
1170NewGVN::ExprResult NewGVN::createExpression(
Instruction *
I)
const {
1176 bool AllConstant = setBasicExpressionInfo(
I,
E);
1178 if (
I->isCommutative()) {
1183 assert(
I->getNumOperands() == 2 &&
"Unsupported commutative instruction!");
1184 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1185 E->swapOperands(0, 1);
1188 if (
auto *CI = dyn_cast<CmpInst>(
I)) {
1192 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1))) {
1193 E->swapOperands(0, 1);
1196 E->setOpcode((CI->getOpcode() << 8) | Predicate);
1198 assert(
I->getOperand(0)->getType() ==
I->getOperand(1)->getType() &&
1199 "Wrong types on cmp instruction");
1200 assert((
E->getOperand(0)->getType() ==
I->getOperand(0)->getType() &&
1201 E->getOperand(1)->getType() ==
I->getOperand(1)->getType()));
1204 if (
auto Simplified = checkExprResults(
E,
I, V))
1206 }
else if (isa<SelectInst>(
I)) {
1207 if (isa<Constant>(
E->getOperand(0)) ||
1208 E->getOperand(1) ==
E->getOperand(2)) {
1209 assert(
E->getOperand(1)->getType() ==
I->getOperand(1)->getType() &&
1210 E->getOperand(2)->getType() ==
I->getOperand(2)->getType());
1212 E->getOperand(2), Q);
1213 if (
auto Simplified = checkExprResults(
E,
I, V))
1216 }
else if (
I->isBinaryOp()) {
1219 if (
auto Simplified = checkExprResults(
E,
I, V))
1221 }
else if (
auto *CI = dyn_cast<CastInst>(
I)) {
1224 if (
auto Simplified = checkExprResults(
E,
I, V))
1226 }
else if (
auto *GEPI = dyn_cast<GetElementPtrInst>(
I)) {
1228 ArrayRef(std::next(
E->op_begin()),
E->op_end()),
1229 GEPI->getNoWrapFlags(), Q);
1230 if (
auto Simplified = checkExprResults(
E,
I, V))
1232 }
else if (AllConstant) {
1241 for (
Value *Arg :
E->operands())
1242 C.emplace_back(cast<Constant>(Arg));
1245 if (
auto Simplified = checkExprResults(
E,
I, V))
1248 return ExprResult::some(
E);
1252NewGVN::createAggregateValueExpression(
Instruction *
I)
const {
1253 if (
auto *
II = dyn_cast<InsertValueInst>(
I)) {
1254 auto *
E =
new (ExpressionAllocator)
1256 setBasicExpressionInfo(
I,
E);
1257 E->allocateIntOperands(ExpressionAllocator);
1260 }
else if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1261 auto *
E =
new (ExpressionAllocator)
1263 setBasicExpressionInfo(EI,
E);
1264 E->allocateIntOperands(ExpressionAllocator);
1274 return SingletonDeadExpression;
1279 E->setOpcode(
V->getValueID());
1284 if (
auto *
C = dyn_cast<Constant>(V))
1285 return createConstantExpression(
C);
1286 return createVariableExpression(V);
1291 E->setOpcode(
C->getValueID());
1297 E->setOpcode(
I->getOpcode());
1306 setBasicExpressionInfo(CI,
E);
1312 if (shouldSwapOperands(
E->getOperand(0),
E->getOperand(1)))
1313 E->swapOperands(0, 1);
1319bool NewGVN::someEquivalentDominates(
const Instruction *Inst,
1321 auto *
CC = ValueToClass.
lookup(Inst);
1342 if (DT->
dominates(cast<Instruction>(
CC->getLeader()), U))
1344 if (
CC->getNextLeader().first &&
1345 DT->
dominates(cast<Instruction>(
CC->getNextLeader().first), U))
1348 return Member !=
CC->getLeader() &&
1349 DT->
dominates(cast<Instruction>(Member), U);
1355Value *NewGVN::lookupOperandLeader(
Value *V)
const {
1356 CongruenceClass *
CC = ValueToClass.
lookup(V);
1363 return CC->getStoredValue() ?
CC->getStoredValue() :
CC->getLeader();
1370 auto *
CC = getMemoryClass(MA);
1372 "Every MemoryAccess should be mapped to a congruence class with a "
1373 "representative memory access");
1374 return CC->getMemoryLeader();
1380bool NewGVN::isMemoryAccessTOP(
const MemoryAccess *MA)
const {
1381 return getMemoryClass(MA) == TOPClass;
1388 new (ExpressionAllocator)
LoadExpression(1, LI, lookupMemoryLeader(MA));
1389 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1390 E->setType(LoadType);
1394 E->op_push_back(PointerOp);
1404 auto *StoredValueLeader = lookupOperandLeader(
SI->getValueOperand());
1405 auto *
E =
new (ExpressionAllocator)
1407 E->allocateOperands(ArgRecycler, ExpressionAllocator);
1408 E->setType(
SI->getValueOperand()->getType());
1412 E->op_push_back(lookupOperandLeader(
SI->getPointerOperand()));
1423 auto *
SI = cast<StoreInst>(
I);
1424 auto *StoreAccess = getMemoryAccess(SI);
1426 const MemoryAccess *StoreRHS = StoreAccess->getDefiningAccess();
1430 StoreRHS = lookupMemoryLeader(StoreRHS);
1431 if (StoreRHS != StoreAccess->getDefiningAccess())
1432 addMemoryUsers(StoreRHS, StoreAccess);
1434 if (StoreRHS == StoreAccess)
1437 if (
SI->isSimple()) {
1441 const auto *LastStore = createStoreExpression(SI, StoreRHS);
1442 const auto *LastCC = ExpressionToClass.lookup(LastStore);
1448 if (LastCC && LastCC->getStoredValue() == LastStore->getStoredValue())
1454 if (
auto *LI = dyn_cast<LoadInst>(LastStore->getStoredValue()))
1456 LastStore->getOperand(0)) &&
1457 (lookupMemoryLeader(getMemoryAccess(LI)->getDefiningAccess()) ==
1460 deleteExpression(LastStore);
1466 return createStoreExpression(SI, StoreAccess);
1472NewGVN::performSymbolicLoadCoercion(
Type *LoadType,
Value *LoadPtr,
1476 if (
auto *DepSI = dyn_cast<StoreInst>(DepInst)) {
1480 if (LI->
isAtomic() > DepSI->isAtomic() ||
1481 LoadType == DepSI->getValueOperand()->getType())
1485 if (
auto *
C = dyn_cast<Constant>(
1486 lookupOperandLeader(DepSI->getValueOperand()))) {
1489 <<
" to constant " << *Res <<
"\n");
1490 return createConstantExpression(Res);
1494 }
else if (
auto *DepLI = dyn_cast<LoadInst>(DepInst)) {
1496 if (LI->
isAtomic() > DepLI->isAtomic())
1501 if (
auto *
C = dyn_cast<Constant>(lookupOperandLeader(DepLI)))
1502 if (
auto *PossibleConstant =
1505 <<
" to constant " << *PossibleConstant <<
"\n");
1506 return createConstantExpression(PossibleConstant);
1509 }
else if (
auto *DepMI = dyn_cast<MemIntrinsic>(DepInst)) {
1512 if (
auto *PossibleConstant =
1515 <<
" to constant " << *PossibleConstant <<
"\n");
1516 return createConstantExpression(PossibleConstant);
1523 if (LoadPtr != lookupOperandLeader(DepInst) &&
1530 if (isa<AllocaInst>(DepInst)) {
1535 else if (
auto *
II = dyn_cast<IntrinsicInst>(DepInst)) {
1536 if (
II->getIntrinsicID() == Intrinsic::lifetime_start)
1538 }
else if (
auto *InitVal =
1540 return createConstantExpression(InitVal);
1546 auto *LI = cast<LoadInst>(
I);
1555 if (isa<UndefValue>(LoadAddressLeader))
1562 if (
auto *MD = dyn_cast<MemoryDef>(DefiningAccess)) {
1571 if (
const auto *CoercionResult =
1572 performSymbolicLoadCoercion(LI->
getType(), LoadAddressLeader, LI,
1573 DefiningInst, DefiningAccess))
1574 return CoercionResult;
1578 const auto *
LE = createLoadExpression(LI->
getType(), LoadAddressLeader, LI,
1582 if (
LE->getMemoryLeader() != DefiningAccess)
1583 addMemoryUsers(
LE->getMemoryLeader(), OriginalAccess);
1588NewGVN::performSymbolicPredicateInfoEvaluation(
IntrinsicInst *
I)
const {
1589 auto *PI = PredInfo->getPredicateInfoFor(
I);
1591 return ExprResult::none();
1593 LLVM_DEBUG(
dbgs() <<
"Found predicate info from instruction !\n");
1595 const std::optional<PredicateConstraint> &Constraint = PI->getConstraint();
1597 return ExprResult::none();
1600 Value *CmpOp0 =
I->getOperand(0);
1601 Value *CmpOp1 = Constraint->OtherOp;
1603 Value *FirstOp = lookupOperandLeader(CmpOp0);
1604 Value *SecondOp = lookupOperandLeader(CmpOp1);
1605 Value *AdditionallyUsedValue = CmpOp0;
1608 if (shouldSwapOperandsForIntrinsic(FirstOp, SecondOp,
I)) {
1611 AdditionallyUsedValue = CmpOp1;
1615 return ExprResult::some(createVariableOrConstant(FirstOp),
1616 AdditionallyUsedValue, PI);
1620 !cast<ConstantFP>(FirstOp)->
isZero())
1621 return ExprResult::some(createConstantExpression(cast<Constant>(FirstOp)),
1622 AdditionallyUsedValue, PI);
1624 return ExprResult::none();
1628NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(
Instruction *
I)
const {
1629 auto *CI = cast<CallInst>(
I);
1630 if (
auto *
II = dyn_cast<IntrinsicInst>(
I)) {
1632 if (
auto *ReturnedValue =
II->getReturnedArgOperand()) {
1633 if (
II->getIntrinsicID() == Intrinsic::ssa_copy)
1634 if (
auto Res = performSymbolicPredicateInfoEvaluation(
II))
1636 return ExprResult::some(createVariableOrConstant(ReturnedValue));
1648 return ExprResult::none();
1654 return ExprResult::none();
1657 return ExprResult::some(
1658 createCallExpression(CI, TOPClass->getMemoryLeader()));
1662 return ExprResult::some(createCallExpression(CI, DefiningAccess));
1664 return ExprResult::some(
1665 createCallExpression(CI, TOPClass->getMemoryLeader()));
1667 return ExprResult::none();
1671CongruenceClass *NewGVN::getMemoryClass(
const MemoryAccess *MA)
const {
1673 assert(Result &&
"Should have found memory class");
1680 CongruenceClass *NewClass) {
1682 "Every MemoryAccess should be getting mapped to a non-null class");
1686 <<
" with current MemoryAccess leader ");
1690 bool Changed =
false;
1692 if (LookupResult != MemoryAccessToClass.
end()) {
1694 if (OldClass != NewClass) {
1696 if (
auto *MP = dyn_cast<MemoryPhi>(
From)) {
1697 OldClass->memory_erase(MP);
1698 NewClass->memory_insert(MP);
1700 if (OldClass->getMemoryLeader() ==
From) {
1701 if (OldClass->definesNoMemory()) {
1702 OldClass->setMemoryLeader(
nullptr);
1704 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
1706 << OldClass->getID() <<
" to "
1707 << *OldClass->getMemoryLeader()
1708 <<
" due to removal of a memory member " << *
From
1710 markMemoryLeaderChangeTouched(OldClass);
1733 auto ICS = InstCycleState.
lookup(
I);
1734 if (ICS == ICS_Unknown) {
1736 auto &
SCC = SCCFinder.getComponentFor(
I);
1738 if (
SCC.size() == 1)
1739 InstCycleState.
insert({
I, ICS_CycleFree});
1744 ICS = AllPhis ? ICS_CycleFree : ICS_Cycle;
1745 for (
const auto *Member : SCC)
1746 if (
auto *MemberPhi = dyn_cast<PHINode>(Member))
1747 InstCycleState.
insert({MemberPhi, ICS});
1750 if (ICS == ICS_Cycle)
1761 bool HasBackedge =
false;
1766 bool OriginalOpsConstant =
true;
1767 auto *
E = cast<PHIExpression>(createPHIExpression(
1768 PHIOps,
I, PHIBlock, HasBackedge, OriginalOpsConstant));
1772 bool HasUndef =
false, HasPoison =
false;
1774 if (isa<PoisonValue>(Arg)) {
1778 if (isa<UndefValue>(Arg)) {
1785 if (Filtered.empty()) {
1790 dbgs() <<
"PHI Node " << *
I
1791 <<
" has no non-undef arguments, valuing it as undef\n");
1796 dbgs() <<
"PHI Node " << *
I
1797 <<
" has no non-poison arguments, valuing it as poison\n");
1801 LLVM_DEBUG(
dbgs() <<
"No arguments of PHI node " << *
I <<
" are live\n");
1802 deleteExpression(
E);
1803 return createDeadExpression();
1805 Value *AllSameValue = *(Filtered.begin());
1823 if (HasPoison || HasUndef) {
1829 if (HasBackedge && !OriginalOpsConstant &&
1830 !isa<UndefValue>(AllSameValue) && !isCycleFree(
I))
1834 if (
auto *AllSameInst = dyn_cast<Instruction>(AllSameValue))
1835 if (!someEquivalentDominates(AllSameInst,
I))
1841 if (isa<Instruction>(AllSameValue) &&
1842 InstrToDFSNum(AllSameValue) > InstrToDFSNum(
I))
1844 NumGVNPhisAllSame++;
1845 LLVM_DEBUG(
dbgs() <<
"Simplified PHI node " << *
I <<
" to " << *AllSameValue
1847 deleteExpression(
E);
1848 return createVariableOrConstant(AllSameValue);
1854NewGVN::performSymbolicAggrValueEvaluation(
Instruction *
I)
const {
1855 if (
auto *EI = dyn_cast<ExtractValueInst>(
I)) {
1856 auto *WO = dyn_cast<WithOverflowInst>(EI->getAggregateOperand());
1857 if (WO && EI->getNumIndices() == 1 && *EI->idx_begin() == 0)
1861 return createBinaryExpression(WO->getBinaryOp(), EI->getType(),
1862 WO->getLHS(), WO->getRHS(),
I);
1865 return createAggregateValueExpression(
I);
1868NewGVN::ExprResult NewGVN::performSymbolicCmpEvaluation(
Instruction *
I)
const {
1869 assert(isa<CmpInst>(
I) &&
"Expected a cmp instruction.");
1871 auto *CI = cast<CmpInst>(
I);
1874 auto Op0 = lookupOperandLeader(CI->
getOperand(0));
1875 auto Op1 = lookupOperandLeader(CI->
getOperand(1));
1876 auto OurPredicate = CI->getPredicate();
1877 if (shouldSwapOperands(Op0, Op1)) {
1879 OurPredicate = CI->getSwappedPredicate();
1886 auto *CmpPI = PredInfo->getPredicateInfoFor(
I);
1887 if (isa_and_nonnull<PredicateAssume>(CmpPI))
1888 return ExprResult::some(
1893 if (CI->isTrueWhenEqual())
1894 return ExprResult::some(
1896 else if (CI->isFalseWhenEqual())
1897 return ExprResult::some(
1927 auto *PI = PredInfo->getPredicateInfoFor(
Op);
1928 if (
const auto *PBranch = dyn_cast_or_null<PredicateBranch>(PI)) {
1929 if (PI == LastPredInfo)
1934 if (!DT->
dominates(PBranch->To,
I->getParent()))
1941 auto *BranchCond = dyn_cast<CmpInst>(PBranch->Condition);
1944 auto *BranchOp0 = lookupOperandLeader(BranchCond->getOperand(0));
1945 auto *BranchOp1 = lookupOperandLeader(BranchCond->getOperand(1));
1946 auto BranchPredicate = BranchCond->getPredicate();
1947 if (shouldSwapOperands(BranchOp0, BranchOp1)) {
1949 BranchPredicate = BranchCond->getSwappedPredicate();
1951 if (BranchOp0 == Op0 && BranchOp1 == Op1) {
1952 if (PBranch->TrueEdge) {
1957 return ExprResult::some(
1964 return ExprResult::some(
1971 if (BranchPredicate == OurPredicate) {
1973 return ExprResult::some(
1976 }
else if (BranchPredicate ==
1979 return ExprResult::some(
1988 return createExpression(
I);
2000 switch (
I->getOpcode()) {
2001 case Instruction::ExtractValue:
2002 case Instruction::InsertValue:
2003 E = performSymbolicAggrValueEvaluation(
I);
2005 case Instruction::PHI: {
2007 auto *PN = cast<PHINode>(
I);
2008 for (
unsigned i = 0; i < PN->getNumOperands(); ++i)
2009 Ops.
push_back({PN->getIncomingValue(i), PN->getIncomingBlock(i)});
2012 E = performSymbolicPHIEvaluation(Ops,
I, getBlockForValue(
I));
2014 case Instruction::Call:
2015 return performSymbolicCallEvaluation(
I);
2017 case Instruction::Store:
2018 E = performSymbolicStoreEvaluation(
I);
2020 case Instruction::Load:
2021 E = performSymbolicLoadEvaluation(
I);
2023 case Instruction::BitCast:
2024 case Instruction::AddrSpaceCast:
2025 case Instruction::Freeze:
2026 return createExpression(
I);
2028 case Instruction::ICmp:
2029 case Instruction::FCmp:
2030 return performSymbolicCmpEvaluation(
I);
2032 case Instruction::FNeg:
2033 case Instruction::Add:
2034 case Instruction::FAdd:
2035 case Instruction::Sub:
2036 case Instruction::FSub:
2037 case Instruction::Mul:
2038 case Instruction::FMul:
2039 case Instruction::UDiv:
2040 case Instruction::SDiv:
2041 case Instruction::FDiv:
2042 case Instruction::URem:
2043 case Instruction::SRem:
2044 case Instruction::FRem:
2045 case Instruction::Shl:
2046 case Instruction::LShr:
2047 case Instruction::AShr:
2048 case Instruction::And:
2049 case Instruction::Or:
2050 case Instruction::Xor:
2051 case Instruction::Trunc:
2052 case Instruction::ZExt:
2053 case Instruction::SExt:
2054 case Instruction::FPToUI:
2055 case Instruction::FPToSI:
2056 case Instruction::UIToFP:
2057 case Instruction::SIToFP:
2058 case Instruction::FPTrunc:
2059 case Instruction::FPExt:
2060 case Instruction::PtrToInt:
2061 case Instruction::IntToPtr:
2062 case Instruction::Select:
2063 case Instruction::ExtractElement:
2064 case Instruction::InsertElement:
2065 case Instruction::GetElementPtr:
2066 return createExpression(
I);
2068 case Instruction::ShuffleVector:
2070 return ExprResult::none();
2072 return ExprResult::none();
2074 return ExprResult::some(
E);
2079template <
typename Map,
typename KeyType>
2080void NewGVN::touchAndErase(Map &M,
const KeyType &Key) {
2081 const auto Result =
M.find_as(Key);
2082 if (Result !=
M.end()) {
2083 for (
const typename Map::mapped_type::value_type Mapped :
Result->second)
2084 TouchedInstructions.
set(InstrToDFSNum(Mapped));
2091 if (isa<Instruction>(To))
2095void NewGVN::addAdditionalUsers(ExprResult &Res,
Instruction *
User)
const {
2096 if (Res.ExtraDep && Res.ExtraDep !=
User)
2097 addAdditionalUsers(Res.ExtraDep,
User);
2098 Res.ExtraDep =
nullptr;
2101 if (
const auto *PBranch = dyn_cast<PredicateBranch>(Res.PredDep))
2102 PredicateToUsers[PBranch->Condition].
insert(
User);
2103 else if (
const auto *PAssume = dyn_cast<PredicateAssume>(Res.PredDep))
2104 PredicateToUsers[PAssume->Condition].
insert(
User);
2106 Res.PredDep =
nullptr;
2109void NewGVN::markUsersTouched(
Value *V) {
2111 for (
auto *
User :
V->users()) {
2112 assert(isa<Instruction>(
User) &&
"Use of value not within an instruction?");
2113 TouchedInstructions.
set(InstrToDFSNum(
User));
2115 touchAndErase(AdditionalUsers, V);
2119 LLVM_DEBUG(
dbgs() <<
"Adding memory user " << *U <<
" to " << *To <<
"\n");
2120 MemoryToUsers[To].
insert(U);
2123void NewGVN::markMemoryDefTouched(
const MemoryAccess *MA) {
2124 TouchedInstructions.
set(MemoryToDFSNum(MA));
2127void NewGVN::markMemoryUsersTouched(
const MemoryAccess *MA) {
2128 if (isa<MemoryUse>(MA))
2130 for (
const auto *U : MA->
users())
2131 TouchedInstructions.
set(MemoryToDFSNum(U));
2132 touchAndErase(MemoryToUsers, MA);
2136void NewGVN::markPredicateUsersTouched(
Instruction *
I) {
2137 touchAndErase(PredicateToUsers,
I);
2141void NewGVN::markMemoryLeaderChangeTouched(CongruenceClass *
CC) {
2142 for (
const auto *M :
CC->memory())
2143 markMemoryDefTouched(M);
2148void NewGVN::markValueLeaderChangeTouched(CongruenceClass *
CC) {
2149 for (
auto *M : *
CC) {
2150 if (
auto *
I = dyn_cast<Instruction>(M))
2151 TouchedInstructions.
set(InstrToDFSNum(
I));
2158template <
class T,
class Range>
2159T *NewGVN::getMinDFSOfRange(
const Range &R)
const {
2160 std::pair<T *, unsigned> MinDFS = {
nullptr, ~0
U};
2161 for (
const auto X : R) {
2162 auto DFSNum = InstrToDFSNum(
X);
2163 if (DFSNum < MinDFS.second)
2164 MinDFS = {
X, DFSNum};
2166 return MinDFS.first;
2172const MemoryAccess *NewGVN::getNextMemoryLeader(CongruenceClass *
CC)
const {
2176 assert(!
CC->definesNoMemory() &&
"Can't get next leader if there is none");
2177 if (
CC->getStoreCount() > 0) {
2178 if (
auto *
NL = dyn_cast_or_null<StoreInst>(
CC->getNextLeader().first))
2179 return getMemoryAccess(
NL);
2182 *
CC, [&](
const Value *V) {
return isa<StoreInst>(V); }));
2183 return getMemoryAccess(cast<StoreInst>(V));
2189 if (
CC->memory_size() == 1)
2190 return *
CC->memory_begin();
2191 return getMinDFSOfRange<const MemoryPhi>(
CC->memory());
2197Value *NewGVN::getNextValueLeader(CongruenceClass *
CC)
const {
2202 if (
CC->size() == 1 ||
CC == TOPClass) {
2203 return *(
CC->begin());
2204 }
else if (
CC->getNextLeader().first) {
2205 ++NumGVNAvoidedSortedLeaderChanges;
2206 return CC->getNextLeader().first;
2208 ++NumGVNSortedLeaderChanges;
2212 return getMinDFSOfRange<Value>(*
CC);
2225void NewGVN::moveMemoryToNewCongruenceClass(
Instruction *
I,
2227 CongruenceClass *OldClass,
2228 CongruenceClass *NewClass) {
2231 assert((!InstMA || !OldClass->getMemoryLeader() ||
2232 OldClass->getLeader() !=
I ||
2233 MemoryAccessToClass.
lookup(OldClass->getMemoryLeader()) ==
2234 MemoryAccessToClass.
lookup(InstMA)) &&
2235 "Representative MemoryAccess mismatch");
2237 if (!NewClass->getMemoryLeader()) {
2239 assert(NewClass->size() == 1 ||
2240 (isa<StoreInst>(
I) && NewClass->getStoreCount() == 1));
2241 NewClass->setMemoryLeader(InstMA);
2244 << NewClass->getID()
2245 <<
" due to new memory instruction becoming leader\n");
2246 markMemoryLeaderChangeTouched(NewClass);
2248 setMemoryClass(InstMA, NewClass);
2250 if (OldClass->getMemoryLeader() == InstMA) {
2251 if (!OldClass->definesNoMemory()) {
2252 OldClass->setMemoryLeader(getNextMemoryLeader(OldClass));
2254 << OldClass->getID() <<
" to "
2255 << *OldClass->getMemoryLeader()
2256 <<
" due to removal of old leader " << *InstMA <<
"\n");
2257 markMemoryLeaderChangeTouched(OldClass);
2259 OldClass->setMemoryLeader(
nullptr);
2266 CongruenceClass *OldClass,
2267 CongruenceClass *NewClass) {
2268 if (
I == OldClass->getNextLeader().first)
2269 OldClass->resetNextLeader();
2272 NewClass->insert(
I);
2276 if (NewClass->getLeader() !=
I &&
2277 NewClass->addPossibleLeader({I, InstrToDFSNum(I)})) {
2278 markValueLeaderChangeTouched(NewClass);
2282 if (
auto *SI = dyn_cast<StoreInst>(
I)) {
2283 OldClass->decStoreCount();
2291 if (NewClass->getStoreCount() == 0 && !NewClass->getStoredValue()) {
2294 if (
auto *SE = dyn_cast<StoreExpression>(
E)) {
2295 NewClass->setStoredValue(SE->getStoredValue());
2296 markValueLeaderChangeTouched(NewClass);
2299 << NewClass->getID() <<
" from "
2300 << *NewClass->getLeader() <<
" to " << *SI
2301 <<
" because store joined class\n");
2304 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2308 NewClass->incStoreCount();
2314 auto *InstMA = dyn_cast_or_null<MemoryDef>(getMemoryAccess(
I));
2316 moveMemoryToNewCongruenceClass(
I, InstMA, OldClass, NewClass);
2317 ValueToClass[
I] = NewClass;
2319 if (OldClass->empty() && OldClass != TOPClass) {
2320 if (OldClass->getDefiningExpr()) {
2321 LLVM_DEBUG(
dbgs() <<
"Erasing expression " << *OldClass->getDefiningExpr()
2322 <<
" from table\n");
2325 auto Iter = ExpressionToClass.find_as(
2327 if (Iter != ExpressionToClass.end())
2328 ExpressionToClass.erase(Iter);
2329#ifdef EXPENSIVE_CHECKS
2331 (*OldClass->getDefiningExpr() != *
E || ExpressionToClass.lookup(
E)) &&
2332 "We erased the expression we just inserted, which should not happen");
2335 }
else if (OldClass->getLeader() ==
I) {
2340 << OldClass->getID() <<
"\n");
2341 ++NumGVNLeaderChanges;
2346 if (OldClass->getStoreCount() == 0) {
2347 if (OldClass->getStoredValue())
2348 OldClass->setStoredValue(
nullptr);
2350 OldClass->setLeader({getNextValueLeader(OldClass),
2351 InstrToDFSNum(getNextValueLeader(OldClass))});
2352 OldClass->resetNextLeader();
2353 markValueLeaderChangeTouched(OldClass);
2359void NewGVN::markPhiOfOpsChanged(
const Expression *
E) {
2360 touchAndErase(ExpressionToPhiOfOps,
E);
2368 CongruenceClass *IClass = ValueToClass.
lookup(
I);
2369 assert(IClass &&
"Should have found a IClass");
2371 assert(!IClass->isDead() &&
"Found a dead class");
2373 CongruenceClass *EClass =
nullptr;
2374 if (
const auto *VE = dyn_cast<VariableExpression>(
E)) {
2375 EClass = ValueToClass.
lookup(VE->getVariableValue());
2376 }
else if (isa<DeadExpression>(
E)) {
2380 auto lookupResult = ExpressionToClass.insert({
E,
nullptr});
2383 if (lookupResult.second) {
2384 CongruenceClass *NewClass = createCongruenceClass(
nullptr,
E);
2385 auto place = lookupResult.first;
2386 place->second = NewClass;
2389 if (
const auto *CE = dyn_cast<ConstantExpression>(
E)) {
2390 NewClass->setLeader({
CE->getConstantValue(), 0});
2391 }
else if (
const auto *SE = dyn_cast<StoreExpression>(
E)) {
2393 NewClass->setLeader({
SI, InstrToDFSNum(SI)});
2394 NewClass->setStoredValue(SE->getStoredValue());
2398 NewClass->setLeader({
I, InstrToDFSNum(
I)});
2400 assert(!isa<VariableExpression>(
E) &&
2401 "VariableExpression should have been handled already");
2405 <<
" using expression " << *
E <<
" at "
2406 << NewClass->getID() <<
" and leader "
2407 << *(NewClass->getLeader()));
2408 if (NewClass->getStoredValue())
2410 << *(NewClass->getStoredValue()));
2413 EClass = lookupResult.first->second;
2414 if (isa<ConstantExpression>(
E))
2415 assert((isa<Constant>(EClass->getLeader()) ||
2416 (EClass->getStoredValue() &&
2417 isa<Constant>(EClass->getStoredValue()))) &&
2418 "Any class with a constant expression should have a "
2421 assert(EClass &&
"Somehow don't have an eclass");
2423 assert(!EClass->isDead() &&
"We accidentally looked up a dead class");
2426 bool ClassChanged = IClass != EClass;
2427 bool LeaderChanged = LeaderChanges.
erase(
I);
2428 if (ClassChanged || LeaderChanged) {
2429 LLVM_DEBUG(
dbgs() <<
"New class " << EClass->getID() <<
" for expression "
2432 moveValueToNewCongruenceClass(
I,
E, IClass, EClass);
2433 markPhiOfOpsChanged(
E);
2436 markUsersTouched(
I);
2438 markMemoryUsersTouched(MA);
2439 if (
auto *CI = dyn_cast<CmpInst>(
I))
2440 markPredicateUsersTouched(CI);
2446 if (ClassChanged && isa<StoreInst>(
I)) {
2447 auto *OldE = ValueToExpression.
lookup(
I);
2450 if (OldE && isa<StoreExpression>(OldE) && *
E != *OldE) {
2454 if (Iter != ExpressionToClass.end())
2455 ExpressionToClass.erase(Iter);
2458 ValueToExpression[
I] =
E;
2465 if (ReachableEdges.
insert({From, To}).second) {
2467 if (ReachableBlocks.
insert(To).second) {
2469 <<
" marked reachable\n");
2470 const auto &InstRange = BlockInstRange.
lookup(To);
2471 TouchedInstructions.
set(InstRange.first, InstRange.second);
2474 <<
" was reachable, but new edge {"
2476 <<
"} to it found\n");
2483 TouchedInstructions.
set(InstrToDFSNum(MemPhi));
2488 for (
auto InstNum : RevisitOnReachabilityChange[To])
2489 TouchedInstructions.
set(InstNum);
2498 return isa<Constant>(Result) ?
Result :
nullptr;
2507 Value *CondEvaluated = findConditionEquivalence(
Cond);
2508 if (!CondEvaluated) {
2509 if (
auto *
I = dyn_cast<Instruction>(
Cond)) {
2511 auto Res = performSymbolicEvaluation(
I, Visited);
2512 if (
const auto *CE = dyn_cast_or_null<ConstantExpression>(Res.Expr)) {
2513 CondEvaluated =
CE->getConstantValue();
2514 addAdditionalUsers(Res,
I);
2518 Res.ExtraDep =
nullptr;
2520 }
else if (isa<ConstantInt>(
Cond)) {
2521 CondEvaluated =
Cond;
2525 if (CondEvaluated && (CI = dyn_cast<ConstantInt>(CondEvaluated))) {
2528 <<
" evaluated to true\n");
2529 updateReachableEdge(
B, TrueSucc);
2530 }
else if (CI->
isZero()) {
2532 <<
" evaluated to false\n");
2533 updateReachableEdge(
B, FalseSucc);
2536 updateReachableEdge(
B, TrueSucc);
2537 updateReachableEdge(
B, FalseSucc);
2539 }
else if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
2543 Value *SwitchCond =
SI->getCondition();
2544 Value *CondEvaluated = findConditionEquivalence(SwitchCond);
2546 if (CondEvaluated && isa<ConstantInt>(CondEvaluated)) {
2547 auto *CondVal = cast<ConstantInt>(CondEvaluated);
2549 auto Case = *
SI->findCaseValue(CondVal);
2550 if (Case.getCaseSuccessor() ==
SI->getDefaultDest()) {
2554 updateReachableEdge(
B,
SI->getDefaultDest());
2558 BasicBlock *TargetBlock = Case.getCaseSuccessor();
2559 updateReachableEdge(
B, TargetBlock);
2562 updateReachableEdge(
B, TargetBlock);
2568 updateReachableEdge(
B, TargetBlock);
2573 auto *MA = getMemoryAccess(TI);
2574 if (MA && !isa<MemoryUse>(MA)) {
2575 auto *
CC = ensureLeaderOfMemoryClass(MA);
2576 if (setMemoryClass(MA,
CC))
2577 markMemoryUsersTouched(MA);
2584 InstrDFS.
erase(PHITemp);
2587 TempToBlock.
erase(PHITemp);
2598 InstrDFS[
Op] = InstrToDFSNum(ExistingValue);
2600 TempToBlock[
Op] = BB;
2601 RealToTemp[ExistingValue] =
Op;
2604 for (
auto *U : ExistingValue->
users())
2605 if (
auto *UI = dyn_cast<Instruction>(U))
2612 return isa<BinaryOperator>(
I) || isa<SelectInst>(
I) || isa<CmpInst>(
I) ||
2627 while (!Worklist.
empty()) {
2629 if (!isa<Instruction>(
I))
2632 auto OISIt = OpSafeForPHIOfOps.
find({
I, CacheIdx});
2633 if (OISIt != OpSafeForPHIOfOps.
end())
2634 return OISIt->second;
2639 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
true});
2643 if (isa<PHINode>(
I) && getBlockForValue(
I) == PHIBlock) {
2644 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2648 auto *OrigI = cast<Instruction>(
I);
2655 if (OrigI->mayReadFromMemory())
2659 for (
auto *
Op : OrigI->operand_values()) {
2660 if (!isa<Instruction>(
Op))
2663 auto OISIt = OpSafeForPHIOfOps.
find({OrigI, CacheIdx});
2664 if (OISIt != OpSafeForPHIOfOps.
end()) {
2665 if (!OISIt->second) {
2666 OpSafeForPHIOfOps.
insert({{
I, CacheIdx},
false});
2676 OpSafeForPHIOfOps.
insert({{
V, CacheIdx},
true});
2689 unsigned IDFSNum = InstrToDFSNum(OrigInst);
2691 AllTempInstructions.
insert(TransInst);
2695 TempToBlock.
insert({TransInst, PredBB});
2696 InstrDFS.
insert({TransInst, IDFSNum});
2698 auto Res = performSymbolicEvaluation(TransInst, Visited);
2700 addAdditionalUsers(Res, OrigInst);
2701 InstrDFS.
erase(TransInst);
2702 AllTempInstructions.
erase(TransInst);
2703 TempToBlock.
erase(TransInst);
2705 TempToMemory.
erase(TransInst);
2708 auto *FoundVal = findPHIOfOpsLeader(
E, OrigInst, PredBB);
2710 ExpressionToPhiOfOps[
E].
insert(OrigInst);
2711 LLVM_DEBUG(
dbgs() <<
"Cannot find phi of ops operand for " << *TransInst
2715 if (
auto *SI = dyn_cast<StoreInst>(FoundVal))
2716 FoundVal =
SI->getValueOperand();
2728 if (!Visited.
insert(
I).second)
2734 if (!isCycleFree(
I))
2741 auto *MemAccess = getMemoryAccess(
I);
2745 if (MemAccess && !isa<MemoryPhi>(MemAccess->getDefiningAccess()) &&
2746 MemAccess->getDefiningAccess()->
getBlock() ==
I->getParent())
2756 for (
auto *
Op : Ops) {
2757 if (!isa<PHINode>(
Op)) {
2758 auto *ValuePHI = RealToTemp.
lookup(
Op);
2764 OpPHI = cast<PHINode>(
Op);
2765 if (!SamePHIBlock) {
2766 SamePHIBlock = getBlockForValue(OpPHI);
2767 }
else if (SamePHIBlock != getBlockForValue(OpPHI)) {
2770 <<
"PHIs for operands are not all in the same block, aborting\n");
2785 auto *PHIBlock = getBlockForValue(OpPHI);
2786 RevisitOnReachabilityChange[PHIBlock].reset(InstrToDFSNum(
I));
2787 for (
unsigned PredNum = 0; PredNum < OpPHI->
getNumOperands(); ++PredNum) {
2789 Value *FoundVal =
nullptr;
2793 if (ReachableEdges.
count({PredBB, PHIBlock})) {
2801 TempToMemory.
insert({ValueOp, MemAccess});
2802 bool SafeForPHIOfOps =
true;
2805 auto *OrigOp = &*
Op;
2808 if (isa<PHINode>(
Op)) {
2809 Op =
Op->DoPHITranslation(PHIBlock, PredBB);
2810 if (
Op != OrigOp &&
Op !=
I)
2812 }
else if (
auto *ValuePHI = RealToTemp.
lookup(
Op)) {
2813 if (getBlockForValue(ValuePHI) == PHIBlock)
2814 Op = ValuePHI->getIncomingValueForBlock(PredBB);
2819 (
Op != OrigOp || OpIsSafeForPHIOfOps(
Op, PHIBlock, VisitedOps));
2826 FoundVal = !SafeForPHIOfOps ? nullptr
2827 : findLeaderForInst(ValueOp, Visited,
2828 MemAccess,
I, PredBB);
2833 if (SafeForPHIOfOps)
2834 for (
auto *Dep : CurrentDeps)
2835 addAdditionalUsers(Dep,
I);
2841 LLVM_DEBUG(
dbgs() <<
"Skipping phi of ops operand for incoming block "
2843 <<
" because the block is unreachable\n");
2845 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2849 LLVM_DEBUG(
dbgs() <<
"Found phi of ops operand " << *FoundVal <<
" in "
2852 for (
auto *Dep : Deps)
2853 addAdditionalUsers(Dep,
I);
2855 auto *
E = performSymbolicPHIEvaluation(PHIOps,
I, PHIBlock);
2856 if (isa<ConstantExpression>(
E) || isa<VariableExpression>(
E)) {
2859 <<
"Not creating real PHI of ops because it simplified to existing "
2860 "value or constant\n");
2866 for (
auto &O : PHIOps)
2867 addAdditionalUsers(
O.first,
I);
2871 auto *ValuePHI = RealToTemp.
lookup(
I);
2872 bool NewPHI =
false;
2876 addPhiOfOps(ValuePHI, PHIBlock,
I);
2878 NumGVNPHIOfOpsCreated++;
2881 for (
auto PHIOp : PHIOps)
2882 ValuePHI->addIncoming(PHIOp.first, PHIOp.second);
2884 TempToBlock[ValuePHI] = PHIBlock;
2886 for (
auto PHIOp : PHIOps) {
2887 ValuePHI->setIncomingValue(i, PHIOp.first);
2888 ValuePHI->setIncomingBlock(i, PHIOp.second);
2892 RevisitOnReachabilityChange[PHIBlock].set(InstrToDFSNum(
I));
2893 LLVM_DEBUG(
dbgs() <<
"Created phi of ops " << *ValuePHI <<
" for " << *
I
2902void NewGVN::initializeCongruenceClasses(
Function &
F) {
2903 NextCongruenceNum = 0;
2913 TOPClass = createCongruenceClass(
nullptr,
nullptr);
2919 for (
auto *DTN :
nodes(DT)) {
2926 if (MemoryBlockDefs)
2927 for (
const auto &Def : *MemoryBlockDefs) {
2928 MemoryAccessToClass[&
Def] = TOPClass;
2929 auto *MD = dyn_cast<MemoryDef>(&Def);
2932 const MemoryPhi *MP = cast<MemoryPhi>(&Def);
2933 TOPClass->memory_insert(MP);
2934 MemoryPhiState.
insert({MP, MPS_TOP});
2937 if (MD && isa<StoreInst>(MD->getMemoryInst()))
2938 TOPClass->incStoreCount();
2944 for (
auto &
I : *BB) {
2945 if (isa<PHINode>(&
I))
2946 for (
auto *U :
I.users())
2947 if (
auto *UInst = dyn_cast<Instruction>(U))
2949 PHINodeUses.
insert(UInst);
2952 if (
I.isTerminator() &&
I.getType()->isVoidTy())
2954 TOPClass->insert(&
I);
2955 ValueToClass[&
I] = TOPClass;
2960 for (
auto &FA :
F.args())
2961 createSingletonCongruenceClass(&FA);
2964void NewGVN::cleanupTables() {
2965 for (CongruenceClass *&
CC : CongruenceClasses) {
2967 <<
CC->size() <<
" members\n");
2976 AllTempInstructions.
end());
2977 AllTempInstructions.
clear();
2981 for (
auto *
I : TempInst) {
2982 I->dropAllReferences();
2985 while (!TempInst.empty()) {
2986 auto *
I = TempInst.pop_back_val();
2990 ValueToClass.
clear();
2991 ArgRecycler.
clear(ExpressionAllocator);
2992 ExpressionAllocator.
Reset();
2993 CongruenceClasses.clear();
2994 ExpressionToClass.clear();
2995 ValueToExpression.
clear();
2997 AdditionalUsers.
clear();
2998 ExpressionToPhiOfOps.
clear();
2999 TempToBlock.
clear();
3000 TempToMemory.
clear();
3001 PHINodeUses.
clear();
3002 OpSafeForPHIOfOps.
clear();
3003 ReachableBlocks.
clear();
3004 ReachableEdges.
clear();
3006 ProcessedCount.
clear();
3009 InstructionsToErase.
clear();
3011 BlockInstRange.
clear();
3012 TouchedInstructions.
clear();
3013 MemoryAccessToClass.
clear();
3014 PredicateToUsers.
clear();
3015 MemoryToUsers.
clear();
3016 RevisitOnReachabilityChange.
clear();
3017 IntrinsicInstPred.
clear();
3022std::pair<unsigned, unsigned> NewGVN::assignDFSNumbers(
BasicBlock *
B,
3024 unsigned End = Start;
3026 InstrDFS[MemPhi] =
End++;
3031 for (
auto &
I : *
B) {
3037 LLVM_DEBUG(
dbgs() <<
"Skipping trivially dead instruction " <<
I <<
"\n");
3038 markInstructionForDeletion(&
I);
3041 if (isa<PHINode>(&
I))
3042 RevisitOnReachabilityChange[
B].set(
End);
3043 InstrDFS[&
I] =
End++;
3050 return std::make_pair(Start,
End);
3053void NewGVN::updateProcessedCount(
const Value *V) {
3055 if (ProcessedCount.
count(V) == 0) {
3056 ProcessedCount.
insert({
V, 1});
3058 ++ProcessedCount[
V];
3059 assert(ProcessedCount[V] < 100 &&
3060 "Seem to have processed the same Value a lot");
3066void NewGVN::valueNumberMemoryPhi(
MemoryPhi *MP) {
3073 return cast<MemoryAccess>(U) != MP &&
3074 !isMemoryAccessTOP(cast<MemoryAccess>(U)) &&
3075 ReachableEdges.count({MP->getIncomingBlock(U), PHIBlock});
3080 if (Filtered.begin() == Filtered.end()) {
3081 if (setMemoryClass(MP, TOPClass))
3082 markMemoryUsersTouched(MP);
3088 auto LookupFunc = [&](
const Use &
U) {
3089 return lookupMemoryLeader(cast<MemoryAccess>(U));
3091 auto MappedBegin =
map_iterator(Filtered.begin(), LookupFunc);
3092 auto MappedEnd =
map_iterator(Filtered.end(), LookupFunc);
3096 const auto *AllSameValue = *MappedBegin;
3098 bool AllEqual = std::all_of(
3099 MappedBegin, MappedEnd,
3100 [&AllSameValue](
const MemoryAccess *V) {
return V == AllSameValue; });
3103 LLVM_DEBUG(
dbgs() <<
"Memory Phi value numbered to " << *AllSameValue
3112 CongruenceClass *
CC =
3113 AllEqual ? getMemoryClass(AllSameValue) : ensureLeaderOfMemoryClass(MP);
3114 auto OldState = MemoryPhiState.
lookup(MP);
3115 assert(OldState != MPS_Invalid &&
"Invalid memory phi state");
3116 auto NewState = AllEqual ? MPS_Equivalent : MPS_Unique;
3117 MemoryPhiState[MP] = NewState;
3118 if (setMemoryClass(MP,
CC) || OldState != NewState)
3119 markMemoryUsersTouched(MP);
3126 if (!
I->isTerminator()) {
3130 auto Res = performSymbolicEvaluation(
I, Visited);
3131 Symbolized = Res.Expr;
3132 addAdditionalUsers(Res,
I);
3135 if (Symbolized && !isa<ConstantExpression>(Symbolized) &&
3136 !isa<VariableExpression>(Symbolized) && PHINodeUses.
count(
I)) {
3137 auto *PHIE = makePossiblePHIOfOps(
I, Visited);
3142 }
else if (
auto *
Op = RealToTemp.
lookup(
I)) {
3143 removePhiOfOps(
I,
Op);
3152 if (Symbolized ==
nullptr)
3153 Symbolized = createUnknownExpression(
I);
3154 performCongruenceFinding(
I, Symbolized);
3159 if (!
I->getType()->isVoidTy()) {
3160 auto *Symbolized = createUnknownExpression(
I);
3161 performCongruenceFinding(
I, Symbolized);
3163 processOutgoingEdges(
I,
I->getParent());
3169bool NewGVN::singleReachablePHIPath(
3172 if (
First == Second)
3185 const auto *EndDef =
First;
3187 if (ChainDef == Second)
3193 auto *MP = cast<MemoryPhi>(EndDef);
3194 auto ReachableOperandPred = [&](
const Use &
U) {
3197 auto FilteredPhiArgs =
3200 llvm::copy(FilteredPhiArgs, std::back_inserter(OperandList));
3203 return singleReachablePHIPath(Visited, cast<MemoryAccess>(OperandList[0]),
3212void NewGVN::verifyMemoryCongruency()
const {
3215 for (
const auto *
CC : CongruenceClasses) {
3216 if (
CC == TOPClass ||
CC->isDead())
3218 if (
CC->getStoreCount() != 0) {
3219 assert((
CC->getStoredValue() || !isa<StoreInst>(
CC->getLeader())) &&
3220 "Any class with a store as a leader should have a "
3221 "representative stored value");
3223 "Any congruence class with a store should have a "
3224 "representative access");
3227 if (
CC->getMemoryLeader())
3229 "Representative MemoryAccess does not appear to be reverse "
3231 for (
const auto *M :
CC->memory())
3233 "Memory member does not appear to be reverse mapped properly");
3241 auto ReachableAccessPred =
3242 [&](
const std::pair<const MemoryAccess *, CongruenceClass *> Pair) {
3243 bool Result = ReachableBlocks.
count(Pair.first->getBlock());
3245 MemoryToDFSNum(Pair.first) == 0)
3247 if (
auto *MemDef = dyn_cast<MemoryDef>(Pair.first))
3252 if (
auto *MemPHI = dyn_cast<MemoryPhi>(Pair.first)) {
3253 for (
const auto &U : MemPHI->incoming_values()) {
3254 if (
auto *
I = dyn_cast<Instruction>(&*U)) {
3266 for (
auto KV : Filtered) {
3267 if (
auto *FirstMUD = dyn_cast<MemoryUseOrDef>(KV.first)) {
3268 auto *SecondMUD = dyn_cast<MemoryUseOrDef>(KV.second->getMemoryLeader());
3269 if (FirstMUD && SecondMUD) {
3271 assert((singleReachablePHIPath(VisitedMAS, FirstMUD, SecondMUD) ||
3272 ValueToClass.
lookup(FirstMUD->getMemoryInst()) ==
3273 ValueToClass.
lookup(SecondMUD->getMemoryInst())) &&
3274 "The instructions for these memory operations should have "
3275 "been in the same congruence class or reachable through"
3276 "a single argument phi");
3278 }
else if (
auto *FirstMP = dyn_cast<MemoryPhi>(KV.first)) {
3281 auto ReachableOperandPred = [&](
const Use &
U) {
3282 return ReachableEdges.
count(
3283 {FirstMP->getIncomingBlock(U), FirstMP->getBlock()}) &&
3287 auto FilteredPhiArgs =
3290 std::transform(FilteredPhiArgs.begin(), FilteredPhiArgs.end(),
3291 std::back_inserter(PhiOpClasses), [&](
const Use &U) {
3292 const MemoryDef *MD = cast<MemoryDef>(U);
3293 return ValueToClass.lookup(MD->getMemoryInst());
3296 "All MemoryPhi arguments should be in the same class");
3305void NewGVN::verifyIterationSettled(
Function &
F) {
3315 std::map<const Value *, CongruenceClass> BeforeIteration;
3317 for (
auto &KV : ValueToClass) {
3318 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3320 if (InstrToDFSNum(
I) == 0)
3322 BeforeIteration.insert({KV.first, *KV.second});
3325 TouchedInstructions.
set();
3326 TouchedInstructions.
reset(0);
3327 OpSafeForPHIOfOps.
clear();
3329 iterateTouchedInstructions();
3332 for (
const auto &KV : ValueToClass) {
3333 if (
auto *
I = dyn_cast<Instruction>(KV.first))
3335 if (InstrToDFSNum(
I) == 0)
3339 auto *BeforeCC = &BeforeIteration.
find(KV.first)->second;
3340 auto *AfterCC = KV.second;
3343 if (!EqualClasses.
count({BeforeCC, AfterCC})) {
3344 assert(BeforeCC->isEquivalentTo(AfterCC) &&
3345 "Value number changed after main loop completed!");
3346 EqualClasses.
insert({BeforeCC, AfterCC});
3357void NewGVN::verifyStoreExpressions()
const {
3362 std::pair<
const Value *,
3363 std::tuple<const Value *, const CongruenceClass *, Value *>>>
3365 for (
const auto &KV : ExpressionToClass) {
3366 if (
auto *SE = dyn_cast<StoreExpression>(KV.first)) {
3368 auto Res = StoreExpressionSet.insert(
3369 {SE->getOperand(0), std::make_tuple(SE->getMemoryLeader(), KV.second,
3370 SE->getStoredValue())});
3371 bool Okay = Res.second;
3376 Okay = (std::get<1>(Res.first->second) == KV.second) &&
3377 (lookupOperandLeader(std::get<2>(Res.first->second)) ==
3378 lookupOperandLeader(SE->getStoredValue()));
3379 assert(Okay &&
"Stored expression conflict exists in expression table");
3380 auto *ValueExpr = ValueToExpression.
lookup(SE->getStoreInst());
3381 assert(ValueExpr && ValueExpr->equals(*SE) &&
3382 "StoreExpression in ExpressionToClass is not latest "
3383 "StoreExpression for value");
3392void NewGVN::iterateTouchedInstructions() {
3395 int FirstInstr = TouchedInstructions.
find_first();
3397 if (FirstInstr == -1)
3399 const BasicBlock *LastBlock = getBlockForValue(InstrFromDFSNum(FirstInstr));
3400 while (TouchedInstructions.
any()) {
3406 for (
unsigned InstrNum : TouchedInstructions.
set_bits()) {
3410 if (InstrNum == 0) {
3411 TouchedInstructions.
reset(InstrNum);
3415 Value *
V = InstrFromDFSNum(InstrNum);
3416 const BasicBlock *CurrBlock = getBlockForValue(V);
3419 if (CurrBlock != LastBlock) {
3420 LastBlock = CurrBlock;
3421 bool BlockReachable = ReachableBlocks.
count(CurrBlock);
3422 const auto &CurrInstRange = BlockInstRange.
lookup(CurrBlock);
3425 if (!BlockReachable) {
3426 TouchedInstructions.
reset(CurrInstRange.first, CurrInstRange.second);
3429 <<
" because it is unreachable\n");
3434 updateProcessedCount(CurrBlock);
3438 TouchedInstructions.
reset(InstrNum);
3440 if (
auto *MP = dyn_cast<MemoryPhi>(V)) {
3442 valueNumberMemoryPhi(MP);
3443 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
3444 valueNumberInstruction(
I);
3448 updateProcessedCount(V);
3451 NumGVNMaxIterations = std::max(NumGVNMaxIterations.getValue(), Iterations);
3455bool NewGVN::runGVN() {
3458 bool Changed =
false;
3459 NumFuncArgs =
F.arg_size();
3461 SingletonDeadExpression =
new (ExpressionAllocator)
DeadExpression();
3465 unsigned ICount = 1;
3477 unsigned Counter = 0;
3478 for (
auto &
B : RPOT) {
3480 assert(
Node &&
"RPO and Dominator tree should have same reachability");
3481 RPOOrdering[
Node] = ++Counter;
3484 for (
auto &
B : RPOT) {
3486 if (
Node->getNumChildren() > 1)
3488 return RPOOrdering[
A] < RPOOrdering[
B];
3495 const auto &BlockRange = assignDFSNumbers(
B, ICount);
3496 BlockInstRange.
insert({
B, BlockRange});
3497 ICount += BlockRange.second - BlockRange.first;
3499 initializeCongruenceClasses(
F);
3501 TouchedInstructions.
resize(ICount);
3505 ExpressionToClass.reserve(ICount);
3508 const auto &InstRange = BlockInstRange.
lookup(&
F.getEntryBlock());
3509 TouchedInstructions.
set(InstRange.first, InstRange.second);
3511 <<
" marked reachable\n");
3512 ReachableBlocks.
insert(&
F.getEntryBlock());
3516 iterateTouchedInstructions();
3517 verifyMemoryCongruency();
3518 verifyIterationSettled(
F);
3519 verifyStoreExpressions();
3521 Changed |= eliminateInstructions(
F);
3524 for (
Instruction *ToErase : InstructionsToErase) {
3525 if (!ToErase->use_empty())
3528 assert(ToErase->getParent() &&
3529 "BB containing ToErase deleted unexpectedly!");
3530 ToErase->eraseFromParent();
3532 Changed |= !InstructionsToErase.empty();
3535 auto UnreachableBlockPred = [&](
const BasicBlock &BB) {
3536 return !ReachableBlocks.
count(&BB);
3541 <<
" is unreachable\n");
3542 deleteInstructionsInBlock(&BB);
3600 return std::tie(DFSIn, DFSOut,
LocalNum, Def, U) <
3611void NewGVN::convertClassToDFSOrdered(
3620 assert(BB &&
"Should have figured out a basic block for value");
3628 if (
auto *SI = dyn_cast<StoreInst>(
D)) {
3629 auto Leader = lookupOperandLeader(SI->getValueOperand());
3631 VDDef.
Def.setPointer(Leader);
3633 VDDef.
Def.setPointer(
SI->getValueOperand());
3634 VDDef.
Def.setInt(
true);
3637 VDDef.
Def.setPointer(
D);
3640 "The dense set member should always be an instruction");
3645 if (
auto *PN = RealToTemp.
lookup(Def)) {
3647 dyn_cast_or_null<PHIExpression>(ValueToExpression.
lookup(Def));
3649 VDDef.
Def.setInt(
false);
3650 VDDef.
Def.setPointer(PN);
3656 unsigned int UseCount = 0;
3658 for (
auto &U :
Def->uses()) {
3659 if (
auto *
I = dyn_cast<Instruction>(
U.getUser())) {
3661 if (InstructionsToErase.count(
I))
3666 if (
auto *
P = dyn_cast<PHINode>(
I)) {
3667 IBlock =
P->getIncomingBlock(U);
3672 IBlock = getBlockForValue(
I);
3678 if (!ReachableBlocks.
contains(IBlock))
3694 ProbablyDead.
insert(Def);
3696 UseCounts[
Def] = UseCount;
3702void NewGVN::convertClassToLoadsAndStores(
3703 const CongruenceClass &
Dense,
3706 if (!isa<LoadInst>(
D) && !isa<StoreInst>(
D))
3714 VD.
Def.setPointer(
D);
3717 if (
auto *
I = dyn_cast<Instruction>(
D))
3728 I->replaceAllUsesWith(Repl);
3731void NewGVN::deleteInstructionsInBlock(
BasicBlock *BB) {
3733 ++NumGVNBlocksDeleted;
3737 auto StartPoint = BB->
rbegin();
3745 if (isa<LandingPadInst>(Inst))
3750 ++NumGVNInstrDeleted;
3760void NewGVN::markInstructionForDeletion(
Instruction *
I) {
3762 InstructionsToErase.insert(
I);
3770 markInstructionForDeletion(
I);
3777class ValueDFSStack {
3779 Value *back()
const {
return ValueStack.back(); }
3780 std::pair<int, int> dfs_back()
const {
return DFSStack.back(); }
3782 void push_back(
Value *V,
int DFSIn,
int DFSOut) {
3783 ValueStack.emplace_back(V);
3784 DFSStack.emplace_back(DFSIn, DFSOut);
3787 bool empty()
const {
return DFSStack.empty(); }
3789 bool isInScope(
int DFSIn,
int DFSOut)
const {
3792 return DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second;
3795 void popUntilDFSScope(
int DFSIn,
int DFSOut) {
3798 assert(ValueStack.size() == DFSStack.size() &&
3799 "Mismatch between ValueStack and DFSStack");
3801 !DFSStack.empty() &&
3802 !(DFSIn >= DFSStack.back().first && DFSOut <= DFSStack.back().second)) {
3803 DFSStack.pop_back();
3804 ValueStack.pop_back();
3816CongruenceClass *NewGVN::getClassForExpression(
const Expression *E)
const {
3817 if (
auto *VE = dyn_cast<VariableExpression>(E))
3818 return ValueToClass.lookup(VE->getVariableValue());
3819 else if (isa<DeadExpression>(E))
3821 return ExpressionToClass.lookup(E);
3830 if (
auto *CE = dyn_cast<ConstantExpression>(E))
3831 return CE->getConstantValue();
3832 if (
auto *VE = dyn_cast<VariableExpression>(E)) {
3833 auto *
V = VE->getVariableValue();
3835 return VE->getVariableValue();
3838 auto *
CC = getClassForExpression(E);
3842 return CC->getLeader();
3844 for (
auto *Member : *
CC) {
3845 auto *MemberInst = dyn_cast<Instruction>(Member);
3846 if (MemberInst == OrigInst)
3851 if (DT->
dominates(getBlockForValue(MemberInst), BB))
3857bool NewGVN::eliminateInstructions(
Function &
F) {
3881 bool AnythingReplaced =
false;
3890 for (
auto &Operand :
PHI->incoming_values())
3891 if (!ReachableEdges.
count({PHI->getIncomingBlock(Operand), BB})) {
3895 <<
" with poison due to it being unreachable\n");
3909 for (
auto &KV : ReachableEdges)
3910 ReachablePredCount[KV.getEnd()]++;
3911 for (
auto &BBPair : RevisitOnReachabilityChange) {
3912 for (
auto InstNum : BBPair.second) {
3913 auto *Inst = InstrFromDFSNum(InstNum);
3914 auto *
PHI = dyn_cast<PHINode>(Inst);
3918 auto *BB = BBPair.first;
3919 if (ReachablePredCount.
lookup(BB) !=
PHI->getNumIncomingValues())
3920 ReplaceUnreachablePHIArgs(
PHI, BB);
3926 for (
auto *
CC :
reverse(CongruenceClasses)) {
3933 if (
CC->isDead() ||
CC->empty())
3936 if (
CC == TOPClass) {
3937 for (
auto *M : *
CC) {
3938 auto *VTE = ValueToExpression.
lookup(M);
3939 if (VTE && isa<DeadExpression>(VTE))
3940 markInstructionForDeletion(cast<Instruction>(M));
3941 assert((!ReachableBlocks.
count(cast<Instruction>(M)->getParent()) ||
3942 InstructionsToErase.count(cast<Instruction>(M))) &&
3943 "Everything in TOP should be unreachable or dead at this "
3949 assert(
CC->getLeader() &&
"We should have had a leader");
3955 CC->getStoredValue() ?
CC->getStoredValue() :
CC->getLeader();
3958 for (
auto *M : *
CC) {
3961 if (Member == Leader || !isa<Instruction>(Member) ||
3962 Member->getType()->isVoidTy()) {
3963 MembersLeft.
insert(Member);
3966 LLVM_DEBUG(
dbgs() <<
"Found replacement " << *(Leader) <<
" for "
3967 << *Member <<
"\n");
3968 auto *
I = cast<Instruction>(Member);
3969 assert(Leader !=
I &&
"About to accidentally remove our leader");
3970 replaceInstruction(
I, Leader);
3971 AnythingReplaced =
true;
3973 CC->swap(MembersLeft);
3976 if (
CC->size() != 1 || RealToTemp.
count(Leader)) {
3981 ValueDFSStack EliminationStack;
3985 convertClassToDFSOrdered(*
CC, DFSOrderedSet, UseCounts, ProbablyDead);
3989 for (
auto &VD : DFSOrderedSet) {
3990 int MemberDFSIn = VD.
DFSIn;
3991 int MemberDFSOut = VD.
DFSOut;
3993 bool FromStore = VD.
Def.getInt();
3996 if (Def &&
Def->getType()->isVoidTy())
3998 auto *DefInst = dyn_cast_or_null<Instruction>(Def);
3999 if (DefInst && AllTempInstructions.
count(DefInst)) {
4000 auto *PN = cast<PHINode>(DefInst);
4005 AllTempInstructions.
erase(PN);
4006 auto *DefBlock = getBlockForValue(Def);
4010 PN->insertBefore(&DefBlock->front());
4012 NumGVNPHIOfOpsEliminations++;
4015 if (EliminationStack.empty()) {
4019 << EliminationStack.dfs_back().first <<
","
4020 << EliminationStack.dfs_back().second <<
")\n");
4023 LLVM_DEBUG(
dbgs() <<
"Current DFS numbers are (" << MemberDFSIn <<
","
4024 << MemberDFSOut <<
")\n");
4038 bool ShouldPush =
Def && EliminationStack.empty();
4040 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut);
4042 if (OutOfScope || ShouldPush) {
4044 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4045 bool ShouldPush =
Def && EliminationStack.empty();
4047 EliminationStack.push_back(Def, MemberDFSIn, MemberDFSOut);
4066 auto *DefI = dyn_cast<Instruction>(Def);
4067 if (!EliminationStack.empty() && DefI && !FromStore) {
4068 Value *DominatingLeader = EliminationStack.back();
4069 if (DominatingLeader != Def) {
4072 if (!
match(DefI, m_Intrinsic<Intrinsic::ssa_copy>()))
4075 markInstructionForDeletion(DefI);
4083 assert(isa<Instruction>(
U->get()) &&
4084 "Current def should have been an instruction");
4085 assert(isa<Instruction>(
U->getUser()) &&
4086 "Current user should have been an instruction");
4092 Instruction *InstUse = cast<Instruction>(
U->getUser());
4093 if (InstructionsToErase.count(InstUse)) {
4094 auto &UseCount = UseCounts[
U->get()];
4095 if (--UseCount == 0) {
4096 ProbablyDead.
insert(cast<Instruction>(
U->get()));
4102 if (EliminationStack.empty())
4105 Value *DominatingLeader = EliminationStack.back();
4107 auto *
II = dyn_cast<IntrinsicInst>(DominatingLeader);
4108 bool isSSACopy =
II &&
II->getIntrinsicID() == Intrinsic::ssa_copy;
4110 DominatingLeader =
II->getOperand(0);
4113 if (
U->get() == DominatingLeader)
4116 <<
"Found replacement " << *DominatingLeader <<
" for "
4117 << *
U->get() <<
" in " << *(
U->getUser()) <<
"\n");
4122 auto *ReplacedInst = cast<Instruction>(
U->get());
4123 auto *PI = PredInfo->getPredicateInfoFor(ReplacedInst);
4124 if (!PI || DominatingLeader != PI->OriginalOp)
4126 U->set(DominatingLeader);
4129 auto &LeaderUseCount = UseCounts[DominatingLeader];
4131 if (LeaderUseCount == 0 && isa<Instruction>(DominatingLeader))
4132 ProbablyDead.
erase(cast<Instruction>(DominatingLeader));
4136 auto It = UseCounts.
find(
II);
4137 if (It != UseCounts.
end()) {
4138 unsigned &IIUseCount = It->second;
4139 if (--IIUseCount == 0)
4144 AnythingReplaced =
true;
4151 for (
auto *
I : ProbablyDead)
4153 markInstructionForDeletion(
I);
4157 for (
auto *Member : *
CC)
4158 if (!isa<Instruction>(Member) ||
4159 !InstructionsToErase.count(cast<Instruction>(Member)))
4160 MembersLeft.
insert(Member);
4161 CC->swap(MembersLeft);
4164 if (
CC->getStoreCount() > 0) {
4165 convertClassToLoadsAndStores(*
CC, PossibleDeadStores);
4167 ValueDFSStack EliminationStack;
4168 for (
auto &VD : PossibleDeadStores) {
4169 int MemberDFSIn = VD.
DFSIn;
4170 int MemberDFSOut = VD.
DFSOut;
4172 if (EliminationStack.empty() ||
4173 !EliminationStack.isInScope(MemberDFSIn, MemberDFSOut)) {
4175 EliminationStack.popUntilDFSScope(MemberDFSIn, MemberDFSOut);
4176 if (EliminationStack.empty()) {
4177 EliminationStack.push_back(Member, MemberDFSIn, MemberDFSOut);
4182 if (isa<LoadInst>(Member))
4184 assert(!EliminationStack.empty());
4185 Instruction *Leader = cast<Instruction>(EliminationStack.back());
4190 <<
" that is dominated by " << *Leader <<
"\n");
4191 markInstructionForDeletion(Member);
4197 return AnythingReplaced;
4205unsigned int NewGVN::getRank(
const Value *V)
const {
4211 if (isa<ConstantExpr>(V))
4213 if (isa<PoisonValue>(V))
4215 if (isa<UndefValue>(V))
4217 if (isa<Constant>(V))
4219 if (
auto *
A = dyn_cast<Argument>(V))
4220 return 4 +
A->getArgNo();
4224 unsigned Result = InstrToDFSNum(V);
4226 return 5 + NumFuncArgs +
Result;
4233bool NewGVN::shouldSwapOperands(
const Value *
A,
const Value *
B)
const {
4237 return std::make_pair(getRank(
A),
A) > std::make_pair(getRank(
B),
B);
4240bool NewGVN::shouldSwapOperandsForIntrinsic(
const Value *
A,
const Value *
B,
4243 if (shouldSwapOperands(
A,
B)) {
4244 if (LookupResult == IntrinsicInstPred.
end())
4251 if (LookupResult != IntrinsicInstPred.
end()) {
4253 if (SeenPredicate) {
4254 if (SeenPredicate ==
B)
4273 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())
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.
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.
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
~CallExpression() override
bool equals(const Expression &Other) const override
~LoadExpression() 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()
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.
Value * simplifyCmpInst(unsigned Predicate, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a CmpInst, 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.
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