From 89b33d35885255d7cd5bc3a496359e77c5f7133a Mon Sep 17 00:00:00 2001 From: RIvance Date: Sat, 25 May 2024 03:16:01 +0800 Subject: [PATCH 1/2] feat(tablegen): add MLIR TableGen grammar --- pom.xml | 1 + tablegen/README.md | 3 + tablegen/TableGen.g4 | 481 ++++++++++++++++++++++++++++++++++++ tablegen/desc.xml | 4 + tablegen/examples/ToyOps.td | 454 ++++++++++++++++++++++++++++++++++ tablegen/pom.xml | 56 +++++ 6 files changed, 999 insertions(+) create mode 100755 tablegen/README.md create mode 100644 tablegen/TableGen.g4 create mode 100644 tablegen/desc.xml create mode 100644 tablegen/examples/ToyOps.td create mode 100644 tablegen/pom.xml diff --git a/pom.xml b/pom.xml index 843705201c..9a40f0bdcd 100644 --- a/pom.xml +++ b/pom.xml @@ -350,6 +350,7 @@ swift swift-fin szf + tablegen tcpheader telephone terraform diff --git a/tablegen/README.md b/tablegen/README.md new file mode 100755 index 0000000000..6f2c592355 --- /dev/null +++ b/tablegen/README.md @@ -0,0 +1,3 @@ +# MLIR TableGen + +https://llvm.org/docs/TableGen \ No newline at end of file diff --git a/tablegen/TableGen.g4 b/tablegen/TableGen.g4 new file mode 100644 index 0000000000..4c4580e51e --- /dev/null +++ b/tablegen/TableGen.g4 @@ -0,0 +1,481 @@ +grammar TableGen; + +// TableGenFile ::= (Statement | IncludeDirective | PreprocessorDirective)* +tableGenFile + : (statement | includeDirective | preprocessorDirective)* + ; + +preprocessorDirective + : predDefine + | preIfdef + | preElse + | preEndif + ; + +// MacroName ::= ualpha (ualpha | "0"..."9")* +macroName + : TokIdentifier + ; + +// PreDefine ::= LineBegin (WhiteSpaceOrCComment)* +// "#define" (WhiteSpace)+ MacroName +// (WhiteSpaceOrAnyComment)* LineEnd +predDefine + : PreprocessorDefine macroName + ; + +// PreIfdef ::= LineBegin (WhiteSpaceOrCComment)* +// ("#ifdef" | "#ifndef") (WhiteSpace)+ MacroName +// (WhiteSpaceOrAnyComment)* LineEnd +preIfdef + : (PreprocessorIfdef | PreprocessorIfndef) macroName + ; + +// PreElse ::= LineBegin (WhiteSpaceOrCComment)* +// "#else" (WhiteSpaceOrAnyComment)* LineEnd +preElse + : PreprocessorElse + ; + +// PreEndif ::= LineBegin (WhiteSpaceOrCComment)* +// "#endif" (WhiteSpaceOrAnyComment)* LineEnd +preEndif + : PreprocessorEndif + ; + +// Statement ::= Assert | Class | Def | Defm | Defset | Deftype +// | Defvar | Dump | Foreach | If | Let | MultiClass +statement + : assertStmt + | classStmt + | defStmt + | defmStmt + | defsetStmt + | deftypeStmt + | defvarStmt + | dumpStmt + | foreachStmt + | ifStmt + | letStmt + | multiclassStmt + ; + +// Class ::= "class" ClassID [TemplateArgList] RecordBody +classStmt + : Class classID templateArgList? recordBody + ; + +// TemplateArgList ::= "<" TemplateArgDecl ("," TemplateArgDecl)* ">" +templateArgList + : '<' templateArgDecl (',' templateArgDecl)* '>' + ; + +// TemplateArgDecl ::= Type TokIdentifier ["=" Value] +templateArgDecl + : type TokIdentifier ('=' value)? + ; + +// RecordBody ::= ParentClassList Body +recordBody + : parentClassList body + ; + +// ParentClassList ::= [":" ParentClassListNE] +parentClassList + : (':' parentClassListNE)? + ; + +// ParentClassListNE ::= ClassRef ("," ClassRef)* +parentClassListNE + : classRef (',' classRef)* + ; + +// ClassRef ::= (ClassID | MultiClassID) ["<" [ArgValueList] ">"] +classRef + : (classID | multiClassID) ('<' argValueList '>')? + ; + +// ArgValueList ::= PostionalArgValueList [","] NamedArgValueList +argValueList + : positionalArgValueList (',')? namedArgValueList + ; + +// PostionalArgValueList ::= [Value {"," Value}*] +positionalArgValueList + : (value (',' value)*)? + ; + +// NamedArgValueList ::= [NameValue "=" Value {"," NameValue "=" Value}*] +namedArgValueList + : (nameValue '=' value (',' nameValue '=' value)*)? + ; + +// Body ::= ";" | "{" BodyItem* "}" +body + : ';' + | '{' bodyItem* '}' + ; + +// BodyItem ::= (Type | "code") TokIdentifier ["=" Value] ";" +// | "let" TokIdentifier ["{" RangeList "}"] "=" Value ";" +// | "defvar" TokIdentifier "=" Value ";" +// | Assert +bodyItem + : (type | Code) TokIdentifier ('=' value)? ';' + | Let TokIdentifier ('{' rangeList '}')? '=' value ';' + | Defvar TokIdentifier '=' value ';' + | assertStmt + ; + +// Def ::= "def" [NameValue] RecordBody +defStmt + : Def nameValue? recordBody + ; + +// NameValue ::= Value (parsed in a special mode) +nameValue + : value + ; + +// Let ::= "let" LetList "in" "{" Statement* "}" +// | "let" LetList "in" Statement +letStmt + : Let letList In '{' statement* '}' + | Let letList In statement + ; + +// LetList ::= LetItem ("," LetItem)* +letList + : letItem (',' letItem)* + ; + +// LetItem ::= TokIdentifier ["<" RangeList ">"] "=" Value +letItem + : TokIdentifier ('<' rangeList '>')? '=' value + ; + +// MultiClass ::= "multiclass" TokIdentifier [TemplateArgList] ParentClassList "{" MultiClassStatement+ "}" +multiclassStmt + : Multiclass TokIdentifier templateArgList? parentClassList '{' multiClassStatement+ '}' + ; + +// MultiClassID ::= TokIdentifier +multiClassID + : TokIdentifier + ; + +// MultiClassStatement ::= Assert | Def | Defm | Defvar | Foreach | If | Let +multiClassStatement + : assertStmt + | defStmt + | defmStmt + | defvarStmt + | foreachStmt + | ifStmt + | letStmt + ; + +// Defm ::= "defm" [NameValue] ParentClassList ";" +defmStmt + : Defm nameValue? parentClassList ';' + ; + +// Defset ::= "defset" Type TokIdentifier "=" "{" Statement* "}" +defsetStmt + : Defset type TokIdentifier '=' '{' statement* '}' + ; + +// Deftype ::= "deftype" TokIdentifier "=" Type ";" +deftypeStmt + : Deftype TokIdentifier '=' type ';' + ; + +// Defvar ::= "defvar" TokIdentifier "=" Value ";" +defvarStmt + : Defvar TokIdentifier '=' value ';' + ; + +// Foreach ::= "foreach" ForeachIterator "in" "{" Statement* "}" +// | "foreach" ForeachIterator "in" Statement +foreachStmt + : Foreach foreachIterator In '{' statement* '}' + | Foreach foreachIterator In statement + ; + +// ForeachIterator ::= TokIdentifier "=" ("{" RangeList "}" | RangePiece | Value) +foreachIterator + : TokIdentifier '=' ('{' rangeList '}' | rangePiece | value) + ; + +// Dump ::= "dump" string ";" +dumpStmt + : Dump value ';' + ; + +// If ::= "if" Value "then" IfBody +// | "if" Value "then" IfBody "else" IfBody +ifStmt + : If value Then ifBody + | If value Then ifBody Else ifBody + ; + +// IfBody ::= "{" Statement* "}" | Statement +ifBody + : '{' statement* '}' + | statement + ; + +// Assert ::= "assert" condition "," message ";" +assertStmt + : Assert value ',' value ';' + ; + +// Value ::= SimpleValue ValueSuffix* +// | Value "#" [Value] +value + : simpleValue valueSuffix* + | value '#' value? + ; + +// ValueSuffix ::= "{" RangeList "}" +// | "[" SliceElements "]" +// | "." TokIdentifier +valueSuffix + : '{' rangeList '}' + | '[' sliceElements ']' + | '.' TokIdentifier + ; + +// RangeList ::= RangePiece ("," RangePiece)* +rangeList + : rangePiece (',' rangePiece)* + ; + +// RangePiece ::= TokInteger +// | TokInteger "..." TokInteger +// | TokInteger "-" TokInteger +// | TokInteger TokInteger +rangePiece + : TokInteger + | TokInteger '...' TokInteger + | TokInteger '-' TokInteger + | TokInteger TokInteger + ; + +// SliceElements ::= (SliceElement ",")* SliceElement ","? +sliceElements + : (sliceElement ',')* sliceElement ',' + ; + +// SliceElement ::= Value +// | Value "..." Value +// | Value "-" Value +// | Value TokInteger +sliceElement + : value + | value '...' value + | value '-' value + | value TokInteger + ; + +simpleValue + : simpleValueTok + | simpleValueBool + | simpleValueQuestion + | simpleValueList + | simpleValueListType + | simpleValueDag + | simpleValueIdentifier + | simpleValueClass + | simpleValueOperator + ; + +// SimpleValue1 ::= TokInteger | TokString+ | TokCode +simpleValueTok + : TokInteger + | TokString+ + | TokCode + ; + +// SimpleValue2 ::= "true" | "false" +simpleValueBool + : True + | False + ; + +// SimpleValue3 ::= "?" +simpleValueQuestion + : '?' + ; + +// SimpleValue4 ::= "{" [ValueList] "}" +simpleValueList + : '{' valueList '}' + ; + +// ValueList ::= ValueListNE +valueList + : valueListNE? + ; + +// ValueListNE ::= Value ("," Value)* +valueListNE + : value (',' value)* ','? + ; + +// SimpleValue5 ::= "[" ValueList "]" ["<" Type ">"] +simpleValueListType + : '[' valueList ']' ('<' type '>')? + ; + +// SimpleValue6 ::= "(" DagArg [DagArgList] ")" +simpleValueDag + : '(' dagArg (dagArgList)? ')' + ; + +// DagArgList ::= DagArg ("," DagArg)* +dagArgList + : dagArg (',' dagArg)* ','? + ; + +// DagArg ::= Value [":" TokVarName] | TokVarName +dagArg + : value (':' TokVarName)? + | TokVarName + ; + +// SimpleValue7 ::= TokIdentifier +simpleValueIdentifier + : TokIdentifier + ; + +// SimpleValue8 ::= ClassID "<" ArgValueList ">" +simpleValueClass + : classID '<' argValueList '>' + ; + +// SimpleValue9 ::= BangOperator ["<" Type ">"] "(" ValueListNE ")" +// | CondOperator "(" CondClause ("," CondClause)* ")" +simpleValueOperator + : bangOperator ('<' type '>')? '(' valueListNE ')' + | condOperator '(' condClause (',' condClause)* ')' + ; + +// CondClause ::= Value ":" Value +condClause + : value ':' value + ; + +// Type ::= "bit" | "int" | "string" | "dag" +// | "bits" "<" TokInteger ">" +// | "list" "<" Type ">" +// | ClassID +type + : Bit + | Int + | String + | Dag + | Bits '<' TokInteger '>' + | List '<' type '>' + | classID + ; + +// ClassID ::= TokIdentifier +classID + : TokIdentifier + ; + +includeDirective + : Include TokString + ; + +// BangOperator ::= one of +// !add !and !cast !con !dag +// !div !empty !eq !exists !filter +// !find !foldl !foreach !ge !getdagarg +// !getdagname !getdagop !gt !head !if +// !interleave !isa !le !listconcat !listremove +// !listsplat !logtwo !lt !mul !ne +// !not !or !range !repr !setdagarg +// !setdagname !setdagop !shl !size !sra +// !srl !strconcat !sub !subst !substr +// !tail !tolower !toupper !xor +bangOperator + : '!add' | '!and' | '!cast' | '!con' | '!dag' + | '!div' | '!empty' | '!eq' | '!exists' | '!filter' + | '!find' | '!foldl' | '!foreach' | '!ge' | '!getdagarg' + | '!getdagname' | '!getdagop' | '!gt' | '!head' | '!if' + | '!interleave' | '!isa' | '!le' | '!listconcat' | '!listremove' + | '!listsplat' | '!logtwo' | '!lt' | '!mul' | '!ne' + | '!not' | '!or' | '!range' | '!repr' | '!setdagarg' + | '!setdagname' | '!setdagop' | '!shl' | '!size' | '!sra' + | '!srl' | '!strconcat' | '!sub' | '!subst' | '!substr' + | '!tail' | '!tolower' | '!toupper' | '!xor' + ; + +// CondOperator ::= !cond +condOperator + : '!cond' + ; + +// Keywords: +// assert bit bits class code +// dag def dump else false +// foreach defm defset defvar field +// if in include int let +// list multiclass string then true +Assert : 'assert'; +Bit : 'bit'; +Bits : 'bits'; +Class : 'class'; +Code : 'code'; +Dag : 'dag'; +Def : 'def'; +Dump : 'dump'; +Else : 'else'; +False : 'false'; +Foreach : 'foreach'; +Defm : 'defm'; +Defset : 'defset'; +Defvar : 'defvar'; +Deftype : 'deftype'; +Field : 'field'; +If : 'if'; +In : 'in'; +Include : 'include'; +Int : 'int'; +Let : 'let'; +List : 'list'; +Multiclass : 'multiclass'; +String : 'string'; +Then : 'then'; +True : 'true'; + +// '"' (non-'"' characters and escapes) '"' +TokString : '"' (~('"') | Escape)* '"'; +// "[{" (shortest text not containing "}]") "}]" +TokCode : '[{' (~(']') | ']' ~('}') | Escape)*? '}]'; + +TokInteger : DecimalInteger | HexInteger | BinInteger; +DecimalInteger : ('+' | '-')? (UDigit)+; +HexInteger : '0x' (UDigit | 'a'..'f' | 'A'..'F')+; +BinInteger : '0b' ('0' | '1')+; + +TokIdentifier : (UDigit)* UAlpha (UAlpha | UDigit)*; +TokVarName : '$' UAlpha (UAlpha | UDigit)*; + +// Preprocessor directives +PreprocessorDefine : '#define'; +PreprocessorIfdef : '#ifdef'; +PreprocessorIfndef : '#ifndef'; +PreprocessorElse : '#else'; +PreprocessorEndif : '#endif'; + +WhiteSpace : [ \n\t\r]+ -> skip; +SingleLineComment : '//' ~[\r\n]* -> skip; +MultiLineComment : '/*' .*? '*/' -> skip; + +fragment UDigit : '0'..'9'; +fragment UAlpha : 'a'..'z' | 'A'..'Z' | '_'; +fragment EOL : '\r'? '\n'; +fragment Escape : '\\' [btnfr"'\\]; diff --git a/tablegen/desc.xml b/tablegen/desc.xml new file mode 100644 index 0000000000..3c57d45acb --- /dev/null +++ b/tablegen/desc.xml @@ -0,0 +1,4 @@ + + + CSharp;Cpp;Dart;Go;Java;JavaScript;PHP;Python3;TypeScript;Antlr4ng + diff --git a/tablegen/examples/ToyOps.td b/tablegen/examples/ToyOps.td new file mode 100644 index 0000000000..20908ecae1 --- /dev/null +++ b/tablegen/examples/ToyOps.td @@ -0,0 +1,454 @@ +//===- ToyOps.td - Toy dialect operation definitions -------*- tablegen -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Defines the operations of the Toy dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef TOY_OPS +#define TOY_OPS + +include "mlir/Interfaces/FunctionInterfaces.td" +include "mlir/IR/SymbolInterfaces.td" +include "mlir/Interfaces/CallInterfaces.td" +include "mlir/Interfaces/CastInterfaces.td" +include "mlir/Interfaces/SideEffectInterfaces.td" +include "toy/ShapeInferenceInterface.td" + +// Provide a definition of the 'toy' dialect in the ODS framework so that we +// can define our operations. +def Toy_Dialect : Dialect { + let name = "toy"; + let cppNamespace = "::mlir::toy"; + + // We set this bit to generate a declaration of the `materializeConstant` + // method so that we can materialize constants for our toy operations. + let hasConstantMaterializer = 1; + + // We set this bit to generate the declarations for the dialect's type parsing + // and printing hooks. + let useDefaultTypePrinterParser = 1; + +} + +// Base class for toy dialect operations. This operation inherits from the base +// `Op` class in OpBase.td, and provides: +// * The parent dialect of the operation. +// * The mnemonic for the operation, or the name without the dialect prefix. +// * A list of traits for the operation. +class Toy_Op traits = []> : + Op; + +// Provide a definition for the Toy StructType for use in ODS. This allows for +// using StructType in a similar way to Tensor or MemRef. We use `DialectType` +// to demarcate the StructType as belonging to the Toy dialect. +def Toy_StructType : + DialectType($_self)">, + "Toy struct type">; + +// Provide a definition of the types that are used within the Toy dialect. +def Toy_Type : AnyTypeOf<[F64Tensor, Toy_StructType]>; + +//===----------------------------------------------------------------------===// +// Toy Operations +//===----------------------------------------------------------------------===// + +//===----------------------------------------------------------------------===// +// ConstantOp +//===----------------------------------------------------------------------===// + +// We define a toy operation by inheriting from our base 'Toy_Op' class above. +// Here we provide the mnemonic and a list of traits for the operation. The +// constant operation is marked as 'Pure' as it is a pure operation +// and may be removed if dead. +def ConstantOp : Toy_Op<"constant", + [ConstantLike, Pure, + DeclareOpInterfaceMethods]> { + // Provide a summary and description for this operation. This can be used to + // auto-generate documentation of the operations within our dialect. + let summary = "constant"; + let description = [{ + Constant operation turns a literal into an SSA value. The data is attached + to the operation as an attribute. For example: + + ```mlir + %0 = toy.constant dense<[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]> + : tensor<2x3xf64> + ``` + }]; + + // The constant operation takes an attribute as the only input. + let arguments = (ins F64ElementsAttr:$value); + + // The constant operation returns a single value of TensorType. + let results = (outs F64Tensor); + + // Indicate that the operation has a custom parser and printer method. + let hasCustomAssemblyFormat = 1; + + // Add custom build methods for the constant operation. These method populates + // the `state` that MLIR uses to create operations, i.e. these are used when + // using `builder.create(...)`. + let builders = [ + // Build a constant with a given constant tensor value. + OpBuilder<(ins "DenseElementsAttr":$value), [{ + build($_builder, $_state, value.getType(), value); + }]>, + + // Build a constant with a given constant floating-point value. + OpBuilder<(ins "double":$value)> + ]; + + // Indicate that additional verification for this operation is necessary. + let hasVerifier = 1; + + // Set the folder bit so that we can implement constant folders. + let hasFolder = 1; +} + +//===----------------------------------------------------------------------===// +// AddOp +//===----------------------------------------------------------------------===// + +def AddOp : Toy_Op<"add", + [Pure, DeclareOpInterfaceMethods]> { + let summary = "element-wise addition operation"; + let description = [{ + The "add" operation performs element-wise addition between two tensors. + The shapes of the tensor operands are expected to match. + }]; + + let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs); + let results = (outs F64Tensor); + + // Indicate that the operation has a custom parser and printer method. + let hasCustomAssemblyFormat = 1; + + // Allow building an AddOp with from the two input operands. + let builders = [ + OpBuilder<(ins "Value":$lhs, "Value":$rhs)> + ]; +} + +//===----------------------------------------------------------------------===// +// CastOp +//===----------------------------------------------------------------------===// + +def CastOp : Toy_Op<"cast", [ + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods, + Pure, + SameOperandsAndResultShape + ]> { + let summary = "shape cast operation"; + let description = [{ + The "cast" operation converts a tensor from one type to an equivalent type + without changing any data elements. The source and destination types must + both be tensor types with the same element type. If both are ranked, then + shape is required to match. The operation is invalid if converting to a + mismatching constant dimension. + }]; + + let arguments = (ins F64Tensor:$input); + let results = (outs F64Tensor:$output); + + let assemblyFormat = "$input attr-dict `:` type($input) `to` type($output)"; +} + +//===----------------------------------------------------------------------===// +// FuncOp +//===----------------------------------------------------------------------===// + +def FuncOp : Toy_Op<"func", [ + FunctionOpInterface, IsolatedFromAbove + ]> { + let summary = "user defined function operation"; + let description = [{ + The "toy.func" operation represents a user defined function. These are + callable SSA-region operations that contain toy computations. + + Example: + + ```mlir + toy.func @main() { + %0 = toy.constant dense<5.500000e+00> : tensor + %1 = toy.reshape(%0 : tensor) to tensor<2x2xf64> + toy.print %1 : tensor<2x2xf64> + toy.return + } + ``` + }]; + + let arguments = (ins + SymbolNameAttr:$sym_name, + TypeAttrOf:$function_type, + OptionalAttr:$arg_attrs, + OptionalAttr:$res_attrs + ); + let regions = (region AnyRegion:$body); + + let builders = [OpBuilder<(ins + "StringRef":$name, "FunctionType":$type, + CArg<"ArrayRef", "{}">:$attrs) + >]; + let extraClassDeclaration = [{ + //===------------------------------------------------------------------===// + // FunctionOpInterface Methods + //===------------------------------------------------------------------===// + + /// Returns the argument types of this function. + ArrayRef getArgumentTypes() { return getFunctionType().getInputs(); } + + /// Returns the result types of this function. + ArrayRef getResultTypes() { return getFunctionType().getResults(); } + + Region *getCallableRegion() { return &getBody(); } + }]; + let hasCustomAssemblyFormat = 1; + let skipDefaultBuilders = 1; +} + +//===----------------------------------------------------------------------===// +// GenericCallOp +//===----------------------------------------------------------------------===// + +def GenericCallOp : Toy_Op<"generic_call", + [DeclareOpInterfaceMethods]> { + let summary = "generic call operation"; + let description = [{ + Generic calls represent calls to a user defined function that needs to + be specialized for the shape of its arguments. The callee name is attached + as a symbol reference via an attribute. The arguments list must match the + arguments expected by the callee. For example: + + ```mlir + %4 = toy.generic_call @my_func(%1, %3) + : (tensor<2x3xf64>, tensor<2x3xf64>) -> tensor<*xf64> + ``` + + This is only valid if a function named "my_func" exists and takes two + arguments. + }]; + + // The generic call operation takes a symbol reference attribute as the + // callee, and inputs for the call. + let arguments = (ins FlatSymbolRefAttr:$callee, Variadic:$inputs); + + // The generic call operation returns a single value of TensorType or + // StructType. + let results = (outs Toy_Type); + + // Specialize assembly printing and parsing using a declarative format. + let assemblyFormat = [{ + $callee `(` $inputs `)` attr-dict `:` functional-type($inputs, results) + }]; + + // Add custom build methods for the generic call operation. + let builders = [ + OpBuilder<(ins "StringRef":$callee, "ArrayRef":$arguments)> + ]; +} + +//===----------------------------------------------------------------------===// +// MulOp +//===----------------------------------------------------------------------===// + +def MulOp : Toy_Op<"mul", + [Pure, DeclareOpInterfaceMethods]> { + let summary = "element-wise multiplication operation"; + let description = [{ + The "mul" operation performs element-wise multiplication between two + tensors. The shapes of the tensor operands are expected to match. + }]; + + let arguments = (ins F64Tensor:$lhs, F64Tensor:$rhs); + let results = (outs F64Tensor); + + // Indicate that the operation has a custom parser and printer method. + let hasCustomAssemblyFormat = 1; + + // Allow building a MulOp with from the two input operands. + let builders = [ + OpBuilder<(ins "Value":$lhs, "Value":$rhs)> + ]; +} + +//===----------------------------------------------------------------------===// +// PrintOp +//===----------------------------------------------------------------------===// + +def PrintOp : Toy_Op<"print"> { + let summary = "print operation"; + let description = [{ + The "print" builtin operation prints a given input tensor, and produces + no results. + }]; + + // The print operation takes an input tensor to print. + // We also allow a F64MemRef to enable interop during partial lowering. + let arguments = (ins AnyTypeOf<[F64Tensor, F64MemRef]>:$input); + + let assemblyFormat = "$input attr-dict `:` type($input)"; +} + +//===----------------------------------------------------------------------===// +// ReshapeOp +//===----------------------------------------------------------------------===// + +def ReshapeOp : Toy_Op<"reshape", [Pure]> { + let summary = "tensor reshape operation"; + let description = [{ + Reshape operation is transforming its input tensor into a new tensor with + the same number of elements but different shapes. For example: + + ```mlir + %0 = toy.reshape (%arg1 : tensor<10xf64>) to tensor<5x2xf64> + ``` + }]; + + let arguments = (ins F64Tensor:$input); + + let assemblyFormat = [{ + `(` $input `:` type($input) `)` attr-dict `to` type(results) + }]; + + // Enable registering canonicalization patterns with this operation. + let hasCanonicalizer = 1; + + // We expect that the reshape operation returns a statically shaped tensor. + let results = (outs StaticShapeTensorOf<[F64]>); +} + +//===----------------------------------------------------------------------===// +// ReturnOp +//===----------------------------------------------------------------------===// + +def ReturnOp : Toy_Op<"return", [Pure, HasParent<"FuncOp">, + Terminator]> { + let summary = "return operation"; + let description = [{ + The "return" operation represents a return operation within a function. + The operation takes an optional operand and produces no results. + The operand type must match the signature of the function that contains + the operation. For example: + + ```mlir + toy.func @foo() -> tensor<2xf64> { + ... + toy.return %0 : tensor<2xf64> + } + ``` + }]; + + // The return operation takes an optional input operand to return. This + // value must match the return type of the enclosing function. + let arguments = (ins Variadic:$input); + + // The return operation only emits the input in the format if it is present. + let assemblyFormat = "($input^ `:` type($input))? attr-dict "; + + // Allow building a ReturnOp with no return operand. + let builders = [ + OpBuilder<(ins), [{ build($_builder, $_state, std::nullopt); }]> + ]; + + // Provide extra utility definitions on the c++ operation class definition. + let extraClassDeclaration = [{ + bool hasOperand() { return getNumOperands() != 0; } + }]; + + // Indicate that additional verification for this operation is necessary. + let hasVerifier = 1; +} + +//===----------------------------------------------------------------------===// +// StructAccessOp +//===----------------------------------------------------------------------===// + +def StructAccessOp : Toy_Op<"struct_access", [Pure]> { + let summary = "struct access"; + let description = [{ + Access the Nth element of a value returning a struct type. + }]; + + let arguments = (ins Toy_StructType:$input, I64Attr:$index); + let results = (outs Toy_Type:$output); + + let assemblyFormat = [{ + $input `[` $index `]` attr-dict `:` type($input) `->` type($output) + }]; + + // Allow building a StructAccessOp with just a struct value and an index. + let builders = [ + OpBuilder<(ins "Value":$input, "size_t":$index)> + ]; + + // Indicate that additional verification for this operation is necessary. + let hasVerifier = 1; + + // Set the folder bit so that we can fold constant accesses. + let hasFolder = 1; +} + +//===----------------------------------------------------------------------===// +// StructConstantOp +//===----------------------------------------------------------------------===// + +def StructConstantOp : Toy_Op<"struct_constant", [ConstantLike, Pure]> { + let summary = "struct constant"; + let description = [{ + Constant operation turns a literal struct value into an SSA value. The data + is attached to the operation as an attribute. The struct constant is encoded + as an array of other constant values. For example: + + ```mlir + %0 = toy.struct_constant [ + dense<[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]> : tensor<2x3xf64> + ] : !toy.struct> + ``` + }]; + + let arguments = (ins ArrayAttr:$value); + let results = (outs Toy_StructType:$output); + + let assemblyFormat = "$value attr-dict `:` type($output)"; + + // Indicate that additional verification for this operation is necessary. + let hasVerifier = 1; + let hasFolder = 1; +} + +//===----------------------------------------------------------------------===// +// TransposeOp +//===----------------------------------------------------------------------===// + +def TransposeOp : Toy_Op<"transpose", + [Pure, DeclareOpInterfaceMethods]> { + let summary = "transpose operation"; + + let arguments = (ins F64Tensor:$input); + let results = (outs F64Tensor); + + let assemblyFormat = [{ + `(` $input `:` type($input) `)` attr-dict `to` type(results) + }]; + + // Enable registering canonicalization patterns with this operation. + let hasCanonicalizer = 1; + + // Allow building a TransposeOp with from the input operand. + let builders = [ + OpBuilder<(ins "Value":$input)> + ]; + + // Indicate that additional verification for this operation is necessary. + let hasVerifier = 1; +} + +#endif // TOY_OPS + diff --git a/tablegen/pom.xml b/tablegen/pom.xml new file mode 100644 index 0000000000..d90aab380f --- /dev/null +++ b/tablegen/pom.xml @@ -0,0 +1,56 @@ + + 4.0.0 + tablegen + jar + MLIR TableGen grammar + + org.antlr.grammars + grammarsv4 + 1.0-SNAPSHOT + + + + + org.antlr + antlr4-maven-plugin + ${antlr.version} + + ${basedir} + + TableGen.g4 + + true + true + + + + + antlr4 + + + + + + com.khubla.antlr + antlr4test-maven-plugin + ${antlr4test-maven-plugin.version} + + false + false + tableGenFile + TableGen + + examples/ + + + + + test + + + + + + + From a7f9f8d40a61ec541eeafd7d4fb4cca3d0ed54fc Mon Sep 17 00:00:00 2001 From: RIvance Date: Sat, 25 May 2024 15:12:22 +0800 Subject: [PATCH 2/2] chore(tablegen): EOF --- tablegen/TableGen.g4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tablegen/TableGen.g4 b/tablegen/TableGen.g4 index 4c4580e51e..be55b0f775 100644 --- a/tablegen/TableGen.g4 +++ b/tablegen/TableGen.g4 @@ -2,7 +2,7 @@ grammar TableGen; // TableGenFile ::= (Statement | IncludeDirective | PreprocessorDirective)* tableGenFile - : (statement | includeDirective | preprocessorDirective)* + : (statement | includeDirective | preprocessorDirective)* EOF ; preprocessorDirective