@@ -1167,12 +1167,12 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
11671167 let arguments = (ins FlatSymbolRefAttr:$global_name);
11681168 let results = (outs LLVM_AnyPointer:$res);
11691169
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";
11711171
11721172 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
11761176 allowed.
11771177
11781178 Examples:
@@ -1190,10 +1190,19 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
11901190
11911191 // The function address can be used for indirect calls.
11921192 llvm.call %2() : !llvm.ptr, () -> ()
1193+
1194+ // Get the address of an aliased global.
1195+ %3 = llvm.mlir.addressof @const_alias : !llvm.ptr
11931196 }
11941197
11951198 // Define the global.
11961199 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+ }
11971206 ```
11981207 }];
11991208
@@ -1212,6 +1221,14 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
12121221 build($_builder, $_state,
12131222 LLVM::LLVMPointerType::get($_builder.getContext()), func.getName());
12141223 $_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);
12151232 }]>
12161233 ];
12171234
@@ -1222,6 +1239,10 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
12221239
12231240 /// Return the llvm.func operation that is referenced here.
12241241 LLVMFuncOp getFunction(SymbolTableCollection &symbolTable);
1242+
1243+ /// Return the llvm.mlir.alias operation that defined the value referenced
1244+ /// here.
1245+ AliasOp getAlias(SymbolTableCollection &symbolTable);
12251246 }];
12261247
12271248 let assemblyFormat = "$global_name attr-dict `:` qualified(type($res))";
@@ -1447,6 +1468,85 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
14471468 let hasVerifier = 1;
14481469}
14491470
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+
14501550def LLVM_ComdatSelectorOp : LLVM_Op<"comdat_selector", [Symbol]> {
14511551 let arguments = (ins
14521552 SymbolNameAttr:$sym_name,
0 commit comments