rust/compiler/rustc_codegen_llvm/src
Matthias Krüger c29fb2e57e
Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4
TypeTree support in autodiff

# TypeTrees for Autodiff

## What are TypeTrees?
Memory layout descriptors for Enzyme. Tell Enzyme exactly how types are structured in memory so it can compute derivatives efficiently.

## Structure
```rust
TypeTree(Vec<Type>)

Type {
    offset: isize,  // byte offset (-1 = everywhere)
    size: usize,    // size in bytes
    kind: Kind,     // Float, Integer, Pointer, etc.
    child: TypeTree // nested structure
}
```

## Example: `fn compute(x: &f32, data: &[f32]) -> f32`

**Input 0: `x: &f32`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, size: 4, kind: Float,
        child: TypeTree::new()
    }])
}])
```

**Input 1: `data: &[f32]`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, size: 4, kind: Float,  // -1 = all elements
        child: TypeTree::new()
    }])
}])
```

**Output: `f32`**
```rust
TypeTree(vec![Type {
    offset: -1, size: 4, kind: Float,
    child: TypeTree::new()
}])
```

## Why Needed?
- Enzyme can't deduce complex type layouts from LLVM IR
- Prevents slow memory pattern analysis
- Enables correct derivative computation for nested structures
- Tells Enzyme which bytes are differentiable vs metadata

## What Enzyme Does With This Information:

Without TypeTrees (current state):
```llvm
; Enzyme sees generic LLVM IR:
define float ``@distance(ptr*`` %p1, ptr* %p2) {
; Has to guess what these pointers point to
; Slow analysis of all memory operations
; May miss optimization opportunities
}
```

With TypeTrees (our implementation):
```llvm
define "enzyme_type"="{[]:Float@float}" float ``@distance(``
    ptr "enzyme_type"="{[]:Pointer}" %p1,
    ptr "enzyme_type"="{[]:Pointer}" %p2
) {
; Enzyme knows exact type layout
; Can generate efficient derivative code directly
}
```

# TypeTrees - Offset and -1 Explained

## Type Structure

```rust
Type {
    offset: isize, // WHERE this type starts
    size: usize,   // HOW BIG this type is
    kind: Kind,    // WHAT KIND of data (Float, Int, Pointer)
    child: TypeTree // WHAT'S INSIDE (for pointers/containers)
}
```

## Offset Values

### Regular Offset (0, 4, 8, etc.)
**Specific byte position within a structure**

```rust
struct Point {
    x: f32, // offset 0, size 4
    y: f32, // offset 4, size 4
    id: i32, // offset 8, size 4
}
```

TypeTree for `&Point` (internal representation):
```rust
TypeTree(vec![
    Type { offset: 0, size: 4, kind: Float },   // x at byte 0
    Type { offset: 4, size: 4, kind: Float },   // y at byte 4
    Type { offset: 8, size: 4, kind: Integer }  // id at byte 8
])
```

Generates LLVM:
```llvm
"enzyme_type"="{[]:Float@float}"
```

### Offset -1 (Special: "Everywhere")
**Means "this pattern repeats for ALL elements"**

#### Example 1: Array `[f32; 100]`
```rust
TypeTree(vec![Type {
    offset: -1, // ALL positions
    size: 4,    // each f32 is 4 bytes
    kind: Float, // every element is float
}])
```

Instead of listing 100 separate Types with offsets `0,4,8,12...396`

#### Example 2: Slice `&[i32]`
```rust
// Pointer to slice data
TypeTree(vec![Type {
    offset: -1, size: 8, kind: Pointer,
    child: TypeTree(vec![Type {
        offset: -1, // ALL slice elements
        size: 4,    // each i32 is 4 bytes
        kind: Integer
    }])
}])
```

#### Example 3: Mixed Structure
```rust
struct Container {
    header: i64,        // offset 0
    data: [f32; 1000],  // offset 8, but elements use -1
}
```

```rust
TypeTree(vec![
    Type { offset: 0, size: 8, kind: Integer }, // header
    Type { offset: 8, size: 4000, kind: Pointer,
        child: TypeTree(vec![Type {
            offset: -1, size: 4, kind: Float // ALL array elements
        }])
    }
])
```
2025-09-28 18:13:11 +02:00
..
back Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
builder Add TypeTree metadata attachment for autodiff 2025-09-19 04:02:19 +00:00
coverageinfo coverage: Remove all unstable support for MC/DC instrumentation 2025-08-06 22:38:52 +10:00
debuginfo Rollup merge of #146763 - Zalathar:di-builder, r=jdonszelmann 2025-09-28 09:15:23 +02:00
llvm Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
abi.rs Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
allocator.rs Use standard attribute logic for allocator shim 2025-09-25 10:04:40 +02:00
asm.rs Rollup merge of #146831 - taiki-e:powerpc-clobber, r=Amanieu 2025-09-22 20:25:14 +10:00
attributes.rs Use standard attribute logic for allocator shim 2025-09-25 10:04:40 +02:00
base.rs Use standard attribute logic for allocator shim 2025-09-25 10:04:40 +02:00
builder.rs Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
callee.rs remove rustc_attr_data_structures 2025-07-31 14:19:27 +02:00
common.rs initial implementation of the darwin_objc unstable feature 2025-09-13 16:06:22 -07:00
consts.rs initial implementation of the darwin_objc unstable feature 2025-09-13 16:06:22 -07:00
context.rs Rollup merge of #146778 - nikic:allocator-shim-attributes, r=jackh726 2025-09-26 18:11:11 +02:00
declare.rs Use standard attribute logic for allocator shim 2025-09-25 10:04:40 +02:00
errors.rs Use the object crate rather than LLVM for extracting bitcode sections 2025-07-25 11:21:28 +00:00
intrinsic.rs Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
lib.rs Rollup merge of #144197 - KMJ-007:type-tree, r=ZuseZ4 2025-09-28 18:13:11 +02:00
llvm_util.rs Add panic=immediate-abort 2025-09-21 13:12:18 -04:00
mono_item.rs Replace the llvm::Bool typedef with a proper newtype 2025-08-24 23:09:54 +10:00
type_.rs Rename llvm::Bool aliases to standard const case 2025-08-24 23:09:54 +10:00
type_of.rs Auto merge of #145717 - BoxyUwU:erase_regions_rename, r=lcnr 2025-09-09 15:04:44 +00:00
typetree.rs autodiff: typetree recursive depth query from enzyme with fallback 2025-09-19 05:42:27 +00:00
va_arg.rs added typetree support for memcpy 2025-09-19 04:02:20 +00:00
value.rs Add warn(unreachable_pub) to rustc_codegen_llvm. 2024-08-16 08:46:57 +10:00