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");
122 cl::desc(
"Max number of dependences to attempt Load PRE (default = 100)"));
127 cl::desc(
"Max number of blocks we're willing to speculate on (and recurse "
128 "into) when deducing if a value is fully available or not in GVN "
133 cl::desc(
"Max number of visited instructions when trying to find "
134 "dominating value of select dependency (default = 100)"));
138 cl::desc(
"Max number of instructions to scan in each basic block in GVN "
162 if ((!
Attrs.isEmpty() || !
Other.Attrs.isEmpty()) &&
163 !
Attrs.intersectWith(
Ty->getContext(),
Other.Attrs).has_value())
300 Res.
AV = std::move(
AV);
321 return AV.MaterializeAdjustedValue(Load,
BB->getTerminator());
332 E.Opcode =
I->getOpcode();
337 E.VarArgs.push_back(
lookupOrAdd(GCR->getOperand(0)));
338 E.VarArgs.push_back(
lookupOrAdd(GCR->getBasePtr()));
339 E.VarArgs.push_back(
lookupOrAdd(GCR->getDerivedPtr()));
341 for (
Use &
Op :
I->operands())
344 if (
I->isCommutative()) {
349 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
350 if (
E.VarArgs[0] >
E.VarArgs[1])
352 E.Commutative =
true;
358 if (
E.VarArgs[0] >
E.VarArgs[1]) {
363 E.Commutative =
true;
365 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
367 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
368 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
370 E.Attrs = CB->getAttributes();
376GVNPass::Expression GVNPass::ValueTable::createCmpExpr(
378 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
379 "Not a comparison!");
382 E.VarArgs.push_back(lookupOrAdd(
LHS));
383 E.VarArgs.push_back(lookupOrAdd(
RHS));
386 if (
E.VarArgs[0] >
E.VarArgs[1]) {
390 E.Opcode = (Opcode << 8) | Predicate;
391 E.Commutative =
true;
396GVNPass::ValueTable::createExtractvalueExpr(ExtractValueInst *EI) {
397 assert(EI &&
"Not an ExtractValueInst?");
408 E.VarArgs.push_back(lookupOrAdd(WO->
getLHS()));
409 E.VarArgs.push_back(lookupOrAdd(WO->
getRHS()));
417 E.VarArgs.push_back(lookupOrAdd(
Op));
424GVNPass::Expression GVNPass::ValueTable::createGEPExpr(GetElementPtrInst *
GEP) {
426 Type *PtrTy =
GEP->getType()->getScalarType();
427 const DataLayout &
DL =
GEP->getDataLayout();
428 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
429 SmallMapVector<Value *, APInt, 4> VariableOffsets;
431 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
435 E.Opcode =
GEP->getOpcode();
437 E.VarArgs.push_back(lookupOrAdd(
GEP->getPointerOperand()));
438 for (
const auto &[V, Scale] : VariableOffsets) {
439 E.VarArgs.push_back(lookupOrAdd(V));
440 E.VarArgs.push_back(lookupOrAdd(ConstantInt::get(
Context, Scale)));
442 if (!ConstantOffset.isZero())
444 lookupOrAdd(ConstantInt::get(
Context, ConstantOffset)));
448 E.Opcode =
GEP->getOpcode();
449 E.Ty =
GEP->getSourceElementType();
450 for (Use &
Op :
GEP->operands())
451 E.VarArgs.push_back(lookupOrAdd(
Op));
460GVNPass::ValueTable::ValueTable() =
default;
461GVNPass::ValueTable::ValueTable(
const ValueTable &) =
default;
462GVNPass::ValueTable::ValueTable(
ValueTable &&) =
default;
463GVNPass::ValueTable::~ValueTable() =
default;
469 ValueNumbering.
insert(std::make_pair(V, Num));
471 NumberingPhi[Num] = PN;
481 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
482 assert(MSSA->getMemoryAccess(
I) &&
"Instruction does not access memory");
483 MemoryAccess *MA = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(
I);
484 Exp.VarArgs.push_back(lookupOrAdd(MA));
495 if (
C->getFunction()->isPresplitCoroutine()) {
496 ValueNumbering[
C] = NextValueNumber;
497 return NextValueNumber++;
503 if (
C->isConvergent()) {
504 ValueNumbering[
C] = NextValueNumber;
505 return NextValueNumber++;
508 if (AA->doesNotAccessMemory(
C)) {
510 uint32_t
E = assignExpNewValueNum(Exp).first;
511 ValueNumbering[
C] =
E;
515 if (MD && AA->onlyReadsMemory(
C)) {
517 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
519 ValueNumbering[
C] =
E;
523 MemDepResult LocalDep = MD->getDependency(
C);
526 ValueNumbering[
C] = NextValueNumber;
527 return NextValueNumber++;
530 if (LocalDep.
isDef()) {
535 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
536 ValueNumbering[
C] = NextValueNumber;
537 return NextValueNumber++;
540 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
541 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
542 uint32_t LocalDepCallVN = lookupOrAdd(LocalDepCall->
getArgOperand(
I));
543 if (CVN != LocalDepCallVN) {
544 ValueNumbering[
C] = NextValueNumber;
545 return NextValueNumber++;
549 uint32_t
V = lookupOrAdd(LocalDepCall);
550 ValueNumbering[
C] =
V;
556 MD->getNonLocalCallDependency(
C);
558 CallInst *CDep =
nullptr;
562 for (
const NonLocalDepEntry &
I : Deps) {
563 if (
I.getResult().isNonLocal())
568 if (!
I.getResult().isDef() || CDep !=
nullptr) {
575 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
576 CDep = NonLocalDepCall;
585 ValueNumbering[
C] = NextValueNumber;
586 return NextValueNumber++;
590 ValueNumbering[
C] = NextValueNumber;
591 return NextValueNumber++;
593 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
594 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
597 ValueNumbering[
C] = NextValueNumber;
598 return NextValueNumber++;
602 uint32_t
V = lookupOrAdd(CDep);
603 ValueNumbering[
C] =
V;
607 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
609 addMemoryStateToExp(
C, Exp);
610 auto [
V,
_] = assignExpNewValueNum(Exp);
611 ValueNumbering[
C] =
V;
615 ValueNumbering[
C] = NextValueNumber;
616 return NextValueNumber++;
620uint32_t GVNPass::ValueTable::computeLoadStoreVN(Instruction *
I) {
621 if (!MSSA || !IsMSSAEnabled) {
622 ValueNumbering[
I] = NextValueNumber;
623 return NextValueNumber++;
627 Exp.Ty =
I->getType();
628 Exp.Opcode =
I->getOpcode();
629 for (Use &
Op :
I->operands())
630 Exp.VarArgs.push_back(lookupOrAdd(
Op));
631 addMemoryStateToExp(
I, Exp);
633 auto [
V,
_] = assignExpNewValueNum(Exp);
634 ValueNumbering[
I] =
V;
639bool GVNPass::ValueTable::exists(
Value *V)
const {
640 return ValueNumbering.contains(V);
652 auto VI = ValueNumbering.find(V);
653 if (VI != ValueNumbering.end())
658 ValueNumbering[V] = NextValueNumber;
661 return NextValueNumber++;
665 switch (
I->getOpcode()) {
666 case Instruction::Call:
668 case Instruction::FNeg:
669 case Instruction::Add:
670 case Instruction::FAdd:
671 case Instruction::Sub:
672 case Instruction::FSub:
673 case Instruction::Mul:
674 case Instruction::FMul:
675 case Instruction::UDiv:
676 case Instruction::SDiv:
677 case Instruction::FDiv:
678 case Instruction::URem:
679 case Instruction::SRem:
680 case Instruction::FRem:
681 case Instruction::Shl:
682 case Instruction::LShr:
683 case Instruction::AShr:
684 case Instruction::And:
685 case Instruction::Or:
686 case Instruction::Xor:
687 case Instruction::ICmp:
688 case Instruction::FCmp:
689 case Instruction::Trunc:
690 case Instruction::ZExt:
691 case Instruction::SExt:
692 case Instruction::FPToUI:
693 case Instruction::FPToSI:
694 case Instruction::UIToFP:
695 case Instruction::SIToFP:
696 case Instruction::FPTrunc:
697 case Instruction::FPExt:
698 case Instruction::PtrToInt:
699 case Instruction::PtrToAddr:
700 case Instruction::IntToPtr:
701 case Instruction::AddrSpaceCast:
702 case Instruction::BitCast:
703 case Instruction::Select:
704 case Instruction::Freeze:
705 case Instruction::ExtractElement:
706 case Instruction::InsertElement:
707 case Instruction::ShuffleVector:
708 case Instruction::InsertValue:
711 case Instruction::GetElementPtr:
714 case Instruction::ExtractValue:
717 case Instruction::PHI:
718 ValueNumbering[V] = NextValueNumber;
720 return NextValueNumber++;
721 case Instruction::Load:
722 case Instruction::Store:
723 return computeLoadStoreVN(
I);
725 ValueNumbering[V] = NextValueNumber;
726 return NextValueNumber++;
729 uint32_t E = assignExpNewValueNum(Exp).first;
730 ValueNumbering[V] = E;
737 auto VI = ValueNumbering.find(V);
739 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
742 return (VI != ValueNumbering.end()) ? VI->second : 0;
749uint32_t GVNPass::ValueTable::lookupOrAddCmp(
unsigned Opcode,
752 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
753 return assignExpNewValueNum(Exp).first;
758 ValueNumbering.clear();
759 ExpressionNumbering.clear();
760 NumberingPhi.clear();
762 PhiTranslateTable.clear();
771 uint32_t Num = ValueNumbering.lookup(V);
772 ValueNumbering.erase(V);
775 NumberingPhi.erase(Num);
777 NumberingBB.erase(Num);
782void GVNPass::ValueTable::verifyRemoved(
const Value *V)
const {
783 assert(!ValueNumbering.contains(V) &&
784 "Inst still occurs in value numbering map!");
793 const auto &[It, Inserted] = NumToLeaders.try_emplace(
N, V, BB,
nullptr);
796 auto *NewSlot = TableAllocator.Allocate<LeaderListNode>();
797 new (NewSlot) LeaderListNode(V, BB, It->second.Next);
798 It->second.Next = NewSlot;
806 auto It = NumToLeaders.find(
N);
807 if (It == NumToLeaders.end())
810 LeaderListNode *Prev =
nullptr;
811 LeaderListNode *Curr = &It->second;
813 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
823 Prev->Next = Curr->Next;
824 Curr->~LeaderListNode();
825 TableAllocator.Deallocate<LeaderListNode>(Curr);
830 NumToLeaders.erase(It);
833 LeaderListNode *
Next = Curr->Next;
834 Curr->Entry.Val = std::move(
Next->Entry.Val);
835 Curr->Entry.BB =
Next->Entry.BB;
836 Curr->Next =
Next->Next;
837 Next->~LeaderListNode();
838 TableAllocator.Deallocate<LeaderListNode>(
Next);
860 return Options.AllowLoadPRESplitBackedge.value_or(
887 "On-demand computation of MemSSA implies that MemDep is disabled!");
891 bool Changed = runImpl(
F, AC, DT, TLI,
AA, MemDep, LI, &ORE,
892 MSSA ? &MSSA->getMSSA() :
nullptr);
907 OS, MapClassName2PassName);
910 if (Options.AllowScalarPRE != std::nullopt)
911 OS << (*Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
912 if (Options.AllowLoadPRE != std::nullopt)
913 OS << (*Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
914 if (Options.AllowLoadPRESplitBackedge != std::nullopt)
915 OS << (*Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
916 <<
"split-backedge-load-pre;";
917 if (Options.AllowMemDep != std::nullopt)
918 OS << (*Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
919 if (Options.AllowMemorySSA != std::nullopt)
920 OS << (*Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
927 removeInstruction(
I);
930#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
933 for (
const auto &[Num, Exp] : Map) {
934 errs() << Num <<
"\n";
965 std::optional<BasicBlock *> UnavailableBB;
969 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
977 while (!Worklist.
empty()) {
981 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
989 UnavailableBB = CurrBB;
1000 ++NumNewNewSpeculativelyAvailableBBs;
1006 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1008 UnavailableBB = CurrBB;
1014 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1020#if LLVM_ENABLE_STATS
1021 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1022 NumNewNewSpeculativelyAvailableBBs);
1027 auto MarkAsFixpointAndEnqueueSuccessors =
1029 auto It = FullyAvailableBlocks.
find(BB);
1030 if (It == FullyAvailableBlocks.
end())
1037 State = FixpointState;
1040 "Found a speculatively available successor leftover?");
1048 if (UnavailableBB) {
1055 while (!Worklist.
empty())
1056 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1064 while (!Worklist.
empty())
1065 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1069 "Must have fixed all the new speculatively available blocks.");
1072 return !UnavailableBB;
1081 if (V.AV.Val == OldValue)
1082 V.AV.Val = NewValue;
1083 if (V.AV.isSelectValue()) {
1084 if (V.AV.V1 == OldValue)
1086 if (V.AV.V2 == OldValue)
1101 if (ValuesPerBlock.
size() == 1 &&
1103 Load->getParent())) {
1104 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1105 "Dead BB dominate this block");
1106 return ValuesPerBlock[0].MaterializeAdjustedValue(Load);
1112 SSAUpdate.
Initialize(Load->getType(), Load->getName());
1117 if (AV.AV.isUndefValue())
1127 if (BB == Load->getParent() &&
1128 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() == Load) ||
1129 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() == Load)))
1142 Type *LoadTy = Load->getType();
1146 if (Res->
getType() != LoadTy) {
1161 Load->getFunction());
1171 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1173 {LLVMContext::MD_dereferenceable,
1174 LLVMContext::MD_dereferenceable_or_null,
1175 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group});
1191 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1200 assert(Res &&
"failed to materialize?");
1206 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1223 Value *PtrOp = Load->getPointerOperand();
1229 for (
auto *U : PtrOp->
users()) {
1232 if (
I->getFunction() == Load->getFunction() && DT->
dominates(
I, Load)) {
1250 for (
auto *U : PtrOp->
users()) {
1253 if (
I->getFunction() == Load->getFunction() &&
1261 OtherAccess =
nullptr;
1280 using namespace ore;
1283 R <<
"load of type " << NV(
"Type", Load->getType()) <<
" not eliminated"
1288 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1290 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1304 for (
auto *Inst = BB == FromBB ? From : BB->
getTerminator();
1312 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1313 SI->getValueOperand()->getType() == LoadTy)
1314 return SI->getValueOperand();
1318 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1324std::optional<AvailableValue>
1325GVNPass::AnalyzeLoadAvailability(LoadInst *Load, MemDepResult DepInfo,
1327 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1332 const DataLayout &
DL =
Load->getDataLayout();
1339 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1355 if (DepLoad != Load &&
Address &&
1356 Load->isAtomic() <= DepLoad->isAtomic()) {
1363 DepLoad->getFunction())) {
1364 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1366 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1393 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1397 return std::nullopt;
1406 if (Constant *InitVal =
1416 return std::nullopt;
1419 if (S->isAtomic() <
Load->isAtomic())
1420 return std::nullopt;
1431 return std::nullopt;
1434 if (
LD->isAtomic() <
Load->isAtomic())
1435 return std::nullopt;
1444 assert(Sel->getType() ==
Load->getPointerOperandType());
1450 return std::nullopt;
1455 return std::nullopt;
1463 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1464 return std::nullopt;
1467void GVNPass::AnalyzeLoadAvailability(LoadInst *Load, LoadDepVect &Deps,
1468 AvailValInBlkVect &ValuesPerBlock,
1469 UnavailBlkVect &UnavailableBlocks) {
1474 for (
const auto &Dep : Deps) {
1476 MemDepResult DepInfo = Dep.getResult();
1478 if (DeadBlocks.count(DepBB)) {
1486 UnavailableBlocks.push_back(DepBB);
1493 if (
auto AV = AnalyzeLoadAvailability(Load, DepInfo, Dep.getAddress())) {
1497 ValuesPerBlock.push_back(
1500 UnavailableBlocks.push_back(DepBB);
1504 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1505 "post condition violation");
1527LoadInst *GVNPass::findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
1531 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1533 auto *SuccBB =
Term->getSuccessor(0);
1534 if (SuccBB == LoadBB)
1535 SuccBB =
Term->getSuccessor(1);
1536 if (!SuccBB->getSinglePredecessor())
1540 for (Instruction &Inst : *SuccBB) {
1541 if (Inst.isDebugOrPseudoInst())
1543 if (--NumInsts == 0)
1546 if (!Inst.isIdenticalTo(Load))
1549 MemDepResult Dep = MD->getDependency(&Inst);
1554 if (Dep.
isNonLocal() && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1565void GVNPass::eliminatePartiallyRedundantLoad(
1566 LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
1567 MapVector<BasicBlock *, Value *> &AvailableLoads,
1568 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad) {
1569 for (
const auto &AvailableLoad : AvailableLoads) {
1570 BasicBlock *UnavailableBlock = AvailableLoad.first;
1571 Value *LoadPtr = AvailableLoad.second;
1573 auto *NewLoad =
new LoadInst(
1574 Load->getType(), LoadPtr,
Load->getName() +
".pre",
Load->isVolatile(),
1575 Load->getAlign(),
Load->getOrdering(),
Load->getSyncScopeID(),
1577 NewLoad->setDebugLoc(
Load->getDebugLoc());
1579 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1582 MSSAU->insertDef(NewDef,
true);
1588 AAMDNodes Tags =
Load->getAAMetadata();
1590 NewLoad->setAAMetadata(Tags);
1592 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1593 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1594 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1595 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1596 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1597 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1598 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1599 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
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";);
2029 if (GetElementPtrInst *
GEP =
2031 for (Use &U :
GEP->indices())
2038 AvailValInBlkVect ValuesPerBlock;
2039 UnavailBlkVect UnavailableBlocks;
2040 AnalyzeLoadAvailability(Load, Deps, ValuesPerBlock, UnavailableBlocks);
2044 if (ValuesPerBlock.empty())
2052 if (UnavailableBlocks.empty()) {
2053 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING NONLOCAL LOAD: " << *Load <<
'\n');
2058 ICF->removeUsersOf(Load);
2059 Load->replaceAllUsesWith(V);
2067 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2068 I->setDebugLoc(
Load->getDebugLoc());
2069 if (
V->getType()->isPtrOrPtrVectorTy())
2070 MD->invalidateCachedPointerInfo(V);
2083 if (performLoopLoadPRE(Load, ValuesPerBlock, UnavailableBlocks) ||
2084 PerformLoadPRE(Load, ValuesPerBlock, UnavailableBlocks))
2090bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
2094 if (
Cond->isZero()) {
2104 const MemoryUseOrDef *FirstNonDom =
nullptr;
2106 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2113 for (
const auto &Acc : *AL) {
2115 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2116 FirstNonDom = Current;
2123 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2125 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2126 : MSSAU->createMemoryAccessInBB(
2148 return propagateEquality(V, True, IntrinsicI);
2153 I->replaceAllUsesWith(Repl);
2158bool GVNPass::processLoad(LoadInst *L) {
2163 if (!
L->isUnordered())
2166 if (
L->getType()->isTokenLikeTy())
2169 if (
L->use_empty()) {
2175 MemDepResult Dep = MD->getDependency(L);
2179 return processNonLocalLoad(L);
2186 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
2187 dbgs() <<
" has unknown dependence\n";);
2191 auto AV = AnalyzeLoadAvailability(L, Dep,
L->getPointerOperand());
2195 Value *AvailableValue = AV->MaterializeAdjustedValue(L, L);
2198 ICF->removeUsersOf(L);
2199 L->replaceAllUsesWith(AvailableValue);
2201 MSSAU->removeMemoryAccess(L);
2208 MD->invalidateCachedPointerInfo(AvailableValue);
2214bool GVNPass::processMaskedLoad(IntrinsicInst *
I) {
2217 MemDepResult Dep = MD->getDependency(
I);
2223 Value *Passthrough =
I->getOperand(2);
2227 StoreVal->
getType() !=
I->getType())
2234 ICF->removeUsersOf(
I);
2235 I->replaceAllUsesWith(OpToForward);
2243std::pair<uint32_t, bool>
2244GVNPass::ValueTable::assignExpNewValueNum(
Expression &Exp) {
2245 uint32_t &
E = ExpressionNumbering[
Exp];
2246 bool CreateNewValNum = !
E;
2247 if (CreateNewValNum) {
2248 Expressions.push_back(Exp);
2249 if (ExprIdx.size() < NextValueNumber + 1)
2250 ExprIdx.resize(NextValueNumber * 2);
2251 E = NextValueNumber;
2252 ExprIdx[NextValueNumber++] = NextExprNumber++;
2254 return {
E, CreateNewValNum};
2259bool GVNPass::ValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
2262 GVN.LeaderTable.getLeaders(Num),
2270 auto FindRes = PhiTranslateTable.find({Num, Pred});
2271 if (FindRes != PhiTranslateTable.end())
2272 return FindRes->second;
2273 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, GVN);
2274 PhiTranslateTable.insert({{Num, Pred}, NewNum});
2285 auto Leaders = GVN.LeaderTable.getLeaders(Num);
2286 for (
const auto &Entry : Leaders) {
2288 if (
Call &&
Call->getParent() == PhiBlock)
2292 if (
AA->doesNotAccessMemory(
Call))
2295 if (!MD || !
AA->onlyReadsMemory(
Call))
2307 if (
D.getResult().isNonFuncLocal())
2315uint32_t GVNPass::ValueTable::phiTranslateImpl(
const BasicBlock *Pred,
2316 const BasicBlock *PhiBlock,
2320 if (PHINode *PN = NumberingPhi[Num]) {
2321 if (PN->getParent() != PhiBlock)
2323 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
2324 if (PN->getIncomingBlock(
I) != Pred)
2326 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
2332 if (BasicBlock *BB = NumberingBB[Num]) {
2333 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
2339 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
2345 return lookupOrAdd(PredPhi->getBlock());
2346 if (MSSA->isLiveOnEntryDef(MA))
2351 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
2357 if (!areAllValsInBB(Num, PhiBlock, GVN))
2360 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
2364 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
2368 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
2369 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
2370 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
2372 Exp.VarArgs[
I] = phiTranslate(Pred, PhiBlock,
Exp.VarArgs[
I], GVN);
2375 if (
Exp.Commutative) {
2376 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
2377 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
2379 uint32_t Opcode =
Exp.Opcode >> 8;
2380 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
2381 Exp.Opcode = (Opcode << 8) |
2387 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
2388 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
2389 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, GVN) ? NewNum : Num;
2397void GVNPass::ValueTable::eraseTranslateCacheEntry(
2400 PhiTranslateTable.erase({Num, Pred});
2409 auto Leaders = LeaderTable.getLeaders(Num);
2410 if (Leaders.empty())
2413 Value *Val =
nullptr;
2414 for (
const auto &Entry : Leaders) {
2415 if (DT->dominates(Entry.BB, BB)) {
2435 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
2436 assert((!Pred || Pred ==
E.getStart()) &&
2437 "No edge between these basic blocks!");
2438 return Pred !=
nullptr;
2441void GVNPass::assignBlockRPONumber(Function &
F) {
2442 BlockRPONumber.clear();
2443 uint32_t NextBlockNumber = 1;
2444 ReversePostOrderTraversal<Function *> RPOT(&
F);
2445 for (BasicBlock *BB : RPOT)
2446 BlockRPONumber[BB] = NextBlockNumber++;
2447 InvalidBlockRPONumbers =
false;
2455bool GVNPass::propagateEquality(
2457 const std::variant<BasicBlockEdge, Instruction *> &Root) {
2462 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
2469 for (
const auto *Node : DT->getNode(
I->getParent())->children())
2473 while (!Worklist.
empty()) {
2474 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
2475 LHS = Item.first;
RHS = Item.second;
2489 const DataLayout &
DL =
2498 uint32_t LVN = VN.lookupOrAdd(
LHS);
2503 uint32_t RVN = VN.lookupOrAdd(
RHS);
2520 for (
const BasicBlock *BB : DominatedBlocks)
2521 LeaderTable.insert(LVN,
RHS, BB);
2528 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
2531 unsigned NumReplacements;
2532 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
2534 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
2537 LHS,
RHS, *DT, std::get<Instruction *>(Root),
2538 CanReplacePointersCallBack);
2540 if (NumReplacements > 0) {
2542 NumGVNEqProp += NumReplacements;
2545 MD->invalidateCachedPointerInfo(
LHS);
2562 bool IsKnownFalse = !IsKnownTrue;
2578 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
2583 if (
Cmp->isEquivalence(IsKnownFalse))
2584 Worklist.
push_back(std::make_pair(Op0, Op1));
2588 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
2592 uint32_t NextNum = VN.getNextUnusedValueNumber();
2593 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
2596 if (Num < NextNum) {
2597 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
2602 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
2603 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
2604 !DT->dominates(
Edge->getEnd(),
Entry.BB))
2607 auto *InstBB = std::get<Instruction *>(Root)->getParent();
2608 if (!DT->dominates(
Entry.BB, InstBB) &&
2609 !DT->dominates(InstBB,
Entry.BB))
2615 unsigned NumReplacements;
2616 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
2621 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
2622 Changed |= NumReplacements > 0;
2623 NumGVNEqProp += NumReplacements;
2626 MD->invalidateCachedPointerInfo(NotCmp);
2634 for (
const BasicBlock *BB : DominatedBlocks)
2635 LeaderTable.insert(Num, NotVal, BB);
2644 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
2649 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
2659bool GVNPass::processInstruction(Instruction *
I) {
2664 const DataLayout &
DL =
I->getDataLayout();
2667 if (!
I->use_empty()) {
2670 ICF->removeUsersOf(
I);
2671 I->replaceAllUsesWith(V);
2679 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2680 MD->invalidateCachedPointerInfo(V);
2687 return processAssumeIntrinsic(Assume);
2690 if (processLoad(Load))
2693 unsigned Num = VN.lookupOrAdd(Load);
2694 LeaderTable.insert(Num, Load,
Load->getParent());
2706 return processFoldableCondBr(BI);
2708 Value *BranchCond = BI->getCondition();
2712 if (TrueSucc == FalseSucc)
2719 BasicBlockEdge TrueE(Parent, TrueSucc);
2720 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
2723 BasicBlockEdge FalseE(Parent, FalseSucc);
2724 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
2731 Value *SwitchCond =
SI->getCondition();
2736 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
2738 ++SwitchEdges[Succ];
2740 for (
const auto &Case :
SI->cases()) {
2743 if (SwitchEdges.
lookup(Dst) == 1) {
2744 BasicBlockEdge
E(Parent, Dst);
2745 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
2753 if (
I->getType()->isVoidTy())
2756 uint32_t NextNum = VN.getNextUnusedValueNumber();
2757 unsigned Num = VN.lookupOrAdd(
I);
2762 LeaderTable.insert(Num,
I,
I->getParent());
2769 if (Num >= NextNum) {
2770 LeaderTable.insert(Num,
I,
I->getParent());
2776 Value *Repl = findLeader(
I->getParent(), Num);
2779 LeaderTable.insert(Num,
I,
I->getParent());
2792 MD->invalidateCachedPointerInfo(Repl);
2798bool GVNPass::runImpl(Function &
F, AssumptionCache &RunAC, DominatorTree &RunDT,
2799 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
2800 MemoryDependenceResults *RunMD, LoopInfo &LI,
2801 OptimizationRemarkEmitter *RunORE,
MemorySSA *MSSA) {
2806 VN.setAliasAnalysis(&RunAA);
2808 ImplicitControlFlowTracking ImplicitCFT;
2817 InvalidBlockRPONumbers =
true;
2818 MemorySSAUpdater Updater(MSSA);
2819 MSSAU = MSSA ? &Updater :
nullptr;
2822 bool ShouldContinue =
true;
2824 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
2836 unsigned Iteration = 0;
2837 while (ShouldContinue) {
2840 ShouldContinue = iterateOnFunction(
F);
2848 assignValNumForDeadCode();
2849 bool PREChanged =
true;
2850 while (PREChanged) {
2851 PREChanged = performPRE(
F);
2861 cleanupGlobalSets();
2872bool GVNPass::processBlock(BasicBlock *BB) {
2873 if (DeadBlocks.count(BB))
2876 bool ChangedFunction =
false;
2882 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
2884 for (PHINode *PN : PHINodesToRemove) {
2885 removeInstruction(PN);
2888 ChangedFunction |= processInstruction(&Inst);
2889 return ChangedFunction;
2893bool GVNPass::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
2894 BasicBlock *Curr,
unsigned int ValNo) {
2900 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
2908 if (!VN.exists(
Op)) {
2913 VN.phiTranslate(Pred, Curr, VN.lookup(
Op), *
this);
2914 if (
Value *V = findLeader(Pred, TValNo)) {
2932 ICF->insertInstructionTo(Instr, Pred);
2934 unsigned Num = VN.lookupOrAdd(Instr);
2938 LeaderTable.insert(Num, Instr, Pred);
2942bool GVNPass::performScalarPRE(Instruction *CurInst) {
2968 if (CallB->isInlineAsm())
2972 uint32_t ValNo = VN.lookup(CurInst);
2980 unsigned NumWith = 0;
2981 unsigned NumWithout = 0;
2986 if (InvalidBlockRPONumbers)
2987 assignBlockRPONumber(*CurrentBlock->
getParent());
2993 if (!DT->isReachableFromEntry(
P)) {
2998 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
2999 "Invalid BlockRPONumber map.");
3000 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
3005 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, *
this);
3006 Value *PredV = findLeader(
P, TValNo);
3011 }
else if (PredV == CurInst) {
3023 if (NumWithout > 1 || NumWith == 0)
3031 if (NumWithout != 0) {
3037 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
3050 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
3054 PREInstr = CurInst->
clone();
3055 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
3058 verifyRemoved(PREInstr);
3067 assert(PREInstr !=
nullptr || NumWithout == 0);
3073 CurInst->
getName() +
".pre-phi");
3074 Phi->insertBefore(CurrentBlock->begin());
3075 for (
auto &[V, BB] : PredMap) {
3080 Phi->addIncoming(V, BB);
3082 Phi->addIncoming(PREInstr, PREPred);
3088 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
3089 LeaderTable.insert(ValNo, Phi, CurrentBlock);
3092 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
3093 MD->invalidateCachedPointerInfo(Phi);
3094 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
3097 removeInstruction(CurInst);
3104bool GVNPass::performPRE(Function &
F) {
3106 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
3108 if (CurrentBlock == &
F.getEntryBlock())
3112 if (CurrentBlock->isEHPad())
3116 BE = CurrentBlock->end();
3119 Changed |= performScalarPRE(CurInst);
3123 if (splitCriticalEdges())
3131BasicBlock *GVNPass::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) {
3136 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
3139 MD->invalidateCachedPredecessors();
3140 InvalidBlockRPONumbers =
true;
3147bool GVNPass::splitCriticalEdges() {
3148 if (ToSplit.empty())
3153 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
3155 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
3157 }
while (!ToSplit.empty());
3160 MD->invalidateCachedPredecessors();
3161 InvalidBlockRPONumbers =
true;
3167bool GVNPass::iterateOnFunction(Function &
F) {
3168 cleanupGlobalSets();
3175 ReversePostOrderTraversal<Function *> RPOT(&
F);
3177 for (BasicBlock *BB : RPOT)
3183void GVNPass::cleanupGlobalSets() {
3185 LeaderTable.clear();
3186 BlockRPONumber.clear();
3188 InvalidBlockRPONumbers =
true;
3191void GVNPass::removeInstruction(Instruction *
I) {
3193 if (MD) MD->removeInstruction(
I);
3195 MSSAU->removeMemoryAccess(
I);
3199 ICF->removeInstruction(
I);
3200 I->eraseFromParent();
3206void GVNPass::verifyRemoved(
const Instruction *Inst)
const {
3207 VN.verifyRemoved(Inst);
3214void GVNPass::addDeadBlock(BasicBlock *BB) {
3216 SmallSetVector<BasicBlock *, 4>
DF;
3219 while (!NewDead.
empty()) {
3221 if (DeadBlocks.count(
D))
3225 SmallVector<BasicBlock *, 8> Dom;
3226 DT->getDescendants(
D, Dom);
3227 DeadBlocks.insert_range(Dom);
3230 for (BasicBlock *
B : Dom) {
3232 if (DeadBlocks.count(S))
3235 bool AllPredDead =
true;
3237 if (!DeadBlocks.count(
P)) {
3238 AllPredDead =
false;
3258 for (BasicBlock *
B :
DF) {
3259 if (DeadBlocks.count(
B))
3265 for (BasicBlock *
P : Preds) {
3266 if (!DeadBlocks.count(
P))
3271 if (BasicBlock *S = splitCriticalEdges(
P,
B))
3272 DeadBlocks.insert(
P = S);
3278 if (!DeadBlocks.count(
P))
3280 for (PHINode &Phi :
B->phis()) {
3283 MD->invalidateCachedPointerInfo(&Phi);
3302bool GVNPass::processFoldableCondBr(CondBrInst *BI) {
3313 if (DeadBlocks.count(DeadRoot))
3317 DeadRoot = splitCriticalEdges(BI->getParent(), DeadRoot);
3319 addDeadBlock(DeadRoot);
3327void GVNPass::assignValNumForDeadCode() {
3328 for (BasicBlock *BB : DeadBlocks) {
3329 for (Instruction &Inst : *BB) {
3330 unsigned ValNum = VN.lookupOrAdd(&Inst);
3331 LeaderTable.insert(ValNum, &Inst, BB);
3342 bool ScalarPRE =
true)
3344 .setMemDep(MemDepAnalysis)
3345 .setMemorySSA(MemSSAAnalysis)
3346 .setScalarPRE(ScalarPRE)) {
3355 if (Impl.isMemorySSAEnabled() && !MSSAWP)
3358 return Impl.runImpl(
3363 Impl.isMemDepEnabled()
3368 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
3376 if (Impl.isMemDepEnabled())
3385 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 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 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 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.
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< 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, GsymDataExtractor &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
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]
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.
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.
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.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
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
Return the entry for the specified key, or a default constructed value if no such entry exists.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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 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 isScalarPREEnabled() 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.
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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)
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.
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.
An efficient, type-erasing, non-owning reference to a callable.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
GVNLegacyPass(bool MemDepAnalysis=GVNEnableMemDep, bool MemSSAAnalysis=GVNEnableMemorySSA, bool ScalarPRE=true)
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.
m_Intrinsic_Ty< Opnd0, Opnd1, Opnd2 >::Ty m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
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))
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_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
NodeAddr< NodeBase * > Node
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 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)
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.
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()
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...
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.
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.