MLIR 24.0.0git
Utils.cpp
Go to the documentation of this file.
1//===- StackToShared.cpp -------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements various OpenMP dialect utilities.
10//
11//===----------------------------------------------------------------------===//
12
14
17
18using namespace mlir;
19
21 ModuleOp module, const OffloadModuleOpts &opts) {
22 if (auto offloadMod = llvm::dyn_cast<OffloadModuleInterface>(*module)) {
23 offloadMod.setIsTargetDevice(opts.isTargetDevice);
24 offloadMod.setIsGPU(opts.isGPU);
25 if (opts.forceUSM)
26 offloadMod.setRequires(offloadMod.getRequires() |
27 ClauseRequires::unified_shared_memory);
28 offloadMod.setFlags(opts.targetDebugKind, opts.assumeTeamsOversubscription,
32 opts.openMPDeviceVersion, opts.noGPULib);
33 if (opts.isTargetDevice && !opts.hostIRFile.empty())
34 offloadMod.setHostIRFilePath(opts.hostIRFile);
35
36 auto strTriples = llvm::to_vector(
37 llvm::map_range(opts.targetTriples, [](const llvm::Triple &triple) {
38 return triple.normalize();
39 }));
40 offloadMod.setTargetTriples(strTriples);
41 }
42}
43
44void mlir::omp::setOpenMPVersionAttribute(ModuleOp module, int64_t version) {
45 module->setAttr(
46 StringAttr::get(module.getContext(), llvm::Twine{"omp.version"}),
47 VersionAttr::get(module.getContext(), version));
48}
49
51 int64_t fallback) {
52 if (Attribute verAttr = module->getAttr("omp.version"))
53 return llvm::cast<VersionAttr>(verAttr).getVersion();
54 return fallback;
55}
56
57bool mlir::omp::isOpenMPModule(ModuleOp module) {
58 return module->hasAttr("omp.version");
59}
60
61static bool allocaUseRequiresSharedMem(const OpOperand &use) {
62 Operation *owner = use.getOwner();
63 if (auto parallelOp = dyn_cast<omp::ParallelOp>(owner)) {
64 if (llvm::is_contained(parallelOp.getReductionVars(), use.get()))
65 return true;
66 } else if (auto callOp = dyn_cast<CallOpInterface>(owner)) {
67 if (llvm::is_contained(callOp.getArgOperands(), use.get()))
68 return true;
69 }
70
71 // If it is used directly inside of a parallel region, it has to be replaced
72 // unless the use is a private clause.
73 if (owner->getParentOfType<omp::ParallelOp>()) {
74 if (auto argIface = dyn_cast<omp::BlockArgOpenMPOpInterface>(owner)) {
75 OperandRange privateVars = argIface.getPrivateVars();
76 auto it = llvm::find(privateVars, use.get());
77 if (it != privateVars.end()) {
78 auto privateSyms = owner->getAttrOfType<ArrayAttr>("private_syms");
79 size_t idx = std::distance(privateVars.begin(), it);
80 auto privateOp =
82 owner, cast<SymbolRefAttr>(privateSyms[idx]));
83 return privateOp.getDataSharingType() !=
84 omp::DataSharingClauseType::Private;
85 }
86 }
87 return true;
88 }
89 return false;
90}
91
93 for (const OpOperand &use : alloc.getUses()) {
94 Operation *owner = use.getOwner();
95 if (isa<LLVM::AddrSpaceCastOp, LLVM::GEPOp>(owner)) {
96 if (llvm::any_of(owner->getResults(), [&](Value result) {
97 return allocaUsesRequireSharedMem(result);
98 }))
99 return true;
100 } else if (allocaUseRequiresSharedMem(use)) {
101 return true;
102 }
103 }
104 return false;
105}
106
108 if (isa<omp::ParallelOp>(op))
109 return false;
110
111 auto offloadIface = op.getParentOfType<omp::OffloadModuleInterface>();
112 if (!offloadIface || !offloadIface.getIsTargetDevice())
113 return false;
114
115 auto targetOp = op.getParentOfType<omp::TargetOp>();
116
117 // It must be inside of a generic omp.target or in a target device function,
118 // and not inside of omp.parallel.
119 if (auto parallelOp = op.getParentOfType<omp::ParallelOp>()) {
120 if (!targetOp || targetOp->isProperAncestor(parallelOp))
121 return false;
122 }
123
124 // The omp.target operation itself is considered in a shared device context in
125 // order to properly process its own allocation-defining entry block
126 // arguments.
127 if (!targetOp)
128 targetOp = dyn_cast<omp::TargetOp>(op);
129
130 if (targetOp) {
131 if (targetOp.getKernelType() != omp::TargetExecMode::generic)
132 return false;
133 } else {
134 auto declTargetIface = op.getParentOfType<omp::DeclareTargetInterface>();
135 if (!declTargetIface || !declTargetIface.isDeclareTarget() ||
136 declTargetIface.getDeclareTargetDeviceType() ==
137 omp::DeclareTargetDeviceType::host)
138 return false;
139 }
140 return true;
141}
static bool allocaUseRequiresSharedMem(const OpOperand &use)
Definition Utils.cpp:61
ArrayAttr()
Attributes are known-constant values of operations.
Definition Attributes.h:25
IRValueT get() const
Return the current value being used by this operand.
This class represents an operand of an operation.
Definition Value.h:254
This class implements the operand iterators for the Operation class.
Definition ValueRange.h:44
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
AttrClass getAttrOfType(StringAttr name)
Definition Operation.h:575
OpTy getParentOfType()
Return the closest surrounding parent operation that is of type 'OpTy'.
Definition Operation.h:255
result_range getResults()
Definition Operation.h:440
static Operation * lookupNearestSymbolFrom(Operation *from, StringAttr symbol)
Returns the operation registered with the given symbol name within the closest parent operation of,...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition Value.h:96
use_range getUses() const
Returns a range of all uses, which is useful for iterating over all uses.
Definition Value.h:188
Operation * getOwner() const
Return the owner of this operand.
Definition UseDefLists.h:38
void setOffloadModuleInterfaceAttributes(ModuleOp module, const OffloadModuleOpts &opts)
Sets OpenMP offload module interface attributes on a ModuleOp, shared between Flang and Clang (CIR) f...
Definition Utils.cpp:20
bool isOpenMPModule(ModuleOp module)
Checks whether this is an OpenMP-enabled module.
Definition Utils.cpp:57
int64_t getOpenMPVersionAttribute(ModuleOp module, int64_t fallback=-1)
Returns the value of the omp.version attribute, if present, or the fallback.
Definition Utils.cpp:50
bool opInSharedDeviceContext(Operation &op)
Check whether the given operation is located in a context where an allocation to be used by multiple ...
Definition Utils.cpp:107
void setOpenMPVersionAttribute(ModuleOp module, int64_t version)
Adds or updates the omp.version attribute.
Definition Utils.cpp:44
bool allocaUsesRequireSharedMem(Value alloc)
Check whether the value representing an allocation, assumed to have been defined in a shared device c...
Definition Utils.cpp:92
Include the generated interface declarations.
Offload-specific OpenMP module attributes, associated to the OffloadModuleInterface.
Definition Utils.h:29
std::vector< llvm::Triple > targetTriples
Definition Utils.h:58