Skip to content

Commit cd0c557

Browse files
committed
[Flang][MLIR][OpenMP] Use function-attached target attributes for OpenMP lowering
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 c105848 commit cd0c557

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)