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