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;
270 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);
1177 auto *MemDep = Impl->isMemDepEnabled()
1182 if (Impl->isMemorySSAEnabled() && !MSSA) {
1184 "On-demand computation of MemSSA implies that MemDep is disabled!");
1185 MSSA = &AM.getResult<MemorySSAAnalysis>(F);
1188 bool Changed = Impl->run(
F, AC, DT, TLI,
AA, MemDep, LI, &ORE,
1189 MSSA ? &MSSA->getMSSA() :
nullptr);
1204 removeInstruction(
I);
1210 OS, MapClassName2PassName);
1214 if (
Options.AllowScalarPRE != std::nullopt)
1215 OS << (*
Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
1216 if (
Options.AllowLoadPRE != std::nullopt)
1217 OS << (*
Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
1218 if (
Options.AllowLoadPRESplitBackedge != std::nullopt)
1219 OS << (*
Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
1220 <<
"split-backedge-load-pre;";
1221 if (
Options.AllowMemDep != std::nullopt)
1222 OS << (*
Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
1223 if (
Options.AllowMemorySSA != std::nullopt)
1224 OS << (*
Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
1252 std::optional<BasicBlock *> UnavailableBB;
1256 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
1264 while (!Worklist.
empty()) {
1268 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
1276 UnavailableBB = CurrBB;
1287 ++NumNewNewSpeculativelyAvailableBBs;
1289 NumNewNewSpeculativelyAvailableBBs > Opts.gvn_max_block_speculations;
1294 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1296 UnavailableBB = CurrBB;
1302 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1308#if LLVM_ENABLE_STATS
1309 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1310 NumNewNewSpeculativelyAvailableBBs);
1315 auto MarkAsFixpointAndEnqueueSuccessors =
1317 auto It = FullyAvailableBlocks.
find(BB);
1318 if (It == FullyAvailableBlocks.
end())
1325 State = FixpointState;
1328 "Found a speculatively available successor leftover?");
1336 if (UnavailableBB) {
1343 while (!Worklist.
empty())
1344 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1352 while (!Worklist.
empty())
1353 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1357 "Must have fixed all the new speculatively available blocks.");
1360 return !UnavailableBB;
1372 if (V.AV.Val == OldValue)
1373 V.AV.Val = NewValue;
1374 if (V.AV.isSelectValue()) {
1375 if (V.AV.V1 == OldValue)
1377 if (V.AV.V2 == OldValue)
1392 if (ValuesPerBlock.
size() == 1 &&
1394 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1395 "Dead BB dominate this block");
1396 return ValuesPerBlock[0].MaterializeAdjustedValue(
Load);
1407 if (AV.AV.isUndefValue())
1417 if (BB ==
Load->getParent() &&
1418 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() ==
Load) ||
1419 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() ==
Load)))
1436 if (Res->
getType() != LoadTy) {
1451 Load->getFunction());
1462 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1464 {LLVMContext::MD_dereferenceable,
1465 LLVMContext::MD_dereferenceable_or_null,
1466 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group,
1467 LLVMContext::MD_alias_scope, LLVMContext::MD_noalias});
1483 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1493 assert(Res &&
"failed to materialize?");
1499 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1516 Value *PtrOp =
Load->getPointerOperand();
1522 for (
auto *U : PtrOp->
users()) {
1543 for (
auto *U : PtrOp->
users()) {
1546 if (
I->getFunction() ==
Load->getFunction() &&
1554 OtherAccess =
nullptr;
1573 using namespace ore;
1576 R <<
"load of type " << NV(
"Type",
Load->getType()) <<
" not eliminated"
1581 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1583 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1598 for (
auto *Inst = BB == FromBB ? From : BB->getTerminator();
1601 if (++NumVisitedInsts > Opts.gvn_max_num_visited_insts)
1606 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1607 SI->getValueOperand()->getType() == LoadTy)
1608 return SI->getValueOperand();
1612 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1618std::optional<AvailableValue>
1623 "Invalid address type of true side of select dependency");
1625 "Invalid address type of false side of select dependency");
1633 return std::nullopt;
1637 return std::nullopt;
1641std::optional<AvailableValue>
1642GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
const ReachingMemVal &Dep,
1644 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1645 assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) &&
1646 "expected a local dependence");
1650 const DataLayout &
DL =
Load->getDataLayout();
1651 if (Dep.Kind == DepKind::Clobber) {
1657 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1674 Load->isAtomic() <= DepLoad->isAtomic()) {
1681 DepLoad->getFunction())) {
1682 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1684 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1690 DepLoad->getFunction()) ||
1717 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1721 return std::nullopt;
1723 assert(Dep.Kind == DepKind::Def &&
"follows from above");
1730 if (Constant *InitVal =
1740 return std::nullopt;
1743 if (S->isAtomic() <
Load->isAtomic())
1744 return std::nullopt;
1755 return std::nullopt;
1758 if (
LD->isAtomic() <
Load->isAtomic())
1759 return std::nullopt;
1772 return std::nullopt;
1779 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1780 return std::nullopt;
1783void GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
1785 AvailValInBlkVect &ValuesPerBlock,
1786 UnavailBlkVect &UnavailableBlocks) {
1791 for (
const auto &Dep : Deps) {
1794 if (DeadBlocks.count(DepBB)) {
1801 if (Dep.Kind == DepKind::Other) {
1802 UnavailableBlocks.push_back(DepBB);
1809 if (Dep.Kind == DepKind::Select) {
1810 if (
auto AV = analyzeSelectAvailability(
1811 Load, Dep.Sel,
const_cast<Value *
>(Dep.SelTrueAddr),
1813 ValuesPerBlock.push_back(
1816 UnavailableBlocks.push_back(DepBB);
1825 analyzeLoadAvailability(
Load, Dep,
const_cast<Value *
>(Dep.Addr))) {
1829 ValuesPerBlock.push_back(
1832 UnavailableBlocks.push_back(DepBB);
1836 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1837 "post condition violation");
1864 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1866 auto *SuccBB =
Term->getSuccessor(0);
1867 if (SuccBB == LoadBB)
1868 SuccBB =
Term->getSuccessor(1);
1869 if (!SuccBB->getSinglePredecessor())
1872 unsigned int NumInsts = Opts.gvn_max_num_insns;
1873 for (Instruction &Inst : *SuccBB) {
1876 if (--NumInsts == 0)
1882 bool HasLocalDep =
true;
1884 MemDepResult Dep = MD->getDependency(&Inst);
1887 auto *MSSA = MSSAU->getMemorySSA();
1889 if (
auto *MA = MSSA->getMemoryAccess(&Inst); MA &&
isa<MemoryUse>(MA)) {
1890 auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
1891 HasLocalDep = Clobber->getBlock() == SuccBB;
1899 if (!HasLocalDep && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1910void GVNPassImpl::eliminatePartiallyRedundantLoad(
1914 for (
const auto &AvailableLoad : AvailableLoads) {
1915 BasicBlock *UnavailableBlock = AvailableLoad.first;
1916 Value *LoadPtr = AvailableLoad.second;
1919 new LoadInst(
Load->getType(), LoadPtr,
Load->getName() +
".pre",
1920 Load->getProperties(),
1922 NewLoad->setDebugLoc(
Load->getDebugLoc());
1924 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1927 MSSAU->insertDef(NewDef,
true);
1933 AAMDNodes Tags =
Load->getAAMetadata();
1935 NewLoad->setAAMetadata(Tags);
1937 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1938 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1939 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1940 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1941 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1942 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1943 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1944 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
1946 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1947 if (LI->getLoopFor(
Load->getParent()) == LI->getLoopFor(UnavailableBlock))
1948 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1957 ValuesPerBlock.push_back(
1960 MD->invalidateCachedPointerInfo(LoadPtr);
1965 if (CriticalEdgePredAndLoad) {
1966 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1967 if (It != CriticalEdgePredAndLoad->
end()) {
1968 ++NumPRELoadMoved2CEPred;
1969 ICF->insertInstructionTo(NewLoad, UnavailableBlock);
1970 LoadInst *OldLoad = It->second;
1974 if (uint32_t ValNo = VN.lookup(OldLoad,
false))
1975 LeaderTable.erase(ValNo, OldLoad, OldLoad->
getParent());
1976 removeInstruction(OldLoad);
1984 ICF->removeUsersOf(
Load);
1985 Load->replaceAllUsesWith(V);
1989 I->setDebugLoc(
Load->getDebugLoc());
1990 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
1991 MD->invalidateCachedPointerInfo(V);
1994 <<
"load eliminated by PRE";
2000 AvailValInBlkVect &ValuesPerBlock,
2001 UnavailBlkVect &UnavailableBlocks) {
2010 SmallPtrSet<BasicBlock *, 4> Blockers(
llvm::from_range, UnavailableBlocks);
2032 bool MustEnsureSafetyOfSpeculativeExecution =
2033 ICF->isDominatedByICFIFromSameBlock(
Load);
2037 if (TmpBB == LoadBB)
2039 if (Blockers.count(TmpBB))
2051 MustEnsureSafetyOfSpeculativeExecution =
2052 MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
2060 MapVector<BasicBlock *, Value *> PredLoads;
2061 DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
2064 for (BasicBlock *UnavailableBB : UnavailableBlocks)
2072 MapVector<BasicBlock *, LoadInst *> CriticalEdgePredAndLoad;
2078 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
2090 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
2097 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
2104 if (DT->dominates(LoadBB, Pred)) {
2107 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
2112 if (LoadInst *LI = findLoadToHoistIntoPred(Pred, LoadBB,
Load))
2113 CriticalEdgePredAndLoad[Pred] = LI;
2118 PredLoads[Pred] =
nullptr;
2123 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
2124 unsigned NumUnavailablePreds = NumInsertPreds +
2125 CriticalEdgePredAndLoad.
size();
2126 assert(NumUnavailablePreds != 0 &&
2127 "Fully available value should already be eliminated!");
2128 (void)NumUnavailablePreds;
2134 if (NumInsertPreds > 1)
2139 if (MustEnsureSafetyOfSpeculativeExecution) {
2140 if (CriticalEdgePredSplit.
size())
2144 for (
auto &PL : PredLoads)
2148 for (
auto &CEP : CriticalEdgePredAndLoad)
2155 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
2156 BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
2157 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
2158 PredLoads[NewPred] =
nullptr;
2159 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
2160 << LoadBB->
getName() <<
'\n');
2163 for (
auto &CEP : CriticalEdgePredAndLoad)
2164 PredLoads[CEP.first] =
nullptr;
2167 bool CanDoPRE =
true;
2168 const DataLayout &
DL =
Load->getDataLayout();
2169 SmallVector<Instruction*, 8> NewInsts;
2170 for (
auto &PredLoad : PredLoads) {
2171 BasicBlock *UnavailablePred = PredLoad.first;
2181 Value *LoadPtr =
Load->getPointerOperand();
2183 while (Cur != LoadBB) {
2196 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
2203 << *
Load->getPointerOperand() <<
"\n");
2208 PredLoad.second = LoadPtr;
2212 while (!NewInsts.
empty()) {
2222 return !CriticalEdgePredSplit.empty();
2230 <<
" INSTS: " << *NewInsts.
back()
2234 for (Instruction *
I : NewInsts) {
2238 I->updateLocationAfterHoist();
2247 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, PredLoads,
2248 &CriticalEdgePredAndLoad);
2254 AvailValInBlkVect &ValuesPerBlock,
2255 UnavailBlkVect &UnavailableBlocks) {
2256 const Loop *
L = LI->getLoopFor(
Load->getParent());
2258 if (!L ||
L->getHeader() !=
Load->getParent())
2263 if (!Preheader || !Latch)
2266 Value *LoadPtr =
Load->getPointerOperand();
2268 if (!
L->isLoopInvariant(LoadPtr))
2274 if (ICF->isDominatedByICFIFromSameBlock(
Load))
2278 for (
auto *Blocker : UnavailableBlocks) {
2280 if (!
L->contains(Blocker))
2292 if (L != LI->getLoopFor(Blocker))
2300 if (DT->dominates(Blocker, Latch))
2304 if (Blocker->getTerminator()->mayWriteToMemory())
2307 LoopBlock = Blocker;
2325 MapVector<BasicBlock *, Value *> AvailableLoads;
2326 AvailableLoads[LoopBlock] = LoadPtr;
2327 AvailableLoads[Preheader] = LoadPtr;
2330 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, AvailableLoads,
2338 using namespace ore;
2342 <<
"load of type " << NV(
"Type",
Load->getType()) <<
" eliminated"
2343 << setExtraArgs() <<
" in favor of "
2352 if (
Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2353 Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2358 MD->getNonLocalPointerDependency(
Load, Deps);
2363 unsigned NumDeps = Deps.size();
2364 if (NumDeps > Opts.gvn_max_num_deps)
2370 for (
const NonLocalDepResult &Dep : Deps) {
2371 const auto &
R = Dep.getResult();
2372 SelectAddr SelAddr = Dep.getAddress();
2378 ReachingMemVal::getSelect(BB, Sel, Addrs.first, Addrs.second));
2390 return processNonLocalLoad(
Load, MemVals);
2397 if (Deps.
size() == 1 && Deps[0].Kind == DepKind::Other) {
2399 dbgs() <<
" has unknown dependencies\n";);
2407 if (GetElementPtrInst *
GEP =
2409 for (Use &U :
GEP->indices())
2419 AvailValInBlkVect ValuesPerBlock;
2420 UnavailBlkVect UnavailableBlocks;
2421 analyzeLoadAvailability(
Load, Deps, ValuesPerBlock, UnavailableBlocks);
2425 if (ValuesPerBlock.empty())
2433 if (UnavailableBlocks.empty()) {
2439 ICF->removeUsersOf(
Load);
2440 Load->replaceAllUsesWith(V);
2448 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2449 I->setDebugLoc(
Load->getDebugLoc());
2450 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2451 MD->invalidateCachedPointerInfo(V);
2464 if (performLoopLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks) ||
2465 performLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks))
2471bool GVNPassImpl::processAssumeIntrinsic(
AssumeInst *IntrinsicI) {
2475 if (
Cond->isZero()) {
2485 const MemoryUseOrDef *FirstNonDom =
nullptr;
2487 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2494 for (
const auto &Acc : *AL) {
2496 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2497 FirstNonDom = Current;
2504 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2506 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2507 : MSSAU->createMemoryAccessInBB(
2529 return propagateEquality(V,
True, IntrinsicI);
2534 I->replaceAllUsesWith(Repl);
2541 Value *PointerOperand = L->getPointerOperand()->stripPointerCasts();
2552 PointerUsesQueue.
push_back(PointerOperand);
2557 while (!PointerUsesQueue.
empty()) {
2560 "Null or GlobalValue should not be inserted");
2564 if (!
I ||
I == L || !DT.
dominates(
I, MostDominatingInstruction))
2579 if (
I->hasMetadata(LLVMContext::MD_invariant_group) &&
2581 MostDominatingInstruction =
I;
2585 return MostDominatingInstruction != L ? MostDominatingInstruction :
nullptr;
2591static std::optional<MemoryLocation>
2598 switch (
II->getIntrinsicID()) {
2599 case Intrinsic::masked_load:
2601 case Intrinsic::masked_store:
2604 return std::nullopt;
2611 return std::nullopt;
2615 return std::nullopt;
2621std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::scanMemoryAccessesUsers(
2627 auto UpdateChoice = [&](std::optional<ReachingMemVal> &Choice,
2631 Choice = ReachingMemVal::getClobber(Loc.
Ptr, Candidate, AR.getOffset());
2633 Choice = ReachingMemVal::getDef(Loc.
Ptr, Candidate);
2641 Choice->Kind = DepKind::Clobber;
2642 Choice->Offset = AR.getOffset();
2644 Choice->Kind = DepKind::Def;
2645 Choice->Offset = -1;
2648 Choice->Inst = Candidate;
2649 Choice->Block = Candidate->getParent();
2652 std::optional<ReachingMemVal> ReachingVal;
2653 for (MemoryAccess *MA : ClobbersList) {
2655 for (User *U : MA->
users()) {
2656 if (++Scanned >= Opts.gvn_scan_users_limit)
2657 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2660 if (!UseOrDef || UseOrDef->getBlock() != BB)
2669 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2683 UpdateChoice(ReachingVal, AR, MemI);
2695std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::accessMayModifyLocation(
2705 if (
Alloc->getParent() == BB)
2706 return ReachingMemVal::getDef(Loc.
Ptr,
const_cast<AllocaInst *
>(
Alloc));
2707 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2711 if (IsInvariantLoad || AA.pointsToConstantMemory(Loc))
2712 return std::nullopt;
2716 return L->getOrdering();
2723 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2725 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2736 return std::nullopt;
2737 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2742 return std::nullopt;
2748 Opts.gvn_max_num_insns))
2749 return std::nullopt;
2754 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2759 "Must be the superset/partial overlap case with positive offset");
2760 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI, AR.
getOffset());
2764 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2766 if (AA.isMustAlias(IIObjLoc, Loc))
2767 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2768 return std::nullopt;
2776 if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.
Ptr))
2777 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2783 return std::nullopt;
2787 ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc);
2791 return std::nullopt;
2795 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2803 DependencyBlockSet &Blocks,
2814 if (!DT->isReachableFromEntry(Pred))
2818 if (
llvm::any_of(Preds, [Pred](
const auto &
P) {
return P.first == Pred; }))
2821 PHITransAddr TransAddr = Addr;
2825 auto It = Blocks.find(Pred);
2826 if (It != Blocks.end()) {
2830 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2837 Pred, DependencyBlockInfo(TransAddr,
2838 MPhi ? MPhi->getIncomingValueForBlock(Pred)
2845 for (
auto &
P : Preds) {
2846 [[maybe_unused]]
auto It =
2847 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2861 const DependencyBlockInfo &StartInfo,
2862 const DependencyBlockSet &Blocks,
2864 MemoryAccess *MA = StartInfo.InitialClobberMA;
2865 MemoryAccess *LastMA = StartInfo.ClobberMA;
2868 while (MA != LastMA) {
2882 BB = DT->getNode(BB)->getIDom()->getBlock();
2886 auto It = Blocks.find(BB);
2887 if (It == Blocks.end())
2890 MA = It->second.InitialClobberMA;
2891 LastMA = It->second.ClobberMA;
2892 if (MA == Clobbers.
back())
2909bool GVNPassImpl::findReachingValuesForLoad(
2912 EarliestEscapeAnalysis EA(*DT, LI);
2913 BatchAAResults AA(AAR, &EA);
2915 bool IsInvariantLoad =
L->hasMetadata(LLVMContext::MD_invariant_load);
2921 if (
L->hasMetadata(LLVMContext::MD_invariant_group)) {
2934 if (
auto RMV = scanMemoryAccessesUsers(
2935 Loc, IsInvariantLoad, StartBlock,
2937 Values.emplace_back(*RMV);
2948 accessMayModifyLocation(ClobberMA, Loc,
L->getAlign(),
2949 IsInvariantLoad, StartBlock, MSSA, AA)) {
2950 Values.emplace_back(*RMV);
2960 if (
L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2961 L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2970 DependencyBlockSet Blocks;
2971 SmallVector<BasicBlock *, 16> InitialWorklist;
2972 const DataLayout &
DL =
L->getDataLayout();
2973 if (!collectPredecessors(StartBlock,
2974 PHITransAddr(
L->getPointerOperand(),
DL, AC),
2975 ClobberMA, Blocks, InitialWorklist))
2979 auto Worklist = InitialWorklist;
2980 while (!Worklist.
empty()) {
2982 if (Blocks.size() > Opts.gvn_max_num_reaching_blocks)
2985 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
2988 if (!
Info.Addr.getAddr())
2998 accessMayModifyLocation(
Info.ClobberMA, BBLoc,
L->getAlign(),
2999 IsInvariantLoad, BB, MSSA, AA)) {
3004 "LiveOnEntry aliases everything");
3020 if (BB == StartBlock &&
Info.Addr.getAddr() !=
L->getPointerOperand()) {
3021 Info.ForceUnknown =
true;
3024 if (BB != StartBlock &&
3025 !collectPredecessors(BB,
Info.Addr,
Info.ClobberMA, Blocks, Worklist))
3026 Info.ForceUnknown =
true;
3036 Worklist = InitialWorklist;
3037 for (BasicBlock *BB : Worklist) {
3038 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3039 Info.Visited =
true;
3043 while (!Worklist.empty()) {
3044 auto *BB = Worklist.pop_back_val();
3045 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3049 if (!
Info.Addr.getAddr()) {
3050 Values.push_back(ReachingMemVal::getUnknown(BB,
nullptr));
3055 collectClobberList(Clobbers, BB, Info, Blocks, MSSA);
3058 IsInvariantLoad, BB, Clobbers, MSSA, AA)) {
3070 if (
Info.ForceUnknown) {
3071 Values.push_back(ReachingMemVal::getUnknown(BB,
Info.Addr.getAddr()));
3077 auto It = Blocks.find(Pred);
3078 if (It == Blocks.end())
3080 DependencyBlockInfo &PredInfo = It->second;
3081 if (PredInfo.Visited)
3083 PredInfo.Visited =
true;
3084 Worklist.push_back(Pred);
3093bool GVNPassImpl::processLoad(
LoadInst *L) {
3098 if (!
L->isUnordered())
3101 if (
L->getType()->isTokenLikeTy())
3104 if (
L->use_empty()) {
3109 ReachingMemVal MemVal = ReachingMemVal::getUnknown(
nullptr,
nullptr);
3112 MemDepResult Dep = MD->getDependency(L);
3116 return processNonLocalLoad(L);
3120 MemVal = ReachingMemVal::getDef(
L->getPointerOperand(), Dep.
getInst());
3123 ReachingMemVal::getClobber(
L->getPointerOperand(), Dep.
getInst());
3126 if (!findReachingValuesForLoad(L, MemVals, *MSSAU->getMemorySSA(), *AA))
3128 assert(MemVals.
size() &&
"Expected at least an unknown value");
3129 if (MemVals.
size() > 1 || MemVals[0].Block !=
L->getParent())
3130 return processNonLocalLoad(L, MemVals);
3132 MemVal = MemVals[0];
3135 if (MemVal.Kind == DepKind::Other) {
3139 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
3140 dbgs() <<
" has unknown dependence\n";);
3144 auto AV = analyzeLoadAvailability(L, MemVal,
L->getPointerOperand());
3151 ICF->removeUsersOf(L);
3154 MSSAU->removeMemoryAccess(L);
3170 MemDepResult Dep = MD->getDependency(
I);
3176 Value *Passthrough =
I->getOperand(2);
3180 StoreVal->
getType() !=
I->getType())
3187 ICF->removeUsersOf(
I);
3188 I->replaceAllUsesWith(OpToForward);
3196std::pair<uint32_t, bool> GVNValueTable::assignExpNewValueNum(
Expression &Exp) {
3197 uint32_t &
E = ExpressionNumbering[
Exp];
3198 bool CreateNewValNum = !
E;
3199 if (CreateNewValNum) {
3200 Expressions.push_back(Exp);
3201 if (ExprIdx.size() < NextValueNumber + 1)
3202 ExprIdx.resize(NextValueNumber * 2);
3203 E = NextValueNumber;
3204 ExprIdx[NextValueNumber++] = NextExprNumber++;
3206 return {
E, CreateNewValNum};
3211bool GVNValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
3215 [=](
const GVNLeaderMap::LeaderTableEntry &L) { return L.BB == BB; });
3222 auto FindRes = PhiTranslateTable.find({Num, Pred});
3223 if (FindRes != PhiTranslateTable.end())
3224 return FindRes->second;
3225 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, LeaderTable);
3226 PhiTranslateTable.insert({{Num, Pred}, NewNum});
3238 for (
const auto &Entry : Leaders) {
3240 if (
Call &&
Call->getParent() == PhiBlock)
3244 if (
AA->doesNotAccessMemory(
Call))
3247 if (!MD || !
AA->onlyReadsMemory(
Call))
3259 if (
D.getResult().isNonFuncLocal())
3267uint32_t GVNValueTable::phiTranslateImpl(
const BasicBlock *Pred,
3273 if (PHINode *PN = NumberingPhi[Num]) {
3274 if (PN->getParent() != PhiBlock)
3276 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
3277 if (PN->getIncomingBlock(
I) != Pred)
3279 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
3285 if (BasicBlock *BB = NumberingBB[Num]) {
3286 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
3292 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
3299 if (MSSA->isLiveOnEntryDef(MA))
3304 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3310 if (!areAllValsInBB(Num, PhiBlock, LeaderTable))
3313 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3317 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3321 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3322 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3323 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3328 if (
Exp.Commutative) {
3329 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3330 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3332 uint32_t Opcode =
Exp.Opcode >> 8;
3333 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3334 Exp.Opcode = (Opcode << 8) |
3340 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3341 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3342 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, LeaderTable) ? NewNum
3354 PhiTranslateTable.erase({Num, Pred});
3364 if (Leaders.empty())
3367 Value *Val =
nullptr;
3368 for (
const auto &Entry : Leaders) {
3389 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
3390 assert((!Pred || Pred ==
E.getStart()) &&
3391 "No edge between these basic blocks!");
3392 return Pred !=
nullptr;
3395void GVNPassImpl::assignBlockRPONumber(
Function &
F) {
3396 BlockRPONumber.clear();
3397 uint32_t NextBlockNumber = 1;
3398 ReversePostOrderTraversal<Function *> RPOT(&
F);
3399 for (BasicBlock *BB : RPOT)
3400 BlockRPONumber[BB] = NextBlockNumber++;
3401 InvalidBlockRPONumbers =
false;
3409bool GVNPassImpl::propagateEquality(
3411 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3413 SmallDenseSet<std::pair<Value *, Value *>, 4> Visited;
3417 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3424 for (
const auto *Node : DT->getNode(
I->getParent())->children())
3428 while (!Worklist.
empty()) {
3429 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3430 LHS = Item.first;
RHS = Item.second;
3444 const DataLayout &
DL =
3453 uint32_t LVN = VN.lookupOrAdd(
LHS);
3458 uint32_t RVN = VN.lookupOrAdd(
RHS);
3465 if (!Visited.
insert({LHS, RHS}).second)
3478 for (
const BasicBlock *BB : DominatedBlocks)
3479 LeaderTable.insert(LVN,
RHS, BB);
3486 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3489 unsigned NumReplacements;
3490 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3492 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3495 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3496 CanReplacePointersCallBack);
3498 if (NumReplacements > 0) {
3500 NumGVNEqProp += NumReplacements;
3503 MD->invalidateCachedPointerInfo(
LHS);
3520 bool IsKnownFalse = !IsKnownTrue;
3536 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3541 if (
Cmp->isEquivalence(IsKnownFalse))
3542 Worklist.
push_back(std::make_pair(Op0, Op1));
3546 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3550 uint32_t NextNum = VN.getNextUnusedValueNumber();
3551 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
3554 if (Num < NextNum) {
3555 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
3560 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3561 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
3562 !DT->dominates(
Edge->getEnd(),
Entry.BB))
3565 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3566 if (!DT->dominates(
Entry.BB, InstBB) &&
3567 !DT->dominates(InstBB,
Entry.BB))
3573 unsigned NumReplacements;
3574 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3579 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3580 Changed |= NumReplacements > 0;
3581 NumGVNEqProp += NumReplacements;
3584 MD->invalidateCachedPointerInfo(NotCmp);
3592 for (
const BasicBlock *BB : DominatedBlocks)
3593 LeaderTable.insert(Num, NotVal, BB);
3602 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3607 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3615bool GVNPassImpl::replaceWithEquivalentCmp(
CmpInst *Cmp) {
3617 uint32_t Num = VN.lookupCmp(
Cmp->getOpcode(), Pred,
Cmp->getOperand(0),
3618 Cmp->getOperand(1));
3620 return findLeader(
Cmp->getParent(), Num);
3625 if (
Value *Repl = FindCmpLeader(
Cmp->getInversePredicate())) {
3628 Repl, Repl->getName() +
".not",
Cmp->getIterator());
3629 Not->setDebugLoc(
Cmp->getDebugLoc());
3630 Cmp->replaceAllUsesWith(Not);
3637 if (ICmp && ICmp->hasSameSign() && !ICmp->isEquality()) {
3638 if (
Value *Repl = FindCmpLeader(
3655 const DataLayout &
DL =
I->getDataLayout();
3658 if (!
I->use_empty()) {
3661 ICF->removeUsersOf(
I);
3662 I->replaceAllUsesWith(V);
3670 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3671 MD->invalidateCachedPointerInfo(V);
3678 return processAssumeIntrinsic(Assume);
3681 if (processLoad(
Load))
3684 unsigned Num = VN.lookupOrAdd(
Load);
3685 LeaderTable.insert(Num,
Load,
Load->getParent());
3697 return processFoldableCondBr(BI);
3699 Value *BranchCond = BI->getCondition();
3703 if (TrueSucc == FalseSucc)
3710 BasicBlockEdge TrueE(Parent, TrueSucc);
3711 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3714 BasicBlockEdge FalseE(Parent, FalseSucc);
3715 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3722 Value *SwitchCond =
SI->getCondition();
3727 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
3729 ++SwitchEdges[Succ];
3731 for (
const auto &Case :
SI->cases()) {
3734 if (SwitchEdges.
lookup(Dst) == 1) {
3735 BasicBlockEdge
E(Parent, Dst);
3736 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3744 if (
I->getType()->isVoidTy())
3747 uint32_t NextNum = VN.getNextUnusedValueNumber();
3748 unsigned Num = VN.lookupOrAdd(
I);
3753 LeaderTable.insert(Num,
I,
I->getParent());
3760 const DataLayout &
DL =
I->getDataLayout();
3761 unsigned AS = PTA->getPointerAddressSpace();
3762 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3763 !
DL.hasUnstableRepresentation(AS)) {
3765 VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
3766 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3778 Value *Repl = Num < NextNum ? findLeader(
I->getParent(), Num) : nullptr;
3784 LeaderTable.insert(Num,
I,
I->getParent());
3797 MD->invalidateCachedPointerInfo(Repl);
3812 Opts.enable_gvn_memoryssa)
3814 "mutually exclusive",
3821 VN.setAliasAnalysis(&RunAA);
3823 ImplicitControlFlowTracking ImplicitCFT;
3832 InvalidBlockRPONumbers =
true;
3833 MemorySSAUpdater Updater(MSSA);
3834 MSSAU = MSSA ? &Updater :
nullptr;
3837 bool ShouldContinue =
true;
3839 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
3851 unsigned Iteration = 0;
3852 while (ShouldContinue) {
3855 ShouldContinue = iterateOnFunction(
F);
3863 assignValNumForDeadCode();
3864 bool PREChanged =
true;
3865 while (PREChanged) {
3866 PREChanged = performPRE(
F);
3876 cleanupGlobalSets();
3887bool GVNPassImpl::processBlock(
BasicBlock *BB) {
3888 if (DeadBlocks.count(BB))
3891 bool ChangedFunction =
false;
3897 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
3899 for (PHINode *PN : PHINodesToRemove) {
3900 removeInstruction(PN);
3903 ChangedFunction |= processInstruction(&Inst);
3904 return ChangedFunction;
3908bool GVNPassImpl::performScalarPREInsertion(
Instruction *Instr,
3910 unsigned int ValNo) {
3916 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3924 if (!VN.exists(
Op)) {
3928 uint32_t TValNo = VN.phiTranslate(Pred, Curr, VN.lookup(
Op), LeaderTable);
3929 if (
Value *V = findLeader(Pred, TValNo)) {
3947 ICF->insertInstructionTo(Instr, Pred);
3949 unsigned Num = VN.lookupOrAdd(Instr);
3953 LeaderTable.insert(Num, Instr, Pred);
3957bool GVNPassImpl::performScalarPRE(
Instruction *CurInst) {
3983 if (CallB->isInlineAsm())
3987 uint32_t ValNo = VN.lookup(CurInst);
3995 unsigned NumWith = 0;
3996 unsigned NumWithout = 0;
4001 if (InvalidBlockRPONumbers)
4002 assignBlockRPONumber(*CurrentBlock->
getParent());
4008 if (!DT->isReachableFromEntry(
P)) {
4013 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
4014 "Invalid BlockRPONumber map.");
4015 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
4020 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, LeaderTable);
4021 Value *PredV = findLeader(
P, TValNo);
4026 }
else if (PredV == CurInst) {
4038 if (NumWithout > 1 || NumWith == 0)
4046 if (NumWithout != 0) {
4052 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
4065 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
4069 PREInstr = CurInst->
clone();
4070 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
4073 verifyRemoved(PREInstr);
4082 assert(PREInstr !=
nullptr || NumWithout == 0);
4088 CurInst->
getName() +
".pre-phi");
4089 Phi->insertBefore(CurrentBlock->begin());
4090 for (
auto &[V, BB] : PredMap) {
4095 Phi->addIncoming(V, BB);
4097 Phi->addIncoming(PREInstr, PREPred);
4103 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
4104 LeaderTable.insert(ValNo, Phi, CurrentBlock);
4107 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
4108 MD->invalidateCachedPointerInfo(Phi);
4109 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
4112 removeInstruction(CurInst);
4119bool GVNPassImpl::performPRE(
Function &
F) {
4121 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
4123 if (CurrentBlock == &
F.getEntryBlock())
4127 if (CurrentBlock->isEHPad())
4131 BE = CurrentBlock->end();
4134 Changed |= performScalarPRE(CurInst);
4138 if (splitCriticalEdges())
4152 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
4155 MD->invalidateCachedPredecessors();
4156 InvalidBlockRPONumbers =
true;
4163bool GVNPassImpl::splitCriticalEdges() {
4164 if (ToSplit.empty())
4169 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
4171 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
4173 }
while (!ToSplit.empty());
4176 MD->invalidateCachedPredecessors();
4177 InvalidBlockRPONumbers =
true;
4183bool GVNPassImpl::iterateOnFunction(
Function &
F) {
4184 cleanupGlobalSets();
4191 ReversePostOrderTraversal<Function *> RPOT(&
F);
4193 for (BasicBlock *BB : RPOT)
4199void GVNPassImpl::cleanupGlobalSets() {
4201 LeaderTable.clear();
4202 BlockRPONumber.clear();
4204 InvalidBlockRPONumbers =
true;
4209 if (MD) MD->removeInstruction(
I);
4211 MSSAU->removeMemoryAccess(
I);
4215 ICF->removeInstruction(
I);
4216 I->eraseFromParent();
4222void GVNPassImpl::verifyRemoved(
const Instruction *Inst)
const {
4223 VN.verifyRemoved(Inst);
4230void GVNPassImpl::addDeadBlock(
BasicBlock *BB) {
4232 SmallSetVector<BasicBlock *, 4>
DF;
4235 while (!NewDead.
empty()) {
4237 if (DeadBlocks.count(
D))
4241 SmallVector<BasicBlock *, 8> Dom;
4242 DT->getDescendants(
D, Dom);
4243 DeadBlocks.insert_range(Dom);
4246 for (BasicBlock *
B : Dom) {
4248 if (DeadBlocks.count(S))
4251 bool AllPredDead =
true;
4253 if (!DeadBlocks.count(
P)) {
4254 AllPredDead =
false;
4274 for (BasicBlock *
B :
DF) {
4275 if (DeadBlocks.count(
B))
4281 for (BasicBlock *
P : Preds) {
4282 if (!DeadBlocks.count(
P))
4287 if (BasicBlock *S = splitCriticalEdges(
P,
B))
4288 DeadBlocks.insert(
P = S);
4294 if (!DeadBlocks.count(
P))
4296 for (PHINode &Phi :
B->phis()) {
4299 MD->invalidateCachedPointerInfo(&Phi);
4318bool GVNPassImpl::processFoldableCondBr(
CondBrInst *BI) {
4329 if (DeadBlocks.count(DeadRoot))
4333 DeadRoot = splitCriticalEdges(BI->
getParent(), DeadRoot);
4335 addDeadBlock(DeadRoot);
4343void GVNPassImpl::assignValNumForDeadCode() {
4344 for (BasicBlock *BB : DeadBlocks) {
4345 for (Instruction &Inst : *BB) {
4346 unsigned ValNum = VN.lookupOrAdd(&Inst);
4347 LeaderTable.insert(ValNum, &Inst, BB);
4357 bool MemDepAnalysis =
valueOr(ScalarOptions::Global.enable_gvn_memdep,
4359 bool MemSSAAnalysis = ScalarOptions::Global.enable_gvn_memoryssa,
4360 bool ScalarPRE =
true)
4362 .setMemDep(MemDepAnalysis)
4363 .setMemorySSA(MemSSAAnalysis)
4364 .setScalarPRE(ScalarPRE)) {
4373 if (Impl.isMemorySSAEnabled() && !MSSAWP)
4381 Impl.isMemDepEnabled()
4386 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
4394 if (Impl.isMemDepEnabled())
4403 if (Impl.isMemorySSAEnabled())
4427 const ScalarOptions &Opts = ScalarOptions::Global;
4429 Opts.enable_gvn_memoryssa, ScalarPRE);
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.
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]
GVNLegacyPass(bool MemDepAnalysis=valueOr(ScalarOptions::Global.enable_gvn_memdep, true), bool MemSSAAnalysis=ScalarOptions::Global.enable_gvn_memoryssa, bool ScalarPRE=true)
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.
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.
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.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
bool hasMetadata() const
Return true if this instruction has any metadata attached to it.
LLVM_ABI bool isAtomic() const LLVM_READONLY
Return true if this instruction has an AtomicOrdering of unordered or higher.
bool isEHPad() const
Return true if the instruction is a variety of EH-block.
LLVM_ABI bool mayHaveSideEffects() const LLVM_READONLY
Return true if the instruction may have side effects.
bool isTerminator() const
LLVM_ABI bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
LLVM_ABI void dropUnknownNonDebugMetadata(ArrayRef< unsigned > KnownIDs={})
Drop all unknown metadata except for debug locations.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
LLVM_ABI bool isIdenticalTo(const Instruction *I) const LLVM_READONLY
Return true if the specified instruction is exactly identical to the current one.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Analysis pass that exposes the LoopInfo for a function.
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 ...
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...
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
LLVM_ABI bool canReplacePointersInUseIfEqual(const Use &U, const Value *To, const DataLayout &DL)
LLVM_ABI bool canReplacePointersIfEqual(const Value *From, const Value *To, const DataLayout &DL)
Returns true if a pointer value From can be replaced with another pointer value \To if they are deeme...
bool isModSet(const ModRefInfo MRI)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
LLVM_ABI void patchReplacementInstruction(Instruction *I, Value *Repl)
Patch the replacement so that it is not more restrictive than the value being replaced.
LLVM_ABI void initializeGVNLegacyPassPass(PassRegistry &)
LLVM_ABI unsigned replaceDominatedUsesWith(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge)
Replace each use of 'From' with 'To' if that use is dominated by the given edge.
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)
@ Global
Append to llvm.global_dtors.
LLVM_ABI void combineMetadataForCSE(Instruction *K, const Instruction *J, bool DoesKMove)
Combine the metadata of two instructions so that K can replace J.
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
@ Ref
The access may reference the value stored in memory.
@ NoModRef
The access neither references nor modifies the value stored in memory.
LLVM_ABI bool VerifyMemorySSA
Enables verification of MemorySSA.
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
LLVM_ABI bool salvageKnowledge(Instruction *I, AssumptionCache *AC=nullptr, DominatorTree *DT=nullptr)
Calls BuildAssumeFromInst and if the resulting llvm.assume is valid insert if before I.
LLVM_ABI bool MergeBlockIntoPredecessor(BasicBlock *BB, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, MemoryDependenceResults *MemDep=nullptr, bool PredecessorWithTwoSuccessors=false, DominatorTree *DT=nullptr)
Attempts to merge a block into its predecessor, if possible.
LLVM_ABI FunctionPass * createGVNPass()
LLVM_ABI bool isPotentiallyReachable(const Instruction *From, const Instruction *To, const SmallPtrSetImpl< BasicBlock * > *ExclusionSet=nullptr, const DominatorTree *DT=nullptr, const LoopInfo *LI=nullptr, const CycleInfo *CI=nullptr)
Determine whether instruction 'To' is reachable from 'From', without passing through any blocks in Ex...
DWARFExpression::Operation Op
LLVM_ABI BasicBlock * SplitCriticalEdge(Instruction *TI, unsigned SuccNum, const CriticalEdgeSplittingOptions &Options=CriticalEdgeSplittingOptions(), const Twine &BBName="")
If this edge is a critical edge, insert a new node to split the critical edge.
LLVM_ABI bool isCriticalEdge(const Instruction *TI, unsigned SuccNum, bool AllowIdenticalEdges=false)
Return true if the specified edge is a critical edge.
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)