@@ -27,7 +27,6 @@ pub use intrinsic::IntrinsicDef;
2727use rustc_abi:: {
2828 Align , FieldIdx , Integer , IntegerType , ReprFlags , ReprOptions , ScalableElt , VariantIdx ,
2929} ;
30- use rustc_ast:: expand:: typetree:: { FncTree , Kind , Type , TypeTree } ;
3130use rustc_ast:: node_id:: NodeMap ;
3231use rustc_ast:: { self as ast} ;
3332pub use rustc_ast_ir:: { Movability , Mutability , try_visit} ;
@@ -67,7 +66,7 @@ pub use rustc_type_ir::solve::{CandidatePreferenceMode, SizedTraitKind, VisibleF
6766pub use rustc_type_ir:: * ;
6867#[ allow( hidden_glob_reexports, unused_imports) ]
6968use rustc_type_ir:: { InferCtxtLike , Interner } ;
70- use tracing:: { debug, instrument, trace } ;
69+ use tracing:: { debug, instrument} ;
7170pub use vtable:: * ;
7271
7372pub use self :: closure:: {
@@ -145,6 +144,7 @@ pub mod print;
145144pub mod relate;
146145pub mod significant_drop_order;
147146pub mod trait_def;
147+ pub mod typetree;
148148pub mod util;
149149pub mod vtable;
150150
@@ -2378,228 +2378,3 @@ pub struct DestructuredAdtConst<'tcx> {
23782378 pub variant : VariantIdx ,
23792379 pub fields : & ' tcx [ ty:: Const < ' tcx > ] ,
23802380}
2381-
2382- /// Generate TypeTree information for autodiff.
2383- /// This function creates TypeTree metadata that describes the memory layout
2384- /// of function parameters and return types for Enzyme autodiff.
2385- pub fn fnc_typetrees < ' tcx > ( tcx : TyCtxt < ' tcx > , fn_ty : Ty < ' tcx > ) -> FncTree {
2386- // Check if TypeTrees are disabled via NoTT flag
2387- if tcx. sess . opts . unstable_opts . autodiff . contains ( & rustc_session:: config:: AutoDiff :: NoTT ) {
2388- return FncTree { args : vec ! [ ] , ret : TypeTree :: new ( ) } ;
2389- }
2390-
2391- // Check if this is actually a function type
2392- if !fn_ty. is_fn ( ) {
2393- return FncTree { args : vec ! [ ] , ret : TypeTree :: new ( ) } ;
2394- }
2395-
2396- // Get the function signature
2397- let fn_sig = fn_ty. fn_sig ( tcx) ;
2398- let sig = tcx. instantiate_bound_regions_with_erased ( fn_sig) ;
2399-
2400- // Create TypeTrees for each input parameter
2401- let mut args = vec ! [ ] ;
2402- for ty in sig. inputs ( ) . iter ( ) {
2403- let type_tree = typetree_from_ty ( tcx, * ty) ;
2404- args. push ( type_tree) ;
2405- }
2406-
2407- // Create TypeTree for return type
2408- let ret = typetree_from_ty ( tcx, sig. output ( ) ) ;
2409-
2410- FncTree { args, ret }
2411- }
2412-
2413- /// Generate TypeTree for a specific type.
2414- /// This function analyzes a Rust type and creates appropriate TypeTree metadata.
2415- pub fn typetree_from_ty < ' tcx > ( tcx : TyCtxt < ' tcx > , ty : Ty < ' tcx > ) -> TypeTree {
2416- let mut visited = Vec :: new ( ) ;
2417- typetree_from_ty_inner ( tcx, ty, 0 , & mut visited)
2418- }
2419-
2420- /// Maximum recursion depth for TypeTree generation to prevent stack overflow
2421- /// from pathological deeply nested types. Combined with cycle detection.
2422- const MAX_TYPETREE_DEPTH : usize = 6 ;
2423-
2424- /// Internal recursive function for TypeTree generation with cycle detection and depth limiting.
2425- fn typetree_from_ty_inner < ' tcx > (
2426- tcx : TyCtxt < ' tcx > ,
2427- ty : Ty < ' tcx > ,
2428- depth : usize ,
2429- visited : & mut Vec < Ty < ' tcx > > ,
2430- ) -> TypeTree {
2431- if depth >= MAX_TYPETREE_DEPTH {
2432- trace ! ( "typetree depth limit {} reached for type: {}" , MAX_TYPETREE_DEPTH , ty) ;
2433- return TypeTree :: new ( ) ;
2434- }
2435-
2436- if visited. contains ( & ty) {
2437- return TypeTree :: new ( ) ;
2438- }
2439-
2440- visited. push ( ty) ;
2441- let result = typetree_from_ty_impl ( tcx, ty, depth, visited) ;
2442- visited. pop ( ) ;
2443- result
2444- }
2445-
2446- /// Implementation of TypeTree generation logic.
2447- fn typetree_from_ty_impl < ' tcx > (
2448- tcx : TyCtxt < ' tcx > ,
2449- ty : Ty < ' tcx > ,
2450- depth : usize ,
2451- visited : & mut Vec < Ty < ' tcx > > ,
2452- ) -> TypeTree {
2453- typetree_from_ty_impl_inner ( tcx, ty, depth, visited, false )
2454- }
2455-
2456- /// Internal implementation with context about whether this is for a reference target.
2457- fn typetree_from_ty_impl_inner < ' tcx > (
2458- tcx : TyCtxt < ' tcx > ,
2459- ty : Ty < ' tcx > ,
2460- depth : usize ,
2461- visited : & mut Vec < Ty < ' tcx > > ,
2462- is_reference_target : bool ,
2463- ) -> TypeTree {
2464- if ty. is_scalar ( ) {
2465- let ( kind, size) = if ty. is_integral ( ) || ty. is_char ( ) || ty. is_bool ( ) {
2466- ( Kind :: Integer , ty. primitive_size ( tcx) . bytes_usize ( ) )
2467- } else if ty. is_floating_point ( ) {
2468- match ty {
2469- x if x == tcx. types . f16 => ( Kind :: Half , 2 ) ,
2470- x if x == tcx. types . f32 => ( Kind :: Float , 4 ) ,
2471- x if x == tcx. types . f64 => ( Kind :: Double , 8 ) ,
2472- x if x == tcx. types . f128 => ( Kind :: F128 , 16 ) ,
2473- _ => ( Kind :: Integer , 0 ) ,
2474- }
2475- } else {
2476- ( Kind :: Integer , 0 )
2477- } ;
2478-
2479- // Use offset 0 for scalars that are direct targets of references (like &f64)
2480- // Use offset -1 for scalars used directly (like function return types)
2481- let offset = if is_reference_target && !ty. is_array ( ) { 0 } else { -1 } ;
2482- return TypeTree ( vec ! [ Type { offset, size, kind, child: TypeTree :: new( ) } ] ) ;
2483- }
2484-
2485- if ty. is_ref ( ) || ty. is_raw_ptr ( ) || ty. is_box ( ) {
2486- let Some ( inner_ty) = ty. builtin_deref ( true ) else {
2487- return TypeTree :: new ( ) ;
2488- } ;
2489-
2490- let child = typetree_from_ty_impl_inner ( tcx, inner_ty, depth + 1 , visited, true ) ;
2491- return TypeTree ( vec ! [ Type {
2492- offset: -1 ,
2493- size: tcx. data_layout. pointer_size( ) . bytes_usize( ) ,
2494- kind: Kind :: Pointer ,
2495- child,
2496- } ] ) ;
2497- }
2498-
2499- if ty. is_array ( ) {
2500- if let ty:: Array ( element_ty, len_const) = ty. kind ( ) {
2501- let len = len_const. try_to_target_usize ( tcx) . unwrap_or ( 0 ) ;
2502- if len == 0 {
2503- return TypeTree :: new ( ) ;
2504- }
2505- let element_tree =
2506- typetree_from_ty_impl_inner ( tcx, * element_ty, depth + 1 , visited, false ) ;
2507- let mut types = Vec :: new ( ) ;
2508- for elem_type in & element_tree. 0 {
2509- types. push ( Type {
2510- offset : -1 ,
2511- size : elem_type. size ,
2512- kind : elem_type. kind ,
2513- child : elem_type. child . clone ( ) ,
2514- } ) ;
2515- }
2516-
2517- return TypeTree ( types) ;
2518- }
2519- }
2520-
2521- if ty. is_slice ( ) {
2522- if let ty:: Slice ( element_ty) = ty. kind ( ) {
2523- let element_tree =
2524- typetree_from_ty_impl_inner ( tcx, * element_ty, depth + 1 , visited, false ) ;
2525- return element_tree;
2526- }
2527- }
2528-
2529- if let ty:: Tuple ( tuple_types) = ty. kind ( ) {
2530- if tuple_types. is_empty ( ) {
2531- return TypeTree :: new ( ) ;
2532- }
2533-
2534- let mut types = Vec :: new ( ) ;
2535- let mut current_offset = 0 ;
2536-
2537- for tuple_ty in tuple_types. iter ( ) {
2538- let element_tree =
2539- typetree_from_ty_impl_inner ( tcx, tuple_ty, depth + 1 , visited, false ) ;
2540-
2541- let element_layout = tcx
2542- . layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( tuple_ty) )
2543- . ok ( )
2544- . map ( |layout| layout. size . bytes_usize ( ) )
2545- . unwrap_or ( 0 ) ;
2546-
2547- for elem_type in & element_tree. 0 {
2548- types. push ( Type {
2549- offset : if elem_type. offset == -1 {
2550- current_offset as isize
2551- } else {
2552- current_offset as isize + elem_type. offset
2553- } ,
2554- size : elem_type. size ,
2555- kind : elem_type. kind ,
2556- child : elem_type. child . clone ( ) ,
2557- } ) ;
2558- }
2559-
2560- current_offset += element_layout;
2561- }
2562-
2563- return TypeTree ( types) ;
2564- }
2565-
2566- if let ty:: Adt ( adt_def, args) = ty. kind ( ) {
2567- if adt_def. is_struct ( ) {
2568- let struct_layout =
2569- tcx. layout_of ( ty:: TypingEnv :: fully_monomorphized ( ) . as_query_input ( ty) ) ;
2570- if let Ok ( layout) = struct_layout {
2571- let mut types = Vec :: new ( ) ;
2572-
2573- for ( field_idx, field_def) in adt_def. all_fields ( ) . enumerate ( ) {
2574- let field_ty = field_def. ty ( tcx, args) ;
2575- let field_tree = typetree_from_ty_impl_inner (
2576- tcx,
2577- field_ty. skip_norm_wip ( ) ,
2578- depth + 1 ,
2579- visited,
2580- false ,
2581- ) ;
2582-
2583- let field_offset = layout. fields . offset ( field_idx) . bytes_usize ( ) ;
2584-
2585- for elem_type in & field_tree. 0 {
2586- types. push ( Type {
2587- offset : if elem_type. offset == -1 {
2588- field_offset as isize
2589- } else {
2590- field_offset as isize + elem_type. offset
2591- } ,
2592- size : elem_type. size ,
2593- kind : elem_type. kind ,
2594- child : elem_type. child . clone ( ) ,
2595- } ) ;
2596- }
2597- }
2598-
2599- return TypeTree ( types) ;
2600- }
2601- }
2602- }
2603-
2604- TypeTree :: new ( )
2605- }
0 commit comments