Skip to content

Commit b376c7b

Browse files
committed
fixing ffi issue
1 parent 3c978eb commit b376c7b

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
@@ -2678,145 +2678,4 @@ unsafe extern "C" {
26782678
pub(crate) fn LLVMRustSetNoSanitizeAddress(Global: &Value);
26792679
pub(crate) fn LLVMRustSetNoSanitizeHWAddress(Global: &Value);
26802680

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

0 commit comments

Comments
 (0)