LLVM 22.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"
36#include "llvm/IR/PassManager.h"
37#include "llvm/IR/Type.h"
38#include "llvm/IR/Value.h"
39#include "llvm/Pass.h"
40#include "llvm/Support/Debug.h"
45
46using namespace llvm;
47
48#define DEBUG_TYPE "sccp"
49
50STATISTIC(NumInstRemoved, "Number of instructions removed");
51STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
52STATISTIC(NumInstReplaced,
53 "Number of instructions replaced with (simpler) instruction");
54
55// runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
56// and return true if the function was modified.
57static bool runSCCP(Function &F, const DataLayout &DL,
58 const TargetLibraryInfo *TLI, DominatorTree &DT,
59 AssumptionCache &AC) {
60 LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
61 SCCPSolver Solver(
62 DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
63 F.getContext());
64
65 Solver.addPredicateInfo(F, DT, AC);
66
67 // While we don't do any actual inter-procedural analysis, still track
68 // return values so we can infer attributes.
70 Solver.addTrackedFunction(&F);
71
72 // Mark the first block of the function as being executable.
73 Solver.markBlockExecutable(&F.front());
74
75 // Initialize arguments based on attributes.
76 for (Argument &AI : F.args())
77 Solver.trackValueOfArgument(&AI);
78
79 // Solve for constants.
80 bool ResolvedUndefs = true;
81 while (ResolvedUndefs) {
82 Solver.solve();
83 LLVM_DEBUG(dbgs() << "RESOLVING UNDEFs\n");
84 ResolvedUndefs = Solver.resolvedUndefsIn(F);
85 }
86
87 bool MadeChanges = false;
88
89 // If we decided that there are basic blocks that are dead in this function,
90 // delete their contents now. Note that we cannot actually delete the blocks,
91 // as we cannot modify the CFG of the function.
92
93 SmallPtrSet<Value *, 32> InsertedValues;
94 SmallVector<BasicBlock *, 8> BlocksToErase;
95 for (BasicBlock &BB : F) {
96 if (!Solver.isBlockExecutable(&BB)) {
97 LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
98 ++NumDeadBlocks;
99 BlocksToErase.push_back(&BB);
100 MadeChanges = true;
101 continue;
102 }
103
104 MadeChanges |= Solver.simplifyInstsInBlock(BB, InsertedValues,
105 NumInstRemoved, NumInstReplaced);
106 }
107
108 // Remove unreachable blocks and non-feasible edges.
109 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
110 for (BasicBlock *DeadBB : BlocksToErase)
111 NumInstRemoved += changeToUnreachable(&*DeadBB->getFirstNonPHIIt(),
112 /*PreserveLCSSA=*/false, &DTU);
113
114 BasicBlock *NewUnreachableBB = nullptr;
115 for (BasicBlock &BB : F)
116 MadeChanges |= Solver.removeNonFeasibleEdges(&BB, DTU, NewUnreachableBB);
117
118 for (BasicBlock *DeadBB : BlocksToErase)
119 if (!DeadBB->hasAddressTaken())
120 DTU.deleteBB(DeadBB);
121
122 Solver.removeSSACopies(F);
123
124 Solver.inferReturnAttributes();
125
126 return MadeChanges;
127}
128
130 const DataLayout &DL = F.getDataLayout();
131 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
132 auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
133 auto &AC = AM.getResult<AssumptionAnalysis>(F);
134 if (!runSCCP(F, DL, &TLI, DT, AC))
135 return PreservedAnalyses::all();
136
137 auto PA = PreservedAnalyses();
138 PA.preserve<DominatorTreeAnalysis>();
139 return PA;
140}
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:55
static bool runSCCP(Function &F, const DataLayout &DL, const TargetLibraryInfo *TLI, DominatorTree &DT, AssumptionCache &AC)
Definition: SCCP.cpp:57
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:167
#define LLVM_DEBUG(...)
Definition: Debug.h:119
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
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:63
LLVM_ABI void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:284
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition: Dominators.h:165
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:129
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)
Definition: SCCPSolver.cpp:290
LLVM_ABI bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
Definition: SCCPSolver.cpp:319
LLVM_ABI bool isBlockExecutable(BasicBlock *BB) const
LLVM_ABI void inferReturnAttributes() const
Definition: SCCPSolver.cpp:442
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.
Definition: SmallPtrSet.h:541
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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.
Definition: AddressRanges.h:18
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:2513
bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.