Skip to content

Commit 5b61277

Browse files
committed
Refactoring: Merge compiler and jit-rt optimizer.cpp versions
1 parent 62e5cc5 commit 5b61277

File tree

5 files changed

+91
-412
lines changed

5 files changed

+91
-412
lines changed

driver/toobj.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ void writeModule(llvm::Module *m, const char *filename) {
364364
// run LLVM optimization passes
365365
{
366366
::TimeTraceScope timeScope("Optimize", filename);
367-
ldc_optimize_module(m);
367+
ldc_optimize_module(m, gTargetMachine);
368368
}
369369

370370
if (global.params.dllimport != DLLImport::none) {

gen/optimizer.cpp

Lines changed: 86 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,37 @@
55
// This file is distributed under the BSD-style LDC license. See the LICENSE
66
// file for details.
77
//
8+
// This module is compiled into both the compiler and the JIT runtime library
9+
// (with predefined IN_JITRT).
10+
//
811
//===----------------------------------------------------------------------===//
912

13+
#ifdef IN_JITRT
14+
#include "runtime/jit-rt/cpp-so/optimizer.h"
15+
#include "runtime/jit-rt/cpp-so/valueparser.h"
16+
#include "runtime/jit-rt/cpp-so/utils.h"
17+
#endif
18+
1019
#include "gen/optimizer.h"
1120

21+
#ifndef IN_JITRT
1222
#include "dmd/errors.h"
1323
#include "gen/logger.h"
24+
#endif
25+
1426
#include "gen/passes/GarbageCollect2Stack.h"
1527
#include "gen/passes/StripExternals.h"
1628
#include "gen/passes/SimplifyDRuntimeCalls.h"
1729
#include "gen/passes/Passes.h"
30+
31+
#ifndef IN_JITRT
1832
#include "driver/cl_options.h"
1933
#include "driver/cl_options_instrumentation.h"
2034
#include "driver/cl_options_sanitizers.h"
2135
#include "driver/plugins.h"
2236
#include "driver/targetmachine.h"
37+
#endif
38+
2339
#if LDC_LLVM_VER < 1700
2440
#include "llvm/ADT/Triple.h"
2541
#else
@@ -55,7 +71,6 @@
5571
#include "llvm/Transforms/Scalar/Reassociate.h"
5672
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
5773

58-
extern llvm::TargetMachine *gTargetMachine;
5974
using namespace llvm;
6075

6176
static cl::opt<signed char> optimizeLevel(
@@ -96,6 +111,7 @@ static cl::opt<bool> disableGCToStack(
96111
"disable-gc2stack", cl::ZeroOrMore,
97112
cl::desc("Disable promotion of GC allocations to stack memory"));
98113

114+
#ifndef IN_JITRT
99115
static cl::opt<cl::boolOrDefault, false, opts::FlagParser<cl::boolOrDefault>>
100116
enableInlining(
101117
"inlining", cl::ZeroOrMore,
@@ -105,6 +121,7 @@ static cl::opt<cl::boolOrDefault, false, opts::FlagParser<cl::boolOrDefault>>
105121
enableCrossModuleInlining(
106122
"cross-module-inlining", cl::ZeroOrMore, cl::Hidden,
107123
cl::desc("(*) Enable cross-module function inlining (default disabled)"));
124+
#endif
108125

109126
static cl::opt<bool> stripDebug(
110127
"strip-debug", cl::ZeroOrMore,
@@ -135,12 +152,20 @@ static unsigned sizeLevel() { return optimizeLevel < 0 ? -optimizeLevel : 0; }
135152

136153
// Determines whether or not to run the normal, full inlining pass.
137154
bool willInline() {
155+
#ifdef IN_JITRT
156+
return false;
157+
#else
138158
return enableInlining == cl::BOU_TRUE ||
139159
(enableInlining == cl::BOU_UNSET && optLevel() > 1);
160+
#endif
140161
}
141162

142163
bool willCrossModuleInline() {
164+
#ifdef IN_JITRT
165+
return false;
166+
#else
143167
return enableCrossModuleInlining == llvm::cl::BOU_TRUE && willInline();
168+
#endif
144169
}
145170

146171
bool isOptimizationEnabled() { return optimizeLevel != 0; }
@@ -180,6 +205,7 @@ static OptimizationLevel getOptimizationLevel(){
180205
return OptimizationLevel::O0;
181206
}
182207

208+
#ifndef IN_JITRT
183209
static void addAddressSanitizerPasses(ModulePassManager &mpm,
184210
OptimizationLevel level ) {
185211
AddressSanitizerOptions aso;
@@ -262,6 +288,7 @@ static void addPGOPasses(ModulePassManager &mpm,
262288
}
263289
}
264290
}
291+
#endif // !IN_JITRT
265292

266293
static void addStripExternalsPass(ModulePassManager &mpm,
267294
OptimizationLevel level ) {
@@ -296,7 +323,7 @@ static void addGarbageCollect2StackPass(ModulePassManager &mpm,
296323
}
297324
}
298325

299-
326+
#ifndef IN_JITRT
300327
static llvm::Optional<PGOOptions> getPGOOptions() {
301328
// FIXME: Do we have these anywhere?
302329
bool debugInfoForProfiling = false;
@@ -341,6 +368,7 @@ static llvm::Optional<PGOOptions> getPGOOptions() {
341368
return std::nullopt;
342369
#endif
343370
}
371+
#endif // !IN_JITRT
344372

345373
static PipelineTuningOptions getPipelineTuningOptions(unsigned optLevelVal, unsigned sizeLevelVal) {
346374
PipelineTuningOptions pto;
@@ -373,7 +401,7 @@ static PipelineTuningOptions getPipelineTuningOptions(unsigned optLevelVal, unsi
373401
* PassManagerBuilder.
374402
*/
375403
//Run optimization passes using the new pass manager
376-
void runOptimizationPasses(llvm::Module *M) {
404+
void runOptimizationPasses(llvm::Module *M, llvm::TargetMachine *TM) {
377405
// Create a ModulePassManager to hold and optimize the collection of
378406
// per-module passes we are about to build.
379407

@@ -415,8 +443,12 @@ void runOptimizationPasses(llvm::Module *M) {
415443
si.registerCallbacks(pic, &mam);
416444
#endif
417445

418-
PassBuilder pb(gTargetMachine, getPipelineTuningOptions(optLevelVal, sizeLevelVal),
446+
PassBuilder pb(TM, getPipelineTuningOptions(optLevelVal, sizeLevelVal),
447+
#ifdef IN_JITRT
448+
{}, &pic);
449+
#else
419450
getPGOOptions(), &pic);
451+
#endif
420452

421453
// register the target library analysis directly because clang does :)
422454
auto tlii = createTLII(*M);
@@ -433,6 +465,7 @@ void runOptimizationPasses(llvm::Module *M) {
433465

434466
// TODO: port over strip-debuginfos pass for -strip-debug
435467

468+
#ifndef IN_JITRT
436469
pb.registerPipelineStartEPCallback(addPGOPasses);
437470

438471
if (opts::isSanitizerEnabled(opts::AddressSanitizer)) {
@@ -455,6 +488,7 @@ void runOptimizationPasses(llvm::Module *M) {
455488
if (opts::isSanitizerEnabled(opts::CoverageSanitizer)) {
456489
pb.registerOptimizerLastEPCallback(addSanitizerCoveragePass);
457490
}
491+
#endif // !IN_JITRT
458492

459493
if (!disableLangSpecificPasses) {
460494
if (!disableSimplifyDruntimeCalls) {
@@ -474,7 +508,9 @@ void runOptimizationPasses(llvm::Module *M) {
474508

475509
pb.registerOptimizerLastEPCallback(addStripExternalsPass);
476510

511+
#ifndef IN_JITRT
477512
registerAllPluginsWithPassBuilder(pb);
513+
#endif
478514

479515
pb.registerModuleAnalyses(mam);
480516
pb.registerCGSCCAnalyses(cgam);
@@ -486,6 +522,9 @@ void runOptimizationPasses(llvm::Module *M) {
486522
OptimizationLevel level = getOptimizationLevel();
487523

488524
if (optLevelVal == 0) {
525+
#ifdef IN_JITRT
526+
mpm = pb.buildO0DefaultPipeline(level, false);
527+
#else
489528
mpm = pb.buildO0DefaultPipeline(level, opts::isUsingLTO());
490529
#if LDC_LLVM_VER >= 1700
491530
} else if (opts::ltoFatObjects && opts::isUsingLTO()) {
@@ -498,6 +537,7 @@ void runOptimizationPasses(llvm::Module *M) {
498537
mpm = pb.buildThinLTOPreLinkDefaultPipeline(level);
499538
} else if (opts::isUsingLTO()) {
500539
mpm = pb.buildLTOPreLinkDefaultPipeline(level);
540+
#endif // !IN_JITRT
501541
} else {
502542
mpm = pb.buildPerModuleDefaultPipeline(level);
503543
}
@@ -508,7 +548,8 @@ void runOptimizationPasses(llvm::Module *M) {
508548
////////////////////////////////////////////////////////////////////////////////
509549
// This function runs optimization passes based on command line arguments.
510550
// Returns true if any optimization passes were invoked.
511-
bool ldc_optimize_module(llvm::Module *M) {
551+
bool ldc_optimize_module(llvm::Module *M, llvm::TargetMachine *TM) {
552+
#ifndef IN_JITRT
512553
// Dont optimise spirv modules because turning GEPs into extracts triggers
513554
// asserts in the IR -> SPIR-V translation pass. SPIRV doesn't have a target
514555
// machine, so any optimisation passes that rely on it to provide analysis,
@@ -518,8 +559,9 @@ bool ldc_optimize_module(llvm::Module *M) {
518559
// TODO: run rudimentary optimisations to improve IR debuggability.
519560
if (getComputeTargetType(M) == ComputeBackend::SPIRV)
520561
return false;
562+
#endif
521563

522-
runOptimizationPasses(M);
564+
runOptimizationPasses(M, TM);
523565

524566
// Verify the resulting module.
525567
if (!noVerify) {
@@ -530,18 +572,38 @@ bool ldc_optimize_module(llvm::Module *M) {
530572
return true;
531573
}
532574

575+
#ifdef IN_JITRT
576+
void optimizeModule(const OptimizerSettings &settings, llvm::Module *M,
577+
llvm::TargetMachine *TM) {
578+
if (settings.sizeLevel > 0) {
579+
optimizeLevel = -settings.sizeLevel;
580+
} else {
581+
optimizeLevel = settings.optLevel;
582+
}
583+
584+
ldc_optimize_module(M, TM);
585+
}
586+
#endif // IN_JITRT
533587

534588
// Verifies the module.
535589
void verifyModule(llvm::Module *m) {
590+
#ifndef IN_JITRT
536591
Logger::println("Verifying module...");
537592
LOG_SCOPE;
593+
#endif
538594
std::string ErrorStr;
539595
raw_string_ostream OS(ErrorStr);
540596
if (llvm::verifyModule(*m, &OS)) {
597+
#ifndef IN_JITRT
541598
error(Loc(), "%s", ErrorStr.c_str());
542599
fatal();
600+
#else
601+
assert(false && "Verification failed!");
602+
#endif
543603
}
604+
#ifndef IN_JITRT
544605
Logger::println("Verification passed!");
606+
#endif
545607
}
546608

547609
// Output to `hash_os` all optimization settings that influence object code
@@ -559,3 +621,21 @@ void outputOptimizationSettings(llvm::raw_ostream &hash_os) {
559621
hash_os << disableLoopVectorization;
560622
hash_os << disableSLPVectorization;
561623
}
624+
625+
#ifdef IN_JITRT
626+
void setRtCompileVar(const Context &context, llvm::Module &module,
627+
const char *name, const void *init) {
628+
assert(nullptr != name);
629+
assert(nullptr != init);
630+
auto var = module.getGlobalVariable(name);
631+
if (nullptr != var) {
632+
auto type = var->getValueType();
633+
auto initializer =
634+
parseInitializer(module.getDataLayout(), *type, init,
635+
[&](const std::string &str) { fatal(context, str); });
636+
var->setConstant(true);
637+
var->setInitializer(initializer);
638+
var->setLinkage(llvm::GlobalValue::PrivateLinkage);
639+
}
640+
}
641+
#endif // IN_JITRT

gen/optimizer.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,10 @@ class raw_ostream;
3232
namespace llvm {
3333
class Module;
3434
class TargetLibraryInfoImpl;
35+
class TargetMachine;
3536
}
3637

37-
bool ldc_optimize_module(llvm::Module *m);
38+
bool ldc_optimize_module(llvm::Module *m, llvm::TargetMachine *tm);
3839

3940
// Returns whether the normal, full inlining pass will be run.
4041
bool willInline();

runtime/jit-rt/DefineBuildJitRT.cmake

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
if(LDC_DYNAMIC_COMPILE)
22
file(GLOB LDC_JITRT_D ${JITRT_DIR}/d/ldc/*.d)
33

4-
# Choose the correct subfolder depending on the LLVM version
54
file(GLOB LDC_JITRT_CXX ${JITRT_DIR}/cpp/*.cpp)
65
file(GLOB LDC_JITRT_H ${JITRT_DIR}/cpp/*.h)
7-
file(GLOB LDC_JITRT_SO_CXX ${JITRT_DIR}/cpp-so/*.cpp)
6+
file(GLOB LDC_JITRT_SO_CXX ${JITRT_DIR}/cpp-so/*.cpp ${CMAKE_SOURCE_DIR}/gen/optimizer.cpp)
87
file(GLOB LDC_JITRT_SO_H ${JITRT_DIR}/cpp-so/*.h)
98
message(STATUS "Use custom passes in jit: ${LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES}")
109
if(LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES)
@@ -62,6 +61,7 @@ if(LDC_DYNAMIC_COMPILE)
6261
)
6362
set_target_properties(ldc-jit-rt-so${target_suffix} PROPERTIES LINKER_LANGUAGE CXX)
6463

64+
target_compile_definitions(ldc-jit-rt-so${target_suffix} PRIVATE IN_JITRT)
6565
if(LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES)
6666
target_compile_definitions(ldc-jit-rt-so${target_suffix} PRIVATE LDC_DYNAMIC_COMPILE_USE_CUSTOM_PASSES)
6767
endif()

0 commit comments

Comments
 (0)