Skip to content

Commit 5d878a4

Browse files
committed
fixing ffi issue
1 parent 54a8339 commit 5d878a4

File tree

3 files changed

+100
-147
lines changed

3 files changed

+100
-147
lines changed

compiler/rustc_codegen_llvm/src/builder/autodiff.rs

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::context::SimpleCx;
1616
use crate::declare::declare_simple_fn;
1717
use crate::errors::{AutoDiffWithoutEnable, LlvmError};
1818
use crate::llvm::AttributePlace::Function;
19-
use crate::llvm::{Metadata, True};
19+
use crate::llvm::{Metadata, True, TypeTree};
2020
use crate::value::Value;
2121
use crate::{CodegenContext, LlvmCodegenBackend, ModuleLlvm, attributes, llvm};
2222

@@ -520,13 +520,14 @@ pub(crate) fn differentiate<'ll>(
520520
/// This function takes a Rust-side TypeTree (from rustc_ast::expand::typetree)
521521
/// and converts it to Enzyme's internal C++ TypeTree representation that
522522
/// Enzyme can understand during differentiation analysis.
523+
#[cfg(llvm_enzyme)]
523524
fn to_enzyme_typetree(
524525
rust_typetree: RustTypeTree,
525526
data_layout: &str,
526527
llcx: &llvm::Context,
527-
) -> llvm::TypeTree {
528+
) -> TypeTree {
528529
// Start with an empty TypeTree
529-
let mut enzyme_tt = llvm::TypeTree::new();
530+
let mut enzyme_tt = TypeTree::new();
530531

531532
// Convert each Type in the Rust TypeTree to Enzyme format
532533
for rust_type in rust_typetree.0 {
@@ -541,7 +542,7 @@ fn to_enzyme_typetree(
541542
};
542543

543544
// Create a TypeTree for this specific type
544-
let type_tt = llvm::TypeTree::from_type(concrete_type, llcx);
545+
let type_tt = TypeTree::from_type(concrete_type, llcx);
545546

546547
// Apply offset if specified
547548
let type_tt = if rust_type.offset == -1 {
@@ -558,7 +559,17 @@ fn to_enzyme_typetree(
558559
enzyme_tt
559560
}
560561

562+
#[cfg(not(llvm_enzyme))]
563+
fn to_enzyme_typetree(
564+
_rust_typetree: RustTypeTree,
565+
_data_layout: &str,
566+
_llcx: &llvm::Context,
567+
) -> ! {
568+
unimplemented!("TypeTree conversion not available without llvm_enzyme support")
569+
}
570+
561571
// Attaches TypeTree information to LLVM function as enzyme_type attributes.
572+
#[cfg(llvm_enzyme)]
562573
pub(crate) fn add_tt<'ll>(
563574
llmod: &'ll llvm::Module,
564575
llcx: &'ll llvm::Context,

compiler/rustc_codegen_llvm/src/llvm/enzyme_ffi.rs

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![expect(dead_code)]
22

3-
use libc::{c_char, c_uint, size_t};
3+
use libc::{c_char, c_uint};
44

55
use super::MetadataKindId;
66
use super::ffi::{AttributeKind, BasicBlock, Context, Metadata, Module, Type, Value};
@@ -17,6 +17,7 @@ pub(crate) struct EnzymeTypeTree {
1717

1818
#[repr(u32)]
1919
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
20+
#[allow(non_camel_case_types)]
2021
pub(crate) enum CConcreteType {
2122
DT_Anything = 0,
2223
DT_Integer = 1,
@@ -27,6 +28,10 @@ pub(crate) enum CConcreteType {
2728
DT_Unknown = 6,
2829
}
2930

31+
pub(crate) struct TypeTree {
32+
pub(crate) inner: CTypeTreeRef,
33+
}
34+
3035
#[link(name = "llvm-wrapper", kind = "static")]
3136
unsafe extern "C" {
3237
// Enzyme
@@ -87,7 +92,7 @@ pub(crate) use self::Enzyme_AD::*;
8792
pub(crate) mod Enzyme_AD {
8893
use std::ffi::{CString, c_char};
8994

90-
use libc::{c_void, size_t};
95+
use libc::c_void;
9196

9297
use super::{CConcreteType, CTypeTreeRef, Context};
9398

@@ -264,3 +269,81 @@ pub(crate) mod Fallback_AD {
264269
unimplemented!()
265270
}
266271
}
272+
273+
impl TypeTree {
274+
pub(crate) fn new() -> TypeTree {
275+
let inner = unsafe { EnzymeNewTypeTree() };
276+
TypeTree { inner }
277+
}
278+
279+
pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree {
280+
let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) };
281+
TypeTree { inner }
282+
}
283+
284+
pub(crate) fn merge(self, other: Self) -> Self {
285+
unsafe {
286+
EnzymeMergeTypeTree(self.inner, other.inner);
287+
}
288+
drop(other);
289+
self
290+
}
291+
292+
#[must_use]
293+
pub(crate) fn shift(
294+
self,
295+
layout: &str,
296+
offset: isize,
297+
max_size: isize,
298+
add_offset: usize,
299+
) -> Self {
300+
let layout = std::ffi::CString::new(layout).unwrap();
301+
302+
unsafe {
303+
EnzymeTypeTreeShiftIndiciesEq(
304+
self.inner,
305+
layout.as_ptr(),
306+
offset as i64,
307+
max_size as i64,
308+
add_offset as u64,
309+
)
310+
}
311+
312+
self
313+
}
314+
}
315+
316+
impl Clone for TypeTree {
317+
fn clone(&self) -> Self {
318+
let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) };
319+
TypeTree { inner }
320+
}
321+
}
322+
323+
impl std::fmt::Display for TypeTree {
324+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
325+
let ptr = unsafe { EnzymeTypeTreeToString(self.inner) };
326+
let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) };
327+
match cstr.to_str() {
328+
Ok(x) => write!(f, "{}", x)?,
329+
Err(err) => write!(f, "could not parse: {}", err)?,
330+
}
331+
332+
// delete C string pointer
333+
unsafe { EnzymeTypeTreeToStringFree(ptr) }
334+
335+
Ok(())
336+
}
337+
}
338+
339+
impl std::fmt::Debug for TypeTree {
340+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
341+
<Self as std::fmt::Display>::fmt(self, f)
342+
}
343+
}
344+
345+
impl Drop for TypeTree {
346+
fn drop(&mut self) {
347+
unsafe { EnzymeFreeTypeTree(self.inner) }
348+
}
349+
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

Lines changed: 0 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -2674,145 +2674,4 @@ unsafe extern "C" {
26742674
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
26752675
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
26762676

2677-
// ========== ENZYME AUTODIFF FFI FUNCTIONS ==========
2678-
2679-
#[cfg(llvm_enzyme)]
2680-
// Enzyme Type Tree Functions (minimal set for TypeTree support)
2681-
pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef;
2682-
#[cfg(llvm_enzyme)]
2683-
pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef);
2684-
#[cfg(llvm_enzyme)]
2685-
pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef;
2686-
#[cfg(llvm_enzyme)]
2687-
pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef;
2688-
#[cfg(llvm_enzyme)]
2689-
pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef);
2690-
#[cfg(llvm_enzyme)]
2691-
pub(crate) fn EnzymeTypeTreeShiftIndiciesEq(
2692-
arg1: CTypeTreeRef,
2693-
data_layout: *const c_char,
2694-
offset: i64,
2695-
max_size: i64,
2696-
add_offset: u64,
2697-
);
2698-
#[cfg(llvm_enzyme)]
2699-
pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char;
2700-
#[cfg(llvm_enzyme)]
2701-
pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char);
2702-
}
2703-
2704-
// ========== ENZYME TYPES AND ENUMS ==========
2705-
2706-
// Type Tree Support for Autodiff
2707-
2708-
#[cfg(llvm_enzyme)]
2709-
#[repr(u32)]
2710-
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
2711-
pub(crate) enum CConcreteType {
2712-
DT_Anything = 0,
2713-
DT_Integer = 1,
2714-
DT_Pointer = 2,
2715-
DT_Half = 3,
2716-
DT_Float = 4,
2717-
DT_Double = 5,
2718-
DT_Unknown = 6,
2719-
}
2720-
2721-
#[cfg(llvm_enzyme)]
2722-
pub(crate) type CTypeTreeRef = *mut EnzymeTypeTree;
2723-
2724-
#[cfg(llvm_enzyme)]
2725-
#[repr(C)]
2726-
#[derive(Debug, Copy, Clone)]
2727-
pub(crate) struct EnzymeTypeTree {
2728-
_unused: [u8; 0],
2729-
}
2730-
2731-
// TypeTree wrapper for Rust-side type safety and memory management
2732-
#[cfg(llvm_enzyme)]
2733-
pub(crate) struct TypeTree {
2734-
pub(crate) inner: CTypeTreeRef,
2735-
}
2736-
2737-
#[cfg(llvm_enzyme)]
2738-
impl TypeTree {
2739-
pub(crate) fn new() -> TypeTree {
2740-
let inner = unsafe { EnzymeNewTypeTree() };
2741-
TypeTree { inner }
2742-
}
2743-
2744-
pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree {
2745-
let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) };
2746-
TypeTree { inner }
2747-
}
2748-
2749-
pub(crate) fn merge(self, other: Self) -> Self {
2750-
unsafe {
2751-
EnzymeMergeTypeTree(self.inner, other.inner);
2752-
}
2753-
drop(other);
2754-
self
2755-
}
2756-
2757-
#[must_use]
2758-
pub(crate) fn shift(
2759-
self,
2760-
layout: &str,
2761-
offset: isize,
2762-
max_size: isize,
2763-
add_offset: usize,
2764-
) -> Self {
2765-
let layout = std::ffi::CString::new(layout).unwrap();
2766-
2767-
unsafe {
2768-
EnzymeTypeTreeShiftIndiciesEq(
2769-
self.inner,
2770-
layout.as_ptr(),
2771-
offset as i64,
2772-
max_size as i64,
2773-
add_offset as u64,
2774-
)
2775-
}
2776-
2777-
self
2778-
}
2779-
}
2780-
2781-
#[cfg(llvm_enzyme)]
2782-
impl Clone for TypeTree {
2783-
fn clone(&self) -> Self {
2784-
let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) };
2785-
TypeTree { inner }
2786-
}
2787-
}
2788-
2789-
#[cfg(llvm_enzyme)]
2790-
impl std::fmt::Display for TypeTree {
2791-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2792-
let ptr = unsafe { EnzymeTypeTreeToString(self.inner) };
2793-
let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) };
2794-
match cstr.to_str() {
2795-
Ok(x) => write!(f, "{}", x)?,
2796-
Err(err) => write!(f, "could not parse: {}", err)?,
2797-
}
2798-
2799-
// delete C string pointer
2800-
unsafe { EnzymeTypeTreeToStringFree(ptr) }
2801-
2802-
Ok(())
2803-
}
2804-
}
2805-
2806-
#[cfg(llvm_enzyme)]
2807-
impl std::fmt::Debug for TypeTree {
2808-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
2809-
<Self as std::fmt::Display>::fmt(self, f)
2810-
}
2811-
}
2812-
2813-
#[cfg(llvm_enzyme)]
2814-
impl Drop for TypeTree {
2815-
fn drop(&mut self) {
2816-
unsafe { EnzymeFreeTypeTree(self.inner) }
2817-
}
28182677
}

0 commit comments

Comments
 (0)