From ebbdecdd57160fb4816b365f79c1185d68a94c0f Mon Sep 17 00:00:00 2001 From: Alex Zinenko Date: Mon, 20 Jul 2020 13:54:30 +0200 Subject: [PATCH] [mlir] Support translating function linkage between MLIR and LLVM IR 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 | 5 +++-- mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 1 + mlir/test/Target/import.ll | 11 ++++++++++- mlir/test/Target/llvmir.mlir | 14 +++++++++++++- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp index c6a58a8dc5a..9754c614efd 100644 --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -846,8 +846,9 @@ LogicalResult Importer::processFunction(llvm::Function *f) { return failure(); b.setInsertionPoint(module.getBody(), getFuncInsertPt()); - LLVMFuncOp fop = b.create(UnknownLoc::get(context), f->getName(), - functionType); + LLVMFuncOp fop = + b.create(UnknownLoc::get(context), f->getName(), functionType, + convertLinkageFromLLVM(f->getLinkage())); if (FlatSymbolRefAttr personality = getPersonalityAsAttr(f)) fop.setAttr(b.getIdentifier("personality"), personality); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 0defea6bbbb..12d3d4009be 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -884,6 +884,7 @@ LogicalResult ModuleTranslation::convertFunctionSignatures() { function.getName(), cast(function.getType().getUnderlyingType())); llvm::Function *llvmFunc = cast(llvmFuncCst.getCallee()); + llvmFunc->setLinkage(convertLinkageToLLVM(function.linkage())); functionMapping[function.getName()] = llvmFunc; // Forward the pass-through attributes to LLVM. diff --git a/mlir/test/Target/import.ll b/mlir/test/Target/import.ll index 4f4e822eb78..24b4a0b392b 100644 --- a/mlir/test/Target/import.ll +++ b/mlir/test/Target/import.ll @@ -64,11 +64,20 @@ ; 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> , <2 x i32> ]] +; +; 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 diff --git a/mlir/test/Target/llvmir.mlir b/mlir/test/Target/llvmir.mlir index 05b8ef10588..566212aa124 100644 --- a/mlir/test/Target/llvmir.mlir +++ b/mlir/test/Target/llvmir.mlir @@ -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. // -- 2.11.0