36#define DEBUG_TYPE "sccp"
38STATISTIC(NumInstRemoved,
"Number of instructions removed");
39STATISTIC(NumArgsElimed ,
"Number of arguments constant propagated");
40STATISTIC(NumGlobalConst,
"Number of globals found to be constant");
41STATISTIC(NumDeadBlocks ,
"Number of basic blocks unreachable");
43 "Number of instructions replaced with (simpler) instruction");
47 "The maximum number of iterations function specialization is run"));
59 <<
"Can't zap returns of the function : " <<
F.getName()
60 <<
" due to present musttail or \"clang.arc.attachedcall\" call of "
68 if (isa<Instruction>(U) &&
69 !Solver.isBlockExecutable(cast<Instruction>(U)->getParent()))
75 if (!isa<CallBase>(U))
77 if (U->getType()->isStructTy()) {
78 return all_of(Solver.getStructLatticeValueFor(U),
79 [](const ValueLatticeElement &LV) {
80 return !SCCPSolver::isOverdefined(LV);
86 if (
auto *II = dyn_cast<IntrinsicInst>(U)) {
87 if (II->isAssumeLikeIntrinsic())
93 "We can only zap functions where all live users have a concrete value");
96 if (
CallInst *CI = BB.getTerminatingMustTailCall()) {
97 LLVM_DEBUG(
dbgs() <<
"Can't zap return of the block due to present "
98 <<
"musttail call : " << *CI <<
"\n");
103 if (
auto *RI = dyn_cast<ReturnInst>(BB.getTerminator()))
104 if (!isa<UndefValue>(RI->getOperand(0)))
105 ReturnsToZap.push_back(RI);
115 bool IsFuncSpecEnabled) {
122 if (
F.isDeclaration())
151 G.removeDeadConstantUsers();
159 if (IsFuncSpecEnabled) {
166 bool MadeChanges =
false;
168 if (
F.isDeclaration())
174 bool ReplacedPointerArg =
false;
177 ReplacedPointerArg |=
Arg.getType()->isPointerTy();
184 if (ReplacedPointerArg) {
192 return AL.addFnAttribute(
197 F.setAttributes(UpdateAttrs(
F.getAttributes()));
198 for (
User *U :
F.users()) {
199 auto *CB = dyn_cast<CallBase>(U);
200 if (!CB || CB->getCalledFunction() != &
F)
203 CB->setAttributes(UpdateAttrs(CB->getAttributes()));
206 MadeChanges |= ReplacedPointerArg;
217 if (&BB != &
F.front())
223 BB, InsertedValues, NumInstRemoved, NumInstReplaced);
247 if (!DeadBB->hasAddressTaken())
253 if (
auto *II = dyn_cast<IntrinsicInst>(&Inst)) {
254 if (II->getIntrinsicID() == Intrinsic::ssa_copy) {
255 Value *Op = II->getOperand(0);
256 Inst.replaceAllUsesWith(Op);
257 Inst.eraseFromParent();
291 auto *CB = dyn_cast<CallBase>(
User);
292 if (!CB || CB->getCalledFunction() !=
F)
298 if (CB->getMetadata(LLVMContext::MD_range))
309 if (
F->getReturnType()->isVoidTy())
316 assert(
F->getReturnType()->isStructTy() &&
317 "The return type should be a struct");
318 StructType *STy = cast<StructType>(
F->getReturnType());
326 Function *
F = RI->getParent()->getParent();
340 F->removeParamAttr(
A.getArgNo(), Attribute::Returned);
341 F->removeRetAttrs(UBImplyingAttributes);
342 for (
Use &U :
F->uses()) {
343 CallBase *CB = dyn_cast<CallBase>(U.getUser());
345 assert(isa<BlockAddress>(U.getUser()) ||
346 (isa<Constant>(U.getUser()) &&
347 all_of(U.getUser()->users(), [](
const User *UserUser) {
348 return cast<IntrinsicInst>(UserUser)->isAssumeLikeIntrinsic();
366 <<
"' is constant!\n");
369 SI->eraseFromParent();
372 M.eraseGlobalVariable(GV);
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
amdgpu Simplify well known AMD library false FunctionCallee Value * Arg
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void findReturnsToZap(Function &F, SmallVector< ReturnInst *, 8 > &ReturnsToZap, SCCPSolver &Solver)
static cl::opt< unsigned > FuncSpecMaxIters("funcspec-max-iters", cl::init(1), cl::Hidden, cl::desc("The maximum number of iterations function specialization is run"))
static bool runIPSCCP(Module &M, const DataLayout &DL, FunctionAnalysisManager *FAM, std::function< const TargetLibraryInfo &(Function &)> GetTLI, std::function< TargetTransformInfo &(Function &)> GetTTI, std::function< AssumptionCache &(Function &)> GetAC, function_ref< AnalysisResultsForFn(Function &)> getAnalysis, bool IsFuncSpecEnabled)
FunctionAnalysisManager FAM
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
#define STATISTIC(VARNAME, DESC)
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
static Attribute getWithMemoryEffects(LLVMContext &Context, MemoryEffects ME)
LLVM Basic Block Representation.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
Removes the attribute from the given argument.
void removeRetAttrs(const AttributeMask &AttrsToRemove)
Removes the attributes from the return value.
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
This class represents a function call, abstracting a target machine's calling convention.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
bool isSingleElement() const
Return true if this set contains exactly one member.
A parsed version of the target data layout string in and methods for querying it.
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool run()
Attempt to specialize functions in the module to enable constant propagation across function boundari...
bool isClonedFunction(Function *F)
bool isFuncSpecEnabled() const
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
This is an important class for using LLVM in a threaded context.
Analysis pass that exposes the LoopInfo for a function.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Summary of how a function affects memory in the program.
@ ArgMem
Access to memory via argument pointers.
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
static MemoryEffects unknown()
Create MemoryEffects that can read and write any memory.
A Module instance is used to store all the information related to an LLVM module.
Analysis pass which computes a PostDominatorTree.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void preserve()
Mark an analysis as preserved.
Return a value (possibly void), from a function.
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
const DenseMap< GlobalVariable *, ValueLatticeElement > & getTrackedGlobals()
getTrackedGlobals - Get and return the set of inferred initializers for global variables.
void trackValueOfGlobalVariable(GlobalVariable *GV)
trackValueOfGlobalVariable - Clients can use this method to inform the SCCPSolver that it should trac...
bool tryToReplaceWithConstant(Value *V)
bool isStructLatticeConstant(Function *F, StructType *STy)
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
getTrackedRetVals - Get the inferred return value map.
void solveWhileResolvedUndefsIn(Module &M)
const PredicateBase * getPredicateInfoFor(Instruction *I)
DomTreeUpdater getDTU(Function &F)
void addArgumentTrackedFunction(Function *F)
void addAnalysis(Function &F, AnalysisResultsForFn A)
const SmallPtrSet< Function *, 16 > getMRVFunctionsTracked()
getMRVFunctionsTracked - Get the set of functions which return multiple values tracked by the pass.
bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
const ValueLatticeElement & getLatticeValueFor(Value *V) const
bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
bool isBlockExecutable(BasicBlock *BB) const
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
static bool isConstant(const ValueLatticeElement &LV)
bool mustPreserveReturn(Function *F)
Returns true if the return of the given function cannot be modified.
static bool isOverdefined(const ValueLatticeElement &LV)
bool isArgumentTrackedFunction(Function *F)
Returns true if the given function is in the solver's set of argument-tracked functions.
void markOverdefined(Value *V)
markOverdefined - Mark the specified value overdefined.
bool insert(const value_type &X)
Insert a new element into the SetVector.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Class to represent struct types.
Analysis pass providing the TargetTransformInfo.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
This class represents lattice values for constants.
bool isConstantRangeIncludingUndef() const
const ConstantRange & getConstantRange(bool UndefAllowed=true) const
Returns the constant range for this value.
bool isConstantRange(bool UndefAllowed=true) const
Returns true if this value is a constant range.
bool isUnknownOrUndef() const
LLVM Value Representation.
StringRef getName() const
Return a constant reference to the value's name.
An efficient, type-erasing, non-owning reference to a callable.
AttributeMask getUBImplyingAttributes()
Get param/return attributes which imply immediate undefined behavior if an invalid value is passed.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool canTrackGlobalVariableInterprocedurally(GlobalVariable *GV)
Determine if the value maintained in the given global variable can be tracked interprocedurally.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned changeToUnreachable(Instruction *I, bool PreserveLCSSA=false, DomTreeUpdater *DTU=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Insert an unreachable instruction before the specified instruction, making it and the rest of the cod...
bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.
bool canTrackArgumentsInterprocedurally(Function *F)
Determine if the values of the given function's arguments can be tracked interprocedurally.
Helper struct for bundling up the analysis results per function for IPSCCP.