Skip to content

Commit b4a909e

Browse files
committed
Use non thread-local allocator for DistinctAttr when threading is disabled
1 parent 51ce6c4 commit b4a909e

File tree

4 files changed

+57
-2
lines changed

4 files changed

+57
-2
lines changed

mlir/lib/IR/AttributeDetail.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "mlir/Support/ThreadLocalCache.h"
2424
#include "llvm/ADT/APFloat.h"
2525
#include "llvm/ADT/PointerIntPair.h"
26+
#include "llvm/Support/Allocator.h"
2627
#include "llvm/Support/TrailingObjects.h"
2728

2829
namespace mlir {
@@ -409,14 +410,31 @@ class DistinctAttributeAllocator {
409410
operator=(const DistinctAttributeAllocator &) = delete;
410411

411412
/// Allocates a distinct attribute storage using a thread local bump pointer
412-
/// allocator to enable synchronization free parallel allocations.
413+
/// allocator to enable synchronization free parallel allocations. If
414+
/// threading is disabled on the owning MLIR context, a normal non
415+
/// thread-local bump pointer allocator is used instead to prevent
416+
/// use-after-free errors whenever attribute storage created on a crash
417+
/// recover thread is accessed after the thread joins.
413418
DistinctAttrStorage *allocate(Attribute referencedAttr) {
414-
return new (allocatorCache.get().Allocate<DistinctAttrStorage>())
419+
return new (getAllocatorInUse().Allocate<DistinctAttrStorage>())
415420
DistinctAttrStorage(referencedAttr);
416421
}
417422

423+
void disableMultithreading(bool disable = true) {
424+
useThreadLocalCache = !disable;
425+
};
426+
418427
private:
428+
llvm::BumpPtrAllocator &getAllocatorInUse() {
429+
if (useThreadLocalCache) {
430+
return allocatorCache.get();
431+
}
432+
return allocator;
433+
}
434+
419435
ThreadLocalCache<llvm::BumpPtrAllocator> allocatorCache;
436+
llvm::BumpPtrAllocator allocator;
437+
bool useThreadLocalCache : 1;
420438
};
421439
} // namespace detail
422440
} // namespace mlir

mlir/lib/IR/MLIRContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,7 @@ void MLIRContext::disableMultithreading(bool disable) {
596596
// Update the threading mode for each of the uniquers.
597597
impl->affineUniquer.disableMultithreading(disable);
598598
impl->attributeUniquer.disableMultithreading(disable);
599+
impl->distinctAttributeAllocator.disableMultithreading(disable);
599600
impl->typeUniquer.disableMultithreading(disable);
600601

601602
// Destroy thread pool (stop all threads) if it is no longer needed, or create
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Test that the enable-debug-info-scope-on-llvm-func pass can create its
2+
// DI attributes when running in the crash reproducer thread,
3+
4+
// RUN: mlir-opt --mlir-disable-threading --mlir-pass-pipeline-crash-reproducer=. \
5+
// RUN: --pass-pipeline="builtin.module(ensure-debug-info-scope-on-llvm-func)" \
6+
// RUN: --mlir-print-debuginfo %s | FileCheck %s
7+
8+
module {
9+
llvm.func @func_no_debug() {
10+
llvm.return loc(unknown)
11+
} loc(unknown)
12+
} loc(unknown)
13+
14+
// CHECK-LABEL: llvm.func @func_no_debug()
15+
// CHECK: llvm.return loc(#loc
16+
// CHECK: loc(#loc[[LOC:[0-9]+]])
17+
// CHECK: #di_file = #llvm.di_file<"<unknown>" in "">
18+
// CHECK: #di_subprogram = #llvm.di_subprogram<id = distinct[{{.*}}]<>, compileUnit = #di_compile_unit, scope = #di_file, name = "func_no_debug", linkageName = "func_no_debug", file = #di_file, line = 1, scopeLine = 1, subprogramFlags = "Definition|Optimized", type = #di_subroutine_type>
19+
// CHECK: #loc[[LOC]] = loc(fused<#di_subprogram>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This is a regression test that verifies that when running with crash
2+
// reproduction enabled, distinct attribute storage is not allocated in
3+
// thread-local storage. Since crash reproduction runs the pass manager in a
4+
// separate thread, using thread-local storage for distinct attributes causes
5+
// use-after-free errors once the thread that runs the pass manager joins.
6+
7+
// RUN: mlir-opt --mlir-disable-threading --mlir-pass-pipeline-crash-reproducer=. %s -test-distinct-attrs | FileCheck %s
8+
9+
// CHECK: #[[DIST0:.*]] = distinct[0]<42 : i32>
10+
// CHECK: #[[DIST1:.*]] = distinct[1]<42 : i32>
11+
#distinct = distinct[0]<42 : i32>
12+
13+
// CHECK: @foo_1
14+
func.func @foo_1() {
15+
// CHECK: "test.op"() {distinct.input = #[[DIST0]], distinct.output = #[[DIST1]]}
16+
"test.op"() {distinct.input = #distinct} : () -> ()
17+
}

0 commit comments

Comments
 (0)