LLVM 20.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"
28#include "llvm/IR/BasicBlock.h"
30#include "llvm/IR/Function.h"
31#include "llvm/IR/InstrTypes.h"
32#include "llvm/IR/Instruction.h"
34#include "llvm/IR/PassManager.h"
35#include "llvm/IR/Type.h"
36#include "llvm/IR/Value.h"
37#include "llvm/Pass.h"
38#include "llvm/Support/Debug.h"
43
44using namespace llvm;
45
46#define DEBUG_TYPE "sccp"
47
48STATISTIC(NumInstRemoved, "Number of instructions removed");
49STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
50STATISTIC(NumInstReplaced,
51 "Number of instructions replaced with (simpler) instruction");
52
53// runSCCP() - Run the Sparse Conditional Constant Propagation algorithm,
54// and return true if the function was modified.
55static bool runSCCP(Function &F, const DataLayout &DL,
56 const TargetLibraryInfo *TLI, DomTreeUpdater &DTU) {
57 LLVM_DEBUG(dbgs() << "SCCP on function '" << F.getName() << "'\n");
58 SCCPSolver Solver(
59 DL, [TLI](Function &F) -> const TargetLibraryInfo & { return *TLI; },
60 F.getContext());
61
62 // While we don't do any actual inter-procedural analysis, still track
63 // return values so we can infer attributes.
65 Solver.addTrackedFunction(&F);
66
67 // Mark the first block of the function as being executable.
68 Solver.markBlockExecutable(&F.front());
69
70 // Initialize arguments based on attributes.
71 for (Argument &AI : F.args())
72 Solver.trackValueOfArgument(&AI);
73
74 // Solve for constants.
75 bool ResolvedUndefs = true;
76 while (ResolvedUndefs) {
77 Solver.solve();
78 LLVM_DEBUG(dbgs() << "RESOLVING UNDEFs\n");
79 ResolvedUndefs = Solver.resolvedUndefsIn(F);
80 }
81
82 bool MadeChanges = false;
83
84 // If we decided that there are basic blocks that are dead in this function,
85 // delete their contents now. Note that we cannot actually delete the blocks,
86 // as we cannot modify the CFG of the function.
87
88 SmallPtrSet<Value *, 32> InsertedValues;
89 SmallVector<BasicBlock *, 8> BlocksToErase;
90 for (BasicBlock &BB : F) {
91 if (!Solver.isBlockExecutable(&BB)) {
92 LLVM_DEBUG(dbgs() << " BasicBlock Dead:" << BB);
93 ++NumDeadBlocks;
94 BlocksToErase.push_back(&BB);
95 MadeChanges = true;
96 continue;
97 }
98
99 MadeChanges |= Solver.simplifyInstsInBlock(BB, InsertedValues,
100 NumInstRemoved, NumInstReplaced);
101 }
102
103 // Remove unreachable blocks and non-feasible edges.
104 for (BasicBlock *DeadBB : BlocksToErase)
105 NumInstRemoved += changeToUnreachable(DeadBB->getFirstNonPHI(),
106 /*PreserveLCSSA=*/false, &DTU);
107
108 BasicBlock *NewUnreachableBB = nullptr;
109 for (BasicBlock &BB : F)
110 MadeChanges |= Solver.removeNonFeasibleEdges(&BB, DTU, NewUnreachableBB);
111
112 for (BasicBlock *DeadBB : BlocksToErase)
113 if (!DeadBB->hasAddressTaken())
114 DTU.deleteBB(DeadBB);
115
116 Solver.inferReturnAttributes();
117
118 return MadeChanges;
119}
120
122 const DataLayout &DL = F.getDataLayout();
123 auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
125 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Lazy);
126 if (!runSCCP(F, DL, &TLI, DTU))
127 return PreservedAnalyses::all();
128
129 auto PA = PreservedAnalyses();
130 PA.preserve<DominatorTreeAnalysis>();
131 return PA;
132}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
#define LLVM_DEBUG(...)
Definition: Debug.h:106
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, DomTreeUpdater &DTU)
Definition: SCCP.cpp:55
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:166
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
Definition: PassManager.h:429
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:410
This class represents an incoming formal argument to a Function.
Definition: Argument.h:31
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:63
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:279
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: SCCP.cpp:121
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
Definition: SCCPSolver.h:65
void solve()
Solve - Solve for constants and executable blocks.
void trackValueOfArgument(Argument *V)
trackValueOfArgument - Mark the specified argument overdefined unless it have range attribute.
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
bool resolvedUndefsIn(Function &F)
resolvedUndefsIn - While solving the dataflow for a function, we assume that branches on undef values...
bool simplifyInstsInBlock(BasicBlock &BB, SmallPtrSetImpl< Value * > &InsertedValues, Statistic &InstRemovedStat, Statistic &InstReplacedStat)
Definition: SCCPSolver.cpp:235
bool removeNonFeasibleEdges(BasicBlock *BB, DomTreeUpdater &DTU, BasicBlock *&NewUnreachableBB) const
Definition: SCCPSolver.cpp:259
bool isBlockExecutable(BasicBlock *BB) const
void inferReturnAttributes() const
Definition: SCCPSolver.cpp:380
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:519
void push_back(const T &Elt)
Definition: SmallVector.h:413
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1196
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
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
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:2906
bool canTrackReturnsInterprocedurally(Function *F)
Determine if the values of the given function's returns can be tracked interprocedurally.