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(
"The number of memory accesses to scan in a block in reaching "
123 "memory values analysis (default = 100)"));
127 cl::desc(
"Max number of dependences to attempt Load PRE (default = 100)"));
132 cl::desc(
"Max number of blocks we're willing to speculate on (and recurse "
133 "into) when deducing if a value is fully available or not in GVN "
138 cl::desc(
"Max number of visited instructions when trying to find "
139 "dominating value of select dependency (default = 100)"));
143 cl::desc(
"Max number of instructions to scan in each basic block in GVN "
159 if (
Opcode != Other.Opcode)
167 if ((!
Attrs.isEmpty() || !Other.Attrs.isEmpty()) &&
168 !
Attrs.intersectWith(
Ty->getContext(), Other.Attrs).has_value())
302 Res.
AV = std::move(
AV);
318 return AV.MaterializeAdjustedValue(Load,
BB->getTerminator());
329 E.Opcode =
I->getOpcode();
334 E.VarArgs.push_back(
lookupOrAdd(GCR->getOperand(0)));
335 E.VarArgs.push_back(
lookupOrAdd(GCR->getBasePtr()));
336 E.VarArgs.push_back(
lookupOrAdd(GCR->getDerivedPtr()));
338 for (
Use &
Op :
I->operands())
341 if (
I->isCommutative()) {
346 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
347 if (
E.VarArgs[0] >
E.VarArgs[1])
349 E.Commutative =
true;
355 if (
E.VarArgs[0] >
E.VarArgs[1]) {
360 E.Commutative =
true;
362 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
364 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
365 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
367 E.Attrs = CB->getAttributes();
373GVNPass::Expression GVNPass::ValueTable::createCmpExpr(
375 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
376 "Not a comparison!");
379 E.VarArgs.push_back(lookupOrAdd(
LHS));
380 E.VarArgs.push_back(lookupOrAdd(
RHS));
383 if (
E.VarArgs[0] >
E.VarArgs[1]) {
387 E.Opcode = (Opcode << 8) | Predicate;
388 E.Commutative =
true;
393GVNPass::ValueTable::createExtractvalueExpr(ExtractValueInst *EI) {
394 assert(EI &&
"Not an ExtractValueInst?");
405 E.VarArgs.push_back(lookupOrAdd(WO->
getLHS()));
406 E.VarArgs.push_back(lookupOrAdd(WO->
getRHS()));
414 E.VarArgs.push_back(lookupOrAdd(
Op));
421GVNPass::Expression GVNPass::ValueTable::createGEPExpr(GetElementPtrInst *
GEP) {
423 Type *PtrTy =
GEP->getType()->getScalarType();
424 const DataLayout &
DL =
GEP->getDataLayout();
425 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
426 SmallMapVector<Value *, APInt, 4> VariableOffsets;
428 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
432 E.Opcode =
GEP->getOpcode();
434 E.VarArgs.push_back(lookupOrAdd(
GEP->getPointerOperand()));
435 for (
const auto &[V, Scale] : VariableOffsets) {
436 E.VarArgs.push_back(lookupOrAdd(V));
437 E.VarArgs.push_back(lookupOrAdd(ConstantInt::get(
Context, Scale)));
439 if (!ConstantOffset.isZero())
441 lookupOrAdd(ConstantInt::get(
Context, ConstantOffset)));
445 E.Opcode =
GEP->getOpcode();
446 E.Ty =
GEP->getSourceElementType();
447 for (Use &
Op :
GEP->operands())
448 E.VarArgs.push_back(lookupOrAdd(
Op));
457GVNPass::ValueTable::ValueTable() =
default;
458GVNPass::ValueTable::ValueTable(
const ValueTable &) =
default;
459GVNPass::ValueTable::ValueTable(
ValueTable &&) =
default;
460GVNPass::ValueTable::~ValueTable() =
default;
466 ValueNumbering.
insert(std::make_pair(V, Num));
468 NumberingPhi[Num] = PN;
478 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
479 assert(MSSA->getMemoryAccess(
I) &&
"Instruction does not access memory");
480 MemoryAccess *MA = MSSA->getSkipSelfWalker()->getClobberingMemoryAccess(
I);
481 Exp.VarArgs.push_back(lookupOrAdd(MA));
492 if (
C->getFunction()->isPresplitCoroutine()) {
493 ValueNumbering[
C] = NextValueNumber;
494 return NextValueNumber++;
500 if (
C->isConvergent()) {
501 ValueNumbering[
C] = NextValueNumber;
502 return NextValueNumber++;
505 if (AA->doesNotAccessMemory(
C)) {
507 uint32_t
E = assignExpNewValueNum(Exp).first;
508 ValueNumbering[
C] =
E;
512 if (MD && AA->onlyReadsMemory(
C)) {
514 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
516 ValueNumbering[
C] =
E;
520 MemDepResult LocalDep = MD->getDependency(
C);
523 ValueNumbering[
C] = NextValueNumber;
524 return NextValueNumber++;
527 if (LocalDep.
isDef()) {
532 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
533 ValueNumbering[
C] = NextValueNumber;
534 return NextValueNumber++;
537 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
538 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
539 uint32_t LocalDepCallVN = lookupOrAdd(LocalDepCall->
getArgOperand(
I));
540 if (CVN != LocalDepCallVN) {
541 ValueNumbering[
C] = NextValueNumber;
542 return NextValueNumber++;
546 uint32_t
V = lookupOrAdd(LocalDepCall);
547 ValueNumbering[
C] =
V;
553 MD->getNonLocalCallDependency(
C);
555 CallInst *CDep =
nullptr;
559 for (
const NonLocalDepEntry &
I : Deps) {
560 if (
I.getResult().isNonLocal())
565 if (!
I.getResult().isDef() || CDep !=
nullptr) {
572 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
573 CDep = NonLocalDepCall;
582 ValueNumbering[
C] = NextValueNumber;
583 return NextValueNumber++;
587 ValueNumbering[
C] = NextValueNumber;
588 return NextValueNumber++;
590 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
591 uint32_t CVN = lookupOrAdd(
C->getArgOperand(
I));
594 ValueNumbering[
C] = NextValueNumber;
595 return NextValueNumber++;
599 uint32_t
V = lookupOrAdd(CDep);
600 ValueNumbering[
C] =
V;
604 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
606 addMemoryStateToExp(
C, Exp);
607 auto [
V,
_] = assignExpNewValueNum(Exp);
608 ValueNumbering[
C] =
V;
612 ValueNumbering[
C] = NextValueNumber;
613 return NextValueNumber++;
617uint32_t GVNPass::ValueTable::computeLoadStoreVN(Instruction *
I) {
618 if (!MSSA || !IsMSSAEnabled) {
619 ValueNumbering[
I] = NextValueNumber;
620 return NextValueNumber++;
624 Exp.Ty =
I->getType();
625 Exp.Opcode =
I->getOpcode();
626 for (Use &
Op :
I->operands())
627 Exp.VarArgs.push_back(lookupOrAdd(
Op));
628 addMemoryStateToExp(
I, Exp);
630 auto [
V,
_] = assignExpNewValueNum(Exp);
631 ValueNumbering[
I] =
V;
636bool GVNPass::ValueTable::exists(
Value *V)
const {
637 return ValueNumbering.contains(V);
649 auto VI = ValueNumbering.find(V);
650 if (VI != ValueNumbering.end())
655 ValueNumbering[V] = NextValueNumber;
658 return NextValueNumber++;
662 switch (
I->getOpcode()) {
663 case Instruction::Call:
665 case Instruction::FNeg:
666 case Instruction::Add:
667 case Instruction::FAdd:
668 case Instruction::Sub:
669 case Instruction::FSub:
670 case Instruction::Mul:
671 case Instruction::FMul:
672 case Instruction::UDiv:
673 case Instruction::SDiv:
674 case Instruction::FDiv:
675 case Instruction::URem:
676 case Instruction::SRem:
677 case Instruction::FRem:
678 case Instruction::Shl:
679 case Instruction::LShr:
680 case Instruction::AShr:
681 case Instruction::And:
682 case Instruction::Or:
683 case Instruction::Xor:
684 case Instruction::ICmp:
685 case Instruction::FCmp:
686 case Instruction::Trunc:
687 case Instruction::ZExt:
688 case Instruction::SExt:
689 case Instruction::FPToUI:
690 case Instruction::FPToSI:
691 case Instruction::UIToFP:
692 case Instruction::SIToFP:
693 case Instruction::FPTrunc:
694 case Instruction::FPExt:
695 case Instruction::PtrToInt:
696 case Instruction::PtrToAddr:
697 case Instruction::IntToPtr:
698 case Instruction::AddrSpaceCast:
699 case Instruction::BitCast:
700 case Instruction::Select:
701 case Instruction::Freeze:
702 case Instruction::ExtractElement:
703 case Instruction::InsertElement:
704 case Instruction::ShuffleVector:
705 case Instruction::InsertValue:
708 case Instruction::GetElementPtr:
711 case Instruction::ExtractValue:
714 case Instruction::PHI:
715 ValueNumbering[V] = NextValueNumber;
717 return NextValueNumber++;
718 case Instruction::Load:
719 case Instruction::Store:
720 return computeLoadStoreVN(
I);
722 ValueNumbering[V] = NextValueNumber;
723 return NextValueNumber++;
726 uint32_t E = assignExpNewValueNum(Exp).first;
727 ValueNumbering[V] = E;
734 auto VI = ValueNumbering.find(V);
736 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
739 return (VI != ValueNumbering.end()) ? VI->second : 0;
746uint32_t GVNPass::ValueTable::lookupOrAddCmp(
unsigned Opcode,
749 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
750 return assignExpNewValueNum(Exp).first;
758 return ExpressionNumbering.lookup(Exp);
763 ValueNumbering.clear();
764 ExpressionNumbering.clear();
765 NumberingPhi.clear();
767 PhiTranslateTable.clear();
776 uint32_t Num = ValueNumbering.lookup(V);
777 ValueNumbering.erase(V);
780 NumberingPhi.erase(Num);
782 NumberingBB.erase(Num);
787void GVNPass::ValueTable::verifyRemoved(
const Value *V)
const {
788 assert(!ValueNumbering.contains(V) &&
789 "Inst still occurs in value numbering map!");
798 const auto &[It, Inserted] = NumToLeaders.try_emplace(
N, V, BB,
nullptr);
801 auto *NewSlot = TableAllocator.Allocate<LeaderListNode>();
802 new (NewSlot) LeaderListNode(V, BB, It->second.Next);
803 It->second.Next = NewSlot;
811 auto It = NumToLeaders.find(
N);
812 if (It == NumToLeaders.end())
815 LeaderListNode *Prev =
nullptr;
816 LeaderListNode *Curr = &It->second;
818 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
828 Prev->Next = Curr->Next;
829 Curr->~LeaderListNode();
830 TableAllocator.Deallocate<LeaderListNode>(Curr);
835 NumToLeaders.erase(It);
838 LeaderListNode *
Next = Curr->Next;
839 Curr->Entry.Val = std::move(
Next->Entry.Val);
840 Curr->Entry.BB =
Next->Entry.BB;
841 Curr->Next =
Next->Next;
842 Next->~LeaderListNode();
843 TableAllocator.Deallocate<LeaderListNode>(
Next);
865 return Options.AllowLoadPRESplitBackedge.value_or(
892 "On-demand computation of MemSSA implies that MemDep is disabled!");
896 bool Changed = runImpl(
F, AC, DT, TLI, AA, MemDep, LI, &ORE,
897 MSSA ? &MSSA->getMSSA() :
nullptr);
912 OS, MapClassName2PassName);
915 if (Options.AllowScalarPRE != std::nullopt)
916 OS << (*Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
917 if (Options.AllowLoadPRE != std::nullopt)
918 OS << (*Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
919 if (Options.AllowLoadPRESplitBackedge != std::nullopt)
920 OS << (*Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
921 <<
"split-backedge-load-pre;";
922 if (Options.AllowMemDep != std::nullopt)
923 OS << (*Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
924 if (Options.AllowMemorySSA != std::nullopt)
925 OS << (*Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
932 removeInstruction(
I);
935#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
938 for (
const auto &[Num, Exp] : Map) {
939 errs() << Num <<
"\n";
970 std::optional<BasicBlock *> UnavailableBB;
974 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
982 while (!Worklist.
empty()) {
986 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
994 UnavailableBB = CurrBB;
1005 ++NumNewNewSpeculativelyAvailableBBs;
1011 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1013 UnavailableBB = CurrBB;
1019 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1025#if LLVM_ENABLE_STATS
1026 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1027 NumNewNewSpeculativelyAvailableBBs);
1032 auto MarkAsFixpointAndEnqueueSuccessors =
1034 auto It = FullyAvailableBlocks.
find(BB);
1035 if (It == FullyAvailableBlocks.
end())
1042 State = FixpointState;
1045 "Found a speculatively available successor leftover?");
1053 if (UnavailableBB) {
1060 while (!Worklist.
empty())
1061 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1069 while (!Worklist.
empty())
1070 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1074 "Must have fixed all the new speculatively available blocks.");
1077 return !UnavailableBB;
1086 if (V.AV.Val == OldValue)
1087 V.AV.Val = NewValue;
1088 if (V.AV.isSelectValue()) {
1089 if (V.AV.V1 == OldValue)
1091 if (V.AV.V2 == OldValue)
1106 if (ValuesPerBlock.
size() == 1 &&
1108 Load->getParent())) {
1109 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1110 "Dead BB dominate this block");
1111 return ValuesPerBlock[0].MaterializeAdjustedValue(Load);
1117 SSAUpdate.
Initialize(Load->getType(), Load->getName());
1122 if (AV.AV.isUndefValue())
1132 if (BB == Load->getParent() &&
1133 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() == Load) ||
1134 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() == Load)))
1147 Type *LoadTy = Load->getType();
1151 if (Res->
getType() != LoadTy) {
1166 Load->getFunction());
1177 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1179 {LLVMContext::MD_dereferenceable,
1180 LLVMContext::MD_dereferenceable_or_null,
1181 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group,
1182 LLVMContext::MD_alias_scope, LLVMContext::MD_noalias});
1198 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1206 assert(Res &&
"failed to materialize?");
1212 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1229 Value *PtrOp = Load->getPointerOperand();
1235 for (
auto *U : PtrOp->
users()) {
1238 if (
I->getFunction() == Load->getFunction() && DT->
dominates(
I, Load)) {
1256 for (
auto *U : PtrOp->
users()) {
1259 if (
I->getFunction() == Load->getFunction() &&
1267 OtherAccess =
nullptr;
1286 using namespace ore;
1289 R <<
"load of type " << NV(
"Type", Load->getType()) <<
" not eliminated"
1294 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1296 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1310 for (
auto *Inst = BB == FromBB ? From : BB->
getTerminator();
1318 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1319 SI->getValueOperand()->getType() == LoadTy)
1320 return SI->getValueOperand();
1324 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1330std::optional<AvailableValue>
1331GVNPass::AnalyzeSelectAvailability(LoadInst *Load,
Value *
Cond,
Value *TrueAddr,
1332 Value *FalseAddr, Instruction *From) {
1334 "Invalid address type of true side of select dependency");
1336 "Invalid address type of false side of select dependency");
1344 return std::nullopt;
1348 return std::nullopt;
1352std::optional<AvailableValue>
1353GVNPass::AnalyzeLoadAvailability(LoadInst *Load,
const ReachingMemVal &Dep,
1355 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1356 assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) &&
1357 "expected a local dependence");
1361 const DataLayout &
DL =
Load->getDataLayout();
1362 if (Dep.Kind == DepKind::Clobber) {
1368 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1384 if (DepLoad != Load &&
Address &&
1385 Load->isAtomic() <= DepLoad->isAtomic()) {
1392 DepLoad->getFunction())) {
1393 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1395 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1401 DepLoad->getFunction()) ||
1428 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1432 return std::nullopt;
1434 assert(Dep.Kind == DepKind::Def &&
"follows from above");
1441 if (Constant *InitVal =
1451 return std::nullopt;
1454 if (S->isAtomic() <
Load->isAtomic())
1455 return std::nullopt;
1466 return std::nullopt;
1469 if (
LD->isAtomic() <
Load->isAtomic())
1470 return std::nullopt;
1479 assert(Sel->getType() ==
Load->getPointerOperandType());
1480 if (
auto AV = AnalyzeSelectAvailability(Load, Sel->getCondition(),
1481 Sel->getTrueValue(),
1482 Sel->getFalseValue(), DepInst))
1484 return std::nullopt;
1491 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1492 return std::nullopt;
1495void GVNPass::AnalyzeLoadAvailability(LoadInst *Load,
1496 SmallVectorImpl<ReachingMemVal> &Deps,
1497 AvailValInBlkVect &ValuesPerBlock,
1498 UnavailBlkVect &UnavailableBlocks) {
1503 for (
const auto &Dep : Deps) {
1506 if (DeadBlocks.count(DepBB)) {
1513 if (Dep.Kind == DepKind::Other) {
1514 UnavailableBlocks.push_back(DepBB);
1521 if (Dep.Kind == DepKind::Select) {
1522 if (
auto AV = AnalyzeSelectAvailability(
1523 Load,
const_cast<Value *
>(Dep.SelCond),
1524 const_cast<Value *
>(Dep.SelTrueAddr),
1526 ValuesPerBlock.push_back(
1529 UnavailableBlocks.push_back(DepBB);
1538 AnalyzeLoadAvailability(Load, Dep,
const_cast<Value *
>(Dep.Addr))) {
1542 ValuesPerBlock.push_back(
1545 UnavailableBlocks.push_back(DepBB);
1549 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1550 "post condition violation");
1572LoadInst *GVNPass::findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
1576 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1578 auto *SuccBB =
Term->getSuccessor(0);
1579 if (SuccBB == LoadBB)
1580 SuccBB =
Term->getSuccessor(1);
1581 if (!SuccBB->getSinglePredecessor())
1585 for (Instruction &Inst : *SuccBB) {
1586 if (Inst.isDebugOrPseudoInst())
1588 if (--NumInsts == 0)
1591 if (!Inst.isIdenticalTo(Load))
1594 bool HasLocalDep =
true;
1596 MemDepResult Dep = MD->getDependency(&Inst);
1599 auto *MSSA = MSSAU->getMemorySSA();
1601 if (
auto *MA = MSSA->getMemoryAccess(&Inst); MA &&
isa<MemoryUse>(MA)) {
1602 auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
1603 HasLocalDep = Clobber->getBlock() == SuccBB;
1611 if (!HasLocalDep && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1622void GVNPass::eliminatePartiallyRedundantLoad(
1623 LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
1624 MapVector<BasicBlock *, Value *> &AvailableLoads,
1625 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad) {
1626 for (
const auto &AvailableLoad : AvailableLoads) {
1627 BasicBlock *UnavailableBlock = AvailableLoad.first;
1628 Value *LoadPtr = AvailableLoad.second;
1630 auto *NewLoad =
new LoadInst(
1631 Load->getType(), LoadPtr,
Load->getName() +
".pre",
Load->isVolatile(),
1632 Load->getAlign(),
Load->getOrdering(),
Load->getSyncScopeID(),
1634 NewLoad->setDebugLoc(
Load->getDebugLoc());
1636 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1639 MSSAU->insertDef(NewDef,
true);
1645 AAMDNodes Tags =
Load->getAAMetadata();
1647 NewLoad->setAAMetadata(Tags);
1649 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1650 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1651 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1652 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1653 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1654 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1655 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1656 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
1658 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1659 if (LI->getLoopFor(
Load->getParent()) == LI->getLoopFor(UnavailableBlock))
1660 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1669 ValuesPerBlock.push_back(
1672 MD->invalidateCachedPointerInfo(LoadPtr);
1677 if (CriticalEdgePredAndLoad) {
1678 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1679 if (It != CriticalEdgePredAndLoad->
end()) {
1680 ++NumPRELoadMoved2CEPred;
1681 ICF->insertInstructionTo(NewLoad, UnavailableBlock);
1682 LoadInst *OldLoad = It->second;
1686 if (uint32_t ValNo = VN.lookup(OldLoad,
false))
1687 LeaderTable.erase(ValNo, OldLoad, OldLoad->
getParent());
1688 removeInstruction(OldLoad);
1696 ICF->removeUsersOf(Load);
1697 Load->replaceAllUsesWith(V);
1701 I->setDebugLoc(
Load->getDebugLoc());
1702 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
1703 MD->invalidateCachedPointerInfo(V);
1705 return OptimizationRemark(
DEBUG_TYPE,
"LoadPRE", Load)
1706 <<
"load eliminated by PRE";
1711bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
1712 UnavailBlkVect &UnavailableBlocks) {
1721 SmallPtrSet<BasicBlock *, 4> Blockers(
llvm::from_range, UnavailableBlocks);
1743 bool MustEnsureSafetyOfSpeculativeExecution =
1744 ICF->isDominatedByICFIFromSameBlock(Load);
1748 if (TmpBB == LoadBB)
1750 if (Blockers.count(TmpBB))
1762 MustEnsureSafetyOfSpeculativeExecution =
1763 MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
1771 MapVector<BasicBlock *, Value *> PredLoads;
1772 DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
1773 for (
const AvailableValueInBlock &AV : ValuesPerBlock)
1775 for (BasicBlock *UnavailableBB : UnavailableBlocks)
1783 MapVector<BasicBlock *, LoadInst *> CriticalEdgePredAndLoad;
1789 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
1790 << Pred->
getName() <<
"': " << *Load <<
'\n');
1801 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
1802 << Pred->
getName() <<
"': " << *Load <<
'\n');
1808 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
1809 << Pred->
getName() <<
"': " << *Load <<
'\n');
1815 if (DT->dominates(LoadBB, Pred)) {
1818 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
1819 << Pred->
getName() <<
"': " << *Load <<
'\n');
1823 if (LoadInst *LI = findLoadToHoistIntoPred(Pred, LoadBB, Load))
1824 CriticalEdgePredAndLoad[Pred] = LI;
1829 PredLoads[Pred] =
nullptr;
1834 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
1835 unsigned NumUnavailablePreds = NumInsertPreds +
1836 CriticalEdgePredAndLoad.
size();
1837 assert(NumUnavailablePreds != 0 &&
1838 "Fully available value should already be eliminated!");
1839 (void)NumUnavailablePreds;
1845 if (NumInsertPreds > 1)
1850 if (MustEnsureSafetyOfSpeculativeExecution) {
1851 if (CriticalEdgePredSplit.
size())
1855 for (
auto &PL : PredLoads)
1859 for (
auto &CEP : CriticalEdgePredAndLoad)
1866 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
1867 BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
1868 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
1869 PredLoads[NewPred] =
nullptr;
1870 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
1871 << LoadBB->
getName() <<
'\n');
1874 for (
auto &CEP : CriticalEdgePredAndLoad)
1875 PredLoads[CEP.first] =
nullptr;
1878 bool CanDoPRE =
true;
1879 const DataLayout &
DL =
Load->getDataLayout();
1880 SmallVector<Instruction*, 8> NewInsts;
1881 for (
auto &PredLoad : PredLoads) {
1882 BasicBlock *UnavailablePred = PredLoad.first;
1892 Value *LoadPtr =
Load->getPointerOperand();
1894 while (Cur != LoadBB) {
1907 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
1914 << *
Load->getPointerOperand() <<
"\n");
1919 PredLoad.second = LoadPtr;
1923 while (!NewInsts.
empty()) {
1933 return !CriticalEdgePredSplit.empty();
1939 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING PRE LOAD: " << *Load <<
'\n');
1941 <<
" INSTS: " << *NewInsts.
back()
1945 for (Instruction *
I : NewInsts) {
1949 I->updateLocationAfterHoist();
1958 eliminatePartiallyRedundantLoad(Load, ValuesPerBlock, PredLoads,
1959 &CriticalEdgePredAndLoad);
1964bool GVNPass::performLoopLoadPRE(LoadInst *Load,
1965 AvailValInBlkVect &ValuesPerBlock,
1966 UnavailBlkVect &UnavailableBlocks) {
1967 const Loop *
L = LI->getLoopFor(
Load->getParent());
1969 if (!L ||
L->getHeader() !=
Load->getParent())
1974 if (!Preheader || !Latch)
1977 Value *LoadPtr =
Load->getPointerOperand();
1979 if (!
L->isLoopInvariant(LoadPtr))
1985 if (ICF->isDominatedByICFIFromSameBlock(Load))
1989 for (
auto *Blocker : UnavailableBlocks) {
1991 if (!
L->contains(Blocker))
2003 if (L != LI->getLoopFor(Blocker))
2011 if (DT->dominates(Blocker, Latch))
2015 if (Blocker->getTerminator()->mayWriteToMemory())
2018 LoopBlock = Blocker;
2030 MapVector<BasicBlock *, Value *> AvailableLoads;
2031 AvailableLoads[LoopBlock] = LoadPtr;
2032 AvailableLoads[Preheader] = LoadPtr;
2034 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING PRE LOOP LOAD: " << *Load <<
'\n');
2035 eliminatePartiallyRedundantLoad(Load, ValuesPerBlock, AvailableLoads,
2043 using namespace ore;
2047 <<
"load of type " << NV(
"Type", Load->getType()) <<
" eliminated"
2048 << setExtraArgs() <<
" in favor of "
2055bool GVNPass::processNonLocalLoad(LoadInst *Load) {
2057 if (
Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2058 Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2063 MD->getNonLocalPointerDependency(Load, Deps);
2068 unsigned NumDeps = Deps.size();
2075 for (
const NonLocalDepResult &Dep : Deps) {
2076 const auto &
R = Dep.getResult();
2077 SelectAddr SelAddr = Dep.getAddress();
2083 ReachingMemVal::getSelect(BB,
Cond, Addrs.first, Addrs.second));
2095 return processNonLocalLoad(Load, MemVals);
2098bool GVNPass::processNonLocalLoad(LoadInst *Load,
2099 SmallVectorImpl<ReachingMemVal> &Deps) {
2102 if (Deps.
size() == 1 && Deps[0].Kind == DepKind::Other) {
2104 dbgs() <<
" has unknown dependencies\n";);
2112 if (GetElementPtrInst *
GEP =
2114 for (Use &U :
GEP->indices())
2121 AvailValInBlkVect ValuesPerBlock;
2122 UnavailBlkVect UnavailableBlocks;
2123 AnalyzeLoadAvailability(Load, Deps, ValuesPerBlock, UnavailableBlocks);
2127 if (ValuesPerBlock.empty())
2135 if (UnavailableBlocks.empty()) {
2136 LLVM_DEBUG(
dbgs() <<
"GVN REMOVING NONLOCAL LOAD: " << *Load <<
'\n');
2141 ICF->removeUsersOf(Load);
2142 Load->replaceAllUsesWith(V);
2150 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2151 I->setDebugLoc(
Load->getDebugLoc());
2152 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2153 MD->invalidateCachedPointerInfo(V);
2166 if (performLoopLoadPRE(Load, ValuesPerBlock, UnavailableBlocks) ||
2167 PerformLoadPRE(Load, ValuesPerBlock, UnavailableBlocks))
2173bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
2177 if (
Cond->isZero()) {
2187 const MemoryUseOrDef *FirstNonDom =
nullptr;
2189 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2196 for (
const auto &Acc : *AL) {
2198 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2199 FirstNonDom = Current;
2206 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2208 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2209 : MSSAU->createMemoryAccessInBB(
2231 return propagateEquality(V, True, IntrinsicI);
2236 I->replaceAllUsesWith(Repl);
2243 Value *PointerOperand = L->getPointerOperand()->stripPointerCasts();
2254 PointerUsesQueue.
push_back(PointerOperand);
2259 while (!PointerUsesQueue.
empty()) {
2262 "Null or GlobalValue should not be inserted");
2266 if (!
I ||
I == L || !DT.
dominates(
I, MostDominatingInstruction))
2281 if (
I->hasMetadata(LLVMContext::MD_invariant_group) &&
2283 MostDominatingInstruction =
I;
2287 return MostDominatingInstruction != L ? MostDominatingInstruction :
nullptr;
2293static std::optional<MemoryLocation>
2300 switch (
II->getIntrinsicID()) {
2301 case Intrinsic::masked_load:
2303 case Intrinsic::masked_store:
2306 return std::nullopt;
2313 return std::nullopt;
2317 return std::nullopt;
2323std::optional<GVNPass::ReachingMemVal> GVNPass::scanMemoryAccessesUsers(
2324 const MemoryLocation &Loc,
bool IsInvariantLoad, BasicBlock *BB,
2325 const SmallVectorImpl<MemoryAccess *> &ClobbersList,
MemorySSA &MSSA,
2326 BatchAAResults &AA, LoadInst *L) {
2329 auto UpdateChoice = [&](std::optional<ReachingMemVal> &Choice,
2333 Choice = ReachingMemVal::getClobber(Loc.
Ptr, Candidate, AR.getOffset());
2335 Choice = ReachingMemVal::getDef(Loc.
Ptr, Candidate);
2343 Choice->Kind = DepKind::Clobber;
2344 Choice->Offset = AR.getOffset();
2346 Choice->Kind = DepKind::Def;
2347 Choice->Offset = -1;
2350 Choice->Inst = Candidate;
2351 Choice->Block = Candidate->getParent();
2354 std::optional<ReachingMemVal> ReachingVal;
2355 for (MemoryAccess *MA : ClobbersList) {
2357 for (User *U : MA->
users()) {
2359 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2362 if (!UseOrDef || UseOrDef->getBlock() != BB)
2371 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2385 UpdateChoice(ReachingVal, AR, MemI);
2397std::optional<GVNPass::ReachingMemVal> GVNPass::accessMayModifyLocation(
2398 MemoryAccess *ClobberMA,
const MemoryLocation &Loc,
bool IsInvariantLoad,
2399 BasicBlock *BB,
MemorySSA &MSSA, BatchAAResults &AA) {
2407 if (
Alloc->getParent() == BB)
2408 return ReachingMemVal::getDef(Loc.
Ptr,
const_cast<AllocaInst *
>(
Alloc));
2409 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2413 if (IsInvariantLoad || AA.pointsToConstantMemory(Loc))
2414 return std::nullopt;
2418 return L->getOrdering();
2425 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2427 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2438 return std::nullopt;
2439 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2444 return std::nullopt;
2449 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2454 "Must be the superset/partial overlap case with positive offset");
2455 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI, AR.
getOffset());
2460 return std::nullopt;
2461 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2463 if (AA.isMustAlias(IIObjLoc, Loc))
2464 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2465 return std::nullopt;
2473 if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.
Ptr))
2474 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2480 return std::nullopt;
2484 ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc);
2488 return std::nullopt;
2492 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2498bool GVNPass::collectPredecessors(BasicBlock *BB,
const PHITransAddr &Addr,
2499 MemoryAccess *ClobberMA,
2500 DependencyBlockSet &Blocks,
2501 SmallVectorImpl<BasicBlock *> &Worklist) {
2511 if (!DT->isReachableFromEntry(Pred))
2515 if (
llvm::any_of(Preds, [Pred](
const auto &
P) {
return P.first == Pred; }))
2518 PHITransAddr TransAddr = Addr;
2522 auto It = Blocks.find(Pred);
2523 if (It != Blocks.end()) {
2527 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2534 Pred, DependencyBlockInfo(TransAddr,
2535 MPhi ? MPhi->getIncomingValueForBlock(Pred)
2542 for (
auto &
P : Preds) {
2543 [[maybe_unused]]
auto It =
2544 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2556void GVNPass::collectClobberList(SmallVectorImpl<MemoryAccess *> &Clobbers,
2558 const DependencyBlockInfo &StartInfo,
2559 const DependencyBlockSet &Blocks,
2561 MemoryAccess *MA = StartInfo.InitialClobberMA;
2562 MemoryAccess *LastMA = StartInfo.ClobberMA;
2565 while (MA != LastMA) {
2579 BB = DT->getNode(BB)->getIDom()->getBlock();
2583 auto It = Blocks.find(BB);
2584 if (It == Blocks.end())
2587 MA = It->second.InitialClobberMA;
2588 LastMA = It->second.ClobberMA;
2589 if (MA == Clobbers.
back())
2606bool GVNPass::findReachingValuesForLoad(LoadInst *L,
2607 SmallVectorImpl<ReachingMemVal> &
Values,
2609 EarliestEscapeAnalysis EA(*DT, LI);
2610 BatchAAResults AA(AAR, &EA);
2612 bool IsInvariantLoad =
L->hasMetadata(LLVMContext::MD_invariant_load);
2618 if (
L->hasMetadata(LLVMContext::MD_invariant_group)) {
2631 if (
auto RMV = scanMemoryAccessesUsers(
2632 Loc, IsInvariantLoad, StartBlock,
2634 Values.emplace_back(*RMV);
2644 if (
auto RMV = accessMayModifyLocation(ClobberMA, Loc, IsInvariantLoad,
2645 StartBlock, MSSA, AA)) {
2646 Values.emplace_back(*RMV);
2653 }
while (ClobberMA->
getBlock() == StartBlock);
2656 if (
L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2657 L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2666 DependencyBlockSet Blocks;
2667 SmallVector<BasicBlock *, 16> InitialWorklist;
2668 const DataLayout &
DL =
L->getModule()->getDataLayout();
2669 if (!collectPredecessors(StartBlock,
2670 PHITransAddr(
L->getPointerOperand(),
DL, AC),
2671 ClobberMA, Blocks, InitialWorklist))
2675 auto Worklist = InitialWorklist;
2676 while (!Worklist.
empty()) {
2678 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
2681 if (!
Info.Addr.getAddr())
2689 if (
auto RMV = accessMayModifyLocation(
2691 IsInvariantLoad, BB, MSSA, AA)) {
2696 "LiveOnEntry aliases everything");
2712 if (BB == StartBlock &&
Info.Addr.getAddr() !=
L->getPointerOperand()) {
2713 Info.ForceUnknown =
true;
2716 if (BB != StartBlock &&
2717 !collectPredecessors(BB,
Info.Addr,
Info.ClobberMA, Blocks, Worklist))
2718 Info.ForceUnknown =
true;
2728 Worklist = InitialWorklist;
2729 for (BasicBlock *BB : Worklist) {
2730 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
2731 Info.Visited =
true;
2735 while (!Worklist.empty()) {
2736 auto *BB = Worklist.pop_back_val();
2737 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
2741 if (!
Info.Addr.getAddr()) {
2742 Values.push_back(ReachingMemVal::getUnknown(BB,
nullptr));
2747 collectClobberList(Clobbers, BB, Info, Blocks, MSSA);
2750 IsInvariantLoad, BB, Clobbers, MSSA, AA)) {
2762 if (
Info.ForceUnknown) {
2763 Values.push_back(ReachingMemVal::getUnknown(BB,
Info.Addr.getAddr()));
2769 auto It = Blocks.find(Pred);
2770 if (It == Blocks.end())
2772 DependencyBlockInfo &PredInfo = It->second;
2773 if (PredInfo.Visited)
2775 PredInfo.Visited =
true;
2776 Worklist.push_back(Pred);
2785bool GVNPass::processLoad(LoadInst *L) {
2790 if (!
L->isUnordered())
2793 if (
L->getType()->isTokenLikeTy())
2796 if (
L->use_empty()) {
2801 ReachingMemVal MemVal = ReachingMemVal::getUnknown(
nullptr,
nullptr);
2804 MemDepResult Dep = MD->getDependency(L);
2808 return processNonLocalLoad(L);
2812 MemVal = ReachingMemVal::getDef(
L->getPointerOperand(), Dep.
getInst());
2815 ReachingMemVal::getClobber(
L->getPointerOperand(), Dep.
getInst());
2818 if (!findReachingValuesForLoad(L, MemVals, *MSSAU->getMemorySSA(), *AA))
2820 assert(MemVals.
size() &&
"Expected at least an unknown value");
2821 if (MemVals.
size() > 1 || MemVals[0].Block !=
L->getParent())
2822 return processNonLocalLoad(L, MemVals);
2824 MemVal = MemVals[0];
2827 if (MemVal.Kind == DepKind::Other) {
2831 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
2832 dbgs() <<
" has unknown dependence\n";);
2836 auto AV = AnalyzeLoadAvailability(L, MemVal,
L->getPointerOperand());
2840 Value *AvailableValue = AV->MaterializeAdjustedValue(L, L);
2843 ICF->removeUsersOf(L);
2844 L->replaceAllUsesWith(AvailableValue);
2846 MSSAU->removeMemoryAccess(L);
2853 MD->invalidateCachedPointerInfo(AvailableValue);
2859bool GVNPass::processMaskedLoad(IntrinsicInst *
I) {
2862 MemDepResult Dep = MD->getDependency(
I);
2868 Value *Passthrough =
I->getOperand(2);
2872 StoreVal->
getType() !=
I->getType())
2879 ICF->removeUsersOf(
I);
2880 I->replaceAllUsesWith(OpToForward);
2888std::pair<uint32_t, bool>
2889GVNPass::ValueTable::assignExpNewValueNum(
Expression &Exp) {
2890 uint32_t &
E = ExpressionNumbering[
Exp];
2891 bool CreateNewValNum = !
E;
2892 if (CreateNewValNum) {
2893 Expressions.push_back(Exp);
2894 if (ExprIdx.size() < NextValueNumber + 1)
2895 ExprIdx.resize(NextValueNumber * 2);
2896 E = NextValueNumber;
2897 ExprIdx[NextValueNumber++] = NextExprNumber++;
2899 return {
E, CreateNewValNum};
2904bool GVNPass::ValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
2907 GVN.LeaderTable.getLeaders(Num),
2915 auto FindRes = PhiTranslateTable.find({Num, Pred});
2916 if (FindRes != PhiTranslateTable.end())
2917 return FindRes->second;
2918 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, GVN);
2919 PhiTranslateTable.insert({{Num, Pred}, NewNum});
2930 auto Leaders = GVN.LeaderTable.getLeaders(Num);
2931 for (
const auto &Entry : Leaders) {
2933 if (
Call &&
Call->getParent() == PhiBlock)
2937 if (
AA->doesNotAccessMemory(
Call))
2940 if (!MD || !
AA->onlyReadsMemory(
Call))
2952 if (
D.getResult().isNonFuncLocal())
2960uint32_t GVNPass::ValueTable::phiTranslateImpl(
const BasicBlock *Pred,
2961 const BasicBlock *PhiBlock,
2965 if (PHINode *PN = NumberingPhi[Num]) {
2966 if (PN->getParent() != PhiBlock)
2968 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
2969 if (PN->getIncomingBlock(
I) != Pred)
2971 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
2977 if (BasicBlock *BB = NumberingBB[Num]) {
2978 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
2990 return lookupOrAdd(PredPhi->getBlock());
2996 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3002 if (!areAllValsInBB(Num, PhiBlock, GVN))
3005 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3009 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3013 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3014 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3015 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3017 Exp.VarArgs[
I] = phiTranslate(Pred, PhiBlock,
Exp.VarArgs[
I], GVN);
3020 if (
Exp.Commutative) {
3021 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3022 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3024 uint32_t Opcode =
Exp.Opcode >> 8;
3025 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3026 Exp.Opcode = (Opcode << 8) |
3032 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3033 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3034 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, GVN) ? NewNum : Num;
3042void GVNPass::ValueTable::eraseTranslateCacheEntry(
3045 PhiTranslateTable.erase({Num, Pred});
3054 auto Leaders = LeaderTable.getLeaders(Num);
3055 if (Leaders.empty())
3058 Value *Val =
nullptr;
3059 for (
const auto &Entry : Leaders) {
3060 if (DT->dominates(Entry.BB, BB)) {
3080 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
3081 assert((!Pred || Pred ==
E.getStart()) &&
3082 "No edge between these basic blocks!");
3083 return Pred !=
nullptr;
3086void GVNPass::assignBlockRPONumber(Function &
F) {
3087 BlockRPONumber.clear();
3088 uint32_t NextBlockNumber = 1;
3089 ReversePostOrderTraversal<Function *> RPOT(&
F);
3090 for (BasicBlock *BB : RPOT)
3091 BlockRPONumber[BB] = NextBlockNumber++;
3092 InvalidBlockRPONumbers =
false;
3100bool GVNPass::propagateEquality(
3102 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3107 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3114 for (
const auto *Node : DT->getNode(
I->getParent())->children())
3118 while (!Worklist.
empty()) {
3119 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3120 LHS = Item.first;
RHS = Item.second;
3134 const DataLayout &
DL =
3143 uint32_t LVN = VN.lookupOrAdd(
LHS);
3148 uint32_t RVN = VN.lookupOrAdd(
RHS);
3165 for (
const BasicBlock *BB : DominatedBlocks)
3166 LeaderTable.insert(LVN,
RHS, BB);
3173 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3176 unsigned NumReplacements;
3177 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3179 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3182 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3183 CanReplacePointersCallBack);
3185 if (NumReplacements > 0) {
3187 NumGVNEqProp += NumReplacements;
3190 MD->invalidateCachedPointerInfo(
LHS);
3207 bool IsKnownFalse = !IsKnownTrue;
3223 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3228 if (
Cmp->isEquivalence(IsKnownFalse))
3229 Worklist.
push_back(std::make_pair(Op0, Op1));
3233 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3237 uint32_t NextNum = VN.getNextUnusedValueNumber();
3238 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
3241 if (Num < NextNum) {
3242 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
3247 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3248 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
3249 !DT->dominates(
Edge->getEnd(),
Entry.BB))
3252 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3253 if (!DT->dominates(
Entry.BB, InstBB) &&
3254 !DT->dominates(InstBB,
Entry.BB))
3260 unsigned NumReplacements;
3261 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3266 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3267 Changed |= NumReplacements > 0;
3268 NumGVNEqProp += NumReplacements;
3271 MD->invalidateCachedPointerInfo(NotCmp);
3279 for (
const BasicBlock *BB : DominatedBlocks)
3280 LeaderTable.insert(Num, NotVal, BB);
3289 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3294 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3304bool GVNPass::processInstruction(Instruction *
I) {
3309 const DataLayout &
DL =
I->getDataLayout();
3312 if (!
I->use_empty()) {
3315 ICF->removeUsersOf(
I);
3316 I->replaceAllUsesWith(V);
3324 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3325 MD->invalidateCachedPointerInfo(V);
3332 return processAssumeIntrinsic(Assume);
3335 if (processLoad(Load))
3338 unsigned Num = VN.lookupOrAdd(Load);
3339 LeaderTable.insert(Num, Load,
Load->getParent());
3351 return processFoldableCondBr(BI);
3353 Value *BranchCond = BI->getCondition();
3357 if (TrueSucc == FalseSucc)
3364 BasicBlockEdge TrueE(Parent, TrueSucc);
3365 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3368 BasicBlockEdge FalseE(Parent, FalseSucc);
3369 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3376 Value *SwitchCond =
SI->getCondition();
3381 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
3383 ++SwitchEdges[Succ];
3385 for (
const auto &Case :
SI->cases()) {
3388 if (SwitchEdges.
lookup(Dst) == 1) {
3389 BasicBlockEdge
E(Parent, Dst);
3390 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3398 if (
I->getType()->isVoidTy())
3401 uint32_t NextNum = VN.getNextUnusedValueNumber();
3402 unsigned Num = VN.lookupOrAdd(
I);
3407 LeaderTable.insert(Num,
I,
I->getParent());
3414 const DataLayout &
DL =
I->getDataLayout();
3415 unsigned AS = PTA->getPointerAddressSpace();
3416 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3417 !
DL.hasUnstableRepresentation(AS)) {
3419 VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
3420 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3431 if (Num >= NextNum) {
3432 LeaderTable.insert(Num,
I,
I->getParent());
3438 Value *Repl = findLeader(
I->getParent(), Num);
3441 LeaderTable.insert(Num,
I,
I->getParent());
3454 MD->invalidateCachedPointerInfo(Repl);
3460bool GVNPass::runImpl(Function &
F, AssumptionCache &RunAC, DominatorTree &RunDT,
3461 const TargetLibraryInfo &RunTLI, AAResults &RunAA,
3462 MemoryDependenceResults *RunMD, LoopInfo &LI,
3463 OptimizationRemarkEmitter *RunORE,
MemorySSA *MSSA) {
3469 VN.setAliasAnalysis(&RunAA);
3471 ImplicitControlFlowTracking ImplicitCFT;
3480 InvalidBlockRPONumbers =
true;
3481 MemorySSAUpdater Updater(MSSA);
3482 MSSAU = MSSA ? &Updater :
nullptr;
3485 bool ShouldContinue =
true;
3487 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
3499 unsigned Iteration = 0;
3500 while (ShouldContinue) {
3503 ShouldContinue = iterateOnFunction(
F);
3511 assignValNumForDeadCode();
3512 bool PREChanged =
true;
3513 while (PREChanged) {
3514 PREChanged = performPRE(
F);
3524 cleanupGlobalSets();
3535bool GVNPass::processBlock(BasicBlock *BB) {
3536 if (DeadBlocks.count(BB))
3539 bool ChangedFunction =
false;
3545 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
3547 for (PHINode *PN : PHINodesToRemove) {
3548 removeInstruction(PN);
3551 ChangedFunction |= processInstruction(&Inst);
3552 return ChangedFunction;
3556bool GVNPass::performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
3557 BasicBlock *Curr,
unsigned int ValNo) {
3563 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3571 if (!VN.exists(
Op)) {
3576 VN.phiTranslate(Pred, Curr, VN.lookup(
Op), *
this);
3577 if (
Value *V = findLeader(Pred, TValNo)) {
3595 ICF->insertInstructionTo(Instr, Pred);
3597 unsigned Num = VN.lookupOrAdd(Instr);
3601 LeaderTable.insert(Num, Instr, Pred);
3605bool GVNPass::performScalarPRE(Instruction *CurInst) {
3631 if (CallB->isInlineAsm())
3635 uint32_t ValNo = VN.lookup(CurInst);
3643 unsigned NumWith = 0;
3644 unsigned NumWithout = 0;
3649 if (InvalidBlockRPONumbers)
3650 assignBlockRPONumber(*CurrentBlock->
getParent());
3656 if (!DT->isReachableFromEntry(
P)) {
3661 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
3662 "Invalid BlockRPONumber map.");
3663 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
3668 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, *
this);
3669 Value *PredV = findLeader(
P, TValNo);
3674 }
else if (PredV == CurInst) {
3686 if (NumWithout > 1 || NumWith == 0)
3694 if (NumWithout != 0) {
3700 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
3713 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
3717 PREInstr = CurInst->
clone();
3718 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
3721 verifyRemoved(PREInstr);
3730 assert(PREInstr !=
nullptr || NumWithout == 0);
3736 CurInst->
getName() +
".pre-phi");
3737 Phi->insertBefore(CurrentBlock->begin());
3738 for (
auto &[V, BB] : PredMap) {
3743 Phi->addIncoming(V, BB);
3745 Phi->addIncoming(PREInstr, PREPred);
3751 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
3752 LeaderTable.insert(ValNo, Phi, CurrentBlock);
3755 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
3756 MD->invalidateCachedPointerInfo(Phi);
3757 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
3760 removeInstruction(CurInst);
3767bool GVNPass::performPRE(Function &
F) {
3769 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
3771 if (CurrentBlock == &
F.getEntryBlock())
3775 if (CurrentBlock->isEHPad())
3779 BE = CurrentBlock->end();
3782 Changed |= performScalarPRE(CurInst);
3786 if (splitCriticalEdges())
3794BasicBlock *GVNPass::splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ) {
3799 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
3802 MD->invalidateCachedPredecessors();
3803 InvalidBlockRPONumbers =
true;
3810bool GVNPass::splitCriticalEdges() {
3811 if (ToSplit.empty())
3816 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
3818 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
3820 }
while (!ToSplit.empty());
3823 MD->invalidateCachedPredecessors();
3824 InvalidBlockRPONumbers =
true;
3830bool GVNPass::iterateOnFunction(Function &
F) {
3831 cleanupGlobalSets();
3838 ReversePostOrderTraversal<Function *> RPOT(&
F);
3840 for (BasicBlock *BB : RPOT)
3846void GVNPass::cleanupGlobalSets() {
3848 LeaderTable.clear();
3849 BlockRPONumber.clear();
3851 InvalidBlockRPONumbers =
true;
3854void GVNPass::removeInstruction(Instruction *
I) {
3856 if (MD) MD->removeInstruction(
I);
3858 MSSAU->removeMemoryAccess(
I);
3862 ICF->removeInstruction(
I);
3863 I->eraseFromParent();
3869void GVNPass::verifyRemoved(
const Instruction *Inst)
const {
3870 VN.verifyRemoved(Inst);
3877void GVNPass::addDeadBlock(BasicBlock *BB) {
3879 SmallSetVector<BasicBlock *, 4>
DF;
3882 while (!NewDead.
empty()) {
3884 if (DeadBlocks.count(
D))
3888 SmallVector<BasicBlock *, 8> Dom;
3889 DT->getDescendants(
D, Dom);
3890 DeadBlocks.insert_range(Dom);
3893 for (BasicBlock *
B : Dom) {
3895 if (DeadBlocks.count(S))
3898 bool AllPredDead =
true;
3900 if (!DeadBlocks.count(
P)) {
3901 AllPredDead =
false;
3921 for (BasicBlock *
B :
DF) {
3922 if (DeadBlocks.count(
B))
3928 for (BasicBlock *
P : Preds) {
3929 if (!DeadBlocks.count(
P))
3934 if (BasicBlock *S = splitCriticalEdges(
P,
B))
3935 DeadBlocks.insert(
P = S);
3941 if (!DeadBlocks.count(
P))
3943 for (PHINode &Phi :
B->phis()) {
3946 MD->invalidateCachedPointerInfo(&Phi);
3965bool GVNPass::processFoldableCondBr(CondBrInst *BI) {
3976 if (DeadBlocks.count(DeadRoot))
3980 DeadRoot = splitCriticalEdges(BI->getParent(), DeadRoot);
3982 addDeadBlock(DeadRoot);
3990void GVNPass::assignValNumForDeadCode() {
3991 for (BasicBlock *BB : DeadBlocks) {
3992 for (Instruction &Inst : *BB) {
3993 unsigned ValNum = VN.lookupOrAdd(&Inst);
3994 LeaderTable.insert(ValNum, &Inst, BB);
4005 bool ScalarPRE =
true)
4007 .setMemDep(MemDepAnalysis)
4008 .setMemorySSA(MemSSAAnalysis)
4009 .setScalarPRE(ScalarPRE)) {
4018 if (Impl.isMemorySSAEnabled() && !MSSAWP)
4021 return Impl.runImpl(
4026 Impl.isMemDepEnabled()
4031 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
4039 if (Impl.isMemDepEnabled())
4048 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 Instruction * findInvariantGroupValue(LoadInst *L, DominatorTree &DT)
If a load has !invariant.group, try to find the most-dominating instruction with the same metadata an...
static void reportLoadElim(LoadInst *Load, Value *AvailableValue, OptimizationRemarkEmitter *ORE)
static cl::opt< uint32_t > MaxNumInsnsPerBlock("gvn-max-num-insns", cl::Hidden, cl::init(100), cl::desc("Max number of instructions to scan in each basic block in GVN " "(default = 100)"))
static cl::opt< bool > GVNEnableMemDep("enable-gvn-memdep", cl::init(true))
static cl::opt< bool > GVNEnableLoadInLoopPRE("enable-load-in-loop-pre", cl::init(true))
static const Instruction * findMayClobberedPtrAccess(LoadInst *Load, const DominatorTree *DT)
static cl::opt< uint32_t > MaxNumDeps("gvn-max-num-deps", cl::Hidden, cl::init(100), cl::desc("Max number of dependences to attempt Load PRE (default = 100)"))
static std::optional< MemoryLocation > maybeLoadStoreLocation(Instruction *I, bool AllowStores, const TargetLibraryInfo *TLI)
Return the memory location accessed by the (masked) load/store instruction I, if the instruction coul...
static cl::opt< 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 cl::opt< unsigned > ScanUsersLimit("gvn-scan-users-limit", cl::Hidden, cl::init(100), cl::desc("The number of memory accesses to scan in a block in reaching " "memory values analysis (default = 100)"))
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.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
constexpr int32_t getOffset() const
constexpr bool hasOffset() const
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.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
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
LLVM_ABI MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
LLVM_ABI const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
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.
MemoryLocation getWithNewPtr(const Value *NewPtr) const
const Value * Ptr
The address of the start of the location.
static LLVM_ABI MemoryLocation getForArgument(const CallBase *Call, unsigned ArgIdx, const TargetLibraryInfo *TLI)
Return a location representing a particular argument of a call.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
BasicBlock * getIncomingBlock(unsigned I) const
Return incoming basic block number i.
MemoryAccess * getIncomingValue(unsigned I) const
Return incoming value number x.
An analysis that produces MemorySSA for a function.
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 ...
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
LLVM_ABI bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
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...
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool needsPHITranslationFromBlock(BasicBlock *BB) const
needsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
static LLVM_ABI PointerType * get(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.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
LLVM_ABI bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
std::pair< Value *, SelectAddrs > getSelectCondAndAddrs() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
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)
void reserve(size_type N)
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.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isTokenLikeTy() const
Returns true if this is 'token' or a token-like target type.s.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI bool canBeFreed() const
Return true if the memory object referred to by V can by freed in the scope for which the SSA value d...
LLVM_ABI void deleteValue()
Delete a pointer to a generic Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
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.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
LLVM_ABI int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
LLVM_ABI Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...
LLVM_ABI int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
LLVM_ABI Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
LLVM_ABI int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
LLVM_ABI bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
initializer< Ty > init(const Ty &Val)
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.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
LLVM_ABI unsigned replaceDominatedUsesWithIf(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge, function_ref< bool(const Use &U, const Value *To)> ShouldReplace)
Replace each use of 'From' with 'To' if that use is dominated by the given edge and the callback Shou...
RelativeUniformCounterPtr Values
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createGVNPass(bool ScalarPRE)
Create a legacy GVN pass.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
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 isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
LLVM_ABI bool isAssumeWithEmptyBundle(const AssumeInst &Assume)
Return true iff the operand bundles of the provided llvm.assume doesn't contain any valuable informat...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool canReplacePointersInUseIfEqual(const Use &U, const Value *To, const DataLayout &DL)
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
bool isModSet(const ModRefInfo MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void 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.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
LLVM_ABI FunctionPass * createGVNPass()
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
DWARFExpression::Operation Op
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
LLVM_ABI bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
constexpr unsigned BitWidth
auto pred_begin(const MachineBasicBlock *BB)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB)
Check for and eliminate duplicate PHI nodes in this block.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static bool isEqual(const GVNPass::Expression &LHS, const GVNPass::Expression &RHS)
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.
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
bool isCoercedLoadValue() const
static AvailableValue get(Value *V, unsigned Offset=0)
ValType Kind
Kind of the live-out value.
static AvailableValue getSelect(Value *Cond, Value *V1, Value *V2)
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()
Value * getSelectCondition() 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.