33#define DEBUG_TYPE "sccp"
65 return isa<LoadInst>(
I);
76 CallBase *CB = dyn_cast<CallBase>(V);
87 <<
" as a constant\n");
91 LLVM_DEBUG(
dbgs() <<
" Constant: " << *Const <<
" = " << *V <<
'\n');
94 V->replaceAllUsesWith(Const);
102 bool Changed =
false;
103 auto GetRange = [&Solver, &InsertedValues](
Value *
Op) {
104 if (
auto *Const = dyn_cast<Constant>(
Op))
105 return Const->toConstantRange();
107 unsigned Bitwidth =
Op->getType()->getScalarSizeInBits();
108 return ConstantRange::getFull(Bitwidth);
111 Op->getType(),
false);
114 if (isa<OverflowingBinaryOperator>(Inst)) {
124 if (NUWRange.contains(RangeA)) {
133 if (NSWRange.contains(RangeA)) {
138 }
else if (isa<PossiblyNonNegInst>(Inst) && !Inst.
hasNonNeg()) {
144 }
else if (
TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
145 if (TI->hasNoSignedWrap() && TI->hasNoUnsignedWrap())
149 uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
150 if (!TI->hasNoUnsignedWrap()) {
152 TI->setHasNoUnsignedWrap(
true);
156 if (!TI->hasNoSignedWrap()) {
158 TI->setHasNoSignedWrap(
true);
172 auto isNonNegative = [&Solver](
Value *V) {
175 if (
auto *
C = dyn_cast<Constant>(V)) {
176 auto *CInt = dyn_cast<ConstantInt>(
C);
177 return CInt && !CInt->isNegative();
180 return IV.isConstantRange(
false) &&
181 IV.getConstantRange().isAllNonNegative();
186 case Instruction::SIToFP:
187 case Instruction::SExt: {
190 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
194 : Instruction::UIToFP,
199 case Instruction::AShr: {
202 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
208 case Instruction::SDiv:
209 case Instruction::SRem: {
212 if (InsertedValues.
count(Op0) || InsertedValues.
count(Op1) ||
213 !isNonNegative(Op0) || !isNonNegative(Op1))
215 auto NewOpcode = Inst.
getOpcode() == Instruction::SDiv ? Instruction::UDiv
218 if (Inst.
getOpcode() == Instruction::SDiv)
227 assert(NewInst &&
"Expected replacement instruction");
229 InsertedValues.
insert(NewInst);
241 bool MadeChanges =
false;
243 if (Inst.getType()->isVoidTy())
247 Inst.eraseFromParent();
264 bool HasNonFeasibleEdges =
false;
267 FeasibleSuccessors.
insert(Succ);
269 HasNonFeasibleEdges =
true;
273 if (!HasNonFeasibleEdges)
278 assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
279 isa<IndirectBrInst>(TI)) &&
280 "Terminator must be a br, switch or indirectbr");
282 if (FeasibleSuccessors.
size() == 0) {
287 Succ->removePredecessor(BB);
288 if (SeenSuccs.
insert(Succ).second)
294 }
else if (FeasibleSuccessors.
size() == 1) {
298 bool HaveSeenOnlyFeasibleSuccessor =
false;
300 if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
303 HaveSeenOnlyFeasibleSuccessor =
true;
307 Succ->removePredecessor(BB);
315 }
else if (FeasibleSuccessors.
size() > 1) {
321 BasicBlock *DefaultDest = SI->getDefaultDest();
322 if (!FeasibleSuccessors.
contains(DefaultDest)) {
323 if (!NewUnreachableBB) {
331 SI->setDefaultDest(NewUnreachableBB);
336 for (
auto CI = SI->case_begin(); CI != SI->case_end();) {
337 if (FeasibleSuccessors.
contains(CI->getCaseSuccessor())) {
383 TrackedMultipleRetVals;
416 using Edge = std::pair<BasicBlock *, BasicBlock *>;
441 bool MayIncludeUndef =
false);
444 assert(!V->getType()->isStructTy() &&
"structs should use mergeInValue");
445 return markConstant(ValueState[V], V,
C);
470 assert(!V->getType()->isStructTy() &&
471 "non-structs should use markConstant");
472 return mergeInValue(ValueState[V], V, MergeWithV, Opts);
479 assert(!V->getType()->isStructTy() &&
"Should use getStructValueState");
487 if (
auto *
C = dyn_cast<Constant>(V))
498 assert(V->getType()->isStructTy() &&
"Should use getValueState");
499 assert(i < cast<StructType>(V->getType())->getNumElements() &&
500 "Invalid element #");
502 auto I = StructValueState.
insert(
509 if (
auto *
C = dyn_cast<Constant>(V)) {
510 Constant *Elt =
C->getAggregateElement(i);
528 while (!ToInvalidate.
empty()) {
534 if (!BBExecutable.count(Inst->
getParent()))
540 if (
auto *RetInst = dyn_cast<ReturnInst>(Inst)) {
541 Function *
F = RetInst->getParent()->getParent();
542 if (
auto It = TrackedRetVals.
find(
F); It != TrackedRetVals.
end()) {
545 }
else if (MRVFunctionsTracked.
count(
F)) {
546 auto *STy = cast<StructType>(
F->getReturnType());
547 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I)
551 }
else if (
auto *STy = dyn_cast<StructType>(Inst->
getType())) {
552 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I) {
553 if (
auto It = StructValueState.
find({Inst, I});
554 It != StructValueState.
end()) {
559 }
else if (
auto It = ValueState.
find(Inst); It != ValueState.
end()) {
567 for (
User *U : V->users())
568 if (
auto *UI = dyn_cast<Instruction>(U))
571 auto It = AdditionalUsers.
find(V);
572 if (It != AdditionalUsers.
end())
573 for (
User *U : It->second)
574 if (
auto *UI = dyn_cast<Instruction>(U))
592 if (BBExecutable.count(
I->getParent()))
597 void addAdditionalUser(
Value *V,
User *U) {
598 auto Iter = AdditionalUsers.
insert({V, {}});
599 Iter.first->second.insert(U);
603 void markUsersAsChanged(
Value *
I) {
608 if (isa<Function>(
I)) {
609 for (
User *U :
I->users()) {
610 if (
auto *CB = dyn_cast<CallBase>(U))
611 handleCallResult(*CB);
614 for (
User *U :
I->users())
615 if (
auto *UI = dyn_cast<Instruction>(U))
616 operandChangedState(UI);
619 auto Iter = AdditionalUsers.
find(
I);
620 if (Iter != AdditionalUsers.
end()) {
624 for (
User *U : Iter->second)
625 if (
auto *UI = dyn_cast<Instruction>(U))
628 operandChangedState(UI);
631 void handleCallOverdefined(
CallBase &CB);
632 void handleCallResult(
CallBase &CB);
633 void handleCallArguments(
CallBase &CB);
660 markOverdefined(&CPI);
661 visitTerminator(CPI);
677 visitTerminator(CBI);
692 FnPredicateInfo.
insert({&
F, std::make_unique<PredicateInfo>(
F, DT, AC)});
700 auto It = FnPredicateInfo.
find(
I->getParent()->getParent());
701 if (It == FnPredicateInfo.
end())
703 return It->second->getPredicateInfoFor(
I);
709 :
DL(
DL), GetTLI(GetTLI), Ctx(Ctx) {}
721 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
723 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
724 TrackedMultipleRetVals.
insert(
726 }
else if (!
F->getReturnType()->isVoidTy())
731 MustPreserveReturnsInFunctions.
insert(
F);
735 return MustPreserveReturnsInFunctions.
count(
F);
739 TrackingIncomingArguments.
insert(
F);
743 return TrackingIncomingArguments.
count(
F);
753 return BBExecutable.count(BB);
759 std::vector<ValueLatticeElement> StructValues;
760 auto *STy = dyn_cast<StructType>(V->getType());
761 assert(STy &&
"getStructLatticeValueFor() can be called only on structs");
762 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
763 auto I = StructValueState.
find(std::make_pair(V, i));
764 assert(
I != StructValueState.
end() &&
"Value not in valuemap!");
765 StructValues.push_back(
I->second);
778 assert(!
F->getReturnType()->isVoidTy() &&
779 (TrackedRetVals.
count(
F) || MRVFunctionsTracked.
count(
F)) &&
780 "All non void specializations should be tracked");
782 handleCallResult(*Call);
786 assert(!V->getType()->isStructTy() &&
787 "Should use getStructLatticeValueFor");
791 "V not found in ValueState nor Paramstate map!");
796 return TrackedRetVals;
800 return TrackedGlobals;
804 return MRVFunctionsTracked;
808 if (
auto *STy = dyn_cast<StructType>(V->getType()))
809 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
810 markOverdefined(getStructValueState(V, i), V);
812 markOverdefined(ValueState[V], V);
816 if (
A->getType()->isIntOrIntVectorTy()) {
817 if (std::optional<ConstantRange>
Range =
A->getRange()) {
818 markConstantRange(ValueState[
A],
A, *
Range);
833 return TrackingIncomingArguments;
841 BBExecutable.erase(&BB);
845 bool ResolvedUndefs =
true;
846 while (ResolvedUndefs) {
848 ResolvedUndefs =
false;
855 bool ResolvedUndefs =
true;
856 while (ResolvedUndefs) {
858 ResolvedUndefs =
false;
865 bool ResolvedUndefs =
true;
866 while (ResolvedUndefs) {
868 ResolvedUndefs =
false;
870 if (
auto *
I = dyn_cast<Instruction>(V))
880 if (!BBExecutable.insert(BB).second)
883 BBWorkList.push_back(BB);
888 if (
IV.isOverdefined()) {
889 if (OverdefinedInstWorkList.empty() || OverdefinedInstWorkList.back() != V)
890 OverdefinedInstWorkList.push_back(V);
893 if (InstWorkList.empty() || InstWorkList.back() != V)
894 InstWorkList.push_back(V);
899 pushToWorkList(
IV, V);
904 if (!
IV.markConstant(
C, MayIncludeUndef))
907 pushToWorkList(
IV, V);
913 if (!
IV.markConstantRange(CR))
915 LLVM_DEBUG(
dbgs() <<
"markConstantRange: " << CR <<
": " << *V <<
'\n');
916 pushToWorkList(
IV, V);
921 if (!
IV.markOverdefined())
925 if (
auto *
F = dyn_cast<Function>(V))
dbgs()
926 <<
"Function '" <<
F->getName() <<
"'\n";
927 else dbgs() << *V <<
'\n');
929 pushToWorkList(
IV, V);
935 const auto &It = TrackedMultipleRetVals.find(std::make_pair(
F, i));
936 assert(It != TrackedMultipleRetVals.end());
948 assert(
C->getType() == Ty &&
"Type mismatch");
962 if (V->getType()->isStructTy()) {
966 std::vector<Constant *> ConstVals;
967 auto *ST = cast<StructType>(V->getType());
968 for (
unsigned I = 0,
E = ST->getNumElements();
I !=
E; ++
I) {
982 assert(Const &&
"Constant is nullptr here!");
988 assert(!Args.empty() &&
"Specialization without arguments");
989 assert(
F->arg_size() == Args[0].Formal->getParent()->arg_size() &&
990 "Functions should have the same number of arguments");
992 auto Iter = Args.begin();
995 for (
auto End =
F->arg_end(); NewArg !=
End; ++NewArg, ++OldArg) {
1002 if (Iter != Args.end() && Iter->Formal == &*OldArg) {
1003 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1004 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1006 NewValue.
markConstant(Iter->Actual->getAggregateElement(
I));
1009 ValueState[&*NewArg].markConstant(Iter->Actual);
1013 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1014 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1016 NewValue = StructValueState[{&*OldArg,
I}];
1020 NewValue = ValueState[&*OldArg];
1026void SCCPInstVisitor::visitInstruction(
Instruction &
I) {
1029 LLVM_DEBUG(
dbgs() <<
"SCCP: Don't know how to handle: " <<
I <<
'\n');
1030 markOverdefined(&
I);
1036 if (
IV.mergeIn(MergeWithV, Opts)) {
1037 pushToWorkList(
IV, V);
1038 LLVM_DEBUG(
dbgs() <<
"Merged " << MergeWithV <<
" into " << *V <<
" : "
1046 if (!KnownFeasibleEdges.
insert(Edge(Source, Dest)).second)
1054 <<
" -> " << Dest->
getName() <<
'\n');
1064void SCCPInstVisitor::getFeasibleSuccessors(
Instruction &TI,
1067 if (
auto *BI = dyn_cast<BranchInst>(&TI)) {
1068 if (BI->isUnconditional()) {
1079 Succs[0] = Succs[1] =
true;
1084 Succs[CI->
isZero()] =
true;
1095 if (
auto *SI = dyn_cast<SwitchInst>(&TI)) {
1096 if (!
SI->getNumCases()) {
1103 Succs[
SI->findCaseValue(CI)->getSuccessorIndex()] =
true;
1111 unsigned ReachableCaseCount = 0;
1112 for (
const auto &Case :
SI->cases()) {
1113 const APInt &CaseValue = Case.getCaseValue()->getValue();
1115 Succs[Case.getSuccessorIndex()] =
true;
1116 ++ReachableCaseCount;
1120 Succs[
SI->case_default()->getSuccessorIndex()] =
1133 if (
auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
1137 getConstant(IBRValue, IBR->getAddress()->getType()));
1147 "Block address of a different function ?");
1148 for (
unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
1150 if (IBR->getDestination(i) ==
T) {
1161 LLVM_DEBUG(
dbgs() <<
"Unknown terminator instruction: " << TI <<
'\n');
1171 return KnownFeasibleEdges.
count(Edge(
From, To));
1191void SCCPInstVisitor::visitPHINode(
PHINode &PN) {
1195 return (
void)markOverdefined(&PN);
1197 if (getValueState(&PN).isOverdefined())
1203 return (
void)markOverdefined(&PN);
1205 unsigned NumActiveIncoming = 0;
1219 NumActiveIncoming++;
1229 mergeInValue(&PN, PhiState,
1231 NumActiveIncoming + 1));
1237void SCCPInstVisitor::visitReturnInst(
ReturnInst &
I) {
1238 if (
I.getNumOperands() == 0)
1242 Value *ResultOp =
I.getOperand(0);
1246 auto TFRVI = TrackedRetVals.find(
F);
1247 if (TFRVI != TrackedRetVals.end()) {
1248 mergeInValue(TFRVI->second,
F, getValueState(ResultOp));
1254 if (!TrackedMultipleRetVals.empty()) {
1255 if (
auto *STy = dyn_cast<StructType>(ResultOp->
getType()))
1256 if (MRVFunctionsTracked.count(
F))
1257 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1258 mergeInValue(TrackedMultipleRetVals[std::make_pair(
F, i)],
F,
1259 getStructValueState(ResultOp, i));
1263void SCCPInstVisitor::visitTerminator(
Instruction &TI) {
1265 getFeasibleSuccessors(TI, SuccFeasible);
1270 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++i)
1271 if (SuccFeasible[i])
1275void SCCPInstVisitor::visitCastInst(
CastInst &
I) {
1278 if (ValueState[&
I].isOverdefined())
1289 return (
void)markConstant(&
I,
C);
1293 if (
I.getDestTy()->isIntOrIntVectorTy() &&
1294 I.getSrcTy()->isIntOrIntVectorTy() &&
1295 I.getOpcode() != Instruction::BitCast) {
1296 auto &LV = getValueState(&
I);
1300 Type *DestTy =
I.getDestTy();
1305 markOverdefined(&
I);
1314 addAdditionalUser(
LHS, &EVI);
1315 addAdditionalUser(
RHS, &EVI);
1316 if (
L.isUnknownOrUndef() ||
R.isUnknownOrUndef())
1326 assert(
Idx == 1 &&
"Index can only be 0 or 1");
1331 markOverdefined(&EVI);
1339 return (
void)markOverdefined(&EVI);
1343 if (ValueState[&EVI].isOverdefined())
1344 return (
void)markOverdefined(&EVI);
1348 return (
void)markOverdefined(&EVI);
1353 if (
auto *WO = dyn_cast<WithOverflowInst>(AggVal))
1354 return handleExtractOfWithOverflow(EVI, WO, i);
1356 mergeInValue(getValueState(&EVI), &EVI, EltVal);
1359 return (
void)markOverdefined(&EVI);
1364 auto *STy = dyn_cast<StructType>(IVI.
getType());
1366 return (
void)markOverdefined(&IVI);
1371 return (
void)markOverdefined(&IVI);
1375 if (IVI.getNumIndices() != 1)
1376 return (
void)markOverdefined(&IVI);
1378 Value *Aggr = IVI.getAggregateOperand();
1379 unsigned Idx = *IVI.idx_begin();
1382 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1386 mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
1390 Value *Val = IVI.getInsertedValueOperand();
1393 markOverdefined(getStructValueState(&IVI, i), &IVI);
1396 mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
1401void SCCPInstVisitor::visitSelectInst(
SelectInst &
I) {
1404 if (
I.getType()->isStructTy())
1405 return (
void)markOverdefined(&
I);
1409 if (ValueState[&
I].isOverdefined())
1410 return (
void)markOverdefined(&
I);
1418 Value *OpVal = CondCB->isZero() ?
I.getFalseValue() :
I.getTrueValue();
1419 mergeInValue(&
I, getValueState(OpVal));
1429 bool Changed = ValueState[&
I].mergeIn(TVal);
1430 Changed |= ValueState[&
I].mergeIn(FVal);
1432 pushToWorkListMsg(ValueState[&
I], &
I);
1436void SCCPInstVisitor::visitUnaryOperator(
Instruction &
I) {
1443 return (
void)markOverdefined(&
I);
1452 return (
void)markConstant(
IV, &
I,
C);
1454 markOverdefined(&
I);
1457void SCCPInstVisitor::visitFreezeInst(
FreezeInst &
I) {
1460 if (
I.getType()->isStructTy())
1461 return (
void)markOverdefined(&
I);
1468 return (
void)markOverdefined(&
I);
1478 markOverdefined(&
I);
1482void SCCPInstVisitor::visitBinaryOperator(
Instruction &
I) {
1487 if (
IV.isOverdefined())
1495 return (
void)markOverdefined(&
I);
1507 auto *
C = dyn_cast_or_null<Constant>(R);
1516 return (
void)mergeInValue(&
I, NewV);
1521 if (!
I.getType()->isIntOrIntVectorTy())
1522 return markOverdefined(&
I);
1530 auto *BO = cast<BinaryOperator>(&
I);
1531 ConstantRange R = ConstantRange::getEmpty(
I.getType()->getScalarSizeInBits());
1532 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO))
1533 R =
A.overflowingBinaryOp(BO->getOpcode(),
B, OBO->getNoWrapKind());
1535 R =
A.binaryOp(BO->getOpcode(),
B);
1544void SCCPInstVisitor::visitCmpInst(
CmpInst &
I) {
1548 return (
void)markOverdefined(&
I);
1550 Value *Op1 =
I.getOperand(0);
1551 Value *Op2 =
I.getOperand(1);
1555 auto V1State = getValueState(Op1);
1556 auto V2State = getValueState(Op2);
1562 mergeInValue(&
I, CV);
1571 markOverdefined(&
I);
1578 return (
void)markOverdefined(&
I);
1583 for (
unsigned i = 0, e =
I.getNumOperands(); i != e; ++i) {
1589 return (
void)markOverdefined(&
I);
1596 return (
void)markOverdefined(&
I);
1600 markConstant(&
I,
C);
1603void SCCPInstVisitor::visitStoreInst(
StoreInst &SI) {
1605 if (
SI.getOperand(0)->getType()->isStructTy())
1608 if (TrackedGlobals.empty() || !isa<GlobalVariable>(
SI.getOperand(1)))
1612 auto I = TrackedGlobals.find(GV);
1613 if (
I == TrackedGlobals.end())
1617 mergeInValue(
I->second, GV, getValueState(
SI.getOperand(0)),
1619 if (
I->second.isOverdefined())
1620 TrackedGlobals.erase(
I);
1624 if (
I->getType()->isIntOrIntVectorTy()) {
1625 if (
MDNode *Ranges =
I->getMetadata(LLVMContext::MD_range))
1629 if (
const auto *CB = dyn_cast<CallBase>(
I))
1630 if (std::optional<ConstantRange>
Range = CB->getRange())
1633 if (
I->hasMetadata(LLVMContext::MD_nonnull))
1641void SCCPInstVisitor::visitLoadInst(
LoadInst &
I) {
1644 if (
I.getType()->isStructTy() ||
I.isVolatile())
1645 return (
void)markOverdefined(&
I);
1649 if (ValueState[&
I].isOverdefined())
1650 return (
void)markOverdefined(&
I);
1662 if (isa<ConstantPointerNull>(
Ptr)) {
1664 return (
void)markOverdefined(
IV, &
I);
1670 if (
auto *GV = dyn_cast<GlobalVariable>(
Ptr)) {
1671 if (!TrackedGlobals.empty()) {
1673 auto It = TrackedGlobals.find(GV);
1674 if (It != TrackedGlobals.end()) {
1683 return (
void)markConstant(
IV, &
I,
C);
1690void SCCPInstVisitor::visitCallBase(
CallBase &CB) {
1691 handleCallResult(CB);
1692 handleCallArguments(CB);
1695void SCCPInstVisitor::handleCallOverdefined(
CallBase &CB) {
1704 return (
void)markOverdefined(&CB);
1711 if (
A.get()->getType()->isStructTy())
1712 return markOverdefined(&CB);
1713 if (
A.get()->getType()->isMetadataTy())
1720 return (
void)markOverdefined(&CB);
1726 return (
void)markOverdefined(&CB);
1731 return (
void)markConstant(&CB,
C);
1738void SCCPInstVisitor::handleCallArguments(
CallBase &CB) {
1743 if (TrackingIncomingArguments.count(
F)) {
1752 if (AI->hasByValAttr() && !
F->onlyReadsMemory()) {
1753 markOverdefined(&*AI);
1757 if (
auto *STy = dyn_cast<StructType>(AI->getType())) {
1758 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1760 mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1769void SCCPInstVisitor::handleCallResult(
CallBase &CB) {
1772 if (
auto *
II = dyn_cast<IntrinsicInst>(&CB)) {
1773 if (
II->getIntrinsicID() == Intrinsic::ssa_copy) {
1774 if (ValueState[&CB].isOverdefined())
1780 assert(PI &&
"Missing predicate info for ssa.copy");
1782 const std::optional<PredicateConstraint> &Constraint =
1783 PI->getConstraint();
1785 mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1790 Value *OtherOp = Constraint->OtherOp;
1793 if (getValueState(OtherOp).isUnknown()) {
1794 addAdditionalUser(OtherOp, &CB);
1802 ConstantRange::getFull(
DL.getTypeSizeInBits(CopyOf->
getType()));
1814 if (CopyOfCR.isEmptySet())
1815 CopyOfCR = ConstantRange::getFull(CopyOfCR.getBitWidth());
1816 auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1820 if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1828 addAdditionalUser(OtherOp, &CB);
1837 addAdditionalUser(OtherOp, &CB);
1838 mergeInValue(
IV, &CB, CondVal);
1842 addAdditionalUser(OtherOp, &CB);
1843 mergeInValue(
IV, &CB,
1848 return (
void)mergeInValue(
IV, &CB, CopyOfVal);
1873 if (!
F ||
F->isDeclaration())
1874 return handleCallOverdefined(CB);
1877 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
1878 if (!MRVFunctionsTracked.count(
F))
1879 return handleCallOverdefined(CB);
1883 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1884 mergeInValue(getStructValueState(&CB, i), &CB,
1885 TrackedMultipleRetVals[std::make_pair(
F, i)],
1888 auto TFRVI = TrackedRetVals.find(
F);
1889 if (TFRVI == TrackedRetVals.end())
1890 return handleCallOverdefined(CB);
1899 while (!BBWorkList.empty() || !InstWorkList.empty() ||
1900 !OverdefinedInstWorkList.empty()) {
1903 while (!OverdefinedInstWorkList.empty()) {
1904 Value *
I = OverdefinedInstWorkList.pop_back_val();
1916 markUsersAsChanged(
I);
1920 while (!InstWorkList.empty()) {
1921 Value *
I = InstWorkList.pop_back_val();
1933 if (
I->getType()->isStructTy() || !getValueState(
I).isOverdefined())
1934 markUsersAsChanged(
I);
1938 while (!BBWorkList.empty()) {
1952 if (
I.getType()->isVoidTy())
1955 if (
auto *STy = dyn_cast<StructType>(
I.getType())) {
1959 if (
auto *CB = dyn_cast<CallBase>(&
I))
1961 if (MRVFunctionsTracked.count(
F))
1966 if (isa<ExtractValueInst>(
I) || isa<InsertValueInst>(
I))
1970 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1973 markOverdefined(LV, &
I);
1989 if (
auto *CB = dyn_cast<CallBase>(&
I))
1991 if (TrackedRetVals.count(
F))
1994 if (isa<LoadInst>(
I)) {
2001 markOverdefined(&
I);
2019 bool MadeChange =
false;
2021 if (!BBExecutable.count(&BB))
2029 <<
"\nResolved undefs in " <<
F.getName() <<
'\n');
2048 Visitor->addPredicateInfo(
F, DT, AC);
2052 return Visitor->markBlockExecutable(BB);
2056 return Visitor->getPredicateInfoFor(
I);
2060 Visitor->trackValueOfGlobalVariable(GV);
2064 Visitor->addTrackedFunction(
F);
2068 Visitor->addToMustPreserveReturnsInFunctions(
F);
2072 return Visitor->mustPreserveReturn(
F);
2076 Visitor->addArgumentTrackedFunction(
F);
2080 return Visitor->isArgumentTrackedFunction(
F);
2086 return Visitor->resolvedUndefsIn(
F);
2090 Visitor->solveWhileResolvedUndefsIn(M);
2095 Visitor->solveWhileResolvedUndefsIn(WorkList);
2099 Visitor->solveWhileResolvedUndefs();
2103 return Visitor->isBlockExecutable(BB);
2107 return Visitor->isEdgeFeasible(
From, To);
2110std::vector<ValueLatticeElement>
2112 return Visitor->getStructLatticeValueFor(V);
2116 return Visitor->removeLatticeValueFor(V);
2120 Visitor->resetLatticeValueFor(Call);
2124 return Visitor->getLatticeValueFor(V);
2129 return Visitor->getTrackedRetVals();
2134 return Visitor->getTrackedGlobals();
2138 return Visitor->getMRVFunctionsTracked();
2144 Visitor->trackValueOfArgument(V);
2148 return Visitor->isStructLatticeConstant(
F, STy);
2153 return Visitor->getConstant(LV, Ty);
2157 return Visitor->getConstantOrNull(V);
2161 return Visitor->getArgumentTrackedFunctions();
2166 Visitor->setLatticeValueForSpecializationArguments(
F, Args);
2170 Visitor->markFunctionUnreachable(
F);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
BlockVerifier::State From
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
mir Rename Register Operands
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
uint64_t IntrinsicInst * II
static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts()
Returns MergeOptions with MaxWidenSteps set to MaxNumRangeExtensions.
static const unsigned MaxNumRangeExtensions
static ValueLatticeElement getValueFromMetadata(const Instruction *I)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static ConstantInt * getConstantInt(Value *V, const DataLayout &DL)
Extract ConstantInt from value, looking through IntToPtr and PointerNullValue.
static const uint32_t IV[8]
Class for arbitrary precision integers.
This class represents an incoming formal argument to a Function.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
void removePredecessor(BasicBlock *Pred, bool KeepOneInputPHIs=false)
Update PHI nodes in this BasicBlock before removal of predecessor Pred.
unsigned getNoWrapKind() const
Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap.
Instruction::BinaryOps getBinaryOp() const
Returns the binary operation underlying the intrinsic.
static BinaryOperator * Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name=Twine(), InsertPosition InsertBefore=nullptr)
Construct a binary instruction, given the opcode and the two operands.
The address of a basic block.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
CallBr instruction, tracking function calls that may not return control but instead transfer it to a ...
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
static CastInst * Create(Instruction::CastOps, Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Provides a way to construct any of the CastInst subclasses using an opcode instead of the subclass's ...
This class is the base class for the comparison instructions.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
static ConstantInt * getFalse(LLVMContext &Context)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
This class represents a range of values.
unsigned getActiveBits() const
Compute the maximal number of active bits needed to represent every value in this range.
const APInt * getSingleElement() const
If this set contains a single element, return it, otherwise return null.
ConstantRange castOp(Instruction::CastOps CastOp, uint32_t BitWidth) const
Return a new range representing the possible values resulting from an application of the specified ca...
static ConstantRange intrinsic(Intrinsic::ID IntrinsicID, ArrayRef< ConstantRange > Ops)
Compute range of intrinsic result for the given operand ranges.
bool isSizeLargerThan(uint64_t MaxSize) const
Compare set size of this range with Value.
static bool isIntrinsicSupported(Intrinsic::ID IntrinsicID)
Returns true if ConstantRange calculations are supported for intrinsic with IntrinsicID.
bool isSingleElement() const
Return true if this set contains exactly one member.
bool isAllNonNegative() const
Return true if all values in this range are non-negative.
static ConstantRange makeAllowedICmpRegion(CmpInst::Predicate Pred, const ConstantRange &Other)
Produce the smallest range such that all values that may satisfy the given predicate with any value c...
bool contains(const APInt &Val) const
Return true if the specified value is in the set.
static ConstantRange makeGuaranteedNoWrapRegion(Instruction::BinaryOps BinOp, const ConstantRange &Other, unsigned NoWrapKind)
Produce the largest range containing all X such that "X BinOp Y" is guaranteed not to wrap (overflow)...
unsigned getMinSignedBits() const
Compute the maximal number of bits needed to represent every value in this signed range.
ConstantRange binaryOp(Instruction::BinaryOps BinOp, const ConstantRange &Other) const
Return a new range representing the possible values resulting from an application of the specified bi...
static Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
An instruction for ordering other memory operations.
This class represents a freeze function that returns random concrete value if an operand is either a ...
void applyUpdatesPermissive(ArrayRef< typename DomTreeT::UpdateType > Updates)
Submit updates to all available trees.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
This instruction inserts a struct field of array element value into an aggregate value.
Base class for instruction visitors.
void visit(Iterator Start, Iterator End)
void setHasNoUnsignedWrap(bool b=true)
Set or clear the nuw flag on this instruction, which must be an operator which supports this flag.
bool hasNoUnsignedWrap() const LLVM_READONLY
Determine whether the no unsigned wrap flag is set.
unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
bool hasNoSignedWrap() const LLVM_READONLY
Determine whether the no signed wrap flag is set.
void setHasNoSignedWrap(bool b=true)
Set or clear the nsw flag on this instruction, which must be an operator which supports this flag.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool isExact() const LLVM_READONLY
Determine whether the exact flag is set.
BasicBlock * getSuccessor(unsigned Idx) const LLVM_READONLY
Return the specified successor. This instruction must be a terminator.
void setNonNeg(bool b=true)
Set or clear the nneg flag on this instruction, which must be a zext instruction.
bool hasNonNeg() const LLVM_READONLY
Determine whether the the nneg flag is set.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void setIsExact(bool b=true)
Set or clear the exact flag on this instruction, which must be an operator which supports this flag.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
bool isSpecialTerminator() const
This is an important class for using LLVM in a threaded context.
@ OB_clang_arc_attachedcall
An instruction for reading from memory.
This class implements a map that also provides access to all stored values in a deterministic order.
size_type count(const KeyT &Key) const
iterator find(const KeyT &Key)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
A Module instance is used to store all the information related to an LLVM module.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
Resume the propagation of an exception.
Return a value (possibly void), from a function.
Helper class for SCCPSolver.
const PredicateBase * getPredicateInfoFor(Instruction *I)
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
bool resolvedUndef(Instruction &I)
void markFunctionUnreachable(Function *F)
bool markBlockExecutable(BasicBlock *BB)
bool resolvedUndefsIn(Function &F)
While solving the dataflow for a function, we don't compute a result for operations with an undef ope...
Constant * getConstant(const ValueLatticeElement &LV, Type *Ty) const
SCCPInstVisitor(const DataLayout &DL, std::function< const TargetLibraryInfo &(Function &)> GetTLI, LLVMContext &Ctx)
const ValueLatticeElement & getLatticeValueFor(Value *V) const
void removeLatticeValueFor(Value *V)
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
void trackValueOfArgument(Argument *A)
void visitCallInst(CallInst &I)
void markOverdefined(Value *V)
bool isArgumentTrackedFunction(Function *F)
void addTrackedFunction(Function *F)
void solveWhileResolvedUndefs()
SmallPtrSetImpl< Function * > & getArgumentTrackedFunctions()
void solveWhileResolvedUndefsIn(Module &M)
void trackValueOfGlobalVariable(GlobalVariable *GV)
Constant * getConstantOrNull(Value *V) const
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)
void addToMustPreserveReturnsInFunctions(Function *F)
void addArgumentTrackedFunction(Function *F)
bool isStructLatticeConstant(Function *F, StructType *STy)
void solveWhileResolvedUndefsIn(SmallVectorImpl< Function * > &WorkList)
bool isBlockExecutable(BasicBlock *BB) const
bool mustPreserveReturn(Function *F)
void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
void visitCall(CallInst &I)
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
getTrackedGlobals - Get and return the set of inferred initializers for global variables.
void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
void trackValueOfGlobalVariable(GlobalVariable *GV)
trackValueOfGlobalVariable - Clients can use this method to inform the SCCPSolver that it should trac...
bool tryToReplaceWithConstant(Value *V)
bool isStructLatticeConstant(Function *F, StructType *STy)
void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)
void solve()
Solve - Solve for constants and executable blocks.
void visit(Instruction *I)
void trackValueOfArgument(Argument *V)
trackValueOfArgument - Mark the specified argument overdefined unless it have range attribute.
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
getTrackedRetVals - Get the inferred return value map.
void solveWhileResolvedUndefsIn(Module &M)
const PredicateBase * getPredicateInfoFor(Instruction *I)
bool resolvedUndefsIn(Function &F)
resolvedUndefsIn - While solving the dataflow for a function, we assume that branches on undef values...
void addArgumentTrackedFunction(Function *F)
void solveWhileResolvedUndefs()
void removeLatticeValueFor(Value *V)
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
getMRVFunctionsTracked - Get the set of functions which return multiple values tracked by the pass.
Constant * getConstantOrNull(Value *V) const
Return either a Constant or nullptr for a given Value.
bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
Constant * getConstant(const ValueLatticeElement &LV, Type *Ty) const
Helper to return a Constant if LV is either a constant or a constant range with a single element.
const ValueLatticeElement & getLatticeValueFor(Value *V) const
void addToMustPreserveReturnsInFunctions(Function *F)
Add function to the list of functions whose return cannot be modified.
bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
bool isBlockExecutable(BasicBlock *BB) const
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
Set the Lattice Value for the arguments of a specialization F.
static bool isConstant(const ValueLatticeElement &LV)
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const
bool mustPreserveReturn(Function *F)
Returns true if the return of the given function cannot be modified.
static bool isOverdefined(const ValueLatticeElement &LV)
void markFunctionUnreachable(Function *F)
Mark all of the blocks in function F non-executable.
bool isArgumentTrackedFunction(Function *F)
Returns true if the given function is in the solver's set of argument-tracked functions.
SCCPSolver(const DataLayout &DL, std::function< const TargetLibraryInfo &(Function &)> GetTLI, LLVMContext &Ctx)
SmallPtrSetImpl< Function * > & getArgumentTrackedFunctions()
Return a reference to the set of argument tracked functions.
void markOverdefined(Value *V)
markOverdefined - Mark the specified value overdefined.
This class represents the LLVM 'select' instruction.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
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...
void assign(size_type NumElts, ValueParamT Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Class to represent struct types.
unsigned getNumElements() const
Random access to the elements.
A wrapper class to simplify modification of SwitchInst cases along with their prof branch_weights met...
Provides information about what library functions are available for the current target.
This class represents a truncation of integer types.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
bool isStructTy() const
True if this is an instance of StructType.
bool isVoidTy() const
Return true if this is 'void'.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
This function has undefined behavior.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
This class represents lattice values for constants.
static ValueLatticeElement getRange(ConstantRange CR, bool MayIncludeUndef=false)
bool isOverdefined() const
Constant * getCompare(CmpInst::Predicate Pred, Type *Ty, const ValueLatticeElement &Other, const DataLayout &DL) const
true, false or undef constants, or nullptr if the comparison cannot be evaluated.
static ValueLatticeElement getNot(Constant *C)
ConstantRange asConstantRange(unsigned BW, bool UndefAllowed=false) const
bool isNotConstant() const
void setNumRangeExtensions(unsigned N)
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
unsigned getNumRangeExtensions() const
bool isUnknownOrUndef() const
Constant * getConstant() const
bool mergeIn(const ValueLatticeElement &RHS, MergeOptions Opts=MergeOptions())
Updates this object to approximate both this object and RHS.
bool markConstant(Constant *V, bool MayIncludeUndef=false)
static ValueLatticeElement getOverdefined()
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
std::string getNameOrAsOperand() const
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
StringRef getName() const
Return a constant reference to the value's name.
void takeName(Value *V)
Transfer the name from V to this value.
Represents an op.with.overflow intrinsic.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
static bool replaceSignedInst(SCCPSolver &Solver, SmallPtrSetImpl< Value * > &InsertedValues, Instruction &Inst)
Try to replace signed instructions with their unsigned equivalent.
bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
auto successors(const MachineBasicBlock *BB)
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...
Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
ConstantRange getConstantRangeFromMetadata(const MDNode &RangeMD)
Parse out a conservative ConstantRange from !range metadata.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
bool NullPointerIsDefined(const Function *F, unsigned AS=0)
Check whether null pointer dereferencing is considered undefined behavior for a given function or an ...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool wouldInstructionBeTriviallyDead(const Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction would have no side effects if it was not used.
Constant * ConstantFoldInstOperands(Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
DWARFExpression::Operation Op
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
static bool canRemoveInstruction(Instruction *I)
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
static bool refineInstruction(SCCPSolver &Solver, const SmallPtrSetImpl< Value * > &InsertedValues, Instruction &Inst)
Try to use Inst's value range from Solver to infer the NUW flag.
Implement std::hash so that hash_code can be used in STL containers.
Struct to control some aspects related to merging constant ranges.
MergeOptions & setMaxWidenSteps(unsigned Steps=1)
MergeOptions & setCheckWiden(bool V=true)