1344a3780SDimitry Andric //===- SCCPSolver.cpp - SCCP Utility --------------------------- *- C++ -*-===//
2344a3780SDimitry Andric //
3344a3780SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4344a3780SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5344a3780SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6344a3780SDimitry Andric //
7344a3780SDimitry Andric //===----------------------------------------------------------------------===//
8344a3780SDimitry Andric //
9344a3780SDimitry Andric // \file
10344a3780SDimitry Andric // This file implements the Sparse Conditional Constant Propagation (SCCP)
11344a3780SDimitry Andric // utility.
12344a3780SDimitry Andric //
13344a3780SDimitry Andric //===----------------------------------------------------------------------===//
14344a3780SDimitry Andric
15344a3780SDimitry Andric #include "llvm/Transforms/Utils/SCCPSolver.h"
16344a3780SDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
17344a3780SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
18145449b1SDimitry Andric #include "llvm/Analysis/ValueLattice.h"
19e3b55780SDimitry Andric #include "llvm/Analysis/ValueLatticeUtils.h"
207fa27ce4SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
21145449b1SDimitry Andric #include "llvm/IR/InstVisitor.h"
22344a3780SDimitry Andric #include "llvm/Support/Casting.h"
23344a3780SDimitry Andric #include "llvm/Support/Debug.h"
24344a3780SDimitry Andric #include "llvm/Support/ErrorHandling.h"
25344a3780SDimitry Andric #include "llvm/Support/raw_ostream.h"
26e3b55780SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
27344a3780SDimitry Andric #include <cassert>
28344a3780SDimitry Andric #include <utility>
29344a3780SDimitry Andric #include <vector>
30344a3780SDimitry Andric
31344a3780SDimitry Andric using namespace llvm;
32344a3780SDimitry Andric
33344a3780SDimitry Andric #define DEBUG_TYPE "sccp"
34344a3780SDimitry Andric
35344a3780SDimitry Andric // The maximum number of range extensions allowed for operations requiring
36344a3780SDimitry Andric // widening.
37344a3780SDimitry Andric static const unsigned MaxNumRangeExtensions = 10;
38344a3780SDimitry Andric
39344a3780SDimitry Andric /// Returns MergeOptions with MaxWidenSteps set to MaxNumRangeExtensions.
getMaxWidenStepsOpts()40344a3780SDimitry Andric static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts() {
41344a3780SDimitry Andric return ValueLatticeElement::MergeOptions().setMaxWidenSteps(
42344a3780SDimitry Andric MaxNumRangeExtensions);
43344a3780SDimitry Andric }
44344a3780SDimitry Andric
45e3b55780SDimitry Andric namespace llvm {
46344a3780SDimitry Andric
isConstant(const ValueLatticeElement & LV)47e3b55780SDimitry Andric bool SCCPSolver::isConstant(const ValueLatticeElement &LV) {
48344a3780SDimitry Andric return LV.isConstant() ||
49344a3780SDimitry Andric (LV.isConstantRange() && LV.getConstantRange().isSingleElement());
50344a3780SDimitry Andric }
51344a3780SDimitry Andric
isOverdefined(const ValueLatticeElement & LV)52e3b55780SDimitry Andric bool SCCPSolver::isOverdefined(const ValueLatticeElement &LV) {
53e3b55780SDimitry Andric return !LV.isUnknownOrUndef() && !SCCPSolver::isConstant(LV);
54344a3780SDimitry Andric }
55344a3780SDimitry Andric
canRemoveInstruction(Instruction * I)56e3b55780SDimitry Andric static bool canRemoveInstruction(Instruction *I) {
57e3b55780SDimitry Andric if (wouldInstructionBeTriviallyDead(I))
58e3b55780SDimitry Andric return true;
59344a3780SDimitry Andric
60e3b55780SDimitry Andric // Some instructions can be handled but are rejected above. Catch
61e3b55780SDimitry Andric // those cases by falling through to here.
62e3b55780SDimitry Andric // TODO: Mark globals as being constant earlier, so
63e3b55780SDimitry Andric // TODO: wouldInstructionBeTriviallyDead() knows that atomic loads
64e3b55780SDimitry Andric // TODO: are safe to remove.
65e3b55780SDimitry Andric return isa<LoadInst>(I);
66e3b55780SDimitry Andric }
67e3b55780SDimitry Andric
tryToReplaceWithConstant(Value * V)68e3b55780SDimitry Andric bool SCCPSolver::tryToReplaceWithConstant(Value *V) {
697fa27ce4SDimitry Andric Constant *Const = getConstantOrNull(V);
707fa27ce4SDimitry Andric if (!Const)
71e3b55780SDimitry Andric return false;
72e3b55780SDimitry Andric // Replacing `musttail` instructions with constant breaks `musttail` invariant
73e3b55780SDimitry Andric // unless the call itself can be removed.
74e3b55780SDimitry Andric // Calls with "clang.arc.attachedcall" implicitly use the return value and
75e3b55780SDimitry Andric // those uses cannot be updated with a constant.
76e3b55780SDimitry Andric CallBase *CB = dyn_cast<CallBase>(V);
77e3b55780SDimitry Andric if (CB && ((CB->isMustTailCall() &&
78e3b55780SDimitry Andric !canRemoveInstruction(CB)) ||
79e3b55780SDimitry Andric CB->getOperandBundle(LLVMContext::OB_clang_arc_attachedcall))) {
80e3b55780SDimitry Andric Function *F = CB->getCalledFunction();
81e3b55780SDimitry Andric
82e3b55780SDimitry Andric // Don't zap returns of the callee
83e3b55780SDimitry Andric if (F)
84e3b55780SDimitry Andric addToMustPreserveReturnsInFunctions(F);
85e3b55780SDimitry Andric
86e3b55780SDimitry Andric LLVM_DEBUG(dbgs() << " Can\'t treat the result of call " << *CB
87e3b55780SDimitry Andric << " as a constant\n");
88e3b55780SDimitry Andric return false;
89e3b55780SDimitry Andric }
90e3b55780SDimitry Andric
91e3b55780SDimitry Andric LLVM_DEBUG(dbgs() << " Constant: " << *Const << " = " << *V << '\n');
92e3b55780SDimitry Andric
93e3b55780SDimitry Andric // Replaces all of the uses of a variable with uses of the constant.
94e3b55780SDimitry Andric V->replaceAllUsesWith(Const);
95e3b55780SDimitry Andric return true;
96e3b55780SDimitry Andric }
97e3b55780SDimitry Andric
987fa27ce4SDimitry Andric /// Try to use \p Inst's value range from \p Solver to infer the NUW flag.
refineInstruction(SCCPSolver & Solver,const SmallPtrSetImpl<Value * > & InsertedValues,Instruction & Inst)997fa27ce4SDimitry Andric static bool refineInstruction(SCCPSolver &Solver,
1007fa27ce4SDimitry Andric const SmallPtrSetImpl<Value *> &InsertedValues,
1017fa27ce4SDimitry Andric Instruction &Inst) {
102b1c73532SDimitry Andric bool Changed = false;
1037fa27ce4SDimitry Andric auto GetRange = [&Solver, &InsertedValues](Value *Op) {
104ac9a064cSDimitry Andric if (auto *Const = dyn_cast<Constant>(Op))
105ac9a064cSDimitry Andric return Const->toConstantRange();
106ac9a064cSDimitry Andric if (InsertedValues.contains(Op)) {
1077fa27ce4SDimitry Andric unsigned Bitwidth = Op->getType()->getScalarSizeInBits();
1087fa27ce4SDimitry Andric return ConstantRange::getFull(Bitwidth);
1097fa27ce4SDimitry Andric }
110ac9a064cSDimitry Andric return Solver.getLatticeValueFor(Op).asConstantRange(
111ac9a064cSDimitry Andric Op->getType(), /*UndefAllowed=*/false);
1127fa27ce4SDimitry Andric };
113b1c73532SDimitry Andric
114b1c73532SDimitry Andric if (isa<OverflowingBinaryOperator>(Inst)) {
115ac9a064cSDimitry Andric if (Inst.hasNoSignedWrap() && Inst.hasNoUnsignedWrap())
116ac9a064cSDimitry Andric return false;
117ac9a064cSDimitry Andric
1187fa27ce4SDimitry Andric auto RangeA = GetRange(Inst.getOperand(0));
1197fa27ce4SDimitry Andric auto RangeB = GetRange(Inst.getOperand(1));
1207fa27ce4SDimitry Andric if (!Inst.hasNoUnsignedWrap()) {
1217fa27ce4SDimitry Andric auto NUWRange = ConstantRange::makeGuaranteedNoWrapRegion(
1227fa27ce4SDimitry Andric Instruction::BinaryOps(Inst.getOpcode()), RangeB,
1237fa27ce4SDimitry Andric OverflowingBinaryOperator::NoUnsignedWrap);
1247fa27ce4SDimitry Andric if (NUWRange.contains(RangeA)) {
1257fa27ce4SDimitry Andric Inst.setHasNoUnsignedWrap();
1267fa27ce4SDimitry Andric Changed = true;
1277fa27ce4SDimitry Andric }
1287fa27ce4SDimitry Andric }
1297fa27ce4SDimitry Andric if (!Inst.hasNoSignedWrap()) {
1307fa27ce4SDimitry Andric auto NSWRange = ConstantRange::makeGuaranteedNoWrapRegion(
131b1c73532SDimitry Andric Instruction::BinaryOps(Inst.getOpcode()), RangeB,
132b1c73532SDimitry Andric OverflowingBinaryOperator::NoSignedWrap);
1337fa27ce4SDimitry Andric if (NSWRange.contains(RangeA)) {
1347fa27ce4SDimitry Andric Inst.setHasNoSignedWrap();
1357fa27ce4SDimitry Andric Changed = true;
1367fa27ce4SDimitry Andric }
1377fa27ce4SDimitry Andric }
138ac9a064cSDimitry Andric } else if (isa<PossiblyNonNegInst>(Inst) && !Inst.hasNonNeg()) {
139b1c73532SDimitry Andric auto Range = GetRange(Inst.getOperand(0));
140b1c73532SDimitry Andric if (Range.isAllNonNegative()) {
141b1c73532SDimitry Andric Inst.setNonNeg();
142b1c73532SDimitry Andric Changed = true;
143b1c73532SDimitry Andric }
144ac9a064cSDimitry Andric } else if (TruncInst *TI = dyn_cast<TruncInst>(&Inst)) {
145ac9a064cSDimitry Andric if (TI->hasNoSignedWrap() && TI->hasNoUnsignedWrap())
146ac9a064cSDimitry Andric return false;
147ac9a064cSDimitry Andric
148ac9a064cSDimitry Andric auto Range = GetRange(Inst.getOperand(0));
149ac9a064cSDimitry Andric uint64_t DestWidth = TI->getDestTy()->getScalarSizeInBits();
150ac9a064cSDimitry Andric if (!TI->hasNoUnsignedWrap()) {
151ac9a064cSDimitry Andric if (Range.getActiveBits() <= DestWidth) {
152ac9a064cSDimitry Andric TI->setHasNoUnsignedWrap(true);
153ac9a064cSDimitry Andric Changed = true;
154ac9a064cSDimitry Andric }
155ac9a064cSDimitry Andric }
156ac9a064cSDimitry Andric if (!TI->hasNoSignedWrap()) {
157ac9a064cSDimitry Andric if (Range.getMinSignedBits() <= DestWidth) {
158ac9a064cSDimitry Andric TI->setHasNoSignedWrap(true);
159ac9a064cSDimitry Andric Changed = true;
160ac9a064cSDimitry Andric }
161ac9a064cSDimitry Andric }
162b1c73532SDimitry Andric }
1637fa27ce4SDimitry Andric
1647fa27ce4SDimitry Andric return Changed;
1657fa27ce4SDimitry Andric }
1667fa27ce4SDimitry Andric
167e3b55780SDimitry Andric /// Try to replace signed instructions with their unsigned equivalent.
replaceSignedInst(SCCPSolver & Solver,SmallPtrSetImpl<Value * > & InsertedValues,Instruction & Inst)168e3b55780SDimitry Andric static bool replaceSignedInst(SCCPSolver &Solver,
169e3b55780SDimitry Andric SmallPtrSetImpl<Value *> &InsertedValues,
170e3b55780SDimitry Andric Instruction &Inst) {
171e3b55780SDimitry Andric // Determine if a signed value is known to be >= 0.
172e3b55780SDimitry Andric auto isNonNegative = [&Solver](Value *V) {
173e3b55780SDimitry Andric // If this value was constant-folded, it may not have a solver entry.
174e3b55780SDimitry Andric // Handle integers. Otherwise, return false.
175e3b55780SDimitry Andric if (auto *C = dyn_cast<Constant>(V)) {
176e3b55780SDimitry Andric auto *CInt = dyn_cast<ConstantInt>(C);
177e3b55780SDimitry Andric return CInt && !CInt->isNegative();
178e3b55780SDimitry Andric }
179e3b55780SDimitry Andric const ValueLatticeElement &IV = Solver.getLatticeValueFor(V);
180e3b55780SDimitry Andric return IV.isConstantRange(/*UndefAllowed=*/false) &&
181e3b55780SDimitry Andric IV.getConstantRange().isAllNonNegative();
182e3b55780SDimitry Andric };
183e3b55780SDimitry Andric
184e3b55780SDimitry Andric Instruction *NewInst = nullptr;
185e3b55780SDimitry Andric switch (Inst.getOpcode()) {
186ac9a064cSDimitry Andric case Instruction::SIToFP:
187e3b55780SDimitry Andric case Instruction::SExt: {
188ac9a064cSDimitry Andric // If the source value is not negative, this is a zext/uitofp.
189e3b55780SDimitry Andric Value *Op0 = Inst.getOperand(0);
190e3b55780SDimitry Andric if (InsertedValues.count(Op0) || !isNonNegative(Op0))
191e3b55780SDimitry Andric return false;
192ac9a064cSDimitry Andric NewInst = CastInst::Create(Inst.getOpcode() == Instruction::SExt
193ac9a064cSDimitry Andric ? Instruction::ZExt
194ac9a064cSDimitry Andric : Instruction::UIToFP,
195ac9a064cSDimitry Andric Op0, Inst.getType(), "", Inst.getIterator());
196b1c73532SDimitry Andric NewInst->setNonNeg();
197e3b55780SDimitry Andric break;
198e3b55780SDimitry Andric }
199e3b55780SDimitry Andric case Instruction::AShr: {
200e3b55780SDimitry Andric // If the shifted value is not negative, this is a logical shift right.
201e3b55780SDimitry Andric Value *Op0 = Inst.getOperand(0);
202e3b55780SDimitry Andric if (InsertedValues.count(Op0) || !isNonNegative(Op0))
203e3b55780SDimitry Andric return false;
204ac9a064cSDimitry Andric NewInst = BinaryOperator::CreateLShr(Op0, Inst.getOperand(1), "", Inst.getIterator());
205b1c73532SDimitry Andric NewInst->setIsExact(Inst.isExact());
206e3b55780SDimitry Andric break;
207e3b55780SDimitry Andric }
208e3b55780SDimitry Andric case Instruction::SDiv:
209e3b55780SDimitry Andric case Instruction::SRem: {
210e3b55780SDimitry Andric // If both operands are not negative, this is the same as udiv/urem.
211e3b55780SDimitry Andric Value *Op0 = Inst.getOperand(0), *Op1 = Inst.getOperand(1);
212e3b55780SDimitry Andric if (InsertedValues.count(Op0) || InsertedValues.count(Op1) ||
213e3b55780SDimitry Andric !isNonNegative(Op0) || !isNonNegative(Op1))
214e3b55780SDimitry Andric return false;
215e3b55780SDimitry Andric auto NewOpcode = Inst.getOpcode() == Instruction::SDiv ? Instruction::UDiv
216e3b55780SDimitry Andric : Instruction::URem;
217ac9a064cSDimitry Andric NewInst = BinaryOperator::Create(NewOpcode, Op0, Op1, "", Inst.getIterator());
218b1c73532SDimitry Andric if (Inst.getOpcode() == Instruction::SDiv)
219b1c73532SDimitry Andric NewInst->setIsExact(Inst.isExact());
220e3b55780SDimitry Andric break;
221e3b55780SDimitry Andric }
222e3b55780SDimitry Andric default:
223e3b55780SDimitry Andric return false;
224e3b55780SDimitry Andric }
225e3b55780SDimitry Andric
226e3b55780SDimitry Andric // Wire up the new instruction and update state.
227e3b55780SDimitry Andric assert(NewInst && "Expected replacement instruction");
228e3b55780SDimitry Andric NewInst->takeName(&Inst);
229e3b55780SDimitry Andric InsertedValues.insert(NewInst);
230e3b55780SDimitry Andric Inst.replaceAllUsesWith(NewInst);
231ac9a064cSDimitry Andric NewInst->setDebugLoc(Inst.getDebugLoc());
232e3b55780SDimitry Andric Solver.removeLatticeValueFor(&Inst);
233e3b55780SDimitry Andric Inst.eraseFromParent();
234e3b55780SDimitry Andric return true;
235e3b55780SDimitry Andric }
236e3b55780SDimitry Andric
simplifyInstsInBlock(BasicBlock & BB,SmallPtrSetImpl<Value * > & InsertedValues,Statistic & InstRemovedStat,Statistic & InstReplacedStat)237e3b55780SDimitry Andric bool SCCPSolver::simplifyInstsInBlock(BasicBlock &BB,
238e3b55780SDimitry Andric SmallPtrSetImpl<Value *> &InsertedValues,
239e3b55780SDimitry Andric Statistic &InstRemovedStat,
240e3b55780SDimitry Andric Statistic &InstReplacedStat) {
241e3b55780SDimitry Andric bool MadeChanges = false;
242e3b55780SDimitry Andric for (Instruction &Inst : make_early_inc_range(BB)) {
243e3b55780SDimitry Andric if (Inst.getType()->isVoidTy())
244e3b55780SDimitry Andric continue;
245e3b55780SDimitry Andric if (tryToReplaceWithConstant(&Inst)) {
246e3b55780SDimitry Andric if (canRemoveInstruction(&Inst))
247e3b55780SDimitry Andric Inst.eraseFromParent();
248e3b55780SDimitry Andric
249e3b55780SDimitry Andric MadeChanges = true;
250e3b55780SDimitry Andric ++InstRemovedStat;
251e3b55780SDimitry Andric } else if (replaceSignedInst(*this, InsertedValues, Inst)) {
252e3b55780SDimitry Andric MadeChanges = true;
253e3b55780SDimitry Andric ++InstReplacedStat;
2547fa27ce4SDimitry Andric } else if (refineInstruction(*this, InsertedValues, Inst)) {
2557fa27ce4SDimitry Andric MadeChanges = true;
256e3b55780SDimitry Andric }
257e3b55780SDimitry Andric }
258e3b55780SDimitry Andric return MadeChanges;
259e3b55780SDimitry Andric }
260e3b55780SDimitry Andric
removeNonFeasibleEdges(BasicBlock * BB,DomTreeUpdater & DTU,BasicBlock * & NewUnreachableBB) const261e3b55780SDimitry Andric bool SCCPSolver::removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
262e3b55780SDimitry Andric BasicBlock *&NewUnreachableBB) const {
263e3b55780SDimitry Andric SmallPtrSet<BasicBlock *, 8> FeasibleSuccessors;
264e3b55780SDimitry Andric bool HasNonFeasibleEdges = false;
265e3b55780SDimitry Andric for (BasicBlock *Succ : successors(BB)) {
266e3b55780SDimitry Andric if (isEdgeFeasible(BB, Succ))
267e3b55780SDimitry Andric FeasibleSuccessors.insert(Succ);
268e3b55780SDimitry Andric else
269e3b55780SDimitry Andric HasNonFeasibleEdges = true;
270e3b55780SDimitry Andric }
271e3b55780SDimitry Andric
272e3b55780SDimitry Andric // All edges feasible, nothing to do.
273e3b55780SDimitry Andric if (!HasNonFeasibleEdges)
274e3b55780SDimitry Andric return false;
275e3b55780SDimitry Andric
276e3b55780SDimitry Andric // SCCP can only determine non-feasible edges for br, switch and indirectbr.
277e3b55780SDimitry Andric Instruction *TI = BB->getTerminator();
278e3b55780SDimitry Andric assert((isa<BranchInst>(TI) || isa<SwitchInst>(TI) ||
279e3b55780SDimitry Andric isa<IndirectBrInst>(TI)) &&
280e3b55780SDimitry Andric "Terminator must be a br, switch or indirectbr");
281e3b55780SDimitry Andric
282e3b55780SDimitry Andric if (FeasibleSuccessors.size() == 0) {
283e3b55780SDimitry Andric // Branch on undef/poison, replace with unreachable.
284e3b55780SDimitry Andric SmallPtrSet<BasicBlock *, 8> SeenSuccs;
285e3b55780SDimitry Andric SmallVector<DominatorTree::UpdateType, 8> Updates;
286e3b55780SDimitry Andric for (BasicBlock *Succ : successors(BB)) {
287e3b55780SDimitry Andric Succ->removePredecessor(BB);
288e3b55780SDimitry Andric if (SeenSuccs.insert(Succ).second)
289e3b55780SDimitry Andric Updates.push_back({DominatorTree::Delete, BB, Succ});
290e3b55780SDimitry Andric }
291e3b55780SDimitry Andric TI->eraseFromParent();
292e3b55780SDimitry Andric new UnreachableInst(BB->getContext(), BB);
293e3b55780SDimitry Andric DTU.applyUpdatesPermissive(Updates);
294e3b55780SDimitry Andric } else if (FeasibleSuccessors.size() == 1) {
295e3b55780SDimitry Andric // Replace with an unconditional branch to the only feasible successor.
296e3b55780SDimitry Andric BasicBlock *OnlyFeasibleSuccessor = *FeasibleSuccessors.begin();
297e3b55780SDimitry Andric SmallVector<DominatorTree::UpdateType, 8> Updates;
298e3b55780SDimitry Andric bool HaveSeenOnlyFeasibleSuccessor = false;
299e3b55780SDimitry Andric for (BasicBlock *Succ : successors(BB)) {
300e3b55780SDimitry Andric if (Succ == OnlyFeasibleSuccessor && !HaveSeenOnlyFeasibleSuccessor) {
301e3b55780SDimitry Andric // Don't remove the edge to the only feasible successor the first time
302e3b55780SDimitry Andric // we see it. We still do need to remove any multi-edges to it though.
303e3b55780SDimitry Andric HaveSeenOnlyFeasibleSuccessor = true;
304e3b55780SDimitry Andric continue;
305e3b55780SDimitry Andric }
306e3b55780SDimitry Andric
307e3b55780SDimitry Andric Succ->removePredecessor(BB);
308e3b55780SDimitry Andric Updates.push_back({DominatorTree::Delete, BB, Succ});
309e3b55780SDimitry Andric }
310e3b55780SDimitry Andric
311ac9a064cSDimitry Andric Instruction *BI = BranchInst::Create(OnlyFeasibleSuccessor, BB);
312ac9a064cSDimitry Andric BI->setDebugLoc(TI->getDebugLoc());
313e3b55780SDimitry Andric TI->eraseFromParent();
314e3b55780SDimitry Andric DTU.applyUpdatesPermissive(Updates);
315e3b55780SDimitry Andric } else if (FeasibleSuccessors.size() > 1) {
316e3b55780SDimitry Andric SwitchInstProfUpdateWrapper SI(*cast<SwitchInst>(TI));
317e3b55780SDimitry Andric SmallVector<DominatorTree::UpdateType, 8> Updates;
318e3b55780SDimitry Andric
319e3b55780SDimitry Andric // If the default destination is unfeasible it will never be taken. Replace
320e3b55780SDimitry Andric // it with a new block with a single Unreachable instruction.
321e3b55780SDimitry Andric BasicBlock *DefaultDest = SI->getDefaultDest();
322e3b55780SDimitry Andric if (!FeasibleSuccessors.contains(DefaultDest)) {
323e3b55780SDimitry Andric if (!NewUnreachableBB) {
324e3b55780SDimitry Andric NewUnreachableBB =
325e3b55780SDimitry Andric BasicBlock::Create(DefaultDest->getContext(), "default.unreachable",
326e3b55780SDimitry Andric DefaultDest->getParent(), DefaultDest);
327e3b55780SDimitry Andric new UnreachableInst(DefaultDest->getContext(), NewUnreachableBB);
328e3b55780SDimitry Andric }
329e3b55780SDimitry Andric
330aca2e42cSDimitry Andric DefaultDest->removePredecessor(BB);
331e3b55780SDimitry Andric SI->setDefaultDest(NewUnreachableBB);
332e3b55780SDimitry Andric Updates.push_back({DominatorTree::Delete, BB, DefaultDest});
333e3b55780SDimitry Andric Updates.push_back({DominatorTree::Insert, BB, NewUnreachableBB});
334e3b55780SDimitry Andric }
335e3b55780SDimitry Andric
336e3b55780SDimitry Andric for (auto CI = SI->case_begin(); CI != SI->case_end();) {
337e3b55780SDimitry Andric if (FeasibleSuccessors.contains(CI->getCaseSuccessor())) {
338e3b55780SDimitry Andric ++CI;
339e3b55780SDimitry Andric continue;
340e3b55780SDimitry Andric }
341e3b55780SDimitry Andric
342e3b55780SDimitry Andric BasicBlock *Succ = CI->getCaseSuccessor();
343e3b55780SDimitry Andric Succ->removePredecessor(BB);
344e3b55780SDimitry Andric Updates.push_back({DominatorTree::Delete, BB, Succ});
345e3b55780SDimitry Andric SI.removeCase(CI);
346e3b55780SDimitry Andric // Don't increment CI, as we removed a case.
347e3b55780SDimitry Andric }
348e3b55780SDimitry Andric
349e3b55780SDimitry Andric DTU.applyUpdatesPermissive(Updates);
350e3b55780SDimitry Andric } else {
351e3b55780SDimitry Andric llvm_unreachable("Must have at least one feasible successor");
352e3b55780SDimitry Andric }
353e3b55780SDimitry Andric return true;
354e3b55780SDimitry Andric }
355344a3780SDimitry Andric
356344a3780SDimitry Andric /// Helper class for SCCPSolver. This implements the instruction visitor and
357344a3780SDimitry Andric /// holds all the state.
358344a3780SDimitry Andric class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
359344a3780SDimitry Andric const DataLayout &DL;
360344a3780SDimitry Andric std::function<const TargetLibraryInfo &(Function &)> GetTLI;
361344a3780SDimitry Andric SmallPtrSet<BasicBlock *, 8> BBExecutable; // The BBs that are executable.
362344a3780SDimitry Andric DenseMap<Value *, ValueLatticeElement>
363344a3780SDimitry Andric ValueState; // The state each value is in.
364344a3780SDimitry Andric
365344a3780SDimitry Andric /// StructValueState - This maintains ValueState for values that have
366344a3780SDimitry Andric /// StructType, for example for formal arguments, calls, insertelement, etc.
367344a3780SDimitry Andric DenseMap<std::pair<Value *, unsigned>, ValueLatticeElement> StructValueState;
368344a3780SDimitry Andric
369344a3780SDimitry Andric /// GlobalValue - If we are tracking any values for the contents of a global
370344a3780SDimitry Andric /// variable, we keep a mapping from the constant accessor to the element of
371344a3780SDimitry Andric /// the global, to the currently known value. If the value becomes
372344a3780SDimitry Andric /// overdefined, it's entry is simply removed from this map.
373344a3780SDimitry Andric DenseMap<GlobalVariable *, ValueLatticeElement> TrackedGlobals;
374344a3780SDimitry Andric
375344a3780SDimitry Andric /// TrackedRetVals - If we are tracking arguments into and the return
376344a3780SDimitry Andric /// value out of a function, it will have an entry in this map, indicating
377344a3780SDimitry Andric /// what the known return value for the function is.
378344a3780SDimitry Andric MapVector<Function *, ValueLatticeElement> TrackedRetVals;
379344a3780SDimitry Andric
380344a3780SDimitry Andric /// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
381344a3780SDimitry Andric /// that return multiple values.
382344a3780SDimitry Andric MapVector<std::pair<Function *, unsigned>, ValueLatticeElement>
383344a3780SDimitry Andric TrackedMultipleRetVals;
384344a3780SDimitry Andric
3857fa27ce4SDimitry Andric /// The set of values whose lattice has been invalidated.
3867fa27ce4SDimitry Andric /// Populated by resetLatticeValueFor(), cleared after resolving undefs.
3877fa27ce4SDimitry Andric DenseSet<Value *> Invalidated;
3887fa27ce4SDimitry Andric
389344a3780SDimitry Andric /// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is
390344a3780SDimitry Andric /// represented here for efficient lookup.
391344a3780SDimitry Andric SmallPtrSet<Function *, 16> MRVFunctionsTracked;
392344a3780SDimitry Andric
393344a3780SDimitry Andric /// A list of functions whose return cannot be modified.
394344a3780SDimitry Andric SmallPtrSet<Function *, 16> MustPreserveReturnsInFunctions;
395344a3780SDimitry Andric
396344a3780SDimitry Andric /// TrackingIncomingArguments - This is the set of functions for whose
397344a3780SDimitry Andric /// arguments we make optimistic assumptions about and try to prove as
398344a3780SDimitry Andric /// constants.
399344a3780SDimitry Andric SmallPtrSet<Function *, 16> TrackingIncomingArguments;
400344a3780SDimitry Andric
401344a3780SDimitry Andric /// The reason for two worklists is that overdefined is the lowest state
402344a3780SDimitry Andric /// on the lattice, and moving things to overdefined as fast as possible
403344a3780SDimitry Andric /// makes SCCP converge much faster.
404344a3780SDimitry Andric ///
405344a3780SDimitry Andric /// By having a separate worklist, we accomplish this because everything
406344a3780SDimitry Andric /// possibly overdefined will become overdefined at the soonest possible
407344a3780SDimitry Andric /// point.
408344a3780SDimitry Andric SmallVector<Value *, 64> OverdefinedInstWorkList;
409344a3780SDimitry Andric SmallVector<Value *, 64> InstWorkList;
410344a3780SDimitry Andric
411344a3780SDimitry Andric // The BasicBlock work list
412344a3780SDimitry Andric SmallVector<BasicBlock *, 64> BBWorkList;
413344a3780SDimitry Andric
414344a3780SDimitry Andric /// KnownFeasibleEdges - Entries in this set are edges which have already had
415344a3780SDimitry Andric /// PHI nodes retriggered.
416344a3780SDimitry Andric using Edge = std::pair<BasicBlock *, BasicBlock *>;
417344a3780SDimitry Andric DenseSet<Edge> KnownFeasibleEdges;
418344a3780SDimitry Andric
4197fa27ce4SDimitry Andric DenseMap<Function *, std::unique_ptr<PredicateInfo>> FnPredicateInfo;
4207fa27ce4SDimitry Andric
421344a3780SDimitry Andric DenseMap<Value *, SmallPtrSet<User *, 2>> AdditionalUsers;
422344a3780SDimitry Andric
423344a3780SDimitry Andric LLVMContext &Ctx;
424344a3780SDimitry Andric
425344a3780SDimitry Andric private:
getConstantInt(const ValueLatticeElement & IV,Type * Ty) const4267fa27ce4SDimitry Andric ConstantInt *getConstantInt(const ValueLatticeElement &IV, Type *Ty) const {
4277fa27ce4SDimitry Andric return dyn_cast_or_null<ConstantInt>(getConstant(IV, Ty));
428344a3780SDimitry Andric }
429344a3780SDimitry Andric
430344a3780SDimitry Andric // pushToWorkList - Helper for markConstant/markOverdefined
431344a3780SDimitry Andric void pushToWorkList(ValueLatticeElement &IV, Value *V);
432344a3780SDimitry Andric
433344a3780SDimitry Andric // Helper to push \p V to the worklist, after updating it to \p IV. Also
434344a3780SDimitry Andric // prints a debug message with the updated value.
435344a3780SDimitry Andric void pushToWorkListMsg(ValueLatticeElement &IV, Value *V);
436344a3780SDimitry Andric
437344a3780SDimitry Andric // markConstant - Make a value be marked as "constant". If the value
438344a3780SDimitry Andric // is not already a constant, add it to the instruction work list so that
439344a3780SDimitry Andric // the users of the instruction are updated later.
440344a3780SDimitry Andric bool markConstant(ValueLatticeElement &IV, Value *V, Constant *C,
441344a3780SDimitry Andric bool MayIncludeUndef = false);
442344a3780SDimitry Andric
markConstant(Value * V,Constant * C)443344a3780SDimitry Andric bool markConstant(Value *V, Constant *C) {
444344a3780SDimitry Andric assert(!V->getType()->isStructTy() && "structs should use mergeInValue");
445344a3780SDimitry Andric return markConstant(ValueState[V], V, C);
446344a3780SDimitry Andric }
447344a3780SDimitry Andric
448ac9a064cSDimitry Andric /// markConstantRange - Mark the object as constant range with \p CR. If the
449ac9a064cSDimitry Andric /// object is not a constant range with the range \p CR, add it to the
450ac9a064cSDimitry Andric /// instruction work list so that the users of the instruction are updated
451ac9a064cSDimitry Andric /// later.
452ac9a064cSDimitry Andric bool markConstantRange(ValueLatticeElement &IV, Value *V,
453ac9a064cSDimitry Andric const ConstantRange &CR);
454ac9a064cSDimitry Andric
455344a3780SDimitry Andric // markOverdefined - Make a value be marked as "overdefined". If the
456344a3780SDimitry Andric // value is not already overdefined, add it to the overdefined instruction
457344a3780SDimitry Andric // work list so that the users of the instruction are updated later.
458344a3780SDimitry Andric bool markOverdefined(ValueLatticeElement &IV, Value *V);
459344a3780SDimitry Andric
460344a3780SDimitry Andric /// Merge \p MergeWithV into \p IV and push \p V to the worklist, if \p IV
461344a3780SDimitry Andric /// changes.
462344a3780SDimitry Andric bool mergeInValue(ValueLatticeElement &IV, Value *V,
463344a3780SDimitry Andric ValueLatticeElement MergeWithV,
464344a3780SDimitry Andric ValueLatticeElement::MergeOptions Opts = {
465344a3780SDimitry Andric /*MayIncludeUndef=*/false, /*CheckWiden=*/false});
466344a3780SDimitry Andric
mergeInValue(Value * V,ValueLatticeElement MergeWithV,ValueLatticeElement::MergeOptions Opts={ false, false})467344a3780SDimitry Andric bool mergeInValue(Value *V, ValueLatticeElement MergeWithV,
468344a3780SDimitry Andric ValueLatticeElement::MergeOptions Opts = {
469344a3780SDimitry Andric /*MayIncludeUndef=*/false, /*CheckWiden=*/false}) {
470344a3780SDimitry Andric assert(!V->getType()->isStructTy() &&
471344a3780SDimitry Andric "non-structs should use markConstant");
472344a3780SDimitry Andric return mergeInValue(ValueState[V], V, MergeWithV, Opts);
473344a3780SDimitry Andric }
474344a3780SDimitry Andric
475344a3780SDimitry Andric /// getValueState - Return the ValueLatticeElement object that corresponds to
476344a3780SDimitry Andric /// the value. This function handles the case when the value hasn't been seen
477344a3780SDimitry Andric /// yet by properly seeding constants etc.
getValueState(Value * V)478344a3780SDimitry Andric ValueLatticeElement &getValueState(Value *V) {
479344a3780SDimitry Andric assert(!V->getType()->isStructTy() && "Should use getStructValueState");
480344a3780SDimitry Andric
481344a3780SDimitry Andric auto I = ValueState.insert(std::make_pair(V, ValueLatticeElement()));
482344a3780SDimitry Andric ValueLatticeElement &LV = I.first->second;
483344a3780SDimitry Andric
484344a3780SDimitry Andric if (!I.second)
485344a3780SDimitry Andric return LV; // Common case, already in the map.
486344a3780SDimitry Andric
487344a3780SDimitry Andric if (auto *C = dyn_cast<Constant>(V))
488344a3780SDimitry Andric LV.markConstant(C); // Constants are constant
489344a3780SDimitry Andric
490344a3780SDimitry Andric // All others are unknown by default.
491344a3780SDimitry Andric return LV;
492344a3780SDimitry Andric }
493344a3780SDimitry Andric
494344a3780SDimitry Andric /// getStructValueState - Return the ValueLatticeElement object that
495344a3780SDimitry Andric /// corresponds to the value/field pair. This function handles the case when
496344a3780SDimitry Andric /// the value hasn't been seen yet by properly seeding constants etc.
getStructValueState(Value * V,unsigned i)497344a3780SDimitry Andric ValueLatticeElement &getStructValueState(Value *V, unsigned i) {
498344a3780SDimitry Andric assert(V->getType()->isStructTy() && "Should use getValueState");
499344a3780SDimitry Andric assert(i < cast<StructType>(V->getType())->getNumElements() &&
500344a3780SDimitry Andric "Invalid element #");
501344a3780SDimitry Andric
502344a3780SDimitry Andric auto I = StructValueState.insert(
503344a3780SDimitry Andric std::make_pair(std::make_pair(V, i), ValueLatticeElement()));
504344a3780SDimitry Andric ValueLatticeElement &LV = I.first->second;
505344a3780SDimitry Andric
506344a3780SDimitry Andric if (!I.second)
507344a3780SDimitry Andric return LV; // Common case, already in the map.
508344a3780SDimitry Andric
509344a3780SDimitry Andric if (auto *C = dyn_cast<Constant>(V)) {
510344a3780SDimitry Andric Constant *Elt = C->getAggregateElement(i);
511344a3780SDimitry Andric
512344a3780SDimitry Andric if (!Elt)
513344a3780SDimitry Andric LV.markOverdefined(); // Unknown sort of constant.
514344a3780SDimitry Andric else
515344a3780SDimitry Andric LV.markConstant(Elt); // Constants are constant.
516344a3780SDimitry Andric }
517344a3780SDimitry Andric
518344a3780SDimitry Andric // All others are underdefined by default.
519344a3780SDimitry Andric return LV;
520344a3780SDimitry Andric }
521344a3780SDimitry Andric
5227fa27ce4SDimitry Andric /// Traverse the use-def chain of \p Call, marking itself and its users as
5237fa27ce4SDimitry Andric /// "unknown" on the way.
invalidate(CallBase * Call)5247fa27ce4SDimitry Andric void invalidate(CallBase *Call) {
5257fa27ce4SDimitry Andric SmallVector<Instruction *, 64> ToInvalidate;
5267fa27ce4SDimitry Andric ToInvalidate.push_back(Call);
5277fa27ce4SDimitry Andric
5287fa27ce4SDimitry Andric while (!ToInvalidate.empty()) {
5297fa27ce4SDimitry Andric Instruction *Inst = ToInvalidate.pop_back_val();
5307fa27ce4SDimitry Andric
5317fa27ce4SDimitry Andric if (!Invalidated.insert(Inst).second)
5327fa27ce4SDimitry Andric continue;
5337fa27ce4SDimitry Andric
5347fa27ce4SDimitry Andric if (!BBExecutable.count(Inst->getParent()))
5357fa27ce4SDimitry Andric continue;
5367fa27ce4SDimitry Andric
5377fa27ce4SDimitry Andric Value *V = nullptr;
5387fa27ce4SDimitry Andric // For return instructions we need to invalidate the tracked returns map.
5397fa27ce4SDimitry Andric // Anything else has its lattice in the value map.
5407fa27ce4SDimitry Andric if (auto *RetInst = dyn_cast<ReturnInst>(Inst)) {
5417fa27ce4SDimitry Andric Function *F = RetInst->getParent()->getParent();
5427fa27ce4SDimitry Andric if (auto It = TrackedRetVals.find(F); It != TrackedRetVals.end()) {
5437fa27ce4SDimitry Andric It->second = ValueLatticeElement();
5447fa27ce4SDimitry Andric V = F;
5457fa27ce4SDimitry Andric } else if (MRVFunctionsTracked.count(F)) {
5467fa27ce4SDimitry Andric auto *STy = cast<StructType>(F->getReturnType());
5477fa27ce4SDimitry Andric for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I)
5487fa27ce4SDimitry Andric TrackedMultipleRetVals[{F, I}] = ValueLatticeElement();
5497fa27ce4SDimitry Andric V = F;
5507fa27ce4SDimitry Andric }
5517fa27ce4SDimitry Andric } else if (auto *STy = dyn_cast<StructType>(Inst->getType())) {
5527fa27ce4SDimitry Andric for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
5537fa27ce4SDimitry Andric if (auto It = StructValueState.find({Inst, I});
5547fa27ce4SDimitry Andric It != StructValueState.end()) {
5557fa27ce4SDimitry Andric It->second = ValueLatticeElement();
5567fa27ce4SDimitry Andric V = Inst;
5577fa27ce4SDimitry Andric }
5587fa27ce4SDimitry Andric }
5597fa27ce4SDimitry Andric } else if (auto It = ValueState.find(Inst); It != ValueState.end()) {
5607fa27ce4SDimitry Andric It->second = ValueLatticeElement();
5617fa27ce4SDimitry Andric V = Inst;
5627fa27ce4SDimitry Andric }
5637fa27ce4SDimitry Andric
5647fa27ce4SDimitry Andric if (V) {
5657fa27ce4SDimitry Andric LLVM_DEBUG(dbgs() << "Invalidated lattice for " << *V << "\n");
5667fa27ce4SDimitry Andric
5677fa27ce4SDimitry Andric for (User *U : V->users())
5687fa27ce4SDimitry Andric if (auto *UI = dyn_cast<Instruction>(U))
5697fa27ce4SDimitry Andric ToInvalidate.push_back(UI);
5707fa27ce4SDimitry Andric
5717fa27ce4SDimitry Andric auto It = AdditionalUsers.find(V);
5727fa27ce4SDimitry Andric if (It != AdditionalUsers.end())
5737fa27ce4SDimitry Andric for (User *U : It->second)
5747fa27ce4SDimitry Andric if (auto *UI = dyn_cast<Instruction>(U))
5757fa27ce4SDimitry Andric ToInvalidate.push_back(UI);
5767fa27ce4SDimitry Andric }
5777fa27ce4SDimitry Andric }
5787fa27ce4SDimitry Andric }
5797fa27ce4SDimitry Andric
580344a3780SDimitry Andric /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
581344a3780SDimitry Andric /// work list if it is not already executable.
582344a3780SDimitry Andric bool markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
583344a3780SDimitry Andric
584344a3780SDimitry Andric // getFeasibleSuccessors - Return a vector of booleans to indicate which
585344a3780SDimitry Andric // successors are reachable from a given terminator instruction.
586344a3780SDimitry Andric void getFeasibleSuccessors(Instruction &TI, SmallVectorImpl<bool> &Succs);
587344a3780SDimitry Andric
588344a3780SDimitry Andric // OperandChangedState - This method is invoked on all of the users of an
589344a3780SDimitry Andric // instruction that was just changed state somehow. Based on this
590344a3780SDimitry Andric // information, we need to update the specified user of this instruction.
operandChangedState(Instruction * I)591344a3780SDimitry Andric void operandChangedState(Instruction *I) {
592344a3780SDimitry Andric if (BBExecutable.count(I->getParent())) // Inst is executable?
593344a3780SDimitry Andric visit(*I);
594344a3780SDimitry Andric }
595344a3780SDimitry Andric
596344a3780SDimitry Andric // Add U as additional user of V.
addAdditionalUser(Value * V,User * U)597344a3780SDimitry Andric void addAdditionalUser(Value *V, User *U) {
598344a3780SDimitry Andric auto Iter = AdditionalUsers.insert({V, {}});
599344a3780SDimitry Andric Iter.first->second.insert(U);
600344a3780SDimitry Andric }
601344a3780SDimitry Andric
602344a3780SDimitry Andric // Mark I's users as changed, including AdditionalUsers.
markUsersAsChanged(Value * I)603344a3780SDimitry Andric void markUsersAsChanged(Value *I) {
604344a3780SDimitry Andric // Functions include their arguments in the use-list. Changed function
605344a3780SDimitry Andric // values mean that the result of the function changed. We only need to
606344a3780SDimitry Andric // update the call sites with the new function result and do not have to
607344a3780SDimitry Andric // propagate the call arguments.
608344a3780SDimitry Andric if (isa<Function>(I)) {
609344a3780SDimitry Andric for (User *U : I->users()) {
610344a3780SDimitry Andric if (auto *CB = dyn_cast<CallBase>(U))
611344a3780SDimitry Andric handleCallResult(*CB);
612344a3780SDimitry Andric }
613344a3780SDimitry Andric } else {
614344a3780SDimitry Andric for (User *U : I->users())
615344a3780SDimitry Andric if (auto *UI = dyn_cast<Instruction>(U))
616344a3780SDimitry Andric operandChangedState(UI);
617344a3780SDimitry Andric }
618344a3780SDimitry Andric
619344a3780SDimitry Andric auto Iter = AdditionalUsers.find(I);
620344a3780SDimitry Andric if (Iter != AdditionalUsers.end()) {
621344a3780SDimitry Andric // Copy additional users before notifying them of changes, because new
622344a3780SDimitry Andric // users may be added, potentially invalidating the iterator.
623344a3780SDimitry Andric SmallVector<Instruction *, 2> ToNotify;
624344a3780SDimitry Andric for (User *U : Iter->second)
625344a3780SDimitry Andric if (auto *UI = dyn_cast<Instruction>(U))
626344a3780SDimitry Andric ToNotify.push_back(UI);
627344a3780SDimitry Andric for (Instruction *UI : ToNotify)
628344a3780SDimitry Andric operandChangedState(UI);
629344a3780SDimitry Andric }
630344a3780SDimitry Andric }
631344a3780SDimitry Andric void handleCallOverdefined(CallBase &CB);
632344a3780SDimitry Andric void handleCallResult(CallBase &CB);
633344a3780SDimitry Andric void handleCallArguments(CallBase &CB);
634e3b55780SDimitry Andric void handleExtractOfWithOverflow(ExtractValueInst &EVI,
635e3b55780SDimitry Andric const WithOverflowInst *WO, unsigned Idx);
636344a3780SDimitry Andric
637344a3780SDimitry Andric private:
638344a3780SDimitry Andric friend class InstVisitor<SCCPInstVisitor>;
639344a3780SDimitry Andric
640344a3780SDimitry Andric // visit implementations - Something changed in this instruction. Either an
641344a3780SDimitry Andric // operand made a transition, or the instruction is newly executable. Change
642344a3780SDimitry Andric // the value type of I to reflect these changes if appropriate.
643344a3780SDimitry Andric void visitPHINode(PHINode &I);
644344a3780SDimitry Andric
645344a3780SDimitry Andric // Terminators
646344a3780SDimitry Andric
647344a3780SDimitry Andric void visitReturnInst(ReturnInst &I);
648344a3780SDimitry Andric void visitTerminator(Instruction &TI);
649344a3780SDimitry Andric
650344a3780SDimitry Andric void visitCastInst(CastInst &I);
651344a3780SDimitry Andric void visitSelectInst(SelectInst &I);
652344a3780SDimitry Andric void visitUnaryOperator(Instruction &I);
6537fa27ce4SDimitry Andric void visitFreezeInst(FreezeInst &I);
654344a3780SDimitry Andric void visitBinaryOperator(Instruction &I);
655344a3780SDimitry Andric void visitCmpInst(CmpInst &I);
656344a3780SDimitry Andric void visitExtractValueInst(ExtractValueInst &EVI);
657344a3780SDimitry Andric void visitInsertValueInst(InsertValueInst &IVI);
658344a3780SDimitry Andric
visitCatchSwitchInst(CatchSwitchInst & CPI)659344a3780SDimitry Andric void visitCatchSwitchInst(CatchSwitchInst &CPI) {
660344a3780SDimitry Andric markOverdefined(&CPI);
661344a3780SDimitry Andric visitTerminator(CPI);
662344a3780SDimitry Andric }
663344a3780SDimitry Andric
664344a3780SDimitry Andric // Instructions that cannot be folded away.
665344a3780SDimitry Andric
666344a3780SDimitry Andric void visitStoreInst(StoreInst &I);
667344a3780SDimitry Andric void visitLoadInst(LoadInst &I);
668344a3780SDimitry Andric void visitGetElementPtrInst(GetElementPtrInst &I);
669344a3780SDimitry Andric
visitInvokeInst(InvokeInst & II)670344a3780SDimitry Andric void visitInvokeInst(InvokeInst &II) {
671344a3780SDimitry Andric visitCallBase(II);
672344a3780SDimitry Andric visitTerminator(II);
673344a3780SDimitry Andric }
674344a3780SDimitry Andric
visitCallBrInst(CallBrInst & CBI)675344a3780SDimitry Andric void visitCallBrInst(CallBrInst &CBI) {
676344a3780SDimitry Andric visitCallBase(CBI);
677344a3780SDimitry Andric visitTerminator(CBI);
678344a3780SDimitry Andric }
679344a3780SDimitry Andric
680344a3780SDimitry Andric void visitCallBase(CallBase &CB);
visitResumeInst(ResumeInst & I)681344a3780SDimitry Andric void visitResumeInst(ResumeInst &I) { /*returns void*/
682344a3780SDimitry Andric }
visitUnreachableInst(UnreachableInst & I)683344a3780SDimitry Andric void visitUnreachableInst(UnreachableInst &I) { /*returns void*/
684344a3780SDimitry Andric }
visitFenceInst(FenceInst & I)685344a3780SDimitry Andric void visitFenceInst(FenceInst &I) { /*returns void*/
686344a3780SDimitry Andric }
687344a3780SDimitry Andric
688344a3780SDimitry Andric void visitInstruction(Instruction &I);
689344a3780SDimitry Andric
690344a3780SDimitry Andric public:
addPredicateInfo(Function & F,DominatorTree & DT,AssumptionCache & AC)6917fa27ce4SDimitry Andric void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC) {
6927fa27ce4SDimitry Andric FnPredicateInfo.insert({&F, std::make_unique<PredicateInfo>(F, DT, AC)});
693344a3780SDimitry Andric }
694344a3780SDimitry Andric
visitCallInst(CallInst & I)695344a3780SDimitry Andric void visitCallInst(CallInst &I) { visitCallBase(I); }
696344a3780SDimitry Andric
697344a3780SDimitry Andric bool markBlockExecutable(BasicBlock *BB);
698344a3780SDimitry Andric
getPredicateInfoFor(Instruction * I)699344a3780SDimitry Andric const PredicateBase *getPredicateInfoFor(Instruction *I) {
7007fa27ce4SDimitry Andric auto It = FnPredicateInfo.find(I->getParent()->getParent());
7017fa27ce4SDimitry Andric if (It == FnPredicateInfo.end())
702344a3780SDimitry Andric return nullptr;
7037fa27ce4SDimitry Andric return It->second->getPredicateInfoFor(I);
704344a3780SDimitry Andric }
705344a3780SDimitry Andric
SCCPInstVisitor(const DataLayout & DL,std::function<const TargetLibraryInfo & (Function &)> GetTLI,LLVMContext & Ctx)706344a3780SDimitry Andric SCCPInstVisitor(const DataLayout &DL,
707344a3780SDimitry Andric std::function<const TargetLibraryInfo &(Function &)> GetTLI,
708344a3780SDimitry Andric LLVMContext &Ctx)
709344a3780SDimitry Andric : DL(DL), GetTLI(GetTLI), Ctx(Ctx) {}
710344a3780SDimitry Andric
trackValueOfGlobalVariable(GlobalVariable * GV)711344a3780SDimitry Andric void trackValueOfGlobalVariable(GlobalVariable *GV) {
712344a3780SDimitry Andric // We only track the contents of scalar globals.
713344a3780SDimitry Andric if (GV->getValueType()->isSingleValueType()) {
714344a3780SDimitry Andric ValueLatticeElement &IV = TrackedGlobals[GV];
715344a3780SDimitry Andric IV.markConstant(GV->getInitializer());
716344a3780SDimitry Andric }
717344a3780SDimitry Andric }
718344a3780SDimitry Andric
addTrackedFunction(Function * F)719344a3780SDimitry Andric void addTrackedFunction(Function *F) {
720344a3780SDimitry Andric // Add an entry, F -> undef.
721344a3780SDimitry Andric if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
722344a3780SDimitry Andric MRVFunctionsTracked.insert(F);
723344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
724344a3780SDimitry Andric TrackedMultipleRetVals.insert(
725344a3780SDimitry Andric std::make_pair(std::make_pair(F, i), ValueLatticeElement()));
726344a3780SDimitry Andric } else if (!F->getReturnType()->isVoidTy())
727344a3780SDimitry Andric TrackedRetVals.insert(std::make_pair(F, ValueLatticeElement()));
728344a3780SDimitry Andric }
729344a3780SDimitry Andric
addToMustPreserveReturnsInFunctions(Function * F)730344a3780SDimitry Andric void addToMustPreserveReturnsInFunctions(Function *F) {
731344a3780SDimitry Andric MustPreserveReturnsInFunctions.insert(F);
732344a3780SDimitry Andric }
733344a3780SDimitry Andric
mustPreserveReturn(Function * F)734344a3780SDimitry Andric bool mustPreserveReturn(Function *F) {
735344a3780SDimitry Andric return MustPreserveReturnsInFunctions.count(F);
736344a3780SDimitry Andric }
737344a3780SDimitry Andric
addArgumentTrackedFunction(Function * F)738344a3780SDimitry Andric void addArgumentTrackedFunction(Function *F) {
739344a3780SDimitry Andric TrackingIncomingArguments.insert(F);
740344a3780SDimitry Andric }
741344a3780SDimitry Andric
isArgumentTrackedFunction(Function * F)742344a3780SDimitry Andric bool isArgumentTrackedFunction(Function *F) {
743344a3780SDimitry Andric return TrackingIncomingArguments.count(F);
744344a3780SDimitry Andric }
745344a3780SDimitry Andric
746344a3780SDimitry Andric void solve();
747344a3780SDimitry Andric
7487fa27ce4SDimitry Andric bool resolvedUndef(Instruction &I);
7497fa27ce4SDimitry Andric
750344a3780SDimitry Andric bool resolvedUndefsIn(Function &F);
751344a3780SDimitry Andric
isBlockExecutable(BasicBlock * BB) const752344a3780SDimitry Andric bool isBlockExecutable(BasicBlock *BB) const {
753344a3780SDimitry Andric return BBExecutable.count(BB);
754344a3780SDimitry Andric }
755344a3780SDimitry Andric
756344a3780SDimitry Andric bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
757344a3780SDimitry Andric
getStructLatticeValueFor(Value * V) const758344a3780SDimitry Andric std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const {
759344a3780SDimitry Andric std::vector<ValueLatticeElement> StructValues;
760344a3780SDimitry Andric auto *STy = dyn_cast<StructType>(V->getType());
761344a3780SDimitry Andric assert(STy && "getStructLatticeValueFor() can be called only on structs");
762344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
763344a3780SDimitry Andric auto I = StructValueState.find(std::make_pair(V, i));
764344a3780SDimitry Andric assert(I != StructValueState.end() && "Value not in valuemap!");
765344a3780SDimitry Andric StructValues.push_back(I->second);
766344a3780SDimitry Andric }
767344a3780SDimitry Andric return StructValues;
768344a3780SDimitry Andric }
769344a3780SDimitry Andric
removeLatticeValueFor(Value * V)770344a3780SDimitry Andric void removeLatticeValueFor(Value *V) { ValueState.erase(V); }
771344a3780SDimitry Andric
7727fa27ce4SDimitry Andric /// Invalidate the Lattice Value of \p Call and its users after specializing
7737fa27ce4SDimitry Andric /// the call. Then recompute it.
resetLatticeValueFor(CallBase * Call)7747fa27ce4SDimitry Andric void resetLatticeValueFor(CallBase *Call) {
7757fa27ce4SDimitry Andric // Calls to void returning functions do not need invalidation.
7767fa27ce4SDimitry Andric Function *F = Call->getCalledFunction();
7777fa27ce4SDimitry Andric (void)F;
7787fa27ce4SDimitry Andric assert(!F->getReturnType()->isVoidTy() &&
7797fa27ce4SDimitry Andric (TrackedRetVals.count(F) || MRVFunctionsTracked.count(F)) &&
7807fa27ce4SDimitry Andric "All non void specializations should be tracked");
7817fa27ce4SDimitry Andric invalidate(Call);
7827fa27ce4SDimitry Andric handleCallResult(*Call);
7837fa27ce4SDimitry Andric }
7847fa27ce4SDimitry Andric
getLatticeValueFor(Value * V) const785344a3780SDimitry Andric const ValueLatticeElement &getLatticeValueFor(Value *V) const {
786344a3780SDimitry Andric assert(!V->getType()->isStructTy() &&
787344a3780SDimitry Andric "Should use getStructLatticeValueFor");
788344a3780SDimitry Andric DenseMap<Value *, ValueLatticeElement>::const_iterator I =
789344a3780SDimitry Andric ValueState.find(V);
790344a3780SDimitry Andric assert(I != ValueState.end() &&
791344a3780SDimitry Andric "V not found in ValueState nor Paramstate map!");
792344a3780SDimitry Andric return I->second;
793344a3780SDimitry Andric }
794344a3780SDimitry Andric
getTrackedRetVals()795344a3780SDimitry Andric const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() {
796344a3780SDimitry Andric return TrackedRetVals;
797344a3780SDimitry Andric }
798344a3780SDimitry Andric
getTrackedGlobals()799344a3780SDimitry Andric const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals() {
800344a3780SDimitry Andric return TrackedGlobals;
801344a3780SDimitry Andric }
802344a3780SDimitry Andric
getMRVFunctionsTracked()803344a3780SDimitry Andric const SmallPtrSet<Function *, 16> getMRVFunctionsTracked() {
804344a3780SDimitry Andric return MRVFunctionsTracked;
805344a3780SDimitry Andric }
806344a3780SDimitry Andric
markOverdefined(Value * V)807344a3780SDimitry Andric void markOverdefined(Value *V) {
808344a3780SDimitry Andric if (auto *STy = dyn_cast<StructType>(V->getType()))
809344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
810344a3780SDimitry Andric markOverdefined(getStructValueState(V, i), V);
811344a3780SDimitry Andric else
812344a3780SDimitry Andric markOverdefined(ValueState[V], V);
813344a3780SDimitry Andric }
814344a3780SDimitry Andric
trackValueOfArgument(Argument * A)815ac9a064cSDimitry Andric void trackValueOfArgument(Argument *A) {
816ac9a064cSDimitry Andric if (A->getType()->isIntOrIntVectorTy()) {
817ac9a064cSDimitry Andric if (std::optional<ConstantRange> Range = A->getRange()) {
818ac9a064cSDimitry Andric markConstantRange(ValueState[A], A, *Range);
819ac9a064cSDimitry Andric return;
820ac9a064cSDimitry Andric }
821ac9a064cSDimitry Andric }
822ac9a064cSDimitry Andric // Assume nothing about the incoming arguments without range.
823ac9a064cSDimitry Andric markOverdefined(A);
824ac9a064cSDimitry Andric }
825ac9a064cSDimitry Andric
826344a3780SDimitry Andric bool isStructLatticeConstant(Function *F, StructType *STy);
827344a3780SDimitry Andric
8287fa27ce4SDimitry Andric Constant *getConstant(const ValueLatticeElement &LV, Type *Ty) const;
8297fa27ce4SDimitry Andric
8307fa27ce4SDimitry Andric Constant *getConstantOrNull(Value *V) const;
831344a3780SDimitry Andric
getArgumentTrackedFunctions()832344a3780SDimitry Andric SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() {
833344a3780SDimitry Andric return TrackingIncomingArguments;
834344a3780SDimitry Andric }
835344a3780SDimitry Andric
8367fa27ce4SDimitry Andric void setLatticeValueForSpecializationArguments(Function *F,
837145449b1SDimitry Andric const SmallVectorImpl<ArgInfo> &Args);
838344a3780SDimitry Andric
markFunctionUnreachable(Function * F)839344a3780SDimitry Andric void markFunctionUnreachable(Function *F) {
840344a3780SDimitry Andric for (auto &BB : *F)
841344a3780SDimitry Andric BBExecutable.erase(&BB);
842344a3780SDimitry Andric }
843e3b55780SDimitry Andric
solveWhileResolvedUndefsIn(Module & M)844e3b55780SDimitry Andric void solveWhileResolvedUndefsIn(Module &M) {
845e3b55780SDimitry Andric bool ResolvedUndefs = true;
846e3b55780SDimitry Andric while (ResolvedUndefs) {
847e3b55780SDimitry Andric solve();
848e3b55780SDimitry Andric ResolvedUndefs = false;
849e3b55780SDimitry Andric for (Function &F : M)
850e3b55780SDimitry Andric ResolvedUndefs |= resolvedUndefsIn(F);
851e3b55780SDimitry Andric }
852e3b55780SDimitry Andric }
853e3b55780SDimitry Andric
solveWhileResolvedUndefsIn(SmallVectorImpl<Function * > & WorkList)854e3b55780SDimitry Andric void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
855e3b55780SDimitry Andric bool ResolvedUndefs = true;
856e3b55780SDimitry Andric while (ResolvedUndefs) {
857e3b55780SDimitry Andric solve();
858e3b55780SDimitry Andric ResolvedUndefs = false;
859e3b55780SDimitry Andric for (Function *F : WorkList)
860e3b55780SDimitry Andric ResolvedUndefs |= resolvedUndefsIn(*F);
861e3b55780SDimitry Andric }
862e3b55780SDimitry Andric }
8637fa27ce4SDimitry Andric
solveWhileResolvedUndefs()8647fa27ce4SDimitry Andric void solveWhileResolvedUndefs() {
8657fa27ce4SDimitry Andric bool ResolvedUndefs = true;
8667fa27ce4SDimitry Andric while (ResolvedUndefs) {
8677fa27ce4SDimitry Andric solve();
8687fa27ce4SDimitry Andric ResolvedUndefs = false;
8697fa27ce4SDimitry Andric for (Value *V : Invalidated)
8707fa27ce4SDimitry Andric if (auto *I = dyn_cast<Instruction>(V))
8717fa27ce4SDimitry Andric ResolvedUndefs |= resolvedUndef(*I);
8727fa27ce4SDimitry Andric }
8737fa27ce4SDimitry Andric Invalidated.clear();
8747fa27ce4SDimitry Andric }
875344a3780SDimitry Andric };
876344a3780SDimitry Andric
877344a3780SDimitry Andric } // namespace llvm
878344a3780SDimitry Andric
markBlockExecutable(BasicBlock * BB)879344a3780SDimitry Andric bool SCCPInstVisitor::markBlockExecutable(BasicBlock *BB) {
880344a3780SDimitry Andric if (!BBExecutable.insert(BB).second)
881344a3780SDimitry Andric return false;
882344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << '\n');
883344a3780SDimitry Andric BBWorkList.push_back(BB); // Add the block to the work list!
884344a3780SDimitry Andric return true;
885344a3780SDimitry Andric }
886344a3780SDimitry Andric
pushToWorkList(ValueLatticeElement & IV,Value * V)887344a3780SDimitry Andric void SCCPInstVisitor::pushToWorkList(ValueLatticeElement &IV, Value *V) {
8887fa27ce4SDimitry Andric if (IV.isOverdefined()) {
8897fa27ce4SDimitry Andric if (OverdefinedInstWorkList.empty() || OverdefinedInstWorkList.back() != V)
8907fa27ce4SDimitry Andric OverdefinedInstWorkList.push_back(V);
8917fa27ce4SDimitry Andric return;
8927fa27ce4SDimitry Andric }
8937fa27ce4SDimitry Andric if (InstWorkList.empty() || InstWorkList.back() != V)
894344a3780SDimitry Andric InstWorkList.push_back(V);
895344a3780SDimitry Andric }
896344a3780SDimitry Andric
pushToWorkListMsg(ValueLatticeElement & IV,Value * V)897344a3780SDimitry Andric void SCCPInstVisitor::pushToWorkListMsg(ValueLatticeElement &IV, Value *V) {
898344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n');
899344a3780SDimitry Andric pushToWorkList(IV, V);
900344a3780SDimitry Andric }
901344a3780SDimitry Andric
markConstant(ValueLatticeElement & IV,Value * V,Constant * C,bool MayIncludeUndef)902344a3780SDimitry Andric bool SCCPInstVisitor::markConstant(ValueLatticeElement &IV, Value *V,
903344a3780SDimitry Andric Constant *C, bool MayIncludeUndef) {
904344a3780SDimitry Andric if (!IV.markConstant(C, MayIncludeUndef))
905344a3780SDimitry Andric return false;
906344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "markConstant: " << *C << ": " << *V << '\n');
907344a3780SDimitry Andric pushToWorkList(IV, V);
908344a3780SDimitry Andric return true;
909344a3780SDimitry Andric }
910344a3780SDimitry Andric
markConstantRange(ValueLatticeElement & IV,Value * V,const ConstantRange & CR)911ac9a064cSDimitry Andric bool SCCPInstVisitor::markConstantRange(ValueLatticeElement &IV, Value *V,
912ac9a064cSDimitry Andric const ConstantRange &CR) {
913ac9a064cSDimitry Andric if (!IV.markConstantRange(CR))
914ac9a064cSDimitry Andric return false;
915ac9a064cSDimitry Andric LLVM_DEBUG(dbgs() << "markConstantRange: " << CR << ": " << *V << '\n');
916ac9a064cSDimitry Andric pushToWorkList(IV, V);
917ac9a064cSDimitry Andric return true;
918ac9a064cSDimitry Andric }
919ac9a064cSDimitry Andric
markOverdefined(ValueLatticeElement & IV,Value * V)920344a3780SDimitry Andric bool SCCPInstVisitor::markOverdefined(ValueLatticeElement &IV, Value *V) {
921344a3780SDimitry Andric if (!IV.markOverdefined())
922344a3780SDimitry Andric return false;
923344a3780SDimitry Andric
924344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "markOverdefined: ";
925344a3780SDimitry Andric if (auto *F = dyn_cast<Function>(V)) dbgs()
926344a3780SDimitry Andric << "Function '" << F->getName() << "'\n";
927344a3780SDimitry Andric else dbgs() << *V << '\n');
928344a3780SDimitry Andric // Only instructions go on the work list
929344a3780SDimitry Andric pushToWorkList(IV, V);
930344a3780SDimitry Andric return true;
931344a3780SDimitry Andric }
932344a3780SDimitry Andric
isStructLatticeConstant(Function * F,StructType * STy)933344a3780SDimitry Andric bool SCCPInstVisitor::isStructLatticeConstant(Function *F, StructType *STy) {
934344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
935344a3780SDimitry Andric const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
936344a3780SDimitry Andric assert(It != TrackedMultipleRetVals.end());
937344a3780SDimitry Andric ValueLatticeElement LV = It->second;
938e3b55780SDimitry Andric if (!SCCPSolver::isConstant(LV))
939344a3780SDimitry Andric return false;
940344a3780SDimitry Andric }
941344a3780SDimitry Andric return true;
942344a3780SDimitry Andric }
943344a3780SDimitry Andric
getConstant(const ValueLatticeElement & LV,Type * Ty) const9447fa27ce4SDimitry Andric Constant *SCCPInstVisitor::getConstant(const ValueLatticeElement &LV,
9457fa27ce4SDimitry Andric Type *Ty) const {
9467fa27ce4SDimitry Andric if (LV.isConstant()) {
9477fa27ce4SDimitry Andric Constant *C = LV.getConstant();
9487fa27ce4SDimitry Andric assert(C->getType() == Ty && "Type mismatch");
9497fa27ce4SDimitry Andric return C;
9507fa27ce4SDimitry Andric }
951344a3780SDimitry Andric
952344a3780SDimitry Andric if (LV.isConstantRange()) {
953344a3780SDimitry Andric const auto &CR = LV.getConstantRange();
954344a3780SDimitry Andric if (CR.getSingleElement())
9557fa27ce4SDimitry Andric return ConstantInt::get(Ty, *CR.getSingleElement());
956344a3780SDimitry Andric }
957344a3780SDimitry Andric return nullptr;
958344a3780SDimitry Andric }
959344a3780SDimitry Andric
getConstantOrNull(Value * V) const9607fa27ce4SDimitry Andric Constant *SCCPInstVisitor::getConstantOrNull(Value *V) const {
9617fa27ce4SDimitry Andric Constant *Const = nullptr;
9627fa27ce4SDimitry Andric if (V->getType()->isStructTy()) {
9637fa27ce4SDimitry Andric std::vector<ValueLatticeElement> LVs = getStructLatticeValueFor(V);
9647fa27ce4SDimitry Andric if (any_of(LVs, SCCPSolver::isOverdefined))
9657fa27ce4SDimitry Andric return nullptr;
9667fa27ce4SDimitry Andric std::vector<Constant *> ConstVals;
9677fa27ce4SDimitry Andric auto *ST = cast<StructType>(V->getType());
9687fa27ce4SDimitry Andric for (unsigned I = 0, E = ST->getNumElements(); I != E; ++I) {
9697fa27ce4SDimitry Andric ValueLatticeElement LV = LVs[I];
9707fa27ce4SDimitry Andric ConstVals.push_back(SCCPSolver::isConstant(LV)
9717fa27ce4SDimitry Andric ? getConstant(LV, ST->getElementType(I))
9727fa27ce4SDimitry Andric : UndefValue::get(ST->getElementType(I)));
9737fa27ce4SDimitry Andric }
9747fa27ce4SDimitry Andric Const = ConstantStruct::get(ST, ConstVals);
9757fa27ce4SDimitry Andric } else {
9767fa27ce4SDimitry Andric const ValueLatticeElement &LV = getLatticeValueFor(V);
9777fa27ce4SDimitry Andric if (SCCPSolver::isOverdefined(LV))
9787fa27ce4SDimitry Andric return nullptr;
9797fa27ce4SDimitry Andric Const = SCCPSolver::isConstant(LV) ? getConstant(LV, V->getType())
9807fa27ce4SDimitry Andric : UndefValue::get(V->getType());
9817fa27ce4SDimitry Andric }
9827fa27ce4SDimitry Andric assert(Const && "Constant is nullptr here!");
9837fa27ce4SDimitry Andric return Const;
984e3b55780SDimitry Andric }
985e3b55780SDimitry Andric
setLatticeValueForSpecializationArguments(Function * F,const SmallVectorImpl<ArgInfo> & Args)9867fa27ce4SDimitry Andric void SCCPInstVisitor::setLatticeValueForSpecializationArguments(Function *F,
9877fa27ce4SDimitry Andric const SmallVectorImpl<ArgInfo> &Args) {
988145449b1SDimitry Andric assert(!Args.empty() && "Specialization without arguments");
989145449b1SDimitry Andric assert(F->arg_size() == Args[0].Formal->getParent()->arg_size() &&
990344a3780SDimitry Andric "Functions should have the same number of arguments");
991344a3780SDimitry Andric
992145449b1SDimitry Andric auto Iter = Args.begin();
9937fa27ce4SDimitry Andric Function::arg_iterator NewArg = F->arg_begin();
9947fa27ce4SDimitry Andric Function::arg_iterator OldArg = Args[0].Formal->getParent()->arg_begin();
995145449b1SDimitry Andric for (auto End = F->arg_end(); NewArg != End; ++NewArg, ++OldArg) {
996344a3780SDimitry Andric
997145449b1SDimitry Andric LLVM_DEBUG(dbgs() << "SCCP: Marking argument "
998145449b1SDimitry Andric << NewArg->getNameOrAsOperand() << "\n");
999145449b1SDimitry Andric
10007fa27ce4SDimitry Andric // Mark the argument constants in the new function
10017fa27ce4SDimitry Andric // or copy the lattice state over from the old function.
10027fa27ce4SDimitry Andric if (Iter != Args.end() && Iter->Formal == &*OldArg) {
10037fa27ce4SDimitry Andric if (auto *STy = dyn_cast<StructType>(NewArg->getType())) {
10047fa27ce4SDimitry Andric for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
10057fa27ce4SDimitry Andric ValueLatticeElement &NewValue = StructValueState[{&*NewArg, I}];
10067fa27ce4SDimitry Andric NewValue.markConstant(Iter->Actual->getAggregateElement(I));
10077fa27ce4SDimitry Andric }
10087fa27ce4SDimitry Andric } else {
10097fa27ce4SDimitry Andric ValueState[&*NewArg].markConstant(Iter->Actual);
10107fa27ce4SDimitry Andric }
1011145449b1SDimitry Andric ++Iter;
10127fa27ce4SDimitry Andric } else {
10137fa27ce4SDimitry Andric if (auto *STy = dyn_cast<StructType>(NewArg->getType())) {
10147fa27ce4SDimitry Andric for (unsigned I = 0, E = STy->getNumElements(); I != E; ++I) {
10157fa27ce4SDimitry Andric ValueLatticeElement &NewValue = StructValueState[{&*NewArg, I}];
10167fa27ce4SDimitry Andric NewValue = StructValueState[{&*OldArg, I}];
10177fa27ce4SDimitry Andric }
10187fa27ce4SDimitry Andric } else {
10197fa27ce4SDimitry Andric ValueLatticeElement &NewValue = ValueState[&*NewArg];
10207fa27ce4SDimitry Andric NewValue = ValueState[&*OldArg];
10217fa27ce4SDimitry Andric }
1022145449b1SDimitry Andric }
1023344a3780SDimitry Andric }
1024344a3780SDimitry Andric }
1025344a3780SDimitry Andric
visitInstruction(Instruction & I)1026344a3780SDimitry Andric void SCCPInstVisitor::visitInstruction(Instruction &I) {
1027344a3780SDimitry Andric // All the instructions we don't do any special handling for just
1028344a3780SDimitry Andric // go to overdefined.
1029344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "SCCP: Don't know how to handle: " << I << '\n');
1030344a3780SDimitry Andric markOverdefined(&I);
1031344a3780SDimitry Andric }
1032344a3780SDimitry Andric
mergeInValue(ValueLatticeElement & IV,Value * V,ValueLatticeElement MergeWithV,ValueLatticeElement::MergeOptions Opts)1033344a3780SDimitry Andric bool SCCPInstVisitor::mergeInValue(ValueLatticeElement &IV, Value *V,
1034344a3780SDimitry Andric ValueLatticeElement MergeWithV,
1035344a3780SDimitry Andric ValueLatticeElement::MergeOptions Opts) {
1036344a3780SDimitry Andric if (IV.mergeIn(MergeWithV, Opts)) {
1037344a3780SDimitry Andric pushToWorkList(IV, V);
1038344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "Merged " << MergeWithV << " into " << *V << " : "
1039344a3780SDimitry Andric << IV << "\n");
1040344a3780SDimitry Andric return true;
1041344a3780SDimitry Andric }
1042344a3780SDimitry Andric return false;
1043344a3780SDimitry Andric }
1044344a3780SDimitry Andric
markEdgeExecutable(BasicBlock * Source,BasicBlock * Dest)1045344a3780SDimitry Andric bool SCCPInstVisitor::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
1046344a3780SDimitry Andric if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
1047344a3780SDimitry Andric return false; // This edge is already known to be executable!
1048344a3780SDimitry Andric
1049344a3780SDimitry Andric if (!markBlockExecutable(Dest)) {
1050344a3780SDimitry Andric // If the destination is already executable, we just made an *edge*
1051344a3780SDimitry Andric // feasible that wasn't before. Revisit the PHI nodes in the block
1052344a3780SDimitry Andric // because they have potentially new operands.
1053344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName()
1054344a3780SDimitry Andric << " -> " << Dest->getName() << '\n');
1055344a3780SDimitry Andric
1056344a3780SDimitry Andric for (PHINode &PN : Dest->phis())
1057344a3780SDimitry Andric visitPHINode(PN);
1058344a3780SDimitry Andric }
1059344a3780SDimitry Andric return true;
1060344a3780SDimitry Andric }
1061344a3780SDimitry Andric
1062344a3780SDimitry Andric // getFeasibleSuccessors - Return a vector of booleans to indicate which
1063344a3780SDimitry Andric // successors are reachable from a given terminator instruction.
getFeasibleSuccessors(Instruction & TI,SmallVectorImpl<bool> & Succs)1064344a3780SDimitry Andric void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
1065344a3780SDimitry Andric SmallVectorImpl<bool> &Succs) {
1066344a3780SDimitry Andric Succs.resize(TI.getNumSuccessors());
1067344a3780SDimitry Andric if (auto *BI = dyn_cast<BranchInst>(&TI)) {
1068344a3780SDimitry Andric if (BI->isUnconditional()) {
1069344a3780SDimitry Andric Succs[0] = true;
1070344a3780SDimitry Andric return;
1071344a3780SDimitry Andric }
1072344a3780SDimitry Andric
1073344a3780SDimitry Andric ValueLatticeElement BCValue = getValueState(BI->getCondition());
10747fa27ce4SDimitry Andric ConstantInt *CI = getConstantInt(BCValue, BI->getCondition()->getType());
1075344a3780SDimitry Andric if (!CI) {
1076344a3780SDimitry Andric // Overdefined condition variables, and branches on unfoldable constant
1077344a3780SDimitry Andric // conditions, mean the branch could go either way.
1078344a3780SDimitry Andric if (!BCValue.isUnknownOrUndef())
1079344a3780SDimitry Andric Succs[0] = Succs[1] = true;
1080344a3780SDimitry Andric return;
1081344a3780SDimitry Andric }
1082344a3780SDimitry Andric
1083344a3780SDimitry Andric // Constant condition variables mean the branch can only go a single way.
1084344a3780SDimitry Andric Succs[CI->isZero()] = true;
1085344a3780SDimitry Andric return;
1086344a3780SDimitry Andric }
1087344a3780SDimitry Andric
1088b1c73532SDimitry Andric // We cannot analyze special terminators, so consider all successors
1089b1c73532SDimitry Andric // executable.
1090b1c73532SDimitry Andric if (TI.isSpecialTerminator()) {
1091344a3780SDimitry Andric Succs.assign(TI.getNumSuccessors(), true);
1092344a3780SDimitry Andric return;
1093344a3780SDimitry Andric }
1094344a3780SDimitry Andric
1095344a3780SDimitry Andric if (auto *SI = dyn_cast<SwitchInst>(&TI)) {
1096344a3780SDimitry Andric if (!SI->getNumCases()) {
1097344a3780SDimitry Andric Succs[0] = true;
1098344a3780SDimitry Andric return;
1099344a3780SDimitry Andric }
1100344a3780SDimitry Andric const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
11017fa27ce4SDimitry Andric if (ConstantInt *CI =
11027fa27ce4SDimitry Andric getConstantInt(SCValue, SI->getCondition()->getType())) {
1103344a3780SDimitry Andric Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
1104344a3780SDimitry Andric return;
1105344a3780SDimitry Andric }
1106344a3780SDimitry Andric
1107344a3780SDimitry Andric // TODO: Switch on undef is UB. Stop passing false once the rest of LLVM
1108344a3780SDimitry Andric // is ready.
1109344a3780SDimitry Andric if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
1110344a3780SDimitry Andric const ConstantRange &Range = SCValue.getConstantRange();
1111aca2e42cSDimitry Andric unsigned ReachableCaseCount = 0;
1112344a3780SDimitry Andric for (const auto &Case : SI->cases()) {
1113344a3780SDimitry Andric const APInt &CaseValue = Case.getCaseValue()->getValue();
1114aca2e42cSDimitry Andric if (Range.contains(CaseValue)) {
1115344a3780SDimitry Andric Succs[Case.getSuccessorIndex()] = true;
1116aca2e42cSDimitry Andric ++ReachableCaseCount;
1117aca2e42cSDimitry Andric }
1118344a3780SDimitry Andric }
1119344a3780SDimitry Andric
1120aca2e42cSDimitry Andric Succs[SI->case_default()->getSuccessorIndex()] =
1121aca2e42cSDimitry Andric Range.isSizeLargerThan(ReachableCaseCount);
1122344a3780SDimitry Andric return;
1123344a3780SDimitry Andric }
1124344a3780SDimitry Andric
1125344a3780SDimitry Andric // Overdefined or unknown condition? All destinations are executable!
1126344a3780SDimitry Andric if (!SCValue.isUnknownOrUndef())
1127344a3780SDimitry Andric Succs.assign(TI.getNumSuccessors(), true);
1128344a3780SDimitry Andric return;
1129344a3780SDimitry Andric }
1130344a3780SDimitry Andric
1131344a3780SDimitry Andric // In case of indirect branch and its address is a blockaddress, we mark
1132344a3780SDimitry Andric // the target as executable.
1133344a3780SDimitry Andric if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
1134344a3780SDimitry Andric // Casts are folded by visitCastInst.
1135344a3780SDimitry Andric ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
11367fa27ce4SDimitry Andric BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(
11377fa27ce4SDimitry Andric getConstant(IBRValue, IBR->getAddress()->getType()));
1138344a3780SDimitry Andric if (!Addr) { // Overdefined or unknown condition?
1139344a3780SDimitry Andric // All destinations are executable!
1140344a3780SDimitry Andric if (!IBRValue.isUnknownOrUndef())
1141344a3780SDimitry Andric Succs.assign(TI.getNumSuccessors(), true);
1142344a3780SDimitry Andric return;
1143344a3780SDimitry Andric }
1144344a3780SDimitry Andric
1145344a3780SDimitry Andric BasicBlock *T = Addr->getBasicBlock();
1146344a3780SDimitry Andric assert(Addr->getFunction() == T->getParent() &&
1147344a3780SDimitry Andric "Block address of a different function ?");
1148344a3780SDimitry Andric for (unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
1149344a3780SDimitry Andric // This is the target.
1150344a3780SDimitry Andric if (IBR->getDestination(i) == T) {
1151344a3780SDimitry Andric Succs[i] = true;
1152344a3780SDimitry Andric return;
1153344a3780SDimitry Andric }
1154344a3780SDimitry Andric }
1155344a3780SDimitry Andric
1156344a3780SDimitry Andric // If we didn't find our destination in the IBR successor list, then we
1157344a3780SDimitry Andric // have undefined behavior. Its ok to assume no successor is executable.
1158344a3780SDimitry Andric return;
1159344a3780SDimitry Andric }
1160344a3780SDimitry Andric
1161344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "Unknown terminator instruction: " << TI << '\n');
1162344a3780SDimitry Andric llvm_unreachable("SCCP: Don't know how to handle this terminator!");
1163344a3780SDimitry Andric }
1164344a3780SDimitry Andric
1165344a3780SDimitry Andric // isEdgeFeasible - Return true if the control flow edge from the 'From' basic
1166344a3780SDimitry Andric // block to the 'To' basic block is currently feasible.
isEdgeFeasible(BasicBlock * From,BasicBlock * To) const1167344a3780SDimitry Andric bool SCCPInstVisitor::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
1168344a3780SDimitry Andric // Check if we've called markEdgeExecutable on the edge yet. (We could
1169344a3780SDimitry Andric // be more aggressive and try to consider edges which haven't been marked
1170344a3780SDimitry Andric // yet, but there isn't any need.)
1171344a3780SDimitry Andric return KnownFeasibleEdges.count(Edge(From, To));
1172344a3780SDimitry Andric }
1173344a3780SDimitry Andric
1174344a3780SDimitry Andric // visit Implementations - Something changed in this instruction, either an
1175344a3780SDimitry Andric // operand made a transition, or the instruction is newly executable. Change
1176344a3780SDimitry Andric // the value type of I to reflect these changes if appropriate. This method
1177344a3780SDimitry Andric // makes sure to do the following actions:
1178344a3780SDimitry Andric //
1179344a3780SDimitry Andric // 1. If a phi node merges two constants in, and has conflicting value coming
1180344a3780SDimitry Andric // from different branches, or if the PHI node merges in an overdefined
1181344a3780SDimitry Andric // value, then the PHI node becomes overdefined.
1182344a3780SDimitry Andric // 2. If a phi node merges only constants in, and they all agree on value, the
1183344a3780SDimitry Andric // PHI node becomes a constant value equal to that.
1184344a3780SDimitry Andric // 3. If V <- x (op) y && isConstant(x) && isConstant(y) V = Constant
1185344a3780SDimitry Andric // 4. If V <- x (op) y && (isOverdefined(x) || isOverdefined(y)) V = Overdefined
1186344a3780SDimitry Andric // 5. If V <- MEM or V <- CALL or V <- (unknown) then V = Overdefined
1187344a3780SDimitry Andric // 6. If a conditional branch has a value that is constant, make the selected
1188344a3780SDimitry Andric // destination executable
1189344a3780SDimitry Andric // 7. If a conditional branch has a value that is overdefined, make all
1190344a3780SDimitry Andric // successors executable.
visitPHINode(PHINode & PN)1191344a3780SDimitry Andric void SCCPInstVisitor::visitPHINode(PHINode &PN) {
1192344a3780SDimitry Andric // If this PN returns a struct, just mark the result overdefined.
1193344a3780SDimitry Andric // TODO: We could do a lot better than this if code actually uses this.
1194344a3780SDimitry Andric if (PN.getType()->isStructTy())
1195344a3780SDimitry Andric return (void)markOverdefined(&PN);
1196344a3780SDimitry Andric
1197344a3780SDimitry Andric if (getValueState(&PN).isOverdefined())
1198344a3780SDimitry Andric return; // Quick exit
1199344a3780SDimitry Andric
1200344a3780SDimitry Andric // Super-extra-high-degree PHI nodes are unlikely to ever be marked constant,
1201344a3780SDimitry Andric // and slow us down a lot. Just mark them overdefined.
1202344a3780SDimitry Andric if (PN.getNumIncomingValues() > 64)
1203344a3780SDimitry Andric return (void)markOverdefined(&PN);
1204344a3780SDimitry Andric
1205344a3780SDimitry Andric unsigned NumActiveIncoming = 0;
1206344a3780SDimitry Andric
1207344a3780SDimitry Andric // Look at all of the executable operands of the PHI node. If any of them
1208344a3780SDimitry Andric // are overdefined, the PHI becomes overdefined as well. If they are all
1209344a3780SDimitry Andric // constant, and they agree with each other, the PHI becomes the identical
1210344a3780SDimitry Andric // constant. If they are constant and don't agree, the PHI is a constant
1211344a3780SDimitry Andric // range. If there are no executable operands, the PHI remains unknown.
1212344a3780SDimitry Andric ValueLatticeElement PhiState = getValueState(&PN);
1213344a3780SDimitry Andric for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
1214344a3780SDimitry Andric if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
1215344a3780SDimitry Andric continue;
1216344a3780SDimitry Andric
1217344a3780SDimitry Andric ValueLatticeElement IV = getValueState(PN.getIncomingValue(i));
1218344a3780SDimitry Andric PhiState.mergeIn(IV);
1219344a3780SDimitry Andric NumActiveIncoming++;
1220344a3780SDimitry Andric if (PhiState.isOverdefined())
1221344a3780SDimitry Andric break;
1222344a3780SDimitry Andric }
1223344a3780SDimitry Andric
1224344a3780SDimitry Andric // We allow up to 1 range extension per active incoming value and one
1225344a3780SDimitry Andric // additional extension. Note that we manually adjust the number of range
1226344a3780SDimitry Andric // extensions to match the number of active incoming values. This helps to
1227344a3780SDimitry Andric // limit multiple extensions caused by the same incoming value, if other
1228344a3780SDimitry Andric // incoming values are equal.
1229344a3780SDimitry Andric mergeInValue(&PN, PhiState,
1230344a3780SDimitry Andric ValueLatticeElement::MergeOptions().setMaxWidenSteps(
1231344a3780SDimitry Andric NumActiveIncoming + 1));
1232344a3780SDimitry Andric ValueLatticeElement &PhiStateRef = getValueState(&PN);
1233344a3780SDimitry Andric PhiStateRef.setNumRangeExtensions(
1234344a3780SDimitry Andric std::max(NumActiveIncoming, PhiStateRef.getNumRangeExtensions()));
1235344a3780SDimitry Andric }
1236344a3780SDimitry Andric
visitReturnInst(ReturnInst & I)1237344a3780SDimitry Andric void SCCPInstVisitor::visitReturnInst(ReturnInst &I) {
1238344a3780SDimitry Andric if (I.getNumOperands() == 0)
1239344a3780SDimitry Andric return; // ret void
1240344a3780SDimitry Andric
1241344a3780SDimitry Andric Function *F = I.getParent()->getParent();
1242344a3780SDimitry Andric Value *ResultOp = I.getOperand(0);
1243344a3780SDimitry Andric
1244344a3780SDimitry Andric // If we are tracking the return value of this function, merge it in.
1245344a3780SDimitry Andric if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) {
1246344a3780SDimitry Andric auto TFRVI = TrackedRetVals.find(F);
1247344a3780SDimitry Andric if (TFRVI != TrackedRetVals.end()) {
1248344a3780SDimitry Andric mergeInValue(TFRVI->second, F, getValueState(ResultOp));
1249344a3780SDimitry Andric return;
1250344a3780SDimitry Andric }
1251344a3780SDimitry Andric }
1252344a3780SDimitry Andric
1253344a3780SDimitry Andric // Handle functions that return multiple values.
1254344a3780SDimitry Andric if (!TrackedMultipleRetVals.empty()) {
1255344a3780SDimitry Andric if (auto *STy = dyn_cast<StructType>(ResultOp->getType()))
1256344a3780SDimitry Andric if (MRVFunctionsTracked.count(F))
1257344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1258344a3780SDimitry Andric mergeInValue(TrackedMultipleRetVals[std::make_pair(F, i)], F,
1259344a3780SDimitry Andric getStructValueState(ResultOp, i));
1260344a3780SDimitry Andric }
1261344a3780SDimitry Andric }
1262344a3780SDimitry Andric
visitTerminator(Instruction & TI)1263344a3780SDimitry Andric void SCCPInstVisitor::visitTerminator(Instruction &TI) {
1264344a3780SDimitry Andric SmallVector<bool, 16> SuccFeasible;
1265344a3780SDimitry Andric getFeasibleSuccessors(TI, SuccFeasible);
1266344a3780SDimitry Andric
1267344a3780SDimitry Andric BasicBlock *BB = TI.getParent();
1268344a3780SDimitry Andric
1269344a3780SDimitry Andric // Mark all feasible successors executable.
1270344a3780SDimitry Andric for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
1271344a3780SDimitry Andric if (SuccFeasible[i])
1272344a3780SDimitry Andric markEdgeExecutable(BB, TI.getSuccessor(i));
1273344a3780SDimitry Andric }
1274344a3780SDimitry Andric
visitCastInst(CastInst & I)1275344a3780SDimitry Andric void SCCPInstVisitor::visitCastInst(CastInst &I) {
1276344a3780SDimitry Andric // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1277344a3780SDimitry Andric // discover a concrete value later.
1278344a3780SDimitry Andric if (ValueState[&I].isOverdefined())
1279344a3780SDimitry Andric return;
1280344a3780SDimitry Andric
1281344a3780SDimitry Andric ValueLatticeElement OpSt = getValueState(I.getOperand(0));
1282c0981da4SDimitry Andric if (OpSt.isUnknownOrUndef())
1283c0981da4SDimitry Andric return;
1284c0981da4SDimitry Andric
12857fa27ce4SDimitry Andric if (Constant *OpC = getConstant(OpSt, I.getOperand(0)->getType())) {
1286344a3780SDimitry Andric // Fold the constant as we build.
1287b1c73532SDimitry Andric if (Constant *C =
1288b1c73532SDimitry Andric ConstantFoldCastOperand(I.getOpcode(), OpC, I.getType(), DL))
1289b1c73532SDimitry Andric return (void)markConstant(&I, C);
1290b1c73532SDimitry Andric }
1291b1c73532SDimitry Andric
1292ac9a064cSDimitry Andric // Ignore bitcasts, as they may change the number of vector elements.
1293ac9a064cSDimitry Andric if (I.getDestTy()->isIntOrIntVectorTy() &&
1294ac9a064cSDimitry Andric I.getSrcTy()->isIntOrIntVectorTy() &&
1295ac9a064cSDimitry Andric I.getOpcode() != Instruction::BitCast) {
1296344a3780SDimitry Andric auto &LV = getValueState(&I);
1297ac9a064cSDimitry Andric ConstantRange OpRange =
1298ac9a064cSDimitry Andric OpSt.asConstantRange(I.getSrcTy(), /*UndefAllowed=*/false);
1299c0981da4SDimitry Andric
1300344a3780SDimitry Andric Type *DestTy = I.getDestTy();
1301344a3780SDimitry Andric ConstantRange Res =
1302ac9a064cSDimitry Andric OpRange.castOp(I.getOpcode(), DestTy->getScalarSizeInBits());
1303344a3780SDimitry Andric mergeInValue(LV, &I, ValueLatticeElement::getRange(Res));
1304c0981da4SDimitry Andric } else
1305344a3780SDimitry Andric markOverdefined(&I);
1306344a3780SDimitry Andric }
1307344a3780SDimitry Andric
handleExtractOfWithOverflow(ExtractValueInst & EVI,const WithOverflowInst * WO,unsigned Idx)1308e3b55780SDimitry Andric void SCCPInstVisitor::handleExtractOfWithOverflow(ExtractValueInst &EVI,
1309e3b55780SDimitry Andric const WithOverflowInst *WO,
1310e3b55780SDimitry Andric unsigned Idx) {
1311e3b55780SDimitry Andric Value *LHS = WO->getLHS(), *RHS = WO->getRHS();
1312e3b55780SDimitry Andric ValueLatticeElement L = getValueState(LHS);
1313e3b55780SDimitry Andric ValueLatticeElement R = getValueState(RHS);
1314e3b55780SDimitry Andric addAdditionalUser(LHS, &EVI);
1315e3b55780SDimitry Andric addAdditionalUser(RHS, &EVI);
1316e3b55780SDimitry Andric if (L.isUnknownOrUndef() || R.isUnknownOrUndef())
1317e3b55780SDimitry Andric return; // Wait to resolve.
1318e3b55780SDimitry Andric
1319e3b55780SDimitry Andric Type *Ty = LHS->getType();
1320ac9a064cSDimitry Andric ConstantRange LR = L.asConstantRange(Ty, /*UndefAllowed=*/false);
1321ac9a064cSDimitry Andric ConstantRange RR = R.asConstantRange(Ty, /*UndefAllowed=*/false);
1322e3b55780SDimitry Andric if (Idx == 0) {
1323e3b55780SDimitry Andric ConstantRange Res = LR.binaryOp(WO->getBinaryOp(), RR);
1324e3b55780SDimitry Andric mergeInValue(&EVI, ValueLatticeElement::getRange(Res));
1325e3b55780SDimitry Andric } else {
1326e3b55780SDimitry Andric assert(Idx == 1 && "Index can only be 0 or 1");
1327e3b55780SDimitry Andric ConstantRange NWRegion = ConstantRange::makeGuaranteedNoWrapRegion(
1328e3b55780SDimitry Andric WO->getBinaryOp(), RR, WO->getNoWrapKind());
1329e3b55780SDimitry Andric if (NWRegion.contains(LR))
1330e3b55780SDimitry Andric return (void)markConstant(&EVI, ConstantInt::getFalse(EVI.getType()));
1331e3b55780SDimitry Andric markOverdefined(&EVI);
1332e3b55780SDimitry Andric }
1333e3b55780SDimitry Andric }
1334e3b55780SDimitry Andric
visitExtractValueInst(ExtractValueInst & EVI)1335344a3780SDimitry Andric void SCCPInstVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
1336344a3780SDimitry Andric // If this returns a struct, mark all elements over defined, we don't track
1337344a3780SDimitry Andric // structs in structs.
1338344a3780SDimitry Andric if (EVI.getType()->isStructTy())
1339344a3780SDimitry Andric return (void)markOverdefined(&EVI);
1340344a3780SDimitry Andric
1341344a3780SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1342344a3780SDimitry Andric // discover a concrete value later.
1343344a3780SDimitry Andric if (ValueState[&EVI].isOverdefined())
1344344a3780SDimitry Andric return (void)markOverdefined(&EVI);
1345344a3780SDimitry Andric
1346344a3780SDimitry Andric // If this is extracting from more than one level of struct, we don't know.
1347344a3780SDimitry Andric if (EVI.getNumIndices() != 1)
1348344a3780SDimitry Andric return (void)markOverdefined(&EVI);
1349344a3780SDimitry Andric
1350344a3780SDimitry Andric Value *AggVal = EVI.getAggregateOperand();
1351344a3780SDimitry Andric if (AggVal->getType()->isStructTy()) {
1352344a3780SDimitry Andric unsigned i = *EVI.idx_begin();
1353e3b55780SDimitry Andric if (auto *WO = dyn_cast<WithOverflowInst>(AggVal))
1354e3b55780SDimitry Andric return handleExtractOfWithOverflow(EVI, WO, i);
1355344a3780SDimitry Andric ValueLatticeElement EltVal = getStructValueState(AggVal, i);
1356344a3780SDimitry Andric mergeInValue(getValueState(&EVI), &EVI, EltVal);
1357344a3780SDimitry Andric } else {
1358344a3780SDimitry Andric // Otherwise, must be extracting from an array.
1359344a3780SDimitry Andric return (void)markOverdefined(&EVI);
1360344a3780SDimitry Andric }
1361344a3780SDimitry Andric }
1362344a3780SDimitry Andric
visitInsertValueInst(InsertValueInst & IVI)1363344a3780SDimitry Andric void SCCPInstVisitor::visitInsertValueInst(InsertValueInst &IVI) {
1364344a3780SDimitry Andric auto *STy = dyn_cast<StructType>(IVI.getType());
1365344a3780SDimitry Andric if (!STy)
1366344a3780SDimitry Andric return (void)markOverdefined(&IVI);
1367344a3780SDimitry Andric
1368344a3780SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1369344a3780SDimitry Andric // discover a concrete value later.
1370e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(ValueState[&IVI]))
1371344a3780SDimitry Andric return (void)markOverdefined(&IVI);
1372344a3780SDimitry Andric
1373344a3780SDimitry Andric // If this has more than one index, we can't handle it, drive all results to
1374344a3780SDimitry Andric // undef.
1375344a3780SDimitry Andric if (IVI.getNumIndices() != 1)
1376344a3780SDimitry Andric return (void)markOverdefined(&IVI);
1377344a3780SDimitry Andric
1378344a3780SDimitry Andric Value *Aggr = IVI.getAggregateOperand();
1379344a3780SDimitry Andric unsigned Idx = *IVI.idx_begin();
1380344a3780SDimitry Andric
1381344a3780SDimitry Andric // Compute the result based on what we're inserting.
1382344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1383344a3780SDimitry Andric // This passes through all values that aren't the inserted element.
1384344a3780SDimitry Andric if (i != Idx) {
1385344a3780SDimitry Andric ValueLatticeElement EltVal = getStructValueState(Aggr, i);
1386344a3780SDimitry Andric mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
1387344a3780SDimitry Andric continue;
1388344a3780SDimitry Andric }
1389344a3780SDimitry Andric
1390344a3780SDimitry Andric Value *Val = IVI.getInsertedValueOperand();
1391344a3780SDimitry Andric if (Val->getType()->isStructTy())
1392344a3780SDimitry Andric // We don't track structs in structs.
1393344a3780SDimitry Andric markOverdefined(getStructValueState(&IVI, i), &IVI);
1394344a3780SDimitry Andric else {
1395344a3780SDimitry Andric ValueLatticeElement InVal = getValueState(Val);
1396344a3780SDimitry Andric mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
1397344a3780SDimitry Andric }
1398344a3780SDimitry Andric }
1399344a3780SDimitry Andric }
1400344a3780SDimitry Andric
visitSelectInst(SelectInst & I)1401344a3780SDimitry Andric void SCCPInstVisitor::visitSelectInst(SelectInst &I) {
1402344a3780SDimitry Andric // If this select returns a struct, just mark the result overdefined.
1403344a3780SDimitry Andric // TODO: We could do a lot better than this if code actually uses this.
1404344a3780SDimitry Andric if (I.getType()->isStructTy())
1405344a3780SDimitry Andric return (void)markOverdefined(&I);
1406344a3780SDimitry Andric
1407344a3780SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1408344a3780SDimitry Andric // discover a concrete value later.
1409344a3780SDimitry Andric if (ValueState[&I].isOverdefined())
1410344a3780SDimitry Andric return (void)markOverdefined(&I);
1411344a3780SDimitry Andric
1412344a3780SDimitry Andric ValueLatticeElement CondValue = getValueState(I.getCondition());
1413344a3780SDimitry Andric if (CondValue.isUnknownOrUndef())
1414344a3780SDimitry Andric return;
1415344a3780SDimitry Andric
14167fa27ce4SDimitry Andric if (ConstantInt *CondCB =
14177fa27ce4SDimitry Andric getConstantInt(CondValue, I.getCondition()->getType())) {
1418344a3780SDimitry Andric Value *OpVal = CondCB->isZero() ? I.getFalseValue() : I.getTrueValue();
1419344a3780SDimitry Andric mergeInValue(&I, getValueState(OpVal));
1420344a3780SDimitry Andric return;
1421344a3780SDimitry Andric }
1422344a3780SDimitry Andric
1423344a3780SDimitry Andric // Otherwise, the condition is overdefined or a constant we can't evaluate.
1424344a3780SDimitry Andric // See if we can produce something better than overdefined based on the T/F
1425344a3780SDimitry Andric // value.
1426344a3780SDimitry Andric ValueLatticeElement TVal = getValueState(I.getTrueValue());
1427344a3780SDimitry Andric ValueLatticeElement FVal = getValueState(I.getFalseValue());
1428344a3780SDimitry Andric
1429344a3780SDimitry Andric bool Changed = ValueState[&I].mergeIn(TVal);
1430344a3780SDimitry Andric Changed |= ValueState[&I].mergeIn(FVal);
1431344a3780SDimitry Andric if (Changed)
1432344a3780SDimitry Andric pushToWorkListMsg(ValueState[&I], &I);
1433344a3780SDimitry Andric }
1434344a3780SDimitry Andric
1435344a3780SDimitry Andric // Handle Unary Operators.
visitUnaryOperator(Instruction & I)1436344a3780SDimitry Andric void SCCPInstVisitor::visitUnaryOperator(Instruction &I) {
1437344a3780SDimitry Andric ValueLatticeElement V0State = getValueState(I.getOperand(0));
1438344a3780SDimitry Andric
1439344a3780SDimitry Andric ValueLatticeElement &IV = ValueState[&I];
1440344a3780SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1441344a3780SDimitry Andric // discover a concrete value later.
1442e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(IV))
1443344a3780SDimitry Andric return (void)markOverdefined(&I);
1444344a3780SDimitry Andric
14451f917f69SDimitry Andric // If something is unknown/undef, wait for it to resolve.
14461f917f69SDimitry Andric if (V0State.isUnknownOrUndef())
1447344a3780SDimitry Andric return;
14481f917f69SDimitry Andric
1449e3b55780SDimitry Andric if (SCCPSolver::isConstant(V0State))
14507fa27ce4SDimitry Andric if (Constant *C = ConstantFoldUnaryOpOperand(
14517fa27ce4SDimitry Andric I.getOpcode(), getConstant(V0State, I.getType()), DL))
1452344a3780SDimitry Andric return (void)markConstant(IV, &I, C);
1453344a3780SDimitry Andric
1454344a3780SDimitry Andric markOverdefined(&I);
1455344a3780SDimitry Andric }
1456344a3780SDimitry Andric
visitFreezeInst(FreezeInst & I)14577fa27ce4SDimitry Andric void SCCPInstVisitor::visitFreezeInst(FreezeInst &I) {
14587fa27ce4SDimitry Andric // If this freeze returns a struct, just mark the result overdefined.
14597fa27ce4SDimitry Andric // TODO: We could do a lot better than this.
14607fa27ce4SDimitry Andric if (I.getType()->isStructTy())
14617fa27ce4SDimitry Andric return (void)markOverdefined(&I);
14627fa27ce4SDimitry Andric
14637fa27ce4SDimitry Andric ValueLatticeElement V0State = getValueState(I.getOperand(0));
14647fa27ce4SDimitry Andric ValueLatticeElement &IV = ValueState[&I];
14657fa27ce4SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
14667fa27ce4SDimitry Andric // discover a concrete value later.
14677fa27ce4SDimitry Andric if (SCCPSolver::isOverdefined(IV))
14687fa27ce4SDimitry Andric return (void)markOverdefined(&I);
14697fa27ce4SDimitry Andric
14707fa27ce4SDimitry Andric // If something is unknown/undef, wait for it to resolve.
14717fa27ce4SDimitry Andric if (V0State.isUnknownOrUndef())
14727fa27ce4SDimitry Andric return;
14737fa27ce4SDimitry Andric
14747fa27ce4SDimitry Andric if (SCCPSolver::isConstant(V0State) &&
14757fa27ce4SDimitry Andric isGuaranteedNotToBeUndefOrPoison(getConstant(V0State, I.getType())))
14767fa27ce4SDimitry Andric return (void)markConstant(IV, &I, getConstant(V0State, I.getType()));
14777fa27ce4SDimitry Andric
14787fa27ce4SDimitry Andric markOverdefined(&I);
14797fa27ce4SDimitry Andric }
14807fa27ce4SDimitry Andric
1481344a3780SDimitry Andric // Handle Binary Operators.
visitBinaryOperator(Instruction & I)1482344a3780SDimitry Andric void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
1483344a3780SDimitry Andric ValueLatticeElement V1State = getValueState(I.getOperand(0));
1484344a3780SDimitry Andric ValueLatticeElement V2State = getValueState(I.getOperand(1));
1485344a3780SDimitry Andric
1486344a3780SDimitry Andric ValueLatticeElement &IV = ValueState[&I];
1487344a3780SDimitry Andric if (IV.isOverdefined())
1488344a3780SDimitry Andric return;
1489344a3780SDimitry Andric
1490344a3780SDimitry Andric // If something is undef, wait for it to resolve.
1491344a3780SDimitry Andric if (V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef())
1492344a3780SDimitry Andric return;
1493344a3780SDimitry Andric
1494344a3780SDimitry Andric if (V1State.isOverdefined() && V2State.isOverdefined())
1495344a3780SDimitry Andric return (void)markOverdefined(&I);
1496344a3780SDimitry Andric
1497344a3780SDimitry Andric // If either of the operands is a constant, try to fold it to a constant.
1498344a3780SDimitry Andric // TODO: Use information from notconstant better.
1499344a3780SDimitry Andric if ((V1State.isConstant() || V2State.isConstant())) {
15007fa27ce4SDimitry Andric Value *V1 = SCCPSolver::isConstant(V1State)
15017fa27ce4SDimitry Andric ? getConstant(V1State, I.getOperand(0)->getType())
1502e3b55780SDimitry Andric : I.getOperand(0);
15037fa27ce4SDimitry Andric Value *V2 = SCCPSolver::isConstant(V2State)
15047fa27ce4SDimitry Andric ? getConstant(V2State, I.getOperand(1)->getType())
1505e3b55780SDimitry Andric : I.getOperand(1);
1506145449b1SDimitry Andric Value *R = simplifyBinOp(I.getOpcode(), V1, V2, SimplifyQuery(DL));
1507344a3780SDimitry Andric auto *C = dyn_cast_or_null<Constant>(R);
1508344a3780SDimitry Andric if (C) {
1509344a3780SDimitry Andric // Conservatively assume that the result may be based on operands that may
1510344a3780SDimitry Andric // be undef. Note that we use mergeInValue to combine the constant with
1511344a3780SDimitry Andric // the existing lattice value for I, as different constants might be found
1512344a3780SDimitry Andric // after one of the operands go to overdefined, e.g. due to one operand
1513344a3780SDimitry Andric // being a special floating value.
1514344a3780SDimitry Andric ValueLatticeElement NewV;
1515344a3780SDimitry Andric NewV.markConstant(C, /*MayIncludeUndef=*/true);
1516344a3780SDimitry Andric return (void)mergeInValue(&I, NewV);
1517344a3780SDimitry Andric }
1518344a3780SDimitry Andric }
1519344a3780SDimitry Andric
1520344a3780SDimitry Andric // Only use ranges for binary operators on integers.
1521ac9a064cSDimitry Andric if (!I.getType()->isIntOrIntVectorTy())
1522344a3780SDimitry Andric return markOverdefined(&I);
1523344a3780SDimitry Andric
1524344a3780SDimitry Andric // Try to simplify to a constant range.
1525ac9a064cSDimitry Andric ConstantRange A =
1526ac9a064cSDimitry Andric V1State.asConstantRange(I.getType(), /*UndefAllowed=*/false);
1527ac9a064cSDimitry Andric ConstantRange B =
1528ac9a064cSDimitry Andric V2State.asConstantRange(I.getType(), /*UndefAllowed=*/false);
1529ac9a064cSDimitry Andric
1530ac9a064cSDimitry Andric auto *BO = cast<BinaryOperator>(&I);
1531ac9a064cSDimitry Andric ConstantRange R = ConstantRange::getEmpty(I.getType()->getScalarSizeInBits());
1532ac9a064cSDimitry Andric if (auto *OBO = dyn_cast<OverflowingBinaryOperator>(BO))
1533ac9a064cSDimitry Andric R = A.overflowingBinaryOp(BO->getOpcode(), B, OBO->getNoWrapKind());
1534ac9a064cSDimitry Andric else
1535ac9a064cSDimitry Andric R = A.binaryOp(BO->getOpcode(), B);
1536344a3780SDimitry Andric mergeInValue(&I, ValueLatticeElement::getRange(R));
1537344a3780SDimitry Andric
1538344a3780SDimitry Andric // TODO: Currently we do not exploit special values that produce something
1539344a3780SDimitry Andric // better than overdefined with an overdefined operand for vector or floating
1540344a3780SDimitry Andric // point types, like and <4 x i32> overdefined, zeroinitializer.
1541344a3780SDimitry Andric }
1542344a3780SDimitry Andric
1543344a3780SDimitry Andric // Handle ICmpInst instruction.
visitCmpInst(CmpInst & I)1544344a3780SDimitry Andric void SCCPInstVisitor::visitCmpInst(CmpInst &I) {
1545344a3780SDimitry Andric // Do not cache this lookup, getValueState calls later in the function might
1546344a3780SDimitry Andric // invalidate the reference.
1547e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(ValueState[&I]))
1548344a3780SDimitry Andric return (void)markOverdefined(&I);
1549344a3780SDimitry Andric
1550344a3780SDimitry Andric Value *Op1 = I.getOperand(0);
1551344a3780SDimitry Andric Value *Op2 = I.getOperand(1);
1552344a3780SDimitry Andric
1553344a3780SDimitry Andric // For parameters, use ParamState which includes constant range info if
1554344a3780SDimitry Andric // available.
1555344a3780SDimitry Andric auto V1State = getValueState(Op1);
1556344a3780SDimitry Andric auto V2State = getValueState(Op2);
1557344a3780SDimitry Andric
1558e3b55780SDimitry Andric Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State, DL);
1559344a3780SDimitry Andric if (C) {
1560344a3780SDimitry Andric ValueLatticeElement CV;
1561344a3780SDimitry Andric CV.markConstant(C);
1562344a3780SDimitry Andric mergeInValue(&I, CV);
1563344a3780SDimitry Andric return;
1564344a3780SDimitry Andric }
1565344a3780SDimitry Andric
1566344a3780SDimitry Andric // If operands are still unknown, wait for it to resolve.
1567344a3780SDimitry Andric if ((V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) &&
1568e3b55780SDimitry Andric !SCCPSolver::isConstant(ValueState[&I]))
1569344a3780SDimitry Andric return;
1570344a3780SDimitry Andric
1571344a3780SDimitry Andric markOverdefined(&I);
1572344a3780SDimitry Andric }
1573344a3780SDimitry Andric
1574344a3780SDimitry Andric // Handle getelementptr instructions. If all operands are constants then we
1575344a3780SDimitry Andric // can turn this into a getelementptr ConstantExpr.
visitGetElementPtrInst(GetElementPtrInst & I)1576344a3780SDimitry Andric void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
1577e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(ValueState[&I]))
1578344a3780SDimitry Andric return (void)markOverdefined(&I);
1579344a3780SDimitry Andric
1580344a3780SDimitry Andric SmallVector<Constant *, 8> Operands;
1581344a3780SDimitry Andric Operands.reserve(I.getNumOperands());
1582344a3780SDimitry Andric
1583344a3780SDimitry Andric for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
1584344a3780SDimitry Andric ValueLatticeElement State = getValueState(I.getOperand(i));
1585344a3780SDimitry Andric if (State.isUnknownOrUndef())
1586344a3780SDimitry Andric return; // Operands are not resolved yet.
1587344a3780SDimitry Andric
1588e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(State))
1589344a3780SDimitry Andric return (void)markOverdefined(&I);
1590344a3780SDimitry Andric
15917fa27ce4SDimitry Andric if (Constant *C = getConstant(State, I.getOperand(i)->getType())) {
1592344a3780SDimitry Andric Operands.push_back(C);
1593344a3780SDimitry Andric continue;
1594344a3780SDimitry Andric }
1595344a3780SDimitry Andric
1596344a3780SDimitry Andric return (void)markOverdefined(&I);
1597344a3780SDimitry Andric }
1598344a3780SDimitry Andric
1599b1c73532SDimitry Andric if (Constant *C = ConstantFoldInstOperands(&I, Operands, DL))
1600344a3780SDimitry Andric markConstant(&I, C);
1601344a3780SDimitry Andric }
1602344a3780SDimitry Andric
visitStoreInst(StoreInst & SI)1603344a3780SDimitry Andric void SCCPInstVisitor::visitStoreInst(StoreInst &SI) {
1604344a3780SDimitry Andric // If this store is of a struct, ignore it.
1605344a3780SDimitry Andric if (SI.getOperand(0)->getType()->isStructTy())
1606344a3780SDimitry Andric return;
1607344a3780SDimitry Andric
1608344a3780SDimitry Andric if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1)))
1609344a3780SDimitry Andric return;
1610344a3780SDimitry Andric
1611344a3780SDimitry Andric GlobalVariable *GV = cast<GlobalVariable>(SI.getOperand(1));
1612344a3780SDimitry Andric auto I = TrackedGlobals.find(GV);
1613344a3780SDimitry Andric if (I == TrackedGlobals.end())
1614344a3780SDimitry Andric return;
1615344a3780SDimitry Andric
1616344a3780SDimitry Andric // Get the value we are storing into the global, then merge it.
1617344a3780SDimitry Andric mergeInValue(I->second, GV, getValueState(SI.getOperand(0)),
1618344a3780SDimitry Andric ValueLatticeElement::MergeOptions().setCheckWiden(false));
1619344a3780SDimitry Andric if (I->second.isOverdefined())
1620344a3780SDimitry Andric TrackedGlobals.erase(I); // No need to keep tracking this!
1621344a3780SDimitry Andric }
1622344a3780SDimitry Andric
getValueFromMetadata(const Instruction * I)1623344a3780SDimitry Andric static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
1624ac9a064cSDimitry Andric if (I->getType()->isIntOrIntVectorTy()) {
1625344a3780SDimitry Andric if (MDNode *Ranges = I->getMetadata(LLVMContext::MD_range))
1626344a3780SDimitry Andric return ValueLatticeElement::getRange(
1627344a3780SDimitry Andric getConstantRangeFromMetadata(*Ranges));
1628ac9a064cSDimitry Andric
1629ac9a064cSDimitry Andric if (const auto *CB = dyn_cast<CallBase>(I))
1630ac9a064cSDimitry Andric if (std::optional<ConstantRange> Range = CB->getRange())
1631ac9a064cSDimitry Andric return ValueLatticeElement::getRange(*Range);
1632ac9a064cSDimitry Andric }
1633344a3780SDimitry Andric if (I->hasMetadata(LLVMContext::MD_nonnull))
1634344a3780SDimitry Andric return ValueLatticeElement::getNot(
1635344a3780SDimitry Andric ConstantPointerNull::get(cast<PointerType>(I->getType())));
1636344a3780SDimitry Andric return ValueLatticeElement::getOverdefined();
1637344a3780SDimitry Andric }
1638344a3780SDimitry Andric
1639344a3780SDimitry Andric // Handle load instructions. If the operand is a constant pointer to a constant
1640344a3780SDimitry Andric // global, we can replace the load with the loaded constant value!
visitLoadInst(LoadInst & I)1641344a3780SDimitry Andric void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
1642344a3780SDimitry Andric // If this load is of a struct or the load is volatile, just mark the result
1643344a3780SDimitry Andric // as overdefined.
1644344a3780SDimitry Andric if (I.getType()->isStructTy() || I.isVolatile())
1645344a3780SDimitry Andric return (void)markOverdefined(&I);
1646344a3780SDimitry Andric
1647344a3780SDimitry Andric // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1648344a3780SDimitry Andric // discover a concrete value later.
1649344a3780SDimitry Andric if (ValueState[&I].isOverdefined())
1650344a3780SDimitry Andric return (void)markOverdefined(&I);
1651344a3780SDimitry Andric
1652344a3780SDimitry Andric ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
1653344a3780SDimitry Andric if (PtrVal.isUnknownOrUndef())
1654344a3780SDimitry Andric return; // The pointer is not resolved yet!
1655344a3780SDimitry Andric
1656344a3780SDimitry Andric ValueLatticeElement &IV = ValueState[&I];
1657344a3780SDimitry Andric
1658e3b55780SDimitry Andric if (SCCPSolver::isConstant(PtrVal)) {
16597fa27ce4SDimitry Andric Constant *Ptr = getConstant(PtrVal, I.getOperand(0)->getType());
1660344a3780SDimitry Andric
1661344a3780SDimitry Andric // load null is undefined.
1662344a3780SDimitry Andric if (isa<ConstantPointerNull>(Ptr)) {
1663344a3780SDimitry Andric if (NullPointerIsDefined(I.getFunction(), I.getPointerAddressSpace()))
1664344a3780SDimitry Andric return (void)markOverdefined(IV, &I);
1665344a3780SDimitry Andric else
1666344a3780SDimitry Andric return;
1667344a3780SDimitry Andric }
1668344a3780SDimitry Andric
1669344a3780SDimitry Andric // Transform load (constant global) into the value loaded.
1670344a3780SDimitry Andric if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
1671344a3780SDimitry Andric if (!TrackedGlobals.empty()) {
1672344a3780SDimitry Andric // If we are tracking this global, merge in the known value for it.
1673344a3780SDimitry Andric auto It = TrackedGlobals.find(GV);
1674344a3780SDimitry Andric if (It != TrackedGlobals.end()) {
1675344a3780SDimitry Andric mergeInValue(IV, &I, It->second, getMaxWidenStepsOpts());
1676344a3780SDimitry Andric return;
1677344a3780SDimitry Andric }
1678344a3780SDimitry Andric }
1679344a3780SDimitry Andric }
1680344a3780SDimitry Andric
1681344a3780SDimitry Andric // Transform load from a constant into a constant if possible.
16821f917f69SDimitry Andric if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL))
1683344a3780SDimitry Andric return (void)markConstant(IV, &I, C);
1684344a3780SDimitry Andric }
1685344a3780SDimitry Andric
1686344a3780SDimitry Andric // Fall back to metadata.
1687344a3780SDimitry Andric mergeInValue(&I, getValueFromMetadata(&I));
1688344a3780SDimitry Andric }
1689344a3780SDimitry Andric
visitCallBase(CallBase & CB)1690344a3780SDimitry Andric void SCCPInstVisitor::visitCallBase(CallBase &CB) {
1691344a3780SDimitry Andric handleCallResult(CB);
1692344a3780SDimitry Andric handleCallArguments(CB);
1693344a3780SDimitry Andric }
1694344a3780SDimitry Andric
handleCallOverdefined(CallBase & CB)1695344a3780SDimitry Andric void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
1696344a3780SDimitry Andric Function *F = CB.getCalledFunction();
1697344a3780SDimitry Andric
1698344a3780SDimitry Andric // Void return and not tracking callee, just bail.
1699344a3780SDimitry Andric if (CB.getType()->isVoidTy())
1700344a3780SDimitry Andric return;
1701344a3780SDimitry Andric
1702344a3780SDimitry Andric // Always mark struct return as overdefined.
1703344a3780SDimitry Andric if (CB.getType()->isStructTy())
1704344a3780SDimitry Andric return (void)markOverdefined(&CB);
1705344a3780SDimitry Andric
1706344a3780SDimitry Andric // Otherwise, if we have a single return value case, and if the function is
1707344a3780SDimitry Andric // a declaration, maybe we can constant fold it.
1708344a3780SDimitry Andric if (F && F->isDeclaration() && canConstantFoldCallTo(&CB, F)) {
1709344a3780SDimitry Andric SmallVector<Constant *, 8> Operands;
1710c0981da4SDimitry Andric for (const Use &A : CB.args()) {
1711c0981da4SDimitry Andric if (A.get()->getType()->isStructTy())
1712344a3780SDimitry Andric return markOverdefined(&CB); // Can't handle struct args.
1713e3b55780SDimitry Andric if (A.get()->getType()->isMetadataTy())
1714e3b55780SDimitry Andric continue; // Carried in CB, not allowed in Operands.
1715c0981da4SDimitry Andric ValueLatticeElement State = getValueState(A);
1716344a3780SDimitry Andric
1717344a3780SDimitry Andric if (State.isUnknownOrUndef())
1718344a3780SDimitry Andric return; // Operands are not resolved yet.
1719e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(State))
1720344a3780SDimitry Andric return (void)markOverdefined(&CB);
1721e3b55780SDimitry Andric assert(SCCPSolver::isConstant(State) && "Unknown state!");
17227fa27ce4SDimitry Andric Operands.push_back(getConstant(State, A->getType()));
1723344a3780SDimitry Andric }
1724344a3780SDimitry Andric
1725e3b55780SDimitry Andric if (SCCPSolver::isOverdefined(getValueState(&CB)))
1726344a3780SDimitry Andric return (void)markOverdefined(&CB);
1727344a3780SDimitry Andric
1728344a3780SDimitry Andric // If we can constant fold this, mark the result of the call as a
1729344a3780SDimitry Andric // constant.
17301f917f69SDimitry Andric if (Constant *C = ConstantFoldCall(&CB, F, Operands, &GetTLI(*F)))
1731344a3780SDimitry Andric return (void)markConstant(&CB, C);
1732344a3780SDimitry Andric }
1733344a3780SDimitry Andric
1734344a3780SDimitry Andric // Fall back to metadata.
1735344a3780SDimitry Andric mergeInValue(&CB, getValueFromMetadata(&CB));
1736344a3780SDimitry Andric }
1737344a3780SDimitry Andric
handleCallArguments(CallBase & CB)1738344a3780SDimitry Andric void SCCPInstVisitor::handleCallArguments(CallBase &CB) {
1739344a3780SDimitry Andric Function *F = CB.getCalledFunction();
1740344a3780SDimitry Andric // If this is a local function that doesn't have its address taken, mark its
1741344a3780SDimitry Andric // entry block executable and merge in the actual arguments to the call into
1742344a3780SDimitry Andric // the formal arguments of the function.
1743e3b55780SDimitry Andric if (TrackingIncomingArguments.count(F)) {
1744344a3780SDimitry Andric markBlockExecutable(&F->front());
1745344a3780SDimitry Andric
1746344a3780SDimitry Andric // Propagate information from this call site into the callee.
1747344a3780SDimitry Andric auto CAI = CB.arg_begin();
1748344a3780SDimitry Andric for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
1749344a3780SDimitry Andric ++AI, ++CAI) {
1750344a3780SDimitry Andric // If this argument is byval, and if the function is not readonly, there
1751344a3780SDimitry Andric // will be an implicit copy formed of the input aggregate.
1752344a3780SDimitry Andric if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
1753344a3780SDimitry Andric markOverdefined(&*AI);
1754344a3780SDimitry Andric continue;
1755344a3780SDimitry Andric }
1756344a3780SDimitry Andric
1757344a3780SDimitry Andric if (auto *STy = dyn_cast<StructType>(AI->getType())) {
1758344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1759344a3780SDimitry Andric ValueLatticeElement CallArg = getStructValueState(*CAI, i);
1760344a3780SDimitry Andric mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1761344a3780SDimitry Andric getMaxWidenStepsOpts());
1762344a3780SDimitry Andric }
1763344a3780SDimitry Andric } else
1764344a3780SDimitry Andric mergeInValue(&*AI, getValueState(*CAI), getMaxWidenStepsOpts());
1765344a3780SDimitry Andric }
1766344a3780SDimitry Andric }
1767344a3780SDimitry Andric }
1768344a3780SDimitry Andric
handleCallResult(CallBase & CB)1769344a3780SDimitry Andric void SCCPInstVisitor::handleCallResult(CallBase &CB) {
1770344a3780SDimitry Andric Function *F = CB.getCalledFunction();
1771344a3780SDimitry Andric
1772344a3780SDimitry Andric if (auto *II = dyn_cast<IntrinsicInst>(&CB)) {
1773344a3780SDimitry Andric if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
1774344a3780SDimitry Andric if (ValueState[&CB].isOverdefined())
1775344a3780SDimitry Andric return;
1776344a3780SDimitry Andric
1777344a3780SDimitry Andric Value *CopyOf = CB.getOperand(0);
1778344a3780SDimitry Andric ValueLatticeElement CopyOfVal = getValueState(CopyOf);
1779344a3780SDimitry Andric const auto *PI = getPredicateInfoFor(&CB);
1780344a3780SDimitry Andric assert(PI && "Missing predicate info for ssa.copy");
1781344a3780SDimitry Andric
1782e3b55780SDimitry Andric const std::optional<PredicateConstraint> &Constraint =
1783e3b55780SDimitry Andric PI->getConstraint();
1784344a3780SDimitry Andric if (!Constraint) {
1785344a3780SDimitry Andric mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1786344a3780SDimitry Andric return;
1787344a3780SDimitry Andric }
1788344a3780SDimitry Andric
1789344a3780SDimitry Andric CmpInst::Predicate Pred = Constraint->Predicate;
1790344a3780SDimitry Andric Value *OtherOp = Constraint->OtherOp;
1791344a3780SDimitry Andric
1792344a3780SDimitry Andric // Wait until OtherOp is resolved.
1793344a3780SDimitry Andric if (getValueState(OtherOp).isUnknown()) {
1794344a3780SDimitry Andric addAdditionalUser(OtherOp, &CB);
1795344a3780SDimitry Andric return;
1796344a3780SDimitry Andric }
1797344a3780SDimitry Andric
1798344a3780SDimitry Andric ValueLatticeElement CondVal = getValueState(OtherOp);
1799344a3780SDimitry Andric ValueLatticeElement &IV = ValueState[&CB];
1800344a3780SDimitry Andric if (CondVal.isConstantRange() || CopyOfVal.isConstantRange()) {
1801344a3780SDimitry Andric auto ImposedCR =
1802344a3780SDimitry Andric ConstantRange::getFull(DL.getTypeSizeInBits(CopyOf->getType()));
1803344a3780SDimitry Andric
1804344a3780SDimitry Andric // Get the range imposed by the condition.
1805344a3780SDimitry Andric if (CondVal.isConstantRange())
1806344a3780SDimitry Andric ImposedCR = ConstantRange::makeAllowedICmpRegion(
1807344a3780SDimitry Andric Pred, CondVal.getConstantRange());
1808344a3780SDimitry Andric
1809344a3780SDimitry Andric // Combine range info for the original value with the new range from the
1810344a3780SDimitry Andric // condition.
1811ac9a064cSDimitry Andric auto CopyOfCR = CopyOfVal.asConstantRange(CopyOf->getType(),
1812ac9a064cSDimitry Andric /*UndefAllowed=*/true);
1813ac9a064cSDimitry Andric // Treat an unresolved input like a full range.
1814ac9a064cSDimitry Andric if (CopyOfCR.isEmptySet())
1815ac9a064cSDimitry Andric CopyOfCR = ConstantRange::getFull(CopyOfCR.getBitWidth());
1816344a3780SDimitry Andric auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1817344a3780SDimitry Andric // If the existing information is != x, do not use the information from
1818344a3780SDimitry Andric // a chained predicate, as the != x information is more likely to be
1819344a3780SDimitry Andric // helpful in practice.
1820344a3780SDimitry Andric if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1821344a3780SDimitry Andric NewCR = CopyOfCR;
1822344a3780SDimitry Andric
1823145449b1SDimitry Andric // The new range is based on a branch condition. That guarantees that
1824145449b1SDimitry Andric // neither of the compare operands can be undef in the branch targets,
1825145449b1SDimitry Andric // unless we have conditions that are always true/false (e.g. icmp ule
1826145449b1SDimitry Andric // i32, %a, i32_max). For the latter overdefined/empty range will be
1827145449b1SDimitry Andric // inferred, but the branch will get folded accordingly anyways.
1828344a3780SDimitry Andric addAdditionalUser(OtherOp, &CB);
1829145449b1SDimitry Andric mergeInValue(
1830145449b1SDimitry Andric IV, &CB,
1831145449b1SDimitry Andric ValueLatticeElement::getRange(NewCR, /*MayIncludeUndef*/ false));
1832344a3780SDimitry Andric return;
1833e3b55780SDimitry Andric } else if (Pred == CmpInst::ICMP_EQ &&
1834e3b55780SDimitry Andric (CondVal.isConstant() || CondVal.isNotConstant())) {
1835344a3780SDimitry Andric // For non-integer values or integer constant expressions, only
1836e3b55780SDimitry Andric // propagate equal constants or not-constants.
1837344a3780SDimitry Andric addAdditionalUser(OtherOp, &CB);
1838344a3780SDimitry Andric mergeInValue(IV, &CB, CondVal);
1839344a3780SDimitry Andric return;
1840145449b1SDimitry Andric } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant()) {
1841344a3780SDimitry Andric // Propagate inequalities.
1842344a3780SDimitry Andric addAdditionalUser(OtherOp, &CB);
1843344a3780SDimitry Andric mergeInValue(IV, &CB,
1844344a3780SDimitry Andric ValueLatticeElement::getNot(CondVal.getConstant()));
1845344a3780SDimitry Andric return;
1846344a3780SDimitry Andric }
1847344a3780SDimitry Andric
1848344a3780SDimitry Andric return (void)mergeInValue(IV, &CB, CopyOfVal);
1849344a3780SDimitry Andric }
1850344a3780SDimitry Andric
1851344a3780SDimitry Andric if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
1852344a3780SDimitry Andric // Compute result range for intrinsics supported by ConstantRange.
1853344a3780SDimitry Andric // Do this even if we don't know a range for all operands, as we may
1854344a3780SDimitry Andric // still know something about the result range, e.g. of abs(x).
1855344a3780SDimitry Andric SmallVector<ConstantRange, 2> OpRanges;
1856344a3780SDimitry Andric for (Value *Op : II->args()) {
1857344a3780SDimitry Andric const ValueLatticeElement &State = getValueState(Op);
18587fa27ce4SDimitry Andric if (State.isUnknownOrUndef())
18597fa27ce4SDimitry Andric return;
1860ac9a064cSDimitry Andric OpRanges.push_back(
1861ac9a064cSDimitry Andric State.asConstantRange(Op->getType(), /*UndefAllowed=*/false));
1862344a3780SDimitry Andric }
1863344a3780SDimitry Andric
1864344a3780SDimitry Andric ConstantRange Result =
1865344a3780SDimitry Andric ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
1866344a3780SDimitry Andric return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
1867344a3780SDimitry Andric }
1868344a3780SDimitry Andric }
1869344a3780SDimitry Andric
1870344a3780SDimitry Andric // The common case is that we aren't tracking the callee, either because we
1871344a3780SDimitry Andric // are not doing interprocedural analysis or the callee is indirect, or is
1872344a3780SDimitry Andric // external. Handle these cases first.
1873344a3780SDimitry Andric if (!F || F->isDeclaration())
1874344a3780SDimitry Andric return handleCallOverdefined(CB);
1875344a3780SDimitry Andric
1876344a3780SDimitry Andric // If this is a single/zero retval case, see if we're tracking the function.
1877344a3780SDimitry Andric if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
1878344a3780SDimitry Andric if (!MRVFunctionsTracked.count(F))
1879344a3780SDimitry Andric return handleCallOverdefined(CB); // Not tracking this callee.
1880344a3780SDimitry Andric
1881344a3780SDimitry Andric // If we are tracking this callee, propagate the result of the function
1882344a3780SDimitry Andric // into this call site.
1883344a3780SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1884344a3780SDimitry Andric mergeInValue(getStructValueState(&CB, i), &CB,
1885344a3780SDimitry Andric TrackedMultipleRetVals[std::make_pair(F, i)],
1886344a3780SDimitry Andric getMaxWidenStepsOpts());
1887344a3780SDimitry Andric } else {
1888344a3780SDimitry Andric auto TFRVI = TrackedRetVals.find(F);
1889344a3780SDimitry Andric if (TFRVI == TrackedRetVals.end())
1890344a3780SDimitry Andric return handleCallOverdefined(CB); // Not tracking this callee.
1891344a3780SDimitry Andric
1892344a3780SDimitry Andric // If so, propagate the return value of the callee into this call result.
1893344a3780SDimitry Andric mergeInValue(&CB, TFRVI->second, getMaxWidenStepsOpts());
1894344a3780SDimitry Andric }
1895344a3780SDimitry Andric }
1896344a3780SDimitry Andric
solve()1897344a3780SDimitry Andric void SCCPInstVisitor::solve() {
1898344a3780SDimitry Andric // Process the work lists until they are empty!
1899344a3780SDimitry Andric while (!BBWorkList.empty() || !InstWorkList.empty() ||
1900344a3780SDimitry Andric !OverdefinedInstWorkList.empty()) {
1901344a3780SDimitry Andric // Process the overdefined instruction's work list first, which drives other
1902344a3780SDimitry Andric // things to overdefined more quickly.
1903344a3780SDimitry Andric while (!OverdefinedInstWorkList.empty()) {
1904344a3780SDimitry Andric Value *I = OverdefinedInstWorkList.pop_back_val();
19057fa27ce4SDimitry Andric Invalidated.erase(I);
1906344a3780SDimitry Andric
1907344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "\nPopped off OI-WL: " << *I << '\n');
1908344a3780SDimitry Andric
1909344a3780SDimitry Andric // "I" got into the work list because it either made the transition from
1910344a3780SDimitry Andric // bottom to constant, or to overdefined.
1911344a3780SDimitry Andric //
1912344a3780SDimitry Andric // Anything on this worklist that is overdefined need not be visited
1913344a3780SDimitry Andric // since all of its users will have already been marked as overdefined
1914344a3780SDimitry Andric // Update all of the users of this instruction's value.
1915344a3780SDimitry Andric //
1916344a3780SDimitry Andric markUsersAsChanged(I);
1917344a3780SDimitry Andric }
1918344a3780SDimitry Andric
1919344a3780SDimitry Andric // Process the instruction work list.
1920344a3780SDimitry Andric while (!InstWorkList.empty()) {
1921344a3780SDimitry Andric Value *I = InstWorkList.pop_back_val();
19227fa27ce4SDimitry Andric Invalidated.erase(I);
1923344a3780SDimitry Andric
1924344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "\nPopped off I-WL: " << *I << '\n');
1925344a3780SDimitry Andric
1926344a3780SDimitry Andric // "I" got into the work list because it made the transition from undef to
1927344a3780SDimitry Andric // constant.
1928344a3780SDimitry Andric //
1929344a3780SDimitry Andric // Anything on this worklist that is overdefined need not be visited
1930344a3780SDimitry Andric // since all of its users will have already been marked as overdefined.
1931344a3780SDimitry Andric // Update all of the users of this instruction's value.
1932344a3780SDimitry Andric //
1933344a3780SDimitry Andric if (I->getType()->isStructTy() || !getValueState(I).isOverdefined())
1934344a3780SDimitry Andric markUsersAsChanged(I);
1935344a3780SDimitry Andric }
1936344a3780SDimitry Andric
1937344a3780SDimitry Andric // Process the basic block work list.
1938344a3780SDimitry Andric while (!BBWorkList.empty()) {
1939344a3780SDimitry Andric BasicBlock *BB = BBWorkList.pop_back_val();
1940344a3780SDimitry Andric
1941344a3780SDimitry Andric LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB << '\n');
1942344a3780SDimitry Andric
1943344a3780SDimitry Andric // Notify all instructions in this basic block that they are newly
1944344a3780SDimitry Andric // executable.
1945344a3780SDimitry Andric visit(BB);
1946344a3780SDimitry Andric }
1947344a3780SDimitry Andric }
1948344a3780SDimitry Andric }
1949344a3780SDimitry Andric
resolvedUndef(Instruction & I)19507fa27ce4SDimitry Andric bool SCCPInstVisitor::resolvedUndef(Instruction &I) {
19517fa27ce4SDimitry Andric // Look for instructions which produce undef values.
19527fa27ce4SDimitry Andric if (I.getType()->isVoidTy())
19537fa27ce4SDimitry Andric return false;
19547fa27ce4SDimitry Andric
19557fa27ce4SDimitry Andric if (auto *STy = dyn_cast<StructType>(I.getType())) {
19567fa27ce4SDimitry Andric // Only a few things that can be structs matter for undef.
19577fa27ce4SDimitry Andric
19587fa27ce4SDimitry Andric // Tracked calls must never be marked overdefined in resolvedUndefsIn.
19597fa27ce4SDimitry Andric if (auto *CB = dyn_cast<CallBase>(&I))
19607fa27ce4SDimitry Andric if (Function *F = CB->getCalledFunction())
19617fa27ce4SDimitry Andric if (MRVFunctionsTracked.count(F))
19627fa27ce4SDimitry Andric return false;
19637fa27ce4SDimitry Andric
19647fa27ce4SDimitry Andric // extractvalue and insertvalue don't need to be marked; they are
19657fa27ce4SDimitry Andric // tracked as precisely as their operands.
19667fa27ce4SDimitry Andric if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
19677fa27ce4SDimitry Andric return false;
19687fa27ce4SDimitry Andric // Send the results of everything else to overdefined. We could be
19697fa27ce4SDimitry Andric // more precise than this but it isn't worth bothering.
19707fa27ce4SDimitry Andric for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
19717fa27ce4SDimitry Andric ValueLatticeElement &LV = getStructValueState(&I, i);
19727fa27ce4SDimitry Andric if (LV.isUnknown()) {
19737fa27ce4SDimitry Andric markOverdefined(LV, &I);
19747fa27ce4SDimitry Andric return true;
19757fa27ce4SDimitry Andric }
19767fa27ce4SDimitry Andric }
19777fa27ce4SDimitry Andric return false;
19787fa27ce4SDimitry Andric }
19797fa27ce4SDimitry Andric
19807fa27ce4SDimitry Andric ValueLatticeElement &LV = getValueState(&I);
19817fa27ce4SDimitry Andric if (!LV.isUnknown())
19827fa27ce4SDimitry Andric return false;
19837fa27ce4SDimitry Andric
19847fa27ce4SDimitry Andric // There are two reasons a call can have an undef result
19857fa27ce4SDimitry Andric // 1. It could be tracked.
19867fa27ce4SDimitry Andric // 2. It could be constant-foldable.
19877fa27ce4SDimitry Andric // Because of the way we solve return values, tracked calls must
19887fa27ce4SDimitry Andric // never be marked overdefined in resolvedUndefsIn.
19897fa27ce4SDimitry Andric if (auto *CB = dyn_cast<CallBase>(&I))
19907fa27ce4SDimitry Andric if (Function *F = CB->getCalledFunction())
19917fa27ce4SDimitry Andric if (TrackedRetVals.count(F))
19927fa27ce4SDimitry Andric return false;
19937fa27ce4SDimitry Andric
19947fa27ce4SDimitry Andric if (isa<LoadInst>(I)) {
19957fa27ce4SDimitry Andric // A load here means one of two things: a load of undef from a global,
19967fa27ce4SDimitry Andric // a load from an unknown pointer. Either way, having it return undef
19977fa27ce4SDimitry Andric // is okay.
19987fa27ce4SDimitry Andric return false;
19997fa27ce4SDimitry Andric }
20007fa27ce4SDimitry Andric
20017fa27ce4SDimitry Andric markOverdefined(&I);
20027fa27ce4SDimitry Andric return true;
20037fa27ce4SDimitry Andric }
20047fa27ce4SDimitry Andric
2005145449b1SDimitry Andric /// While solving the dataflow for a function, we don't compute a result for
2006145449b1SDimitry Andric /// operations with an undef operand, to allow undef to be lowered to a
2007145449b1SDimitry Andric /// constant later. For example, constant folding of "zext i8 undef to i16"
2008145449b1SDimitry Andric /// would result in "i16 0", and if undef is later lowered to "i8 1", then the
2009145449b1SDimitry Andric /// zext result would become "i16 1" and would result into an overdefined
2010145449b1SDimitry Andric /// lattice value once merged with the previous result. Not computing the
2011145449b1SDimitry Andric /// result of the zext (treating undef the same as unknown) allows us to handle
2012145449b1SDimitry Andric /// a later undef->constant lowering more optimally.
2013344a3780SDimitry Andric ///
2014145449b1SDimitry Andric /// However, if the operand remains undef when the solver returns, we do need
2015145449b1SDimitry Andric /// to assign some result to the instruction (otherwise we would treat it as
2016145449b1SDimitry Andric /// unreachable). For simplicity, we mark any instructions that are still
2017145449b1SDimitry Andric /// unknown as overdefined.
resolvedUndefsIn(Function & F)2018344a3780SDimitry Andric bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
2019344a3780SDimitry Andric bool MadeChange = false;
2020344a3780SDimitry Andric for (BasicBlock &BB : F) {
2021344a3780SDimitry Andric if (!BBExecutable.count(&BB))
2022344a3780SDimitry Andric continue;
2023344a3780SDimitry Andric
20247fa27ce4SDimitry Andric for (Instruction &I : BB)
20257fa27ce4SDimitry Andric MadeChange |= resolvedUndef(I);
2026344a3780SDimitry Andric }
2027344a3780SDimitry Andric
2028e3b55780SDimitry Andric LLVM_DEBUG(if (MadeChange) dbgs()
2029e3b55780SDimitry Andric << "\nResolved undefs in " << F.getName() << '\n');
2030e3b55780SDimitry Andric
2031344a3780SDimitry Andric return MadeChange;
2032344a3780SDimitry Andric }
2033344a3780SDimitry Andric
2034344a3780SDimitry Andric //===----------------------------------------------------------------------===//
2035344a3780SDimitry Andric //
2036344a3780SDimitry Andric // SCCPSolver implementations
2037344a3780SDimitry Andric //
SCCPSolver(const DataLayout & DL,std::function<const TargetLibraryInfo & (Function &)> GetTLI,LLVMContext & Ctx)2038344a3780SDimitry Andric SCCPSolver::SCCPSolver(
2039344a3780SDimitry Andric const DataLayout &DL,
2040344a3780SDimitry Andric std::function<const TargetLibraryInfo &(Function &)> GetTLI,
2041344a3780SDimitry Andric LLVMContext &Ctx)
2042344a3780SDimitry Andric : Visitor(new SCCPInstVisitor(DL, std::move(GetTLI), Ctx)) {}
2043344a3780SDimitry Andric
2044145449b1SDimitry Andric SCCPSolver::~SCCPSolver() = default;
2045344a3780SDimitry Andric
addPredicateInfo(Function & F,DominatorTree & DT,AssumptionCache & AC)20467fa27ce4SDimitry Andric void SCCPSolver::addPredicateInfo(Function &F, DominatorTree &DT,
20477fa27ce4SDimitry Andric AssumptionCache &AC) {
20487fa27ce4SDimitry Andric Visitor->addPredicateInfo(F, DT, AC);
2049344a3780SDimitry Andric }
2050344a3780SDimitry Andric
markBlockExecutable(BasicBlock * BB)2051344a3780SDimitry Andric bool SCCPSolver::markBlockExecutable(BasicBlock *BB) {
2052344a3780SDimitry Andric return Visitor->markBlockExecutable(BB);
2053344a3780SDimitry Andric }
2054344a3780SDimitry Andric
getPredicateInfoFor(Instruction * I)2055344a3780SDimitry Andric const PredicateBase *SCCPSolver::getPredicateInfoFor(Instruction *I) {
2056344a3780SDimitry Andric return Visitor->getPredicateInfoFor(I);
2057344a3780SDimitry Andric }
2058344a3780SDimitry Andric
trackValueOfGlobalVariable(GlobalVariable * GV)2059344a3780SDimitry Andric void SCCPSolver::trackValueOfGlobalVariable(GlobalVariable *GV) {
2060344a3780SDimitry Andric Visitor->trackValueOfGlobalVariable(GV);
2061344a3780SDimitry Andric }
2062344a3780SDimitry Andric
addTrackedFunction(Function * F)2063344a3780SDimitry Andric void SCCPSolver::addTrackedFunction(Function *F) {
2064344a3780SDimitry Andric Visitor->addTrackedFunction(F);
2065344a3780SDimitry Andric }
2066344a3780SDimitry Andric
addToMustPreserveReturnsInFunctions(Function * F)2067344a3780SDimitry Andric void SCCPSolver::addToMustPreserveReturnsInFunctions(Function *F) {
2068344a3780SDimitry Andric Visitor->addToMustPreserveReturnsInFunctions(F);
2069344a3780SDimitry Andric }
2070344a3780SDimitry Andric
mustPreserveReturn(Function * F)2071344a3780SDimitry Andric bool SCCPSolver::mustPreserveReturn(Function *F) {
2072344a3780SDimitry Andric return Visitor->mustPreserveReturn(F);
2073344a3780SDimitry Andric }
2074344a3780SDimitry Andric
addArgumentTrackedFunction(Function * F)2075344a3780SDimitry Andric void SCCPSolver::addArgumentTrackedFunction(Function *F) {
2076344a3780SDimitry Andric Visitor->addArgumentTrackedFunction(F);
2077344a3780SDimitry Andric }
2078344a3780SDimitry Andric
isArgumentTrackedFunction(Function * F)2079344a3780SDimitry Andric bool SCCPSolver::isArgumentTrackedFunction(Function *F) {
2080344a3780SDimitry Andric return Visitor->isArgumentTrackedFunction(F);
2081344a3780SDimitry Andric }
2082344a3780SDimitry Andric
solve()2083344a3780SDimitry Andric void SCCPSolver::solve() { Visitor->solve(); }
2084344a3780SDimitry Andric
resolvedUndefsIn(Function & F)2085344a3780SDimitry Andric bool SCCPSolver::resolvedUndefsIn(Function &F) {
2086344a3780SDimitry Andric return Visitor->resolvedUndefsIn(F);
2087344a3780SDimitry Andric }
2088344a3780SDimitry Andric
solveWhileResolvedUndefsIn(Module & M)2089e3b55780SDimitry Andric void SCCPSolver::solveWhileResolvedUndefsIn(Module &M) {
2090e3b55780SDimitry Andric Visitor->solveWhileResolvedUndefsIn(M);
2091e3b55780SDimitry Andric }
2092e3b55780SDimitry Andric
2093e3b55780SDimitry Andric void
solveWhileResolvedUndefsIn(SmallVectorImpl<Function * > & WorkList)2094e3b55780SDimitry Andric SCCPSolver::solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList) {
2095e3b55780SDimitry Andric Visitor->solveWhileResolvedUndefsIn(WorkList);
2096e3b55780SDimitry Andric }
2097e3b55780SDimitry Andric
solveWhileResolvedUndefs()20987fa27ce4SDimitry Andric void SCCPSolver::solveWhileResolvedUndefs() {
20997fa27ce4SDimitry Andric Visitor->solveWhileResolvedUndefs();
21007fa27ce4SDimitry Andric }
21017fa27ce4SDimitry Andric
isBlockExecutable(BasicBlock * BB) const2102344a3780SDimitry Andric bool SCCPSolver::isBlockExecutable(BasicBlock *BB) const {
2103344a3780SDimitry Andric return Visitor->isBlockExecutable(BB);
2104344a3780SDimitry Andric }
2105344a3780SDimitry Andric
isEdgeFeasible(BasicBlock * From,BasicBlock * To) const2106344a3780SDimitry Andric bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
2107344a3780SDimitry Andric return Visitor->isEdgeFeasible(From, To);
2108344a3780SDimitry Andric }
2109344a3780SDimitry Andric
2110344a3780SDimitry Andric std::vector<ValueLatticeElement>
getStructLatticeValueFor(Value * V) const2111344a3780SDimitry Andric SCCPSolver::getStructLatticeValueFor(Value *V) const {
2112344a3780SDimitry Andric return Visitor->getStructLatticeValueFor(V);
2113344a3780SDimitry Andric }
2114344a3780SDimitry Andric
removeLatticeValueFor(Value * V)2115344a3780SDimitry Andric void SCCPSolver::removeLatticeValueFor(Value *V) {
2116344a3780SDimitry Andric return Visitor->removeLatticeValueFor(V);
2117344a3780SDimitry Andric }
2118344a3780SDimitry Andric
resetLatticeValueFor(CallBase * Call)21197fa27ce4SDimitry Andric void SCCPSolver::resetLatticeValueFor(CallBase *Call) {
21207fa27ce4SDimitry Andric Visitor->resetLatticeValueFor(Call);
21217fa27ce4SDimitry Andric }
21227fa27ce4SDimitry Andric
getLatticeValueFor(Value * V) const2123344a3780SDimitry Andric const ValueLatticeElement &SCCPSolver::getLatticeValueFor(Value *V) const {
2124344a3780SDimitry Andric return Visitor->getLatticeValueFor(V);
2125344a3780SDimitry Andric }
2126344a3780SDimitry Andric
2127344a3780SDimitry Andric const MapVector<Function *, ValueLatticeElement> &
getTrackedRetVals()2128344a3780SDimitry Andric SCCPSolver::getTrackedRetVals() {
2129344a3780SDimitry Andric return Visitor->getTrackedRetVals();
2130344a3780SDimitry Andric }
2131344a3780SDimitry Andric
2132344a3780SDimitry Andric const DenseMap<GlobalVariable *, ValueLatticeElement> &
getTrackedGlobals()2133344a3780SDimitry Andric SCCPSolver::getTrackedGlobals() {
2134344a3780SDimitry Andric return Visitor->getTrackedGlobals();
2135344a3780SDimitry Andric }
2136344a3780SDimitry Andric
getMRVFunctionsTracked()2137344a3780SDimitry Andric const SmallPtrSet<Function *, 16> SCCPSolver::getMRVFunctionsTracked() {
2138344a3780SDimitry Andric return Visitor->getMRVFunctionsTracked();
2139344a3780SDimitry Andric }
2140344a3780SDimitry Andric
markOverdefined(Value * V)2141344a3780SDimitry Andric void SCCPSolver::markOverdefined(Value *V) { Visitor->markOverdefined(V); }
2142344a3780SDimitry Andric
trackValueOfArgument(Argument * V)2143ac9a064cSDimitry Andric void SCCPSolver::trackValueOfArgument(Argument *V) {
2144ac9a064cSDimitry Andric Visitor->trackValueOfArgument(V);
2145ac9a064cSDimitry Andric }
2146ac9a064cSDimitry Andric
isStructLatticeConstant(Function * F,StructType * STy)2147344a3780SDimitry Andric bool SCCPSolver::isStructLatticeConstant(Function *F, StructType *STy) {
2148344a3780SDimitry Andric return Visitor->isStructLatticeConstant(F, STy);
2149344a3780SDimitry Andric }
2150344a3780SDimitry Andric
getConstant(const ValueLatticeElement & LV,Type * Ty) const21517fa27ce4SDimitry Andric Constant *SCCPSolver::getConstant(const ValueLatticeElement &LV,
21527fa27ce4SDimitry Andric Type *Ty) const {
21537fa27ce4SDimitry Andric return Visitor->getConstant(LV, Ty);
21547fa27ce4SDimitry Andric }
21557fa27ce4SDimitry Andric
getConstantOrNull(Value * V) const21567fa27ce4SDimitry Andric Constant *SCCPSolver::getConstantOrNull(Value *V) const {
21577fa27ce4SDimitry Andric return Visitor->getConstantOrNull(V);
2158344a3780SDimitry Andric }
2159344a3780SDimitry Andric
getArgumentTrackedFunctions()2160344a3780SDimitry Andric SmallPtrSetImpl<Function *> &SCCPSolver::getArgumentTrackedFunctions() {
2161344a3780SDimitry Andric return Visitor->getArgumentTrackedFunctions();
2162344a3780SDimitry Andric }
2163344a3780SDimitry Andric
setLatticeValueForSpecializationArguments(Function * F,const SmallVectorImpl<ArgInfo> & Args)21647fa27ce4SDimitry Andric void SCCPSolver::setLatticeValueForSpecializationArguments(Function *F,
21657fa27ce4SDimitry Andric const SmallVectorImpl<ArgInfo> &Args) {
21667fa27ce4SDimitry Andric Visitor->setLatticeValueForSpecializationArguments(F, Args);
2167344a3780SDimitry Andric }
2168344a3780SDimitry Andric
markFunctionUnreachable(Function * F)2169344a3780SDimitry Andric void SCCPSolver::markFunctionUnreachable(Function *F) {
2170344a3780SDimitry Andric Visitor->markFunctionUnreachable(F);
2171344a3780SDimitry Andric }
2172344a3780SDimitry Andric
visit(Instruction * I)2173344a3780SDimitry Andric void SCCPSolver::visit(Instruction *I) { Visitor->visit(I); }
2174344a3780SDimitry Andric
visitCall(CallInst & I)2175344a3780SDimitry Andric void SCCPSolver::visitCall(CallInst &I) { Visitor->visitCall(I); }
2176