From 1bf792137478ddbe036b2c04c64985d11ba33d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20B=C3=B6ck?= Date: Fri, 11 Feb 2022 10:23:35 +0100 Subject: [PATCH] [mlir][LLVM] Add support for adding a garbage collector to a LLVM function This patch simply adds an optional garbage collector attribute to LLVMFuncOp which maps 1:1 to the "gc" property of functions in LLVM. Differential Revision: https://reviews.llvm.org/D119492 --- mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td | 1 + mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp | 3 +++ mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 3 +++ mlir/test/Target/LLVMIR/import.ll | 6 ++++++ mlir/test/Target/LLVMIR/llvmir.mlir | 6 ++++++ 5 files changed, 19 insertions(+) diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 7dae79047b1b..d9883f33086e 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1237,6 +1237,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [ let arguments = (ins DefaultValuedAttr:$linkage, UnitAttr:$dso_local, OptionalAttr:$personality, + OptionalAttr:$garbageCollector, OptionalAttr:$passthrough); let regions = (region AnyRegion:$body); diff --git a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp index 7b42f40f5ae6..5415905c517d 100644 --- a/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp +++ b/mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp @@ -812,6 +812,9 @@ LogicalResult Importer::processFunction(llvm::Function *f) { emitWarning(UnknownLoc::get(context), "could not deduce personality, skipping it"); + if (f->hasGC()) + fop.setGarbageCollectorAttr(b.getStringAttr(f->getGC())); + if (f->isDeclaration()) return success(); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 75d04e164868..544af4cf48c5 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -797,6 +797,9 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) { llvmFunc->setPersonalityFn(pfunc); } + if (auto gc = func.getGarbageCollector()) + llvmFunc->setGC(gc->str()); + // First, create all blocks so we can jump to them. llvm::LLVMContext &llvmContext = llvmFunc->getContext(); for (auto &bb : func) { diff --git a/mlir/test/Target/LLVMIR/import.ll b/mlir/test/Target/LLVMIR/import.ll index a8884bdd91a3..c1deb500d1cf 100644 --- a/mlir/test/Target/LLVMIR/import.ll +++ b/mlir/test/Target/LLVMIR/import.ll @@ -331,6 +331,12 @@ define i32 @invokeLandingpad() personality i8* bitcast (i32 (...)* @__gxx_person ret i32 0 } +; CHECK-LABEL: @hasGCFunction +; CHECK-SAME: garbageCollector = "statepoint-example" +define void @hasGCFunction() gc "statepoint-example" { + ret void +} + ;CHECK-LABEL: @useFreezeOp define i32 @useFreezeOp(i32 %x) { ;CHECK: %{{[0-9]+}} = llvm.freeze %{{[0-9a-z]+}} : i32 diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 644d48040404..ef369714d94f 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -1378,6 +1378,12 @@ llvm.func @invoke_phis() -> i32 attributes { personality = @__gxx_personality_v0 // ----- +// CHECK-LABEL: @hasGCFunction +// CHECK-SAME: gc "statepoint-example" +llvm.func @hasGCFunction() attributes { garbageCollector = "statepoint-example" } { + llvm.return +} + // CHECK-LABEL: @callFreezeOp llvm.func @callFreezeOp(%x : i32) { // CHECK: freeze i32 %{{[0-9]+}}