20 #include "llvm/Support/Casting.h"
31 if (keyword ==
"else")
33 return ParseResult::success();
38 if (elseRegion.
empty())
45 #define GET_OP_CLASSES
46 #include "mlir/Dialect/WasmSSA/IR/WasmSSAOps.cpp.inc"
50 #include "llvm/Support/LogicalResult.h"
52 using namespace wasmssa;
60 auto opType = dyn_cast<LocalRefType>(operands.front().
getType());
63 inferredReturnTypes.push_back(opType.getElementType());
68 std::string importName;
75 if (
failed(res) || fromStr !=
"from")
78 std::string moduleName;
86 if (
failed(res) || asStr !=
"as")
89 StringAttr symbolName;
100 Block *BlockOp::getLabelTarget() {
return getTarget(); }
106 std::size_t BlockReturnOp::getExitLevel() {
return 0; }
108 Block *BlockReturnOp::getTarget() {
109 return cast<LabelBranchingOpInterface>(getOperation())
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";
136 Block *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())
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());
187 parser, result,
false,
188 getFunctionTypeAttrName(result.
name), buildFuncType,
189 getArgAttrsAttrName(result.
name), getResAttrsAttrName(result.
name));
195 LogicalResult 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 "
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,
251 StringAttr symbolName;
254 std::string visibilityString;
257 if (res.succeeded()) {
258 if (visibilityString !=
"exported")
260 loc,
"expecting either `exported` or symbol name. got ")
269 std::string mutableString;
271 if (res.succeeded() && mutableString ==
"mutable")
282 printer <<
" exported";
283 printer <<
" @" << getSymName().str() <<
" " <<
getType();
285 printer <<
" mutable";
287 Region &body = getRegion();
303 if (!this->getOperation()
304 ->getParentWithTrait<ConstantExpressionInitializerOpTrait>())
307 StringRef referencedSymbol = getGlobal();
311 return emitError() <<
"symbol @" << referencedSymbol <<
" is undefined";
312 auto definitionImport = dyn_cast<GlobalImportOp>(definitionOp);
313 if (!definitionImport || definitionImport.getIsMutable()) {
314 return emitError(
"global.get op is considered constant if it's referring "
315 "to a import.global symbol marked non-mutable");
326 ParseResult res = parseImportOp(parser, result);
329 std::string mutableOrSymVisString;
331 if (res.succeeded() && mutableOrSymVisString ==
"mutable") {
346 printer <<
" \"" << getImportName() <<
"\" from \"" << getModuleName()
347 <<
"\" as @" << getSymName();
349 printer <<
" mutable";
357 Block *IfOp::getLabelTarget() {
return getTarget(); }
363 LogicalResult LocalOp::inferReturnTypes(
364 MLIRContext *context, ::std::optional<Location> location,
367 LocalOp::GenericAdaptor<ValueRange> adaptor{operands, attributes, properties,
369 auto type = adaptor.getTypeAttr();
373 inferredReturnTypes.push_back(resType);
381 LogicalResult LocalGetOp::inferReturnTypes(
382 MLIRContext *context, ::std::optional<Location> location,
385 return inferTeeGetResType(operands, inferredReturnTypes);
394 return emitError(
"input type and result type of local.set do not match");
402 LogicalResult LocalTeeOp::inferReturnTypes(
403 MLIRContext *context, ::std::optional<Location> location,
406 return inferTeeGetResType(operands, inferredReturnTypes);
412 return emitError(
"input type and output type of local.tee do not match");
420 Block *LoopOp::getLabelTarget() {
return &getBody().
front(); }
427 auto inT = getInput().getType();
428 auto resT = getResult().getType();
430 return emitError(
"reinterpret input and output type should be distinct");
431 if (inT.getIntOrFloatBitWidth() != resT.getIntOrFloatBitWidth())
432 return emitError() <<
"input type (" << inT <<
") and output type (" << resT
433 <<
") have incompatible bit widths";
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 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.
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.