92#define DEBUG_TYPE "gvn"
94STATISTIC(NumGVNInstr,
"Number of instructions deleted");
96STATISTIC(NumGVNPRE,
"Number of instructions PRE'd");
98STATISTIC(NumGVNSimpl,
"Number of instructions simplified");
99STATISTIC(NumGVNEqProp,
"Number of equalities propagated");
103 "Number of loads moved to predecessor of a critical edge in PRE");
105STATISTIC(IsValueFullyAvailableInBlockNumSpeculationsMax,
106 "Number of blocks speculated as available in "
107 "IsValueFullyAvailableInBlock(), max");
109 "Number of times we we reached gvn-max-block-speculations cut-off "
110 "preventing further exploration");
133 if ((!
Attrs.isEmpty() || !
Other.Attrs.isEmpty()) &&
134 !
Attrs.intersectWith(
Ty->getContext(),
Other.Attrs).has_value())
172 struct LeaderListNode {
173 LeaderTableEntry Entry;
174 LeaderListNode *
Next;
178 DenseMap<uint32_t, LeaderListNode> NumToLeaders;
183 const LeaderListNode *Current;
194 assert(Current &&
"Dereferenced end of leader list!");
195 Current = Current->Next;
199 return Current ==
Other.Current;
202 return Current !=
Other.Current;
208 auto I = NumToLeaders.find(
N);
209 if (
I == NumToLeaders.end()) {
223 for (
auto &[
_, HeadNode] : NumToLeaders) {
224 LeaderListNode *
N = HeadNode.Next;
226 auto *
Next =
N->Next;
227 N->~LeaderListNode();
231 NumToLeaders.clear();
232 TableAllocator.Reset();
243 const ScalarOptions *Opts =
nullptr;
269 friend class ::GVNLegacyPass;
294 bool InvalidBlockRPONumbers =
true;
317 struct ReachingMemVal {
326 const Value *SelTrueAddr =
nullptr;
327 const Value *SelFalseAddr =
nullptr;
331 return {DepKind::Other, BB, Addr, Inst, -1};
334 static ReachingMemVal getDef(
const Value *Addr, Instruction *Inst) {
335 return {DepKind::Def, Inst->getParent(), Addr, Inst, -1};
338 static ReachingMemVal getClobber(
const Value *Addr, Instruction *Inst,
339 int32_t Offset = -1) {
340 return {DepKind::Clobber, Inst->getParent(), Addr, Inst, Offset};
343 static ReachingMemVal getSelect(BasicBlock *BB, SelectInst *Sel,
344 const Value *TrueAddr,
345 const Value *FalseAddr) {
346 return {DepKind::Select, BB,
nullptr,
nullptr, -1, Sel,
347 TrueAddr, FalseAddr};
351 struct DependencyBlockInfo {
352 DependencyBlockInfo() =
delete;
353 DependencyBlockInfo(
const PHITransAddr &Addr, MemoryAccess *ClobberMA)
354 : Addr(Addr), InitialClobberMA(ClobberMA), ClobberMA(ClobberMA),
357 MemoryAccess *InitialClobberMA;
358 MemoryAccess *ClobberMA;
359 std::optional<ReachingMemVal> MemVal;
360 bool ForceUnknown : 1;
364 using DependencyBlockSet = DenseMap<BasicBlock *, DependencyBlockInfo>;
366 std::optional<GVNPassImpl::ReachingMemVal> scanMemoryAccessesUsers(
367 const MemoryLocation &Loc,
bool IsInvariantLoad, BasicBlock *BB,
368 const SmallVectorImpl<MemoryAccess *> &ClobbersList,
MemorySSA &MSSA,
369 BatchAAResults &AA, LoadInst *L =
nullptr);
371 std::optional<GVNPassImpl::ReachingMemVal>
372 accessMayModifyLocation(MemoryAccess *ClobberMA,
const MemoryLocation &Loc,
373 Align LoadAlign,
bool IsInvariantLoad, BasicBlock *BB,
376 bool collectPredecessors(BasicBlock *BB,
const PHITransAddr &Addr,
377 MemoryAccess *ClobberMA, DependencyBlockSet &Blocks,
378 SmallVectorImpl<BasicBlock *> &Worklist);
380 void collectClobberList(SmallVectorImpl<MemoryAccess *> &Clobbers,
381 BasicBlock *BB,
const DependencyBlockInfo &StartInfo,
382 const DependencyBlockSet &Blocks,
MemorySSA &MSSA);
384 bool findReachingValuesForLoad(LoadInst *Inst,
385 SmallVectorImpl<ReachingMemVal> &
Values,
389 bool processLoad(LoadInst *L);
390 bool processMaskedLoad(IntrinsicInst *
I);
391 bool processNonLocalLoad(LoadInst *L);
392 bool processNonLocalLoad(LoadInst *L, SmallVectorImpl<ReachingMemVal> &Deps);
393 bool processAssumeIntrinsic(AssumeInst *
II);
397 std::optional<AvailableValue>
398 analyzeLoadAvailability(LoadInst *
Load,
const ReachingMemVal &Dep,
405 std::optional<AvailableValue>
406 analyzeSelectAvailability(LoadInst *
Load, SelectInst *Sel,
Value *TrueAddr,
407 Value *FalseAddr, Instruction *From);
412 void analyzeLoadAvailability(LoadInst *
Load,
413 SmallVectorImpl<ReachingMemVal> &Deps,
414 AvailValInBlkVect &ValuesPerBlock,
415 UnavailBlkVect &UnavailableBlocks);
419 LoadInst *findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
422 bool performLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
423 UnavailBlkVect &UnavailableBlocks);
428 bool performLoopLoadPRE(LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
429 UnavailBlkVect &UnavailableBlocks);
433 void eliminatePartiallyRedundantLoad(
434 LoadInst *
Load, AvailValInBlkVect &ValuesPerBlock,
435 MapVector<BasicBlock *, Value *> &AvailableLoads,
436 MapVector<BasicBlock *, LoadInst *> *CriticalEdgePredAndLoad);
439 bool processInstruction(Instruction *
I);
440 bool processBlock(BasicBlock *BB);
441 bool replaceWithEquivalentCmp(CmpInst *Cmp);
444 bool performScalarPRE(Instruction *
I);
445 bool performScalarPREInsertion(Instruction *Instr, BasicBlock *Pred,
446 BasicBlock *Curr,
unsigned int ValNo);
447 Value *findLeader(
const BasicBlock *BB, uint32_t Num);
448 void cleanupGlobalSets();
449 void removeInstruction(Instruction *
I);
450 void verifyRemoved(
const Instruction *
I)
const;
451 bool splitCriticalEdges();
452 BasicBlock *splitCriticalEdges(BasicBlock *Pred, BasicBlock *Succ);
455 const std::variant<BasicBlockEdge, Instruction *> &Root);
456 bool processFoldableCondBr(CondBrInst *BI);
457 void addDeadBlock(BasicBlock *BB);
458 void assignValNumForDeadCode();
490 Res.
Kind = ValType::SimpleVal;
498 Res.
Kind = ValType::MemIntrin;
506 Res.
Kind = ValType::LoadVal;
514 Res.
Kind = ValType::UndefVal;
522 Res.
Kind = ValType::SelectVal;
572 Res.
AV = std::move(
AV);
588 return AV.MaterializeAdjustedValue(
Load,
BB->getTerminator());
599 E.Opcode =
I->getOpcode();
604 E.VarArgs.push_back(
lookupOrAdd(GCR->getOperand(0)));
605 E.VarArgs.push_back(
lookupOrAdd(GCR->getBasePtr()));
606 E.VarArgs.push_back(
lookupOrAdd(GCR->getDerivedPtr()));
608 for (
Use &
Op :
I->operands())
611 if (
I->isCommutative()) {
616 assert(
I->getNumOperands() >= 2 &&
"Unsupported commutative instruction!");
617 if (
E.VarArgs[0] >
E.VarArgs[1])
619 E.Commutative =
true;
623 E.VarArgs.append(IVI->idx_begin(), IVI->idx_end());
625 ArrayRef<int> ShuffleMask = SVI->getShuffleMask();
626 E.VarArgs.append(ShuffleMask.
begin(), ShuffleMask.
end());
628 E.Attrs = CB->getAttributes();
637 assert((Opcode == Instruction::ICmp || Opcode == Instruction::FCmp) &&
638 "Not a comparison!");
645 if (
E.VarArgs[0] >
E.VarArgs[1]) {
649 E.Opcode = (Opcode << 8) | Predicate;
650 E.Commutative =
true;
656 assert(EI &&
"Not an ExtractValueInst?");
685 Type *PtrTy =
GEP->getType()->getScalarType();
686 const DataLayout &
DL =
GEP->getDataLayout();
687 unsigned BitWidth =
DL.getIndexTypeSizeInBits(PtrTy);
688 SmallMapVector<Value *, APInt, 4> VariableOffsets;
690 if (
GEP->collectOffset(
DL,
BitWidth, VariableOffsets, ConstantOffset)) {
694 E.Opcode =
GEP->getOpcode();
697 for (
const auto &[V, Scale] : VariableOffsets) {
701 if (!ConstantOffset.isZero())
707 E.Opcode =
GEP->getOpcode();
708 E.Ty =
GEP->getSourceElementType();
709 for (Use &
Op :
GEP->operands())
727 ValueNumbering.insert(std::make_pair(V, Num));
729 NumberingPhi[Num] = PN;
739 assert(MSSA &&
"addMemoryStateToExp should not be called without MemorySSA");
753 if (
C->getFunction()->isPresplitCoroutine()) {
754 ValueNumbering[
C] = NextValueNumber;
755 return NextValueNumber++;
761 if (
C->isConvergent()) {
762 ValueNumbering[
C] = NextValueNumber;
763 return NextValueNumber++;
769 if (
C->hasOperandBundles()) {
770 ValueNumbering[
C] = NextValueNumber;
771 return NextValueNumber++;
774 if (AA->doesNotAccessMemory(
C)) {
776 uint32_t
E = assignExpNewValueNum(Exp).first;
777 ValueNumbering[
C] =
E;
781 if (MD && AA->onlyReadsMemory(
C)) {
783 auto [
E, IsValNumNew] = assignExpNewValueNum(Exp);
785 ValueNumbering[
C] =
E;
789 MemDepResult LocalDep = MD->getDependency(
C);
792 ValueNumbering[
C] = NextValueNumber;
793 return NextValueNumber++;
796 if (LocalDep.
isDef()) {
801 if (!LocalDepCall || LocalDepCall->
arg_size() !=
C->arg_size()) {
802 ValueNumbering[
C] = NextValueNumber;
803 return NextValueNumber++;
806 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
809 if (CVN != LocalDepCallVN) {
810 ValueNumbering[
C] = NextValueNumber;
811 return NextValueNumber++;
816 ValueNumbering[
C] =
V;
822 MD->getNonLocalCallDependency(
C);
824 CallInst *CDep =
nullptr;
828 for (
const NonLocalDepEntry &
I : Deps) {
829 if (
I.getResult().isNonLocal())
834 if (!
I.getResult().isDef() || CDep !=
nullptr) {
841 if (NonLocalDepCall && DT->properlyDominates(
I.getBB(),
C->getParent())) {
842 CDep = NonLocalDepCall;
851 ValueNumbering[
C] = NextValueNumber;
852 return NextValueNumber++;
856 ValueNumbering[
C] = NextValueNumber;
857 return NextValueNumber++;
859 for (
unsigned I = 0,
E =
C->arg_size();
I <
E; ++
I) {
863 ValueNumbering[
C] = NextValueNumber;
864 return NextValueNumber++;
869 ValueNumbering[
C] =
V;
873 if (MSSA && IsMSSAEnabled && AA->onlyReadsMemory(
C)) {
875 addMemoryStateToExp(
C, Exp);
876 auto [
V,
_] = assignExpNewValueNum(Exp);
877 ValueNumbering[
C] =
V;
881 ValueNumbering[
C] = NextValueNumber;
882 return NextValueNumber++;
886uint32_t GVNValueTable::computeLoadStoreVN(
Instruction *
I) {
887 if (!MSSA || !IsMSSAEnabled) {
888 ValueNumbering[
I] = NextValueNumber;
889 return NextValueNumber++;
893 Exp.Ty =
I->getType();
894 Exp.Opcode =
I->getOpcode();
895 for (Use &
Op :
I->operands())
897 addMemoryStateToExp(
I, Exp);
899 auto [
V,
_] = assignExpNewValueNum(Exp);
900 ValueNumbering[
I] =
V;
906 return ValueNumbering.contains(V);
918 auto VI = ValueNumbering.find(V);
919 if (VI != ValueNumbering.end())
924 ValueNumbering[V] = NextValueNumber;
927 return NextValueNumber++;
931 switch (
I->getOpcode()) {
932 case Instruction::Call:
934 case Instruction::FNeg:
935 case Instruction::Add:
936 case Instruction::FAdd:
937 case Instruction::Sub:
938 case Instruction::FSub:
939 case Instruction::Mul:
940 case Instruction::FMul:
941 case Instruction::UDiv:
942 case Instruction::SDiv:
943 case Instruction::FDiv:
944 case Instruction::URem:
945 case Instruction::SRem:
946 case Instruction::FRem:
947 case Instruction::Shl:
948 case Instruction::LShr:
949 case Instruction::AShr:
950 case Instruction::And:
951 case Instruction::Or:
952 case Instruction::Xor:
953 case Instruction::Trunc:
954 case Instruction::ZExt:
955 case Instruction::SExt:
956 case Instruction::FPToUI:
957 case Instruction::FPToSI:
958 case Instruction::UIToFP:
959 case Instruction::SIToFP:
960 case Instruction::FPTrunc:
961 case Instruction::FPExt:
962 case Instruction::PtrToInt:
963 case Instruction::PtrToAddr:
964 case Instruction::IntToPtr:
965 case Instruction::AddrSpaceCast:
966 case Instruction::BitCast:
967 case Instruction::Select:
968 case Instruction::Freeze:
969 case Instruction::ExtractElement:
970 case Instruction::InsertElement:
971 case Instruction::ShuffleVector:
972 case Instruction::InsertValue:
975 case Instruction::ICmp:
976 case Instruction::FCmp:
978 I->getOperand(0),
I->getOperand(1));
980 case Instruction::GetElementPtr:
983 case Instruction::ExtractValue:
986 case Instruction::PHI:
987 ValueNumbering[V] = NextValueNumber;
989 return NextValueNumber++;
990 case Instruction::Load:
991 case Instruction::Store:
992 return computeLoadStoreVN(
I);
994 ValueNumbering[V] = NextValueNumber;
995 return NextValueNumber++;
998 uint32_t E = assignExpNewValueNum(Exp).first;
999 ValueNumbering[V] = E;
1006 auto VI = ValueNumbering.find(V);
1008 assert(VI != ValueNumbering.end() &&
"Value not numbered?");
1011 return (VI != ValueNumbering.end()) ? VI->second : 0;
1021 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1022 return assignExpNewValueNum(Exp).first;
1027 Expression Exp = createCmpExpr(Opcode, Predicate, LHS, RHS);
1028 return ExpressionNumbering.lookup(Exp);
1036 return ExpressionNumbering.lookup(Exp);
1041 ValueNumbering.clear();
1042 ExpressionNumbering.clear();
1043 NumberingPhi.clear();
1044 NumberingBB.clear();
1045 PhiTranslateTable.clear();
1046 NextValueNumber = 1;
1047 Expressions.clear();
1054 uint32_t Num = ValueNumbering.lookup(V);
1055 ValueNumbering.erase(V);
1058 NumberingPhi.erase(Num);
1060 NumberingBB.erase(Num);
1066 assert(!ValueNumbering.contains(V) &&
1067 "Inst still occurs in value numbering map!");
1076 const auto &[It, Inserted] = NumToLeaders.try_emplace(
N, V, BB,
nullptr);
1079 auto *NewSlot = TableAllocator.Allocate<LeaderListNode>();
1080 new (NewSlot) LeaderListNode(V, BB, It->second.Next);
1081 It->second.Next = NewSlot;
1088 auto It = NumToLeaders.find(
N);
1089 if (It == NumToLeaders.end())
1092 LeaderListNode *Prev =
nullptr;
1093 LeaderListNode *Curr = &It->second;
1095 while (Curr && (Curr->Entry.Val !=
I || Curr->Entry.BB != BB)) {
1105 Prev->Next = Curr->Next;
1106 Curr->~LeaderListNode();
1107 TableAllocator.Deallocate<LeaderListNode>(Curr);
1112 NumToLeaders.erase(It);
1115 LeaderListNode *
Next = Curr->Next;
1116 Curr->Entry.Val = std::move(
Next->Entry.Val);
1117 Curr->Entry.BB =
Next->Entry.BB;
1118 Curr->Next =
Next->Next;
1119 Next->~LeaderListNode();
1120 TableAllocator.Deallocate<LeaderListNode>(
Next);
1130 return Options.AllowScalarPRE.value_or(Opts->enable_scalar_pre);
1134 return Options.AllowLoadPRE.value_or(Opts->enable_load_pre);
1138 return Options.AllowLoadInLoopPRE.value_or(Opts->enable_load_in_loop_pre);
1142 return Options.AllowLoadPRESplitBackedge.value_or(
1143 Opts->enable_split_backedge_in_load_pre);
1151 return Options.AllowMemDep.value_or(
false);
1152 return Options.AllowMemDep.value_or(
valueOr(Opts->enable_gvn_memdep,
true));
1156 return Options.AllowMemorySSA.value_or(Opts->enable_gvn_memoryssa);
1178 auto *MemDep = Impl->isMemDepEnabled()
1183 if (Impl->isMemorySSAEnabled() && !MSSA) {
1185 "On-demand computation of MemSSA implies that MemDep is disabled!");
1186 MSSA = &AM.getResult<MemorySSAAnalysis>(F);
1189 bool Changed = Impl->run(
F, AC, DT, TLI,
AA, MemDep, LI, &ORE,
1190 MSSA ? &MSSA->getMSSA() :
nullptr);
1205 removeInstruction(
I);
1211 OS, MapClassName2PassName);
1215 if (
Options.AllowScalarPRE != std::nullopt)
1216 OS << (*
Options.AllowScalarPRE ?
"" :
"no-") <<
"scalar-pre;";
1217 if (
Options.AllowLoadPRE != std::nullopt)
1218 OS << (*
Options.AllowLoadPRE ?
"" :
"no-") <<
"load-pre;";
1219 if (
Options.AllowLoadPRESplitBackedge != std::nullopt)
1220 OS << (*
Options.AllowLoadPRESplitBackedge ?
"" :
"no-")
1221 <<
"split-backedge-load-pre;";
1222 if (
Options.AllowMemDep != std::nullopt)
1223 OS << (*
Options.AllowMemDep ?
"" :
"no-") <<
"memdep;";
1224 if (
Options.AllowMemorySSA != std::nullopt)
1225 OS << (*
Options.AllowMemorySSA ?
"" :
"no-") <<
"memoryssa";
1253 std::optional<BasicBlock *> UnavailableBB;
1257 unsigned NumNewNewSpeculativelyAvailableBBs = 0;
1265 while (!Worklist.
empty()) {
1269 std::pair<DenseMap<BasicBlock *, AvailabilityState>::iterator,
bool>
IV =
1277 UnavailableBB = CurrBB;
1288 ++NumNewNewSpeculativelyAvailableBBs;
1290 NumNewNewSpeculativelyAvailableBBs > Opts.gvn_max_block_speculations;
1295 MaxBBSpeculationCutoffReachedTimes += (int)OutOfBudget;
1297 UnavailableBB = CurrBB;
1303 NewSpeculativelyAvailableBBs.
insert(CurrBB);
1309#if LLVM_ENABLE_STATS
1310 IsValueFullyAvailableInBlockNumSpeculationsMax.updateMax(
1311 NumNewNewSpeculativelyAvailableBBs);
1316 auto MarkAsFixpointAndEnqueueSuccessors =
1318 auto It = FullyAvailableBlocks.
find(BB);
1319 if (It == FullyAvailableBlocks.
end())
1326 State = FixpointState;
1329 "Found a speculatively available successor leftover?");
1337 if (UnavailableBB) {
1344 while (!Worklist.
empty())
1345 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1353 while (!Worklist.
empty())
1354 MarkAsFixpointAndEnqueueSuccessors(Worklist.
pop_back_val(),
1358 "Must have fixed all the new speculatively available blocks.");
1361 return !UnavailableBB;
1373 if (V.AV.Val == OldValue)
1374 V.AV.Val = NewValue;
1375 if (V.AV.isSelectValue()) {
1376 if (V.AV.V1 == OldValue)
1378 if (V.AV.V2 == OldValue)
1393 if (ValuesPerBlock.
size() == 1 &&
1395 assert(!ValuesPerBlock[0].AV.isUndefValue() &&
1396 "Dead BB dominate this block");
1397 return ValuesPerBlock[0].MaterializeAdjustedValue(
Load);
1408 if (AV.AV.isUndefValue())
1418 if (BB ==
Load->getParent() &&
1419 ((AV.AV.isSimpleValue() && AV.AV.getSimpleValue() ==
Load) ||
1420 (AV.AV.isCoercedLoadValue() && AV.AV.getCoercedLoadValue() ==
Load)))
1437 if (Res->
getType() != LoadTy) {
1452 Load->getFunction());
1463 if (!CoercedLoad->
hasMetadata(LLVMContext::MD_noundef))
1465 {LLVMContext::MD_dereferenceable,
1466 LLVMContext::MD_dereferenceable_or_null,
1467 LLVMContext::MD_invariant_load, LLVMContext::MD_invariant_group,
1468 LLVMContext::MD_alias_scope, LLVMContext::MD_noalias});
1484 assert(
V1 &&
V2 &&
"both value operands of the select must be present");
1494 assert(Res &&
"failed to materialize?");
1500 return II->getIntrinsicID() == Intrinsic::lifetime_start;
1517 Value *PtrOp =
Load->getPointerOperand();
1523 for (
auto *U : PtrOp->
users()) {
1544 for (
auto *U : PtrOp->
users()) {
1547 if (
I->getFunction() ==
Load->getFunction() &&
1555 OtherAccess =
nullptr;
1574 using namespace ore;
1577 R <<
"load of type " << NV(
"Type",
Load->getType()) <<
" not eliminated"
1582 R <<
" in favor of " << NV(
"OtherAccess", OtherAccess);
1584 R <<
" because it is clobbered by " << NV(
"ClobberedBy", DepInst);
1599 for (
auto *Inst = BB == FromBB ? From : BB->getTerminator();
1602 if (++NumVisitedInsts > Opts.gvn_max_num_visited_insts)
1607 if (
SI->isSimple() &&
SI->getPointerOperand() ==
Loc.Ptr &&
1608 SI->getValueOperand()->getType() == LoadTy)
1609 return SI->getValueOperand();
1613 if (LI->getPointerOperand() ==
Loc.Ptr && LI->getType() == LoadTy)
1619std::optional<AvailableValue>
1624 "Invalid address type of true side of select dependency");
1626 "Invalid address type of false side of select dependency");
1634 return std::nullopt;
1638 return std::nullopt;
1642std::optional<AvailableValue>
1643GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
const ReachingMemVal &Dep,
1645 assert(
Load->isUnordered() &&
"rules below are incorrect for ordered access");
1646 assert((Dep.Kind == DepKind::Def || Dep.Kind == DepKind::Clobber) &&
1647 "expected a local dependence");
1651 const DataLayout &
DL =
Load->getDataLayout();
1652 if (Dep.Kind == DepKind::Clobber) {
1658 if (
Address &&
Load->isAtomic() <= DepSI->isAtomic()) {
1675 Load->isAtomic() <= DepLoad->isAtomic()) {
1682 DepLoad->getFunction())) {
1683 const auto ClobberOff = MD->getClobberOffset(DepLoad);
1685 Offset = (ClobberOff == std::nullopt || *ClobberOff < 0)
1691 DepLoad->getFunction()) ||
1718 dbgs() <<
" is clobbered by " << *DepInst <<
'\n';);
1722 return std::nullopt;
1724 assert(Dep.Kind == DepKind::Def &&
"follows from above");
1731 if (Constant *InitVal =
1741 return std::nullopt;
1744 if (S->isAtomic() <
Load->isAtomic())
1745 return std::nullopt;
1756 return std::nullopt;
1759 if (
LD->isAtomic() <
Load->isAtomic())
1760 return std::nullopt;
1773 return std::nullopt;
1780 dbgs() <<
" has unknown def " << *DepInst <<
'\n';);
1781 return std::nullopt;
1784void GVNPassImpl::analyzeLoadAvailability(
LoadInst *
Load,
1786 AvailValInBlkVect &ValuesPerBlock,
1787 UnavailBlkVect &UnavailableBlocks) {
1792 for (
const auto &Dep : Deps) {
1795 if (DeadBlocks.count(DepBB)) {
1802 if (Dep.Kind == DepKind::Other) {
1803 UnavailableBlocks.push_back(DepBB);
1810 if (Dep.Kind == DepKind::Select) {
1811 if (
auto AV = analyzeSelectAvailability(
1812 Load, Dep.Sel,
const_cast<Value *
>(Dep.SelTrueAddr),
1814 ValuesPerBlock.push_back(
1817 UnavailableBlocks.push_back(DepBB);
1826 analyzeLoadAvailability(
Load, Dep,
const_cast<Value *
>(Dep.Addr))) {
1830 ValuesPerBlock.push_back(
1833 UnavailableBlocks.push_back(DepBB);
1837 assert(Deps.size() == ValuesPerBlock.size() + UnavailableBlocks.size() &&
1838 "post condition violation");
1865 if (
Term->getNumSuccessors() != 2 ||
Term->isSpecialTerminator())
1867 auto *SuccBB =
Term->getSuccessor(0);
1868 if (SuccBB == LoadBB)
1869 SuccBB =
Term->getSuccessor(1);
1870 if (!SuccBB->getSinglePredecessor())
1873 unsigned int NumInsts = Opts->gvn_max_num_insns;
1874 for (Instruction &Inst : *SuccBB) {
1877 if (--NumInsts == 0)
1883 bool HasLocalDep =
true;
1885 MemDepResult Dep = MD->getDependency(&Inst);
1888 auto *MSSA = MSSAU->getMemorySSA();
1890 if (
auto *MA = MSSA->getMemoryAccess(&Inst); MA &&
isa<MemoryUse>(MA)) {
1891 auto *Clobber = MSSA->getWalker()->getClobberingMemoryAccess(MA);
1892 HasLocalDep = Clobber->getBlock() == SuccBB;
1900 if (!HasLocalDep && !ICF->isDominatedByICFIFromSameBlock(&Inst))
1911void GVNPassImpl::eliminatePartiallyRedundantLoad(
1915 for (
const auto &AvailableLoad : AvailableLoads) {
1916 BasicBlock *UnavailableBlock = AvailableLoad.first;
1917 Value *LoadPtr = AvailableLoad.second;
1920 new LoadInst(
Load->getType(), LoadPtr,
Load->getName() +
".pre",
1921 Load->getProperties(),
1923 NewLoad->setDebugLoc(
Load->getDebugLoc());
1925 auto *NewAccess = MSSAU->createMemoryAccessInBB(
1928 MSSAU->insertDef(NewDef,
true);
1934 AAMDNodes Tags =
Load->getAAMetadata();
1936 NewLoad->setAAMetadata(Tags);
1938 if (
auto *MD =
Load->getMetadata(LLVMContext::MD_invariant_load))
1939 NewLoad->setMetadata(LLVMContext::MD_invariant_load, MD);
1940 if (
auto *InvGroupMD =
Load->getMetadata(LLVMContext::MD_invariant_group))
1941 NewLoad->setMetadata(LLVMContext::MD_invariant_group, InvGroupMD);
1942 if (
auto *RangeMD =
Load->getMetadata(LLVMContext::MD_range))
1943 NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
1944 if (
auto *NoFPClassMD =
Load->getMetadata(LLVMContext::MD_nofpclass))
1945 NewLoad->setMetadata(LLVMContext::MD_nofpclass, NoFPClassMD);
1947 if (
auto *AccessMD =
Load->getMetadata(LLVMContext::MD_access_group))
1948 if (LI->getLoopFor(
Load->getParent()) == LI->getLoopFor(UnavailableBlock))
1949 NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
1958 ValuesPerBlock.push_back(
1961 MD->invalidateCachedPointerInfo(LoadPtr);
1966 if (CriticalEdgePredAndLoad) {
1967 auto It = CriticalEdgePredAndLoad->
find(UnavailableBlock);
1968 if (It != CriticalEdgePredAndLoad->
end()) {
1969 ++NumPRELoadMoved2CEPred;
1970 ICF->insertInstructionTo(NewLoad, UnavailableBlock);
1971 LoadInst *OldLoad = It->second;
1975 if (uint32_t ValNo = VN.lookup(OldLoad,
false))
1976 LeaderTable.erase(ValNo, OldLoad, OldLoad->
getParent());
1977 removeInstruction(OldLoad);
1985 ICF->removeUsersOf(
Load);
1986 Load->replaceAllUsesWith(V);
1990 I->setDebugLoc(
Load->getDebugLoc());
1991 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
1992 MD->invalidateCachedPointerInfo(V);
1995 <<
"load eliminated by PRE";
2001 AvailValInBlkVect &ValuesPerBlock,
2002 UnavailBlkVect &UnavailableBlocks) {
2011 SmallPtrSet<BasicBlock *, 4> Blockers(
llvm::from_range, UnavailableBlocks);
2033 bool MustEnsureSafetyOfSpeculativeExecution =
2034 ICF->isDominatedByICFIFromSameBlock(
Load);
2038 if (TmpBB == LoadBB)
2040 if (Blockers.count(TmpBB))
2052 MustEnsureSafetyOfSpeculativeExecution =
2053 MustEnsureSafetyOfSpeculativeExecution || ICF->hasICF(TmpBB);
2061 MapVector<BasicBlock *, Value *> PredLoads;
2062 DenseMap<BasicBlock *, AvailabilityState> FullyAvailableBlocks;
2065 for (BasicBlock *UnavailableBB : UnavailableBlocks)
2073 MapVector<BasicBlock *, LoadInst *> CriticalEdgePredAndLoad;
2079 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD PREDECESSOR '"
2091 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF INDBR CRITICAL EDGE '"
2098 dbgs() <<
"COULD NOT PRE LOAD BECAUSE OF AN EH PAD CRITICAL EDGE '"
2105 if (DT->dominates(LoadBB, Pred)) {
2108 <<
"COULD NOT PRE LOAD BECAUSE OF A BACKEDGE CRITICAL EDGE '"
2113 if (LoadInst *LI = findLoadToHoistIntoPred(Pred, LoadBB,
Load))
2114 CriticalEdgePredAndLoad[Pred] = LI;
2119 PredLoads[Pred] =
nullptr;
2124 unsigned NumInsertPreds = PredLoads.
size() + CriticalEdgePredSplit.
size();
2125 unsigned NumUnavailablePreds = NumInsertPreds +
2126 CriticalEdgePredAndLoad.
size();
2127 assert(NumUnavailablePreds != 0 &&
2128 "Fully available value should already be eliminated!");
2129 (void)NumUnavailablePreds;
2135 if (NumInsertPreds > 1)
2140 if (MustEnsureSafetyOfSpeculativeExecution) {
2141 if (CriticalEdgePredSplit.
size())
2145 for (
auto &PL : PredLoads)
2149 for (
auto &CEP : CriticalEdgePredAndLoad)
2156 for (BasicBlock *OrigPred : CriticalEdgePredSplit) {
2157 BasicBlock *NewPred = splitCriticalEdges(OrigPred, LoadBB);
2158 assert(!PredLoads.count(OrigPred) &&
"Split edges shouldn't be in map!");
2159 PredLoads[NewPred] =
nullptr;
2160 LLVM_DEBUG(
dbgs() <<
"Split critical edge " << OrigPred->getName() <<
"->"
2161 << LoadBB->
getName() <<
'\n');
2164 for (
auto &CEP : CriticalEdgePredAndLoad)
2165 PredLoads[CEP.first] =
nullptr;
2168 bool CanDoPRE =
true;
2169 const DataLayout &
DL =
Load->getDataLayout();
2170 SmallVector<Instruction*, 8> NewInsts;
2171 for (
auto &PredLoad : PredLoads) {
2172 BasicBlock *UnavailablePred = PredLoad.first;
2182 Value *LoadPtr =
Load->getPointerOperand();
2184 while (Cur != LoadBB) {
2197 LoadPtr =
Address.translateWithInsertion(LoadBB, UnavailablePred, *DT,
2204 << *
Load->getPointerOperand() <<
"\n");
2209 PredLoad.second = LoadPtr;
2213 while (!NewInsts.
empty()) {
2223 return !CriticalEdgePredSplit.empty();
2231 <<
" INSTS: " << *NewInsts.
back()
2235 for (Instruction *
I : NewInsts) {
2239 I->updateLocationAfterHoist();
2248 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, PredLoads,
2249 &CriticalEdgePredAndLoad);
2255 AvailValInBlkVect &ValuesPerBlock,
2256 UnavailBlkVect &UnavailableBlocks) {
2257 const Loop *
L = LI->getLoopFor(
Load->getParent());
2259 if (!L ||
L->getHeader() !=
Load->getParent())
2264 if (!Preheader || !Latch)
2267 Value *LoadPtr =
Load->getPointerOperand();
2269 if (!
L->isLoopInvariant(LoadPtr))
2275 if (ICF->isDominatedByICFIFromSameBlock(
Load))
2279 for (
auto *Blocker : UnavailableBlocks) {
2281 if (!
L->contains(Blocker))
2293 if (L != LI->getLoopFor(Blocker))
2301 if (DT->dominates(Blocker, Latch))
2305 if (Blocker->getTerminator()->mayWriteToMemory())
2308 LoopBlock = Blocker;
2326 MapVector<BasicBlock *, Value *> AvailableLoads;
2327 AvailableLoads[LoopBlock] = LoadPtr;
2328 AvailableLoads[Preheader] = LoadPtr;
2331 eliminatePartiallyRedundantLoad(
Load, ValuesPerBlock, AvailableLoads,
2339 using namespace ore;
2343 <<
"load of type " << NV(
"Type",
Load->getType()) <<
" eliminated"
2344 << setExtraArgs() <<
" in favor of "
2353 if (
Load->getFunction()->hasFnAttribute(Attribute::SanitizeAddress) ||
2354 Load->getFunction()->hasFnAttribute(Attribute::SanitizeHWAddress))
2359 MD->getNonLocalPointerDependency(
Load, Deps);
2364 unsigned NumDeps = Deps.size();
2365 if (NumDeps > Opts->gvn_max_num_deps)
2371 for (
const NonLocalDepResult &Dep : Deps) {
2372 const auto &
R = Dep.getResult();
2373 SelectAddr SelAddr = Dep.getAddress();
2379 ReachingMemVal::getSelect(BB, Sel, Addrs.first, Addrs.second));
2391 return processNonLocalLoad(
Load, MemVals);
2398 if (Deps.
size() == 1 && Deps[0].Kind == DepKind::Other) {
2400 dbgs() <<
" has unknown dependencies\n";);
2408 if (GetElementPtrInst *
GEP =
2410 for (Use &U :
GEP->indices())
2420 AvailValInBlkVect ValuesPerBlock;
2421 UnavailBlkVect UnavailableBlocks;
2422 analyzeLoadAvailability(
Load, Deps, ValuesPerBlock, UnavailableBlocks);
2426 if (ValuesPerBlock.empty())
2434 if (UnavailableBlocks.empty()) {
2440 ICF->removeUsersOf(
Load);
2441 Load->replaceAllUsesWith(V);
2449 if (
Load->getDebugLoc() &&
Load->getParent() ==
I->getParent())
2450 I->setDebugLoc(
Load->getDebugLoc());
2451 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
2452 MD->invalidateCachedPointerInfo(V);
2465 if (performLoopLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks) ||
2466 performLoadPRE(
Load, ValuesPerBlock, UnavailableBlocks))
2472bool GVNPassImpl::processAssumeIntrinsic(
AssumeInst *IntrinsicI) {
2476 if (
Cond->isZero()) {
2486 const MemoryUseOrDef *FirstNonDom =
nullptr;
2488 MSSAU->getMemorySSA()->getBlockAccesses(IntrinsicI->
getParent());
2495 for (
const auto &Acc : *AL) {
2497 if (!Current->getMemoryInst()->comesBefore(NewS)) {
2498 FirstNonDom = Current;
2505 FirstNonDom ? MSSAU->createMemoryAccessBefore(
2507 const_cast<MemoryUseOrDef *
>(FirstNonDom))
2508 : MSSAU->createMemoryAccessInBB(
2530 return propagateEquality(V,
True, IntrinsicI);
2535 I->replaceAllUsesWith(Repl);
2542 Value *PointerOperand = L->getPointerOperand()->stripPointerCasts();
2553 PointerUsesQueue.
push_back(PointerOperand);
2558 while (!PointerUsesQueue.
empty()) {
2561 "Null or GlobalValue should not be inserted");
2565 if (!
I ||
I == L || !DT.
dominates(
I, MostDominatingInstruction))
2580 if (
I->hasMetadata(LLVMContext::MD_invariant_group) &&
2582 MostDominatingInstruction =
I;
2586 return MostDominatingInstruction != L ? MostDominatingInstruction :
nullptr;
2592static std::optional<MemoryLocation>
2599 switch (
II->getIntrinsicID()) {
2600 case Intrinsic::masked_load:
2602 case Intrinsic::masked_store:
2605 return std::nullopt;
2612 return std::nullopt;
2616 return std::nullopt;
2622std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::scanMemoryAccessesUsers(
2628 auto UpdateChoice = [&](std::optional<ReachingMemVal> &Choice,
2632 Choice = ReachingMemVal::getClobber(Loc.
Ptr, Candidate, AR.getOffset());
2634 Choice = ReachingMemVal::getDef(Loc.
Ptr, Candidate);
2642 Choice->Kind = DepKind::Clobber;
2643 Choice->Offset = AR.getOffset();
2645 Choice->Kind = DepKind::Def;
2646 Choice->Offset = -1;
2649 Choice->Inst = Candidate;
2650 Choice->Block = Candidate->getParent();
2653 std::optional<ReachingMemVal> ReachingVal;
2654 for (MemoryAccess *MA : ClobbersList) {
2656 for (User *U : MA->
users()) {
2657 if (++Scanned >= Opts->gvn_scan_users_limit)
2658 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2661 if (!UseOrDef || UseOrDef->getBlock() != BB)
2670 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2684 UpdateChoice(ReachingVal, AR, MemI);
2696std::optional<GVNPassImpl::ReachingMemVal> GVNPassImpl::accessMayModifyLocation(
2706 if (
Alloc->getParent() == BB)
2707 return ReachingMemVal::getDef(Loc.
Ptr,
const_cast<AllocaInst *
>(
Alloc));
2708 return ReachingMemVal::getUnknown(BB, Loc.
Ptr);
2712 if (IsInvariantLoad || AA.pointsToConstantMemory(Loc))
2713 return std::nullopt;
2717 return L->getOrdering();
2724 AliasResult AR = AA.alias(*MaybeLoc, Loc);
2726 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2737 return std::nullopt;
2738 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2743 return std::nullopt;
2749 Opts->gvn_max_num_insns))
2750 return std::nullopt;
2755 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2760 "Must be the superset/partial overlap case with positive offset");
2761 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI, AR.
getOffset());
2765 if (
II->getIntrinsicID() == Intrinsic::lifetime_start) {
2767 if (AA.isMustAlias(IIObjLoc, Loc))
2768 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2769 return std::nullopt;
2777 if (Obj == ClobberI || AA.isMustAlias(ClobberI, Loc.
Ptr))
2778 return ReachingMemVal::getDef(Loc.
Ptr, ClobberI);
2784 return std::nullopt;
2788 ModRefInfo MR = AA.getModRefInfo(ClobberI, Loc);
2792 return std::nullopt;
2796 return ReachingMemVal::getClobber(Loc.
Ptr, ClobberI);
2804 DependencyBlockSet &Blocks,
2815 if (!DT->isReachableFromEntry(Pred))
2819 if (
llvm::any_of(Preds, [Pred](
const auto &
P) {
return P.first == Pred; }))
2822 PHITransAddr TransAddr = Addr;
2826 auto It = Blocks.find(Pred);
2827 if (It != Blocks.end()) {
2831 if (It->second.Addr.getAddr() != TransAddr.
getAddr())
2838 Pred, DependencyBlockInfo(TransAddr,
2839 MPhi ? MPhi->getIncomingValueForBlock(Pred)
2846 for (
auto &
P : Preds) {
2847 [[maybe_unused]]
auto It =
2848 Blocks.try_emplace(
P.first, std::move(
P.second)).first;
2862 const DependencyBlockInfo &StartInfo,
2863 const DependencyBlockSet &Blocks,
2865 MemoryAccess *MA = StartInfo.InitialClobberMA;
2866 MemoryAccess *LastMA = StartInfo.ClobberMA;
2869 while (MA != LastMA) {
2883 BB = DT->getNode(BB)->getIDom()->getBlock();
2887 auto It = Blocks.find(BB);
2888 if (It == Blocks.end())
2891 MA = It->second.InitialClobberMA;
2892 LastMA = It->second.ClobberMA;
2893 if (MA == Clobbers.
back())
2910bool GVNPassImpl::findReachingValuesForLoad(
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);
3168 BatchAAResults BatchAA(*AA);
3175 MemDepResult Dep = MD->getDependency(
I);
3180 auto *MSSA = MSSAU->getMemorySSA();
3186 Def->getBlock() !=
I->getParent())
3188 DepInst = Def->getMemoryInst();
3192 Value *Passthrough =
I->getOperand(2);
3196 StoreVal->
getType() !=
I->getType())
3201 MemoryLocation StoreLoc =
3203 if (!BatchAA.isMustAlias(StoreLoc, LoadLoc))
3211 ICF->removeUsersOf(
I);
3212 I->replaceAllUsesWith(OpToForward);
3220std::pair<uint32_t, bool> GVNValueTable::assignExpNewValueNum(
Expression &Exp) {
3221 uint32_t &
E = ExpressionNumbering[
Exp];
3222 bool CreateNewValNum = !
E;
3223 if (CreateNewValNum) {
3224 Expressions.push_back(Exp);
3225 if (ExprIdx.size() < NextValueNumber + 1)
3226 ExprIdx.resize(NextValueNumber * 2);
3227 E = NextValueNumber;
3228 ExprIdx[NextValueNumber++] = NextExprNumber++;
3230 return {
E, CreateNewValNum};
3235bool GVNValueTable::areAllValsInBB(uint32_t Num,
const BasicBlock *BB,
3239 [=](
const GVNLeaderMap::LeaderTableEntry &L) { return L.BB == BB; });
3246 auto FindRes = PhiTranslateTable.find({Num, Pred});
3247 if (FindRes != PhiTranslateTable.end())
3248 return FindRes->second;
3249 uint32_t NewNum = phiTranslateImpl(Pred, PhiBlock, Num, LeaderTable);
3250 PhiTranslateTable.insert({{Num, Pred}, NewNum});
3262 for (
const auto &Entry : Leaders) {
3264 if (
Call &&
Call->getParent() == PhiBlock)
3268 if (
AA->doesNotAccessMemory(
Call))
3271 if (!MD || !
AA->onlyReadsMemory(
Call))
3283 if (
D.getResult().isNonFuncLocal())
3291uint32_t GVNValueTable::phiTranslateImpl(
const BasicBlock *Pred,
3297 if (PHINode *PN = NumberingPhi[Num]) {
3298 if (PN->getParent() != PhiBlock)
3300 for (
unsigned I = 0;
I != PN->getNumIncomingValues(); ++
I) {
3301 if (PN->getIncomingBlock(
I) != Pred)
3303 if (uint32_t TransVal =
lookup(PN->getIncomingValue(
I),
false))
3309 if (BasicBlock *BB = NumberingBB[Num]) {
3310 assert(MSSA &&
"NumberingBB is non-empty only when using MemorySSA");
3316 MemoryPhi *MPhi = MSSA->getMemoryAccess(BB);
3323 if (MSSA->isLiveOnEntryDef(MA))
3328 "CFG/MemorySSA mismatch: predecessor not found among incoming blocks");
3334 if (!areAllValsInBB(Num, PhiBlock, LeaderTable))
3337 if (Num >= ExprIdx.size() || ExprIdx[Num] == 0)
3341 for (
unsigned I = 0;
I <
Exp.VarArgs.size();
I++) {
3345 if ((
I > 1 &&
Exp.Opcode == Instruction::InsertValue) ||
3346 (
I > 0 &&
Exp.Opcode == Instruction::ExtractValue) ||
3347 (
I > 1 &&
Exp.Opcode == Instruction::ShuffleVector))
3352 if (
Exp.Commutative) {
3353 assert(
Exp.VarArgs.size() >= 2 &&
"Unsupported commutative instruction!");
3354 if (
Exp.VarArgs[0] >
Exp.VarArgs[1]) {
3356 uint32_t Opcode =
Exp.Opcode >> 8;
3357 if (Opcode == Instruction::ICmp || Opcode == Instruction::FCmp)
3358 Exp.Opcode = (Opcode << 8) |
3364 if (uint32_t NewNum = ExpressionNumbering[Exp]) {
3365 if (
Exp.Opcode == Instruction::Call && NewNum != Num)
3366 return areCallValsEqual(Num, NewNum, Pred, PhiBlock, LeaderTable) ? NewNum
3378 PhiTranslateTable.erase({Num, Pred});
3388 if (Leaders.empty())
3391 Value *Val =
nullptr;
3392 for (
const auto &Entry : Leaders) {
3413 const BasicBlock *Pred =
E.getEnd()->getSinglePredecessor();
3414 assert((!Pred || Pred ==
E.getStart()) &&
3415 "No edge between these basic blocks!");
3416 return Pred !=
nullptr;
3419void GVNPassImpl::assignBlockRPONumber(
Function &
F) {
3420 BlockRPONumber.clear();
3421 uint32_t NextBlockNumber = 1;
3422 ReversePostOrderTraversal<Function *> RPOT(&
F);
3423 for (BasicBlock *BB : RPOT)
3424 BlockRPONumber[BB] = NextBlockNumber++;
3425 InvalidBlockRPONumbers =
false;
3433bool GVNPassImpl::propagateEquality(
3435 const std::variant<BasicBlockEdge, Instruction *> &Root) {
3437 SmallDenseSet<std::pair<Value *, Value *>, 4> Visited;
3441 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3448 for (
const auto *Node : DT->getNode(
I->getParent())->children())
3452 while (!Worklist.
empty()) {
3453 std::pair<Value*, Value*> Item = Worklist.
pop_back_val();
3454 LHS = Item.first;
RHS = Item.second;
3468 const DataLayout &
DL =
3477 uint32_t LVN = VN.lookupOrAdd(
LHS);
3482 uint32_t RVN = VN.lookupOrAdd(
RHS);
3489 if (!Visited.
insert({LHS, RHS}).second)
3502 for (
const BasicBlock *BB : DominatedBlocks)
3503 LeaderTable.insert(LVN,
RHS, BB);
3510 auto CanReplacePointersCallBack = [&
DL](
const Use &
U,
const Value *To) {
3513 unsigned NumReplacements;
3514 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3516 LHS,
RHS, *DT, *
Edge, CanReplacePointersCallBack);
3519 LHS,
RHS, *DT, std::get<Instruction *>(Root),
3520 CanReplacePointersCallBack);
3522 if (NumReplacements > 0) {
3524 NumGVNEqProp += NumReplacements;
3527 MD->invalidateCachedPointerInfo(
LHS);
3544 bool IsKnownFalse = !IsKnownTrue;
3560 Value *Op0 =
Cmp->getOperand(0), *Op1 =
Cmp->getOperand(1);
3565 if (
Cmp->isEquivalence(IsKnownFalse))
3566 Worklist.
push_back(std::make_pair(Op0, Op1));
3570 Constant *NotVal = ConstantInt::get(
Cmp->getType(), IsKnownFalse);
3574 uint32_t NextNum = VN.getNextUnusedValueNumber();
3575 uint32_t Num = VN.lookupOrAddCmp(
Cmp->getOpcode(), NotPred, Op0, Op1);
3578 if (Num < NextNum) {
3579 for (
const auto &Entry : LeaderTable.getLeaders(Num)) {
3584 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root)) {
3585 if (!DT->dominates(
Entry.BB,
Edge->getStart()) &&
3586 !DT->dominates(
Edge->getEnd(),
Entry.BB))
3589 auto *InstBB = std::get<Instruction *>(Root)->getParent();
3590 if (!DT->dominates(
Entry.BB, InstBB) &&
3591 !DT->dominates(InstBB,
Entry.BB))
3597 unsigned NumReplacements;
3598 if (
const BasicBlockEdge *
Edge = std::get_if<BasicBlockEdge>(&Root))
3603 NotCmp, NotVal, *DT, std::get<Instruction *>(Root));
3604 Changed |= NumReplacements > 0;
3605 NumGVNEqProp += NumReplacements;
3608 MD->invalidateCachedPointerInfo(NotCmp);
3616 for (
const BasicBlock *BB : DominatedBlocks)
3617 LeaderTable.insert(Num, NotVal, BB);
3626 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), IsKnownTrue));
3631 Worklist.
emplace_back(
A, ConstantInt::get(
A->getType(), !IsKnownTrue));
3639bool GVNPassImpl::replaceWithEquivalentCmp(
CmpInst *Cmp) {
3641 uint32_t Num = VN.lookupCmp(
Cmp->getOpcode(), Pred,
Cmp->getOperand(0),
3642 Cmp->getOperand(1));
3644 return findLeader(
Cmp->getParent(), Num);
3649 if (
Value *Repl = FindCmpLeader(
Cmp->getInversePredicate())) {
3652 Repl, Repl->getName() +
".not",
Cmp->getIterator());
3653 Not->setDebugLoc(
Cmp->getDebugLoc());
3654 Cmp->replaceAllUsesWith(Not);
3661 if (ICmp && ICmp->hasSameSign() && !ICmp->isEquality()) {
3662 if (
Value *Repl = FindCmpLeader(
3679 const DataLayout &
DL =
I->getDataLayout();
3682 if (!
I->use_empty()) {
3685 ICF->removeUsersOf(
I);
3686 I->replaceAllUsesWith(V);
3694 if (MD &&
V->getType()->isPtrOrPtrVectorTy())
3695 MD->invalidateCachedPointerInfo(V);
3702 return processAssumeIntrinsic(Assume);
3705 if (processLoad(
Load))
3708 unsigned Num = VN.lookupOrAdd(
Load);
3709 LeaderTable.insert(Num,
Load,
Load->getParent());
3721 return processFoldableCondBr(BI);
3723 Value *BranchCond = BI->getCondition();
3727 if (TrueSucc == FalseSucc)
3734 BasicBlockEdge TrueE(Parent, TrueSucc);
3735 Changed |= propagateEquality(BranchCond, TrueVal, TrueE);
3738 BasicBlockEdge FalseE(Parent, FalseSucc);
3739 Changed |= propagateEquality(BranchCond, FalseVal, FalseE);
3746 Value *SwitchCond =
SI->getCondition();
3751 SmallDenseMap<BasicBlock *, unsigned, 16> SwitchEdges;
3753 ++SwitchEdges[Succ];
3755 for (
const auto &Case :
SI->cases()) {
3758 if (SwitchEdges.
lookup(Dst) == 1) {
3759 BasicBlockEdge
E(Parent, Dst);
3760 Changed |= propagateEquality(SwitchCond, Case.getCaseValue(),
E);
3768 if (
I->getType()->isVoidTy())
3771 uint32_t NextNum = VN.getNextUnusedValueNumber();
3772 unsigned Num = VN.lookupOrAdd(
I);
3777 LeaderTable.insert(Num,
I,
I->getParent());
3784 const DataLayout &
DL =
I->getDataLayout();
3785 unsigned AS = PTA->getPointerAddressSpace();
3786 if (
DL.getAddressSizeInBits(AS) ==
DL.getPointerSizeInBits(AS) &&
3787 !
DL.hasUnstableRepresentation(AS)) {
3789 VN.lookupPtrToInt(PTA->getPointerOperand(), PTA->getType());
3790 if (
Value *PTI = findLeader(
I->getParent(), PTINum)) {
3802 Value *Repl = Num < NextNum ? findLeader(
I->getParent(), Num) : nullptr;
3808 LeaderTable.insert(Num,
I,
I->getParent());
3821 MD->invalidateCachedPointerInfo(Repl);
3836 Opts->enable_gvn_memoryssa)
3838 "mutually exclusive",
3845 VN.setAliasAnalysis(&RunAA);
3847 ImplicitControlFlowTracking ImplicitCFT;
3856 InvalidBlockRPONumbers =
true;
3857 MemorySSAUpdater Updater(MSSA);
3858 MSSAU = MSSA ? &Updater :
nullptr;
3861 bool ShouldContinue =
true;
3863 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
3875 EarliestEscapeAnalysis RunEA(*DT, &LI);
3876 EA = MSSA ? &RunEA :
nullptr;
3878 unsigned Iteration = 0;
3879 while (ShouldContinue) {
3882 ShouldContinue = iterateOnFunction(
F);
3890 assignValNumForDeadCode();
3891 bool PREChanged =
true;
3892 while (PREChanged) {
3893 PREChanged = performPRE(
F);
3903 cleanupGlobalSets();
3914bool GVNPassImpl::processBlock(
BasicBlock *BB) {
3915 if (DeadBlocks.count(BB))
3918 bool ChangedFunction =
false;
3924 SmallPtrSet<PHINode *, 8> PHINodesToRemove;
3926 for (PHINode *PN : PHINodesToRemove) {
3927 removeInstruction(PN);
3930 ChangedFunction |= processInstruction(&Inst);
3931 return ChangedFunction;
3935bool GVNPassImpl::performScalarPREInsertion(
Instruction *Instr,
3937 unsigned int ValNo) {
3943 for (
unsigned I = 0,
E =
Instr->getNumOperands();
I !=
E; ++
I) {
3951 if (!VN.exists(
Op)) {
3955 uint32_t TValNo = VN.phiTranslate(Pred, Curr, VN.lookup(
Op), LeaderTable);
3956 if (
Value *V = findLeader(Pred, TValNo)) {
3974 ICF->insertInstructionTo(Instr, Pred);
3976 unsigned Num = VN.lookupOrAdd(Instr);
3980 LeaderTable.insert(Num, Instr, Pred);
3984bool GVNPassImpl::performScalarPRE(
Instruction *CurInst) {
4010 if (CallB->isInlineAsm())
4014 uint32_t ValNo = VN.lookup(CurInst);
4022 unsigned NumWith = 0;
4023 unsigned NumWithout = 0;
4028 if (InvalidBlockRPONumbers)
4029 assignBlockRPONumber(*CurrentBlock->
getParent());
4035 if (!DT->isReachableFromEntry(
P)) {
4040 assert(BlockRPONumber.count(
P) && BlockRPONumber.count(CurrentBlock) &&
4041 "Invalid BlockRPONumber map.");
4042 if (BlockRPONumber[
P] >= BlockRPONumber[CurrentBlock]) {
4047 uint32_t TValNo = VN.phiTranslate(
P, CurrentBlock, ValNo, LeaderTable);
4048 Value *PredV = findLeader(
P, TValNo);
4053 }
else if (PredV == CurInst) {
4065 if (NumWithout > 1 || NumWith == 0)
4073 if (NumWithout != 0) {
4079 if (ICF->isDominatedByICFIFromSameBlock(CurInst))
4092 ToSplit.push_back(std::make_pair(PREPred->
getTerminator(), SuccNum));
4096 PREInstr = CurInst->
clone();
4097 if (!performScalarPREInsertion(PREInstr, PREPred, CurrentBlock, ValNo)) {
4100 verifyRemoved(PREInstr);
4109 assert(PREInstr !=
nullptr || NumWithout == 0);
4115 CurInst->
getName() +
".pre-phi");
4116 Phi->insertBefore(CurrentBlock->begin());
4117 for (
auto &[V, BB] : PredMap) {
4122 Phi->addIncoming(V, BB);
4124 Phi->addIncoming(PREInstr, PREPred);
4130 VN.eraseTranslateCacheEntry(ValNo, *CurrentBlock);
4131 LeaderTable.insert(ValNo, Phi, CurrentBlock);
4134 if (MD &&
Phi->getType()->isPtrOrPtrVectorTy())
4135 MD->invalidateCachedPointerInfo(Phi);
4136 LeaderTable.erase(ValNo, CurInst, CurrentBlock);
4139 removeInstruction(CurInst);
4146bool GVNPassImpl::performPRE(
Function &
F) {
4148 for (BasicBlock *CurrentBlock :
depth_first(&
F.getEntryBlock())) {
4150 if (CurrentBlock == &
F.getEntryBlock())
4154 if (CurrentBlock->isEHPad())
4158 BE = CurrentBlock->end();
4161 Changed |= performScalarPRE(CurInst);
4165 if (splitCriticalEdges())
4179 CriticalEdgeSplittingOptions(DT, LI, MSSAU).unsetPreserveLoopSimplify());
4182 MD->invalidateCachedPredecessors();
4183 InvalidBlockRPONumbers =
true;
4190bool GVNPassImpl::splitCriticalEdges() {
4191 if (ToSplit.empty())
4196 std::pair<Instruction *, unsigned>
Edge = ToSplit.pop_back_val();
4198 CriticalEdgeSplittingOptions(DT, LI, MSSAU)) !=
4200 }
while (!ToSplit.empty());
4203 MD->invalidateCachedPredecessors();
4204 InvalidBlockRPONumbers =
true;
4210bool GVNPassImpl::iterateOnFunction(
Function &
F) {
4211 cleanupGlobalSets();
4218 ReversePostOrderTraversal<Function *> RPOT(&
F);
4220 for (BasicBlock *BB : RPOT)
4226void GVNPassImpl::cleanupGlobalSets() {
4228 LeaderTable.clear();
4229 BlockRPONumber.clear();
4231 InvalidBlockRPONumbers =
true;
4236 if (MD) MD->removeInstruction(
I);
4238 EA->removeInstruction(
I);
4240 MSSAU->removeMemoryAccess(
I);
4244 ICF->removeInstruction(
I);
4245 I->eraseFromParent();
4251void GVNPassImpl::verifyRemoved(
const Instruction *Inst)
const {
4252 VN.verifyRemoved(Inst);
4259void GVNPassImpl::addDeadBlock(
BasicBlock *BB) {
4261 SmallSetVector<BasicBlock *, 4>
DF;
4264 while (!NewDead.
empty()) {
4266 if (DeadBlocks.count(
D))
4270 SmallVector<BasicBlock *, 8> Dom;
4271 DT->getDescendants(
D, Dom);
4272 DeadBlocks.insert_range(Dom);
4275 for (BasicBlock *
B : Dom) {
4277 if (DeadBlocks.count(S))
4280 bool AllPredDead =
true;
4282 if (!DeadBlocks.count(
P)) {
4283 AllPredDead =
false;
4303 for (BasicBlock *
B :
DF) {
4304 if (DeadBlocks.count(
B))
4310 for (BasicBlock *
P : Preds) {
4311 if (!DeadBlocks.count(
P))
4316 if (BasicBlock *S = splitCriticalEdges(
P,
B))
4317 DeadBlocks.insert(
P = S);
4323 if (!DeadBlocks.count(
P))
4325 for (PHINode &Phi :
B->phis()) {
4328 MD->invalidateCachedPointerInfo(&Phi);
4347bool GVNPassImpl::processFoldableCondBr(
CondBrInst *BI) {
4358 if (DeadBlocks.count(DeadRoot))
4362 DeadRoot = splitCriticalEdges(BI->
getParent(), DeadRoot);
4364 addDeadBlock(DeadRoot);
4372void GVNPassImpl::assignValNumForDeadCode() {
4373 for (BasicBlock *BB : DeadBlocks) {
4374 for (Instruction &Inst : *BB) {
4375 unsigned ValNum = VN.lookupOrAdd(&Inst);
4376 LeaderTable.insert(ValNum, &Inst, BB);
4397 Impl.Opts = &
F.getContext().getLibraryOptions().get<ScalarOptions>();
4407 MSSAWP ? &MSSAWP->getMSSA() :
nullptr);
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]
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
bool runOnFunction(Function &F) override
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
GVNLegacyPass(bool ScalarPRE=true)
A manager for alias analyses.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
@ MayAlias
The two locations may or may not alias.
@ NoAlias
The two locations do not alias at all.
@ PartialAlias
The two locations alias, but only due to a partial overlap.
@ MustAlias
The two locations precisely alias each other.
constexpr int32_t getOffset() const
constexpr bool hasOffset() const
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Value handle that asserts if the Value is deleted.
This represents the llvm.assume intrinsic.
A function analysis which provides an AssumptionCache.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
LLVM_ABI const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
InstListType::iterator iterator
Instruction iterators...
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
bool isEHPad() const
Return true if this basic block is an exception handling block.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
This class is a wrapper over an AAResults, and it is intended to be used only when there are no IR ch...
ModRefInfo getModRefInfo(const Instruction *I, const std::optional< MemoryLocation > &OptLoc)
LLVM_ABI Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static LLVM_ABI BinaryOperator * CreateNot(Value *Op, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
This class is the base class for the comparison instructions.
static Type * makeCmpResultType(Type *opnd_type)
Create a result type for fcmp/icmp.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Conditional Branch instruction.
Value * getCondition() const
BasicBlock * getSuccessor(unsigned i) const
bool isMinusOne() const
This function will return true iff every bit in this constant is set to true.
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Analysis pass which computes a DominatorTree.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Context-sensitive CaptureAnalysis provider, which computes and caches the earliest common dominator c...
Class representing an expression and its matching format.
FunctionPass class - This class is used to implement most global optimizations.
bool skipFunction(const Function &F) const
Optional passes call this function to check whether the pass should be skipped.
const BasicBlock & getEntryBlock() const
Represents calls to the gc.relocate intrinsic.
leader_iterator & operator++()
bool operator!=(const leader_iterator &Other) const
leader_iterator(const LeaderListNode *C)
reference operator*() const
const LeaderTableEntry value_type
std::forward_iterator_tag iterator_category
std::ptrdiff_t difference_type
bool operator==(const leader_iterator &Other) const
A mapping from value numbers to lists of Value*'s that have that value number.
LLVM_ABI void insert(uint32_t N, Value *V, const BasicBlock *BB)
Push a new Value to the LeaderTable onto the list for its value number.
LLVM_ABI void erase(uint32_t N, Instruction *I, const BasicBlock *BB)
Scan the list of values corresponding to a given value number, and remove the given instruction if en...
iterator_range< leader_iterator > getLeaders(uint32_t N)
The core GVN pass object.
bool isMemDepEnabled() const
bool isScalarPREEnabled() const
bool isLoadPRESplitBackedgeEnabled() const
MemoryDependenceResults & getMemDep() const
AAResults * getAliasAnalysis() const
void salvageAndRemoveInstruction(Instruction *I)
This removes the specified instruction from our various maps and marks it for deletion.
bool isLoadInLoopPREEnabled() const
bool isLoadPREEnabled() const
bool isMemorySSAEnabled() const
DominatorTree & getDominatorTree() const
GVNPassImpl(llvm::GVNOptions Options={})
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
LLVM_ABI GVNPass(GVNOptions Options={})
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
This class holds the mapping between values and value numbers.
LLVM_ABI uint32_t lookupOrAddCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
Returns the value number of the given comparison, assigning it a new number if it did not have one be...
LLVM_ABI void erase(Value *V)
Remove a value from the value numbering.
LLVM_ABI uint32_t lookup(Value *V, bool Verify=true) const
Returns the value number of the specified value.
LLVM_ABI void add(Value *V, uint32_t Num)
add - Insert a value into the table with a specified value number.
LLVM_ABI void eraseTranslateCacheEntry(uint32_t Num, const BasicBlock &CurrBlock)
Erase stale entry from phiTranslate cache so phiTranslate can be computed again.
LLVM_ABI void verifyRemoved(const Value *) const
verifyRemoved - Verify that the value is removed from all internal data structures.
LLVM_ABI uint32_t phiTranslate(const BasicBlock *BB, const BasicBlock *PhiBlock, uint32_t Num, GVNLeaderMap &LeaderTable)
Wrap phiTranslateImpl to provide caching functionality.
LLVM_ABI uint32_t lookupCmp(unsigned Opcode, CmpInst::Predicate Pred, Value *LHS, Value *RHS)
LLVM_ABI uint32_t lookupOrAdd(MemoryAccess *MA)
LLVM_ABI void clear()
Remove all entries from the ValueTable.
LLVM_ABI bool exists(Value *V) const
Returns true if a value number exists for the specified value.
LLVM_ABI GVNValueTable & operator=(const GVNValueTable &Arg)
LLVM_ABI uint32_t lookupPtrToInt(Value *Ptr, Type *Ty)
Returns the value number of ptrtoint Ptr to \Ty.
LLVM_ABI ~GVNValueTable()
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Legacy wrapper pass to provide the GlobalsAAResult object.
Predicate getFlippedSignednessPredicate() const
For example, SLT->ULT, ULT->SLT, SLE->ULE, ULE->SLE, EQ->EQ.
This class allows to keep track on instructions with implicit control flow.
LLVM_ABI Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
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 ...
LLVM_ABI MemorySSAWalker * getWalker()
MemoryUseOrDef * getMemoryAccess(const Instruction *I) const
Given a memory Mod/Ref'ing instruction, get the MemorySSA access associated with it.
LLVM_ABI bool locallyDominates(const MemoryAccess *A, const MemoryAccess *B) const
Given two memory accesses in the same basic block, determine whether MemoryAccess A dominates MemoryA...
bool isLiveOnEntryDef(const MemoryAccess *MA) const
Return true if MA represents the live on entry value.
MemoryAccess * getDefiningAccess() const
Get the access that produces the memory state used by this Use.
This is an entry in the NonLocalDepInfo cache.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
PHITransAddr - An address value which tracks and handles phi translation.
LLVM_ABI Value * translateValue(BasicBlock *CurBB, BasicBlock *PredBB, const DominatorTree *DT, bool MustDominate)
translateValue - PHI translate the current address up the CFG from CurBB to Pred, updating our state ...
LLVM_ABI bool isPotentiallyPHITranslatable() const
isPotentiallyPHITranslatable - If this needs PHI translation, return true if we have some hope of doi...
bool needsPHITranslationFromBlock(BasicBlock *BB) const
needsPHITranslationFromBlock - Return true if moving from the specified BasicBlock to its predecessor...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
AnalysisType * getAnalysisIfAvailable() const
getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to get analysis information tha...
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Helper class for SSA formation on a set of values defined in multiple blocks.
LLVM_ABI void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
LLVM_ABI Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
LLVM_ABI bool HasValueForBlock(BasicBlock *BB) const
Return true if the SSAUpdater already has a value for the specified block.
LLVM_ABI void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
std::pair< SelectInst *, SelectAddrs > getSelectAndAddrs() const
This class represents the LLVM 'select' instruction.
const Value * getFalseValue() const
const Value * getCondition() const
static SelectInst * Create(Value *C, Value *S1, Value *S2, const Twine &NameStr="", InsertPosition InsertBefore=nullptr, const Instruction *MDFrom=nullptr)
const Value * getTrueValue() const
A vector that has set insertion semantics.
bool erase(PtrType Ptr)
Remove pointer from the set.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
The instances of the Type class are immutable: once they are created, they are never changed.
LLVM_ABI bool isTokenLikeTy() const
Returns true if this is 'token' or a token-like target type.s.
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
bool isPtrOrPtrVectorTy() const
Return true if this is a pointer type or a vector of pointer types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
bool isVoidTy() const
Return true if this is 'void'.
static LLVM_ABI UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
bool hasUseList() const
Check if this Value has a use-list.
LLVM_ABI bool canBeFreed() const
Return true if the memory object referred to by V can by freed in the scope for which the SSA value d...
LLVM_ABI void deleteValue()
Delete a pointer to a generic Value.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
An efficient, type-erasing, non-owning reference to a callable.
An opaque object representing a hash code.
const ParentTy * getParent() const
self_iterator getIterator()
A range adaptor for a pair of iterators.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Abstract Attribute helper functions.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
auto m_Value()
Match an arbitrary value and ignore it.
auto m_LogicalOr()
Matches L || R where L and R are arbitrary values.
NoWrapTrunc_match< OpTy, TruncInst::NoUnsignedWrap > m_NUWTrunc(const OpTy &Op)
Matches trunc nuw.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_MaskedStore(const Opnd0 &Op0, const Opnd1 &Op1, const Opnd2 &Op2)
Matches MaskedStore Intrinsic.
auto m_LogicalAnd()
Matches L && R where L and R are arbitrary values.
Not(const Pred &P) -> Not< Pred >
LLVM_ABI int analyzeLoadFromClobberingStore(Type *LoadTy, Value *LoadPtr, StoreInst *DepSI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the store at D...
LLVM_ABI Value * getMemInstValueForLoad(MemIntrinsic *SrcInst, unsigned Offset, Type *LoadTy, Instruction *InsertPt, const DataLayout &DL)
If analyzeLoadFromClobberingMemInst returned an offset, this function can be used to actually perform...
LLVM_ABI int analyzeLoadFromClobberingLoad(Type *LoadTy, Value *LoadPtr, LoadInst *DepLI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the load at De...
LLVM_ABI Value * getValueForLoad(Value *SrcVal, unsigned Offset, Type *LoadTy, Instruction *InsertPt, Function *F)
If analyzeLoadFromClobberingStore/Load returned an offset, this function can be used to actually perf...
LLVM_ABI int analyzeLoadFromClobberingMemInst(Type *LoadTy, Value *LoadPtr, MemIntrinsic *DepMI, const DataLayout &DL)
This function determines whether a value for the pointer LoadPtr can be extracted from the memory int...
LLVM_ABI bool canCoerceMustAliasedValueToLoad(Value *StoredVal, Type *LoadTy, Function *F)
Return true if CoerceAvailableValueToLoadType would succeed if it was called.
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
NodeAddr< UseNode * > Use
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI Constant * getInitialValueOfAllocation(const Value *V, const TargetLibraryInfo *TLI, Type *Ty)
If this is a call to an allocation function that initializes memory to a fixed value,...
LLVM_ABI unsigned replaceDominatedUsesWithIf(Value *From, Value *To, DominatorTree &DT, const BasicBlockEdge &Edge, function_ref< bool(const Use &U, const Value *To)> ShouldReplace)
Replace each use of 'From' with 'To' if that use is dominated by the given edge and the callback Shou...
RelativeUniformCounterPtr Values
LLVM_ABI unsigned GetSuccessorNumber(const BasicBlock *BB, const BasicBlock *Succ)
Search for the specified successor of basic block BB and return its position in the terminator instru...
auto pred_end(const MachineBasicBlock *BB)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createGVNPass(bool ScalarPRE)
Create a legacy GVN pass.
LLVM_ABI void salvageDebugInfo(const MachineRegisterInfo &MRI, MachineInstr &MI)
Assuming the instruction MI is going to be deleted, attempt to salvage debug users of MI by writing t...
auto successors(const MachineBasicBlock *BB)
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
@ Load
The value being inserted comes from a load (InsertElement only).
constexpr from_range_t from_range
LLVM_ABI bool isStorePreservingMemoryLocation(const StoreInst *SI, const MemoryLocation &MemLoc, Align MemLocAlign, BatchAAResults &AA, unsigned ScanLimit)
Check whether SI, which may alias MemLoc, can be safely skipped.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI bool isNoAliasCall(const Value *V)
Return true if this pointer is returned by a noalias function.
LLVM_ABI bool isAssumeWithEmptyBundle(const AssumeInst &Assume)
Return true iff the operand bundles of the provided llvm.assume doesn't contain any valuable informat...
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)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
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)
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)