Commit Graph

541 Commits

Author SHA1 Message Date
AMS21
064e3b8212 remove intrinsic wrapper functions from LLVM bindings 2025-10-09 09:26:44 +02:00
AMS21
1aed495ed7 refactor: replace LLVMRustAtomicLoad/Store with LLVM built-in functions 2025-10-08 13:53:09 +02:00
dianqk
1bd89bd42e codegen: Generate dbg_value for the ref statement 2025-10-02 14:55:51 +08:00
Zalathar
906bf49ade Declare all "fixed" metadata kinds as MetadataKindId 2025-09-30 20:10:10 +10:00
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
Matthias Krüger
e8578c8808 Rollup merge of #146763 - Zalathar:di-builder, r=jdonszelmann
cg_llvm: Replace some DIBuilder wrappers with LLVM-C API bindings (part 5)

- Part of rust-lang/rust#134001
- Follow-up to rust-lang/rust#146673

---

This is another batch of LLVMDIBuilder binding migrations, replacing some our own LLVMRust bindings with bindings to upstream LLVM-C APIs.

Some of these are a little more complex than most of the previous migrations, because they split one LLVMRust binding into multiple LLVM bindings, but nothing too fancy.

This appears to be the last of the low-hanging fruit. As noted in https://github.com/rust-lang/rust/issues/134001#issuecomment-2524979268, the remaining bindings are difficult or impossible to migrate at present.
2025-09-28 09:15:23 +02:00
Augie Fackler
bd860bdf26 Fix typo in LLVM_VERSION_ macro use
Co-authored-by: Nikita Popov <github@npopov.com>
2025-09-26 15:38:30 -04:00
Augie Fackler
4c7292aba3 PassWrapper: drop unused variable for LLVM 22+ 2025-09-26 13:27:34 -04:00
Augie Fackler
7a9b6d94d4 PassWrapper: update for new PGOOptions args in LLVM 22
This changed in upstream change a5569b4bd7f8.

@rustbot label llvm-main
2025-09-25 18:24:16 -04:00
Stuart Cook
59866ef305 Rollup merge of #147015 - Zalathar:dispose-tm, r=lqd
Use `LLVMDisposeTargetMachine`

After bumping the minimum LLVM version to 20 (rust-lang/rust#145071), we no longer need to run any custom code when disposing of a TargetMachine, so we can just use the upstream LLVM-C function.
2025-09-25 20:32:00 +10:00
Zalathar
85018f09f6 Use LLVMDisposeTargetMachine 2025-09-25 18:10:55 +10:00
Josh Stone
fe440ec934 llvm: add a destructor to call releaseSerializer 2025-09-24 16:53:17 -07:00
Augie Fackler
42cf78f762 llvm: update remarks support on LLVM 22
LLVM change dfbd76bda01e removed separate remark support entirely, but
it turns out we can just drop the parameter and everything appears to
work fine.

Fixes 146912 as far as I can tell (the test passes.)

@rustbot label llvm-main
2025-09-23 13:25:04 -04:00
Folkert de Vries
3565b0699d emit attribute for readonly non-pure inline assembly 2025-09-21 21:16:06 +02:00
Zalathar
741e1e2ec7 Remove unused LLVMRustDIBuilder(Create|Dispose)
These should have been removed earlier, when we switched to the corresponding
LLVM-C bindings.
2025-09-20 12:48:48 +10:00
bors
0be8e16088 Auto merge of #146700 - Zalathar:quoted-args, r=nikic
cg_llvm: Move target machine command-line quoting from C++ to Rust

When this code was introduced in rust-lang/rust#130446 and rust-lang/rust#131805, it was complicated by the need to maintain compatibility with earlier versions of LLVM.

Now that LLVM 20 is the baseline (rust-lang/rust#145071), we can do all of the quoting in pure Rust code, and pass two flat strings to LLVM to be used as-is.

---

In this PR, my priority has been to preserve the existing behaviour as much as possible, without worrying too much about what the behaviour *should* be. (Though I did avoid a leading space before the first argument.)
2025-09-19 18:32:17 +00:00
Zalathar
e39e5a0d15 Use LLVMDIBuilderCreate(Auto|Parameter)Variable 2025-09-19 20:56:58 +10:00
Zalathar
9daa026cad Use LLVMDIBuilder(CreateExpression|InsertDeclareRecordAtEnd) 2025-09-19 17:15:32 +10:00
Karan Janthe
3ba5f19182 autodiff: typetree recursive depth query from enzyme with fallback
Signed-off-by: Karan Janthe <karanjanthe@gmail.com>
2025-09-19 05:42:27 +00:00
Zalathar
a6d261712e Use LLVMDIBuilderGetOrCreateArray 2025-09-19 14:44:54 +10:00
Zalathar
b1a9f231fe Use LLVMDIBuilderGetOrCreateSubrange 2025-09-19 14:41:18 +10:00
Zalathar
8b0a254860 Move target machine command-line quoting from C++ to Rust 2025-09-18 15:25:25 +10:00
Zalathar
6b51f7c076 Use LLVMDIBuilderCreateTypedef 2025-09-17 22:32:22 +10:00
Zalathar
002771ab5c Use LLVMDIBuilderCreateQualifiedType 2025-09-17 22:32:22 +10:00
Zalathar
bb21dbeac7 Use LLVMDIBuilderCreateStaticMemberType 2025-09-17 22:32:22 +10:00
Zalathar
923d1be6b6 Use LLVMDIBuilderCreateMemberType 2025-09-17 22:32:21 +10:00
Stuart Cook
4e6640be66 Rollup merge of #146631 - Zalathar:di-builder, r=nnethercote
cg_llvm: Replace some DIBuilder wrappers with LLVM-C API bindings (part 3)

- Part of rust-lang/rust#134001
- Follow-up to rust-lang/rust#136375
- Follow-up to rust-lang/rust#136632

---

This is another batch of LLVMDIBuilder binding migrations, replacing some our own LLVMRust bindings with bindings to upstream LLVM-C APIs.

This PR migrates all of the bindings that were touched by rust-lang/rust#136632, plus `LLVMDIBuilderCreateStructType`.
2025-09-17 14:56:49 +10:00
Zalathar
af88d14cac Use LLVMDIBuilderCreateStructType 2025-09-17 12:28:08 +10:00
Zalathar
bae6fde270 Use LLVMDIBuilderCreatePointerType 2025-09-17 12:28:08 +10:00
Zalathar
3e9048d9a4 Use LLVMDIBuilderCreateBasicType 2025-09-17 12:28:08 +10:00
Zalathar
bef8f646a6 Use LLVMDIBuilderCreateArrayType 2025-09-17 12:28:08 +10:00
Zalathar
2552deb9cd Use LLVMDIBuilderCreateUnionType 2025-09-17 12:28:08 +10:00
Zalathar
5419896111 Use LLVMDIBuilderCreateSubroutineType 2025-09-17 12:28:08 +10:00
Josh Stone
580b4891aa Update the minimum external LLVM to 20 2025-09-16 11:49:20 -07:00
klensy
acb35038ff remove unused getLongestEntryLength 2025-09-11 21:43:18 +03:00
klensy
0e5281cea8 remove unused macro 2025-09-11 21:40:25 +03:00
bjorn3
f2933b34a8 Remove want_summary argument from prepare_thin
It is always false nowadays. ThinLTO summary writing is instead done by
llvm_optimize.
2025-09-06 18:37:23 +00:00
Daniel Paoliello
da8f230d5f Update to ar_archive_writer 0.5.1 2025-08-29 16:37:42 -07:00
bjorn3
23e72ab41e Move ___asan_globals_registered export
All other sanitizer symbols are handled in prepare_lto already.
2025-08-28 19:36:51 +00:00
bors
d36f964125 Auto merge of #145877 - nikic:capture-address, r=tmiasko
Use captures(address) instead of captures(none) for indirect args

While provenance cannot be captured through these arguments, the address / object identity can.

Fixes https://github.com/rust-lang/rust/issues/137668.

r? `@ghost`
2025-08-28 00:01:22 +00:00
Nikita Popov
c3ab409b4f Use captures(address) instead of captures(none) for indirect args
While provenance cannot be captured through these arguments, the
address / object identity can.
2025-08-26 16:16:23 +02:00
Zalathar
fcff8f7f5a Assert that LLVM range-attribute values don't exceed 128 bits
The underlying implementation of `LLVMCreateConstantRangeAttribute` assumes
that each of `LowerWords` and `UpperWords` points to enough u64 values to
define an integer of the specified bit-length, and will encounter UB if that is
not the case.

Our safe wrapper function always passes pointers to `[u64; 2]` arrays,
regardless of the bit-length specified. That's fine in practice, because scalar
primitives never exceed 128 bits, but it is technically a soundness hole in a
safe function.

We can close the soundness hole by explicitly asserting `size_bits <= 128`.
This is effectively just a stricter version of the existing check that the
value must be small enough to fit in `c_uint`.
2025-08-26 13:07:19 +10:00
Nikita Popov
d71ed8d19b Tell LLVM about read-only captures
`&Freeze` parameters are not only `readonly` within the function,
but any captures of the pointer can also only be used for reads.
This can now be encoded using the `captures(address, read_provenance)`
attribute.
2025-08-20 19:08:16 +02:00
Stuart Cook
8748d8e7d5 Rollup merge of #145484 - Zalathar:archive-builder, r=bjorn3
Remove `LlvmArchiveBuilder` and supporting code/bindings

Switching over to the newer Rust-based `ArArchiveBuilder` happened in rust-lang/rust#128936, a year ago.

Per the comment in `new_archive_builder`, that seems like enough time to justify removing the older, unused `LlvmArchiveBuilder` implementation and its associated bindings.

Fixes rust-lang/rust#128955.
2025-08-19 14:18:25 +10:00
Zalathar
cf8ec6798f Remove LlvmArchiveBuilder and supporting code/bindings 2025-08-16 16:38:12 +10:00
Zalathar
e193b5342b Use LLVMGetTypeKind 2025-08-15 19:35:35 +10:00
Zalathar
c64c6d85e1 Use LLVMSetTailCallKind 2025-08-15 13:57:37 +10:00
Nikita Popov
ebef9d7f63 Set dead_on_return attribute for indirect arguments
Set the dead_on_return attribute (added in LLVM 21) for arguments
that are passed indirectly, but not byval.

This indicates that the value of the argument on return does not
matter, enabling additional dead store elimination.
2025-08-11 12:39:23 +02:00
Zalathar
81ed042c8c coverage: Remove all unstable support for MC/DC instrumentation 2025-08-06 22:38:52 +10:00
Stuart Cook
8628b78f24 Rollup merge of #144232 - xacrimon:explicit-tail-call, r=WaffleLapkin
Implement support for `become` and explicit tail call codegen for the LLVM backend

This PR implements codegen of explicit tail calls via `become` in `rustc_codegen_ssa` and support within the LLVM backend. Completes a task on (https://github.com/rust-lang/rust/issues/112788). This PR implements all the necessary bits to make explicit tail calls usable, other backends have received stubs for now and will ICE if you use `become` on them. I suspect there is some bikeshedding to be done on how we should go about implementing this for other backends, but it should be relatively straightforward for GCC after this is merged.

During development I also put together a POC bytecode VM based on tail call dispatch to test these changes out and analyze the codegen to make sure it generates expected assembly. That is available [here](https://github.com/xacrimon/tcvm).
2025-07-31 15:42:00 +10:00