brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 8575487 Raw
166 lines · cpp
1//===- SPIRVOpDefinition.cpp - MLIR SPIR-V Op Definition Implementation ---===//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-exception6//7//===----------------------------------------------------------------------===//8//9// Defines the TableGen'erated SPIR-V op implementation in the SPIR-V dialect.10// These are placed in a separate file to reduce the total amount of code in11// SPIRVOps.cpp and make that file faster to recompile.12//13//===----------------------------------------------------------------------===//14 15#include "mlir/Dialect/SPIRV/IR/SPIRVOps.h"16 17#include "SPIRVParsingUtils.h"18 19#include "mlir/IR/TypeUtilities.h"20 21namespace mlir::spirv {22/// Returns true if the given op is a function-like op or nested in a23/// function-like op without a module-like op in the middle.24static bool isNestedInFunctionOpInterface(Operation *op) {25  if (!op)26    return false;27  if (op->hasTrait<OpTrait::SymbolTable>())28    return false;29  if (isa<FunctionOpInterface>(op))30    return true;31  return isNestedInFunctionOpInterface(op->getParentOp());32}33 34/// Returns true if the given op is a GraphARM op or nested in a35/// GraphARM op without a module-like op in the middle.36static bool isNestedInGraphARMOpInterface(Operation *op) {37  if (!op)38    return false;39  if (op->hasTrait<OpTrait::SymbolTable>())40    return false;41  if (isa<spirv::GraphARMOp>(op))42    return true;43  return isNestedInGraphARMOpInterface(op->getParentOp());44}45 46/// Returns true if the given op is an module-like op that maintains a symbol47/// table.48static bool isDirectInModuleLikeOp(Operation *op) {49  return op && op->hasTrait<OpTrait::SymbolTable>();50}51 52/// Result of a logical op must be a scalar or vector of boolean type.53static Type getUnaryOpResultType(Type operandType) {54  Builder builder(operandType.getContext());55  Type resultType = builder.getIntegerType(1);56  if (auto vecType = llvm::dyn_cast<VectorType>(operandType))57    return VectorType::get(vecType.getNumElements(), resultType);58  return resultType;59}60 61static ParseResult parseImageOperands(OpAsmParser &parser,62                                      spirv::ImageOperandsAttr &attr) {63  // Expect image operands64  if (parser.parseOptionalLSquare())65    return success();66 67  spirv::ImageOperands imageOperands;68  if (parseEnumStrAttr(imageOperands, parser))69    return failure();70 71  attr = spirv::ImageOperandsAttr::get(parser.getContext(), imageOperands);72 73  return parser.parseRSquare();74}75 76static void printImageOperands(OpAsmPrinter &printer, Operation *imageOp,77                               spirv::ImageOperandsAttr attr) {78  if (attr) {79    auto strImageOperands = stringifyImageOperands(attr.getValue());80    printer << "[\"" << strImageOperands << "\"]";81  }82}83 84/// Adapted from the cf.switch implementation.85/// <cases> ::= `default` `:` bb-id (`(` ssa-use-and-type-list `)`)?86///             ( `,` integer `:` bb-id (`(` ssa-use-and-type-list `)`)? )*87static ParseResult parseSwitchOpCases(88    OpAsmParser &parser, Type &selectorType, Block *&defaultTarget,89    SmallVectorImpl<OpAsmParser::UnresolvedOperand> &defaultOperands,90    SmallVectorImpl<Type> &defaultOperandTypes, DenseIntElementsAttr &literals,91    SmallVectorImpl<Block *> &targets,92    SmallVectorImpl<SmallVector<OpAsmParser::UnresolvedOperand>>93        &targetOperands,94    SmallVectorImpl<SmallVector<Type>> &targetOperandTypes) {95  if (parser.parseKeyword("default") || parser.parseColon() ||96      parser.parseSuccessor(defaultTarget))97    return failure();98  if (succeeded(parser.parseOptionalLParen())) {99    if (parser.parseOperandList(defaultOperands, OpAsmParser::Delimiter::None,100                                /*allowResultNumber=*/false) ||101        parser.parseColonTypeList(defaultOperandTypes) || parser.parseRParen())102      return failure();103  }104 105  SmallVector<APInt> values;106  unsigned bitWidth = selectorType.getIntOrFloatBitWidth();107  while (succeeded(parser.parseOptionalComma())) {108    int64_t value = 0;109    if (failed(parser.parseInteger(value)))110      return failure();111    values.push_back(APInt(bitWidth, value, /*isSigned=*/true));112 113    Block *target;114    SmallVector<OpAsmParser::UnresolvedOperand> operands;115    SmallVector<Type> operandTypes;116    if (failed(parser.parseColon()) || failed(parser.parseSuccessor(target)))117      return failure();118    if (succeeded(parser.parseOptionalLParen())) {119      if (failed(parser.parseOperandList(operands,120                                         OpAsmParser::Delimiter::None)) ||121          failed(parser.parseColonTypeList(operandTypes)) ||122          failed(parser.parseRParen()))123        return failure();124    }125    targets.push_back(target);126    targetOperands.emplace_back(operands);127    targetOperandTypes.emplace_back(operandTypes);128  }129 130  if (!values.empty()) {131    ShapedType literalType =132        VectorType::get(static_cast<int64_t>(values.size()), selectorType);133    literals = DenseIntElementsAttr::get(literalType, values);134  }135  return success();136}137 138static void139printSwitchOpCases(OpAsmPrinter &p, SwitchOp op, Type selectorType,140                   Block *defaultTarget, OperandRange defaultOperands,141                   TypeRange defaultOperandTypes, DenseIntElementsAttr literals,142                   SuccessorRange targets, OperandRangeRange targetOperands,143                   const TypeRangeRange &targetOperandTypes) {144  p << "  default: ";145  p.printSuccessorAndUseList(defaultTarget, defaultOperands);146 147  if (!literals)148    return;149 150  for (auto [index, literal] : llvm::enumerate(literals.getValues<APInt>())) {151    p << ',';152    p.printNewline();153    p << "  ";154    p << literal.getLimitedValue();155    p << ": ";156    p.printSuccessorAndUseList(targets[index], targetOperands[index]);157  }158  p.printNewline();159}160 161} // namespace mlir::spirv162 163// TablenGen'erated operation definitions.164#define GET_OP_CLASSES165#include "mlir/Dialect/SPIRV/IR/SPIRVOps.cpp.inc"166