Skip to content

Commit bbab9f9

Browse files
author
Sjoerd Meijer
committed
[SCCP] Create SCCP Solver
This refactors SCCP and creates a SCCPSolver interface and class so that it can be used by other passes and transformations. We will use this in D93838, which adds a function specialisation pass. This is based on an early version by Vinay Madhusudan. Differential Revision: https://reviews.llvm.org/D93762
1 parent 7a9cb80 commit bbab9f9

File tree

5 files changed

+1807
-1528
lines changed

5 files changed

+1807
-1528
lines changed

llvm/include/llvm/Transforms/Scalar/SCCP.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/IR/Module.h"
2828
#include "llvm/IR/PassManager.h"
2929
#include "llvm/Transforms/Utils/PredicateInfo.h"
30+
#include "llvm/Transforms/Utils/SCCPSolver.h"
3031

3132
namespace llvm {
3233

@@ -38,13 +39,6 @@ class SCCPPass : public PassInfoMixin<SCCPPass> {
3839
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
3940
};
4041

41-
/// Helper struct for bundling up the analysis results per function for IPSCCP.
42-
struct AnalysisResultsForFn {
43-
std::unique_ptr<PredicateInfo> PredInfo;
44-
DominatorTree *DT;
45-
PostDominatorTree *PDT;
46-
};
47-
4842
bool runIPSCCP(Module &M, const DataLayout &DL,
4943
std::function<const TargetLibraryInfo &(Function &)> GetTLI,
5044
function_ref<AnalysisResultsForFn(Function &)> getAnalysis);
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
//===- SCCPSolver.h - SCCP Utility ----------------------------- *- C++ -*-===//
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+
// \file
10+
// This file implements Sparse Conditional Constant Propagation (SCCP) utility.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_TRANSFORMS_UTILS_SCCP_SOLVER_H
15+
#define LLVM_TRANSFORMS_UTILS_SCCP_SOLVER_H
16+
17+
#include "llvm/ADT/MapVector.h"
18+
#include "llvm/Analysis/DomTreeUpdater.h"
19+
#include "llvm/Analysis/TargetLibraryInfo.h"
20+
#include "llvm/Analysis/ValueLattice.h"
21+
#include "llvm/Analysis/ValueLatticeUtils.h"
22+
#include "llvm/IR/InstVisitor.h"
23+
#include "llvm/Transforms/Utils/PredicateInfo.h"
24+
#include <cassert>
25+
#include <utility>
26+
#include <vector>
27+
28+
namespace llvm {
29+
30+
/// Helper struct for bundling up the analysis results per function for IPSCCP.
31+
struct AnalysisResultsForFn {
32+
std::unique_ptr<PredicateInfo> PredInfo;
33+
DominatorTree *DT;
34+
PostDominatorTree *PDT;
35+
};
36+
37+
class SCCPInstVisitor;
38+
39+
//===----------------------------------------------------------------------===//
40+
//
41+
/// SCCPSolver - This interface class is a general purpose solver for Sparse
42+
/// Conditional Constant Propagation (SCCP).
43+
///
44+
class SCCPSolver {
45+
std::unique_ptr<SCCPInstVisitor> Visitor;
46+
47+
public:
48+
SCCPSolver(const DataLayout &DL,
49+
std::function<const TargetLibraryInfo &(Function &)> GetTLI,
50+
LLVMContext &Ctx);
51+
52+
~SCCPSolver();
53+
54+
void addAnalysis(Function &F, AnalysisResultsForFn A);
55+
56+
/// MarkBlockExecutable - This method can be used by clients to mark all of
57+
/// the blocks that are known to be intrinsically live in the processed unit.
58+
/// This returns true if the block was not considered live before.
59+
bool MarkBlockExecutable(BasicBlock *BB);
60+
61+
const PredicateBase *getPredicateInfoFor(Instruction *I);
62+
63+
DomTreeUpdater getDTU(Function &F);
64+
65+
/// TrackValueOfGlobalVariable - Clients can use this method to
66+
/// inform the SCCPSolver that it should track loads and stores to the
67+
/// specified global variable if it can. This is only legal to call if
68+
/// performing Interprocedural SCCP.
69+
void TrackValueOfGlobalVariable(GlobalVariable *GV);
70+
71+
/// AddTrackedFunction - If the SCCP solver is supposed to track calls into
72+
/// and out of the specified function (which cannot have its address taken),
73+
/// this method must be called.
74+
void AddTrackedFunction(Function *F);
75+
76+
/// Add function to the list of functions whose return cannot be modified.
77+
void addToMustPreserveReturnsInFunctions(Function *F);
78+
79+
/// Returns true if the return of the given function cannot be modified.
80+
bool mustPreserveReturn(Function *F);
81+
82+
void AddArgumentTrackedFunction(Function *F);
83+
84+
/// Returns true if the given function is in the solver's set of
85+
/// argument-tracked functions.
86+
bool isArgumentTrackedFunction(Function *F);
87+
88+
/// Solve - Solve for constants and executable blocks.
89+
void Solve();
90+
91+
/// ResolvedUndefsIn - While solving the dataflow for a function, we assume
92+
/// that branches on undef values cannot reach any of their successors.
93+
/// However, this is not a safe assumption. After we solve dataflow, this
94+
/// method should be use to handle this. If this returns true, the solver
95+
/// should be rerun.
96+
bool ResolvedUndefsIn(Function &F);
97+
98+
bool isBlockExecutable(BasicBlock *BB) const;
99+
100+
// isEdgeFeasible - Return true if the control flow edge from the 'From' basic
101+
// block to the 'To' basic block is currently feasible.
102+
bool isEdgeFeasible(BasicBlock *From, BasicBlock *To) const;
103+
104+
std::vector<ValueLatticeElement> getStructLatticeValueFor(Value *V) const;
105+
106+
void removeLatticeValueFor(Value *V);
107+
108+
const ValueLatticeElement &getLatticeValueFor(Value *V) const;
109+
110+
/// getTrackedRetVals - Get the inferred return value map.
111+
const MapVector<Function *, ValueLatticeElement> &getTrackedRetVals();
112+
113+
/// getTrackedGlobals - Get and return the set of inferred initializers for
114+
/// global variables.
115+
const DenseMap<GlobalVariable *, ValueLatticeElement> &getTrackedGlobals();
116+
117+
/// getMRVFunctionsTracked - Get the set of functions which return multiple
118+
/// values tracked by the pass.
119+
const SmallPtrSet<Function *, 16> getMRVFunctionsTracked();
120+
121+
/// markOverdefined - Mark the specified value overdefined. This
122+
/// works with both scalars and structs.
123+
void markOverdefined(Value *V);
124+
125+
// isStructLatticeConstant - Return true if all the lattice values
126+
// corresponding to elements of the structure are constants,
127+
// false otherwise.
128+
bool isStructLatticeConstant(Function *F, StructType *STy);
129+
130+
/// Helper to return a Constant if \p LV is either a constant or a constant
131+
/// range with a single element.
132+
Constant *getConstant(const ValueLatticeElement &LV) const;
133+
};
134+
135+
} // namespace llvm
136+
137+
#endif // LLVM_TRANSFORMS_UTILS_SCCP_SOLVER_H

0 commit comments

Comments
 (0)