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());
2765 return std::nullopt;
2766 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2768 if (AA.isMustAlias(IIObjLoc, Loc))
2769 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2770 return std::nullopt;
2778 if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.
Ptr))
2779 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2785 return std::nullopt;
2789 ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc);
2793 return std::nullopt;
2797 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2805 DependencyBlockSet &Blocks,
2816 if (!DT->isReachableFromEntry(Pred))
2820 if (
llvm::any_of(Preds, [Pred](
const auto &
P) {
return P.first == Pred; }))
2823 PHITransAddr TransAddr = Addr;
2827 auto It = Blocks.find(Pred);
2828 if (It != Blocks.end()) {
2832 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2839 Pred, DependencyBlockInfo(TransAddr,
2840 MPhi ? MPhi->getIncomingValueForBlock(Pred)
2847 for (
auto &
P : Preds) {
2848 [[maybe_unused]]
auto It =
2849 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2863 const DependencyBlockInfo &StartInfo,
2864 const DependencyBlockSet &Blocks,
2866 MemoryAccess *MA = StartInfo.InitialClobberMA;
2867 MemoryAccess *LastMA = StartInfo.ClobberMA;
2870 while (MA != LastMA) {
2884 BB = DT->getNode(BB)->getIDom()->getBlock();
2888 auto It = Blocks.find(BB);
2889 if (It == Blocks.end())
2892 MA = It->second.InitialClobberMA;
2893 LastMA = It->second.ClobberMA;
2894 if (MA == Clobbers.
back())
2911bool GVNPassImpl::findReachingValuesForLoad(
2914 EarliestEscapeAnalysis EA(*DT, LI);
2915 BatchAAResults AA(AAR, &EA);
2917 bool IsInvariantLoad =
L->hasMetadata(LLVMContext::MD_invariant_load);
2923 if (
L->hasMetadata(LLVMContext::MD_invariant_group)) {
2936 if (
auto RMV = scanMemoryAccessesUsers(
2937 Loc, IsInvariantLoad, StartBlock,
2939 Values.emplace_back(*RMV);
2950 accessMayModifyLocation(ClobberMA, Loc,
L->getAlign(),
2951 IsInvariantLoad, StartBlock, MSSA, AA)) {
2952 Values.emplace_back(*RMV);
2962 if (
L->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2963 L->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2972 DependencyBlockSet Blocks;
2973 SmallVector<BasicBlock *, 16> InitialWorklist;
2974 const DataLayout &
DL =
L->getDataLayout();
2975 if (!collectPredecessors(StartBlock,
2976 PHITransAddr(
L->getPointerOperand(),
DL, AC),
2977 ClobberMA, Blocks, InitialWorklist))
2981 auto Worklist = InitialWorklist;
2982 while (!Worklist.
empty()) {
2984 if (Blocks.size() > Opts.gvn_max_num_reaching_blocks)
2987 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
2990 if (!
Info.Addr.getAddr())
3000 accessMayModifyLocation(
Info.ClobberMA, BBLoc,
L->getAlign(),
3001 IsInvariantLoad, BB, MSSA, AA)) {
3006 "LiveOnEntry aliases everything");
3022 if (BB == StartBlock &&
Info.Addr.getAddr() !=
L->getPointerOperand()) {
3023 Info.ForceUnknown =
true;
3026 if (BB != StartBlock &&
3027 !collectPredecessors(BB,
Info.Addr,
Info.ClobberMA, Blocks, Worklist))
3028 Info.ForceUnknown =
true;
3038 Worklist = InitialWorklist;
3039 for (BasicBlock *BB : Worklist) {
3040 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3041 Info.Visited =
true;
3045 while (!Worklist.empty()) {
3046 auto *BB = Worklist.pop_back_val();
3047 DependencyBlockInfo &
Info = Blocks.find(BB)->second;
3051 if (!
Info.Addr.getAddr()) {
3052 Values.push_back(ReachingMemVal::getUnknown(BB,
nullptr));
3057 collectClobberList(Clobbers, BB, Info, Blocks, MSSA);
3060 IsInvariantLoad, BB, Clobbers, MSSA, AA)) {
3072 if (
Info.ForceUnknown) {
3073 Values.push_back(ReachingMemVal::getUnknown(BB,
Info.Addr.getAddr()));
3079 auto It = Blocks.find(Pred);
3080 if (It == Blocks.end())
3082 DependencyBlockInfo &PredInfo = It->second;
3083 if (PredInfo.Visited)
3085 PredInfo.Visited =
true;
3086 Worklist.push_back(Pred);
3095bool GVNPassImpl::processLoad(
LoadInst *L) {
3100 if (!
L->isUnordered())
3103 if (
L->getType()->isTokenLikeTy())
3106 if (
L->use_empty()) {
3111 ReachingMemVal MemVal = ReachingMemVal::getUnknown(
nullptr,
nullptr);
3114 MemDepResult Dep = MD->getDependency(L);
3118 return processNonLocalLoad(L);
3122 MemVal = ReachingMemVal::getDef(
L->getPointerOperand(), Dep.
getInst());
3125 ReachingMemVal::getClobber(
L->getPointerOperand(), Dep.
getInst());
3128 if (!findReachingValuesForLoad(L, MemVals, *MSSAU->getMemorySSA(), *AA))
3130 assert(MemVals.
size() &&
"Expected at least an unknown value");
3131 if (MemVals.
size() > 1 || MemVals[0].Block !=
L->getParent())
3132 return processNonLocalLoad(L, MemVals);
3134 MemVal = MemVals[0];
3137 if (MemVal.Kind == DepKind::Other) {
3141 dbgs() <<
"GVN: load ";
L->printAsOperand(
dbgs());
3142 dbgs() <<
" has unknown dependence\n";);
3146 auto AV = analyzeLoadAvailability(L, MemVal,
L->getPointerOperand());
3153 ICF->removeUsersOf(L);
3156 MSSAU->removeMemoryAccess(L);
3172 MemDepResult Dep = MD->getDependency(
I);
3178 Value *Passthrough =
I->getOperand(2);
3182 StoreVal->
getType() !=
I->getType())
3189 ICF->removeUsersOf(
I);
3190 I->replaceAllUsesWith(OpToForward);
3198std::pair<uint32_t, bool> GVNValueTable::assignExpNewValueNum(
Expression &Exp) {
3199 uint32_t &
E = ExpressionNumbering[
Exp];
3200 bool CreateNewValNum = !
E;
3201 if (CreateNewValNum) {
3202 Expressions.push_back(Exp);
3203 if (ExprIdx.size() < NextValueNumber + 1)
3204 ExprIdx.resize(NextValueNumber * 2);
3205 E = NextValueNumber;
3206 ExprIdx[NextValueNumber++] = NextExprNumber++;
3208 return {
E, CreateNewValNum};
3213bool GVNValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
3217 [=](
const GVNLeaderMap::LeaderTableEntry &L) { return L.BB == BB; });
3224 auto FindRes = PhiTranslateTable.find({Num, Pred});
3225 if (FindRes != PhiTranslateTable.end())
3226 return FindRes->second;
3227 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, LeaderTable);
3228 PhiTranslateTable.insert({{Num, Pred}, NewNum});
3240 for (
const auto &Entry : Leaders) {
3242 if (
Call &&
Call->getParent() == PhiBlock)
3246 if (
AA->doesNotAccessMemory(
Call))
3249 if (!MD || !
AA->onlyReadsMemory(
Call))
3261 if (
D.getResult().isNonFuncLocal())
3269uint32_t GVNValueTable::phiTranslateImpl(
const BasicBlock *Pred,
3275 if (PHINode *PN = NumberingPhi[Num]) {
3276 if (PN->getParent() != PhiBlock)
3278 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
3279 if (PN->getIncomingBlock(
I) != Pred)
3281 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
3287 if (BasicBlock *BB = NumberingBB[Num]) {
3288 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
3294 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
3301 if (MSSA->isLiveOnEntryDef(MA))
3306 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3312 if (!areAllValsInBB(Num, PhiBlock, LeaderTable))
3315 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3319 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3323 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3324 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3325 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3330 if (
Exp.Commutative) {
3331 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3332 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3334 uint32_t Opcode =
Exp.Opcode >> 8;
3335 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3336 Exp.Opcode = (Opcode << 8) |
3342 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3343 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3344 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, LeaderTable) ? NewNum
3356 PhiTranslateTable.erase({Num, Pred});
3366 if (Leaders.empty())
3369 Value *Val =
nullptr;
3370 for (
const auto &Entry : Leaders) {
3391 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
3392 assert((!Pred || Pred ==
E.getStart()) &&
3393 "No edge between these basic blocks!");
3394 return Pred !=
nullptr;
3397void GVNPassImpl::assignBlockRPONumber(
Function &
F) {
3398 BlockRPONumber.clear();
3399 uint32_t NextBlockNumber = 1;
3400 ReversePostOrderTraversal<Function *> RPOT(&
F);
3401 for (BasicBlock *BB : RPOT)
3402 BlockRPONumber[BB] = NextBlockNumber++;
3403 InvalidBlockRPONumbers =
false;
3411bool GVNPassImpl::propagateEquality(
3413 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3415 SmallDenseSet<std::pair<Value *, Value *>, 4> Visited;
3419 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3426 for (
const auto *Node : DT->getNode(
I->getParent())->children())
3430 while (!Worklist.
empty()) {
3431 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3432 LHS = Item.first;
RHS = Item.second;
3446 const DataLayout &
DL =
3455 uint32_t LVN = VN.lookupOrAdd(
LHS);
3460 uint32_t RVN = VN.lookupOrAdd(
RHS);
3467 if (!Visited.
insert({LHS, RHS}).second)
3480 for (
const BasicBlock *BB : DominatedBlocks)
3481 LeaderTable.insert(LVN,
RHS, BB);
3488 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3491 unsigned NumReplacements;
3492 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3494 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3497 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3498 CanReplacePointersCallBack);
3500 if (NumReplacements > 0) {
3502 NumGVNEqProp += NumReplacements;
3505 MD->invalidateCachedPointerInfo(
LHS);
3522 bool IsKnownFalse = !IsKnownTrue;
3538 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3543 if (
Cmp->isEquivalence(IsKnownFalse))
3544 Worklist.
push_back(std::make_pair(Op0, Op1));
3548 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3552 uint32_t NextNum = VN.getNextUnusedValueNumber();
3553 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
3556 if (Num < NextNum) {
3557 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
3562 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3563 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
3564 !DT->dominates(
Edge->getEnd(),
Entry.BB))
3567 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3568 if (!DT->dominates(
Entry.BB, InstBB) &&
3569 !DT->dominates(InstBB,
Entry.BB))
3575 unsigned NumReplacements;
3576 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3581 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3582 Changed |= NumReplacements > 0;
3583 NumGVNEqProp += NumReplacements;
3586 MD->invalidateCachedPointerInfo(NotCmp);
3594 for (
const BasicBlock *BB : DominatedBlocks)
3595 LeaderTable.insert(Num, NotVal, BB);
3604 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3609 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3617bool GVNPassImpl::replaceWithEquivalentCmp(
CmpInst *Cmp) {
3619 uint32_t Num = VN.lookupCmp(
Cmp->getOpcode(), Pred,
Cmp->getOperand(0),
3620 Cmp->getOperand(1));
3622 return findLeader(
Cmp->getParent(), Num);
3627 if (
Value *Repl = FindCmpLeader(
Cmp->getInversePredicate())) {
3630 Repl, Repl->getName() +
".not",
Cmp->getIterator());
3631 Not->setDebugLoc(
Cmp->getDebugLoc());
3632 Cmp->replaceAllUsesWith(Not);
3639 if (ICmp && ICmp->hasSameSign() && !ICmp->isEquality()) {
3640 if (
Value *Repl = FindCmpLeader(
3657 const DataLayout &
DL =
I->getDataLayout();
3660 if (!
I->use_empty()) {
3663 ICF->removeUsersOf(
I);
3664 I->replaceAllUsesWith(V);
3672 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3673 MD->invalidateCachedPointerInfo(V);
3680 return processAssumeIntrinsic(Assume);
3683 if (processLoad(
Load))
3686 unsigned Num = VN.lookupOrAdd(
Load);
3687 LeaderTable.insert(Num,
Load,
Load->getParent());
3699 return processFoldableCondBr(BI);
3701 Value *BranchCond = BI->getCondition();
3705 if (TrueSucc == FalseSucc)
3712 BasicBlockEdge TrueE(Parent, TrueSucc);
3713 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3716 BasicBlockEdge FalseE(Parent, FalseSucc);
3717 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3724 Value *SwitchCond =
SI->getCondition();
3729 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
3731 ++SwitchEdges[Succ];
3733 for (
const auto &Case :
SI->cases()) {
3736 if (SwitchEdges.
lookup(Dst) == 1) {
3737 BasicBlockEdge
E(Parent, Dst);
3738 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3746 if (
I->getType()->isVoidTy())
3749 uint32_t NextNum = VN.getNextUnusedValueNumber();
3750 unsigned Num = VN.lookupOrAdd(
I);
3755 LeaderTable.insert(Num,
I,
I->getParent());
3762 const DataLayout &
DL =
I->getDataLayout();
3763 unsigned AS = PTA->getPointerAddressSpace();
3764 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3765 !
DL.hasUnstableRepresentation(AS)) {
3767 VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
3768 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3780 Value *Repl = Num < NextNum ? findLeader(
I->getParent(), Num) : nullptr;
3786 LeaderTable.insert(Num,
I,
I->getParent());
3799 MD->invalidateCachedPointerInfo(Repl);
3814 Opts.enable_gvn_memoryssa)
3816 "mutually exclusive",
3823 VN.setAliasAnalysis(&RunAA);
3825 ImplicitControlFlowTracking ImplicitCFT;
3834 InvalidBlockRPONumbers =
true;
3835 MemorySSAUpdater Updater(MSSA);
3836 MSSAU = MSSA ? &Updater :
nullptr;
3839 bool ShouldContinue =
true;
3841 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
3853 unsigned Iteration = 0;
3854 while (ShouldContinue) {
3857 ShouldContinue = iterateOnFunction(
F);
3865 assignValNumForDeadCode();
3866 bool PREChanged =
true;
3867 while (PREChanged) {
3868 PREChanged = performPRE(
F);
3878 cleanupGlobalSets();
3889bool GVNPassImpl::processBlock(
BasicBlock *BB) {
3890 if (DeadBlocks.count(BB))
3893 bool ChangedFunction =
false;
3899 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
3901 for (PHINode *PN : PHINodesToRemove) {
3902 removeInstruction(PN);
3905 ChangedFunction |= processInstruction(&Inst);
3906 return ChangedFunction;
3910bool GVNPassImpl::performScalarPREInsertion(
Instruction *Instr,
3912 unsigned int ValNo) {
3918 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3926 if (!VN.exists(
Op)) {
3930 uint32_t TValNo = VN.phiTranslate(Pred, Curr, VN.lookup(
Op), LeaderTable);
3931 if (
Value *V = findLeader(Pred, TValNo)) {
3949 ICF->insertInstructionTo(Instr, Pred);
3951 unsigned Num = VN.lookupOrAdd(Instr);
3955 LeaderTable.insert(Num, Instr, Pred);
3959bool GVNPassImpl::performScalarPRE(
Instruction *CurInst) {
3985 if (CallB->isInlineAsm())
3989 uint32_t ValNo = VN.lookup(CurInst);
3997 unsigned NumWith = 0;
3998 unsigned NumWithout = 0;
4003 if (InvalidBlockRPONumbers)
4004 assignBlockRPONumber(*CurrentBlock->
getParent());
4010 if (!DT->isReachableFromEntry(
P)) {
4015 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
4016 "Invalid BlockRPONumber map.");
4017 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
4022 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, LeaderTable);
4023 Value *PredV = findLeader(
P, TValNo);
4028 }
else if (PredV == CurInst) {
4040 if (NumWithout > 1 || NumWith == 0)
4048 if (NumWithout != 0) {
4054 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
4067 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
4071 PREInstr = CurInst->
clone();
4072 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
4075 verifyRemoved(PREInstr);
4084 assert(PREInstr !=
nullptr || NumWithout == 0);
4090 CurInst->
getName() +
".pre-phi");
4091 Phi->insertBefore(CurrentBlock->begin());
4092 for (
auto &[V, BB] : PredMap) {
4097 Phi->addIncoming(V, BB);
4099 Phi->addIncoming(PREInstr, PREPred);
4105 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
4106 LeaderTable.insert(ValNo, Phi, CurrentBlock);
4109 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
4110 MD->invalidateCachedPointerInfo(Phi);
4111 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
4114 removeInstruction(CurInst);
4121bool GVNPassImpl::performPRE(
Function &
F) {
4123 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
4125 if (CurrentBlock == &
F.getEntryBlock())
4129 if (CurrentBlock->isEHPad())
4133 BE = CurrentBlock->end();
4136 Changed |= performScalarPRE(CurInst);
4140 if (splitCriticalEdges())
4154 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
4157 MD->invalidateCachedPredecessors();
4158 InvalidBlockRPONumbers =
true;
4165bool GVNPassImpl::splitCriticalEdges() {
4166 if (ToSplit.empty())
4171 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
4173 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
4175 }
while (!ToSplit.empty());
4178 MD->invalidateCachedPredecessors();
4179 InvalidBlockRPONumbers =
true;
4185bool GVNPassImpl::iterateOnFunction(
Function &
F) {
4186 cleanupGlobalSets();
4193 ReversePostOrderTraversal<Function *> RPOT(&
F);
4195 for (BasicBlock *BB : RPOT)
4201void GVNPassImpl::cleanupGlobalSets() {
4203 LeaderTable.clear();
4204 BlockRPONumber.clear();
4206 InvalidBlockRPONumbers =
true;
4211 if (MD) MD->removeInstruction(
I);
4213 MSSAU->removeMemoryAccess(
I);
4217 ICF->removeInstruction(
I);
4218 I->eraseFromParent();
4224void GVNPassImpl::verifyRemoved(
const Instruction *Inst)
const {
4225 VN.verifyRemoved(Inst);
4232void GVNPassImpl::addDeadBlock(
BasicBlock *BB) {
4234 SmallSetVector<BasicBlock *, 4>
DF;
4237 while (!NewDead.
empty()) {
4239 if (DeadBlocks.count(
D))
4243 SmallVector<BasicBlock *, 8> Dom;
4244 DT->getDescendants(
D, Dom);
4245 DeadBlocks.insert_range(Dom);
4248 for (BasicBlock *
B : Dom) {
4250 if (DeadBlocks.count(S))
4253 bool AllPredDead =
true;
4255 if (!DeadBlocks.count(
P)) {
4256 AllPredDead =
false;
4276 for (BasicBlock *
B :
DF) {
4277 if (DeadBlocks.count(
B))
4283 for (BasicBlock *
P : Preds) {
4284 if (!DeadBlocks.count(
P))
4289 if (BasicBlock *S = splitCriticalEdges(
P,
B))
4290 DeadBlocks.insert(
P = S);
4296 if (!DeadBlocks.count(
P))
4298 for (PHINode &Phi :
B->phis()) {
4301 MD->invalidateCachedPointerInfo(&Phi);
4320bool GVNPassImpl::processFoldableCondBr(
CondBrInst *BI) {
4331 if (DeadBlocks.count(DeadRoot))
4335 DeadRoot = splitCriticalEdges(BI->
getParent(), DeadRoot);
4337 addDeadBlock(DeadRoot);
4345void GVNPassImpl::assignValNumForDeadCode() {
4346 for (BasicBlock *BB : DeadBlocks) {
4347 for (Instruction &Inst : *BB) {
4348 unsigned ValNum = VN.lookupOrAdd(&Inst);
4349 LeaderTable.insert(ValNum, &Inst, BB);
4359 bool MemDepAnalysis =
valueOr(ScalarOptions::Global.enable_gvn_memdep,
4361 bool MemSSAAnalysis = ScalarOptions::Global.enable_gvn_memoryssa,
4362 bool ScalarPRE =
true)
4364 .setMemDep(MemDepAnalysis)
4365 .setMemorySSA(MemSSAAnalysis)
4366 .setScalarPRE(ScalarPRE)) {
4375 if (Impl.isMemorySSAEnabled() && !MSSAWP)
4383 Impl.isMemDepEnabled()
4388 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
4396 if (Impl.isMemDepEnabled())
4405 if (Impl.isMemorySSAEnabled())
4429 const ScalarOptions &Opts = ScalarOptions::Global;
4431 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 bool isDebugOrPseudoInst() const LLVM_READONLY
Return true if the instruction is a DbgInfoIntrinsic or PseudoProbeInst.
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)