Skip to content

Commit 54e52e8

Browse files
committed
[Flang][OpenMP] Add frontend support for -fopenmp-targets
This patch adds support for the `-fopenmp-targets` option to the `bbc` and `flang -fc1` tools. It adds an `OMPTargetTriples` property to the `LangOptions` structure, which is filled with the triples represented by the compiler option. This is used to initialize the `omp.target_triples` module attribute for later use by lowering stages.
1 parent 3dbb225 commit 54e52e8

File tree

5 files changed

+74
-4
lines changed

5 files changed

+74
-4
lines changed

flang/include/flang/Frontend/LangOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#define FORTRAN_FRONTEND_LANGOPTIONS_H
1717

1818
#include <string>
19+
#include <vector>
20+
21+
#include "llvm/TargetParser/Triple.h"
1922

2023
namespace Fortran::frontend {
2124

@@ -58,6 +61,9 @@ class LangOptions : public LangOptionsBase {
5861
/// host code generation.
5962
std::string OMPHostIRFile;
6063

64+
/// List of triples passed in using -fopenmp-targets.
65+
std::vector<llvm::Triple> OMPTargetTriples;
66+
6167
LangOptions();
6268
};
6369

flang/include/flang/Tools/CrossToolHelpers.h

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,15 +131,19 @@ struct OffloadModuleOpts {
131131
bool OpenMPThreadSubscription, bool OpenMPNoThreadState,
132132
bool OpenMPNoNestedParallelism, bool OpenMPIsTargetDevice,
133133
bool OpenMPIsGPU, bool OpenMPForceUSM, uint32_t OpenMPVersion,
134-
std::string OMPHostIRFile = {}, bool NoGPULib = false)
134+
std::string OMPHostIRFile = {},
135+
const std::vector<llvm::Triple> &OMPTargetTriples = {},
136+
bool NoGPULib = false)
135137
: OpenMPTargetDebug(OpenMPTargetDebug),
136138
OpenMPTeamSubscription(OpenMPTeamSubscription),
137139
OpenMPThreadSubscription(OpenMPThreadSubscription),
138140
OpenMPNoThreadState(OpenMPNoThreadState),
139141
OpenMPNoNestedParallelism(OpenMPNoNestedParallelism),
140142
OpenMPIsTargetDevice(OpenMPIsTargetDevice), OpenMPIsGPU(OpenMPIsGPU),
141143
OpenMPForceUSM(OpenMPForceUSM), OpenMPVersion(OpenMPVersion),
142-
OMPHostIRFile(OMPHostIRFile), NoGPULib(NoGPULib) {}
144+
OMPHostIRFile(OMPHostIRFile),
145+
OMPTargetTriples(OMPTargetTriples.begin(), OMPTargetTriples.end()),
146+
NoGPULib(NoGPULib) {}
143147

144148
OffloadModuleOpts(Fortran::frontend::LangOptions &Opts)
145149
: OpenMPTargetDebug(Opts.OpenMPTargetDebug),
@@ -150,7 +154,7 @@ struct OffloadModuleOpts {
150154
OpenMPIsTargetDevice(Opts.OpenMPIsTargetDevice),
151155
OpenMPIsGPU(Opts.OpenMPIsGPU), OpenMPForceUSM(Opts.OpenMPForceUSM),
152156
OpenMPVersion(Opts.OpenMPVersion), OMPHostIRFile(Opts.OMPHostIRFile),
153-
NoGPULib(Opts.NoGPULib) {}
157+
OMPTargetTriples(Opts.OMPTargetTriples), NoGPULib(Opts.NoGPULib) {}
154158

155159
uint32_t OpenMPTargetDebug = 0;
156160
bool OpenMPTeamSubscription = false;
@@ -162,6 +166,7 @@ struct OffloadModuleOpts {
162166
bool OpenMPForceUSM = false;
163167
uint32_t OpenMPVersion = 11;
164168
std::string OMPHostIRFile = {};
169+
std::vector<llvm::Triple> OMPTargetTriples = {};
165170
bool NoGPULib = false;
166171
};
167172

@@ -185,6 +190,9 @@ struct OffloadModuleOpts {
185190
if (!Opts.OMPHostIRFile.empty())
186191
offloadMod.setHostIRFilePath(Opts.OMPHostIRFile);
187192
}
193+
auto strTriples = llvm::to_vector(llvm::map_range(Opts.OMPTargetTriples,
194+
[](llvm::Triple triple) { return triple.normalize(); }));
195+
offloadMod.setTargetTriples(strTriples);
188196
}
189197
}
190198

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,7 @@ static bool parseDiagArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
894894
/// options accordingly. Returns false if new errors are generated.
895895
static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
896896
clang::DiagnosticsEngine &diags) {
897+
llvm::Triple t(res.getTargetOpts().triple);
897898
unsigned numErrorsBefore = diags.getNumErrors();
898899

899900
// -fdefault* family
@@ -1012,6 +1013,40 @@ static bool parseDialectArgs(CompilerInvocation &res, llvm::opt::ArgList &args,
10121013
res.getLangOpts().OpenMPIsGPU = 0;
10131014
break;
10141015
}
1016+
1017+
// Get the OpenMP target triples if any.
1018+
if (auto *arg =
1019+
args.getLastArg(clang::driver::options::OPT_fopenmp_targets_EQ)) {
1020+
enum ArchPtrSize { Arch16Bit, Arch32Bit, Arch64Bit };
1021+
auto getArchPtrSize = [](const llvm::Triple &triple) {
1022+
if (triple.isArch16Bit())
1023+
return Arch16Bit;
1024+
if (triple.isArch32Bit())
1025+
return Arch32Bit;
1026+
assert(triple.isArch64Bit() && "Expected 64-bit architecture");
1027+
return Arch64Bit;
1028+
};
1029+
1030+
for (unsigned i = 0; i < arg->getNumValues(); ++i) {
1031+
llvm::Triple tt(arg->getValue(i));
1032+
1033+
if (tt.getArch() == llvm::Triple::UnknownArch ||
1034+
!(tt.getArch() == llvm::Triple::aarch64 || tt.isPPC() ||
1035+
tt.getArch() == llvm::Triple::systemz ||
1036+
tt.getArch() == llvm::Triple::nvptx ||
1037+
tt.getArch() == llvm::Triple::nvptx64 ||
1038+
tt.getArch() == llvm::Triple::amdgcn ||
1039+
tt.getArch() == llvm::Triple::x86 ||
1040+
tt.getArch() == llvm::Triple::x86_64))
1041+
diags.Report(clang::diag::err_drv_invalid_omp_target)
1042+
<< arg->getValue(i);
1043+
else if (getArchPtrSize(t) != getArchPtrSize(tt))
1044+
diags.Report(clang::diag::err_drv_incompatible_omp_arch)
1045+
<< arg->getValue(i) << t.str();
1046+
else
1047+
res.getLangOpts().OMPTargetTriples.push_back(tt);
1048+
}
1049+
}
10151050
}
10161051

10171052
// -pedantic
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda %s -o - | FileCheck %s
2+
! RUN: bbc -emit-hlfir -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa,nvptx64-nvidia-cuda %s -o - | FileCheck %s
3+
4+
! This test checks the addition of the omp.target_triples attribute when the
5+
! -fopenmp-targets option is set
6+
7+
!CHECK: module attributes {
8+
!CHECK-SAME: omp.target_triples = ["amdgcn-amd-amdhsa", "nvptx64-nvidia-cuda"]
9+
program targets
10+
end program targets

flang/tools/bbc/bbc.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,11 @@ static llvm::cl::opt<bool> enableOpenMPForceUSM(
149149
llvm::cl::desc("force openmp unified shared memory mode"),
150150
llvm::cl::init(false));
151151

152+
static llvm::cl::list<std::string> targetTriplesOpenMP(
153+
"fopenmp-targets",
154+
llvm::cl::desc("comma-separated list of OpenMP offloading triples"),
155+
llvm::cl::CommaSeparated);
156+
152157
// A simplified subset of the OpenMP RTL Flags from Flang, only the primary
153158
// positive options are available, no negative options e.g. fopen_assume* vs
154159
// fno_open_assume*
@@ -380,11 +385,17 @@ static llvm::LogicalResult convertFortranSourceToMLIR(
380385
"-fopenmp-is-target-device is also set";
381386
return mlir::failure();
382387
}
388+
// Construct offloading target triples vector.
389+
std::vector<llvm::Triple> targetTriples;
390+
targetTriples.reserve(targetTriplesOpenMP.size());
391+
for (llvm::StringRef s : targetTriplesOpenMP)
392+
targetTriples.emplace_back(s);
393+
383394
auto offloadModuleOpts = OffloadModuleOpts(
384395
setOpenMPTargetDebug, setOpenMPTeamSubscription,
385396
setOpenMPThreadSubscription, setOpenMPNoThreadState,
386397
setOpenMPNoNestedParallelism, enableOpenMPDevice, enableOpenMPGPU,
387-
enableOpenMPForceUSM, setOpenMPVersion, "", setNoGPULib);
398+
enableOpenMPForceUSM, setOpenMPVersion, "", targetTriples, setNoGPULib);
388399
setOffloadModuleInterfaceAttributes(mlirModule, offloadModuleOpts);
389400
setOpenMPVersionAttribute(mlirModule, setOpenMPVersion);
390401
}

0 commit comments

Comments
 (0)