24#include "llvm/Support/FormatVariadic.h"
30#define GEN_PASS_DEF_SPIRVCOMPOSITETYPELAYOUTPASS
31#include "mlir/Dialect/SPIRV/Transforms/Passes.h.inc"
36class SPIRVGlobalVariableOpLayoutInfoDecoration
41 LogicalResult matchAndRewrite(spirv::GlobalVariableOp op,
42 PatternRewriter &rewriter)
const override {
43 NamedAttrList globalVarAttrs(op->getDiscardableAttrDictionary());
44 op->getName().populateInherentAttrs(op, globalVarAttrs);
46 auto ptrType = cast<spirv::PointerType>(op.getType());
47 auto pointeeType = cast<spirv::StructType>(ptrType.getPointeeType());
51 return op->emitError(llvm::formatv(
52 "failed to decorate (unsuported pointee type: '{0}')", pointeeType));
58 globalVarAttrs.
erase(
"type");
61 op, TypeAttr::get(decoratedType), globalVarAttrs);
66class SPIRVAddressOfOpLayoutInfoDecoration
71 LogicalResult matchAndRewrite(spirv::AddressOfOp op,
72 PatternRewriter &rewriter)
const override {
73 auto spirvModule = op->getParentOfType<spirv::ModuleOp>();
74 auto varName = op.getVariableAttr();
75 auto varOp = spirvModule.lookupSymbol<spirv::GlobalVariableOp>(varName);
78 op, varOp.getType(), SymbolRefAttr::get(varName.getAttr()));
83template <
typename OpT>
84class SPIRVPassThroughConversion :
public OpConversionPattern<OpT> {
86 using OpConversionPattern<OpT>::OpConversionPattern;
89 matchAndRewrite(OpT op,
typename OpT::Adaptor adaptor,
90 ConversionPatternRewriter &rewriter)
const override {
91 rewriter.modifyOpInPlace(op,
92 [&] { op->setOperands(adaptor.getOperands()); });
99 patterns.
add<SPIRVGlobalVariableOpLayoutInfoDecoration,
100 SPIRVAddressOfOpLayoutInfoDecoration,
101 SPIRVPassThroughConversion<spirv::AccessChainOp>,
102 SPIRVPassThroughConversion<spirv::LoadOp>,
103 SPIRVPassThroughConversion<spirv::StoreOp>>(
108class DecorateSPIRVCompositeTypeLayoutPass
110 DecorateSPIRVCompositeTypeLayoutPass> {
115void DecorateSPIRVCompositeTypeLayoutPass::runOnOperation() {
116 auto module = getOperation();
120 target.addLegalDialect<spirv::SPIRVDialect>();
121 target.addLegalOp<func::FuncOp>();
122 target.addDynamicallyLegalOp<spirv::GlobalVariableOp>(
123 [](spirv::GlobalVariableOp op) {
128 target.addDynamicallyLegalOp<spirv::AddressOfOp>([](spirv::AddressOfOp op) {
133 target.addDynamicallyLegalOp<spirv::AccessChainOp, spirv::LoadOp,
135 for (
Value operand : op->getOperands()) {
136 auto addrOp = operand.getDefiningOp<spirv::AddressOfOp>();
145 for (
auto spirvModule : module.getOps<spirv::ModuleOp>())
146 if (failed(applyFullConversion(spirvModule,
target, frozenPatterns)))
static void populateSPIRVLayoutInfoPatterns(RewritePatternSet &patterns)
This class represents a frozen set of patterns that can be processed by a pattern applicator.
Attribute erase(StringAttr name)
Erase the attribute with the given name from the list.
Operation is the basic unit of execution within MLIR.
virtual void runOnOperation()=0
The polymorphic API that runs the pass over the currently held operation.
void signalPassFailure()
Signal that some invariant was broken when running.
MLIRContext * getContext() const
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replace the results of the given (original) op with a new op that is created without verification (re...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
static bool isLegalType(Type type)
Checks whether a type is legal in terms of Vulkan layout info decoration.
static spirv::StructType decorateType(spirv::StructType structType)
Returns a new StructType with layout decoration.
static PointerType get(Type pointeeType, StorageClass storageClass)
Include the generated interface declarations.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...