62#define GEN_PASS_DEF_ACCDECLAREGPUMODULEINSERTION
63#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
67#define DEBUG_TYPE "acc-declare-gpu-module-insertion"
72static bool hasAccDeclareGlobals(ModuleOp mod) {
73 for (
Operation &op : mod.getBody()->getOperations())
79static void makeDeviceGlobalDeclaration(
Operation &globalOp) {
85 region.dropAllReferences();
86 region.getBlocks().clear();
90class ACCDeclareGPUModuleInsertion
92 ACCDeclareGPUModuleInsertion> {
95 ACCDeclareGPUModuleInsertion>::ACCDeclareGPUModuleInsertionBase;
99 ACCDeclareGPUModuleInsertion>::getDependentDialects(registry);
103 LogicalResult copyGlobalsToGPUModule(gpu::GPUModuleOp gpuMod, ModuleOp mod,
107 for (
Operation &globalOp : mod.getBody()->getOperations()) {
111 auto symOp = dyn_cast<SymbolOpInterface>(&globalOp);
115 StringAttr name = symOp.getNameAttr();
119 auto globalVar = dyn_cast<acc::GlobalVariableOpInterface>(&globalOp);
120 bool makeUnifiedDeclaration =
122 declareAttr.getDataClause().getValue() !=
123 acc::DataClause::acc_declare_device_resident &&
124 (!globalVar || !globalVar.isConstant() ||
125 globalVar.isCompilerGenerated());
126 if (makeUnifiedDeclaration)
127 makeDeviceGlobalDeclaration(*deviceGlobal);
134 return lhs->getName() == rhs->getName() &&
141 if (!isEquivalent(existing, deviceGlobal)) {
145 if (makeUnifiedDeclaration) {
147 makeDeviceGlobalDeclaration(*normalizedExisting);
148 bool canReuse = isEquivalent(normalizedExisting, deviceGlobal);
151 makeDeviceGlobalDeclaration(*existing);
154 if (!isEquivalent(existing, deviceGlobal)) {
157 llvm::Twine(
"duplicate global symbol '") +
158 name.getValue() +
"' in gpu module");
172 gpuSymTable.
insert(deviceGlobal);
177 void runOnOperation()
override {
178 ModuleOp mod = getOperation();
182 if (!hasAccDeclareGlobals(mod))
186 std::optional<gpu::GPUModuleOp> gpuMod =
189 accSupport.
emitNYI(mod.getLoc(),
"Failed to create GPU module");
193 if (failed(copyGlobalsToGPUModule(*gpuMod, mod, accSupport)))
Attributes are known-constant values of operations.
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
Operation is the basic unit of execution within MLIR.
void setInherentAttr(StringAttr name, Attribute value)
Set an inherent attribute by name.
Attribute getDiscardableAttr(StringRef name)
Access a discardable attribute by name, returns a null Attribute if the discardable attribute does no...
Location getLoc()
The source location the operation was defined or derived from.
void destroy()
Destroys this operation and its subclass data.
MutableArrayRef< Region > getRegions()
Returns the regions held by this operation.
AttrClass getDiscardableAttrOfType(StringRef name)
Access a discardable attribute by name and cast it to AttrClass.
Operation * clone(IRMapping &mapper, const CloneOptions &options=CloneOptions::all())
Create a deep copy of this operation, remapping any operands that use values outside of the operation...
MLIRContext * getContext()
Return the context this operation is associated with.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
Operation * lookup(StringRef name) const
Look up a symbol with the specified name, returning null if no such name exists.
StringAttr insert(Operation *symbol, Block::iterator insertPt={})
Insert a new symbol into the table, and rename it as necessary to avoid collisions.
InFlightDiagnostic emitNYI(Location loc, const Twine &message)
Report a case that is not yet supported by the implementation.
std::optional< gpu::GPUModuleOp > getOrCreateGPUModule(ModuleOp mod, bool create=true, llvm::StringRef name="")
Get or optionally create a GPU module in the given module.
void registerAllExtensions(DialectRegistry ®istry)
Register the standard OpenACC models for GPU, LLVM and MemRef IR.
static constexpr StringLiteral getDeclareAttrName()
Used to obtain the attribute name for declare.
Include the generated interface declarations.
static bool isEquivalentTo(Operation *lhs, Operation *rhs, function_ref< LogicalResult(Value, Value)> checkEquivalent, function_ref< void(Value, Value)> markEquivalent=nullptr, Flags flags=Flags::None, function_ref< LogicalResult(ValueRange, ValueRange)> checkCommutativeEquivalent=nullptr)
Compare two operations (including their regions) and return if they are equivalent.
static LogicalResult ignoreValueEquivalence(Value lhs, Value rhs)
Helper that can be used with isEquivalentTo above to consider ops equivalent even if their operands a...