@@ -1167,12 +1167,12 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
1167
1167
let arguments = (ins FlatSymbolRefAttr:$global_name);
1168
1168
let results = (outs LLVM_AnyPointer:$res);
1169
1169
1170
- let summary = "Creates a pointer pointing to a global or a function";
1170
+ let summary = "Creates a pointer pointing to a global, alias or a function";
1171
1171
1172
1172
let description = [{
1173
- Creates an SSA value containing a pointer to a global variable or constant
1174
- defined by `llvm.mlir.global`. The global value can be defined after its
1175
- first referenced. If the global value is a constant, storing into it is not
1173
+ Creates an SSA value containing a pointer to a global value (function,
1174
+ variable or alias). The global value can be defined after its first
1175
+ referenced. If the global value is a constant, storing into it is not
1176
1176
allowed.
1177
1177
1178
1178
Examples:
@@ -1190,10 +1190,19 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
1190
1190
1191
1191
// The function address can be used for indirect calls.
1192
1192
llvm.call %2() : !llvm.ptr, () -> ()
1193
+
1194
+ // Get the address of an aliased global.
1195
+ %3 = llvm.mlir.addressof @const_alias : !llvm.ptr
1193
1196
}
1194
1197
1195
1198
// Define the global.
1196
1199
llvm.mlir.global @const(42 : i32) : i32
1200
+
1201
+ // Define an alias.
1202
+ llvm.mlir.alias @const_alias : i32 {
1203
+ %0 = llvm.mlir.addressof @const : !llvm.ptr
1204
+ llvm.return %0 : !llvm.ptr
1205
+ }
1197
1206
```
1198
1207
}];
1199
1208
@@ -1212,6 +1221,14 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
1212
1221
build($_builder, $_state,
1213
1222
LLVM::LLVMPointerType::get($_builder.getContext()), func.getName());
1214
1223
$_state.addAttributes(attrs);
1224
+ }]>,
1225
+ OpBuilder<(ins "AliasOp":$alias,
1226
+ CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs),
1227
+ [{
1228
+ build($_builder, $_state,
1229
+ LLVM::LLVMPointerType::get($_builder.getContext(), alias.getAddrSpace()),
1230
+ alias.getSymName());
1231
+ $_state.addAttributes(attrs);
1215
1232
}]>
1216
1233
];
1217
1234
@@ -1222,6 +1239,10 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
1222
1239
1223
1240
/// Return the llvm.func operation that is referenced here.
1224
1241
LLVMFuncOp getFunction(SymbolTableCollection &symbolTable);
1242
+
1243
+ /// Return the llvm.mlir.alias operation that defined the value referenced
1244
+ /// here.
1245
+ AliasOp getAlias(SymbolTableCollection &symbolTable);
1225
1246
}];
1226
1247
1227
1248
let assemblyFormat = "$global_name attr-dict `:` qualified(type($res))";
@@ -1447,6 +1468,85 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
1447
1468
let hasVerifier = 1;
1448
1469
}
1449
1470
1471
+ def LLVM_AliasOp : LLVM_Op<"mlir.alias",
1472
+ [IsolatedFromAbove, SingleBlockImplicitTerminator<"ReturnOp">, Symbol]> {
1473
+ let arguments = (ins
1474
+ TypeAttr:$alias_type,
1475
+ StrAttr:$sym_name,
1476
+ Linkage:$linkage,
1477
+ UnitAttr:$dso_local,
1478
+ UnitAttr:$thread_local_,
1479
+ OptionalAttr<UnnamedAddr>:$unnamed_addr,
1480
+ DefaultValuedAttr<Visibility, "mlir::LLVM::Visibility::Default">:$visibility_
1481
+ );
1482
+ let summary = "LLVM dialect alias.";
1483
+ let description = [{
1484
+ `llvm.mlir.alias` is a top level operation that defines a global alias for
1485
+ global variables and functions. The operation is always initialized by
1486
+ using a initializer region which could be a direct map to another global
1487
+ value or contain some address computation on top of it.
1488
+
1489
+ It uses a symbol for its value, which will be uniqued by the module
1490
+ with respect to other symbols in it.
1491
+
1492
+ Similarly to functions and globals, they can also have a linkage attribute.
1493
+ This attribute is placed between `llvm.mlir.alias` and the symbol name. If
1494
+ the attribute is omitted, `external` linkage is assumed by default.
1495
+
1496
+ Examples:
1497
+
1498
+ ```mlir
1499
+ // Global alias use @-identifiers.
1500
+ llvm.mlir.alias external @foo_alias {addr_space = 0 : i32} : !llvm.ptr {
1501
+ %0 = llvm.mlir.addressof @some_function : !llvm.ptr
1502
+ llvm.return %0 : !llvm.ptr
1503
+ }
1504
+
1505
+ // More complex initialization.
1506
+ llvm.mlir.alias linkonce_odr hidden @glob
1507
+ {addr_space = 0 : i32, dso_local} : !llvm.array<32 x i32> {
1508
+ %0 = llvm.mlir.constant(1234 : i64) : i64
1509
+ %1 = llvm.mlir.addressof @glob.private : !llvm.ptr
1510
+ %2 = llvm.ptrtoint %1 : !llvm.ptr to i64
1511
+ %3 = llvm.add %2, %0 : i64
1512
+ %4 = llvm.inttoptr %3 : i64 to !llvm.ptr
1513
+ llvm.return %4 : !llvm.ptr
1514
+ }
1515
+ ```
1516
+ }];
1517
+ let regions = (region SizedRegion<1>:$initializer);
1518
+
1519
+ let builders = [
1520
+ OpBuilder<(ins "Type":$type, "Linkage":$linkage,
1521
+ "StringRef":$name,
1522
+ CArg<"bool", "false">:$dsoLocal,
1523
+ CArg<"bool", "false">:$thread_local_,
1524
+ CArg<"ArrayRef<NamedAttribute>", "{}">:$attrs)>
1525
+ ];
1526
+
1527
+ let extraClassDeclaration = [{
1528
+ /// Return the LLVM type of the global alias.
1529
+ Type getType() {
1530
+ return getAliasType();
1531
+ }
1532
+ /// Return the initializer region. It's always present and terminates
1533
+ /// with an `llvm.return` op with the initializer value.
1534
+ Region &getInitializerRegion() {
1535
+ return getOperation()->getRegion(0);
1536
+ }
1537
+ Block &getInitializerBlock() {
1538
+ return getInitializerRegion().front();
1539
+ }
1540
+ // Retrieve address space information from the initializer block
1541
+ // result.
1542
+ unsigned getAddrSpace();
1543
+ }];
1544
+
1545
+ let hasCustomAssemblyFormat = 1;
1546
+ let hasVerifier = 1;
1547
+ let hasRegionVerifier = 1;
1548
+ }
1549
+
1450
1550
def LLVM_ComdatSelectorOp : LLVM_Op<"comdat_selector", [Symbol]> {
1451
1551
let arguments = (ins
1452
1552
SymbolNameAttr:$sym_name,
0 commit comments