39#include "llvm/Support/Debug.h"
43#define GEN_PASS_DEF_ACCBINDROUTINE
44#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
48#define DEBUG_TYPE "acc-bind-routine"
55static RoutineOp getFirstAccRoutineOp(FunctionOpInterface funcOp,
58 auto attr = funcOp->getAttrOfType<SpecializedRoutineAttr>(
60 return symTab.
lookup<RoutineOp>(attr.getRoutine().getLeafReference());
64 assert(routineInfo &&
"expected acc.routine_info for acc routine function");
65 auto accRoutines = routineInfo.getAccRoutines();
66 assert(!accRoutines.empty() &&
"expected at least one acc routine");
67 return symTab.
lookup<RoutineOp>(accRoutines[0].getLeafReference());
70static bool isACCRoutineBindDefaultOrDeviceType(RoutineOp op,
71 DeviceType deviceType) {
72 if (!op.getBindIdName() && !op.getBindStrName())
74 return op.getBindNameValue().has_value() ||
75 op.getBindNameValue(deviceType).has_value();
78class ACCBindRoutine :
public acc::impl::ACCBindRoutineBase<ACCBindRoutine> {
80 using acc::impl::ACCBindRoutineBase<ACCBindRoutine>::ACCBindRoutineBase;
82 void runOnOperation()
override {
83 FunctionOpInterface
func = getOperation();
84 ModuleOp module =
func->getParentOfType<ModuleOp>();
89 getCachedParentAnalysis<OpenACCSupport>(
func->getParentOp());
91 cachedAnalysis ? cachedAnalysis->get() : getAnalysis<OpenACCSupport>();
96 func.walk([&](CallOpInterface callOp) {
97 if (!callOp.getCallableForCallee())
99 if (!callOp->getParentOfType<OffloadRegionOpInterface>() &&
100 !callOp->getParentOfType<gpu::GPUFuncOp>())
102 SymbolRefAttr calleeSymbolRef =
103 dyn_cast<SymbolRefAttr>(callOp.getCallableForCallee());
104 if (!calleeSymbolRef)
106 FunctionOpInterface callee = symTab.
lookup<FunctionOpInterface>(
107 calleeSymbolRef.getLeafReference());
114 if (
auto routineInfo = callee->getAttrOfType<RoutineInfoAttr>(
116 if (routineInfo.getAccRoutines().size() > 1) {
117 (
void)accSupport.
emitNYI(callOp.getLoc(),
"multiple `acc routine`s");
123 RoutineOp routine = getFirstAccRoutineOp(callee, symTab);
124 if (!isACCRoutineBindDefaultOrDeviceType(routine, this->deviceType))
127 auto bindNameOpt = routine.getBindNameValue(this->deviceType);
129 bindNameOpt = routine.getBindNameValue();
132 SymbolRefAttr calleeRef;
133 if (
auto *symRef = std::get_if<SymbolRefAttr>(&*bindNameOpt)) {
136 StringRef bindName = std::get<StringAttr>(*bindNameOpt).getValue();
137 auto gpuMod =
func->getParentOfType<gpu::GPUModuleOp>();
139 gpuMod ? gpuMod.getOperation() :
module.getOperation();
141 if (!insertSymTab.
lookup(bindName)) {
143 Block *insertBlock = gpuMod ? gpuMod.getBody() :
module.getBody();
145 auto funcType = cast<FunctionType>(callee.getFunctionType());
146 func::FuncOp bindFunc = func::FuncOp::create(builder, callee.getLoc(),
148 bindFunc.setPrivate();
149 insertSymTab.
insert(bindFunc);
153 callOp.setCalleeFromCallable(calleeRef);
Block represents an ordered list of Operations.
static FlatSymbolRefAttr get(StringAttr value)
Construct a symbol reference for the given value name.
This class helps build Operations.
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
Operation is the basic unit of execution within MLIR.
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.
bool isAccRoutine(mlir::Operation *op)
Used to check whether the current operation is marked with acc routine.
static constexpr StringLiteral getSpecializedRoutineAttrName()
bool isSpecializedAccRoutine(mlir::Operation *op)
Used to check whether this is a specialized accelerator version of acc routine function.
static constexpr StringLiteral getRoutineInfoAttrName()
Include the generated interface declarations.