33#define DEBUG_TYPE "sccp"
73 return isa<LoadInst>(
I);
84 CallBase *CB = dyn_cast<CallBase>(V);
95 <<
" as a constant\n");
99 LLVM_DEBUG(
dbgs() <<
" Constant: " << *Const <<
" = " << *V <<
'\n');
102 V->replaceAllUsesWith(Const);
110 bool Changed =
false;
111 auto GetRange = [&Solver, &InsertedValues](
Value *
Op) {
112 if (
auto *Const = dyn_cast<ConstantInt>(
Op))
115 unsigned Bitwidth =
Op->getType()->getScalarSizeInBits();
116 return ConstantRange::getFull(Bitwidth);
122 if (isa<OverflowingBinaryOperator>(Inst)) {
132 if (NUWRange.contains(RangeA)) {
141 if (NSWRange.contains(RangeA)) {
146 }
else if (isa<PossiblyNonNegInst>(Inst) && !Inst.
hasNonNeg()) {
152 }
else if (
TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
153 if (TI->hasNoSignedWrap() && TI->hasNoUnsignedWrap())
157 uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
158 if (!TI->hasNoUnsignedWrap()) {
160 TI->setHasNoUnsignedWrap(
true);
164 if (!TI->hasNoSignedWrap()) {
166 TI->setHasNoSignedWrap(
true);
180 auto isNonNegative = [&Solver](
Value *V) {
183 if (
auto *
C = dyn_cast<Constant>(V)) {
184 auto *CInt = dyn_cast<ConstantInt>(
C);
185 return CInt && !CInt->isNegative();
188 return IV.isConstantRange(
false) &&
189 IV.getConstantRange().isAllNonNegative();
194 case Instruction::SIToFP:
195 case Instruction::SExt: {
198 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
202 : Instruction::UIToFP,
207 case Instruction::AShr: {
210 if (InsertedValues.
count(Op0) || !isNonNegative(Op0))
216 case Instruction::SDiv:
217 case Instruction::SRem: {
220 if (InsertedValues.
count(Op0) || InsertedValues.
count(Op1) ||
221 !isNonNegative(Op0) || !isNonNegative(Op1))
223 auto NewOpcode = Inst.
getOpcode() == Instruction::SDiv ? Instruction::UDiv
226 if (Inst.
getOpcode() == Instruction::SDiv)
235 assert(NewInst &&
"Expected replacement instruction");
237 InsertedValues.
insert(NewInst);
248 bool MadeChanges =
false;
250 if (Inst.getType()->isVoidTy())
254 Inst.eraseFromParent();
271 bool HasNonFeasibleEdges =
false;
274 FeasibleSuccessors.
insert(Succ);
276 HasNonFeasibleEdges =
true;
280 if (!HasNonFeasibleEdges)
285 assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
286 isa<IndirectBrInst>(TI)) &&
287 "Terminator must be a br, switch or indirectbr");
289 if (FeasibleSuccessors.
size() == 0) {
294 Succ->removePredecessor(BB);
295 if (SeenSuccs.
insert(Succ).second)
301 }
else if (FeasibleSuccessors.
size() == 1) {
305 bool HaveSeenOnlyFeasibleSuccessor =
false;
307 if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
310 HaveSeenOnlyFeasibleSuccessor =
true;
314 Succ->removePredecessor(BB);
321 }
else if (FeasibleSuccessors.
size() > 1) {
327 BasicBlock *DefaultDest = SI->getDefaultDest();
328 if (!FeasibleSuccessors.
contains(DefaultDest)) {
329 if (!NewUnreachableBB) {
337 SI->setDefaultDest(NewUnreachableBB);
342 for (
auto CI = SI->case_begin(); CI != SI->case_end();) {
343 if (FeasibleSuccessors.
contains(CI->getCaseSuccessor())) {
389 TrackedMultipleRetVals;
422 using Edge = std::pair<BasicBlock *, BasicBlock *>;
447 bool MayIncludeUndef =
false);
450 assert(!V->getType()->isStructTy() &&
"structs should use mergeInValue");
451 return markConstant(ValueState[V], V,
C);
476 assert(!V->getType()->isStructTy() &&
477 "non-structs should use markConstant");
478 return mergeInValue(ValueState[V], V, MergeWithV, Opts);
485 assert(!V->getType()->isStructTy() &&
"Should use getStructValueState");
493 if (
auto *
C = dyn_cast<Constant>(V))
504 assert(V->getType()->isStructTy() &&
"Should use getValueState");
505 assert(i < cast<StructType>(V->getType())->getNumElements() &&
506 "Invalid element #");
508 auto I = StructValueState.
insert(
515 if (
auto *
C = dyn_cast<Constant>(V)) {
516 Constant *Elt =
C->getAggregateElement(i);
534 while (!ToInvalidate.
empty()) {
540 if (!BBExecutable.count(Inst->
getParent()))
546 if (
auto *RetInst = dyn_cast<ReturnInst>(Inst)) {
547 Function *
F = RetInst->getParent()->getParent();
548 if (
auto It = TrackedRetVals.
find(
F); It != TrackedRetVals.
end()) {
551 }
else if (MRVFunctionsTracked.
count(
F)) {
552 auto *STy = cast<StructType>(
F->getReturnType());
553 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I)
557 }
else if (
auto *STy = dyn_cast<StructType>(Inst->
getType())) {
558 for (
unsigned I = 0, E = STy->getNumElements();
I != E; ++
I) {
559 if (
auto It = StructValueState.
find({Inst, I});
560 It != StructValueState.
end()) {
565 }
else if (
auto It = ValueState.
find(Inst); It != ValueState.
end()) {
573 for (
User *U : V->users())
574 if (
auto *UI = dyn_cast<Instruction>(U))
577 auto It = AdditionalUsers.
find(V);
578 if (It != AdditionalUsers.
end())
579 for (
User *U : It->second)
580 if (
auto *UI = dyn_cast<Instruction>(U))
598 if (BBExecutable.count(
I->getParent()))
603 void addAdditionalUser(
Value *V,
User *U) {
604 auto Iter = AdditionalUsers.
insert({V, {}});
605 Iter.first->second.insert(U);
609 void markUsersAsChanged(
Value *
I) {
614 if (isa<Function>(
I)) {
615 for (
User *U :
I->users()) {
616 if (
auto *CB = dyn_cast<CallBase>(U))
617 handleCallResult(*CB);
620 for (
User *U :
I->users())
621 if (
auto *UI = dyn_cast<Instruction>(U))
622 operandChangedState(UI);
625 auto Iter = AdditionalUsers.
find(
I);
626 if (Iter != AdditionalUsers.
end()) {
630 for (
User *U : Iter->second)
631 if (
auto *UI = dyn_cast<Instruction>(U))
634 operandChangedState(UI);
637 void handleCallOverdefined(
CallBase &CB);
638 void handleCallResult(
CallBase &CB);
639 void handleCallArguments(
CallBase &CB);
666 markOverdefined(&CPI);
667 visitTerminator(CPI);
683 visitTerminator(CBI);
698 FnPredicateInfo.
insert({&
F, std::make_unique<PredicateInfo>(
F, DT, AC)});
706 auto It = FnPredicateInfo.
find(
I->getParent()->getParent());
707 if (It == FnPredicateInfo.
end())
709 return It->second->getPredicateInfoFor(
I);
715 :
DL(
DL), GetTLI(GetTLI), Ctx(Ctx) {}
727 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
729 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
730 TrackedMultipleRetVals.
insert(
732 }
else if (!
F->getReturnType()->isVoidTy())
737 MustPreserveReturnsInFunctions.
insert(
F);
741 return MustPreserveReturnsInFunctions.
count(
F);
745 TrackingIncomingArguments.
insert(
F);
749 return TrackingIncomingArguments.
count(
F);
759 return BBExecutable.count(BB);
765 std::vector<ValueLatticeElement> StructValues;
766 auto *STy = dyn_cast<StructType>(V->getType());
767 assert(STy &&
"getStructLatticeValueFor() can be called only on structs");
768 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
769 auto I = StructValueState.
find(std::make_pair(V, i));
770 assert(
I != StructValueState.
end() &&
"Value not in valuemap!");
771 StructValues.push_back(
I->second);
784 assert(!
F->getReturnType()->isVoidTy() &&
785 (TrackedRetVals.
count(
F) || MRVFunctionsTracked.
count(
F)) &&
786 "All non void specializations should be tracked");
788 handleCallResult(*Call);
792 assert(!V->getType()->isStructTy() &&
793 "Should use getStructLatticeValueFor");
797 "V not found in ValueState nor Paramstate map!");
802 return TrackedRetVals;
806 return TrackedGlobals;
810 return MRVFunctionsTracked;
814 if (
auto *STy = dyn_cast<StructType>(V->getType()))
815 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
816 markOverdefined(getStructValueState(V, i), V);
818 markOverdefined(ValueState[V], V);
822 if (
A->getType()->isIntegerTy()) {
823 if (std::optional<ConstantRange>
Range =
A->getRange()) {
824 markConstantRange(ValueState[
A],
A, *
Range);
839 return TrackingIncomingArguments;
847 BBExecutable.erase(&BB);
851 bool ResolvedUndefs =
true;
852 while (ResolvedUndefs) {
854 ResolvedUndefs =
false;
861 bool ResolvedUndefs =
true;
862 while (ResolvedUndefs) {
864 ResolvedUndefs =
false;
871 bool ResolvedUndefs =
true;
872 while (ResolvedUndefs) {
874 ResolvedUndefs =
false;
876 if (
auto *
I = dyn_cast<Instruction>(V))
886 if (!BBExecutable.insert(BB).second)
889 BBWorkList.push_back(BB);
894 if (
IV.isOverdefined()) {
895 if (OverdefinedInstWorkList.empty() || OverdefinedInstWorkList.back() != V)
896 OverdefinedInstWorkList.push_back(V);
899 if (InstWorkList.empty() || InstWorkList.back() != V)
900 InstWorkList.push_back(V);
905 pushToWorkList(
IV, V);
910 if (!
IV.markConstant(
C, MayIncludeUndef))
913 pushToWorkList(
IV, V);
919 if (!
IV.markConstantRange(CR))
921 LLVM_DEBUG(
dbgs() <<
"markConstantRange: " << CR <<
": " << *V <<
'\n');
922 pushToWorkList(
IV, V);
927 if (!
IV.markOverdefined())
931 if (
auto *
F = dyn_cast<Function>(V))
dbgs()
932 <<
"Function '" <<
F->getName() <<
"'\n";
933 else dbgs() << *V <<
'\n');
935 pushToWorkList(
IV, V);
941 const auto &It = TrackedMultipleRetVals.find(std::make_pair(
F, i));
942 assert(It != TrackedMultipleRetVals.end());
954 assert(
C->getType() == Ty &&
"Type mismatch");
968 if (V->getType()->isStructTy()) {
972 std::vector<Constant *> ConstVals;
973 auto *ST = cast<StructType>(V->getType());
974 for (
unsigned I = 0,
E = ST->getNumElements();
I !=
E; ++
I) {
988 assert(Const &&
"Constant is nullptr here!");
994 assert(!Args.empty() &&
"Specialization without arguments");
995 assert(
F->arg_size() == Args[0].Formal->getParent()->arg_size() &&
996 "Functions should have the same number of arguments");
998 auto Iter = Args.begin();
1001 for (
auto End =
F->arg_end(); NewArg !=
End; ++NewArg, ++OldArg) {
1008 if (Iter != Args.end() && Iter->Formal == &*OldArg) {
1009 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1010 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1012 NewValue.
markConstant(Iter->Actual->getAggregateElement(
I));
1015 ValueState[&*NewArg].markConstant(Iter->Actual);
1019 if (
auto *STy = dyn_cast<StructType>(NewArg->
getType())) {
1020 for (
unsigned I = 0,
E = STy->getNumElements();
I !=
E; ++
I) {
1022 NewValue = StructValueState[{&*OldArg,
I}];
1026 NewValue = ValueState[&*OldArg];
1032void SCCPInstVisitor::visitInstruction(
Instruction &
I) {
1035 LLVM_DEBUG(
dbgs() <<
"SCCP: Don't know how to handle: " <<
I <<
'\n');
1036 markOverdefined(&
I);
1042 if (
IV.mergeIn(MergeWithV, Opts)) {
1043 pushToWorkList(
IV, V);
1044 LLVM_DEBUG(
dbgs() <<
"Merged " << MergeWithV <<
" into " << *V <<
" : "
1052 if (!KnownFeasibleEdges.
insert(Edge(Source, Dest)).second)
1060 <<
" -> " << Dest->
getName() <<
'\n');
1070void SCCPInstVisitor::getFeasibleSuccessors(
Instruction &TI,
1073 if (
auto *BI = dyn_cast<BranchInst>(&TI)) {
1074 if (BI->isUnconditional()) {
1080 ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
1085 Succs[0] = Succs[1] =
true;
1090 Succs[CI->
isZero()] =
true;
1101 if (
auto *SI = dyn_cast<SwitchInst>(&TI)) {
1102 if (!
SI->getNumCases()) {
1108 getConstantInt(SCValue,
SI->getCondition()->getType())) {
1109 Succs[
SI->findCaseValue(CI)->getSuccessorIndex()] =
true;
1117 unsigned ReachableCaseCount = 0;
1118 for (
const auto &Case :
SI->cases()) {
1119 const APInt &CaseValue = Case.getCaseValue()->getValue();
1121 Succs[Case.getSuccessorIndex()] =
true;
1122 ++ReachableCaseCount;
1126 Succs[
SI->case_default()->getSuccessorIndex()] =
1139 if (
auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
1143 getConstant(IBRValue, IBR->getAddress()->getType()));
1153 "Block address of a different function ?");
1154 for (
unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
1156 if (IBR->getDestination(i) ==
T) {
1167 LLVM_DEBUG(
dbgs() <<
"Unknown terminator instruction: " << TI <<
'\n');
1177 return KnownFeasibleEdges.
count(Edge(
From, To));
1197void SCCPInstVisitor::visitPHINode(
PHINode &PN) {
1201 return (
void)markOverdefined(&PN);
1203 if (getValueState(&PN).isOverdefined())
1209 return (
void)markOverdefined(&PN);
1211 unsigned NumActiveIncoming = 0;
1225 NumActiveIncoming++;
1235 mergeInValue(&PN, PhiState,
1237 NumActiveIncoming + 1));
1243void SCCPInstVisitor::visitReturnInst(
ReturnInst &
I) {
1244 if (
I.getNumOperands() == 0)
1248 Value *ResultOp =
I.getOperand(0);
1252 auto TFRVI = TrackedRetVals.find(
F);
1253 if (TFRVI != TrackedRetVals.end()) {
1254 mergeInValue(TFRVI->second,
F, getValueState(ResultOp));
1260 if (!TrackedMultipleRetVals.empty()) {
1261 if (
auto *STy = dyn_cast<StructType>(ResultOp->
getType()))
1262 if (MRVFunctionsTracked.count(
F))
1263 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1264 mergeInValue(TrackedMultipleRetVals[std::make_pair(
F, i)],
F,
1265 getStructValueState(ResultOp, i));
1269void SCCPInstVisitor::visitTerminator(
Instruction &TI) {
1271 getFeasibleSuccessors(TI, SuccFeasible);
1276 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++i)
1277 if (SuccFeasible[i])
1281void SCCPInstVisitor::visitCastInst(
CastInst &
I) {
1284 if (ValueState[&
I].isOverdefined())
1295 return (
void)markConstant(&
I,
C);
1298 if (
I.getDestTy()->isIntegerTy() &&
I.getSrcTy()->isIntOrIntVectorTy()) {
1299 auto &LV = getValueState(&
I);
1303 Type *DestTy =
I.getDestTy();
1309 if (
I.getOpcode() == Instruction::BitCast &&
1310 I.getOperand(0)->getType()->isVectorTy() &&
1312 return (
void)markOverdefined(&
I);
1315 OpRange.
castOp(
I.getOpcode(),
DL.getTypeSizeInBits(DestTy));
1318 markOverdefined(&
I);
1327 addAdditionalUser(
LHS, &EVI);
1328 addAdditionalUser(
RHS, &EVI);
1329 if (
L.isUnknownOrUndef() ||
R.isUnknownOrUndef())
1339 assert(
Idx == 1 &&
"Index can only be 0 or 1");
1344 markOverdefined(&EVI);
1352 return (
void)markOverdefined(&EVI);
1356 if (ValueState[&EVI].isOverdefined())
1357 return (
void)markOverdefined(&EVI);
1361 return (
void)markOverdefined(&EVI);
1366 if (
auto *WO = dyn_cast<WithOverflowInst>(AggVal))
1367 return handleExtractOfWithOverflow(EVI, WO, i);
1369 mergeInValue(getValueState(&EVI), &EVI, EltVal);
1372 return (
void)markOverdefined(&EVI);
1377 auto *STy = dyn_cast<StructType>(IVI.
getType());
1379 return (
void)markOverdefined(&IVI);
1384 return (
void)markOverdefined(&IVI);
1388 if (IVI.getNumIndices() != 1)
1389 return (
void)markOverdefined(&IVI);
1391 Value *Aggr = IVI.getAggregateOperand();
1392 unsigned Idx = *IVI.idx_begin();
1395 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1399 mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
1403 Value *Val = IVI.getInsertedValueOperand();
1406 markOverdefined(getStructValueState(&IVI, i), &IVI);
1409 mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
1414void SCCPInstVisitor::visitSelectInst(
SelectInst &
I) {
1417 if (
I.getType()->isStructTy())
1418 return (
void)markOverdefined(&
I);
1422 if (ValueState[&
I].isOverdefined())
1423 return (
void)markOverdefined(&
I);
1430 getConstantInt(CondValue,
I.getCondition()->getType())) {
1431 Value *OpVal = CondCB->isZero() ?
I.getFalseValue() :
I.getTrueValue();
1432 mergeInValue(&
I, getValueState(OpVal));
1442 bool Changed = ValueState[&
I].mergeIn(TVal);
1443 Changed |= ValueState[&
I].mergeIn(FVal);
1445 pushToWorkListMsg(ValueState[&
I], &
I);
1449void SCCPInstVisitor::visitUnaryOperator(
Instruction &
I) {
1456 return (
void)markOverdefined(&
I);
1465 return (
void)markConstant(
IV, &
I,
C);
1467 markOverdefined(&
I);
1470void SCCPInstVisitor::visitFreezeInst(
FreezeInst &
I) {
1473 if (
I.getType()->isStructTy())
1474 return (
void)markOverdefined(&
I);
1481 return (
void)markOverdefined(&
I);
1491 markOverdefined(&
I);
1495void SCCPInstVisitor::visitBinaryOperator(
Instruction &
I) {
1500 if (
IV.isOverdefined())
1508 return (
void)markOverdefined(&
I);
1520 auto *
C = dyn_cast_or_null<Constant>(R);
1529 return (
void)mergeInValue(&
I, NewV);
1534 if (!
I.getType()->isIntegerTy())
1535 return markOverdefined(&
I);
1543 auto *BO = cast<BinaryOperator>(&
I);
1544 ConstantRange R = ConstantRange::getEmpty(
I.getType()->getScalarSizeInBits());
1545 if (
auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO))
1546 R =
A.overflowingBinaryOp(BO->getOpcode(),
B, OBO->getNoWrapKind());
1548 R =
A.binaryOp(BO->getOpcode(),
B);
1557void SCCPInstVisitor::visitCmpInst(
CmpInst &
I) {
1561 return (
void)markOverdefined(&
I);
1563 Value *Op1 =
I.getOperand(0);
1564 Value *Op2 =
I.getOperand(1);
1568 auto V1State = getValueState(Op1);
1569 auto V2State = getValueState(Op2);
1575 mergeInValue(&
I, CV);
1584 markOverdefined(&
I);
1591 return (
void)markOverdefined(&
I);
1596 for (
unsigned i = 0, e =
I.getNumOperands(); i != e; ++i) {
1602 return (
void)markOverdefined(&
I);
1609 return (
void)markOverdefined(&
I);
1613 markConstant(&
I,
C);
1616void SCCPInstVisitor::visitStoreInst(
StoreInst &SI) {
1618 if (
SI.getOperand(0)->getType()->isStructTy())
1621 if (TrackedGlobals.empty() || !isa<GlobalVariable>(
SI.getOperand(1)))
1625 auto I = TrackedGlobals.find(GV);
1626 if (
I == TrackedGlobals.end())
1630 mergeInValue(
I->second, GV, getValueState(
SI.getOperand(0)),
1632 if (
I->second.isOverdefined())
1633 TrackedGlobals.erase(
I);
1637 if (
I->getType()->isIntegerTy()) {
1638 if (
MDNode *Ranges =
I->getMetadata(LLVMContext::MD_range))
1642 if (
const auto *CB = dyn_cast<CallBase>(
I))
1643 if (std::optional<ConstantRange>
Range = CB->getRange())
1646 if (
I->hasMetadata(LLVMContext::MD_nonnull))
1654void SCCPInstVisitor::visitLoadInst(
LoadInst &
I) {
1657 if (
I.getType()->isStructTy() ||
I.isVolatile())
1658 return (
void)markOverdefined(&
I);
1662 if (ValueState[&
I].isOverdefined())
1663 return (
void)markOverdefined(&
I);
1675 if (isa<ConstantPointerNull>(
Ptr)) {
1677 return (
void)markOverdefined(
IV, &
I);
1683 if (
auto *GV = dyn_cast<GlobalVariable>(
Ptr)) {
1684 if (!TrackedGlobals.empty()) {
1686 auto It = TrackedGlobals.find(GV);
1687 if (It != TrackedGlobals.end()) {
1696 return (
void)markConstant(
IV, &
I,
C);
1703void SCCPInstVisitor::visitCallBase(
CallBase &CB) {
1704 handleCallResult(CB);
1705 handleCallArguments(CB);
1708void SCCPInstVisitor::handleCallOverdefined(
CallBase &CB) {
1717 return (
void)markOverdefined(&CB);
1724 if (
A.get()->getType()->isStructTy())
1725 return markOverdefined(&CB);
1726 if (
A.get()->getType()->isMetadataTy())
1733 return (
void)markOverdefined(&CB);
1739 return (
void)markOverdefined(&CB);
1744 return (
void)markConstant(&CB,
C);
1751void SCCPInstVisitor::handleCallArguments(
CallBase &CB) {
1756 if (TrackingIncomingArguments.count(
F)) {
1765 if (AI->hasByValAttr() && !
F->onlyReadsMemory()) {
1766 markOverdefined(&*AI);
1770 if (
auto *STy = dyn_cast<StructType>(AI->getType())) {
1771 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1773 mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1782void SCCPInstVisitor::handleCallResult(
CallBase &CB) {
1785 if (
auto *
II = dyn_cast<IntrinsicInst>(&CB)) {
1786 if (
II->getIntrinsicID() == Intrinsic::ssa_copy) {
1787 if (ValueState[&CB].isOverdefined())
1793 assert(PI &&
"Missing predicate info for ssa.copy");
1795 const std::optional<PredicateConstraint> &Constraint =
1796 PI->getConstraint();
1798 mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1803 Value *OtherOp = Constraint->OtherOp;
1806 if (getValueState(OtherOp).isUnknown()) {
1807 addAdditionalUser(OtherOp, &CB);
1815 ConstantRange::getFull(
DL.getTypeSizeInBits(CopyOf->
getType()));
1826 auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1830 if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1838 addAdditionalUser(OtherOp, &CB);
1847 addAdditionalUser(OtherOp, &CB);
1848 mergeInValue(
IV, &CB, CondVal);
1852 addAdditionalUser(OtherOp, &CB);
1853 mergeInValue(
IV, &CB,
1858 return (
void)mergeInValue(
IV, &CB, CopyOfVal);
1883 if (!
F ||
F->isDeclaration())
1884 return handleCallOverdefined(CB);
1887 if (
auto *STy = dyn_cast<StructType>(
F->getReturnType())) {
1888 if (!MRVFunctionsTracked.count(
F))
1889 return handleCallOverdefined(CB);
1893 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1894 mergeInValue(getStructValueState(&CB, i), &CB,
1895 TrackedMultipleRetVals[std::make_pair(
F, i)],
1898 auto TFRVI = TrackedRetVals.find(
F);
1899 if (TFRVI == TrackedRetVals.end())
1900 return handleCallOverdefined(CB);
1909 while (!BBWorkList.empty() || !InstWorkList.empty() ||
1910 !OverdefinedInstWorkList.empty()) {
1913 while (!OverdefinedInstWorkList.empty()) {
1914 Value *
I = OverdefinedInstWorkList.pop_back_val();
1926 markUsersAsChanged(
I);
1930 while (!InstWorkList.empty()) {
1931 Value *
I = InstWorkList.pop_back_val();
1943 if (
I->getType()->isStructTy() || !getValueState(
I).isOverdefined())
1944 markUsersAsChanged(
I);
1948 while (!BBWorkList.empty()) {
1962 if (
I.getType()->isVoidTy())
1965 if (
auto *STy = dyn_cast<StructType>(
I.getType())) {
1969 if (
auto *CB = dyn_cast<CallBase>(&
I))
1971 if (MRVFunctionsTracked.count(
F))
1976 if (isa<ExtractValueInst>(
I) || isa<InsertValueInst>(
I))
1980 for (
unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1983 markOverdefined(LV, &
I);
1999 if (
auto *CB = dyn_cast<CallBase>(&
I))
2001 if (TrackedRetVals.count(
F))
2004 if (isa<LoadInst>(
I)) {
2011 markOverdefined(&
I);
2029 bool MadeChange =
false;
2031 if (!BBExecutable.count(&BB))
2039 <<
"\nResolved undefs in " <<
F.getName() <<
'\n');
2058 Visitor->addPredicateInfo(
F, DT, AC);
2062 return Visitor->markBlockExecutable(BB);
2066 return Visitor->getPredicateInfoFor(
I);
2070 Visitor->trackValueOfGlobalVariable(GV);
2074 Visitor->addTrackedFunction(
F);
2078 Visitor->addToMustPreserveReturnsInFunctions(
F);
2082 return Visitor->mustPreserveReturn(
F);
2086 Visitor->addArgumentTrackedFunction(
F);
2090 return Visitor->isArgumentTrackedFunction(
F);
2096 return Visitor->resolvedUndefsIn(
F);
2100 Visitor->solveWhileResolvedUndefsIn(M);
2105 Visitor->solveWhileResolvedUndefsIn(WorkList);
2109 Visitor->solveWhileResolvedUndefs();
2113 return Visitor->isBlockExecutable(BB);
2117 return Visitor->isEdgeFeasible(
From, To);
2120std::vector<ValueLatticeElement>
2122 return Visitor->getStructLatticeValueFor(V);
2126 return Visitor->removeLatticeValueFor(V);
2130 Visitor->resetLatticeValueFor(Call);
2134 return Visitor->getLatticeValueFor(V);
2139 return Visitor->getTrackedRetVals();
2144 return Visitor->getTrackedGlobals();
2148 return Visitor->getMRVFunctionsTracked();
2154 Visitor->trackValueOfArgument(V);
2158 return Visitor->isStructLatticeConstant(
F, STy);
2163 return Visitor->getConstant(LV, Ty);
2167 return Visitor->getConstantOrNull(V);
2171 return Visitor->getArgumentTrackedFunctions();
2176 Visitor->setLatticeValueForSpecializationArguments(
F, Args);
2180 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)
static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty, bool UndefAllowed)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
uint32_t getBitWidth() const
Get the bit width of this ConstantRange.
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.
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.
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 isIntOrIntVectorTy() const
Return true if this is an integer type or a vector of integer types.
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)
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)