Skip to content

Commit 800104c

Browse files
committed
Create new pass manager struct
1 parent 6366857 commit 800104c

File tree

6 files changed

+130
-86
lines changed

6 files changed

+130
-86
lines changed

src/aotcompile.cpp

Lines changed: 67 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ void jl_dump_native_impl(void *native_code,
556556
PM.add(createBitcodeWriterPass(unopt_bc_OS));
557557
PM.run(M);
558558
}
559-
optimizeModule(M, TM.get(), jl_options.opt_level, true, true);
559+
NewPassManager NPM(*TM, jl_options.opt_level, true, true);
560+
NPM.run(M);
560561
legacy::PassManager PM;
561562
if (bc_fname)
562563
PM.add(createBitcodeWriterPass(bc_OS));
@@ -1049,7 +1050,7 @@ static void addSanitizers(ModulePassManager &MPM, int optlevel) {
10491050
// }
10501051
}
10511052

1052-
static void addPipeline(ModulePassManager &MPM, int opt_level, bool lower_intrinsics, bool dump_native)
1053+
static void addPipeline(ModulePassManager &MPM, int opt_level, bool lower_intrinsics, bool dump_native, bool external_use)
10531054
{
10541055
// TODO: CommonInstruction hoisting/sinking enables AllocOpt
10551056
// to merge allocations and sometimes eliminate them,
@@ -1115,7 +1116,7 @@ static void addPipeline(ModulePassManager &MPM, int opt_level, bool lower_intrin
11151116
}
11161117
MPM.addPass(LowerSIMDLoop()); // Annotate loop marked with "loopinfo" as LLVM parallel loop
11171118
if (dump_native) {
1118-
MPM.addPass(MultiVersioning());
1119+
MPM.addPass(MultiVersioning(external_use));
11191120
MPM.addPass(CPUFeatures());
11201121
// minimal clean-up to get rid of CPU feature checks
11211122
if (opt_level == 1) {
@@ -1150,7 +1151,7 @@ static void addPipeline(ModulePassManager &MPM, int opt_level, bool lower_intrin
11501151
}
11511152

11521153
if (dump_native)
1153-
MPM.addPass(MultiVersioning());
1154+
MPM.addPass(MultiVersioning(external_use));
11541155
MPM.addPass(CPUFeatures());
11551156
{
11561157
FunctionPassManager FPM;
@@ -1314,80 +1315,88 @@ static void addPipeline(ModulePassManager &MPM, int opt_level, bool lower_intrin
13141315
// TargetMachine::registerPassBuilderCallbacks. We need to find a solution either in working with upstream
13151316
// or adapting PassBuilder (or subclassing it) to suite our needs. This is in particular important for
13161317
// BPF, NVPTX, and AMDGPU.
1317-
1318-
void optimizeModule(Module &M, TargetMachine *TM, int opt_level, bool lower_intrinsics, bool dump_native)
1319-
{
1320-
// llvm::PassBuilder pb(targetMachine->LLVM, llvm::PipelineTuningOptions(), llvm::None, &passInstrumentationCallbacks);
1321-
PassInstrumentationCallbacks PIC;
1322-
StandardInstrumentations SI(false);
1323-
SI.registerCallbacks(PIC);
1318+
namespace { // NewPM
1319+
auto createPIC(StandardInstrumentations &SI) {
1320+
auto PIC = std::make_unique<PassInstrumentationCallbacks>();
1321+
SI.registerCallbacks(*PIC);
13241322

13251323
//Borrowed from LLVM PassBuilder.cpp:386
13261324
#define MODULE_PASS(NAME, CREATE_PASS) \
1327-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1325+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13281326
#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1329-
PIC.addClassToPassName(CLASS, NAME);
1327+
PIC->addClassToPassName(CLASS, NAME);
13301328
#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1331-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1329+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13321330
#define FUNCTION_PASS(NAME, CREATE_PASS) \
1333-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1331+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13341332
#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1335-
PIC.addClassToPassName(CLASS, NAME);
1333+
PIC->addClassToPassName(CLASS, NAME);
13361334
#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1337-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1335+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13381336
#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1339-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1337+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13401338
#define LOOP_PASS(NAME, CREATE_PASS) \
1341-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1339+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13421340
#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1343-
PIC.addClassToPassName(CLASS, NAME);
1341+
PIC->addClassToPassName(CLASS, NAME);
13441342
#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1345-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1343+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13461344
#define CGSCC_PASS(NAME, CREATE_PASS) \
1347-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1345+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13481346
#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1349-
PIC.addClassToPassName(CLASS, NAME);
1347+
PIC->addClassToPassName(CLASS, NAME);
13501348
#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1351-
PIC.addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
1349+
PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
13521350

13531351
#include "llvm-julia-passes.inc"
13541352

1355-
PassBuilder PB(TM, PipelineTuningOptions(), None, &PIC);
1356-
// Create the analysis managers.
1357-
LoopAnalysisManager LAM;
1358-
PB.registerLoopAnalyses(LAM);
1359-
1360-
AAManager AA;
1361-
// TODO: Why are we only doing this for -O3?
1362-
if (opt_level >= 3) {
1363-
AA.registerFunctionAnalysis<BasicAA>();
1353+
return PIC;
13641354
}
1365-
if (opt_level >= 2) {
1366-
AA.registerFunctionAnalysis<ScopedNoAliasAA>();
1367-
AA.registerFunctionAnalysis<TypeBasedAA>();
1368-
}
1369-
// TM->registerDefaultAliasAnalyses(AA);
1370-
1371-
FunctionAnalysisManager FAM;
1372-
// Register the AA manager first so that our version is the one used.
1373-
FAM.registerPass([&] { return std::move(AA); });
1374-
// Register our TargetLibraryInfoImpl.
1375-
FAM.registerPass([&] { return llvm::TargetIRAnalysis(TM->getTargetIRAnalysis()); });
1376-
FAM.registerPass([&] { return llvm::TargetLibraryAnalysis(llvm::TargetLibraryInfoImpl(TM->getTargetTriple())); });
13771355

1378-
PB.registerFunctionAnalyses(FAM);
1379-
1380-
CGSCCAnalysisManager CGAM;
1381-
PB.registerCGSCCAnalyses(CGAM);
1356+
auto createFAM(TargetMachine &TM, int opt_level) {
1357+
AAManager AA;
1358+
// TODO: Why are we only doing this for -O3?
1359+
if (opt_level >= 3) {
1360+
AA.registerFunctionAnalysis<BasicAA>();
1361+
}
1362+
if (opt_level >= 2) {
1363+
AA.registerFunctionAnalysis<ScopedNoAliasAA>();
1364+
AA.registerFunctionAnalysis<TypeBasedAA>();
1365+
}
1366+
// TM->registerDefaultAliasAnalyses(AA);
1367+
1368+
FunctionAnalysisManager FAM;
1369+
// Register the AA manager first so that our version is the one used.
1370+
FAM.registerPass([&] { return std::move(AA); });
1371+
// Register our TargetLibraryInfoImpl.
1372+
FAM.registerPass([&] { return llvm::TargetIRAnalysis(TM.getTargetIRAnalysis()); });
1373+
FAM.registerPass([&] { return llvm::TargetLibraryAnalysis(llvm::TargetLibraryInfoImpl(TM.getTargetTriple())); });
1374+
return FAM;
1375+
}
13821376

1383-
ModuleAnalysisManager MAM;
1384-
PB.registerModuleAnalyses(MAM);
1377+
auto createPB(TargetMachine &TM, PassInstrumentationCallbacks &PIC, LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM) {
1378+
PassBuilder PB(&TM, PipelineTuningOptions(), None, &PIC);
1379+
PB.registerLoopAnalyses(LAM);
1380+
PB.registerFunctionAnalyses(FAM);
1381+
PB.registerCGSCCAnalyses(CGAM);
1382+
PB.registerModuleAnalyses(MAM);
1383+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1384+
return PB;
1385+
}
13851386

1386-
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1387+
auto createMPM(int opt_level, bool lower_intrinsics, bool dump_native, bool external_use) {
1388+
ModulePassManager MPM;
1389+
addPipeline(MPM, opt_level, lower_intrinsics, dump_native, external_use);
1390+
return MPM;
1391+
}
1392+
}
13871393

1388-
ModulePassManager MPM;
1389-
addPipeline(MPM, opt_level, lower_intrinsics, dump_native);
1394+
NewPassManager::NewPassManager(TargetMachine &TM, int opt_level, bool lower_intrinsics, bool dump_native, bool external_use)
1395+
: SI(false), PIC(createPIC(SI)), LAM(), FAM(createFAM(TM, opt_level)), CGAM(), MAM(),
1396+
PB(createPB(TM, *PIC, LAM, FAM, CGAM, MAM)),
1397+
MPM(createMPM(opt_level, lower_intrinsics, dump_native, external_use)) {}
13901398

1399+
void NewPassManager::run(Module &M) {
13911400
MPM.run(M, MAM);
13921401
}
13931402

@@ -1550,10 +1559,12 @@ void *jl_get_llvmf_defn_impl(jl_method_instance_t *mi, size_t world, char getwra
15501559
// and will better match what's actually in sysimg.
15511560
for (auto &global : output.globals)
15521561
global.second->setLinkage(GlobalValue::ExternalLinkage);
1553-
if (optimize)
1562+
if (optimize) {
15541563
//Safe b/c context lock is held by output
15551564
// PM->run(*m.getModuleUnlocked());
1556-
optimizeModule(*m.getModuleUnlocked(), &jl_ExecutionEngine->getTargetMachine(), jl_options.opt_level);
1565+
NewPassManager NPM(jl_ExecutionEngine->getTargetMachine(), jl_options.opt_level);
1566+
NPM.run(*m.getModuleUnlocked());
1567+
}
15571568
const std::string *fname;
15581569
if (decls.functionObject == "jl_fptr_args" || decls.functionObject == "jl_fptr_sparam")
15591570
getwrapper = false;

src/codegen.cpp

Lines changed: 25 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -86,32 +86,8 @@
8686
#include <llvm/Bitcode/BitcodeReader.h>
8787
#include <llvm/Linker/Linker.h>
8888

89-
#define DEBUG_TYPE "julia_irgen_codegen"
90-
9189
using namespace llvm;
9290

93-
STATISTIC(EmittedAllocas, "Number of allocas emitted");
94-
STATISTIC(EmittedIntToPtrs, "Number of inttoptrs emitted");
95-
STATISTIC(ModulesCreated, "Number of LLVM Modules created");
96-
STATISTIC(EmittedBoxCompares, "Number of box compares emitted");
97-
STATISTIC(EmittedBitsUnionCompares, "Number of bitsunion compares emitted");
98-
STATISTIC(EmittedBitsCompares, "Number of bits compares emitted");
99-
STATISTIC(EmittedEgals, "Number of egals emitted");
100-
STATISTIC(EmittedOpfields, "Number of opfields emitted");
101-
STATISTIC(EmittedBuiltinCalls, "Number of builtin calls emitted");
102-
STATISTIC(EmittedJLCalls, "Number of jlcalls emitted");
103-
STATISTIC(EmittedSpecfunCalls, "Number of specialized calls emitted");
104-
STATISTIC(EmittedInvokes, "Number of invokes emitted");
105-
STATISTIC(EmittedCalls, "Number of calls emitted");
106-
STATISTIC(EmittedUndefVarErrors, "Number of undef var errors emitted");
107-
STATISTIC(EmittedOpaqueClosureFunctions, "Number of opaque closures emitted");
108-
STATISTIC(EmittedToJLInvokes, "Number of tojlinvoke calls emitted");
109-
STATISTIC(EmittedCFuncInvalidates, "Number of C function invalidates emitted");
110-
STATISTIC(GeneratedCFuncWrappers, "Number of C function wrappers generated");
111-
STATISTIC(GeneratedCCallables, "Number of C-callable functions generated");
112-
STATISTIC(GeneratedInvokeWrappers, "Number of invoke wrappers generated");
113-
STATISTIC(EmittedFunctions, "Number of functions emitted");
114-
11591
//Drag some useful type functions into our namespace
11692
//to reduce verbosity of our code
11793
auto getInt1Ty(LLVMContext &ctxt) {
@@ -186,6 +162,31 @@ typedef Instruction TerminatorInst;
186162
#include "processor.h"
187163
#include "julia_assert.h"
188164

165+
#undef DEBUG_TYPE
166+
#define DEBUG_TYPE "julia_irgen_codegen"
167+
168+
STATISTIC(EmittedAllocas, "Number of allocas emitted");
169+
STATISTIC(EmittedIntToPtrs, "Number of inttoptrs emitted");
170+
STATISTIC(ModulesCreated, "Number of LLVM Modules created");
171+
STATISTIC(EmittedBoxCompares, "Number of box compares emitted");
172+
STATISTIC(EmittedBitsUnionCompares, "Number of bitsunion compares emitted");
173+
STATISTIC(EmittedBitsCompares, "Number of bits compares emitted");
174+
STATISTIC(EmittedEgals, "Number of egals emitted");
175+
STATISTIC(EmittedOpfields, "Number of opfields emitted");
176+
STATISTIC(EmittedBuiltinCalls, "Number of builtin calls emitted");
177+
STATISTIC(EmittedJLCalls, "Number of jlcalls emitted");
178+
STATISTIC(EmittedSpecfunCalls, "Number of specialized calls emitted");
179+
STATISTIC(EmittedInvokes, "Number of invokes emitted");
180+
STATISTIC(EmittedCalls, "Number of calls emitted");
181+
STATISTIC(EmittedUndefVarErrors, "Number of undef var errors emitted");
182+
STATISTIC(EmittedOpaqueClosureFunctions, "Number of opaque closures emitted");
183+
STATISTIC(EmittedToJLInvokes, "Number of tojlinvoke calls emitted");
184+
STATISTIC(EmittedCFuncInvalidates, "Number of C function invalidates emitted");
185+
STATISTIC(GeneratedCFuncWrappers, "Number of C function wrappers generated");
186+
STATISTIC(GeneratedCCallables, "Number of C-callable functions generated");
187+
STATISTIC(GeneratedInvokeWrappers, "Number of invoke wrappers generated");
188+
STATISTIC(EmittedFunctions, "Number of functions emitted");
189+
189190
JL_STREAM *dump_emitted_mi_name_stream = NULL;
190191
extern "C" JL_DLLEXPORT
191192
void jl_dump_emitted_mi_name_impl(void *s)

src/jitlayers.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,14 @@ CodeGenOpt::Level CodeGenOptLevelFor(int optlevel)
480480
#endif
481481
}
482482

483+
#ifndef JL_USE_NEW_PM
483484
static void addPassesForOptLevel(legacy::PassManager &PM, TargetMachine &TM, int optlevel)
484485
{
485486
addTargetPasses(&PM, &TM);
486487
addOptimizationPasses(&PM, optlevel);
487488
addMachinePasses(&PM, &TM, optlevel);
488489
}
490+
#endif
489491

490492
static auto countBasicBlocks(const Function &F)
491493
{
@@ -882,6 +884,12 @@ namespace {
882884
}
883885
};
884886

887+
#ifdef JL_USE_NEW_PM
888+
typedef NewPassManager PassManager;
889+
#else
890+
typedef legacy::PassManager PassManager;
891+
#endif
892+
885893
struct PMCreator {
886894
std::unique_ptr<TargetMachine> TM;
887895
int optlevel;
@@ -897,10 +905,14 @@ namespace {
897905
swap(*this, other);
898906
return *this;
899907
}
900-
std::unique_ptr<legacy::PassManager> operator()() {
908+
std::unique_ptr<PassManager> operator()() {
909+
#ifdef JL_USE_NEW_PM
910+
return std::make_unique<NewPassManager>(*TM, optlevel);
911+
#else
901912
auto PM = std::make_unique<legacy::PassManager>();
902913
addPassesForOptLevel(*PM, *TM, optlevel);
903914
return PM;
915+
#endif
904916
}
905917
};
906918

@@ -933,8 +945,7 @@ namespace {
933945
JL_TIMING(LLVM_OPT);
934946

935947
//Run the optimization
936-
// (***PMs).run(M);
937-
optimizeModule(M, &jl_ExecutionEngine->getTargetMachine(), optlevel);
948+
(***PMs).run(M);
938949

939950
uint64_t end_time = 0;
940951
if (dump_llvm_opt_stream != NULL) {
@@ -958,7 +969,7 @@ namespace {
958969
}
959970
private:
960971
int optlevel;
961-
JuliaOJIT::ResourcePool<std::unique_ptr<legacy::PassManager>> PMs;
972+
JuliaOJIT::ResourcePool<std::unique_ptr<PassManager>> PMs;
962973
};
963974

964975
struct CompilerT : orc::IRCompileLayer::IRCompiler {

src/jitlayers.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
#include <llvm/IR/Value.h>
77
#include <llvm/IR/PassManager.h>
88
#include <llvm/IR/LegacyPassManager.h>
9+
#include <llvm/Passes/PassBuilder.h>
10+
#include <llvm/Passes/PassPlugin.h>
11+
#include <llvm/Passes/StandardInstrumentations.h>
912

1013
#include <llvm/ExecutionEngine/Orc/IRCompileLayer.h>
1114
#include <llvm/ExecutionEngine/Orc/IRTransformLayer.h>
@@ -44,16 +47,32 @@
4447
# include <llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h>
4548
#endif
4649

50+
#define JL_USE_NEW_PM
51+
4752
using namespace llvm;
4853

4954
extern "C" jl_cgparams_t jl_default_cgparams;
5055

56+
struct NewPassManager {
57+
StandardInstrumentations SI;
58+
std::unique_ptr<PassInstrumentationCallbacks> PIC;
59+
LoopAnalysisManager LAM;
60+
FunctionAnalysisManager FAM;
61+
CGSCCAnalysisManager CGAM;
62+
ModuleAnalysisManager MAM;
63+
PassBuilder PB;
64+
ModulePassManager MPM;
65+
66+
NewPassManager(TargetMachine &TM, int opt_level, bool lower_intrinsics = true, bool dump_native = false, bool external_use = false);
67+
68+
void run(Module &M);
69+
};
70+
5171
void addTargetPasses(legacy::PassManagerBase *PM, TargetMachine *TM);
5272
void addOptimizationPasses(legacy::PassManagerBase *PM, int opt_level, bool lower_intrinsics=true, bool dump_native=false, bool external_use=false);
5373
void addMachinePasses(legacy::PassManagerBase *PM, TargetMachine *TM, int optlevel);
5474
void jl_finalize_module(orc::ThreadSafeModule m);
5575
void jl_merge_module(orc::ThreadSafeModule &dest, orc::ThreadSafeModule src);
56-
void optimizeModule(Module &M, TargetMachine *TM, int opt_level, bool lower_intrinsics=true, bool dump_native=false);
5776
GlobalVariable *jl_emit_RTLD_DEFAULT_var(Module *M);
5877
DataLayout jl_create_datalayout(TargetMachine &TM);
5978

src/llvm-multiversioning.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1184,7 +1184,7 @@ PreservedAnalyses MultiVersioning::run(Module &M, ModuleAnalysisManager &AM)
11841184
auto GetCG = [&]() -> CallGraph & {
11851185
return AM.getResult<CallGraphAnalysis>(M);
11861186
};
1187-
if (runMultiVersioning(M, GetLI, GetCG, false)) {
1187+
if (runMultiVersioning(M, GetLI, GetCG, external_use)) {
11881188
auto preserved = PreservedAnalyses::allInSet<CFGAnalyses>();
11891189
preserved.preserve<LoopAnalysis>();
11901190
return preserved;

src/passes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ struct FinalLowerGCPass : PassInfoMixin<FinalLowerGCPass> {
6565
};
6666

6767
struct MultiVersioning : PassInfoMixin<MultiVersioning> {
68+
bool external_use;
69+
MultiVersioning(bool external_use = false) : external_use(external_use) {}
6870
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
6971
static bool isRequired() { return true; }
7072
};

0 commit comments

Comments
 (0)