Skip to content

Commit 5c53093

Browse files
committed
Auto merge of rust-lang#150133 - ZuseZ4:enzyme-frontend-nightly, r=jieyouxu
remove llvm_enzyme and enzyme fallbacks from most places Using dlopen to get symbols has the nice benefit that rustc itself doesn't depend on libenzyme symbols anymore. We can therefore delete most fallback implementations in the backend (independently of whether we enable enzyme or not). When trying to use autodiff on nightly, we will now fail with a nice error if and only if we fail to load libEnzyme-21.so in our backend. Verified: Build as nightly, without Enzyme Build as nightly, with Enzyme Build as stable (without Enzyme) With this PR we will now run `tests/ui/autodiff` on nightly, the tests are passing. r? `@kobzol`
2 parents a0c97e3 + c34ea6e commit 5c53093

21 files changed

+48
-225
lines changed

compiler/rustc_builtin_macros/messages.ftl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ builtin_macros_assert_requires_expression = macro requires an expression as an a
5555
builtin_macros_autodiff = autodiff must be applied to function
5656
builtin_macros_autodiff_missing_config = autodiff requires at least a name and mode
5757
builtin_macros_autodiff_mode_activity = {$act} can not be used in {$mode} Mode
58-
builtin_macros_autodiff_not_build = this rustc version does not support autodiff
5958
builtin_macros_autodiff_number_activities = expected {$expected} activities, but found {$found}
6059
builtin_macros_autodiff_ret_activity = invalid return activity {$act} in {$mode} Mode
6160
builtin_macros_autodiff_ty_activity = {$act} can not be used for this type

compiler/rustc_builtin_macros/src/autodiff.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,6 @@ mod llvm_enzyme {
209209
mut item: Annotatable,
210210
mode: DiffMode,
211211
) -> Vec<Annotatable> {
212-
// FIXME(bjorn3) maybe have the backend directly tell if autodiff is supported?
213-
if cfg!(not(feature = "llvm_enzyme")) {
214-
ecx.sess.dcx().emit_err(errors::AutoDiffSupportNotBuild { span: meta_item.span });
215-
return vec![item];
216-
}
217212
let dcx = ecx.sess.dcx();
218213

219214
// first get information about the annotable item: visibility, signature, name and generic

compiler/rustc_builtin_macros/src/errors.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,6 @@ mod autodiff {
216216
}
217217
}
218218

219-
pub(crate) use ad_fallback::*;
220-
mod ad_fallback {
221-
use super::*;
222-
#[derive(Diagnostic)]
223-
#[diag(builtin_macros_autodiff_not_build)]
224-
pub(crate) struct AutoDiffSupportNotBuild {
225-
#[primary_span]
226-
pub(crate) span: Span,
227-
}
228-
}
229-
230219
#[derive(Diagnostic)]
231220
#[diag(builtin_macros_concat_bytes_invalid)]
232221
pub(crate) struct ConcatBytesInvalid {

compiler/rustc_codegen_llvm/Cargo.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ bitflags = "2.4.1"
1414
gimli = "0.31"
1515
itertools = "0.12"
1616
libc = "0.2"
17-
libloading = { version = "0.9.0", optional = true }
17+
libloading = { version = "0.9.0" }
1818
measureme = "12.0.1"
1919
object = { version = "0.37.0", default-features = false, features = ["std", "read"] }
2020
rustc-demangle = "0.1.21"
@@ -47,7 +47,7 @@ tracing = "0.1"
4747
[features]
4848
# tidy-alphabetical-start
4949
check_only = ["rustc_llvm/check_only"]
50-
llvm_enzyme = ["dep:libloading"]
50+
llvm_enzyme = []
5151
llvm_offload = []
5252
# tidy-alphabetical-end
5353

compiler/rustc_codegen_llvm/src/back/lto.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,6 @@ fn thin_lto(
528528
}
529529
}
530530

531-
#[cfg(feature = "llvm_enzyme")]
532531
pub(crate) fn enable_autodiff_settings(ad: &[config::AutoDiff]) {
533532
let mut enzyme = llvm::EnzymeWrapper::get_instance();
534533

compiler/rustc_codegen_llvm/src/back/write.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -568,8 +568,7 @@ pub(crate) unsafe fn llvm_optimize(
568568
// FIXME(ZuseZ4): In a future update we could figure out how to only optimize individual functions getting
569569
// differentiated.
570570

571-
let consider_ad =
572-
cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable);
571+
let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable);
573572
let run_enzyme = autodiff_stage == AutodiffStage::DuringAD;
574573
let print_before_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModBefore);
575574
let print_after_enzyme = config.autodiff.contains(&config::AutoDiff::PrintModAfter);
@@ -818,8 +817,7 @@ pub(crate) fn optimize(
818817

819818
// If we know that we will later run AD, then we disable vectorization and loop unrolling.
820819
// Otherwise we pretend AD is already done and run the normal opt pipeline (=PostAD).
821-
let consider_ad =
822-
cfg!(feature = "llvm_enzyme") && config.autodiff.contains(&config::AutoDiff::Enable);
820+
let consider_ad = config.autodiff.contains(&config::AutoDiff::Enable);
823821
let autodiff_stage = if consider_ad { AutodiffStage::PreAD } else { AutodiffStage::PostAD };
824822
// The embedded bitcode is used to run LTO/ThinLTO.
825823
// The bitcode obtained during the `codegen` phase is no longer suitable for performing LTO.

compiler/rustc_codegen_llvm/src/errors.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ParseTargetMachineConfig<'_> {
3232
}
3333
}
3434

35-
#[cfg(feature = "llvm_enzyme")]
3635
#[derive(Diagnostic)]
3736
#[diag(codegen_llvm_autodiff_component_unavailable)]
3837
pub(crate) struct AutoDiffComponentUnavailable;

compiler/rustc_codegen_llvm/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,9 @@ impl CodegenBackend for LlvmCodegenBackend {
241241
fn init(&self, sess: &Session) {
242242
llvm_util::init(sess); // Make sure llvm is inited
243243

244-
#[cfg(feature = "llvm_enzyme")]
244+
// autodiff is based on Enzyme, a library which we might not have available, when it was
245+
// neither build, nor downloaded via rustup. If autodiff is used, but not available we emit
246+
// an early error here and abort compilation.
245247
{
246248
use rustc_session::config::AutoDiff;
247249

compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs

Lines changed: 0 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,8 @@ pub(crate) enum LLVMRustVerifierFailureAction {
8686
LLVMReturnStatusAction = 2,
8787
}
8888

89-
#[cfg(feature = "llvm_enzyme")]
9089
pub(crate) use self::Enzyme_AD::*;
9190

92-
#[cfg(feature = "llvm_enzyme")]
9391
pub(crate) mod Enzyme_AD {
9492
use std::ffi::{c_char, c_void};
9593
use std::sync::{Mutex, MutexGuard, OnceLock};
@@ -450,147 +448,6 @@ pub(crate) mod Enzyme_AD {
450448
}
451449
}
452450

453-
#[cfg(not(feature = "llvm_enzyme"))]
454-
pub(crate) use self::Fallback_AD::*;
455-
456-
#[cfg(not(feature = "llvm_enzyme"))]
457-
pub(crate) mod Fallback_AD {
458-
#![allow(unused_variables)]
459-
460-
use std::ffi::c_void;
461-
use std::sync::{Mutex, MutexGuard};
462-
463-
use libc::c_char;
464-
use rustc_codegen_ssa::back::write::CodegenContext;
465-
use rustc_codegen_ssa::traits::WriteBackendMethods;
466-
467-
use super::{CConcreteType, CTypeTreeRef, Context, EnzymeTypeTree};
468-
469-
pub(crate) struct EnzymeWrapper {
470-
pub registerEnzymeAndPassPipeline: *const c_void,
471-
}
472-
473-
impl EnzymeWrapper {
474-
pub(crate) fn get_or_init(
475-
_sysroot: &rustc_session::config::Sysroot,
476-
) -> Result<MutexGuard<'static, Self>, Box<dyn std::error::Error>> {
477-
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
478-
}
479-
480-
pub(crate) fn init<'a, B: WriteBackendMethods>(
481-
_cgcx: &'a CodegenContext<B>,
482-
) -> &'static Mutex<Self> {
483-
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
484-
}
485-
486-
pub(crate) fn get_instance() -> MutexGuard<'static, Self> {
487-
unimplemented!("Enzyme not available: build with llvm_enzyme feature")
488-
}
489-
490-
pub(crate) fn new_type_tree(&self) -> CTypeTreeRef {
491-
unimplemented!()
492-
}
493-
494-
pub(crate) fn new_type_tree_ct(
495-
&self,
496-
t: CConcreteType,
497-
ctx: &Context,
498-
) -> *mut EnzymeTypeTree {
499-
unimplemented!()
500-
}
501-
502-
pub(crate) fn new_type_tree_tr(&self, tree: CTypeTreeRef) -> CTypeTreeRef {
503-
unimplemented!()
504-
}
505-
506-
pub(crate) fn free_type_tree(&self, tree: CTypeTreeRef) {
507-
unimplemented!()
508-
}
509-
510-
pub(crate) fn merge_type_tree(&self, tree1: CTypeTreeRef, tree2: CTypeTreeRef) -> bool {
511-
unimplemented!()
512-
}
513-
514-
pub(crate) fn tree_only_eq(&self, tree: CTypeTreeRef, num: i64) {
515-
unimplemented!()
516-
}
517-
518-
pub(crate) fn tree_data0_eq(&self, tree: CTypeTreeRef) {
519-
unimplemented!()
520-
}
521-
522-
pub(crate) fn shift_indicies_eq(
523-
&self,
524-
tree: CTypeTreeRef,
525-
data_layout: *const c_char,
526-
offset: i64,
527-
max_size: i64,
528-
add_offset: u64,
529-
) {
530-
unimplemented!()
531-
}
532-
533-
pub(crate) fn tree_insert_eq(
534-
&self,
535-
tree: CTypeTreeRef,
536-
indices: *const i64,
537-
len: usize,
538-
ct: CConcreteType,
539-
ctx: &Context,
540-
) {
541-
unimplemented!()
542-
}
543-
544-
pub(crate) fn tree_to_string(&self, tree: *mut EnzymeTypeTree) -> *const c_char {
545-
unimplemented!()
546-
}
547-
548-
pub(crate) fn tree_to_string_free(&self, ch: *const c_char) {
549-
unimplemented!()
550-
}
551-
552-
pub(crate) fn get_max_type_depth(&self) -> usize {
553-
unimplemented!()
554-
}
555-
556-
pub(crate) fn set_inline(&mut self, val: bool) {
557-
unimplemented!()
558-
}
559-
560-
pub(crate) fn set_print_perf(&mut self, print: bool) {
561-
unimplemented!()
562-
}
563-
564-
pub(crate) fn set_print_activity(&mut self, print: bool) {
565-
unimplemented!()
566-
}
567-
568-
pub(crate) fn set_print_type(&mut self, print: bool) {
569-
unimplemented!()
570-
}
571-
572-
pub(crate) fn set_print_type_fun(&mut self, fun_name: &str) {
573-
unimplemented!()
574-
}
575-
576-
pub(crate) fn set_print(&mut self, print: bool) {
577-
unimplemented!()
578-
}
579-
580-
pub(crate) fn set_strict_aliasing(&mut self, strict: bool) {
581-
unimplemented!()
582-
}
583-
584-
pub(crate) fn set_loose_types(&mut self, loose: bool) {
585-
unimplemented!()
586-
}
587-
588-
pub(crate) fn set_rust_rules(&mut self, val: bool) {
589-
unimplemented!()
590-
}
591-
}
592-
}
593-
594451
impl TypeTree {
595452
pub(crate) fn new() -> TypeTree {
596453
let wrapper = EnzymeWrapper::get_instance();

compiler/rustc_codegen_llvm/src/typetree.rs

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,10 @@
1-
use rustc_ast::expand::typetree::FncTree;
2-
#[cfg(feature = "llvm_enzyme")]
3-
use {
4-
crate::attributes,
5-
crate::llvm::EnzymeWrapper,
6-
rustc_ast::expand::typetree::TypeTree as RustTypeTree,
7-
std::ffi::{CString, c_char, c_uint},
8-
};
9-
10-
use crate::llvm::{self, Value};
11-
12-
#[cfg(feature = "llvm_enzyme")]
1+
use std::ffi::{CString, c_char, c_uint};
2+
3+
use rustc_ast::expand::typetree::{FncTree, TypeTree as RustTypeTree};
4+
5+
use crate::attributes;
6+
use crate::llvm::{self, EnzymeWrapper, Value};
7+
138
fn to_enzyme_typetree(
149
rust_typetree: RustTypeTree,
1510
_data_layout: &str,
@@ -19,7 +14,6 @@ fn to_enzyme_typetree(
1914
process_typetree_recursive(&mut enzyme_tt, &rust_typetree, &[], llcx);
2015
enzyme_tt
2116
}
22-
#[cfg(feature = "llvm_enzyme")]
2317
fn process_typetree_recursive(
2418
enzyme_tt: &mut llvm::TypeTree,
2519
rust_typetree: &RustTypeTree,
@@ -57,13 +51,21 @@ fn process_typetree_recursive(
5751
}
5852
}
5953

60-
#[cfg(feature = "llvm_enzyme")]
54+
#[cfg_attr(not(feature = "llvm_enzyme"), allow(unused))]
6155
pub(crate) fn add_tt<'ll>(
6256
llmod: &'ll llvm::Module,
6357
llcx: &'ll llvm::Context,
6458
fn_def: &'ll Value,
6559
tt: FncTree,
6660
) {
61+
// TypeTree processing uses functions from Enzyme, which we might not have available if we did
62+
// not build this compiler with `llvm_enzyme`. This feature is not strictly necessary, but
63+
// skipping this function increases the chance that Enzyme fails to compile some code.
64+
// FIXME(autodiff): In the future we should conditionally run this function even without the
65+
// `llvm_enzyme` feature, in case that libEnzyme was provided via rustup.
66+
#[cfg(not(feature = "llvm_enzyme"))]
67+
return;
68+
6769
let inputs = tt.args;
6870
let ret_tt: RustTypeTree = tt.ret;
6971

@@ -113,13 +115,3 @@ pub(crate) fn add_tt<'ll>(
113115
enzyme_wrapper.tree_to_string_free(c_str.as_ptr());
114116
}
115117
}
116-
117-
#[cfg(not(feature = "llvm_enzyme"))]
118-
pub(crate) fn add_tt<'ll>(
119-
_llmod: &'ll llvm::Module,
120-
_llcx: &'ll llvm::Context,
121-
_fn_def: &'ll Value,
122-
_tt: FncTree,
123-
) {
124-
unimplemented!()
125-
}

0 commit comments

Comments
 (0)