20#include "llvm/Support/Casting.h"
31 if (keyword ==
"else")
33 return ParseResult::success();
38 if (elseRegion.
empty())
46#include "mlir/Dialect/WasmSSA/IR/WasmSSAOps.cpp.inc"
50#include "llvm/Support/LogicalResult.h"
60 auto opType = dyn_cast<LocalRefType>(operands.front().
getType());
63 inferredReturnTypes.push_back(opType.getElementType());
68 std::string importName;
71 result.addAttribute(
"importName", StringAttr::get(ctx, importName));
75 if (failed(res) || fromStr !=
"from")
78 std::string moduleName;
82 result.addAttribute(
"moduleName", StringAttr::get(ctx, moduleName));
86 if (failed(res) || asStr !=
"as")
89 StringAttr symbolName;
100Block *BlockOp::getLabelTarget() {
return getTarget(); }
106std::size_t BlockReturnOp::getExitLevel() {
return 0; }
108Block *BlockReturnOp::getTarget() {
109 return cast<LabelBranchingOpInterface>(getOperation())
119LogicalResult ExtendLowBitsSOp::verify() {
120 auto bitsToTake = getBitsToTake().getValue().getLimitedValue();
121 if (bitsToTake != 32 && bitsToTake != 16 && bitsToTake != 8)
122 return emitError(
"extend op can only take 8, 16 or 32 bits. Got ")
125 if (bitsToTake >= getInput().
getType().getIntOrFloatBitWidth())
126 return emitError(
"trying to extend the ")
127 << bitsToTake <<
" low bits from a " << getInput().getType()
128 <<
" value is illegal";
136Block *FuncOp::addEntryBlock() {
137 if (!getBody().empty()) {
138 emitError(
"adding entry block to a FuncOp which already has one");
139 return &getBody().front();
141 Block &block = getBody().emplaceBlock();
142 for (
auto argType : getFunctionType().getInputs())
143 block.
addArgument(LocalRefType::get(argType), getLoc());
148 StringRef symbol, FunctionType funcType) {
149 FuncOp::build(odsBuilder, odsState, symbol, funcType, {}, {});
154 std::string visibilityString;
157 bool exported{
false};
158 if (res.succeeded()) {
159 if (visibilityString !=
"exported")
161 loc,
"expecting either `exported` or symbol name. got ")
171 argTypesWithoutLocal.reserve(argTypes.size());
172 llvm::for_each(argTypes, [&parser, &argTypesWithoutLocal](
Type argType) {
173 auto refType = dyn_cast<LocalRefType>(argType);
177 "!wasm<local T>, got ")
181 argTypesWithoutLocal.push_back(refType.getElementType());
188 getFunctionTypeAttrName(
result.name), buildFuncType,
189 getArgAttrsAttrName(
result.name), getResAttrsAttrName(
result.name));
191 result.addAttribute(getExportedAttrName(
result.name), UnitAttr::get(ctx));
195LogicalResult FuncOp::verifyBody() {
196 if (getBody().empty())
200 return emitError(
"entry block should have same number of arguments as "
201 "function type. Function type has ")
202 << getFunctionType().getNumInputs() <<
", entry block has "
205 for (
auto [argNo, funcSignatureType, blockType] : llvm::enumerate(
207 auto blockLocalRefType = dyn_cast<LocalRefType>(blockType);
208 if (!blockLocalRefType)
209 return emitError(
"entry block argument type should be LocalRefType, got ")
210 << blockType <<
" for block argument " << argNo;
211 if (blockLocalRefType.getElementType() != funcSignatureType)
213 << argNo <<
"(" << funcSignatureType
214 <<
") doesn't match entry block referenced type ("
215 << blockLocalRefType.getElementType() <<
")";
223 auto exported = getExported();
226 removeExportedAttr();
229 p, *
this,
false, getFunctionTypeAttrName(),
230 getArgAttrsAttrName(), getResAttrsAttrName());
240 StringRef symbol, StringRef moduleName,
241 StringRef importName, FunctionType type) {
242 FuncImportOp::build(odsBuilder, odsState, symbol, moduleName, importName,
250Operation *getGlobalOpTerminatorOp(GlobalOp gop) {
251 return gop.getInitializer().begin()->getTerminator();
255ReturnOp GlobalOp::getInitTerminator() {
256 return llvm::cast<wasmssa::ReturnOp>(getGlobalOpTerminatorOp(*
this));
261 StringAttr symbolName;
264 std::string visibilityString;
267 if (res.succeeded()) {
268 if (visibilityString !=
"exported")
270 loc,
"expecting either `exported` or symbol name. got ")
272 result.addAttribute(getExportedAttrName(
result.name), UnitAttr::get(ctx));
278 result.addAttribute(getTypeAttrName(
result.name), TypeAttr::get(globalType));
279 std::string mutableString;
281 if (res.succeeded() && mutableString ==
"mutable")
282 result.addAttribute(
"isMutable", UnitAttr::get(ctx));
292 printer <<
" exported";
293 printer <<
" @" << getSymName().str() <<
" " <<
getType();
295 printer <<
" mutable";
297 Region &body = getRegion();
305LogicalResult GlobalOp::verify() {
306 return success(llvm::isa<ReturnOp>(getGlobalOpTerminatorOp(*
this)));
317 if (!this->getOperation()
318 ->getParentWithTrait<ConstantExpressionInitializerOpTrait>())
321 StringRef referencedSymbol = getGlobal();
323 symTabOp, StringAttr::get(this->
getContext(), referencedSymbol));
325 return emitError() <<
"symbol @" << referencedSymbol <<
" is undefined";
326 auto definitionImport = dyn_cast<GlobalImportOp>(definitionOp);
327 if (!definitionImport || definitionImport.getIsMutable()) {
328 return emitError(
"global.get op is considered constant if it's referring "
329 "to a import.global symbol marked non-mutable");
340 ParseResult res = parseImportOp(parser,
result);
343 std::string mutableOrSymVisString;
345 if (res.succeeded() && mutableOrSymVisString ==
"mutable") {
346 result.addAttribute(
"isMutable", UnitAttr::get(ctx));
355 TypeAttr::get(importedType));
360 printer <<
" \"" << getImportName() <<
"\" from \"" << getModuleName()
361 <<
"\" as @" << getSymName();
363 printer <<
" mutable";
371Block *IfOp::getLabelTarget() {
return getTarget(); }
377LogicalResult LocalOp::inferReturnTypes(
378 MLIRContext *context, ::std::optional<Location> location,
381 LocalOp::GenericAdaptor<ValueRange> adaptor{operands, attributes, properties,
383 auto type = adaptor.getTypeAttr();
386 auto resType = LocalRefType::get(type.getContext(), type.getValue());
387 inferredReturnTypes.push_back(resType);
395LogicalResult LocalGetOp::inferReturnTypes(
396 MLIRContext *context, ::std::optional<Location> location,
399 return inferTeeGetResType(operands, inferredReturnTypes);
406LogicalResult LocalSetOp::verify() {
408 return emitError(
"input type and result type of local.set do not match");
416LogicalResult LocalTeeOp::inferReturnTypes(
417 MLIRContext *context, ::std::optional<Location> location,
420 return inferTeeGetResType(operands, inferredReturnTypes);
423LogicalResult LocalTeeOp::verify() {
426 return emitError(
"input type and output type of local.tee do not match");
434Block *LoopOp::getLabelTarget() {
return &getBody().
front(); }
440LogicalResult ReinterpretOp::verify() {
441 auto inT = getInput().getType();
442 auto resT = getResult().getType();
444 return emitError(
"reinterpret input and output type should be distinct");
445 if (inT.getIntOrFloatBitWidth() != resT.getIntOrFloatBitWidth())
446 return emitError() <<
"input type (" << inT <<
") and output type (" << resT
447 <<
") have incompatible bit widths";
static Type getElementType(Type type)
Determine the element type of type.
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 SMLoc getNameLoc() const =0
Return the location of the original name 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...
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)
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.
Operation is the basic unit of execution within MLIR.
Type-safe wrapper around a void* for passing properties, including the properties structs of operatio...
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.
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.
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.
This represents an operation in an abstracted form, suitable for use with the builder APIs.