Skip to content

Commit c14fd58

Browse files
skatrakagozillon
authored andcommitted
[Flang][MLIR][OpenMP] Use function-attached target attributes for OpenMP lowering (llvm#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 3636023 commit c14fd58

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
@@ -2616,6 +2616,7 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
26162616
llvm::OpenMPIRBuilder *ompBuilder = moduleTranslation.getOpenMPBuilder();
26172617
bool isTargetDevice = ompBuilder->Config.isTargetDevice();
26182618
bool isGPU = ompBuilder->Config.isGPU();
2619+
auto parentFn = opInst.getParentOfType<LLVM::LLVMFuncOp>();
26192620
auto targetOp = cast<omp::TargetOp>(opInst);
26202621
auto &targetRegion = targetOp.getRegion();
26212622
DataLayout dl = DataLayout(opInst.getParentOfType<ModuleOp>());
@@ -2626,6 +2627,22 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
26262627
using InsertPointTy = llvm::OpenMPIRBuilder::InsertPointTy;
26272628
auto bodyCB = [&](InsertPointTy allocaIP,
26282629
InsertPointTy codeGenIP) -> InsertPointTy {
2630+
// Forward target-cpu and target-features function attributes from the
2631+
// original function to the new outlined function.
2632+
llvm::Function *llvmParentFn =
2633+
moduleTranslation.lookupFunction(parentFn.getName());
2634+
llvm::Function *llvmOutlinedFn = codeGenIP.getBlock()->getParent();
2635+
assert(llvmParentFn && llvmOutlinedFn &&
2636+
"Both parent and outlined functions must exist at this point");
2637+
2638+
if (auto attr = llvmParentFn->getFnAttribute("target-cpu");
2639+
attr.isStringAttribute())
2640+
llvmOutlinedFn->addFnAttr(attr);
2641+
2642+
if (auto attr = llvmParentFn->getFnAttribute("target-features");
2643+
attr.isStringAttribute())
2644+
llvmOutlinedFn->addFnAttr(attr);
2645+
26292646
builder.restoreIP(codeGenIP);
26302647
unsigned argIndex = 0;
26312648
for (auto &mapOp : mapOperands) {
@@ -2648,7 +2665,7 @@ convertOmpTarget(Operation &opInst, llvm::IRBuilderBase &builder,
26482665
};
26492666

26502667
llvm::OpenMPIRBuilder::LocationDescription ompLoc(builder);
2651-
StringRef parentName = opInst.getParentOfType<LLVM::LLVMFuncOp>().getName();
2668+
StringRef parentName = parentFn.getName();
26522669

26532670
llvm::TargetRegionEntryInfo entryInfo;
26542671

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)