LLVM 24.0.0git
SCCP.cpp
Go to the documentation of this file.
1//===- SCCP.cpp - Sparse Conditional Constant Propagation -----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements sparse conditional constant propagation and merging:
10//
11// Specifically, this:
12// * Assumes values are constant unless proven otherwise
13// * Assumes BasicBlocks are dead unless proven otherwise
14// * Proves values to be constant, and replaces them with constants
15// * Proves conditional branches to be unconditional
16//
17//===----------------------------------------------------------------------===//
18
22#include "llvm/ADT/Statistic.h"
29#include "llvm/IR/BasicBlock.h"
31#include "llvm/IR/Function.h"
32#include "llvm/IR/InstrTypes.h"
33#include "llvm/IR/Instruction.h"
35#include "llvm/IR/PassManager.h"
36#include "llvm/IR/Type.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Pass.h"
39#include "llvm/Support/Debug.h"
44
45using namespace llvm;
46
47#define DEBUG_TYPE "sccp"
48
49STATISTIC(NumInstRemoved, "Number of instructions removed");
50STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
51STATISTIC(NumInstReplaced,
52 "Number of instructions replaced with (simpler) instruction");
53
54// runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
55// and return true if the function was modified.
56static bool runSCCP(Function &F, const DataLayout &DL,
57 const TargetLibraryInfo *TLI, DominatorTree &DT,
58 AssumptionCache &AC) {
59 LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
60 SCCPSolver Solver(
61 DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
62 F.getContext());
63
64 Solver.addPredicateInfo(F, DT, AC);
65
66 // While we don't do any actual inter-procedural analysis, still track
67 // return values so we can infer attributes.
69 Solver.addTrackedFunction(&F);
70
71 // Mark the first block of the function as being executable.
72 Solver.markBlockExecutable(&F.front());
73
74 // Initialize arguments based on attributes.
75 for (Argument &AI : F.args())
76 Solver.trackValueOfArgument(&AI);
77
78 // Solve for constants.
79 bool ResolvedUndefs = true;
80 while (ResolvedUndefs) {
81 Solver.solve();
82 LLVM_DEBUG(dbgs() << "RESOLVING UNDEFs\n");
83 ResolvedUndefs = Solver.resolvedUndefsIn(F);
84 }
85
86 bool MadeChanges = false;
87
88 // If we decided that there are basic blocks that are dead in this function,
89 // delete their contents now. Note that we cannot actually delete the blocks,
90 // as we cannot modify the CFG of the function.
91
92 SmallPtrSet<Value *, 32> InsertedValues;
93 SmallVector<BasicBlock *, 8> BlocksToErase;
94 for (BasicBlock &BB : F) {
95 if (!Solver.isBlockExecutable(&BB)) {
96 LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
97 ++NumDeadBlocks;
98 BlocksToErase.push_back(&BB);
99 MadeChanges = true;
100 continue;
101 }
102
103 MadeChanges |= Solver.simplifyInstsInBlock(BB, InsertedValues,
104 NumInstRemoved, NumInstReplaced);
105 }
106
107 // Remove unreachable blocks and non-feasible edges.
108 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
109 for (BasicBlock *DeadBB : BlocksToErase)
110 NumInstRemoved += changeToUnreachable(&*DeadBB->getFirstNonPHIIt(),
111 /*PreserveLCSSA=*/false, &DTU);
112
113 BasicBlock *NewUnreachableBB = nullptr;
114 for (BasicBlock &BB : F)
115 MadeChanges |= Solver.removeNonFeasibleEdges(&BB, DTU, NewUnreachableBB);
116
117 for (BasicBlock *DeadBB : BlocksToErase)
118 if (!DeadBB->hasAddressTaken())
119 DTU.deleteBB(DeadBB);
120
121 Solver.removeSSACopies(F);
122
123 Solver.inferReturnAttributes();
124
125 return MadeChanges;
126}
127
129 const DataLayout &DL = F.getDataLayout();
130 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
131 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
132 auto &AC = AM.getResult<AssumptionAnalysis>(F);
133 if (!runSCCP(F, DL, &TLI, DT, AC))
134 return PreservedAnalyses::all();
135
136 auto PA = PreservedAnalyses();
137 PA.preserve<DominatorTreeAnalysis>();
138 return PA;
139}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This is the interface for a simple mod/ref and alias analysis over globals.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
static bool runSCCP(Function &F, const DataLayout &DL, const TargetLibraryInfo *TLI, DominatorTree &DT, AssumptionCache &AC)
Definition SCCP.cpp:56
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
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.
Definition Argument.h:32
A function analysis which provides an AssumptionCache.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
Definition BasicBlock.h:62
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition SCCP.cpp:128
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
Definition SCCPSolver.h:66
LLVM_ABI void addPredicateInfo(Function &F, DominatorTree &DT, AssumptionCache &AC)
LLVM_ABI void solve()
Solve - Solve for constants and executable blocks.
LLVM_ABI void trackValueOfArgument(Argument *V)
trackValueOfArgument - Mark the specified argument overdefined unless it have range attribute.
LLVM_ABI void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
LLVM_ABI bool resolvedUndefsIn(Function &F)
resolvedUndefsIn - While solving the dataflow for a function, we assume that branches on undef values...
LLVM_ABI bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
LLVM_ABI bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
LLVM_ABI bool isBlockExecutable(BasicBlock *BB) const
LLVM_ABI void inferReturnAttributes() const
LLVM_ABI bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
LLVM_ABI void removeSSACopies(Function &F)
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI 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...
Definition Local.cpp:2543
LLVM_ABI bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.