[llvm-branch-commits] [mlir] [mlir][IR] Auto-generate element type verification for VectorType (PR #102449)
https://github.com/River707 approved this pull request. https://github.com/llvm/llvm-project/pull/102449 ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] fce9dd6 - [mlir][NFC] Remove StandardTypes.h now that all usages point to BuiltinTypes.h
Author: River Riddle Date: 2020-12-16T20:41:42-08:00 New Revision: fce9dd6b252146d3d6e112be5026b9045419116d URL: https://github.com/llvm/llvm-project/commit/fce9dd6b252146d3d6e112be5026b9045419116d DIFF: https://github.com/llvm/llvm-project/commit/fce9dd6b252146d3d6e112be5026b9045419116d.diff LOG: [mlir][NFC] Remove StandardTypes.h now that all usages point to BuiltinTypes.h Differential Revision: https://reviews.llvm.org/D93430 Added: Modified: mlir/include/mlir/Dialect/ArmSVE/ArmSVEDialect.h mlir/lib/Dialect/ArmSVE/IR/ArmSVEDialect.cpp Removed: mlir/include/mlir/IR/StandardTypes.h diff --git a/mlir/include/mlir/Dialect/ArmSVE/ArmSVEDialect.h b/mlir/include/mlir/Dialect/ArmSVE/ArmSVEDialect.h index 15ca3403bef0..7689eb4b1378 100644 --- a/mlir/include/mlir/Dialect/ArmSVE/ArmSVEDialect.h +++ b/mlir/include/mlir/Dialect/ArmSVE/ArmSVEDialect.h @@ -13,9 +13,9 @@ #ifndef MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H #define MLIR_DIALECT_ARMSVE_ARMSVEDIALECT_H +#include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/OpDefinition.h" -#include "mlir/IR/StandardTypes.h" #include "mlir/Interfaces/SideEffectInterfaces.h" #include "mlir/Dialect/ArmSVE/ArmSVEDialect.h.inc" diff --git a/mlir/include/mlir/IR/StandardTypes.h b/mlir/include/mlir/IR/StandardTypes.h deleted file mode 100644 index bf186ef46019.. --- a/mlir/include/mlir/IR/StandardTypes.h +++ /dev/null @@ -1,16 +0,0 @@ -//===- StandardTypes.h - MLIR Standard Type Classes -*- C++ -*-===// -// -// 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 -// -//===--===// - -#ifndef MLIR_IR_STANDARDTYPES_H -#define MLIR_IR_STANDARDTYPES_H - -/// TODO: Remove this file when all references have been replaced by -/// BuiltinTypes.h. -#include "mlir/IR/BuiltinTypes.h" - -#endif // MLIR_IR_STANDARDTYPES_H diff --git a/mlir/lib/Dialect/ArmSVE/IR/ArmSVEDialect.cpp b/mlir/lib/Dialect/ArmSVE/IR/ArmSVEDialect.cpp index 2c76a64fac5c..c10458a442b2 100644 --- a/mlir/lib/Dialect/ArmSVE/IR/ArmSVEDialect.cpp +++ b/mlir/lib/Dialect/ArmSVE/IR/ArmSVEDialect.cpp @@ -15,7 +15,6 @@ #include "mlir/IR/Builders.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/IR/OpImplementation.h" -#include "mlir/IR/StandardTypes.h" #include "mlir/IR/TypeUtilities.h" #include "llvm/ADT/TypeSwitch.h" ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 1b97cdf - [mlir][IR][NFC] Move context/location parameters of builtin Type::get methods to the start of the parameter list
Author: River Riddle Date: 2020-12-17T13:01:36-08:00 New Revision: 1b97cdf885d6455841280b8da858835e641ee941 URL: https://github.com/llvm/llvm-project/commit/1b97cdf885d6455841280b8da858835e641ee941 DIFF: https://github.com/llvm/llvm-project/commit/1b97cdf885d6455841280b8da858835e641ee941.diff LOG: [mlir][IR][NFC] Move context/location parameters of builtin Type::get methods to the start of the parameter list This better matches the rest of the infrastructure, is much simpler, and makes it easier to move these types to being declaratively specified. Differential Revision: https://reviews.llvm.org/D93432 Added: Modified: flang/include/flang/Optimizer/Dialect/FIROps.td flang/lib/Lower/ConvertType.cpp flang/lib/Lower/IntrinsicCall.cpp flang/lib/Lower/RTBuilder.h flang/lib/Optimizer/Dialect/FIROps.cpp mlir/include/mlir/Dialect/AVX512/AVX512.td mlir/include/mlir/Dialect/Linalg/IR/LinalgStructuredOpsInterface.td mlir/include/mlir/IR/BuiltinTypes.h mlir/include/mlir/IR/OpBase.td mlir/lib/CAPI/IR/BuiltinTypes.cpp mlir/lib/Conversion/AsyncToLLVM/AsyncToLLVM.cpp mlir/lib/Conversion/GPUToVulkan/ConvertGPULaunchFuncToVulkanLaunchFunc.cpp mlir/lib/Conversion/LinalgToLLVM/LinalgToLLVM.cpp mlir/lib/Conversion/LinalgToStandard/LinalgToStandard.cpp mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp mlir/lib/Conversion/VectorToSCF/VectorToSCF.cpp mlir/lib/Dialect/Async/IR/Async.cpp mlir/lib/Dialect/Async/Transforms/AsyncRefCounting.cpp mlir/lib/Dialect/GPU/Transforms/AllReduceLowering.cpp mlir/lib/Dialect/GPU/Transforms/KernelOutlining.cpp mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp mlir/lib/Dialect/Linalg/Transforms/Promotion.cpp mlir/lib/Dialect/Quant/Utils/FakeQuantSupport.cpp mlir/lib/Dialect/Quant/Utils/UniformSupport.cpp mlir/lib/Dialect/SCF/Transforms/Utils.cpp mlir/lib/Dialect/SPIRV/IR/TargetAndABI.cpp mlir/lib/Dialect/SPIRV/Transforms/SPIRVConversion.cpp mlir/lib/Dialect/StandardOps/IR/Ops.cpp mlir/lib/Dialect/Vector/VectorOps.cpp mlir/lib/Dialect/Vector/VectorTransforms.cpp mlir/lib/IR/Builders.cpp mlir/lib/IR/BuiltinDialect.cpp mlir/lib/IR/BuiltinTypes.cpp mlir/lib/IR/Dialect.cpp mlir/lib/IR/MLIRContext.cpp mlir/lib/IR/Operation.cpp mlir/lib/IR/Value.cpp mlir/lib/Parser/DialectSymbolParser.cpp mlir/lib/Parser/TypeParser.cpp mlir/lib/Target/LLVMIR/ConvertFromLLVMIR.cpp mlir/lib/Target/SPIRV/Deserialization.cpp mlir/lib/Target/SPIRV/Serialization.cpp mlir/lib/Transforms/BufferResultsToOutParams.cpp mlir/lib/Transforms/NormalizeMemRefs.cpp mlir/lib/Transforms/Utils/DialectConversion.cpp mlir/test/EDSC/builder-api-test.cpp mlir/test/lib/Dialect/Test/TestDialect.cpp mlir/test/lib/Dialect/Test/TestPatterns.cpp mlir/test/lib/Transforms/TestDecomposeCallGraphTypes.cpp mlir/unittests/Dialect/Quant/QuantizationUtilsTest.cpp mlir/unittests/IR/AttributeTest.cpp mlir/unittests/TableGen/StructsGenTest.cpp Removed: diff --git a/flang/include/flang/Optimizer/Dialect/FIROps.td b/flang/include/flang/Optimizer/Dialect/FIROps.td index 8d7a6d4af950..cecd1cbbb46b 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROps.td +++ b/flang/include/flang/Optimizer/Dialect/FIROps.td @@ -2176,7 +2176,7 @@ def fir_DispatchOp : fir_Op<"dispatch", p.printOptionalAttrDict(getAttrs(), {"fn_type", "method"}); auto resTy{getResultTypes()}; llvm::SmallVector argTy(getOperandTypes()); -p << " : " << mlir::FunctionType::get(argTy, resTy, getContext()); +p << " : " << mlir::FunctionType::get(getContext(), argTy, resTy); }]; let extraClassDeclaration = [{ diff --git a/flang/lib/Lower/ConvertType.cpp b/flang/lib/Lower/ConvertType.cpp index 746d7ade9972..b3fa85d4691d 100644 --- a/flang/lib/Lower/ConvertType.cpp +++ b/flang/lib/Lower/ConvertType.cpp @@ -49,7 +49,7 @@ mlir::Type genFIRType(mlir::MLIRContext *context) { if constexpr (TC == Fortran::common::TypeCategory::Integer) { auto bits{Fortran::evaluate::Type::Scalar::bits}; -return mlir::IntegerType::get(bits, context); +return mlir::IntegerType::get(context, bits); } else if constexpr (TC == Fortran::common::TypeCategory::Logical || TC == Fortran::common::TypeCategory::Character || TC == Fortran::common::TypeCategory::Complex) { @@ -278,7 +278,7 @@ class TypeBuilder { // some sequence of `n` bytes mlir::Type gen(const Fortran::evaluate::StaticDataObject::Pointer &ptr) { -mlir::Type byteTy{mlir::IntegerType::get(8, context)}; +mlir::Type byteTy{mlir::IntegerType::get(context, 8)}; return fir::SequenceType::get(trivialShape(ptr->itemBytes()), byteTy); } diff --git a/flang/lib/Lower/IntrinsicCall.cpp b/flang/lib/Lower/IntrinsicCall.cpp index 0e0081ef664c..7053cd976
[llvm-branch-commits] [mlir] fc5cf50 - [mlir] Remove the MutableDictionaryAttr class
Author: River Riddle Date: 2020-12-17T17:18:42-08:00 New Revision: fc5cf50e892b5e2307de924923fe799702b055d2 URL: https://github.com/llvm/llvm-project/commit/fc5cf50e892b5e2307de924923fe799702b055d2 DIFF: https://github.com/llvm/llvm-project/commit/fc5cf50e892b5e2307de924923fe799702b055d2.diff LOG: [mlir] Remove the MutableDictionaryAttr class This class used to serve a few useful purposes: * Allowed containing a null DictionaryAttr * Provided some simple mutable API around a DictionaryAttr The first of which is no longer an issue now that there is much better caching support for attributes in general, and a cache in the context for empty dictionaries. The second results in more trouble than it's worth because it mutates the internal dictionary on every action, leading to a potentially large number of dictionary copies. NamedAttrList is a much better alternative for the second use case, and should be modified as needed to better fit it's usage as a DictionaryAttrBuilder. Differential Revision: https://reviews.llvm.org/D93442 Added: Modified: flang/lib/Optimizer/Dialect/FIROps.cpp mlir/docs/OpDefinitions.md mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td mlir/include/mlir/IR/BuiltinAttributes.h mlir/include/mlir/IR/BuiltinOps.td mlir/include/mlir/IR/FunctionSupport.h mlir/include/mlir/IR/OpDefinition.h mlir/include/mlir/IR/Operation.h mlir/include/mlir/IR/OperationSupport.h mlir/lib/CAPI/IR/IR.cpp mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp mlir/lib/Dialect/GPU/Transforms/AsyncRegionRewriter.cpp mlir/lib/Dialect/LLVMIR/IR/LLVMDialect.cpp mlir/lib/IR/Attributes.cpp mlir/lib/IR/BuiltinAttributes.cpp mlir/lib/IR/BuiltinDialect.cpp mlir/lib/IR/FunctionSupport.cpp mlir/lib/IR/Operation.cpp mlir/lib/IR/OperationSupport.cpp mlir/lib/IR/SymbolTable.cpp mlir/lib/Pass/IRPrinting.cpp mlir/lib/Target/SPIRV/Deserialization.cpp mlir/lib/Transforms/SCCP.cpp mlir/lib/Transforms/Utils/DialectConversion.cpp mlir/test/lib/Dialect/Test/TestDialect.cpp mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/flang/lib/Optimizer/Dialect/FIROps.cpp b/flang/lib/Optimizer/Dialect/FIROps.cpp index e8d8d6c64d1e..7ab24320a666 100644 --- a/flang/lib/Optimizer/Dialect/FIROps.cpp +++ b/flang/lib/Optimizer/Dialect/FIROps.cpp @@ -1008,7 +1008,7 @@ getMutableSuccessorOperands(unsigned pos, mlir::MutableOperandRange operands, StringRef offsetAttr) { Operation *owner = operands.getOwner(); NamedAttribute targetOffsetAttr = - *owner->getMutableAttrDict().getNamed(offsetAttr); + *owner->getAttrDictionary().getNamed(offsetAttr); return getSubOperands( pos, operands, targetOffsetAttr.second.cast(), mlir::MutableOperandRange::OperandSegment(pos, targetOffsetAttr)); diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index c5ffe452b927..0b235f993e3d 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -761,7 +761,7 @@ declarative parameter to `print` method argument is detailed below: - Single: `Type` - Optional: `Type` - Variadic: `TypeRange` -* `attr-dict` Directive: `const MutableDictionaryAttr&` +* `attr-dict` Directive: `DictionaryAttr` When a variable is optional, the provided value may be null. diff --git a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td index 9608e15bb81a..df022ef47b33 100644 --- a/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td +++ b/mlir/include/mlir/Dialect/LLVMIR/LLVMOps.td @@ -962,7 +962,7 @@ def LLVM_LLVMFuncOp : LLVM_Op<"func", OpBuilderDAG<(ins "StringRef":$name, "LLVMType":$type, CArg<"Linkage", "Linkage::External">:$linkage, CArg<"ArrayRef", "{}">:$attrs, - CArg<"ArrayRef", "{}">:$argAttrs)> + CArg<"ArrayRef", "{}">:$argAttrs)> ]; let extraClassDeclaration = [{ diff --git a/mlir/include/mlir/IR/BuiltinAttributes.h b/mlir/include/mlir/IR/BuiltinAttributes.h index 300741a7923b..34e7e8cfce12 100644 --- a/mlir/include/mlir/IR/BuiltinAttributes.h +++ b/mlir/include/mlir/IR/BuiltinAttributes.h @@ -1472,75 +1472,6 @@ auto ElementsAttr::getValues() const -> iterator_range { llvm_unreachable("unexpected attribute kind"); } -//===--===// -// MutableDictionaryAttr -//===--===// - -/// A MutableDictionaryAttr is a mutable wrapper around a DictionaryAttr. It -/// provides additional interfaces for adding, removing, replacing attributes -/// within a DictionaryAttr. -/// -/// We assume there will be relatively few attributes on a given operation -/// (maybe a dozen or so, but not hundreds or thousands) s
[llvm-branch-commits] [mlir] c78219f - [mlir] Add a new builtin `unrealized_conversion_cast` operation
Author: River Riddle Date: 2021-01-20T16:28:18-08:00 New Revision: c78219f644c7a6e352cd416f8ebb4374b745967e URL: https://github.com/llvm/llvm-project/commit/c78219f644c7a6e352cd416f8ebb4374b745967e DIFF: https://github.com/llvm/llvm-project/commit/c78219f644c7a6e352cd416f8ebb4374b745967e.diff LOG: [mlir] Add a new builtin `unrealized_conversion_cast` operation An `unrealized_conversion_cast` operation represents an unrealized conversion from one set of types to another, that is used to enable the inter-mixing of different type systems. This operation should not be attributed any special representational or execution semantics, and is generally only intended to be used to satisfy the temporary intermixing of type systems during the conversion of one type system to another. This operation was discussed in the following RFC(and ODM): https://llvm.discourse.group/t/open-meeting-1-14-dialect-conversion-and-type-conversion-the-question-of-cast-operations/ Differential Revision: https://reviews.llvm.org/D94832 Added: mlir/test/Dialect/Builtin/canonicalize.mlir mlir/test/Dialect/Builtin/invalid.mlir mlir/test/Dialect/Builtin/ops.mlir Modified: mlir/include/mlir/IR/BuiltinOps.h mlir/include/mlir/IR/BuiltinOps.td mlir/lib/IR/BuiltinDialect.cpp mlir/lib/IR/CMakeLists.txt Removed: diff --git a/mlir/include/mlir/IR/BuiltinOps.h b/mlir/include/mlir/IR/BuiltinOps.h index c695a005283b..c0163b148f3c 100644 --- a/mlir/include/mlir/IR/BuiltinOps.h +++ b/mlir/include/mlir/IR/BuiltinOps.h @@ -17,6 +17,8 @@ #include "mlir/IR/OwningOpRef.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Interfaces/CallInterfaces.h" +#include "mlir/Interfaces/CastInterfaces.h" +#include "mlir/Interfaces/SideEffectInterfaces.h" #include "llvm/Support/PointerLikeTypeTraits.h" //===--===// diff --git a/mlir/include/mlir/IR/BuiltinOps.td b/mlir/include/mlir/IR/BuiltinOps.td index 86de251094cd..2c4d47d61cbe 100644 --- a/mlir/include/mlir/IR/BuiltinOps.td +++ b/mlir/include/mlir/IR/BuiltinOps.td @@ -17,6 +17,8 @@ include "mlir/IR/BuiltinDialect.td" include "mlir/IR/SymbolInterfaces.td" include "mlir/Interfaces/CallInterfaces.td" +include "mlir/Interfaces/CastInterfaces.td" +include "mlir/Interfaces/SideEffectInterfaces.td" // Base class for Builtin dialect ops. class Builtin_Op traits = []> : @@ -220,4 +222,53 @@ def ModuleTerminatorOp : Builtin_Op<"module_terminator", [ let assemblyFormat = "attr-dict"; } +//===--===// +// UnrealizedConversionCastOp +//===--===// + +def UnrealizedConversionCastOp : Builtin_Op<"unrealized_conversion_cast", [ +DeclareOpInterfaceMethods, NoSideEffect + ]> { + let summary = "An unrealized conversion from one set of types to another"; + let description = [{ +An `unrealized_conversion_cast` operation represents an unrealized +conversion from one set of types to another, that is used to enable the +inter-mixing of diff erent type systems. This operation should not be +attributed any special representational or execution semantics, and is +generally only intended to be used to satisfy the temporary intermixing of +type systems during the conversion of one type system to another. + +This operation may produce results of arity 1-N, and accept as input +operands of arity 0-N. + +Example: + +```mlir +// An unrealized 0-1 conversion. These types of conversions are useful in +// cases where a type is removed from the type system, but not all uses have +// been converted. For example, imagine we have a tuple type that is +// expanded to its element types. If only some uses of an empty tuple type +// instance are converted we still need an instance of the tuple type, but +// have no inputs to the unrealized conversion. +%result = unrealized_conversion_cast to !bar.tuple_type<> + +// An unrealized 1-1 conversion. +%result1 = unrealized_conversion_cast %operand : !foo.type to !bar.lowered_type + +// An unrealized 1-N conversion. +%results2:2 = unrealized_conversion_cast %tuple_operand : !foo.tuple_type to !foo.type, !foo.type + +// An unrealized N-1 conversion. +%result3 = unrealized_conversion_cast %operand, %operand : !foo.type, !foo.type to !bar.tuple_type +``` + }]; + + let arguments = (ins Variadic:$inputs); + let results = (outs Variadic:$outputs); + let assemblyFormat = [{ +($inputs^ `:` type($inputs))? `to` type($outputs) attr-dict + }]; + let hasFolder = 1; +} + #endif // BUILTIN_OPS diff --git a/mlir/lib/IR/BuiltinDialect.cpp b/mlir/lib/IR/BuiltinDialect.cpp index 2cd90f3d0fde..138321e734e2 100644 --- a/mlir/lib/IR/BuiltinDialect.cpp +++ b/mlir/lib/IR/
[llvm-branch-commits] [mlir] 6ccf2d6 - [mlir] Add an interface for Cast-Like operations
Author: River Riddle Date: 2021-01-20T16:28:17-08:00 New Revision: 6ccf2d62b4876c88427ae97d0cd3c9ed4330560a URL: https://github.com/llvm/llvm-project/commit/6ccf2d62b4876c88427ae97d0cd3c9ed4330560a DIFF: https://github.com/llvm/llvm-project/commit/6ccf2d62b4876c88427ae97d0cd3c9ed4330560a.diff LOG: [mlir] Add an interface for Cast-Like operations A cast-like operation is one that converts from a set of input types to a set of output types. The arity of the inputs may be from 0-N, whereas the arity of the outputs may be anything from 1-N. Cast-like operations are removable in cases where they produce a "no-op", i.e when the input types and output types match 1-1. Differential Revision: https://reviews.llvm.org/D94831 Added: mlir/include/mlir/Interfaces/CastInterfaces.h mlir/include/mlir/Interfaces/CastInterfaces.td mlir/lib/Interfaces/CastInterfaces.cpp Modified: mlir/docs/Tutorials/Toy/Ch-4.md mlir/examples/toy/Ch4/CMakeLists.txt mlir/examples/toy/Ch4/include/toy/Dialect.h mlir/examples/toy/Ch4/include/toy/Ops.td mlir/examples/toy/Ch4/mlir/Dialect.cpp mlir/examples/toy/Ch4/mlir/ToyCombine.cpp mlir/examples/toy/Ch5/CMakeLists.txt mlir/examples/toy/Ch5/include/toy/Dialect.h mlir/examples/toy/Ch5/include/toy/Ops.td mlir/examples/toy/Ch5/mlir/Dialect.cpp mlir/examples/toy/Ch5/mlir/ToyCombine.cpp mlir/examples/toy/Ch6/CMakeLists.txt mlir/examples/toy/Ch6/include/toy/Dialect.h mlir/examples/toy/Ch6/include/toy/Ops.td mlir/examples/toy/Ch6/mlir/Dialect.cpp mlir/examples/toy/Ch6/mlir/ToyCombine.cpp mlir/examples/toy/Ch7/CMakeLists.txt mlir/examples/toy/Ch7/include/toy/Dialect.h mlir/examples/toy/Ch7/include/toy/Ops.td mlir/examples/toy/Ch7/mlir/Dialect.cpp mlir/examples/toy/Ch7/mlir/ToyCombine.cpp mlir/include/mlir/Dialect/StandardOps/IR/Ops.h mlir/include/mlir/Dialect/StandardOps/IR/Ops.td mlir/include/mlir/Dialect/Tensor/IR/Tensor.h mlir/include/mlir/Dialect/Tensor/IR/TensorOps.td mlir/include/mlir/IR/Diagnostics.h mlir/include/mlir/IR/OpDefinition.h mlir/include/mlir/Interfaces/CMakeLists.txt mlir/lib/Dialect/Shape/IR/CMakeLists.txt mlir/lib/Dialect/StandardOps/CMakeLists.txt mlir/lib/Dialect/StandardOps/IR/Ops.cpp mlir/lib/Dialect/Tensor/IR/CMakeLists.txt mlir/lib/Dialect/Tensor/IR/TensorOps.cpp mlir/lib/IR/Operation.cpp mlir/lib/Interfaces/CMakeLists.txt Removed: diff --git a/mlir/docs/Tutorials/Toy/Ch-4.md b/mlir/docs/Tutorials/Toy/Ch-4.md index dc1314419320..c454a762e2b5 100644 --- a/mlir/docs/Tutorials/Toy/Ch-4.md +++ b/mlir/docs/Tutorials/Toy/Ch-4.md @@ -182,26 +182,50 @@ to add a new operation to the Toy dialect, `ToyCastOp`(toy.cast), to represent casts between two diff erent shapes. ```tablegen -def CastOp : Toy_Op<"cast", [NoSideEffect, SameOperandsAndResultShape]> { +def CastOp : Toy_Op<"cast", [ +DeclareOpInterfaceMethods, +NoSideEffect, +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 the rank should be the same and static dimensions should match. The -operation is invalid if converting to a mismatching constant dimension. +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); +} +``` + +Note that the definition of this cast operation adds a `CastOpInterface` to the +traits list. This interface provides several utilities for cast-like operation, +such as folding identity casts and verification. We hook into this interface by +providing a definition for the `areCastCompatible` method: - // Set the folder bit so that we can fold redundant cast operations. - let hasFolder = 1; +```c++ +/// Returns true if the given set of input and result types are compatible with +/// this cast operation. This is required by the `CastOpInterface` to verify +/// this operation and provide other additional utilities. +bool CastOp::areCastCompatible(TypeRange inputs, TypeRange outputs) { + if (inputs.size() != 1 || outputs.size() != 1) +return false; + // The inputs must be Tensors with the same element type. + TensorType input = inputs.front().dyn_cast(); + TensorType output = outputs.front().dyn_cast(); + if (!input || !output || input.getElementType() != output.getElementType()) +return false; + // The shape is required to match if both types are ranked. + return !input.hasRank() || !output.hasRank() ||
[llvm-branch-commits] [mlir] 825c2b4 - [mlir][OpFormatGen] Fix incorrect kind used for RegionsDirective
Author: River Riddle Date: 2021-01-20T16:50:59-08:00 New Revision: 825c2b4a41c7df935dc12fdfab9879b98c744e1e URL: https://github.com/llvm/llvm-project/commit/825c2b4a41c7df935dc12fdfab9879b98c744e1e DIFF: https://github.com/llvm/llvm-project/commit/825c2b4a41c7df935dc12fdfab9879b98c744e1e.diff LOG: [mlir][OpFormatGen] Fix incorrect kind used for RegionsDirective I attempted to write a test case for this, but the situations in which the kind is used for RegionDirective and ResultsDirective have zero overlap; meaning that there isn't a situation in which sharing the kind creates a conflict. Differential Revision: https://reviews.llvm.org/D94988 Added: Modified: mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp index ca504530cffa..6010bba255ec 100644 --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -166,7 +166,7 @@ using OperandsDirective = DirectiveElement; /// This class represents the `regions` directive. This directive represents /// all of the regions of an operation. -using RegionsDirective = DirectiveElement; +using RegionsDirective = DirectiveElement; /// This class represents the `results` directive. This directive represents /// all of the results of an operation. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 29d420e - [mlir][OpFormatGen] Add support for anchoring optional groups with types
Author: River Riddle Date: 2021-01-22T12:07:27-08:00 New Revision: 29d420e0bf0273cdef35b2d2453f0f574d1e8313 URL: https://github.com/llvm/llvm-project/commit/29d420e0bf0273cdef35b2d2453f0f574d1e8313 DIFF: https://github.com/llvm/llvm-project/commit/29d420e0bf0273cdef35b2d2453f0f574d1e8313.diff LOG: [mlir][OpFormatGen] Add support for anchoring optional groups with types This revision adds support for using either operand or result types to anchor an optional group. It also removes the arbitrary restriction that type directives must refer to variables in the same group, which is overly limiting for a declarative format syntax. Fixes PR#48784 Differential Revision: https://reviews.llvm.org/D95109 Added: Modified: mlir/docs/OpDefinitions.md mlir/test/lib/Dialect/Test/TestOps.td mlir/test/mlir-tblgen/op-format-spec.td mlir/test/mlir-tblgen/op-format.mlir mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index dd522904dd73..8a7f6a238732 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -777,8 +777,8 @@ information. An optional group is defined by wrapping a set of elements within * The first element of the group must either be a attribute, literal, operand, or region. - This is because the first element must be optionally parsable. -* Exactly one argument variable within the group must be marked as the anchor -of the group. +* Exactly one argument variable or type directive within the group must be +marked as the anchor of the group. - The anchor is the element whose presence controls whether the group should be printed/parsed. - An element is marked as the anchor by adding a trailing `^`. @@ -789,11 +789,9 @@ information. An optional group is defined by wrapping a set of elements within valid elements within the group. - Any attribute variable may be used, but only optional attributes can be marked as the anchor. -- Only variadic or optional operand arguments can be used. +- Only variadic or optional results and operand arguments and can be used. - All region variables can be used. When a non-variable length region is used, if the group is not present the region is empty. -- The operands to a type directive must be defined within the optional -group. An example of an operation with an optional group is `std.return`, which has a variadic number of operands. diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index d1cbe77ac21b..89d2ee87356b 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1571,6 +1571,25 @@ def FormatOptionalOperandResultBOp : FormatOptionalOperandResultOpBase<"b", [{ (`[` $variadic^ `]`)? attr-dict }]>; +// Test optional result type formatting. +class FormatOptionalResultOpBase +: TEST_Op<"format_optional_result_" # suffix # "_op", + [AttrSizedResultSegments]> { + let results = (outs Optional:$optional, Variadic:$variadic); + let assemblyFormat = fmt; +} +def FormatOptionalResultAOp : FormatOptionalResultOpBase<"a", [{ + (`:` type($optional)^ `->` type($variadic))? attr-dict +}]>; + +def FormatOptionalResultBOp : FormatOptionalResultOpBase<"b", [{ + (`:` type($optional) `->` type($variadic)^)? attr-dict +}]>; + +def FormatOptionalResultCOp : FormatOptionalResultOpBase<"c", [{ + (`:` functional-type($optional, $variadic)^)? attr-dict +}]>; + def FormatTwoVariadicOperandsNoBuildableTypeOp : TEST_Op<"format_two_variadic_operands_no_buildable_type_op", [AttrSizedOperandSegments]> { diff --git a/mlir/test/mlir-tblgen/op-format-spec.td b/mlir/test/mlir-tblgen/op-format-spec.td index 424dbb83c276..652bbd08679d 100644 --- a/mlir/test/mlir-tblgen/op-format-spec.td +++ b/mlir/test/mlir-tblgen/op-format-spec.td @@ -333,7 +333,7 @@ def OptionalInvalidC : TestFormat_Op<"optional_invalid_c", [{ def OptionalInvalidD : TestFormat_Op<"optional_invalid_d", [{ (type($operand) $operand^)? attr-dict }]>, Arguments<(ins Optional:$operand)>; -// CHECK: error: type directive can only refer to variables within the optional group +// CHECK: error: only literals, types, and variables can be used within an optional group def OptionalInvalidE : TestFormat_Op<"optional_invalid_e", [{ (`,` $attr^ type(operands))? attr-dict }]>, Arguments<(ins OptionalAttr:$attr)>; @@ -349,9 +349,9 @@ def OptionalInvalidG : TestFormat_Op<"optional_invalid_g", [{ def OptionalInvalidH : TestFormat_Op<"optional_invalid_h", [{ ($arg^) attr-dict }]>, Arguments<(ins I64:$arg)>; -// CHECK: error: only variables can be used to anchor an optional group +// CHECK: error: only literals, types, and variables can be used within an optional group def Opti
[llvm-branch-commits] [mlir] fa20ab7 - [mlir][PDL] Add append specialization for ByteCode OpCode to fix GCC5 build
Author: River Riddle Date: 2020-12-01T17:13:16-08:00 New Revision: fa20ab7b1bb2c77570f46888fe46e6ecf7aeafc6 URL: https://github.com/llvm/llvm-project/commit/fa20ab7b1bb2c77570f46888fe46e6ecf7aeafc6 DIFF: https://github.com/llvm/llvm-project/commit/fa20ab7b1bb2c77570f46888fe46e6ecf7aeafc6.diff LOG: [mlir][PDL] Add append specialization for ByteCode OpCode to fix GCC5 build Added: Modified: mlir/lib/Rewrite/ByteCode.cpp Removed: diff --git a/mlir/lib/Rewrite/ByteCode.cpp b/mlir/lib/Rewrite/ByteCode.cpp index ae5f322d2948..972f5097d4e7 100644 --- a/mlir/lib/Rewrite/ByteCode.cpp +++ b/mlir/lib/Rewrite/ByteCode.cpp @@ -265,6 +265,7 @@ struct ByteCodeWriter { /// Append a field to the bytecode. void append(ByteCodeField field) { bytecode.push_back(field); } + void append(OpCode opCode) { bytecode.push_back(opCode); } /// Append an address to the bytecode. void append(ByteCodeAddr field) { ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 8affe88 - [mlir][PDL] Use .getOperation() when construction SuccessorRange to avoid ambiguous constructor in GCC5
Author: River Riddle Date: 2020-12-01T18:13:27-08:00 New Revision: 8affe88108a1d5f37303cb2128e0650e70ab1eae URL: https://github.com/llvm/llvm-project/commit/8affe88108a1d5f37303cb2128e0650e70ab1eae DIFF: https://github.com/llvm/llvm-project/commit/8affe88108a1d5f37303cb2128e0650e70ab1eae.diff LOG: [mlir][PDL] Use .getOperation() when construction SuccessorRange to avoid ambiguous constructor in GCC5 Added: Modified: mlir/lib/Rewrite/ByteCode.cpp Removed: diff --git a/mlir/lib/Rewrite/ByteCode.cpp b/mlir/lib/Rewrite/ByteCode.cpp index 972f5097d4e7..33a754bb3c07 100644 --- a/mlir/lib/Rewrite/ByteCode.cpp +++ b/mlir/lib/Rewrite/ByteCode.cpp @@ -529,7 +529,7 @@ void Generator::generate(pdl_interp::AreEqualOp op, ByteCodeWriter &writer) { writer.append(OpCode::AreEqual, op.lhs(), op.rhs(), op.getSuccessors()); } void Generator::generate(pdl_interp::BranchOp op, ByteCodeWriter &writer) { - writer.append(OpCode::Branch, SuccessorRange(op)); + writer.append(OpCode::Branch, SuccessorRange(op.getOperation())); } void Generator::generate(pdl_interp::CheckAttributeOp op, ByteCodeWriter &writer) { @@ -637,8 +637,9 @@ void Generator::generate(pdl_interp::RecordMatchOp op, ByteCodeWriter &writer) { ByteCodeField patternIndex = patterns.size(); patterns.emplace_back(PDLByteCodePattern::create( op, rewriterToAddr[op.rewriter().getLeafReference()])); - writer.append(OpCode::RecordMatch, patternIndex, SuccessorRange(op), -op.matchedOps(), op.inputs()); + writer.append(OpCode::RecordMatch, patternIndex, +SuccessorRange(op.getOperation()), op.matchedOps(), +op.inputs()); } void Generator::generate(pdl_interp::ReplaceOp op, ByteCodeWriter &writer) { writer.append(OpCode::ReplaceOp, op.operation(), op.replValues()); ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 7d746b3 - [mlir][PDL] Forward captured single entity constraint functions instead of copy-capture
Author: River Riddle Date: 2020-12-01T21:08:34-08:00 New Revision: 7d746b390c6e3b9b4eded3eb84e5973a1b689775 URL: https://github.com/llvm/llvm-project/commit/7d746b390c6e3b9b4eded3eb84e5973a1b689775 DIFF: https://github.com/llvm/llvm-project/commit/7d746b390c6e3b9b4eded3eb84e5973a1b689775.diff LOG: [mlir][PDL] Forward captured single entity constraint functions instead of copy-capture Added: Modified: mlir/include/mlir/IR/PatternMatch.h Removed: diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index 4fdc0878c590..0bbb2216ee7b 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -355,12 +355,14 @@ class PDLPatternModule { std::enable_if_t, ArrayAttr, PatternRewriter &>::value> registerConstraintFunction(StringRef name, SingleEntityFn &&constraintFn) { -registerConstraintFunction(name, [=](ArrayRef values, - ArrayAttr constantParams, - PatternRewriter &rewriter) { - assert(values.size() == 1 && "expected values to have a single entity"); - return constraintFn(values[0], constantParams, rewriter); -}); +registerConstraintFunction( +name, [constraintFn = std::forward(constraintFn)]( + ArrayRef values, ArrayAttr constantParams, + PatternRewriter &rewriter) { + assert(values.size() == 1 && + "expected values to have a single entity"); + return constraintFn(values[0], constantParams, rewriter); +}); } /// Register a creation function. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] f80b630 - [mlir][PDL] Use explicit loop over llvm::find to fix MSVC breakage
Author: River Riddle Date: 2020-12-02T10:43:16-08:00 New Revision: f80b630460e2a1646fe432f919fa378cabb002c8 URL: https://github.com/llvm/llvm-project/commit/f80b630460e2a1646fe432f919fa378cabb002c8 DIFF: https://github.com/llvm/llvm-project/commit/f80b630460e2a1646fe432f919fa378cabb002c8.diff LOG: [mlir][PDL] Use explicit loop over llvm::find to fix MSVC breakage Added: Modified: mlir/lib/Rewrite/ByteCode.cpp Removed: diff --git a/mlir/lib/Rewrite/ByteCode.cpp b/mlir/lib/Rewrite/ByteCode.cpp index 33a754bb3c07..481e7b6db1d1 100644 --- a/mlir/lib/Rewrite/ByteCode.cpp +++ b/mlir/lib/Rewrite/ByteCode.cpp @@ -769,8 +769,10 @@ class ByteCodeExecutor { // Check to see if the attribute value is within the case list. Jump to // the correct successor index based on the result. -auto it = llvm::find(cases, value); -selectJump(it == cases.end() ? size_t(0) : ((it - cases.begin()) + 1)); +for (auto it = cases.begin(), e = cases.end(); it != e; ++it) + if (*it == value) +return selectJump(size_t((it - cases.begin()) + 1)); +selectJump(size_t(0)); } /// Internal implementation of reading various data types from the bytecode ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 00c6ef8 - [mlir][Pass] Remove the restriction that PassManager can only run on ModuleOp
Author: River Riddle Date: 2020-12-03T15:47:01-08:00 New Revision: 00c6ef8628a6ee062d5104692a92d5e000dd7c05 URL: https://github.com/llvm/llvm-project/commit/00c6ef8628a6ee062d5104692a92d5e000dd7c05 DIFF: https://github.com/llvm/llvm-project/commit/00c6ef8628a6ee062d5104692a92d5e000dd7c05.diff LOG: [mlir][Pass] Remove the restriction that PassManager can only run on ModuleOp This was a somewhat important restriction in the past when ModuleOp was distinctly the top-level container operation, as well as before the pass manager had support for running nested pass managers natively. With these two issues fading away, there isn't really a good reason to enforce that a ModuleOp is the thing running within a pass manager. As such, this revision removes the restriction and allows for users to pass in the name of the operation that the pass manager will be scheduled on. The only remaining dependency on BuiltinOps from Pass after this revision is due to FunctionPass, which will be resolved in a followup revision. Differential Revision: https://reviews.llvm.org/D92450 Added: Modified: mlir/include/mlir/Pass/AnalysisManager.h mlir/include/mlir/Pass/PassManager.h mlir/lib/Pass/IRPrinting.cpp mlir/lib/Pass/Pass.cpp mlir/lib/Pass/PassManagerOptions.cpp Removed: diff --git a/mlir/include/mlir/Pass/AnalysisManager.h b/mlir/include/mlir/Pass/AnalysisManager.h index de428da5abd4..ec6b7696ce60 100644 --- a/mlir/include/mlir/Pass/AnalysisManager.h +++ b/mlir/include/mlir/Pass/AnalysisManager.h @@ -9,7 +9,7 @@ #ifndef MLIR_PASS_ANALYSISMANAGER_H #define MLIR_PASS_ANALYSISMANAGER_H -#include "mlir/IR/BuiltinOps.h" +#include "mlir/IR/Operation.h" #include "mlir/Pass/PassInstrumentation.h" #include "mlir/Support/LLVM.h" #include "llvm/ADT/DenseMap.h" @@ -177,8 +177,8 @@ class AnalysisMap { bool wasInserted; std::tie(it, wasInserted) = analyses.try_emplace(id); -// If we don't have a cached analysis for this function, compute it directly -// and add it to the cache. +// If we don't have a cached analysis for this operation, compute it +// directly and add it to the cache. if (wasInserted) { if (pi) pi->runBeforeAnalysis(getAnalysisName(), id, ir); @@ -321,14 +321,14 @@ class AnalysisManager { friend class ModuleAnalysisManager; }; -/// An analysis manager class specifically for the top-level module operation. -/// This class contains the memory allocations for all nested analysis managers, -/// and provides an anchor point. This is necessary because AnalysisManager is +/// An analysis manager class specifically for the top-level operation. This +/// class contains the memory allocations for all nested analysis managers, and +/// provides an anchor point. This is necessary because AnalysisManager is /// designed to be a thin wrapper around an existing analysis map instance. class ModuleAnalysisManager { public: - ModuleAnalysisManager(ModuleOp module, PassInstrumentor *passInstrumentor) - : analyses(module), passInstrumentor(passInstrumentor) {} + ModuleAnalysisManager(Operation *op, PassInstrumentor *passInstrumentor) + : analyses(op), passInstrumentor(passInstrumentor) {} ModuleAnalysisManager(const ModuleAnalysisManager &) = delete; ModuleAnalysisManager &operator=(const ModuleAnalysisManager &) = delete; diff --git a/mlir/include/mlir/Pass/PassManager.h b/mlir/include/mlir/Pass/PassManager.h index eb21359d6211..5e9c9a790d29 100644 --- a/mlir/include/mlir/Pass/PassManager.h +++ b/mlir/include/mlir/Pass/PassManager.h @@ -28,7 +28,6 @@ namespace mlir { class AnalysisManager; class Identifier; class MLIRContext; -class ModuleOp; class Operation; class Pass; class PassInstrumentation; @@ -158,12 +157,20 @@ enum class PassDisplayMode { /// The main pass manager and pipeline builder. class PassManager : public OpPassManager { public: - PassManager(MLIRContext *ctx, Nesting nesting = Nesting::Explicit); + /// Create a new pass manager under the given context with a specific nesting + /// style. The created pass manager can schedule operations that match + /// `operationName`. + PassManager(MLIRContext *ctx, Nesting nesting = Nesting::Explicit, + StringRef operationName = "module"); + PassManager(MLIRContext *ctx, StringRef operationName) + : PassManager(ctx, Nesting::Explicit, operationName) {} ~PassManager(); - /// Run the passes within this manager on the provided module. + /// Run the passes within this manager on the provided operation. The + /// specified operation must have the same name as the one provided the pass + /// manager on construction. LLVM_NODISCARD - LogicalResult run(ModuleOp module); + LogicalResult run(Operation *op); /// Return an instance of the context. MLIRContext *getContext() const { return context; } @@ -318,11 +325,11 @@ class Pass
[llvm-branch-commits] [mlir] b579803 - [mlir][Parser] Don't hardcode the use of ModuleOp in the parser
Author: River Riddle Date: 2020-12-03T15:47:02-08:00 New Revision: b57980309a699a47a46b5b5749b36fea06eaaf33 URL: https://github.com/llvm/llvm-project/commit/b57980309a699a47a46b5b5749b36fea06eaaf33 DIFF: https://github.com/llvm/llvm-project/commit/b57980309a699a47a46b5b5749b36fea06eaaf33.diff LOG: [mlir][Parser] Don't hardcode the use of ModuleOp in the parser This was important when ModuleOp was the only top level operation, but that isn't necessarily the case anymore. This is one of the last remaining aspects of the infrastructure that is hardcoded to ModuleOp. Differential Revision: https://reviews.llvm.org/D92605 Added: mlir/include/mlir/IR/OwningOpRef.h Modified: mlir/include/mlir/Dialect/SPIRV/SPIRVModule.h mlir/include/mlir/IR/BuiltinOps.h mlir/include/mlir/IR/OpDefinition.h mlir/include/mlir/Parser.h mlir/lib/Parser/Parser.cpp Removed: mlir/include/mlir/IR/OwningOpRefBase.h diff --git a/mlir/include/mlir/Dialect/SPIRV/SPIRVModule.h b/mlir/include/mlir/Dialect/SPIRV/SPIRVModule.h index a53331eda4fa..9f2692f8e903 100644 --- a/mlir/include/mlir/Dialect/SPIRV/SPIRVModule.h +++ b/mlir/include/mlir/Dialect/SPIRV/SPIRVModule.h @@ -10,7 +10,7 @@ #define MLIR_DIALECT_SPIRV_SPIRVMODULE_H #include "mlir/Dialect/SPIRV/SPIRVOps.h" -#include "mlir/IR/OwningOpRefBase.h" +#include "mlir/IR/OwningOpRef.h" namespace mlir { namespace spirv { @@ -18,9 +18,10 @@ namespace spirv { /// This class acts as an owning reference to a SPIR-V module, and will /// automatically destroy the held module on destruction if the held module /// is valid. -class OwningSPIRVModuleRef : public OwningOpRefBase { +// TODO: Remove this class in favor of using OwningOpRef directly. +class OwningSPIRVModuleRef : public OwningOpRef { public: - using OwningOpRefBase::OwningOpRefBase; + using OwningOpRef::OwningOpRef; }; } // end namespace spirv diff --git a/mlir/include/mlir/IR/BuiltinOps.h b/mlir/include/mlir/IR/BuiltinOps.h index 811b87ba4f09..dd23f90af6c7 100644 --- a/mlir/include/mlir/IR/BuiltinOps.h +++ b/mlir/include/mlir/IR/BuiltinOps.h @@ -14,7 +14,7 @@ #define MLIR_IR_BUILTINOPS_H_ #include "mlir/IR/FunctionSupport.h" -#include "mlir/IR/OwningOpRefBase.h" +#include "mlir/IR/OwningOpRef.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Interfaces/CallInterfaces.h" #include "llvm/Support/PointerLikeTypeTraits.h" @@ -33,9 +33,12 @@ namespace mlir { /// This class acts as an owning reference to a module, and will automatically /// destroy the held module on destruction if the held module is valid. -class OwningModuleRef : public OwningOpRefBase { +// TODO: Remove this class in favor of using OwningOpRef directly. +class OwningModuleRef : public OwningOpRef { public: - using OwningOpRefBase::OwningOpRefBase; + using OwningOpRef::OwningOpRef; + OwningModuleRef(OwningOpRef &&other) + : OwningOpRef(std::move(other)) {} }; } // end namespace mlir diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h index 2867c4c73290..b200f7c2dc6c 100644 --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -808,6 +808,9 @@ struct SingleBlockImplicitTerminator { } public: +/// The type of the operation used as the implicit terminator type. +using ImplicitTerminatorOpT = TerminatorOpType; + static LogicalResult verifyTrait(Operation *op) { for (unsigned i = 0, e = op->getNumRegions(); i < e; ++i) { Region ®ion = op->getRegion(i); diff --git a/mlir/include/mlir/IR/OwningOpRefBase.h b/mlir/include/mlir/IR/OwningOpRef.h similarity index 70% rename from mlir/include/mlir/IR/OwningOpRefBase.h rename to mlir/include/mlir/IR/OwningOpRef.h index bfdf98f6f37e..c7ea1c615e60 100644 --- a/mlir/include/mlir/IR/OwningOpRefBase.h +++ b/mlir/include/mlir/IR/OwningOpRef.h @@ -1,4 +1,4 @@ -//===- OwningOpRefBase.h - MLIR OwningOpRefBase -*- C++ -*-===// +//===- OwningOpRef.h - MLIR OwningOpRef -*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,8 +10,8 @@ // //===--===// -#ifndef MLIR_IR_OWNINGOPREFBASE_H -#define MLIR_IR_OWNINGOPREFBASE_H +#ifndef MLIR_IR_OWNINGOPREF_H +#define MLIR_IR_OWNINGOPREF_H #include @@ -24,20 +24,23 @@ namespace mlir { /// instead, and this should only be used in situations where existing solutions /// are not viable. template -class OwningOpRefBase { +class OwningOpRef { public: - OwningOpRefBase(std::nullptr_t = nullptr) {} - OwningOpRefBase(OpTy op) : op(op) {} - OwningOpRefBase(OwningOpRefBase &&other) : op(other.release()) {} - ~OwningOpRefBase() { + /// The underlying operation type stored in this reference. + using Op
[llvm-branch-commits] [flang] 672cc75 - [mlir][IR] Remove references to BuiltinOps from IR/
Author: River Riddle Date: 2020-12-03T15:47:01-08:00 New Revision: 672cc75cceda12e67915643566362f832edcb66d URL: https://github.com/llvm/llvm-project/commit/672cc75cceda12e67915643566362f832edcb66d DIFF: https://github.com/llvm/llvm-project/commit/672cc75cceda12e67915643566362f832edcb66d.diff LOG: [mlir][IR] Remove references to BuiltinOps from IR/ There isn't a good reason for anything within IR to specifically reference any of the builtin operations. The only place that had a good reason in the past was AsmPrinter, but the behavior there doesn't need to hardcode ModuleOp anymore. Differential Revision: https://reviews.llvm.org/D92448 Added: Modified: flang/include/flang/Optimizer/Dialect/FIROpsSupport.h mlir/include/mlir/IR/Builders.h mlir/include/mlir/IR/BuiltinOps.td mlir/include/mlir/IR/MLIRContext.h mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h mlir/lib/IR/AsmPrinter.cpp mlir/lib/IR/Attributes.cpp mlir/lib/IR/Builders.cpp mlir/lib/IR/MLIRContext.cpp mlir/test/EDSC/builder-api-test.cpp Removed: diff --git a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h index 13e4e5ab71b2..43588ff17962 100644 --- a/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h +++ b/flang/include/flang/Optimizer/Dialect/FIROpsSupport.h @@ -11,6 +11,7 @@ #include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" +#include "mlir/IR/BuiltinOps.h" namespace fir { diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h index 5e12e477dd86..761a74b1c489 100644 --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -15,7 +15,6 @@ namespace mlir { class AffineExpr; class BlockAndValueMapping; -class ModuleOp; class UnknownLoc; class FileLineColLoc; class Type; @@ -47,7 +46,7 @@ class UnitAttr; class Builder { public: explicit Builder(MLIRContext *context) : context(context) {} - explicit Builder(ModuleOp module); + explicit Builder(Operation *op) : Builder(op->getContext()) {} MLIRContext *getContext() const { return context; } diff --git a/mlir/include/mlir/IR/BuiltinOps.td b/mlir/include/mlir/IR/BuiltinOps.td index 1c102ffdcc40..567a1249f0df 100644 --- a/mlir/include/mlir/IR/BuiltinOps.td +++ b/mlir/include/mlir/IR/BuiltinOps.td @@ -197,12 +197,6 @@ def ModuleOp : Builtin_Op<"module", [ /// Return the name of this module if present. Optional getName() { return sym_name(); } -/// Print this module in the custom top-level form. -void print(raw_ostream &os, OpPrintingFlags flags = llvm::None); -void print(raw_ostream &os, AsmState &state, - OpPrintingFlags flags = llvm::None); -void dump(); - //===--===// // SymbolOpInterface Methods //===--===// diff --git a/mlir/include/mlir/IR/MLIRContext.h b/mlir/include/mlir/IR/MLIRContext.h index 7fb941d344b7..e460064a889f 100644 --- a/mlir/include/mlir/IR/MLIRContext.h +++ b/mlir/include/mlir/IR/MLIRContext.h @@ -25,7 +25,7 @@ class Location; class MLIRContextImpl; class StorageUniquer; -/// MLIRContext is the top-level object for a collection of MLIR modules. It +/// MLIRContext is the top-level object for a collection of MLIR operations. It /// holds immortal uniqued objects like types, and the tables used to unique /// them. /// diff --git a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h index 98bb95699594..15ba8cca3262 100644 --- a/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h +++ b/mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h @@ -19,6 +19,8 @@ #include "llvm/ADT/MapVector.h" namespace mlir { +class ModuleOp; + namespace pdl_to_pdl_interp { class MatcherNode; diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index 9d3e26112200..14281f707fcd 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -15,7 +15,6 @@ #include "mlir/IR/AffineMap.h" #include "mlir/IR/AsmState.h" #include "mlir/IR/Attributes.h" -#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/IR/IntegerSet.h" @@ -2189,8 +2188,9 @@ class OperationPrinter : public ModulePrinter, private OpAsmPrinter { AsmStateImpl &state) : ModulePrinter(os, flags, &state) {} - /// Print the given top-level module. - void print(ModuleOp op); + /// Print the given top-level operation. + void printTopLevelOperation(Operation *op); + /// Print the given operation with its indent and location. void print(Operation *op); /// Print the bare location, not including indentation/location/etc. @@ -228
[llvm-branch-commits] [mlir] 96efe90 - [mlir][IR] Add explicit default constructor to OwningModuleRef to appease MSVC
Author: River Riddle Date: 2020-12-03T16:31:21-08:00 New Revision: 96efe90fe7c347c503cd6ade200da7a3e94f7b41 URL: https://github.com/llvm/llvm-project/commit/96efe90fe7c347c503cd6ade200da7a3e94f7b41 DIFF: https://github.com/llvm/llvm-project/commit/96efe90fe7c347c503cd6ade200da7a3e94f7b41.diff LOG: [mlir][IR] Add explicit default constructor to OwningModuleRef to appease MSVC Added: Modified: mlir/include/mlir/IR/BuiltinOps.h Removed: diff --git a/mlir/include/mlir/IR/BuiltinOps.h b/mlir/include/mlir/IR/BuiltinOps.h index dd23f90af6c7..c695a005283b 100644 --- a/mlir/include/mlir/IR/BuiltinOps.h +++ b/mlir/include/mlir/IR/BuiltinOps.h @@ -37,6 +37,7 @@ namespace mlir { class OwningModuleRef : public OwningOpRef { public: using OwningOpRef::OwningOpRef; + OwningModuleRef() = default; OwningModuleRef(OwningOpRef &&other) : OwningOpRef(std::move(other)) {} }; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] e66c2e2 - [mlir][NFC] Remove Function.h and Module.h in favor of BuiltinOps.h
Author: River Riddle Date: 2020-12-03T18:02:10-08:00 New Revision: e66c2e259f8140373ee73ceffe1e913483b711b5 URL: https://github.com/llvm/llvm-project/commit/e66c2e259f8140373ee73ceffe1e913483b711b5 DIFF: https://github.com/llvm/llvm-project/commit/e66c2e259f8140373ee73ceffe1e913483b711b5.diff LOG: [mlir][NFC] Remove Function.h and Module.h in favor of BuiltinOps.h The definitions of ModuleOp and FuncOp are now within BuiltinOps.h, making the individual files obsolete. Differential Revision: https://reviews.llvm.org/D92622 Added: Modified: mlir/include/mlir/Transforms/BufferUtils.h mlir/lib/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.cpp mlir/lib/Dialect/Vector/VectorTransferOpTransforms.cpp mlir/lib/Rewrite/ByteCode.cpp Removed: mlir/include/mlir/IR/Function.h mlir/include/mlir/IR/Module.h diff --git a/mlir/include/mlir/IR/Function.h b/mlir/include/mlir/IR/Function.h deleted file mode 100644 index f11530164789.. --- a/mlir/include/mlir/IR/Function.h +++ /dev/null @@ -1,19 +0,0 @@ -//===- Function.h - MLIR Function Class -*- C++ -*-===// -// -// 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 -// -//===--===// -// -// Functions are the basic unit of composition in MLIR. -// -//===--===// - -#ifndef MLIR_IR_FUNCTION_H -#define MLIR_IR_FUNCTION_H - -// TODO: This is a temporary forward until Function.h is removed. -#include "mlir/IR/BuiltinOps.h" - -#endif // MLIR_IR_FUNCTION_H diff --git a/mlir/include/mlir/IR/Module.h b/mlir/include/mlir/IR/Module.h deleted file mode 100644 index 8fa27a1c72c5.. --- a/mlir/include/mlir/IR/Module.h +++ /dev/null @@ -1,19 +0,0 @@ -//===- Module.h - MLIR Module Class -*- C++ -*-===// -// -// 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 -// -//===--===// -// -// Module is the top-level container for code in an MLIR program. -// -//===--===// - -#ifndef MLIR_IR_MODULE_H -#define MLIR_IR_MODULE_H - -// TODO: This is a temporary forward until Module.h is removed. -#include "mlir/IR/BuiltinOps.h" - -#endif // MLIR_IR_MODULE_H diff --git a/mlir/include/mlir/Transforms/BufferUtils.h b/mlir/include/mlir/Transforms/BufferUtils.h index d35163758cb0..70da6a025343 100644 --- a/mlir/include/mlir/Transforms/BufferUtils.h +++ b/mlir/include/mlir/Transforms/BufferUtils.h @@ -18,8 +18,8 @@ #include "mlir/Analysis/Liveness.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" #include "mlir/IR/Builders.h" +#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Dominance.h" -#include "mlir/IR/Function.h" #include "mlir/IR/Operation.h" #include "mlir/Transforms/DialectConversion.h" diff --git a/mlir/lib/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.cpp b/mlir/lib/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.cpp index fdd73b21237a..52c3249df58b 100644 --- a/mlir/lib/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.cpp +++ b/mlir/lib/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.cpp @@ -8,7 +8,7 @@ #include "mlir/Dialect/StandardOps/Transforms/DecomposeCallGraphTypes.h" #include "mlir/Dialect/StandardOps/IR/Ops.h" -#include "mlir/IR/Function.h" +#include "mlir/IR/BuiltinOps.h" using namespace mlir; diff --git a/mlir/lib/Dialect/Vector/VectorTransferOpTransforms.cpp b/mlir/lib/Dialect/Vector/VectorTransferOpTransforms.cpp index fd3317ded246..8c00cadf7032 100644 --- a/mlir/lib/Dialect/Vector/VectorTransferOpTransforms.cpp +++ b/mlir/lib/Dialect/Vector/VectorTransferOpTransforms.cpp @@ -14,8 +14,8 @@ #include "mlir/Dialect/Vector/VectorOps.h" #include "mlir/Dialect/Vector/VectorTransforms.h" #include "mlir/Dialect/Vector/VectorUtils.h" +#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Dominance.h" -#include "mlir/IR/Function.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Debug.h" diff --git a/mlir/lib/Rewrite/ByteCode.cpp b/mlir/lib/Rewrite/ByteCode.cpp index 481e7b6db1d1..451be3036767 100644 --- a/mlir/lib/Rewrite/ByteCode.cpp +++ b/mlir/lib/Rewrite/ByteCode.cpp @@ -14,7 +14,7 @@ #include "mlir/Analysis/Liveness.h" #include "mlir/Dialect/PDL/IR/PDLTypes.h" #include "mlir/Dialect/PDLInterp/IR/PDLInterp.h" -#include "mlir/IR/Function.h" +#include "mlir/IR/BuiltinOps.h" #include "mlir/IR/RegionGraphTraits.h" #include "llvm/ADT/IntervalMap.h" #i
[llvm-branch-commits] [mlir] 7924fb3 - [mlir][OpFormatGen] Add support for optional enum attributes
Author: River Riddle Date: 2020-12-04T21:00:44-08:00 New Revision: 7924fb34f33a76fd3c36f5635dd40990ecd79741 URL: https://github.com/llvm/llvm-project/commit/7924fb34f33a76fd3c36f5635dd40990ecd79741 DIFF: https://github.com/llvm/llvm-project/commit/7924fb34f33a76fd3c36f5635dd40990ecd79741.diff LOG: [mlir][OpFormatGen] Add support for optional enum attributes The check for formatting enum attributes was missing a call to get the base attribute, which is necessary to strip off the top-level OptionalAttr<> wrapper. Differential Revision: https://reviews.llvm.org/D92713 Added: Modified: mlir/test/Target/llvmir.mlir mlir/test/lib/Dialect/Test/TestOps.td mlir/test/mlir-tblgen/op-format.mlir mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/mlir/test/Target/llvmir.mlir b/mlir/test/Target/llvmir.mlir index 473e54025ab6..9f8a37198558 100644 --- a/mlir/test/Target/llvmir.mlir +++ b/mlir/test/Target/llvmir.mlir @@ -1350,7 +1350,7 @@ llvm.func @useInlineAsm(%arg0: !llvm.i32) { %3 = llvm.inline_asm is_align_stack "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8 // CHECK-NEXT: call i8 asm inteldialect "foo", "=r,r,r"(i32 {{.*}}, i32 {{.*}}), !dbg !13 - %4 = llvm.inline_asm asm_dialect = 1 "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8 + %4 = llvm.inline_asm asm_dialect = "intel" "foo", "=r,r,r" %arg0, %arg0 : (!llvm.i32, !llvm.i32) -> !llvm.i8 // CHECK-NEXT: call { i8, i8 } asm "foo", "=r,=r,r"(i32 {{.*}}), !dbg !14 %5 = llvm.inline_asm "foo", "=r,=r,r" %arg0 : (!llvm.i32) -> !llvm.struct<(i8, i8)> diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 7d9274fbddee..7547500b2835 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1592,6 +1592,11 @@ def FormatOptionalUnitAttrNoElide let assemblyFormat = "($is_optional^)? attr-dict"; } +def FormatOptionalEnumAttr : TEST_Op<"format_optional_enum_attr"> { + let arguments = (ins OptionalAttr:$attr); + let assemblyFormat = "($attr^)? attr-dict"; +} + //===--===// // Custom Directives diff --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir index d19d569729aa..6286f7655146 100644 --- a/mlir/test/mlir-tblgen/op-format.mlir +++ b/mlir/test/mlir-tblgen/op-format.mlir @@ -185,6 +185,13 @@ test.format_optional_unit_attribute // CHECK: test.format_optional_unit_attribute_no_elide unit test.format_optional_unit_attribute_no_elide unit +// CHECK: test.format_optional_enum_attr "case5" +test.format_optional_enum_attr "case5" + +// CHECK: test.format_optional_enum_attr +// CHECK-NOT: "case5" +test.format_optional_enum_attr + //===--===// // Format optional operands and results //===--===// diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp index e5775c09ab25..4b53c18b7717 100644 --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -462,7 +462,8 @@ struct OperationFormat { /// Returns true if we can format the given attribute as an EnumAttr in the /// parser format. static bool canFormatEnumAttr(const NamedAttribute *attr) { - const EnumAttr *enumAttr = dyn_cast(&attr->attr); + Attribute baseAttr = attr->attr.getBaseAttr(); + const EnumAttr *enumAttr = dyn_cast(&baseAttr); if (!enumAttr) return false; @@ -1107,7 +1108,8 @@ void OperationFormat::genElementParser(Element *element, OpMethodBody &body, // Check to see if we can parse this as an enum attribute. if (canFormatEnumAttr(var)) { - const EnumAttr &enumAttr = cast(var->attr); + Attribute baseAttr = var->attr.getBaseAttr(); + const EnumAttr &enumAttr = cast(baseAttr); // Generate the code for building an attribute for this enum. std::string attrBuilderStr; @@ -1682,9 +1684,11 @@ void OperationFormat::genElementPrinter(Element *element, OpMethodBody &body, // If we are formatting as an enum, symbolize the attribute as a string. if (canFormatEnumAttr(var)) { - const EnumAttr &enumAttr = cast(var->attr); + Attribute baseAttr = var->attr.getBaseAttr(); + const EnumAttr &enumAttr = cast(baseAttr); body << " p << '\"' << " << enumAttr.getSymbolToStringFnName() << "(" - << var->name << "()) << '\"';\n"; + << (var->attr.isOptional() ? "*" : "") << var->name + << "()) << '\"';\n"; return; } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 47364f9 - [mlir][IR] Move the storage for results to before the Operation instead of after.
Author: River Riddle Date: 2020-12-04T21:01:42-08:00 New Revision: 47364f95e810f96fd300ceaa095719f76683e6fa URL: https://github.com/llvm/llvm-project/commit/47364f95e810f96fd300ceaa095719f76683e6fa DIFF: https://github.com/llvm/llvm-project/commit/47364f95e810f96fd300ceaa095719f76683e6fa.diff LOG: [mlir][IR] Move the storage for results to before the Operation instead of after. Trailing objects are really nice for storing additional data inline with the main class, and is something that we heavily take advantage of for Operation(and many other classes). To get the address of the inline data you need to compute the address by doing some pointer arithmetic taking into account any objects stored before the object you want to access. Most classes keep the count of the number of objects, so this is relatively cheap to compute. This is not the case for results though, which have two different types(inline and trailing) that are not necessarily as cheap to compute as the count for other objects. This revision moves the storage for results to before the operation and stores them in reverse order. This allows for getting results to still be very fast given that they are never iterated directly in order, and also greatly improves the speed when accessing the other trailing objects of an operation(operands/regions/blocks/etc). This reduced compile time when compiling a decently sized mlir module by about ~400ms, or 2.17s -> 1.76s. Differential Revision: https://reviews.llvm.org/D92687 Added: Modified: mlir/include/mlir/IR/Operation.h mlir/include/mlir/IR/OperationSupport.h mlir/lib/IR/Operation.cpp mlir/lib/IR/OperationSupport.cpp Removed: diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index 5ed5cd9930fa..0c295027923d 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -21,15 +21,14 @@ #include "llvm/ADT/Twine.h" namespace mlir { -/// Operation is a basic unit of execution within a function. Operations can -/// be nested within other operations effectively forming a tree. Child -/// operations are organized into operation blocks represented by a 'Block' -/// class. -class Operation final +/// Operation is a basic unit of execution within MLIR. Operations can +/// be nested within `Region`s held by other operations effectively forming a +/// tree. Child operations are organized into operation blocks represented by a +/// 'Block' class. +class alignas(8) Operation final : public llvm::ilist_node_with_parent, - private llvm::TrailingObjects { + private llvm::TrailingObjects { public: /// Create a new Operation with the specific fields. static Operation *create(Location location, OperationName name, @@ -654,6 +653,21 @@ class Operation final // allocated with malloc. ~Operation(); + /// Returns the additional size necessary for allocating the given objects + /// before an Operation in-memory. + static size_t prefixAllocSize(unsigned numTrailingResults, +unsigned numInlineResults) { +return sizeof(detail::TrailingOpResult) * numTrailingResults + + sizeof(detail::InLineOpResult) * numInlineResults; + } + /// Returns the additional size allocated before this Operation in-memory. + size_t prefixAllocSize() { +unsigned numResults = getNumResults(); +unsigned numTrailingResults = OpResult::getNumTrailing(numResults); +unsigned numInlineResults = OpResult::getNumInline(numResults); +return prefixAllocSize(numTrailingResults, numInlineResults); + } + /// Returns the operand storage object. detail::OperandStorage &getOperandStorage() { assert(hasOperandStorage && "expected operation to have operand storage"); @@ -662,12 +676,18 @@ class Operation final /// Returns a pointer to the use list for the given trailing result. detail::TrailingOpResult *getTrailingResult(unsigned resultNumber) { -return getTrailingObjects() + resultNumber; +// Trailing results are stored in reverse order after(before in memory) the +// inline results. +return reinterpret_cast( + getInlineResult(OpResult::getMaxInlineResults() - 1)) - + ++resultNumber; } /// Returns a pointer to the use list for the given inline result. detail::InLineOpResult *getInlineResult(unsigned resultNumber) { -return getTrailingObjects() + resultNumber; +// Inline results are stored in reverse order before the operation in +// memory. +return reinterpret_cast(this) - ++resultNumber; } /// Provide a 'getParent' method for ilist_node_with_parent methods. @@ -725,17 +745,8 @@ class Operation final friend class llvm::ilist_node_with_parent; // This stuff is used by the TrailingObjects template. - friend llvm::TrailingObjects; - size_t numTrailingObjects(OverloadToken) const {
[llvm-branch-commits] [mlir] c42cee0 - [mlir][ODS] Fix the use of cppClassName in Type constraints for TypeDefs
Author: River Riddle Date: 2021-01-06T14:18:58-08:00 New Revision: c42cee0c64fe20235123ba44aac12d7e38117a7e URL: https://github.com/llvm/llvm-project/commit/c42cee0c64fe20235123ba44aac12d7e38117a7e DIFF: https://github.com/llvm/llvm-project/commit/c42cee0c64fe20235123ba44aac12d7e38117a7e.diff LOG: [mlir][ODS] Fix the use of cppClassName in Type constraints for TypeDefs This field is currently being used to mean "Fully resolved class name", which breaks the usage by TypeDefs. This revision prefixes the name with the dialect namespace when necessary. Differential Revision: https://reviews.llvm.org/D94192 Added: Modified: mlir/include/mlir/IR/OpBase.td mlir/include/mlir/TableGen/Type.h mlir/lib/TableGen/Type.cpp mlir/test/mlir-tblgen/op-decl.td Removed: diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td index 17996dfde5ae..dc3e8a6367cd 100644 --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -345,7 +345,8 @@ class AnyTypeOf allowedTypes, string summary = "", Or, !if(!eq(summary, ""), !interleave(!foreach(t, allowedTypes, t.summary), " or "), -summary)>; +summary), +cppClassName>; // Integer types. diff --git a/mlir/include/mlir/TableGen/Type.h b/mlir/include/mlir/TableGen/Type.h index c604a4bd7009..6af6d05076a2 100644 --- a/mlir/include/mlir/TableGen/Type.h +++ b/mlir/include/mlir/TableGen/Type.h @@ -49,7 +49,7 @@ class TypeConstraint : public Constraint { Optional getBuilderCall() const; // Return the C++ class name for this type (which may just be ::mlir::Type). - StringRef getCPPClassName() const; + std::string getCPPClassName() const; }; // Wrapper class with helper methods for accessing Types defined in TableGen. diff --git a/mlir/lib/TableGen/Type.cpp b/mlir/lib/TableGen/Type.cpp index d7b129e83ee7..fd5a0f705897 100644 --- a/mlir/lib/TableGen/Type.cpp +++ b/mlir/lib/TableGen/Type.cpp @@ -11,6 +11,8 @@ //===--===// #include "mlir/TableGen/Type.h" +#include "mlir/TableGen/Dialect.h" +#include "llvm/ADT/Twine.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/TableGen/Record.h" @@ -54,8 +56,19 @@ Optional TypeConstraint::getBuilderCall() const { } // Return the C++ class name for this type (which may just be ::mlir::Type). -StringRef TypeConstraint::getCPPClassName() const { - return def->getValueAsString("cppClassName"); +std::string TypeConstraint::getCPPClassName() const { + StringRef className = def->getValueAsString("cppClassName"); + + // If the class name is already namespace resolved, use it. + if (className.contains("::")) +return className.str(); + + // Otherwise, check to see if there is a namespace from a dialect to prepend. + if (const llvm::RecordVal *value = def->getValue("dialect")) { +Dialect dialect(cast(value->getValue())->getDef()); +return (dialect.getCppNamespace() + "::" + className).str(); + } + return className.str(); } Type::Type(const llvm::Record *record) : TypeConstraint(record) {} diff --git a/mlir/test/mlir-tblgen/op-decl.td b/mlir/test/mlir-tblgen/op-decl.td index 3d4d46ceb42f..91e46b59c2e6 100644 --- a/mlir/test/mlir-tblgen/op-decl.td +++ b/mlir/test/mlir-tblgen/op-decl.td @@ -248,6 +248,23 @@ def NS_JOp : NS_Op<"op_with_InferTypeOpInterface_interface", [DeclareOpInterface // CHECK: static void build(::mlir::OpBuilder &, ::mlir::OperationState &odsState, ::mlir::TypeRange resultTypes, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); // CHECK: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::ValueRange operands, ::llvm::ArrayRef<::mlir::NamedAttribute> attributes = {}); +// Test that type defs have the proper namespaces when used as a constraint. +// --- + +def Test_Dialect2 : Dialect { + let name = "test"; + let cppNamespace = "::mlir::dialect2"; +} +def TestDialect2Type : TypeDef; + +def NS_ResultWithDialectTypeOp : NS_Op<"op_with_dialect_type", []> { + let results = (outs TestDialect2Type); +} + +// CHECK-LABEL: NS::ResultWithDialectTypeOp declarations +// CHECK: class ResultWithDialectTypeOp : +// CHECK-SAME: ::mlir::OpTrait::OneTypedResult<::mlir::dialect2::Dialect2TypeType> + // Check that default builders can be suppressed. // --- ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] e0a93e4 - [mlir][ODS] Rename several uses of 'description' to 'summary'
Author: River Riddle Date: 2021-01-06T14:18:58-08:00 New Revision: e0a93e4b65b63b0ae0fbde826790dc1728789fab URL: https://github.com/llvm/llvm-project/commit/e0a93e4b65b63b0ae0fbde826790dc1728789fab DIFF: https://github.com/llvm/llvm-project/commit/e0a93e4b65b63b0ae0fbde826790dc1728789fab.diff LOG: [mlir][ODS] Rename several uses of 'description' to 'summary' Right now constraint/predicate traits/etc. use their "description" field as a one line human readable string. This breaks the current convention, by which a "description" may be multi-line. This revision renames the "description" field in these cases to "summary" which matches what the string is actually used as. This also unbreaks the use of TypeDefs(and eventually AttrDefs) in conjunction with existing type constraint facilities like `Optional`. Differential Revision: https://reviews.llvm.org/D94133 Added: Modified: mlir/docs/OpDefinitions.md mlir/include/mlir/Dialect/ArmSVE/ArmSVE.td mlir/include/mlir/Dialect/Async/IR/AsyncBase.td mlir/include/mlir/Dialect/LLVMIR/LLVMOpBase.td mlir/include/mlir/Dialect/Quant/QuantOpsBase.td mlir/include/mlir/Dialect/Shape/IR/ShapeBase.td mlir/include/mlir/Dialect/Tosa/IR/TosaOpBase.td mlir/include/mlir/IR/OpBase.td mlir/include/mlir/TableGen/Constraint.h mlir/include/mlir/TableGen/OpTrait.h mlir/include/mlir/TableGen/Type.h mlir/include/mlir/TableGen/TypeDef.h mlir/lib/TableGen/Constraint.cpp mlir/lib/TableGen/OpTrait.cpp mlir/lib/TableGen/Type.cpp mlir/lib/TableGen/TypeDef.cpp mlir/test/mlir-tblgen/op-attribute.td mlir/tools/mlir-tblgen/EnumsGen.cpp mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp mlir/tools/mlir-tblgen/OpDocGen.cpp mlir/tools/mlir-tblgen/OpFormatGen.cpp mlir/tools/mlir-tblgen/RewriterGen.cpp mlir/tools/mlir-tblgen/StructsGen.cpp mlir/unittests/TableGen/structs.td Removed: diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index 0b235f993e3d..bfd3d43c60b9 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -4,16 +4,17 @@ In addition to specializing the `mlir::Op` C++ template, MLIR also supports defining operations and data types in a table-driven manner. This is achieved via [TableGen][TableGen], which is both a generic language and its tooling to maintain records of domain-specific information. Facts regarding an operation -are specified concisely into a TableGen record, which will be expanded into -an equivalent `mlir::Op` C++ template specialization at compiler build time. +are specified concisely into a TableGen record, which will be expanded into an +equivalent `mlir::Op` C++ template specialization at compiler build time. This manual explains in detail all the available mechanisms for defining operations in such a table-driven manner. It aims to be a specification instead -of a tutorial. Please refer to [Quickstart tutorial to adding MLIR graph -rewrite](Tutorials/QuickstartRewrites.md) for the latter. +of a tutorial. Please refer to +[Quickstart tutorial to adding MLIR graph rewrite](Tutorials/QuickstartRewrites.md) +for the latter. -In addition to detailing each mechanism, this manual also tries to capture -best practices. They are rendered as quoted bullet points. +In addition to detailing each mechanism, this manual also tries to capture best +practices. They are rendered as quoted bullet points. ## Motivation @@ -22,12 +23,12 @@ operations. This open and extensible ecosystem leads to the "stringly" type IR problem, e.g., repetitive string comparisons during optimization and analysis passes, unintuitive accessor methods (e.g., generic/error prone `getOperand(3)` vs self-documenting `getStride()`) with more generic return types, verbose and -generic constructors without default arguments, verbose textual IR dump, and -so on. Furthermore, operation verification is: +generic constructors without default arguments, verbose textual IR dump, and so +on. Furthermore, operation verification is: -1. best case: a central string-to-verification-function map, -1. middle case: duplication of verification across the code base, or -1. worst case: no verification functions. +1. best case: a central string-to-verification-function map, +1. middle case: duplication of verification across the code base, or +1. worst case: no verification functions. The fix is to support defining ops in a table-driven manner. Then for each dialect, we can have a central place that contains everything you need to know @@ -40,17 +41,17 @@ building, verification, parsing, printing, analysis, and many more. Compared to the C++ template, this table-driven approach has several benefits including but not limited to: -* **Single source of truth**: We strive to encode all facts regarding an - operation into the record, so that readers don't need to jump amon
[llvm-branch-commits] [mlir] 41d919a - [mlir][TypeDefGen] Remove the need to define parser/printer for singleton types
Author: River Riddle Date: 2021-01-06T15:00:14-08:00 New Revision: 41d919aa29468ac072755b8449b8a38ff26f6979 URL: https://github.com/llvm/llvm-project/commit/41d919aa29468ac072755b8449b8a38ff26f6979 DIFF: https://github.com/llvm/llvm-project/commit/41d919aa29468ac072755b8449b8a38ff26f6979.diff LOG: [mlir][TypeDefGen] Remove the need to define parser/printer for singleton types This allows for singleton types without an explicit parser/printer to simply use the mnemonic as the assembly format, removing the need for these types to provide the parser/printer fields. Differential Revision: https://reviews.llvm.org/D94194 Added: Modified: mlir/test/lib/Dialect/Test/TestTypeDefs.td mlir/tools/mlir-tblgen/TypeDefGen.cpp Removed: diff --git a/mlir/test/lib/Dialect/Test/TestTypeDefs.td b/mlir/test/lib/Dialect/Test/TestTypeDefs.td index 75fffa11cb21..80927dff62c2 100644 --- a/mlir/test/lib/Dialect/Test/TestTypeDefs.td +++ b/mlir/test/lib/Dialect/Test/TestTypeDefs.td @@ -21,9 +21,6 @@ class Test_Type : TypeDef { } def SimpleTypeA : Test_Type<"SimpleA"> { let mnemonic = "smpla"; - - let printer = [{ $_printer << "smpla"; }]; - let parser = [{ return get($_ctxt); }]; } // A more complex parameterized type. diff --git a/mlir/tools/mlir-tblgen/TypeDefGen.cpp b/mlir/tools/mlir-tblgen/TypeDefGen.cpp index 8fdb5f4feeaf..20168168bc8d 100644 --- a/mlir/tools/mlir-tblgen/TypeDefGen.cpp +++ b/mlir/tools/mlir-tblgen/TypeDefGen.cpp @@ -537,12 +537,21 @@ static void emitParsePrintDispatch(ArrayRef types, raw_ostream &os) { os << "static ::mlir::Type generatedTypeParser(::mlir::MLIRContext* " "ctxt, " "::mlir::DialectAsmParser& parser, ::llvm::StringRef mnemonic) {\n"; - for (const TypeDef &type : types) -if (type.getMnemonic()) + for (const TypeDef &type : types) { +if (type.getMnemonic()) { os << formatv(" if (mnemonic == {0}::{1}::getMnemonic()) return " -"{0}::{1}::parse(ctxt, parser);\n", +"{0}::{1}::", type.getDialect().getCppNamespace(), type.getCppClassName()); + + // If the type has no parameters and no parser code, just invoke a normal + // `get`. + if (type.getNumParameters() == 0 && !type.getParserCode()) +os << "get(ctxt);\n"; + else +os << "parse(ctxt, parser);\n"; +} + } os << " return ::mlir::Type();\n"; os << "}\n\n"; @@ -551,17 +560,26 @@ static void emitParsePrintDispatch(ArrayRef types, raw_ostream &os) { os << "static ::mlir::LogicalResult generatedTypePrinter(::mlir::Type " "type, " "::mlir::DialectAsmPrinter& printer) {\n" - << " ::mlir::LogicalResult found = ::mlir::success();\n" - << " ::llvm::TypeSwitch<::mlir::Type>(type)\n"; - for (const TypeDef &type : types) -if (type.getMnemonic()) - os << formatv(".Case<{0}::{1}>([&](::mlir::Type t) {{ " -"t.dyn_cast<{0}::{1}>().print(printer); })\n", -type.getDialect().getCppNamespace(), -type.getCppClassName()); - os << ".Default([&found](::mlir::Type) { found = ::mlir::failure(); " -"});\n" - << " return found;\n" + << " return ::llvm::TypeSwitch<::mlir::Type, " +"::mlir::LogicalResult>(type)\n"; + for (const TypeDef &type : types) { +if (Optional mnemonic = type.getMnemonic()) { + StringRef cppNamespace = type.getDialect().getCppNamespace(); + StringRef cppClassName = type.getCppClassName(); + os << formatv(".Case<{0}::{1}>([&]({0}::{1} t) {{\n ", +cppNamespace, cppClassName); + + // If the type has no parameters and no printer code, just print the + // mnemonic. + if (type.getNumParameters() == 0 && !type.getPrinterCode()) +os << formatv("printer << {0}::{1}::getMnemonic();", cppNamespace, + cppClassName); + else +os << "t.print(printer);"; + os << "\n return ::mlir::success();\n})\n"; +} + } + os << ".Default([](::mlir::Type) { return ::mlir::failure(); });\n" << "}\n\n"; } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 238dbeb - [mlir][ODS] Fix missed rename of TypeParameter 'description' to 'summary'
Author: River Riddle Date: 2021-01-06T22:25:06-08:00 New Revision: 238dbeb1e7bab488b964492f51b8ebbe850b6631 URL: https://github.com/llvm/llvm-project/commit/238dbeb1e7bab488b964492f51b8ebbe850b6631 DIFF: https://github.com/llvm/llvm-project/commit/238dbeb1e7bab488b964492f51b8ebbe850b6631.diff LOG: [mlir][ODS] Fix missed rename of TypeParameter 'description' to 'summary' This fixes document generation for type parameters. Added: Modified: mlir/lib/TableGen/TypeDef.cpp Removed: diff --git a/mlir/lib/TableGen/TypeDef.cpp b/mlir/lib/TableGen/TypeDef.cpp index 03bbb85d29ab..5c4f5348d1b3 100644 --- a/mlir/lib/TableGen/TypeDef.cpp +++ b/mlir/lib/TableGen/TypeDef.cpp @@ -145,7 +145,7 @@ StringRef TypeParameter::getCppType() const { Optional TypeParameter::getSummary() const { auto *parameterType = def->getArg(num); if (auto *typeParameter = dyn_cast(parameterType)) { -const auto *desc = typeParameter->getDef()->getValue("description"); +const auto *desc = typeParameter->getDef()->getValue("summary"); if (llvm::StringInit *ci = dyn_cast(desc->getValue())) return ci->getValue(); } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] e45840f - [mlir][PDL] Use ODS for defining PDL types
Author: River Riddle Date: 2021-01-08T12:32:28-08:00 New Revision: e45840f4af46df0f8be92790b45f9432cf8ba19e URL: https://github.com/llvm/llvm-project/commit/e45840f4af46df0f8be92790b45f9432cf8ba19e DIFF: https://github.com/llvm/llvm-project/commit/e45840f4af46df0f8be92790b45f9432cf8ba19e.diff LOG: [mlir][PDL] Use ODS for defining PDL types This removes the need to define these classes and their parser/printers in C++. Differential Revision: https://reviews.llvm.org/D94135 Added: mlir/include/mlir/Dialect/PDL/IR/PDLDialect.td mlir/include/mlir/Dialect/PDL/IR/PDLOps.h mlir/include/mlir/Dialect/PDL/IR/PDLTypes.td Modified: mlir/include/mlir/Dialect/PDL/IR/PDL.h mlir/include/mlir/Dialect/PDL/IR/PDLOps.td mlir/include/mlir/Dialect/PDL/IR/PDLTypes.h mlir/include/mlir/Dialect/PDLInterp/IR/PDLInterp.h mlir/include/mlir/Dialect/PDLInterp/IR/PDLInterpOps.td mlir/lib/Conversion/PDLToPDLInterp/PredicateTree.h mlir/lib/Dialect/PDL/IR/PDL.cpp mlir/lib/Rewrite/FrozenRewritePatternList.cpp Removed: mlir/include/mlir/Dialect/PDL/IR/PDLBase.td diff --git a/mlir/include/mlir/Dialect/PDL/IR/PDL.h b/mlir/include/mlir/Dialect/PDL/IR/PDL.h index 14136021d26c..bbc52301360d 100644 --- a/mlir/include/mlir/Dialect/PDL/IR/PDL.h +++ b/mlir/include/mlir/Dialect/PDL/IR/PDL.h @@ -13,11 +13,7 @@ #ifndef MLIR_DIALECT_PDL_IR_PDL_H_ #define MLIR_DIALECT_PDL_IR_PDL_H_ -#include "mlir/IR/Builders.h" #include "mlir/IR/Dialect.h" -#include "mlir/IR/OpImplementation.h" -#include "mlir/IR/SymbolTable.h" -#include "mlir/Interfaces/SideEffectInterfaces.h" //===--===// // PDL Dialect @@ -25,12 +21,4 @@ #include "mlir/Dialect/PDL/IR/PDLOpsDialect.h.inc" -//===--===// -// PDL Dialect Operations -//===--===// - -#define GET_OP_CLASSES -#include "mlir/Dialect/PDL/IR/PDLOps.h.inc" - - #endif // MLIR_DIALECT_PDL_IR_PDL_H_ diff --git a/mlir/include/mlir/Dialect/PDL/IR/PDLBase.td b/mlir/include/mlir/Dialect/PDL/IR/PDLDialect.td similarity index 69% rename from mlir/include/mlir/Dialect/PDL/IR/PDLBase.td rename to mlir/include/mlir/Dialect/PDL/IR/PDLDialect.td index b372e594e2e7..14a8400a79b9 100644 --- a/mlir/include/mlir/Dialect/PDL/IR/PDLBase.td +++ b/mlir/include/mlir/Dialect/PDL/IR/PDLDialect.td @@ -1,4 +1,4 @@ -//===- PDLBase.td - PDL base definitions ---*- tablegen -*-===// +//===- PDLDialect.td - PDL dialect definition --*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,12 +6,12 @@ // //===--===// // -// Defines base support for MLIR PDL operations. +// Defines the MLIR PDL dialect. // //===--===// -#ifndef MLIR_DIALECT_PDL_IR_PDLBASE -#define MLIR_DIALECT_PDL_IR_PDLBASE +#ifndef MLIR_DIALECT_PDL_IR_PDLDIALECT +#define MLIR_DIALECT_PDL_IR_PDLDIALECT include "mlir/IR/OpBase.td" @@ -66,31 +66,4 @@ def PDL_Dialect : Dialect { let cppNamespace = "::mlir::pdl"; } -//===--===// -// PDL Types -//===--===// - -class PDL_Handle : -DialectType()">, -underlying>, -BuildableType<"$_builder.getType<" # underlying # ">()">; - -// Handle for `mlir::Attribute`. -def PDL_Attribute : PDL_Handle<"mlir::pdl::AttributeType">; - -// Handle for `mlir::Operation*`. -def PDL_Operation : PDL_Handle<"mlir::pdl::OperationType">; - -// Handle for `mlir::Type`. -def PDL_Type : PDL_Handle<"mlir::pdl::TypeType">; - -// Handle for `mlir::Value`. -def PDL_Value : PDL_Handle<"mlir::pdl::ValueType">; - -// A positional value is a location on a pattern DAG, which may be an operation, -// an attribute, or an operand/result. -def PDL_PositionalValue : -AnyTypeOf<[PDL_Attribute, PDL_Operation, PDL_Type, PDL_Value], - "Positional Value">; - -#endif // MLIR_DIALECT_PDL_IR_PDLBASE +#endif // MLIR_DIALECT_PDL_IR_PDLDIALECT diff --git a/mlir/include/mlir/Dialect/PDL/IR/PDLOps.h b/mlir/include/mlir/Dialect/PDL/IR/PDLOps.h new file mode 100644 index ..8e560ae09ee8 --- /dev/null +++ b/mlir/include/mlir/Dialect/PDL/IR/PDLOps.h @@ -0,0 +1,29 @@ +//===- PDLOps.h - Pattern Descriptor Language Operations *- C++ -*-===// +// +// 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 +// +//===--
[llvm-branch-commits] [mlir] 1ba5ea6 - [mlir] Add a hook for initializing passes before execution and use it in the Canonicalizer
Author: River Riddle Date: 2021-01-08T13:36:12-08:00 New Revision: 1ba5ea67a30170053964a28f2f47aea4bb7f5ff1 URL: https://github.com/llvm/llvm-project/commit/1ba5ea67a30170053964a28f2f47aea4bb7f5ff1 DIFF: https://github.com/llvm/llvm-project/commit/1ba5ea67a30170053964a28f2f47aea4bb7f5ff1.diff LOG: [mlir] Add a hook for initializing passes before execution and use it in the Canonicalizer This revision adds a new `initialize(MLIRContext *)` hook to passes that allows for them to initialize any heavy state before the first execution of the pass. A concrete use case of this is with patterns that rely on PDL, given that PDL is compiled at run time it is imperative that compilation results are cached as much as possible. The first use of this hook is in the Canonicalizer, which has the added benefit of reducing the number of expensive accesses to the context when collecting patterns. Differential Revision: https://reviews.llvm.org/D93147 Added: Modified: mlir/docs/PassManagement.md mlir/include/mlir/Pass/Pass.h mlir/include/mlir/Pass/PassManager.h mlir/lib/Pass/Pass.cpp mlir/lib/Pass/PassDetail.h mlir/lib/Transforms/Canonicalizer.cpp Removed: diff --git a/mlir/docs/PassManagement.md b/mlir/docs/PassManagement.md index ee47d0bcc437..558d5f6d315f 100644 --- a/mlir/docs/PassManagement.md +++ b/mlir/docs/PassManagement.md @@ -131,6 +131,23 @@ end, a pass that may create an entity from a dialect that isn't guaranteed to already ne loaded must express this by overriding the `getDependentDialects()` method and declare this list of Dialects explicitly. +### Initialization + +In certain situations, a Pass may contain state that is constructed dynamically, +but is potentially expensive to recompute in successive runs of the Pass. One +such example is when using [`PDL`-based](Dialects/PDLOps.md) +[patterns](PatternRewriter.md), which are compiled into a bytecode during +runtime. In these situations, a pass may override the following hook to +initialize this heavy state: + +* `void initialize(MLIRContext *context)` + +This hook is executed once per run of a full pass pipeline, meaning that it does +not have access to the state available during a `runOnOperation` call. More +concretely, all necessary accesses to an `MLIRContext` should be driven via the +provided `context` parameter, and methods that utilize "per-run" state such as +`getContext`/`getOperation`/`getAnalysis`/etc. must not be used. + ## Analysis Management An important concept, along with transformation passes, are analyses. These are diff --git a/mlir/include/mlir/Pass/Pass.h b/mlir/include/mlir/Pass/Pass.h index 7a9523714293..3eeaf79b9610 100644 --- a/mlir/include/mlir/Pass/Pass.h +++ b/mlir/include/mlir/Pass/Pass.h @@ -166,6 +166,12 @@ class Pass { /// The polymorphic API that runs the pass over the currently held operation. virtual void runOnOperation() = 0; + /// Initialize any complex state necessary for running this pass. This hook + /// should not rely on any state accessible during the execution of a pass. + /// For example, `getContext`/`getOperation`/`getAnalysis`/etc. should not be + /// invoked within this hook. + virtual void initialize(MLIRContext *context) {} + /// Schedule an arbitrary pass pipeline on the provided operation. /// This can be invoke any time in a pass to dynamic schedule more passes. /// The provided operation must be the current one or one nested below. diff --git a/mlir/include/mlir/Pass/PassManager.h b/mlir/include/mlir/Pass/PassManager.h index 2715ebd05cac..9fc81b5e421d 100644 --- a/mlir/include/mlir/Pass/PassManager.h +++ b/mlir/include/mlir/Pass/PassManager.h @@ -35,6 +35,7 @@ class PassInstrumentor; namespace detail { struct OpPassManagerImpl; +class OpToOpPassAdaptor; struct PassExecutionState; } // end namespace detail @@ -126,9 +127,17 @@ class OpPassManager { Nesting getNesting(); private: + /// Initialize all of the passes within this pass manager with the given + /// initialization generation. The initialization generation is used to detect + /// if a pass manager has already been initialized. + void initialize(MLIRContext *context, unsigned newInitGeneration); + /// A pointer to an internal implementation instance. std::unique_ptr impl; + /// Allow access to initialize. + friend detail::OpToOpPassAdaptor; + /// Allow access to the constructor. friend class PassManager; friend class Pass; diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp index d9046bef1469..fdc6d56d86a5 100644 --- a/mlir/lib/Pass/Pass.cpp +++ b/mlir/lib/Pass/Pass.cpp @@ -81,9 +81,10 @@ namespace mlir { namespace detail { struct OpPassManagerImpl { OpPassManagerImpl(Identifier identifier, OpPassManager::Nesting nesting) - : name(identifier.str()), identifier(identifier), nesting(nesting) {} + : name(identifier
[llvm-branch-commits] [mlir] 77501bd - [mlir][PassManager] Properly set the initialization generation when cloning a pass manager
Author: River Riddle Date: 2021-01-08T14:41:29-08:00 New Revision: 77501bd1754fd15bc5044af78e987f894f494ee9 URL: https://github.com/llvm/llvm-project/commit/77501bd1754fd15bc5044af78e987f894f494ee9 DIFF: https://github.com/llvm/llvm-project/commit/77501bd1754fd15bc5044af78e987f894f494ee9.diff LOG: [mlir][PassManager] Properly set the initialization generation when cloning a pass manager Fixes a bug where dynamic pass pipelines of cloned pass managers weren't being initialized properly. Added: Modified: mlir/lib/Pass/Pass.cpp Removed: diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp index fdc6d56d86a5..d8a59bc83661 100644 --- a/mlir/lib/Pass/Pass.cpp +++ b/mlir/lib/Pass/Pass.cpp @@ -246,6 +246,7 @@ OpPassManager::OpPassManager(OpPassManager &&rhs) : impl(std::move(rhs.impl)) {} OpPassManager::OpPassManager(const OpPassManager &rhs) { *this = rhs; } OpPassManager &OpPassManager::operator=(const OpPassManager &rhs) { impl.reset(new OpPassManagerImpl(rhs.impl->name, rhs.impl->nesting)); + impl->initializationGeneration = rhs.impl->initializationGeneration; for (auto &pass : rhs.impl->passes) impl->passes.emplace_back(pass->clone()); return *this; ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 2074177 - [mlir][ODS] Add a C++ abstraction for OpBuilders
Author: River Riddle Date: 2021-01-11T12:06:22-08:00 New Revision: 207417730134931c7d5bf82e0b16c7757ad05e05 URL: https://github.com/llvm/llvm-project/commit/207417730134931c7d5bf82e0b16c7757ad05e05 DIFF: https://github.com/llvm/llvm-project/commit/207417730134931c7d5bf82e0b16c7757ad05e05.diff LOG: [mlir][ODS] Add a C++ abstraction for OpBuilders This removes the need for OpDefinitionsGen to use raw tablegen API, and will also simplify adding builders to TypeDefs as well. Differential Revision: https://reviews.llvm.org/D94273 Added: mlir/include/mlir/TableGen/Builder.h mlir/lib/TableGen/Builder.cpp Modified: mlir/include/mlir/TableGen/Operator.h mlir/lib/TableGen/CMakeLists.txt mlir/lib/TableGen/Operator.cpp mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp Removed: diff --git a/mlir/include/mlir/TableGen/Builder.h b/mlir/include/mlir/TableGen/Builder.h new file mode 100644 index ..b901c8414e81 --- /dev/null +++ b/mlir/include/mlir/TableGen/Builder.h @@ -0,0 +1,85 @@ +//===- Builder.h - Builder classes --*- C++ -*-===// +// +// 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 +// +//===--===// +// +// Builder wrapper to simplify using TableGen Record for building +// operations/types/etc. +// +//===--===// + +#ifndef MLIR_TABLEGEN_BUILDER_H_ +#define MLIR_TABLEGEN_BUILDER_H_ + +#include "mlir/Support/LLVM.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" + +namespace llvm { +class Init; +class Record; +class SMLoc; +} // end namespace llvm + +namespace mlir { +namespace tblgen { + +/// Wrapper class with helper methods for accessing Builders defined in +/// TableGen. +class Builder { +public: + /// This class represents a single parameter to a builder method. + class Parameter { + public: +/// Return a string containing the C++ type of this parameter. +StringRef getCppType() const; + +/// Return an optional string containing the name of this parameter. If +/// None, no name was specified for this parameter by the user. +Optional getName() const { return name; } + +/// Return an optional string containing the default value to use for this +/// parameter. +Optional getDefaultValue() const; + + private: +Parameter(Optional name, const llvm::Init *def) +: name(name), def(def) {} + +/// The optional name of the parameter. +Optional name; + +/// The tablegen definition of the parameter. This is either a StringInit, +/// or a CArg DefInit. +const llvm::Init *def; + +// Allow access to the constructor. +friend Builder; + }; + + /// Construct a builder from the given Record instance. + Builder(const llvm::Record *record, ArrayRef loc); + + /// Return a list of parameters used in this build method. + ArrayRef getParameters() const { return parameters; } + + /// Return an optional string containing the body of the builder. + Optional getBody() const; + +protected: + /// The TableGen definition of this builder. + const llvm::Record *def; + +private: + /// A collection of parameters to the builder. + SmallVector parameters; +}; + +} // end namespace tblgen +} // end namespace mlir + +#endif // MLIR_TABLEGEN_BUILDER_H_ diff --git a/mlir/include/mlir/TableGen/Operator.h b/mlir/include/mlir/TableGen/Operator.h index 16d154b3beb0..d21b4b213ee4 100644 --- a/mlir/include/mlir/TableGen/Operator.h +++ b/mlir/include/mlir/TableGen/Operator.h @@ -16,6 +16,7 @@ #include "mlir/Support/LLVM.h" #include "mlir/TableGen/Argument.h" #include "mlir/TableGen/Attribute.h" +#include "mlir/TableGen/Builder.h" #include "mlir/TableGen/Dialect.h" #include "mlir/TableGen/OpTrait.h" #include "mlir/TableGen/Region.h" @@ -287,6 +288,9 @@ class Operator { // Returns the OperandOrAttribute corresponding to the index. OperandOrAttribute getArgToOperandOrAttribute(int index) const; + // Returns the builders of this operation. + ArrayRef getBuilders() const { return builders; } + private: // Populates the vectors containing operands, attributes, results and traits. void populateOpStructure(); @@ -332,6 +336,9 @@ class Operator { // Map from argument to attribute or operand number. SmallVector attrOrOperandMapping; + // The builders of this operator. + SmallVector builders; + // The number of native attributes stored in the leading positions of // `attributes`. int numNativeAttributes; diff --git a/mlir/lib/TableGen/Builder.cpp b/mlir/lib/TableGen/Builder.cpp new file mode 100644 index ..8210e8fe1a12 --- /dev/null ++
[llvm-branch-commits] [mlir] 948be58 - [mlir][TypeDefGen] Add support for adding builders when generating a TypeDef
Author: River Riddle Date: 2021-01-11T12:06:22-08:00 New Revision: 948be58258dd81d56b1057657193f7dcf6dfa9bd URL: https://github.com/llvm/llvm-project/commit/948be58258dd81d56b1057657193f7dcf6dfa9bd DIFF: https://github.com/llvm/llvm-project/commit/948be58258dd81d56b1057657193f7dcf6dfa9bd.diff LOG: [mlir][TypeDefGen] Add support for adding builders when generating a TypeDef This allows for specifying additional get/getChecked methods that should be generated on the type, and acts similarly to how OpBuilders work. TypeBuilders have two additional components though: * InferredContextParam - Bit indicating that the context parameter of a get method is inferred from one of the builder parameters * checkedBody - A code block representing the body of the equivalent getChecked method. Differential Revision: https://reviews.llvm.org/D94274 Added: Modified: mlir/docs/OpDefinitions.md mlir/include/mlir/Dialect/ArmSVE/ArmSVE.td mlir/include/mlir/IR/OpBase.td mlir/include/mlir/TableGen/TypeDef.h mlir/lib/TableGen/TypeDef.cpp mlir/test/lib/Dialect/Test/TestTypeDefs.td mlir/test/lib/Dialect/Test/TestTypes.cpp mlir/test/mlir-tblgen/typedefs.td mlir/tools/mlir-tblgen/TypeDefGen.cpp Removed: diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index bfd3d43c60b9..dd522904dd73 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -1536,6 +1536,171 @@ responsible for parsing/printing the types in `Dialect::printType` and - The `extraClassDeclaration` field is used to include extra code in the class declaration. +### Type builder methods + +For each type, there are a few builders(`get`/`getChecked`) automatically +generated based on the parameters of the type. For example, given the following +type definition: + +```tablegen +def MyType : ... { + let parameters = (ins "int":$intParam); +} +``` + +The following builders are generated: + +```c++ +// Type builders are named `get`, and return a new instance of a type for a +// given set of parameters. +static MyType get(MLIRContext *context, int intParam); + +// If `genVerifyInvariantsDecl` is set to 1, the following method is also +// generated. +static MyType getChecked(Location loc, int intParam); +``` + +If these autogenerated methods are not desired, such as when they conflict with +a custom builder method, a type can set `skipDefaultBuilders` to 1 to signal +that they should not be generated. + + Custom type builder methods + +The default build methods may cover a majority of the simple cases related to +type construction, but when they cannot satisfy a type's needs, you can define +additional convenience get methods in the `builders` field as follows: + +```tablegen +def MyType : ... { + let parameters = (ins "int":$intParam); + + let builders = [ +TypeBuilder<(ins "int":$intParam)>, +TypeBuilder<(ins CArg<"int", "0">:$intParam)>, +TypeBuilder<(ins CArg<"int", "0">:$intParam), [{ + // Write the body of the `get` builder inline here. + return Base::get($_ctxt, intParam); +}]>, +TypeBuilderWithInferredContext<(ins "Type":$typeParam), [{ + // This builder states that it can infer an MLIRContext instance from + // its arguments. + return Base::get(typeParam.getContext(), ...); +}]>, + ]; +} +``` + +The `builders` field is a list of custom builders that are added to the type +class. In this example, we provide a several diff erent convenience builders that +are useful in diff erent scenarios. The `ins` prefix is common to many function +declarations in ODS, which use a TableGen [`dag`](#tablegen-syntax). What +follows is a comma-separated list of types (quoted string or CArg) and names +prefixed with the `$` sign. The use of `CArg` allows for providing a default +value to that argument. Let's take a look at each of these builders individually + +The first builder will generate the declaration of a builder method that looks +like: + +```tablegen + let builders = [ +TypeBuilder<(ins "int":$intParam)>, + ]; +``` + +```c++ +class MyType : /*...*/ { + /*...*/ + static MyType get(::mlir::MLIRContext *context, int intParam); +}; +``` + +This builder is identical to the one that will be automatically generated for +`MyType`. The `context` parameter is implicitly added by the generator, and is +used when building the file Type instance (with `Base::get`). The distinction +here is that we can provide the implementation of this `get` method. With this +style of builder definition only the declaration is generated, the implementor +of MyType will need to provide a definition of `MyType::get`. + +The second builder will generate the declaration of a builder method that looks +like: + +```tablegen + let builders = [ +TypeBuilder<(ins CArg<"int", "0">:$intParam)>, + ]; +``` + +```c++ +class MyType : /*...*/ { + /*...*/ +
[llvm-branch-commits] [mlir] d79642b - [mlir][IR][NFC] Move the definitions of Complex/Function/Integer/Opaque/TupleType to ODS
Author: River Riddle Date: 2021-01-11T12:06:22-08:00 New Revision: d79642b3db1d74524f41d37f78385950158787a4 URL: https://github.com/llvm/llvm-project/commit/d79642b3db1d74524f41d37f78385950158787a4 DIFF: https://github.com/llvm/llvm-project/commit/d79642b3db1d74524f41d37f78385950158787a4.diff LOG: [mlir][IR][NFC] Move the definitions of Complex/Function/Integer/Opaque/TupleType to ODS The type tablegen backend now has enough support to represent these types well enough, so we can now move them to be declaratively defined. Differential Revision: https://reviews.llvm.org/D94275 Added: Modified: mlir/include/mlir/IR/BuiltinTypes.h mlir/include/mlir/IR/BuiltinTypes.td mlir/lib/IR/BuiltinTypes.cpp mlir/lib/IR/MLIRContext.cpp mlir/lib/IR/TypeDetail.h Removed: diff --git a/mlir/include/mlir/IR/BuiltinTypes.h b/mlir/include/mlir/IR/BuiltinTypes.h index d9d1a6e4e68c..835f46dc2295 100644 --- a/mlir/include/mlir/IR/BuiltinTypes.h +++ b/mlir/include/mlir/IR/BuiltinTypes.h @@ -29,119 +29,15 @@ class TypeRange; namespace detail { struct BaseMemRefTypeStorage; -struct ComplexTypeStorage; -struct FunctionTypeStorage; -struct IntegerTypeStorage; struct MemRefTypeStorage; -struct OpaqueTypeStorage; struct RankedTensorTypeStorage; struct ShapedTypeStorage; -struct TupleTypeStorage; struct UnrankedMemRefTypeStorage; struct UnrankedTensorTypeStorage; struct VectorTypeStorage; } // namespace detail -//===--===// -// ComplexType -//===--===// - -/// The 'complex' type represents a complex number with a parameterized element -/// type, which is composed of a real and imaginary value of that element type. -/// -/// The element must be a floating point or integer scalar type. -/// -class ComplexType -: public Type::TypeBase { -public: - using Base::Base; - - /// Get or create a ComplexType with the provided element type. - static ComplexType get(Type elementType); - - /// Get or create a ComplexType with the provided element type. This emits - /// and error at the specified location and returns null if the element type - /// isn't supported. - static ComplexType getChecked(Location location, Type elementType); - - /// Verify the construction of an integer type. - static LogicalResult verifyConstructionInvariants(Location loc, -Type elementType); - - Type getElementType(); -}; - -//===--===// -// IntegerType -//===--===// - -/// Integer types can have arbitrary bitwidth up to a large fixed limit. -class IntegerType -: public Type::TypeBase { -public: - using Base::Base; - - /// Signedness semantics. - enum SignednessSemantics : uint32_t { -Signless, /// No signedness semantics -Signed, /// Signed integer -Unsigned, /// Unsigned integer - }; - - /// Get or create a new IntegerType of the given width within the context. - /// The created IntegerType is signless (i.e., no signedness semantics). - /// Assume the width is within the allowed range and assert on failures. Use - /// getChecked to handle failures gracefully. - static IntegerType get(MLIRContext *context, unsigned width); - - /// Get or create a new IntegerType of the given width within the context. - /// The created IntegerType has signedness semantics as indicated via - /// `signedness`. Assume the width is within the allowed range and assert on - /// failures. Use getChecked to handle failures gracefully. - static IntegerType get(MLIRContext *context, unsigned width, - SignednessSemantics signedness); - - /// Get or create a new IntegerType of the given width within the context, - /// defined at the given, potentially unknown, location. The created - /// IntegerType is signless (i.e., no signedness semantics). If the width is - /// outside the allowed range, emit errors and return a null type. - static IntegerType getChecked(Location location, unsigned width); - - /// Get or create a new IntegerType of the given width within the context, - /// defined at the given, potentially unknown, location. The created - /// IntegerType has signedness semantics as indicated via `signedness`. If the - /// width is outside the allowed range, emit errors and return a null type. - static IntegerType getChecked(Location location, unsigned width, -SignednessSemantics signedness); - - /// Verify the construction of an integer type. - static LogicalResult - verifyConstructionInvariants(Location loc, unsigned width, - SignednessSemantics signedness); - - /// Return the bitwidth of this i
[llvm-branch-commits] [mlir] 00a61b3 - [mlir][ODS] Add new RangedTypesMatchWith operation predicate
Author: River Riddle Date: 2021-01-14T11:35:49-08:00 New Revision: 00a61b327dd8a7071ce0baadd16ea4c7b7e31e73 URL: https://github.com/llvm/llvm-project/commit/00a61b327dd8a7071ce0baadd16ea4c7b7e31e73 DIFF: https://github.com/llvm/llvm-project/commit/00a61b327dd8a7071ce0baadd16ea4c7b7e31e73.diff LOG: [mlir][ODS] Add new RangedTypesMatchWith operation predicate This is a variant of TypesMatchWith that provides support for variadic arguments. This is necessary because ranges generally can't use the default operator== comparators for checking equality. Differential Revision: https://reviews.llvm.org/D94574 Added: Modified: mlir/include/mlir/IR/OpBase.td mlir/test/lib/Dialect/Test/TestOps.td mlir/test/mlir-tblgen/op-format.mlir mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/mlir/include/mlir/IR/OpBase.td b/mlir/include/mlir/IR/OpBase.td index 73ddbc1d56eb..3b55e51d8178 100644 --- a/mlir/include/mlir/IR/OpBase.td +++ b/mlir/include/mlir/IR/OpBase.td @@ -2191,16 +2191,28 @@ class AllTypesMatch names> : AllMatchSameOperatorTrait; // A type constraint that denotes `transform(lhs.getType()) == rhs.getType()`. +// An optional comparator function may be provided that changes the above form +// into: `comparator(transform(lhs.getType()), rhs.getType())`. class TypesMatchWith : -PredOpTrait> { + string transform, string comparator = "std::equal_to<>()"> + : PredOpTrait> { string lhs = lhsArg; string rhs = rhsArg; string transformer = transform; } +// Special variant of `TypesMatchWith` that provides a comparator suitable for +// ranged arguments. +class RangedTypesMatchWith + : TypesMatchWith; + // Type Constraint operand `idx`'s Element type is `type`. class TCopVTEtIs : And<[ CPred<"$_op.getNumOperands() > " # idx>, diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 1fc419cc375f..d1cbe77ac21b 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1733,6 +1733,15 @@ def FormatTypesMatchVarOp : TEST_Op<"format_types_match_var", [ let assemblyFormat = "attr-dict $value `:` type($value)"; } +def FormatTypesMatchVariadicOp : TEST_Op<"format_types_match_variadic", [ +RangedTypesMatchWith<"result type matches operand", "value", "result", + "llvm::make_range($_self.begin(), $_self.end())"> + ]> { + let arguments = (ins Variadic:$value); + let results = (outs Variadic:$result); + let assemblyFormat = "attr-dict $value `:` type($value)"; +} + def FormatTypesMatchAttrOp : TEST_Op<"format_types_match_attr", [ TypesMatchWith<"result type matches constant", "value", "result", "$_self"> ]> { diff --git a/mlir/test/mlir-tblgen/op-format.mlir b/mlir/test/mlir-tblgen/op-format.mlir index 334313debda1..4eb64772aee2 100644 --- a/mlir/test/mlir-tblgen/op-format.mlir +++ b/mlir/test/mlir-tblgen/op-format.mlir @@ -308,5 +308,8 @@ test.format_infer_variadic_type_from_non_variadic %i64, %i64 : i64 // CHECK: test.format_types_match_var %[[I64]] : i64 %ignored_res3 = test.format_types_match_var %i64 : i64 +// CHECK: test.format_types_match_variadic %[[I64]], %[[I64]], %[[I64]] : i64, i64, i64 +%ignored_res4:3 = test.format_types_match_variadic %i64, %i64, %i64 : i64, i64, i64 + // CHECK: test.format_types_match_attr 1 : i64 -%ignored_res4 = test.format_types_match_attr 1 : i64 +%ignored_res5 = test.format_types_match_attr 1 : i64 diff --git a/mlir/tools/mlir-tblgen/OpFormatGen.cpp b/mlir/tools/mlir-tblgen/OpFormatGen.cpp index 749ef1613c14..bba796f9b492 100644 --- a/mlir/tools/mlir-tblgen/OpFormatGen.cpp +++ b/mlir/tools/mlir-tblgen/OpFormatGen.cpp @@ -1287,10 +1287,16 @@ void OperationFormat::genParserTypeResolution(Operator &op, if (Optional val = resolver.getBuilderIdx()) { body << "odsBuildableType" << *val; } else if (const NamedTypeConstraint *var = resolver.getVariable()) { - if (Optional tform = resolver.getVarTransformer()) -body << tgfmt(*tform, &FmtContext().withSelf(var->name + "Types[0]")); - else + if (Optional tform = resolver.getVarTransformer()) { +FmtContext fmtContext; +if (var->isVariadic()) + fmtContext.withSelf(var->name + "Types"); +else + fmtContext.withSelf(var->name + "Types[0]"); +body << tgfmt(*tform, &fmtContext); + } else { body << var->name << "Types"; + } } else if (const NamedAttribute *attr = resolver.getAttribute()) { if (Optional tform = resolver.getVarTransformer()) body << tgfmt(*tform, ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] c8fb6ee - [mlir][PatternRewriter] Add a new hook to selectively replace uses of an operation
Author: River Riddle Date: 2021-01-14T11:58:21-08:00 New Revision: c8fb6ee34151b18bcc9ed1a6b8f502a0b40a414e URL: https://github.com/llvm/llvm-project/commit/c8fb6ee34151b18bcc9ed1a6b8f502a0b40a414e DIFF: https://github.com/llvm/llvm-project/commit/c8fb6ee34151b18bcc9ed1a6b8f502a0b40a414e.diff LOG: [mlir][PatternRewriter] Add a new hook to selectively replace uses of an operation This revision adds a new `replaceOpWithIf` hook that replaces uses of an operation that satisfy a given functor. If all uses are replaced, the operation gets erased in a similar manner to `replaceOp`. DialectConversion support will be added in a followup as this requires adjusting how replacements are tracked there. Differential Revision: https://reviews.llvm.org/D94632 Added: mlir/test/Transforms/test-pattern-selective-replacement.mlir Modified: mlir/include/mlir/IR/PatternMatch.h mlir/include/mlir/Transforms/DialectConversion.h mlir/lib/IR/PatternMatch.cpp mlir/lib/Transforms/Utils/DialectConversion.cpp mlir/test/lib/Dialect/Test/TestPatterns.cpp Removed: diff --git a/mlir/include/mlir/IR/PatternMatch.h b/mlir/include/mlir/IR/PatternMatch.h index d97b328cdc01..1a306e6ba58c 100644 --- a/mlir/include/mlir/IR/PatternMatch.h +++ b/mlir/include/mlir/IR/PatternMatch.h @@ -11,6 +11,7 @@ #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" +#include "llvm/ADT/FunctionExtras.h" namespace mlir { @@ -447,6 +448,30 @@ class PatternRewriter : public OpBuilder, public OpBuilder::Listener { Region::iterator before); void cloneRegionBefore(Region ®ion, Block *before); + /// This method replaces the uses of the results of `op` with the values in + /// `newValues` when the provided `functor` returns true for a specific use. + /// The number of values in `newValues` is required to match the number of + /// results of `op`. `allUsesReplaced`, if non-null, is set to true if all of + /// the uses of `op` were replaced. Note that in some pattern rewriters, the + /// given 'functor' may be stored beyond the lifetime of the pattern being + /// applied. As such, the function should not capture by reference and instead + /// use value capture as necessary. + virtual void + replaceOpWithIf(Operation *op, ValueRange newValues, bool *allUsesReplaced, + llvm::unique_function functor); + void replaceOpWithIf(Operation *op, ValueRange newValues, + llvm::unique_function functor) { +replaceOpWithIf(op, newValues, /*allUsesReplaced=*/nullptr, +std::move(functor)); + } + + /// This method replaces the uses of the results of `op` with the values in + /// `newValues` when a use is nested within the given `block`. The number of + /// values in `newValues` is required to match the number of results of `op`. + /// If all uses of this operation are replaced, the operation is erased. + void replaceOpWithinBlock(Operation *op, ValueRange newValues, Block *block, +bool *allUsesReplaced = nullptr); + /// This method performs the final replacement for a pattern, where the /// results of the operation are updated to use the specified list of SSA /// values. diff --git a/mlir/include/mlir/Transforms/DialectConversion.h b/mlir/include/mlir/Transforms/DialectConversion.h index 51c7788ffb14..ca28c175fbdd 100644 --- a/mlir/include/mlir/Transforms/DialectConversion.h +++ b/mlir/include/mlir/Transforms/DialectConversion.h @@ -470,6 +470,12 @@ class ConversionPatternRewriter final : public PatternRewriter { // PatternRewriter Hooks //======// + /// PatternRewriter hook for replacing the results of an operation when the + /// given functor returns true. + void replaceOpWithIf( + Operation *op, ValueRange newValues, bool *allUsesReplaced, + llvm::unique_function functor) override; + /// PatternRewriter hook for replacing the results of an operation. void replaceOp(Operation *op, ValueRange newValues) override; using PatternRewriter::replaceOp; diff --git a/mlir/lib/IR/PatternMatch.cpp b/mlir/lib/IR/PatternMatch.cpp index 6558fcf4606d..44f22ceeb3cf 100644 --- a/mlir/lib/IR/PatternMatch.cpp +++ b/mlir/lib/IR/PatternMatch.cpp @@ -155,6 +155,41 @@ PatternRewriter::~PatternRewriter() { // Out of line to provide a vtable anchor for the class. } +/// This method replaces the uses of the results of `op` with the values in +/// `newValues` when the provided `functor` returns true for a specific use. +/// The number of values in `newValues` is required to match the number of +/// results of `op`. +void PatternRewriter::replaceOpWithIf( +Operation *op, ValueRange newValues, bool *allUsesReplaced, +llvm::unique_function functor) { + assert(op->getNumResults() == newValues.size() && +
[llvm-branch-commits] [mlir] 2a27a98 - [mlir][AsmPrinter] Properly escape strings when printing locations
Author: River Riddle Date: 2021-01-15T17:14:57-08:00 New Revision: 2a27a9819a1e3371e3e08d7fbad6235cf50d336d URL: https://github.com/llvm/llvm-project/commit/2a27a9819a1e3371e3e08d7fbad6235cf50d336d DIFF: https://github.com/llvm/llvm-project/commit/2a27a9819a1e3371e3e08d7fbad6235cf50d336d.diff LOG: [mlir][AsmPrinter] Properly escape strings when printing locations This fixes errors when location strings contains newlines, or other non-ascii characters. Differential Revision: https://reviews.llvm.org/D94847 Added: Modified: mlir/lib/IR/AsmPrinter.cpp mlir/test/IR/locations.mlir Removed: diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index c56fdff2cde5..3182e906ce93 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -1257,12 +1257,19 @@ void ModulePrinter::printLocationInternal(LocationAttr loc, bool pretty) { os << "unknown"; }) .Case([&](FileLineColLoc loc) { -StringRef mayQuote = pretty ? "" : "\""; -os << mayQuote << loc.getFilename() << mayQuote << ':' << loc.getLine() - << ':' << loc.getColumn(); +if (pretty) { + os << loc.getFilename(); +} else { + os << "\""; + printEscapedString(loc.getFilename(), os); + os << "\""; +} +os << ':' << loc.getLine() << ':' << loc.getColumn(); }) .Case([&](NameLoc loc) { -os << '\"' << loc.getName() << '\"'; +os << '\"'; +printEscapedString(loc.getName(), os); +os << '\"'; // Print the child if it isn't unknown. auto childLoc = loc.getChildLoc(); diff --git a/mlir/test/IR/locations.mlir b/mlir/test/IR/locations.mlir index 950b67827a0f..5ad854eedc10 100644 --- a/mlir/test/IR/locations.mlir +++ b/mlir/test/IR/locations.mlir @@ -27,6 +27,20 @@ func @inline_notation() -> i32 { // CHECK-LABEL: func private @loc_attr(i1 {foo.loc_attr = loc(callsite("foo" at "mysource.cc":10:8))}) func private @loc_attr(i1 {foo.loc_attr = loc(callsite("foo" at "mysource.cc":10:8))}) + // Check that locations get properly escaped. +// CHECK-LABEL: func @escape_strings() +func @escape_strings() { + // CHECK: loc("escaped\0A") + "foo"() : () -> () loc("escaped\n") + + // CHECK: loc("escaped\0A") + "foo"() : () -> () loc("escaped\0A") + + // CHECK: loc("escaped\0A":0:0) + "foo"() : () -> () loc("escaped\n":0:0) + return +} + // CHECK-ALIAS: "foo.op"() : () -> () loc(#[[LOC:.*]]) "foo.op"() : () -> () loc(#loc) ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] d1e0545 - [mlir][Interfaces] Tidy up the documentation for interfaces
Author: River Riddle Date: 2020-12-09T15:34:07-08:00 New Revision: d1e0545445ced928ae4f0437997278e09cefde1d URL: https://github.com/llvm/llvm-project/commit/d1e0545445ced928ae4f0437997278e09cefde1d DIFF: https://github.com/llvm/llvm-project/commit/d1e0545445ced928ae4f0437997278e09cefde1d.diff LOG: [mlir][Interfaces] Tidy up the documentation for interfaces The documentation has become a bit stale with age, and doesn't include great documentation for some newer concepts. This revision tidies up a majority of it, with some more cleanup to come in the future. The documentation for the declarative specification is also moved from OpDefinitions.md to Interfaces.md, which is a much more logical place for it to live. Differential Revision: https://reviews.llvm.org/D92895 Added: Modified: mlir/docs/Interfaces.md mlir/docs/OpDefinitions.md Removed: diff --git a/mlir/docs/Interfaces.md b/mlir/docs/Interfaces.md index 9e32a70888aa..4fe8421295ec 100644 --- a/mlir/docs/Interfaces.md +++ b/mlir/docs/Interfaces.md @@ -1,46 +1,47 @@ # Interfaces -MLIR is a generic and extensible framework, representing diff erent -dialects with their own operations, attributes, types, and so on. -MLIR Dialects can express operations with a wide variety of semantics -and diff erent levels of abstraction. The downside to this is that MLIR -transformations and analyses need to account for the semantics of -every operation, or handle operations conservatively. Without care, -this can result in code with special-cases for each supported -operation type. To combat this, MLIR provides the concept of -`interfaces`. +MLIR is a generic and extensible framework, representing diff erent dialects with +their own attributes, operations, types, and so on. MLIR Dialects can express +operations with a wide variety of semantics and diff erent levels of abstraction. +The downside to this is that MLIR transformations and analyses need to be able +to account for the semantics of every operation, or be overly conservative. +Without care, this can result in code with special-cases for each supported +operation type. To combat this, MLIR provides a concept of `interfaces`. ## Motivation Interfaces provide a generic way of interacting with the IR. The goal is to be able to express transformations/analyses in terms of these interfaces without encoding specific knowledge about the exact operation or dialect involved. This -makes the compiler more extensible by allowing the addition of new dialects and -operations in a decoupled way with respect to the implementation of +makes the compiler more easily extensible by allowing the addition of new +dialects and operations in a decoupled way with respect to the implementation of transformations/analyses. ### Dialect Interfaces Dialect interfaces are generally useful for transformation passes or analyses that want to operate generically on a set of attributes/operations/types, which -might even be defined in diff erent dialects. These interfaces generally involve -wide coverage over the entire dialect and are only used for a handful of -transformations/analyses. In these cases, registering the interface directly on -each operation is overly complex and cumbersome. The interface is not core to -the operation, just to the specific transformation. An example of where this -type of interface would be used is inlining. Inlining generally queries -high-level information about the operations within a dialect, like legality and -cost modeling, that often is not specific to one operation. - -A dialect interface can be defined by inheriting from the CRTP base class -`DialectInterfaceBase::Base`. This class provides the necessary utilities for -registering an interface with the dialect so that it can be looked up later. -Once the interface has been defined, dialects can override it using -dialect-specific information. The interfaces defined by a dialect are registered -in a similar mechanism to Attributes, Operations, Types, etc. +may be defined in diff erent dialects. These interfaces generally involve wide +coverage over an entire dialect and are only used for a handful of analyses or +transformations. In these cases, registering the interface directly on each +operation is overly complex and cumbersome. The interface is not core to the +operation, just to the specific transformation. An example of where this type of +interface would be used is inlining. Inlining generally queries high-level +information about the operations within a dialect, like cost modeling and +legality, that often is not specific to one operation. + +A dialect interface can be defined by inheriting from the +[CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) base +class `DialectInterfaceBase::Base<>`. This class provides the necessary +utilities for registering an interface with a dialect s
[llvm-branch-commits] [mlir] 1f5f006 - [mlir][StandardOps] Verify that the result of an integer constant is signless
Author: River Riddle Date: 2020-12-10T12:40:10-08:00 New Revision: 1f5f006d9d53e785296d1a8fbb0e90904a5eaf60 URL: https://github.com/llvm/llvm-project/commit/1f5f006d9d53e785296d1a8fbb0e90904a5eaf60 DIFF: https://github.com/llvm/llvm-project/commit/1f5f006d9d53e785296d1a8fbb0e90904a5eaf60.diff LOG: [mlir][StandardOps] Verify that the result of an integer constant is signless This was missed when supported for unsigned/signed integer types was first added, and results in crashes if a user tries to create/print a constant with the incorrect integer type. Fixes PR#46222 Differential Revision: https://reviews.llvm.org/D92981 Added: Modified: mlir/lib/Dialect/StandardOps/IR/Ops.cpp mlir/test/Dialect/Standard/invalid.mlir Removed: diff --git a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp index 34c3da9b5eca..0efba0d9d4d8 100644 --- a/mlir/lib/Dialect/StandardOps/IR/Ops.cpp +++ b/mlir/lib/Dialect/StandardOps/IR/Ops.cpp @@ -1136,7 +1136,7 @@ static LogicalResult verify(ConstantOp &op) { if (!value) return op.emitOpError("requires a 'value' attribute"); - auto type = op.getType(); + Type type = op.getType(); if (!value.getType().isa() && type != value.getType()) return op.emitOpError() << "requires attribute's type (" << value.getType() << ") to match op's return type (" << type << ")"; @@ -1145,10 +1145,14 @@ static LogicalResult verify(ConstantOp &op) { return success(); if (auto intAttr = value.dyn_cast()) { +IntegerType intType = type.cast(); +if (!intType.isSignless()) + return op.emitOpError("requires integer result types to be signless"); + // If the type has a known bitwidth we verify that the value can be // represented with the given bitwidth. -auto bitwidth = type.cast().getWidth(); -auto intVal = intAttr.getValue(); +unsigned bitwidth = intType.getWidth(); +APInt intVal = intAttr.getValue(); if (!intVal.isSignedIntN(bitwidth) && !intVal.isIntN(bitwidth)) return op.emitOpError("requires 'value' to be an integer within the " "range of the integer result type"); @@ -1228,9 +1232,13 @@ bool ConstantOp::isBuildableWith(Attribute value, Type type) { // SymbolRefAttr can only be used with a function type. if (value.isa()) return type.isa(); - // Otherwise, the attribute must have the same type as 'type'. + // The attribute must have the same type as 'type'. if (value.getType() != type) return false; + // If the type is an integer type, it must be signless. + if (IntegerType integerTy = type.dyn_cast()) +if (!integerTy.isSignless()) + return false; // Finally, check that the attribute kind is handled. return value.isa(); } diff --git a/mlir/test/Dialect/Standard/invalid.mlir b/mlir/test/Dialect/Standard/invalid.mlir index 04ecdc64351a..48d2ae23466c 100644 --- a/mlir/test/Dialect/Standard/invalid.mlir +++ b/mlir/test/Dialect/Standard/invalid.mlir @@ -298,3 +298,18 @@ func @mismatched_types() { return } +// - + +func @non_signless_constant() { + // expected-error @+1 {{requires integer result types to be signless}} + %0 = constant 0 : ui32 + return +} + +// - + +func @non_signless_constant() { + // expected-error @+1 {{requires integer result types to be signless}} + %0 = constant 0 : si32 + return +} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] 75eca67 - [mlir][Parser] Fix crash in DenseElementsAttr parser when no elements are parsed
Author: River Riddle Date: 2020-12-10T12:48:37-08:00 New Revision: 75eca67c1c4b53a07a70cd3c8036713aec537769 URL: https://github.com/llvm/llvm-project/commit/75eca67c1c4b53a07a70cd3c8036713aec537769 DIFF: https://github.com/llvm/llvm-project/commit/75eca67c1c4b53a07a70cd3c8036713aec537769.diff LOG: [mlir][Parser] Fix crash in DenseElementsAttr parser when no elements are parsed This fixes a crash when no elements are parsed, but the type expects at least one. Fixes PR#47763 Differential Revision: https://reviews.llvm.org/D92982 Added: Modified: mlir/lib/Parser/AttributeParser.cpp mlir/test/IR/invalid.mlir Removed: diff --git a/mlir/lib/Parser/AttributeParser.cpp b/mlir/lib/Parser/AttributeParser.cpp index 2e385cfa30e7..e78237e8e5a0 100644 --- a/mlir/lib/Parser/AttributeParser.cpp +++ b/mlir/lib/Parser/AttributeParser.cpp @@ -531,6 +531,13 @@ DenseElementsAttr TensorLiteralParser::getAttr(llvm::SMLoc loc, return nullptr; } + // Handle the case where no elements were parsed. + if (!hexStorage.hasValue() && storage.empty() && type.getNumElements()) { +p.emitError(loc) << "parsed zero elements, but type (" << type + << ") expected at least 1"; +return nullptr; + } + // Handle complex types in the specific element type cases below. bool isComplex = false; if (ComplexType complexTy = eltType.dyn_cast()) { diff --git a/mlir/test/IR/invalid.mlir b/mlir/test/IR/invalid.mlir index 4930341a8b64..6b28b33e7c78 100644 --- a/mlir/test/IR/invalid.mlir +++ b/mlir/test/IR/invalid.mlir @@ -687,6 +687,11 @@ func @elementsattr_toolarge1() -> () { // - +// expected-error@+1 {{parsed zero elements, but type ('tensor') expected at least 1}} +#attr = dense<> : tensor + +// - + func @elementsattr_toolarge2() -> () { ^bb0: "foo"(){bar = dense<[-777]> : tensor<1xi8>} : () -> () // expected-error {{integer constant out of range}} ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] c24f88b - [mlir][SCCP] Don't visit private callables unless they are used when tracking interprocedural arguments/results
Author: River Riddle Date: 2020-12-10T12:53:27-08:00 New Revision: c24f88b4db2ef359f47e976d8d79334ced221288 URL: https://github.com/llvm/llvm-project/commit/c24f88b4db2ef359f47e976d8d79334ced221288 DIFF: https://github.com/llvm/llvm-project/commit/c24f88b4db2ef359f47e976d8d79334ced221288.diff LOG: [mlir][SCCP] Don't visit private callables unless they are used when tracking interprocedural arguments/results This fixes a subtle bug where SCCP could incorrectly optimize a private callable while waiting for its arguments to be resolved. Fixes PR#48457 Differential Revision: https://reviews.llvm.org/D92976 Added: Modified: mlir/lib/Transforms/SCCP.cpp mlir/test/Transforms/sccp-callgraph.mlir Removed: diff --git a/mlir/lib/Transforms/SCCP.cpp b/mlir/lib/Transforms/SCCP.cpp index 919559c8a6df..9886331820e3 100644 --- a/mlir/lib/Transforms/SCCP.cpp +++ b/mlir/lib/Transforms/SCCP.cpp @@ -236,6 +236,11 @@ class SCCPSolver { /// state. void visitBlockArgument(Block *block, int i); + /// Mark the entry block of the given region as executable. Returns false if + /// the block was already marked executable. If `markArgsOverdefined` is true, + /// the arguments of the entry block are also set to overdefined. + bool markEntryBlockExecutable(Region *region, bool markArgsOverdefined); + /// Mark the given block as executable. Returns false if the block was already /// marked executable. bool markBlockExecutable(Block *block); @@ -313,16 +318,9 @@ class SCCPSolver { SCCPSolver::SCCPSolver(Operation *op) { /// Initialize the solver with the regions within this operation. for (Region ®ion : op->getRegions()) { -if (region.empty()) - continue; -Block *entryBlock = ®ion.front(); - -// Mark the entry block as executable. -markBlockExecutable(entryBlock); - -// The values passed to these regions are invisible, so mark any arguments -// as overdefined. -markAllOverdefined(entryBlock->getArguments()); +// Mark the entry block as executable. The values passed to these regions +// are also invisible, so mark any arguments as overdefined. +markEntryBlockExecutable(®ion, /*markArgsOverdefined=*/true); } initializeSymbolCallables(op); } @@ -405,8 +403,10 @@ void SCCPSolver::initializeSymbolCallables(Operation *op) { // If not all of the uses of this symbol are visible, we can't track the // state of the arguments. - if (symbol.isPublic() || (!allUsesVisible && symbol.isNested())) -markAllOverdefined(callableRegion->getArguments()); + if (symbol.isPublic() || (!allUsesVisible && symbol.isNested())) { +for (Region ®ion : callable->getRegions()) + markEntryBlockExecutable(®ion, /*markArgsOverdefined=*/true); + } } if (callableLatticeState.empty()) return; @@ -443,8 +443,10 @@ void SCCPSolver::initializeSymbolCallables(Operation *op) { // This use isn't a call, so don't we know all of the callers. auto *symbol = symbolTable.lookupSymbolIn(op, use.getSymbolRef()); auto it = callableLatticeState.find(symbol); - if (it != callableLatticeState.end()) -markAllOverdefined(it->second.getCallableArguments()); + if (it != callableLatticeState.end()) { +for (Region ®ion : it->first->getRegions()) + markEntryBlockExecutable(®ion, /*markArgsOverdefined=*/true); + } } }; SymbolTable::walkSymbolTables(op, /*allSymUsesVisible=*/!op->getBlock(), @@ -495,8 +497,14 @@ void SCCPSolver::visitOperation(Operation *op) { // Process callable operations. These are specially handled region operations // that track dataflow via calls. - if (isa(op)) + if (isa(op)) { +// If this callable has a tracked lattice state, it will be visited by calls +// that reference it instead. This way, we don't assume that it is +// executable unless there is a proper reference to it. +if (callableLatticeState.count(op)) + return; return visitCallableOperation(op); + } // Process region holding operations. The region visitor processes result // values, so we can exit afterwards. @@ -551,19 +559,11 @@ void SCCPSolver::visitOperation(Operation *op) { } void SCCPSolver::visitCallableOperation(Operation *op) { - // Mark the regions as executable. + // Mark the regions as executable. If we aren't tracking lattice state for + // this callable, mark all of the region arguments as overdefined. bool isTrackingLatticeState = callableLatticeState.count(op); - for (Region ®ion : op->getRegions()) { -if (region.empty()) - continue; -Block *entryBlock = ®ion.front(); -markBlockExecutable(entryBlock); - -// If we aren't tracking lattice state for this callable, mark all of the -// region arguments as overdefined. -if (!isTrackingLatticeState) - markAllOverdefined(entryBlock
[llvm-branch-commits] [mlir] 186c154 - [mlir] Remove the dependency on StandardOps from FoldUtils
Author: River Riddle Date: 2020-12-10T14:13:57-08:00 New Revision: 186c154991e85f8d6a4a77c5add3322351862725 URL: https://github.com/llvm/llvm-project/commit/186c154991e85f8d6a4a77c5add3322351862725 DIFF: https://github.com/llvm/llvm-project/commit/186c154991e85f8d6a4a77c5add3322351862725.diff LOG: [mlir] Remove the dependency on StandardOps from FoldUtils OperationFolder currently uses ConstantOp as a backup when trying to materialize a constant after an operation is folded. This dependency isn't really useful or necessary given that dialects can/should provide a `materializeConstant` implementation. Fixes PR#44866 Differential Revision: https://reviews.llvm.org/D92980 Added: Modified: mlir/lib/Dialect/Shape/IR/Shape.cpp mlir/lib/Transforms/Utils/FoldUtils.cpp mlir/test/lib/Dialect/Test/TestDialect.cpp mlir/test/lib/Dialect/Test/TestOps.td mlir/test/mlir-tblgen/pattern.mlir Removed: diff --git a/mlir/lib/Dialect/Shape/IR/Shape.cpp b/mlir/lib/Dialect/Shape/IR/Shape.cpp index c71360cdaba5..ef29ddc510ae 100644 --- a/mlir/lib/Dialect/Shape/IR/Shape.cpp +++ b/mlir/lib/Dialect/Shape/IR/Shape.cpp @@ -110,7 +110,7 @@ Operation *ShapeDialect::materializeConstant(OpBuilder &builder, return builder.create(loc, type, value.cast()); if (type.isa()) return builder.create(loc, type, value.cast()); - if (type.isa()) + if (ConstantOp::isBuildableWith(value, type)) return builder.create(loc, type, value); return nullptr; } diff --git a/mlir/lib/Transforms/Utils/FoldUtils.cpp b/mlir/lib/Transforms/Utils/FoldUtils.cpp index 074f71c92fff..ba755a748418 100644 --- a/mlir/lib/Transforms/Utils/FoldUtils.cpp +++ b/mlir/lib/Transforms/Utils/FoldUtils.cpp @@ -13,7 +13,6 @@ #include "mlir/Transforms/FoldUtils.h" -#include "mlir/Dialect/StandardOps/IR/Ops.h" #include "mlir/IR/Builders.h" #include "mlir/IR/Matchers.h" #include "mlir/IR/Operation.h" @@ -60,11 +59,6 @@ static Operation *materializeConstant(Dialect *dialect, OpBuilder &builder, assert(matchPattern(constOp, m_Constant())); return constOp; } - - // If the dialect is unable to materialize a constant, check to see if the - // standard constant can be used. - if (ConstantOp::isBuildableWith(value, type)) -return builder.create(loc, type, value); return nullptr; } diff --git a/mlir/test/lib/Dialect/Test/TestDialect.cpp b/mlir/test/lib/Dialect/Test/TestDialect.cpp index c7e1b7f48f43..eeff840daeea 100644 --- a/mlir/test/lib/Dialect/Test/TestDialect.cpp +++ b/mlir/test/lib/Dialect/Test/TestDialect.cpp @@ -178,6 +178,11 @@ void TestDialect::initialize() { allowUnknownOperations(); } +Operation *TestDialect::materializeConstant(OpBuilder &builder, Attribute value, +Type type, Location loc) { + return builder.create(loc, type, value); +} + static Type parseTestType(MLIRContext *ctxt, DialectAsmParser &parser, llvm::SetVector &stack) { StringRef typeTag; diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 1579e53e5277..9008ee7ca99f 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -23,6 +23,7 @@ include "TestInterfaces.td" def Test_Dialect : Dialect { let name = "test"; let cppNamespace = "::mlir::test"; + let hasConstantMaterializer = 1; let hasOperationAttrVerify = 1; let hasRegionArgAttrVerify = 1; let hasRegionResultAttrVerify = 1; diff --git a/mlir/test/mlir-tblgen/pattern.mlir b/mlir/test/mlir-tblgen/pattern.mlir index 5496209d3886..0425cf819e60 100644 --- a/mlir/test/mlir-tblgen/pattern.mlir +++ b/mlir/test/mlir-tblgen/pattern.mlir @@ -254,7 +254,7 @@ func @verifyUnitAttr() -> (i32, i32) { // CHECK-LABEL: testConstOp func @testConstOp() -> (i32) { - // CHECK-NEXT: [[C0:%.+]] = constant 1 + // CHECK-NEXT: [[C0:%.+]] = "test.constant"() {value = 1 %0 = "test.constant"() {value = 1 : i32} : () -> i32 // CHECK-NEXT: return [[C0]] @@ -263,7 +263,7 @@ func @testConstOp() -> (i32) { // CHECK-LABEL: testConstOpUsed func @testConstOpUsed() -> (i32) { - // CHECK-NEXT: [[C0:%.+]] = constant 1 + // CHECK-NEXT: [[C0:%.+]] = "test.constant"() {value = 1 %0 = "test.constant"() {value = 1 : i32} : () -> i32 // CHECK-NEXT: [[V0:%.+]] = "test.op_s"([[C0]]) @@ -275,7 +275,7 @@ func @testConstOpUsed() -> (i32) { // CHECK-LABEL: testConstOpReplaced func @testConstOpReplaced() -> (i32) { - // CHECK-NEXT: [[C0:%.+]] = constant 1 + // CHECK-NEXT: [[C0:%.+]] = "test.constant"() {value = 1 %0 = "test.constant"() {value = 1 : i32} : () -> i32 %1 = "test.constant"() {value = 2 : i32} : () -> i32 @@ -288,10 +288,10 @@ func @testConstOpReplaced() -> (i32) { // CHECK-LABEL: testConstOpMatchFailure func @testConstOpMatchFailure() -> (i64) { - // CHECK-DAG: [[C0:%.+]] = const
[llvm-branch-commits] [mlir] e9987ad - [mlir][docs] Tidy up the pass infrastructure documentation
Author: River Riddle Date: 2020-12-11T17:53:33-08:00 New Revision: e9987ad8783be164b63bdf2fffdd64a6e289e18f URL: https://github.com/llvm/llvm-project/commit/e9987ad8783be164b63bdf2fffdd64a6e289e18f DIFF: https://github.com/llvm/llvm-project/commit/e9987ad8783be164b63bdf2fffdd64a6e289e18f.diff LOG: [mlir][docs] Tidy up the pass infrastructure documentation The doc has grown stale and is missing some recent changes to the infrastructure. Differential Revision: https://reviews.llvm.org/D93081 Added: Modified: mlir/docs/PassManagement.md Removed: diff --git a/mlir/docs/PassManagement.md b/mlir/docs/PassManagement.md index 6e577db4501c..a3a5a49444a9 100644 --- a/mlir/docs/PassManagement.md +++ b/mlir/docs/PassManagement.md @@ -3,15 +3,15 @@ [TOC] Passes represent the basic infrastructure for transformation and optimization. -This document provides a quickstart to the pass infrastructure in MLIR and how -to use it. +This document provides an overview of the pass infrastructure in MLIR and how to +use it. See [MLIR specification](LangRef.md) for more information about MLIR and its core aspects, such as the IR structure and operations. See [MLIR Rewrites](Tutorials/QuickstartRewrites.md) for a quick start on graph -rewriting in MLIR. If your transformation involves pattern matching operation -DAGs, this is a great place to start. +rewriting in MLIR. If a transformation involves pattern matching operation DAGs, +this is a great place to start. ## Operation Pass @@ -23,24 +23,27 @@ further below. All passes in MLIR derive from `OperationPass` and adhere to the following restrictions; any noncompliance will lead to problematic behavior in multithreaded and other advanced scenarios: -* Modify anything within the parent block/region/operation/etc, outside of the -current operation being operated on. This includes adding or removing -operations from the parent block. -* Maintain pass state across invocations of `runOnOperation`. A pass may be -run on several diff erent operations with no guarantee of execution order. -* When multithreading, a specific pass instance may not even execute on -all operations within the module. As such, a pass should not rely on -running on all operations. +* Modify any state referenced or relied upon outside the current being +operated on. This includes adding or removing operations from the parent +block, changing the attributes(depending on the contract of the current +operation)/operands/results/successors of the current operation. * Modify the state of another operation not nested within the current operation being operated on. -* Other threads may be operating on diff erent operations within the module -simultaneously. +* Other threads may be operating on these operations simultaneously. +* Inspect the state of sibling operations. +* Other threads may be modifying these operations in parallel. +* Inspecting the state of ancestor/parent operations is permitted. +* Maintain mutable pass state across invocations of `runOnOperation`. A pass +may be run on many diff erent operations with no guarantee of execution +order. +* When multithreading, a specific pass instance may not even execute on +all operations within the IR. As such, a pass should not rely on running +on all operations. * Maintain any global mutable state, e.g. static variables within the source file. All mutable state should be maintained by an instance of the pass. -* Must be copy-constructible, multiple instances of the pass may be created by -the pass manager to process operations in parallel. -* Inspect the IR of sibling operations. Other threads may be modifying these -operations in parallel. +* Must be copy-constructible +* Multiple instances of the pass may be created by the pass manager to +process operations in parallel. When creating an operation pass, there are two diff erent types to choose from depending on the usage scenario: @@ -62,7 +65,12 @@ A simple pass may look like: ```c++ namespace { -struct MyFunctionPass : public OperationPass { +/// Here we utilize the CRTP `PassWrapper` utility class to provide some +/// necessary utility hooks. This is only necessary for passes defined directly +/// in C++. Passes defined declaratively use a cleaner mechanism for providing +/// these utilities. +struct MyFunctionPass : public PassWrapper, + MyFunctionPass> { void runOnOperation() override { // Get the current FuncOp operation being operated on. FuncOp f = getOperation(); @@ -75,17 +83,23 @@ struct MyFunctionPass : public OperationPass { }; } // end anonymous namespace -// Register this pass to make it accessible to utilities like mlir-opt. -// (Pass
[llvm-branch-commits] [mlir] c234b65 - [mlir][OpFormat] Add support for emitting newlines from the custom format of an operation
Author: River Riddle Date: 2020-12-14T12:00:43-08:00 New Revision: c234b65cef07b38c91b9ab7dec6a35f8b390e658 URL: https://github.com/llvm/llvm-project/commit/c234b65cef07b38c91b9ab7dec6a35f8b390e658 DIFF: https://github.com/llvm/llvm-project/commit/c234b65cef07b38c91b9ab7dec6a35f8b390e658.diff LOG: [mlir][OpFormat] Add support for emitting newlines from the custom format of an operation This revision adds a new `printNewline` hook to OpAsmPrinter that allows for printing a newline within the custom format of an operation, that is then indented to the start of the operation. Support for the declarative assembly format is also added, in the form of a `\n` literal. Differential Revision: https://reviews.llvm.org/D93151 Added: Modified: mlir/docs/OpDefinitions.md mlir/include/mlir/IR/OpImplementation.h mlir/lib/IR/AsmPrinter.cpp mlir/test/lib/Dialect/Test/TestOps.td mlir/test/mlir-tblgen/op-format-spec.td mlir/test/mlir-tblgen/op-format.mlir mlir/tools/mlir-tblgen/OpFormatGen.cpp Removed: diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index a267a60adc3e..189cd0825af7 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -646,6 +646,30 @@ The following are the set of valid punctuation: `:`, `,`, `=`, `<`, `>`, `(`, `)`, `{`, `}`, `[`, `]`, `->`, `?`, `+`, `*` +The following are valid whitespace punctuation: + +`\n`, ` ` + +The `\n` literal emits a newline an indents to the start of the operation. An +example is shown below: + +```tablegen +let assemblyFormat = [{ + `{` `\n` ` ` ` ` `this_is_on_a_newline` `\n` `}` attr-dict +}]; +``` + +```mlir +%results = my.operation { + this_is_on_a_newline +} +``` + +An empty literal \`\` may be used to remove a space that is inserted implicitly +after certain literal elements, such as `)`/`]`/etc. For example, "`]`" may +result in an output of `]` it is not the last element in the format. "`]` \`\`" +would trim the trailing space in this situation. + Variables A variable is an entity that has been registered on the operation itself, i.e. diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h index a7e87dc0ab06..31d3b42c8493 100644 --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -36,6 +36,10 @@ class OpAsmPrinter { virtual ~OpAsmPrinter(); virtual raw_ostream &getStream() const = 0; + /// Print a newline and indent the printer to the start of the current + /// operation. + virtual void printNewline() = 0; + /// Print implementations for various things an operation contains. virtual void printOperand(Value value) = 0; virtual void printOperand(Value value, raw_ostream &os) = 0; diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index 49e7048cfb13..1c2caa0bdfd6 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -429,6 +429,7 @@ class DummyAliasOperationPrinter : private OpAsmPrinter { /// The following are hooks of `OpAsmPrinter` that are not necessary for /// determining potential aliases. void printAffineMapOfSSAIds(AffineMapAttr, ValueRange) override {} + void printNewline() override {} void printOperand(Value) override {} void printOperand(Value, raw_ostream &os) override { // Users expect the output string to have at least the prefixed % to signal @@ -2218,6 +2219,13 @@ class OperationPrinter : public ModulePrinter, private OpAsmPrinter { /// Return the current stream of the printer. raw_ostream &getStream() const override { return os; } + /// Print a newline and indent the printer to the start of the current + /// operation. + void printNewline() override { +os << newLine; +os.indent(currentIndent); + } + /// Print the given type. void printType(Type type) override { ModulePrinter::printType(type); } diff --git a/mlir/test/lib/Dialect/Test/TestOps.td b/mlir/test/lib/Dialect/Test/TestOps.td index 6a7291abfec7..9a7eb5940fb9 100644 --- a/mlir/test/lib/Dialect/Test/TestOps.td +++ b/mlir/test/lib/Dialect/Test/TestOps.td @@ -1393,7 +1393,8 @@ def AsmDialectInterfaceOp : TEST_Op<"asm_dialect_interface_op"> { def FormatLiteralOp : TEST_Op<"format_literal_op"> { let assemblyFormat = [{ -`keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)` `?` `+` `*` attr-dict +`keyword_$.` `->` `:` `,` `=` `<` `>` `(` `)` `[` `]` `` `(` ` ` `)` +`?` `+` `*` `{` `\n` `}` attr-dict }]; } diff --git a/mlir/test/mlir-tblgen/op-format-spec.td b/mlir/test/mlir-tblgen/op-format-spec.td index 7817920f8955..424dbb83c276 100644 --- a/mlir/test/mlir-tblgen/op-format-spec.td +++ b/mlir/test/mlir-tblgen/op-format-spec.td @@ -309,7 +309,7 @@ def LiteralInvalidB : TestFormat_Op<"literal_invalid_b", [{ }]>; // CHECK-NOT: error def LiteralValid : TestFormat_Op<"liter
[llvm-branch-commits] [mlir] 6bc9439 - [mlir][OpAsmParser] Add support for parsing integer literals without going through IntegerAttr
Author: River Riddle Date: 2020-12-14T12:00:43-08:00 New Revision: 6bc9439f59acbcc5e46a108c2f74a4d5ffe55a3b URL: https://github.com/llvm/llvm-project/commit/6bc9439f59acbcc5e46a108c2f74a4d5ffe55a3b DIFF: https://github.com/llvm/llvm-project/commit/6bc9439f59acbcc5e46a108c2f74a4d5ffe55a3b.diff LOG: [mlir][OpAsmParser] Add support for parsing integer literals without going through IntegerAttr Some operations use integer literals as part of their custom format that don't necessarily map to an internal IntegerAttr. This revision exposes the same `parseInteger` functions as the DialectAsmParser to allow for these operations to parse integer literals without incurring the otherwise unnecessary roundtrip through IntegerAttr. Differential Revision: https://reviews.llvm.org/D93152 Added: Modified: mlir/include/mlir/IR/OpImplementation.h mlir/lib/Parser/DialectSymbolParser.cpp mlir/lib/Parser/Parser.cpp mlir/lib/Parser/Parser.h mlir/test/IR/parser.mlir mlir/test/lib/Dialect/Test/TestDialect.cpp mlir/test/lib/Dialect/Test/TestOps.td Removed: diff --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h index 31d3b42c8493..f74eb52aec6d 100644 --- a/mlir/include/mlir/IR/OpImplementation.h +++ b/mlir/include/mlir/IR/OpImplementation.h @@ -413,6 +413,35 @@ class OpAsmParser { /// Parse a `...` token if present; virtual ParseResult parseOptionalEllipsis() = 0; + /// Parse an integer value from the stream. + template ParseResult parseInteger(IntT &result) { +auto loc = getCurrentLocation(); +OptionalParseResult parseResult = parseOptionalInteger(result); +if (!parseResult.hasValue()) + return emitError(loc, "expected integer value"); +return *parseResult; + } + + /// Parse an optional integer value from the stream. + virtual OptionalParseResult parseOptionalInteger(uint64_t &result) = 0; + + template + OptionalParseResult parseOptionalInteger(IntT &result) { +auto loc = getCurrentLocation(); + +// Parse the unsigned variant. +uint64_t uintResult; +OptionalParseResult parseResult = parseOptionalInteger(uintResult); +if (!parseResult.hasValue() || failed(*parseResult)) + return parseResult; + +// Try to convert to the provided integer type. +result = IntT(uintResult); +if (uint64_t(result) != uintResult) + return emitError(loc, "integer value too large"); +return success(); + } + //======// // Attribute Parsing //======// diff --git a/mlir/lib/Parser/DialectSymbolParser.cpp b/mlir/lib/Parser/DialectSymbolParser.cpp index 3bbc495cab65..11e7e237a192 100644 --- a/mlir/lib/Parser/DialectSymbolParser.cpp +++ b/mlir/lib/Parser/DialectSymbolParser.cpp @@ -82,20 +82,7 @@ class CustomDialectAsmParser : public DialectAsmParser { /// Parse an optional integer value from the stream. OptionalParseResult parseOptionalInteger(uint64_t &result) override { -Token curToken = parser.getToken(); -if (curToken.isNot(Token::integer, Token::minus)) - return llvm::None; - -bool negative = parser.consumeIf(Token::minus); -Token curTok = parser.getToken(); -if (parser.parseToken(Token::integer, "expected integer value")) - return failure(); - -auto val = curTok.getUInt64IntegerValue(); -if (!val) - return emitError(curTok.getLoc(), "integer value too large"); -result = negative ? -*val : *val; -return success(); +return parser.parseOptionalInteger(result); } //======// diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp index 47fef1ca393c..58ed9004c56c 100644 --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -94,6 +94,24 @@ ParseResult Parser::parseToken(Token::Kind expectedToken, return emitError(message); } +/// Parse an optional integer value from the stream. +OptionalParseResult Parser::parseOptionalInteger(uint64_t &result) { + Token curToken = getToken(); + if (curToken.isNot(Token::integer, Token::minus)) +return llvm::None; + + bool negative = consumeIf(Token::minus); + Token curTok = getToken(); + if (parseToken(Token::integer, "expected integer value")) +return failure(); + + auto val = curTok.getUInt64IntegerValue(); + if (!val) +return emitError(curTok.getLoc(), "integer value too large"); + result = negative ? -*val : *val; + return success(); +} + //===--===// // OperationParser //===--===// @@ -1109,6 +1127,11 @@ class CustomOpAsmParser : public OpAsmParser { return success(parser.consumeIf
[llvm-branch-commits] [mlir] 6af2c4c - [mlir] Change the internal representation of FrozenRewritePatternList to use shared_ptr
Author: River Riddle Date: 2020-12-14T12:32:44-08:00 New Revision: 6af2c4ca9bdb37e56cfda8dae4f6c3c6ca21b8d7 URL: https://github.com/llvm/llvm-project/commit/6af2c4ca9bdb37e56cfda8dae4f6c3c6ca21b8d7 DIFF: https://github.com/llvm/llvm-project/commit/6af2c4ca9bdb37e56cfda8dae4f6c3c6ca21b8d7.diff LOG: [mlir] Change the internal representation of FrozenRewritePatternList to use shared_ptr This will allow for caching pattern lists across multiple pass instances, such as when multithreading. This is an extremely important invariant for PDL patterns, which are compiled at runtime when the FrozenRewritePatternList is built. Differential Revision: https://reviews.llvm.org/D93146 Added: Modified: mlir/include/mlir/Rewrite/FrozenRewritePatternList.h mlir/lib/Rewrite/FrozenRewritePatternList.cpp Removed: diff --git a/mlir/include/mlir/Rewrite/FrozenRewritePatternList.h b/mlir/include/mlir/Rewrite/FrozenRewritePatternList.h index c2335b9dd5a1..0e583aab3dc4 100644 --- a/mlir/include/mlir/Rewrite/FrozenRewritePatternList.h +++ b/mlir/include/mlir/Rewrite/FrozenRewritePatternList.h @@ -18,34 +18,52 @@ class PDLByteCode; /// This class represents a frozen set of patterns that can be processed by a /// pattern applicator. This class is designed to enable caching pattern lists -/// such that they need not be continuously recomputed. +/// such that they need not be continuously recomputed. Note that all copies of +/// this class share the same compiled pattern list, allowing for a reduction in +/// the number of duplicated patterns that need to be created. class FrozenRewritePatternList { using NativePatternListT = std::vector>; public: /// Freeze the patterns held in `patterns`, and take ownership. + FrozenRewritePatternList(); FrozenRewritePatternList(OwningRewritePatternList &&patterns); - FrozenRewritePatternList(FrozenRewritePatternList &&patterns); + FrozenRewritePatternList(FrozenRewritePatternList &&patterns) = default; + FrozenRewritePatternList(const FrozenRewritePatternList &patterns) = default; + FrozenRewritePatternList & + operator=(const FrozenRewritePatternList &patterns) = default; + FrozenRewritePatternList & + operator=(FrozenRewritePatternList &&patterns) = default; ~FrozenRewritePatternList(); /// Return the native patterns held by this list. iterator_range> getNativePatterns() const { +const NativePatternListT &nativePatterns = impl->nativePatterns; return llvm::make_pointee_range(nativePatterns); } /// Return the compiled PDL bytecode held by this list. Returns null if /// there are no PDL patterns within the list. const detail::PDLByteCode *getPDLByteCode() const { -return pdlByteCode.get(); +return impl->pdlByteCode.get(); } private: - /// The set of. - std::vector> nativePatterns; + /// The internal implementation of the frozen pattern list. + struct Impl { +/// The set of native C++ rewrite patterns. +NativePatternListT nativePatterns; - /// The bytecode containing the compiled PDL patterns. - std::unique_ptr pdlByteCode; +/// The bytecode containing the compiled PDL patterns. +std::unique_ptr pdlByteCode; + }; + + /// A pointer to the internal pattern list. This uses a shared_ptr to avoid + /// the need to compile the same pattern list multiple times. For example, + /// during multi-threaded pass execution, all copies of a pass can share the + /// same pattern list. + std::shared_ptr impl; }; } // end namespace mlir diff --git a/mlir/lib/Rewrite/FrozenRewritePatternList.cpp b/mlir/lib/Rewrite/FrozenRewritePatternList.cpp index 60f6dcea88f2..40d7fcde8f33 100644 --- a/mlir/lib/Rewrite/FrozenRewritePatternList.cpp +++ b/mlir/lib/Rewrite/FrozenRewritePatternList.cpp @@ -50,12 +50,16 @@ static LogicalResult convertPDLToPDLInterp(ModuleOp pdlModule) { // FrozenRewritePatternList //===--===// +FrozenRewritePatternList::FrozenRewritePatternList() +: impl(std::make_shared()) {} + FrozenRewritePatternList::FrozenRewritePatternList( OwningRewritePatternList &&patterns) -: nativePatterns(std::move(patterns.getNativePatterns())) { - PDLPatternModule &pdlPatterns = patterns.getPDLPatterns(); +: impl(std::make_shared()) { + impl->nativePatterns = std::move(patterns.getNativePatterns()); // Generate the bytecode for the PDL patterns if any were provided. + PDLPatternModule &pdlPatterns = patterns.getPDLPatterns(); ModuleOp pdlModule = pdlPatterns.getModule(); if (!pdlModule) return; @@ -64,14 +68,9 @@ FrozenRewritePatternList::FrozenRewritePatternList( "failed to lower PDL pattern module to the PDL Interpreter"); // Generate the pdl bytecode. - pdlByteCode = std::make_unique( + impl->pdlByteCode = std::make_unique( pdlModule, pdlPatterns.takeConstraintFu
[llvm-branch-commits] [mlir] b3ee7f1 - [mlir][OpDefGen] Add support for generating local functions for shared utilities
Author: River Riddle Date: 2020-12-14T14:21:30-08:00 New Revision: b3ee7f1f312dd41a0ac883d78b71c14d96e78939 URL: https://github.com/llvm/llvm-project/commit/b3ee7f1f312dd41a0ac883d78b71c14d96e78939 DIFF: https://github.com/llvm/llvm-project/commit/b3ee7f1f312dd41a0ac883d78b71c14d96e78939.diff LOG: [mlir][OpDefGen] Add support for generating local functions for shared utilities This revision adds a new `StaticVerifierFunctionEmitter` class that emits local static functions in the .cpp file for shared operation verification. This class deduplicates shared operation verification code by emitting static functions alongside the op definitions. These methods are local to the definition file, and are invoked within the operation verify methods. The first bit of shared verification is for the type constraints used when verifying operands and results. An example is shown below: ``` static LogicalResult localVerify(...) { ... } LogicalResult OpA::verify(...) { if (failed(localVerify(...))) return failure(); ... } LogicalResult OpB::verify(...) { if (failed(localVerify(...))) return failure(); ... } ``` This allowed for saving >400kb of code size from a downstream TensorFlow project (~15% of MLIR code size). Differential Revision: https://reviews.llvm.org/D91381 Added: Modified: mlir/include/mlir/TableGen/Constraint.h mlir/test/mlir-tblgen/predicate.td mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp Removed: diff --git a/mlir/include/mlir/TableGen/Constraint.h b/mlir/include/mlir/TableGen/Constraint.h index 775b3545a034..e5ced0361c16 100644 --- a/mlir/include/mlir/TableGen/Constraint.h +++ b/mlir/include/mlir/TableGen/Constraint.h @@ -52,6 +52,13 @@ class Constraint { Kind getKind() const { return kind; } + /// Get an opaque pointer to the constraint. + const void *getAsOpaquePointer() const { return def; } + /// Construct a constraint from the opaque pointer representation. + static Constraint getFromOpaquePointer(const void *ptr) { +return Constraint(reinterpret_cast(ptr)); + } + protected: Constraint(Kind kind, const llvm::Record *record); diff --git a/mlir/test/mlir-tblgen/predicate.td b/mlir/test/mlir-tblgen/predicate.td index e5d4ac853b50..386c61319b79 100644 --- a/mlir/test/mlir-tblgen/predicate.td +++ b/mlir/test/mlir-tblgen/predicate.td @@ -15,10 +15,22 @@ def OpA : NS_Op<"op_for_CPred_containing_multiple_same_placeholder", []> { let arguments = (ins I32OrF32:$x); } +// CHECK: static ::mlir::LogicalResult [[$INTEGER_FLOAT_CONSTRAINT:__mlir_ods_local_type_constraint.*]]( +// CHECK: if (!((type.isInteger(32) || type.isF32( { +// CHECK:return op->emitOpError(valueKind) << " #" << valueGroupStartIndex << " must be 32-bit integer or floating-point type, but got " << type; + +// CHECK: static ::mlir::LogicalResult [[$TENSOR_CONSTRAINT:__mlir_ods_local_type_constraint.*]]( +// CHECK: if (!(((type.isa<::mlir::TensorType>())) && ((true { +// CHECK:return op->emitOpError(valueKind) << " #" << valueGroupStartIndex << " must be tensor of any type values, but got " << type; + +// CHECK: static ::mlir::LogicalResult [[$TENSOR_INTEGER_FLOAT_CONSTRAINT:__mlir_ods_local_type_constraint.*]]( +// CHECK: if (!(((type.isa<::mlir::TensorType>())) && (((type.cast<::mlir::ShapedType>().getElementType().isF32())) || ((type.cast<::mlir::ShapedType>().getElementType().isSignlessInteger(32)) { +// CHECK:return op->emitOpError(valueKind) << " #" << valueGroupStartIndex << " must be tensor of 32-bit float or 32-bit signless integer values, but got " << type; + // CHECK-LABEL: OpA::verify // CHECK: auto valueGroup0 = getODSOperands(0); // CHECK: for (::mlir::Value v : valueGroup0) { -// CHECK: if (!((v.getType().isInteger(32) || v.getType().isF32( +// CHECK: if (::mlir::failed([[$INTEGER_FLOAT_CONSTRAINT]] def OpB : NS_Op<"op_for_And_PredOpTrait", [ PredOpTrait<"both first and second holds", @@ -93,4 +105,4 @@ def OpK : NS_Op<"op_for_AnyTensorOf", []> { // CHECK-LABEL: OpK::verify // CHECK: auto valueGroup0 = getODSOperands(0); // CHECK: for (::mlir::Value v : valueGroup0) { -// CHECK: if (!(((v.getType().isa<::mlir::TensorType>())) && (((v.getType().cast<::mlir::ShapedType>().getElementType().isF32())) || ((v.getType().cast<::mlir::ShapedType>().getElementType().isSignlessInteger(32)) +// CHECK: if (::mlir::failed([[$TENSOR_INTEGER_FLOAT_CONSTRAINT]] diff --git a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp index f2a57fbbb00f..9a4ddbffac43 100644 --- a/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp +++ b/mlir/tools/mlir-tblgen/OpDefinitionsGen.cpp @@ -117,6 +117,144 @@ static const char *const opCommentHeader = R"( )"; +//===--===// +// StaticVerifierFunctionEmitter +//===
[llvm-branch-commits] [mlir] ee43dca - [mlir] Add section page for Rationale docs.
Author: Richard Uhler Date: 2020-12-14T14:49:30-08:00 New Revision: ee43dcaad75b8de43b914459c14050dc2a5dbb16 URL: https://github.com/llvm/llvm-project/commit/ee43dcaad75b8de43b914459c14050dc2a5dbb16 DIFF: https://github.com/llvm/llvm-project/commit/ee43dcaad75b8de43b914459c14050dc2a5dbb16.diff LOG: [mlir] Add section page for Rationale docs. With a brief overview and summary of each of the Rationale docs. Differential Revision: https://reviews.llvm.org/D93245 Added: mlir/docs/Rationale/_index.md Modified: mlir/docs/Rationale/UsageOfConst.md Removed: diff --git a/mlir/docs/Rationale/UsageOfConst.md b/mlir/docs/Rationale/UsageOfConst.md index 1f0d9c6fee2f..3082dda7ad23 100644 --- a/mlir/docs/Rationale/UsageOfConst.md +++ b/mlir/docs/Rationale/UsageOfConst.md @@ -1,4 +1,4 @@ -# Usage of 'Const' in MLIR, for core IR types +# Usage of 'const' in MLIR, for core IR types aka, where'd `const` go? diff --git a/mlir/docs/Rationale/_index.md b/mlir/docs/Rationale/_index.md new file mode 100644 index ..4fd0362ff55f --- /dev/null +++ b/mlir/docs/Rationale/_index.md @@ -0,0 +1,31 @@ +# Rationale + +This section contains a collection of documents describing the motivation and +rationale for some of the design decisions behind MLIR. + +[MLIR: Incremental Application to Graph Algorithms in ML Frameworks](MLIRForGraphAlgorithms.md) +: A discussion of how the adoption of MLIR can be taken in incremental steps, +with each step providing tangible benefits along the way. Refutes the idea +that full adoption of MLIR is required before we can reap the benefits of +MLIR. + +[MLIR Rationale](Rationale.md) +: Introduces the motivation for MLIR and captures design discussions and +decisions made for various core features of MLIR. + +[Generic DAG Rewriter Infrastructure Rationale](RationaleGenericDAGRewriter.md) +: Details the rationale behind a general DAG-to-DAG rewrite infrastructure for +MLIR. + +[Linalg Dialect Rationale: The Case for Compiler-Friendly Custom Operations](RationaleLinalgDialect.md) +: Describes the key design principles that led to the existing implementation +of Linalg and lessons learned along the way. + +[MLIR: The case for a simplified polyhedral form](RationaleSimplifiedPolyhedralForm.md) +: An early design proposal exploring the tradeoffs of using a simplified form +for polyhedral compiler techniques in MLIR instead of the traditional +polyhedral schedule list form. + +[Usage of 'const' in MLIR, for core IR types](UsageOfConst.md) +: Explains the rationale for eschewing the use of `const` entirely for the +core IR types in MLIR. ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [mlir] d7eba20 - [mlir][Inliner] Refactor the inliner to use nested pass pipelines instead of just canonicalization
Author: River Riddle Date: 2020-12-14T18:09:47-08:00 New Revision: d7eba2005267aa4a8f46f73f208c7cc23e6c6a1a URL: https://github.com/llvm/llvm-project/commit/d7eba2005267aa4a8f46f73f208c7cc23e6c6a1a DIFF: https://github.com/llvm/llvm-project/commit/d7eba2005267aa4a8f46f73f208c7cc23e6c6a1a.diff LOG: [mlir][Inliner] Refactor the inliner to use nested pass pipelines instead of just canonicalization Now that passes have support for running nested pipelines, the inliner can now allow for users to provide proper nested pipelines to use for optimization during inlining. This revision also changes the behavior of optimization during inlining to optimize before attempting to inline, which should lead to a more accurate cost model and prevents the need for users to schedule additional duplicate cleanup passes before/after the inliner that would already be run during inlining. Differential Revision: https://reviews.llvm.org/D91211 Added: Modified: llvm/include/llvm/ADT/Sequence.h mlir/include/mlir/Pass/AnalysisManager.h mlir/include/mlir/Pass/Pass.h mlir/include/mlir/Pass/PassManager.h mlir/include/mlir/Transforms/Passes.h mlir/include/mlir/Transforms/Passes.td mlir/lib/Pass/Pass.cpp mlir/lib/Pass/PassDetail.h mlir/lib/Pass/PassRegistry.cpp mlir/lib/Pass/PassTiming.cpp mlir/lib/Transforms/Inliner.cpp mlir/test/Dialect/Affine/inlining.mlir mlir/test/Dialect/SPIRV/Transforms/inlining.mlir mlir/test/Pass/dynamic-pipeline-nested.mlir mlir/test/Transforms/inlining.mlir mlir/test/lib/Transforms/TestDynamicPipeline.cpp Removed: diff --git a/llvm/include/llvm/ADT/Sequence.h b/llvm/include/llvm/ADT/Sequence.h index 8c505f2010dd..8a695d75f77a 100644 --- a/llvm/include/llvm/ADT/Sequence.h +++ b/llvm/include/llvm/ADT/Sequence.h @@ -42,6 +42,10 @@ class value_sequence_iterator value_sequence_iterator(const value_sequence_iterator &) = default; value_sequence_iterator(value_sequence_iterator &&Arg) : Value(std::move(Arg.Value)) {} + value_sequence_iterator &operator=(const value_sequence_iterator &Arg) { +Value = Arg.Value; +return *this; + } template ()))> value_sequence_iterator(U &&Value) : Value(std::forward(Value)) {} diff --git a/mlir/include/mlir/Pass/AnalysisManager.h b/mlir/include/mlir/Pass/AnalysisManager.h index ec6b7696ce60..5da0c95d78dc 100644 --- a/mlir/include/mlir/Pass/AnalysisManager.h +++ b/mlir/include/mlir/Pass/AnalysisManager.h @@ -98,7 +98,7 @@ struct AnalysisConcept { /// A derived analysis model used to hold a specific analysis object. template struct AnalysisModel : public AnalysisConcept { template - explicit AnalysisModel(Args &&... args) + explicit AnalysisModel(Args &&...args) : analysis(std::forward(args)...) {} /// A hook used to query analyses for invalidation. @@ -198,7 +198,10 @@ class AnalysisMap { /// An analysis map that contains a map for the current operation, and a set of /// maps for any child operations. struct NestedAnalysisMap { - NestedAnalysisMap(Operation *op) : analyses(op) {} + NestedAnalysisMap(Operation *op, PassInstrumentor *instrumentor) + : analyses(op), parentOrInstrumentor(instrumentor) {} + NestedAnalysisMap(Operation *op, NestedAnalysisMap *parent) + : analyses(op), parentOrInstrumentor(parent) {} /// Get the operation for this analysis map. Operation *getOperation() const { return analyses.getOperation(); } @@ -206,11 +209,34 @@ struct NestedAnalysisMap { /// Invalidate any non preserved analyses. void invalidate(const PreservedAnalyses &pa); + /// Returns the parent analysis map for this analysis map, or null if this is + /// the top-level map. + const NestedAnalysisMap *getParent() const { +return parentOrInstrumentor.dyn_cast(); + } + + /// Returns a pass instrumentation object for the current operation. This + /// value may be null. + PassInstrumentor *getPassInstrumentor() const { +if (auto *parent = getParent()) + return parent->getPassInstrumentor(); +return parentOrInstrumentor.get(); + } + /// The cached analyses for nested operations. DenseMap> childAnalyses; - /// The analyses for the owning module. + /// The analyses for the owning operation. detail::AnalysisMap analyses; + + /// This value has three possible states: + /// NestedAnalysisMap*: A pointer to the parent analysis map. + /// PassInstrumentor*: This analysis map is the top-level map, and this + ///pointer is the optional pass instrumentor for the + ///current compilation. + /// nullptr: This analysis map is the top-level map, and there is nop pass + /// instrumentor. + PointerUnion parentOrInstrumentor; }; } // namespace detail @@ -236,11 +262,11 @@ class AnalysisManager { template Optional> getCachedParentAnalysis(Operation *parentO
[llvm-branch-commits] [mlir] 95019de - [mlir][IR] Define the singleton builtin types in ODS instead of C++
Author: River Riddle Date: 2020-12-15T13:42:19-08:00 New Revision: 95019de8a122619fc038c9fe3c80e625e3456bbf URL: https://github.com/llvm/llvm-project/commit/95019de8a122619fc038c9fe3c80e625e3456bbf DIFF: https://github.com/llvm/llvm-project/commit/95019de8a122619fc038c9fe3c80e625e3456bbf.diff LOG: [mlir][IR] Define the singleton builtin types in ODS instead of C++ This exposes several issues with the current generation that this revision also fixes. * TypeDef now allows specifying the base class to use when generating. * TypeDef now inherits from DialectType, which allows for using it as a TypeConstraint * Parser/Printers are now no longer generated in the header(removing duplicate symbols), and are now only generated when necessary. - Now that generatedTypeParser/Printer are only generated in the definition file, existing users will need to manually expose this functionality when necessary. * ::get() is no longer generated for singleton types, because it isn't necessary. Differential Revision: https://reviews.llvm.org/D93270 Added: mlir/include/mlir/IR/BuiltinDialect.td mlir/include/mlir/IR/BuiltinTypes.td Modified: mlir/docs/OpDefinitions.md mlir/include/mlir/IR/BuiltinOps.td mlir/include/mlir/IR/BuiltinTypes.h mlir/include/mlir/IR/CMakeLists.txt mlir/include/mlir/IR/OpBase.td mlir/include/mlir/TableGen/TypeDef.h mlir/lib/IR/BuiltinTypes.cpp mlir/lib/IR/CMakeLists.txt mlir/lib/TableGen/Constraint.cpp mlir/lib/TableGen/TypeDef.cpp mlir/test/lib/Dialect/Test/TestDialect.cpp mlir/test/lib/Dialect/Test/TestTypes.cpp mlir/test/mlir-tblgen/typedefs.td mlir/tools/mlir-tblgen/TypeDefGen.cpp Removed: diff --git a/mlir/docs/OpDefinitions.md b/mlir/docs/OpDefinitions.md index 189cd0825af7..c5ffe452b927 100644 --- a/mlir/docs/OpDefinitions.md +++ b/mlir/docs/OpDefinitions.md @@ -1370,10 +1370,10 @@ llvm::Optional symbolizeMyBitEnum(uint32_t value) { ## Type Definitions -MLIR defines the TypeDef class hierarchy to enable generation of data types -from their specifications. A type is defined by specializing the TypeDef -class with concrete contents for all the fields it requires. For example, an -integer type could be defined as: +MLIR defines the TypeDef class hierarchy to enable generation of data types from +their specifications. A type is defined by specializing the TypeDef class with +concrete contents for all the fields it requires. For example, an integer type +could be defined as: ```tablegen // All of the types will extend this class. @@ -1414,45 +1414,43 @@ def IntegerType : Test_Type<"TestInteger"> { ### Type name The name of the C++ class which gets generated defaults to -`Type` (e.g. `TestIntegerType` in the above example). This -can be overridden via the `cppClassName` field. The field `mnemonic` is -to specify the asm name for parsing. It is optional and not specifying it -will imply that no parser or printer methods are attached to this class. +`Type` (e.g. `TestIntegerType` in the above example). This can +be overridden via the `cppClassName` field. The field `mnemonic` is to specify +the asm name for parsing. It is optional and not specifying it will imply that +no parser or printer methods are attached to this class. ### Type documentation -The `summary` and `description` fields exist and are to be used the same way -as in Operations. Namely, the summary should be a one-liner and `description` +The `summary` and `description` fields exist and are to be used the same way as +in Operations. Namely, the summary should be a one-liner and `description` should be a longer explanation. ### Type parameters -The `parameters` field is a list of the types parameters. If no parameters -are specified (the default), this type is considered a singleton type. -Parameters are in the `"c++Type":$paramName` format. -To use C++ types as parameters which need allocation in the storage -constructor, there are two options: +The `parameters` field is a list of the types parameters. If no parameters are +specified (the default), this type is considered a singleton type. Parameters +are in the `"c++Type":$paramName` format. To use C++ types as parameters which +need allocation in the storage constructor, there are two options: -- Set `hasCustomStorageConstructor` to generate the TypeStorage class with -a constructor which is just declared -- no definition -- so you can write it -yourself. -- Use the `TypeParameter` tablegen class instead of the "c++Type" string. +- Set `hasCustomStorageConstructor` to generate the TypeStorage class with a +constructor which is just declared -- no definition -- so you can write it +yourself. +- Use the `TypeParameter` tablegen class instead of the "c++Type" string. ### TypeParameter tablegen class -This is used to further specify attributes about each of the types -
[llvm-branch-commits] [mlir] e9cda7c - [mlir][Pass] Add a new PassNameCLParser specifically for parsing lists of pass names
Author: River Riddle Date: 2020-12-15T14:56:09-08:00 New Revision: e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672 URL: https://github.com/llvm/llvm-project/commit/e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672 DIFF: https://github.com/llvm/llvm-project/commit/e9cda7c5a0b70dd029e201cd2cc2e1d7105d0672.diff LOG: [mlir][Pass] Add a new PassNameCLParser specifically for parsing lists of pass names This parser does not include the general `pass_pipeline` option, the pass pipeline entries, or the options of pass entries. This is useful for cases such as `print-ir-after` that just want the user to select specific pass types. This revision greatly reduces the amount of text in --help for several MLIR based tools. Fixes PR#45495 Differential Revision: https://reviews.llvm.org/D92987 Added: Modified: mlir/include/mlir/Pass/PassRegistry.h mlir/lib/Pass/PassManagerOptions.cpp mlir/lib/Pass/PassRegistry.cpp Removed: diff --git a/mlir/include/mlir/Pass/PassRegistry.h b/mlir/include/mlir/Pass/PassRegistry.h index 52ded58ccfe6..9937102f316d 100644 --- a/mlir/include/mlir/Pass/PassRegistry.h +++ b/mlir/include/mlir/Pass/PassRegistry.h @@ -246,6 +246,26 @@ class PassPipelineCLParser { std::unique_ptr impl; }; +/// This class implements a command-line parser spefically for MLIR pass names. +/// It registers a cl option with a given argument and description that accepts +/// a comma delimited list of pass names. +class PassNameCLParser { +public: + /// Construct a parser with the given command line description. + PassNameCLParser(StringRef arg, StringRef description); + ~PassNameCLParser(); + + /// Returns true if this parser contains any valid options to add. + bool hasAnyOccurrences() const; + + /// Returns true if the given pass registry entry was registered at the + /// top-level of the parser, i.e. not within an explicit textual pipeline. + bool contains(const PassRegistryEntry *entry) const; + +private: + std::unique_ptr impl; +}; + } // end namespace mlir #endif // MLIR_PASS_PASSREGISTRY_H_ diff --git a/mlir/lib/Pass/PassManagerOptions.cpp b/mlir/lib/Pass/PassManagerOptions.cpp index a581ce070fc4..0af58ad9738b 100644 --- a/mlir/lib/Pass/PassManagerOptions.cpp +++ b/mlir/lib/Pass/PassManagerOptions.cpp @@ -32,10 +32,10 @@ struct PassManagerOptions { //======// // IR Printing //======// - PassPipelineCLParser printBefore{"print-ir-before", - "Print IR before specified passes"}; - PassPipelineCLParser printAfter{"print-ir-after", - "Print IR after specified passes"}; + PassNameCLParser printBefore{"print-ir-before", + "Print IR before specified passes"}; + PassNameCLParser printAfter{"print-ir-after", + "Print IR after specified passes"}; llvm::cl::opt printBeforeAll{ "print-ir-before-all", llvm::cl::desc("Print IR before each pass"), llvm::cl::init(false)}; diff --git a/mlir/lib/Pass/PassRegistry.cpp b/mlir/lib/Pass/PassRegistry.cpp index 50cbee8dc12d..f41ca72d7838 100644 --- a/mlir/lib/Pass/PassRegistry.cpp +++ b/mlir/lib/Pass/PassRegistry.cpp @@ -543,6 +543,12 @@ struct PassNameParser : public llvm::cl::parser { size_t getOptionWidth(const llvm::cl::Option &opt) const override; bool parse(llvm::cl::Option &opt, StringRef argName, StringRef arg, PassArgData &value); + + /// If true, this parser only parses entries that correspond to a concrete + /// pass registry entry, and does not add a `pass-pipeline` argument, does not + /// include the options for pass entries, and does not include pass pipelines + /// entries. + bool passNamesOnly = false; }; } // namespace @@ -550,8 +556,10 @@ void PassNameParser::initialize() { llvm::cl::parser::initialize(); /// Add an entry for the textual pass pipeline option. - addLiteralOption(passPipelineArg, PassArgData(), - "A textual description of a pass pipeline to run"); + if (!passNamesOnly) { +addLiteralOption(passPipelineArg, PassArgData(), + "A textual description of a pass pipeline to run"); + } /// Add the pass entries. for (const auto &kv : *passRegistry) { @@ -559,14 +567,24 @@ void PassNameParser::initialize() { kv.second.getPassDescription()); } /// Add the pass pipeline entries. - for (const auto &kv : *passPipelineRegistry) { -addLiteralOption(kv.second.getPassArgument(), &kv.second, - kv.second.getPassDescription()); + if (!passNamesOnly) { +for (const auto &kv : *passPipelineRegistry) { + addLiteralOption(kv.second.getPassArgument(), &kv.second, + kv.second.getPassDescripti