Skip to content

Commit f952bc0

Browse files
committed
[IPSCCP] Create a Pass parameter to control specialization of functions.
Required for D140210 in order to disable FuncSpec at {Os, Oz} optimization levels. Differential Revision: https://reviews.llvm.org/D140564
1 parent a337c16 commit f952bc0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+119
-63
lines changed

llvm/include/llvm/Transforms/IPO/SCCP.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,36 @@ namespace llvm {
2626

2727
class Module;
2828

29+
/// A set of parameters to control various transforms performed by IPSCCP pass.
30+
/// Each of the boolean parameters can be set to:
31+
/// true - enabling the transformation.
32+
/// false - disabling the transformation.
33+
/// Intended use is to create a default object, modify parameters with
34+
/// additional setters and then pass it to IPSCCP.
35+
struct IPSCCPOptions {
36+
bool AllowFuncSpec;
37+
38+
IPSCCPOptions(bool AllowFuncSpec = false) : AllowFuncSpec(AllowFuncSpec) {}
39+
40+
/// Enables or disables Specialization of Functions.
41+
IPSCCPOptions &setFuncSpec(bool FuncSpec) {
42+
AllowFuncSpec = FuncSpec;
43+
return *this;
44+
}
45+
};
46+
2947
/// Pass to perform interprocedural constant propagation.
3048
class IPSCCPPass : public PassInfoMixin<IPSCCPPass> {
49+
IPSCCPOptions Options;
50+
3151
public:
52+
IPSCCPPass() = default;
53+
54+
IPSCCPPass(IPSCCPOptions Options) : Options(Options) {}
55+
3256
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
57+
58+
bool isFuncSpecEnabled() const { return Options.AllowFuncSpec; }
3359
};
3460

3561
} // end namespace llvm

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,23 @@ Expected<GVNOptions> parseGVNOptions(StringRef Params) {
835835
return Result;
836836
}
837837

838+
Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
839+
IPSCCPOptions Result;
840+
while (!Params.empty()) {
841+
StringRef ParamName;
842+
std::tie(ParamName, Params) = Params.split(';');
843+
844+
bool Enable = !ParamName.consume_front("no-");
845+
if (ParamName == "func-spec")
846+
Result.setFuncSpec(Enable);
847+
else
848+
return make_error<StringError>(
849+
formatv("invalid IPSCCP pass parameter '{0}' ", ParamName).str(),
850+
inconvertibleErrorCode());
851+
}
852+
return Result;
853+
}
854+
838855
Expected<SROAOptions> parseSROAOptions(StringRef Params) {
839856
if (Params.empty() || Params == "modify-cfg")
840857
return SROAOptions::ModifyCFG;

llvm/lib/Passes/PassRegistry.def

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,6 @@ MODULE_PASS("instrorderfile", InstrOrderFilePass())
7575
MODULE_PASS("instrprof", InstrProfiling())
7676
MODULE_PASS("internalize", InternalizePass())
7777
MODULE_PASS("invalidate<all>", InvalidateAllAnalysesPass())
78-
MODULE_PASS("ipsccp", IPSCCPPass())
7978
MODULE_PASS("iroutliner", IROutlinerPass())
8079
MODULE_PASS("print-ir-similarity", IRSimilarityAnalysisPrinterPass(dbgs()))
8180
MODULE_PASS("lower-global-dtors", LowerGlobalDtorsPass())
@@ -161,6 +160,13 @@ MODULE_PASS_WITH_PARAMS("msan",
161160
},
162161
parseMSanPassOptions,
163162
"recover;kernel;eager-checks;track-origins=N")
163+
MODULE_PASS_WITH_PARAMS("ipsccp",
164+
"IPSCCPPass",
165+
[](IPSCCPOptions Opts) {
166+
return IPSCCPPass(Opts);
167+
},
168+
parseIPSCCPOptions,
169+
"no-func-spec;func-spec")
164170
#undef MODULE_PASS_WITH_PARAMS
165171

166172
#ifndef CGSCC_ANALYSIS

llvm/lib/Transforms/IPO/SCCP.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ STATISTIC(NumDeadBlocks , "Number of basic blocks unreachable");
4242
STATISTIC(NumInstReplaced,
4343
"Number of instructions replaced with (simpler) instruction");
4444

45-
static cl::opt<bool> SpecializeFunctions("specialize-functions",
46-
cl::init(false), cl::Hidden, cl::desc("Enable function specialization"));
47-
4845
static cl::opt<unsigned> FuncSpecializationMaxIters(
4946
"func-specialization-max-iters", cl::init(1), cl::Hidden, cl::desc(
5047
"The maximum number of iterations function specialization is run"));
@@ -114,7 +111,8 @@ static bool runIPSCCP(
114111
std::function<const TargetLibraryInfo &(Function &)> GetTLI,
115112
std::function<TargetTransformInfo &(Function &)> GetTTI,
116113
std::function<AssumptionCache &(Function &)> GetAC,
117-
function_ref<AnalysisResultsForFn(Function &)> getAnalysis) {
114+
function_ref<AnalysisResultsForFn(Function &)> getAnalysis,
115+
bool IsFuncSpecEnabled) {
118116
SCCPSolver Solver(DL, GetTLI, M.getContext());
119117
FunctionSpecializer Specializer(Solver, M, FAM, GetTLI, GetTTI, GetAC);
120118

@@ -158,7 +156,7 @@ static bool runIPSCCP(
158156
// Solve for constants.
159157
Solver.solveWhileResolvedUndefsIn(M);
160158

161-
if (SpecializeFunctions) {
159+
if (IsFuncSpecEnabled) {
162160
unsigned Iters = 0;
163161
while (Iters++ < FuncSpecializationMaxIters && Specializer.run());
164162
}
@@ -225,7 +223,7 @@ static bool runIPSCCP(
225223
NumInstRemoved, NumInstReplaced);
226224
}
227225

228-
DomTreeUpdater DTU = SpecializeFunctions && Specializer.isClonedFunction(&F)
226+
DomTreeUpdater DTU = IsFuncSpecEnabled && Specializer.isClonedFunction(&F)
229227
? DomTreeUpdater(DomTreeUpdater::UpdateStrategy::Lazy)
230228
: Solver.getDTU(F);
231229

@@ -391,15 +389,16 @@ PreservedAnalyses IPSCCPPass::run(Module &M, ModuleAnalysisManager &AM) {
391389
auto GetAC = [&FAM](Function &F) -> AssumptionCache & {
392390
return FAM.getResult<AssumptionAnalysis>(F);
393391
};
394-
auto getAnalysis = [&FAM](Function &F) -> AnalysisResultsForFn {
392+
auto getAnalysis = [&FAM, this](Function &F) -> AnalysisResultsForFn {
395393
DominatorTree &DT = FAM.getResult<DominatorTreeAnalysis>(F);
396394
return {
397395
std::make_unique<PredicateInfo>(F, DT, FAM.getResult<AssumptionAnalysis>(F)),
398396
&DT, FAM.getCachedResult<PostDominatorTreeAnalysis>(F),
399-
SpecializeFunctions ? &FAM.getResult<LoopAnalysis>(F) : nullptr };
397+
isFuncSpecEnabled() ? &FAM.getResult<LoopAnalysis>(F) : nullptr };
400398
};
401399

402-
if (!runIPSCCP(M, DL, &FAM, GetTLI, GetTTI, GetAC, getAnalysis))
400+
if (!runIPSCCP(M, DL, &FAM, GetTLI, GetTTI, GetAC, getAnalysis,
401+
isFuncSpecEnabled()))
403402
return PreservedAnalyses::all();
404403

405404
PreservedAnalyses PA;
@@ -450,7 +449,7 @@ class IPSCCPLegacyPass : public ModulePass {
450449
nullptr};
451450
};
452451

453-
return runIPSCCP(M, DL, nullptr, GetTLI, GetTTI, GetAC, getAnalysis);
452+
return runIPSCCP(M, DL, nullptr, GetTLI, GetTTI, GetAC, getAnalysis, false);
454453
}
455454

456455
void getAnalysisUsage(AnalysisUsage &AU) const override {

llvm/test/Transforms/FunctionSpecialization/bug52821-use-after-free.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -passes=ipsccp -specialize-functions -S < %s | FileCheck %s
2+
; RUN: opt -passes="ipsccp<func-spec>" -S < %s | FileCheck %s
33

44
%mystruct = type { i32, [2 x i64] }
55

llvm/test/Transforms/FunctionSpecialization/bug55000-read-uninitialized-value.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -passes=ipsccp -specialize-functions -force-function-specialization -func-specialization-max-iters=2 -func-specialization-max-clones=1 -function-specialization-for-literal-constant=true -S < %s | FileCheck %s
1+
; RUN: opt -passes="ipsccp<func-spec>" -force-function-specialization -func-specialization-max-iters=2 -func-specialization-max-clones=1 -function-specialization-for-literal-constant=true -S < %s | FileCheck %s
22

33
declare hidden i1 @compare(ptr) align 2
44
declare hidden { i8, ptr } @getType(ptr) align 2

llvm/test/Transforms/FunctionSpecialization/compiler-crash-58759.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -S --passes='default<O3>' -specialize-functions < %s | FileCheck %s
1+
; RUN: opt -S --passes="default<O3>,ipsccp<func-spec>" < %s | FileCheck %s
22

33
define dso_local i32 @g0(i32 noundef %x) local_unnamed_addr {
44
entry:

llvm/test/Transforms/FunctionSpecialization/function-specialization-always-inline.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; RUN: opt -passes=ipsccp -specialize-functions -func-specialization-avg-iters-cost=3 -func-specialization-size-threshold=10 -S < %s | FileCheck %s
1+
; RUN: opt -passes="ipsccp<func-spec>" -func-specialization-avg-iters-cost=3 -func-specialization-size-threshold=10 -S < %s | FileCheck %s
22

33
; CHECK-NOT: foo.{{[0-9]+}}
44

llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-expression.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
; Note that this test case shows that function specialization pass would
55
; transform the function even if no specialization happened.
66

7-
; RUN: opt -passes=ipsccp -specialize-functions -force-function-specialization -S < %s | FileCheck %s
7+
; RUN: opt -passes="ipsccp<func-spec>" -force-function-specialization -S < %s | FileCheck %s
88

99
%struct = type { i8, i16, i32, i64, i64}
1010
@Global = internal constant %struct {i8 0, i16 1, i32 2, i64 3, i64 4}

llvm/test/Transforms/FunctionSpecialization/function-specialization-constant-expression2.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
2-
; RUN: opt -passes=ipsccp -specialize-functions -force-function-specialization -S < %s | FileCheck %s
2+
; RUN: opt -passes="ipsccp<func-spec>" -force-function-specialization -S < %s | FileCheck %s
33

44
; Check that we don't crash and specialise on a constant expression.
55

0 commit comments

Comments
 (0)