<feed xmlns='http://www.w3.org/2005/Atom'>
<title>llvm-project.git, branch users/davidstone/remove-owning-array-ref</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/'/>
<entry>
<title>[llvm][clang] Remove `llvm::OwningArrayRef`</title>
<updated>2025-11-21T23:12:54+00:00</updated>
<author>
<name>David Stone</name>
<email>davidfromonline@gmail.com</email>
</author>
<published>2025-11-21T23:12:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=01164dbcc1dcd5b8a1f09af225ed5582fbb0f3cb'/>
<id>01164dbcc1dcd5b8a1f09af225ed5582fbb0f3cb</id>
<content type='text'>
`OwningArrayRef` has several problems.

The naming is strange: `ArrayRef` is specifically a non-owning view, so the name means "owning non-owning view".

It has a const-correctness bug that is inherent to the interface. `OwningArrayRef&lt;T&gt;` publicly derives from `MutableArrayRef&lt;T&gt;`. This means that the following code compiles:

```c++
void const_incorrect(llvm::OwningArrayRef&lt;int&gt; const a) {
	a[0] = 5;
}
```

It's surprising for a non-reference type to allow modification of its elements even when it's declared `const`. However, the problems from this inheritance (which ultimately stem from the same issue as the weird name) are even worse. The following function compiles without warning but corrupts memory when called:

```c++
void memory_corruption(llvm::OwningArrayRef&lt;int&gt; a) {
	a.consume_front();
}
```

This happens because `MutableArrayRef::consume_front` modifies the internal data pointer to advance the referenced array forward. That's not an issue for `MutableArrayRef` because it's just a view. It is an issue for `OwningArrayRef` because that pointer is passed as the argument to `delete[]`, so when it's modified by advancing it forward it ceases to be valid to `delete[]`. From there, undefined behavior occurs.

It is mostly less convenient than `std::vector` for construction. By combining the `size` and the `capacity` together without going through `std::allocator` to get memory, it's not possible to fill in data with the correct value to begin with. Instead, the user must construct an `OwningArrayRef` of the appropriate size, then fill in the data. This has one of two consequences:

1. If `T` is a class type, we have to first default construct all of the elements when we construct `OwningArrayRef` and then in a second pass we can assign to those elements to give what we want. This wastes time and for some classes is not possible.
2. If `T` is a built-in type, the data starts out uninitialized. This easily forgotten step means we access uninitialized memory.

Using `std::vector`, by constrast, has well-known constructors that can fill in the data that we actually want on construction.

`OwningArrayRef` has slightly different performance characteristics than `std::vector`, but the difference is minimal.

The first difference is a theoretical negative for `OwningArrayRef`: by implementing in terms of `new[]` and `delete[]`, the implementation has less room to optimize these calls. However, I say this is theoretical because for clang, at least, the extra freedom of optimization given to `std::allocator` is not yet taken advantage of (see https://github.com/llvm/llvm-project/issues/68365)

The second difference is slightly in favor of `OwningArrayRef`: `sizeof(std::vector&lt;T&gt;) == sizeof(void *) 3` on pretty much any implementation, whereas `sizeof(OwningArrayRef) == sizeof(void *) * 2` which seems like a win. However, this is just a misdirection of the accounting costs: array-new sticks bookkeeping information in the allocated storage. There are some cases where this is beneficial to reduce stack usage, but that minor benefit doesn't seem worth the costs. If we actually need that optimization, we'd be better served by writing a `DynamicArray` type that implements a full vector-like feature set (except for operations that change the size of the container) while allocating through `std::allocator` to avoid the pitfalls outlined earlier.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`OwningArrayRef` has several problems.

The naming is strange: `ArrayRef` is specifically a non-owning view, so the name means "owning non-owning view".

It has a const-correctness bug that is inherent to the interface. `OwningArrayRef&lt;T&gt;` publicly derives from `MutableArrayRef&lt;T&gt;`. This means that the following code compiles:

```c++
void const_incorrect(llvm::OwningArrayRef&lt;int&gt; const a) {
	a[0] = 5;
}
```

It's surprising for a non-reference type to allow modification of its elements even when it's declared `const`. However, the problems from this inheritance (which ultimately stem from the same issue as the weird name) are even worse. The following function compiles without warning but corrupts memory when called:

```c++
void memory_corruption(llvm::OwningArrayRef&lt;int&gt; a) {
	a.consume_front();
}
```

This happens because `MutableArrayRef::consume_front` modifies the internal data pointer to advance the referenced array forward. That's not an issue for `MutableArrayRef` because it's just a view. It is an issue for `OwningArrayRef` because that pointer is passed as the argument to `delete[]`, so when it's modified by advancing it forward it ceases to be valid to `delete[]`. From there, undefined behavior occurs.

It is mostly less convenient than `std::vector` for construction. By combining the `size` and the `capacity` together without going through `std::allocator` to get memory, it's not possible to fill in data with the correct value to begin with. Instead, the user must construct an `OwningArrayRef` of the appropriate size, then fill in the data. This has one of two consequences:

1. If `T` is a class type, we have to first default construct all of the elements when we construct `OwningArrayRef` and then in a second pass we can assign to those elements to give what we want. This wastes time and for some classes is not possible.
2. If `T` is a built-in type, the data starts out uninitialized. This easily forgotten step means we access uninitialized memory.

Using `std::vector`, by constrast, has well-known constructors that can fill in the data that we actually want on construction.

`OwningArrayRef` has slightly different performance characteristics than `std::vector`, but the difference is minimal.

The first difference is a theoretical negative for `OwningArrayRef`: by implementing in terms of `new[]` and `delete[]`, the implementation has less room to optimize these calls. However, I say this is theoretical because for clang, at least, the extra freedom of optimization given to `std::allocator` is not yet taken advantage of (see https://github.com/llvm/llvm-project/issues/68365)

The second difference is slightly in favor of `OwningArrayRef`: `sizeof(std::vector&lt;T&gt;) == sizeof(void *) 3` on pretty much any implementation, whereas `sizeof(OwningArrayRef) == sizeof(void *) * 2` which seems like a win. However, this is just a misdirection of the accounting costs: array-new sticks bookkeeping information in the allocated storage. There are some cases where this is beneficial to reduce stack usage, but that minor benefit doesn't seem worth the costs. If we actually need that optimization, we'd be better served by writing a `DynamicArray` type that implements a full vector-like feature set (except for operations that change the size of the container) while allocating through `std::allocator` to avoid the pitfalls outlined earlier.
</pre>
</div>
</content>
</entry>
<entry>
<title>[llvm] Replace `OwningArrayRef` with `std::vector` in `BTFParser`</title>
<updated>2025-11-21T22:43:27+00:00</updated>
<author>
<name>David Stone</name>
<email>davidfromonline@gmail.com</email>
</author>
<published>2025-11-21T22:43:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=c3bc565c959ee690db386241d2c16d808b961faf'/>
<id>c3bc565c959ee690db386241d2c16d808b961faf</id>
<content type='text'>
`OwningArrayRef` requires that the size and the capacity are the same. This prevents reusing memory allocations unless the size happens to be exactly the same (which is rare enough we don't even try). Switch to `std::vector` instead so that we're not repeatedly calling `new[]` and `delete[]`.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
`OwningArrayRef` requires that the size and the capacity are the same. This prevents reusing memory allocations unless the size happens to be exactly the same (which is rare enough we don't even try). Switch to `std::vector` instead so that we're not repeatedly calling `new[]` and `delete[]`.
</pre>
</div>
</content>
</entry>
<entry>
<title>Use `llvm::SmallVector` instead of `OwningArrayRef` in `VTableLayout`.</title>
<updated>2025-11-21T16:57:54+00:00</updated>
<author>
<name>David Stone</name>
<email>davidfromonline@gmail.com</email>
</author>
<published>2025-11-19T19:58:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=1653d14099cd722c00e575a4b5a9a9673f20e813'/>
<id>1653d14099cd722c00e575a4b5a9a9673f20e813</id>
<content type='text'>
This simplifies the code by removing the manual optimization for size == 1, and also gives us an optimization for other small sizes.

Accept a `llvm::SmallVector` by value for the constructor and move it into the destination, rather than accepting `ArrayRef` that we copy from. This also lets us not have to construct a reference to the elements of a `std::initializer_list`, which requires reading the implementation of the constructor to know whether it's safe.

Also explicitly document that the constructor requires the input indexes to have a size of at least 1.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This simplifies the code by removing the manual optimization for size == 1, and also gives us an optimization for other small sizes.

Accept a `llvm::SmallVector` by value for the constructor and move it into the destination, rather than accepting `ArrayRef` that we copy from. This also lets us not have to construct a reference to the elements of a `std::initializer_list`, which requires reading the implementation of the constructor to know whether it's safe.

Also explicitly document that the constructor requires the input indexes to have a size of at least 1.
</pre>
</div>
</content>
</entry>
<entry>
<title>[lldb] Add MockMemory class for dwarf expression testing (#168467)</title>
<updated>2025-11-21T16:44:08+00:00</updated>
<author>
<name>David Peixotto</name>
<email>peix@meta.com</email>
</author>
<published>2025-11-21T16:44:08+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=e724009f2f449dfcfb44c29f39872b56f6a85af1'/>
<id>e724009f2f449dfcfb44c29f39872b56f6a85af1</id>
<content type='text'>
This change unifies the way that we specify mocked memory to make it
easy to control the process and target memory contents for unit tests.
We add a MockMemory class that can be used in dwarf expression testing
to specify the output of the `ReadMemory` function.

The MockMemory class is built on a map that maps a `(address, size)`
pair to a vector of bytes that is `size` bytes long and contains the
memory contents for that `address`.

The MockProcessWithMemRead and MockTarget classes are updated to use the
new MockMemory interface. The MockProcessWithMemRead class was renamed
to MockProcess and the old MockProcess was deleted. The old MockProcess had
and ReadMemory implementation that returned the value `i &amp; 0xff` for reading the
address `i` and was easily be replaced with the MockMemory object.

The CreateTestContext function now takes optional values for process memory and 
target memory and uses those to create the mock objects.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This change unifies the way that we specify mocked memory to make it
easy to control the process and target memory contents for unit tests.
We add a MockMemory class that can be used in dwarf expression testing
to specify the output of the `ReadMemory` function.

The MockMemory class is built on a map that maps a `(address, size)`
pair to a vector of bytes that is `size` bytes long and contains the
memory contents for that `address`.

The MockProcessWithMemRead and MockTarget classes are updated to use the
new MockMemory interface. The MockProcessWithMemRead class was renamed
to MockProcess and the old MockProcess was deleted. The old MockProcess had
and ReadMemory implementation that returned the value `i &amp; 0xff` for reading the
address `i` and was easily be replaced with the MockMemory object.

The CreateTestContext function now takes optional values for process memory and 
target memory and uses those to create the mock objects.</pre>
</div>
</content>
</entry>
<entry>
<title>[bazel][ORC] Port #168518: orc deps (#169059)</title>
<updated>2025-11-21T16:25:50+00:00</updated>
<author>
<name>Jordan Rupprecht</name>
<email>rupprecht@google.com</email>
</author>
<published>2025-11-21T16:25:50+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=01227abf8d0f2c4f8d0718354dab2e8ddca8640e'/>
<id>01227abf8d0f2c4f8d0718354dab2e8ddca8640e</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[ARM] Restore hasSideEffects flag on t2WhileLoopSetup (#168948)</title>
<updated>2025-11-21T16:16:41+00:00</updated>
<author>
<name>Sergei Barannikov</name>
<email>barannikov88@gmail.com</email>
</author>
<published>2025-11-21T16:16:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=f56ddde410cd143792ce165958bc42fdcc9f7bb5'/>
<id>f56ddde410cd143792ce165958bc42fdcc9f7bb5</id>
<content type='text'>
ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before #168209, TableGen conservatively guessed that `t2WhileLoopSetup`
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add `SDNPSideEffect` to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM ever
sets `guessInstructionProperties` to false.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
ARM relies on deprecated TableGen behavior of guessing instruction
properties from patterns (`def ARM : Target` doesn't have
`guessInstructionProperties` set to false).

Before #168209, TableGen conservatively guessed that `t2WhileLoopSetup`
has side effects because the instruction wasn't matched by any pattern.

After the patch, TableGen guesses it has no side effects because the
added pattern uses only `arm_wlssetup` node, which has no side effects.

Add `SDNPSideEffect` to the node so that TableGen guesses the property
right, and also `hasSideEffects = 1` to the instruction in case ARM ever
sets `guessInstructionProperties` to false.</pre>
</div>
</content>
</entry>
<entry>
<title>[flang][NFC] replace std::exit by fir::emitFatalError in Lower/Runtime.cpp (#169050)</title>
<updated>2025-11-21T15:48:03+00:00</updated>
<author>
<name>jeanPerier</name>
<email>jperier@nvidia.com</email>
</author>
<published>2025-11-21T15:48:03+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=76a68164bb29171664c91f3583b047e2913f5e73'/>
<id>76a68164bb29171664c91f3583b047e2913f5e73</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[TSan] [Darwin] Fix off by one in TSAN init due to MemoryRangeIsAvailable (#169008)</title>
<updated>2025-11-21T15:47:11+00:00</updated>
<author>
<name>Andrew Haberlandt</name>
<email>ndrewh@users.noreply.github.com</email>
</author>
<published>2025-11-21T15:47:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=bb2e4686c1c8e4955ff5d18a7baaef3fe14ba36e'/>
<id>bb2e4686c1c8e4955ff5d18a7baaef3fe14ba36e</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>[OpenMP][OMPIRBuilder] Use runtime CC for runtime calls (#168608)</title>
<updated>2025-11-21T15:40:20+00:00</updated>
<author>
<name>Nick Sarnie</name>
<email>nick.sarnie@intel.com</email>
</author>
<published>2025-11-21T15:40:20+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=4538818c797a486edf48cbdf047a354210c3843b'/>
<id>4538818c797a486edf48cbdf047a354210c3843b</id>
<content type='text'>
Some targets have a specific calling convention that should be used for
generated calls to runtime functions.

Pass that down and use it.

Signed-off-by: Nick Sarnie &lt;nick.sarnie@intel.com&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Some targets have a specific calling convention that should be used for
generated calls to runtime functions.

Pass that down and use it.

Signed-off-by: Nick Sarnie &lt;nick.sarnie@intel.com&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>[acc][flang] Implement acc interface for tracking type descriptors (#168982)</title>
<updated>2025-11-21T15:40:04+00:00</updated>
<author>
<name>Razvan Lupusoru</name>
<email>razvan.lupusoru@gmail.com</email>
</author>
<published>2025-11-21T15:40:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/llvm-project.git/commit/?id=89bb99dd0ed9c7e5dbbc80c6cfb369768bfee96b'/>
<id>89bb99dd0ed9c7e5dbbc80c6cfb369768bfee96b</id>
<content type='text'>
FIR operations that use derived types need to have type descriptor
globals available on device when offloading. Examples of this can be
seen in `CUFDeviceGlobal` which ensures that such type descriptor uses
work on device for CUF.

Similarly, this is needed for OpenACC. This change introduces a new
interface to the OpenACC dialect named
`IndirectGlobalAccessOpInterface` which can be attached to operations
that may result in generation of accesses that use type descriptor
globals. This functionality is needed for the `ACCImplicitDeclare` pass
that is coming in a follow-up change which implicitly ensures that all
referenced globals are available in OpenACC compute contexts.

The interface provides a `getReferencedSymbols` method that collects all
global symbols referenced by an operation. When a symbol table is
provided, the implementation for FIR recursively walks type descriptor
globals to find all transitively referenced symbols.

Note that alternately this could have been implemented in different
ways:
- Codegen could implicitly generate such type globals as needed by
changing the technique that relies on populating them during lowering
(eg generate them directly in gpu.module during codegen).
- This interface could attach to types instead of operations for a
potentially more conservative implementation which maps all type
descriptors even if the underlying implementation using it won't
necessarily need such mapping.

The technique chosen here is consistent with `CUFDeviceGlobal` (which
walks operations inside `prepareImplicitDeviceGlobals`) and avoids
conservative mapping of all type descriptors.</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
FIR operations that use derived types need to have type descriptor
globals available on device when offloading. Examples of this can be
seen in `CUFDeviceGlobal` which ensures that such type descriptor uses
work on device for CUF.

Similarly, this is needed for OpenACC. This change introduces a new
interface to the OpenACC dialect named
`IndirectGlobalAccessOpInterface` which can be attached to operations
that may result in generation of accesses that use type descriptor
globals. This functionality is needed for the `ACCImplicitDeclare` pass
that is coming in a follow-up change which implicitly ensures that all
referenced globals are available in OpenACC compute contexts.

The interface provides a `getReferencedSymbols` method that collects all
global symbols referenced by an operation. When a symbol table is
provided, the implementation for FIR recursively walks type descriptor
globals to find all transitively referenced symbols.

Note that alternately this could have been implemented in different
ways:
- Codegen could implicitly generate such type globals as needed by
changing the technique that relies on populating them during lowering
(eg generate them directly in gpu.module during codegen).
- This interface could attach to types instead of operations for a
potentially more conservative implementation which maps all type
descriptors even if the underlying implementation using it won't
necessarily need such mapping.

The technique chosen here is consistent with `CUFDeviceGlobal` (which
walks operations inside `prepareImplicitDeviceGlobals`) and avoids
conservative mapping of all type descriptors.</pre>
</div>
</content>
</entry>
</feed>
