Skip to content

Commit 550a4bb

Browse files
committed
Update PR to new upstream logic
1 parent 3a781ef commit 550a4bb

File tree

5 files changed

+261
-81
lines changed

5 files changed

+261
-81
lines changed

deps/LLVMExtra/lib/NewPM.cpp

Lines changed: 156 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include <llvm/Passes/PassBuilder.h>
77
#include <llvm/Passes/StandardInstrumentations.h>
88
#include <llvm/Support/CBindingWrapping.h>
9+
#include <optional>
910

1011
using namespace llvm;
1112

@@ -143,53 +144,166 @@ void LLVMPassBuilderExtensionsSetAAPipeline(LLVMPassBuilderExtensionsRef Extensi
143144
}
144145
#endif
145146

147+
static bool checkParametrizedPassName(StringRef Name, StringRef PassName) {
148+
if (!Name.consume_front(PassName))
149+
return false;
150+
// normal pass name w/o parameters == default parameters
151+
if (Name.empty())
152+
return true;
153+
#if LLVM_VERSION_MAJOR >= 16
154+
return Name.starts_with("<") && Name.ends_with(">");
155+
#else
156+
return Name.startswith("<") && Name.endswith(">");
157+
#endif
158+
}
159+
160+
static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
161+
return StringSwitch<std::optional<OptimizationLevel>>(S)
162+
.Case("O0", OptimizationLevel::O0)
163+
.Case("O1", OptimizationLevel::O1)
164+
.Case("O2", OptimizationLevel::O2)
165+
.Case("O3", OptimizationLevel::O3)
166+
.Case("Os", OptimizationLevel::Os)
167+
.Case("Oz", OptimizationLevel::Oz)
168+
.Default(std::nullopt);
169+
}
170+
171+
static Expected<OptimizationLevel> parseOptLevelParam(StringRef S) {
172+
std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
173+
if (OptLevel)
174+
return *OptLevel;
175+
return make_error<StringError>(
176+
formatv("invalid optimization level '{}'", S).str(),
177+
inconvertibleErrorCode());
178+
}
179+
180+
template <typename ParametersParseCallableT>
181+
static auto parsePassParameters(ParametersParseCallableT &&Parser,
182+
StringRef Name, StringRef PassName)
183+
-> decltype(Parser(StringRef{})) {
184+
using ParametersT = typename decltype(Parser(StringRef{}))::value_type;
185+
186+
StringRef Params = Name;
187+
if (!Params.consume_front(PassName)) {
188+
llvm_unreachable(
189+
"unable to strip pass name from parametrized pass specification");
190+
}
191+
if (!Params.empty() &&
192+
(!Params.consume_front("<") || !Params.consume_back(">"))) {
193+
llvm_unreachable("invalid format for parametrized pass name");
194+
}
195+
196+
Expected<ParametersT> Result = Parser(Params);
197+
assert((Result || Result.template errorIsA<StringError>()) &&
198+
"Pass parameter parser can only return StringErrors.");
199+
return Result;
200+
}
201+
202+
146203
// Register target specific parsing callbacks
147204
static void registerCallbackParsing(PassBuilder &PB) {
148-
PB.registerPipelineParsingCallback(
149-
[&](StringRef Name, FunctionPassManager &PM,
150-
ArrayRef<PassBuilder::PipelineElement> InnerPipeline) {
151-
#define FUNCTION_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(PM, OptimizationLevel::O2); return true; }
152-
#include "callbacks.inc"
153-
#undef FUNCTION_CALLBACK
154-
return false;
155-
}
156-
);
157-
158-
PB.registerPipelineParsingCallback(
159-
[&](StringRef Name, ModulePassManager &PM,
160-
ArrayRef<PassBuilder::PipelineElement> InnerPipeline) {
161-
#define MODULE_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(PM, OptimizationLevel::O2); return true; }
162-
#include "callbacks.inc"
163-
#undef MODULE_CALLBACK
164-
#if LLVM_VERSION_MAJOR >= 20
165-
#define MODULE_LTO_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(PM, OptimizationLevel::O2, ThinOrFullLTOPhase::None); return true; }
205+
PB.registerPipelineParsingCallback(
206+
[&](StringRef Name, ModulePassManager &PM,
207+
ArrayRef<PassBuilder::PipelineElement>) {
208+
#define MODULE_CALLBACK(NAME, INVOKE) \
209+
if (checkParametrizedPassName(Name, NAME)) { \
210+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
211+
if (!L) { \
212+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
213+
return false; \
214+
} \
215+
PB.INVOKE(PM, L.get()); \
216+
return true; \
217+
}
218+
#include "callbacks.inc"
219+
return false;
220+
});
221+
222+
// Module-level callbacks with LTO phase (use Phase::None for string API)
223+
PB.registerPipelineParsingCallback(
224+
[&](StringRef Name, ModulePassManager &PM,
225+
ArrayRef<PassBuilder::PipelineElement>) {
226+
#if LLVM_VERSION_MAJOR > 20
227+
#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
228+
if (checkParametrizedPassName(Name, NAME)) { \
229+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
230+
if (!L) { \
231+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
232+
return false; \
233+
} \
234+
PB.INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
235+
return true; \
236+
}
237+
#include "callbacks.inc"
166238
#else
167-
#define MODULE_LTO_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(PM, OptimizationLevel::O2); return true; }
239+
#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
240+
if (checkParametrizedPassName(Name, NAME)) { \
241+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
242+
if (!L) { \
243+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
244+
return false; \
245+
} \
246+
PB.INVOKE(PM, L.get()); \
247+
return true; \
248+
}
249+
#include "callbacks.inc"
168250
#endif
169-
#include "callbacks.inc"
170-
#undef MODULE_LTO_CALLBACK
171-
return false;
172-
}
173-
);
174-
175-
PB.registerPipelineParsingCallback(
176-
[&](StringRef Name, CGSCCPassManager &CGPM,
177-
ArrayRef<PassBuilder::PipelineElement> InnerPipeline) {
178-
#define CGSCC_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(CGPM, OptimizationLevel::O2); return true; }
179-
#include "callbacks.inc"
180-
#undef CGSCC_CALLBACK
181-
return false;
182-
}
183-
);
184-
PB.registerPipelineParsingCallback(
185-
[&](StringRef Name, LoopPassManager &PM,
186-
ArrayRef<PassBuilder::PipelineElement> InnerPipeline) {
187-
#define LOOP_CALLBACK(NAME, INVOKE) if (Name == NAME) { PB.INVOKE(PM, OptimizationLevel::O2); return true; }
188-
#include "callbacks.inc"
189-
#undef LOOP_CALLBACK
190-
return false;
251+
return false;
252+
});
253+
254+
// Function-level callbacks
255+
PB.registerPipelineParsingCallback(
256+
[&](StringRef Name, FunctionPassManager &PM,
257+
ArrayRef<PassBuilder::PipelineElement>) {
258+
#define FUNCTION_CALLBACK(NAME, INVOKE) \
259+
if (checkParametrizedPassName(Name, NAME)) { \
260+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
261+
if (!L) { \
262+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
263+
return false; \
264+
} \
265+
PB.INVOKE(PM, L.get()); \
266+
return true; \
267+
}
268+
#include "callbacks.inc"
269+
return false;
270+
});
271+
272+
// CGSCC-level callbacks
273+
PB.registerPipelineParsingCallback(
274+
[&](StringRef Name, CGSCCPassManager &PM,
275+
ArrayRef<PassBuilder::PipelineElement>) {
276+
#define CGSCC_CALLBACK(NAME, INVOKE) \
277+
if (checkParametrizedPassName(Name, NAME)) { \
278+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
279+
if (!L) { \
280+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
281+
return false; \
282+
} \
283+
PB.INVOKE(PM, L.get()); \
284+
return true; \
285+
}
286+
#include "callbacks.inc"
287+
return false;
288+
});
289+
290+
// Loop-level callbacks
291+
PB.registerPipelineParsingCallback(
292+
[&](StringRef Name, LoopPassManager &PM,
293+
ArrayRef<PassBuilder::PipelineElement>) {
294+
#define LOOP_CALLBACK(NAME, INVOKE) \
295+
if (checkParametrizedPassName(Name, NAME)) { \
296+
auto L = parsePassParameters(parseOptLevelParam, Name, NAME); \
297+
if (!L) { \
298+
errs() << NAME ": " << toString(L.takeError()) << '\n'; \
299+
return false; \
300+
} \
301+
PB.INVOKE(PM, L.get()); \
302+
return true; \
191303
}
192-
);
304+
#include "callbacks.inc"
305+
return false;
306+
});
193307
}
194308

195309
// Vendored API entrypoint

deps/LLVMExtra/lib/callbacks.inc

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1-
#ifdef FUNCTION_CALLBACK
2-
FUNCTION_CALLBACK("PeepholeCallbacks", invokePeepholeEPCallbacks)
3-
FUNCTION_CALLBACK("ScalarOptimizerLateCallbacks", invokeScalarOptimizerLateEPCallbacks)
4-
FUNCTION_CALLBACK("VectorizerStartCallbacks", invokeVectorizerStartEPCallbacks)
1+
#ifdef MODULE_CALLBACK
2+
MODULE_CALLBACK("pipeline-start-callbacks", invokePipelineStartEPCallbacks)
53
#endif
4+
#undef MODULE_CALLBACK
65

7-
#ifdef LOOP_CALLBACK
8-
LOOP_CALLBACK("LateLoopOptimizationsCallbacks", invokeLateLoopOptimizationsEPCallbacks)
9-
LOOP_CALLBACK("LoopOptimizerEndCallbacks", invokeLoopOptimizerEndEPCallbacks)
6+
// There are some full lto specific ones that are ignored here for now
7+
#ifdef MODULE_LTO_CALLBACK
8+
MODULE_LTO_CALLBACK("pipeline-early-simplification-callbacks", invokePipelineEarlySimplificationEPCallbacks)
9+
MODULE_LTO_CALLBACK("optimizer-early-callbacks", invokeOptimizerEarlyEPCallbacks)
10+
MODULE_LTO_CALLBACK("optimizer-last-callbacks", invokeOptimizerLastEPCallbacks)
1011
#endif
12+
#undef MODULE_LTO_CALLBACK
1113

12-
#ifdef MODULE_CALLBACK
13-
MODULE_CALLBACK("PipelineStartCallbacks", invokePipelineStartEPCallbacks)
14+
#ifdef FUNCTION_CALLBACK
15+
FUNCTION_CALLBACK("peephole-callbacks", invokePeepholeEPCallbacks)
16+
FUNCTION_CALLBACK("scalar-optimizer-late-callbacks", invokeScalarOptimizerLateEPCallbacks)
17+
FUNCTION_CALLBACK("vectorizer-start-callbacks", invokeVectorizerStartEPCallbacks)
18+
#if LLVM_VERSION_MAJOR >= 21
19+
FUNCTION_CALLBACK("vectorizer-end-callbacks", invokeVectorizerEndEPCallbacks)
1420
#endif
15-
16-
// There are some full lto specific ones that are ignored here
17-
#ifdef MODULE_LTO_CALLBACK
18-
MODULE_LTO_CALLBACK("PipelineEarlySimplificationCallbacks", invokePipelineEarlySimplificationEPCallbacks)
19-
MODULE_LTO_CALLBACK("OptimizerEarlyCallbacks", invokeOptimizerEarlyEPCallbacks)
20-
MODULE_LTO_CALLBACK("OptimizerLastCallbacks", invokeOptimizerLastEPCallbacks)
2121
#endif
22+
#undef FUNCTION_CALLBACK
2223

2324
#ifdef CGSCC_CALLBACK
24-
CGSCC_CALLBACK("CGSCCOptimizerLateCallbacks", invokeCGSCCOptimizerLateEPCallbacks)
25-
#endif
25+
CGSCC_CALLBACK("cgscc-optimizer-late-callbacks", invokeCGSCCOptimizerLateEPCallbacks)
26+
#endif
27+
#undef CGSCC_CALLBACK
28+
29+
#ifdef LOOP_CALLBACK
30+
LOOP_CALLBACK("late-loop-optimizations-callbacks", invokeLateLoopOptimizationsEPCallbacks)
31+
LOOP_CALLBACK("loop-optimizer-end-callbacks", invokeLoopOptimizerEndEPCallbacks)
32+
#endif
33+
#undef LOOP_CALLBACK

deps/build_local.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ LLVM_DIR = joinpath(LLVM.artifact_dir, "lib", "cmake", "llvm")
4747

4848
# build and install
4949
@info "Building" source_dir scratch_dir build_dir LLVM_DIR
50-
cmake() do cmake_path
50+
cmake(adjust_LIBPATH=false) do cmake_path
5151
config_opts = `-DLLVM_ROOT=$(LLVM_DIR) -DCMAKE_INSTALL_PREFIX=$(scratch_dir)`
5252
if Sys.iswindows()
5353
# prevent picking up MSVC

src/newpm.jl

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -514,11 +514,29 @@ function InternalizePass(; preserved_gvs::Vector=String[], kwargs...)
514514

515515
"internalize" * kwargs_to_params(kwargs)
516516
end
517-
# Module callbacks
518-
@module_pass "PipelineStartCallbacks" PipelineStartCallbacks
519-
@module_pass "PipelineEarlySimplificationCallbacks" PipelineEarlySimplificationCallbacks
520-
@module_pass "OptimizerEarlyCallbacks" OptimizerEarlyCallbacks
521-
@module_pass "OptimizerLastCallbacks" OptimizerLastCallbacks
517+
# Module callbacks (not part of general pass sweep)
518+
export PipelineStartCallbacks, PipelineEarlySimplificationCallbacks,
519+
OptimizerEarlyCallbacks, OptimizerLastCallbacks
520+
function PipelineStartCallbacks(; opt_level=0)
521+
opts = Dict{Symbol,Any}()
522+
opts[Symbol("O$opt_level")] = true
523+
"pipeline-start-callbacks" * kwargs_to_params(opts)
524+
end
525+
function PipelineEarlySimplificationCallbacks(; opt_level=0)
526+
opts = Dict{Symbol,Any}()
527+
opts[Symbol("O$opt_level")] = true
528+
"pipeline-early-simplification-callbacks" * kwargs_to_params(opts)
529+
end
530+
function OptimizerEarlyCallbacks(; opt_level=0)
531+
opts = Dict{Symbol,Any}()
532+
opts[Symbol("O$opt_level")] = true
533+
"optimizer-early-callbacks" * kwargs_to_params(opts)
534+
end
535+
function OptimizerLastCallbacks(; opt_level=0)
536+
opts = Dict{Symbol,Any}()
537+
opts[Symbol("O$opt_level")] = true
538+
"optimizer-last-callbacks" * kwargs_to_params(opts)
539+
end
522540

523541
# CGSCC passes
524542

@@ -531,8 +549,13 @@ end
531549
@cgscc_pass "inline" InlinerPass
532550
@cgscc_pass "coro-split" CoroSplitPass
533551

534-
#CGSCC callbacks
535-
@cgscc_pass "CGSCCOptimizerLateCallbacks" CGSCCOptimizerLateCallbacks
552+
#CGSCC callbacks (not part of general pass sweep)
553+
export CGSCCOptimizerLateCallbacks
554+
function CGSCCOptimizerLateCallbacks(; opt_level=0)
555+
opts = Dict{Symbol,Any}()
556+
opts[Symbol("O$opt_level")] = true
557+
"cgscc-optimizer-late-callbacks" * kwargs_to_params(opts)
558+
end
536559

537560
# function passes
538561

@@ -717,10 +740,31 @@ end
717740
@function_pass "gvn" GVNPass
718741
@function_pass "print<stack-lifetime>" StackLifetimePrinterPass
719742

720-
# Function pass callbacks
721-
@function_pass "PeepholeCallbacks" PeepholeCallbacks
722-
@function_pass "ScalarOptimizerLateCallbacks" ScalarOptimizerLateCallbacks
723-
@function_pass "VectorizerStartCallbacks" VectorizerStartCallbacks
743+
# Function pass callbacks (not part of general pass sweep)
744+
export PeepholeCallbacks, ScalarOptimizerLateCallbacks, VectorizerStartCallbacks
745+
function PeepholeCallbacks(; opt_level=0)
746+
opts = Dict{Symbol,Any}()
747+
opts[Symbol("O$opt_level")] = true
748+
"peephole-callbacks" * kwargs_to_params(opts)
749+
end
750+
function ScalarOptimizerLateCallbacks(; opt_level=0)
751+
opts = Dict{Symbol,Any}()
752+
opts[Symbol("O$opt_level")] = true
753+
"scalar-optimizer-late-callbacks" * kwargs_to_params(opts)
754+
end
755+
function VectorizerStartCallbacks(; opt_level=0)
756+
opts = Dict{Symbol,Any}()
757+
opts[Symbol("O$opt_level")] = true
758+
"vectorizer-start-callbacks" * kwargs_to_params(opts)
759+
end
760+
@static if version() >= v"21"
761+
export VectorizerEndCallbacks
762+
function VectorizerEndCallbacks(; opt_level=0)
763+
opts = Dict{Symbol,Any}()
764+
opts[Symbol("O$opt_level")] = true
765+
"vectorizer-end-callbacks" * kwargs_to_params(opts)
766+
end
767+
end
724768
# loop nest passes
725769

726770
@loop_pass "loop-flatten" LoopFlattenPass
@@ -758,9 +802,18 @@ end
758802
@loop_pass "licm" LICMPass
759803
@loop_pass "lnicm" LNICMPass
760804

761-
# Loop Callbacks
762-
@loop_pass "LateLoopOptimizationsCallbacks" LateLoopOptimizationsCallbacks
763-
@loop_pass "LoopOptimizerEndCallbacks" LoopOptimizerEndCallbacks
805+
# Loop Callbacks (not part of general pass sweep)
806+
export LateLoopOptimizationsCallbacks, LoopOptimizerEndCallbacks
807+
function LateLoopOptimizationsCallbacks(; opt_level=0)
808+
opts = Dict{Symbol,Any}()
809+
opts[Symbol("O$opt_level")] = true
810+
"late-loop-optimizations-callbacks" * kwargs_to_params(opts)
811+
end
812+
function LoopOptimizerEndCallbacks(; opt_level=0)
813+
opts = Dict{Symbol,Any}()
814+
opts[Symbol("O$opt_level")] = true
815+
"loop-optimizer-end-callbacks" * kwargs_to_params(opts)
816+
end
764817

765818

766819
## alias analyses

0 commit comments

Comments
 (0)