diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index b107b64e55b46..9cb4f2a9deb36 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -1826,6 +1826,8 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", [ OptionalAttr:$denormal_fp_math, OptionalAttr:$denormal_fp_math_f32, OptionalAttr:$fp_contract, + OptionalAttr:$instrument_function_entry, + OptionalAttr:$instrument_function_exit, OptionalAttr:$no_inline, OptionalAttr:$always_inline, OptionalAttr:$no_unwind, diff --git a/mlir/lib/Target/LLVMIR/ModuleImport.cpp b/mlir/lib/Target/LLVMIR/ModuleImport.cpp index 2859abdb41772..42fd69beb09db 100644 --- a/mlir/lib/Target/LLVMIR/ModuleImport.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleImport.cpp @@ -2066,6 +2066,8 @@ static constexpr std::array kExplicitAttributes{ StringLiteral("denormal-fp-math-f32"), StringLiteral("fp-contract"), StringLiteral("frame-pointer"), + StringLiteral("instrument-function-entry"), + StringLiteral("instrument-function-exit"), StringLiteral("no-infs-fp-math"), StringLiteral("no-nans-fp-math"), StringLiteral("no-signed-zeros-fp-math"), @@ -2220,6 +2222,16 @@ void ModuleImport::processFunctionAttributes(llvm::Function *func, attr.isStringAttribute()) funcOp.setApproxFuncFpMath(attr.getValueAsBool()); + if (llvm::Attribute attr = func->getFnAttribute("instrument-function-entry"); + attr.isStringAttribute()) + funcOp.setInstrumentFunctionEntry( + StringAttr::get(context, attr.getValueAsString())); + + if (llvm::Attribute attr = func->getFnAttribute("instrument-function-exit"); + attr.isStringAttribute()) + funcOp.setInstrumentFunctionExit( + StringAttr::get(context, attr.getValueAsString())); + if (llvm::Attribute attr = func->getFnAttribute("no-signed-zeros-fp-math"); attr.isStringAttribute()) funcOp.setNoSignedZerosFpMath(attr.getValueAsBool()); diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index ee7dc3a5231f4..e1534bb508445 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -1525,6 +1525,12 @@ LogicalResult ModuleTranslation::convertOneFunction(LLVMFuncOp func) { if (auto fpContract = func.getFpContract()) llvmFunc->addFnAttr("fp-contract", *fpContract); + if (auto instrumentFunctionEntry = func.getInstrumentFunctionEntry()) + llvmFunc->addFnAttr("instrument-function-entry", *instrumentFunctionEntry); + + if (auto instrumentFunctionExit = func.getInstrumentFunctionExit()) + llvmFunc->addFnAttr("instrument-function-exit", *instrumentFunctionExit); + // First, create all blocks so we can jump to them. llvm::LLVMContext &llvmContext = llvmFunc->getContext(); for (auto &bb : func) { diff --git a/mlir/test/Dialect/LLVMIR/func.mlir b/mlir/test/Dialect/LLVMIR/func.mlir index 7caea3920255a..a168cebff019b 100644 --- a/mlir/test/Dialect/LLVMIR/func.mlir +++ b/mlir/test/Dialect/LLVMIR/func.mlir @@ -312,6 +312,18 @@ module { llvm.return } + llvm.func @instrument_function_entry_function() attributes {instrument_function_entry = "__cyg_profile_func_enter"} { + // CHECK: @instrument_function_entry_function + // CHECK-SAME: attributes {instrument_function_entry = "__cyg_profile_func_enter"} + llvm.return + } + + llvm.func @instrument_function_exit_function() attributes {instrument_function_exit = "__cyg_profile_func_exit"} { + // CHECK: @instrument_function_exit_function + // CHECK-SAME: attributes {instrument_function_exit = "__cyg_profile_func_exit"} + llvm.return + } + llvm.func @nounwind_function() attributes {no_unwind} { // CHECK: @nounwind_function // CHECK-SAME: attributes {no_unwind} diff --git a/mlir/test/Target/LLVMIR/Import/function-attributes.ll b/mlir/test/Target/LLVMIR/Import/function-attributes.ll index beda421504648..0b13645853cea 100644 --- a/mlir/test/Target/LLVMIR/Import/function-attributes.ll +++ b/mlir/test/Target/LLVMIR/Import/function-attributes.ll @@ -381,6 +381,18 @@ declare void @func_attr_fp_contract_fast() "fp-contract"="fast" // ----- +; CHECK-LABEL: @func_attr_instrument_function_entry +; CHECK-SAME: attributes {instrument_function_entry = "__cyg_profile_func_enter"} +declare void @func_attr_instrument_function_entry() "instrument-function-entry"="__cyg_profile_func_enter" + +// ----- + +; CHECK-LABEL: @func_attr_instrument_function_exit +; CHECK-SAME: attributes {instrument_function_exit = "__cyg_profile_func_exit"} +declare void @func_attr_instrument_function_exit() "instrument-function-exit"="__cyg_profile_func_exit" + +// ----- + ; CHECK-LABEL: @noinline_attribute ; CHECK-SAME: attributes {no_inline} declare void @noinline_attribute() noinline diff --git a/mlir/test/Target/LLVMIR/llvmir.mlir b/mlir/test/Target/LLVMIR/llvmir.mlir index 39c71b43d9edc..132bc0cd03a54 100644 --- a/mlir/test/Target/LLVMIR/llvmir.mlir +++ b/mlir/test/Target/LLVMIR/llvmir.mlir @@ -2559,6 +2559,24 @@ llvm.func @convergent() attributes { convergent } { // ----- +// CHECK-LABEL: define void @function_entry_instrument_test() +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @function_entry_instrument_test() attributes {instrument_function_entry = "__cyg_profile_func_enter"} { + llvm.return +} +// CHECK: attributes #[[ATTRS]] = { "instrument-function-entry"="__cyg_profile_func_enter" } + +// ----- + +// CHECK-LABEL: define void @function_exit_instrument_test() +// CHECK-SAME: #[[ATTRS:[0-9]+]] +llvm.func @function_exit_instrument_test() attributes {instrument_function_exit = "__cyg_profile_func_exit"} { + llvm.return +} +// CHECK: attributes #[[ATTRS]] = { "instrument-function-exit"="__cyg_profile_func_exit" } + +// ----- + // CHECK-LABEL: @nounwind // CHECK-SAME: #[[ATTRS:[0-9]+]] llvm.func @nounwind() attributes { no_unwind } {