1#![expect(dead_code)]
2
3use libc::{c_char, c_uint};
4
5use super::MetadataKindId;
6use super::ffi::{AttributeKind, BasicBlock, Context, Metadata, Module, Type, Value};
7use crate::llvm::{Bool, Builder};
8
9pub(crate) type CTypeTreeRef = *mut EnzymeTypeTree;
11
12#[repr(C)]
13#[derive(Debug, Copy, Clone)]
14pub(crate) struct EnzymeTypeTree {
15 _unused: [u8; 0],
16}
17
18#[repr(u32)]
19#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
20#[allow(non_camel_case_types)]
21pub(crate) enum CConcreteType {
22 DT_Anything = 0,
23 DT_Integer = 1,
24 DT_Pointer = 2,
25 DT_Half = 3,
26 DT_Float = 4,
27 DT_Double = 5,
28 DT_Unknown = 6,
29 DT_FP128 = 9,
30}
31
32pub(crate) struct TypeTree {
33 pub(crate) inner: CTypeTreeRef,
34}
35
36#[link(name = "llvm-wrapper", kind = "static")]
37unsafe extern "C" {
38 pub(crate) safe fn LLVMRustHasMetadata(I: &Value, KindID: MetadataKindId) -> bool;
40 pub(crate) fn LLVMRustEraseInstUntilInclusive(BB: &BasicBlock, I: &Value);
41 pub(crate) fn LLVMRustGetLastInstruction<'a>(BB: &BasicBlock) -> Option<&'a Value>;
42 pub(crate) fn LLVMRustDIGetInstMetadata(I: &Value) -> Option<&Metadata>;
43 pub(crate) fn LLVMRustEraseInstFromParent(V: &Value);
44 pub(crate) fn LLVMRustGetTerminator<'a>(B: &BasicBlock) -> &'a Value;
45 pub(crate) fn LLVMRustVerifyFunction(V: &Value, action: LLVMRustVerifierFailureAction) -> Bool;
46 pub(crate) fn LLVMRustHasAttributeAtIndex(V: &Value, i: c_uint, Kind: AttributeKind) -> bool;
47 pub(crate) fn LLVMRustGetArrayNumElements(Ty: &Type) -> u64;
48 pub(crate) fn LLVMRustHasFnAttribute(
49 F: &Value,
50 Name: *const c_char,
51 NameLen: libc::size_t,
52 ) -> bool;
53 pub(crate) fn LLVMRustRemoveFnAttribute(F: &Value, Name: *const c_char, NameLen: libc::size_t);
54 pub(crate) fn LLVMGetFirstFunction(M: &Module) -> Option<&Value>;
55 pub(crate) fn LLVMGetNextFunction(Fn: &Value) -> Option<&Value>;
56 pub(crate) fn LLVMRustRemoveEnumAttributeAtIndex(
57 Fn: &Value,
58 index: c_uint,
59 kind: AttributeKind,
60 );
61 pub(crate) fn LLVMRustPositionBefore<'a>(B: &'a Builder<'_>, I: &'a Value);
62 pub(crate) fn LLVMRustPositionAfter<'a>(B: &'a Builder<'_>, I: &'a Value);
63 pub(crate) fn LLVMRustGetFunctionCall(
64 F: &Value,
65 name: *const c_char,
66 NameLen: libc::size_t,
67 ) -> Option<&Value>;
68
69}
70
71unsafe extern "C" {
72 pub(crate) fn LLVMDumpModule(M: &Module);
74 pub(crate) fn LLVMDumpValue(V: &Value);
75 pub(crate) fn LLVMGetFunctionCallConv(F: &Value) -> c_uint;
76 pub(crate) fn LLVMGetReturnType(T: &Type) -> &Type;
77 pub(crate) fn LLVMGetParams(Fnc: &Value, params: *mut &Value);
78 pub(crate) fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> Option<&Value>;
79}
80
81#[repr(C)]
82#[derive(Copy, Clone, PartialEq)]
83pub(crate) enum LLVMRustVerifierFailureAction {
84 LLVMAbortProcessAction = 0,
85 LLVMPrintMessageAction = 1,
86 LLVMReturnStatusAction = 2,
87}
88
89#[cfg(feature = "llvm_enzyme")]
90pub(crate) use self::Enzyme_AD::*;
91
92#[cfg(feature = "llvm_enzyme")]
93pub(crate) mod Enzyme_AD {
94 use std::ffi::{CString, c_char};
95
96 use libc::c_void;
97
98 use super::{CConcreteType, CTypeTreeRef, Context};
99
100 unsafe extern "C" {
101 pub(crate) fn EnzymeSetCLBool(arg1: *mut ::std::os::raw::c_void, arg2: u8);
102 pub(crate) fn EnzymeSetCLString(arg1: *mut ::std::os::raw::c_void, arg2: *const c_char);
103 }
104
105 unsafe extern "C" {
107 pub(crate) fn EnzymeNewTypeTree() -> CTypeTreeRef;
108 pub(crate) fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef;
109 pub(crate) fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef;
110 pub(crate) fn EnzymeFreeTypeTree(CTT: CTypeTreeRef);
111 pub(crate) fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool;
112 pub(crate) fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64);
113 pub(crate) fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef);
114 pub(crate) fn EnzymeTypeTreeShiftIndiciesEq(
115 arg1: CTypeTreeRef,
116 data_layout: *const c_char,
117 offset: i64,
118 max_size: i64,
119 add_offset: u64,
120 );
121 pub(crate) fn EnzymeTypeTreeInsertEq(
122 CTT: CTypeTreeRef,
123 indices: *const i64,
124 len: usize,
125 ct: CConcreteType,
126 ctx: &Context,
127 );
128 pub(crate) fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char;
129 pub(crate) fn EnzymeTypeTreeToStringFree(arg1: *const c_char);
130 }
131
132 unsafe extern "C" {
133 static mut EnzymePrintPerf: c_void;
134 static mut EnzymePrintActivity: c_void;
135 static mut EnzymePrintType: c_void;
136 static mut EnzymeFunctionToAnalyze: c_void;
137 static mut EnzymePrint: c_void;
138 static mut EnzymeStrictAliasing: c_void;
139 static mut looseTypeAnalysis: c_void;
140 static mut EnzymeInline: c_void;
141 static mut RustTypeRules: c_void;
142 }
143 pub(crate) fn set_print_perf(print: bool) {
144 unsafe {
145 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintPerf), print as u8);
146 }
147 }
148 pub(crate) fn set_print_activity(print: bool) {
149 unsafe {
150 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintActivity), print as u8);
151 }
152 }
153 pub(crate) fn set_print_type(print: bool) {
154 unsafe {
155 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrintType), print as u8);
156 }
157 }
158 pub(crate) fn set_print_type_fun(fun_name: &str) {
159 let c_fun_name = CString::new(fun_name).unwrap();
160 unsafe {
161 EnzymeSetCLString(
162 std::ptr::addr_of_mut!(EnzymeFunctionToAnalyze),
163 c_fun_name.as_ptr() as *const c_char,
164 );
165 }
166 }
167 pub(crate) fn set_print(print: bool) {
168 unsafe {
169 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymePrint), print as u8);
170 }
171 }
172 pub(crate) fn set_strict_aliasing(strict: bool) {
173 unsafe {
174 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeStrictAliasing), strict as u8);
175 }
176 }
177 pub(crate) fn set_loose_types(loose: bool) {
178 unsafe {
179 EnzymeSetCLBool(std::ptr::addr_of_mut!(looseTypeAnalysis), loose as u8);
180 }
181 }
182 pub(crate) fn set_inline(val: bool) {
183 unsafe {
184 EnzymeSetCLBool(std::ptr::addr_of_mut!(EnzymeInline), val as u8);
185 }
186 }
187 pub(crate) fn set_rust_rules(val: bool) {
188 unsafe {
189 EnzymeSetCLBool(std::ptr::addr_of_mut!(RustTypeRules), val as u8);
190 }
191 }
192}
193
194#[cfg(not(feature = "llvm_enzyme"))]
195pub(crate) use self::Fallback_AD::*;
196
197#[cfg(not(feature = "llvm_enzyme"))]
198pub(crate) mod Fallback_AD {
199 #![allow(unused_variables)]
200
201 use libc::c_char;
202
203 use super::{CConcreteType, CTypeTreeRef, Context};
204
205 pub(crate) unsafe fn EnzymeNewTypeTree() -> CTypeTreeRef {
207 unimplemented!()
208 }
209
210 pub(crate) unsafe fn EnzymeNewTypeTreeCT(arg1: CConcreteType, ctx: &Context) -> CTypeTreeRef {
211 unimplemented!()
212 }
213
214 pub(crate) unsafe fn EnzymeNewTypeTreeTR(arg1: CTypeTreeRef) -> CTypeTreeRef {
215 unimplemented!()
216 }
217
218 pub(crate) unsafe fn EnzymeFreeTypeTree(CTT: CTypeTreeRef) {
219 unimplemented!()
220 }
221
222 pub(crate) unsafe fn EnzymeMergeTypeTree(arg1: CTypeTreeRef, arg2: CTypeTreeRef) -> bool {
223 unimplemented!()
224 }
225
226 pub(crate) unsafe fn EnzymeTypeTreeOnlyEq(arg1: CTypeTreeRef, pos: i64) {
227 unimplemented!()
228 }
229
230 pub(crate) unsafe fn EnzymeTypeTreeData0Eq(arg1: CTypeTreeRef) {
231 unimplemented!()
232 }
233
234 pub(crate) unsafe fn EnzymeTypeTreeShiftIndiciesEq(
235 arg1: CTypeTreeRef,
236 data_layout: *const c_char,
237 offset: i64,
238 max_size: i64,
239 add_offset: u64,
240 ) {
241 unimplemented!()
242 }
243
244 pub(crate) unsafe fn EnzymeTypeTreeInsertEq(
245 CTT: CTypeTreeRef,
246 indices: *const i64,
247 len: usize,
248 ct: CConcreteType,
249 ctx: &Context,
250 ) {
251 unimplemented!()
252 }
253
254 pub(crate) unsafe fn EnzymeTypeTreeToString(arg1: CTypeTreeRef) -> *const c_char {
255 unimplemented!()
256 }
257
258 pub(crate) unsafe fn EnzymeTypeTreeToStringFree(arg1: *const c_char) {
259 unimplemented!()
260 }
261
262 pub(crate) fn set_inline(val: bool) {
263 unimplemented!()
264 }
265 pub(crate) fn set_print_perf(print: bool) {
266 unimplemented!()
267 }
268 pub(crate) fn set_print_activity(print: bool) {
269 unimplemented!()
270 }
271 pub(crate) fn set_print_type(print: bool) {
272 unimplemented!()
273 }
274 pub(crate) fn set_print_type_fun(fun_name: &str) {
275 unimplemented!()
276 }
277 pub(crate) fn set_print(print: bool) {
278 unimplemented!()
279 }
280 pub(crate) fn set_strict_aliasing(strict: bool) {
281 unimplemented!()
282 }
283 pub(crate) fn set_loose_types(loose: bool) {
284 unimplemented!()
285 }
286 pub(crate) fn set_rust_rules(val: bool) {
287 unimplemented!()
288 }
289}
290
291impl TypeTree {
292 pub(crate) fn new() -> TypeTree {
293 let inner = unsafe { EnzymeNewTypeTree() };
294 TypeTree { inner }
295 }
296
297 pub(crate) fn from_type(t: CConcreteType, ctx: &Context) -> TypeTree {
298 let inner = unsafe { EnzymeNewTypeTreeCT(t, ctx) };
299 TypeTree { inner }
300 }
301
302 pub(crate) fn merge(self, other: Self) -> Self {
303 unsafe {
304 EnzymeMergeTypeTree(self.inner, other.inner);
305 }
306 drop(other);
307 self
308 }
309
310 #[must_use]
311 pub(crate) fn shift(
312 self,
313 layout: &str,
314 offset: isize,
315 max_size: isize,
316 add_offset: usize,
317 ) -> Self {
318 let layout = std::ffi::CString::new(layout).unwrap();
319
320 unsafe {
321 EnzymeTypeTreeShiftIndiciesEq(
322 self.inner,
323 layout.as_ptr(),
324 offset as i64,
325 max_size as i64,
326 add_offset as u64,
327 );
328 }
329
330 self
331 }
332
333 pub(crate) fn insert(&mut self, indices: &[i64], ct: CConcreteType, ctx: &Context) {
334 unsafe {
335 EnzymeTypeTreeInsertEq(self.inner, indices.as_ptr(), indices.len(), ct, ctx);
336 }
337 }
338}
339
340impl Clone for TypeTree {
341 fn clone(&self) -> Self {
342 let inner = unsafe { EnzymeNewTypeTreeTR(self.inner) };
343 TypeTree { inner }
344 }
345}
346
347impl std::fmt::Display for TypeTree {
348 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
349 let ptr = unsafe { EnzymeTypeTreeToString(self.inner) };
350 let cstr = unsafe { std::ffi::CStr::from_ptr(ptr) };
351 match cstr.to_str() {
352 Ok(x) => write!(f, "{}", x)?,
353 Err(err) => write!(f, "could not parse: {}", err)?,
354 }
355
356 unsafe {
358 EnzymeTypeTreeToStringFree(ptr);
359 }
360
361 Ok(())
362 }
363}
364
365impl std::fmt::Debug for TypeTree {
366 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
367 <Self as std::fmt::Display>::fmt(self, f)
368 }
369}
370
371impl Drop for TypeTree {
372 fn drop(&mut self) {
373 unsafe { EnzymeFreeTypeTree(self.inner) }
374 }
375}