xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/Utils/SCCPSolver.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1*fe6060f1SDimitry Andric //===- SCCPSolver.cpp - SCCP Utility --------------------------- *- C++ -*-===//
2*fe6060f1SDimitry Andric //
3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*fe6060f1SDimitry Andric //
7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8*fe6060f1SDimitry Andric //
9*fe6060f1SDimitry Andric // \file
10*fe6060f1SDimitry Andric // This file implements the Sparse Conditional Constant Propagation (SCCP)
11*fe6060f1SDimitry Andric // utility.
12*fe6060f1SDimitry Andric //
13*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
14*fe6060f1SDimitry Andric 
15*fe6060f1SDimitry Andric #include "llvm/Transforms/Utils/SCCPSolver.h"
16*fe6060f1SDimitry Andric #include "llvm/Analysis/ConstantFolding.h"
17*fe6060f1SDimitry Andric #include "llvm/Analysis/InstructionSimplify.h"
18*fe6060f1SDimitry Andric #include "llvm/Analysis/ValueTracking.h"
19*fe6060f1SDimitry Andric #include "llvm/InitializePasses.h"
20*fe6060f1SDimitry Andric #include "llvm/Pass.h"
21*fe6060f1SDimitry Andric #include "llvm/Support/Casting.h"
22*fe6060f1SDimitry Andric #include "llvm/Support/Debug.h"
23*fe6060f1SDimitry Andric #include "llvm/Support/ErrorHandling.h"
24*fe6060f1SDimitry Andric #include "llvm/Support/raw_ostream.h"
25*fe6060f1SDimitry Andric #include "llvm/Transforms/Utils/Local.h"
26*fe6060f1SDimitry Andric #include <cassert>
27*fe6060f1SDimitry Andric #include <utility>
28*fe6060f1SDimitry Andric #include <vector>
29*fe6060f1SDimitry Andric 
30*fe6060f1SDimitry Andric using namespace llvm;
31*fe6060f1SDimitry Andric 
32*fe6060f1SDimitry Andric #define DEBUG_TYPE "sccp"
33*fe6060f1SDimitry Andric 
34*fe6060f1SDimitry Andric // The maximum number of range extensions allowed for operations requiring
35*fe6060f1SDimitry Andric // widening.
36*fe6060f1SDimitry Andric static const unsigned MaxNumRangeExtensions = 10;
37*fe6060f1SDimitry Andric 
38*fe6060f1SDimitry Andric /// Returns MergeOptions with MaxWidenSteps set to MaxNumRangeExtensions.
39*fe6060f1SDimitry Andric static ValueLatticeElement::MergeOptions getMaxWidenStepsOpts() {
40*fe6060f1SDimitry Andric   return ValueLatticeElement::MergeOptions().setMaxWidenSteps(
41*fe6060f1SDimitry Andric       MaxNumRangeExtensions);
42*fe6060f1SDimitry Andric }
43*fe6060f1SDimitry Andric 
44*fe6060f1SDimitry Andric namespace {
45*fe6060f1SDimitry Andric 
46*fe6060f1SDimitry Andric // Helper to check if \p LV is either a constant or a constant
47*fe6060f1SDimitry Andric // range with a single element. This should cover exactly the same cases as the
48*fe6060f1SDimitry Andric // old ValueLatticeElement::isConstant() and is intended to be used in the
49*fe6060f1SDimitry Andric // transition to ValueLatticeElement.
50*fe6060f1SDimitry Andric bool isConstant(const ValueLatticeElement &LV) {
51*fe6060f1SDimitry Andric   return LV.isConstant() ||
52*fe6060f1SDimitry Andric          (LV.isConstantRange() && LV.getConstantRange().isSingleElement());
53*fe6060f1SDimitry Andric }
54*fe6060f1SDimitry Andric 
55*fe6060f1SDimitry Andric // Helper to check if \p LV is either overdefined or a constant range with more
56*fe6060f1SDimitry Andric // than a single element. This should cover exactly the same cases as the old
57*fe6060f1SDimitry Andric // ValueLatticeElement::isOverdefined() and is intended to be used in the
58*fe6060f1SDimitry Andric // transition to ValueLatticeElement.
59*fe6060f1SDimitry Andric bool isOverdefined(const ValueLatticeElement &LV) {
60*fe6060f1SDimitry Andric   return !LV.isUnknownOrUndef() && !isConstant(LV);
61*fe6060f1SDimitry Andric }
62*fe6060f1SDimitry Andric 
63*fe6060f1SDimitry Andric } // namespace
64*fe6060f1SDimitry Andric 
65*fe6060f1SDimitry Andric namespace llvm {
66*fe6060f1SDimitry Andric 
67*fe6060f1SDimitry Andric /// Helper class for SCCPSolver. This implements the instruction visitor and
68*fe6060f1SDimitry Andric /// holds all the state.
69*fe6060f1SDimitry Andric class SCCPInstVisitor : public InstVisitor<SCCPInstVisitor> {
70*fe6060f1SDimitry Andric   const DataLayout &DL;
71*fe6060f1SDimitry Andric   std::function<const TargetLibraryInfo &(Function &)> GetTLI;
72*fe6060f1SDimitry Andric   SmallPtrSet<BasicBlock *, 8> BBExecutable; // The BBs that are executable.
73*fe6060f1SDimitry Andric   DenseMap<Value *, ValueLatticeElement>
74*fe6060f1SDimitry Andric       ValueState; // The state each value is in.
75*fe6060f1SDimitry Andric 
76*fe6060f1SDimitry Andric   /// StructValueState - This maintains ValueState for values that have
77*fe6060f1SDimitry Andric   /// StructType, for example for formal arguments, calls, insertelement, etc.
78*fe6060f1SDimitry Andric   DenseMap<std::pair<Value *, unsigned>, ValueLatticeElement> StructValueState;
79*fe6060f1SDimitry Andric 
80*fe6060f1SDimitry Andric   /// GlobalValue - If we are tracking any values for the contents of a global
81*fe6060f1SDimitry Andric   /// variable, we keep a mapping from the constant accessor to the element of
82*fe6060f1SDimitry Andric   /// the global, to the currently known value.  If the value becomes
83*fe6060f1SDimitry Andric   /// overdefined, it's entry is simply removed from this map.
84*fe6060f1SDimitry Andric   DenseMap<GlobalVariable *, ValueLatticeElement> TrackedGlobals;
85*fe6060f1SDimitry Andric 
86*fe6060f1SDimitry Andric   /// TrackedRetVals - If we are tracking arguments into and the return
87*fe6060f1SDimitry Andric   /// value out of a function, it will have an entry in this map, indicating
88*fe6060f1SDimitry Andric   /// what the known return value for the function is.
89*fe6060f1SDimitry Andric   MapVector<Function *, ValueLatticeElement> TrackedRetVals;
90*fe6060f1SDimitry Andric 
91*fe6060f1SDimitry Andric   /// TrackedMultipleRetVals - Same as TrackedRetVals, but used for functions
92*fe6060f1SDimitry Andric   /// that return multiple values.
93*fe6060f1SDimitry Andric   MapVector<std::pair<Function *, unsigned>, ValueLatticeElement>
94*fe6060f1SDimitry Andric       TrackedMultipleRetVals;
95*fe6060f1SDimitry Andric 
96*fe6060f1SDimitry Andric   /// MRVFunctionsTracked - Each function in TrackedMultipleRetVals is
97*fe6060f1SDimitry Andric   /// represented here for efficient lookup.
98*fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> MRVFunctionsTracked;
99*fe6060f1SDimitry Andric 
100*fe6060f1SDimitry Andric   /// A list of functions whose return cannot be modified.
101*fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> MustPreserveReturnsInFunctions;
102*fe6060f1SDimitry Andric 
103*fe6060f1SDimitry Andric   /// TrackingIncomingArguments - This is the set of functions for whose
104*fe6060f1SDimitry Andric   /// arguments we make optimistic assumptions about and try to prove as
105*fe6060f1SDimitry Andric   /// constants.
106*fe6060f1SDimitry Andric   SmallPtrSet<Function *, 16> TrackingIncomingArguments;
107*fe6060f1SDimitry Andric 
108*fe6060f1SDimitry Andric   /// The reason for two worklists is that overdefined is the lowest state
109*fe6060f1SDimitry Andric   /// on the lattice, and moving things to overdefined as fast as possible
110*fe6060f1SDimitry Andric   /// makes SCCP converge much faster.
111*fe6060f1SDimitry Andric   ///
112*fe6060f1SDimitry Andric   /// By having a separate worklist, we accomplish this because everything
113*fe6060f1SDimitry Andric   /// possibly overdefined will become overdefined at the soonest possible
114*fe6060f1SDimitry Andric   /// point.
115*fe6060f1SDimitry Andric   SmallVector<Value *, 64> OverdefinedInstWorkList;
116*fe6060f1SDimitry Andric   SmallVector<Value *, 64> InstWorkList;
117*fe6060f1SDimitry Andric 
118*fe6060f1SDimitry Andric   // The BasicBlock work list
119*fe6060f1SDimitry Andric   SmallVector<BasicBlock *, 64> BBWorkList;
120*fe6060f1SDimitry Andric 
121*fe6060f1SDimitry Andric   /// KnownFeasibleEdges - Entries in this set are edges which have already had
122*fe6060f1SDimitry Andric   /// PHI nodes retriggered.
123*fe6060f1SDimitry Andric   using Edge = std::pair<BasicBlock *, BasicBlock *>;
124*fe6060f1SDimitry Andric   DenseSet<Edge> KnownFeasibleEdges;
125*fe6060f1SDimitry Andric 
126*fe6060f1SDimitry Andric   DenseMap<Function *, AnalysisResultsForFn> AnalysisResults;
127*fe6060f1SDimitry Andric   DenseMap<Value *, SmallPtrSet<User *, 2>> AdditionalUsers;
128*fe6060f1SDimitry Andric 
129*fe6060f1SDimitry Andric   LLVMContext &Ctx;
130*fe6060f1SDimitry Andric 
131*fe6060f1SDimitry Andric private:
132*fe6060f1SDimitry Andric   ConstantInt *getConstantInt(const ValueLatticeElement &IV) const {
133*fe6060f1SDimitry Andric     return dyn_cast_or_null<ConstantInt>(getConstant(IV));
134*fe6060f1SDimitry Andric   }
135*fe6060f1SDimitry Andric 
136*fe6060f1SDimitry Andric   // pushToWorkList - Helper for markConstant/markOverdefined
137*fe6060f1SDimitry Andric   void pushToWorkList(ValueLatticeElement &IV, Value *V);
138*fe6060f1SDimitry Andric 
139*fe6060f1SDimitry Andric   // Helper to push \p V to the worklist, after updating it to \p IV. Also
140*fe6060f1SDimitry Andric   // prints a debug message with the updated value.
141*fe6060f1SDimitry Andric   void pushToWorkListMsg(ValueLatticeElement &IV, Value *V);
142*fe6060f1SDimitry Andric 
143*fe6060f1SDimitry Andric   // markConstant - Make a value be marked as "constant".  If the value
144*fe6060f1SDimitry Andric   // is not already a constant, add it to the instruction work list so that
145*fe6060f1SDimitry Andric   // the users of the instruction are updated later.
146*fe6060f1SDimitry Andric   bool markConstant(ValueLatticeElement &IV, Value *V, Constant *C,
147*fe6060f1SDimitry Andric                     bool MayIncludeUndef = false);
148*fe6060f1SDimitry Andric 
149*fe6060f1SDimitry Andric   bool markConstant(Value *V, Constant *C) {
150*fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() && "structs should use mergeInValue");
151*fe6060f1SDimitry Andric     return markConstant(ValueState[V], V, C);
152*fe6060f1SDimitry Andric   }
153*fe6060f1SDimitry Andric 
154*fe6060f1SDimitry Andric   // markOverdefined - Make a value be marked as "overdefined". If the
155*fe6060f1SDimitry Andric   // value is not already overdefined, add it to the overdefined instruction
156*fe6060f1SDimitry Andric   // work list so that the users of the instruction are updated later.
157*fe6060f1SDimitry Andric   bool markOverdefined(ValueLatticeElement &IV, Value *V);
158*fe6060f1SDimitry Andric 
159*fe6060f1SDimitry Andric   /// Merge \p MergeWithV into \p IV and push \p V to the worklist, if \p IV
160*fe6060f1SDimitry Andric   /// changes.
161*fe6060f1SDimitry Andric   bool mergeInValue(ValueLatticeElement &IV, Value *V,
162*fe6060f1SDimitry Andric                     ValueLatticeElement MergeWithV,
163*fe6060f1SDimitry Andric                     ValueLatticeElement::MergeOptions Opts = {
164*fe6060f1SDimitry Andric                         /*MayIncludeUndef=*/false, /*CheckWiden=*/false});
165*fe6060f1SDimitry Andric 
166*fe6060f1SDimitry Andric   bool mergeInValue(Value *V, ValueLatticeElement MergeWithV,
167*fe6060f1SDimitry Andric                     ValueLatticeElement::MergeOptions Opts = {
168*fe6060f1SDimitry Andric                         /*MayIncludeUndef=*/false, /*CheckWiden=*/false}) {
169*fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() &&
170*fe6060f1SDimitry Andric            "non-structs should use markConstant");
171*fe6060f1SDimitry Andric     return mergeInValue(ValueState[V], V, MergeWithV, Opts);
172*fe6060f1SDimitry Andric   }
173*fe6060f1SDimitry Andric 
174*fe6060f1SDimitry Andric   /// getValueState - Return the ValueLatticeElement object that corresponds to
175*fe6060f1SDimitry Andric   /// the value.  This function handles the case when the value hasn't been seen
176*fe6060f1SDimitry Andric   /// yet by properly seeding constants etc.
177*fe6060f1SDimitry Andric   ValueLatticeElement &getValueState(Value *V) {
178*fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() && "Should use getStructValueState");
179*fe6060f1SDimitry Andric 
180*fe6060f1SDimitry Andric     auto I = ValueState.insert(std::make_pair(V, ValueLatticeElement()));
181*fe6060f1SDimitry Andric     ValueLatticeElement &LV = I.first->second;
182*fe6060f1SDimitry Andric 
183*fe6060f1SDimitry Andric     if (!I.second)
184*fe6060f1SDimitry Andric       return LV; // Common case, already in the map.
185*fe6060f1SDimitry Andric 
186*fe6060f1SDimitry Andric     if (auto *C = dyn_cast<Constant>(V))
187*fe6060f1SDimitry Andric       LV.markConstant(C); // Constants are constant
188*fe6060f1SDimitry Andric 
189*fe6060f1SDimitry Andric     // All others are unknown by default.
190*fe6060f1SDimitry Andric     return LV;
191*fe6060f1SDimitry Andric   }
192*fe6060f1SDimitry Andric 
193*fe6060f1SDimitry Andric   /// getStructValueState - Return the ValueLatticeElement object that
194*fe6060f1SDimitry Andric   /// corresponds to the value/field pair.  This function handles the case when
195*fe6060f1SDimitry Andric   /// the value hasn't been seen yet by properly seeding constants etc.
196*fe6060f1SDimitry Andric   ValueLatticeElement &getStructValueState(Value *V, unsigned i) {
197*fe6060f1SDimitry Andric     assert(V->getType()->isStructTy() && "Should use getValueState");
198*fe6060f1SDimitry Andric     assert(i < cast<StructType>(V->getType())->getNumElements() &&
199*fe6060f1SDimitry Andric            "Invalid element #");
200*fe6060f1SDimitry Andric 
201*fe6060f1SDimitry Andric     auto I = StructValueState.insert(
202*fe6060f1SDimitry Andric         std::make_pair(std::make_pair(V, i), ValueLatticeElement()));
203*fe6060f1SDimitry Andric     ValueLatticeElement &LV = I.first->second;
204*fe6060f1SDimitry Andric 
205*fe6060f1SDimitry Andric     if (!I.second)
206*fe6060f1SDimitry Andric       return LV; // Common case, already in the map.
207*fe6060f1SDimitry Andric 
208*fe6060f1SDimitry Andric     if (auto *C = dyn_cast<Constant>(V)) {
209*fe6060f1SDimitry Andric       Constant *Elt = C->getAggregateElement(i);
210*fe6060f1SDimitry Andric 
211*fe6060f1SDimitry Andric       if (!Elt)
212*fe6060f1SDimitry Andric         LV.markOverdefined(); // Unknown sort of constant.
213*fe6060f1SDimitry Andric       else if (isa<UndefValue>(Elt))
214*fe6060f1SDimitry Andric         ; // Undef values remain unknown.
215*fe6060f1SDimitry Andric       else
216*fe6060f1SDimitry Andric         LV.markConstant(Elt); // Constants are constant.
217*fe6060f1SDimitry Andric     }
218*fe6060f1SDimitry Andric 
219*fe6060f1SDimitry Andric     // All others are underdefined by default.
220*fe6060f1SDimitry Andric     return LV;
221*fe6060f1SDimitry Andric   }
222*fe6060f1SDimitry Andric 
223*fe6060f1SDimitry Andric   /// markEdgeExecutable - Mark a basic block as executable, adding it to the BB
224*fe6060f1SDimitry Andric   /// work list if it is not already executable.
225*fe6060f1SDimitry Andric   bool markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest);
226*fe6060f1SDimitry Andric 
227*fe6060f1SDimitry Andric   // getFeasibleSuccessors - Return a vector of booleans to indicate which
228*fe6060f1SDimitry Andric   // successors are reachable from a given terminator instruction.
229*fe6060f1SDimitry Andric   void getFeasibleSuccessors(Instruction &TI, SmallVectorImpl<bool> &Succs);
230*fe6060f1SDimitry Andric 
231*fe6060f1SDimitry Andric   // OperandChangedState - This method is invoked on all of the users of an
232*fe6060f1SDimitry Andric   // instruction that was just changed state somehow.  Based on this
233*fe6060f1SDimitry Andric   // information, we need to update the specified user of this instruction.
234*fe6060f1SDimitry Andric   void operandChangedState(Instruction *I) {
235*fe6060f1SDimitry Andric     if (BBExecutable.count(I->getParent())) // Inst is executable?
236*fe6060f1SDimitry Andric       visit(*I);
237*fe6060f1SDimitry Andric   }
238*fe6060f1SDimitry Andric 
239*fe6060f1SDimitry Andric   // Add U as additional user of V.
240*fe6060f1SDimitry Andric   void addAdditionalUser(Value *V, User *U) {
241*fe6060f1SDimitry Andric     auto Iter = AdditionalUsers.insert({V, {}});
242*fe6060f1SDimitry Andric     Iter.first->second.insert(U);
243*fe6060f1SDimitry Andric   }
244*fe6060f1SDimitry Andric 
245*fe6060f1SDimitry Andric   // Mark I's users as changed, including AdditionalUsers.
246*fe6060f1SDimitry Andric   void markUsersAsChanged(Value *I) {
247*fe6060f1SDimitry Andric     // Functions include their arguments in the use-list. Changed function
248*fe6060f1SDimitry Andric     // values mean that the result of the function changed. We only need to
249*fe6060f1SDimitry Andric     // update the call sites with the new function result and do not have to
250*fe6060f1SDimitry Andric     // propagate the call arguments.
251*fe6060f1SDimitry Andric     if (isa<Function>(I)) {
252*fe6060f1SDimitry Andric       for (User *U : I->users()) {
253*fe6060f1SDimitry Andric         if (auto *CB = dyn_cast<CallBase>(U))
254*fe6060f1SDimitry Andric           handleCallResult(*CB);
255*fe6060f1SDimitry Andric       }
256*fe6060f1SDimitry Andric     } else {
257*fe6060f1SDimitry Andric       for (User *U : I->users())
258*fe6060f1SDimitry Andric         if (auto *UI = dyn_cast<Instruction>(U))
259*fe6060f1SDimitry Andric           operandChangedState(UI);
260*fe6060f1SDimitry Andric     }
261*fe6060f1SDimitry Andric 
262*fe6060f1SDimitry Andric     auto Iter = AdditionalUsers.find(I);
263*fe6060f1SDimitry Andric     if (Iter != AdditionalUsers.end()) {
264*fe6060f1SDimitry Andric       // Copy additional users before notifying them of changes, because new
265*fe6060f1SDimitry Andric       // users may be added, potentially invalidating the iterator.
266*fe6060f1SDimitry Andric       SmallVector<Instruction *, 2> ToNotify;
267*fe6060f1SDimitry Andric       for (User *U : Iter->second)
268*fe6060f1SDimitry Andric         if (auto *UI = dyn_cast<Instruction>(U))
269*fe6060f1SDimitry Andric           ToNotify.push_back(UI);
270*fe6060f1SDimitry Andric       for (Instruction *UI : ToNotify)
271*fe6060f1SDimitry Andric         operandChangedState(UI);
272*fe6060f1SDimitry Andric     }
273*fe6060f1SDimitry Andric   }
274*fe6060f1SDimitry Andric   void handleCallOverdefined(CallBase &CB);
275*fe6060f1SDimitry Andric   void handleCallResult(CallBase &CB);
276*fe6060f1SDimitry Andric   void handleCallArguments(CallBase &CB);
277*fe6060f1SDimitry Andric 
278*fe6060f1SDimitry Andric private:
279*fe6060f1SDimitry Andric   friend class InstVisitor<SCCPInstVisitor>;
280*fe6060f1SDimitry Andric 
281*fe6060f1SDimitry Andric   // visit implementations - Something changed in this instruction.  Either an
282*fe6060f1SDimitry Andric   // operand made a transition, or the instruction is newly executable.  Change
283*fe6060f1SDimitry Andric   // the value type of I to reflect these changes if appropriate.
284*fe6060f1SDimitry Andric   void visitPHINode(PHINode &I);
285*fe6060f1SDimitry Andric 
286*fe6060f1SDimitry Andric   // Terminators
287*fe6060f1SDimitry Andric 
288*fe6060f1SDimitry Andric   void visitReturnInst(ReturnInst &I);
289*fe6060f1SDimitry Andric   void visitTerminator(Instruction &TI);
290*fe6060f1SDimitry Andric 
291*fe6060f1SDimitry Andric   void visitCastInst(CastInst &I);
292*fe6060f1SDimitry Andric   void visitSelectInst(SelectInst &I);
293*fe6060f1SDimitry Andric   void visitUnaryOperator(Instruction &I);
294*fe6060f1SDimitry Andric   void visitBinaryOperator(Instruction &I);
295*fe6060f1SDimitry Andric   void visitCmpInst(CmpInst &I);
296*fe6060f1SDimitry Andric   void visitExtractValueInst(ExtractValueInst &EVI);
297*fe6060f1SDimitry Andric   void visitInsertValueInst(InsertValueInst &IVI);
298*fe6060f1SDimitry Andric 
299*fe6060f1SDimitry Andric   void visitCatchSwitchInst(CatchSwitchInst &CPI) {
300*fe6060f1SDimitry Andric     markOverdefined(&CPI);
301*fe6060f1SDimitry Andric     visitTerminator(CPI);
302*fe6060f1SDimitry Andric   }
303*fe6060f1SDimitry Andric 
304*fe6060f1SDimitry Andric   // Instructions that cannot be folded away.
305*fe6060f1SDimitry Andric 
306*fe6060f1SDimitry Andric   void visitStoreInst(StoreInst &I);
307*fe6060f1SDimitry Andric   void visitLoadInst(LoadInst &I);
308*fe6060f1SDimitry Andric   void visitGetElementPtrInst(GetElementPtrInst &I);
309*fe6060f1SDimitry Andric 
310*fe6060f1SDimitry Andric   void visitInvokeInst(InvokeInst &II) {
311*fe6060f1SDimitry Andric     visitCallBase(II);
312*fe6060f1SDimitry Andric     visitTerminator(II);
313*fe6060f1SDimitry Andric   }
314*fe6060f1SDimitry Andric 
315*fe6060f1SDimitry Andric   void visitCallBrInst(CallBrInst &CBI) {
316*fe6060f1SDimitry Andric     visitCallBase(CBI);
317*fe6060f1SDimitry Andric     visitTerminator(CBI);
318*fe6060f1SDimitry Andric   }
319*fe6060f1SDimitry Andric 
320*fe6060f1SDimitry Andric   void visitCallBase(CallBase &CB);
321*fe6060f1SDimitry Andric   void visitResumeInst(ResumeInst &I) { /*returns void*/
322*fe6060f1SDimitry Andric   }
323*fe6060f1SDimitry Andric   void visitUnreachableInst(UnreachableInst &I) { /*returns void*/
324*fe6060f1SDimitry Andric   }
325*fe6060f1SDimitry Andric   void visitFenceInst(FenceInst &I) { /*returns void*/
326*fe6060f1SDimitry Andric   }
327*fe6060f1SDimitry Andric 
328*fe6060f1SDimitry Andric   void visitInstruction(Instruction &I);
329*fe6060f1SDimitry Andric 
330*fe6060f1SDimitry Andric public:
331*fe6060f1SDimitry Andric   void addAnalysis(Function &F, AnalysisResultsForFn A) {
332*fe6060f1SDimitry Andric     AnalysisResults.insert({&F, std::move(A)});
333*fe6060f1SDimitry Andric   }
334*fe6060f1SDimitry Andric 
335*fe6060f1SDimitry Andric   void visitCallInst(CallInst &I) { visitCallBase(I); }
336*fe6060f1SDimitry Andric 
337*fe6060f1SDimitry Andric   bool markBlockExecutable(BasicBlock *BB);
338*fe6060f1SDimitry Andric 
339*fe6060f1SDimitry Andric   const PredicateBase *getPredicateInfoFor(Instruction *I) {
340*fe6060f1SDimitry Andric     auto A = AnalysisResults.find(I->getParent()->getParent());
341*fe6060f1SDimitry Andric     if (A == AnalysisResults.end())
342*fe6060f1SDimitry Andric       return nullptr;
343*fe6060f1SDimitry Andric     return A->second.PredInfo->getPredicateInfoFor(I);
344*fe6060f1SDimitry Andric   }
345*fe6060f1SDimitry Andric 
346*fe6060f1SDimitry Andric   DomTreeUpdater getDTU(Function &F) {
347*fe6060f1SDimitry Andric     auto A = AnalysisResults.find(&F);
348*fe6060f1SDimitry Andric     assert(A != AnalysisResults.end() && "Need analysis results for function.");
349*fe6060f1SDimitry Andric     return {A->second.DT, A->second.PDT, DomTreeUpdater::UpdateStrategy::Lazy};
350*fe6060f1SDimitry Andric   }
351*fe6060f1SDimitry Andric 
352*fe6060f1SDimitry Andric   SCCPInstVisitor(const DataLayout &DL,
353*fe6060f1SDimitry Andric                   std::function<const TargetLibraryInfo &(Function &)> GetTLI,
354*fe6060f1SDimitry Andric                   LLVMContext &Ctx)
355*fe6060f1SDimitry Andric       : DL(DL), GetTLI(GetTLI), Ctx(Ctx) {}
356*fe6060f1SDimitry Andric 
357*fe6060f1SDimitry Andric   void trackValueOfGlobalVariable(GlobalVariable *GV) {
358*fe6060f1SDimitry Andric     // We only track the contents of scalar globals.
359*fe6060f1SDimitry Andric     if (GV->getValueType()->isSingleValueType()) {
360*fe6060f1SDimitry Andric       ValueLatticeElement &IV = TrackedGlobals[GV];
361*fe6060f1SDimitry Andric       if (!isa<UndefValue>(GV->getInitializer()))
362*fe6060f1SDimitry Andric         IV.markConstant(GV->getInitializer());
363*fe6060f1SDimitry Andric     }
364*fe6060f1SDimitry Andric   }
365*fe6060f1SDimitry Andric 
366*fe6060f1SDimitry Andric   void addTrackedFunction(Function *F) {
367*fe6060f1SDimitry Andric     // Add an entry, F -> undef.
368*fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
369*fe6060f1SDimitry Andric       MRVFunctionsTracked.insert(F);
370*fe6060f1SDimitry Andric       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
371*fe6060f1SDimitry Andric         TrackedMultipleRetVals.insert(
372*fe6060f1SDimitry Andric             std::make_pair(std::make_pair(F, i), ValueLatticeElement()));
373*fe6060f1SDimitry Andric     } else if (!F->getReturnType()->isVoidTy())
374*fe6060f1SDimitry Andric       TrackedRetVals.insert(std::make_pair(F, ValueLatticeElement()));
375*fe6060f1SDimitry Andric   }
376*fe6060f1SDimitry Andric 
377*fe6060f1SDimitry Andric   void addToMustPreserveReturnsInFunctions(Function *F) {
378*fe6060f1SDimitry Andric     MustPreserveReturnsInFunctions.insert(F);
379*fe6060f1SDimitry Andric   }
380*fe6060f1SDimitry Andric 
381*fe6060f1SDimitry Andric   bool mustPreserveReturn(Function *F) {
382*fe6060f1SDimitry Andric     return MustPreserveReturnsInFunctions.count(F);
383*fe6060f1SDimitry Andric   }
384*fe6060f1SDimitry Andric 
385*fe6060f1SDimitry Andric   void addArgumentTrackedFunction(Function *F) {
386*fe6060f1SDimitry Andric     TrackingIncomingArguments.insert(F);
387*fe6060f1SDimitry Andric   }
388*fe6060f1SDimitry Andric 
389*fe6060f1SDimitry Andric   bool isArgumentTrackedFunction(Function *F) {
390*fe6060f1SDimitry Andric     return TrackingIncomingArguments.count(F);
391*fe6060f1SDimitry Andric   }
392*fe6060f1SDimitry Andric 
393*fe6060f1SDimitry Andric   void solve();
394*fe6060f1SDimitry Andric 
395*fe6060f1SDimitry Andric   bool resolvedUndefsIn(Function &F);
396*fe6060f1SDimitry Andric 
397*fe6060f1SDimitry Andric   bool isBlockExecutable(BasicBlock *BB) const {
398*fe6060f1SDimitry Andric     return BBExecutable.count(BB);
399*fe6060f1SDimitry Andric   }
400*fe6060f1SDimitry Andric 
401*fe6060f1SDimitry Andric   bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
402*fe6060f1SDimitry Andric 
403*fe6060f1SDimitry Andric   std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const {
404*fe6060f1SDimitry Andric     std::vector<ValueLatticeElement> StructValues;
405*fe6060f1SDimitry Andric     auto *STy = dyn_cast<StructType>(V->getType());
406*fe6060f1SDimitry Andric     assert(STy && "getStructLatticeValueFor() can be called only on structs");
407*fe6060f1SDimitry Andric     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
408*fe6060f1SDimitry Andric       auto I = StructValueState.find(std::make_pair(V, i));
409*fe6060f1SDimitry Andric       assert(I != StructValueState.end() && "Value not in valuemap!");
410*fe6060f1SDimitry Andric       StructValues.push_back(I->second);
411*fe6060f1SDimitry Andric     }
412*fe6060f1SDimitry Andric     return StructValues;
413*fe6060f1SDimitry Andric   }
414*fe6060f1SDimitry Andric 
415*fe6060f1SDimitry Andric   void removeLatticeValueFor(Value *V) { ValueState.erase(V); }
416*fe6060f1SDimitry Andric 
417*fe6060f1SDimitry Andric   const ValueLatticeElement &getLatticeValueFor(Value *V) const {
418*fe6060f1SDimitry Andric     assert(!V->getType()->isStructTy() &&
419*fe6060f1SDimitry Andric            "Should use getStructLatticeValueFor");
420*fe6060f1SDimitry Andric     DenseMap<Value *, ValueLatticeElement>::const_iterator I =
421*fe6060f1SDimitry Andric         ValueState.find(V);
422*fe6060f1SDimitry Andric     assert(I != ValueState.end() &&
423*fe6060f1SDimitry Andric            "V not found in ValueState nor Paramstate map!");
424*fe6060f1SDimitry Andric     return I->second;
425*fe6060f1SDimitry Andric   }
426*fe6060f1SDimitry Andric 
427*fe6060f1SDimitry Andric   const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() {
428*fe6060f1SDimitry Andric     return TrackedRetVals;
429*fe6060f1SDimitry Andric   }
430*fe6060f1SDimitry Andric 
431*fe6060f1SDimitry Andric   const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals() {
432*fe6060f1SDimitry Andric     return TrackedGlobals;
433*fe6060f1SDimitry Andric   }
434*fe6060f1SDimitry Andric 
435*fe6060f1SDimitry Andric   const SmallPtrSet<Function *, 16> getMRVFunctionsTracked() {
436*fe6060f1SDimitry Andric     return MRVFunctionsTracked;
437*fe6060f1SDimitry Andric   }
438*fe6060f1SDimitry Andric 
439*fe6060f1SDimitry Andric   void markOverdefined(Value *V) {
440*fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(V->getType()))
441*fe6060f1SDimitry Andric       for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
442*fe6060f1SDimitry Andric         markOverdefined(getStructValueState(V, i), V);
443*fe6060f1SDimitry Andric     else
444*fe6060f1SDimitry Andric       markOverdefined(ValueState[V], V);
445*fe6060f1SDimitry Andric   }
446*fe6060f1SDimitry Andric 
447*fe6060f1SDimitry Andric   bool isStructLatticeConstant(Function *F, StructType *STy);
448*fe6060f1SDimitry Andric 
449*fe6060f1SDimitry Andric   Constant *getConstant(const ValueLatticeElement &LV) const;
450*fe6060f1SDimitry Andric 
451*fe6060f1SDimitry Andric   SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() {
452*fe6060f1SDimitry Andric     return TrackingIncomingArguments;
453*fe6060f1SDimitry Andric   }
454*fe6060f1SDimitry Andric 
455*fe6060f1SDimitry Andric   void markArgInFuncSpecialization(Function *F, Argument *A, Constant *C);
456*fe6060f1SDimitry Andric 
457*fe6060f1SDimitry Andric   void markFunctionUnreachable(Function *F) {
458*fe6060f1SDimitry Andric     for (auto &BB : *F)
459*fe6060f1SDimitry Andric       BBExecutable.erase(&BB);
460*fe6060f1SDimitry Andric   }
461*fe6060f1SDimitry Andric };
462*fe6060f1SDimitry Andric 
463*fe6060f1SDimitry Andric } // namespace llvm
464*fe6060f1SDimitry Andric 
465*fe6060f1SDimitry Andric bool SCCPInstVisitor::markBlockExecutable(BasicBlock *BB) {
466*fe6060f1SDimitry Andric   if (!BBExecutable.insert(BB).second)
467*fe6060f1SDimitry Andric     return false;
468*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "Marking Block Executable: " << BB->getName() << '\n');
469*fe6060f1SDimitry Andric   BBWorkList.push_back(BB); // Add the block to the work list!
470*fe6060f1SDimitry Andric   return true;
471*fe6060f1SDimitry Andric }
472*fe6060f1SDimitry Andric 
473*fe6060f1SDimitry Andric void SCCPInstVisitor::pushToWorkList(ValueLatticeElement &IV, Value *V) {
474*fe6060f1SDimitry Andric   if (IV.isOverdefined())
475*fe6060f1SDimitry Andric     return OverdefinedInstWorkList.push_back(V);
476*fe6060f1SDimitry Andric   InstWorkList.push_back(V);
477*fe6060f1SDimitry Andric }
478*fe6060f1SDimitry Andric 
479*fe6060f1SDimitry Andric void SCCPInstVisitor::pushToWorkListMsg(ValueLatticeElement &IV, Value *V) {
480*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "updated " << IV << ": " << *V << '\n');
481*fe6060f1SDimitry Andric   pushToWorkList(IV, V);
482*fe6060f1SDimitry Andric }
483*fe6060f1SDimitry Andric 
484*fe6060f1SDimitry Andric bool SCCPInstVisitor::markConstant(ValueLatticeElement &IV, Value *V,
485*fe6060f1SDimitry Andric                                    Constant *C, bool MayIncludeUndef) {
486*fe6060f1SDimitry Andric   if (!IV.markConstant(C, MayIncludeUndef))
487*fe6060f1SDimitry Andric     return false;
488*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "markConstant: " << *C << ": " << *V << '\n');
489*fe6060f1SDimitry Andric   pushToWorkList(IV, V);
490*fe6060f1SDimitry Andric   return true;
491*fe6060f1SDimitry Andric }
492*fe6060f1SDimitry Andric 
493*fe6060f1SDimitry Andric bool SCCPInstVisitor::markOverdefined(ValueLatticeElement &IV, Value *V) {
494*fe6060f1SDimitry Andric   if (!IV.markOverdefined())
495*fe6060f1SDimitry Andric     return false;
496*fe6060f1SDimitry Andric 
497*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "markOverdefined: ";
498*fe6060f1SDimitry Andric              if (auto *F = dyn_cast<Function>(V)) dbgs()
499*fe6060f1SDimitry Andric              << "Function '" << F->getName() << "'\n";
500*fe6060f1SDimitry Andric              else dbgs() << *V << '\n');
501*fe6060f1SDimitry Andric   // Only instructions go on the work list
502*fe6060f1SDimitry Andric   pushToWorkList(IV, V);
503*fe6060f1SDimitry Andric   return true;
504*fe6060f1SDimitry Andric }
505*fe6060f1SDimitry Andric 
506*fe6060f1SDimitry Andric bool SCCPInstVisitor::isStructLatticeConstant(Function *F, StructType *STy) {
507*fe6060f1SDimitry Andric   for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
508*fe6060f1SDimitry Andric     const auto &It = TrackedMultipleRetVals.find(std::make_pair(F, i));
509*fe6060f1SDimitry Andric     assert(It != TrackedMultipleRetVals.end());
510*fe6060f1SDimitry Andric     ValueLatticeElement LV = It->second;
511*fe6060f1SDimitry Andric     if (!isConstant(LV))
512*fe6060f1SDimitry Andric       return false;
513*fe6060f1SDimitry Andric   }
514*fe6060f1SDimitry Andric   return true;
515*fe6060f1SDimitry Andric }
516*fe6060f1SDimitry Andric 
517*fe6060f1SDimitry Andric Constant *SCCPInstVisitor::getConstant(const ValueLatticeElement &LV) const {
518*fe6060f1SDimitry Andric   if (LV.isConstant())
519*fe6060f1SDimitry Andric     return LV.getConstant();
520*fe6060f1SDimitry Andric 
521*fe6060f1SDimitry Andric   if (LV.isConstantRange()) {
522*fe6060f1SDimitry Andric     const auto &CR = LV.getConstantRange();
523*fe6060f1SDimitry Andric     if (CR.getSingleElement())
524*fe6060f1SDimitry Andric       return ConstantInt::get(Ctx, *CR.getSingleElement());
525*fe6060f1SDimitry Andric   }
526*fe6060f1SDimitry Andric   return nullptr;
527*fe6060f1SDimitry Andric }
528*fe6060f1SDimitry Andric 
529*fe6060f1SDimitry Andric void SCCPInstVisitor::markArgInFuncSpecialization(Function *F, Argument *A,
530*fe6060f1SDimitry Andric                                                   Constant *C) {
531*fe6060f1SDimitry Andric   assert(F->arg_size() == A->getParent()->arg_size() &&
532*fe6060f1SDimitry Andric          "Functions should have the same number of arguments");
533*fe6060f1SDimitry Andric 
534*fe6060f1SDimitry Andric   // Mark the argument constant in the new function.
535*fe6060f1SDimitry Andric   markConstant(A, C);
536*fe6060f1SDimitry Andric 
537*fe6060f1SDimitry Andric   // For the remaining arguments in the new function, copy the lattice state
538*fe6060f1SDimitry Andric   // over from the old function.
539*fe6060f1SDimitry Andric   for (auto I = F->arg_begin(), J = A->getParent()->arg_begin(),
540*fe6060f1SDimitry Andric             E = F->arg_end();
541*fe6060f1SDimitry Andric        I != E; ++I, ++J)
542*fe6060f1SDimitry Andric     if (J != A && ValueState.count(I)) {
543*fe6060f1SDimitry Andric       ValueState[J] = ValueState[I];
544*fe6060f1SDimitry Andric       pushToWorkList(ValueState[J], J);
545*fe6060f1SDimitry Andric     }
546*fe6060f1SDimitry Andric }
547*fe6060f1SDimitry Andric 
548*fe6060f1SDimitry Andric void SCCPInstVisitor::visitInstruction(Instruction &I) {
549*fe6060f1SDimitry Andric   // All the instructions we don't do any special handling for just
550*fe6060f1SDimitry Andric   // go to overdefined.
551*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "SCCP: Don't know how to handle: " << I << '\n');
552*fe6060f1SDimitry Andric   markOverdefined(&I);
553*fe6060f1SDimitry Andric }
554*fe6060f1SDimitry Andric 
555*fe6060f1SDimitry Andric bool SCCPInstVisitor::mergeInValue(ValueLatticeElement &IV, Value *V,
556*fe6060f1SDimitry Andric                                    ValueLatticeElement MergeWithV,
557*fe6060f1SDimitry Andric                                    ValueLatticeElement::MergeOptions Opts) {
558*fe6060f1SDimitry Andric   if (IV.mergeIn(MergeWithV, Opts)) {
559*fe6060f1SDimitry Andric     pushToWorkList(IV, V);
560*fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "Merged " << MergeWithV << " into " << *V << " : "
561*fe6060f1SDimitry Andric                       << IV << "\n");
562*fe6060f1SDimitry Andric     return true;
563*fe6060f1SDimitry Andric   }
564*fe6060f1SDimitry Andric   return false;
565*fe6060f1SDimitry Andric }
566*fe6060f1SDimitry Andric 
567*fe6060f1SDimitry Andric bool SCCPInstVisitor::markEdgeExecutable(BasicBlock *Source, BasicBlock *Dest) {
568*fe6060f1SDimitry Andric   if (!KnownFeasibleEdges.insert(Edge(Source, Dest)).second)
569*fe6060f1SDimitry Andric     return false; // This edge is already known to be executable!
570*fe6060f1SDimitry Andric 
571*fe6060f1SDimitry Andric   if (!markBlockExecutable(Dest)) {
572*fe6060f1SDimitry Andric     // If the destination is already executable, we just made an *edge*
573*fe6060f1SDimitry Andric     // feasible that wasn't before.  Revisit the PHI nodes in the block
574*fe6060f1SDimitry Andric     // because they have potentially new operands.
575*fe6060f1SDimitry Andric     LLVM_DEBUG(dbgs() << "Marking Edge Executable: " << Source->getName()
576*fe6060f1SDimitry Andric                       << " -> " << Dest->getName() << '\n');
577*fe6060f1SDimitry Andric 
578*fe6060f1SDimitry Andric     for (PHINode &PN : Dest->phis())
579*fe6060f1SDimitry Andric       visitPHINode(PN);
580*fe6060f1SDimitry Andric   }
581*fe6060f1SDimitry Andric   return true;
582*fe6060f1SDimitry Andric }
583*fe6060f1SDimitry Andric 
584*fe6060f1SDimitry Andric // getFeasibleSuccessors - Return a vector of booleans to indicate which
585*fe6060f1SDimitry Andric // successors are reachable from a given terminator instruction.
586*fe6060f1SDimitry Andric void SCCPInstVisitor::getFeasibleSuccessors(Instruction &TI,
587*fe6060f1SDimitry Andric                                             SmallVectorImpl<bool> &Succs) {
588*fe6060f1SDimitry Andric   Succs.resize(TI.getNumSuccessors());
589*fe6060f1SDimitry Andric   if (auto *BI = dyn_cast<BranchInst>(&TI)) {
590*fe6060f1SDimitry Andric     if (BI->isUnconditional()) {
591*fe6060f1SDimitry Andric       Succs[0] = true;
592*fe6060f1SDimitry Andric       return;
593*fe6060f1SDimitry Andric     }
594*fe6060f1SDimitry Andric 
595*fe6060f1SDimitry Andric     ValueLatticeElement BCValue = getValueState(BI->getCondition());
596*fe6060f1SDimitry Andric     ConstantInt *CI = getConstantInt(BCValue);
597*fe6060f1SDimitry Andric     if (!CI) {
598*fe6060f1SDimitry Andric       // Overdefined condition variables, and branches on unfoldable constant
599*fe6060f1SDimitry Andric       // conditions, mean the branch could go either way.
600*fe6060f1SDimitry Andric       if (!BCValue.isUnknownOrUndef())
601*fe6060f1SDimitry Andric         Succs[0] = Succs[1] = true;
602*fe6060f1SDimitry Andric       return;
603*fe6060f1SDimitry Andric     }
604*fe6060f1SDimitry Andric 
605*fe6060f1SDimitry Andric     // Constant condition variables mean the branch can only go a single way.
606*fe6060f1SDimitry Andric     Succs[CI->isZero()] = true;
607*fe6060f1SDimitry Andric     return;
608*fe6060f1SDimitry Andric   }
609*fe6060f1SDimitry Andric 
610*fe6060f1SDimitry Andric   // Unwinding instructions successors are always executable.
611*fe6060f1SDimitry Andric   if (TI.isExceptionalTerminator()) {
612*fe6060f1SDimitry Andric     Succs.assign(TI.getNumSuccessors(), true);
613*fe6060f1SDimitry Andric     return;
614*fe6060f1SDimitry Andric   }
615*fe6060f1SDimitry Andric 
616*fe6060f1SDimitry Andric   if (auto *SI = dyn_cast<SwitchInst>(&TI)) {
617*fe6060f1SDimitry Andric     if (!SI->getNumCases()) {
618*fe6060f1SDimitry Andric       Succs[0] = true;
619*fe6060f1SDimitry Andric       return;
620*fe6060f1SDimitry Andric     }
621*fe6060f1SDimitry Andric     const ValueLatticeElement &SCValue = getValueState(SI->getCondition());
622*fe6060f1SDimitry Andric     if (ConstantInt *CI = getConstantInt(SCValue)) {
623*fe6060f1SDimitry Andric       Succs[SI->findCaseValue(CI)->getSuccessorIndex()] = true;
624*fe6060f1SDimitry Andric       return;
625*fe6060f1SDimitry Andric     }
626*fe6060f1SDimitry Andric 
627*fe6060f1SDimitry Andric     // TODO: Switch on undef is UB. Stop passing false once the rest of LLVM
628*fe6060f1SDimitry Andric     // is ready.
629*fe6060f1SDimitry Andric     if (SCValue.isConstantRange(/*UndefAllowed=*/false)) {
630*fe6060f1SDimitry Andric       const ConstantRange &Range = SCValue.getConstantRange();
631*fe6060f1SDimitry Andric       for (const auto &Case : SI->cases()) {
632*fe6060f1SDimitry Andric         const APInt &CaseValue = Case.getCaseValue()->getValue();
633*fe6060f1SDimitry Andric         if (Range.contains(CaseValue))
634*fe6060f1SDimitry Andric           Succs[Case.getSuccessorIndex()] = true;
635*fe6060f1SDimitry Andric       }
636*fe6060f1SDimitry Andric 
637*fe6060f1SDimitry Andric       // TODO: Determine whether default case is reachable.
638*fe6060f1SDimitry Andric       Succs[SI->case_default()->getSuccessorIndex()] = true;
639*fe6060f1SDimitry Andric       return;
640*fe6060f1SDimitry Andric     }
641*fe6060f1SDimitry Andric 
642*fe6060f1SDimitry Andric     // Overdefined or unknown condition? All destinations are executable!
643*fe6060f1SDimitry Andric     if (!SCValue.isUnknownOrUndef())
644*fe6060f1SDimitry Andric       Succs.assign(TI.getNumSuccessors(), true);
645*fe6060f1SDimitry Andric     return;
646*fe6060f1SDimitry Andric   }
647*fe6060f1SDimitry Andric 
648*fe6060f1SDimitry Andric   // In case of indirect branch and its address is a blockaddress, we mark
649*fe6060f1SDimitry Andric   // the target as executable.
650*fe6060f1SDimitry Andric   if (auto *IBR = dyn_cast<IndirectBrInst>(&TI)) {
651*fe6060f1SDimitry Andric     // Casts are folded by visitCastInst.
652*fe6060f1SDimitry Andric     ValueLatticeElement IBRValue = getValueState(IBR->getAddress());
653*fe6060f1SDimitry Andric     BlockAddress *Addr = dyn_cast_or_null<BlockAddress>(getConstant(IBRValue));
654*fe6060f1SDimitry Andric     if (!Addr) { // Overdefined or unknown condition?
655*fe6060f1SDimitry Andric       // All destinations are executable!
656*fe6060f1SDimitry Andric       if (!IBRValue.isUnknownOrUndef())
657*fe6060f1SDimitry Andric         Succs.assign(TI.getNumSuccessors(), true);
658*fe6060f1SDimitry Andric       return;
659*fe6060f1SDimitry Andric     }
660*fe6060f1SDimitry Andric 
661*fe6060f1SDimitry Andric     BasicBlock *T = Addr->getBasicBlock();
662*fe6060f1SDimitry Andric     assert(Addr->getFunction() == T->getParent() &&
663*fe6060f1SDimitry Andric            "Block address of a different function ?");
664*fe6060f1SDimitry Andric     for (unsigned i = 0; i < IBR->getNumSuccessors(); ++i) {
665*fe6060f1SDimitry Andric       // This is the target.
666*fe6060f1SDimitry Andric       if (IBR->getDestination(i) == T) {
667*fe6060f1SDimitry Andric         Succs[i] = true;
668*fe6060f1SDimitry Andric         return;
669*fe6060f1SDimitry Andric       }
670*fe6060f1SDimitry Andric     }
671*fe6060f1SDimitry Andric 
672*fe6060f1SDimitry Andric     // If we didn't find our destination in the IBR successor list, then we
673*fe6060f1SDimitry Andric     // have undefined behavior. Its ok to assume no successor is executable.
674*fe6060f1SDimitry Andric     return;
675*fe6060f1SDimitry Andric   }
676*fe6060f1SDimitry Andric 
677*fe6060f1SDimitry Andric   // In case of callbr, we pessimistically assume that all successors are
678*fe6060f1SDimitry Andric   // feasible.
679*fe6060f1SDimitry Andric   if (isa<CallBrInst>(&TI)) {
680*fe6060f1SDimitry Andric     Succs.assign(TI.getNumSuccessors(), true);
681*fe6060f1SDimitry Andric     return;
682*fe6060f1SDimitry Andric   }
683*fe6060f1SDimitry Andric 
684*fe6060f1SDimitry Andric   LLVM_DEBUG(dbgs() << "Unknown terminator instruction: " << TI << '\n');
685*fe6060f1SDimitry Andric   llvm_unreachable("SCCP: Don't know how to handle this terminator!");
686*fe6060f1SDimitry Andric }
687*fe6060f1SDimitry Andric 
688*fe6060f1SDimitry Andric // isEdgeFeasible - Return true if the control flow edge from the 'From' basic
689*fe6060f1SDimitry Andric // block to the 'To' basic block is currently feasible.
690*fe6060f1SDimitry Andric bool SCCPInstVisitor::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
691*fe6060f1SDimitry Andric   // Check if we've called markEdgeExecutable on the edge yet. (We could
692*fe6060f1SDimitry Andric   // be more aggressive and try to consider edges which haven't been marked
693*fe6060f1SDimitry Andric   // yet, but there isn't any need.)
694*fe6060f1SDimitry Andric   return KnownFeasibleEdges.count(Edge(From, To));
695*fe6060f1SDimitry Andric }
696*fe6060f1SDimitry Andric 
697*fe6060f1SDimitry Andric // visit Implementations - Something changed in this instruction, either an
698*fe6060f1SDimitry Andric // operand made a transition, or the instruction is newly executable.  Change
699*fe6060f1SDimitry Andric // the value type of I to reflect these changes if appropriate.  This method
700*fe6060f1SDimitry Andric // makes sure to do the following actions:
701*fe6060f1SDimitry Andric //
702*fe6060f1SDimitry Andric // 1. If a phi node merges two constants in, and has conflicting value coming
703*fe6060f1SDimitry Andric //    from different branches, or if the PHI node merges in an overdefined
704*fe6060f1SDimitry Andric //    value, then the PHI node becomes overdefined.
705*fe6060f1SDimitry Andric // 2. If a phi node merges only constants in, and they all agree on value, the
706*fe6060f1SDimitry Andric //    PHI node becomes a constant value equal to that.
707*fe6060f1SDimitry Andric // 3. If V <- x (op) y && isConstant(x) && isConstant(y) V = Constant
708*fe6060f1SDimitry Andric // 4. If V <- x (op) y && (isOverdefined(x) || isOverdefined(y)) V = Overdefined
709*fe6060f1SDimitry Andric // 5. If V <- MEM or V <- CALL or V <- (unknown) then V = Overdefined
710*fe6060f1SDimitry Andric // 6. If a conditional branch has a value that is constant, make the selected
711*fe6060f1SDimitry Andric //    destination executable
712*fe6060f1SDimitry Andric // 7. If a conditional branch has a value that is overdefined, make all
713*fe6060f1SDimitry Andric //    successors executable.
714*fe6060f1SDimitry Andric void SCCPInstVisitor::visitPHINode(PHINode &PN) {
715*fe6060f1SDimitry Andric   // If this PN returns a struct, just mark the result overdefined.
716*fe6060f1SDimitry Andric   // TODO: We could do a lot better than this if code actually uses this.
717*fe6060f1SDimitry Andric   if (PN.getType()->isStructTy())
718*fe6060f1SDimitry Andric     return (void)markOverdefined(&PN);
719*fe6060f1SDimitry Andric 
720*fe6060f1SDimitry Andric   if (getValueState(&PN).isOverdefined())
721*fe6060f1SDimitry Andric     return; // Quick exit
722*fe6060f1SDimitry Andric 
723*fe6060f1SDimitry Andric   // Super-extra-high-degree PHI nodes are unlikely to ever be marked constant,
724*fe6060f1SDimitry Andric   // and slow us down a lot.  Just mark them overdefined.
725*fe6060f1SDimitry Andric   if (PN.getNumIncomingValues() > 64)
726*fe6060f1SDimitry Andric     return (void)markOverdefined(&PN);
727*fe6060f1SDimitry Andric 
728*fe6060f1SDimitry Andric   unsigned NumActiveIncoming = 0;
729*fe6060f1SDimitry Andric 
730*fe6060f1SDimitry Andric   // Look at all of the executable operands of the PHI node.  If any of them
731*fe6060f1SDimitry Andric   // are overdefined, the PHI becomes overdefined as well.  If they are all
732*fe6060f1SDimitry Andric   // constant, and they agree with each other, the PHI becomes the identical
733*fe6060f1SDimitry Andric   // constant.  If they are constant and don't agree, the PHI is a constant
734*fe6060f1SDimitry Andric   // range. If there are no executable operands, the PHI remains unknown.
735*fe6060f1SDimitry Andric   ValueLatticeElement PhiState = getValueState(&PN);
736*fe6060f1SDimitry Andric   for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) {
737*fe6060f1SDimitry Andric     if (!isEdgeFeasible(PN.getIncomingBlock(i), PN.getParent()))
738*fe6060f1SDimitry Andric       continue;
739*fe6060f1SDimitry Andric 
740*fe6060f1SDimitry Andric     ValueLatticeElement IV = getValueState(PN.getIncomingValue(i));
741*fe6060f1SDimitry Andric     PhiState.mergeIn(IV);
742*fe6060f1SDimitry Andric     NumActiveIncoming++;
743*fe6060f1SDimitry Andric     if (PhiState.isOverdefined())
744*fe6060f1SDimitry Andric       break;
745*fe6060f1SDimitry Andric   }
746*fe6060f1SDimitry Andric 
747*fe6060f1SDimitry Andric   // We allow up to 1 range extension per active incoming value and one
748*fe6060f1SDimitry Andric   // additional extension. Note that we manually adjust the number of range
749*fe6060f1SDimitry Andric   // extensions to match the number of active incoming values. This helps to
750*fe6060f1SDimitry Andric   // limit multiple extensions caused by the same incoming value, if other
751*fe6060f1SDimitry Andric   // incoming values are equal.
752*fe6060f1SDimitry Andric   mergeInValue(&PN, PhiState,
753*fe6060f1SDimitry Andric                ValueLatticeElement::MergeOptions().setMaxWidenSteps(
754*fe6060f1SDimitry Andric                    NumActiveIncoming + 1));
755*fe6060f1SDimitry Andric   ValueLatticeElement &PhiStateRef = getValueState(&PN);
756*fe6060f1SDimitry Andric   PhiStateRef.setNumRangeExtensions(
757*fe6060f1SDimitry Andric       std::max(NumActiveIncoming, PhiStateRef.getNumRangeExtensions()));
758*fe6060f1SDimitry Andric }
759*fe6060f1SDimitry Andric 
760*fe6060f1SDimitry Andric void SCCPInstVisitor::visitReturnInst(ReturnInst &I) {
761*fe6060f1SDimitry Andric   if (I.getNumOperands() == 0)
762*fe6060f1SDimitry Andric     return; // ret void
763*fe6060f1SDimitry Andric 
764*fe6060f1SDimitry Andric   Function *F = I.getParent()->getParent();
765*fe6060f1SDimitry Andric   Value *ResultOp = I.getOperand(0);
766*fe6060f1SDimitry Andric 
767*fe6060f1SDimitry Andric   // If we are tracking the return value of this function, merge it in.
768*fe6060f1SDimitry Andric   if (!TrackedRetVals.empty() && !ResultOp->getType()->isStructTy()) {
769*fe6060f1SDimitry Andric     auto TFRVI = TrackedRetVals.find(F);
770*fe6060f1SDimitry Andric     if (TFRVI != TrackedRetVals.end()) {
771*fe6060f1SDimitry Andric       mergeInValue(TFRVI->second, F, getValueState(ResultOp));
772*fe6060f1SDimitry Andric       return;
773*fe6060f1SDimitry Andric     }
774*fe6060f1SDimitry Andric   }
775*fe6060f1SDimitry Andric 
776*fe6060f1SDimitry Andric   // Handle functions that return multiple values.
777*fe6060f1SDimitry Andric   if (!TrackedMultipleRetVals.empty()) {
778*fe6060f1SDimitry Andric     if (auto *STy = dyn_cast<StructType>(ResultOp->getType()))
779*fe6060f1SDimitry Andric       if (MRVFunctionsTracked.count(F))
780*fe6060f1SDimitry Andric         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
781*fe6060f1SDimitry Andric           mergeInValue(TrackedMultipleRetVals[std::make_pair(F, i)], F,
782*fe6060f1SDimitry Andric                        getStructValueState(ResultOp, i));
783*fe6060f1SDimitry Andric   }
784*fe6060f1SDimitry Andric }
785*fe6060f1SDimitry Andric 
786*fe6060f1SDimitry Andric void SCCPInstVisitor::visitTerminator(Instruction &TI) {
787*fe6060f1SDimitry Andric   SmallVector<bool, 16> SuccFeasible;
788*fe6060f1SDimitry Andric   getFeasibleSuccessors(TI, SuccFeasible);
789*fe6060f1SDimitry Andric 
790*fe6060f1SDimitry Andric   BasicBlock *BB = TI.getParent();
791*fe6060f1SDimitry Andric 
792*fe6060f1SDimitry Andric   // Mark all feasible successors executable.
793*fe6060f1SDimitry Andric   for (unsigned i = 0, e = SuccFeasible.size(); i != e; ++i)
794*fe6060f1SDimitry Andric     if (SuccFeasible[i])
795*fe6060f1SDimitry Andric       markEdgeExecutable(BB, TI.getSuccessor(i));
796*fe6060f1SDimitry Andric }
797*fe6060f1SDimitry Andric 
798*fe6060f1SDimitry Andric void SCCPInstVisitor::visitCastInst(CastInst &I) {
799*fe6060f1SDimitry Andric   // ResolvedUndefsIn might mark I as overdefined. Bail out, even if we would
800*fe6060f1SDimitry Andric   // discover a concrete value later.
801*fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
802*fe6060f1SDimitry Andric     return;
803*fe6060f1SDimitry Andric 
804*fe6060f1SDimitry Andric   ValueLatticeElement OpSt = getValueState(I.getOperand(0));
805*fe6060f1SDimitry Andric   if (Constant *OpC = getConstant(OpSt)) {
806*fe6060f1SDimitry Andric     // Fold the constant as we build.
807*fe6060f1SDimitry Andric     Constant *C = ConstantFoldCastOperand(I.getOpcode(), OpC, I.getType(), DL);
808*fe6060f1SDimitry Andric     if (isa<UndefValue>(C))
809*fe6060f1SDimitry Andric       return;
810*fe6060f1SDimitry Andric     // Propagate constant value
811*fe6060f1SDimitry Andric     markConstant(&I, C);
812*fe6060f1SDimitry Andric   } else if (OpSt.isConstantRange() && I.getDestTy()->isIntegerTy()) {
813*fe6060f1SDimitry Andric     auto &LV = getValueState(&I);
814*fe6060f1SDimitry Andric     ConstantRange OpRange = OpSt.getConstantRange();
815*fe6060f1SDimitry Andric     Type *DestTy = I.getDestTy();
816*fe6060f1SDimitry Andric     // Vectors where all elements have the same known constant range are treated
817*fe6060f1SDimitry Andric     // as a single constant range in the lattice. When bitcasting such vectors,
818*fe6060f1SDimitry Andric     // there is a mis-match between the width of the lattice value (single
819*fe6060f1SDimitry Andric     // constant range) and the original operands (vector). Go to overdefined in
820*fe6060f1SDimitry Andric     // that case.
821*fe6060f1SDimitry Andric     if (I.getOpcode() == Instruction::BitCast &&
822*fe6060f1SDimitry Andric         I.getOperand(0)->getType()->isVectorTy() &&
823*fe6060f1SDimitry Andric         OpRange.getBitWidth() < DL.getTypeSizeInBits(DestTy))
824*fe6060f1SDimitry Andric       return (void)markOverdefined(&I);
825*fe6060f1SDimitry Andric 
826*fe6060f1SDimitry Andric     ConstantRange Res =
827*fe6060f1SDimitry Andric         OpRange.castOp(I.getOpcode(), DL.getTypeSizeInBits(DestTy));
828*fe6060f1SDimitry Andric     mergeInValue(LV, &I, ValueLatticeElement::getRange(Res));
829*fe6060f1SDimitry Andric   } else if (!OpSt.isUnknownOrUndef())
830*fe6060f1SDimitry Andric     markOverdefined(&I);
831*fe6060f1SDimitry Andric }
832*fe6060f1SDimitry Andric 
833*fe6060f1SDimitry Andric void SCCPInstVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
834*fe6060f1SDimitry Andric   // If this returns a struct, mark all elements over defined, we don't track
835*fe6060f1SDimitry Andric   // structs in structs.
836*fe6060f1SDimitry Andric   if (EVI.getType()->isStructTy())
837*fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
838*fe6060f1SDimitry Andric 
839*fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
840*fe6060f1SDimitry Andric   // discover a concrete value later.
841*fe6060f1SDimitry Andric   if (ValueState[&EVI].isOverdefined())
842*fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
843*fe6060f1SDimitry Andric 
844*fe6060f1SDimitry Andric   // If this is extracting from more than one level of struct, we don't know.
845*fe6060f1SDimitry Andric   if (EVI.getNumIndices() != 1)
846*fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
847*fe6060f1SDimitry Andric 
848*fe6060f1SDimitry Andric   Value *AggVal = EVI.getAggregateOperand();
849*fe6060f1SDimitry Andric   if (AggVal->getType()->isStructTy()) {
850*fe6060f1SDimitry Andric     unsigned i = *EVI.idx_begin();
851*fe6060f1SDimitry Andric     ValueLatticeElement EltVal = getStructValueState(AggVal, i);
852*fe6060f1SDimitry Andric     mergeInValue(getValueState(&EVI), &EVI, EltVal);
853*fe6060f1SDimitry Andric   } else {
854*fe6060f1SDimitry Andric     // Otherwise, must be extracting from an array.
855*fe6060f1SDimitry Andric     return (void)markOverdefined(&EVI);
856*fe6060f1SDimitry Andric   }
857*fe6060f1SDimitry Andric }
858*fe6060f1SDimitry Andric 
859*fe6060f1SDimitry Andric void SCCPInstVisitor::visitInsertValueInst(InsertValueInst &IVI) {
860*fe6060f1SDimitry Andric   auto *STy = dyn_cast<StructType>(IVI.getType());
861*fe6060f1SDimitry Andric   if (!STy)
862*fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
863*fe6060f1SDimitry Andric 
864*fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
865*fe6060f1SDimitry Andric   // discover a concrete value later.
866*fe6060f1SDimitry Andric   if (isOverdefined(ValueState[&IVI]))
867*fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
868*fe6060f1SDimitry Andric 
869*fe6060f1SDimitry Andric   // If this has more than one index, we can't handle it, drive all results to
870*fe6060f1SDimitry Andric   // undef.
871*fe6060f1SDimitry Andric   if (IVI.getNumIndices() != 1)
872*fe6060f1SDimitry Andric     return (void)markOverdefined(&IVI);
873*fe6060f1SDimitry Andric 
874*fe6060f1SDimitry Andric   Value *Aggr = IVI.getAggregateOperand();
875*fe6060f1SDimitry Andric   unsigned Idx = *IVI.idx_begin();
876*fe6060f1SDimitry Andric 
877*fe6060f1SDimitry Andric   // Compute the result based on what we're inserting.
878*fe6060f1SDimitry Andric   for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
879*fe6060f1SDimitry Andric     // This passes through all values that aren't the inserted element.
880*fe6060f1SDimitry Andric     if (i != Idx) {
881*fe6060f1SDimitry Andric       ValueLatticeElement EltVal = getStructValueState(Aggr, i);
882*fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&IVI, i), &IVI, EltVal);
883*fe6060f1SDimitry Andric       continue;
884*fe6060f1SDimitry Andric     }
885*fe6060f1SDimitry Andric 
886*fe6060f1SDimitry Andric     Value *Val = IVI.getInsertedValueOperand();
887*fe6060f1SDimitry Andric     if (Val->getType()->isStructTy())
888*fe6060f1SDimitry Andric       // We don't track structs in structs.
889*fe6060f1SDimitry Andric       markOverdefined(getStructValueState(&IVI, i), &IVI);
890*fe6060f1SDimitry Andric     else {
891*fe6060f1SDimitry Andric       ValueLatticeElement InVal = getValueState(Val);
892*fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&IVI, i), &IVI, InVal);
893*fe6060f1SDimitry Andric     }
894*fe6060f1SDimitry Andric   }
895*fe6060f1SDimitry Andric }
896*fe6060f1SDimitry Andric 
897*fe6060f1SDimitry Andric void SCCPInstVisitor::visitSelectInst(SelectInst &I) {
898*fe6060f1SDimitry Andric   // If this select returns a struct, just mark the result overdefined.
899*fe6060f1SDimitry Andric   // TODO: We could do a lot better than this if code actually uses this.
900*fe6060f1SDimitry Andric   if (I.getType()->isStructTy())
901*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
902*fe6060f1SDimitry Andric 
903*fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
904*fe6060f1SDimitry Andric   // discover a concrete value later.
905*fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
906*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
907*fe6060f1SDimitry Andric 
908*fe6060f1SDimitry Andric   ValueLatticeElement CondValue = getValueState(I.getCondition());
909*fe6060f1SDimitry Andric   if (CondValue.isUnknownOrUndef())
910*fe6060f1SDimitry Andric     return;
911*fe6060f1SDimitry Andric 
912*fe6060f1SDimitry Andric   if (ConstantInt *CondCB = getConstantInt(CondValue)) {
913*fe6060f1SDimitry Andric     Value *OpVal = CondCB->isZero() ? I.getFalseValue() : I.getTrueValue();
914*fe6060f1SDimitry Andric     mergeInValue(&I, getValueState(OpVal));
915*fe6060f1SDimitry Andric     return;
916*fe6060f1SDimitry Andric   }
917*fe6060f1SDimitry Andric 
918*fe6060f1SDimitry Andric   // Otherwise, the condition is overdefined or a constant we can't evaluate.
919*fe6060f1SDimitry Andric   // See if we can produce something better than overdefined based on the T/F
920*fe6060f1SDimitry Andric   // value.
921*fe6060f1SDimitry Andric   ValueLatticeElement TVal = getValueState(I.getTrueValue());
922*fe6060f1SDimitry Andric   ValueLatticeElement FVal = getValueState(I.getFalseValue());
923*fe6060f1SDimitry Andric 
924*fe6060f1SDimitry Andric   bool Changed = ValueState[&I].mergeIn(TVal);
925*fe6060f1SDimitry Andric   Changed |= ValueState[&I].mergeIn(FVal);
926*fe6060f1SDimitry Andric   if (Changed)
927*fe6060f1SDimitry Andric     pushToWorkListMsg(ValueState[&I], &I);
928*fe6060f1SDimitry Andric }
929*fe6060f1SDimitry Andric 
930*fe6060f1SDimitry Andric // Handle Unary Operators.
931*fe6060f1SDimitry Andric void SCCPInstVisitor::visitUnaryOperator(Instruction &I) {
932*fe6060f1SDimitry Andric   ValueLatticeElement V0State = getValueState(I.getOperand(0));
933*fe6060f1SDimitry Andric 
934*fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
935*fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
936*fe6060f1SDimitry Andric   // discover a concrete value later.
937*fe6060f1SDimitry Andric   if (isOverdefined(IV))
938*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
939*fe6060f1SDimitry Andric 
940*fe6060f1SDimitry Andric   if (isConstant(V0State)) {
941*fe6060f1SDimitry Andric     Constant *C = ConstantExpr::get(I.getOpcode(), getConstant(V0State));
942*fe6060f1SDimitry Andric 
943*fe6060f1SDimitry Andric     // op Y -> undef.
944*fe6060f1SDimitry Andric     if (isa<UndefValue>(C))
945*fe6060f1SDimitry Andric       return;
946*fe6060f1SDimitry Andric     return (void)markConstant(IV, &I, C);
947*fe6060f1SDimitry Andric   }
948*fe6060f1SDimitry Andric 
949*fe6060f1SDimitry Andric   // If something is undef, wait for it to resolve.
950*fe6060f1SDimitry Andric   if (!isOverdefined(V0State))
951*fe6060f1SDimitry Andric     return;
952*fe6060f1SDimitry Andric 
953*fe6060f1SDimitry Andric   markOverdefined(&I);
954*fe6060f1SDimitry Andric }
955*fe6060f1SDimitry Andric 
956*fe6060f1SDimitry Andric // Handle Binary Operators.
957*fe6060f1SDimitry Andric void SCCPInstVisitor::visitBinaryOperator(Instruction &I) {
958*fe6060f1SDimitry Andric   ValueLatticeElement V1State = getValueState(I.getOperand(0));
959*fe6060f1SDimitry Andric   ValueLatticeElement V2State = getValueState(I.getOperand(1));
960*fe6060f1SDimitry Andric 
961*fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
962*fe6060f1SDimitry Andric   if (IV.isOverdefined())
963*fe6060f1SDimitry Andric     return;
964*fe6060f1SDimitry Andric 
965*fe6060f1SDimitry Andric   // If something is undef, wait for it to resolve.
966*fe6060f1SDimitry Andric   if (V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef())
967*fe6060f1SDimitry Andric     return;
968*fe6060f1SDimitry Andric 
969*fe6060f1SDimitry Andric   if (V1State.isOverdefined() && V2State.isOverdefined())
970*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
971*fe6060f1SDimitry Andric 
972*fe6060f1SDimitry Andric   // If either of the operands is a constant, try to fold it to a constant.
973*fe6060f1SDimitry Andric   // TODO: Use information from notconstant better.
974*fe6060f1SDimitry Andric   if ((V1State.isConstant() || V2State.isConstant())) {
975*fe6060f1SDimitry Andric     Value *V1 = isConstant(V1State) ? getConstant(V1State) : I.getOperand(0);
976*fe6060f1SDimitry Andric     Value *V2 = isConstant(V2State) ? getConstant(V2State) : I.getOperand(1);
977*fe6060f1SDimitry Andric     Value *R = SimplifyBinOp(I.getOpcode(), V1, V2, SimplifyQuery(DL));
978*fe6060f1SDimitry Andric     auto *C = dyn_cast_or_null<Constant>(R);
979*fe6060f1SDimitry Andric     if (C) {
980*fe6060f1SDimitry Andric       // X op Y -> undef.
981*fe6060f1SDimitry Andric       if (isa<UndefValue>(C))
982*fe6060f1SDimitry Andric         return;
983*fe6060f1SDimitry Andric       // Conservatively assume that the result may be based on operands that may
984*fe6060f1SDimitry Andric       // be undef. Note that we use mergeInValue to combine the constant with
985*fe6060f1SDimitry Andric       // the existing lattice value for I, as different constants might be found
986*fe6060f1SDimitry Andric       // after one of the operands go to overdefined, e.g. due to one operand
987*fe6060f1SDimitry Andric       // being a special floating value.
988*fe6060f1SDimitry Andric       ValueLatticeElement NewV;
989*fe6060f1SDimitry Andric       NewV.markConstant(C, /*MayIncludeUndef=*/true);
990*fe6060f1SDimitry Andric       return (void)mergeInValue(&I, NewV);
991*fe6060f1SDimitry Andric     }
992*fe6060f1SDimitry Andric   }
993*fe6060f1SDimitry Andric 
994*fe6060f1SDimitry Andric   // Only use ranges for binary operators on integers.
995*fe6060f1SDimitry Andric   if (!I.getType()->isIntegerTy())
996*fe6060f1SDimitry Andric     return markOverdefined(&I);
997*fe6060f1SDimitry Andric 
998*fe6060f1SDimitry Andric   // Try to simplify to a constant range.
999*fe6060f1SDimitry Andric   ConstantRange A = ConstantRange::getFull(I.getType()->getScalarSizeInBits());
1000*fe6060f1SDimitry Andric   ConstantRange B = ConstantRange::getFull(I.getType()->getScalarSizeInBits());
1001*fe6060f1SDimitry Andric   if (V1State.isConstantRange())
1002*fe6060f1SDimitry Andric     A = V1State.getConstantRange();
1003*fe6060f1SDimitry Andric   if (V2State.isConstantRange())
1004*fe6060f1SDimitry Andric     B = V2State.getConstantRange();
1005*fe6060f1SDimitry Andric 
1006*fe6060f1SDimitry Andric   ConstantRange R = A.binaryOp(cast<BinaryOperator>(&I)->getOpcode(), B);
1007*fe6060f1SDimitry Andric   mergeInValue(&I, ValueLatticeElement::getRange(R));
1008*fe6060f1SDimitry Andric 
1009*fe6060f1SDimitry Andric   // TODO: Currently we do not exploit special values that produce something
1010*fe6060f1SDimitry Andric   // better than overdefined with an overdefined operand for vector or floating
1011*fe6060f1SDimitry Andric   // point types, like and <4 x i32> overdefined, zeroinitializer.
1012*fe6060f1SDimitry Andric }
1013*fe6060f1SDimitry Andric 
1014*fe6060f1SDimitry Andric // Handle ICmpInst instruction.
1015*fe6060f1SDimitry Andric void SCCPInstVisitor::visitCmpInst(CmpInst &I) {
1016*fe6060f1SDimitry Andric   // Do not cache this lookup, getValueState calls later in the function might
1017*fe6060f1SDimitry Andric   // invalidate the reference.
1018*fe6060f1SDimitry Andric   if (isOverdefined(ValueState[&I]))
1019*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1020*fe6060f1SDimitry Andric 
1021*fe6060f1SDimitry Andric   Value *Op1 = I.getOperand(0);
1022*fe6060f1SDimitry Andric   Value *Op2 = I.getOperand(1);
1023*fe6060f1SDimitry Andric 
1024*fe6060f1SDimitry Andric   // For parameters, use ParamState which includes constant range info if
1025*fe6060f1SDimitry Andric   // available.
1026*fe6060f1SDimitry Andric   auto V1State = getValueState(Op1);
1027*fe6060f1SDimitry Andric   auto V2State = getValueState(Op2);
1028*fe6060f1SDimitry Andric 
1029*fe6060f1SDimitry Andric   Constant *C = V1State.getCompare(I.getPredicate(), I.getType(), V2State);
1030*fe6060f1SDimitry Andric   if (C) {
1031*fe6060f1SDimitry Andric     if (isa<UndefValue>(C))
1032*fe6060f1SDimitry Andric       return;
1033*fe6060f1SDimitry Andric     ValueLatticeElement CV;
1034*fe6060f1SDimitry Andric     CV.markConstant(C);
1035*fe6060f1SDimitry Andric     mergeInValue(&I, CV);
1036*fe6060f1SDimitry Andric     return;
1037*fe6060f1SDimitry Andric   }
1038*fe6060f1SDimitry Andric 
1039*fe6060f1SDimitry Andric   // If operands are still unknown, wait for it to resolve.
1040*fe6060f1SDimitry Andric   if ((V1State.isUnknownOrUndef() || V2State.isUnknownOrUndef()) &&
1041*fe6060f1SDimitry Andric       !isConstant(ValueState[&I]))
1042*fe6060f1SDimitry Andric     return;
1043*fe6060f1SDimitry Andric 
1044*fe6060f1SDimitry Andric   markOverdefined(&I);
1045*fe6060f1SDimitry Andric }
1046*fe6060f1SDimitry Andric 
1047*fe6060f1SDimitry Andric // Handle getelementptr instructions.  If all operands are constants then we
1048*fe6060f1SDimitry Andric // can turn this into a getelementptr ConstantExpr.
1049*fe6060f1SDimitry Andric void SCCPInstVisitor::visitGetElementPtrInst(GetElementPtrInst &I) {
1050*fe6060f1SDimitry Andric   if (isOverdefined(ValueState[&I]))
1051*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1052*fe6060f1SDimitry Andric 
1053*fe6060f1SDimitry Andric   SmallVector<Constant *, 8> Operands;
1054*fe6060f1SDimitry Andric   Operands.reserve(I.getNumOperands());
1055*fe6060f1SDimitry Andric 
1056*fe6060f1SDimitry Andric   for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) {
1057*fe6060f1SDimitry Andric     ValueLatticeElement State = getValueState(I.getOperand(i));
1058*fe6060f1SDimitry Andric     if (State.isUnknownOrUndef())
1059*fe6060f1SDimitry Andric       return; // Operands are not resolved yet.
1060*fe6060f1SDimitry Andric 
1061*fe6060f1SDimitry Andric     if (isOverdefined(State))
1062*fe6060f1SDimitry Andric       return (void)markOverdefined(&I);
1063*fe6060f1SDimitry Andric 
1064*fe6060f1SDimitry Andric     if (Constant *C = getConstant(State)) {
1065*fe6060f1SDimitry Andric       Operands.push_back(C);
1066*fe6060f1SDimitry Andric       continue;
1067*fe6060f1SDimitry Andric     }
1068*fe6060f1SDimitry Andric 
1069*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1070*fe6060f1SDimitry Andric   }
1071*fe6060f1SDimitry Andric 
1072*fe6060f1SDimitry Andric   Constant *Ptr = Operands[0];
1073*fe6060f1SDimitry Andric   auto Indices = makeArrayRef(Operands.begin() + 1, Operands.end());
1074*fe6060f1SDimitry Andric   Constant *C =
1075*fe6060f1SDimitry Andric       ConstantExpr::getGetElementPtr(I.getSourceElementType(), Ptr, Indices);
1076*fe6060f1SDimitry Andric   if (isa<UndefValue>(C))
1077*fe6060f1SDimitry Andric     return;
1078*fe6060f1SDimitry Andric   markConstant(&I, C);
1079*fe6060f1SDimitry Andric }
1080*fe6060f1SDimitry Andric 
1081*fe6060f1SDimitry Andric void SCCPInstVisitor::visitStoreInst(StoreInst &SI) {
1082*fe6060f1SDimitry Andric   // If this store is of a struct, ignore it.
1083*fe6060f1SDimitry Andric   if (SI.getOperand(0)->getType()->isStructTy())
1084*fe6060f1SDimitry Andric     return;
1085*fe6060f1SDimitry Andric 
1086*fe6060f1SDimitry Andric   if (TrackedGlobals.empty() || !isa<GlobalVariable>(SI.getOperand(1)))
1087*fe6060f1SDimitry Andric     return;
1088*fe6060f1SDimitry Andric 
1089*fe6060f1SDimitry Andric   GlobalVariable *GV = cast<GlobalVariable>(SI.getOperand(1));
1090*fe6060f1SDimitry Andric   auto I = TrackedGlobals.find(GV);
1091*fe6060f1SDimitry Andric   if (I == TrackedGlobals.end())
1092*fe6060f1SDimitry Andric     return;
1093*fe6060f1SDimitry Andric 
1094*fe6060f1SDimitry Andric   // Get the value we are storing into the global, then merge it.
1095*fe6060f1SDimitry Andric   mergeInValue(I->second, GV, getValueState(SI.getOperand(0)),
1096*fe6060f1SDimitry Andric                ValueLatticeElement::MergeOptions().setCheckWiden(false));
1097*fe6060f1SDimitry Andric   if (I->second.isOverdefined())
1098*fe6060f1SDimitry Andric     TrackedGlobals.erase(I); // No need to keep tracking this!
1099*fe6060f1SDimitry Andric }
1100*fe6060f1SDimitry Andric 
1101*fe6060f1SDimitry Andric static ValueLatticeElement getValueFromMetadata(const Instruction *I) {
1102*fe6060f1SDimitry Andric   if (MDNode *Ranges = I->getMetadata(LLVMContext::MD_range))
1103*fe6060f1SDimitry Andric     if (I->getType()->isIntegerTy())
1104*fe6060f1SDimitry Andric       return ValueLatticeElement::getRange(
1105*fe6060f1SDimitry Andric           getConstantRangeFromMetadata(*Ranges));
1106*fe6060f1SDimitry Andric   if (I->hasMetadata(LLVMContext::MD_nonnull))
1107*fe6060f1SDimitry Andric     return ValueLatticeElement::getNot(
1108*fe6060f1SDimitry Andric         ConstantPointerNull::get(cast<PointerType>(I->getType())));
1109*fe6060f1SDimitry Andric   return ValueLatticeElement::getOverdefined();
1110*fe6060f1SDimitry Andric }
1111*fe6060f1SDimitry Andric 
1112*fe6060f1SDimitry Andric // Handle load instructions.  If the operand is a constant pointer to a constant
1113*fe6060f1SDimitry Andric // global, we can replace the load with the loaded constant value!
1114*fe6060f1SDimitry Andric void SCCPInstVisitor::visitLoadInst(LoadInst &I) {
1115*fe6060f1SDimitry Andric   // If this load is of a struct or the load is volatile, just mark the result
1116*fe6060f1SDimitry Andric   // as overdefined.
1117*fe6060f1SDimitry Andric   if (I.getType()->isStructTy() || I.isVolatile())
1118*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1119*fe6060f1SDimitry Andric 
1120*fe6060f1SDimitry Andric   // resolvedUndefsIn might mark I as overdefined. Bail out, even if we would
1121*fe6060f1SDimitry Andric   // discover a concrete value later.
1122*fe6060f1SDimitry Andric   if (ValueState[&I].isOverdefined())
1123*fe6060f1SDimitry Andric     return (void)markOverdefined(&I);
1124*fe6060f1SDimitry Andric 
1125*fe6060f1SDimitry Andric   ValueLatticeElement PtrVal = getValueState(I.getOperand(0));
1126*fe6060f1SDimitry Andric   if (PtrVal.isUnknownOrUndef())
1127*fe6060f1SDimitry Andric     return; // The pointer is not resolved yet!
1128*fe6060f1SDimitry Andric 
1129*fe6060f1SDimitry Andric   ValueLatticeElement &IV = ValueState[&I];
1130*fe6060f1SDimitry Andric 
1131*fe6060f1SDimitry Andric   if (isConstant(PtrVal)) {
1132*fe6060f1SDimitry Andric     Constant *Ptr = getConstant(PtrVal);
1133*fe6060f1SDimitry Andric 
1134*fe6060f1SDimitry Andric     // load null is undefined.
1135*fe6060f1SDimitry Andric     if (isa<ConstantPointerNull>(Ptr)) {
1136*fe6060f1SDimitry Andric       if (NullPointerIsDefined(I.getFunction(), I.getPointerAddressSpace()))
1137*fe6060f1SDimitry Andric         return (void)markOverdefined(IV, &I);
1138*fe6060f1SDimitry Andric       else
1139*fe6060f1SDimitry Andric         return;
1140*fe6060f1SDimitry Andric     }
1141*fe6060f1SDimitry Andric 
1142*fe6060f1SDimitry Andric     // Transform load (constant global) into the value loaded.
1143*fe6060f1SDimitry Andric     if (auto *GV = dyn_cast<GlobalVariable>(Ptr)) {
1144*fe6060f1SDimitry Andric       if (!TrackedGlobals.empty()) {
1145*fe6060f1SDimitry Andric         // If we are tracking this global, merge in the known value for it.
1146*fe6060f1SDimitry Andric         auto It = TrackedGlobals.find(GV);
1147*fe6060f1SDimitry Andric         if (It != TrackedGlobals.end()) {
1148*fe6060f1SDimitry Andric           mergeInValue(IV, &I, It->second, getMaxWidenStepsOpts());
1149*fe6060f1SDimitry Andric           return;
1150*fe6060f1SDimitry Andric         }
1151*fe6060f1SDimitry Andric       }
1152*fe6060f1SDimitry Andric     }
1153*fe6060f1SDimitry Andric 
1154*fe6060f1SDimitry Andric     // Transform load from a constant into a constant if possible.
1155*fe6060f1SDimitry Andric     if (Constant *C = ConstantFoldLoadFromConstPtr(Ptr, I.getType(), DL)) {
1156*fe6060f1SDimitry Andric       if (isa<UndefValue>(C))
1157*fe6060f1SDimitry Andric         return;
1158*fe6060f1SDimitry Andric       return (void)markConstant(IV, &I, C);
1159*fe6060f1SDimitry Andric     }
1160*fe6060f1SDimitry Andric   }
1161*fe6060f1SDimitry Andric 
1162*fe6060f1SDimitry Andric   // Fall back to metadata.
1163*fe6060f1SDimitry Andric   mergeInValue(&I, getValueFromMetadata(&I));
1164*fe6060f1SDimitry Andric }
1165*fe6060f1SDimitry Andric 
1166*fe6060f1SDimitry Andric void SCCPInstVisitor::visitCallBase(CallBase &CB) {
1167*fe6060f1SDimitry Andric   handleCallResult(CB);
1168*fe6060f1SDimitry Andric   handleCallArguments(CB);
1169*fe6060f1SDimitry Andric }
1170*fe6060f1SDimitry Andric 
1171*fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallOverdefined(CallBase &CB) {
1172*fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1173*fe6060f1SDimitry Andric 
1174*fe6060f1SDimitry Andric   // Void return and not tracking callee, just bail.
1175*fe6060f1SDimitry Andric   if (CB.getType()->isVoidTy())
1176*fe6060f1SDimitry Andric     return;
1177*fe6060f1SDimitry Andric 
1178*fe6060f1SDimitry Andric   // Always mark struct return as overdefined.
1179*fe6060f1SDimitry Andric   if (CB.getType()->isStructTy())
1180*fe6060f1SDimitry Andric     return (void)markOverdefined(&CB);
1181*fe6060f1SDimitry Andric 
1182*fe6060f1SDimitry Andric   // Otherwise, if we have a single return value case, and if the function is
1183*fe6060f1SDimitry Andric   // a declaration, maybe we can constant fold it.
1184*fe6060f1SDimitry Andric   if (F && F->isDeclaration() && canConstantFoldCallTo(&CB, F)) {
1185*fe6060f1SDimitry Andric     SmallVector<Constant *, 8> Operands;
1186*fe6060f1SDimitry Andric     for (auto AI = CB.arg_begin(), E = CB.arg_end(); AI != E; ++AI) {
1187*fe6060f1SDimitry Andric       if (AI->get()->getType()->isStructTy())
1188*fe6060f1SDimitry Andric         return markOverdefined(&CB); // Can't handle struct args.
1189*fe6060f1SDimitry Andric       ValueLatticeElement State = getValueState(*AI);
1190*fe6060f1SDimitry Andric 
1191*fe6060f1SDimitry Andric       if (State.isUnknownOrUndef())
1192*fe6060f1SDimitry Andric         return; // Operands are not resolved yet.
1193*fe6060f1SDimitry Andric       if (isOverdefined(State))
1194*fe6060f1SDimitry Andric         return (void)markOverdefined(&CB);
1195*fe6060f1SDimitry Andric       assert(isConstant(State) && "Unknown state!");
1196*fe6060f1SDimitry Andric       Operands.push_back(getConstant(State));
1197*fe6060f1SDimitry Andric     }
1198*fe6060f1SDimitry Andric 
1199*fe6060f1SDimitry Andric     if (isOverdefined(getValueState(&CB)))
1200*fe6060f1SDimitry Andric       return (void)markOverdefined(&CB);
1201*fe6060f1SDimitry Andric 
1202*fe6060f1SDimitry Andric     // If we can constant fold this, mark the result of the call as a
1203*fe6060f1SDimitry Andric     // constant.
1204*fe6060f1SDimitry Andric     if (Constant *C = ConstantFoldCall(&CB, F, Operands, &GetTLI(*F))) {
1205*fe6060f1SDimitry Andric       // call -> undef.
1206*fe6060f1SDimitry Andric       if (isa<UndefValue>(C))
1207*fe6060f1SDimitry Andric         return;
1208*fe6060f1SDimitry Andric       return (void)markConstant(&CB, C);
1209*fe6060f1SDimitry Andric     }
1210*fe6060f1SDimitry Andric   }
1211*fe6060f1SDimitry Andric 
1212*fe6060f1SDimitry Andric   // Fall back to metadata.
1213*fe6060f1SDimitry Andric   mergeInValue(&CB, getValueFromMetadata(&CB));
1214*fe6060f1SDimitry Andric }
1215*fe6060f1SDimitry Andric 
1216*fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallArguments(CallBase &CB) {
1217*fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1218*fe6060f1SDimitry Andric   // If this is a local function that doesn't have its address taken, mark its
1219*fe6060f1SDimitry Andric   // entry block executable and merge in the actual arguments to the call into
1220*fe6060f1SDimitry Andric   // the formal arguments of the function.
1221*fe6060f1SDimitry Andric   if (!TrackingIncomingArguments.empty() &&
1222*fe6060f1SDimitry Andric       TrackingIncomingArguments.count(F)) {
1223*fe6060f1SDimitry Andric     markBlockExecutable(&F->front());
1224*fe6060f1SDimitry Andric 
1225*fe6060f1SDimitry Andric     // Propagate information from this call site into the callee.
1226*fe6060f1SDimitry Andric     auto CAI = CB.arg_begin();
1227*fe6060f1SDimitry Andric     for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
1228*fe6060f1SDimitry Andric          ++AI, ++CAI) {
1229*fe6060f1SDimitry Andric       // If this argument is byval, and if the function is not readonly, there
1230*fe6060f1SDimitry Andric       // will be an implicit copy formed of the input aggregate.
1231*fe6060f1SDimitry Andric       if (AI->hasByValAttr() && !F->onlyReadsMemory()) {
1232*fe6060f1SDimitry Andric         markOverdefined(&*AI);
1233*fe6060f1SDimitry Andric         continue;
1234*fe6060f1SDimitry Andric       }
1235*fe6060f1SDimitry Andric 
1236*fe6060f1SDimitry Andric       if (auto *STy = dyn_cast<StructType>(AI->getType())) {
1237*fe6060f1SDimitry Andric         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1238*fe6060f1SDimitry Andric           ValueLatticeElement CallArg = getStructValueState(*CAI, i);
1239*fe6060f1SDimitry Andric           mergeInValue(getStructValueState(&*AI, i), &*AI, CallArg,
1240*fe6060f1SDimitry Andric                        getMaxWidenStepsOpts());
1241*fe6060f1SDimitry Andric         }
1242*fe6060f1SDimitry Andric       } else
1243*fe6060f1SDimitry Andric         mergeInValue(&*AI, getValueState(*CAI), getMaxWidenStepsOpts());
1244*fe6060f1SDimitry Andric     }
1245*fe6060f1SDimitry Andric   }
1246*fe6060f1SDimitry Andric }
1247*fe6060f1SDimitry Andric 
1248*fe6060f1SDimitry Andric void SCCPInstVisitor::handleCallResult(CallBase &CB) {
1249*fe6060f1SDimitry Andric   Function *F = CB.getCalledFunction();
1250*fe6060f1SDimitry Andric 
1251*fe6060f1SDimitry Andric   if (auto *II = dyn_cast<IntrinsicInst>(&CB)) {
1252*fe6060f1SDimitry Andric     if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
1253*fe6060f1SDimitry Andric       if (ValueState[&CB].isOverdefined())
1254*fe6060f1SDimitry Andric         return;
1255*fe6060f1SDimitry Andric 
1256*fe6060f1SDimitry Andric       Value *CopyOf = CB.getOperand(0);
1257*fe6060f1SDimitry Andric       ValueLatticeElement CopyOfVal = getValueState(CopyOf);
1258*fe6060f1SDimitry Andric       const auto *PI = getPredicateInfoFor(&CB);
1259*fe6060f1SDimitry Andric       assert(PI && "Missing predicate info for ssa.copy");
1260*fe6060f1SDimitry Andric 
1261*fe6060f1SDimitry Andric       const Optional<PredicateConstraint> &Constraint = PI->getConstraint();
1262*fe6060f1SDimitry Andric       if (!Constraint) {
1263*fe6060f1SDimitry Andric         mergeInValue(ValueState[&CB], &CB, CopyOfVal);
1264*fe6060f1SDimitry Andric         return;
1265*fe6060f1SDimitry Andric       }
1266*fe6060f1SDimitry Andric 
1267*fe6060f1SDimitry Andric       CmpInst::Predicate Pred = Constraint->Predicate;
1268*fe6060f1SDimitry Andric       Value *OtherOp = Constraint->OtherOp;
1269*fe6060f1SDimitry Andric 
1270*fe6060f1SDimitry Andric       // Wait until OtherOp is resolved.
1271*fe6060f1SDimitry Andric       if (getValueState(OtherOp).isUnknown()) {
1272*fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1273*fe6060f1SDimitry Andric         return;
1274*fe6060f1SDimitry Andric       }
1275*fe6060f1SDimitry Andric 
1276*fe6060f1SDimitry Andric       // TODO: Actually filp MayIncludeUndef for the created range to false,
1277*fe6060f1SDimitry Andric       // once most places in the optimizer respect the branches on
1278*fe6060f1SDimitry Andric       // undef/poison are UB rule. The reason why the new range cannot be
1279*fe6060f1SDimitry Andric       // undef is as follows below:
1280*fe6060f1SDimitry Andric       // The new range is based on a branch condition. That guarantees that
1281*fe6060f1SDimitry Andric       // neither of the compare operands can be undef in the branch targets,
1282*fe6060f1SDimitry Andric       // unless we have conditions that are always true/false (e.g. icmp ule
1283*fe6060f1SDimitry Andric       // i32, %a, i32_max). For the latter overdefined/empty range will be
1284*fe6060f1SDimitry Andric       // inferred, but the branch will get folded accordingly anyways.
1285*fe6060f1SDimitry Andric       bool MayIncludeUndef = !isa<PredicateAssume>(PI);
1286*fe6060f1SDimitry Andric 
1287*fe6060f1SDimitry Andric       ValueLatticeElement CondVal = getValueState(OtherOp);
1288*fe6060f1SDimitry Andric       ValueLatticeElement &IV = ValueState[&CB];
1289*fe6060f1SDimitry Andric       if (CondVal.isConstantRange() || CopyOfVal.isConstantRange()) {
1290*fe6060f1SDimitry Andric         auto ImposedCR =
1291*fe6060f1SDimitry Andric             ConstantRange::getFull(DL.getTypeSizeInBits(CopyOf->getType()));
1292*fe6060f1SDimitry Andric 
1293*fe6060f1SDimitry Andric         // Get the range imposed by the condition.
1294*fe6060f1SDimitry Andric         if (CondVal.isConstantRange())
1295*fe6060f1SDimitry Andric           ImposedCR = ConstantRange::makeAllowedICmpRegion(
1296*fe6060f1SDimitry Andric               Pred, CondVal.getConstantRange());
1297*fe6060f1SDimitry Andric 
1298*fe6060f1SDimitry Andric         // Combine range info for the original value with the new range from the
1299*fe6060f1SDimitry Andric         // condition.
1300*fe6060f1SDimitry Andric         auto CopyOfCR = CopyOfVal.isConstantRange()
1301*fe6060f1SDimitry Andric                             ? CopyOfVal.getConstantRange()
1302*fe6060f1SDimitry Andric                             : ConstantRange::getFull(
1303*fe6060f1SDimitry Andric                                   DL.getTypeSizeInBits(CopyOf->getType()));
1304*fe6060f1SDimitry Andric         auto NewCR = ImposedCR.intersectWith(CopyOfCR);
1305*fe6060f1SDimitry Andric         // If the existing information is != x, do not use the information from
1306*fe6060f1SDimitry Andric         // a chained predicate, as the != x information is more likely to be
1307*fe6060f1SDimitry Andric         // helpful in practice.
1308*fe6060f1SDimitry Andric         if (!CopyOfCR.contains(NewCR) && CopyOfCR.getSingleMissingElement())
1309*fe6060f1SDimitry Andric           NewCR = CopyOfCR;
1310*fe6060f1SDimitry Andric 
1311*fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1312*fe6060f1SDimitry Andric         mergeInValue(IV, &CB,
1313*fe6060f1SDimitry Andric                      ValueLatticeElement::getRange(NewCR, MayIncludeUndef));
1314*fe6060f1SDimitry Andric         return;
1315*fe6060f1SDimitry Andric       } else if (Pred == CmpInst::ICMP_EQ && CondVal.isConstant()) {
1316*fe6060f1SDimitry Andric         // For non-integer values or integer constant expressions, only
1317*fe6060f1SDimitry Andric         // propagate equal constants.
1318*fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1319*fe6060f1SDimitry Andric         mergeInValue(IV, &CB, CondVal);
1320*fe6060f1SDimitry Andric         return;
1321*fe6060f1SDimitry Andric       } else if (Pred == CmpInst::ICMP_NE && CondVal.isConstant() &&
1322*fe6060f1SDimitry Andric                  !MayIncludeUndef) {
1323*fe6060f1SDimitry Andric         // Propagate inequalities.
1324*fe6060f1SDimitry Andric         addAdditionalUser(OtherOp, &CB);
1325*fe6060f1SDimitry Andric         mergeInValue(IV, &CB,
1326*fe6060f1SDimitry Andric                      ValueLatticeElement::getNot(CondVal.getConstant()));
1327*fe6060f1SDimitry Andric         return;
1328*fe6060f1SDimitry Andric       }
1329*fe6060f1SDimitry Andric 
1330*fe6060f1SDimitry Andric       return (void)mergeInValue(IV, &CB, CopyOfVal);
1331*fe6060f1SDimitry Andric     }
1332*fe6060f1SDimitry Andric 
1333*fe6060f1SDimitry Andric     if (ConstantRange::isIntrinsicSupported(II->getIntrinsicID())) {
1334*fe6060f1SDimitry Andric       // Compute result range for intrinsics supported by ConstantRange.
1335*fe6060f1SDimitry Andric       // Do this even if we don't know a range for all operands, as we may
1336*fe6060f1SDimitry Andric       // still know something about the result range, e.g. of abs(x).
1337*fe6060f1SDimitry Andric       SmallVector<ConstantRange, 2> OpRanges;
1338*fe6060f1SDimitry Andric       for (Value *Op : II->args()) {
1339*fe6060f1SDimitry Andric         const ValueLatticeElement &State = getValueState(Op);
1340*fe6060f1SDimitry Andric         if (State.isConstantRange())
1341*fe6060f1SDimitry Andric           OpRanges.push_back(State.getConstantRange());
1342*fe6060f1SDimitry Andric         else
1343*fe6060f1SDimitry Andric           OpRanges.push_back(
1344*fe6060f1SDimitry Andric               ConstantRange::getFull(Op->getType()->getScalarSizeInBits()));
1345*fe6060f1SDimitry Andric       }
1346*fe6060f1SDimitry Andric 
1347*fe6060f1SDimitry Andric       ConstantRange Result =
1348*fe6060f1SDimitry Andric           ConstantRange::intrinsic(II->getIntrinsicID(), OpRanges);
1349*fe6060f1SDimitry Andric       return (void)mergeInValue(II, ValueLatticeElement::getRange(Result));
1350*fe6060f1SDimitry Andric     }
1351*fe6060f1SDimitry Andric   }
1352*fe6060f1SDimitry Andric 
1353*fe6060f1SDimitry Andric   // The common case is that we aren't tracking the callee, either because we
1354*fe6060f1SDimitry Andric   // are not doing interprocedural analysis or the callee is indirect, or is
1355*fe6060f1SDimitry Andric   // external.  Handle these cases first.
1356*fe6060f1SDimitry Andric   if (!F || F->isDeclaration())
1357*fe6060f1SDimitry Andric     return handleCallOverdefined(CB);
1358*fe6060f1SDimitry Andric 
1359*fe6060f1SDimitry Andric   // If this is a single/zero retval case, see if we're tracking the function.
1360*fe6060f1SDimitry Andric   if (auto *STy = dyn_cast<StructType>(F->getReturnType())) {
1361*fe6060f1SDimitry Andric     if (!MRVFunctionsTracked.count(F))
1362*fe6060f1SDimitry Andric       return handleCallOverdefined(CB); // Not tracking this callee.
1363*fe6060f1SDimitry Andric 
1364*fe6060f1SDimitry Andric     // If we are tracking this callee, propagate the result of the function
1365*fe6060f1SDimitry Andric     // into this call site.
1366*fe6060f1SDimitry Andric     for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
1367*fe6060f1SDimitry Andric       mergeInValue(getStructValueState(&CB, i), &CB,
1368*fe6060f1SDimitry Andric                    TrackedMultipleRetVals[std::make_pair(F, i)],
1369*fe6060f1SDimitry Andric                    getMaxWidenStepsOpts());
1370*fe6060f1SDimitry Andric   } else {
1371*fe6060f1SDimitry Andric     auto TFRVI = TrackedRetVals.find(F);
1372*fe6060f1SDimitry Andric     if (TFRVI == TrackedRetVals.end())
1373*fe6060f1SDimitry Andric       return handleCallOverdefined(CB); // Not tracking this callee.
1374*fe6060f1SDimitry Andric 
1375*fe6060f1SDimitry Andric     // If so, propagate the return value of the callee into this call result.
1376*fe6060f1SDimitry Andric     mergeInValue(&CB, TFRVI->second, getMaxWidenStepsOpts());
1377*fe6060f1SDimitry Andric   }
1378*fe6060f1SDimitry Andric }
1379*fe6060f1SDimitry Andric 
1380*fe6060f1SDimitry Andric void SCCPInstVisitor::solve() {
1381*fe6060f1SDimitry Andric   // Process the work lists until they are empty!
1382*fe6060f1SDimitry Andric   while (!BBWorkList.empty() || !InstWorkList.empty() ||
1383*fe6060f1SDimitry Andric          !OverdefinedInstWorkList.empty()) {
1384*fe6060f1SDimitry Andric     // Process the overdefined instruction's work list first, which drives other
1385*fe6060f1SDimitry Andric     // things to overdefined more quickly.
1386*fe6060f1SDimitry Andric     while (!OverdefinedInstWorkList.empty()) {
1387*fe6060f1SDimitry Andric       Value *I = OverdefinedInstWorkList.pop_back_val();
1388*fe6060f1SDimitry Andric 
1389*fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off OI-WL: " << *I << '\n');
1390*fe6060f1SDimitry Andric 
1391*fe6060f1SDimitry Andric       // "I" got into the work list because it either made the transition from
1392*fe6060f1SDimitry Andric       // bottom to constant, or to overdefined.
1393*fe6060f1SDimitry Andric       //
1394*fe6060f1SDimitry Andric       // Anything on this worklist that is overdefined need not be visited
1395*fe6060f1SDimitry Andric       // since all of its users will have already been marked as overdefined
1396*fe6060f1SDimitry Andric       // Update all of the users of this instruction's value.
1397*fe6060f1SDimitry Andric       //
1398*fe6060f1SDimitry Andric       markUsersAsChanged(I);
1399*fe6060f1SDimitry Andric     }
1400*fe6060f1SDimitry Andric 
1401*fe6060f1SDimitry Andric     // Process the instruction work list.
1402*fe6060f1SDimitry Andric     while (!InstWorkList.empty()) {
1403*fe6060f1SDimitry Andric       Value *I = InstWorkList.pop_back_val();
1404*fe6060f1SDimitry Andric 
1405*fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off I-WL: " << *I << '\n');
1406*fe6060f1SDimitry Andric 
1407*fe6060f1SDimitry Andric       // "I" got into the work list because it made the transition from undef to
1408*fe6060f1SDimitry Andric       // constant.
1409*fe6060f1SDimitry Andric       //
1410*fe6060f1SDimitry Andric       // Anything on this worklist that is overdefined need not be visited
1411*fe6060f1SDimitry Andric       // since all of its users will have already been marked as overdefined.
1412*fe6060f1SDimitry Andric       // Update all of the users of this instruction's value.
1413*fe6060f1SDimitry Andric       //
1414*fe6060f1SDimitry Andric       if (I->getType()->isStructTy() || !getValueState(I).isOverdefined())
1415*fe6060f1SDimitry Andric         markUsersAsChanged(I);
1416*fe6060f1SDimitry Andric     }
1417*fe6060f1SDimitry Andric 
1418*fe6060f1SDimitry Andric     // Process the basic block work list.
1419*fe6060f1SDimitry Andric     while (!BBWorkList.empty()) {
1420*fe6060f1SDimitry Andric       BasicBlock *BB = BBWorkList.pop_back_val();
1421*fe6060f1SDimitry Andric 
1422*fe6060f1SDimitry Andric       LLVM_DEBUG(dbgs() << "\nPopped off BBWL: " << *BB << '\n');
1423*fe6060f1SDimitry Andric 
1424*fe6060f1SDimitry Andric       // Notify all instructions in this basic block that they are newly
1425*fe6060f1SDimitry Andric       // executable.
1426*fe6060f1SDimitry Andric       visit(BB);
1427*fe6060f1SDimitry Andric     }
1428*fe6060f1SDimitry Andric   }
1429*fe6060f1SDimitry Andric }
1430*fe6060f1SDimitry Andric 
1431*fe6060f1SDimitry Andric /// resolvedUndefsIn - While solving the dataflow for a function, we assume
1432*fe6060f1SDimitry Andric /// that branches on undef values cannot reach any of their successors.
1433*fe6060f1SDimitry Andric /// However, this is not a safe assumption.  After we solve dataflow, this
1434*fe6060f1SDimitry Andric /// method should be use to handle this.  If this returns true, the solver
1435*fe6060f1SDimitry Andric /// should be rerun.
1436*fe6060f1SDimitry Andric ///
1437*fe6060f1SDimitry Andric /// This method handles this by finding an unresolved branch and marking it one
1438*fe6060f1SDimitry Andric /// of the edges from the block as being feasible, even though the condition
1439*fe6060f1SDimitry Andric /// doesn't say it would otherwise be.  This allows SCCP to find the rest of the
1440*fe6060f1SDimitry Andric /// CFG and only slightly pessimizes the analysis results (by marking one,
1441*fe6060f1SDimitry Andric /// potentially infeasible, edge feasible).  This cannot usefully modify the
1442*fe6060f1SDimitry Andric /// constraints on the condition of the branch, as that would impact other users
1443*fe6060f1SDimitry Andric /// of the value.
1444*fe6060f1SDimitry Andric ///
1445*fe6060f1SDimitry Andric /// This scan also checks for values that use undefs. It conservatively marks
1446*fe6060f1SDimitry Andric /// them as overdefined.
1447*fe6060f1SDimitry Andric bool SCCPInstVisitor::resolvedUndefsIn(Function &F) {
1448*fe6060f1SDimitry Andric   bool MadeChange = false;
1449*fe6060f1SDimitry Andric   for (BasicBlock &BB : F) {
1450*fe6060f1SDimitry Andric     if (!BBExecutable.count(&BB))
1451*fe6060f1SDimitry Andric       continue;
1452*fe6060f1SDimitry Andric 
1453*fe6060f1SDimitry Andric     for (Instruction &I : BB) {
1454*fe6060f1SDimitry Andric       // Look for instructions which produce undef values.
1455*fe6060f1SDimitry Andric       if (I.getType()->isVoidTy())
1456*fe6060f1SDimitry Andric         continue;
1457*fe6060f1SDimitry Andric 
1458*fe6060f1SDimitry Andric       if (auto *STy = dyn_cast<StructType>(I.getType())) {
1459*fe6060f1SDimitry Andric         // Only a few things that can be structs matter for undef.
1460*fe6060f1SDimitry Andric 
1461*fe6060f1SDimitry Andric         // Tracked calls must never be marked overdefined in resolvedUndefsIn.
1462*fe6060f1SDimitry Andric         if (auto *CB = dyn_cast<CallBase>(&I))
1463*fe6060f1SDimitry Andric           if (Function *F = CB->getCalledFunction())
1464*fe6060f1SDimitry Andric             if (MRVFunctionsTracked.count(F))
1465*fe6060f1SDimitry Andric               continue;
1466*fe6060f1SDimitry Andric 
1467*fe6060f1SDimitry Andric         // extractvalue and insertvalue don't need to be marked; they are
1468*fe6060f1SDimitry Andric         // tracked as precisely as their operands.
1469*fe6060f1SDimitry Andric         if (isa<ExtractValueInst>(I) || isa<InsertValueInst>(I))
1470*fe6060f1SDimitry Andric           continue;
1471*fe6060f1SDimitry Andric         // Send the results of everything else to overdefined.  We could be
1472*fe6060f1SDimitry Andric         // more precise than this but it isn't worth bothering.
1473*fe6060f1SDimitry Andric         for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
1474*fe6060f1SDimitry Andric           ValueLatticeElement &LV = getStructValueState(&I, i);
1475*fe6060f1SDimitry Andric           if (LV.isUnknownOrUndef()) {
1476*fe6060f1SDimitry Andric             markOverdefined(LV, &I);
1477*fe6060f1SDimitry Andric             MadeChange = true;
1478*fe6060f1SDimitry Andric           }
1479*fe6060f1SDimitry Andric         }
1480*fe6060f1SDimitry Andric         continue;
1481*fe6060f1SDimitry Andric       }
1482*fe6060f1SDimitry Andric 
1483*fe6060f1SDimitry Andric       ValueLatticeElement &LV = getValueState(&I);
1484*fe6060f1SDimitry Andric       if (!LV.isUnknownOrUndef())
1485*fe6060f1SDimitry Andric         continue;
1486*fe6060f1SDimitry Andric 
1487*fe6060f1SDimitry Andric       // There are two reasons a call can have an undef result
1488*fe6060f1SDimitry Andric       // 1. It could be tracked.
1489*fe6060f1SDimitry Andric       // 2. It could be constant-foldable.
1490*fe6060f1SDimitry Andric       // Because of the way we solve return values, tracked calls must
1491*fe6060f1SDimitry Andric       // never be marked overdefined in resolvedUndefsIn.
1492*fe6060f1SDimitry Andric       if (auto *CB = dyn_cast<CallBase>(&I))
1493*fe6060f1SDimitry Andric         if (Function *F = CB->getCalledFunction())
1494*fe6060f1SDimitry Andric           if (TrackedRetVals.count(F))
1495*fe6060f1SDimitry Andric             continue;
1496*fe6060f1SDimitry Andric 
1497*fe6060f1SDimitry Andric       if (isa<LoadInst>(I)) {
1498*fe6060f1SDimitry Andric         // A load here means one of two things: a load of undef from a global,
1499*fe6060f1SDimitry Andric         // a load from an unknown pointer.  Either way, having it return undef
1500*fe6060f1SDimitry Andric         // is okay.
1501*fe6060f1SDimitry Andric         continue;
1502*fe6060f1SDimitry Andric       }
1503*fe6060f1SDimitry Andric 
1504*fe6060f1SDimitry Andric       markOverdefined(&I);
1505*fe6060f1SDimitry Andric       MadeChange = true;
1506*fe6060f1SDimitry Andric     }
1507*fe6060f1SDimitry Andric 
1508*fe6060f1SDimitry Andric     // Check to see if we have a branch or switch on an undefined value.  If so
1509*fe6060f1SDimitry Andric     // we force the branch to go one way or the other to make the successor
1510*fe6060f1SDimitry Andric     // values live.  It doesn't really matter which way we force it.
1511*fe6060f1SDimitry Andric     Instruction *TI = BB.getTerminator();
1512*fe6060f1SDimitry Andric     if (auto *BI = dyn_cast<BranchInst>(TI)) {
1513*fe6060f1SDimitry Andric       if (!BI->isConditional())
1514*fe6060f1SDimitry Andric         continue;
1515*fe6060f1SDimitry Andric       if (!getValueState(BI->getCondition()).isUnknownOrUndef())
1516*fe6060f1SDimitry Andric         continue;
1517*fe6060f1SDimitry Andric 
1518*fe6060f1SDimitry Andric       // If the input to SCCP is actually branch on undef, fix the undef to
1519*fe6060f1SDimitry Andric       // false.
1520*fe6060f1SDimitry Andric       if (isa<UndefValue>(BI->getCondition())) {
1521*fe6060f1SDimitry Andric         BI->setCondition(ConstantInt::getFalse(BI->getContext()));
1522*fe6060f1SDimitry Andric         markEdgeExecutable(&BB, TI->getSuccessor(1));
1523*fe6060f1SDimitry Andric         MadeChange = true;
1524*fe6060f1SDimitry Andric         continue;
1525*fe6060f1SDimitry Andric       }
1526*fe6060f1SDimitry Andric 
1527*fe6060f1SDimitry Andric       // Otherwise, it is a branch on a symbolic value which is currently
1528*fe6060f1SDimitry Andric       // considered to be undef.  Make sure some edge is executable, so a
1529*fe6060f1SDimitry Andric       // branch on "undef" always flows somewhere.
1530*fe6060f1SDimitry Andric       // FIXME: Distinguish between dead code and an LLVM "undef" value.
1531*fe6060f1SDimitry Andric       BasicBlock *DefaultSuccessor = TI->getSuccessor(1);
1532*fe6060f1SDimitry Andric       if (markEdgeExecutable(&BB, DefaultSuccessor))
1533*fe6060f1SDimitry Andric         MadeChange = true;
1534*fe6060f1SDimitry Andric 
1535*fe6060f1SDimitry Andric       continue;
1536*fe6060f1SDimitry Andric     }
1537*fe6060f1SDimitry Andric 
1538*fe6060f1SDimitry Andric     if (auto *IBR = dyn_cast<IndirectBrInst>(TI)) {
1539*fe6060f1SDimitry Andric       // Indirect branch with no successor ?. Its ok to assume it branches
1540*fe6060f1SDimitry Andric       // to no target.
1541*fe6060f1SDimitry Andric       if (IBR->getNumSuccessors() < 1)
1542*fe6060f1SDimitry Andric         continue;
1543*fe6060f1SDimitry Andric 
1544*fe6060f1SDimitry Andric       if (!getValueState(IBR->getAddress()).isUnknownOrUndef())
1545*fe6060f1SDimitry Andric         continue;
1546*fe6060f1SDimitry Andric 
1547*fe6060f1SDimitry Andric       // If the input to SCCP is actually branch on undef, fix the undef to
1548*fe6060f1SDimitry Andric       // the first successor of the indirect branch.
1549*fe6060f1SDimitry Andric       if (isa<UndefValue>(IBR->getAddress())) {
1550*fe6060f1SDimitry Andric         IBR->setAddress(BlockAddress::get(IBR->getSuccessor(0)));
1551*fe6060f1SDimitry Andric         markEdgeExecutable(&BB, IBR->getSuccessor(0));
1552*fe6060f1SDimitry Andric         MadeChange = true;
1553*fe6060f1SDimitry Andric         continue;
1554*fe6060f1SDimitry Andric       }
1555*fe6060f1SDimitry Andric 
1556*fe6060f1SDimitry Andric       // Otherwise, it is a branch on a symbolic value which is currently
1557*fe6060f1SDimitry Andric       // considered to be undef.  Make sure some edge is executable, so a
1558*fe6060f1SDimitry Andric       // branch on "undef" always flows somewhere.
1559*fe6060f1SDimitry Andric       // FIXME: IndirectBr on "undef" doesn't actually need to go anywhere:
1560*fe6060f1SDimitry Andric       // we can assume the branch has undefined behavior instead.
1561*fe6060f1SDimitry Andric       BasicBlock *DefaultSuccessor = IBR->getSuccessor(0);
1562*fe6060f1SDimitry Andric       if (markEdgeExecutable(&BB, DefaultSuccessor))
1563*fe6060f1SDimitry Andric         MadeChange = true;
1564*fe6060f1SDimitry Andric 
1565*fe6060f1SDimitry Andric       continue;
1566*fe6060f1SDimitry Andric     }
1567*fe6060f1SDimitry Andric 
1568*fe6060f1SDimitry Andric     if (auto *SI = dyn_cast<SwitchInst>(TI)) {
1569*fe6060f1SDimitry Andric       if (!SI->getNumCases() ||
1570*fe6060f1SDimitry Andric           !getValueState(SI->getCondition()).isUnknownOrUndef())
1571*fe6060f1SDimitry Andric         continue;
1572*fe6060f1SDimitry Andric 
1573*fe6060f1SDimitry Andric       // If the input to SCCP is actually switch on undef, fix the undef to
1574*fe6060f1SDimitry Andric       // the first constant.
1575*fe6060f1SDimitry Andric       if (isa<UndefValue>(SI->getCondition())) {
1576*fe6060f1SDimitry Andric         SI->setCondition(SI->case_begin()->getCaseValue());
1577*fe6060f1SDimitry Andric         markEdgeExecutable(&BB, SI->case_begin()->getCaseSuccessor());
1578*fe6060f1SDimitry Andric         MadeChange = true;
1579*fe6060f1SDimitry Andric         continue;
1580*fe6060f1SDimitry Andric       }
1581*fe6060f1SDimitry Andric 
1582*fe6060f1SDimitry Andric       // Otherwise, it is a branch on a symbolic value which is currently
1583*fe6060f1SDimitry Andric       // considered to be undef.  Make sure some edge is executable, so a
1584*fe6060f1SDimitry Andric       // branch on "undef" always flows somewhere.
1585*fe6060f1SDimitry Andric       // FIXME: Distinguish between dead code and an LLVM "undef" value.
1586*fe6060f1SDimitry Andric       BasicBlock *DefaultSuccessor = SI->case_begin()->getCaseSuccessor();
1587*fe6060f1SDimitry Andric       if (markEdgeExecutable(&BB, DefaultSuccessor))
1588*fe6060f1SDimitry Andric         MadeChange = true;
1589*fe6060f1SDimitry Andric 
1590*fe6060f1SDimitry Andric       continue;
1591*fe6060f1SDimitry Andric     }
1592*fe6060f1SDimitry Andric   }
1593*fe6060f1SDimitry Andric 
1594*fe6060f1SDimitry Andric   return MadeChange;
1595*fe6060f1SDimitry Andric }
1596*fe6060f1SDimitry Andric 
1597*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
1598*fe6060f1SDimitry Andric //
1599*fe6060f1SDimitry Andric // SCCPSolver implementations
1600*fe6060f1SDimitry Andric //
1601*fe6060f1SDimitry Andric SCCPSolver::SCCPSolver(
1602*fe6060f1SDimitry Andric     const DataLayout &DL,
1603*fe6060f1SDimitry Andric     std::function<const TargetLibraryInfo &(Function &)> GetTLI,
1604*fe6060f1SDimitry Andric     LLVMContext &Ctx)
1605*fe6060f1SDimitry Andric     : Visitor(new SCCPInstVisitor(DL, std::move(GetTLI), Ctx)) {}
1606*fe6060f1SDimitry Andric 
1607*fe6060f1SDimitry Andric SCCPSolver::~SCCPSolver() {}
1608*fe6060f1SDimitry Andric 
1609*fe6060f1SDimitry Andric void SCCPSolver::addAnalysis(Function &F, AnalysisResultsForFn A) {
1610*fe6060f1SDimitry Andric   return Visitor->addAnalysis(F, std::move(A));
1611*fe6060f1SDimitry Andric }
1612*fe6060f1SDimitry Andric 
1613*fe6060f1SDimitry Andric bool SCCPSolver::markBlockExecutable(BasicBlock *BB) {
1614*fe6060f1SDimitry Andric   return Visitor->markBlockExecutable(BB);
1615*fe6060f1SDimitry Andric }
1616*fe6060f1SDimitry Andric 
1617*fe6060f1SDimitry Andric const PredicateBase *SCCPSolver::getPredicateInfoFor(Instruction *I) {
1618*fe6060f1SDimitry Andric   return Visitor->getPredicateInfoFor(I);
1619*fe6060f1SDimitry Andric }
1620*fe6060f1SDimitry Andric 
1621*fe6060f1SDimitry Andric DomTreeUpdater SCCPSolver::getDTU(Function &F) { return Visitor->getDTU(F); }
1622*fe6060f1SDimitry Andric 
1623*fe6060f1SDimitry Andric void SCCPSolver::trackValueOfGlobalVariable(GlobalVariable *GV) {
1624*fe6060f1SDimitry Andric   Visitor->trackValueOfGlobalVariable(GV);
1625*fe6060f1SDimitry Andric }
1626*fe6060f1SDimitry Andric 
1627*fe6060f1SDimitry Andric void SCCPSolver::addTrackedFunction(Function *F) {
1628*fe6060f1SDimitry Andric   Visitor->addTrackedFunction(F);
1629*fe6060f1SDimitry Andric }
1630*fe6060f1SDimitry Andric 
1631*fe6060f1SDimitry Andric void SCCPSolver::addToMustPreserveReturnsInFunctions(Function *F) {
1632*fe6060f1SDimitry Andric   Visitor->addToMustPreserveReturnsInFunctions(F);
1633*fe6060f1SDimitry Andric }
1634*fe6060f1SDimitry Andric 
1635*fe6060f1SDimitry Andric bool SCCPSolver::mustPreserveReturn(Function *F) {
1636*fe6060f1SDimitry Andric   return Visitor->mustPreserveReturn(F);
1637*fe6060f1SDimitry Andric }
1638*fe6060f1SDimitry Andric 
1639*fe6060f1SDimitry Andric void SCCPSolver::addArgumentTrackedFunction(Function *F) {
1640*fe6060f1SDimitry Andric   Visitor->addArgumentTrackedFunction(F);
1641*fe6060f1SDimitry Andric }
1642*fe6060f1SDimitry Andric 
1643*fe6060f1SDimitry Andric bool SCCPSolver::isArgumentTrackedFunction(Function *F) {
1644*fe6060f1SDimitry Andric   return Visitor->isArgumentTrackedFunction(F);
1645*fe6060f1SDimitry Andric }
1646*fe6060f1SDimitry Andric 
1647*fe6060f1SDimitry Andric void SCCPSolver::solve() { Visitor->solve(); }
1648*fe6060f1SDimitry Andric 
1649*fe6060f1SDimitry Andric bool SCCPSolver::resolvedUndefsIn(Function &F) {
1650*fe6060f1SDimitry Andric   return Visitor->resolvedUndefsIn(F);
1651*fe6060f1SDimitry Andric }
1652*fe6060f1SDimitry Andric 
1653*fe6060f1SDimitry Andric bool SCCPSolver::isBlockExecutable(BasicBlock *BB) const {
1654*fe6060f1SDimitry Andric   return Visitor->isBlockExecutable(BB);
1655*fe6060f1SDimitry Andric }
1656*fe6060f1SDimitry Andric 
1657*fe6060f1SDimitry Andric bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) const {
1658*fe6060f1SDimitry Andric   return Visitor->isEdgeFeasible(From, To);
1659*fe6060f1SDimitry Andric }
1660*fe6060f1SDimitry Andric 
1661*fe6060f1SDimitry Andric std::vector<ValueLatticeElement>
1662*fe6060f1SDimitry Andric SCCPSolver::getStructLatticeValueFor(Value *V) const {
1663*fe6060f1SDimitry Andric   return Visitor->getStructLatticeValueFor(V);
1664*fe6060f1SDimitry Andric }
1665*fe6060f1SDimitry Andric 
1666*fe6060f1SDimitry Andric void SCCPSolver::removeLatticeValueFor(Value *V) {
1667*fe6060f1SDimitry Andric   return Visitor->removeLatticeValueFor(V);
1668*fe6060f1SDimitry Andric }
1669*fe6060f1SDimitry Andric 
1670*fe6060f1SDimitry Andric const ValueLatticeElement &SCCPSolver::getLatticeValueFor(Value *V) const {
1671*fe6060f1SDimitry Andric   return Visitor->getLatticeValueFor(V);
1672*fe6060f1SDimitry Andric }
1673*fe6060f1SDimitry Andric 
1674*fe6060f1SDimitry Andric const MapVector<Function *, ValueLatticeElement> &
1675*fe6060f1SDimitry Andric SCCPSolver::getTrackedRetVals() {
1676*fe6060f1SDimitry Andric   return Visitor->getTrackedRetVals();
1677*fe6060f1SDimitry Andric }
1678*fe6060f1SDimitry Andric 
1679*fe6060f1SDimitry Andric const DenseMap<GlobalVariable *, ValueLatticeElement> &
1680*fe6060f1SDimitry Andric SCCPSolver::getTrackedGlobals() {
1681*fe6060f1SDimitry Andric   return Visitor->getTrackedGlobals();
1682*fe6060f1SDimitry Andric }
1683*fe6060f1SDimitry Andric 
1684*fe6060f1SDimitry Andric const SmallPtrSet<Function *, 16> SCCPSolver::getMRVFunctionsTracked() {
1685*fe6060f1SDimitry Andric   return Visitor->getMRVFunctionsTracked();
1686*fe6060f1SDimitry Andric }
1687*fe6060f1SDimitry Andric 
1688*fe6060f1SDimitry Andric void SCCPSolver::markOverdefined(Value *V) { Visitor->markOverdefined(V); }
1689*fe6060f1SDimitry Andric 
1690*fe6060f1SDimitry Andric bool SCCPSolver::isStructLatticeConstant(Function *F, StructType *STy) {
1691*fe6060f1SDimitry Andric   return Visitor->isStructLatticeConstant(F, STy);
1692*fe6060f1SDimitry Andric }
1693*fe6060f1SDimitry Andric 
1694*fe6060f1SDimitry Andric Constant *SCCPSolver::getConstant(const ValueLatticeElement &LV) const {
1695*fe6060f1SDimitry Andric   return Visitor->getConstant(LV);
1696*fe6060f1SDimitry Andric }
1697*fe6060f1SDimitry Andric 
1698*fe6060f1SDimitry Andric SmallPtrSetImpl<Function *> &SCCPSolver::getArgumentTrackedFunctions() {
1699*fe6060f1SDimitry Andric   return Visitor->getArgumentTrackedFunctions();
1700*fe6060f1SDimitry Andric }
1701*fe6060f1SDimitry Andric 
1702*fe6060f1SDimitry Andric void SCCPSolver::markArgInFuncSpecialization(Function *F, Argument *A,
1703*fe6060f1SDimitry Andric                                              Constant *C) {
1704*fe6060f1SDimitry Andric   Visitor->markArgInFuncSpecialization(F, A, C);
1705*fe6060f1SDimitry Andric }
1706*fe6060f1SDimitry Andric 
1707*fe6060f1SDimitry Andric void SCCPSolver::markFunctionUnreachable(Function *F) {
1708*fe6060f1SDimitry Andric   Visitor->markFunctionUnreachable(F);
1709*fe6060f1SDimitry Andric }
1710*fe6060f1SDimitry Andric 
1711*fe6060f1SDimitry Andric void SCCPSolver::visit(Instruction *I) { Visitor->visit(I); }
1712*fe6060f1SDimitry Andric 
1713*fe6060f1SDimitry Andric void SCCPSolver::visitCall(CallInst &I) { Visitor->visitCall(I); }
1714