Skip to content

Commit c6b0803

Browse files
committedFeb 12, 2020
Add support for new pass manager
The new pass manager can be enabled using -Z new-llvm-pass-manager=on.
1 parent 737f08b commit c6b0803

File tree

7 files changed

+422
-23
lines changed

7 files changed

+422
-23
lines changed
 

‎src/librustc_codegen_llvm/back/lto.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,20 @@ pub(crate) fn run_pass_manager(
584584
// tools/lto/LTOCodeGenerator.cpp
585585
debug!("running the pass manager");
586586
unsafe {
587+
if write::should_use_new_llvm_pass_manager(config) {
588+
let opt_stage = if thin { llvm::OptStage::ThinLTO } else { llvm::OptStage::FatLTO };
589+
let opt_level = config.opt_level.unwrap_or(config::OptLevel::No);
590+
// See comment below for why this is necessary.
591+
let opt_level = if let config::OptLevel::No = opt_level {
592+
config::OptLevel::Less
593+
} else {
594+
opt_level
595+
};
596+
write::optimize_with_new_llvm_pass_manager(module, config, opt_level, opt_stage);
597+
debug!("lto done");
598+
return;
599+
}
600+
587601
let pm = llvm::LLVMCreatePassManager();
588602
llvm::LLVMAddAnalysisPasses(module.module_llvm.tm, pm);
589603

‎src/librustc_codegen_llvm/back/write.rs

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ pub fn to_llvm_opt_settings(
111111
}
112112
}
113113

114+
fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel {
115+
use config::OptLevel::*;
116+
match cfg {
117+
No => llvm::PassBuilderOptLevel::O0,
118+
Less => llvm::PassBuilderOptLevel::O1,
119+
Default => llvm::PassBuilderOptLevel::O2,
120+
Aggressive => llvm::PassBuilderOptLevel::O3,
121+
Size => llvm::PassBuilderOptLevel::Os,
122+
SizeMin => llvm::PassBuilderOptLevel::Oz,
123+
}
124+
}
125+
114126
// If find_features is true this won't access `sess.crate_types` by assuming
115127
// that `is_pie_binary` is false. When we discover LLVM target features
116128
// `sess.crate_types` is uninitialized so we cannot access it.
@@ -303,6 +315,88 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
303315
}
304316
}
305317

318+
fn get_pgo_gen_path(config: &ModuleConfig) -> Option<CString> {
319+
match config.pgo_gen {
320+
SwitchWithOptPath::Enabled(ref opt_dir_path) => {
321+
let path = if let Some(dir_path) = opt_dir_path {
322+
dir_path.join("default_%m.profraw")
323+
} else {
324+
PathBuf::from("default_%m.profraw")
325+
};
326+
327+
Some(CString::new(format!("{}", path.display())).unwrap())
328+
}
329+
SwitchWithOptPath::Disabled => None,
330+
}
331+
}
332+
333+
fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
334+
config
335+
.pgo_use
336+
.as_ref()
337+
.map(|path_buf| CString::new(path_buf.to_string_lossy().as_bytes()).unwrap())
338+
}
339+
340+
pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
341+
// We only support the new pass manager starting with LLVM 9.
342+
if llvm_util::get_major_version() < 9 {
343+
return false;
344+
}
345+
346+
// The new pass manager is disabled by default.
347+
config.new_llvm_pass_manager.unwrap_or(false)
348+
}
349+
350+
pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
351+
module: &ModuleCodegen<ModuleLlvm>,
352+
config: &ModuleConfig,
353+
opt_level: config::OptLevel,
354+
opt_stage: llvm::OptStage,
355+
) {
356+
let unroll_loops =
357+
opt_level != config::OptLevel::Size && opt_level != config::OptLevel::SizeMin;
358+
let using_thin_buffers = opt_stage == llvm::OptStage::PreLinkThinLTO || config.bitcode_needed();
359+
let pgo_gen_path = get_pgo_gen_path(config);
360+
let pgo_use_path = get_pgo_use_path(config);
361+
let is_lto = opt_stage == llvm::OptStage::ThinLTO || opt_stage == llvm::OptStage::FatLTO;
362+
// Sanitizer instrumentation is only inserted during the pre-link optimization stage.
363+
let sanitizer_options = if !is_lto {
364+
config.sanitizer.as_ref().map(|s| llvm::SanitizerOptions {
365+
sanitize_memory: *s == Sanitizer::Memory,
366+
sanitize_thread: *s == Sanitizer::Thread,
367+
sanitize_address: *s == Sanitizer::Address,
368+
sanitize_recover: config.sanitizer_recover.contains(s),
369+
sanitize_memory_track_origins: config.sanitizer_memory_track_origins as c_int,
370+
})
371+
} else {
372+
None
373+
};
374+
375+
// FIXME: NewPM doesn't provide a facility to pass custom InlineParams.
376+
// We would have to add upstream support for this first, before we can support
377+
// config.inline_threshold and our more aggressive default thresholds.
378+
// FIXME: NewPM uses an different and more explicit way to textually represent
379+
// pass pipelines. It would probably make sense to expose this, but it would
380+
// require a different format than the current -C passes.
381+
llvm::LLVMRustOptimizeWithNewPassManager(
382+
module.module_llvm.llmod(),
383+
&*module.module_llvm.tm,
384+
to_pass_builder_opt_level(opt_level),
385+
opt_stage,
386+
config.no_prepopulate_passes,
387+
config.verify_llvm_ir,
388+
using_thin_buffers,
389+
config.merge_functions,
390+
unroll_loops,
391+
config.vectorize_slp,
392+
config.vectorize_loop,
393+
config.no_builtins,
394+
sanitizer_options.as_ref(),
395+
pgo_gen_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
396+
pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
397+
);
398+
}
399+
306400
// Unsafe due to LLVM calls.
307401
pub(crate) unsafe fn optimize(
308402
cgcx: &CodegenContext<LlvmCodegenBackend>,
@@ -327,6 +421,17 @@ pub(crate) unsafe fn optimize(
327421
}
328422

329423
if let Some(opt_level) = config.opt_level {
424+
if should_use_new_llvm_pass_manager(config) {
425+
let opt_stage = match cgcx.lto {
426+
Lto::Fat => llvm::OptStage::PreLinkFatLTO,
427+
Lto::Thin | Lto::ThinLocal => llvm::OptStage::PreLinkThinLTO,
428+
_ if cgcx.opts.cg.linker_plugin_lto.enabled() => llvm::OptStage::PreLinkThinLTO,
429+
_ => llvm::OptStage::PreLinkNoLTO,
430+
};
431+
optimize_with_new_llvm_pass_manager(module, config, opt_level, opt_stage);
432+
return Ok(());
433+
}
434+
330435
// Create the two optimizing pass managers. These mirror what clang
331436
// does, and are by populated by LLVM's default PassManagerBuilder.
332437
// Each manager has a different set of passes, but they also share
@@ -757,24 +862,8 @@ pub unsafe fn with_llvm_pmb(
757862
let opt_size =
758863
config.opt_size.map(|x| to_llvm_opt_settings(x).1).unwrap_or(llvm::CodeGenOptSizeNone);
759864
let inline_threshold = config.inline_threshold;
760-
761-
let pgo_gen_path = match config.pgo_gen {
762-
SwitchWithOptPath::Enabled(ref opt_dir_path) => {
763-
let path = if let Some(dir_path) = opt_dir_path {
764-
dir_path.join("default_%m.profraw")
765-
} else {
766-
PathBuf::from("default_%m.profraw")
767-
};
768-
769-
Some(CString::new(format!("{}", path.display())).unwrap())
770-
}
771-
SwitchWithOptPath::Disabled => None,
772-
};
773-
774-
let pgo_use_path = config
775-
.pgo_use
776-
.as_ref()
777-
.map(|path_buf| CString::new(path_buf.to_string_lossy().as_bytes()).unwrap());
865+
let pgo_gen_path = get_pgo_gen_path(config);
866+
let pgo_use_path = get_pgo_use_path(config);
778867

779868
llvm::LLVMRustConfigurePassManagerBuilder(
780869
builder,

‎src/librustc_codegen_llvm/llvm/ffi.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,38 @@ pub enum CodeGenOptLevel {
402402
Aggressive,
403403
}
404404

405+
/// LLVMRustPassBuilderOptLevel
406+
#[repr(C)]
407+
pub enum PassBuilderOptLevel {
408+
O0,
409+
O1,
410+
O2,
411+
O3,
412+
Os,
413+
Oz,
414+
}
415+
416+
/// LLVMRustOptStage
417+
#[derive(PartialEq)]
418+
#[repr(C)]
419+
pub enum OptStage {
420+
PreLinkNoLTO,
421+
PreLinkThinLTO,
422+
PreLinkFatLTO,
423+
ThinLTO,
424+
FatLTO,
425+
}
426+
427+
/// LLVMRustSanitizerOptions
428+
#[repr(C)]
429+
pub struct SanitizerOptions {
430+
pub sanitize_memory: bool,
431+
pub sanitize_thread: bool,
432+
pub sanitize_address: bool,
433+
pub sanitize_recover: bool,
434+
pub sanitize_memory_track_origins: c_int,
435+
}
436+
405437
/// LLVMRelocMode
406438
#[derive(Copy, Clone, PartialEq)]
407439
#[repr(C)]
@@ -1896,6 +1928,23 @@ extern "C" {
18961928
Output: *const c_char,
18971929
FileType: FileType,
18981930
) -> LLVMRustResult;
1931+
pub fn LLVMRustOptimizeWithNewPassManager(
1932+
M: &'a Module,
1933+
TM: &'a TargetMachine,
1934+
OptLevel: PassBuilderOptLevel,
1935+
OptStage: OptStage,
1936+
NoPrepopulatePasses: bool,
1937+
VerifyIR: bool,
1938+
UseThinLTOBuffers: bool,
1939+
MergeFunctions: bool,
1940+
UnrollLoops: bool,
1941+
SLPVectorize: bool,
1942+
LoopVectorize: bool,
1943+
DisableSimplifyLibCalls: bool,
1944+
SanitizerOptions: Option<&SanitizerOptions>,
1945+
PGOGenPath: *const c_char,
1946+
PGOUsePath: *const c_char,
1947+
);
18991948
pub fn LLVMRustPrintModule(
19001949
M: &'a Module,
19011950
Output: *const c_char,

‎src/librustc_codegen_ssa/back/write.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ pub struct ModuleConfig {
8888
pub vectorize_slp: bool,
8989
pub merge_functions: bool,
9090
pub inline_threshold: Option<usize>,
91+
pub new_llvm_pass_manager: Option<bool>,
9192
// Instead of creating an object file by doing LLVM codegen, just
9293
// make the object file bitcode. Provides easy compatibility with
9394
// emscripten's ecc compiler, when used as the linker.
@@ -132,6 +133,7 @@ impl ModuleConfig {
132133
vectorize_slp: false,
133134
merge_functions: false,
134135
inline_threshold: None,
136+
new_llvm_pass_manager: None,
135137
}
136138
}
137139

@@ -140,6 +142,7 @@ impl ModuleConfig {
140142
self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
141143
self.no_builtins = no_builtins || sess.target.target.options.no_builtins;
142144
self.inline_threshold = sess.opts.cg.inline_threshold;
145+
self.new_llvm_pass_manager = sess.opts.debugging_opts.new_llvm_pass_manager;
143146
self.obj_is_bitcode =
144147
sess.target.target.options.obj_is_bitcode || sess.opts.cg.linker_plugin_lto.enabled();
145148
let embed_bitcode =

‎src/librustc_session/options.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -968,4 +968,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
968968
"compile without linking"),
969969
link_only: bool = (false, parse_bool, [TRACKED],
970970
"link the `.rlink` file generated by `-Z no-link`"),
971+
new_llvm_pass_manager: Option<bool> = (None, parse_opt_bool, [TRACKED],
972+
"use new LLVM pass manager"),
971973
}

‎src/rustllvm/PassWrapper.cpp

Lines changed: 243 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@
1212
#include "llvm/IR/AutoUpgrade.h"
1313
#include "llvm/IR/AssemblyAnnotationWriter.h"
1414
#include "llvm/IR/IntrinsicInst.h"
15+
#include "llvm/IR/Verifier.h"
16+
#include "llvm/Passes/PassBuilder.h"
17+
#if LLVM_VERSION_GE(9, 0)
18+
#include "llvm/Passes/StandardInstrumentations.h"
19+
#endif
1520
#include "llvm/Support/CBindingWrapping.h"
1621
#include "llvm/Support/FileSystem.h"
1722
#include "llvm/Support/Host.h"
@@ -32,9 +37,12 @@
3237
#include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
3338
#include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
3439
#endif
40+
#if LLVM_VERSION_GE(9, 0)
41+
#include "llvm/Transforms/Utils/CanonicalizeAliases.h"
42+
#endif
43+
#include "llvm/Transforms/Utils/NameAnonGlobals.h"
3544

3645
using namespace llvm;
37-
using namespace llvm::legacy;
3846

3947
typedef struct LLVMOpaquePass *LLVMPassRef;
4048
typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
@@ -314,6 +322,34 @@ static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
314322
}
315323
}
316324

325+
enum class LLVMRustPassBuilderOptLevel {
326+
O0,
327+
O1,
328+
O2,
329+
O3,
330+
Os,
331+
Oz,
332+
};
333+
334+
static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
335+
switch (Level) {
336+
case LLVMRustPassBuilderOptLevel::O0:
337+
return PassBuilder::O0;
338+
case LLVMRustPassBuilderOptLevel::O1:
339+
return PassBuilder::O1;
340+
case LLVMRustPassBuilderOptLevel::O2:
341+
return PassBuilder::O2;
342+
case LLVMRustPassBuilderOptLevel::O3:
343+
return PassBuilder::O3;
344+
case LLVMRustPassBuilderOptLevel::Os:
345+
return PassBuilder::Os;
346+
case LLVMRustPassBuilderOptLevel::Oz:
347+
return PassBuilder::Oz;
348+
default:
349+
report_fatal_error("Bad PassBuilderOptLevel.");
350+
}
351+
}
352+
317353
enum class LLVMRustRelocMode {
318354
Default,
319355
Static,
@@ -604,6 +640,212 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
604640
return LLVMRustResult::Success;
605641
}
606642

643+
enum class LLVMRustOptStage {
644+
PreLinkNoLTO,
645+
PreLinkThinLTO,
646+
PreLinkFatLTO,
647+
ThinLTO,
648+
FatLTO,
649+
};
650+
651+
struct LLVMRustSanitizerOptions {
652+
bool SanitizeMemory;
653+
bool SanitizeThread;
654+
bool SanitizeAddress;
655+
bool SanitizeRecover;
656+
int SanitizeMemoryTrackOrigins;
657+
};
658+
659+
extern "C" void
660+
LLVMRustOptimizeWithNewPassManager(
661+
LLVMModuleRef ModuleRef,
662+
LLVMTargetMachineRef TMRef,
663+
LLVMRustPassBuilderOptLevel OptLevelRust,
664+
LLVMRustOptStage OptStage,
665+
bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
666+
bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
667+
bool DisableSimplifyLibCalls,
668+
LLVMRustSanitizerOptions *SanitizerOptions,
669+
const char *PGOGenPath, const char *PGOUsePath) {
670+
#if LLVM_VERSION_GE(9, 0)
671+
Module *TheModule = unwrap(ModuleRef);
672+
TargetMachine *TM = unwrap(TMRef);
673+
PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
674+
675+
// FIXME: MergeFunctions is not supported by NewPM yet.
676+
(void) MergeFunctions;
677+
678+
PipelineTuningOptions PTO;
679+
PTO.LoopUnrolling = UnrollLoops;
680+
PTO.LoopInterleaving = UnrollLoops;
681+
PTO.LoopVectorization = LoopVectorize;
682+
PTO.SLPVectorization = SLPVectorize;
683+
684+
PassInstrumentationCallbacks PIC;
685+
StandardInstrumentations SI;
686+
SI.registerCallbacks(PIC);
687+
688+
Optional<PGOOptions> PGOOpt;
689+
if (PGOGenPath) {
690+
assert(!PGOUsePath);
691+
PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr);
692+
} else if (PGOUsePath) {
693+
assert(!PGOGenPath);
694+
PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse);
695+
}
696+
697+
PassBuilder PB(TM, PTO, PGOOpt, &PIC);
698+
699+
// FIXME: We may want to expose this as an option.
700+
bool DebugPassManager = false;
701+
LoopAnalysisManager LAM(DebugPassManager);
702+
FunctionAnalysisManager FAM(DebugPassManager);
703+
CGSCCAnalysisManager CGAM(DebugPassManager);
704+
ModuleAnalysisManager MAM(DebugPassManager);
705+
706+
FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
707+
708+
Triple TargetTriple(TheModule->getTargetTriple());
709+
std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
710+
if (DisableSimplifyLibCalls)
711+
TLII->disableAllFunctions();
712+
FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
713+
714+
PB.registerModuleAnalyses(MAM);
715+
PB.registerCGSCCAnalyses(CGAM);
716+
PB.registerFunctionAnalyses(FAM);
717+
PB.registerLoopAnalyses(LAM);
718+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
719+
720+
// We manually collect pipeline callbacks so we can apply them at O0, where the
721+
// PassBuilder does not create a pipeline.
722+
std::vector<std::function<void(ModulePassManager &)>> PipelineStartEPCallbacks;
723+
std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
724+
OptimizerLastEPCallbacks;
725+
726+
if (VerifyIR) {
727+
PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
728+
MPM.addPass(VerifierPass());
729+
});
730+
}
731+
732+
if (SanitizerOptions) {
733+
if (SanitizerOptions->SanitizeMemory) {
734+
MemorySanitizerOptions Options(
735+
SanitizerOptions->SanitizeMemoryTrackOrigins,
736+
SanitizerOptions->SanitizeRecover,
737+
/*CompileKernel=*/false);
738+
#if LLVM_VERSION_GE(10, 0)
739+
PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
740+
MPM.addPass(MemorySanitizerPass(Options));
741+
});
742+
#endif
743+
OptimizerLastEPCallbacks.push_back(
744+
[Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
745+
FPM.addPass(MemorySanitizerPass(Options));
746+
}
747+
);
748+
}
749+
750+
if (SanitizerOptions->SanitizeThread) {
751+
#if LLVM_VERSION_GE(10, 0)
752+
PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
753+
MPM.addPass(ThreadSanitizerPass());
754+
});
755+
#endif
756+
OptimizerLastEPCallbacks.push_back(
757+
[](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
758+
FPM.addPass(ThreadSanitizerPass());
759+
}
760+
);
761+
}
762+
763+
if (SanitizerOptions->SanitizeAddress) {
764+
// FIXME: Rust does not expose the UseAfterScope option.
765+
PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
766+
MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
767+
});
768+
OptimizerLastEPCallbacks.push_back(
769+
[SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
770+
FPM.addPass(AddressSanitizerPass(
771+
/*CompileKernel=*/false, SanitizerOptions->SanitizeRecover));
772+
}
773+
);
774+
PipelineStartEPCallbacks.push_back(
775+
[SanitizerOptions](ModulePassManager &MPM) {
776+
MPM.addPass(ModuleAddressSanitizerPass(
777+
/*CompileKernel=*/false, SanitizerOptions->SanitizeRecover));
778+
}
779+
);
780+
}
781+
}
782+
783+
ModulePassManager MPM(DebugPassManager);
784+
if (!NoPrepopulatePasses) {
785+
if (OptLevel == PassBuilder::O0) {
786+
for (const auto &C : PipelineStartEPCallbacks)
787+
C(MPM);
788+
789+
if (!OptimizerLastEPCallbacks.empty()) {
790+
FunctionPassManager FPM(DebugPassManager);
791+
for (const auto &C : OptimizerLastEPCallbacks)
792+
C(FPM, OptLevel);
793+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
794+
}
795+
796+
MPM.addPass(AlwaysInlinerPass(/*InsertLifetimeIntrinsics=*/false));
797+
798+
#if LLVM_VERSION_GE(10, 0)
799+
if (PGOOpt) {
800+
PB.addPGOInstrPassesForO0(
801+
MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
802+
/*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
803+
}
804+
#endif
805+
} else {
806+
for (const auto &C : PipelineStartEPCallbacks)
807+
PB.registerPipelineStartEPCallback(C);
808+
for (const auto &C : OptimizerLastEPCallbacks)
809+
PB.registerOptimizerLastEPCallback(C);
810+
811+
switch (OptStage) {
812+
case LLVMRustOptStage::PreLinkNoLTO:
813+
MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
814+
break;
815+
case LLVMRustOptStage::PreLinkThinLTO:
816+
MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
817+
break;
818+
case LLVMRustOptStage::PreLinkFatLTO:
819+
MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
820+
break;
821+
case LLVMRustOptStage::ThinLTO:
822+
// FIXME: Does it make sense to pass the ModuleSummaryIndex?
823+
// It only seems to be needed for C++ specific optimizations.
824+
MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
825+
break;
826+
case LLVMRustOptStage::FatLTO:
827+
MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
828+
break;
829+
}
830+
}
831+
}
832+
833+
if (UseThinLTOBuffers) {
834+
MPM.addPass(CanonicalizeAliasesPass());
835+
MPM.addPass(NameAnonGlobalPass());
836+
}
837+
838+
// Upgrade all calls to old intrinsics first.
839+
for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
840+
UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
841+
842+
MPM.run(*TheModule, MAM);
843+
#else
844+
// The new pass manager has been available for a long time,
845+
// but we don't bother supporting it on old LLVM versions.
846+
report_fatal_error("New pass manager only supported since LLVM 9");
847+
#endif
848+
}
607849

608850
// Callback to demangle function name
609851
// Parameters:

‎src/test/codegen/sanitizer-memory-track-orgins.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
#![crate_type="lib"]
1616

1717
// MSAN-0-NOT: @__msan_track_origins
18-
// MSAN-1: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1
19-
// MSAN-2: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2
20-
// MSAN-1-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 1
21-
// MSAN-2-LTO: @__msan_track_origins = weak_odr local_unnamed_addr constant i32 2
18+
// MSAN-1: @__msan_track_origins = weak_odr {{.*}}constant i32 1
19+
// MSAN-2: @__msan_track_origins = weak_odr {{.*}}constant i32 2
20+
// MSAN-1-LTO: @__msan_track_origins = weak_odr {{.*}}constant i32 1
21+
// MSAN-2-LTO: @__msan_track_origins = weak_odr {{.*}}constant i32 2
2222
//
2323
// MSAN-0-LABEL: define void @copy(
2424
// MSAN-1-LABEL: define void @copy(

0 commit comments

Comments
 (0)
Please sign in to comment.