44#define GEN_PASS_DEF_CONVERTGPUOPSTONVVMOPS
45#include "mlir/Conversion/Passes.h.inc"
53static NVVM::ShflKind convertShflKind(gpu::ShuffleMode mode) {
55 case gpu::ShuffleMode::XOR:
56 return NVVM::ShflKind::bfly;
57 case gpu::ShuffleMode::UP:
58 return NVVM::ShflKind::up;
59 case gpu::ShuffleMode::DOWN:
60 return NVVM::ShflKind::down;
61 case gpu::ShuffleMode::IDX:
62 return NVVM::ShflKind::idx;
64 llvm_unreachable(
"unknown shuffle mode");
67static std::optional<NVVM::ReductionKind>
68convertToNVVMReductionKind(gpu::AllReduceOperation mode) {
70 case gpu::AllReduceOperation::ADD:
71 return NVVM::ReductionKind::ADD;
72 case gpu::AllReduceOperation::MUL:
74 case gpu::AllReduceOperation::MINSI:
75 return NVVM::ReductionKind::MIN;
76 case gpu::AllReduceOperation::MINUI:
78 case gpu::AllReduceOperation::MINNUMF:
79 return NVVM::ReductionKind::MIN;
80 case gpu::AllReduceOperation::MAXSI:
81 return NVVM::ReductionKind::MAX;
82 case gpu::AllReduceOperation::MAXUI:
84 case gpu::AllReduceOperation::MAXNUMF:
85 return NVVM::ReductionKind::MAX;
86 case gpu::AllReduceOperation::AND:
87 return NVVM::ReductionKind::AND;
88 case gpu::AllReduceOperation::OR:
89 return NVVM::ReductionKind::OR;
90 case gpu::AllReduceOperation::XOR:
91 return NVVM::ReductionKind::XOR;
92 case gpu::AllReduceOperation::MINIMUMF:
93 case gpu::AllReduceOperation::MAXIMUMF:
94 case gpu::AllReduceOperation::MINIMUMNUMF:
95 case gpu::AllReduceOperation::MAXIMUMNUMF:
101static constexpr llvm::StringLiteral kNVVMNamedBarrierIdPrefix =
102 "__named_barrier_id";
103static constexpr int32_t kNVVMFirstNamedBarrierId = 1;
104static constexpr int32_t kNVVMLastNamedBarrierId = 15;
105static constexpr int32_t kNVVMWarpSize = 32;
107static FailureOr<StringAttr>
108createNVVMNamedBarrierIdGlobal(gpu::InitializeNamedBarrierOp op,
109 ConversionPatternRewriter &rewriter) {
110 auto funcOp = op->getParentOfType<FunctionOpInterface>();
112 op.emitOpError(
"must be inside a function-like op");
116 if (!symbolTableOp) {
118 "enclosing function-like op must have a symbol-table parent");
122 int32_t numNamedBarriers = 0;
125 if (globalOp.getSymName().starts_with(kNVVMNamedBarrierIdPrefix))
128 int32_t barrierId = kNVVMFirstNamedBarrierId + numNamedBarriers;
129 if (barrierId > kNVVMLastNamedBarrierId) {
130 op.emitOpError(
"NVVM supports at most 15 named barriers per CTA");
134 OpBuilder detachedBuilder(rewriter.getContext());
135 Type i32 = rewriter.getI32Type();
136 auto globalOp = LLVM::GlobalOp::create(
137 detachedBuilder, op.getLoc(), i32,
true,
138 LLVM::Linkage::Internal, kNVVMNamedBarrierIdPrefix,
139 rewriter.getI32IntegerAttr(barrierId), 0,
146struct GPUSubgroupReduceOpLowering
148 using ConvertOpToLLVMPattern<gpu::SubgroupReduceOp>::ConvertOpToLLVMPattern;
151 matchAndRewrite(gpu::SubgroupReduceOp op, OpAdaptor adaptor,
152 ConversionPatternRewriter &rewriter)
const override {
153 if (op.getClusterSize())
154 return rewriter.notifyMatchFailure(
155 op,
"lowering for clustered reduce not implemented");
157 if (!op.getUniform())
158 return rewriter.notifyMatchFailure(
159 op,
"cannot be lowered to redux as the op must be run "
160 "uniformly (entire subgroup).");
161 if (!op.getValue().getType().isInteger(32))
162 return rewriter.notifyMatchFailure(op,
"unsupported data type");
164 std::optional<NVVM::ReductionKind> mode =
165 convertToNVVMReductionKind(op.getOp());
166 if (!mode.has_value())
167 return rewriter.notifyMatchFailure(
168 op,
"unsupported reduction mode for redux");
170 Location loc = op->getLoc();
171 auto int32Type = IntegerType::get(rewriter.getContext(), 32);
172 Value offset = LLVM::ConstantOp::create(rewriter, loc, int32Type, -1);
174 auto reduxOp = NVVM::ReduxOp::create(rewriter, loc, int32Type,
175 op.getValue(), mode.value(), offset);
177 rewriter.replaceOp(op, reduxOp->getResult(0));
183 using ConvertOpToLLVMPattern<gpu::ShuffleOp>::ConvertOpToLLVMPattern;
204 matchAndRewrite(gpu::ShuffleOp op, OpAdaptor adaptor,
205 ConversionPatternRewriter &rewriter)
const override {
206 Location loc = op->getLoc();
208 auto valueTy = adaptor.getValue().getType();
209 auto int32Type = IntegerType::get(rewriter.getContext(), 32);
210 auto predTy = IntegerType::get(rewriter.getContext(), 1);
212 Value one = LLVM::ConstantOp::create(rewriter, loc, int32Type, 1);
213 Value minusOne = LLVM::ConstantOp::create(rewriter, loc, int32Type, -1);
214 Value thirtyTwo = LLVM::ConstantOp::create(rewriter, loc, int32Type, 32);
215 Value numLeadInactiveLane = LLVM::SubOp::create(
216 rewriter, loc, int32Type, thirtyTwo, adaptor.getWidth());
218 Value activeMask = LLVM::LShrOp::create(rewriter, loc, int32Type, minusOne,
219 numLeadInactiveLane);
221 if (op.getMode() == gpu::ShuffleMode::UP) {
223 maskAndClamp = numLeadInactiveLane;
226 maskAndClamp = LLVM::SubOp::create(rewriter, loc, int32Type,
227 adaptor.getWidth(), one);
230 bool predIsUsed = !op->getResult(1).use_empty();
231 UnitAttr returnValueAndIsValidAttr =
nullptr;
232 Type resultTy = valueTy;
234 returnValueAndIsValidAttr = rewriter.getUnitAttr();
235 resultTy = LLVM::LLVMStructType::getLiteral(rewriter.getContext(),
238 Value shfl = NVVM::ShflOp::create(
239 rewriter, loc, resultTy, activeMask, adaptor.getValue(),
240 adaptor.getOffset(), maskAndClamp, convertShflKind(op.getMode()),
241 returnValueAndIsValidAttr);
243 Value shflValue = LLVM::ExtractValueOp::create(rewriter, loc, shfl, 0);
244 Value isActiveSrcLane =
245 LLVM::ExtractValueOp::create(rewriter, loc, shfl, 1);
246 rewriter.replaceOp(op, {shflValue, isActiveSrcLane});
248 rewriter.replaceOp(op, {shfl,
nullptr});
255 using ConvertOpToLLVMPattern<gpu::LaneIdOp>::ConvertOpToLLVMPattern;
258 matchAndRewrite(gpu::LaneIdOp op, gpu::LaneIdOp::Adaptor adaptor,
259 ConversionPatternRewriter &rewriter)
const override {
260 auto loc = op->getLoc();
261 MLIRContext *context = rewriter.getContext();
262 LLVM::ConstantRangeAttr bounds =
nullptr;
263 if (std::optional<APInt> upperBound = op.getUpperBound())
264 bounds = rewriter.getAttr<LLVM::ConstantRangeAttr>(
265 32, 0, upperBound->getZExtValue());
267 bounds = rewriter.getAttr<LLVM::ConstantRangeAttr>(
270 NVVM::LaneIdOp::create(rewriter, loc, rewriter.getI32Type(), bounds);
273 const unsigned indexBitwidth = getTypeConverter()->getIndexTypeBitwidth();
274 if (indexBitwidth > 32) {
275 newOp = LLVM::SExtOp::create(
276 rewriter, loc, IntegerType::get(context, indexBitwidth), newOp);
277 }
else if (indexBitwidth < 32) {
278 newOp = LLVM::TruncOp::create(
279 rewriter, loc, IntegerType::get(context, indexBitwidth), newOp);
281 rewriter.replaceOp(op, {newOp});
287 using ConvertOpToLLVMPattern<gpu::BallotOp>::ConvertOpToLLVMPattern;
290 matchAndRewrite(gpu::BallotOp op, gpu::BallotOp::Adaptor adaptor,
291 ConversionPatternRewriter &rewriter)
const override {
292 Location loc = op->getLoc();
293 auto int32Type = IntegerType::get(rewriter.getContext(), 32);
294 auto intType = cast<IntegerType>(op.getType());
295 unsigned width = intType.getWidth();
299 if (width != 32 && width != 64)
300 return rewriter.notifyMatchFailure(
301 op,
"nvvm.vote.sync ballot only supports i32 and i64 result types");
304 Value mask = LLVM::ConstantOp::create(rewriter, loc, int32Type,
305 rewriter.getI32IntegerAttr(-1));
307 auto voteKind = NVVM::VoteSyncKindAttr::get(rewriter.getContext(),
308 NVVM::VoteSyncKind::ballot);
309 Value
result = NVVM::VoteSyncOp::create(rewriter, loc, int32Type, mask,
310 adaptor.getPredicate(), voteKind);
313 result = LLVM::ZExtOp::create(rewriter, loc, op.getType(),
result);
315 rewriter.replaceOp(op,
result);
321struct AssertOpToAssertfailLowering
323 using ConvertOpToLLVMPattern<cf::AssertOp>::ConvertOpToLLVMPattern;
326 matchAndRewrite(cf::AssertOp assertOp, cf::AssertOpAdaptor adaptor,
327 ConversionPatternRewriter &rewriter)
const override {
328 MLIRContext *ctx = rewriter.getContext();
329 Location loc = assertOp.getLoc();
330 Type i8Type = typeConverter->convertType(rewriter.getIntegerType(8));
331 Type i32Type = typeConverter->convertType(rewriter.getIntegerType(32));
332 Type i64Type = typeConverter->convertType(rewriter.getIntegerType(64));
333 Type ptrType = LLVM::LLVMPointerType::get(ctx);
334 Type voidType = LLVM::LLVMVoidType::get(ctx);
337 auto moduleOp = assertOp->getParentOfType<gpu::GPUModuleOp>();
338 auto assertfailType = LLVM::LLVMFunctionType::get(
339 voidType, {ptrType, ptrType, i32Type, ptrType, i64Type});
341 moduleOp, loc, rewriter,
"__assertfail", assertfailType);
342 assertfailDecl.setPassthroughAttr(
343 ArrayAttr::get(ctx, StringAttr::get(ctx,
"noreturn")));
354 Block *beforeBlock = assertOp->getBlock();
356 rewriter.splitBlock(beforeBlock, assertOp->getIterator());
358 rewriter.splitBlock(assertBlock, ++assertOp->getIterator());
359 rewriter.setInsertionPointToEnd(beforeBlock);
360 cf::CondBranchOp::create(rewriter, loc, adaptor.getArg(), afterBlock,
362 rewriter.setInsertionPointToEnd(assertBlock);
363 cf::BranchOp::create(rewriter, loc, afterBlock);
366 rewriter.setInsertionPoint(assertOp);
370 StringRef fileName =
"(unknown)";
371 StringRef funcName =
"(unknown)";
372 int32_t fileLine = 0;
373 while (
auto callSiteLoc = dyn_cast<CallSiteLoc>(loc))
374 loc = callSiteLoc.getCallee();
375 if (
auto fileLineColLoc = dyn_cast<FileLineColRange>(loc)) {
376 fileName = fileLineColLoc.getFilename().strref();
377 fileLine = fileLineColLoc.getStartLine();
378 }
else if (
auto nameLoc = dyn_cast<NameLoc>(loc)) {
379 funcName = nameLoc.getName().strref();
380 if (
auto fileLineColLoc =
381 dyn_cast<FileLineColRange>(nameLoc.getChildLoc())) {
382 fileName = fileLineColLoc.getFilename().strref();
383 fileLine = fileLineColLoc.getStartLine();
388 auto getGlobal = [&](LLVM::GlobalOp global) {
390 Value globalPtr = LLVM::AddressOfOp::create(
391 rewriter, loc, LLVM::LLVMPointerType::get(ctx, global.getAddrSpace()),
392 global.getSymNameAttr());
394 LLVM::GEPOp::create(rewriter, loc, ptrType, global.getGlobalType(),
395 globalPtr, ArrayRef<LLVM::GEPArg>{0, 0});
399 rewriter, loc, moduleOp, i8Type,
"assert_message_", assertOp.getMsg()));
401 rewriter, loc, moduleOp, i8Type,
"assert_file_", fileName));
403 rewriter, loc, moduleOp, i8Type,
"assert_func_", funcName));
405 LLVM::ConstantOp::create(rewriter, loc, i32Type, fileLine);
406 Value c1 = LLVM::ConstantOp::create(rewriter, loc, i64Type, 1);
409 SmallVector<Value> arguments{assertMessage, assertFile, assertLine,
411 rewriter.replaceOpWithNewOp<LLVM::CallOp>(assertOp, assertfailDecl,
417struct GPUBarrierOpToNVVMLowering final
422 matchAndRewrite(gpu::BarrierOp op, gpu::BarrierOp::Adaptor adaptor,
423 ConversionPatternRewriter &rewriter)
const override {
424 if (Value namedBarrier = adaptor.getNamedBarrier()) {
425 Location loc = op.getLoc();
427 LLVM::ExtractValueOp::create(rewriter, loc, namedBarrier, 0);
428 Value numberOfThreads =
429 LLVM::ExtractValueOp::create(rewriter, loc, namedBarrier, 1);
430 NVVM::BarrierOp::create(rewriter, loc, barrierId, numberOfThreads);
431 rewriter.eraseOp(op);
435 gpu::BarrierScope scope = op.getScope();
437 case gpu::BarrierScope::Workgroup:
438 rewriter.replaceOpWithNewOp<NVVM::BarrierOp>(op);
440 case gpu::BarrierScope::Subgroup: {
443 LLVM::ConstantOp::create(rewriter, op.getLoc(), rewriter.getI32Type(),
444 rewriter.getI32IntegerAttr(0xFFFFFFFF));
445 rewriter.replaceOpWithNewOp<NVVM::SyncWarpOp>(op, mask);
449 return rewriter.notifyMatchFailure(
450 op,
"unsupported scope for NVVM barrier lowering");
455struct GPUInitializeNamedBarrierOpToNVVMLowering final
460 matchAndRewrite(gpu::InitializeNamedBarrierOp op,
461 gpu::InitializeNamedBarrierOp::Adaptor adaptor,
462 ConversionPatternRewriter &rewriter)
const override {
463 Location loc = op.getLoc();
464 MLIRContext *ctx = rewriter.getContext();
465 Type i32 = rewriter.getI32Type();
466 Type namedBarrierType =
467 getTypeConverter()->convertType(op.getResult().getType());
468 if (!namedBarrierType)
469 return rewriter.notifyMatchFailure(op,
"failed to convert result type");
471 FailureOr<StringAttr> maybeGlobalName =
472 createNVVMNamedBarrierIdGlobal(op, rewriter);
473 if (
failed(maybeGlobalName))
476 auto addressOf = LLVM::AddressOfOp::create(
477 rewriter, loc, LLVM::LLVMPointerType::get(ctx), *maybeGlobalName);
479 LLVM::LoadOp::create(rewriter, loc, i32, addressOf.getResult());
481 Value warpSize = LLVM::ConstantOp::create(
482 rewriter, loc, i32, rewriter.getI32IntegerAttr(kNVVMWarpSize));
483 Value numberOfThreads =
484 LLVM::MulOp::create(rewriter, loc, adaptor.getMemberCount(), warpSize);
487 LLVM::PoisonOp::create(rewriter, loc, namedBarrierType);
490 namedBarrier = LLVM::InsertValueOp::create(rewriter, loc, namedBarrier,
491 barrierId, barrierIdPos);
492 namedBarrier = LLVM::InsertValueOp::create(
493 rewriter, loc, namedBarrier, numberOfThreads, numberOfThreadsPos);
494 rewriter.replaceOp(op, namedBarrier);
504struct LowerGpuOpsToNVVMOpsPass final
508 void getDependentDialects(DialectRegistry ®istry)
const override {
509 Base::getDependentDialects(registry);
513 void runOnOperation()
override {
514 gpu::GPUModuleOp m = getOperation();
520 for (
auto func : m.getOps<func::FuncOp>()) {
521 if (func.isPrivate())
523 func->setDiscardableAttr(LLVM::LLVMDialect::getEmitCWrapperAttrName(),
530 DataLayout(cast<DataLayoutOpInterface>(m.getOperation())));
532 options.overrideIndexBitwidth(indexBitwidth);
533 options.useBarePtrCallConv = useBarePtrCallConv;
539 RewritePatternSet patterns(m.getContext());
543 vector::populateVectorFromElementsUnrollPatterns(patterns);
545 return signalPassFailure();
548 LLVMTypeConverter converter(m.getContext(),
options);
550 RewritePatternSet llvmPatterns(m.getContext());
557 llvm::SmallDenseSet<StringRef> allowedDialectsSet(allowedDialects.begin(),
558 allowedDialects.end());
559 for (Dialect *dialect :
getContext().getLoadedDialects()) {
561 if (isa<math::MathDialect>(dialect))
564 bool allowed = allowedDialectsSet.contains(dialect->getNamespace());
566 if (!allowedDialectsSet.empty() && !allowed)
569 auto *iface = dyn_cast<ConvertToLLVMPatternInterface>(dialect);
575 <<
"dialect does not implement ConvertToLLVMPatternInterface: "
576 << dialect->getNamespace();
577 return signalPassFailure();
582 iface->populateConvertToLLVMConversionPatterns(
target, converter,
590 ConversionConfig config;
591 config.allowPatternRollback = allowPatternRollback;
593 applyPartialConversion(m,
target, std::move(llvmPatterns), config)))
601 target.addIllegalOp<func::FuncOp>();
602 target.addIllegalOp<cf::AssertOp>();
603 target.addLegalDialect<::mlir::LLVM::LLVMDialect>();
604 target.addLegalDialect<::mlir::NVVM::NVVMDialect>();
605 target.addIllegalDialect<gpu::GPUDialect>();
606 target.addIllegalOp<LLVM::CopySignOp, LLVM::CosOp, LLVM::ExpOp, LLVM::Exp2Op,
607 LLVM::FAbsOp, LLVM::FCeilOp, LLVM::FFloorOp, LLVM::FRemOp,
608 LLVM::LogOp, LLVM::Log10Op, LLVM::Log2Op, LLVM::PowOp,
609 LLVM::RoundEvenOp, LLVM::RoundOp, LLVM::SinOp,
610 LLVM::SincosOp, LLVM::SqrtOp>();
613 target.addLegalOp<gpu::YieldOp, gpu::GPUModuleOp>();
620 Type i32 = IntegerType::get(type.getContext(), 32);
621 return LLVM::LLVMStructType::getLiteral(type.getContext(), {i32, i32});
633 patterns.
add<GPUSubgroupReduceOpLowering>(converter, benefit);
642 patterns.
add<GPUBarrierOpToNVVMLowering,
643 GPUInitializeNamedBarrierOpToNVVMLowering,
648 NVVM::ThreadIdYOp, NVVM::ThreadIdZOp>>(
649 converter, IndexKind::Block, IntrType::Id, benefit);
652 NVVM::BlockDimYOp, NVVM::BlockDimZOp>>(
653 converter, IndexKind::Block, IntrType::Dim, benefit);
656 NVVM::ClusterIdYOp, NVVM::ClusterIdZOp>>(
657 converter, IndexKind::Other, IntrType::Id, benefit);
659 gpu::ClusterDimOp, NVVM::ClusterDimXOp, NVVM::ClusterDimYOp,
660 NVVM::ClusterDimZOp>>(converter, IndexKind::Other, IntrType::Dim,
663 gpu::ClusterBlockIdOp, NVVM::BlockInClusterIdXOp,
664 NVVM::BlockInClusterIdYOp, NVVM::BlockInClusterIdZOp>>(
665 converter, IndexKind::Cluster, IntrType::Id, benefit);
667 gpu::ClusterDimBlocksOp, NVVM::ClusterDimBlocksXOp,
668 NVVM::ClusterDimBlocksYOp, NVVM::ClusterDimBlocksZOp>>(
669 converter, IndexKind::Cluster, IntrType::Dim, benefit);
671 gpu::BlockIdOp, NVVM::BlockIdXOp, NVVM::BlockIdYOp, NVVM::BlockIdZOp>>(
672 converter, IndexKind::Grid, IntrType::Id, benefit);
674 gpu::GridDimOp, NVVM::GridDimXOp, NVVM::GridDimYOp, NVVM::GridDimZOp>>(
675 converter, IndexKind::Grid, IntrType::Dim, benefit);
676 patterns.
add<GPULaneIdOpToNVVM, GPUBallotOpToNVVM, GPUShuffleOpLowering,
690 static_cast<unsigned>(NVVM::NVVMMemorySpace::Shared),
692 NVVM::NVVMDialect::getKernelFuncAttrName()),
694 NVVM::NVVMDialect::getMaxntidAttrName()),
696 NVVM::NVVMDialect::getClusterDimAttrName())},
707struct NVVMTargetConvertToLLVMAttrInterface
708 :
public ConvertToLLVMAttrInterface::ExternalModel<
709 NVVMTargetConvertToLLVMAttrInterface, NVVM::NVVMTargetAttr> {
711 void populateConvertToLLVMConversionPatterns(
717void NVVMTargetConvertToLLVMAttrInterface::
718 populateConvertToLLVMConversionPatterns(
Attribute attr,
729 NVVMTargetAttr::attachInterface<NVVMTargetConvertToLLVMAttrInterface>(*ctx);
static llvm::ManagedStatic< PassManagerOptions > options
Attributes are known-constant values of operations.
auto getOps()
Return an iterator range over the operations within this block that are of 'OpT'.
Utility class for operation conversions targeting the LLVM dialect that match exactly one source oper...
ConvertOpToLLVMPattern(const LLVMTypeConverter &typeConverter, PatternBenefit benefit=1)
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
bool addExtension(TypeID extensionID, std::unique_ptr< DialectExtensionBase > extension)
Add the given extension to the registry.
Conversion from types to the LLVM IR dialect.
MLIRContext & getContext() const
Returns the MLIR context.
MLIRContext is the top-level object for a collection of MLIR operations.
This class helps build Operations.
A trait used to provide symbol table functionalities to a region operation.
Operation is the basic unit of execution within MLIR.
Region & getRegion(unsigned index)
Returns the region held by this operation at position 'index'.
Operation * getParentWithTrait()
Returns the closest surrounding parent operation with trait Trait.
This class represents the benefit of a pattern match in a unitless scheme that ranges from 0 (very li...
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
This class allows for representing and managing the symbol table used by operations with the 'SymbolT...
StringAttr insert(Operation *symbol, Block::iterator insertPt={})
Insert a new symbol into the table, and rename it as necessary to avoid collisions.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
MMAMatrix represents a matrix held by a subgroup for matrix-matrix multiply accumulate operations.
constexpr int kSharedMemoryAlignmentBit
void registerConvertGpuToNVVMInterface(DialectRegistry ®istry)
Registers the ConvertToLLVMAttrInterface interface on the NVVM::NVVMTargetAttr attribute.
gpu::DimensionKind IndexKind
void populateCommonGPUTypeAndAttributeConversions(TypeConverter &typeConverter)
Remap common GPU memory spaces (Workgroup, Private, etc) to LLVM address spaces.
Include the generated interface declarations.
detail::DenseArrayAttrImpl< int64_t > DenseI64ArrayAttr
static constexpr unsigned kDeriveIndexBitwidthFromDataLayout
Value to pass as bitwidth for the index type when the converter is expected to derive the bitwidth fr...
LogicalResult applyPatternsGreedily(Region ®ion, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
void populateGpuRewritePatterns(RewritePatternSet &patterns)
Collect all patterns to rewrite ops within the GPU dialect.
Type convertMMAToLLVMType(gpu::MMAMatrixType type)
Return the LLVMStructureType corresponding to the MMAMatrixType type.
LLVM::LLVMFuncOp getOrDefineFunction(Operation *moduleOp, Location loc, OpBuilder &b, StringRef name, LLVM::LLVMFunctionType type)
Note that these functions don't take a SymbolTable because GPU module lowerings can have name collisi...
void configureGpuToNVVMTypeConverter(LLVMTypeConverter &converter)
Configure the LLVM type convert to convert types and address spaces from the GPU dialect to NVVM.
void configureGpuToNVVMConversionLegality(ConversionTarget &target)
Configure target to convert from the GPU dialect to NVVM.
void registerConvertToLLVMDependentDialectLoading(DialectRegistry ®istry)
Register the extension that will load dependent dialects for LLVM conversion.
void populateGpuSubgroupReduceOpLoweringPattern(const LLVMTypeConverter &converter, RewritePatternSet &patterns, PatternBenefit benefit=1)
Populate GpuSubgroupReduce pattern to NVVM.
void populateGpuToNVVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, PatternBenefit benefit=1)
Collect a set of patterns to convert from the GPU dialect to NVVM.
LLVM::GlobalOp getOrCreateStringConstant(OpBuilder &b, Location loc, Operation *moduleOp, Type llvmI8, StringRef namePrefix, StringRef str, uint64_t alignment=0, unsigned addrSpace=0)
Create a global that contains the given string.
void populateLibDeviceConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, PatternBenefit benefit=1)
Populate the given list with patterns that convert from Math to NVVM libdevice calls.
void populateGpuWMMAToNVVMConversionPatterns(const LLVMTypeConverter &converter, RewritePatternSet &patterns, PatternBenefit benefit=1)
Collect a set of patterns to convert WMMA ops from GPU dialect to NVVM.
Lowering for gpu.dynamic.shared.memory to LLVM dialect.
Lowering of gpu.printf to a vprintf standard library.