Skip to content

Commit 0e7fc25

Browse files
Jezurkofrabert
authored andcommitted
[MLIR][mlir-link] Implement unnamed_addr support
1 parent eca2073 commit 0e7fc25

File tree

3 files changed

+184
-0
lines changed

3 files changed

+184
-0
lines changed

mlir/include/mlir/Linker/LLVMLinkerMixin.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,28 @@ static inline Visibility getMinVisibility(Visibility lhs, Visibility rhs) {
111111
return Visibility::Default;
112112
}
113113

114+
//===----------------------------------------------------------------------===//
115+
// Unnamed_addr helpers
116+
//===----------------------------------------------------------------------===//
117+
118+
using UnnamedAddr = LLVM::UnnamedAddr;
119+
120+
static bool isNoneUnnamedAddr(UnnamedAddr val) {
121+
return val == UnnamedAddr::None;
122+
}
123+
124+
static bool isLocalUnnamedAddr(UnnamedAddr val) {
125+
return val == UnnamedAddr::Local;
126+
}
127+
128+
static UnnamedAddr getMinUnnamedAddr(UnnamedAddr lhs, UnnamedAddr rhs) {
129+
if (isNoneUnnamedAddr(lhs) || isNoneUnnamedAddr(rhs))
130+
return UnnamedAddr::None;
131+
if (isLocalUnnamedAddr(lhs) || isLocalUnnamedAddr(rhs))
132+
return UnnamedAddr::Local;
133+
return UnnamedAddr::Global;
134+
}
135+
114136
//===----------------------------------------------------------------------===//
115137
// LLVMLinkerMixin
116138
//===----------------------------------------------------------------------===//
@@ -176,6 +198,29 @@ class LLVMLinkerMixin {
176198
isAvailableExternallyLinkage(srcLinkage));
177199
}
178200

201+
LogicalResult verifyLinkageCompatibility(Conflict pair) {
202+
const DerivedLinkerInterface &derived = getDerived();
203+
assert(derived.canBeLinked(pair.src) && "expected linkable operation");
204+
assert(derived.canBeLinked(pair.dst) && "expected linkable operation");
205+
206+
auto linkError = [&](const Twine &error) -> LogicalResult {
207+
return pair.src->emitError(error) << " dst: " << pair.dst->getLoc();
208+
};
209+
210+
Linkage srcLinkage = derived.getLinkage(pair.src);
211+
Linkage dstLinkage = derived.getLinkage(pair.dst);
212+
213+
UnnamedAddr srcUnnamedAddr = derived.getUnnamedAddr(pair.src);
214+
UnnamedAddr dstUnnamedAddr = derived.getUnnamedAddr(pair.dst);
215+
216+
if (isAppendingLinkage(srcLinkage) && isAppendingLinkage(dstLinkage)) {
217+
if (srcUnnamedAddr != dstUnnamedAddr) {
218+
return linkError("Appending variables with different unnamed_addr need to be linked");
219+
}
220+
}
221+
return success();
222+
}
223+
179224
ConflictResolution resolveConflict(Conflict pair) {
180225
const DerivedLinkerInterface &derived = getDerived();
181226
assert(derived.canBeLinked(pair.src) && "expected linkable operation");
@@ -191,6 +236,13 @@ class LLVMLinkerMixin {
191236
derived.setVisibility(pair.src, visibility);
192237
derived.setVisibility(pair.dst, visibility);
193238

239+
UnnamedAddr srcUnnamedAddr = derived.getUnnamedAddr(pair.src);
240+
UnnamedAddr dstUnnamedAddr = derived.getUnnamedAddr(pair.dst);
241+
242+
UnnamedAddr unnamedAddr = getMinUnnamedAddr(srcUnnamedAddr, dstUnnamedAddr);
243+
derived.setUnnamedAddr(pair.src, unnamedAddr);
244+
derived.setUnnamedAddr(pair.dst, unnamedAddr);
245+
194246
const bool srcIsDeclaration = isDeclarationForLinker(pair.src);
195247
const bool dstIsDeclaration = isDeclarationForLinker(pair.dst);
196248

@@ -267,6 +319,8 @@ class SymbolAttrLLVMLinkerInterface
267319
}
268320

269321
LogicalResult resolveConflict(Conflict pair) override {
322+
if (failed(LinkerMixin::verifyLinkageCompatibility(pair)))
323+
return failure();
270324
ConflictResolution resolution = LinkerMixin::resolveConflict(pair);
271325

272326
switch (resolution) {

mlir/lib/Dialect/LLVMIR/IR/LLVMLinkerInterface.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,26 @@ class LLVMSymbolLinkerInterface
7474
return gv.getType().getIntOrFloatBitWidth();
7575
llvm_unreachable("unexpected operation");
7676
}
77+
78+
static UnnamedAddr getUnnamedAddr(Operation *op) {
79+
if (auto gv = dyn_cast<LLVM::GlobalOp>(op)) {
80+
auto addr = gv.getUnnamedAddr();
81+
return addr ? *addr : UnnamedAddr::Global;
82+
}
83+
if (auto fn = dyn_cast<LLVM::LLVMFuncOp>(op)) {
84+
auto addr = fn.getUnnamedAddr();
85+
return addr ? *addr : UnnamedAddr::Global;
86+
}
87+
llvm_unreachable("unexpected operation");
88+
}
89+
90+
static void setUnnamedAddr(Operation *op, UnnamedAddr val) {
91+
if (auto gv = dyn_cast<LLVM::GlobalOp>(op))
92+
return gv.setUnnamedAddr(val);
93+
if (auto fn = dyn_cast<LLVM::LLVMFuncOp>(op))
94+
return fn.setUnnamedAddr(val);
95+
llvm_unreachable("unexpected operation");
96+
}
7797
};
7898

7999
//===----------------------------------------------------------------------===//
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
// RUN: mlir-link %s -split-input-file -o - | FileCheck %s
2+
3+
module {
4+
// CHECK-DAG: llvm.mlir.global common @"global-a"(0 : i32)
5+
llvm.mlir.global common @"global-a"(0 : i32) {addr_space = 0 : i32} : i32
6+
7+
// CHECK-DAG: llvm.mlir.global common unnamed_addr @"global-b"(0 : i32)
8+
llvm.mlir.global common unnamed_addr @"global-b"(0 : i32) {addr_space = 0 : i32} : i32
9+
10+
// CHECK-DAG: llvm.mlir.global common unnamed_addr @"global-c"(0 : i32)
11+
llvm.mlir.global common unnamed_addr @"global-c"(0 : i32) {addr_space = 0 : i32} : i32
12+
13+
// CHECK-DAG: llvm.mlir.global external @"global-d"(42 : i32)
14+
llvm.mlir.global external @"global-d"() {addr_space = 0 : i32} : i32
15+
16+
// CHECK-DAG: llvm.mlir.global external unnamed_addr @"global-e"(42 : i32)
17+
llvm.mlir.global external unnamed_addr @"global-e"() {addr_space = 0 : i32} : i32
18+
19+
// CHECK-DAG: llvm.mlir.global external @"global-f"(42 : i32)
20+
llvm.mlir.global weak @"global-f"(42 : i32) {addr_space = 0 : i32} : i32
21+
22+
// CHECK-DAG: llvm.mlir.global common @"global-g"(0 : i32)
23+
llvm.mlir.global common unnamed_addr @"global-g"(0 : i32) {addr_space = 0 : i32} : i32
24+
25+
// CHECK-DAG: llvm.mlir.global external @"global-h"(42 : i32)
26+
llvm.mlir.global external @"global-h"() {addr_space = 0 : i32} : i32
27+
28+
// CHECK-DAG: llvm.mlir.global external @"global-i"(42 : i32)
29+
llvm.mlir.global external unnamed_addr @"global-i"() {addr_space = 0 : i32} : i32
30+
31+
// CHECK-DAG: llvm.mlir.global external @"global-j"(42 : i32)
32+
llvm.mlir.global weak @"global-j"(42 : i32) {addr_space = 0 : i32} : i32
33+
34+
// CHECK-DAG: llvm.func weak @"func-a"() {
35+
llvm.func weak @"func-a"() {
36+
llvm.return
37+
}
38+
39+
// CHECK-DAG: llvm.func weak unnamed_addr @"func-b"() {
40+
llvm.func weak unnamed_addr @"func-b"() {
41+
llvm.return
42+
}
43+
44+
llvm.func @"use-global-d"() -> !llvm.ptr {
45+
%0 = llvm.mlir.addressof @"global-d" : !llvm.ptr
46+
llvm.return %0 : !llvm.ptr
47+
}
48+
49+
// CHECK-DAG: llvm.func weak @"func-c"() {
50+
llvm.func @"func-c"()
51+
52+
llvm.func @"use-func-c"() {
53+
llvm.call @"func-c"() : () -> ()
54+
llvm.return
55+
}
56+
57+
// CHECK-DAG: llvm.func weak @"func-d"() {
58+
llvm.func weak @"func-d"() {
59+
llvm.return
60+
}
61+
62+
// CHECK-DAG llvm.func weak unnamed_addr @"func-e"() {
63+
llvm.func weak unnamed_addr @"func-e"() {
64+
llvm.return
65+
}
66+
67+
// CHECK-DAG: llvm.func weak @"func-g"() {
68+
llvm.func @"func-g"()
69+
70+
// CHECK-DAG: llvm.func weak @"func-h"() {
71+
llvm.func weak @"func-h"() {
72+
llvm.return
73+
}
74+
75+
// CHECK-DAG: llvm.func weak @"func-i"() {
76+
llvm.func weak unnamed_addr @"func-i"() {
77+
llvm.return
78+
}
79+
}
80+
81+
// -----
82+
83+
module {
84+
llvm.mlir.global common unnamed_addr @"global-c"(0 : i32) {addr_space = 0 : i32} : i32
85+
llvm.mlir.global external unnamed_addr @"global-d"(42 : i32) {addr_space = 0 : i32} : i32
86+
llvm.mlir.global external unnamed_addr @"global-e"(42 : i32) {addr_space = 0 : i32} : i32
87+
llvm.mlir.global external unnamed_addr @"global-f"(42 : i32) {addr_space = 0 : i32} : i32
88+
llvm.mlir.global common @"global-g"(0 : i32) {addr_space = 0 : i32} : i32
89+
llvm.mlir.global external @"global-h"(42 : i32) {addr_space = 0 : i32} : i32
90+
llvm.mlir.global external @"global-i"(42 : i32) {addr_space = 0 : i32} : i32
91+
llvm.mlir.global external @"global-j"(42 : i32) {addr_space = 0 : i32} : i32
92+
llvm.func weak unnamed_addr @"func-c"() {
93+
llvm.return
94+
}
95+
llvm.func weak unnamed_addr @"func-d"() {
96+
llvm.return
97+
}
98+
llvm.func weak unnamed_addr @"func-e"() {
99+
llvm.return
100+
}
101+
llvm.func weak @"func-g"() {
102+
llvm.return
103+
}
104+
llvm.func weak @"func-h"() {
105+
llvm.return
106+
}
107+
llvm.func weak @"func-i"() {
108+
llvm.return
109+
}
110+
}

0 commit comments

Comments
 (0)