[mlir] LLVM dialect: support globals without linkage keyword, assuming 'external'
authorAlex Zinenko <zinenko@google.com>
Tue, 14 Apr 2020 11:01:53 +0000 (13:01 +0200)
committerAlex Zinenko <zinenko@google.com>
Wed, 15 Apr 2020 08:58:32 +0000 (10:58 +0200)
Similarly to actual LLVM IR, and to `llvm.mlir.func`, allow the custom syntax
of `llvm.mlir.global` to omit the linkage keyword. If omitted, the linkage is
assumed to be external. This makes the modeling of globals in the LLVM dialect
more consistent, both within the dialect and with LLVM IR.

Differential Revision: https://reviews.llvm.org/D78096

mlir/docs/Dialects/LLVM.md
mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp
mlir/test/Dialect/LLVMIR/global.mlir

index 5264f98..95f9e17 100644 (file)
@@ -105,6 +105,14 @@ llvm.func @func() attributes {
 If the attribute is not known to LLVM IR, it will be attached as a string
 attribute.
 
+#### Linkage
+
+An LLVM IR dialect function has a linkage attribute derived from LLVM IR
+[linkage types](https://llvm.org/docs/LangRef.html#linkage-types). Linkage is
+specified by the same keyword as in LLVM IR and is located between `llvm.func`
+and the symbol name. If no linkage keyword is present, `external` linkage is
+assumed by default.
+
 ### LLVM IR operations
 
 The following operations are currently supported. The semantics of these
@@ -423,6 +431,21 @@ llvm.mlir.global constant @int_gep() : !llvm<"i32*"> {
 }
 ```
 
+Similarly to functions, globals have a linkage attribute. In the custom syntax,
+this attribute is placed between `llvm.mlir.global` and the optional `constant`
+keyword. If the attribute is omitted, `external` linkage is assumed by default.
+
+Examples:
+
+```mlir
+// A constant with internal linkage will not participate in linking.
+llvm.mlir.global internal constant @cst(42 : i32) : !llvm.i32
+
+// By default, "external" linkage is assumed and the global participates in
+// symbol resolution at link-time.
+llvm.mlir.global @glob(0 : f32) : !llvm.float
+```
+
 #### `llvm.mlir.null`
 
 Unlike LLVM IR, MLIR does not have first-class null pointers. They must be
index 01e3500..9ad8780 100644 (file)
@@ -1010,7 +1010,7 @@ static ParseResult parseOptionalLLVMKeyword(OpAsmParser &parser,
   return success();
 }
 
-// operation ::= `llvm.mlir.global` linkage `constant`? `@` identifier
+// operation ::= `llvm.mlir.global` linkage? `constant`? `@` identifier
 //               `(` attribute? `)` attribute-list? (`:` type)? region?
 //
 // The type can be omitted for string attributes, in which case it will be
@@ -1018,7 +1018,9 @@ static ParseResult parseOptionalLLVMKeyword(OpAsmParser &parser,
 static ParseResult parseGlobalOp(OpAsmParser &parser, OperationState &result) {
   if (failed(parseOptionalLLVMKeyword<Linkage>(parser, result,
                                                getLinkageAttrName())))
-    return parser.emitError(parser.getCurrentLocation(), "expected linkage");
+    result.addAttribute(getLinkageAttrName(),
+                        parser.getBuilder().getI64IntegerAttr(
+                            static_cast<int64_t>(LLVM::Linkage::External)));
 
   if (succeeded(parser.parseOptionalKeyword("constant")))
     result.addAttribute("constant", parser.getBuilder().getUnitAttr());
index cc4a00b..0b97a8e 100644 (file)
@@ -1,5 +1,11 @@
 // RUN: mlir-opt -split-input-file -verify-diagnostics %s | FileCheck %s
 
+// CHECK: llvm.mlir.global external @default_external
+llvm.mlir.global @default_external() : !llvm.i64
+
+// CHECK: llvm.mlir.global external constant @default_external_constant
+llvm.mlir.global constant @default_external_constant(42) : !llvm.i64
+
 // CHECK: llvm.mlir.global internal @global(42 : i64) : !llvm.i64
 llvm.mlir.global internal @global(42 : i64) : !llvm.i64