90#define DEBUG_TYPE "gvn"
92STATISTIC(NumGVNInstr,
"Number of instructions deleted");
94STATISTIC(NumGVNPRE,
"Number of instructions PRE'd");
96STATISTIC(NumGVNSimpl,
"Number of instructions simplified");
97STATISTIC(NumGVNEqProp,
"Number of equalities propagated");
99STATISTIC(NumPRELoopLoad,
"Number of loop loads PRE'd");
101 "Number of loads moved to predecessor of a critical edge in PRE");
103STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
104 "Number of blocks speculated as available in "
105 "IsValueFullyAvailableInBlock(), max");
107 "Number of times we we reached gvn-max-block-speculations cut-off "
108 "preventing further exploration");
124 cl::desc(
"The number of memory accesses to scan in a block in reaching "
125 "memory values analysis (default = 100)"));
129 cl::desc(
"Max number of dependences to attempt Load PRE (default = 100)"));
133 cl::desc(
"Max number of blocks scanned per load in the MemorySSA "
134 "reaching-value analysis (default = 200)"));
139 cl::desc(
"Max number of blocks we're willing to speculate on (and recurse "
140 "into) when deducing if a value is fully available or not in GVN "
145 cl::desc(
"Max number of visited instructions when trying to find "
146 "dominating value of select dependency (default = 100)"));
150 cl::desc(
"Max number of instructions to scan in each basic block in GVN "
174 if ((!
Attrs.isEmpty() || !
Other.Attrs.isEmpty()) &&
175 !
Attrs.intersectWith(
Ty->getContext(),
Other.Attrs).has_value())
213 struct LeaderListNode {
214 LeaderTableEntry Entry;
215 LeaderListNode *
Next;
219 DenseMap<uint32_t, LeaderListNode> NumToLeaders;
224 const LeaderListNode *Current;
235 assert(Current &&
"Dereferenced end of leader list!");
236 Current = Current->Next;
240 return Current ==
Other.Current;
243 return Current !=
Other.Current;
249 auto I = NumToLeaders.find(
N);
250 if (
I == NumToLeaders.end()) {
264 for (
auto &[
_, HeadNode] : NumToLeaders) {
265 LeaderListNode *
N = HeadNode.Next;
267 auto *
Next =
N->Next;
268 N->~LeaderListNode();
272 NumToLeaders.clear();
273 TableAllocator.Reset();
331 bool InvalidBlockRPONumbers =
true;
354 struct ReachingMemVal {
362 const Value *SelCond =
nullptr;
363 const Value *SelTrueAddr =
nullptr;
364 const Value *SelFalseAddr =
nullptr;
368 return {DepKind::Other, BB, Addr, Inst, -1};
371 static ReachingMemVal getDef(
const Value *Addr, Instruction *Inst) {
372 return {DepKind::Def, Inst->getParent(), Addr, Inst, -1};
375 static ReachingMemVal getClobber(
const Value *Addr, Instruction *Inst,
376 int32_t Offset = -1) {
377 return {DepKind::Clobber, Inst->getParent(), Addr, Inst, Offset};
380 static ReachingMemVal getSelect(BasicBlock *BB,
const Value *
Cond,
381 const Value *TrueAddr,
382 const Value *FalseAddr) {
383 return {DepKind::Select, BB,
nullptr,
nullptr, -1,
Cond,
384 TrueAddr, FalseAddr};
388 struct DependencyBlockInfo {
389 DependencyBlockInfo() =
delete;
390 DependencyBlockInfo(
const PHITransAddr &Addr, MemoryAccess *ClobberMA)
391 : Addr(Addr), InitialClobberMA(ClobberMA), ClobberMA(ClobberMA),
394 MemoryAccess *InitialClobberMA;
395 MemoryAccess *ClobberMA;
396 std::optional<ReachingMemVal> MemVal;
397 bool ForceUnknown : 1;
401 using DependencyBlockSet = DenseMap<BasicBlock *, DependencyBlockInfo>;
403 std::optional<GVNPassImpl::ReachingMemVal> scanMemoryAccessesUsers(
404 const MemoryLocation &Loc,
bool IsInvariantLoad, BasicBlock *BB,
405 const SmallVectorImpl<MemoryAccess *> &ClobbersList,
MemorySSA &MSSA,
406 BatchAAResults &AA, LoadInst *L =
nullptr);
408 std::optional<GVNPassImpl::ReachingMemVal>
409 accessMayModifyLocation(MemoryAccess *ClobberMA,
const MemoryLocation &Loc,
410 Align LoadAlign,
bool IsInvariantLoad, BasicBlock *BB,
413 bool collectPredecessors(BasicBlock *BB,
const PHITransAddr &Addr,
414 MemoryAccess *ClobberMA, DependencyBlockSet &Blocks,
415 SmallVectorImpl<BasicBlock *> &Worklist);
417 void collectClobberList(SmallVectorImpl<MemoryAccess *> &Clobbers,
418 BasicBlock *BB,
const DependencyBlockInfo &StartInfo,
419 const DependencyBlockSet &Blocks,
MemorySSA &MSSA);
421 bool findReachingValuesForLoad(LoadInst *Inst,
422 SmallVectorImpl<ReachingMemVal> &
Values,
426 bool processLoad(LoadInst *L);
427 bool processMaskedLoad(IntrinsicInst *
I);
428 bool processNonLocalLoad(LoadInst *L);
429 bool processNonLocalLoad(LoadInst *L, SmallVectorImpl<ReachingMemVal> &Deps);
430 bool processAssumeIntrinsic(AssumeInst *
II);
434 std::optional<AvailableValue>
435 analyzeLoadAvailability(LoadInst *
Load,
const ReachingMemVal &Dep,
442 std::optional<AvailableValue>
444 Value *FalseAddr, Instruction *From);
449 void analyzeLoadAvailability(LoadInst *
Load,
450 SmallVectorImpl<ReachingMemVal> &Deps,
451 AvailValInBlkVect &ValuesPerBlock,
452 UnavailBlkVect &UnavailableBlocks);
456 LoadInst *findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
459 bool performLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
460 UnavailBlkVect &UnavailableBlocks);
465 bool performLoopLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
466 UnavailBlkVect &UnavailableBlocks);
470 void eliminatePartiallyRedundantLoad(
471 LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
472 MapVector<BasicBlock *, Value *> &AvailableLoads,
473 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad);
476 bool processInstruction(Instruction *
I);
477 bool processBlock(BasicBlock *BB);
480 bool performScalarPRE(Instruction *
I);
481 bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
482 BasicBlock *Curr,
unsigned int ValNo);
483 Value *findLeader(
const BasicBlock *BB, uint32_t Num);
484 void cleanupGlobalSets();
485 void removeInstruction(Instruction *
I);
486 void verifyRemoved(
const Instruction *
I)
const;
487 bool splitCriticalEdges();
488 BasicBlock *splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ);
491 const std::variant<BasicBlockEdge, Instruction *> &Root);
492 bool processFoldableCondBr(CondBrInst *BI);
493 void addDeadBlock(BasicBlock *BB);
494 void assignValNumForDeadCode();
608 Res.
AV = std::move(
AV);
624 return AV.MaterializeAdjustedValue(
Load,
BB->getTerminator());
635 E.Opcode =
I->getOpcode();
644 for (Use &
Op :
I->operands())
647 if (
I->isCommutative()) {
652 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
653 if (
E.VarArgs[0] >
E.VarArgs[1])
655 E.Commutative =
true;
659 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
661 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
662 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
664 E.Attrs = CB->getAttributes();
673 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
674 "Not a comparison!");
681 if (
E.VarArgs[0] >
E.VarArgs[1]) {
685 E.Opcode = (Opcode << 8) | Predicate;
686 E.Commutative =
true;
692 assert(EI &&
"Not an ExtractValueInst?");
721 Type *PtrTy =
GEP->getType()->getScalarType();
722 const DataLayout &
DL =
GEP->getDataLayout();
723 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
724 SmallMapVector<Value *, APInt, 4> VariableOffsets;
726 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
730 E.Opcode =
GEP->getOpcode();
733 for (
const auto &[V, Scale] : VariableOffsets) {
737 if (!ConstantOffset.isZero())
743 E.Opcode =
GEP->getOpcode();
744 E.Ty =
GEP->getSourceElementType();
745 for (Use &
Op :
GEP->operands())
763 ValueNumbering.insert(std::make_pair(V, Num));
765 NumberingPhi[Num] = PN;
775 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
789 if (
C->getFunction()->isPresplitCoroutine()) {
790 ValueNumbering[
C] = NextValueNumber;
791 return NextValueNumber++;
797 if (
C->isConvergent()) {
798 ValueNumbering[
C] = NextValueNumber;
799 return NextValueNumber++;
805 if (
C->hasOperandBundles()) {
806 ValueNumbering[
C] = NextValueNumber;
807 return NextValueNumber++;
810 if (AA->doesNotAccessMemory(
C)) {
812 uint32_t
E = assignExpNewValueNum(Exp).first;
813 ValueNumbering[
C] =
E;
817 if (MD && AA->onlyReadsMemory(
C)) {
819 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
821 ValueNumbering[
C] =
E;
825 MemDepResult LocalDep = MD->getDependency(
C);
828 ValueNumbering[
C] = NextValueNumber;
829 return NextValueNumber++;
832 if (LocalDep.
isDef()) {
837 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
838 ValueNumbering[
C] = NextValueNumber;
839 return NextValueNumber++;
842 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
845 if (CVN != LocalDepCallVN) {
846 ValueNumbering[
C] = NextValueNumber;
847 return NextValueNumber++;
852 ValueNumbering[
C] =
V;
858 MD->getNonLocalCallDependency(
C);
860 CallInst *CDep =
nullptr;
864 for (
const NonLocalDepEntry &
I : Deps) {
865 if (
I.getResult().isNonLocal())
870 if (!
I.getResult().isDef() || CDep !=
nullptr) {
877 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
878 CDep = NonLocalDepCall;
887 ValueNumbering[
C] = NextValueNumber;
888 return NextValueNumber++;
892 ValueNumbering[
C] = NextValueNumber;
893 return NextValueNumber++;
895 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
899 ValueNumbering[
C] = NextValueNumber;
900 return NextValueNumber++;
905 ValueNumbering[
C] =
V;
909 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
911 addMemoryStateToExp(
C, Exp);
912 auto [
V,
_] = assignExpNewValueNum(Exp);
913 ValueNumbering[
C] =
V;
917 ValueNumbering[
C] = NextValueNumber;
918 return NextValueNumber++;
922uint32_t GVNValueTable::computeLoadStoreVN(
Instruction *
I) {
923 if (!MSSA || !IsMSSAEnabled) {
924 ValueNumbering[
I] = NextValueNumber;
925 return NextValueNumber++;
929 Exp.Ty =
I->getType();
930 Exp.Opcode =
I->getOpcode();
931 for (Use &
Op :
I->operands())
933 addMemoryStateToExp(
I, Exp);
935 auto [
V,
_] = assignExpNewValueNum(Exp);
936 ValueNumbering[
I] =
V;
942 return ValueNumbering.contains(V);
954 auto VI = ValueNumbering.find(V);
955 if (VI != ValueNumbering.end())
960 ValueNumbering[V] = NextValueNumber;
963 return NextValueNumber++;
967 switch (
I->getOpcode()) {
968 case Instruction::Call:
970 case Instruction::FNeg:
971 case Instruction::Add:
972 case Instruction::FAdd:
973 case Instruction::Sub:
974 case Instruction::FSub:
975 case Instruction::Mul:
976 case Instruction::FMul:
977 case Instruction::UDiv:
978 case Instruction::SDiv:
979 case Instruction::FDiv:
980 case Instruction::URem:
981 case Instruction::SRem:
982 case Instruction::FRem:
983 case Instruction::Shl:
984 case Instruction::LShr:
985 case Instruction::AShr:
986 case Instruction::And:
987 case Instruction::Or:
988 case Instruction::Xor:
989 case Instruction::Trunc:
990 case Instruction::ZExt:
991 case Instruction::SExt:
992 case Instruction::FPToUI:
993 case Instruction::FPToSI:
994 case Instruction::UIToFP:
995 case Instruction::SIToFP:
996 case Instruction::FPTrunc:
997 case Instruction::FPExt:
998 case Instruction::PtrToInt:
999 case Instruction::PtrToAddr:
1000 case Instruction::IntToPtr:
1001 case Instruction::AddrSpaceCast:
1002 case Instruction::BitCast:
1003 case Instruction::Select:
1004 case Instruction::Freeze:
1005 case Instruction::ExtractElement:
1006 case Instruction::InsertElement:
1007 case Instruction::ShuffleVector:
1008 case Instruction::InsertValue:
1009 Exp = createExpr(
I);
1011 case Instruction::ICmp:
1012 case Instruction::FCmp:
1014 I->getOperand(0),
I->getOperand(1));
1016 case Instruction::GetElementPtr:
1019 case Instruction::ExtractValue:
1022 case Instruction::PHI:
1023 ValueNumbering[V] = NextValueNumber;
1025 return NextValueNumber++;
1026 case Instruction::Load:
1027 case Instruction::Store:
1028 return computeLoadStoreVN(
I);
1030 ValueNumbering[V] = NextValueNumber;
1031 return NextValueNumber++;
1034 uint32_t E = assignExpNewValueNum(Exp).first;
1035 ValueNumbering[V] = E;
1042 auto VI = ValueNumbering.find(V);
1044 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
1047 return (VI != ValueNumbering.end()) ? VI->second : 0;
1057 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1058 return assignExpNewValueNum(Exp).first;
1063 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1064 return ExpressionNumbering.lookup(Exp);
1072 return ExpressionNumbering.lookup(Exp);
1077 ValueNumbering.clear();
1078 ExpressionNumbering.clear();
1079 NumberingPhi.clear();
1080 NumberingBB.clear();
1081 PhiTranslateTable.clear();
1082 NextValueNumber = 1;
1083 Expressions.clear();
1090 uint32_t Num = ValueNumbering.lookup(V);
1091 ValueNumbering.erase(V);
1094 NumberingPhi.erase(Num);
1096 NumberingBB.erase(Num);
1102 assert(!ValueNumbering.contains(V) &&
1103 "Inst still occurs in value numbering map!");
1112 const auto &[It, Inserted] = NumToLeaders.try_emplace(
N, V, BB,
nullptr);
1115 auto *NewSlot = TableAllocator.Allocate<LeaderListNode>();
1116 new (NewSlot) LeaderListNode(V, BB, It->second.Next);
1117 It->second.Next = NewSlot;
1124 auto It = NumToLeaders.find(
N);
1125 if (It == NumToLeaders.end())
1128 LeaderListNode *Prev =
nullptr;
1129 LeaderListNode *Curr = &It->second;
1131 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
1141 Prev->Next = Curr->Next;
1142 Curr->~LeaderListNode();
1143 TableAllocator.Deallocate<LeaderListNode>(Curr);
1148 NumToLeaders.erase(It);
1151 LeaderListNode *
Next = Curr->Next;
1152 Curr->Entry.Val = std::move(
Next->Entry.Val);
1153 Curr->Entry.BB =
Next->Entry.BB;
1154 Curr->Next =
Next->Next;
1155 Next->~LeaderListNode();
1156 TableAllocator.Deallocate<LeaderListNode>(
Next);
1178 return Options.AllowLoadPRESplitBackedge.value_or(
1187 return Options.AllowMemDep.value_or(
false);
1206 auto *MemDep = Impl.isMemDepEnabled()
1211 if (Impl.isMemorySSAEnabled() && !MSSA) {
1213 "On-demand computation of MemSSA implies that MemDep is disabled!");
1217 bool Changed = Impl.run(
F, AC, DT, TLI,
AA, MemDep, LI, &ORE,
1218 MSSA ? &MSSA->getMSSA() :
nullptr);
1233 removeInstruction(
I);
1239 OS, MapClassName2PassName);
1242 if (Options.AllowScalarPRE != std::nullopt)
1243 OS << (*Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
1244 if (Options.AllowLoadPRE != std::nullopt)
1245 OS << (*Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
1246 if (Options.AllowLoadPRESplitBackedge != std::nullopt)
1247 OS << (*Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
1248 <<
"split-backedge-load-pre;";
1249 if (Options.AllowMemDep != std::nullopt)
1250 OS << (*Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
1251 if (Options.AllowMemorySSA != std::nullopt)
1252 OS << (*Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
1280 std::optional<BasicBlock *> UnavailableBB;
1284 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
1292 while (!Worklist.
empty()) {
1296 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
1304 UnavailableBB = CurrBB;
1315 ++NumNewNewSpeculativelyAvailableBBs;
1321 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1323 UnavailableBB = CurrBB;
1329 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1335#if LLVM_ENABLE_STATS
1336 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1337 NumNewNewSpeculativelyAvailableBBs);
1342 auto MarkAsFixpointAndEnqueueSuccessors =
1344 auto It = FullyAvailableBlocks.
find(BB);
1345 if (It == FullyAvailableBlocks.
end())
1352 State = FixpointState;
1355 "Found a speculatively available successor leftover?");
1363 if (UnavailableBB) {
1370 while (!Worklist.
empty())
1371 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1379 while (!Worklist.
empty())
1380 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1384 "Must have fixed all the new speculatively available blocks.");
1387 return !UnavailableBB;
1399 if (V.AV.Val == OldValue)
1400 V.AV.Val = NewValue;
1401 if (V.AV.isSelectValue()) {
1402 if (V.AV.V1 == OldValue)
1404 if (V.AV.V2 == OldValue)
1419 if (ValuesPerBlock.
size() == 1 &&
1421 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1422 "Dead BB dominate this block");
1423 return ValuesPerBlock[0].MaterializeAdjustedValue(
Load);
1434 if (AV.AV.isUndefValue())
1444 if (BB ==
Load->getParent() &&
1445 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() ==
Load) ||
1446 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() ==
Load)))
1463 if (Res->
getType() != LoadTy) {
1478 Load->getFunction());
1489 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1491 {LLVMContext::MD_dereferenceable,
1492 LLVMContext::MD_dereferenceable_or_null,
1493 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group,
1494 LLVMContext::MD_alias_scope, LLVMContext::MD_noalias});
1510 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1518 assert(Res &&
"failed to materialize?");
1524 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1541 Value *PtrOp =
Load->getPointerOperand();
1547 for (
auto *U : PtrOp->
users()) {
1568 for (
auto *U : PtrOp->
users()) {
1571 if (
I->getFunction() ==
Load->getFunction() &&
1579 OtherAccess =
nullptr;
1598 using namespace ore;
1601 R <<
"load of type " << NV(
"Type",
Load->getType()) <<
" not eliminated"
1606 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1608 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1622 for (
auto *Inst = BB == FromBB ? From : BB->getTerminator();
1630 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1631 SI->getValueOperand()->getType() == LoadTy)
1632 return SI->getValueOperand();
1636 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1642std::optional<AvailableValue>
1647 "Invalid address type of true side of select dependency");
1649 "Invalid address type of false side of select dependency");
1655 From, getAliasAnalysis());
1657 return std::nullopt;
1659 From, getAliasAnalysis());
1661 return std::nullopt;
1665std::optional<AvailableValue>
1666GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
const ReachingMemVal &Dep,
1668 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1669 assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) &&
1670 "expected a local dependence");
1675 if (Dep.Kind == DepKind::Clobber) {
1681 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1698 Load->isAtomic() <= DepLoad->isAtomic()) {
1702 if (!isMemorySSAEnabled()) {
1705 DepLoad->getFunction())) {
1708 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1714 DepLoad->getFunction()) ||
1741 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1745 return std::nullopt;
1747 assert(Dep.Kind == DepKind::Def &&
"follows from above");
1764 return std::nullopt;
1767 if (S->isAtomic() <
Load->isAtomic())
1768 return std::nullopt;
1779 return std::nullopt;
1782 if (
LD->isAtomic() <
Load->isAtomic())
1783 return std::nullopt;
1792 assert(Sel->getType() ==
Load->getPointerOperandType());
1793 if (
auto AV = analyzeSelectAvailability(
Load, Sel->getCondition(),
1794 Sel->getTrueValue(),
1795 Sel->getFalseValue(), DepInst))
1797 return std::nullopt;
1804 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1805 return std::nullopt;
1808void GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
1810 AvailValInBlkVect &ValuesPerBlock,
1811 UnavailBlkVect &UnavailableBlocks) {
1816 for (
const auto &Dep : Deps) {
1819 if (DeadBlocks.
count(DepBB)) {
1826 if (Dep.Kind == DepKind::Other) {
1827 UnavailableBlocks.push_back(DepBB);
1834 if (Dep.Kind == DepKind::Select) {
1835 if (
auto AV = analyzeSelectAvailability(
1837 const_cast<Value *
>(Dep.SelTrueAddr),
1839 ValuesPerBlock.push_back(
1842 UnavailableBlocks.push_back(DepBB);
1851 analyzeLoadAvailability(
Load, Dep,
const_cast<Value *
>(Dep.Addr))) {
1855 ValuesPerBlock.push_back(
1858 UnavailableBlocks.push_back(DepBB);
1862 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1863 "post condition violation");
1890 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1892 auto *SuccBB =
Term->getSuccessor(0);
1893 if (SuccBB == LoadBB)
1894 SuccBB =
Term->getSuccessor(1);
1895 if (!SuccBB->getSinglePredecessor())
1902 if (--NumInsts == 0)
1908 bool HasLocalDep =
true;
1909 if (!isMemorySSAEnabled()) {
1915 if (
auto *MA = MSSA->getMemoryAccess(&Inst); MA &&
isa<MemoryUse>(MA)) {
1916 auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
1917 HasLocalDep = Clobber->getBlock() == SuccBB;
1936void GVNPassImpl::eliminatePartiallyRedundantLoad(
1940 for (
const auto &AvailableLoad : AvailableLoads) {
1941 BasicBlock *UnavailableBlock = AvailableLoad.first;
1942 Value *LoadPtr = AvailableLoad.second;
1946 Load->getProperties(),
1948 NewLoad->setDebugLoc(
Load->getDebugLoc());
1961 NewLoad->setAAMetadata(Tags);
1963 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1964 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1965 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1966 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1967 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1968 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1969 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1970 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
1972 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1974 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1983 ValuesPerBlock.push_back(
1991 if (CriticalEdgePredAndLoad) {
1992 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1993 if (It != CriticalEdgePredAndLoad->
end()) {
1994 ++NumPRELoadMoved2CEPred;
2000 if (uint32_t ValNo = VN.
lookup(OldLoad,
false))
2002 removeInstruction(OldLoad);
2011 Load->replaceAllUsesWith(V);
2015 I->setDebugLoc(
Load->getDebugLoc());
2016 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2020 <<
"load eliminated by PRE";
2022 salvageAndRemoveInstruction(
Load);
2026 AvailValInBlkVect &ValuesPerBlock,
2027 UnavailBlkVect &UnavailableBlocks) {
2058 bool MustEnsureSafetyOfSpeculativeExecution =
2063 if (TmpBB == LoadBB)
2065 if (Blockers.count(TmpBB))
2077 MustEnsureSafetyOfSpeculativeExecution =
2078 MustEnsureSafetyOfSpeculativeExecution || ICF->
hasICF(TmpBB);
2090 for (
BasicBlock *UnavailableBB : UnavailableBlocks)
2104 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
2116 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
2123 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
2129 if (!isLoadPRESplitBackedgeEnabled())
2133 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
2138 if (
LoadInst *LI = findLoadToHoistIntoPred(Pred, LoadBB,
Load))
2139 CriticalEdgePredAndLoad[Pred] = LI;
2144 PredLoads[Pred] =
nullptr;
2149 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
2150 unsigned NumUnavailablePreds = NumInsertPreds +
2151 CriticalEdgePredAndLoad.
size();
2152 assert(NumUnavailablePreds != 0 &&
2153 "Fully available value should already be eliminated!");
2154 (void)NumUnavailablePreds;
2160 if (NumInsertPreds > 1)
2165 if (MustEnsureSafetyOfSpeculativeExecution) {
2166 if (CriticalEdgePredSplit.
size())
2170 for (
auto &PL : PredLoads)
2174 for (
auto &CEP : CriticalEdgePredAndLoad)
2181 for (
BasicBlock *OrigPred : CriticalEdgePredSplit) {
2183 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
2184 PredLoads[NewPred] =
nullptr;
2185 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
2186 << LoadBB->
getName() <<
'\n');
2189 for (
auto &CEP : CriticalEdgePredAndLoad)
2190 PredLoads[CEP.first] =
nullptr;
2193 bool CanDoPRE =
true;
2196 for (
auto &PredLoad : PredLoads) {
2197 BasicBlock *UnavailablePred = PredLoad.first;
2207 Value *LoadPtr =
Load->getPointerOperand();
2209 while (Cur != LoadBB) {
2222 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
2229 << *
Load->getPointerOperand() <<
"\n");
2234 PredLoad.second = LoadPtr;
2238 while (!NewInsts.
empty()) {
2248 return !CriticalEdgePredSplit.empty();
2256 <<
" INSTS: " << *NewInsts.
back()
2264 I->updateLocationAfterHoist();
2273 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, PredLoads,
2274 &CriticalEdgePredAndLoad);
2280 AvailValInBlkVect &ValuesPerBlock,
2281 UnavailBlkVect &UnavailableBlocks) {
2284 if (!L ||
L->getHeader() !=
Load->getParent())
2289 if (!Preheader || !Latch)
2292 Value *LoadPtr =
Load->getPointerOperand();
2294 if (!
L->isLoopInvariant(LoadPtr))
2304 for (
auto *Blocker : UnavailableBlocks) {
2306 if (!
L->contains(Blocker))
2330 if (Blocker->getTerminator()->mayWriteToMemory())
2333 LoopBlock = Blocker;
2346 AvailableLoads[LoopBlock] = LoadPtr;
2347 AvailableLoads[Preheader] = LoadPtr;
2350 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, AvailableLoads,
2358 using namespace ore;
2362 <<
"load of type " << NV(
"Type",
Load->getType()) <<
" eliminated"
2363 << setExtraArgs() <<
" in favor of "
2372 if (
Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2373 Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2383 unsigned NumDeps = Deps.size();
2391 const auto &
R = Dep.getResult();
2398 ReachingMemVal::getSelect(BB,
Cond, Addrs.first, Addrs.second));
2410 return processNonLocalLoad(
Load, MemVals);
2417 if (Deps.
size() == 1 && Deps[0].Kind == DepKind::Other) {
2419 dbgs() <<
" has unknown dependencies\n";);
2426 if (isScalarPREEnabled()) {
2429 for (
Use &U :
GEP->indices())
2439 AvailValInBlkVect ValuesPerBlock;
2440 UnavailBlkVect UnavailableBlocks;
2441 analyzeLoadAvailability(
Load, Deps, ValuesPerBlock, UnavailableBlocks);
2445 if (ValuesPerBlock.empty())
2453 if (UnavailableBlocks.empty()) {
2460 Load->replaceAllUsesWith(V);
2468 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2469 I->setDebugLoc(
Load->getDebugLoc());
2470 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2474 salvageAndRemoveInstruction(
Load);
2479 if (!isLoadPREEnabled())
2481 if (!isLoadInLoopPREEnabled() && LI->
getLoopFor(
Load->getParent()))
2484 if (performLoopLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks) ||
2485 performLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks))
2491bool GVNPassImpl::processAssumeIntrinsic(
AssumeInst *IntrinsicI) {
2495 if (
Cond->isZero()) {
2514 for (
const auto &Acc : *AL) {
2516 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2517 FirstNonDom = Current;
2535 salvageAndRemoveInstruction(IntrinsicI);
2549 return propagateEquality(V, True, IntrinsicI);
2554 I->replaceAllUsesWith(Repl);
2561 Value *PointerOperand = L->getPointerOperand()->stripPointerCasts();
2572 PointerUsesQueue.
push_back(PointerOperand);
2577 while (!PointerUsesQueue.
empty()) {
2580 "Null or GlobalValue should not be inserted");
2584 if (!
I ||
I == L || !DT.
dominates(
I, MostDominatingInstruction))
2599 if (
I->hasMetadata(LLVMContext::MD_invariant_group) &&
2601 MostDominatingInstruction =
I;
2605 return MostDominatingInstruction != L ? MostDominatingInstruction :
nullptr;
2611static std::optional<MemoryLocation>
2618 switch (
II->getIntrinsicID()) {
2619 case Intrinsic::masked_load:
2621 case Intrinsic::masked_store:
2624 return std::nullopt;
2631 return std::nullopt;
2635 return std::nullopt;
2641std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::scanMemoryAccessesUsers(
2647 auto UpdateChoice = [&](std::optional<ReachingMemVal> &Choice,
2651 Choice = ReachingMemVal::getClobber(
Loc.Ptr, Candidate, AR.getOffset());
2653 Choice = ReachingMemVal::getDef(
Loc.Ptr, Candidate);
2661 Choice->Kind = DepKind::Clobber;
2662 Choice->Offset = AR.getOffset();
2664 Choice->Kind = DepKind::Def;
2665 Choice->Offset = -1;
2668 Choice->Inst = Candidate;
2669 Choice->Block = Candidate->getParent();
2672 std::optional<ReachingMemVal> ReachingVal;
2677 return ReachingMemVal::getUnknown(BB,
Loc.Ptr);
2680 if (!UseOrDef || UseOrDef->getBlock() != BB)
2703 UpdateChoice(ReachingVal, AR, MemI);
2715std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::accessMayModifyLocation(
2725 if (
Alloc->getParent() == BB)
2727 return ReachingMemVal::getUnknown(BB,
Loc.Ptr);
2731 if (IsInvariantLoad ||
AA.pointsToConstantMemory(
Loc))
2732 return std::nullopt;
2736 return L->getOrdering();
2745 return ReachingMemVal::getDef(
Loc.Ptr, ClobberI);
2756 return std::nullopt;
2757 return ReachingMemVal::getClobber(
Loc.Ptr, ClobberI);
2762 return std::nullopt;
2769 return std::nullopt;
2774 return ReachingMemVal::getClobber(
Loc.Ptr, ClobberI);
2779 "Must be the superset/partial overlap case with positive offset");
2780 return ReachingMemVal::getClobber(
Loc.Ptr, ClobberI, AR.
getOffset());
2785 return std::nullopt;
2786 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2788 if (
AA.isMustAlias(IIObjLoc,
Loc))
2789 return ReachingMemVal::getDef(
Loc.Ptr, ClobberI);
2790 return std::nullopt;
2798 if (Obj == ClobberI ||
AA.isMustAlias(ClobberI,
Loc.Ptr))
2799 return ReachingMemVal::getDef(
Loc.Ptr, ClobberI);
2805 return std::nullopt;
2813 return std::nullopt;
2817 return ReachingMemVal::getClobber(
Loc.Ptr, ClobberI);
2825 DependencyBlockSet &Blocks,
2840 if (
llvm::any_of(Preds, [Pred](
const auto &
P) {
return P.first == Pred; }))
2847 auto It = Blocks.find(Pred);
2848 if (It != Blocks.end()) {
2852 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2859 Pred, DependencyBlockInfo(TransAddr,
2860 MPhi ? MPhi->getIncomingValueForBlock(Pred)
2867 for (
auto &
P : Preds) {
2868 [[maybe_unused]]
auto It =
2869 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2883 const DependencyBlockInfo &StartInfo,
2884 const DependencyBlockSet &Blocks,
2890 while (MA != LastMA) {
2908 auto It = Blocks.find(BB);
2909 if (It == Blocks.end())
2912 MA = It->second.InitialClobberMA;
2913 LastMA = It->second.ClobberMA;
2914 if (MA == Clobbers.
back())
2931bool GVNPassImpl::findReachingValuesForLoad(
2937 bool IsInvariantLoad =
L->hasMetadata(LLVMContext::MD_invariant_load);
2943 if (
L->hasMetadata(LLVMContext::MD_invariant_group)) {
2956 if (
auto RMV = scanMemoryAccessesUsers(
2957 Loc, IsInvariantLoad, StartBlock,
2959 Values.emplace_back(*RMV);
2970 accessMayModifyLocation(ClobberMA,
Loc,
L->getAlign(),
2971 IsInvariantLoad, StartBlock, MSSA,
AA)) {
2972 Values.emplace_back(*RMV);
2979 }
while (ClobberMA->
getBlock() == StartBlock);
2982 if (
L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2983 L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2992 DependencyBlockSet Blocks;
2995 if (!collectPredecessors(StartBlock,
2997 ClobberMA, Blocks, InitialWorklist))
3001 auto Worklist = InitialWorklist;
3002 while (!Worklist.
empty()) {
3007 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3010 if (!
Info.Addr.getAddr())
3020 accessMayModifyLocation(
Info.ClobberMA, BBLoc,
L->getAlign(),
3021 IsInvariantLoad, BB, MSSA,
AA)) {
3026 "LiveOnEntry aliases everything");
3042 if (BB == StartBlock &&
Info.Addr.getAddr() !=
L->getPointerOperand()) {
3043 Info.ForceUnknown =
true;
3046 if (BB != StartBlock &&
3047 !collectPredecessors(BB,
Info.Addr,
Info.ClobberMA, Blocks, Worklist))
3048 Info.ForceUnknown =
true;
3058 Worklist = InitialWorklist;
3060 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3061 Info.Visited =
true;
3065 while (!Worklist.empty()) {
3066 auto *BB = Worklist.pop_back_val();
3067 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3071 if (!
Info.Addr.getAddr()) {
3072 Values.push_back(ReachingMemVal::getUnknown(BB,
nullptr));
3077 collectClobberList(Clobbers, BB, Info, Blocks, MSSA);
3079 scanMemoryAccessesUsers(
Loc.getWithNewPtr(
Info.Addr.getAddr()),
3080 IsInvariantLoad, BB, Clobbers, MSSA,
AA)) {
3092 if (
Info.ForceUnknown) {
3093 Values.push_back(ReachingMemVal::getUnknown(BB,
Info.Addr.getAddr()));
3099 auto It = Blocks.find(Pred);
3100 if (It == Blocks.end())
3102 DependencyBlockInfo &PredInfo = It->second;
3103 if (PredInfo.Visited)
3105 PredInfo.Visited =
true;
3106 Worklist.push_back(Pred);
3115bool GVNPassImpl::processLoad(
LoadInst *L) {
3116 if (!MD && !isMemorySSAEnabled())
3120 if (!
L->isUnordered())
3123 if (
L->getType()->isTokenLikeTy())
3126 if (
L->use_empty()) {
3127 salvageAndRemoveInstruction(L);
3131 ReachingMemVal MemVal = ReachingMemVal::getUnknown(
nullptr,
nullptr);
3132 if (!isMemorySSAEnabled()) {
3138 return processNonLocalLoad(L);
3142 MemVal = ReachingMemVal::getDef(
L->getPointerOperand(), Dep.
getInst());
3145 ReachingMemVal::getClobber(
L->getPointerOperand(), Dep.
getInst());
3148 if (!findReachingValuesForLoad(L, MemVals, *MSSAU->
getMemorySSA(), *
AA))
3150 assert(MemVals.
size() &&
"Expected at least an unknown value");
3151 if (MemVals.
size() > 1 || MemVals[0].Block !=
L->getParent())
3152 return processNonLocalLoad(L, MemVals);
3154 MemVal = MemVals[0];
3157 if (MemVal.Kind == DepKind::Other) {
3161 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
3162 dbgs() <<
" has unknown dependence\n";);
3166 auto AV = analyzeLoadAvailability(L, MemVal,
L->getPointerOperand());
3179 salvageAndRemoveInstruction(L);
3198 Value *Passthrough =
I->getOperand(2);
3202 StoreVal->
getType() !=
I->getType())
3210 I->replaceAllUsesWith(OpToForward);
3211 salvageAndRemoveInstruction(
I);
3218std::pair<uint32_t, bool> GVNValueTable::assignExpNewValueNum(
Expression &Exp) {
3219 uint32_t &
E = ExpressionNumbering[
Exp];
3220 bool CreateNewValNum = !
E;
3221 if (CreateNewValNum) {
3222 Expressions.push_back(Exp);
3223 if (ExprIdx.size() < NextValueNumber + 1)
3224 ExprIdx.resize(NextValueNumber * 2);
3225 E = NextValueNumber;
3226 ExprIdx[NextValueNumber++] = NextExprNumber++;
3228 return {
E, CreateNewValNum};
3233bool GVNValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
3237 [=](
const GVNLeaderMap::LeaderTableEntry &L) { return L.BB == BB; });
3244 auto FindRes = PhiTranslateTable.find({Num, Pred});
3245 if (FindRes != PhiTranslateTable.end())
3246 return FindRes->second;
3247 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, LeaderTable);
3248 PhiTranslateTable.insert({{Num, Pred}, NewNum});
3260 for (
const auto &Entry : Leaders) {
3262 if (
Call &&
Call->getParent() == PhiBlock)
3266 if (
AA->doesNotAccessMemory(
Call))
3269 if (!MD || !
AA->onlyReadsMemory(
Call))
3281 if (
D.getResult().isNonFuncLocal())
3289uint32_t GVNValueTable::phiTranslateImpl(
const BasicBlock *Pred,
3295 if (PHINode *PN = NumberingPhi[Num]) {
3296 if (PN->getParent() != PhiBlock)
3298 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
3299 if (PN->getIncomingBlock(
I) != Pred)
3301 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
3307 if (BasicBlock *BB = NumberingBB[Num]) {
3308 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
3314 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
3321 if (MSSA->isLiveOnEntryDef(MA))
3326 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3332 if (!areAllValsInBB(Num, PhiBlock, LeaderTable))
3335 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3339 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3343 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3344 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3345 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3350 if (
Exp.Commutative) {
3351 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3352 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3354 uint32_t Opcode =
Exp.Opcode >> 8;
3355 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3356 Exp.Opcode = (Opcode << 8) |
3362 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3363 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3364 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, LeaderTable) ? NewNum
3376 PhiTranslateTable.erase({Num, Pred});
3386 if (Leaders.empty())
3389 Value *Val =
nullptr;
3390 for (
const auto &Entry : Leaders) {
3411 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
3412 assert((!Pred || Pred ==
E.getStart()) &&
3413 "No edge between these basic blocks!");
3414 return Pred !=
nullptr;
3417void GVNPassImpl::assignBlockRPONumber(
Function &
F) {
3418 BlockRPONumber.
clear();
3419 uint32_t NextBlockNumber = 1;
3422 BlockRPONumber[BB] = NextBlockNumber++;
3423 InvalidBlockRPONumbers =
false;
3431bool GVNPassImpl::propagateEquality(
3433 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3450 while (!Worklist.
empty()) {
3451 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3452 LHS = Item.first;
RHS = Item.second;
3487 if (!Visited.
insert({LHS, RHS}).second)
3508 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3511 unsigned NumReplacements;
3514 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3517 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3518 CanReplacePointersCallBack);
3520 if (NumReplacements > 0) {
3522 NumGVNEqProp += NumReplacements;
3542 bool IsKnownFalse = !IsKnownTrue;
3558 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3563 if (
Cmp->isEquivalence(IsKnownFalse))
3564 Worklist.
push_back(std::make_pair(Op0, Op1));
3568 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3576 if (Num < NextNum) {
3577 for (
const auto &Entry : LeaderTable.
getLeaders(Num)) {
3587 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3595 unsigned NumReplacements;
3601 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3602 Changed |= NumReplacements > 0;
3603 NumGVNEqProp += NumReplacements;
3615 LeaderTable.
insert(Num, NotVal, BB);
3624 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3629 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3647 if (!
I->use_empty()) {
3651 I->replaceAllUsesWith(V);
3655 salvageAndRemoveInstruction(
I);
3659 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3667 return processAssumeIntrinsic(Assume);
3670 if (processLoad(
Load))
3686 return processFoldableCondBr(BI);
3688 Value *BranchCond = BI->getCondition();
3692 if (TrueSucc == FalseSucc)
3700 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3704 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3711 Value *SwitchCond =
SI->getCondition();
3718 ++SwitchEdges[Succ];
3720 for (
const auto &Case :
SI->cases()) {
3723 if (SwitchEdges.
lookup(Dst) == 1) {
3725 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3733 if (
I->getType()->isVoidTy())
3742 LeaderTable.
insert(Num,
I,
I->getParent());
3750 unsigned AS = PTA->getPointerAddressSpace();
3751 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3752 !
DL.hasUnstableRepresentation(AS)) {
3755 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3757 salvageAndRemoveInstruction(
I);
3767 Value *Repl = Num < NextNum ? findLeader(
I->getParent(), Num) : nullptr;
3773 Cmp->getOperand(0),
Cmp->getOperand(1));
3775 Value *NotRepl = findLeader(
I->getParent(), NotNum);
3779 NotRepl, NotRepl->
getName() +
".not",
I->getIterator());
3780 Not->setDebugLoc(
I->getDebugLoc());
3781 I->replaceAllUsesWith(Not);
3782 salvageAndRemoveInstruction(
I);
3787 if (ICmp && ICmp->hasSameSign() && !ICmp->isEquality()) {
3791 ICmp->getOperand(0), ICmp->getOperand(1));
3792 if (SameSignNum != 0) {
3793 Repl = findLeader(
I->getParent(), SameSignNum);
3796 salvageAndRemoveInstruction(
I);
3803 LeaderTable.
insert(Num,
I,
I->getParent());
3817 salvageAndRemoveInstruction(
I);
3833 "mutually exclusive",
3851 InvalidBlockRPONumbers =
true;
3853 MSSAU = MSSA ? &Updater :
nullptr;
3856 bool ShouldContinue =
true;
3870 unsigned Iteration = 0;
3871 while (ShouldContinue) {
3874 ShouldContinue = iterateOnFunction(
F);
3879 if (isScalarPREEnabled()) {
3882 assignValNumForDeadCode();
3883 bool PREChanged =
true;
3884 while (PREChanged) {
3885 PREChanged = performPRE(
F);
3895 cleanupGlobalSets();
3906bool GVNPassImpl::processBlock(
BasicBlock *BB) {
3907 if (DeadBlocks.
count(BB))
3910 bool ChangedFunction =
false;
3918 for (
PHINode *PN : PHINodesToRemove) {
3919 removeInstruction(PN);
3922 ChangedFunction |= processInstruction(&Inst);
3923 return ChangedFunction;
3927bool GVNPassImpl::performScalarPREInsertion(
Instruction *Instr,
3929 unsigned int ValNo) {
3935 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3948 if (
Value *V = findLeader(Pred, TValNo)) {
3972 LeaderTable.
insert(Num, Instr, Pred);
3976bool GVNPassImpl::performScalarPRE(
Instruction *CurInst) {
4002 if (CallB->isInlineAsm())
4006 uint32_t ValNo = VN.
lookup(CurInst);
4014 unsigned NumWith = 0;
4015 unsigned NumWithout = 0;
4020 if (InvalidBlockRPONumbers)
4021 assignBlockRPONumber(*CurrentBlock->
getParent());
4033 "Invalid BlockRPONumber map.");
4034 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
4039 uint32_t TValNo = VN.
phiTranslate(
P, CurrentBlock, ValNo, LeaderTable);
4040 Value *PredV = findLeader(
P, TValNo);
4045 }
else if (PredV == CurInst) {
4057 if (NumWithout > 1 || NumWith == 0)
4065 if (NumWithout != 0) {
4088 PREInstr = CurInst->
clone();
4089 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
4092 verifyRemoved(PREInstr);
4101 assert(PREInstr !=
nullptr || NumWithout == 0);
4107 CurInst->
getName() +
".pre-phi");
4108 Phi->insertBefore(CurrentBlock->begin());
4109 for (
auto &[V, BB] : PredMap) {
4114 Phi->addIncoming(V, BB);
4116 Phi->addIncoming(PREInstr, PREPred);
4123 LeaderTable.
insert(ValNo, Phi, CurrentBlock);
4126 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
4128 LeaderTable.
erase(ValNo, CurInst, CurrentBlock);
4131 removeInstruction(CurInst);
4138bool GVNPassImpl::performPRE(
Function &
F) {
4142 if (CurrentBlock == &
F.getEntryBlock())
4146 if (CurrentBlock->isEHPad())
4150 BE = CurrentBlock->end();
4153 Changed |= performScalarPRE(CurInst);
4175 InvalidBlockRPONumbers =
true;
4182bool GVNPassImpl::splitCriticalEdges() {
4183 if (ToSplit.
empty())
4192 }
while (!ToSplit.
empty());
4196 InvalidBlockRPONumbers =
true;
4202bool GVNPassImpl::iterateOnFunction(
Function &
F) {
4203 cleanupGlobalSets();
4218void GVNPassImpl::cleanupGlobalSets() {
4220 LeaderTable.
clear();
4221 BlockRPONumber.
clear();
4223 InvalidBlockRPONumbers =
true;
4235 I->eraseFromParent();
4241void GVNPassImpl::verifyRemoved(
const Instruction *Inst)
const {
4249void GVNPassImpl::addDeadBlock(
BasicBlock *BB) {
4254 while (!NewDead.
empty()) {
4267 if (DeadBlocks.
count(S))
4270 bool AllPredDead =
true;
4272 if (!DeadBlocks.
count(
P)) {
4273 AllPredDead =
false;
4301 if (!DeadBlocks.
count(
P))
4313 if (!DeadBlocks.
count(
P))
4337bool GVNPassImpl::processFoldableCondBr(
CondBrInst *BI) {
4348 if (DeadBlocks.
count(DeadRoot))
4354 addDeadBlock(DeadRoot);
4362void GVNPassImpl::assignValNumForDeadCode() {
4366 LeaderTable.
insert(ValNum, &Inst, BB);
4377 bool ScalarPRE =
true)
4379 .setMemDep(MemDepAnalysis)
4380 .setMemorySSA(MemSSAAnalysis)
4381 .setScalarPRE(ScalarPRE)) {
4390 if (Impl.isMemorySSAEnabled() && !MSSAWP)
4398 Impl.isMemDepEnabled()
4403 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
4411 if (Impl.isMemDepEnabled())
4420 if (Impl.isMemorySSAEnabled())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
early cse Early CSE w MemorySSA
This file provides a data structure for mapping values and expressions to congruence class IDs.
static void reportMayClobberedLoad(LoadInst *Load, Instruction *DepInst, const DominatorTree *DT, OptimizationRemarkEmitter *ORE)
Try to locate the three instruction involved in a missed load-elimination case that is due to an inte...
static bool isValueFullyAvailableInBlock(BasicBlock *BB, DenseMap< BasicBlock *, AvailabilityState > &FullyAvailableBlocks)
Return true if we can prove that the value we're analyzing is fully available in the specified block.
static Instruction * findInvariantGroupValue(LoadInst *L, DominatorTree &DT)
If a load has !invariant.group, try to find the most-dominating instruction with the same metadata an...
static void reportLoadElim(LoadInst *Load, Value *AvailableValue, OptimizationRemarkEmitter *ORE)
static cl::opt< uint32_t > MaxNumInsnsPerBlock("gvn-max-num-insns", cl::Hidden, cl::init(100), cl::desc("Max number of instructions to scan in each basic block in GVN " "(default = 100)"))
static cl::opt< bool > GVNEnableMemDep("enable-gvn-memdep", cl::init(true))
static cl::opt< bool > GVNEnableLoadInLoopPRE("enable-load-in-loop-pre", cl::init(true))
static const Instruction * findMayClobberedPtrAccess(LoadInst *Load, const DominatorTree *DT)
static cl::opt< uint32_t > MaxNumDeps("gvn-max-num-deps", cl::Hidden, cl::init(100), cl::desc("Max number of dependences to attempt Load PRE (default = 100)"))
static std::optional< MemoryLocation > maybeLoadStoreLocation(Instruction *I, bool AllowStores, const TargetLibraryInfo *TLI)
Return the memory location accessed by the (masked) load/store instruction I, if the instruction coul...
static cl::opt< uint32_t > MaxNumReachingBlocks("gvn-max-num-reaching-blocks", cl::Hidden, cl::init(200), cl::desc("Max number of blocks scanned per load in the MemorySSA " "reaching-value analysis (default = 200)"))
static cl::opt< bool > GVNEnableMemorySSA("enable-gvn-memoryssa", cl::init(false))
GVNPassImpl::AvailableValue AvailableValue
static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E, DominatorTree *DT)
There is an edge from 'Src' to 'Dst'.
static cl::opt< bool > GVNEnableScalarPRE("enable-scalar-pre", cl::init(true), cl::Hidden)
static Value * findDominatingValue(const MemoryLocation &Loc, Type *LoadTy, Instruction *From, AAResults *AA)
static bool liesBetween(const Instruction *From, Instruction *Between, const Instruction *To, const DominatorTree *DT)
Assuming To can be reached from both From and Between, does Between lie on every path from From to To...
static bool isLifetimeStart(const Instruction *Inst)
static cl::opt< bool > GVNEnableSplitBackedgeInLoadPRE("enable-split-backedge-in-load-pre", cl::init(false))
static void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
static void replaceValuesPerBlockEntry(SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, Value *OldValue, Value *NewValue)
If the specified OldValue exists in ValuesPerBlock, replace its value with NewValue.
GVNPassImpl::AvailableValueInBlock AvailableValueInBlock
static cl::opt< unsigned > ScanUsersLimit("gvn-scan-users-limit", cl::Hidden, cl::init(100), cl::desc("The number of memory accesses to scan in a block in reaching " "memory values analysis (default = 100)"))
@ Unavailable
We know the block is not fully available. This is a fixpoint.
@ Available
We know the block is fully available. This is a fixpoint.
@ SpeculativelyAvailable
We do not know whether the block is fully available or not, but we are currently speculating that it ...
static Value * constructSSAForLoadSet(LoadInst *Load, SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, DominatorTree &DT)
Given a set of loads specified by ValuesPerBlock, construct SSA form, allowing us to eliminate Load.
static cl::opt< uint32_t > MaxNumVisitedInsts("gvn-max-num-visited-insts", cl::Hidden, cl::init(100), cl::desc("Max number of visited instructions when trying to find " "dominating value of select dependency (default = 100)"))
static cl::opt< uint32_t > MaxBBSpeculations("gvn-max-block-speculations", cl::Hidden, cl::init(600), cl::desc("Max number of blocks we're willing to speculate on (and recurse " "into) when deducing if a value is fully available or not in GVN " "(default = 600)"))
static cl::opt< bool > GVNEnableLoadPRE("enable-load-pre", cl::init(true))
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
static bool splitCriticalEdges(CallBrInst *CBR, DominatorTree *DT)
This file implements a map that provides insertion order iteration.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
uint64_t IntrinsicInst * II
ppc ctr loops PowerPC CTR Loops Verify
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > & Cond
static DominatorTree getDomTree(Function &F)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static const uint32_t IV[8]
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
GVNLegacyPass(bool MemDepAnalysis=GVNEnableMemDep, bool MemSSAAnalysis=GVNEnableMemorySSA, bool ScalarPRE=true)
The core GVN pass object.
bool isMemDepEnabled() const
bool isScalarPREEnabled() const
bool isLoadPRESplitBackedgeEnabled() const
void salvageAndRemoveInstruction(Instruction *I)
This removes the specified instruction from our various maps and marks it for deletion.
DominatorTree & getDominatorTree() const
bool isLoadInLoopPREEnabled() const
GVNPassImpl(llvm::GVNOptions Options={})
bool isLoadPREEnabled() const
bool isMemorySSAEnabled() const
MemoryDependenceResults & getMemDep() const
AAResults * getAliasAnalysis() const
friend class GVNLegacyPass
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
The possible results of an alias query.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
constexpr int32_t getOffset() const
constexpr bool hasOffset() const
an instruction to allocate memory on the stack
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Value handle that asserts if the Value is deleted.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
This is the shared class of boolean and integer constants.
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
This is an important base class in LLVM.
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
iterator find(const_arg_type_t< KeyT > Val)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
iterator_range< iterator > children()
DomTreeNodeBase * getIDom() const
Analysis pass which computes a DominatorTree.
void getDescendants(NodeT *R, SmallVectorImpl< NodeT * > &Result) const
Get all nodes dominated by R, including R itself.
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.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Context-sensitive CaptureAnalysis provider, which computes and caches the earliest common dominator c...
Class representing an expression and its matching format.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
const BasicBlock & getEntryBlock() const
Represents calls to the gc.relocate intrinsic.
leader_iterator & operator++()
bool operator!=(const leader_iterator &Other) const
leader_iterator(const LeaderListNode *C)
reference operator*() const
const LeaderTableEntry value_type
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
bool operator==(const leader_iterator &Other) const
A mapping from value numbers to lists of Value*'s that have that value number.
LLVM_ABI void insert(uint32_t N, Value *V, const BasicBlock *BB)
Push a new Value to the LeaderTable onto the list for its value number.
LLVM_ABI void erase(uint32_t N, Instruction *I, const BasicBlock *BB)
Scan the list of values corresponding to a given value number, and remove the given instruction if en...
iterator_range< leader_iterator > getLeaders(uint32_t N)
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
Returns the value number of the given comparison, assigning it a new number if it did not have one be...
LLVM_ABI void erase(Value *V)
Remove a value from the value numbering.
LLVM_ABI uint32_t lookup(Value *V, bool Verify=true) const
Returns the value number of the specified value.
LLVM_ABI void add(Value *V, uint32_t Num)
add - Insert a value into the table with a specified value number.
LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock)
Erase stale entry from phiTranslate cache so phiTranslate can be computed again.
LLVM_ABI void verifyRemoved(const Value *) const
verifyRemoved - Verify that the value is removed from all internal data structures.
void setAliasAnalysis(AAResults *A)
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock, uint32_t Num, GVNLeaderMap &LeaderTable)
Wrap phiTranslateImpl to provide caching functionality.
LLVM_ABI uint32_t lookupCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
void setMemDep(MemoryDependenceResults *M, bool MDEnabled=true)
LLVM_ABI void clear()
Remove all entries from the ValueTable.
LLVM_ABI bool exists(Value *V) const
Returns true if a value number exists for the specified value.
uint32_t getNextUnusedValueNumber()
LLVM_ABI GVNValueTable & operator=(const GVNValueTable &Arg)
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty)
Returns the value number of ptrtoint Ptr to \Ty.
void setDomTree(DominatorTree *D)
LLVM_ABI ~GVNValueTable()
void setMemorySSA(MemorySSA *M, bool MSSAEnabled=false)
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Legacy wrapper pass to provide the GlobalsAAResult object.
static LLVM_ABI Predicate getFlippedSignednessPredicate(Predicate Pred)
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
This class allows to keep track on instructions with implicit control flow.
bool isDominatedByICFIFromSameBlock(const Instruction *Insn)
Returns true if the first ICFI of Insn's block exists and dominates Insn.
bool hasICF(const BasicBlock *BB)
Returns true if at least one instruction from the given basic block has implicit control flow.
LLVM_ABI void clear()
Invalidates all information from this tracking.
LLVM_ABI void removeUsersOf(const Instruction *Inst)
Notifies this tracking that we are going to replace all uses of Inst.
LLVM_ABI void insertInstructionTo(const Instruction *Inst, const BasicBlock *BB)
Notifies this tracking that we are going to insert a new instruction Inst to the basic block BB.
LLVM_ABI void removeInstruction(const Instruction *Inst)
Notifies this tracking that we are going to remove the instruction Inst It makes all necessary update...
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool isIdenticalTo(const Instruction *I) const LLVM_READONLY
Return true if the specified instruction is exactly identical to the current one.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
A memory dependence query can return one of three different answers.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block,...
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
bool isLocal() const
Tests if this MemDepResult represents a valid local query (Clobber/Def).
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
This is the common base class for memset/memcpy/memmove.
BasicBlock * getBlock() const
An analysis that produces MemoryDependenceResults for a function.
Provides a lazy, caching interface for making common memory aliasing information queries,...
std::vector< NonLocalDepEntry > NonLocalDepInfo
LLVM_ABI void invalidateCachedPredecessors()
Clears the PredIteratorCache info.
LLVM_ABI void invalidateCachedPointerInfo(Value *Ptr)
Invalidates cached information about the specified pointer, because it may be too conservative in mem...
std::optional< int32_t > getClobberOffset(LoadInst *DepInst) const
Return the clobber offset to dependent instruction.
LLVM_ABI void removeInstruction(Instruction *InstToRemove)
Removes an instruction from the dependence analysis, updating the dependence of instructions that pre...
LLVM_ABI MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
LLVM_ABI const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
LLVM_ABI void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location,...
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
Representation for a specific memory location.
static LLVM_ABI MemoryLocation get(const LoadInst *LI)
Return a location with information about the memory reference by the given instruction.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
An analysis that produces MemorySSA for a function.
MemorySSA * getMemorySSA() const
Get handle on MemorySSA.
LLVM_ABI MemoryUseOrDef * createMemoryAccessBefore(Instruction *I, MemoryAccess *Definition, MemoryUseOrDef *InsertPt)
Create a MemoryAccess in MemorySSA before an existing MemoryAccess.
LLVM_ABI void insertDef(MemoryDef *Def, bool RenameUses=false)
Insert a definition into the MemorySSA IR.
LLVM_ABI void insertUse(MemoryUse *Use, bool RenameUses=false)
LLVM_ABI MemoryAccess * createMemoryAccessInBB(Instruction *I, MemoryAccess *Definition, const BasicBlock *BB, MemorySSA::InsertionPlace Point, bool CreationMustSucceed=true)
Create a MemoryAccess in MemorySSA at a specified point in a block.
LLVM_ABI void removeMemoryAccess(MemoryAccess *, bool OptimizePhis=false)
Remove a MemoryAccess from MemorySSA, including updating all definitions and uses.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Legacy analysis pass which computes MemorySSA.
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI MemorySSAWalker * getSkipSelfWalker()
AccessList * getBlockAccesses(const BasicBlock *BB) const
Return the list of MemoryAccess's for a given basic block.
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
LLVM_ABI bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
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.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
This is an entry in the NonLocalDepInfo cache.
This is a result from a NonLocal dependence query.
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...
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool needsPHITranslationFromBlock(BasicBlock *BB) const
needsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
LLVM_ABI bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
Storage of either a normal Value address, or a select condition together with a pair of addresses for...
std::pair< Value *, SelectAddrs > getSelectCondAndAddrs() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
A vector that has set insertion semantics.
void insert_range(Range &&R)
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
Implements a dense probed hash-table based set with some number of buckets stored inline.
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
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.
Represent a constant reference to a string, i.e.
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.
LLVM_ABI bool isTokenLikeTy() const
Returns true if this is 'token' or a token-like target type.s.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI bool canBeFreed() const
Return true if the memory object referred to by V can by freed in the scope for which the SSA value d...
LLVM_ABI void deleteValue()
Delete a pointer to a generic Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
int getNumOccurrences() const
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
Not(const Pred &P) -> Not< Pred >
LLVM_ABI int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
LLVM_ABI Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...
LLVM_ABI int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
LLVM_ABI Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
LLVM_ABI int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
LLVM_ABI bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
initializer< Ty > init(const Ty &Val)
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
NodeAddr< NodeBase * > Node
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.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
LLVM_ABI unsigned replaceDominatedUsesWithIf(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge, function_ref< bool(const Use &U, const Value *To)> ShouldReplace)
Replace each use of 'From' with 'To' if that use is dominated by the given edge and the callback Shou...
RelativeUniformCounterPtr Values
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createGVNPass(bool ScalarPRE)
Create a legacy GVN pass.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
@ Load
The value being inserted comes from a load (InsertElement only).
constexpr from_range_t from_range
LLVM_ABI bool isStorePreservingMemoryLocation(const StoreInst *SI, const MemoryLocation &MemLoc, Align MemLocAlign, BatchAAResults &AA, unsigned ScanLimit)
Check whether SI, which may alias MemLoc, can be safely skipped.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
LLVM_ABI bool isAssumeWithEmptyBundle(const AssumeInst &Assume)
Return true iff the operand bundles of the provided llvm.assume doesn't contain any valuable informat...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool canReplacePointersInUseIfEqual(const Use &U, const Value *To, const DataLayout &DL)
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
bool isModSet(const ModRefInfo MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
LLVM_ABI void initializeGVNLegacyPassPass(PassRegistry &)
LLVM_ABI unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge)
Replace each use of 'From' with 'To' if that use is dominated by the given edge.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
LLVM_ABI FunctionPass * createGVNPass()
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
DWARFExpression::Operation Op
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
LLVM_ABI bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
constexpr unsigned BitWidth
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB)
Check for and eliminate duplicate PHI nodes in this block.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Represents an AvailableValue which can be rematerialized at the end of the associated BasicBlock.
BasicBlock * BB
BB - The basic block in question.
static AvailableValueInBlock getUndef(BasicBlock *BB)
Value * MaterializeAdjustedValue(LoadInst *Load) const
Emit code at the end of this block to adjust the value defined here to the specified type.
static AvailableValueInBlock get(BasicBlock *BB, Value *V, unsigned Offset=0)
AvailableValue AV
AV - The actual available value.
static AvailableValueInBlock get(BasicBlock *BB, AvailableValue &&AV)
Represents a particular available value that we know how to materialize.
Value * getSimpleValue() const
ValType Kind
Kind of the live-out value.
Value * getSelectCondition() const
static AvailableValue get(Value *V, unsigned Offset=0)
bool isUndefValue() const
static AvailableValue getMI(MemIntrinsic *MI, unsigned Offset=0)
bool isSimpleValue() const
Value * V1
V1, V2 - The dominating non-clobbered values of SelectVal.
MemIntrinsic * getMemIntrinValue() const
LoadInst * getCoercedLoadValue() const
static AvailableValue getUndef()
static AvailableValue getSelect(Value *Cond, Value *V1, Value *V2)
static AvailableValue getLoad(LoadInst *Load, unsigned Offset=0)
bool isSelectValue() const
unsigned Offset
Offset - The byte offset in Val that is interesting for the load query.
Value * MaterializeAdjustedValue(LoadInst *Load, Instruction *InsertPt) const
Emit code at the specified insertion point to adjust the value defined here to the specified type.
Value * Val
Val - The value that is live out of the block.
bool isMemIntrinValue() const
bool isCoercedLoadValue() const
A collection of metadata nodes that might be associated with a memory access used by the alias-analys...
This struct is a compact representation of a valid (non-zero power of two) alignment.
Option class for critical edge splitting.
static unsigned getHashValue(const GVNValueTable::Expression &E)
static bool isEqual(const GVNValueTable::Expression &LHS, const GVNValueTable::Expression &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
LeaderTableEntry(Value *V, const BasicBlock *BB)
A set of parameters to control various transforms performed by GVN pass.
Expression(uint32_t Op=~2U)
SmallVector< uint32_t, 4 > VarArgs
bool operator==(const Expression &Other) const
friend hash_code hash_value(const Expression &Value)