92#define DEBUG_TYPE "gvn"
94STATISTIC(NumGVNInstr,
"Number of instructions deleted");
96STATISTIC(NumGVNPRE,
"Number of instructions PRE'd");
98STATISTIC(NumGVNSimpl,
"Number of instructions simplified");
99STATISTIC(NumGVNEqProp,
"Number of equalities propagated");
103 "Number of loads moved to predecessor of a critical edge in PRE");
105STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
106 "Number of blocks speculated as available in "
107 "IsValueFullyAvailableInBlock(), max");
109 "Number of times we we reached gvn-max-block-speculations cut-off "
110 "preventing further exploration");
133 if ((!
Attrs.isEmpty() || !
Other.Attrs.isEmpty()) &&
134 !
Attrs.intersectWith(
Ty->getContext(),
Other.Attrs).has_value())
172 struct LeaderListNode {
173 LeaderTableEntry Entry;
174 LeaderListNode *
Next;
178 DenseMap<uint32_t, LeaderListNode> NumToLeaders;
183 const LeaderListNode *Current;
194 assert(Current &&
"Dereferenced end of leader list!");
195 Current = Current->Next;
199 return Current ==
Other.Current;
202 return Current !=
Other.Current;
208 auto I = NumToLeaders.find(
N);
209 if (
I == NumToLeaders.end()) {
223 for (
auto &[
_, HeadNode] : NumToLeaders) {
224 LeaderListNode *
N = HeadNode.Next;
226 auto *
Next =
N->Next;
227 N->~LeaderListNode();
231 NumToLeaders.clear();
232 TableAllocator.Reset();
243 const ScalarOptions *Opts =
nullptr;
269 friend class ::GVNLegacyPass;
294 bool InvalidBlockRPONumbers =
true;
317 struct ReachingMemVal {
326 const Value *SelTrueAddr =
nullptr;
327 const Value *SelFalseAddr =
nullptr;
331 return {DepKind::Other, BB, Addr, Inst, -1};
334 static ReachingMemVal getDef(
const Value *Addr, Instruction *Inst) {
335 return {DepKind::Def, Inst->getParent(), Addr, Inst, -1};
338 static ReachingMemVal getClobber(
const Value *Addr, Instruction *Inst,
339 int32_t Offset = -1) {
340 return {DepKind::Clobber, Inst->getParent(), Addr, Inst, Offset};
343 static ReachingMemVal getSelect(BasicBlock *BB, SelectInst *Sel,
344 const Value *TrueAddr,
345 const Value *FalseAddr) {
346 return {DepKind::Select, BB,
nullptr,
nullptr, -1, Sel,
347 TrueAddr, FalseAddr};
351 struct DependencyBlockInfo {
352 DependencyBlockInfo() =
delete;
353 DependencyBlockInfo(
const PHITransAddr &Addr, MemoryAccess *ClobberMA)
354 : Addr(Addr), InitialClobberMA(ClobberMA), ClobberMA(ClobberMA),
357 MemoryAccess *InitialClobberMA;
358 MemoryAccess *ClobberMA;
359 std::optional<ReachingMemVal> MemVal;
360 bool ForceUnknown : 1;
364 using DependencyBlockSet = DenseMap<BasicBlock *, DependencyBlockInfo>;
366 std::optional<GVNPassImpl::ReachingMemVal> scanMemoryAccessesUsers(
367 const MemoryLocation &Loc,
bool IsInvariantLoad, BasicBlock *BB,
368 const SmallVectorImpl<MemoryAccess *> &ClobbersList,
MemorySSA &MSSA,
369 BatchAAResults &AA, LoadInst *L =
nullptr);
371 std::optional<GVNPassImpl::ReachingMemVal>
372 accessMayModifyLocation(MemoryAccess *ClobberMA,
const MemoryLocation &Loc,
373 Align LoadAlign,
bool IsInvariantLoad, BasicBlock *BB,
376 bool collectPredecessors(BasicBlock *BB,
const PHITransAddr &Addr,
377 MemoryAccess *ClobberMA, DependencyBlockSet &Blocks,
378 SmallVectorImpl<BasicBlock *> &Worklist);
380 void collectClobberList(SmallVectorImpl<MemoryAccess *> &Clobbers,
381 BasicBlock *BB,
const DependencyBlockInfo &StartInfo,
382 const DependencyBlockSet &Blocks,
MemorySSA &MSSA);
384 bool findReachingValuesForLoad(LoadInst *Inst,
385 SmallVectorImpl<ReachingMemVal> &
Values,
389 bool processLoad(LoadInst *L);
390 bool processMaskedLoad(IntrinsicInst *
I);
391 bool processNonLocalLoad(LoadInst *L);
392 bool processNonLocalLoad(LoadInst *L, SmallVectorImpl<ReachingMemVal> &Deps);
393 bool processAssumeIntrinsic(AssumeInst *
II);
397 std::optional<AvailableValue>
398 analyzeLoadAvailability(LoadInst *
Load,
const ReachingMemVal &Dep,
405 std::optional<AvailableValue>
406 analyzeSelectAvailability(LoadInst *
Load, SelectInst *Sel,
Value *TrueAddr,
407 Value *FalseAddr, Instruction *From);
412 void analyzeLoadAvailability(LoadInst *
Load,
413 SmallVectorImpl<ReachingMemVal> &Deps,
414 AvailValInBlkVect &ValuesPerBlock,
415 UnavailBlkVect &UnavailableBlocks);
419 LoadInst *findLoadToHoistIntoPred(BasicBlock *
Pred, BasicBlock *LoadBB,
422 bool performLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
423 UnavailBlkVect &UnavailableBlocks);
428 bool performLoopLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
429 UnavailBlkVect &UnavailableBlocks);
433 void eliminatePartiallyRedundantLoad(
434 LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
435 MapVector<BasicBlock *, Value *> &AvailableLoads,
436 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad);
439 bool processInstruction(Instruction *
I);
440 bool processBlock(BasicBlock *BB);
441 bool replaceWithEquivalentCmp(CmpInst *Cmp);
444 bool performScalarPRE(Instruction *
I);
445 bool performScalarPREInsertion(Instruction *Instr, BasicBlock *
Pred,
446 BasicBlock *Curr,
unsigned int ValNo);
447 Value *findLeader(
const BasicBlock *BB, uint32_t Num);
448 void cleanupGlobalSets();
449 void removeInstruction(Instruction *
I);
450 void verifyRemoved(
const Instruction *
I)
const;
451 bool splitCriticalEdges();
452 BasicBlock *splitCriticalEdges(BasicBlock *
Pred, BasicBlock *Succ);
455 const std::variant<BasicBlockEdge, Instruction *> &Root);
456 bool processFoldableCondBr(CondBrInst *BI);
457 void addDeadBlock(BasicBlock *BB);
458 void assignValNumForDeadCode();
490 Res.
Kind = ValType::SimpleVal;
498 Res.
Kind = ValType::MemIntrin;
506 Res.
Kind = ValType::LoadVal;
514 Res.
Kind = ValType::UndefVal;
522 Res.
Kind = ValType::SelectVal;
572 Res.
AV = std::move(
AV);
588 return AV.MaterializeAdjustedValue(
Load,
BB->getTerminator());
599 E.Opcode =
I->getOpcode();
604 E.VarArgs.push_back(
lookupOrAdd(GCR->getOperand(0)));
605 E.VarArgs.push_back(
lookupOrAdd(GCR->getBasePtr()));
606 E.VarArgs.push_back(
lookupOrAdd(GCR->getDerivedPtr()));
608 for (
Use &
Op :
I->operands())
611 if (
I->isCommutative()) {
616 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
617 if (
E.VarArgs[0] >
E.VarArgs[1])
619 E.Commutative =
true;
623 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
625 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
626 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
628 E.Attrs = CB->getAttributes();
637 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
638 "Not a comparison!");
645 if (
E.VarArgs[0] >
E.VarArgs[1]) {
649 E.Opcode = (Opcode << 8) | Predicate;
650 E.Commutative =
true;
656 assert(EI &&
"Not an ExtractValueInst?");
685 Type *PtrTy =
GEP->getType()->getScalarType();
686 const DataLayout &
DL =
GEP->getDataLayout();
687 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
688 SmallMapVector<Value *, APInt, 4> VariableOffsets;
690 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
694 E.Opcode =
GEP->getOpcode();
697 for (
const auto &[
V, Scale] : VariableOffsets) {
701 if (!ConstantOffset.isZero())
707 E.Opcode =
GEP->getOpcode();
708 E.Ty =
GEP->getSourceElementType();
709 for (Use &
Op :
GEP->operands())
727 ValueNumbering.insert(std::make_pair(V, Num));
729 NumberingPhi[Num] = PN;
739 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
753 if (
C->getFunction()->isPresplitCoroutine()) {
754 ValueNumbering[
C] = NextValueNumber;
755 return NextValueNumber++;
761 if (
C->isConvergent()) {
762 ValueNumbering[
C] = NextValueNumber;
763 return NextValueNumber++;
769 if (
C->hasOperandBundles()) {
770 ValueNumbering[
C] = NextValueNumber;
771 return NextValueNumber++;
774 if (AA->doesNotAccessMemory(
C)) {
776 uint32_t
E = assignExpNewValueNum(Exp).first;
777 ValueNumbering[
C] =
E;
781 if (MD && AA->onlyReadsMemory(
C)) {
783 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
785 ValueNumbering[
C] =
E;
789 MemDepResult LocalDep = MD->getDependency(
C);
792 ValueNumbering[
C] = NextValueNumber;
793 return NextValueNumber++;
796 if (LocalDep.
isDef()) {
801 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
802 ValueNumbering[
C] = NextValueNumber;
803 return NextValueNumber++;
806 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
809 if (CVN != LocalDepCallVN) {
810 ValueNumbering[
C] = NextValueNumber;
811 return NextValueNumber++;
816 ValueNumbering[
C] =
V;
822 MD->getNonLocalCallDependency(
C);
824 CallInst *CDep =
nullptr;
828 for (
const NonLocalDepEntry &
I : Deps) {
829 if (
I.getResult().isNonLocal())
834 if (!
I.getResult().isDef() || CDep !=
nullptr) {
841 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
842 CDep = NonLocalDepCall;
851 ValueNumbering[
C] = NextValueNumber;
852 return NextValueNumber++;
856 ValueNumbering[
C] = NextValueNumber;
857 return NextValueNumber++;
859 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
863 ValueNumbering[
C] = NextValueNumber;
864 return NextValueNumber++;
869 ValueNumbering[
C] =
V;
873 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
875 addMemoryStateToExp(
C, Exp);
876 auto [
V,
_] = assignExpNewValueNum(Exp);
877 ValueNumbering[
C] =
V;
881 ValueNumbering[
C] = NextValueNumber;
882 return NextValueNumber++;
886uint32_t GVNValueTable::computeLoadStoreVN(
Instruction *
I) {
887 if (!MSSA || !IsMSSAEnabled) {
888 ValueNumbering[
I] = NextValueNumber;
889 return NextValueNumber++;
893 Exp.Ty =
I->getType();
894 Exp.Opcode =
I->getOpcode();
895 for (Use &
Op :
I->operands())
897 addMemoryStateToExp(
I, Exp);
899 auto [
V,
_] = assignExpNewValueNum(Exp);
900 ValueNumbering[
I] =
V;
906 return ValueNumbering.contains(V);
918 auto VI = ValueNumbering.find(V);
919 if (VI != ValueNumbering.end())
924 ValueNumbering[V] = NextValueNumber;
927 return NextValueNumber++;
931 switch (
I->getOpcode()) {
932 case Instruction::Call:
934 case Instruction::FNeg:
935 case Instruction::Add:
936 case Instruction::FAdd:
937 case Instruction::Sub:
938 case Instruction::FSub:
939 case Instruction::Mul:
940 case Instruction::FMul:
941 case Instruction::UDiv:
942 case Instruction::SDiv:
943 case Instruction::FDiv:
944 case Instruction::URem:
945 case Instruction::SRem:
946 case Instruction::FRem:
947 case Instruction::Shl:
948 case Instruction::LShr:
949 case Instruction::AShr:
950 case Instruction::And:
951 case Instruction::Or:
952 case Instruction::Xor:
953 case Instruction::Trunc:
954 case Instruction::ZExt:
955 case Instruction::SExt:
956 case Instruction::FPToUI:
957 case Instruction::FPToSI:
958 case Instruction::UIToFP:
959 case Instruction::SIToFP:
960 case Instruction::FPTrunc:
961 case Instruction::FPExt:
962 case Instruction::PtrToInt:
963 case Instruction::PtrToAddr:
964 case Instruction::IntToPtr:
965 case Instruction::AddrSpaceCast:
966 case Instruction::BitCast:
967 case Instruction::Select:
968 case Instruction::Freeze:
969 case Instruction::ExtractElement:
970 case Instruction::InsertElement:
971 case Instruction::ShuffleVector:
972 case Instruction::InsertValue:
975 case Instruction::ICmp:
976 case Instruction::FCmp:
978 I->getOperand(0),
I->getOperand(1));
980 case Instruction::GetElementPtr:
983 case Instruction::ExtractValue:
986 case Instruction::PHI:
987 ValueNumbering[V] = NextValueNumber;
989 return NextValueNumber++;
990 case Instruction::Load:
991 case Instruction::Store:
992 return computeLoadStoreVN(
I);
994 ValueNumbering[V] = NextValueNumber;
995 return NextValueNumber++;
998 uint32_t E = assignExpNewValueNum(Exp).first;
999 ValueNumbering[V] = E;
1006 auto VI = ValueNumbering.find(V);
1008 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
1011 return (VI != ValueNumbering.end()) ? VI->second : 0;
1021 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1022 return assignExpNewValueNum(Exp).first;
1027 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1028 return ExpressionNumbering.lookup(Exp);
1036 return ExpressionNumbering.lookup(Exp);
1041 ValueNumbering.clear();
1042 ExpressionNumbering.clear();
1043 NumberingPhi.clear();
1044 NumberingBB.clear();
1045 PhiTranslateTable.clear();
1046 NextValueNumber = 1;
1047 Expressions.clear();
1054 uint32_t Num = ValueNumbering.lookup(V);
1055 ValueNumbering.erase(V);
1058 NumberingPhi.erase(Num);
1060 NumberingBB.erase(Num);
1066 assert(!ValueNumbering.contains(V) &&
1067 "Inst still occurs in value numbering map!");
1076 const auto &[It, Inserted] = NumToLeaders.try_emplace(
N, V, BB,
nullptr);
1079 auto *NewSlot = TableAllocator.Allocate<LeaderListNode>();
1080 new (NewSlot) LeaderListNode(V, BB, It->second.Next);
1081 It->second.Next = NewSlot;
1088 auto It = NumToLeaders.find(
N);
1089 if (It == NumToLeaders.end())
1092 LeaderListNode *Prev =
nullptr;
1093 LeaderListNode *Curr = &It->second;
1095 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
1105 Prev->Next = Curr->Next;
1106 Curr->~LeaderListNode();
1107 TableAllocator.Deallocate<LeaderListNode>(Curr);
1112 NumToLeaders.erase(It);
1115 LeaderListNode *
Next = Curr->Next;
1116 Curr->Entry.Val = std::move(
Next->Entry.Val);
1117 Curr->Entry.BB =
Next->Entry.BB;
1118 Curr->Next =
Next->Next;
1119 Next->~LeaderListNode();
1120 TableAllocator.Deallocate<LeaderListNode>(
Next);
1130 return Options.AllowScalarPRE.value_or(Opts->enable_scalar_pre);
1134 return Options.AllowLoadPRE.value_or(Opts->enable_load_pre);
1138 return Options.AllowLoadInLoopPRE.value_or(Opts->enable_load_in_loop_pre);
1142 return Options.AllowLoadPRESplitBackedge.value_or(
1143 Opts->enable_split_backedge_in_load_pre);
1151 return Options.AllowMemDep.value_or(
false);
1152 return Options.AllowMemDep.value_or(
valueOr(Opts->enable_gvn_memdep,
true));
1156 return Options.AllowMemorySSA.value_or(Opts->enable_gvn_memoryssa);
1178 auto *MemDep = Impl->isMemDepEnabled()
1183 if (Impl->isMemorySSAEnabled() && !MSSA) {
1185 "On-demand computation of MemSSA implies that MemDep is disabled!");
1189 bool Changed = Impl->run(
F, AC, DT,
TLI,
AA, MemDep, LI, &ORE,
1190 MSSA ? &MSSA->getMSSA() :
nullptr);
1205 removeInstruction(
I);
1211 OS, MapClassName2PassName);
1215 if (
Options.AllowScalarPRE != std::nullopt)
1216 OS << (*
Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
1217 if (
Options.AllowLoadPRE != std::nullopt)
1218 OS << (*
Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
1219 if (
Options.AllowLoadPRESplitBackedge != std::nullopt)
1220 OS << (*
Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
1221 <<
"split-backedge-load-pre;";
1222 if (
Options.AllowMemDep != std::nullopt)
1223 OS << (*
Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
1224 if (
Options.AllowMemorySSA != std::nullopt)
1225 OS << (*
Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
1253 std::optional<BasicBlock *> UnavailableBB;
1257 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
1265 while (!Worklist.
empty()) {
1269 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
1277 UnavailableBB = CurrBB;
1288 ++NumNewNewSpeculativelyAvailableBBs;
1290 NumNewNewSpeculativelyAvailableBBs > Opts.gvn_max_block_speculations;
1295 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1297 UnavailableBB = CurrBB;
1303 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1309#if LLVM_ENABLE_STATS
1310 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1311 NumNewNewSpeculativelyAvailableBBs);
1316 auto MarkAsFixpointAndEnqueueSuccessors =
1318 auto It = FullyAvailableBlocks.
find(BB);
1319 if (It == FullyAvailableBlocks.
end())
1326 State = FixpointState;
1329 "Found a speculatively available successor leftover?");
1337 if (UnavailableBB) {
1344 while (!Worklist.
empty())
1345 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1353 while (!Worklist.
empty())
1354 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1358 "Must have fixed all the new speculatively available blocks.");
1361 return !UnavailableBB;
1373 if (
V.AV.Val == OldValue)
1374 V.AV.Val = NewValue;
1375 if (
V.AV.isSelectValue()) {
1376 if (
V.AV.V1 == OldValue)
1378 if (
V.AV.V2 == OldValue)
1393 if (ValuesPerBlock.
size() == 1 &&
1395 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1396 "Dead BB dominate this block");
1397 return ValuesPerBlock[0].MaterializeAdjustedValue(
Load);
1408 if (AV.AV.isUndefValue())
1418 if (BB ==
Load->getParent() &&
1419 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() ==
Load) ||
1420 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() ==
Load)))
1437 if (Res->
getType() != LoadTy) {
1452 Load->getFunction());
1463 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1465 {LLVMContext::MD_dereferenceable,
1466 LLVMContext::MD_dereferenceable_or_null,
1467 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group,
1468 LLVMContext::MD_alias_scope, LLVMContext::MD_noalias});
1484 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1494 assert(Res &&
"failed to materialize?");
1500 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1517 Value *PtrOp =
Load->getPointerOperand();
1523 for (
auto *U : PtrOp->
users()) {
1544 for (
auto *U : PtrOp->
users()) {
1547 if (
I->getFunction() ==
Load->getFunction() &&
1555 OtherAccess =
nullptr;
1574 using namespace ore;
1577 R <<
"load of type " << NV(
"Type",
Load->getType()) <<
" not eliminated"
1582 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1584 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1599 for (
auto *Inst = BB == FromBB ? From : BB->getTerminator();
1602 if (++NumVisitedInsts > Opts.gvn_max_num_visited_insts)
1607 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1608 SI->getValueOperand()->getType() == LoadTy)
1609 return SI->getValueOperand();
1613 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1619std::optional<AvailableValue>
1624 "Invalid address type of true side of select dependency");
1626 "Invalid address type of false side of select dependency");
1634 return std::nullopt;
1638 return std::nullopt;
1642std::optional<AvailableValue>
1643GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
const ReachingMemVal &Dep,
1645 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1646 assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) &&
1647 "expected a local dependence");
1651 const DataLayout &
DL =
Load->getDataLayout();
1652 if (Dep.Kind == DepKind::Clobber) {
1658 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1675 Load->isAtomic() <= DepLoad->isAtomic()) {
1682 DepLoad->getFunction())) {
1683 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1685 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1691 DepLoad->getFunction()) ||
1718 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1722 return std::nullopt;
1724 assert(Dep.Kind == DepKind::Def &&
"follows from above");
1731 if (Constant *InitVal =
1741 return std::nullopt;
1744 if (S->isAtomic() <
Load->isAtomic())
1745 return std::nullopt;
1756 return std::nullopt;
1759 if (
LD->isAtomic() <
Load->isAtomic())
1760 return std::nullopt;
1773 return std::nullopt;
1780 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1781 return std::nullopt;
1784void GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
1786 AvailValInBlkVect &ValuesPerBlock,
1787 UnavailBlkVect &UnavailableBlocks) {
1792 for (
const auto &Dep : Deps) {
1795 if (DeadBlocks.count(DepBB)) {
1802 if (Dep.Kind == DepKind::Other) {
1803 UnavailableBlocks.push_back(DepBB);
1810 if (Dep.Kind == DepKind::Select) {
1811 if (
auto AV = analyzeSelectAvailability(
1812 Load, Dep.Sel,
const_cast<Value *
>(Dep.SelTrueAddr),
1814 ValuesPerBlock.push_back(
1817 UnavailableBlocks.push_back(DepBB);
1826 analyzeLoadAvailability(
Load, Dep,
const_cast<Value *
>(Dep.Addr))) {
1830 ValuesPerBlock.push_back(
1833 UnavailableBlocks.push_back(DepBB);
1837 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1838 "post condition violation");
1864 auto *
Term =
Pred->getTerminator();
1865 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1867 auto *SuccBB =
Term->getSuccessor(0);
1868 if (SuccBB == LoadBB)
1869 SuccBB =
Term->getSuccessor(1);
1870 if (!SuccBB->getSinglePredecessor())
1873 unsigned int NumInsts = Opts->gvn_max_num_insns;
1874 for (Instruction &Inst : *SuccBB) {
1877 if (--NumInsts == 0)
1883 bool HasLocalDep =
true;
1885 MemDepResult Dep = MD->getDependency(&Inst);
1888 auto *MSSA = MSSAU->getMemorySSA();
1890 if (
auto *MA = MSSA->getMemoryAccess(&Inst); MA &&
isa<MemoryUse>(MA)) {
1891 auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
1892 HasLocalDep = Clobber->getBlock() == SuccBB;
1900 if (!HasLocalDep && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1911void GVNPassImpl::eliminatePartiallyRedundantLoad(
1915 for (
const auto &AvailableLoad : AvailableLoads) {
1916 BasicBlock *UnavailableBlock = AvailableLoad.first;
1917 Value *LoadPtr = AvailableLoad.second;
1920 new LoadInst(
Load->getType(), LoadPtr,
Load->getName() +
".pre",
1921 Load->getProperties(),
1923 NewLoad->setDebugLoc(
Load->getDebugLoc());
1925 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1928 MSSAU->insertDef(NewDef,
true);
1934 AAMDNodes Tags =
Load->getAAMetadata();
1936 NewLoad->setAAMetadata(Tags);
1938 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1939 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1940 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1941 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1942 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1943 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1944 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1945 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
1947 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1948 if (LI->getLoopFor(
Load->getParent()) == LI->getLoopFor(UnavailableBlock))
1949 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1958 ValuesPerBlock.push_back(
1961 MD->invalidateCachedPointerInfo(LoadPtr);
1966 if (CriticalEdgePredAndLoad) {
1967 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1968 if (It != CriticalEdgePredAndLoad->
end()) {
1969 ++NumPRELoadMoved2CEPred;
1970 ICF->insertInstructionTo(NewLoad, UnavailableBlock);
1971 LoadInst *OldLoad = It->second;
1975 if (uint32_t ValNo = VN.lookup(OldLoad,
false))
1976 LeaderTable.erase(ValNo, OldLoad, OldLoad->
getParent());
1977 removeInstruction(OldLoad);
1985 ICF->removeUsersOf(
Load);
1986 Load->replaceAllUsesWith(
V);
1990 I->setDebugLoc(
Load->getDebugLoc());
1991 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
1992 MD->invalidateCachedPointerInfo(
V);
1995 <<
"load eliminated by PRE";
2001 AvailValInBlkVect &ValuesPerBlock,
2002 UnavailBlkVect &UnavailableBlocks) {
2011 SmallPtrSet<BasicBlock *, 4> Blockers(
llvm::from_range, UnavailableBlocks);
2033 bool MustEnsureSafetyOfSpeculativeExecution =
2034 ICF->isDominatedByICFIFromSameBlock(
Load);
2038 if (TmpBB == LoadBB)
2040 if (Blockers.count(TmpBB))
2052 MustEnsureSafetyOfSpeculativeExecution =
2053 MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
2061 MapVector<BasicBlock *, Value *> PredLoads;
2062 DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
2065 for (BasicBlock *UnavailableBB : UnavailableBlocks)
2073 MapVector<BasicBlock *, LoadInst *> CriticalEdgePredAndLoad;
2077 if (
Pred->getTerminator()->isEHPad()) {
2079 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
2080 <<
Pred->getName() <<
"': " << *
Load <<
'\n');
2088 if (
Pred->getTerminator()->getNumSuccessors() != 1) {
2091 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
2092 <<
Pred->getName() <<
"': " << *
Load <<
'\n');
2098 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
2099 <<
Pred->getName() <<
"': " << *
Load <<
'\n');
2105 if (DT->dominates(LoadBB,
Pred)) {
2108 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
2109 <<
Pred->getName() <<
"': " << *
Load <<
'\n');
2113 if (LoadInst *LI = findLoadToHoistIntoPred(
Pred, LoadBB,
Load))
2114 CriticalEdgePredAndLoad[
Pred] = LI;
2119 PredLoads[
Pred] =
nullptr;
2124 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
2125 unsigned NumUnavailablePreds = NumInsertPreds +
2126 CriticalEdgePredAndLoad.
size();
2127 assert(NumUnavailablePreds != 0 &&
2128 "Fully available value should already be eliminated!");
2129 (void)NumUnavailablePreds;
2135 if (NumInsertPreds > 1)
2140 if (MustEnsureSafetyOfSpeculativeExecution) {
2141 if (CriticalEdgePredSplit.
size())
2145 for (
auto &PL : PredLoads)
2149 for (
auto &CEP : CriticalEdgePredAndLoad)
2156 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
2157 BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
2158 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
2159 PredLoads[NewPred] =
nullptr;
2160 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
2161 << LoadBB->
getName() <<
'\n');
2164 for (
auto &CEP : CriticalEdgePredAndLoad)
2165 PredLoads[CEP.first] =
nullptr;
2168 bool CanDoPRE =
true;
2169 const DataLayout &
DL =
Load->getDataLayout();
2170 SmallVector<Instruction*, 8> NewInsts;
2171 for (
auto &PredLoad : PredLoads) {
2172 BasicBlock *UnavailablePred = PredLoad.first;
2182 Value *LoadPtr =
Load->getPointerOperand();
2184 while (Cur != LoadBB) {
2197 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
2204 << *
Load->getPointerOperand() <<
"\n");
2209 PredLoad.second = LoadPtr;
2213 while (!NewInsts.
empty()) {
2223 return !CriticalEdgePredSplit.empty();
2231 <<
" INSTS: " << *NewInsts.
back()
2235 for (Instruction *
I : NewInsts) {
2239 I->updateLocationAfterHoist();
2248 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, PredLoads,
2249 &CriticalEdgePredAndLoad);
2255 AvailValInBlkVect &ValuesPerBlock,
2256 UnavailBlkVect &UnavailableBlocks) {
2257 const Loop *
L = LI->getLoopFor(
Load->getParent());
2259 if (!L ||
L->getHeader() !=
Load->getParent())
2264 if (!Preheader || !Latch)
2267 Value *LoadPtr =
Load->getPointerOperand();
2269 if (!
L->isLoopInvariant(LoadPtr))
2275 if (ICF->isDominatedByICFIFromSameBlock(
Load))
2279 for (
auto *Blocker : UnavailableBlocks) {
2281 if (!
L->contains(Blocker))
2298 if (
const Loop *Inner = LI->getLoopFor(Blocker); Inner != L) {
2302 while (Inner->getParentLoop() != L)
2303 Inner = Inner->getParentLoop();
2309 ReloadBB = Inner->getUniqueExitBlock();
2310 if (!ReloadBB || LI->getLoopFor(ReloadBB) != L)
2319 if (DT->dominates(ReloadBB, Latch))
2326 LoopBlock = ReloadBB;
2344 MapVector<BasicBlock *, Value *> AvailableLoads;
2345 AvailableLoads[LoopBlock] = LoadPtr;
2346 AvailableLoads[Preheader] = LoadPtr;
2349 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, AvailableLoads,
2357 using namespace ore;
2361 <<
"load of type " << NV(
"Type",
Load->getType()) <<
" eliminated"
2362 << setExtraArgs() <<
" in favor of "
2371 if (
Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2372 Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2377 MD->getNonLocalPointerDependency(
Load, Deps);
2382 unsigned NumDeps = Deps.size();
2383 if (NumDeps > Opts->gvn_max_num_deps)
2389 for (
const NonLocalDepResult &Dep : Deps) {
2390 const auto &
R = Dep.getResult();
2391 SelectAddr SelAddr = Dep.getAddress();
2397 ReachingMemVal::getSelect(BB, Sel, Addrs.first, Addrs.second));
2409 return processNonLocalLoad(
Load, MemVals);
2416 if (Deps.
size() == 1 && Deps[0].Kind == DepKind::Other) {
2418 dbgs() <<
" has unknown dependencies\n";);
2426 if (GetElementPtrInst *
GEP =
2428 for (Use &U :
GEP->indices())
2438 AvailValInBlkVect ValuesPerBlock;
2439 UnavailBlkVect UnavailableBlocks;
2440 analyzeLoadAvailability(
Load, Deps, ValuesPerBlock, UnavailableBlocks);
2444 if (ValuesPerBlock.empty())
2452 if (UnavailableBlocks.empty()) {
2458 ICF->removeUsersOf(
Load);
2459 Load->replaceAllUsesWith(
V);
2467 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2468 I->setDebugLoc(
Load->getDebugLoc());
2469 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2470 MD->invalidateCachedPointerInfo(
V);
2483 if (performLoopLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks) ||
2484 performLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks))
2490bool GVNPassImpl::processAssumeIntrinsic(
AssumeInst *IntrinsicI) {
2494 if (
Cond->isZero()) {
2504 const MemoryUseOrDef *FirstNonDom =
nullptr;
2506 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2513 for (
const auto &Acc : *AL) {
2515 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2516 FirstNonDom = Current;
2523 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2525 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2526 : MSSAU->createMemoryAccessInBB(
2548 return propagateEquality(
V,
True, IntrinsicI);
2553 I->replaceAllUsesWith(Repl);
2560 Value *PointerOperand = L->getPointerOperand()->stripPointerCasts();
2571 PointerUsesQueue.
push_back(PointerOperand);
2576 while (!PointerUsesQueue.
empty()) {
2579 "Null or GlobalValue should not be inserted");
2583 if (!
I ||
I == L || !DT.
dominates(
I, MostDominatingInstruction))
2598 if (
I->hasMetadata(LLVMContext::MD_invariant_group) &&
2600 MostDominatingInstruction =
I;
2604 return MostDominatingInstruction != L ? MostDominatingInstruction :
nullptr;
2610static std::optional<MemoryLocation>
2617 switch (
II->getIntrinsicID()) {
2618 case Intrinsic::masked_load:
2620 case Intrinsic::masked_store:
2623 return std::nullopt;
2630 return std::nullopt;
2634 return std::nullopt;
2640std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::scanMemoryAccessesUsers(
2646 auto UpdateChoice = [&](std::optional<ReachingMemVal> &Choice,
2650 Choice = ReachingMemVal::getClobber(Loc.
Ptr, Candidate, AR.getOffset());
2652 Choice = ReachingMemVal::getDef(Loc.
Ptr, Candidate);
2660 Choice->Kind = DepKind::Clobber;
2661 Choice->Offset = AR.getOffset();
2663 Choice->Kind = DepKind::Def;
2664 Choice->Offset = -1;
2667 Choice->Inst = Candidate;
2668 Choice->Block = Candidate->getParent();
2671 std::optional<ReachingMemVal> ReachingVal;
2672 for (MemoryAccess *MA : ClobbersList) {
2674 for (User *U : MA->
users()) {
2675 if (++Scanned >= Opts->gvn_scan_users_limit)
2676 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2679 if (!UseOrDef || UseOrDef->getBlock() != BB)
2688 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2702 UpdateChoice(ReachingVal, AR, MemI);
2714std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::accessMayModifyLocation(
2724 if (
Alloc->getParent() == BB)
2725 return ReachingMemVal::getDef(Loc.
Ptr,
const_cast<AllocaInst *
>(
Alloc));
2726 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2730 if (IsInvariantLoad || AA.pointsToConstantMemory(Loc))
2731 return std::nullopt;
2735 return L->getOrdering();
2742 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2744 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2755 return std::nullopt;
2756 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2761 return std::nullopt;
2767 Opts->gvn_max_num_insns))
2768 return std::nullopt;
2773 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2778 "Must be the superset/partial overlap case with positive offset");
2779 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI, AR.
getOffset());
2783 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2785 if (AA.isMustAlias(IIObjLoc, Loc))
2786 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2787 return std::nullopt;
2795 if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.
Ptr))
2796 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2802 return std::nullopt;
2806 ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc);
2810 return std::nullopt;
2814 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2822 DependencyBlockSet &Blocks,
2833 if (!DT->isReachableFromEntry(
Pred))
2840 PHITransAddr TransAddr = Addr;
2844 auto It = Blocks.find(
Pred);
2845 if (It != Blocks.end()) {
2849 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2856 Pred, DependencyBlockInfo(TransAddr,
2857 MPhi ? MPhi->getIncomingValueForBlock(
Pred)
2864 for (
auto &
P : Preds) {
2865 [[maybe_unused]]
auto It =
2866 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2880 const DependencyBlockInfo &StartInfo,
2881 const DependencyBlockSet &Blocks,
2883 MemoryAccess *MA = StartInfo.InitialClobberMA;
2884 MemoryAccess *LastMA = StartInfo.ClobberMA;
2887 while (MA != LastMA) {
2901 BB = DT->getNode(BB)->getIDom()->getBlock();
2905 auto It = Blocks.find(BB);
2906 if (It == Blocks.end())
2909 MA = It->second.InitialClobberMA;
2910 LastMA = It->second.ClobberMA;
2911 if (MA == Clobbers.
back())
2928bool GVNPassImpl::findReachingValuesForLoad(
2931 BatchAAResults AA(AAR, EA);
2933 bool IsInvariantLoad =
L->hasMetadata(LLVMContext::MD_invariant_load);
2939 if (
L->hasMetadata(LLVMContext::MD_invariant_group)) {
2952 if (
auto RMV = scanMemoryAccessesUsers(
2953 Loc, IsInvariantLoad, StartBlock,
2955 Values.emplace_back(*RMV);
2966 accessMayModifyLocation(ClobberMA, Loc,
L->getAlign(),
2967 IsInvariantLoad, StartBlock, MSSA, AA)) {
2968 Values.emplace_back(*RMV);
2978 if (
L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2979 L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2988 DependencyBlockSet Blocks;
2989 SmallVector<BasicBlock *, 16> InitialWorklist;
2990 const DataLayout &
DL =
L->getDataLayout();
2991 if (!collectPredecessors(StartBlock,
2992 PHITransAddr(
L->getPointerOperand(),
DL, AC),
2993 ClobberMA, Blocks, InitialWorklist))
2997 auto Worklist = InitialWorklist;
2998 while (!Worklist.
empty()) {
3000 if (Blocks.size() > Opts->gvn_max_num_reaching_blocks)
3003 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3006 if (!
Info.Addr.getAddr())
3016 accessMayModifyLocation(
Info.ClobberMA, BBLoc,
L->getAlign(),
3017 IsInvariantLoad, BB, MSSA, AA)) {
3022 "LiveOnEntry aliases everything");
3038 if (BB == StartBlock &&
Info.Addr.getAddr() !=
L->getPointerOperand()) {
3039 Info.ForceUnknown =
true;
3042 if (BB != StartBlock &&
3043 !collectPredecessors(BB,
Info.Addr,
Info.ClobberMA, Blocks, Worklist))
3044 Info.ForceUnknown =
true;
3054 Worklist = InitialWorklist;
3055 for (BasicBlock *BB : Worklist) {
3056 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3057 Info.Visited =
true;
3061 while (!Worklist.empty()) {
3062 auto *BB = Worklist.pop_back_val();
3063 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3067 if (!
Info.Addr.getAddr()) {
3068 Values.push_back(ReachingMemVal::getUnknown(BB,
nullptr));
3073 collectClobberList(Clobbers, BB, Info, Blocks, MSSA);
3076 IsInvariantLoad, BB, Clobbers, MSSA, AA)) {
3088 if (
Info.ForceUnknown) {
3089 Values.push_back(ReachingMemVal::getUnknown(BB,
Info.Addr.getAddr()));
3095 auto It = Blocks.find(
Pred);
3096 if (It == Blocks.end())
3098 DependencyBlockInfo &PredInfo = It->second;
3099 if (PredInfo.Visited)
3101 PredInfo.Visited =
true;
3102 Worklist.push_back(
Pred);
3111bool GVNPassImpl::processLoad(
LoadInst *L) {
3116 if (!
L->isUnordered())
3119 if (
L->getType()->isTokenLikeTy())
3122 if (
L->use_empty()) {
3127 ReachingMemVal MemVal = ReachingMemVal::getUnknown(
nullptr,
nullptr);
3130 MemDepResult Dep = MD->getDependency(L);
3134 return processNonLocalLoad(L);
3138 MemVal = ReachingMemVal::getDef(
L->getPointerOperand(), Dep.
getInst());
3141 ReachingMemVal::getClobber(
L->getPointerOperand(), Dep.
getInst());
3144 if (!findReachingValuesForLoad(L, MemVals, *MSSAU->getMemorySSA(), *AA))
3146 assert(MemVals.
size() &&
"Expected at least an unknown value");
3147 if (MemVals.
size() > 1 || MemVals[0].Block !=
L->getParent())
3148 return processNonLocalLoad(L, MemVals);
3150 MemVal = MemVals[0];
3153 if (MemVal.Kind == DepKind::Other) {
3157 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
3158 dbgs() <<
" has unknown dependence\n";);
3162 auto AV = analyzeLoadAvailability(L, MemVal,
L->getPointerOperand());
3169 ICF->removeUsersOf(L);
3172 MSSAU->removeMemoryAccess(L);
3186 BatchAAResults BatchAA(*AA);
3193 MemDepResult Dep = MD->getDependency(
I);
3198 auto *MSSA = MSSAU->getMemorySSA();
3204 Def->getBlock() !=
I->getParent())
3206 DepInst = Def->getMemoryInst();
3210 Value *Passthrough =
I->getOperand(2);
3214 StoreVal->
getType() !=
I->getType())
3219 MemoryLocation StoreLoc =
3221 if (!BatchAA.isMustAlias(StoreLoc, LoadLoc))
3229 ICF->removeUsersOf(
I);
3230 I->replaceAllUsesWith(OpToForward);
3238std::pair<uint32_t, bool> GVNValueTable::assignExpNewValueNum(
Expression &Exp) {
3239 uint32_t &
E = ExpressionNumbering[
Exp];
3240 bool CreateNewValNum = !
E;
3241 if (CreateNewValNum) {
3242 Expressions.push_back(Exp);
3243 if (ExprIdx.size() < NextValueNumber + 1)
3244 ExprIdx.resize(NextValueNumber * 2);
3245 E = NextValueNumber;
3246 ExprIdx[NextValueNumber++] = NextExprNumber++;
3248 return {
E, CreateNewValNum};
3253bool GVNValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
3257 [=](
const GVNLeaderMap::LeaderTableEntry &L) { return L.BB == BB; });
3264 auto FindRes = PhiTranslateTable.find({Num, Pred});
3265 if (FindRes != PhiTranslateTable.end())
3266 return FindRes->second;
3267 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, LeaderTable);
3268 PhiTranslateTable.insert({{Num, Pred}, NewNum});
3280 for (
const auto &Entry : Leaders) {
3282 if (
Call &&
Call->getParent() == PhiBlock)
3286 if (
AA->doesNotAccessMemory(
Call))
3289 if (!MD || !
AA->onlyReadsMemory(
Call))
3301 if (
D.getResult().isNonFuncLocal())
3315 if (PHINode *PN = NumberingPhi[Num]) {
3316 if (PN->getParent() != PhiBlock)
3318 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
3319 if (PN->getIncomingBlock(
I) !=
Pred)
3321 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
3327 if (BasicBlock *BB = NumberingBB[Num]) {
3328 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
3334 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
3341 if (MSSA->isLiveOnEntryDef(MA))
3346 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3352 if (!areAllValsInBB(Num, PhiBlock, LeaderTable))
3355 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3359 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3363 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3364 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3365 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3370 if (
Exp.Commutative) {
3371 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3372 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3374 uint32_t Opcode =
Exp.Opcode >> 8;
3375 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3376 Exp.Opcode = (Opcode << 8) |
3382 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3383 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3384 return areCallValsEqual(Num, NewNum,
Pred, PhiBlock, LeaderTable) ? NewNum
3396 PhiTranslateTable.erase({Num, Pred});
3406 if (Leaders.empty())
3409 Value *Val =
nullptr;
3410 for (
const auto &Entry : Leaders) {
3433 "No edge between these basic blocks!");
3434 return Pred !=
nullptr;
3437void GVNPassImpl::assignBlockRPONumber(
Function &
F) {
3438 BlockRPONumber.clear();
3439 uint32_t NextBlockNumber = 1;
3440 ReversePostOrderTraversal<Function *> RPOT(&
F);
3441 for (BasicBlock *BB : RPOT)
3442 BlockRPONumber[BB] = NextBlockNumber++;
3443 InvalidBlockRPONumbers =
false;
3451bool GVNPassImpl::propagateEquality(
3453 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3455 SmallDenseSet<std::pair<Value *, Value *>, 4> Visited;
3459 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3466 for (
const auto *Node : DT->getNode(
I->getParent())->children())
3470 while (!Worklist.
empty()) {
3471 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3472 LHS = Item.first;
RHS = Item.second;
3486 const DataLayout &
DL =
3495 uint32_t LVN = VN.lookupOrAdd(
LHS);
3500 uint32_t RVN = VN.lookupOrAdd(
RHS);
3507 if (!Visited.
insert({LHS, RHS}).second)
3520 for (
const BasicBlock *BB : DominatedBlocks)
3521 LeaderTable.insert(LVN,
RHS, BB);
3528 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3531 unsigned NumReplacements;
3532 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3534 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3537 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3538 CanReplacePointersCallBack);
3540 if (NumReplacements > 0) {
3542 NumGVNEqProp += NumReplacements;
3545 MD->invalidateCachedPointerInfo(
LHS);
3562 bool IsKnownFalse = !IsKnownTrue;
3578 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3583 if (
Cmp->isEquivalence(IsKnownFalse))
3584 Worklist.
push_back(std::make_pair(Op0, Op1));
3588 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3592 uint32_t NextNum = VN.getNextUnusedValueNumber();
3593 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
3596 if (Num < NextNum) {
3597 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
3602 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3603 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
3604 !DT->dominates(
Edge->getEnd(),
Entry.BB))
3607 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3608 if (!DT->dominates(
Entry.BB, InstBB) &&
3609 !DT->dominates(InstBB,
Entry.BB))
3615 unsigned NumReplacements;
3616 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3621 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3622 Changed |= NumReplacements > 0;
3623 NumGVNEqProp += NumReplacements;
3626 MD->invalidateCachedPointerInfo(NotCmp);
3634 for (
const BasicBlock *BB : DominatedBlocks)
3635 LeaderTable.insert(Num, NotVal, BB);
3644 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3649 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3657bool GVNPassImpl::replaceWithEquivalentCmp(
CmpInst *Cmp) {
3659 uint32_t Num = VN.lookupCmp(
Cmp->getOpcode(),
Pred,
Cmp->getOperand(0),
3660 Cmp->getOperand(1));
3662 return findLeader(
Cmp->getParent(), Num);
3667 if (
Value *Repl = FindCmpLeader(
Cmp->getInversePredicate())) {
3670 Repl, Repl->getName() +
".not",
Cmp->getIterator());
3671 Not->setDebugLoc(
Cmp->getDebugLoc());
3672 Cmp->replaceAllUsesWith(Not);
3679 if (ICmp && ICmp->hasSameSign() && !ICmp->isEquality()) {
3680 if (
Value *Repl = FindCmpLeader(
3697 const DataLayout &
DL =
I->getDataLayout();
3700 if (!
I->use_empty()) {
3703 ICF->removeUsersOf(
I);
3704 I->replaceAllUsesWith(
V);
3712 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3713 MD->invalidateCachedPointerInfo(
V);
3720 return processAssumeIntrinsic(Assume);
3723 if (processLoad(
Load))
3726 unsigned Num = VN.lookupOrAdd(
Load);
3727 LeaderTable.insert(Num,
Load,
Load->getParent());
3739 return processFoldableCondBr(BI);
3741 Value *BranchCond = BI->getCondition();
3745 if (TrueSucc == FalseSucc)
3752 BasicBlockEdge TrueE(Parent, TrueSucc);
3753 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3756 BasicBlockEdge FalseE(Parent, FalseSucc);
3757 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3764 Value *SwitchCond =
SI->getCondition();
3769 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
3771 ++SwitchEdges[Succ];
3773 for (
const auto &Case :
SI->cases()) {
3776 if (SwitchEdges.
lookup(Dst) == 1) {
3777 BasicBlockEdge
E(Parent, Dst);
3778 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3786 if (
I->getType()->isVoidTy())
3789 uint32_t NextNum = VN.getNextUnusedValueNumber();
3790 unsigned Num = VN.lookupOrAdd(
I);
3795 LeaderTable.insert(Num,
I,
I->getParent());
3802 const DataLayout &
DL =
I->getDataLayout();
3803 unsigned AS = PTA->getPointerAddressSpace();
3804 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3805 !
DL.hasUnstableRepresentation(AS)) {
3807 VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
3808 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3820 Value *Repl = Num < NextNum ? findLeader(
I->getParent(), Num) : nullptr;
3826 LeaderTable.insert(Num,
I,
I->getParent());
3839 MD->invalidateCachedPointerInfo(Repl);
3854 Opts->enable_gvn_memoryssa)
3856 "mutually exclusive",
3863 VN.setAliasAnalysis(&RunAA);
3865 ImplicitControlFlowTracking ImplicitCFT;
3874 InvalidBlockRPONumbers =
true;
3875 MemorySSAUpdater Updater(MSSA);
3876 MSSAU = MSSA ? &Updater :
nullptr;
3879 bool ShouldContinue =
true;
3881 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
3893 EarliestEscapeAnalysis RunEA(*DT, &LI);
3894 EA = MSSA ? &RunEA :
nullptr;
3896 unsigned Iteration = 0;
3897 while (ShouldContinue) {
3900 ShouldContinue = iterateOnFunction(
F);
3908 assignValNumForDeadCode();
3909 bool PREChanged =
true;
3910 while (PREChanged) {
3911 PREChanged = performPRE(
F);
3921 cleanupGlobalSets();
3932bool GVNPassImpl::processBlock(
BasicBlock *BB) {
3933 if (DeadBlocks.count(BB))
3936 bool ChangedFunction =
false;
3942 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
3944 for (PHINode *PN : PHINodesToRemove) {
3945 removeInstruction(PN);
3948 ChangedFunction |= processInstruction(&Inst);
3949 return ChangedFunction;
3953bool GVNPassImpl::performScalarPREInsertion(
Instruction *Instr,
3955 unsigned int ValNo) {
3961 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3969 if (!VN.exists(
Op)) {
3973 uint32_t TValNo = VN.phiTranslate(
Pred, Curr, VN.lookup(
Op), LeaderTable);
3992 ICF->insertInstructionTo(Instr,
Pred);
3994 unsigned Num = VN.lookupOrAdd(Instr);
3998 LeaderTable.insert(Num, Instr,
Pred);
4002bool GVNPassImpl::performScalarPRE(
Instruction *CurInst) {
4028 if (CallB->isInlineAsm())
4032 uint32_t ValNo = VN.lookup(CurInst);
4040 unsigned NumWith = 0;
4041 unsigned NumWithout = 0;
4046 if (InvalidBlockRPONumbers)
4047 assignBlockRPONumber(*CurrentBlock->
getParent());
4053 if (!DT->isReachableFromEntry(
P)) {
4058 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
4059 "Invalid BlockRPONumber map.");
4060 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
4065 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, LeaderTable);
4066 Value *PredV = findLeader(
P, TValNo);
4071 }
else if (PredV == CurInst) {
4083 if (NumWithout > 1 || NumWith == 0)
4091 if (NumWithout != 0) {
4097 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
4110 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
4114 PREInstr = CurInst->
clone();
4115 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
4118 verifyRemoved(PREInstr);
4127 assert(PREInstr !=
nullptr || NumWithout == 0);
4133 CurInst->
getName() +
".pre-phi");
4134 Phi->insertBefore(CurrentBlock->begin());
4135 for (
auto &[
V, BB] : PredMap) {
4140 Phi->addIncoming(
V, BB);
4142 Phi->addIncoming(PREInstr, PREPred);
4148 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
4149 LeaderTable.insert(ValNo, Phi, CurrentBlock);
4152 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
4153 MD->invalidateCachedPointerInfo(Phi);
4154 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
4157 removeInstruction(CurInst);
4164bool GVNPassImpl::performPRE(
Function &
F) {
4166 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
4168 if (CurrentBlock == &
F.getEntryBlock())
4172 if (CurrentBlock->isEHPad())
4176 BE = CurrentBlock->end();
4179 Changed |= performScalarPRE(CurInst);
4183 if (splitCriticalEdges())
4197 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
4200 MD->invalidateCachedPredecessors();
4201 InvalidBlockRPONumbers =
true;
4208bool GVNPassImpl::splitCriticalEdges() {
4209 if (ToSplit.empty())
4214 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
4216 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
4218 }
while (!ToSplit.empty());
4221 MD->invalidateCachedPredecessors();
4222 InvalidBlockRPONumbers =
true;
4228bool GVNPassImpl::iterateOnFunction(
Function &
F) {
4229 cleanupGlobalSets();
4236 ReversePostOrderTraversal<Function *> RPOT(&
F);
4238 for (BasicBlock *BB : RPOT)
4244void GVNPassImpl::cleanupGlobalSets() {
4246 LeaderTable.clear();
4247 BlockRPONumber.clear();
4249 InvalidBlockRPONumbers =
true;
4254 if (MD) MD->removeInstruction(
I);
4256 EA->removeInstruction(
I);
4258 MSSAU->removeMemoryAccess(
I);
4262 ICF->removeInstruction(
I);
4263 I->eraseFromParent();
4269void GVNPassImpl::verifyRemoved(
const Instruction *Inst)
const {
4270 VN.verifyRemoved(Inst);
4277void GVNPassImpl::addDeadBlock(
BasicBlock *BB) {
4279 SmallSetVector<BasicBlock *, 4>
DF;
4282 while (!NewDead.
empty()) {
4284 if (DeadBlocks.count(
D))
4288 SmallVector<BasicBlock *, 8> Dom;
4289 DT->getDescendants(
D, Dom);
4290 DeadBlocks.insert_range(Dom);
4293 for (BasicBlock *
B : Dom) {
4295 if (DeadBlocks.count(S))
4298 bool AllPredDead =
true;
4300 if (!DeadBlocks.count(
P)) {
4301 AllPredDead =
false;
4321 for (BasicBlock *
B :
DF) {
4322 if (DeadBlocks.count(
B))
4328 for (BasicBlock *
P : Preds) {
4329 if (!DeadBlocks.count(
P))
4334 if (BasicBlock *S = splitCriticalEdges(
P,
B))
4335 DeadBlocks.insert(
P = S);
4341 if (!DeadBlocks.count(
P))
4343 for (PHINode &Phi :
B->phis()) {
4346 MD->invalidateCachedPointerInfo(&Phi);
4365bool GVNPassImpl::processFoldableCondBr(
CondBrInst *BI) {
4376 if (DeadBlocks.count(DeadRoot))
4380 DeadRoot = splitCriticalEdges(BI->
getParent(), DeadRoot);
4382 addDeadBlock(DeadRoot);
4390void GVNPassImpl::assignValNumForDeadCode() {
4391 for (BasicBlock *BB : DeadBlocks) {
4392 for (Instruction &Inst : *BB) {
4393 unsigned ValNum = VN.lookupOrAdd(&Inst);
4394 LeaderTable.insert(ValNum, &Inst, BB);
4425 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Function Alias Analysis false
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static RegisterPass< DebugifyFunctionPass > DF("debugify-function", "Attach debug info to a function")
This file defines the DenseMap class.
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
early cse Early CSE w MemorySSA
This file provides a data structure for mapping values and expressions to congruence class IDs.
static Value * findDominatingValue(const ScalarOptions &Opts, const MemoryLocation &Loc, Type *LoadTy, Instruction *From, AAResults *AA)
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 const Instruction * findMayClobberedPtrAccess(LoadInst *Load, const DominatorTree *DT)
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...
GVNPassImpl::AvailableValue AvailableValue
static bool isOnlyReachableViaThisEdge(const BasicBlockEdge &E, DominatorTree *DT)
There is an edge from 'Src' to 'Dst'.
static bool isValueFullyAvailableInBlock(const ScalarOptions &Opts, 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 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 void patchAndReplaceAllUsesWith(Instruction *I, Value *Repl)
static void replaceValuesPerBlockEntry(SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, Value *OldValue, Value *NewValue)
If the specified OldValue exists in ValuesPerBlock, replace its value with NewValue.
GVNPassImpl::AvailableValueInBlock AvailableValueInBlock
@ Unavailable
We know the block is not fully available. This is a fixpoint.
@ Available
We know the block is fully available. This is a fixpoint.
@ SpeculativelyAvailable
We do not know whether the block is fully available or not, but we are currently speculating that it ...
static Value * constructSSAForLoadSet(LoadInst *Load, SmallVectorImpl< AvailableValueInBlock > &ValuesPerBlock, DominatorTree &DT)
Given a set of loads specified by ValuesPerBlock, construct SSA form, allowing us to eliminate Load.
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.
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.
This file contains the declarations for profiling metadata utility functions.
SmallVector< MachineOperand, 4 > Cond
static DominatorTree getDomTree(Function &F)
std::pair< BasicBlock *, BasicBlock * > Edge
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
static const uint32_t IV[8]
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
GVNLegacyPass(bool ScalarPRE=true)
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
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Value handle that asserts if the Value is deleted.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
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.
iterator find(const_arg_type_t< KeyT > Val)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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.
Context-sensitive CaptureAnalysis provider, which computes and caches the earliest common dominator c...
Class representing an expression and its matching format.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
const BasicBlock & getEntryBlock() const
Represents calls to the gc.relocate intrinsic.
leader_iterator & operator++()
bool operator!=(const leader_iterator &Other) const
leader_iterator(const LeaderListNode *C)
reference operator*() const
const LeaderTableEntry value_type
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
bool operator==(const leader_iterator &Other) const
A mapping from value numbers to lists of Value*'s that have that value number.
LLVM_ABI void insert(uint32_t N, Value *V, const BasicBlock *BB)
Push a new Value to the LeaderTable onto the list for its value number.
LLVM_ABI void erase(uint32_t N, Instruction *I, const BasicBlock *BB)
Scan the list of values corresponding to a given value number, and remove the given instruction if en...
iterator_range< leader_iterator > getLeaders(uint32_t N)
The core GVN pass object.
bool isMemDepEnabled() const
bool isScalarPREEnabled() const
bool isLoadPRESplitBackedgeEnabled() const
MemoryDependenceResults & getMemDep() const
AAResults * getAliasAnalysis() const
void salvageAndRemoveInstruction(Instruction *I)
This removes the specified instruction from our various maps and marks it for deletion.
bool isLoadInLoopPREEnabled() const
bool isLoadPREEnabled() const
bool isMemorySSAEnabled() const
DominatorTree & getDominatorTree() const
GVNPassImpl(llvm::GVNOptions Options={})
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI GVNPass(GVNOptions Options={})
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
Returns the value number of the given comparison, assigning it a new number if it did not have one be...
LLVM_ABI void erase(Value *V)
Remove a value from the value numbering.
LLVM_ABI uint32_t lookup(Value *V, bool Verify=true) const
Returns the value number of the specified value.
LLVM_ABI void add(Value *V, uint32_t Num)
add - Insert a value into the table with a specified value number.
LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock)
Erase stale entry from phiTranslate cache so phiTranslate can be computed again.
LLVM_ABI void verifyRemoved(const Value *) const
verifyRemoved - Verify that the value is removed from all internal data structures.
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock, uint32_t Num, GVNLeaderMap &LeaderTable)
Wrap phiTranslateImpl to provide caching functionality.
LLVM_ABI uint32_t lookupCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
LLVM_ABI void clear()
Remove all entries from the ValueTable.
LLVM_ABI bool exists(Value *V) const
Returns true if a value number exists for the specified value.
LLVM_ABI GVNValueTable & operator=(const GVNValueTable &Arg)
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty)
Returns the value number of ptrtoint Ptr to \Ty.
LLVM_ABI ~GVNValueTable()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Legacy wrapper pass to provide the GlobalsAAResult object.
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
This class allows to keep track on instructions with implicit control flow.
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.
LLVM_ABI bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
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.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool isIdenticalTo(const Instruction *I) const LLVM_READONLY
Return true if the specified instruction is exactly identical to the current one.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
The legacy pass manager's analysis pass to compute loop information.
This class implements a map that also provides access to all stored values in a deterministic order.
iterator find(const KeyT &Key)
A memory dependence query can return one of three different answers.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block,...
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
bool isLocal() const
Tests if this MemDepResult represents a valid local query (Clobber/Def).
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
This is the common base class for memset/memcpy/memmove.
BasicBlock * getBlock() const
An analysis that produces MemoryDependenceResults for a function.
Provides a lazy, caching interface for making common memory aliasing information queries,...
std::vector< NonLocalDepEntry > NonLocalDepInfo
LLVM_ABI 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.
MemoryAccess * getClobberingMemoryAccess(const Instruction *I, BatchAAResults &AA)
Given a memory Mod/Ref/ModRef'ing instruction, calling this will give you the nearest dominating Memo...
Legacy analysis pass which computes MemorySSA.
Encapsulates MemorySSA, including all data associated with memory accesses.
LLVM_ABI MemorySSAWalker * getSkipSelfWalker()
LLVM_ABI void verifyMemorySSA(VerificationLevel=VerificationLevel::Fast) const
Verify that MemorySSA is self consistent (IE definitions dominate all uses, uses appear in the right ...
LLVM_ABI MemorySSAWalker * getWalker()
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...
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool needsPHITranslationFromBlock(BasicBlock *BB) const
needsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
LLVM_ABI bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
std::pair< SelectInst *, SelectAddrs > getSelectAndAddrs() const
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
const Value * getTrueValue() const
A vector that has set insertion semantics.
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)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
Not(const Pred &P) -> Not< Pred >
LLVM_ABI int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
LLVM_ABI Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...
LLVM_ABI int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
LLVM_ABI Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
LLVM_ABI int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
LLVM_ABI bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
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.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
LLVM_ABI unsigned replaceDominatedUsesWithIf(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge, function_ref< bool(const Use &U, const Value *To)> ShouldReplace)
Replace each use of 'From' with 'To' if that use is dominated by the given edge and the callback Shou...
RelativeUniformCounterPtr Values
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createGVNPass(bool ScalarPRE)
Create a legacy GVN pass.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
@ Load
The value being inserted comes from a load (InsertElement only).
constexpr from_range_t from_range
LLVM_ABI bool isStorePreservingMemoryLocation(const StoreInst *SI, const MemoryLocation &MemLoc, Align MemLocAlign, BatchAAResults &AA, unsigned ScanLimit)
Check whether SI, which may alias MemLoc, can be safely skipped.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
LLVM_ABI bool isAssumeWithEmptyBundle(const AssumeInst &Assume)
Return true iff the operand bundles of the provided llvm.assume doesn't contain any valuable informat...
const ScalarOptions & getScalarOptions(const LLVMContext &C)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool canReplacePointersInUseIfEqual(const Use &U, const Value *To, const DataLayout &DL)
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
bool isModSet(const ModRefInfo MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl, bool DoesKMove=false)
Patch the replacement so that it is not more restrictive than the value being replaced.
LLVM_ABI void initializeGVNLegacyPassPass(PassRegistry &)
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
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...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
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.
LLVM_ABI bool willNotFreeBetween(const Instruction *Assume, const Instruction *CtxI, const DominatorTree *DT=nullptr)
Returns true, if no instruction between Assume and CtxI may free (including through synchronization).
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.
constexpr bool valueOr(BoolOrDefault X, bool Default)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
bool pred_empty(const BasicBlock *BB)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
LLVM_ABI bool EliminateDuplicatePHINodes(BasicBlock *BB)
Check for and eliminate duplicate PHI nodes in this block.
bool isStrongerThan(AtomicOrdering AO, AtomicOrdering Other)
Returns true if ao is stronger than other as defined by the AtomicOrdering lattice,...
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Represents an AvailableValue which can be rematerialized at the end of the associated BasicBlock.
AvailableValue AV
AV - The actual available value.
BasicBlock * BB
BB - The basic block in question.
static AvailableValueInBlock get(BasicBlock *BB, Value *V, unsigned Offset=0)
Value * MaterializeAdjustedValue(LoadInst *Load) const
Emit code at the end of this block to adjust the value defined here to the specified type.
static AvailableValueInBlock getUndef(BasicBlock *BB)
static AvailableValueInBlock get(BasicBlock *BB, AvailableValue &&AV)
Represents a particular available value that we know how to materialize.
bool isMemIntrinValue() const
Value * getSimpleValue() const
SelectInst * getSelectInstr() const
static AvailableValue getUndef()
Value * Val
Val - The value that is live out of the block.
ValType Kind
Kind of the live-out value.
bool isCoercedLoadValue() const
static AvailableValue getMI(MemIntrinsic *MI, unsigned Offset=0)
unsigned Offset
Offset - The byte offset in Val that is interesting for the load query.
LoadInst * getCoercedLoadValue() const
static AvailableValue get(Value *V, unsigned Offset=0)
bool isUndefValue() const
static AvailableValue getSelect(SelectInst *Sel, Value *V1, Value *V2)
bool isSelectValue() const
Value * V1
V1, V2 - The dominating non-clobbered values of SelectVal.
static AvailableValue getLoad(LoadInst *Load, unsigned Offset=0)
Value * MaterializeAdjustedValue(LoadInst *Load, Instruction *InsertPt) const
Emit code at the specified insertion point to adjust the value defined here to the specified type.
MemIntrinsic * getMemIntrinValue() const
bool isSimpleValue() const
This struct is a compact representation of a valid (non-zero power of two) alignment.
static unsigned getHashValue(const GVNValueTable::Expression &E)
static bool isEqual(const GVNValueTable::Expression &LHS, const GVNValueTable::Expression &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
LeaderTableEntry(Value *V, const BasicBlock *BB)
A set of parameters to control various transforms performed by GVN pass.
Expression(uint32_t Op=~2U)
SmallVector< uint32_t, 4 > VarArgs
bool operator==(const Expression &Other) const
friend hash_code hash_value(const Expression &Value)