Skip to content

Commit 92bbf61

Browse files
authored
[Flang][MLIR][OpenMP] Use function-attached target attributes for OpenMP lowering (#78291)
This patch removes the omp.target module attribute, since the information it held on the target CPU and features is available through the fir.target_cpu and fir.target_features module attributes. Target outlining during the MLIR to LLVM IR translation stage is updated, so that these attributes, at that point available as llvm.func attributes, are passed along to the newly created function.
1 parent 7a4570a commit 92bbf61

File tree

9 files changed

+65
-81
lines changed

9 files changed

+65
-81
lines changed

flang/include/flang/Tools/CrossToolHelpers.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -109,17 +109,6 @@ void setOffloadModuleInterfaceAttributes(
109109
}
110110
}
111111

112-
// Shares assinging of the OpenMP OffloadModuleInterface and its TargetCPU
113-
// attribute accross Flang tools (bbc/flang)
114-
void setOffloadModuleInterfaceTargetAttribute(mlir::ModuleOp &module,
115-
llvm::StringRef targetCPU, llvm::StringRef targetFeatures) {
116-
// Should be registered by the OpenMPDialect
117-
if (auto offloadMod = llvm::dyn_cast<mlir::omp::OffloadModuleInterface>(
118-
module.getOperation())) {
119-
offloadMod.setTarget(targetCPU, targetFeatures);
120-
}
121-
}
122-
123112
void setOpenMPVersionAttribute(mlir::ModuleOp &module, int64_t version) {
124113
module.getOperation()->setAttr(
125114
mlir::StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,6 @@ bool CodeGenAction::beginSourceFileAction() {
301301
Fortran::common::LanguageFeature::OpenMP)) {
302302
setOffloadModuleInterfaceAttributes(*mlirModule,
303303
ci.getInvocation().getLangOpts());
304-
setOffloadModuleInterfaceTargetAttribute(
305-
*mlirModule, targetMachine.getTargetCPU(),
306-
targetMachine.getTargetFeatureString());
307304
setOpenMPVersionAttribute(*mlirModule,
308305
ci.getInvocation().getLangOpts().OpenMPVersion);
309306
}
Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
!REQUIRES: amdgpu-registered-target, nvptx-registered-target
2-
!RUN: %flang_fc1 -emit-fir -triple amdgcn-amd-amdhsa -target-cpu gfx908 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
3-
!RUN: %flang_fc1 -emit-hlfir -triple nvptx64-nvidia-cuda -target-cpu sm_80 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck --check-prefix=NVPTX %s
4-
2+
!RUN: %flang_fc1 -emit-fir -triple amdgcn-amd-amdhsa -target-cpu gfx908 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck --check-prefix=AMDGCN %s
3+
!RUN: %flang_fc1 -emit-fir -triple nvptx64-nvidia-cuda -target-cpu sm_80 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck --check-prefix=NVPTX %s
54

65
!===============================================================================
76
! Target_Enter Simple
87
!===============================================================================
98

10-
!CHECK: omp.target = #omp.target<target_cpu = "gfx908",
11-
!CHECK-SAME: target_features = "+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot10-insts,
12-
!CHECK-SAME: +dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,
13-
!CHECK-SAME: +gfx8-insts,+gfx9-insts,+gws,+image-insts,+mai-insts,+s-memrealtime,+s-memtime-inst,
14-
!CHECK-SAME: +wavefrontsize64">
15-
!NVPTX: omp.target = #omp.target<target_cpu = "sm_80", target_features = "+ptx61,+sm_80">
16-
!CHECK-LABEL: func.func @_QPomp_target_simple()
17-
subroutine omp_target_simple
18-
! Directive needed to prevent subroutine from being filtered out when
19-
! compiling for the device.
20-
!$omp declare target
21-
end subroutine omp_target_simple
9+
!AMDGCN: module attributes {
10+
!AMDGCN-SAME: fir.target_cpu = "gfx908"
11+
!AMDGCN-SAME: fir.target_features = #llvm.target_features<["+16-bit-insts", "+ci-insts",
12+
!AMDGCN-SAME: "+dl-insts", "+dot1-insts", "+dot10-insts", "+dot2-insts", "+dot3-insts",
13+
!AMDGCN-SAME: "+dot4-insts", "+dot5-insts", "+dot6-insts", "+dot7-insts", "+dpp",
14+
!AMDGCN-SAME: "+gfx8-insts", "+gfx9-insts", "+gws", "+image-insts", "+mai-insts",
15+
!AMDGCN-SAME: "+s-memrealtime", "+s-memtime-inst", "+wavefrontsize64"]>
2216

17+
!NVPTX: module attributes {
18+
!NVPTX-SAME: fir.target_cpu = "sm_80"
19+
!NVPTX-SAME: fir.target_features = #llvm.target_features<["+ptx61", "+sm_80"]>
Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,19 @@
11
!REQUIRES: amdgpu-registered-target, nvptx-registered-target
2-
!RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -target-cpu gfx908 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck %s
2+
!RUN: %flang_fc1 -emit-hlfir -triple amdgcn-amd-amdhsa -target-cpu gfx908 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck --check-prefix=AMDGCN %s
33
!RUN: %flang_fc1 -emit-hlfir -triple nvptx64-nvidia-cuda -target-cpu sm_80 -fopenmp -fopenmp-is-target-device %s -o - | FileCheck --check-prefix=NVPTX %s
44

55
!===============================================================================
66
! Target_Enter Simple
77
!===============================================================================
88

9-
!CHECK: omp.target = #omp.target<target_cpu = "gfx908",
10-
!CHECK-SAME: target_features = "+16-bit-insts,+ci-insts,+dl-insts,+dot1-insts,+dot10-insts,
11-
!CHECK-SAME: +dot2-insts,+dot3-insts,+dot4-insts,+dot5-insts,+dot6-insts,+dot7-insts,+dpp,
12-
!CHECK-SAME: +gfx8-insts,+gfx9-insts,+gws,+image-insts,+mai-insts,+s-memrealtime,+s-memtime-inst,
13-
!CHECK-SAME: +wavefrontsize64">
14-
!NVPTX: omp.target = #omp.target<target_cpu = "sm_80", target_features = "+ptx61,+sm_80">
15-
!CHECK-LABEL: func.func @_QPomp_target_simple()
16-
subroutine omp_target_simple
17-
! Directive needed to prevent subroutine from being filtered out when
18-
! compiling for the device.
19-
!$omp declare target
20-
end subroutine omp_target_simple
9+
!AMDGCN: module attributes {
10+
!AMDGCN-SAME: fir.target_cpu = "gfx908"
11+
!AMDGCN-SAME: fir.target_features = #llvm.target_features<["+16-bit-insts", "+ci-insts",
12+
!AMDGCN-SAME: "+dl-insts", "+dot1-insts", "+dot10-insts", "+dot2-insts", "+dot3-insts",
13+
!AMDGCN-SAME: "+dot4-insts", "+dot5-insts", "+dot6-insts", "+dot7-insts", "+dpp",
14+
!AMDGCN-SAME: "+gfx8-insts", "+gfx9-insts", "+gws", "+image-insts", "+mai-insts",
15+
!AMDGCN-SAME: "+s-memrealtime", "+s-memtime-inst", "+wavefrontsize64"]>
2116

17+
!NVPTX: module attributes {
18+
!NVPTX-SAME: fir.target_cpu = "sm_80"
19+
!NVPTX-SAME: fir.target_features = #llvm.target_features<["+ptx61", "+sm_80"]>

mlir/include/mlir/Dialect/OpenMP/OpenMPOps.td

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,6 @@ def FlagsAttr : OpenMP_Attr<"Flags", "flags"> {
7272
let assemblyFormat = "`<` struct(params) `>`";
7373
}
7474

75-
def TargetAttr : OpenMP_Attr<"Target", "target"> {
76-
let parameters = (ins
77-
StringRefParameter<>:$target_cpu,
78-
StringRefParameter<>:$target_features
79-
);
80-
81-
let assemblyFormat = "`<` struct(params) `>`";
82-
}
83-
8475

8576
class OpenMP_Op<string mnemonic, list<Trait> traits = []> :
8677
Op<OpenMP_Dialect, mnemonic, traits>;

mlir/include/mlir/Dialect/OpenMP/OpenMPOpsInterfaces.td

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -205,34 +205,6 @@ def OffloadModuleInterface : OpInterface<"OffloadModuleInterface"> {
205205
assumeTeamsOversubscription, assumeThreadsOversubscription,
206206
assumeNoThreadState, assumeNoNestedParallelism, noGPULib, openmpDeviceVersion));
207207
}]>,
208-
InterfaceMethod<
209-
/*description=*/[{
210-
Get the Target attribute on the current module if it exists
211-
and return the attribute, if it doesn't exist it returns a nullptr.
212-
}],
213-
/*retTy=*/"mlir::omp::TargetAttr",
214-
/*methodName=*/"getTarget",
215-
(ins), [{}], [{
216-
if (Attribute flags = $_op->getAttr("omp.target"))
217-
return ::llvm::dyn_cast_or_null<mlir::omp::TargetAttr>(flags);
218-
return nullptr;
219-
}]>,
220-
InterfaceMethod<
221-
/*description=*/[{
222-
Set the attribute target on the current module with the
223-
specified string arguments - name of cpu and corresponding features.
224-
}],
225-
/*retTy=*/"void",
226-
/*methodName=*/"setTarget",
227-
(ins "llvm::StringRef":$targetCPU,
228-
"llvm::StringRef":$targetFeatures), [{}], [{
229-
if (targetCPU.empty())
230-
return;
231-
$_op->setAttr(("omp." + mlir::omp::TargetAttr::getMnemonic()).str(),
232-
mlir::omp::TargetAttr::get($_op->getContext(),
233-
targetCPU.str(),
234-
targetFeatures.str()));
235-
}]>,
236208
InterfaceMethod<
237209
/*description=*/[{
238210
Set a StringAttr on the current module containing the host IR file path. This

mlir/lib/Target/LLVMIR/Dialect/OpenMP/OpenMPToLLVMIRTranslation.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2336,6 +2336,7 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
23362336
if (!targetOpSupported(opInst))
23372337
return failure();
23382338

2339+
auto parentFn = opInst.getParentOfType<LLVM::LLVMFuncOp>();
23392340
auto targetOp = cast<omp::TargetOp>(opInst);
23402341
auto &targetRegion = targetOp.getRegion();
23412342
DataLayout dl = DataLayout(opInst.getParentOfType<ModuleOp>());
@@ -2345,6 +2346,22 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
23452346
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
23462347
auto bodyCB = [&](InsertPointTy allocaIP,
23472348
InsertPointTy codeGenIP) -> InsertPointTy {
2349+
// Forward target-cpu and target-features function attributes from the
2350+
// original function to the new outlined function.
2351+
llvm::Function *llvmParentFn =
2352+
moduleTranslation.lookupFunction(parentFn.getName());
2353+
llvm::Function *llvmOutlinedFn = codeGenIP.getBlock()->getParent();
2354+
assert(llvmParentFn && llvmOutlinedFn &&
2355+
"Both parent and outlined functions must exist at this point");
2356+
2357+
if (auto attr = llvmParentFn->getFnAttribute("target-cpu");
2358+
attr.isStringAttribute())
2359+
llvmOutlinedFn->addFnAttr(attr);
2360+
2361+
if (auto attr = llvmParentFn->getFnAttribute("target-features");
2362+
attr.isStringAttribute())
2363+
llvmOutlinedFn->addFnAttr(attr);
2364+
23482365
builder.restoreIP(codeGenIP);
23492366
unsigned argIndex = 0;
23502367
for (auto &mapOp : mapOperands) {
@@ -2363,7 +2380,7 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
23632380
};
23642381

23652382
llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
2366-
StringRef parentName = opInst.getParentOfType<LLVM::LLVMFuncOp>().getName();
2383+
StringRef parentName = parentFn.getName();
23672384

23682385
llvm::TargetRegionEntryInfo entryInfo;
23692386

mlir/test/Target/LLVMIR/omptarget-parallel-llvm.mlir

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// The aim of the test is to check the LLVM IR codegen for the device
44
// for omp target parallel construct
55

6-
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.data_layout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true, omp.is_target_device = true, omp.target = #omp.target<target_cpu = "gfx90a", target_features = "">} {
6+
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<"dlti.alloca_memory_space", 5 : ui32>>, llvm.data_layout = "e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9", llvm.target_triple = "amdgcn-amd-amdhsa", omp.is_gpu = true, omp.is_target_device = true} {
77
llvm.func @_QQmain_omp_outline_1(%arg0: !llvm.ptr) attributes {omp.declare_target = #omp.declaretarget<device_type = (host), capture_clause = (to)>} {
88
%0 = omp.map_info var_ptr(%arg0 : !llvm.ptr, i32) map_clauses(from) capture(ByRef) -> !llvm.ptr {name = "d"}
99
omp.target map_entries(%0 -> %arg2 : !llvm.ptr) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Test that the target_features and target_cpu llvm.func attributes are
2+
// forwarded to outlined target region functions.
3+
4+
// RUN: mlir-translate -mlir-to-llvmir %s | FileCheck %s
5+
6+
module attributes {omp.is_target_device = false} {
7+
llvm.func @omp_target_region() attributes {
8+
target_cpu = "x86-64",
9+
target_features = #llvm.target_features<["+mmx", "+sse"]>
10+
} {
11+
omp.target {
12+
omp.terminator
13+
}
14+
llvm.return
15+
}
16+
}
17+
18+
// CHECK: define void @omp_target_region() #[[ATTRS:.*]] {
19+
// CHECK: define internal void @__omp_offloading_{{.*}}_omp_target_region_{{.*}}() #[[ATTRS]] {
20+
21+
// CHECK: attributes #[[ATTRS]] = {
22+
// CHECK-SAME: "target-cpu"="x86-64"
23+
// CHECK-SAME: "target-features"="+mmx,+sse"

0 commit comments

Comments
 (0)