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:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
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: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)
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: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.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.