19 #include "llvm/Support/Casting.h"
30 if (keyword ==
"else")
32 return ParseResult::success();
37 if (elseRegion.
empty())
43 ParseResult parseWasmVisibility(
OpAsmParser &opParser, StringAttr &visibility) {
47 if (keyword ==
"nested" or keyword ==
"") {
49 return ParseResult::success();
52 if (keyword ==
"public" || keyword ==
"private") {
54 return ParseResult::success();
56 opParser.
emitError(initLocation,
"expecting symbol visibility");
57 return ParseResult::failure();
66 #define GET_OP_CLASSES
67 #include "mlir/Dialect/WasmSSA/IR/WasmSSAOps.cpp.inc"
71 #include "llvm/Support/LogicalResult.h"
73 using namespace wasmssa;
81 auto opType = dyn_cast<LocalRefType>(operands.front().
getType());
84 inferredReturnTypes.push_back(opType.getElementType());
89 std::string importName;
96 if (
failed(res) || fromStr !=
"from")
99 std::string moduleName;
107 if (
failed(res) || asStr !=
"as")
110 StringAttr symbolName;
121 Block *BlockOp::getLabelTarget() {
return getTarget(); }
127 std::size_t BlockReturnOp::getExitLevel() {
return 0; }
129 Block *BlockReturnOp::getTarget() {
130 return cast<LabelBranchingOpInterface>(getOperation())
141 auto bitsToTake = getBitsToTake().getValue().getLimitedValue();
142 if (bitsToTake != 32 && bitsToTake != 16 && bitsToTake != 8)
143 return emitError(
"extend op can only take 8, 16 or 32 bits. Got ")
146 if (bitsToTake >= getInput().
getType().getIntOrFloatBitWidth())
147 return emitError(
"trying to extend the ")
148 << bitsToTake <<
" low bits from a " << getInput().getType()
149 <<
" value is illegal";
157 Block *FuncOp::addEntryBlock() {
158 if (!getBody().empty()) {
159 emitError(
"adding entry block to a FuncOp which already has one");
160 return &getBody().front();
162 Block &block = getBody().emplaceBlock();
163 for (
auto argType : getFunctionType().getInputs())
169 StringRef symbol, FunctionType funcType) {
170 FuncOp::build(odsBuilder, odsState, symbol, funcType, {}, {},
"nested");
179 argTypesWithoutLocal.reserve(argTypes.size());
180 llvm::for_each(argTypes, [&parser, &argTypesWithoutLocal](
Type argType) {
181 auto refType = dyn_cast<LocalRefType>(argType);
185 "!wasm<local T>, got ")
189 argTypesWithoutLocal.push_back(refType.getElementType());
196 parser, result,
false,
197 getFunctionTypeAttrName(result.
name), buildFuncType,
198 getArgAttrsAttrName(result.
name), getResAttrsAttrName(result.
name));
201 LogicalResult FuncOp::verifyBody() {
202 if (getBody().empty())
206 return emitError(
"entry block should have same number of arguments as "
207 "function type. Function type has ")
208 << getFunctionType().getNumInputs() <<
", entry block has "
213 auto blockLocalRefType = dyn_cast<LocalRefType>(blockType);
214 if (!blockLocalRefType)
215 return emitError(
"entry block argument type should be LocalRefType, got ")
216 << blockType <<
" for block argument " << argNo;
217 if (blockLocalRefType.getElementType() != funcSignatureType)
219 << argNo <<
"(" << funcSignatureType
220 <<
") doesn't match entry block referenced type ("
221 << blockLocalRefType.getElementType() <<
")";
228 p, *
this,
false, getFunctionTypeAttrName(),
229 getArgAttrsAttrName(), getResAttrsAttrName());
237 StringRef symbol, StringRef moduleName,
238 StringRef importName, FunctionType type) {
239 FuncImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
248 StringRef symbol,
Type type,
bool isMutable) {
249 GlobalOp::build(odsBuilder, odsState, symbol, type, isMutable,
255 StringAttr symbolName;
263 std::string mutableString;
265 if (res.succeeded() && mutableString ==
"mutable")
267 std::string visibilityString;
279 printer <<
" @" << getSymName().str() <<
" " <<
getType();
281 printer <<
" mutable";
282 if (
auto vis = getSymVisibility())
283 printer <<
" " << *vis;
285 Region &body = getRegion();
301 if (!this->getOperation()
302 ->getParentWithTrait<ConstantExpressionInitializerOpTrait>())
305 StringRef referencedSymbol = getGlobal();
309 return emitError() <<
"symbol @" << referencedSymbol <<
" is undefined";
310 auto definitionImport = dyn_cast<GlobalImportOp>(definitionOp);
311 if (!definitionImport || definitionImport.getIsMutable()) {
312 return emitError(
"global.get op is considered constant if it's referring "
313 "to a import.global symbol marked non-mutable");
323 StringRef symbol, StringRef moduleName,
324 StringRef importName,
Type type,
bool isMutable) {
325 GlobalImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
331 ParseResult res = parseImportOp(parser, result);
334 std::string mutableOrSymVisString;
336 if (res.succeeded() && mutableOrSymVisString ==
"mutable") {
355 printer <<
" \"" << getImportName() <<
"\" from \"" << getModuleName()
356 <<
"\" as @" << getSymName();
358 printer <<
" mutable";
359 if (
auto vis = getSymVisibility())
360 printer <<
" " << *vis;
368 Block *IfOp::getLabelTarget() {
return getTarget(); }
374 LogicalResult LocalOp::inferReturnTypes(
375 MLIRContext *context, ::std::optional<Location> location,
378 LocalOp::GenericAdaptor<ValueRange> adaptor{operands, attributes, properties,
380 auto type = adaptor.getTypeAttr();
384 inferredReturnTypes.push_back(resType);
392 LogicalResult LocalGetOp::inferReturnTypes(
393 MLIRContext *context, ::std::optional<Location> location,
396 return inferTeeGetResType(operands, inferredReturnTypes);
405 return emitError(
"input type and result type of local.set do not match");
413 LogicalResult LocalTeeOp::inferReturnTypes(
414 MLIRContext *context, ::std::optional<Location> location,
417 return inferTeeGetResType(operands, inferredReturnTypes);
423 return emitError(
"input type and output type of local.tee do not match");
431 Block *LoopOp::getLabelTarget() {
return &getBody().
front(); }
438 StringRef symbol, LimitType limit) {
439 MemOp::build(odsBuilder, odsState, symbol, limit,
448 StringRef symbol, StringRef moduleName,
449 StringRef importName, LimitType limits) {
450 MemImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
459 auto inT = getInput().getType();
460 auto resT = getResult().getType();
462 return emitError(
"reinterpret input and output type should be distinct");
463 if (inT.getIntOrFloatBitWidth() != resT.getIntOrFloatBitWidth())
464 return emitError() <<
"input type (" << inT <<
") and output type (" << resT
465 <<
") have incompatible bit widths";
480 StringRef symbol, TableType type) {
481 TableOp::build(odsBuilder, odsState, symbol, type,
490 StringRef symbol, StringRef moduleName,
491 StringRef importName, TableType type) {
492 TableImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
static MLIRContext * getContext(OpFoldResult val)
static Type getElementType(Type type)
Determine the element type of type.
static void print(spirv::VerCapExtAttr triple, DialectAsmPrinter &printer)
ParseResult parseSymbolName(StringAttr &result)
Parse an -identifier and store it (without the '@' symbol) in a string attribute.
virtual ParseResult parseOptionalKeywordOrString(std::string *result)=0
Parse an optional keyword or string.
MLIRContext * getContext() const
virtual Location getEncodedSourceLoc(SMLoc loc)=0
Re-encode the given source location as an MLIR location and return it.
virtual InFlightDiagnostic emitError(SMLoc loc, const Twine &message={})=0
Emit a diagnostic at the specified location and return failure.
ParseResult parseKeywordOrString(std::string *result)
Parse a keyword or a quoted string.
ParseResult parseString(std::string *string)
Parse a quoted string token.
virtual SMLoc getCurrentLocation()=0
Get the location of the next token and store it into the argument.
virtual ParseResult parseColon()=0
Parse a : token.
virtual ParseResult parseType(Type &result)=0
Parse a type.
virtual void printKeywordOrString(StringRef keyword)
Print the given string as a keyword, or a quoted and escaped string if it has any special or non-prin...
Attributes are known-constant values of operations.
Block represents an ordered list of Operations.
ValueTypeRange< BlockArgListType > getArgumentTypes()
Return a range containing the types of the arguments for this block.
unsigned getNumArguments()
BlockArgument addArgument(Type type, Location loc)
Add one value to the argument list.
Block * getSuccessor(unsigned i)
This class is a general helper class for creating context-global objects like types,...
FunctionType getFunctionType(TypeRange inputs, TypeRange results)
StringAttr getStringAttr(const Twine &bytes)
MLIRContext is the top-level object for a collection of MLIR operations.
The OpAsmParser has methods for interacting with the asm parser: parsing things from it,...
virtual ParseResult parseRegion(Region ®ion, ArrayRef< Argument > arguments={}, bool enableNameShadowing=false)=0
Parses a region.
This is a pure-virtual base class that exposes the asmprinter hooks necessary to implement a custom p...
virtual void printRegion(Region &blocks, bool printEntryBlockArgs=true, bool printBlockTerminators=true, bool printEmptyBlock=false)=0
Prints a region.
This class helps build Operations.
Simple wrapper around a void* in order to express generically how to pass in op properties through AP...
Operation is the basic unit of execution within MLIR.
This class provides an abstraction over the different types of ranges over Regions.
This class contains a list of basic blocks and a link to the parent operation it is attached to.
This class represents a collection of SymbolTables.
virtual Operation * lookupSymbolIn(Operation *symbolTableOp, StringAttr symbol)
Look up a symbol with the specified name within the specified symbol table operation,...
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
static Operation * getNearestSymbolTable(Operation *from)
Returns the nearest symbol table from a given operation from.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
This class provides an abstraction over the different types of ranges over Values.
type_range getType() const
A named class for passing around the variadic flag.
constexpr void enumerate(std::tuple< Tys... > &tuple, CallbackT &&callback)
void printFunctionOp(OpAsmPrinter &p, FunctionOpInterface op, bool isVariadic, StringRef typeAttrName, StringAttr argAttrsName, StringAttr resAttrsName)
Printer implementation for function-like operations.
ParseResult parseFunctionOp(OpAsmParser &parser, OperationState &result, bool allowVariadic, StringAttr typeAttrName, FuncTypeBuilder funcTypeBuilder, StringAttr argAttrsName, StringAttr resAttrsName)
Parser implementation for function-like operations.
QueryRef parse(llvm::StringRef line, const QuerySession &qs)
Include the generated interface declarations.
Type getType(OpFoldResult ofr)
Returns the int type of the integer in ofr.
InFlightDiagnostic emitError(Location loc)
Utility method to emit an error message using this location.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs,...
This represents an operation in an abstracted form, suitable for use with the builder APIs.
void addAttribute(StringRef name, Attribute attr)
Add an attribute with the specified name.
Region * addRegion()
Create a region that should be attached to the operation.