Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:44

0001 //===- SCCPSolver.h - SCCP Utility ----------------------------- *- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // \file
0010 // This file implements Sparse Conditional Constant Propagation (SCCP) utility.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_TRANSFORMS_UTILS_SCCPSOLVER_H
0015 #define LLVM_TRANSFORMS_UTILS_SCCPSOLVER_H
0016 
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/ADT/SmallPtrSet.h"
0019 #include "llvm/ADT/Statistic.h"
0020 #include "llvm/Analysis/DomTreeUpdater.h"
0021 #include "llvm/Transforms/Utils/PredicateInfo.h"
0022 #include <vector>
0023 
0024 namespace llvm {
0025 class Argument;
0026 class BasicBlock;
0027 class CallInst;
0028 class Constant;
0029 class DataLayout;
0030 class DominatorTree;
0031 class Function;
0032 class GlobalVariable;
0033 class Instruction;
0034 class LLVMContext;
0035 class StructType;
0036 class TargetLibraryInfo;
0037 class Value;
0038 class ValueLatticeElement;
0039 
0040 /// Helper struct shared between Function Specialization and SCCP Solver.
0041 struct ArgInfo {
0042   Argument *Formal; // The Formal argument being analysed.
0043   Constant *Actual; // A corresponding actual constant argument.
0044 
0045   ArgInfo(Argument *F, Constant *A) : Formal(F), Actual(A) {}
0046 
0047   bool operator==(const ArgInfo &Other) const {
0048     return Formal == Other.Formal && Actual == Other.Actual;
0049   }
0050 
0051   bool operator!=(const ArgInfo &Other) const { return !(*this == Other); }
0052 
0053   friend hash_code hash_value(const ArgInfo &A) {
0054     return hash_combine(hash_value(A.Formal), hash_value(A.Actual));
0055   }
0056 };
0057 
0058 class SCCPInstVisitor;
0059 
0060 //===----------------------------------------------------------------------===//
0061 //
0062 /// SCCPSolver - This interface class is a general purpose solver for Sparse
0063 /// Conditional Constant Propagation (SCCP).
0064 ///
0065 class SCCPSolver {
0066   std::unique_ptr<SCCPInstVisitor> Visitor;
0067 
0068 public:
0069   SCCPSolver(const DataLayout &DL,
0070              std::function<const TargetLibraryInfo &(Function &)> GetTLI,
0071              LLVMContext &Ctx);
0072 
0073   ~SCCPSolver();
0074 
0075   void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC);
0076 
0077   /// markBlockExecutable - This method can be used by clients to mark all of
0078   /// the blocks that are known to be intrinsically live in the processed unit.
0079   /// This returns true if the block was not considered live before.
0080   bool markBlockExecutable(BasicBlock *BB);
0081 
0082   const PredicateBase *getPredicateInfoFor(Instruction *I);
0083 
0084   /// trackValueOfGlobalVariable - Clients can use this method to
0085   /// inform the SCCPSolver that it should track loads and stores to the
0086   /// specified global variable if it can.  This is only legal to call if
0087   /// performing Interprocedural SCCP.
0088   void trackValueOfGlobalVariable(GlobalVariable *GV);
0089 
0090   /// addTrackedFunction - If the SCCP solver is supposed to track calls into
0091   /// and out of the specified function (which cannot have its address taken),
0092   /// this method must be called.
0093   void addTrackedFunction(Function *F);
0094 
0095   /// Add function to the list of functions whose return cannot be modified.
0096   void addToMustPreserveReturnsInFunctions(Function *F);
0097 
0098   /// Returns true if the return of the given function cannot be modified.
0099   bool mustPreserveReturn(Function *F);
0100 
0101   void addArgumentTrackedFunction(Function *F);
0102 
0103   /// Returns true if the given function is in the solver's set of
0104   /// argument-tracked functions.
0105   bool isArgumentTrackedFunction(Function *F);
0106 
0107   const SmallPtrSetImpl<Function *> &getArgumentTrackedFunctions() const;
0108 
0109   /// Solve - Solve for constants and executable blocks.
0110   void solve();
0111 
0112   /// resolvedUndefsIn - While solving the dataflow for a function, we assume
0113   /// that branches on undef values cannot reach any of their successors.
0114   /// However, this is not a safe assumption.  After we solve dataflow, this
0115   /// method should be use to handle this.  If this returns true, the solver
0116   /// should be rerun.
0117   bool resolvedUndefsIn(Function &F);
0118 
0119   void solveWhileResolvedUndefsIn(Module &M);
0120 
0121   void solveWhileResolvedUndefsIn(SmallVectorImpl<Function *> &WorkList);
0122 
0123   void solveWhileResolvedUndefs();
0124 
0125   bool isBlockExecutable(BasicBlock *BB) const;
0126 
0127   // isEdgeFeasible - Return true if the control flow edge from the 'From' basic
0128   // block to the 'To' basic block is currently feasible.
0129   bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
0130 
0131   std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const;
0132 
0133   void removeLatticeValueFor(Value *V);
0134 
0135   /// Invalidate the Lattice Value of \p Call and its users after specializing
0136   /// the call. Then recompute it.
0137   void resetLatticeValueFor(CallBase *Call);
0138 
0139   const ValueLatticeElement &getLatticeValueFor(Value *V) const;
0140 
0141   /// getTrackedRetVals - Get the inferred return value map.
0142   const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals() const;
0143 
0144   /// getTrackedGlobals - Get and return the set of inferred initializers for
0145   /// global variables.
0146   const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals();
0147 
0148   /// getMRVFunctionsTracked - Get the set of functions which return multiple
0149   /// values tracked by the pass.
0150   const SmallPtrSet<Function *, 16> getMRVFunctionsTracked();
0151 
0152   /// markOverdefined - Mark the specified value overdefined.  This
0153   /// works with both scalars and structs.
0154   void markOverdefined(Value *V);
0155 
0156   /// trackValueOfArgument - Mark the specified argument overdefined unless it
0157   /// have range attribute.  This works with both scalars and structs.
0158   void trackValueOfArgument(Argument *V);
0159 
0160   // isStructLatticeConstant - Return true if all the lattice values
0161   // corresponding to elements of the structure are constants,
0162   // false otherwise.
0163   bool isStructLatticeConstant(Function *F, StructType *STy);
0164 
0165   /// Helper to return a Constant if \p LV is either a constant or a constant
0166   /// range with a single element.
0167   Constant *getConstant(const ValueLatticeElement &LV, Type *Ty) const;
0168 
0169   /// Return either a Constant or nullptr for a given Value.
0170   Constant *getConstantOrNull(Value *V) const;
0171 
0172   /// Set the Lattice Value for the arguments of a specialization \p F.
0173   /// If an argument is Constant then its lattice value is marked with the
0174   /// corresponding actual argument in \p Args. Otherwise, its lattice value
0175   /// is inherited (copied) from the corresponding formal argument in \p Args.
0176   void setLatticeValueForSpecializationArguments(Function *F,
0177                                        const SmallVectorImpl<ArgInfo> &Args);
0178 
0179   /// Mark all of the blocks in function \p F non-executable. Clients can used
0180   /// this method to erase a function from the module (e.g., if it has been
0181   /// completely specialized and is no longer needed).
0182   void markFunctionUnreachable(Function *F);
0183 
0184   void visit(Instruction *I);
0185   void visitCall(CallInst &I);
0186 
0187   bool simplifyInstsInBlock(BasicBlock &BB,
0188                             SmallPtrSetImpl<Value *> &InsertedValues,
0189                             Statistic &InstRemovedStat,
0190                             Statistic &InstReplacedStat);
0191 
0192   bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU,
0193                               BasicBlock *&NewUnreachableBB) const;
0194 
0195   void inferReturnAttributes() const;
0196   void inferArgAttributes() const;
0197 
0198   bool tryToReplaceWithConstant(Value *V);
0199 
0200   // Helper to check if \p LV is either a constant or a constant
0201   // range with a single element. This should cover exactly the same cases as
0202   // the old ValueLatticeElement::isConstant() and is intended to be used in the
0203   // transition to ValueLatticeElement.
0204   static bool isConstant(const ValueLatticeElement &LV);
0205 
0206   // Helper to check if \p LV is either overdefined or a constant range with
0207   // more than a single element. This should cover exactly the same cases as the
0208   // old ValueLatticeElement::isOverdefined() and is intended to be used in the
0209   // transition to ValueLatticeElement.
0210   static bool isOverdefined(const ValueLatticeElement &LV);
0211 };
0212 } // namespace llvm
0213 
0214 #endif // LLVM_TRANSFORMS_UTILS_SCCPSOLVER_H