Skip to content

Commit

Permalink
Auto merge of #88243 - nikic:newpm-2, r=nagisa
Browse files Browse the repository at this point in the history
Enable new pass manager with LLVM 13

The new pass manager is enabled by default in clang since Clang/LLVM 13. Per the recent discussion on llvm-dev (https://lists.llvm.org/pipermail/llvm-dev/2021-August/152305.html) the legacy pass manager will be unmaintained in LLVM 14 and removed entirely in LLVM 15.

This switches us to use the new pass manager if LLVM >= 13 is used. It's possible to still use the old pass manager using `-Z new-llvm-pass-manager=no`.
  • Loading branch information
bors committed Sep 25, 2021
2 parents e9f29a8 + 51203dc commit 63cc2bb
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,9 @@ fn get_pgo_use_path(config: &ModuleConfig) -> Option<CString> {
}

pub(crate) fn should_use_new_llvm_pass_manager(config: &ModuleConfig) -> bool {
// The new pass manager is disabled by default.
config.new_llvm_pass_manager.unwrap_or(false)
// The new pass manager is enabled by default for LLVM >= 13.
// This matches Clang, which also enables it since Clang 13.
config.new_llvm_pass_manager.unwrap_or_else(|| llvm_util::get_version() >= (13, 0, 0))
}

pub(crate) unsafe fn optimize_with_new_llvm_pass_manager(
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1004,7 +1004,10 @@ LLVMRustOptimizeWithNewPassManager(
#endif
bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
if (!NoPrepopulatePasses) {
if (OptLevel == OptimizationLevel::O0) {
// The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
// At the same time, the LTO pipelines do support O0 and using them is required.
bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
#if LLVM_VERSION_GE(12, 0)
for (const auto &C : PipelineStartEPCallbacks)
PB.registerPipelineStartEPCallback(C);
Expand Down
15 changes: 10 additions & 5 deletions src/test/codegen/panic-in-drop-abort.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
// compile-flags: -Z panic-in-drop=abort -O
// compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no

// Ensure that unwinding code paths are eliminated from the output after
// optimization.

// This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen
// on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that
// the drop_in_place() function can't unwind, but implements it in a way that *can*, because we
// currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC
// targets. We should either forbid longjmps, or not assume nounwind, making this optimization
// incompatible with the current behavior of running cleanuppads on longjmp unwinding.

// CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output

#![crate_type = "lib"]
use std::any::Any;
use std::mem::forget;
Expand Down Expand Up @@ -35,17 +44,13 @@ impl Drop for AssertNeverDrop {
}
}

// CHECK-LABEL: normal_drop
// CHECK-NOT: should_not_appear_in_output
#[no_mangle]
pub fn normal_drop(x: ExternDrop) {
let guard = AssertNeverDrop;
drop(x);
forget(guard);
}

// CHECK-LABEL: indirect_drop
// CHECK-NOT: should_not_appear_in_output
#[no_mangle]
pub fn indirect_drop(x: Box<dyn Any>) {
let guard = AssertNeverDrop;
Expand Down

0 comments on commit 63cc2bb

Please sign in to comment.