47 #define DEBUG_TYPE "sccp"
49 STATISTIC(NumInstRemoved,
"Number of instructions removed");
50 STATISTIC(NumDeadBlocks ,
"Number of basic blocks unreachable");
52 STATISTIC(IPNumInstRemoved,
"Number of instructions removed by IPSCCP");
53 STATISTIC(IPNumArgsElimed ,
"Number of arguments constant propagated by IPSCCP");
54 STATISTIC(IPNumGlobalConst,
"Number of globals found to be constant by IPSCCP");
83 LatticeValueTy getLatticeValue()
const {
88 LatticeVal() : Val(nullptr, unknown) {}
90 bool isUnknown()
const {
return getLatticeValue() == unknown; }
91 bool isConstant()
const {
92 return getLatticeValue() == constant || getLatticeValue() == forcedconstant;
94 bool isOverdefined()
const {
return getLatticeValue() == overdefined; }
97 assert(isConstant() &&
"Cannot get the constant of a non-constant!");
98 return Val.getPointer();
102 bool markOverdefined() {
106 Val.setInt(overdefined);
112 if (getLatticeValue() == constant) {
113 assert(getConstant() == V &&
"Marking constant with different value");
118 Val.setInt(constant);
119 assert(V &&
"Marking constant with NULL");
122 assert(getLatticeValue() == forcedconstant &&
123 "Cannot move from overdefined to constant!");
125 if (V == getConstant())
return false;
130 Val.setInt(overdefined);
143 void markForcedConstant(
Constant *V) {
144 assert(isUnknown() &&
"Can't force a defined value!");
145 Val.setInt(forcedconstant);
159 class SCCPSolver :
public InstVisitor<SCCPSolver> {
209 typedef std::pair<BasicBlock*, BasicBlock*> Edge;
213 : DL(DL), TLI(tli) {}
220 if (!BBExecutable.insert(BB).second)
223 BBWorkList.push_back(BB);
234 LatticeVal &IV = TrackedGlobals[GV];
246 MRVFunctionsTracked.insert(F);
247 for (
unsigned i = 0, e = STy->getNumElements();
i != e; ++
i)
248 TrackedMultipleRetVals.insert(std::make_pair(std::make_pair(F,
i),
251 TrackedRetVals.insert(std::make_pair(F, LatticeVal()));
254 void AddArgumentTrackedFunction(
Function *F) {
255 TrackingIncomingArguments.insert(F);
269 bool isBlockExecutable(
BasicBlock *BB)
const {
270 return BBExecutable.count(BB);
273 std::vector<LatticeVal> getStructLatticeValueFor(
Value *V)
const {
274 std::vector<LatticeVal> StructValues;
276 assert(STy &&
"getStructLatticeValueFor() can be called only on structs");
277 for (
unsigned i = 0, e = STy->getNumElements();
i != e; ++
i) {
278 auto I = StructValueState.find(std::make_pair(V,
i));
279 assert(
I != StructValueState.end() &&
"Value not in valuemap!");
280 StructValues.push_back(
I->second);
285 LatticeVal getLatticeValueFor(
Value *V)
const {
287 assert(I != ValueState.
end() &&
"V is not in valuemap!");
294 return TrackedRetVals;
300 return TrackedGlobals;
306 return MRVFunctionsTracked;
309 void markOverdefined(
Value *V) {
311 "structs should use markAnythingOverdefined");
312 markOverdefined(ValueState[V], V);
317 void markAnythingOverdefined(
Value *V) {
318 if (
auto *STy = dyn_cast<StructType>(V->
getType()))
319 for (
unsigned i = 0, e = STy->getNumElements();
i != e; ++
i)
320 markOverdefined(getStructValueState(V,
i), V);
330 const auto &It = TrackedMultipleRetVals.find(std::make_pair(F,
i));
331 assert(It != TrackedMultipleRetVals.end());
332 LatticeVal LV = It->second;
333 if (LV.isOverdefined())
341 void pushToWorkList(LatticeVal &IV,
Value *V) {
342 if (IV.isOverdefined())
343 return OverdefinedInstWorkList.push_back(V);
344 InstWorkList.push_back(V);
352 if (!IV.markConstant(C))
return;
353 DEBUG(
dbgs() <<
"markConstant: " << *C <<
": " << *V <<
'\n');
354 pushToWorkList(IV, V);
359 markConstant(ValueState[V], V, C);
364 LatticeVal &IV = ValueState[V];
365 IV.markForcedConstant(C);
366 DEBUG(
dbgs() <<
"markForcedConstant: " << *C <<
": " << *V <<
'\n');
367 pushToWorkList(IV, V);
374 void markOverdefined(LatticeVal &IV,
Value *V) {
375 if (!IV.markOverdefined())
return;
378 if (
auto *F = dyn_cast<Function>(V))
381 dbgs() << *V <<
'\n');
383 pushToWorkList(IV, V);
386 void mergeInValue(LatticeVal &IV,
Value *V, LatticeVal MergeWithV) {
387 if (IV.isOverdefined() || MergeWithV.isUnknown())
389 if (MergeWithV.isOverdefined())
390 return markOverdefined(IV, V);
392 return markConstant(IV, V, MergeWithV.getConstant());
393 if (IV.getConstant() != MergeWithV.getConstant())
394 return markOverdefined(IV, V);
397 void mergeInValue(
Value *V, LatticeVal MergeWithV) {
399 "non-structs should use markConstant");
400 mergeInValue(ValueState[V], V, MergeWithV);
407 LatticeVal &getValueState(
Value *V) {
410 std::pair<DenseMap<Value*, LatticeVal>::iterator,
bool> I =
411 ValueState.
insert(std::make_pair(V, LatticeVal()));
412 LatticeVal &LV = I.first->second;
417 if (
auto *C = dyn_cast<Constant>(V)) {
419 if (!isa<UndefValue>(V))
430 LatticeVal &getStructValueState(
Value *V,
unsigned i) {
432 assert(i < cast<StructType>(V->
getType())->getNumElements() &&
433 "Invalid element #");
435 std::pair<DenseMap<std::pair<Value*, unsigned>, LatticeVal>::iterator,
436 bool> I = StructValueState.insert(
437 std::make_pair(std::make_pair(V, i), LatticeVal()));
438 LatticeVal &LV = I.first->second;
443 if (
auto *C = dyn_cast<Constant>(V)) {
447 LV.markOverdefined();
448 else if (isa<UndefValue>(Elt))
451 LV.markConstant(Elt);
462 if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
465 if (!MarkBlockExecutable(Dest)) {
470 <<
" -> " << Dest->
getName() <<
'\n');
516 void visitLandingPadInst(
LandingPadInst &I) { markAnythingOverdefined(&I); }
518 markAnythingOverdefined(&FPI);
521 markAnythingOverdefined(&CPI);
522 visitTerminatorInst(CPI);
534 visitTerminatorInst(II);
541 markAnythingOverdefined(&I);
543 void visitAtomicRMWInst (
AtomicRMWInst &I) { markOverdefined(&I); }
544 void visitAllocaInst (
Instruction &I) { markOverdefined(&I); }
545 void visitVAArgInst (
Instruction &I) { markAnythingOverdefined(&I); }
549 DEBUG(
dbgs() <<
"SCCP: Don't know how to handle: " << I <<
'\n');
550 markAnythingOverdefined(&I);
563 if (
auto *BI = dyn_cast<BranchInst>(&TI)) {
564 if (BI->isUnconditional()) {
569 LatticeVal BCValue = getValueState(BI->getCondition());
574 if (!BCValue.isUnknown())
575 Succs[0] = Succs[1] =
true;
580 Succs[CI->isZero()] =
true;
590 if (
auto *
SI = dyn_cast<SwitchInst>(&TI)) {
591 if (!
SI->getNumCases()) {
595 LatticeVal SCValue = getValueState(
SI->getCondition());
600 if (!SCValue.isUnknown())
605 Succs[
SI->findCaseValue(CI).getSuccessorIndex()] =
true;
610 if (isa<IndirectBrInst>(&TI)) {
616 DEBUG(
dbgs() <<
"Unknown terminator instruction: " << TI <<
'\n');
625 assert(BBExecutable.count(To) &&
"Dest should always be alive!");
628 if (!BBExecutable.count(From))
return false;
632 if (
auto *BI = dyn_cast<BranchInst>(TI)) {
633 if (BI->isUnconditional())
636 LatticeVal BCValue = getValueState(BI->getCondition());
642 return !BCValue.isUnknown();
645 return BI->getSuccessor(CI->isZero()) == To;
652 if (
auto *
SI = dyn_cast<SwitchInst>(TI)) {
653 if (
SI->getNumCases() < 1)
656 LatticeVal SCValue = getValueState(
SI->getCondition());
660 return !SCValue.isUnknown();
662 return SI->findCaseValue(CI).getCaseSuccessor() == To;
667 if (isa<IndirectBrInst>(TI))
670 DEBUG(
dbgs() <<
"Unknown terminator instruction: " << *TI <<
'\n');
692 void SCCPSolver::visitPHINode(
PHINode &PN) {
696 return markAnythingOverdefined(&PN);
698 if (getValueState(&PN).isOverdefined())
704 return markOverdefined(&PN);
715 if (IV.isUnknown())
continue;
720 if (IV.isOverdefined())
721 return markOverdefined(&PN);
724 OperandVal = IV.getConstant();
734 if (IV.getConstant() != OperandVal)
735 return markOverdefined(&PN);
744 markConstant(&PN, OperandVal);
747 void SCCPSolver::visitReturnInst(
ReturnInst &I) {
756 TrackedRetVals.
find(F);
757 if (TFRVI != TrackedRetVals.
end()) {
758 mergeInValue(TFRVI->second, F, getValueState(ResultOp));
764 if (!TrackedMultipleRetVals.empty()) {
765 if (
auto *STy = dyn_cast<StructType>(ResultOp->
getType()))
766 if (MRVFunctionsTracked.count(F))
768 mergeInValue(TrackedMultipleRetVals[std::make_pair(F, i)],
F,
769 getStructValueState(ResultOp, i));
776 getFeasibleSuccessors(TI, SuccFeasible);
781 for (
unsigned i = 0, e = SuccFeasible.
size(); i != e; ++
i)
786 void SCCPSolver::visitCastInst(
CastInst &I) {
787 LatticeVal OpSt = getValueState(I.
getOperand(0));
788 if (OpSt.isOverdefined())
790 else if (OpSt.isConstant()) {
794 if (isa<UndefValue>(C))
806 return markAnythingOverdefined(&EVI);
810 return markOverdefined(&EVI);
815 LatticeVal EltVal = getStructValueState(AggVal, i);
816 mergeInValue(getValueState(&EVI), &EVI, EltVal);
819 return markOverdefined(&EVI);
826 return markOverdefined(&IVI);
831 return markAnythingOverdefined(&IVI);
840 LatticeVal EltVal = getStructValueState(Aggr, i);
841 mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
848 markOverdefined(getStructValueState(&IVI, i), &IVI);
850 LatticeVal InVal = getValueState(Val);
851 mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
856 void SCCPSolver::visitSelectInst(
SelectInst &I) {
860 return markAnythingOverdefined(&I);
863 if (CondValue.isUnknown())
866 if (
ConstantInt *CondCB = CondValue.getConstantInt()) {
868 mergeInValue(&I, getValueState(OpVal));
879 if (TVal.isConstant() && FVal.isConstant() &&
880 TVal.getConstant() == FVal.getConstant())
881 return markConstant(&I, FVal.getConstant());
883 if (TVal.isUnknown())
884 return mergeInValue(&I, FVal);
885 if (FVal.isUnknown())
886 return mergeInValue(&I, TVal);
891 void SCCPSolver::visitBinaryOperator(
Instruction &I) {
892 LatticeVal V1State = getValueState(I.
getOperand(0));
893 LatticeVal V2State = getValueState(I.
getOperand(1));
895 LatticeVal &IV = ValueState[&
I];
896 if (IV.isOverdefined())
return;
898 if (V1State.isConstant() && V2State.isConstant()) {
900 V2State.getConstant());
902 if (isa<UndefValue>(C))
904 return markConstant(IV, &I, C);
908 if (!V1State.isOverdefined() && !V2State.isOverdefined())
918 LatticeVal *NonOverdefVal =
nullptr;
919 if (!V1State.isOverdefined())
920 NonOverdefVal = &V1State;
921 else if (!V2State.isOverdefined())
922 NonOverdefVal = &V2State;
925 if (NonOverdefVal->isUnknown())
932 if (NonOverdefVal->getConstant()->isNullValue())
933 return markConstant(IV, &I, NonOverdefVal->getConstant());
936 if (
ConstantInt *CI = NonOverdefVal->getConstantInt())
937 if (CI->isAllOnesValue())
938 return markConstant(IV, &I, NonOverdefVal->getConstant());
948 void SCCPSolver::visitCmpInst(
CmpInst &I) {
949 LatticeVal V1State = getValueState(I.
getOperand(0));
950 LatticeVal V2State = getValueState(I.
getOperand(1));
952 LatticeVal &IV = ValueState[&
I];
953 if (IV.isOverdefined())
return;
955 if (V1State.isConstant() && V2State.isConstant()) {
957 I.
getPredicate(), V1State.getConstant(), V2State.getConstant());
958 if (isa<UndefValue>(C))
960 return markConstant(IV, &I, C);
964 if (!V1State.isOverdefined() && !V2State.isOverdefined())
974 if (ValueState[&I].isOverdefined())
return;
980 LatticeVal State = getValueState(I.
getOperand(i));
981 if (State.isUnknown())
984 if (State.isOverdefined())
985 return markOverdefined(&I);
987 assert(State.isConstant() &&
"Unknown state!");
995 if (isa<UndefValue>(C))
1005 if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.
getOperand(1)))
1010 if (I == TrackedGlobals.end() || I->second.isOverdefined())
return;
1013 mergeInValue(I->second, GV, getValueState(SI.
getOperand(0)));
1014 if (I->second.isOverdefined())
1015 TrackedGlobals.erase(I);
1021 void SCCPSolver::visitLoadInst(
LoadInst &I) {
1024 return markAnythingOverdefined(&I);
1026 LatticeVal PtrVal = getValueState(I.
getOperand(0));
1027 if (PtrVal.isUnknown())
return;
1029 LatticeVal &IV = ValueState[&
I];
1030 if (IV.isOverdefined())
return;
1033 return markOverdefined(IV, &I);
1035 Constant *Ptr = PtrVal.getConstant();
1042 if (
auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
1043 if (!TrackedGlobals.empty()) {
1046 TrackedGlobals.
find(GV);
1047 if (It != TrackedGlobals.
end()) {
1048 mergeInValue(IV, &I, It->second);
1056 if (isa<UndefValue>(C))
1058 return markConstant(IV, &I, C);
1063 markOverdefined(IV, &I);
1066 void SCCPSolver::visitCallSite(
CallSite CS) {
1086 LatticeVal State = getValueState(*AI);
1088 if (State.isUnknown())
1090 if (State.isOverdefined())
1091 return markOverdefined(I);
1092 assert(State.isConstant() &&
"Unknown state!");
1093 Operands.
push_back(State.getConstant());
1096 if (getValueState(I).isOverdefined())
1103 if (isa<UndefValue>(C))
1105 return markConstant(I, C);
1110 return markAnythingOverdefined(I);
1116 if (!TrackingIncomingArguments.empty() && TrackingIncomingArguments.count(F)){
1117 MarkBlockExecutable(&F->
front());
1122 AI !=
E; ++AI, ++CAI) {
1126 markOverdefined(&*AI);
1130 if (
auto *STy = dyn_cast<StructType>(AI->getType())) {
1132 LatticeVal
CallArg = getStructValueState(*CAI, i);
1133 mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg);
1136 mergeInValue(&*AI, getValueState(*CAI));
1143 if (!MRVFunctionsTracked.count(F))
1144 goto CallOverdefined;
1149 mergeInValue(getStructValueState(I, i),
I,
1150 TrackedMultipleRetVals[std::make_pair(F, i)]);
1153 if (TFRVI == TrackedRetVals.
end())
1154 goto CallOverdefined;
1157 mergeInValue(I, TFRVI->second);
1161 void SCCPSolver::Solve() {
1163 while (!BBWorkList.empty() || !InstWorkList.empty() ||
1164 !OverdefinedInstWorkList.empty()) {
1167 while (!OverdefinedInstWorkList.empty()) {
1168 Value *I = OverdefinedInstWorkList.pop_back_val();
1170 DEBUG(
dbgs() <<
"\nPopped off OI-WL: " << *I <<
'\n');
1180 if (
auto *UI = dyn_cast<Instruction>(U))
1181 OperandChangedState(UI);
1185 while (!InstWorkList.empty()) {
1186 Value *I = InstWorkList.pop_back_val();
1188 DEBUG(
dbgs() <<
"\nPopped off I-WL: " << *I <<
'\n');
1199 if (
auto *UI = dyn_cast<Instruction>(U))
1200 OperandChangedState(UI);
1204 while (!BBWorkList.empty()) {
1206 BBWorkList.pop_back();
1208 DEBUG(
dbgs() <<
"\nPopped off BBWL: " << *BB <<
'\n');
1235 bool SCCPSolver::ResolvedUndefsIn(
Function &F) {
1237 if (!BBExecutable.count(&BB))
1244 if (
auto *STy = dyn_cast<StructType>(I.
getType())) {
1250 if (MRVFunctionsTracked.count(F))
1255 if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(
I))
1261 LatticeVal &LV = getStructValueState(&I, i);
1263 markOverdefined(LV, &I);
1268 LatticeVal &LV = getValueState(&I);
1269 if (!LV.isUnknown())
continue;
1272 if (isa<ExtractValueInst>(I))
1279 markOverdefined(&I);
1282 LatticeVal Op0LV = getValueState(I.getOperand(0));
1284 if (I.getNumOperands() == 2) {
1286 markOverdefined(&I);
1290 Op1LV = getValueState(I.getOperand(1));
1295 switch (I.getOpcode()) {
1297 case Instruction::Sub:
1298 case Instruction::Trunc:
1299 case Instruction::FPTrunc:
1300 case Instruction::BitCast:
1302 case Instruction::FSub:
1303 case Instruction::FAdd:
1304 case Instruction::FMul:
1305 case Instruction::FDiv:
1306 case Instruction::FRem:
1308 if (Op0LV.isUnknown() && Op1LV.isUnknown())
1311 markOverdefined(&I);
1313 case Instruction::ZExt:
1314 case Instruction::SExt:
1315 case Instruction::FPToUI:
1316 case Instruction::FPToSI:
1317 case Instruction::FPExt:
1318 case Instruction::PtrToInt:
1319 case Instruction::IntToPtr:
1320 case Instruction::SIToFP:
1321 case Instruction::UIToFP:
1325 case Instruction::Mul:
1328 if (Op0LV.isUnknown() && Op1LV.isUnknown())
1337 if (Op0LV.isUnknown() && Op1LV.isUnknown())
1347 if (Op0LV.isUnknown() && Op1LV.isUnknown()) {
1354 case Instruction::SDiv:
1355 case Instruction::UDiv:
1356 case Instruction::SRem:
1357 case Instruction::URem:
1360 if (Op1LV.isUnknown())
break;
1364 if (Op1LV.isConstant() && Op1LV.getConstant()->isZeroValue())
1372 case Instruction::AShr:
1374 if (Op1LV.isUnknown())
break;
1377 if (Op1LV.isConstant()) {
1378 if (
auto *ShiftAmt = Op1LV.getConstantInt())
1379 if (ShiftAmt->getLimitedValue() >=
1380 ShiftAmt->getType()->getScalarSizeInBits())
1387 case Instruction::LShr:
1388 case Instruction::Shl:
1391 if (Op1LV.isUnknown())
break;
1394 if (Op1LV.isConstant()) {
1395 if (
auto *ShiftAmt = Op1LV.getConstantInt())
1396 if (ShiftAmt->getLimitedValue() >=
1397 ShiftAmt->getType()->getScalarSizeInBits())
1406 Op1LV = getValueState(I.getOperand(1));
1408 if (Op0LV.isUnknown()) {
1409 if (!Op1LV.isConstant())
1410 Op1LV = getValueState(I.getOperand(2));
1411 }
else if (Op1LV.isUnknown()) {
1413 Op1LV = getValueState(I.getOperand(2));
1414 if (Op1LV.isUnknown())
1421 if (Op1LV.isConstant())
1422 markForcedConstant(&I, Op1LV.getConstant());
1424 markOverdefined(&I);
1431 case Instruction::ICmp:
1433 if (cast<ICmpInst>(&I)->isEquality())
1435 markOverdefined(&I);
1438 case Instruction::Invoke: {
1445 if (TrackedRetVals.count(F))
1450 markOverdefined(&I);
1456 markOverdefined(&I);
1465 if (
auto *BI = dyn_cast<BranchInst>(TI)) {
1466 if (!BI->isConditional())
continue;
1467 if (!getValueState(BI->getCondition()).isUnknown())
1472 if (isa<UndefValue>(BI->getCondition())) {
1481 markForcedConstant(BI->getCondition(),
1486 if (
auto *SI = dyn_cast<SwitchInst>(TI)) {
1487 if (!SI->getNumCases() || !getValueState(SI->getCondition()).isUnknown())
1492 if (isa<UndefValue>(SI->getCondition())) {
1493 SI->setCondition(SI->case_begin().getCaseValue());
1494 markEdgeExecutable(&BB, SI->case_begin().getCaseSuccessor());
1498 markForcedConstant(SI->getCondition(), SI->case_begin().getCaseValue());
1509 std::vector<LatticeVal> IVs = Solver.getStructLatticeValueFor(V);
1510 if (
any_of(IVs, [](
const LatticeVal &LV) {
return LV.isOverdefined(); }))
1512 std::vector<Constant *> ConstVals;
1514 for (
unsigned i = 0, e =
ST->getNumElements(); i != e; ++
i) {
1515 LatticeVal V = IVs[
i];
1516 ConstVals.push_back(V.isConstant()
1522 LatticeVal IV = Solver.getLatticeValueFor(V);
1523 if (IV.isOverdefined())
1527 assert(Const &&
"Constant is nullptr here!");
1528 DEBUG(
dbgs() <<
" Constant: " << *Const <<
" = " << *V <<
'\n');
1541 SCCPSolver Solver(DL, TLI);
1544 Solver.MarkBlockExecutable(&F.
front());
1548 Solver.markAnythingOverdefined(&AI);
1551 bool ResolvedUndefs =
true;
1552 while (ResolvedUndefs) {
1555 ResolvedUndefs = Solver.ResolvedUndefsIn(F);
1558 bool MadeChanges =
false;
1565 if (!Solver.isBlockExecutable(&BB)) {
1566 DEBUG(
dbgs() <<
" BasicBlock Dead:" << BB);
1627 bool runOnFunction(
Function &F)
override {
1628 if (skipFunction(F))
1632 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1640 "Sparse Conditional Constant Propagation",
false,
false)
1652 for (
const Use &U : GV->
uses()) {
1653 const User *UR = U.getUser();
1654 if (
const auto *SI = dyn_cast<StoreInst>(UR)) {
1657 }
else if (isa<InvokeInst>(UR) || isa<CallInst>(UR)) {
1662 }
else if (
const auto *LI = dyn_cast<LoadInst>(UR)) {
1663 if (LI->isVolatile())
1665 }
else if (isa<BlockAddress>(UR)) {
1683 if (
auto *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
1684 if (!isa<UndefValue>(RI->getOperand(0)))
1690 SCCPSolver Solver(DL, TLI);
1712 Solver.AddTrackedFunction(&F);
1719 AddressTakenFunctions.
insert(&F);
1721 Solver.AddArgumentTrackedFunction(&F);
1727 Solver.MarkBlockExecutable(&F.
front());
1731 Solver.markAnythingOverdefined(&AI);
1739 Solver.TrackValueOfGlobalVariable(&
G);
1742 bool ResolvedUndefs =
true;
1743 while (ResolvedUndefs) {
1747 ResolvedUndefs =
false;
1749 ResolvedUndefs |= Solver.ResolvedUndefsIn(F);
1752 bool MadeChanges =
false;
1763 if (Solver.isBlockExecutable(&F.
front())) {
1766 if (AI->use_empty())
1774 if (!Solver.isBlockExecutable(&*BB)) {
1775 DEBUG(
dbgs() <<
" BasicBlock Dead:" << *BB);
1783 if (&*BB != &F.
front())
1793 if (!isa<CallInst>(Inst) && !isa<TerminatorInst>(Inst))
1805 for (
unsigned i = 0, e = BlocksToErase.
size(); i != e; ++
i) {
1814 do { ++UI; }
while (UI != UE && *UI == I);
1825 if (
auto *BI = dyn_cast<BranchInst>(I)) {
1826 assert(BI->isConditional() && isa<UndefValue>(BI->getCondition()) &&
1827 "Branch should be foldable!");
1828 }
else if (
auto *SI = dyn_cast<SwitchInst>(I)) {
1829 assert(isa<UndefValue>(SI->getCondition()) &&
"Switch should fold");
1851 BlocksToErase.
clear();
1867 for (
const auto &I : RV) {
1874 for (
const auto &F : Solver.getMRVFunctionsTracked()) {
1876 "The return type should be a struct");
1878 if (Solver.isStructLatticeConstant(F, STy))
1883 for (
unsigned i = 0, e = ReturnsToZap.
size(); i != e; ++
i) {
1884 Function *F = ReturnsToZap[
i]->getParent()->getParent();
1892 E = TG.
end(); I !=
E; ++
I) {
1894 assert(!I->second.isOverdefined() &&
1895 "Overdefined values should have been taken out of the map!");
1901 M.getGlobalList().
erase(GV);
1930 bool runOnModule(
Module &M)
override {
1935 &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
1947 "Interprocedural Sparse Conditional Constant Propagation",
Legacy wrapper pass to provide the GlobalsAAResult object.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Return a value (possibly void), from a function.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
static ConstantInt * getFalse(LLVMContext &Context)
Instruction::CastOps getOpcode() const
Return the opcode of this CastInst.
This class is the base class for the comparison instructions.
INITIALIZE_PASS_BEGIN(SCCPLegacyPass,"sccp","Sparse Conditional Constant Propagation", false, false) INITIALIZE_PASS_END(SCCPLegacyPass
iterator_range< use_iterator > uses()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void removePredecessor(BasicBlock *Pred, bool DontDeleteUselessPHIs=false)
Notify the BasicBlock that the predecessor Pred is no longer able to reach it.
static bool runIPSCCP(Module &M, const DataLayout &DL, const TargetLibraryInfo *TLI)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVM Argument representation.
Base class for instruction visitors.
Value * getAggregateOperand()
const Instruction & back() const
Type * getSourceElementType() const
STATISTIC(NumFunctions,"Total number of functions")
iterator erase(iterator where)
bool isVolatile() const
Return true if this is a store to a volatile memory location.
This is the interface for a simple mod/ref and alias analysis over globals.
bool onlyReadsMemory() const
Determine if the function does not access or only reads memory.
bool canConstantFoldCallTo(const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function...
A Module instance is used to store all the information related to an LLVM module. ...
An instruction for ordering other memory operations.
an instruction that atomically checks whether a specified value is in a memory location, and, if it is, stores a new value there.
static bool AddressIsTaken(const GlobalValue *GV)
Implements a dense probed hash-table based set.
unsigned getNumOperands() const
Type * getValueType() const
This class represents a function call, abstracting a target machine's calling convention.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
ModulePass * createIPSCCPPass()
createIPSCCPPass - This pass propagates constants from call sites into the bodies of functions...
bool hasExactDefinition() const
Return true if this global has an exact defintion.
Type * getReturnType() const
Returns the type of the ret val.
unsigned getNumIndices() const
const Function * getParent() const
Return the enclosing method, or null if none.
An instruction for reading from memory.
an instruction that atomically reads a memory location, combines it with another value, and then stores the result back.
static Constant * getCompare(unsigned short pred, Constant *C1, Constant *C2, bool OnlyIfReduced=false)
Return an ICmp or FCmp comparison operator constant expression.
static bool runSCCP(Function &F, const DataLayout &DL, const TargetLibraryInfo *TLI)
void reserve(size_type N)
unsigned changeToUnreachable(Instruction *I, bool UseLLVMTrap, bool PreserveLCSSA=false)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
StringRef getName() const
Return a constant reference to the value's name.
iterator begin()
Instruction iterator methods.
bool isSingleValueType() const
Return true if the type is a valid type for a register in codegen.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
This class represents the LLVM 'select' instruction.
This is the base class for all instructions that perform data casts.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
void initializeSCCPLegacyPassPass(PassRegistry &)
bool ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions=false, const TargetLibraryInfo *TLI=nullptr)
If a terminator instruction is predicated on a constant value, convert it into an unconditional branc...
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
FunctionPass * createSCCPPass()
void assign(size_type NumElts, const T &Elt)
static Constant * get(unsigned Opcode, Constant *C1, Constant *C2, unsigned Flags=0, Type *OnlyIfReducedTy=nullptr)
get - Return a binary or shift operator constant expression, folding if possible. ...
user_iterator_impl< User > user_iterator
Value * getInsertedValueOperand()
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
unsigned getNumIncomingValues() const
Return the number of incoming edges.
unsigned getNumSuccessors() const
Return the number of successors that this terminator has.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
The landingpad instruction holds all of the information necessary to generate correct exception handl...
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM Basic Block Representation.
PointerIntPair - This class implements a pair of a pointer and small integer.
The instances of the Type class are immutable: once they are created, they are never changed...
BasicBlock * getSuccessor(unsigned idx) const
Return the specified successor.
This is an important base class in LLVM.
const Value * getCondition() const
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
This file contains the declarations for the subclasses of Constant, which represent the different fla...
APInt Or(const APInt &LHS, const APInt &RHS)
Bitwise OR function for APInt.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
APInt Xor(const APInt &LHS, const APInt &RHS)
Bitwise XOR function for APInt.
Represent the analysis usage information of a pass.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
bool any_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly...
Analysis pass providing a never-invalidated alias analysis result.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
Value * getOperand(unsigned i) const
Predicate getPredicate() const
Return the predicate for this instruction.
static Constant * get(StructType *T, ArrayRef< Constant * > V)
Constant * getAggregateElement(unsigned Elt) const
For aggregates (struct/array/vector) return the constant that corresponds to the specified element if...
Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, const DataLayout &DL)
ConstantFoldLoadFromConstPtr - Return the value that a load from C would produce if it is constant an...
static Constant * getAllOnesValue(Type *Ty)
Get the all ones value.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVMContext & getContext() const
All values hold a context through their type.
const Value * getTrueValue() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
User::op_iterator arg_iterator
arg_iterator - The type of iterator to use when looping over actual arguments at this call site...
Sparse Conditional Constant Propagation
idx_iterator idx_begin() const
Iterator for intrusive lists based on ilist_node.
const BasicBlockListType & getBasicBlockList() const
static bool tryToReplaceWithConstant(SCCPSolver &Solver, Value *V)
Sparse Conditional Constant false
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
InstrTy * getInstruction() const
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
Provides information about what library functions are available for the current target.
bool isVolatile() const
Return true if this is a load from a volatile memory location.
static BranchInst * Create(BasicBlock *IfTrue, Instruction *InsertBefore=nullptr)
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
unsigned removeAllNonTerminatorAndEHPadInstructions(BasicBlock *BB)
Remove all instructions from a basic block other than it's terminator and any present EH pad instruct...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
static void findReturnsToZap(Function &F, SmallPtrSet< Function *, 32 > &AddressTakenFunctions, SmallVector< ReturnInst *, 8 > &ReturnsToZap)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
iterator_range< user_iterator > users()
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
bool isStructTy() const
True if this is an instance of StructType.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
void initializeIPSCCPLegacyPassPass(PassRegistry &)
ImmutableCallSite - establish a view to a call site for examination.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
iterator find(const KeyT &Val)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static Function * getCalledFunction(const Value *V, bool LookThroughBitCast, bool &IsNoBuiltin)
bool hasLocalLinkage() const
Analysis pass providing the TargetLibraryInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
const BasicBlock & front() const
void removeDeadConstantUsers() const
If there are any dead constant users dangling off of this constant, remove them.
FunTy * getCalledFunction() const
getCalledFunction - Return the function being called if this is a direct call, otherwise return null ...
Module * getParent()
Get the module that this global value is contained inside of...
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
bool isExceptional() const
const Value * getFalseValue() const
A container for analyses that lazily runs them and caches their results.
unsigned getNumElements() const
Random access to the elements.
const BasicBlock * getParent() const
iterator_range< arg_iterator > args()
Constant * ConstantFoldCall(Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
bool isCallee(Value::const_user_iterator UI) const
isCallee - Determine whether the passed iterator points to the callee operand's Use.
bool isVoidTy() const
Return true if this is 'void'.
This instruction inserts a struct field of array element value into an aggregate value.