88#define DEBUG_TYPE "gvn"
90STATISTIC(NumGVNInstr,
"Number of instructions deleted");
92STATISTIC(NumGVNPRE,
"Number of instructions PRE'd");
94STATISTIC(NumGVNSimpl,
"Number of instructions simplified");
95STATISTIC(NumGVNEqProp,
"Number of equalities propagated");
97STATISTIC(NumPRELoopLoad,
"Number of loop loads PRE'd");
99 "Number of loads moved to predecessor of a critical edge in PRE");
101STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
102 "Number of blocks speculated as available in "
103 "IsValueFullyAvailableInBlock(), max");
105 "Number of times we we reached gvn-max-block-speculations cut-off "
106 "preventing further exploration");
121 cl::desc(
"Max number of dependences to attempt Load PRE (default = 100)"));
126 cl::desc(
"Max number of blocks we're willing to speculate on (and recurse "
127 "into) when deducing if a value is fully available or not in GVN "
132 cl::desc(
"Max number of visited instructions when trying to find "
133 "dominating value of select dependency (default = 100)"));
137 cl::desc(
"Max number of instructions to scan in each basic block in GVN "
161 if ((!
Attrs.isEmpty() || !
Other.Attrs.isEmpty()) &&
162 !
Attrs.intersectWith(
Ty->getContext(),
Other.Attrs).has_value())
303 Res.
AV = std::move(
AV);
324 return AV.MaterializeAdjustedValue(Load,
BB->getTerminator());
335 E.Opcode =
I->getOpcode();
340 E.VarArgs.push_back(
lookupOrAdd(GCR->getOperand(0)));
341 E.VarArgs.push_back(
lookupOrAdd(GCR->getBasePtr()));
342 E.VarArgs.push_back(
lookupOrAdd(GCR->getDerivedPtr()));
344 for (
Use &
Op :
I->operands())
347 if (
I->isCommutative()) {
352 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
353 if (
E.VarArgs[0] >
E.VarArgs[1])
355 E.Commutative =
true;
361 if (
E.VarArgs[0] >
E.VarArgs[1]) {
366 E.Commutative =
true;
368 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
370 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
371 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
373 E.Attrs = CB->getAttributes();
379GVNPass::Expression GVNPass::ValueTable::createCmpExpr(
381 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
382 "Not a comparison!");
385 E.VarArgs.push_back(lookupOrAdd(
LHS));
386 E.VarArgs.push_back(lookupOrAdd(
RHS));
389 if (
E.VarArgs[0] >
E.VarArgs[1]) {
393 E.Opcode = (Opcode << 8) | Predicate;
394 E.Commutative =
true;
399GVNPass::ValueTable::createExtractvalueExpr(ExtractValueInst *EI) {
400 assert(EI &&
"Not an ExtractValueInst?");
411 E.VarArgs.push_back(lookupOrAdd(WO->
getLHS()));
412 E.VarArgs.push_back(lookupOrAdd(WO->
getRHS()));
420 E.VarArgs.push_back(lookupOrAdd(
Op));
427GVNPass::Expression GVNPass::ValueTable::createGEPExpr(GetElementPtrInst *
GEP) {
429 Type *PtrTy =
GEP->getType()->getScalarType();
430 const DataLayout &
DL =
GEP->getDataLayout();
431 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
432 SmallMapVector<Value *, APInt, 4> VariableOffsets;
434 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
438 E.Opcode =
GEP->getOpcode();
440 E.VarArgs.push_back(lookupOrAdd(
GEP->getPointerOperand()));
441 for (
const auto &[V, Scale] : VariableOffsets) {
442 E.VarArgs.push_back(lookupOrAdd(V));
443 E.VarArgs.push_back(lookupOrAdd(ConstantInt::get(
Context, Scale)));
445 if (!ConstantOffset.isZero())
447 lookupOrAdd(ConstantInt::get(
Context, ConstantOffset)));
451 E.Opcode =
GEP->getOpcode();
452 E.Ty =
GEP->getSourceElementType();
453 for (Use &
Op :
GEP->operands())
454 E.VarArgs.push_back(lookupOrAdd(
Op));
463GVNPass::ValueTable::ValueTable() =
default;
464GVNPass::ValueTable::ValueTable(
const ValueTable &) =
default;
465GVNPass::ValueTable::ValueTable(
ValueTable &&) =
default;
466GVNPass::ValueTable::~ValueTable() =
default;
472 ValueNumbering.
insert(std::make_pair(V, Num));
474 NumberingPhi[Num] = PN;
484 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
485 assert(MSSA->getMemoryAccess(
I) &&
"Instruction does not access memory");
486 MemoryAccess *MA = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(
I);
487 Exp.VarArgs.push_back(lookupOrAdd(MA));
498 if (
C->getFunction()->isPresplitCoroutine()) {
499 ValueNumbering[
C] = NextValueNumber;
500 return NextValueNumber++;
506 if (
C->isConvergent()) {
507 ValueNumbering[
C] = NextValueNumber;
508 return NextValueNumber++;
511 if (AA->doesNotAccessMemory(
C)) {
513 uint32_t
E = assignExpNewValueNum(Exp).first;
514 ValueNumbering[
C] =
E;
518 if (MD && AA->onlyReadsMemory(
C)) {
520 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
522 ValueNumbering[
C] =
E;
526 MemDepResult LocalDep = MD->getDependency(
C);
529 ValueNumbering[
C] = NextValueNumber;
530 return NextValueNumber++;
533 if (LocalDep.
isDef()) {
538 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
539 ValueNumbering[
C] = NextValueNumber;
540 return NextValueNumber++;
543 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
544 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
545 uint32_t LocalDepCallVN = lookupOrAdd(LocalDepCall->
getArgOperand(
I));
546 if (CVN != LocalDepCallVN) {
547 ValueNumbering[
C] = NextValueNumber;
548 return NextValueNumber++;
552 uint32_t
V = lookupOrAdd(LocalDepCall);
553 ValueNumbering[
C] =
V;
559 MD->getNonLocalCallDependency(
C);
561 CallInst *CDep =
nullptr;
565 for (
const NonLocalDepEntry &
I : Deps) {
566 if (
I.getResult().isNonLocal())
571 if (!
I.getResult().isDef() || CDep !=
nullptr) {
578 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
579 CDep = NonLocalDepCall;
588 ValueNumbering[
C] = NextValueNumber;
589 return NextValueNumber++;
593 ValueNumbering[
C] = NextValueNumber;
594 return NextValueNumber++;
596 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
597 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
600 ValueNumbering[
C] = NextValueNumber;
601 return NextValueNumber++;
605 uint32_t
V = lookupOrAdd(CDep);
606 ValueNumbering[
C] =
V;
610 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
612 addMemoryStateToExp(
C, Exp);
613 auto [
V,
_] = assignExpNewValueNum(Exp);
614 ValueNumbering[
C] =
V;
618 ValueNumbering[
C] = NextValueNumber;
619 return NextValueNumber++;
623uint32_t GVNPass::ValueTable::computeLoadStoreVN(Instruction *
I) {
624 if (!MSSA || !IsMSSAEnabled) {
625 ValueNumbering[
I] = NextValueNumber;
626 return NextValueNumber++;
630 Exp.Ty =
I->getType();
631 Exp.Opcode =
I->getOpcode();
632 for (Use &
Op :
I->operands())
633 Exp.VarArgs.push_back(lookupOrAdd(
Op));
634 addMemoryStateToExp(
I, Exp);
636 auto [
V,
_] = assignExpNewValueNum(Exp);
637 ValueNumbering[
I] =
V;
642bool GVNPass::ValueTable::exists(
Value *V)
const {
643 return ValueNumbering.contains(V);
656 if (VI != ValueNumbering.end())
661 ValueNumbering[V] = NextValueNumber;
664 return NextValueNumber++;
668 switch (
I->getOpcode()) {
669 case Instruction::Call:
671 case Instruction::FNeg:
672 case Instruction::Add:
673 case Instruction::FAdd:
674 case Instruction::Sub:
675 case Instruction::FSub:
676 case Instruction::Mul:
677 case Instruction::FMul:
678 case Instruction::UDiv:
679 case Instruction::SDiv:
680 case Instruction::FDiv:
681 case Instruction::URem:
682 case Instruction::SRem:
683 case Instruction::FRem:
684 case Instruction::Shl:
685 case Instruction::LShr:
686 case Instruction::AShr:
687 case Instruction::And:
688 case Instruction::Or:
689 case Instruction::Xor:
690 case Instruction::ICmp:
691 case Instruction::FCmp:
692 case Instruction::Trunc:
693 case Instruction::ZExt:
694 case Instruction::SExt:
695 case Instruction::FPToUI:
696 case Instruction::FPToSI:
697 case Instruction::UIToFP:
698 case Instruction::SIToFP:
699 case Instruction::FPTrunc:
700 case Instruction::FPExt:
701 case Instruction::PtrToInt:
702 case Instruction::PtrToAddr:
703 case Instruction::IntToPtr:
704 case Instruction::AddrSpaceCast:
705 case Instruction::BitCast:
706 case Instruction::Select:
707 case Instruction::Freeze:
708 case Instruction::ExtractElement:
709 case Instruction::InsertElement:
710 case Instruction::ShuffleVector:
711 case Instruction::InsertValue:
714 case Instruction::GetElementPtr:
717 case Instruction::ExtractValue:
720 case Instruction::PHI:
721 ValueNumbering[V] = NextValueNumber;
723 return NextValueNumber++;
724 case Instruction::Load:
725 case Instruction::Store:
726 return computeLoadStoreVN(
I);
728 ValueNumbering[V] = NextValueNumber;
729 return NextValueNumber++;
732 uint32_t E = assignExpNewValueNum(Exp).first;
733 ValueNumbering[V] = E;
742 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
745 return (VI != ValueNumbering.end()) ? VI->second : 0;
752uint32_t GVNPass::ValueTable::lookupOrAddCmp(
unsigned Opcode,
755 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
756 return assignExpNewValueNum(Exp).first;
761 ValueNumbering.clear();
762 ExpressionNumbering.clear();
763 NumberingPhi.clear();
765 PhiTranslateTable.clear();
774 uint32_t Num = ValueNumbering.lookup(V);
775 ValueNumbering.erase(V);
778 NumberingPhi.erase(Num);
780 NumberingBB.erase(Num);
785void GVNPass::ValueTable::verifyRemoved(
const Value *V)
const {
786 assert(!ValueNumbering.contains(V) &&
787 "Inst still occurs in value numbering map!");
796 LeaderListNode &Curr = NumToLeaders[
N];
797 if (!Curr.Entry.Val) {
803 LeaderListNode *
Node = TableAllocator.Allocate<LeaderListNode>();
806 Node->Next = Curr.Next;
814 LeaderListNode *Prev =
nullptr;
815 LeaderListNode *Curr = &NumToLeaders[
N];
817 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
826 Prev->Next = Curr->Next;
829 Curr->Entry.Val =
nullptr;
830 Curr->Entry.BB =
nullptr;
832 LeaderListNode *
Next = Curr->Next;
833 Curr->Entry.Val =
Next->Entry.Val;
834 Curr->Entry.BB =
Next->Entry.BB;
835 Curr->Next =
Next->Next;
840void GVNPass::LeaderMap::verifyRemoved(
const Value *V)
const {
843 for (
const auto &
I : NumToLeaders) {
845 assert(
I.second.Entry.Val != V &&
"Inst still in value numbering scope!");
847 std::none_of(leader_iterator(&
I.second), leader_iterator(
nullptr),
848 [=](
const LeaderTableEntry &
E) {
return E.Val ==
V; }) &&
849 "Inst still in value numbering scope!");
870 return Options.AllowLoadPRESplitBackedge.value_or(
897 "On-demand computation of MemSSA implies that MemDep is disabled!");
901 bool Changed = runImpl(
F, AC, DT, TLI,
AA, MemDep, LI, &ORE,
902 MSSA ? &MSSA->getMSSA() :
nullptr);
917 OS, MapClassName2PassName);
920 if (Options.AllowPRE != std::nullopt)
921 OS << (*Options.AllowPRE ?
"" :
"no-") <<
"pre;";
922 if (Options.AllowLoadPRE != std::nullopt)
923 OS << (*Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
924 if (Options.AllowLoadPRESplitBackedge != std::nullopt)
925 OS << (*Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
926 <<
"split-backedge-load-pre;";
927 if (Options.AllowMemDep != std::nullopt)
928 OS << (*Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
929 if (Options.AllowMemorySSA != std::nullopt)
930 OS << (*Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
937 removeInstruction(
I);
940#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
943 for (
const auto &[Num, Exp] : Map) {
944 errs() << Num <<
"\n";
975 std::optional<BasicBlock *> UnavailableBB;
979 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
987 while (!Worklist.
empty()) {
991 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
999 UnavailableBB = CurrBB;
1010 ++NumNewNewSpeculativelyAvailableBBs;
1016 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1018 UnavailableBB = CurrBB;
1024 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1030#if LLVM_ENABLE_STATS
1031 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1032 NumNewNewSpeculativelyAvailableBBs);
1037 auto MarkAsFixpointAndEnqueueSuccessors =
1039 auto It = FullyAvailableBlocks.
find(BB);
1040 if (It == FullyAvailableBlocks.
end())
1047 State = FixpointState;
1050 "Found a speculatively available successor leftover?");
1058 if (UnavailableBB) {
1065 while (!Worklist.
empty())
1066 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1074 while (!Worklist.
empty())
1075 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1079 "Must have fixed all the new speculatively available blocks.");
1082 return !UnavailableBB;
1091 if (V.AV.Val == OldValue)
1092 V.AV.Val = NewValue;
1093 if (V.AV.isSelectValue()) {
1094 if (V.AV.V1 == OldValue)
1096 if (V.AV.V2 == OldValue)
1111 if (ValuesPerBlock.
size() == 1 &&
1113 Load->getParent())) {
1114 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1115 "Dead BB dominate this block");
1116 return ValuesPerBlock[0].MaterializeAdjustedValue(Load);
1122 SSAUpdate.
Initialize(Load->getType(), Load->getName());
1127 if (AV.AV.isUndefValue())
1137 if (BB == Load->getParent() &&
1138 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() == Load) ||
1139 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() == Load)))
1152 Type *LoadTy = Load->getType();
1156 if (Res->
getType() != LoadTy) {
1171 Load->getFunction());
1181 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1183 {LLVMContext::MD_dereferenceable,
1184 LLVMContext::MD_dereferenceable_or_null,
1185 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group});
1201 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1210 assert(Res &&
"failed to materialize?");
1216 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1233 Value *PtrOp = Load->getPointerOperand();
1239 for (
auto *U : PtrOp->
users()) {
1242 if (
I->getFunction() == Load->getFunction() && DT->
dominates(
I, Load)) {
1260 for (
auto *U : PtrOp->
users()) {
1263 if (
I->getFunction() == Load->getFunction() &&
1271 OtherAccess =
nullptr;
1290 using namespace ore;
1293 R <<
"load of type " << NV(
"Type", Load->getType()) <<
" not eliminated"
1298 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1300 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInfo.
getInst());
1313 for (
auto *Inst = BB == FromBB ? From : BB->
getTerminator();
1321 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1327std::optional<AvailableValue>
1328GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo,
1330 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1335 const DataLayout &
DL =
Load->getDataLayout();
1342 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1358 if (DepLoad != Load &&
Address &&
1359 Load->isAtomic() <= DepLoad->isAtomic()) {
1366 DepLoad->getFunction())) {
1367 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1369 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1396 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1400 return std::nullopt;
1409 if (Constant *InitVal =
1419 return std::nullopt;
1422 if (S->isAtomic() <
Load->isAtomic())
1423 return std::nullopt;
1434 return std::nullopt;
1437 if (
LD->isAtomic() <
Load->isAtomic())
1438 return std::nullopt;
1447 assert(Sel->getType() ==
Load->getPointerOperandType());
1453 return std::nullopt;
1458 return std::nullopt;
1466 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1467 return std::nullopt;
1470void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps,
1471 AvailValInBlkVect &ValuesPerBlock,
1472 UnavailBlkVect &UnavailableBlocks) {
1477 for (
const auto &Dep : Deps) {
1479 MemDepResult DepInfo = Dep.getResult();
1481 if (DeadBlocks.count(DepBB)) {
1489 UnavailableBlocks.push_back(DepBB);
1496 if (
auto AV = AnalyzeLoadAvailability(Load, DepInfo, Dep.getAddress())) {
1500 ValuesPerBlock.push_back(
1503 UnavailableBlocks.push_back(DepBB);
1507 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1508 "post condition violation");
1530LoadInst *GVNPass::findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
1534 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1536 auto *SuccBB =
Term->getSuccessor(0);
1537 if (SuccBB == LoadBB)
1538 SuccBB =
Term->getSuccessor(1);
1539 if (!SuccBB->getSinglePredecessor())
1543 for (Instruction &Inst : *SuccBB) {
1544 if (Inst.isDebugOrPseudoInst())
1546 if (--NumInsts == 0)
1549 if (!Inst.isIdenticalTo(Load))
1552 MemDepResult Dep = MD->getDependency(&Inst);
1557 if (Dep.
isNonLocal() && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1568void GVNPass::eliminatePartiallyRedundantLoad(
1569 LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
1570 MapVector<BasicBlock *, Value *> &AvailableLoads,
1571 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad) {
1572 for (
const auto &AvailableLoad : AvailableLoads) {
1573 BasicBlock *UnavailableBlock = AvailableLoad.first;
1574 Value *LoadPtr = AvailableLoad.second;
1576 auto *NewLoad =
new LoadInst(
1577 Load->getType(), LoadPtr,
Load->getName() +
".pre",
Load->isVolatile(),
1578 Load->getAlign(),
Load->getOrdering(),
Load->getSyncScopeID(),
1580 NewLoad->setDebugLoc(
Load->getDebugLoc());
1582 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1585 MSSAU->insertDef(NewDef,
true);
1591 AAMDNodes Tags =
Load->getAAMetadata();
1593 NewLoad->setAAMetadata(Tags);
1595 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1596 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1597 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1598 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1599 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1600 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1601 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1602 if (LI->getLoopFor(
Load->getParent()) == LI->getLoopFor(UnavailableBlock))
1603 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1612 ValuesPerBlock.push_back(
1614 MD->invalidateCachedPointerInfo(LoadPtr);
1619 if (CriticalEdgePredAndLoad) {
1620 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1621 if (It != CriticalEdgePredAndLoad->
end()) {
1622 ++NumPRELoadMoved2CEPred;
1623 ICF->insertInstructionTo(NewLoad, UnavailableBlock);
1624 LoadInst *OldLoad = It->second;
1628 if (uint32_t ValNo = VN.lookup(OldLoad,
false))
1629 LeaderTable.erase(ValNo, OldLoad, OldLoad->
getParent());
1630 removeInstruction(OldLoad);
1638 ICF->removeUsersOf(Load);
1639 Load->replaceAllUsesWith(V);
1643 I->setDebugLoc(
Load->getDebugLoc());
1644 if (
V->getType()->isPtrOrPtrVectorTy())
1645 MD->invalidateCachedPointerInfo(V);
1647 return OptimizationRemark(
DEBUG_TYPE,
"LoadPRE", Load)
1648 <<
"load eliminated by PRE";
1653bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
1654 UnavailBlkVect &UnavailableBlocks) {
1663 SmallPtrSet<BasicBlock *, 4> Blockers(
llvm::from_range, UnavailableBlocks);
1685 bool MustEnsureSafetyOfSpeculativeExecution =
1686 ICF->isDominatedByICFIFromSameBlock(Load);
1690 if (TmpBB == LoadBB)
1692 if (Blockers.count(TmpBB))
1704 MustEnsureSafetyOfSpeculativeExecution =
1705 MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
1713 MapVector<BasicBlock *, Value *> PredLoads;
1714 DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
1715 for (
const AvailableValueInBlock &AV : ValuesPerBlock)
1717 for (BasicBlock *UnavailableBB : UnavailableBlocks)
1725 MapVector<BasicBlock *, LoadInst *> CriticalEdgePredAndLoad;
1731 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
1732 << Pred->
getName() <<
"': " << *Load <<
'\n');
1743 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
1744 << Pred->
getName() <<
"': " << *Load <<
'\n');
1750 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
1751 << Pred->
getName() <<
"': " << *Load <<
'\n');
1757 if (DT->dominates(LoadBB, Pred)) {
1760 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
1761 << Pred->
getName() <<
"': " << *Load <<
'\n');
1765 if (LoadInst *LI = findLoadToHoistIntoPred(Pred, LoadBB, Load))
1766 CriticalEdgePredAndLoad[Pred] = LI;
1771 PredLoads[Pred] =
nullptr;
1776 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
1777 unsigned NumUnavailablePreds = NumInsertPreds +
1778 CriticalEdgePredAndLoad.
size();
1779 assert(NumUnavailablePreds != 0 &&
1780 "Fully available value should already be eliminated!");
1781 (void)NumUnavailablePreds;
1787 if (NumInsertPreds > 1)
1792 if (MustEnsureSafetyOfSpeculativeExecution) {
1793 if (CriticalEdgePredSplit.
size())
1797 for (
auto &PL : PredLoads)
1801 for (
auto &CEP : CriticalEdgePredAndLoad)
1808 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
1809 BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
1810 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
1811 PredLoads[NewPred] =
nullptr;
1812 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
1813 << LoadBB->
getName() <<
'\n');
1816 for (
auto &CEP : CriticalEdgePredAndLoad)
1817 PredLoads[CEP.first] =
nullptr;
1820 bool CanDoPRE =
true;
1821 const DataLayout &
DL =
Load->getDataLayout();
1822 SmallVector<Instruction*, 8> NewInsts;
1823 for (
auto &PredLoad : PredLoads) {
1824 BasicBlock *UnavailablePred = PredLoad.first;
1834 Value *LoadPtr =
Load->getPointerOperand();
1836 while (Cur != LoadBB) {
1849 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
1856 << *
Load->getPointerOperand() <<
"\n");
1861 PredLoad.second = LoadPtr;
1865 while (!NewInsts.
empty()) {
1875 return !CriticalEdgePredSplit.empty();
1881 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING PRE LOAD: " << *Load <<
'\n');
1883 <<
" INSTS: " << *NewInsts.
back()
1887 for (Instruction *
I : NewInsts) {
1891 I->updateLocationAfterHoist();
1900 eliminatePartiallyRedundantLoad(Load, ValuesPerBlock, PredLoads,
1901 &CriticalEdgePredAndLoad);
1906bool GVNPass::performLoopLoadPRE(LoadInst *Load,
1907 AvailValInBlkVect &ValuesPerBlock,
1908 UnavailBlkVect &UnavailableBlocks) {
1909 const Loop *
L = LI->getLoopFor(
Load->getParent());
1911 if (!L ||
L->getHeader() !=
Load->getParent())
1916 if (!Preheader || !Latch)
1919 Value *LoadPtr =
Load->getPointerOperand();
1921 if (!
L->isLoopInvariant(LoadPtr))
1927 if (ICF->isDominatedByICFIFromSameBlock(Load))
1931 for (
auto *Blocker : UnavailableBlocks) {
1933 if (!
L->contains(Blocker))
1945 if (L != LI->getLoopFor(Blocker))
1953 if (DT->dominates(Blocker, Latch))
1957 if (Blocker->getTerminator()->mayWriteToMemory())
1960 LoopBlock = Blocker;
1972 MapVector<BasicBlock *, Value *> AvailableLoads;
1973 AvailableLoads[LoopBlock] = LoadPtr;
1974 AvailableLoads[Preheader] = LoadPtr;
1976 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING PRE LOOP LOAD: " << *Load <<
'\n');
1977 eliminatePartiallyRedundantLoad(Load, ValuesPerBlock, AvailableLoads,
1985 using namespace ore;
1989 <<
"load of type " << NV(
"Type", Load->getType()) <<
" eliminated"
1990 << setExtraArgs() <<
" in favor of "
1997bool GVNPass::processNonLocalLoad(LoadInst *Load) {
1999 if (
Load->getParent()->getParent()->hasFnAttribute(
2000 Attribute::SanitizeAddress) ||
2001 Load->getParent()->getParent()->hasFnAttribute(
2002 Attribute::SanitizeHWAddress))
2007 MD->getNonLocalPointerDependency(Load, Deps);
2012 unsigned NumDeps = Deps.size();
2019 !Deps[0].getResult().isDef() && !Deps[0].getResult().isClobber()) {
2021 dbgs() <<
" has unknown dependencies\n";);
2027 if (GetElementPtrInst *
GEP =
2029 for (Use &U :
GEP->indices())
2035 AvailValInBlkVect ValuesPerBlock;
2036 UnavailBlkVect UnavailableBlocks;
2037 AnalyzeLoadAvailability(Load, Deps, ValuesPerBlock, UnavailableBlocks);
2041 if (ValuesPerBlock.empty())
2049 if (UnavailableBlocks.empty()) {
2050 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING NONLOCAL LOAD: " << *Load <<
'\n');
2055 ICF->removeUsersOf(Load);
2056 Load->replaceAllUsesWith(V);
2064 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2065 I->setDebugLoc(
Load->getDebugLoc());
2066 if (
V->getType()->isPtrOrPtrVectorTy())
2067 MD->invalidateCachedPointerInfo(V);
2080 if (performLoopLoadPRE(Load, ValuesPerBlock, UnavailableBlocks) ||
2081 PerformLoadPRE(Load, ValuesPerBlock, UnavailableBlocks))
2089 auto *I = dyn_cast<Instruction>(U);
2090 return I && I->getParent() == BB;
2094bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
2098 if (
Cond->isZero()) {
2108 const MemoryUseOrDef *FirstNonDom =
nullptr;
2110 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2117 for (
const auto &Acc : *AL) {
2119 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2120 FirstNonDom = Current;
2127 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2129 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2130 : MSSAU->createMemoryAccessInBB(
2159 Changed |= propagateEquality(V, True,
Edge,
false);
2165 ReplaceOperandsWithMap[
V] = True;
2188 if (CmpI->isEquivalence()) {
2189 Value *CmpLHS = CmpI->getOperand(0);
2190 Value *CmpRHS = CmpI->getOperand(1);
2204 uint32_t LVN = VN.lookupOrAdd(CmpLHS);
2205 uint32_t RVN = VN.lookupOrAdd(CmpRHS);
2216 << *CmpLHS <<
" with "
2217 << *CmpRHS <<
" in block "
2218 << IntrinsicI->
getParent()->getName() <<
"\n");
2222 ReplaceOperandsWithMap[CmpLHS] = CmpRHS;
2235 I->replaceAllUsesWith(Repl);
2240bool GVNPass::processLoad(LoadInst *L) {
2245 if (!
L->isUnordered())
2248 if (
L->use_empty()) {
2254 MemDepResult Dep = MD->getDependency(L);
2258 return processNonLocalLoad(L);
2265 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
2266 dbgs() <<
" has unknown dependence\n";);
2270 auto AV = AnalyzeLoadAvailability(L, Dep,
L->getPointerOperand());
2274 Value *AvailableValue = AV->MaterializeAdjustedValue(L, L);
2277 ICF->removeUsersOf(L);
2278 L->replaceAllUsesWith(AvailableValue);
2280 MSSAU->removeMemoryAccess(L);
2287 MD->invalidateCachedPointerInfo(AvailableValue);
2293bool GVNPass::processMaskedLoad(IntrinsicInst *
I) {
2296 MemDepResult Dep = MD->getDependency(
I);
2302 Value *Passthrough =
I->getOperand(3);
2306 StoreVal->
getType() !=
I->getType())
2313 ICF->removeUsersOf(
I);
2314 I->replaceAllUsesWith(OpToForward);
2322std::pair<uint32_t, bool>
2323GVNPass::ValueTable::assignExpNewValueNum(
Expression &Exp) {
2324 uint32_t &
E = ExpressionNumbering[
Exp];
2325 bool CreateNewValNum = !
E;
2326 if (CreateNewValNum) {
2327 Expressions.push_back(Exp);
2328 if (ExprIdx.size() < NextValueNumber + 1)
2329 ExprIdx.resize(NextValueNumber * 2);
2330 E = NextValueNumber;
2331 ExprIdx[NextValueNumber++] = NextExprNumber++;
2333 return {
E, CreateNewValNum};
2338bool GVNPass::ValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
2341 GVN.LeaderTable.getLeaders(Num),
2349 auto FindRes = PhiTranslateTable.find({Num, Pred});
2350 if (FindRes != PhiTranslateTable.end())
2351 return FindRes->second;
2352 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, GVN);
2353 PhiTranslateTable.insert({{Num, Pred}, NewNum});
2364 auto Leaders = GVN.LeaderTable.getLeaders(Num);
2365 for (
const auto &Entry : Leaders) {
2367 if (
Call &&
Call->getParent() == PhiBlock)
2371 if (
AA->doesNotAccessMemory(
Call))
2374 if (!MD || !
AA->onlyReadsMemory(
Call))
2386 if (
D.getResult().isNonFuncLocal())
2394uint32_t GVNPass::ValueTable::phiTranslateImpl(
const BasicBlock *Pred,
2395 const BasicBlock *PhiBlock,
2399 if (PHINode *PN = NumberingPhi[Num]) {
2400 if (PN->getParent() != PhiBlock)
2402 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
2403 if (PN->getIncomingBlock(
I) != Pred)
2405 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
2411 if (BasicBlock *BB = NumberingBB[Num]) {
2412 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
2418 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
2424 return lookupOrAdd(PredPhi->getBlock());
2425 if (MSSA->isLiveOnEntryDef(MA))
2430 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
2436 if (!areAllValsInBB(Num, PhiBlock, GVN))
2439 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
2443 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
2447 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
2448 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
2449 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
2451 Exp.VarArgs[
I] = phiTranslate(Pred, PhiBlock,
Exp.VarArgs[
I], GVN);
2454 if (
Exp.Commutative) {
2455 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
2456 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
2458 uint32_t Opcode =
Exp.Opcode >> 8;
2459 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
2460 Exp.Opcode = (Opcode << 8) |
2466 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
2467 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
2468 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, GVN) ? NewNum : Num;
2476void GVNPass::ValueTable::eraseTranslateCacheEntry(
2479 PhiTranslateTable.erase({Num, Pred});
2488 auto Leaders = LeaderTable.getLeaders(Num);
2489 if (Leaders.empty())
2492 Value *Val =
nullptr;
2493 for (
const auto &Entry : Leaders) {
2494 if (DT->dominates(Entry.BB, BB)) {
2514 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
2515 assert((!Pred || Pred ==
E.getStart()) &&
2516 "No edge between these basic blocks!");
2517 return Pred !=
nullptr;
2520void GVNPass::assignBlockRPONumber(Function &
F) {
2521 BlockRPONumber.clear();
2522 uint32_t NextBlockNumber = 1;
2523 ReversePostOrderTraversal<Function *> RPOT(&
F);
2524 for (BasicBlock *BB : RPOT)
2525 BlockRPONumber[BB] = NextBlockNumber++;
2526 InvalidBlockRPONumbers =
false;
2529bool GVNPass::replaceOperandsForInBlockEquality(Instruction *Instr)
const {
2531 for (
unsigned OpNum = 0; OpNum <
Instr->getNumOperands(); ++OpNum) {
2532 Use &Operand =
Instr->getOperandUse(OpNum);
2533 auto It = ReplaceOperandsWithMap.find(Operand.
get());
2534 if (It != ReplaceOperandsWithMap.end()) {
2535 const DataLayout &
DL =
Instr->getDataLayout();
2540 << *It->second <<
" in instruction " << *Instr <<
'\n');
2541 Instr->setOperand(OpNum, It->second);
2554 const BasicBlockEdge &Root,
2555 bool DominatesByEdge) {
2563 while (!Worklist.
empty()) {
2564 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
2565 LHS = Item.first;
RHS = Item.second;
2579 const DataLayout &
DL =
2588 uint32_t LVN = VN.lookupOrAdd(
LHS);
2593 uint32_t RVN = VN.lookupOrAdd(
RHS);
2611 LeaderTable.insert(LVN,
RHS, Root.
getEnd());
2618 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
2621 unsigned NumReplacements =
2624 CanReplacePointersCallBack)
2626 CanReplacePointersCallBack);
2628 if (NumReplacements > 0) {
2630 NumGVNEqProp += NumReplacements;
2633 MD->invalidateCachedPointerInfo(
LHS);
2650 bool IsKnownFalse = !IsKnownTrue;
2666 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
2671 if (
Cmp->isEquivalence(IsKnownFalse))
2672 Worklist.
push_back(std::make_pair(Op0, Op1));
2676 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
2680 uint32_t NextNum = VN.getNextUnusedValueNumber();
2681 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
2684 if (Num < NextNum) {
2687 unsigned NumReplacements =
2692 Changed |= NumReplacements > 0;
2693 NumGVNEqProp += NumReplacements;
2696 MD->invalidateCachedPointerInfo(NotCmp);
2703 if (RootDominatesEnd)
2704 LeaderTable.insert(Num, NotVal, Root.
getEnd());
2713 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
2718 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
2728bool GVNPass::processInstruction(Instruction *
I) {
2733 const DataLayout &
DL =
I->getDataLayout();
2736 if (!
I->use_empty()) {
2739 ICF->removeUsersOf(
I);
2740 I->replaceAllUsesWith(V);
2748 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2749 MD->invalidateCachedPointerInfo(V);
2756 return processAssumeIntrinsic(Assume);
2759 if (processLoad(Load))
2762 unsigned Num = VN.lookupOrAdd(Load);
2763 LeaderTable.insert(Num, Load,
Load->getParent());
2774 if (!BI->isConditional())
2778 return processFoldableCondBr(BI);
2780 Value *BranchCond = BI->getCondition();
2784 if (TrueSucc == FalseSucc)
2791 BasicBlockEdge TrueE(Parent, TrueSucc);
2792 Changed |= propagateEquality(BranchCond, TrueVal, TrueE,
true);
2795 BasicBlockEdge FalseE(Parent, FalseSucc);
2796 Changed |= propagateEquality(BranchCond, FalseVal, FalseE,
true);
2803 Value *SwitchCond =
SI->getCondition();
2808 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
2810 ++SwitchEdges[Succ];
2812 for (
const auto &Case :
SI->cases()) {
2815 if (SwitchEdges.
lookup(Dst) == 1) {
2816 BasicBlockEdge
E(Parent, Dst);
2817 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E,
true);
2825 if (
I->getType()->isVoidTy())
2828 uint32_t NextNum = VN.getNextUnusedValueNumber();
2829 unsigned Num = VN.lookupOrAdd(
I);
2834 LeaderTable.insert(Num,
I,
I->getParent());
2841 if (Num >= NextNum) {
2842 LeaderTable.insert(Num,
I,
I->getParent());
2848 Value *Repl = findLeader(
I->getParent(), Num);
2851 LeaderTable.insert(Num,
I,
I->getParent());
2864 MD->invalidateCachedPointerInfo(Repl);
2870bool GVNPass::runImpl(Function &
F, AssumptionCache &RunAC, DominatorTree &RunDT,
2871 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
2872 MemoryDependenceResults *RunMD, LoopInfo &LI,
2873 OptimizationRemarkEmitter *RunORE,
MemorySSA *MSSA) {
2878 VN.setAliasAnalysis(&RunAA);
2880 ImplicitControlFlowTracking ImplicitCFT;
2884 VN.setMemorySSA(MSSA);
2886 InvalidBlockRPONumbers =
true;
2887 MemorySSAUpdater Updater(MSSA);
2888 MSSAU = MSSA ? &Updater :
nullptr;
2891 bool ShouldContinue =
true;
2893 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2905 unsigned Iteration = 0;
2906 while (ShouldContinue) {
2909 ShouldContinue = iterateOnFunction(
F);
2917 assignValNumForDeadCode();
2918 bool PREChanged =
true;
2919 while (PREChanged) {
2920 PREChanged = performPRE(
F);
2930 cleanupGlobalSets();
2941bool GVNPass::processBlock(BasicBlock *BB) {
2942 if (DeadBlocks.count(BB))
2946 ReplaceOperandsWithMap.clear();
2947 bool ChangedFunction =
false;
2953 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
2955 for (PHINode *PN : PHINodesToRemove) {
2956 removeInstruction(PN);
2959 if (!ReplaceOperandsWithMap.empty())
2960 ChangedFunction |= replaceOperandsForInBlockEquality(&Inst);
2961 ChangedFunction |= processInstruction(&Inst);
2963 return ChangedFunction;
2967bool GVNPass::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
2968 BasicBlock *Curr,
unsigned int ValNo) {
2974 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
2982 if (!VN.exists(
Op)) {
2987 VN.phiTranslate(Pred, Curr, VN.lookup(
Op), *
this);
2988 if (
Value *V = findLeader(Pred, TValNo)) {
3006 ICF->insertInstructionTo(Instr, Pred);
3008 unsigned Num = VN.lookupOrAdd(Instr);
3012 LeaderTable.insert(Num, Instr, Pred);
3016bool GVNPass::performScalarPRE(Instruction *CurInst) {
3042 if (CallB->isInlineAsm())
3046 uint32_t ValNo = VN.lookup(CurInst);
3054 unsigned NumWith = 0;
3055 unsigned NumWithout = 0;
3060 if (InvalidBlockRPONumbers)
3061 assignBlockRPONumber(*CurrentBlock->
getParent());
3067 if (!DT->isReachableFromEntry(
P)) {
3072 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
3073 "Invalid BlockRPONumber map.");
3074 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
3079 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, *
this);
3080 Value *PredV = findLeader(
P, TValNo);
3085 }
else if (PredV == CurInst) {
3097 if (NumWithout > 1 || NumWith == 0)
3105 if (NumWithout != 0) {
3111 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
3124 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
3128 PREInstr = CurInst->
clone();
3129 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
3132 verifyRemoved(PREInstr);
3141 assert(PREInstr !=
nullptr || NumWithout == 0);
3147 CurInst->
getName() +
".pre-phi");
3148 Phi->insertBefore(CurrentBlock->begin());
3149 for (
auto &[V, BB] : PredMap) {
3154 Phi->addIncoming(V, BB);
3156 Phi->addIncoming(PREInstr, PREPred);
3162 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
3163 LeaderTable.insert(ValNo, Phi, CurrentBlock);
3166 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
3167 MD->invalidateCachedPointerInfo(Phi);
3168 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
3171 removeInstruction(CurInst);
3179bool GVNPass::performPRE(Function &
F) {
3181 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
3183 if (CurrentBlock == &
F.getEntryBlock())
3187 if (CurrentBlock->isEHPad())
3191 BE = CurrentBlock->end();
3194 Changed |= performScalarPRE(CurInst);
3198 if (splitCriticalEdges())
3206BasicBlock *GVNPass::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) {
3211 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
3214 MD->invalidateCachedPredecessors();
3215 InvalidBlockRPONumbers =
true;
3222bool GVNPass::splitCriticalEdges() {
3223 if (ToSplit.empty())
3228 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
3230 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
3232 }
while (!ToSplit.empty());
3235 MD->invalidateCachedPredecessors();
3236 InvalidBlockRPONumbers =
true;
3242bool GVNPass::iterateOnFunction(Function &
F) {
3243 cleanupGlobalSets();
3250 ReversePostOrderTraversal<Function *> RPOT(&
F);
3252 for (BasicBlock *BB : RPOT)
3258void GVNPass::cleanupGlobalSets() {
3260 LeaderTable.clear();
3261 BlockRPONumber.clear();
3263 InvalidBlockRPONumbers =
true;
3266void GVNPass::removeInstruction(Instruction *
I) {
3268 if (MD) MD->removeInstruction(
I);
3270 MSSAU->removeMemoryAccess(
I);
3274 ICF->removeInstruction(
I);
3275 I->eraseFromParent();
3280void GVNPass::verifyRemoved(
const Instruction *Inst)
const {
3281 VN.verifyRemoved(Inst);
3282 LeaderTable.verifyRemoved(Inst);
3289void GVNPass::addDeadBlock(BasicBlock *BB) {
3291 SmallSetVector<BasicBlock *, 4>
DF;
3294 while (!NewDead.
empty()) {
3296 if (DeadBlocks.count(
D))
3300 SmallVector<BasicBlock *, 8> Dom;
3301 DT->getDescendants(
D, Dom);
3302 DeadBlocks.insert_range(Dom);
3305 for (BasicBlock *
B : Dom) {
3307 if (DeadBlocks.count(S))
3310 bool AllPredDead =
true;
3312 if (!DeadBlocks.count(
P)) {
3313 AllPredDead =
false;
3333 for (BasicBlock *
B :
DF) {
3334 if (DeadBlocks.count(
B))
3340 for (BasicBlock *
P : Preds) {
3341 if (!DeadBlocks.count(
P))
3346 if (BasicBlock *S = splitCriticalEdges(
P,
B))
3347 DeadBlocks.insert(
P = S);
3353 if (!DeadBlocks.count(
P))
3355 for (PHINode &Phi :
B->phis()) {
3358 MD->invalidateCachedPointerInfo(&Phi);
3377bool GVNPass::processFoldableCondBr(BranchInst *BI) {
3391 if (DeadBlocks.count(DeadRoot))
3395 DeadRoot = splitCriticalEdges(BI->
getParent(), DeadRoot);
3397 addDeadBlock(DeadRoot);
3405void GVNPass::assignValNumForDeadCode() {
3406 for (BasicBlock *BB : DeadBlocks) {
3407 for (Instruction &Inst : *BB) {
3408 unsigned ValNum = VN.lookupOrAdd(&Inst);
3409 LeaderTable.insert(ValNum, &Inst, BB);
3421 .setMemDep(MemDepAnalysis)
3422 .setMemorySSA(MemSSAAnalysis)) {
3431 if (Impl.isMemorySSAEnabled() && !MSSAWP)
3434 return Impl.runImpl(
3439 Impl.isMemDepEnabled()
3444 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
3452 if (Impl.isMemDepEnabled())
3461 if (Impl.isMemorySSAEnabled())
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
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")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
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
static bool hasUsersIn(Value *V, BasicBlock *BB)
static void reportMayClobberedLoad(LoadInst *Load, MemDepResult DepInfo, 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 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 cl::opt< bool > GVNEnableMemorySSA("enable-gvn-memoryssa", cl::init(false))
static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E, DominatorTree *DT)
There is an edge from 'Src' to 'Dst'.
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 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.
static Value * ConstructSSAForLoadSet(LoadInst *Load, SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, GVNPass &GVN)
Given a set of loads specified by ValuesPerBlock, construct SSA form, allowing us to eliminate Load.
@ 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 cl::opt< bool > GVNEnablePRE("enable-pre", cl::init(true), cl::Hidden)
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 lookup(const GsymReader &GR, DataExtractor &Data, uint64_t &Offset, uint64_t BaseAddr, uint64_t Addr, SourceLocations &SrcLocs, llvm::Error &Err)
A Lookup helper functions.
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
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]
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
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.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
const BasicBlock * getEnd() const
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 if the block is well formed or null if the block is not well forme...
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.
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
Value * getCondition() const
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
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.
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)
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.
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)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Analysis pass which computes a DominatorTree.
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 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.
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.
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
The core GVN pass object.
friend class gvn::GVNLegacyPass
LLVM_ABI bool isPREEnabled() const
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI void salvageAndRemoveInstruction(Instruction *I)
This removes the specified instruction from our various maps and marks it for deletion.
AAResults * getAliasAnalysis() const
LLVM_ABI bool isLoadPREEnabled() const
GVNPass(GVNOptions Options={})
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI bool isMemorySSAEnabled() const
DominatorTree & getDominatorTree() const
LLVM_ABI bool isLoadInLoopPREEnabled() const
LLVM_ABI bool isLoadPRESplitBackedgeEnabled() const
LLVM_ABI bool isMemDepEnabled() const
Legacy wrapper pass to provide the GlobalsAAResult object.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
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.
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.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
The legacy pass manager's analysis pass to compute loop information.
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.
std::vector< NonLocalDepEntry > NonLocalDepInfo
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
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.
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.
Legacy analysis pass which computes MemorySSA.
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
This is an entry in the NonLocalDepInfo cache.
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...
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(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type 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.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
This class represents the LLVM 'select' instruction.
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, Instruction *MDFrom=nullptr)
const Value * getCondition() const
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SmallVector & operator=(const SmallVector &RHS)
StringRef - Represent a constant reference to a string, i.e.
Analysis pass providing the TargetLibraryInfo.
The instances of the Type class are immutable: once they are created, they are never changed.
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.
An efficient, type-erasing, non-owning reference to a callable.
GVNLegacyPass(bool MemDepAnalysis=GVNEnableMemDep, bool MemSSAAnalysis=GVNEnableMemorySSA)
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.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
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.
@ C
The default llvm calling convention, compatible with C.
@ 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.
IntrinsicID_match m_Intrinsic()
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2, Opnd3 >::Ty m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2, const Opnd3 &Op3)
Matches MaskedStore Intrinsic.
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.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
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...
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...
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...
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...
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...
bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
initializer< Ty > init(const Ty &Val)
A private "module" namespace for types and utilities used by GVN.
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
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...
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 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)
constexpr from_range_t from_range
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 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 ...
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 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.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
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.
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()
Create a legacy GVN pass.
FunctionAddr VTableAddr Next
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.
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.
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB)
Check for and eliminate duplicate PHI nodes in this block.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static GVNPass::Expression getTombstoneKey()
static bool isEqual(const GVNPass::Expression &LHS, const GVNPass::Expression &RHS)
static GVNPass::Expression getEmptyKey()
static unsigned getHashValue(const GVNPass::Expression &E)
An information struct used to provide DenseMap with the various necessary components for a given valu...
A set of parameters to control various transforms performed by GVN pass.
bool operator==(const Expression &Other) const
friend hash_code hash_value(const Expression &Value)
SmallVector< uint32_t, 4 > VarArgs
Expression(uint32_t Op=~2U)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Represents an AvailableValue which can be rematerialized at the end of the associated BasicBlock.
static AvailableValueInBlock get(BasicBlock *BB, Value *V, unsigned Offset=0)
static AvailableValueInBlock getUndef(BasicBlock *BB)
static AvailableValueInBlock get(BasicBlock *BB, AvailableValue &&AV)
AvailableValue AV
AV - The actual available value.
static AvailableValueInBlock getSelect(BasicBlock *BB, SelectInst *Sel, Value *V1, Value *V2)
BasicBlock * BB
BB - The basic block in question.
Value * MaterializeAdjustedValue(LoadInst *Load) const
Emit code at the end of this block to adjust the value defined here to the specified type.
Represents a particular available value that we know how to materialize.
unsigned Offset
Offset - The byte offset in Val that is interesting for the load query.
bool isSimpleValue() const
static AvailableValue getSelect(SelectInst *Sel, Value *V1, Value *V2)
bool isCoercedLoadValue() const
static AvailableValue get(Value *V, unsigned Offset=0)
ValType Kind
Kind of the live-out value.
LoadInst * getCoercedLoadValue() const
static AvailableValue getLoad(LoadInst *Load, unsigned Offset=0)
static AvailableValue getMI(MemIntrinsic *MI, unsigned Offset=0)
bool isUndefValue() const
bool isSelectValue() const
Value * Val
Val - The value that is live out of the block.
Value * V1
V1, V2 - The dominating non-clobbered values of SelectVal.
static AvailableValue getUndef()
SelectInst * getSelectValue() const
Value * getSimpleValue() const
bool isMemIntrinValue() const
MemIntrinsic * getMemIntrinValue() const
Value * MaterializeAdjustedValue(LoadInst *Load, Instruction *InsertPt) const
Emit code at the specified insertion point to adjust the value defined here to the specified type.