xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Utils/SCCPSolver.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1fe6060f1SDimitry Andric //===- SCCPSolver.cpp - SCCP Utility --------------------------- *- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric //
9fe6060f1SDimitry Andric // \file
10fe6060f1SDimitry Andric // This file implements the Sparse Conditional Constant Propagation (SCCP)
11fe6060f1SDimitry Andric // utility.
12fe6060f1SDimitry Andric //
13fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
14fe6060f1SDimitry Andric 
15fe6060f1SDimitry Andric #include "llvm/Transforms/Utils/SCCPSolver.h"
16fe6060f1SDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
17fe6060f1SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
1881ad6265SDimitry Andric #include "llvm/Analysis/ValueLattice.h"
19bdd1243dSDimitry Andric #include "llvm/Analysis/ValueLatticeUtils.h"
2006c3fb27SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
2181ad6265SDimitry Andric #include "llvm/IR/InstVisitor.h"
22fe6060f1SDimitry Andric #include "llvm/Support/Casting.h"
23fe6060f1SDimitry Andric #include "llvm/Support/Debug.h"
24fe6060f1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25fe6060f1SDimitry Andric #include "llvm/Support/raw_ostream.h"
26bdd1243dSDimitry Andric #include "llvm/Transforms/Utils/Local.h"
27fe6060f1SDimitry Andric #include <cassert>
28fe6060f1SDimitry Andric #include <utility>
29fe6060f1SDimitry Andric #include <vector>
30fe6060f1SDimitry Andric 
31fe6060f1SDimitry Andric using namespace llvm;
32fe6060f1SDimitry Andric 
33fe6060f1SDimitry Andric #define DEBUG_TYPE "sccp"
34fe6060f1SDimitry Andric 
35fe6060f1SDimitry Andric // The maximum number of range extensions allowed for operations requiring
36fe6060f1SDimitry Andric // widening.
37fe6060f1SDimitry Andric static const unsigned MaxNumRangeExtensions = 10;
38fe6060f1SDimitry Andric 
39fe6060f1SDimitry Andric /// Returns MergeOptions with MaxWidenSteps set to MaxNumRangeExtensions.
40fe6060f1SDimitry Andric static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts() {
41fe6060f1SDimitry Andric   return ValueLatticeElement::MergeOptions().setMaxWidenSteps(
42fe6060f1SDimitry Andric       MaxNumRangeExtensions);
43fe6060f1SDimitry Andric }
44fe6060f1SDimitry Andric 
4506c3fb27SDimitry Andric static ConstantRange getConstantRange(const ValueLatticeElement &LV, Type *Ty,
4606c3fb27SDimitry Andric                                       bool UndefAllowed = true) {
4706c3fb27SDimitry Andric   assert(Ty->isIntOrIntVectorTy() && "Should be int or int vector");
4806c3fb27SDimitry Andric   if (LV.isConstantRange(UndefAllowed))
4906c3fb27SDimitry Andric     return LV.getConstantRange();
5006c3fb27SDimitry Andric   return ConstantRange::getFull(Ty->getScalarSizeInBits());
5106c3fb27SDimitry Andric }
5206c3fb27SDimitry Andric 
53bdd1243dSDimitry Andric namespace llvm {
54fe6060f1SDimitry Andric 
55bdd1243dSDimitry Andric bool SCCPSolver::isConstant(const ValueLatticeElement &LV) {
56fe6060f1SDimitry Andric   return LV.isConstant() ||
57fe6060f1SDimitry Andric          (LV.isConstantRange() && LV.getConstantRange().isSingleElement());
58fe6060f1SDimitry Andric }
59fe6060f1SDimitry Andric 
60bdd1243dSDimitry Andric bool SCCPSolver::isOverdefined(const ValueLatticeElement &LV) {
61bdd1243dSDimitry Andric   return !LV.isUnknownOrUndef() && !SCCPSolver::isConstant(LV);
62fe6060f1SDimitry Andric }
63fe6060f1SDimitry Andric 
64bdd1243dSDimitry Andric static bool canRemoveInstruction(Instruction *I) {
65bdd1243dSDimitry Andric   if (wouldInstructionBeTriviallyDead(I))
66bdd1243dSDimitry Andric     return true;
67fe6060f1SDimitry Andric 
68bdd1243dSDimitry Andric   // Some instructions can be handled but are rejected above. Catch
69bdd1243dSDimitry Andric   // those cases by falling through to here.
70bdd1243dSDimitry Andric   // TODO: Mark globals as being constant earlier, so
71bdd1243dSDimitry Andric   // TODO: wouldInstructionBeTriviallyDead() knows that atomic loads
72bdd1243dSDimitry Andric   // TODO: are safe to remove.
73bdd1243dSDimitry Andric   return isa<LoadInst>(I);
74bdd1243dSDimitry Andric }
75bdd1243dSDimitry Andric 
76bdd1243dSDimitry Andric bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
7706c3fb27SDimitry Andric   Constant *Const = getConstantOrNull(V);
7806c3fb27SDimitry Andric   if (!Const)
79bdd1243dSDimitry Andric     return false;
80bdd1243dSDimitry Andric   // Replacing `musttail` instructions with constant breaks `musttail` invariant
81bdd1243dSDimitry Andric   // unless the call itself can be removed.
82bdd1243dSDimitry Andric   // Calls with "clang.arc.attachedcall" implicitly use the return value and
83bdd1243dSDimitry Andric   // those uses cannot be updated with a constant.
84bdd1243dSDimitry Andric   CallBase *CB = dyn_cast<CallBase>(V);
85bdd1243dSDimitry Andric   if (CB && ((CB->isMustTailCall() &&
86bdd1243dSDimitry Andric               !canRemoveInstruction(CB)) ||
87bdd1243dSDimitry Andric              CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall))) {
88bdd1243dSDimitry Andric     Function *F = CB->getCalledFunction();
89bdd1243dSDimitry Andric 
90bdd1243dSDimitry Andric     // Don't zap returns of the callee
91bdd1243dSDimitry Andric     if (F)
92bdd1243dSDimitry Andric       addToMustPreserveReturnsInFunctions(F);
93bdd1243dSDimitry Andric 
94bdd1243dSDimitry Andric     LLVM_DEBUG(dbgs() << "  Can\'t treat the result of call " << *CB
95bdd1243dSDimitry Andric                       << " as a constant\n");
96bdd1243dSDimitry Andric     return false;
97bdd1243dSDimitry Andric   }
98bdd1243dSDimitry Andric 
99bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "  Constant: " << *Const << " = " << *V << '\n');
100bdd1243dSDimitry Andric 
101bdd1243dSDimitry Andric   // Replaces all of the uses of a variable with uses of the constant.
102bdd1243dSDimitry Andric   V->replaceAllUsesWith(Const);
103bdd1243dSDimitry Andric   return true;
104bdd1243dSDimitry Andric }
105bdd1243dSDimitry Andric 
10606c3fb27SDimitry Andric /// Try to use \p Inst's value range from \p Solver to infer the NUW flag.
10706c3fb27SDimitry Andric static bool refineInstruction(SCCPSolver &Solver,
10806c3fb27SDimitry Andric                               const SmallPtrSetImpl<Value *> &InsertedValues,
10906c3fb27SDimitry Andric                               Instruction &Inst) {
110*5f757f3fSDimitry Andric   bool Changed = false;
11106c3fb27SDimitry Andric   auto GetRange = [&Solver, &InsertedValues](Value *Op) {
11206c3fb27SDimitry Andric     if (auto *Const = dyn_cast<ConstantInt>(Op))
11306c3fb27SDimitry Andric       return ConstantRange(Const->getValue());
11406c3fb27SDimitry Andric     if (isa<Constant>(Op) || InsertedValues.contains(Op)) {
11506c3fb27SDimitry Andric       unsigned Bitwidth = Op->getType()->getScalarSizeInBits();
11606c3fb27SDimitry Andric       return ConstantRange::getFull(Bitwidth);
11706c3fb27SDimitry Andric     }
11806c3fb27SDimitry Andric     return getConstantRange(Solver.getLatticeValueFor(Op), Op->getType(),
11906c3fb27SDimitry Andric                             /*UndefAllowed=*/false);
12006c3fb27SDimitry Andric   };
121*5f757f3fSDimitry Andric 
122*5f757f3fSDimitry Andric   if (isa<OverflowingBinaryOperator>(Inst)) {
12306c3fb27SDimitry Andric     auto RangeA = GetRange(Inst.getOperand(0));
12406c3fb27SDimitry Andric     auto RangeB = GetRange(Inst.getOperand(1));
12506c3fb27SDimitry Andric     if (!Inst.hasNoUnsignedWrap()) {
12606c3fb27SDimitry Andric       auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
12706c3fb27SDimitry Andric           Instruction::BinaryOps(Inst.getOpcode()), RangeB,
12806c3fb27SDimitry Andric           OverflowingBinaryOperator::NoUnsignedWrap);
12906c3fb27SDimitry Andric       if (NUWRange.contains(RangeA)) {
13006c3fb27SDimitry Andric         Inst.setHasNoUnsignedWrap();
13106c3fb27SDimitry Andric         Changed = true;
13206c3fb27SDimitry Andric       }
13306c3fb27SDimitry Andric     }
13406c3fb27SDimitry Andric     if (!Inst.hasNoSignedWrap()) {
13506c3fb27SDimitry Andric       auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
136*5f757f3fSDimitry Andric           Instruction::BinaryOps(Inst.getOpcode()), RangeB,
137*5f757f3fSDimitry Andric           OverflowingBinaryOperator::NoSignedWrap);
13806c3fb27SDimitry Andric       if (NSWRange.contains(RangeA)) {
13906c3fb27SDimitry Andric         Inst.setHasNoSignedWrap();
14006c3fb27SDimitry Andric         Changed = true;
14106c3fb27SDimitry Andric       }
14206c3fb27SDimitry Andric     }
143*5f757f3fSDimitry Andric   } else if (isa<ZExtInst>(Inst) && !Inst.hasNonNeg()) {
144*5f757f3fSDimitry Andric     auto Range = GetRange(Inst.getOperand(0));
145*5f757f3fSDimitry Andric     if (Range.isAllNonNegative()) {
146*5f757f3fSDimitry Andric       Inst.setNonNeg();
147*5f757f3fSDimitry Andric       Changed = true;
148*5f757f3fSDimitry Andric     }
149*5f757f3fSDimitry Andric   }
15006c3fb27SDimitry Andric 
15106c3fb27SDimitry Andric   return Changed;
15206c3fb27SDimitry Andric }
15306c3fb27SDimitry Andric 
154bdd1243dSDimitry Andric /// Try to replace signed instructions with their unsigned equivalent.
155bdd1243dSDimitry Andric static bool replaceSignedInst(SCCPSolver &Solver,
156bdd1243dSDimitry Andric                               SmallPtrSetImpl<Value *> &InsertedValues,
157bdd1243dSDimitry Andric                               Instruction &Inst) {
158bdd1243dSDimitry Andric   // Determine if a signed value is known to be >= 0.
159bdd1243dSDimitry Andric   auto isNonNegative = [&Solver](Value *V) {
160bdd1243dSDimitry Andric     // If this value was constant-folded, it may not have a solver entry.
161bdd1243dSDimitry Andric     // Handle integers. Otherwise, return false.
162bdd1243dSDimitry Andric     if (auto *C = dyn_cast<Constant>(V)) {
163bdd1243dSDimitry Andric       auto *CInt = dyn_cast<ConstantInt>(C);
164bdd1243dSDimitry Andric       return CInt && !CInt->isNegative();
165bdd1243dSDimitry Andric     }
166bdd1243dSDimitry Andric     const ValueLatticeElement &IV = Solver.getLatticeValueFor(V);
167bdd1243dSDimitry Andric     return IV.isConstantRange(/*UndefAllowed=*/false) &&
168bdd1243dSDimitry Andric            IV.getConstantRange().isAllNonNegative();
169bdd1243dSDimitry Andric   };
170bdd1243dSDimitry Andric 
171bdd1243dSDimitry Andric   Instruction *NewInst = nullptr;
172bdd1243dSDimitry Andric   switch (Inst.getOpcode()) {
173bdd1243dSDimitry Andric   // Note: We do not fold sitofp -> uitofp here because that could be more
174bdd1243dSDimitry Andric   // expensive in codegen and may not be reversible in the backend.
175bdd1243dSDimitry Andric   case Instruction::SExt: {
176bdd1243dSDimitry Andric     // If the source value is not negative, this is a zext.
177bdd1243dSDimitry Andric     Value *Op0 = Inst.getOperand(0);
178bdd1243dSDimitry Andric     if (InsertedValues.count(Op0) || !isNonNegative(Op0))
179bdd1243dSDimitry Andric       return false;
180bdd1243dSDimitry Andric     NewInst = new ZExtInst(Op0, Inst.getType(), "", &Inst);
181*5f757f3fSDimitry Andric     NewInst->setNonNeg();
182bdd1243dSDimitry Andric     break;
183bdd1243dSDimitry Andric   }
184bdd1243dSDimitry Andric   case Instruction::AShr: {
185bdd1243dSDimitry Andric     // If the shifted value is not negative, this is a logical shift right.
186bdd1243dSDimitry Andric     Value *Op0 = Inst.getOperand(0);
187bdd1243dSDimitry Andric     if (InsertedValues.count(Op0) || !isNonNegative(Op0))
188bdd1243dSDimitry Andric       return false;
189bdd1243dSDimitry Andric     NewInst = BinaryOperator::CreateLShr(Op0, Inst.getOperand(1), "", &Inst);
190*5f757f3fSDimitry Andric     NewInst->setIsExact(Inst.isExact());
191bdd1243dSDimitry Andric     break;
192bdd1243dSDimitry Andric   }
193bdd1243dSDimitry Andric   case Instruction::SDiv:
194bdd1243dSDimitry Andric   case Instruction::SRem: {
195bdd1243dSDimitry Andric     // If both operands are not negative, this is the same as udiv/urem.
196bdd1243dSDimitry Andric     Value *Op0 = Inst.getOperand(0), *Op1 = Inst.getOperand(1);
197bdd1243dSDimitry Andric     if (InsertedValues.count(Op0) || InsertedValues.count(Op1) ||
198bdd1243dSDimitry Andric         !isNonNegative(Op0) || !isNonNegative(Op1))
199bdd1243dSDimitry Andric       return false;
200bdd1243dSDimitry Andric     auto NewOpcode = Inst.getOpcode() == Instruction::SDiv ? Instruction::UDiv
201bdd1243dSDimitry Andric                                                            : Instruction::URem;
202bdd1243dSDimitry Andric     NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", &Inst);
203*5f757f3fSDimitry Andric     if (Inst.getOpcode() == Instruction::SDiv)
204*5f757f3fSDimitry Andric       NewInst->setIsExact(Inst.isExact());
205bdd1243dSDimitry Andric     break;
206bdd1243dSDimitry Andric   }
207bdd1243dSDimitry Andric   default:
208bdd1243dSDimitry Andric     return false;
209bdd1243dSDimitry Andric   }
210bdd1243dSDimitry Andric 
211bdd1243dSDimitry Andric   // Wire up the new instruction and update state.
212bdd1243dSDimitry Andric   assert(NewInst && "Expected replacement instruction");
213bdd1243dSDimitry Andric   NewInst->takeName(&Inst);
214bdd1243dSDimitry Andric   InsertedValues.insert(NewInst);
215bdd1243dSDimitry Andric   Inst.replaceAllUsesWith(NewInst);
216bdd1243dSDimitry Andric   Solver.removeLatticeValueFor(&Inst);
217bdd1243dSDimitry Andric   Inst.eraseFromParent();
218bdd1243dSDimitry Andric   return true;
219bdd1243dSDimitry Andric }
220bdd1243dSDimitry Andric 
221bdd1243dSDimitry Andric bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
222bdd1243dSDimitry Andric                                       SmallPtrSetImpl<Value *> &InsertedValues,
223bdd1243dSDimitry Andric                                       Statistic &InstRemovedStat,
224bdd1243dSDimitry Andric                                       Statistic &InstReplacedStat) {
225bdd1243dSDimitry Andric   bool MadeChanges = false;
226bdd1243dSDimitry Andric   for (Instruction &Inst : make_early_inc_range(BB)) {
227bdd1243dSDimitry Andric     if (Inst.getType()->isVoidTy())
228bdd1243dSDimitry Andric       continue;
229bdd1243dSDimitry Andric     if (tryToReplaceWithConstant(&Inst)) {
230bdd1243dSDimitry Andric       if (canRemoveInstruction(&Inst))
231bdd1243dSDimitry Andric         Inst.eraseFromParent();
232bdd1243dSDimitry Andric 
233bdd1243dSDimitry Andric       MadeChanges = true;
234bdd1243dSDimitry Andric       ++InstRemovedStat;
235bdd1243dSDimitry Andric     } else if (replaceSignedInst(*this, InsertedValues, Inst)) {
236bdd1243dSDimitry Andric       MadeChanges = true;
237bdd1243dSDimitry Andric       ++InstReplacedStat;
23806c3fb27SDimitry Andric     } else if (refineInstruction(*this, InsertedValues, Inst)) {
23906c3fb27SDimitry Andric       MadeChanges = true;
240bdd1243dSDimitry Andric     }
241bdd1243dSDimitry Andric   }
242bdd1243dSDimitry Andric   return MadeChanges;
243bdd1243dSDimitry Andric }
244bdd1243dSDimitry Andric 
245bdd1243dSDimitry Andric bool SCCPSolver::removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
246bdd1243dSDimitry Andric                                         BasicBlock *&NewUnreachableBB) const {
247bdd1243dSDimitry Andric   SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
248bdd1243dSDimitry Andric   bool HasNonFeasibleEdges = false;
249bdd1243dSDimitry Andric   for (BasicBlock *Succ : successors(BB)) {
250bdd1243dSDimitry Andric     if (isEdgeFeasible(BB, Succ))
251bdd1243dSDimitry Andric       FeasibleSuccessors.insert(Succ);
252bdd1243dSDimitry Andric     else
253bdd1243dSDimitry Andric       HasNonFeasibleEdges = true;
254bdd1243dSDimitry Andric   }
255bdd1243dSDimitry Andric 
256bdd1243dSDimitry Andric   // All edges feasible, nothing to do.
257bdd1243dSDimitry Andric   if (!HasNonFeasibleEdges)
258bdd1243dSDimitry Andric     return false;
259bdd1243dSDimitry Andric 
260bdd1243dSDimitry Andric   // SCCP can only determine non-feasible edges for br, switch and indirectbr.
261bdd1243dSDimitry Andric   Instruction *TI = BB->getTerminator();
262bdd1243dSDimitry Andric   assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
263bdd1243dSDimitry Andric           isa<IndirectBrInst>(TI)) &&
264bdd1243dSDimitry Andric          "Terminator must be a br, switch or indirectbr");
265bdd1243dSDimitry Andric 
266bdd1243dSDimitry Andric   if (FeasibleSuccessors.size() == 0) {
267bdd1243dSDimitry Andric     // Branch on undef/poison, replace with unreachable.
268bdd1243dSDimitry Andric     SmallPtrSet<BasicBlock *, 8> SeenSuccs;
269bdd1243dSDimitry Andric     SmallVector<DominatorTree::UpdateType, 8> Updates;
270bdd1243dSDimitry Andric     for (BasicBlock *Succ : successors(BB)) {
271bdd1243dSDimitry Andric       Succ->removePredecessor(BB);
272bdd1243dSDimitry Andric       if (SeenSuccs.insert(Succ).second)
273bdd1243dSDimitry Andric         Updates.push_back({DominatorTree::Delete, BB, Succ});
274bdd1243dSDimitry Andric     }
275bdd1243dSDimitry Andric     TI->eraseFromParent();
276bdd1243dSDimitry Andric     new UnreachableInst(BB->getContext(), BB);
277bdd1243dSDimitry Andric     DTU.applyUpdatesPermissive(Updates);
278bdd1243dSDimitry Andric   } else if (FeasibleSuccessors.size() == 1) {
279bdd1243dSDimitry Andric     // Replace with an unconditional branch to the only feasible successor.
280bdd1243dSDimitry Andric     BasicBlock *OnlyFeasibleSuccessor = *FeasibleSuccessors.begin();
281bdd1243dSDimitry Andric     SmallVector<DominatorTree::UpdateType, 8> Updates;
282bdd1243dSDimitry Andric     bool HaveSeenOnlyFeasibleSuccessor = false;
283bdd1243dSDimitry Andric     for (BasicBlock *Succ : successors(BB)) {
284bdd1243dSDimitry Andric       if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
285bdd1243dSDimitry Andric         // Don't remove the edge to the only feasible successor the first time
286bdd1243dSDimitry Andric         // we see it. We still do need to remove any multi-edges to it though.
287bdd1243dSDimitry Andric         HaveSeenOnlyFeasibleSuccessor = true;
288bdd1243dSDimitry Andric         continue;
289bdd1243dSDimitry Andric       }
290bdd1243dSDimitry Andric 
291bdd1243dSDimitry Andric       Succ->removePredecessor(BB);
292bdd1243dSDimitry Andric       Updates.push_back({DominatorTree::Delete, BB, Succ});
293bdd1243dSDimitry Andric     }
294bdd1243dSDimitry Andric 
295bdd1243dSDimitry Andric     BranchInst::Create(OnlyFeasibleSuccessor, BB);
296bdd1243dSDimitry Andric     TI->eraseFromParent();
297bdd1243dSDimitry Andric     DTU.applyUpdatesPermissive(Updates);
298bdd1243dSDimitry Andric   } else if (FeasibleSuccessors.size() > 1) {
299bdd1243dSDimitry Andric     SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
300bdd1243dSDimitry Andric     SmallVector<DominatorTree::UpdateType, 8> Updates;
301bdd1243dSDimitry Andric 
302bdd1243dSDimitry Andric     // If the default destination is unfeasible it will never be taken. Replace
303bdd1243dSDimitry Andric     // it with a new block with a single Unreachable instruction.
304bdd1243dSDimitry Andric     BasicBlock *DefaultDest = SI->getDefaultDest();
305bdd1243dSDimitry Andric     if (!FeasibleSuccessors.contains(DefaultDest)) {
306bdd1243dSDimitry Andric       if (!NewUnreachableBB) {
307bdd1243dSDimitry Andric         NewUnreachableBB =
308bdd1243dSDimitry Andric             BasicBlock::Create(DefaultDest->getContext(), "default.unreachable",
309bdd1243dSDimitry Andric                                DefaultDest->getParent(), DefaultDest);
310bdd1243dSDimitry Andric         new UnreachableInst(DefaultDest->getContext(), NewUnreachableBB);
311bdd1243dSDimitry Andric       }
312bdd1243dSDimitry Andric 
313bdd1243dSDimitry Andric       SI->setDefaultDest(NewUnreachableBB);
314bdd1243dSDimitry Andric       Updates.push_back({DominatorTree::Delete, BB, DefaultDest});
315bdd1243dSDimitry Andric       Updates.push_back({DominatorTree::Insert, BB, NewUnreachableBB});
316bdd1243dSDimitry Andric     }
317bdd1243dSDimitry Andric 
318bdd1243dSDimitry Andric     for (auto CI = SI->case_begin(); CI != SI->case_end();) {
319bdd1243dSDimitry Andric       if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
320bdd1243dSDimitry Andric         ++CI;
321bdd1243dSDimitry Andric         continue;
322bdd1243dSDimitry Andric       }
323bdd1243dSDimitry Andric 
324bdd1243dSDimitry Andric       BasicBlock *Succ = CI->getCaseSuccessor();
325bdd1243dSDimitry Andric       Succ->removePredecessor(BB);
326bdd1243dSDimitry Andric       Updates.push_back({DominatorTree::Delete, BB, Succ});
327bdd1243dSDimitry Andric       SI.removeCase(CI);
328bdd1243dSDimitry Andric       // Don't increment CI, as we removed a case.
329bdd1243dSDimitry Andric     }
330bdd1243dSDimitry Andric 
331bdd1243dSDimitry Andric     DTU.applyUpdatesPermissive(Updates);
332bdd1243dSDimitry Andric   } else {
333bdd1243dSDimitry Andric     llvm_unreachable("Must have at least one feasible successor");
334bdd1243dSDimitry Andric   }
335bdd1243dSDimitry Andric   return true;
336bdd1243dSDimitry Andric }
337fe6060f1SDimitry Andric 
338fe6060f1SDimitry Andric /// Helper class for SCCPSolver. This implements the instruction visitor and
339fe6060f1SDimitry Andric /// holds all the state.
340fe6060f1SDimitry Andric class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
341fe6060f1SDimitry Andric   const DataLayout &DL;
342fe6060f1SDimitry Andric   std::function<const TargetLibraryInfo &(Function &)> GetTLI;
343fe6060f1SDimitry Andric   SmallPtrSet<BasicBlock *, 8> BBExecutable; // The BBs that are executable.
344fe6060f1SDimitry Andric   DenseMap<Value *, ValueLatticeElement>
345fe6060f1SDimitry Andric       ValueState; // The state each value is in.
346fe6060f1SDimitry Andric 
347fe6060f1SDimitry Andric   /// StructValueState - This maintains ValueState for values that have
348fe6060f1SDimitry Andric   /// StructType, for example for formal arguments, calls, insertelement, etc.
349fe6060f1SDimitry Andric   DenseMap<std::pair<Value *, unsigned>, ValueLatticeElement> StructValueState;
350fe6060f1SDimitry Andric 
351fe6060f1SDimitry Andric   /// GlobalValue - If we are tracking any values for the contents of a global
352fe6060f1SDimitry Andric   /// variable, we keep a mapping from the constant accessor to the element of
353fe6060f1SDimitry Andric   /// the global, to the currently known value.  If the value becomes
354fe6060f1SDimitry Andric   /// overdefined, it's entry is simply removed from this map.
355fe6060f1SDimitry Andric   DenseMap<GlobalVariable *, ValueLatticeElement> TrackedGlobals;
356fe6060f1SDimitry Andric 
357fe6060f1SDimitry Andric   /// TrackedRetVals - If we are tracking arguments into and the return
358fe6060f1SDimitry Andric   /// value out of a function, it will have an entry in this map, indicating
359fe6060f1SDimitry Andric   /// what the known return value for the function is.
360fe6060f1SDimitry Andric   MapVector<Function *, ValueLatticeElement> TrackedRetVals;
361fe6060f1SDimitry Andric 
362fe6060f1SDimitry Andric   /// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
363fe6060f1SDimitry Andric   /// that return multiple values.
364fe6060f1SDimitry Andric   MapVector<std::pair<Function *, unsigned>, ValueLatticeElement>
365fe6060f1SDimitry Andric       TrackedMultipleRetVals;
366fe6060f1SDimitry Andric 
36706c3fb27SDimitry Andric   /// The set of values whose lattice has been invalidated.
36806c3fb27SDimitry Andric   /// Populated by resetLatticeValueFor(), cleared after resolving undefs.
36906c3fb27SDimitry Andric   DenseSet<Value *> Invalidated;
37006c3fb27SDimitry Andric 
371fe6060f1SDimitry Andric   /// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is
372fe6060f1SDimitry Andric   /// represented here for efficient lookup.
373fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> MRVFunctionsTracked;
374fe6060f1SDimitry Andric 
375fe6060f1SDimitry Andric   /// A list of functions whose return cannot be modified.
376fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> MustPreserveReturnsInFunctions;
377fe6060f1SDimitry Andric 
378fe6060f1SDimitry Andric   /// TrackingIncomingArguments - This is the set of functions for whose
379fe6060f1SDimitry Andric   /// arguments we make optimistic assumptions about and try to prove as
380fe6060f1SDimitry Andric   /// constants.
381fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> TrackingIncomingArguments;
382fe6060f1SDimitry Andric 
383fe6060f1SDimitry Andric   /// The reason for two worklists is that overdefined is the lowest state
384fe6060f1SDimitry Andric   /// on the lattice, and moving things to overdefined as fast as possible
385fe6060f1SDimitry Andric   /// makes SCCP converge much faster.
386fe6060f1SDimitry Andric   ///
387fe6060f1SDimitry Andric   /// By having a separate worklist, we accomplish this because everything
388fe6060f1SDimitry Andric   /// possibly overdefined will become overdefined at the soonest possible
389fe6060f1SDimitry Andric   /// point.
390fe6060f1SDimitry Andric   SmallVector<Value *, 64> OverdefinedInstWorkList;
391fe6060f1SDimitry Andric   SmallVector<Value *, 64> InstWorkList;
392fe6060f1SDimitry Andric 
393fe6060f1SDimitry Andric   // The BasicBlock work list
394fe6060f1SDimitry Andric   SmallVector<BasicBlock *, 64> BBWorkList;
395fe6060f1SDimitry Andric 
396fe6060f1SDimitry Andric   /// KnownFeasibleEdges - Entries in this set are edges which have already had
397fe6060f1SDimitry Andric   /// PHI nodes retriggered.
398fe6060f1SDimitry Andric   using Edge = std::pair<BasicBlock *, BasicBlock *>;
399fe6060f1SDimitry Andric   DenseSet<Edge> KnownFeasibleEdges;
400fe6060f1SDimitry Andric 
40106c3fb27SDimitry Andric   DenseMap<Function *, std::unique_ptr<PredicateInfo>> FnPredicateInfo;
40206c3fb27SDimitry Andric 
403fe6060f1SDimitry Andric   DenseMap<Value *, SmallPtrSet<User *, 2>> AdditionalUsers;
404fe6060f1SDimitry Andric 
405fe6060f1SDimitry Andric   LLVMContext &Ctx;
406fe6060f1SDimitry Andric 
407fe6060f1SDimitry Andric private:
40806c3fb27SDimitry Andric   ConstantInt *getConstantInt(const ValueLatticeElement &IV, Type *Ty) const {
40906c3fb27SDimitry Andric     return dyn_cast_or_null<ConstantInt>(getConstant(IV, Ty));
410fe6060f1SDimitry Andric   }
411fe6060f1SDimitry Andric 
412fe6060f1SDimitry Andric   // pushToWorkList - Helper for markConstant/markOverdefined
413fe6060f1SDimitry Andric   void pushToWorkList(ValueLatticeElement &IV, Value *V);
414fe6060f1SDimitry Andric 
415fe6060f1SDimitry Andric   // Helper to push \p V to the worklist, after updating it to \p IV. Also
416fe6060f1SDimitry Andric   // prints a debug message with the updated value.
417fe6060f1SDimitry Andric   void pushToWorkListMsg(ValueLatticeElement &IV, Value *V);
418fe6060f1SDimitry Andric 
419fe6060f1SDimitry Andric   // markConstant - Make a value be marked as "constant".  If the value
420fe6060f1SDimitry Andric   // is not already a constant, add it to the instruction work list so that
421fe6060f1SDimitry Andric   // the users of the instruction are updated later.
422fe6060f1SDimitry Andric   bool markConstant(ValueLatticeElement &IV, Value *V, Constant *C,
423fe6060f1SDimitry Andric                     bool MayIncludeUndef = false);
424fe6060f1SDimitry Andric 
425fe6060f1SDimitry Andric   bool markConstant(Value *V, Constant *C) {
426fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() && "structs should use mergeInValue");
427fe6060f1SDimitry Andric     return markConstant(ValueState[V], V, C);
428fe6060f1SDimitry Andric   }
429fe6060f1SDimitry Andric 
430fe6060f1SDimitry Andric   // markOverdefined - Make a value be marked as "overdefined". If the
431fe6060f1SDimitry Andric   // value is not already overdefined, add it to the overdefined instruction
432fe6060f1SDimitry Andric   // work list so that the users of the instruction are updated later.
433fe6060f1SDimitry Andric   bool markOverdefined(ValueLatticeElement &IV, Value *V);
434fe6060f1SDimitry Andric 
435fe6060f1SDimitry Andric   /// Merge \p MergeWithV into \p IV and push \p V to the worklist, if \p IV
436fe6060f1SDimitry Andric   /// changes.
437fe6060f1SDimitry Andric   bool mergeInValue(ValueLatticeElement &IV, Value *V,
438fe6060f1SDimitry Andric                     ValueLatticeElement MergeWithV,
439fe6060f1SDimitry Andric                     ValueLatticeElement::MergeOptions Opts = {
440fe6060f1SDimitry Andric                         /*MayIncludeUndef=*/false, /*CheckWiden=*/false});
441fe6060f1SDimitry Andric 
442fe6060f1SDimitry Andric   bool mergeInValue(Value *V, ValueLatticeElement MergeWithV,
443fe6060f1SDimitry Andric                     ValueLatticeElement::MergeOptions Opts = {
444fe6060f1SDimitry Andric                         /*MayIncludeUndef=*/false, /*CheckWiden=*/false}) {
445fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() &&
446fe6060f1SDimitry Andric            "non-structs should use markConstant");
447fe6060f1SDimitry Andric     return mergeInValue(ValueState[V], V, MergeWithV, Opts);
448fe6060f1SDimitry Andric   }
449fe6060f1SDimitry Andric 
450fe6060f1SDimitry Andric   /// getValueState - Return the ValueLatticeElement object that corresponds to
451fe6060f1SDimitry Andric   /// the value.  This function handles the case when the value hasn't been seen
452fe6060f1SDimitry Andric   /// yet by properly seeding constants etc.
453fe6060f1SDimitry Andric   ValueLatticeElement &getValueState(Value *V) {
454fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() && "Should use getStructValueState");
455fe6060f1SDimitry Andric 
456fe6060f1SDimitry Andric     auto I = ValueState.insert(std::make_pair(V, ValueLatticeElement()));
457fe6060f1SDimitry Andric     ValueLatticeElement &LV = I.first->second;
458fe6060f1SDimitry Andric 
459fe6060f1SDimitry Andric     if (!I.second)
460fe6060f1SDimitry Andric       return LV; // Common case, already in the map.
461fe6060f1SDimitry Andric 
462fe6060f1SDimitry Andric     if (auto *C = dyn_cast<Constant>(V))
463fe6060f1SDimitry Andric       LV.markConstant(C); // Constants are constant
464fe6060f1SDimitry Andric 
465fe6060f1SDimitry Andric     // All others are unknown by default.
466fe6060f1SDimitry Andric     return LV;
467fe6060f1SDimitry Andric   }
468fe6060f1SDimitry Andric 
469fe6060f1SDimitry Andric   /// getStructValueState - Return the ValueLatticeElement object that
470fe6060f1SDimitry Andric   /// corresponds to the value/field pair.  This function handles the case when
471fe6060f1SDimitry Andric   /// the value hasn't been seen yet by properly seeding constants etc.
472fe6060f1SDimitry Andric   ValueLatticeElement &getStructValueState(Value *V, unsigned i) {
473fe6060f1SDimitry Andric     assert(V->getType()->isStructTy() && "Should use getValueState");
474fe6060f1SDimitry Andric     assert(i < cast<StructType>(V->getType())->getNumElements() &&
475fe6060f1SDimitry Andric            "Invalid element #");
476fe6060f1SDimitry Andric 
477fe6060f1SDimitry Andric     auto I = StructValueState.insert(
478fe6060f1SDimitry Andric         std::make_pair(std::make_pair(V, i), ValueLatticeElement()));
479fe6060f1SDimitry Andric     ValueLatticeElement &LV = I.first->second;
480fe6060f1SDimitry Andric 
481fe6060f1SDimitry Andric     if (!I.second)
482fe6060f1SDimitry Andric       return LV; // Common case, already in the map.
483fe6060f1SDimitry Andric 
484fe6060f1SDimitry Andric     if (auto *C = dyn_cast<Constant>(V)) {
485fe6060f1SDimitry Andric       Constant *Elt = C->getAggregateElement(i);
486fe6060f1SDimitry Andric 
487fe6060f1SDimitry Andric       if (!Elt)
488fe6060f1SDimitry Andric         LV.markOverdefined(); // Unknown sort of constant.
489fe6060f1SDimitry Andric       else
490fe6060f1SDimitry Andric         LV.markConstant(Elt); // Constants are constant.
491fe6060f1SDimitry Andric     }
492fe6060f1SDimitry Andric 
493fe6060f1SDimitry Andric     // All others are underdefined by default.
494fe6060f1SDimitry Andric     return LV;
495fe6060f1SDimitry Andric   }
496fe6060f1SDimitry Andric 
49706c3fb27SDimitry Andric   /// Traverse the use-def chain of \p Call, marking itself and its users as
49806c3fb27SDimitry Andric   /// "unknown" on the way.
49906c3fb27SDimitry Andric   void invalidate(CallBase *Call) {
50006c3fb27SDimitry Andric     SmallVector<Instruction *, 64> ToInvalidate;
50106c3fb27SDimitry Andric     ToInvalidate.push_back(Call);
50206c3fb27SDimitry Andric 
50306c3fb27SDimitry Andric     while (!ToInvalidate.empty()) {
50406c3fb27SDimitry Andric       Instruction *Inst = ToInvalidate.pop_back_val();
50506c3fb27SDimitry Andric 
50606c3fb27SDimitry Andric       if (!Invalidated.insert(Inst).second)
50706c3fb27SDimitry Andric         continue;
50806c3fb27SDimitry Andric 
50906c3fb27SDimitry Andric       if (!BBExecutable.count(Inst->getParent()))
51006c3fb27SDimitry Andric         continue;
51106c3fb27SDimitry Andric 
51206c3fb27SDimitry Andric       Value *V = nullptr;
51306c3fb27SDimitry Andric       // For return instructions we need to invalidate the tracked returns map.
51406c3fb27SDimitry Andric       // Anything else has its lattice in the value map.
51506c3fb27SDimitry Andric       if (auto *RetInst = dyn_cast<ReturnInst>(Inst)) {
51606c3fb27SDimitry Andric         Function *F = RetInst->getParent()->getParent();
51706c3fb27SDimitry Andric         if (auto It = TrackedRetVals.find(F); It != TrackedRetVals.end()) {
51806c3fb27SDimitry Andric           It->second = ValueLatticeElement();
51906c3fb27SDimitry Andric           V = F;
52006c3fb27SDimitry Andric         } else if (MRVFunctionsTracked.count(F)) {
52106c3fb27SDimitry Andric           auto *STy = cast<StructType>(F->getReturnType());
52206c3fb27SDimitry Andric           for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I)
52306c3fb27SDimitry Andric             TrackedMultipleRetVals[{F, I}] = ValueLatticeElement();
52406c3fb27SDimitry Andric           V = F;
52506c3fb27SDimitry Andric         }
52606c3fb27SDimitry Andric       } else if (auto *STy = dyn_cast<StructType>(Inst->getType())) {
52706c3fb27SDimitry Andric         for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
52806c3fb27SDimitry Andric           if (auto It = StructValueState.find({Inst, I});
52906c3fb27SDimitry Andric               It != StructValueState.end()) {
53006c3fb27SDimitry Andric             It->second = ValueLatticeElement();
53106c3fb27SDimitry Andric             V = Inst;
53206c3fb27SDimitry Andric           }
53306c3fb27SDimitry Andric         }
53406c3fb27SDimitry Andric       } else if (auto It = ValueState.find(Inst); It != ValueState.end()) {
53506c3fb27SDimitry Andric         It->second = ValueLatticeElement();
53606c3fb27SDimitry Andric         V = Inst;
53706c3fb27SDimitry Andric       }
53806c3fb27SDimitry Andric 
53906c3fb27SDimitry Andric       if (V) {
54006c3fb27SDimitry Andric         LLVM_DEBUG(dbgs() << "Invalidated lattice for " << *V << "\n");
54106c3fb27SDimitry Andric 
54206c3fb27SDimitry Andric         for (User *U : V->users())
54306c3fb27SDimitry Andric           if (auto *UI = dyn_cast<Instruction>(U))
54406c3fb27SDimitry Andric             ToInvalidate.push_back(UI);
54506c3fb27SDimitry Andric 
54606c3fb27SDimitry Andric         auto It = AdditionalUsers.find(V);
54706c3fb27SDimitry Andric         if (It != AdditionalUsers.end())
54806c3fb27SDimitry Andric           for (User *U : It->second)
54906c3fb27SDimitry Andric             if (auto *UI = dyn_cast<Instruction>(U))
55006c3fb27SDimitry Andric               ToInvalidate.push_back(UI);
55106c3fb27SDimitry Andric       }
55206c3fb27SDimitry Andric     }
55306c3fb27SDimitry Andric   }
55406c3fb27SDimitry Andric 
555fe6060f1SDimitry Andric   /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
556fe6060f1SDimitry Andric   /// work list if it is not already executable.
557fe6060f1SDimitry Andric   bool markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
558fe6060f1SDimitry Andric 
559fe6060f1SDimitry Andric   // getFeasibleSuccessors - Return a vector of booleans to indicate which
560fe6060f1SDimitry Andric   // successors are reachable from a given terminator instruction.
561fe6060f1SDimitry Andric   void getFeasibleSuccessors(Instruction &TI, SmallVectorImpl<bool> &Succs);
562fe6060f1SDimitry Andric 
563fe6060f1SDimitry Andric   // OperandChangedState - This method is invoked on all of the users of an
564fe6060f1SDimitry Andric   // instruction that was just changed state somehow.  Based on this
565fe6060f1SDimitry Andric   // information, we need to update the specified user of this instruction.
566fe6060f1SDimitry Andric   void operandChangedState(Instruction *I) {
567fe6060f1SDimitry Andric     if (BBExecutable.count(I->getParent())) // Inst is executable?
568fe6060f1SDimitry Andric       visit(*I);
569fe6060f1SDimitry Andric   }
570fe6060f1SDimitry Andric 
571fe6060f1SDimitry Andric   // Add U as additional user of V.
572fe6060f1SDimitry Andric   void addAdditionalUser(Value *V, User *U) {
573fe6060f1SDimitry Andric     auto Iter = AdditionalUsers.insert({V, {}});
574fe6060f1SDimitry Andric     Iter.first->second.insert(U);
575fe6060f1SDimitry Andric   }
576fe6060f1SDimitry Andric 
577fe6060f1SDimitry Andric   // Mark I's users as changed, including AdditionalUsers.
578fe6060f1SDimitry Andric   void markUsersAsChanged(Value *I) {
579fe6060f1SDimitry Andric     // Functions include their arguments in the use-list. Changed function
580fe6060f1SDimitry Andric     // values mean that the result of the function changed. We only need to
581fe6060f1SDimitry Andric     // update the call sites with the new function result and do not have to
582fe6060f1SDimitry Andric     // propagate the call arguments.
583fe6060f1SDimitry Andric     if (isa<Function>(I)) {
584fe6060f1SDimitry Andric       for (User *U : I->users()) {
585fe6060f1SDimitry Andric         if (auto *CB = dyn_cast<CallBase>(U))
586fe6060f1SDimitry Andric           handleCallResult(*CB);
587fe6060f1SDimitry Andric       }
588fe6060f1SDimitry Andric     } else {
589fe6060f1SDimitry Andric       for (User *U : I->users())
590fe6060f1SDimitry Andric         if (auto *UI = dyn_cast<Instruction>(U))
591fe6060f1SDimitry Andric           operandChangedState(UI);
592fe6060f1SDimitry Andric     }
593fe6060f1SDimitry Andric 
594fe6060f1SDimitry Andric     auto Iter = AdditionalUsers.find(I);
595fe6060f1SDimitry Andric     if (Iter != AdditionalUsers.end()) {
596fe6060f1SDimitry Andric       // Copy additional users before notifying them of changes, because new
597fe6060f1SDimitry Andric       // users may be added, potentially invalidating the iterator.
598fe6060f1SDimitry Andric       SmallVector<Instruction *, 2> ToNotify;
599fe6060f1SDimitry Andric       for (User *U : Iter->second)
600fe6060f1SDimitry Andric         if (auto *UI = dyn_cast<Instruction>(U))
601fe6060f1SDimitry Andric           ToNotify.push_back(UI);
602fe6060f1SDimitry Andric       for (Instruction *UI : ToNotify)
603fe6060f1SDimitry Andric         operandChangedState(UI);
604fe6060f1SDimitry Andric     }
605fe6060f1SDimitry Andric   }
606fe6060f1SDimitry Andric   void handleCallOverdefined(CallBase &CB);
607fe6060f1SDimitry Andric   void handleCallResult(CallBase &CB);
608fe6060f1SDimitry Andric   void handleCallArguments(CallBase &CB);
609bdd1243dSDimitry Andric   void handleExtractOfWithOverflow(ExtractValueInst &EVI,
610bdd1243dSDimitry Andric                                    const WithOverflowInst *WO, unsigned Idx);
611fe6060f1SDimitry Andric 
612fe6060f1SDimitry Andric private:
613fe6060f1SDimitry Andric   friend class InstVisitor<SCCPInstVisitor>;
614fe6060f1SDimitry Andric 
615fe6060f1SDimitry Andric   // visit implementations - Something changed in this instruction.  Either an
616fe6060f1SDimitry Andric   // operand made a transition, or the instruction is newly executable.  Change
617fe6060f1SDimitry Andric   // the value type of I to reflect these changes if appropriate.
618fe6060f1SDimitry Andric   void visitPHINode(PHINode &I);
619fe6060f1SDimitry Andric 
620fe6060f1SDimitry Andric   // Terminators
621fe6060f1SDimitry Andric 
622fe6060f1SDimitry Andric   void visitReturnInst(ReturnInst &I);
623fe6060f1SDimitry Andric   void visitTerminator(Instruction &TI);
624fe6060f1SDimitry Andric 
625fe6060f1SDimitry Andric   void visitCastInst(CastInst &I);
626fe6060f1SDimitry Andric   void visitSelectInst(SelectInst &I);
627fe6060f1SDimitry Andric   void visitUnaryOperator(Instruction &I);
62806c3fb27SDimitry Andric   void visitFreezeInst(FreezeInst &I);
629fe6060f1SDimitry Andric   void visitBinaryOperator(Instruction &I);
630fe6060f1SDimitry Andric   void visitCmpInst(CmpInst &I);
631fe6060f1SDimitry Andric   void visitExtractValueInst(ExtractValueInst &EVI);
632fe6060f1SDimitry Andric   void visitInsertValueInst(InsertValueInst &IVI);
633fe6060f1SDimitry Andric 
634fe6060f1SDimitry Andric   void visitCatchSwitchInst(CatchSwitchInst &CPI) {
635fe6060f1SDimitry Andric     markOverdefined(&CPI);
636fe6060f1SDimitry Andric     visitTerminator(CPI);
637fe6060f1SDimitry Andric   }
638fe6060f1SDimitry Andric 
639fe6060f1SDimitry Andric   // Instructions that cannot be folded away.
640fe6060f1SDimitry Andric 
641fe6060f1SDimitry Andric   void visitStoreInst(StoreInst &I);
642fe6060f1SDimitry Andric   void visitLoadInst(LoadInst &I);
643fe6060f1SDimitry Andric   void visitGetElementPtrInst(GetElementPtrInst &I);
644fe6060f1SDimitry Andric 
645fe6060f1SDimitry Andric   void visitInvokeInst(InvokeInst &II) {
646fe6060f1SDimitry Andric     visitCallBase(II);
647fe6060f1SDimitry Andric     visitTerminator(II);
648fe6060f1SDimitry Andric   }
649fe6060f1SDimitry Andric 
650fe6060f1SDimitry Andric   void visitCallBrInst(CallBrInst &CBI) {
651fe6060f1SDimitry Andric     visitCallBase(CBI);
652fe6060f1SDimitry Andric     visitTerminator(CBI);
653fe6060f1SDimitry Andric   }
654fe6060f1SDimitry Andric 
655fe6060f1SDimitry Andric   void visitCallBase(CallBase &CB);
656fe6060f1SDimitry Andric   void visitResumeInst(ResumeInst &I) { /*returns void*/
657fe6060f1SDimitry Andric   }
658fe6060f1SDimitry Andric   void visitUnreachableInst(UnreachableInst &I) { /*returns void*/
659fe6060f1SDimitry Andric   }
660fe6060f1SDimitry Andric   void visitFenceInst(FenceInst &I) { /*returns void*/
661fe6060f1SDimitry Andric   }
662fe6060f1SDimitry Andric 
663fe6060f1SDimitry Andric   void visitInstruction(Instruction &I);
664fe6060f1SDimitry Andric 
665fe6060f1SDimitry Andric public:
66606c3fb27SDimitry Andric   void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC) {
66706c3fb27SDimitry Andric     FnPredicateInfo.insert({&F, std::make_unique<PredicateInfo>(F, DT, AC)});
668fe6060f1SDimitry Andric   }
669fe6060f1SDimitry Andric 
670fe6060f1SDimitry Andric   void visitCallInst(CallInst &I) { visitCallBase(I); }
671fe6060f1SDimitry Andric 
672fe6060f1SDimitry Andric   bool markBlockExecutable(BasicBlock *BB);
673fe6060f1SDimitry Andric 
674fe6060f1SDimitry Andric   const PredicateBase *getPredicateInfoFor(Instruction *I) {
67506c3fb27SDimitry Andric     auto It = FnPredicateInfo.find(I->getParent()->getParent());
67606c3fb27SDimitry Andric     if (It == FnPredicateInfo.end())
677fe6060f1SDimitry Andric       return nullptr;
67806c3fb27SDimitry Andric     return It->second->getPredicateInfoFor(I);
679fe6060f1SDimitry Andric   }
680fe6060f1SDimitry Andric 
681fe6060f1SDimitry Andric   SCCPInstVisitor(const DataLayout &DL,
682fe6060f1SDimitry Andric                   std::function<const TargetLibraryInfo &(Function &)> GetTLI,
683fe6060f1SDimitry Andric                   LLVMContext &Ctx)
684fe6060f1SDimitry Andric       : DL(DL), GetTLI(GetTLI), Ctx(Ctx) {}
685fe6060f1SDimitry Andric 
686fe6060f1SDimitry Andric   void trackValueOfGlobalVariable(GlobalVariable *GV) {
687fe6060f1SDimitry Andric     // We only track the contents of scalar globals.
688fe6060f1SDimitry Andric     if (GV->getValueType()->isSingleValueType()) {
689fe6060f1SDimitry Andric       ValueLatticeElement &IV = TrackedGlobals[GV];
690fe6060f1SDimitry Andric       IV.markConstant(GV->getInitializer());
691fe6060f1SDimitry Andric     }
692fe6060f1SDimitry Andric   }
693fe6060f1SDimitry Andric 
694fe6060f1SDimitry Andric   void addTrackedFunction(Function *F) {
695fe6060f1SDimitry Andric     // Add an entry, F -> undef.
696fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
697fe6060f1SDimitry Andric       MRVFunctionsTracked.insert(F);
698fe6060f1SDimitry Andric       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
699fe6060f1SDimitry Andric         TrackedMultipleRetVals.insert(
700fe6060f1SDimitry Andric             std::make_pair(std::make_pair(F, i), ValueLatticeElement()));
701fe6060f1SDimitry Andric     } else if (!F->getReturnType()->isVoidTy())
702fe6060f1SDimitry Andric       TrackedRetVals.insert(std::make_pair(F, ValueLatticeElement()));
703fe6060f1SDimitry Andric   }
704fe6060f1SDimitry Andric 
705fe6060f1SDimitry Andric   void addToMustPreserveReturnsInFunctions(Function *F) {
706fe6060f1SDimitry Andric     MustPreserveReturnsInFunctions.insert(F);
707fe6060f1SDimitry Andric   }
708fe6060f1SDimitry Andric 
709fe6060f1SDimitry Andric   bool mustPreserveReturn(Function *F) {
710fe6060f1SDimitry Andric     return MustPreserveReturnsInFunctions.count(F);
711fe6060f1SDimitry Andric   }
712fe6060f1SDimitry Andric 
713fe6060f1SDimitry Andric   void addArgumentTrackedFunction(Function *F) {
714fe6060f1SDimitry Andric     TrackingIncomingArguments.insert(F);
715fe6060f1SDimitry Andric   }
716fe6060f1SDimitry Andric 
717fe6060f1SDimitry Andric   bool isArgumentTrackedFunction(Function *F) {
718fe6060f1SDimitry Andric     return TrackingIncomingArguments.count(F);
719fe6060f1SDimitry Andric   }
720fe6060f1SDimitry Andric 
721fe6060f1SDimitry Andric   void solve();
722fe6060f1SDimitry Andric 
72306c3fb27SDimitry Andric   bool resolvedUndef(Instruction &I);
72406c3fb27SDimitry Andric 
725fe6060f1SDimitry Andric   bool resolvedUndefsIn(Function &F);
726fe6060f1SDimitry Andric 
727fe6060f1SDimitry Andric   bool isBlockExecutable(BasicBlock *BB) const {
728fe6060f1SDimitry Andric     return BBExecutable.count(BB);
729fe6060f1SDimitry Andric   }
730fe6060f1SDimitry Andric 
731fe6060f1SDimitry Andric   bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
732fe6060f1SDimitry Andric 
733fe6060f1SDimitry Andric   std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const {
734fe6060f1SDimitry Andric     std::vector<ValueLatticeElement> StructValues;
735fe6060f1SDimitry Andric     auto *STy = dyn_cast<StructType>(V->getType());
736fe6060f1SDimitry Andric     assert(STy && "getStructLatticeValueFor() can be called only on structs");
737fe6060f1SDimitry Andric     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
738fe6060f1SDimitry Andric       auto I = StructValueState.find(std::make_pair(V, i));
739fe6060f1SDimitry Andric       assert(I != StructValueState.end() && "Value not in valuemap!");
740fe6060f1SDimitry Andric       StructValues.push_back(I->second);
741fe6060f1SDimitry Andric     }
742fe6060f1SDimitry Andric     return StructValues;
743fe6060f1SDimitry Andric   }
744fe6060f1SDimitry Andric 
745fe6060f1SDimitry Andric   void removeLatticeValueFor(Value *V) { ValueState.erase(V); }
746fe6060f1SDimitry Andric 
74706c3fb27SDimitry Andric   /// Invalidate the Lattice Value of \p Call and its users after specializing
74806c3fb27SDimitry Andric   /// the call. Then recompute it.
74906c3fb27SDimitry Andric   void resetLatticeValueFor(CallBase *Call) {
75006c3fb27SDimitry Andric     // Calls to void returning functions do not need invalidation.
75106c3fb27SDimitry Andric     Function *F = Call->getCalledFunction();
75206c3fb27SDimitry Andric     (void)F;
75306c3fb27SDimitry Andric     assert(!F->getReturnType()->isVoidTy() &&
75406c3fb27SDimitry Andric            (TrackedRetVals.count(F) || MRVFunctionsTracked.count(F)) &&
75506c3fb27SDimitry Andric            "All non void specializations should be tracked");
75606c3fb27SDimitry Andric     invalidate(Call);
75706c3fb27SDimitry Andric     handleCallResult(*Call);
75806c3fb27SDimitry Andric   }
75906c3fb27SDimitry Andric 
760fe6060f1SDimitry Andric   const ValueLatticeElement &getLatticeValueFor(Value *V) const {
761fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() &&
762fe6060f1SDimitry Andric            "Should use getStructLatticeValueFor");
763fe6060f1SDimitry Andric     DenseMap<Value *, ValueLatticeElement>::const_iterator I =
764fe6060f1SDimitry Andric         ValueState.find(V);
765fe6060f1SDimitry Andric     assert(I != ValueState.end() &&
766fe6060f1SDimitry Andric            "V not found in ValueState nor Paramstate map!");
767fe6060f1SDimitry Andric     return I->second;
768fe6060f1SDimitry Andric   }
769fe6060f1SDimitry Andric 
770fe6060f1SDimitry Andric   const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() {
771fe6060f1SDimitry Andric     return TrackedRetVals;
772fe6060f1SDimitry Andric   }
773fe6060f1SDimitry Andric 
774fe6060f1SDimitry Andric   const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals() {
775fe6060f1SDimitry Andric     return TrackedGlobals;
776fe6060f1SDimitry Andric   }
777fe6060f1SDimitry Andric 
778fe6060f1SDimitry Andric   const SmallPtrSet<Function *, 16> getMRVFunctionsTracked() {
779fe6060f1SDimitry Andric     return MRVFunctionsTracked;
780fe6060f1SDimitry Andric   }
781fe6060f1SDimitry Andric 
782fe6060f1SDimitry Andric   void markOverdefined(Value *V) {
783fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(V->getType()))
784fe6060f1SDimitry Andric       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
785fe6060f1SDimitry Andric         markOverdefined(getStructValueState(V, i), V);
786fe6060f1SDimitry Andric     else
787fe6060f1SDimitry Andric       markOverdefined(ValueState[V], V);
788fe6060f1SDimitry Andric   }
789fe6060f1SDimitry Andric 
790fe6060f1SDimitry Andric   bool isStructLatticeConstant(Function *F, StructType *STy);
791fe6060f1SDimitry Andric 
79206c3fb27SDimitry Andric   Constant *getConstant(const ValueLatticeElement &LV, Type *Ty) const;
79306c3fb27SDimitry Andric 
79406c3fb27SDimitry Andric   Constant *getConstantOrNull(Value *V) const;
795fe6060f1SDimitry Andric 
796fe6060f1SDimitry Andric   SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() {
797fe6060f1SDimitry Andric     return TrackingIncomingArguments;
798fe6060f1SDimitry Andric   }
799fe6060f1SDimitry Andric 
80006c3fb27SDimitry Andric   void setLatticeValueForSpecializationArguments(Function *F,
80181ad6265SDimitry Andric                                        const SmallVectorImpl<ArgInfo> &Args);
802fe6060f1SDimitry Andric 
803fe6060f1SDimitry Andric   void markFunctionUnreachable(Function *F) {
804fe6060f1SDimitry Andric     for (auto &BB : *F)
805fe6060f1SDimitry Andric       BBExecutable.erase(&BB);
806fe6060f1SDimitry Andric   }
807bdd1243dSDimitry Andric 
808bdd1243dSDimitry Andric   void solveWhileResolvedUndefsIn(Module &M) {
809bdd1243dSDimitry Andric     bool ResolvedUndefs = true;
810bdd1243dSDimitry Andric     while (ResolvedUndefs) {
811bdd1243dSDimitry Andric       solve();
812bdd1243dSDimitry Andric       ResolvedUndefs = false;
813bdd1243dSDimitry Andric       for (Function &F : M)
814bdd1243dSDimitry Andric         ResolvedUndefs |= resolvedUndefsIn(F);
815bdd1243dSDimitry Andric     }
816bdd1243dSDimitry Andric   }
817bdd1243dSDimitry Andric 
818bdd1243dSDimitry Andric   void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
819bdd1243dSDimitry Andric     bool ResolvedUndefs = true;
820bdd1243dSDimitry Andric     while (ResolvedUndefs) {
821bdd1243dSDimitry Andric       solve();
822bdd1243dSDimitry Andric       ResolvedUndefs = false;
823bdd1243dSDimitry Andric       for (Function *F : WorkList)
824bdd1243dSDimitry Andric         ResolvedUndefs |= resolvedUndefsIn(*F);
825bdd1243dSDimitry Andric     }
826bdd1243dSDimitry Andric   }
82706c3fb27SDimitry Andric 
82806c3fb27SDimitry Andric   void solveWhileResolvedUndefs() {
82906c3fb27SDimitry Andric     bool ResolvedUndefs = true;
83006c3fb27SDimitry Andric     while (ResolvedUndefs) {
83106c3fb27SDimitry Andric       solve();
83206c3fb27SDimitry Andric       ResolvedUndefs = false;
83306c3fb27SDimitry Andric       for (Value *V : Invalidated)
83406c3fb27SDimitry Andric         if (auto *I = dyn_cast<Instruction>(V))
83506c3fb27SDimitry Andric           ResolvedUndefs |= resolvedUndef(*I);
83606c3fb27SDimitry Andric     }
83706c3fb27SDimitry Andric     Invalidated.clear();
83806c3fb27SDimitry Andric   }
839fe6060f1SDimitry Andric };
840fe6060f1SDimitry Andric 
841fe6060f1SDimitry Andric } // namespace llvm
842fe6060f1SDimitry Andric 
843fe6060f1SDimitry Andric bool SCCPInstVisitor::markBlockExecutable(BasicBlock *BB) {
844fe6060f1SDimitry Andric   if (!BBExecutable.insert(BB).second)
845fe6060f1SDimitry Andric     return false;
846fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << '\n');
847fe6060f1SDimitry Andric   BBWorkList.push_back(BB); // Add the block to the work list!
848fe6060f1SDimitry Andric   return true;
849fe6060f1SDimitry Andric }
850fe6060f1SDimitry Andric 
851fe6060f1SDimitry Andric void SCCPInstVisitor::pushToWorkList(ValueLatticeElement &IV, Value *V) {
85206c3fb27SDimitry Andric   if (IV.isOverdefined()) {
85306c3fb27SDimitry Andric     if (OverdefinedInstWorkList.empty() || OverdefinedInstWorkList.back() != V)
85406c3fb27SDimitry Andric       OverdefinedInstWorkList.push_back(V);
85506c3fb27SDimitry Andric     return;
85606c3fb27SDimitry Andric   }
85706c3fb27SDimitry Andric   if (InstWorkList.empty() || InstWorkList.back() != V)
858fe6060f1SDimitry Andric     InstWorkList.push_back(V);
859fe6060f1SDimitry Andric }
860fe6060f1SDimitry Andric 
861fe6060f1SDimitry Andric void SCCPInstVisitor::pushToWorkListMsg(ValueLatticeElement &IV, Value *V) {
862fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n');
863fe6060f1SDimitry Andric   pushToWorkList(IV, V);
864fe6060f1SDimitry Andric }
865fe6060f1SDimitry Andric 
866fe6060f1SDimitry Andric bool SCCPInstVisitor::markConstant(ValueLatticeElement &IV, Value *V,
867fe6060f1SDimitry Andric                                    Constant *C, bool MayIncludeUndef) {
868fe6060f1SDimitry Andric   if (!IV.markConstant(C, MayIncludeUndef))
869fe6060f1SDimitry Andric     return false;
870fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "markConstant: " << *C << ": " << *V << '\n');
871fe6060f1SDimitry Andric   pushToWorkList(IV, V);
872fe6060f1SDimitry Andric   return true;
873fe6060f1SDimitry Andric }
874fe6060f1SDimitry Andric 
875fe6060f1SDimitry Andric bool SCCPInstVisitor::markOverdefined(ValueLatticeElement &IV, Value *V) {
876fe6060f1SDimitry Andric   if (!IV.markOverdefined())
877fe6060f1SDimitry Andric     return false;
878fe6060f1SDimitry Andric 
879fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "markOverdefined: ";
880fe6060f1SDimitry Andric              if (auto *F = dyn_cast<Function>(V)) dbgs()
881fe6060f1SDimitry Andric              << "Function '" << F->getName() << "'\n";
882fe6060f1SDimitry Andric              else dbgs() << *V << '\n');
883fe6060f1SDimitry Andric   // Only instructions go on the work list
884fe6060f1SDimitry Andric   pushToWorkList(IV, V);
885fe6060f1SDimitry Andric   return true;
886fe6060f1SDimitry Andric }
887fe6060f1SDimitry Andric 
888fe6060f1SDimitry Andric bool SCCPInstVisitor::isStructLatticeConstant(Function *F, StructType *STy) {
889fe6060f1SDimitry Andric   for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
890fe6060f1SDimitry Andric     const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
891fe6060f1SDimitry Andric     assert(It != TrackedMultipleRetVals.end());
892fe6060f1SDimitry Andric     ValueLatticeElement LV = It->second;
893bdd1243dSDimitry Andric     if (!SCCPSolver::isConstant(LV))
894fe6060f1SDimitry Andric       return false;
895fe6060f1SDimitry Andric   }
896fe6060f1SDimitry Andric   return true;
897fe6060f1SDimitry Andric }
898fe6060f1SDimitry Andric 
89906c3fb27SDimitry Andric Constant *SCCPInstVisitor::getConstant(const ValueLatticeElement &LV,
90006c3fb27SDimitry Andric                                        Type *Ty) const {
90106c3fb27SDimitry Andric   if (LV.isConstant()) {
90206c3fb27SDimitry Andric     Constant *C = LV.getConstant();
90306c3fb27SDimitry Andric     assert(C->getType() == Ty && "Type mismatch");
90406c3fb27SDimitry Andric     return C;
90506c3fb27SDimitry Andric   }
906fe6060f1SDimitry Andric 
907fe6060f1SDimitry Andric   if (LV.isConstantRange()) {
908fe6060f1SDimitry Andric     const auto &CR = LV.getConstantRange();
909fe6060f1SDimitry Andric     if (CR.getSingleElement())
91006c3fb27SDimitry Andric       return ConstantInt::get(Ty, *CR.getSingleElement());
911fe6060f1SDimitry Andric   }
912fe6060f1SDimitry Andric   return nullptr;
913fe6060f1SDimitry Andric }
914fe6060f1SDimitry Andric 
91506c3fb27SDimitry Andric Constant *SCCPInstVisitor::getConstantOrNull(Value *V) const {
91606c3fb27SDimitry Andric   Constant *Const = nullptr;
91706c3fb27SDimitry Andric   if (V->getType()->isStructTy()) {
91806c3fb27SDimitry Andric     std::vector<ValueLatticeElement> LVs = getStructLatticeValueFor(V);
91906c3fb27SDimitry Andric     if (any_of(LVs, SCCPSolver::isOverdefined))
92006c3fb27SDimitry Andric       return nullptr;
92106c3fb27SDimitry Andric     std::vector<Constant *> ConstVals;
92206c3fb27SDimitry Andric     auto *ST = cast<StructType>(V->getType());
92306c3fb27SDimitry Andric     for (unsigned I = 0, E = ST->getNumElements(); I != E; ++I) {
92406c3fb27SDimitry Andric       ValueLatticeElement LV = LVs[I];
92506c3fb27SDimitry Andric       ConstVals.push_back(SCCPSolver::isConstant(LV)
92606c3fb27SDimitry Andric                               ? getConstant(LV, ST->getElementType(I))
92706c3fb27SDimitry Andric                               : UndefValue::get(ST->getElementType(I)));
92806c3fb27SDimitry Andric     }
92906c3fb27SDimitry Andric     Const = ConstantStruct::get(ST, ConstVals);
93006c3fb27SDimitry Andric   } else {
93106c3fb27SDimitry Andric     const ValueLatticeElement &LV = getLatticeValueFor(V);
93206c3fb27SDimitry Andric     if (SCCPSolver::isOverdefined(LV))
93306c3fb27SDimitry Andric       return nullptr;
93406c3fb27SDimitry Andric     Const = SCCPSolver::isConstant(LV) ? getConstant(LV, V->getType())
93506c3fb27SDimitry Andric                                        : UndefValue::get(V->getType());
93606c3fb27SDimitry Andric   }
93706c3fb27SDimitry Andric   assert(Const && "Constant is nullptr here!");
93806c3fb27SDimitry Andric   return Const;
939bdd1243dSDimitry Andric }
940bdd1243dSDimitry Andric 
94106c3fb27SDimitry Andric void SCCPInstVisitor::setLatticeValueForSpecializationArguments(Function *F,
94206c3fb27SDimitry Andric                                         const SmallVectorImpl<ArgInfo> &Args) {
94381ad6265SDimitry Andric   assert(!Args.empty() && "Specialization without arguments");
94481ad6265SDimitry Andric   assert(F->arg_size() == Args[0].Formal->getParent()->arg_size() &&
945fe6060f1SDimitry Andric          "Functions should have the same number of arguments");
946fe6060f1SDimitry Andric 
94781ad6265SDimitry Andric   auto Iter = Args.begin();
94806c3fb27SDimitry Andric   Function::arg_iterator NewArg = F->arg_begin();
94906c3fb27SDimitry Andric   Function::arg_iterator OldArg = Args[0].Formal->getParent()->arg_begin();
95081ad6265SDimitry Andric   for (auto End = F->arg_end(); NewArg != End; ++NewArg, ++OldArg) {
951fe6060f1SDimitry Andric 
95281ad6265SDimitry Andric     LLVM_DEBUG(dbgs() << "SCCP: Marking argument "
95381ad6265SDimitry Andric                       << NewArg->getNameOrAsOperand() << "\n");
95481ad6265SDimitry Andric 
95506c3fb27SDimitry Andric     // Mark the argument constants in the new function
95606c3fb27SDimitry Andric     // or copy the lattice state over from the old function.
95706c3fb27SDimitry Andric     if (Iter != Args.end() && Iter->Formal == &*OldArg) {
95806c3fb27SDimitry Andric       if (auto *STy = dyn_cast<StructType>(NewArg->getType())) {
95906c3fb27SDimitry Andric         for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
96006c3fb27SDimitry Andric           ValueLatticeElement &NewValue = StructValueState[{&*NewArg, I}];
96106c3fb27SDimitry Andric           NewValue.markConstant(Iter->Actual->getAggregateElement(I));
96206c3fb27SDimitry Andric         }
96306c3fb27SDimitry Andric       } else {
96406c3fb27SDimitry Andric         ValueState[&*NewArg].markConstant(Iter->Actual);
96506c3fb27SDimitry Andric       }
96681ad6265SDimitry Andric       ++Iter;
96706c3fb27SDimitry Andric     } else {
96806c3fb27SDimitry Andric       if (auto *STy = dyn_cast<StructType>(NewArg->getType())) {
96906c3fb27SDimitry Andric         for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
97006c3fb27SDimitry Andric           ValueLatticeElement &NewValue = StructValueState[{&*NewArg, I}];
97106c3fb27SDimitry Andric           NewValue = StructValueState[{&*OldArg, I}];
97206c3fb27SDimitry Andric         }
97306c3fb27SDimitry Andric       } else {
97406c3fb27SDimitry Andric         ValueLatticeElement &NewValue = ValueState[&*NewArg];
97506c3fb27SDimitry Andric         NewValue = ValueState[&*OldArg];
97606c3fb27SDimitry Andric       }
97781ad6265SDimitry Andric     }
978fe6060f1SDimitry Andric   }
979fe6060f1SDimitry Andric }
980fe6060f1SDimitry Andric 
981fe6060f1SDimitry Andric void SCCPInstVisitor::visitInstruction(Instruction &I) {
982fe6060f1SDimitry Andric   // All the instructions we don't do any special handling for just
983fe6060f1SDimitry Andric   // go to overdefined.
984fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "SCCP: Don't know how to handle: " << I << '\n');
985fe6060f1SDimitry Andric   markOverdefined(&I);
986fe6060f1SDimitry Andric }
987fe6060f1SDimitry Andric 
988fe6060f1SDimitry Andric bool SCCPInstVisitor::mergeInValue(ValueLatticeElement &IV, Value *V,
989fe6060f1SDimitry Andric                                    ValueLatticeElement MergeWithV,
990fe6060f1SDimitry Andric                                    ValueLatticeElement::MergeOptions Opts) {
991fe6060f1SDimitry Andric   if (IV.mergeIn(MergeWithV, Opts)) {
992fe6060f1SDimitry Andric     pushToWorkList(IV, V);
993fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "Merged " << MergeWithV << " into " << *V << " : "
994fe6060f1SDimitry Andric                       << IV << "\n");
995fe6060f1SDimitry Andric     return true;
996fe6060f1SDimitry Andric   }
997fe6060f1SDimitry Andric   return false;
998fe6060f1SDimitry Andric }
999fe6060f1SDimitry Andric 
1000fe6060f1SDimitry Andric bool SCCPInstVisitor::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
1001fe6060f1SDimitry Andric   if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
1002fe6060f1SDimitry Andric     return false; // This edge is already known to be executable!
1003fe6060f1SDimitry Andric 
1004fe6060f1SDimitry Andric   if (!markBlockExecutable(Dest)) {
1005fe6060f1SDimitry Andric     // If the destination is already executable, we just made an *edge*
1006fe6060f1SDimitry Andric     // feasible that wasn't before.  Revisit the PHI nodes in the block
1007fe6060f1SDimitry Andric     // because they have potentially new operands.
1008fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName()
1009fe6060f1SDimitry Andric                       << " -> " << Dest->getName() << '\n');
1010fe6060f1SDimitry Andric 
1011fe6060f1SDimitry Andric     for (PHINode &PN : Dest->phis())
1012fe6060f1SDimitry Andric       visitPHINode(PN);
1013fe6060f1SDimitry Andric   }
1014fe6060f1SDimitry Andric   return true;
1015fe6060f1SDimitry Andric }
1016fe6060f1SDimitry Andric 
1017fe6060f1SDimitry Andric // getFeasibleSuccessors - Return a vector of booleans to indicate which
1018fe6060f1SDimitry Andric // successors are reachable from a given terminator instruction.
1019fe6060f1SDimitry Andric void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
1020fe6060f1SDimitry Andric                                             SmallVectorImpl<bool> &Succs) {
1021fe6060f1SDimitry Andric   Succs.resize(TI.getNumSuccessors());
1022fe6060f1SDimitry Andric   if (auto *BI = dyn_cast<BranchInst>(&TI)) {
1023fe6060f1SDimitry Andric     if (BI->isUnconditional()) {
1024fe6060f1SDimitry Andric       Succs[0] = true;
1025fe6060f1SDimitry Andric       return;
1026fe6060f1SDimitry Andric     }
1027fe6060f1SDimitry Andric 
1028fe6060f1SDimitry Andric     ValueLatticeElement BCValue = getValueState(BI->getCondition());
102906c3fb27SDimitry Andric     ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
1030fe6060f1SDimitry Andric     if (!CI) {
1031fe6060f1SDimitry Andric       // Overdefined condition variables, and branches on unfoldable constant
1032fe6060f1SDimitry Andric       // conditions, mean the branch could go either way.
1033fe6060f1SDimitry Andric       if (!BCValue.isUnknownOrUndef())
1034fe6060f1SDimitry Andric         Succs[0] = Succs[1] = true;
1035fe6060f1SDimitry Andric       return;
1036fe6060f1SDimitry Andric     }
1037fe6060f1SDimitry Andric 
1038fe6060f1SDimitry Andric     // Constant condition variables mean the branch can only go a single way.
1039fe6060f1SDimitry Andric     Succs[CI->isZero()] = true;
1040fe6060f1SDimitry Andric     return;
1041fe6060f1SDimitry Andric   }
1042fe6060f1SDimitry Andric 
1043*5f757f3fSDimitry Andric   // We cannot analyze special terminators, so consider all successors
1044*5f757f3fSDimitry Andric   // executable.
1045*5f757f3fSDimitry Andric   if (TI.isSpecialTerminator()) {
1046fe6060f1SDimitry Andric     Succs.assign(TI.getNumSuccessors(), true);
1047fe6060f1SDimitry Andric     return;
1048fe6060f1SDimitry Andric   }
1049fe6060f1SDimitry Andric 
1050fe6060f1SDimitry Andric   if (auto *SI = dyn_cast<SwitchInst>(&TI)) {
1051fe6060f1SDimitry Andric     if (!SI->getNumCases()) {
1052fe6060f1SDimitry Andric       Succs[0] = true;
1053fe6060f1SDimitry Andric       return;
1054fe6060f1SDimitry Andric     }
1055fe6060f1SDimitry Andric     const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
105606c3fb27SDimitry Andric     if (ConstantInt *CI =
105706c3fb27SDimitry Andric             getConstantInt(SCValue, SI->getCondition()->getType())) {
1058fe6060f1SDimitry Andric       Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
1059fe6060f1SDimitry Andric       return;
1060fe6060f1SDimitry Andric     }
1061fe6060f1SDimitry Andric 
1062fe6060f1SDimitry Andric     // TODO: Switch on undef is UB. Stop passing false once the rest of LLVM
1063fe6060f1SDimitry Andric     // is ready.
1064fe6060f1SDimitry Andric     if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
1065fe6060f1SDimitry Andric       const ConstantRange &Range = SCValue.getConstantRange();
1066fe6060f1SDimitry Andric       for (const auto &Case : SI->cases()) {
1067fe6060f1SDimitry Andric         const APInt &CaseValue = Case.getCaseValue()->getValue();
1068fe6060f1SDimitry Andric         if (Range.contains(CaseValue))
1069fe6060f1SDimitry Andric           Succs[Case.getSuccessorIndex()] = true;
1070fe6060f1SDimitry Andric       }
1071fe6060f1SDimitry Andric 
1072fe6060f1SDimitry Andric       // TODO: Determine whether default case is reachable.
1073fe6060f1SDimitry Andric       Succs[SI->case_default()->getSuccessorIndex()] = true;
1074fe6060f1SDimitry Andric       return;
1075fe6060f1SDimitry Andric     }
1076fe6060f1SDimitry Andric 
1077fe6060f1SDimitry Andric     // Overdefined or unknown condition? All destinations are executable!
1078fe6060f1SDimitry Andric     if (!SCValue.isUnknownOrUndef())
1079fe6060f1SDimitry Andric       Succs.assign(TI.getNumSuccessors(), true);
1080fe6060f1SDimitry Andric     return;
1081fe6060f1SDimitry Andric   }
1082fe6060f1SDimitry Andric 
1083fe6060f1SDimitry Andric   // In case of indirect branch and its address is a blockaddress, we mark
1084fe6060f1SDimitry Andric   // the target as executable.
1085fe6060f1SDimitry Andric   if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
1086fe6060f1SDimitry Andric     // Casts are folded by visitCastInst.
1087fe6060f1SDimitry Andric     ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
108806c3fb27SDimitry Andric     BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(
108906c3fb27SDimitry Andric         getConstant(IBRValue, IBR->getAddress()->getType()));
1090fe6060f1SDimitry Andric     if (!Addr) { // Overdefined or unknown condition?
1091fe6060f1SDimitry Andric       // All destinations are executable!
1092fe6060f1SDimitry Andric       if (!IBRValue.isUnknownOrUndef())
1093fe6060f1SDimitry Andric         Succs.assign(TI.getNumSuccessors(), true);
1094fe6060f1SDimitry Andric       return;
1095fe6060f1SDimitry Andric     }
1096fe6060f1SDimitry Andric 
1097fe6060f1SDimitry Andric     BasicBlock *T = Addr->getBasicBlock();
1098fe6060f1SDimitry Andric     assert(Addr->getFunction() == T->getParent() &&
1099fe6060f1SDimitry Andric            "Block address of a different function ?");
1100fe6060f1SDimitry Andric     for (unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
1101fe6060f1SDimitry Andric       // This is the target.
1102fe6060f1SDimitry Andric       if (IBR->getDestination(i) == T) {
1103fe6060f1SDimitry Andric         Succs[i] = true;
1104fe6060f1SDimitry Andric         return;
1105fe6060f1SDimitry Andric       }
1106fe6060f1SDimitry Andric     }
1107fe6060f1SDimitry Andric 
1108fe6060f1SDimitry Andric     // If we didn't find our destination in the IBR successor list, then we
1109fe6060f1SDimitry Andric     // have undefined behavior. Its ok to assume no successor is executable.
1110fe6060f1SDimitry Andric     return;
1111fe6060f1SDimitry Andric   }
1112fe6060f1SDimitry Andric 
1113fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "Unknown terminator instruction: " << TI << '\n');
1114fe6060f1SDimitry Andric   llvm_unreachable("SCCP: Don't know how to handle this terminator!");
1115fe6060f1SDimitry Andric }
1116fe6060f1SDimitry Andric 
1117fe6060f1SDimitry Andric // isEdgeFeasible - Return true if the control flow edge from the 'From' basic
1118fe6060f1SDimitry Andric // block to the 'To' basic block is currently feasible.
1119fe6060f1SDimitry Andric bool SCCPInstVisitor::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
1120fe6060f1SDimitry Andric   // Check if we've called markEdgeExecutable on the edge yet. (We could
1121fe6060f1SDimitry Andric   // be more aggressive and try to consider edges which haven't been marked
1122fe6060f1SDimitry Andric   // yet, but there isn't any need.)
1123fe6060f1SDimitry Andric   return KnownFeasibleEdges.count(Edge(From, To));
1124fe6060f1SDimitry Andric }
1125fe6060f1SDimitry Andric 
1126fe6060f1SDimitry Andric // visit Implementations - Something changed in this instruction, either an
1127fe6060f1SDimitry Andric // operand made a transition, or the instruction is newly executable.  Change
1128fe6060f1SDimitry Andric // the value type of I to reflect these changes if appropriate.  This method
1129fe6060f1SDimitry Andric // makes sure to do the following actions:
1130fe6060f1SDimitry Andric //
1131fe6060f1SDimitry Andric // 1. If a phi node merges two constants in, and has conflicting value coming
1132fe6060f1SDimitry Andric //    from different branches, or if the PHI node merges in an overdefined
1133fe6060f1SDimitry Andric //    value, then the PHI node becomes overdefined.
1134fe6060f1SDimitry Andric // 2. If a phi node merges only constants in, and they all agree on value, the
1135fe6060f1SDimitry Andric //    PHI node becomes a constant value equal to that.
1136fe6060f1SDimitry Andric // 3. If V <- x (op) y && isConstant(x) && isConstant(y) V = Constant
1137fe6060f1SDimitry Andric // 4. If V <- x (op) y && (isOverdefined(x) || isOverdefined(y)) V = Overdefined
1138fe6060f1SDimitry Andric // 5. If V <- MEM or V <- CALL or V <- (unknown) then V = Overdefined
1139fe6060f1SDimitry Andric // 6. If a conditional branch has a value that is constant, make the selected
1140fe6060f1SDimitry Andric //    destination executable
1141fe6060f1SDimitry Andric // 7. If a conditional branch has a value that is overdefined, make all
1142fe6060f1SDimitry Andric //    successors executable.
1143fe6060f1SDimitry Andric void SCCPInstVisitor::visitPHINode(PHINode &PN) {
1144fe6060f1SDimitry Andric   // If this PN returns a struct, just mark the result overdefined.
1145fe6060f1SDimitry Andric   // TODO: We could do a lot better than this if code actually uses this.
1146fe6060f1SDimitry Andric   if (PN.getType()->isStructTy())
1147fe6060f1SDimitry Andric     return (void)markOverdefined(&PN);
1148fe6060f1SDimitry Andric 
1149fe6060f1SDimitry Andric   if (getValueState(&PN).isOverdefined())
1150fe6060f1SDimitry Andric     return; // Quick exit
1151fe6060f1SDimitry Andric 
1152fe6060f1SDimitry Andric   // Super-extra-high-degree PHI nodes are unlikely to ever be marked constant,
1153fe6060f1SDimitry Andric   // and slow us down a lot.  Just mark them overdefined.
1154fe6060f1SDimitry Andric   if (PN.getNumIncomingValues() > 64)
1155fe6060f1SDimitry Andric     return (void)markOverdefined(&PN);
1156fe6060f1SDimitry Andric 
1157fe6060f1SDimitry Andric   unsigned NumActiveIncoming = 0;
1158fe6060f1SDimitry Andric 
1159fe6060f1SDimitry Andric   // Look at all of the executable operands of the PHI node.  If any of them
1160fe6060f1SDimitry Andric   // are overdefined, the PHI becomes overdefined as well.  If they are all
1161fe6060f1SDimitry Andric   // constant, and they agree with each other, the PHI becomes the identical
1162fe6060f1SDimitry Andric   // constant.  If they are constant and don't agree, the PHI is a constant
1163fe6060f1SDimitry Andric   // range. If there are no executable operands, the PHI remains unknown.
1164fe6060f1SDimitry Andric   ValueLatticeElement PhiState = getValueState(&PN);
1165fe6060f1SDimitry Andric   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
1166fe6060f1SDimitry Andric     if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
1167fe6060f1SDimitry Andric       continue;
1168fe6060f1SDimitry Andric 
1169fe6060f1SDimitry Andric     ValueLatticeElement IV = getValueState(PN.getIncomingValue(i));
1170fe6060f1SDimitry Andric     PhiState.mergeIn(IV);
1171fe6060f1SDimitry Andric     NumActiveIncoming++;
1172fe6060f1SDimitry Andric     if (PhiState.isOverdefined())
1173fe6060f1SDimitry Andric       break;
1174fe6060f1SDimitry Andric   }
1175fe6060f1SDimitry Andric 
1176fe6060f1SDimitry Andric   // We allow up to 1 range extension per active incoming value and one
1177fe6060f1SDimitry Andric   // additional extension. Note that we manually adjust the number of range
1178fe6060f1SDimitry Andric   // extensions to match the number of active incoming values. This helps to
1179fe6060f1SDimitry Andric   // limit multiple extensions caused by the same incoming value, if other
1180fe6060f1SDimitry Andric   // incoming values are equal.
1181fe6060f1SDimitry Andric   mergeInValue(&PN, PhiState,
1182fe6060f1SDimitry Andric                ValueLatticeElement::MergeOptions().setMaxWidenSteps(
1183fe6060f1SDimitry Andric                    NumActiveIncoming + 1));
1184fe6060f1SDimitry Andric   ValueLatticeElement &PhiStateRef = getValueState(&PN);
1185fe6060f1SDimitry Andric   PhiStateRef.setNumRangeExtensions(
1186fe6060f1SDimitry Andric       std::max(NumActiveIncoming, PhiStateRef.getNumRangeExtensions()));
1187fe6060f1SDimitry Andric }
1188fe6060f1SDimitry Andric 
1189fe6060f1SDimitry Andric void SCCPInstVisitor::visitReturnInst(ReturnInst &I) {
1190fe6060f1SDimitry Andric   if (I.getNumOperands() == 0)
1191fe6060f1SDimitry Andric     return; // ret void
1192fe6060f1SDimitry Andric 
1193fe6060f1SDimitry Andric   Function *F = I.getParent()->getParent();
1194fe6060f1SDimitry Andric   Value *ResultOp = I.getOperand(0);
1195fe6060f1SDimitry Andric 
1196fe6060f1SDimitry Andric   // If we are tracking the return value of this function, merge it in.
1197fe6060f1SDimitry Andric   if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) {
1198fe6060f1SDimitry Andric     auto TFRVI = TrackedRetVals.find(F);
1199fe6060f1SDimitry Andric     if (TFRVI != TrackedRetVals.end()) {
1200fe6060f1SDimitry Andric       mergeInValue(TFRVI->second, F, getValueState(ResultOp));
1201fe6060f1SDimitry Andric       return;
1202fe6060f1SDimitry Andric     }
1203fe6060f1SDimitry Andric   }
1204fe6060f1SDimitry Andric 
1205fe6060f1SDimitry Andric   // Handle functions that return multiple values.
1206fe6060f1SDimitry Andric   if (!TrackedMultipleRetVals.empty()) {
1207fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(ResultOp->getType()))
1208fe6060f1SDimitry Andric       if (MRVFunctionsTracked.count(F))
1209fe6060f1SDimitry Andric         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1210fe6060f1SDimitry Andric           mergeInValue(TrackedMultipleRetVals[std::make_pair(F, i)], F,
1211fe6060f1SDimitry Andric                        getStructValueState(ResultOp, i));
1212fe6060f1SDimitry Andric   }
1213fe6060f1SDimitry Andric }
1214fe6060f1SDimitry Andric 
1215fe6060f1SDimitry Andric void SCCPInstVisitor::visitTerminator(Instruction &TI) {
1216fe6060f1SDimitry Andric   SmallVector<bool, 16> SuccFeasible;
1217fe6060f1SDimitry Andric   getFeasibleSuccessors(TI, SuccFeasible);
1218fe6060f1SDimitry Andric 
1219fe6060f1SDimitry Andric   BasicBlock *BB = TI.getParent();
1220fe6060f1SDimitry Andric 
1221fe6060f1SDimitry Andric   // Mark all feasible successors executable.
1222fe6060f1SDimitry Andric   for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
1223fe6060f1SDimitry Andric     if (SuccFeasible[i])
1224fe6060f1SDimitry Andric       markEdgeExecutable(BB, TI.getSuccessor(i));
1225fe6060f1SDimitry Andric }
1226fe6060f1SDimitry Andric 
1227fe6060f1SDimitry Andric void SCCPInstVisitor::visitCastInst(CastInst &I) {
1228fe6060f1SDimitry Andric   // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1229fe6060f1SDimitry Andric   // discover a concrete value later.
1230fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
1231fe6060f1SDimitry Andric     return;
1232fe6060f1SDimitry Andric 
1233fe6060f1SDimitry Andric   ValueLatticeElement OpSt = getValueState(I.getOperand(0));
1234349cc55cSDimitry Andric   if (OpSt.isUnknownOrUndef())
1235349cc55cSDimitry Andric     return;
1236349cc55cSDimitry Andric 
123706c3fb27SDimitry Andric   if (Constant *OpC = getConstant(OpSt, I.getOperand(0)->getType())) {
1238fe6060f1SDimitry Andric     // Fold the constant as we build.
1239*5f757f3fSDimitry Andric     if (Constant *C =
1240*5f757f3fSDimitry Andric             ConstantFoldCastOperand(I.getOpcode(), OpC, I.getType(), DL))
1241*5f757f3fSDimitry Andric       return (void)markConstant(&I, C);
1242*5f757f3fSDimitry Andric   }
1243*5f757f3fSDimitry Andric 
1244*5f757f3fSDimitry Andric   if (I.getDestTy()->isIntegerTy() && I.getSrcTy()->isIntOrIntVectorTy()) {
1245fe6060f1SDimitry Andric     auto &LV = getValueState(&I);
1246bdd1243dSDimitry Andric     ConstantRange OpRange = getConstantRange(OpSt, I.getSrcTy());
1247349cc55cSDimitry Andric 
1248fe6060f1SDimitry Andric     Type *DestTy = I.getDestTy();
1249fe6060f1SDimitry Andric     // Vectors where all elements have the same known constant range are treated
1250fe6060f1SDimitry Andric     // as a single constant range in the lattice. When bitcasting such vectors,
1251fe6060f1SDimitry Andric     // there is a mis-match between the width of the lattice value (single
1252fe6060f1SDimitry Andric     // constant range) and the original operands (vector). Go to overdefined in
1253fe6060f1SDimitry Andric     // that case.
1254fe6060f1SDimitry Andric     if (I.getOpcode() == Instruction::BitCast &&
1255fe6060f1SDimitry Andric         I.getOperand(0)->getType()->isVectorTy() &&
1256fe6060f1SDimitry Andric         OpRange.getBitWidth() < DL.getTypeSizeInBits(DestTy))
1257fe6060f1SDimitry Andric       return (void)markOverdefined(&I);
1258fe6060f1SDimitry Andric 
1259fe6060f1SDimitry Andric     ConstantRange Res =
1260fe6060f1SDimitry Andric         OpRange.castOp(I.getOpcode(), DL.getTypeSizeInBits(DestTy));
1261fe6060f1SDimitry Andric     mergeInValue(LV, &I, ValueLatticeElement::getRange(Res));
1262349cc55cSDimitry Andric   } else
1263fe6060f1SDimitry Andric     markOverdefined(&I);
1264fe6060f1SDimitry Andric }
1265fe6060f1SDimitry Andric 
1266bdd1243dSDimitry Andric void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
1267bdd1243dSDimitry Andric                                                   const WithOverflowInst *WO,
1268bdd1243dSDimitry Andric                                                   unsigned Idx) {
1269bdd1243dSDimitry Andric   Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
1270bdd1243dSDimitry Andric   ValueLatticeElement L = getValueState(LHS);
1271bdd1243dSDimitry Andric   ValueLatticeElement R = getValueState(RHS);
1272bdd1243dSDimitry Andric   addAdditionalUser(LHS, &EVI);
1273bdd1243dSDimitry Andric   addAdditionalUser(RHS, &EVI);
1274bdd1243dSDimitry Andric   if (L.isUnknownOrUndef() || R.isUnknownOrUndef())
1275bdd1243dSDimitry Andric     return; // Wait to resolve.
1276bdd1243dSDimitry Andric 
1277bdd1243dSDimitry Andric   Type *Ty = LHS->getType();
1278bdd1243dSDimitry Andric   ConstantRange LR = getConstantRange(L, Ty);
1279bdd1243dSDimitry Andric   ConstantRange RR = getConstantRange(R, Ty);
1280bdd1243dSDimitry Andric   if (Idx == 0) {
1281bdd1243dSDimitry Andric     ConstantRange Res = LR.binaryOp(WO->getBinaryOp(), RR);
1282bdd1243dSDimitry Andric     mergeInValue(&EVI, ValueLatticeElement::getRange(Res));
1283bdd1243dSDimitry Andric   } else {
1284bdd1243dSDimitry Andric     assert(Idx == 1 && "Index can only be 0 or 1");
1285bdd1243dSDimitry Andric     ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
1286bdd1243dSDimitry Andric         WO->getBinaryOp(), RR, WO->getNoWrapKind());
1287bdd1243dSDimitry Andric     if (NWRegion.contains(LR))
1288bdd1243dSDimitry Andric       return (void)markConstant(&EVI, ConstantInt::getFalse(EVI.getType()));
1289bdd1243dSDimitry Andric     markOverdefined(&EVI);
1290bdd1243dSDimitry Andric   }
1291bdd1243dSDimitry Andric }
1292bdd1243dSDimitry Andric 
1293fe6060f1SDimitry Andric void SCCPInstVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
1294fe6060f1SDimitry Andric   // If this returns a struct, mark all elements over defined, we don't track
1295fe6060f1SDimitry Andric   // structs in structs.
1296fe6060f1SDimitry Andric   if (EVI.getType()->isStructTy())
1297fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
1298fe6060f1SDimitry Andric 
1299fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1300fe6060f1SDimitry Andric   // discover a concrete value later.
1301fe6060f1SDimitry Andric   if (ValueState[&EVI].isOverdefined())
1302fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
1303fe6060f1SDimitry Andric 
1304fe6060f1SDimitry Andric   // If this is extracting from more than one level of struct, we don't know.
1305fe6060f1SDimitry Andric   if (EVI.getNumIndices() != 1)
1306fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
1307fe6060f1SDimitry Andric 
1308fe6060f1SDimitry Andric   Value *AggVal = EVI.getAggregateOperand();
1309fe6060f1SDimitry Andric   if (AggVal->getType()->isStructTy()) {
1310fe6060f1SDimitry Andric     unsigned i = *EVI.idx_begin();
1311bdd1243dSDimitry Andric     if (auto *WO = dyn_cast<WithOverflowInst>(AggVal))
1312bdd1243dSDimitry Andric       return handleExtractOfWithOverflow(EVI, WO, i);
1313fe6060f1SDimitry Andric     ValueLatticeElement EltVal = getStructValueState(AggVal, i);
1314fe6060f1SDimitry Andric     mergeInValue(getValueState(&EVI), &EVI, EltVal);
1315fe6060f1SDimitry Andric   } else {
1316fe6060f1SDimitry Andric     // Otherwise, must be extracting from an array.
1317fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
1318fe6060f1SDimitry Andric   }
1319fe6060f1SDimitry Andric }
1320fe6060f1SDimitry Andric 
1321fe6060f1SDimitry Andric void SCCPInstVisitor::visitInsertValueInst(InsertValueInst &IVI) {
1322fe6060f1SDimitry Andric   auto *STy = dyn_cast<StructType>(IVI.getType());
1323fe6060f1SDimitry Andric   if (!STy)
1324fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
1325fe6060f1SDimitry Andric 
1326fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1327fe6060f1SDimitry Andric   // discover a concrete value later.
1328bdd1243dSDimitry Andric   if (SCCPSolver::isOverdefined(ValueState[&IVI]))
1329fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
1330fe6060f1SDimitry Andric 
1331fe6060f1SDimitry Andric   // If this has more than one index, we can't handle it, drive all results to
1332fe6060f1SDimitry Andric   // undef.
1333fe6060f1SDimitry Andric   if (IVI.getNumIndices() != 1)
1334fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
1335fe6060f1SDimitry Andric 
1336fe6060f1SDimitry Andric   Value *Aggr = IVI.getAggregateOperand();
1337fe6060f1SDimitry Andric   unsigned Idx = *IVI.idx_begin();
1338fe6060f1SDimitry Andric 
1339fe6060f1SDimitry Andric   // Compute the result based on what we're inserting.
1340fe6060f1SDimitry Andric   for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1341fe6060f1SDimitry Andric     // This passes through all values that aren't the inserted element.
1342fe6060f1SDimitry Andric     if (i != Idx) {
1343fe6060f1SDimitry Andric       ValueLatticeElement EltVal = getStructValueState(Aggr, i);
1344fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
1345fe6060f1SDimitry Andric       continue;
1346fe6060f1SDimitry Andric     }
1347fe6060f1SDimitry Andric 
1348fe6060f1SDimitry Andric     Value *Val = IVI.getInsertedValueOperand();
1349fe6060f1SDimitry Andric     if (Val->getType()->isStructTy())
1350fe6060f1SDimitry Andric       // We don't track structs in structs.
1351fe6060f1SDimitry Andric       markOverdefined(getStructValueState(&IVI, i), &IVI);
1352fe6060f1SDimitry Andric     else {
1353fe6060f1SDimitry Andric       ValueLatticeElement InVal = getValueState(Val);
1354fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
1355fe6060f1SDimitry Andric     }
1356fe6060f1SDimitry Andric   }
1357fe6060f1SDimitry Andric }
1358fe6060f1SDimitry Andric 
1359fe6060f1SDimitry Andric void SCCPInstVisitor::visitSelectInst(SelectInst &I) {
1360fe6060f1SDimitry Andric   // If this select returns a struct, just mark the result overdefined.
1361fe6060f1SDimitry Andric   // TODO: We could do a lot better than this if code actually uses this.
1362fe6060f1SDimitry Andric   if (I.getType()->isStructTy())
1363fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1364fe6060f1SDimitry Andric 
1365fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1366fe6060f1SDimitry Andric   // discover a concrete value later.
1367fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
1368fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1369fe6060f1SDimitry Andric 
1370fe6060f1SDimitry Andric   ValueLatticeElement CondValue = getValueState(I.getCondition());
1371fe6060f1SDimitry Andric   if (CondValue.isUnknownOrUndef())
1372fe6060f1SDimitry Andric     return;
1373fe6060f1SDimitry Andric 
137406c3fb27SDimitry Andric   if (ConstantInt *CondCB =
137506c3fb27SDimitry Andric           getConstantInt(CondValue, I.getCondition()->getType())) {
1376fe6060f1SDimitry Andric     Value *OpVal = CondCB->isZero() ? I.getFalseValue() : I.getTrueValue();
1377fe6060f1SDimitry Andric     mergeInValue(&I, getValueState(OpVal));
1378fe6060f1SDimitry Andric     return;
1379fe6060f1SDimitry Andric   }
1380fe6060f1SDimitry Andric 
1381fe6060f1SDimitry Andric   // Otherwise, the condition is overdefined or a constant we can't evaluate.
1382fe6060f1SDimitry Andric   // See if we can produce something better than overdefined based on the T/F
1383fe6060f1SDimitry Andric   // value.
1384fe6060f1SDimitry Andric   ValueLatticeElement TVal = getValueState(I.getTrueValue());
1385fe6060f1SDimitry Andric   ValueLatticeElement FVal = getValueState(I.getFalseValue());
1386fe6060f1SDimitry Andric 
1387fe6060f1SDimitry Andric   bool Changed = ValueState[&I].mergeIn(TVal);
1388fe6060f1SDimitry Andric   Changed |= ValueState[&I].mergeIn(FVal);
1389fe6060f1SDimitry Andric   if (Changed)
1390fe6060f1SDimitry Andric     pushToWorkListMsg(ValueState[&I], &I);
1391fe6060f1SDimitry Andric }
1392fe6060f1SDimitry Andric 
1393fe6060f1SDimitry Andric // Handle Unary Operators.
1394fe6060f1SDimitry Andric void SCCPInstVisitor::visitUnaryOperator(Instruction &I) {
1395fe6060f1SDimitry Andric   ValueLatticeElement V0State = getValueState(I.getOperand(0));
1396fe6060f1SDimitry Andric 
1397fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
1398fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1399fe6060f1SDimitry Andric   // discover a concrete value later.
1400bdd1243dSDimitry Andric   if (SCCPSolver::isOverdefined(IV))
1401fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1402fe6060f1SDimitry Andric 
1403753f127fSDimitry Andric   // If something is unknown/undef, wait for it to resolve.
1404753f127fSDimitry Andric   if (V0State.isUnknownOrUndef())
1405fe6060f1SDimitry Andric     return;
1406753f127fSDimitry Andric 
1407bdd1243dSDimitry Andric   if (SCCPSolver::isConstant(V0State))
140806c3fb27SDimitry Andric     if (Constant *C = ConstantFoldUnaryOpOperand(
140906c3fb27SDimitry Andric             I.getOpcode(), getConstant(V0State, I.getType()), DL))
1410fe6060f1SDimitry Andric       return (void)markConstant(IV, &I, C);
1411fe6060f1SDimitry Andric 
1412fe6060f1SDimitry Andric   markOverdefined(&I);
1413fe6060f1SDimitry Andric }
1414fe6060f1SDimitry Andric 
141506c3fb27SDimitry Andric void SCCPInstVisitor::visitFreezeInst(FreezeInst &I) {
141606c3fb27SDimitry Andric   // If this freeze returns a struct, just mark the result overdefined.
141706c3fb27SDimitry Andric   // TODO: We could do a lot better than this.
141806c3fb27SDimitry Andric   if (I.getType()->isStructTy())
141906c3fb27SDimitry Andric     return (void)markOverdefined(&I);
142006c3fb27SDimitry Andric 
142106c3fb27SDimitry Andric   ValueLatticeElement V0State = getValueState(I.getOperand(0));
142206c3fb27SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
142306c3fb27SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
142406c3fb27SDimitry Andric   // discover a concrete value later.
142506c3fb27SDimitry Andric   if (SCCPSolver::isOverdefined(IV))
142606c3fb27SDimitry Andric     return (void)markOverdefined(&I);
142706c3fb27SDimitry Andric 
142806c3fb27SDimitry Andric   // If something is unknown/undef, wait for it to resolve.
142906c3fb27SDimitry Andric   if (V0State.isUnknownOrUndef())
143006c3fb27SDimitry Andric     return;
143106c3fb27SDimitry Andric 
143206c3fb27SDimitry Andric   if (SCCPSolver::isConstant(V0State) &&
143306c3fb27SDimitry Andric       isGuaranteedNotToBeUndefOrPoison(getConstant(V0State, I.getType())))
143406c3fb27SDimitry Andric     return (void)markConstant(IV, &I, getConstant(V0State, I.getType()));
143506c3fb27SDimitry Andric 
143606c3fb27SDimitry Andric   markOverdefined(&I);
143706c3fb27SDimitry Andric }
143806c3fb27SDimitry Andric 
1439fe6060f1SDimitry Andric // Handle Binary Operators.
1440fe6060f1SDimitry Andric void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
1441fe6060f1SDimitry Andric   ValueLatticeElement V1State = getValueState(I.getOperand(0));
1442fe6060f1SDimitry Andric   ValueLatticeElement V2State = getValueState(I.getOperand(1));
1443fe6060f1SDimitry Andric 
1444fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
1445fe6060f1SDimitry Andric   if (IV.isOverdefined())
1446fe6060f1SDimitry Andric     return;
1447fe6060f1SDimitry Andric 
1448fe6060f1SDimitry Andric   // If something is undef, wait for it to resolve.
1449fe6060f1SDimitry Andric   if (V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef())
1450fe6060f1SDimitry Andric     return;
1451fe6060f1SDimitry Andric 
1452fe6060f1SDimitry Andric   if (V1State.isOverdefined() && V2State.isOverdefined())
1453fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1454fe6060f1SDimitry Andric 
1455fe6060f1SDimitry Andric   // If either of the operands is a constant, try to fold it to a constant.
1456fe6060f1SDimitry Andric   // TODO: Use information from notconstant better.
1457fe6060f1SDimitry Andric   if ((V1State.isConstant() || V2State.isConstant())) {
145806c3fb27SDimitry Andric     Value *V1 = SCCPSolver::isConstant(V1State)
145906c3fb27SDimitry Andric                     ? getConstant(V1State, I.getOperand(0)->getType())
1460bdd1243dSDimitry Andric                     : I.getOperand(0);
146106c3fb27SDimitry Andric     Value *V2 = SCCPSolver::isConstant(V2State)
146206c3fb27SDimitry Andric                     ? getConstant(V2State, I.getOperand(1)->getType())
1463bdd1243dSDimitry Andric                     : I.getOperand(1);
146481ad6265SDimitry Andric     Value *R = simplifyBinOp(I.getOpcode(), V1, V2, SimplifyQuery(DL));
1465fe6060f1SDimitry Andric     auto *C = dyn_cast_or_null<Constant>(R);
1466fe6060f1SDimitry Andric     if (C) {
1467fe6060f1SDimitry Andric       // Conservatively assume that the result may be based on operands that may
1468fe6060f1SDimitry Andric       // be undef. Note that we use mergeInValue to combine the constant with
1469fe6060f1SDimitry Andric       // the existing lattice value for I, as different constants might be found
1470fe6060f1SDimitry Andric       // after one of the operands go to overdefined, e.g. due to one operand
1471fe6060f1SDimitry Andric       // being a special floating value.
1472fe6060f1SDimitry Andric       ValueLatticeElement NewV;
1473fe6060f1SDimitry Andric       NewV.markConstant(C, /*MayIncludeUndef=*/true);
1474fe6060f1SDimitry Andric       return (void)mergeInValue(&I, NewV);
1475fe6060f1SDimitry Andric     }
1476fe6060f1SDimitry Andric   }
1477fe6060f1SDimitry Andric 
1478fe6060f1SDimitry Andric   // Only use ranges for binary operators on integers.
1479fe6060f1SDimitry Andric   if (!I.getType()->isIntegerTy())
1480fe6060f1SDimitry Andric     return markOverdefined(&I);
1481fe6060f1SDimitry Andric 
1482fe6060f1SDimitry Andric   // Try to simplify to a constant range.
1483bdd1243dSDimitry Andric   ConstantRange A = getConstantRange(V1State, I.getType());
1484bdd1243dSDimitry Andric   ConstantRange B = getConstantRange(V2State, I.getType());
1485fe6060f1SDimitry Andric   ConstantRange R = A.binaryOp(cast<BinaryOperator>(&I)->getOpcode(), B);
1486fe6060f1SDimitry Andric   mergeInValue(&I, ValueLatticeElement::getRange(R));
1487fe6060f1SDimitry Andric 
1488fe6060f1SDimitry Andric   // TODO: Currently we do not exploit special values that produce something
1489fe6060f1SDimitry Andric   // better than overdefined with an overdefined operand for vector or floating
1490fe6060f1SDimitry Andric   // point types, like and <4 x i32> overdefined, zeroinitializer.
1491fe6060f1SDimitry Andric }
1492fe6060f1SDimitry Andric 
1493fe6060f1SDimitry Andric // Handle ICmpInst instruction.
1494fe6060f1SDimitry Andric void SCCPInstVisitor::visitCmpInst(CmpInst &I) {
1495fe6060f1SDimitry Andric   // Do not cache this lookup, getValueState calls later in the function might
1496fe6060f1SDimitry Andric   // invalidate the reference.
1497bdd1243dSDimitry Andric   if (SCCPSolver::isOverdefined(ValueState[&I]))
1498fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1499fe6060f1SDimitry Andric 
1500fe6060f1SDimitry Andric   Value *Op1 = I.getOperand(0);
1501fe6060f1SDimitry Andric   Value *Op2 = I.getOperand(1);
1502fe6060f1SDimitry Andric 
1503fe6060f1SDimitry Andric   // For parameters, use ParamState which includes constant range info if
1504fe6060f1SDimitry Andric   // available.
1505fe6060f1SDimitry Andric   auto V1State = getValueState(Op1);
1506fe6060f1SDimitry Andric   auto V2State = getValueState(Op2);
1507fe6060f1SDimitry Andric 
1508bdd1243dSDimitry Andric   Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State, DL);
1509fe6060f1SDimitry Andric   if (C) {
1510fe6060f1SDimitry Andric     ValueLatticeElement CV;
1511fe6060f1SDimitry Andric     CV.markConstant(C);
1512fe6060f1SDimitry Andric     mergeInValue(&I, CV);
1513fe6060f1SDimitry Andric     return;
1514fe6060f1SDimitry Andric   }
1515fe6060f1SDimitry Andric 
1516fe6060f1SDimitry Andric   // If operands are still unknown, wait for it to resolve.
1517fe6060f1SDimitry Andric   if ((V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) &&
1518bdd1243dSDimitry Andric       !SCCPSolver::isConstant(ValueState[&I]))
1519fe6060f1SDimitry Andric     return;
1520fe6060f1SDimitry Andric 
1521fe6060f1SDimitry Andric   markOverdefined(&I);
1522fe6060f1SDimitry Andric }
1523fe6060f1SDimitry Andric 
1524fe6060f1SDimitry Andric // Handle getelementptr instructions.  If all operands are constants then we
1525fe6060f1SDimitry Andric // can turn this into a getelementptr ConstantExpr.
1526fe6060f1SDimitry Andric void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
1527bdd1243dSDimitry Andric   if (SCCPSolver::isOverdefined(ValueState[&I]))
1528fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1529fe6060f1SDimitry Andric 
1530fe6060f1SDimitry Andric   SmallVector<Constant *, 8> Operands;
1531fe6060f1SDimitry Andric   Operands.reserve(I.getNumOperands());
1532fe6060f1SDimitry Andric 
1533fe6060f1SDimitry Andric   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
1534fe6060f1SDimitry Andric     ValueLatticeElement State = getValueState(I.getOperand(i));
1535fe6060f1SDimitry Andric     if (State.isUnknownOrUndef())
1536fe6060f1SDimitry Andric       return; // Operands are not resolved yet.
1537fe6060f1SDimitry Andric 
1538bdd1243dSDimitry Andric     if (SCCPSolver::isOverdefined(State))
1539fe6060f1SDimitry Andric       return (void)markOverdefined(&I);
1540fe6060f1SDimitry Andric 
154106c3fb27SDimitry Andric     if (Constant *C = getConstant(State, I.getOperand(i)->getType())) {
1542fe6060f1SDimitry Andric       Operands.push_back(C);
1543fe6060f1SDimitry Andric       continue;
1544fe6060f1SDimitry Andric     }
1545fe6060f1SDimitry Andric 
1546fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1547fe6060f1SDimitry Andric   }
1548fe6060f1SDimitry Andric 
1549*5f757f3fSDimitry Andric   if (Constant *C = ConstantFoldInstOperands(&I, Operands, DL))
1550fe6060f1SDimitry Andric     markConstant(&I, C);
1551fe6060f1SDimitry Andric }
1552fe6060f1SDimitry Andric 
1553fe6060f1SDimitry Andric void SCCPInstVisitor::visitStoreInst(StoreInst &SI) {
1554fe6060f1SDimitry Andric   // If this store is of a struct, ignore it.
1555fe6060f1SDimitry Andric   if (SI.getOperand(0)->getType()->isStructTy())
1556fe6060f1SDimitry Andric     return;
1557fe6060f1SDimitry Andric 
1558fe6060f1SDimitry Andric   if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1)))
1559fe6060f1SDimitry Andric     return;
1560fe6060f1SDimitry Andric 
1561fe6060f1SDimitry Andric   GlobalVariable *GV = cast<GlobalVariable>(SI.getOperand(1));
1562fe6060f1SDimitry Andric   auto I = TrackedGlobals.find(GV);
1563fe6060f1SDimitry Andric   if (I == TrackedGlobals.end())
1564fe6060f1SDimitry Andric     return;
1565fe6060f1SDimitry Andric 
1566fe6060f1SDimitry Andric   // Get the value we are storing into the global, then merge it.
1567fe6060f1SDimitry Andric   mergeInValue(I->second, GV, getValueState(SI.getOperand(0)),
1568fe6060f1SDimitry Andric                ValueLatticeElement::MergeOptions().setCheckWiden(false));
1569fe6060f1SDimitry Andric   if (I->second.isOverdefined())
1570fe6060f1SDimitry Andric     TrackedGlobals.erase(I); // No need to keep tracking this!
1571fe6060f1SDimitry Andric }
1572fe6060f1SDimitry Andric 
1573fe6060f1SDimitry Andric static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
1574fe6060f1SDimitry Andric   if (MDNode *Ranges = I->getMetadata(LLVMContext::MD_range))
1575fe6060f1SDimitry Andric     if (I->getType()->isIntegerTy())
1576fe6060f1SDimitry Andric       return ValueLatticeElement::getRange(
1577fe6060f1SDimitry Andric           getConstantRangeFromMetadata(*Ranges));
1578fe6060f1SDimitry Andric   if (I->hasMetadata(LLVMContext::MD_nonnull))
1579fe6060f1SDimitry Andric     return ValueLatticeElement::getNot(
1580fe6060f1SDimitry Andric         ConstantPointerNull::get(cast<PointerType>(I->getType())));
1581fe6060f1SDimitry Andric   return ValueLatticeElement::getOverdefined();
1582fe6060f1SDimitry Andric }
1583fe6060f1SDimitry Andric 
1584fe6060f1SDimitry Andric // Handle load instructions.  If the operand is a constant pointer to a constant
1585fe6060f1SDimitry Andric // global, we can replace the load with the loaded constant value!
1586fe6060f1SDimitry Andric void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
1587fe6060f1SDimitry Andric   // If this load is of a struct or the load is volatile, just mark the result
1588fe6060f1SDimitry Andric   // as overdefined.
1589fe6060f1SDimitry Andric   if (I.getType()->isStructTy() || I.isVolatile())
1590fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1591fe6060f1SDimitry Andric 
1592fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1593fe6060f1SDimitry Andric   // discover a concrete value later.
1594fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
1595fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1596fe6060f1SDimitry Andric 
1597fe6060f1SDimitry Andric   ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
1598fe6060f1SDimitry Andric   if (PtrVal.isUnknownOrUndef())
1599fe6060f1SDimitry Andric     return; // The pointer is not resolved yet!
1600fe6060f1SDimitry Andric 
1601fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
1602fe6060f1SDimitry Andric 
1603bdd1243dSDimitry Andric   if (SCCPSolver::isConstant(PtrVal)) {
160406c3fb27SDimitry Andric     Constant *Ptr = getConstant(PtrVal, I.getOperand(0)->getType());
1605fe6060f1SDimitry Andric 
1606fe6060f1SDimitry Andric     // load null is undefined.
1607fe6060f1SDimitry Andric     if (isa<ConstantPointerNull>(Ptr)) {
1608fe6060f1SDimitry Andric       if (NullPointerIsDefined(I.getFunction(), I.getPointerAddressSpace()))
1609fe6060f1SDimitry Andric         return (void)markOverdefined(IV, &I);
1610fe6060f1SDimitry Andric       else
1611fe6060f1SDimitry Andric         return;
1612fe6060f1SDimitry Andric     }
1613fe6060f1SDimitry Andric 
1614fe6060f1SDimitry Andric     // Transform load (constant global) into the value loaded.
1615fe6060f1SDimitry Andric     if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
1616fe6060f1SDimitry Andric       if (!TrackedGlobals.empty()) {
1617fe6060f1SDimitry Andric         // If we are tracking this global, merge in the known value for it.
1618fe6060f1SDimitry Andric         auto It = TrackedGlobals.find(GV);
1619fe6060f1SDimitry Andric         if (It != TrackedGlobals.end()) {
1620fe6060f1SDimitry Andric           mergeInValue(IV, &I, It->second, getMaxWidenStepsOpts());
1621fe6060f1SDimitry Andric           return;
1622fe6060f1SDimitry Andric         }
1623fe6060f1SDimitry Andric       }
1624fe6060f1SDimitry Andric     }
1625fe6060f1SDimitry Andric 
1626fe6060f1SDimitry Andric     // Transform load from a constant into a constant if possible.
1627753f127fSDimitry Andric     if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL))
1628fe6060f1SDimitry Andric       return (void)markConstant(IV, &I, C);
1629fe6060f1SDimitry Andric   }
1630fe6060f1SDimitry Andric 
1631fe6060f1SDimitry Andric   // Fall back to metadata.
1632fe6060f1SDimitry Andric   mergeInValue(&I, getValueFromMetadata(&I));
1633fe6060f1SDimitry Andric }
1634fe6060f1SDimitry Andric 
1635fe6060f1SDimitry Andric void SCCPInstVisitor::visitCallBase(CallBase &CB) {
1636fe6060f1SDimitry Andric   handleCallResult(CB);
1637fe6060f1SDimitry Andric   handleCallArguments(CB);
1638fe6060f1SDimitry Andric }
1639fe6060f1SDimitry Andric 
1640fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
1641fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1642fe6060f1SDimitry Andric 
1643fe6060f1SDimitry Andric   // Void return and not tracking callee, just bail.
1644fe6060f1SDimitry Andric   if (CB.getType()->isVoidTy())
1645fe6060f1SDimitry Andric     return;
1646fe6060f1SDimitry Andric 
1647fe6060f1SDimitry Andric   // Always mark struct return as overdefined.
1648fe6060f1SDimitry Andric   if (CB.getType()->isStructTy())
1649fe6060f1SDimitry Andric     return (void)markOverdefined(&CB);
1650fe6060f1SDimitry Andric 
1651fe6060f1SDimitry Andric   // Otherwise, if we have a single return value case, and if the function is
1652fe6060f1SDimitry Andric   // a declaration, maybe we can constant fold it.
1653fe6060f1SDimitry Andric   if (F && F->isDeclaration() && canConstantFoldCallTo(&CB, F)) {
1654fe6060f1SDimitry Andric     SmallVector<Constant *, 8> Operands;
1655349cc55cSDimitry Andric     for (const Use &A : CB.args()) {
1656349cc55cSDimitry Andric       if (A.get()->getType()->isStructTy())
1657fe6060f1SDimitry Andric         return markOverdefined(&CB); // Can't handle struct args.
1658bdd1243dSDimitry Andric       if (A.get()->getType()->isMetadataTy())
1659bdd1243dSDimitry Andric         continue;                    // Carried in CB, not allowed in Operands.
1660349cc55cSDimitry Andric       ValueLatticeElement State = getValueState(A);
1661fe6060f1SDimitry Andric 
1662fe6060f1SDimitry Andric       if (State.isUnknownOrUndef())
1663fe6060f1SDimitry Andric         return; // Operands are not resolved yet.
1664bdd1243dSDimitry Andric       if (SCCPSolver::isOverdefined(State))
1665fe6060f1SDimitry Andric         return (void)markOverdefined(&CB);
1666bdd1243dSDimitry Andric       assert(SCCPSolver::isConstant(State) && "Unknown state!");
166706c3fb27SDimitry Andric       Operands.push_back(getConstant(State, A->getType()));
1668fe6060f1SDimitry Andric     }
1669fe6060f1SDimitry Andric 
1670bdd1243dSDimitry Andric     if (SCCPSolver::isOverdefined(getValueState(&CB)))
1671fe6060f1SDimitry Andric       return (void)markOverdefined(&CB);
1672fe6060f1SDimitry Andric 
1673fe6060f1SDimitry Andric     // If we can constant fold this, mark the result of the call as a
1674fe6060f1SDimitry Andric     // constant.
1675753f127fSDimitry Andric     if (Constant *C = ConstantFoldCall(&CB, F, Operands, &GetTLI(*F)))
1676fe6060f1SDimitry Andric       return (void)markConstant(&CB, C);
1677fe6060f1SDimitry Andric   }
1678fe6060f1SDimitry Andric 
1679fe6060f1SDimitry Andric   // Fall back to metadata.
1680fe6060f1SDimitry Andric   mergeInValue(&CB, getValueFromMetadata(&CB));
1681fe6060f1SDimitry Andric }
1682fe6060f1SDimitry Andric 
1683fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallArguments(CallBase &CB) {
1684fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1685fe6060f1SDimitry Andric   // If this is a local function that doesn't have its address taken, mark its
1686fe6060f1SDimitry Andric   // entry block executable and merge in the actual arguments to the call into
1687fe6060f1SDimitry Andric   // the formal arguments of the function.
1688bdd1243dSDimitry Andric   if (TrackingIncomingArguments.count(F)) {
1689fe6060f1SDimitry Andric     markBlockExecutable(&F->front());
1690fe6060f1SDimitry Andric 
1691fe6060f1SDimitry Andric     // Propagate information from this call site into the callee.
1692fe6060f1SDimitry Andric     auto CAI = CB.arg_begin();
1693fe6060f1SDimitry Andric     for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
1694fe6060f1SDimitry Andric          ++AI, ++CAI) {
1695fe6060f1SDimitry Andric       // If this argument is byval, and if the function is not readonly, there
1696fe6060f1SDimitry Andric       // will be an implicit copy formed of the input aggregate.
1697fe6060f1SDimitry Andric       if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
1698fe6060f1SDimitry Andric         markOverdefined(&*AI);
1699fe6060f1SDimitry Andric         continue;
1700fe6060f1SDimitry Andric       }
1701fe6060f1SDimitry Andric 
1702fe6060f1SDimitry Andric       if (auto *STy = dyn_cast<StructType>(AI->getType())) {
1703fe6060f1SDimitry Andric         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1704fe6060f1SDimitry Andric           ValueLatticeElement CallArg = getStructValueState(*CAI, i);
1705fe6060f1SDimitry Andric           mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1706fe6060f1SDimitry Andric                        getMaxWidenStepsOpts());
1707fe6060f1SDimitry Andric         }
1708fe6060f1SDimitry Andric       } else
1709fe6060f1SDimitry Andric         mergeInValue(&*AI, getValueState(*CAI), getMaxWidenStepsOpts());
1710fe6060f1SDimitry Andric     }
1711fe6060f1SDimitry Andric   }
1712fe6060f1SDimitry Andric }
1713fe6060f1SDimitry Andric 
1714fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallResult(CallBase &CB) {
1715fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1716fe6060f1SDimitry Andric 
1717fe6060f1SDimitry Andric   if (auto *II = dyn_cast<IntrinsicInst>(&CB)) {
1718fe6060f1SDimitry Andric     if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
1719fe6060f1SDimitry Andric       if (ValueState[&CB].isOverdefined())
1720fe6060f1SDimitry Andric         return;
1721fe6060f1SDimitry Andric 
1722fe6060f1SDimitry Andric       Value *CopyOf = CB.getOperand(0);
1723fe6060f1SDimitry Andric       ValueLatticeElement CopyOfVal = getValueState(CopyOf);
1724fe6060f1SDimitry Andric       const auto *PI = getPredicateInfoFor(&CB);
1725fe6060f1SDimitry Andric       assert(PI && "Missing predicate info for ssa.copy");
1726fe6060f1SDimitry Andric 
1727bdd1243dSDimitry Andric       const std::optional<PredicateConstraint> &Constraint =
1728bdd1243dSDimitry Andric           PI->getConstraint();
1729fe6060f1SDimitry Andric       if (!Constraint) {
1730fe6060f1SDimitry Andric         mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1731fe6060f1SDimitry Andric         return;
1732fe6060f1SDimitry Andric       }
1733fe6060f1SDimitry Andric 
1734fe6060f1SDimitry Andric       CmpInst::Predicate Pred = Constraint->Predicate;
1735fe6060f1SDimitry Andric       Value *OtherOp = Constraint->OtherOp;
1736fe6060f1SDimitry Andric 
1737fe6060f1SDimitry Andric       // Wait until OtherOp is resolved.
1738fe6060f1SDimitry Andric       if (getValueState(OtherOp).isUnknown()) {
1739fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1740fe6060f1SDimitry Andric         return;
1741fe6060f1SDimitry Andric       }
1742fe6060f1SDimitry Andric 
1743fe6060f1SDimitry Andric       ValueLatticeElement CondVal = getValueState(OtherOp);
1744fe6060f1SDimitry Andric       ValueLatticeElement &IV = ValueState[&CB];
1745fe6060f1SDimitry Andric       if (CondVal.isConstantRange() || CopyOfVal.isConstantRange()) {
1746fe6060f1SDimitry Andric         auto ImposedCR =
1747fe6060f1SDimitry Andric             ConstantRange::getFull(DL.getTypeSizeInBits(CopyOf->getType()));
1748fe6060f1SDimitry Andric 
1749fe6060f1SDimitry Andric         // Get the range imposed by the condition.
1750fe6060f1SDimitry Andric         if (CondVal.isConstantRange())
1751fe6060f1SDimitry Andric           ImposedCR = ConstantRange::makeAllowedICmpRegion(
1752fe6060f1SDimitry Andric               Pred, CondVal.getConstantRange());
1753fe6060f1SDimitry Andric 
1754fe6060f1SDimitry Andric         // Combine range info for the original value with the new range from the
1755fe6060f1SDimitry Andric         // condition.
1756bdd1243dSDimitry Andric         auto CopyOfCR = getConstantRange(CopyOfVal, CopyOf->getType());
1757fe6060f1SDimitry Andric         auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1758fe6060f1SDimitry Andric         // If the existing information is != x, do not use the information from
1759fe6060f1SDimitry Andric         // a chained predicate, as the != x information is more likely to be
1760fe6060f1SDimitry Andric         // helpful in practice.
1761fe6060f1SDimitry Andric         if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1762fe6060f1SDimitry Andric           NewCR = CopyOfCR;
1763fe6060f1SDimitry Andric 
176481ad6265SDimitry Andric         // The new range is based on a branch condition. That guarantees that
176581ad6265SDimitry Andric         // neither of the compare operands can be undef in the branch targets,
176681ad6265SDimitry Andric         // unless we have conditions that are always true/false (e.g. icmp ule
176781ad6265SDimitry Andric         // i32, %a, i32_max). For the latter overdefined/empty range will be
176881ad6265SDimitry Andric         // inferred, but the branch will get folded accordingly anyways.
1769fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
177081ad6265SDimitry Andric         mergeInValue(
177181ad6265SDimitry Andric             IV, &CB,
177281ad6265SDimitry Andric             ValueLatticeElement::getRange(NewCR, /*MayIncludeUndef*/ false));
1773fe6060f1SDimitry Andric         return;
1774bdd1243dSDimitry Andric       } else if (Pred == CmpInst::ICMP_EQ &&
1775bdd1243dSDimitry Andric                  (CondVal.isConstant() || CondVal.isNotConstant())) {
1776fe6060f1SDimitry Andric         // For non-integer values or integer constant expressions, only
1777bdd1243dSDimitry Andric         // propagate equal constants or not-constants.
1778fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1779fe6060f1SDimitry Andric         mergeInValue(IV, &CB, CondVal);
1780fe6060f1SDimitry Andric         return;
178181ad6265SDimitry Andric       } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant()) {
1782fe6060f1SDimitry Andric         // Propagate inequalities.
1783fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1784fe6060f1SDimitry Andric         mergeInValue(IV, &CB,
1785fe6060f1SDimitry Andric                      ValueLatticeElement::getNot(CondVal.getConstant()));
1786fe6060f1SDimitry Andric         return;
1787fe6060f1SDimitry Andric       }
1788fe6060f1SDimitry Andric 
1789fe6060f1SDimitry Andric       return (void)mergeInValue(IV, &CB, CopyOfVal);
1790fe6060f1SDimitry Andric     }
1791fe6060f1SDimitry Andric 
1792fe6060f1SDimitry Andric     if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
1793fe6060f1SDimitry Andric       // Compute result range for intrinsics supported by ConstantRange.
1794fe6060f1SDimitry Andric       // Do this even if we don't know a range for all operands, as we may
1795fe6060f1SDimitry Andric       // still know something about the result range, e.g. of abs(x).
1796fe6060f1SDimitry Andric       SmallVector<ConstantRange, 2> OpRanges;
1797fe6060f1SDimitry Andric       for (Value *Op : II->args()) {
1798fe6060f1SDimitry Andric         const ValueLatticeElement &State = getValueState(Op);
179906c3fb27SDimitry Andric         if (State.isUnknownOrUndef())
180006c3fb27SDimitry Andric           return;
1801bdd1243dSDimitry Andric         OpRanges.push_back(getConstantRange(State, Op->getType()));
1802fe6060f1SDimitry Andric       }
1803fe6060f1SDimitry Andric 
1804fe6060f1SDimitry Andric       ConstantRange Result =
1805fe6060f1SDimitry Andric           ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
1806fe6060f1SDimitry Andric       return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
1807fe6060f1SDimitry Andric     }
1808fe6060f1SDimitry Andric   }
1809fe6060f1SDimitry Andric 
1810fe6060f1SDimitry Andric   // The common case is that we aren't tracking the callee, either because we
1811fe6060f1SDimitry Andric   // are not doing interprocedural analysis or the callee is indirect, or is
1812fe6060f1SDimitry Andric   // external.  Handle these cases first.
1813fe6060f1SDimitry Andric   if (!F || F->isDeclaration())
1814fe6060f1SDimitry Andric     return handleCallOverdefined(CB);
1815fe6060f1SDimitry Andric 
1816fe6060f1SDimitry Andric   // If this is a single/zero retval case, see if we're tracking the function.
1817fe6060f1SDimitry Andric   if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
1818fe6060f1SDimitry Andric     if (!MRVFunctionsTracked.count(F))
1819fe6060f1SDimitry Andric       return handleCallOverdefined(CB); // Not tracking this callee.
1820fe6060f1SDimitry Andric 
1821fe6060f1SDimitry Andric     // If we are tracking this callee, propagate the result of the function
1822fe6060f1SDimitry Andric     // into this call site.
1823fe6060f1SDimitry Andric     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1824fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&CB, i), &CB,
1825fe6060f1SDimitry Andric                    TrackedMultipleRetVals[std::make_pair(F, i)],
1826fe6060f1SDimitry Andric                    getMaxWidenStepsOpts());
1827fe6060f1SDimitry Andric   } else {
1828fe6060f1SDimitry Andric     auto TFRVI = TrackedRetVals.find(F);
1829fe6060f1SDimitry Andric     if (TFRVI == TrackedRetVals.end())
1830fe6060f1SDimitry Andric       return handleCallOverdefined(CB); // Not tracking this callee.
1831fe6060f1SDimitry Andric 
1832fe6060f1SDimitry Andric     // If so, propagate the return value of the callee into this call result.
1833fe6060f1SDimitry Andric     mergeInValue(&CB, TFRVI->second, getMaxWidenStepsOpts());
1834fe6060f1SDimitry Andric   }
1835fe6060f1SDimitry Andric }
1836fe6060f1SDimitry Andric 
1837fe6060f1SDimitry Andric void SCCPInstVisitor::solve() {
1838fe6060f1SDimitry Andric   // Process the work lists until they are empty!
1839fe6060f1SDimitry Andric   while (!BBWorkList.empty() || !InstWorkList.empty() ||
1840fe6060f1SDimitry Andric          !OverdefinedInstWorkList.empty()) {
1841fe6060f1SDimitry Andric     // Process the overdefined instruction's work list first, which drives other
1842fe6060f1SDimitry Andric     // things to overdefined more quickly.
1843fe6060f1SDimitry Andric     while (!OverdefinedInstWorkList.empty()) {
1844fe6060f1SDimitry Andric       Value *I = OverdefinedInstWorkList.pop_back_val();
184506c3fb27SDimitry Andric       Invalidated.erase(I);
1846fe6060f1SDimitry Andric 
1847fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off OI-WL: " << *I << '\n');
1848fe6060f1SDimitry Andric 
1849fe6060f1SDimitry Andric       // "I" got into the work list because it either made the transition from
1850fe6060f1SDimitry Andric       // bottom to constant, or to overdefined.
1851fe6060f1SDimitry Andric       //
1852fe6060f1SDimitry Andric       // Anything on this worklist that is overdefined need not be visited
1853fe6060f1SDimitry Andric       // since all of its users will have already been marked as overdefined
1854fe6060f1SDimitry Andric       // Update all of the users of this instruction's value.
1855fe6060f1SDimitry Andric       //
1856fe6060f1SDimitry Andric       markUsersAsChanged(I);
1857fe6060f1SDimitry Andric     }
1858fe6060f1SDimitry Andric 
1859fe6060f1SDimitry Andric     // Process the instruction work list.
1860fe6060f1SDimitry Andric     while (!InstWorkList.empty()) {
1861fe6060f1SDimitry Andric       Value *I = InstWorkList.pop_back_val();
186206c3fb27SDimitry Andric       Invalidated.erase(I);
1863fe6060f1SDimitry Andric 
1864fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off I-WL: " << *I << '\n');
1865fe6060f1SDimitry Andric 
1866fe6060f1SDimitry Andric       // "I" got into the work list because it made the transition from undef to
1867fe6060f1SDimitry Andric       // constant.
1868fe6060f1SDimitry Andric       //
1869fe6060f1SDimitry Andric       // Anything on this worklist that is overdefined need not be visited
1870fe6060f1SDimitry Andric       // since all of its users will have already been marked as overdefined.
1871fe6060f1SDimitry Andric       // Update all of the users of this instruction's value.
1872fe6060f1SDimitry Andric       //
1873fe6060f1SDimitry Andric       if (I->getType()->isStructTy() || !getValueState(I).isOverdefined())
1874fe6060f1SDimitry Andric         markUsersAsChanged(I);
1875fe6060f1SDimitry Andric     }
1876fe6060f1SDimitry Andric 
1877fe6060f1SDimitry Andric     // Process the basic block work list.
1878fe6060f1SDimitry Andric     while (!BBWorkList.empty()) {
1879fe6060f1SDimitry Andric       BasicBlock *BB = BBWorkList.pop_back_val();
1880fe6060f1SDimitry Andric 
1881fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB << '\n');
1882fe6060f1SDimitry Andric 
1883fe6060f1SDimitry Andric       // Notify all instructions in this basic block that they are newly
1884fe6060f1SDimitry Andric       // executable.
1885fe6060f1SDimitry Andric       visit(BB);
1886fe6060f1SDimitry Andric     }
1887fe6060f1SDimitry Andric   }
1888fe6060f1SDimitry Andric }
1889fe6060f1SDimitry Andric 
189006c3fb27SDimitry Andric bool SCCPInstVisitor::resolvedUndef(Instruction &I) {
189106c3fb27SDimitry Andric   // Look for instructions which produce undef values.
189206c3fb27SDimitry Andric   if (I.getType()->isVoidTy())
189306c3fb27SDimitry Andric     return false;
189406c3fb27SDimitry Andric 
189506c3fb27SDimitry Andric   if (auto *STy = dyn_cast<StructType>(I.getType())) {
189606c3fb27SDimitry Andric     // Only a few things that can be structs matter for undef.
189706c3fb27SDimitry Andric 
189806c3fb27SDimitry Andric     // Tracked calls must never be marked overdefined in resolvedUndefsIn.
189906c3fb27SDimitry Andric     if (auto *CB = dyn_cast<CallBase>(&I))
190006c3fb27SDimitry Andric       if (Function *F = CB->getCalledFunction())
190106c3fb27SDimitry Andric         if (MRVFunctionsTracked.count(F))
190206c3fb27SDimitry Andric           return false;
190306c3fb27SDimitry Andric 
190406c3fb27SDimitry Andric     // extractvalue and insertvalue don't need to be marked; they are
190506c3fb27SDimitry Andric     // tracked as precisely as their operands.
190606c3fb27SDimitry Andric     if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
190706c3fb27SDimitry Andric       return false;
190806c3fb27SDimitry Andric     // Send the results of everything else to overdefined.  We could be
190906c3fb27SDimitry Andric     // more precise than this but it isn't worth bothering.
191006c3fb27SDimitry Andric     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
191106c3fb27SDimitry Andric       ValueLatticeElement &LV = getStructValueState(&I, i);
191206c3fb27SDimitry Andric       if (LV.isUnknown()) {
191306c3fb27SDimitry Andric         markOverdefined(LV, &I);
191406c3fb27SDimitry Andric         return true;
191506c3fb27SDimitry Andric       }
191606c3fb27SDimitry Andric     }
191706c3fb27SDimitry Andric     return false;
191806c3fb27SDimitry Andric   }
191906c3fb27SDimitry Andric 
192006c3fb27SDimitry Andric   ValueLatticeElement &LV = getValueState(&I);
192106c3fb27SDimitry Andric   if (!LV.isUnknown())
192206c3fb27SDimitry Andric     return false;
192306c3fb27SDimitry Andric 
192406c3fb27SDimitry Andric   // There are two reasons a call can have an undef result
192506c3fb27SDimitry Andric   // 1. It could be tracked.
192606c3fb27SDimitry Andric   // 2. It could be constant-foldable.
192706c3fb27SDimitry Andric   // Because of the way we solve return values, tracked calls must
192806c3fb27SDimitry Andric   // never be marked overdefined in resolvedUndefsIn.
192906c3fb27SDimitry Andric   if (auto *CB = dyn_cast<CallBase>(&I))
193006c3fb27SDimitry Andric     if (Function *F = CB->getCalledFunction())
193106c3fb27SDimitry Andric       if (TrackedRetVals.count(F))
193206c3fb27SDimitry Andric         return false;
193306c3fb27SDimitry Andric 
193406c3fb27SDimitry Andric   if (isa<LoadInst>(I)) {
193506c3fb27SDimitry Andric     // A load here means one of two things: a load of undef from a global,
193606c3fb27SDimitry Andric     // a load from an unknown pointer.  Either way, having it return undef
193706c3fb27SDimitry Andric     // is okay.
193806c3fb27SDimitry Andric     return false;
193906c3fb27SDimitry Andric   }
194006c3fb27SDimitry Andric 
194106c3fb27SDimitry Andric   markOverdefined(&I);
194206c3fb27SDimitry Andric   return true;
194306c3fb27SDimitry Andric }
194406c3fb27SDimitry Andric 
194581ad6265SDimitry Andric /// While solving the dataflow for a function, we don't compute a result for
194681ad6265SDimitry Andric /// operations with an undef operand, to allow undef to be lowered to a
194781ad6265SDimitry Andric /// constant later. For example, constant folding of "zext i8 undef to i16"
194881ad6265SDimitry Andric /// would result in "i16 0", and if undef is later lowered to "i8 1", then the
194981ad6265SDimitry Andric /// zext result would become "i16 1" and would result into an overdefined
195081ad6265SDimitry Andric /// lattice value once merged with the previous result. Not computing the
195181ad6265SDimitry Andric /// result of the zext (treating undef the same as unknown) allows us to handle
195281ad6265SDimitry Andric /// a later undef->constant lowering more optimally.
1953fe6060f1SDimitry Andric ///
195481ad6265SDimitry Andric /// However, if the operand remains undef when the solver returns, we do need
195581ad6265SDimitry Andric /// to assign some result to the instruction (otherwise we would treat it as
195681ad6265SDimitry Andric /// unreachable). For simplicity, we mark any instructions that are still
195781ad6265SDimitry Andric /// unknown as overdefined.
1958fe6060f1SDimitry Andric bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
1959fe6060f1SDimitry Andric   bool MadeChange = false;
1960fe6060f1SDimitry Andric   for (BasicBlock &BB : F) {
1961fe6060f1SDimitry Andric     if (!BBExecutable.count(&BB))
1962fe6060f1SDimitry Andric       continue;
1963fe6060f1SDimitry Andric 
196406c3fb27SDimitry Andric     for (Instruction &I : BB)
196506c3fb27SDimitry Andric       MadeChange |= resolvedUndef(I);
1966fe6060f1SDimitry Andric   }
1967fe6060f1SDimitry Andric 
1968bdd1243dSDimitry Andric   LLVM_DEBUG(if (MadeChange) dbgs()
1969bdd1243dSDimitry Andric              << "\nResolved undefs in " << F.getName() << '\n');
1970bdd1243dSDimitry Andric 
1971fe6060f1SDimitry Andric   return MadeChange;
1972fe6060f1SDimitry Andric }
1973fe6060f1SDimitry Andric 
1974fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
1975fe6060f1SDimitry Andric //
1976fe6060f1SDimitry Andric // SCCPSolver implementations
1977fe6060f1SDimitry Andric //
1978fe6060f1SDimitry Andric SCCPSolver::SCCPSolver(
1979fe6060f1SDimitry Andric     const DataLayout &DL,
1980fe6060f1SDimitry Andric     std::function<const TargetLibraryInfo &(Function &)> GetTLI,
1981fe6060f1SDimitry Andric     LLVMContext &Ctx)
1982fe6060f1SDimitry Andric     : Visitor(new SCCPInstVisitor(DL, std::move(GetTLI), Ctx)) {}
1983fe6060f1SDimitry Andric 
198481ad6265SDimitry Andric SCCPSolver::~SCCPSolver() = default;
1985fe6060f1SDimitry Andric 
198606c3fb27SDimitry Andric void SCCPSolver::addPredicateInfo(Function &F, DominatorTree &DT,
198706c3fb27SDimitry Andric                                   AssumptionCache &AC) {
198806c3fb27SDimitry Andric   Visitor->addPredicateInfo(F, DT, AC);
1989fe6060f1SDimitry Andric }
1990fe6060f1SDimitry Andric 
1991fe6060f1SDimitry Andric bool SCCPSolver::markBlockExecutable(BasicBlock *BB) {
1992fe6060f1SDimitry Andric   return Visitor->markBlockExecutable(BB);
1993fe6060f1SDimitry Andric }
1994fe6060f1SDimitry Andric 
1995fe6060f1SDimitry Andric const PredicateBase *SCCPSolver::getPredicateInfoFor(Instruction *I) {
1996fe6060f1SDimitry Andric   return Visitor->getPredicateInfoFor(I);
1997fe6060f1SDimitry Andric }
1998fe6060f1SDimitry Andric 
1999fe6060f1SDimitry Andric void SCCPSolver::trackValueOfGlobalVariable(GlobalVariable *GV) {
2000fe6060f1SDimitry Andric   Visitor->trackValueOfGlobalVariable(GV);
2001fe6060f1SDimitry Andric }
2002fe6060f1SDimitry Andric 
2003fe6060f1SDimitry Andric void SCCPSolver::addTrackedFunction(Function *F) {
2004fe6060f1SDimitry Andric   Visitor->addTrackedFunction(F);
2005fe6060f1SDimitry Andric }
2006fe6060f1SDimitry Andric 
2007fe6060f1SDimitry Andric void SCCPSolver::addToMustPreserveReturnsInFunctions(Function *F) {
2008fe6060f1SDimitry Andric   Visitor->addToMustPreserveReturnsInFunctions(F);
2009fe6060f1SDimitry Andric }
2010fe6060f1SDimitry Andric 
2011fe6060f1SDimitry Andric bool SCCPSolver::mustPreserveReturn(Function *F) {
2012fe6060f1SDimitry Andric   return Visitor->mustPreserveReturn(F);
2013fe6060f1SDimitry Andric }
2014fe6060f1SDimitry Andric 
2015fe6060f1SDimitry Andric void SCCPSolver::addArgumentTrackedFunction(Function *F) {
2016fe6060f1SDimitry Andric   Visitor->addArgumentTrackedFunction(F);
2017fe6060f1SDimitry Andric }
2018fe6060f1SDimitry Andric 
2019fe6060f1SDimitry Andric bool SCCPSolver::isArgumentTrackedFunction(Function *F) {
2020fe6060f1SDimitry Andric   return Visitor->isArgumentTrackedFunction(F);
2021fe6060f1SDimitry Andric }
2022fe6060f1SDimitry Andric 
2023fe6060f1SDimitry Andric void SCCPSolver::solve() { Visitor->solve(); }
2024fe6060f1SDimitry Andric 
2025fe6060f1SDimitry Andric bool SCCPSolver::resolvedUndefsIn(Function &F) {
2026fe6060f1SDimitry Andric   return Visitor->resolvedUndefsIn(F);
2027fe6060f1SDimitry Andric }
2028fe6060f1SDimitry Andric 
2029bdd1243dSDimitry Andric void SCCPSolver::solveWhileResolvedUndefsIn(Module &M) {
2030bdd1243dSDimitry Andric   Visitor->solveWhileResolvedUndefsIn(M);
2031bdd1243dSDimitry Andric }
2032bdd1243dSDimitry Andric 
2033bdd1243dSDimitry Andric void
2034bdd1243dSDimitry Andric SCCPSolver::solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
2035bdd1243dSDimitry Andric   Visitor->solveWhileResolvedUndefsIn(WorkList);
2036bdd1243dSDimitry Andric }
2037bdd1243dSDimitry Andric 
203806c3fb27SDimitry Andric void SCCPSolver::solveWhileResolvedUndefs() {
203906c3fb27SDimitry Andric   Visitor->solveWhileResolvedUndefs();
204006c3fb27SDimitry Andric }
204106c3fb27SDimitry Andric 
2042fe6060f1SDimitry Andric bool SCCPSolver::isBlockExecutable(BasicBlock *BB) const {
2043fe6060f1SDimitry Andric   return Visitor->isBlockExecutable(BB);
2044fe6060f1SDimitry Andric }
2045fe6060f1SDimitry Andric 
2046fe6060f1SDimitry Andric bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
2047fe6060f1SDimitry Andric   return Visitor->isEdgeFeasible(From, To);
2048fe6060f1SDimitry Andric }
2049fe6060f1SDimitry Andric 
2050fe6060f1SDimitry Andric std::vector<ValueLatticeElement>
2051fe6060f1SDimitry Andric SCCPSolver::getStructLatticeValueFor(Value *V) const {
2052fe6060f1SDimitry Andric   return Visitor->getStructLatticeValueFor(V);
2053fe6060f1SDimitry Andric }
2054fe6060f1SDimitry Andric 
2055fe6060f1SDimitry Andric void SCCPSolver::removeLatticeValueFor(Value *V) {
2056fe6060f1SDimitry Andric   return Visitor->removeLatticeValueFor(V);
2057fe6060f1SDimitry Andric }
2058fe6060f1SDimitry Andric 
205906c3fb27SDimitry Andric void SCCPSolver::resetLatticeValueFor(CallBase *Call) {
206006c3fb27SDimitry Andric   Visitor->resetLatticeValueFor(Call);
206106c3fb27SDimitry Andric }
206206c3fb27SDimitry Andric 
2063fe6060f1SDimitry Andric const ValueLatticeElement &SCCPSolver::getLatticeValueFor(Value *V) const {
2064fe6060f1SDimitry Andric   return Visitor->getLatticeValueFor(V);
2065fe6060f1SDimitry Andric }
2066fe6060f1SDimitry Andric 
2067fe6060f1SDimitry Andric const MapVector<Function *, ValueLatticeElement> &
2068fe6060f1SDimitry Andric SCCPSolver::getTrackedRetVals() {
2069fe6060f1SDimitry Andric   return Visitor->getTrackedRetVals();
2070fe6060f1SDimitry Andric }
2071fe6060f1SDimitry Andric 
2072fe6060f1SDimitry Andric const DenseMap<GlobalVariable *, ValueLatticeElement> &
2073fe6060f1SDimitry Andric SCCPSolver::getTrackedGlobals() {
2074fe6060f1SDimitry Andric   return Visitor->getTrackedGlobals();
2075fe6060f1SDimitry Andric }
2076fe6060f1SDimitry Andric 
2077fe6060f1SDimitry Andric const SmallPtrSet<Function *, 16> SCCPSolver::getMRVFunctionsTracked() {
2078fe6060f1SDimitry Andric   return Visitor->getMRVFunctionsTracked();
2079fe6060f1SDimitry Andric }
2080fe6060f1SDimitry Andric 
2081fe6060f1SDimitry Andric void SCCPSolver::markOverdefined(Value *V) { Visitor->markOverdefined(V); }
2082fe6060f1SDimitry Andric 
2083fe6060f1SDimitry Andric bool SCCPSolver::isStructLatticeConstant(Function *F, StructType *STy) {
2084fe6060f1SDimitry Andric   return Visitor->isStructLatticeConstant(F, STy);
2085fe6060f1SDimitry Andric }
2086fe6060f1SDimitry Andric 
208706c3fb27SDimitry Andric Constant *SCCPSolver::getConstant(const ValueLatticeElement &LV,
208806c3fb27SDimitry Andric                                   Type *Ty) const {
208906c3fb27SDimitry Andric   return Visitor->getConstant(LV, Ty);
209006c3fb27SDimitry Andric }
209106c3fb27SDimitry Andric 
209206c3fb27SDimitry Andric Constant *SCCPSolver::getConstantOrNull(Value *V) const {
209306c3fb27SDimitry Andric   return Visitor->getConstantOrNull(V);
2094fe6060f1SDimitry Andric }
2095fe6060f1SDimitry Andric 
2096fe6060f1SDimitry Andric SmallPtrSetImpl<Function *> &SCCPSolver::getArgumentTrackedFunctions() {
2097fe6060f1SDimitry Andric   return Visitor->getArgumentTrackedFunctions();
2098fe6060f1SDimitry Andric }
2099fe6060f1SDimitry Andric 
210006c3fb27SDimitry Andric void SCCPSolver::setLatticeValueForSpecializationArguments(Function *F,
210106c3fb27SDimitry Andric                                    const SmallVectorImpl<ArgInfo> &Args) {
210206c3fb27SDimitry Andric   Visitor->setLatticeValueForSpecializationArguments(F, Args);
2103fe6060f1SDimitry Andric }
2104fe6060f1SDimitry Andric 
2105fe6060f1SDimitry Andric void SCCPSolver::markFunctionUnreachable(Function *F) {
2106fe6060f1SDimitry Andric   Visitor->markFunctionUnreachable(F);
2107fe6060f1SDimitry Andric }
2108fe6060f1SDimitry Andric 
2109fe6060f1SDimitry Andric void SCCPSolver::visit(Instruction *I) { Visitor->visit(I); }
2110fe6060f1SDimitry Andric 
2111fe6060f1SDimitry Andric void SCCPSolver::visitCall(CallInst &I) { Visitor->visitCall(I); }
2112