@@ -1164,12 +1164,12 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
11641164 let arguments = (ins FlatSymbolRefAttr:$global_name);
11651165 let results = (outs LLVM_AnyPointer:$res);
11661166
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";
11681168
11691169 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
11731173 allowed.
11741174
11751175 Examples:
@@ -1187,10 +1187,19 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
11871187
11881188 // The function address can be used for indirect calls.
11891189 llvm.call %2() : !llvm.ptr, () -> ()
1190+
1191+ // Get the address of an aliased global.
1192+ %3 = llvm.mlir.addressof @const_alias : !llvm.ptr
11901193 }
11911194
11921195 // Define the global.
11931196 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+ }
11941203 ```
11951204 }];
11961205
@@ -1209,6 +1218,14 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
12091218 build($_builder, $_state,
12101219 LLVM::LLVMPointerType::get($_builder.getContext()), func.getName());
12111220 $_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);
12121229 }]>
12131230 ];
12141231
@@ -1220,6 +1237,11 @@ def LLVM_AddressOfOp : LLVM_Op<"mlir.addressof",
12201237 /// Return the llvm.func operation that is referenced here.
12211238 LLVMFuncOp getFunction(SymbolTableCollection &symbolTable);
12221239
1240+ /// Return the llvm.mlir.alias operation that defined the value referenced
1241+ /// here.
1242+ AliasOp getAlias(SymbolTableCollection &symbolTable);
1243+ }];
1244+
12231245 }];
12241246 let assemblyFormat = "$global_name attr-dict `:` qualified(type($res))";
12251247
@@ -1450,6 +1472,85 @@ def LLVM_GlobalDtorsOp : LLVM_Op<"mlir.global_dtors", [
14501472 let hasVerifier = 1;
14511473}
14521474
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+
14531554def LLVM_ComdatSelectorOp : LLVM_Op<"comdat_selector", [Symbol]> {
14541555 let arguments = (ins
14551556 SymbolNameAttr:$sym_name,
0 commit comments