[mlir] Support translating function linkage between MLIR and LLVM IR
authorAlex Zinenko <zinenko@google.com>
Mon, 20 Jul 2020 11:54:30 +0000 (13:54 +0200)
committerAlex Zinenko <zinenko@google.com>
Mon, 20 Jul 2020 12:04:31 +0000 (14:04 +0200)
Linkage support is already present in the LLVM dialect, and is being translated
for globals other than functions. Translation support has been missing for
functions because their conversion goes through a different code path than
other globals.

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

mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp
mlir/lib/Target/LLVMIR/ModuleTranslation.cpp
mlir/test/Target/import.ll
mlir/test/Target/llvmir.mlir

index c6a58a8..9754c61 100644 (file)
@@ -846,8 +846,9 @@ LogicalResult Importer::processFunction(llvm::Function *f) {
     return failure();
 
   b.setInsertionPoint(module.getBody(), getFuncInsertPt());
-  LLVMFuncOp fop = b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(),
-                                        functionType);
+  LLVMFuncOp fop =
+      b.create<LLVMFuncOp>(UnknownLoc::get(context), f->getName(), functionType,
+                           convertLinkageFromLLVM(f->getLinkage()));
 
   if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f))
     fop.setAttr(b.getIdentifier("personality"), personality);
index 0defea6..12d3d40 100644 (file)
@@ -884,6 +884,7 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() {
         function.getName(),
         cast<llvm::FunctionType>(function.getType().getUnderlyingType()));
     llvm::Function *llvmFunc = cast<llvm::Function>(llvmFuncCst.getCallee());
+    llvmFunc->setLinkage(convertLinkageToLLVM(function.linkage()));
     functionMapping[function.getName()] = llvmFunc;
 
     // Forward the pass-through attributes to LLVM.
index 4f4e822..24b4a0b 100644 (file)
 ; CHECK: llvm.mlir.global internal constant @nested_array_vector(dense<[{{\[}}[1, 2], [3, 4]]]> : vector<1x2x2xi32>) : !llvm<"[1 x [2 x <2 x i32>]]">
 @nested_array_vector = internal constant [1 x [2 x <2 x i32>]] [[2 x <2 x i32>] [<2 x i32> <i32 1, i32 2>, <2 x i32> <i32 3, i32 4>]]
 
+;
+; Linkage on functions.
+;
+
+; CHECK: llvm.func internal @func_internal
+define internal void @func_internal() {
+  ret void
+}
+
 ; CHECK: llvm.func @fe(!llvm.i32) -> !llvm.float
 declare float @fe(i32)
 
 ; FIXME: function attributes.
-; CHECK-LABEL: llvm.func @f1(%arg0: !llvm.i64) -> !llvm.i32 {
+; CHECK-LABEL: llvm.func internal @f1(%arg0: !llvm.i64) -> !llvm.i32 {
 ; CHECK-DAG: %[[c2:[0-9]+]] = llvm.mlir.constant(2 : i32) : !llvm.i32
 ; CHECK-DAG: %[[c42:[0-9]+]] = llvm.mlir.constant(42 : i32) : !llvm.i32
 ; CHECK-DAG: %[[c1:[0-9]+]] = llvm.mlir.constant(true) : !llvm.i1
index 05b8ef1..566212a 100644 (file)
@@ -61,7 +61,8 @@ llvm.mlir.global external @external() : !llvm.i32
 
 
 //
-// Declarations of the allocation functions to be linked against.
+// Declarations of the allocation functions to be linked against. These are
+// inserted before other functions in the module.
 //
 
 // CHECK: declare i8* @malloc(i64)
@@ -390,6 +391,17 @@ llvm.func @more_imperfectly_nested_loops() {
   llvm.return
 }
 
+
+//
+// Check that linkage is translated for functions. No need to check all linkage
+// flags since the logic is the same as for globals.
+//
+
+// CHECK: define internal void @func_internal
+llvm.func internal @func_internal() {
+  llvm.return
+}
+
 //
 // MemRef type conversion, allocation and communication with functions.
 //