From 58a1293d0d6bab11ad35e85c1c8058445c95cda4 Mon Sep 17 00:00:00 2001 From: xlauko Date: Tue, 19 Nov 2024 14:00:29 +0100 Subject: [PATCH 01/24] conv: Add unrealized conversion materialization helper. --- .../TypeConverters/TypeConverter.hpp | 13 +++++++++ .../Generic/LowerValueCategories.cpp | 27 +++---------------- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/include/vast/Conversion/TypeConverters/TypeConverter.hpp b/include/vast/Conversion/TypeConverters/TypeConverter.hpp index ca3c61bb8e..14bfa179a4 100644 --- a/include/vast/Conversion/TypeConverters/TypeConverter.hpp +++ b/include/vast/Conversion/TypeConverters/TypeConverter.hpp @@ -45,6 +45,19 @@ namespace vast::conv::tc { } }; + static inline constexpr auto unrealized_materialization = [] ( + mlir::OpBuilder &builder, mlir::Type resultType, + mlir::ValueRange inputs, mlir::Location loc + ) -> std::optional< mlir::Value > { + if (inputs.size() != 1) { + return std::nullopt; + } + + return builder + .create< mlir::UnrealizedConversionCastOp >(loc, resultType, inputs) + .getResult(0); + }; + struct identity_type_converter : base_type_converter { using base = base_type_converter; diff --git a/lib/vast/Conversion/Generic/LowerValueCategories.cpp b/lib/vast/Conversion/Generic/LowerValueCategories.cpp index 599546a266..e124b19b9d 100644 --- a/lib/vast/Conversion/Generic/LowerValueCategories.cpp +++ b/lib/vast/Conversion/Generic/LowerValueCategories.cpp @@ -39,30 +39,9 @@ namespace vast::conv { auto element_type = this->convert_type_to_type(type.getElementType()); return hl::PointerType::get(&mctx, *element_type); }); - addTargetMaterialization( - [&](mlir::OpBuilder &builder, mlir::Type resultType, - mlir::ValueRange inputs, mlir::Location loc) -> std::optional< Value > { - if (inputs.size() != 1) { - return std::nullopt; - } - - return builder - .create< mlir::UnrealizedConversionCastOp >(loc, resultType, inputs) - .getResult(0); - } - ); - addSourceMaterialization( - [&](mlir::OpBuilder &builder, mlir::Type resultType, - mlir::ValueRange inputs, mlir::Location loc) -> std::optional< Value > { - if (inputs.size() != 1) { - return std::nullopt; - } - - return builder - .create< mlir::UnrealizedConversionCastOp >(loc, resultType, inputs) - .getResult(0); - } - ); + + addTargetMaterialization(tc::unrealized_materialization); + addSourceMaterialization(tc::unrealized_materialization); } using mixin_base = tc::mixins< value_category_type_converter >; From b3999eeb4f03841bb1725deea91d4a5087ee8a9b Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:38:56 +0100 Subject: [PATCH 02/24] core: Add arithmetic binary op interface. --- .../vast/Dialect/Core/Interfaces/CMakeLists.txt | 2 ++ .../Core/Interfaces/OperationInterfaces.hpp | 16 ++++++++++++++++ .../Core/Interfaces/OperationInterfaces.td | 17 +++++++++++++++++ lib/vast/Dialect/Core/Interfaces/CMakeLists.txt | 5 +++++ .../Core/Interfaces/OperationInterfaces.cpp | 10 ++++++++++ 5 files changed, 50 insertions(+) create mode 100644 include/vast/Dialect/Core/Interfaces/OperationInterfaces.hpp create mode 100644 include/vast/Dialect/Core/Interfaces/OperationInterfaces.td create mode 100644 lib/vast/Dialect/Core/Interfaces/OperationInterfaces.cpp diff --git a/include/vast/Dialect/Core/Interfaces/CMakeLists.txt b/include/vast/Dialect/Core/Interfaces/CMakeLists.txt index 14b81880f0..fa65f4d2e4 100644 --- a/include/vast/Dialect/Core/Interfaces/CMakeLists.txt +++ b/include/vast/Dialect/Core/Interfaces/CMakeLists.txt @@ -2,6 +2,8 @@ add_vast_op_interface(DeclStorageInterface) add_vast_op_interface(FunctionInterface) add_vast_op_interface(TypeDefinitionInterface) +add_vast_op_interface(OperationInterfaces) + add_vast_op_interface(SymbolInterface) add_vast_op_interface(SymbolTableInterface) add_vast_attr_interface(SymbolRefInterface) diff --git a/include/vast/Dialect/Core/Interfaces/OperationInterfaces.hpp b/include/vast/Dialect/Core/Interfaces/OperationInterfaces.hpp new file mode 100644 index 0000000000..9a5988b016 --- /dev/null +++ b/include/vast/Dialect/Core/Interfaces/OperationInterfaces.hpp @@ -0,0 +1,16 @@ +// Copyright (c) 2024, Trail of Bits, Inc. + +#pragma once + +#include "vast/Util/Warnings.hpp" + +VAST_RELAX_WARNINGS +#include +#include +#include +#include +#include +VAST_RELAX_WARNINGS + +/// Include the generated interface declarations. +#include "vast/Dialect/Core/Interfaces/OperationInterfaces.h.inc" diff --git a/include/vast/Dialect/Core/Interfaces/OperationInterfaces.td b/include/vast/Dialect/Core/Interfaces/OperationInterfaces.td new file mode 100644 index 0000000000..b14ec4886a --- /dev/null +++ b/include/vast/Dialect/Core/Interfaces/OperationInterfaces.td @@ -0,0 +1,17 @@ +// Copyright (c) 2024, Trail of Bits, Inc. + +#ifndef VAST_INTERFACES_OPERATION_INTERFACES +#define VAST_INTERFACES_OPERATION_INTERFACES + +include "mlir/IR/OpBase.td" + +include "vast/Dialect/Core/CoreTraits.td" +include "vast/Dialect/Core/Interfaces/Common.td" + +def Core_ArithBinOp : Core_OpInterface< "ArithBinOpInterface" > { + let description = [{ + This interface describes an operation that is arithmetic binary operation. + }]; +} + +#endif // VAST_INTERFACES_OPERATION_INTERFACES diff --git a/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt b/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt index 184fe3ddf3..6608474453 100644 --- a/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt +++ b/lib/vast/Dialect/Core/Interfaces/CMakeLists.txt @@ -3,6 +3,7 @@ set(VAST_OPTIONAL_SOURCES DesugarTypeInterface.cpp FunctionInterface.cpp FunctionImplementation.cpp + OperationInterfaces.cpp SymbolInterface.cpp SymbolTableInterface.cpp SymbolRefInterface.cpp @@ -22,6 +23,10 @@ add_vast_interface_library(FunctionInterface FunctionImplementation.cpp ) +add_vast_interface_library(OperationInterfaces + OperationInterfaces.cpp +) + add_vast_interface_library(SymbolInterface SymbolInterface.cpp ) diff --git a/lib/vast/Dialect/Core/Interfaces/OperationInterfaces.cpp b/lib/vast/Dialect/Core/Interfaces/OperationInterfaces.cpp new file mode 100644 index 0000000000..3293793f9f --- /dev/null +++ b/lib/vast/Dialect/Core/Interfaces/OperationInterfaces.cpp @@ -0,0 +1,10 @@ +// Copyright (c) 2024-present, Trail of Bits, Inc. + +#include "vast/Dialect/Core/Interfaces/OperationInterfaces.hpp" + +//===----------------------------------------------------------------------===// +// Operation Interfaces +//===----------------------------------------------------------------------===// + +/// Include the generated operation interfaces. +#include "vast/Dialect/Core/Interfaces/OperationInterfaces.cpp.inc" From 24244326fe7f714fbf759cb7dac93ecfed5596d2 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:39:33 +0100 Subject: [PATCH 03/24] hl: Annotate arithmetic operations with core trait. --- include/vast/Dialect/HighLevel/HighLevelOps.hpp | 1 + include/vast/Dialect/HighLevel/HighLevelOps.td | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/include/vast/Dialect/HighLevel/HighLevelOps.hpp b/include/vast/Dialect/HighLevel/HighLevelOps.hpp index 1155d55710..3e005a85db 100644 --- a/include/vast/Dialect/HighLevel/HighLevelOps.hpp +++ b/include/vast/Dialect/HighLevel/HighLevelOps.hpp @@ -17,6 +17,7 @@ VAST_UNRELAX_WARNINGS #include "vast/Dialect/Core/SymbolTable.hpp" +#include "vast/Dialect/Core/Interfaces/OperationInterfaces.hpp" #include "vast/Dialect/Core/Interfaces/SymbolInterface.hpp" #include "vast/Dialect/Core/Interfaces/TypeDefinitionInterface.hpp" diff --git a/include/vast/Dialect/HighLevel/HighLevelOps.td b/include/vast/Dialect/HighLevel/HighLevelOps.td index ba512269f2..dfd15e9c67 100644 --- a/include/vast/Dialect/HighLevel/HighLevelOps.td +++ b/include/vast/Dialect/HighLevel/HighLevelOps.td @@ -9,6 +9,7 @@ include "mlir/IR/BuiltinAttributes.td" include "mlir/Interfaces/CastInterfaces.td" include "vast/Interfaces/TypeTraitExprInterface.td" +include "vast/Dialect/Core/Interfaces/OperationInterfaces.td" include "vast/Dialect/Core/Interfaces/SymbolInterface.td" include "vast/Dialect/Core/Interfaces/SymbolTableInterface.td" include "vast/Dialect/Core/Interfaces/TypeDefinitionInterface.td" @@ -832,7 +833,7 @@ class HighLevel_IsSub< string lhs, string rhs, string res > >; class HighLevel_ArithBinOp< string mnemonic, list< Trait > traits = [] > - : HighLevel_Op< mnemonic, traits > + : HighLevel_Op< mnemonic, !listconcat(traits, [Core_ArithBinOp]) > , Arguments<(ins AnyType:$lhs, AnyType:$rhs)> , Results<(outs AnyType:$result)> { From 95561f7ab5b18e85a9496e85cf5f73dab869c675 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:41:53 +0100 Subject: [PATCH 04/24] pr: Reconcile unrealized casts on the fly. --- lib/vast/Conversion/Parser/ToParser.cpp | 71 ++++++++----------------- 1 file changed, 22 insertions(+), 49 deletions(-) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 848ee1bc08..4651452835 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -152,21 +152,14 @@ namespace vast::conv { }; namespace pattern { - template< typename op_t > - struct parser_conversion_pattern_base - : mlir_pattern_mixin< operation_conversion_pattern< op_t > > - , mlir::OpConversionPattern< op_t > - { - using base = mlir::OpConversionPattern< op_t >; - - parser_conversion_pattern_base(mcontext_t *mctx, const function_models &models) - : base(mctx), models(models) - {} - - const function_models ⊧ - }; mlir_value cast_value(mlir_value val, mlir_type ty, conversion_rewriter &rewriter) { + if (auto cast = mlir::dyn_cast< mlir::UnrealizedConversionCastOp >(val.getDefiningOp())) { + if (cast->getOperand(0).getType() == ty) { + return cast.getOperand(0); + } + } + return rewriter.create< mlir::UnrealizedConversionCastOp >( val.getLoc(), ty, val ).getResult(0); @@ -175,31 +168,32 @@ namespace vast::conv { std::vector< mlir_value > convert_value_types( mlir::ValueRange values, mlir::TypeRange types, auto &rewriter ) { - // One can provide more types for variadics - VAST_ASSERT(values.size() <= types.size()); std::vector< mlir_value > out; out.reserve(values.size()); - for (auto [val, ty] : llvm::zip(values, types)) { - out.push_back(val.getType() != ty ? cast_value(val, ty, rewriter) : val); + for (size_t i = 0; i < values.size(); ++i) { + // use last type for variadic operations + auto ty = i < types.size() ? types[i] : types.back(); + auto val = values[i]; + out.push_back(val.getType() == ty ? val : cast_value(val, ty, rewriter)); } return out; } - std::vector< mlir_value > convert_value_types( - mlir::ValueRange values, mlir_type type, conversion_rewriter &rewriter - ) { - std::vector< mlir_value > out; - out.reserve(values.size()); - - for (auto val : values) { - out.push_back(val.getType() != type ? cast_value(val, type, rewriter) : val); - } + template< typename op_t > + struct parser_conversion_pattern_base + : mlir_pattern_mixin< operation_conversion_pattern< op_t > > + , mlir::OpConversionPattern< op_t > + { + using base = mlir::OpConversionPattern< op_t >; - return out; - } + parser_conversion_pattern_base(mcontext_t *mctx, const function_models &models) + : base(mctx), models(models) + {} + const function_models ⊧ + }; // // Parser operation conversion patterns @@ -265,14 +259,6 @@ namespace vast::conv { ) const { auto rty = model.get_return_type(op.getContext()); auto arg_tys = model.get_argument_types(op.getContext()); - // Add type padding for variadic functions - if (arg_tys.size() < adaptor.getOperands().size()) { - for (auto i = arg_tys.size(); i < adaptor.getOperands().size(); ++i) { - arg_tys.push_back(arg_tys.back()); - } - } - - VAST_ASSERT(arg_tys.size() >= adaptor.getOperands().size()); auto args = convert_value_types(adaptor.getOperands(), arg_tys, rewriter); if (model.is_source()) { @@ -294,19 +280,6 @@ namespace vast::conv { VAST_UNREACHABLE("Unknown function category"); } - - template< typename new_op_t > - logical_result replace_with_new_op( - op_t op, adaptor_t adaptor, conversion_rewriter &rewriter - ) const { - auto model = models.lookup(op.getCallee()); - - rewriter.replaceOpWithNewOp< new_op_t >( - op, op.getResultTypes(), adaptor.getOperands() - ); - return mlir::success(); - } - static void legalize(parser_conversion_config &cfg) { cfg.target.addLegalOp< pr::NoParse, pr::Parse, pr::Source, pr::Sink >(); cfg.target.addLegalOp< mlir::UnrealizedConversionCastOp >(); From ad64dcb5ac03890bc7af262f384e5240709cf03e Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:44:06 +0100 Subject: [PATCH 05/24] pr: Let parser detector invoke standard conversions. --- tools/detect-parsers/main.cpp | 32 ++++++++++++++++++++++++++++++ tools/vast-detect-parsers/main.cpp | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 tools/detect-parsers/main.cpp diff --git a/tools/detect-parsers/main.cpp b/tools/detect-parsers/main.cpp new file mode 100644 index 0000000000..7d5a51baf0 --- /dev/null +++ b/tools/detect-parsers/main.cpp @@ -0,0 +1,32 @@ +// Copyright (c) 2021-present, Trail of Bits, Inc. + +#include "vast/Util/Warnings.hpp" + +VAST_RELAX_WARNINGS +#include "mlir/Conversion/Passes.h" +#include "mlir/IR/Dialect.h" +#include "mlir/IR/MLIRContext.h" +#include "mlir/InitAllDialects.h" +#include "mlir/Tools/mlir-opt/MlirOptMain.h" +VAST_UNRELAX_WARNINGS + +#include "vast/Conversion/Parser/Passes.hpp" +#include "vast/Dialect/Dialects.hpp" + +#include "vast/Dialect/Parser/Dialect.hpp" + +int main(int argc, char **argv) +{ + mlir::DialectRegistry registry; + // register dialects + vast::registerAllDialects(registry); + mlir::registerAllDialects(registry); + + vast::registerParserConversionPasses(); + mlir::registerConversionPasses(); + registry.insert< vast::pr::ParserDialect >(); + + return mlir::asMainReturnCode( + mlir::MlirOptMain(argc, argv, "VAST Parser Detection driver\n", registry) + ); +} diff --git a/tools/vast-detect-parsers/main.cpp b/tools/vast-detect-parsers/main.cpp index 7cc096a0a5..36aa62af2f 100644 --- a/tools/vast-detect-parsers/main.cpp +++ b/tools/vast-detect-parsers/main.cpp @@ -5,6 +5,7 @@ #include "vast/Util/Warnings.hpp" VAST_RELAX_WARNINGS +include "mlir/Conversion/Passes.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/MLIRContext.h" #include "mlir/InitAllDialects.h" @@ -91,6 +92,7 @@ int main(int argc, char **argv) { vast::registerParserConversionPasses(); vast::registerSarifPasses(); + mlir::registerConversionPasses(); registry.insert< vast::pr::ParserDialect >(); return mlir::asMainReturnCode( From 8d8a9305da16ac87c4cfe81cfe5462d1a5853853 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:55:53 +0100 Subject: [PATCH 06/24] pr: Fix MaybeDataType predicate to include NoDataType. --- include/vast/Dialect/Parser/Types.td | 1 + 1 file changed, 1 insertion(+) diff --git a/include/vast/Dialect/Parser/Types.td b/include/vast/Dialect/Parser/Types.td index b541d8e2d2..f017773511 100644 --- a/include/vast/Dialect/Parser/Types.td +++ b/include/vast/Dialect/Parser/Types.td @@ -23,6 +23,7 @@ def Parser_AnyDataType : Parser_Type< "AnyData", "anydata" > { def Parser_MaybeDataType : Type< Or< [ + Parser_NoDataType.predicate, Parser_DataType.predicate, Parser_AnyDataType.predicate ]> From d67a714172157b91f70b718139e7340898b489c9 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 10:56:10 +0100 Subject: [PATCH 07/24] pr: Fix fclose model to expect nodata. --- include/vast/Conversion/Parser/default-parsers-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vast/Conversion/Parser/default-parsers-config.yaml b/include/vast/Conversion/Parser/default-parsers-config.yaml index 1d7d3cf7f6..59f8ffbfce 100644 --- a/include/vast/Conversion/Parser/default-parsers-config.yaml +++ b/include/vast/Conversion/Parser/default-parsers-config.yaml @@ -151,5 +151,5 @@ model: return_type: nodata arguments: - - anydata # FILE * stream + - nodata # FILE * stream category: nonparser From f3882413489892f7e85a80a466f2072d4a4841ed Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 11:00:35 +0100 Subject: [PATCH 08/24] pr: Swap AnyDataType and MaybeDataType. --- .../Parser/default-parsers-config.yaml | 16 ++++++++-------- include/vast/Dialect/Parser/Types.td | 6 +++--- lib/vast/Conversion/Parser/ToParser.cpp | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/vast/Conversion/Parser/default-parsers-config.yaml b/include/vast/Conversion/Parser/default-parsers-config.yaml index 59f8ffbfce..be5f81db69 100644 --- a/include/vast/Conversion/Parser/default-parsers-config.yaml +++ b/include/vast/Conversion/Parser/default-parsers-config.yaml @@ -67,8 +67,8 @@ model: return_type: nodata arguments: - - anydata # const char * restrict format - - anydata # ... + - maybedata # const char * restrict format + - maybedata # ... category: sink # int fprintf(FILE * restrict stream, const char * restrict format, ...); @@ -77,8 +77,8 @@ return_type: nodata arguments: - nodata # FILE * restrict stream - - anydata # const char * restrict format - - anydata # ... + - maybedata # const char * restrict format + - maybedata # ... category: sink # void perror(const char *s); @@ -86,7 +86,7 @@ model: return_type: nodata arguments: - - anydata # const char *s + - maybedata # const char *s category: sink # void free(void * ptr); @@ -94,7 +94,7 @@ model: return_type: nodata arguments: - - anydata # void * ptr + - maybedata # void * ptr category: sink # FILE * fopen(const char * restrict filename, const char * restrict mode); @@ -102,8 +102,8 @@ model: return_type: nodata arguments: - - anydata # const char * restrict filename - - anydata # const char * restrict mode + - maybedata # const char * restrict filename + - maybedata # const char * restrict mode category: sink # diff --git a/include/vast/Dialect/Parser/Types.td b/include/vast/Dialect/Parser/Types.td index f017773511..693f6b0cda 100644 --- a/include/vast/Dialect/Parser/Types.td +++ b/include/vast/Dialect/Parser/Types.td @@ -17,15 +17,15 @@ def Parser_NoDataType : Parser_Type< "NoData", "nodata" > { let summary = "No data type."; } -def Parser_AnyDataType : Parser_Type< "AnyData", "anydata" > { +def Parser_MaybeDataType : Parser_Type< "AnyData", "anydata" > { let summary = "Any data type."; } -def Parser_MaybeDataType : Type< +def Parser_AnyDataType : Type< Or< [ Parser_NoDataType.predicate, Parser_DataType.predicate, - Parser_AnyDataType.predicate + Parser_MaybeDataType.predicate ]> >; diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 4651452835..4a3200edc8 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -28,13 +28,13 @@ VAST_UNRELAX_WARNINGS namespace vast::conv { - enum class data_type { data, nodata, anydata }; + enum class data_type { data, nodata, maybedata }; mlir_type to_mlir_type(data_type type, mcontext_t *mctx) { switch (type) { case data_type::data: return pr::DataType::get(mctx); case data_type::nodata: return pr::NoDataType::get(mctx); - case data_type::anydata: return pr::AnyDataType::get(mctx); + case data_type::maybedata: return pr::MaybeDataType::get(mctx); } } @@ -90,7 +90,7 @@ struct ScalarEnumerationTraits< vast::conv::data_type > static void enumeration(IO &io, vast::conv::data_type &value) { io.enumCase(value, "data", vast::conv::data_type::data); io.enumCase(value, "nodata", vast::conv::data_type::nodata); - io.enumCase(value, "anydata", vast::conv::data_type::anydata); + io.enumCase(value, "maybedata", vast::conv::data_type::maybedata); } }; From 4e4b55fb9d46b08052d1987ccbe603afad13c129 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 11:01:02 +0100 Subject: [PATCH 09/24] pr: Resurrect type constraints. --- include/vast/Dialect/Parser/Ops.td | 16 ++++++++-------- include/vast/Dialect/Parser/Types.td | 16 +++++++--------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/include/vast/Dialect/Parser/Ops.td b/include/vast/Dialect/Parser/Ops.td index 803e1c2bf0..3c6b24b979 100644 --- a/include/vast/Dialect/Parser/Ops.td +++ b/include/vast/Dialect/Parser/Ops.td @@ -13,8 +13,8 @@ class Parser_Op< string mnemonic, list< Trait > traits = [] > def Parser_Source : Parser_Op< "source" > - , Arguments< (ins Variadic:$arguments) > - , Results< (outs Variadic:$result) > + , Arguments< (ins Variadic:$arguments) > + , Results< (outs Variadic:$result) > { let summary = "Source of parsed data."; @@ -25,8 +25,8 @@ def Parser_Source def Paser_Sink : Parser_Op< "sink" > - , Arguments< (ins Variadic:$arguments) > - , Results< (outs Variadic:$result) > + , Arguments< (ins Variadic:$arguments) > + , Results< (outs Variadic:$result) > { let summary = "Sink of parsed data."; @@ -37,8 +37,8 @@ def Paser_Sink def Parser_Parse : Parser_Op< "parse" > - , Arguments< (ins Variadic:$arguments) > - , Results< (outs Variadic:$result) > + , Arguments< (ins Variadic:$arguments) > + , Results< (outs Variadic:$result) > { let summary = "Parsing operation data."; @@ -49,8 +49,8 @@ def Parser_Parse def Parse_NoParse : Parser_Op< "noparse" > - , Arguments< (ins Variadic:$arguments) > - , Results< (outs Variadic:$result) > + , Arguments< (ins Variadic:$arguments) > + , Results< (outs Variadic:$result) > { let summary = "Non-parsing operation data."; diff --git a/include/vast/Dialect/Parser/Types.td b/include/vast/Dialect/Parser/Types.td index 693f6b0cda..e039c2d29c 100644 --- a/include/vast/Dialect/Parser/Types.td +++ b/include/vast/Dialect/Parser/Types.td @@ -17,16 +17,14 @@ def Parser_NoDataType : Parser_Type< "NoData", "nodata" > { let summary = "No data type."; } -def Parser_MaybeDataType : Parser_Type< "AnyData", "anydata" > { - let summary = "Any data type."; +def Parser_MaybeDataType : Parser_Type< "MaybeData", "maybedata" > { + let summary = "Maybe data type."; } -def Parser_AnyDataType : Type< - Or< [ - Parser_NoDataType.predicate, - Parser_DataType.predicate, - Parser_MaybeDataType.predicate - ]> ->; +def Parser_AnyDataType : AnyTypeOf< [ + Parser_NoDataType, + Parser_DataType, + Parser_MaybeDataType +]>; #endif // VAST_DIALECT_PARSER_TYPES From d770373ea242e42b110aa1a26b8898e55f570fa8 Mon Sep 17 00:00:00 2001 From: xlauko Date: Wed, 20 Nov 2024 11:23:26 +0100 Subject: [PATCH 10/24] pr: Add to_maybe cast. --- include/vast/Dialect/Parser/Ops.hpp | 1 + include/vast/Dialect/Parser/Ops.td | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/vast/Dialect/Parser/Ops.hpp b/include/vast/Dialect/Parser/Ops.hpp index 59ecd36688..143f71ed9d 100644 --- a/include/vast/Dialect/Parser/Ops.hpp +++ b/include/vast/Dialect/Parser/Ops.hpp @@ -10,6 +10,7 @@ VAST_RELAX_WARNINGS VAST_UNRELAX_WARNINGS #include "vast/Dialect/Parser/Dialect.hpp" +#include "vast/Dialect/Parser/Types.hpp" #include "vast/Util/Common.hpp" #define GET_OP_CLASSES diff --git a/include/vast/Dialect/Parser/Ops.td b/include/vast/Dialect/Parser/Ops.td index 3c6b24b979..a92ce31f81 100644 --- a/include/vast/Dialect/Parser/Ops.td +++ b/include/vast/Dialect/Parser/Ops.td @@ -61,4 +61,16 @@ def Parse_NoParse }]; } +def Parse_ToMaybe + : Parser_Op< "to_maybe" > + , Arguments< (ins Parser_AnyDataType:$arguments) > + , Results< (outs Parser_MaybeDataType:$result) > +{ + let summary = "Casting operation to maybe type."; + + let assemblyFormat = [{ + $arguments attr-dict `:` functional-type($arguments, $result) + }]; +} + #endif // VAST_DIALECT_PARSER_OPS From 51718437c51bc0afb19d4e4ba102b9837a4d2d06 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 11:25:25 +0100 Subject: [PATCH 11/24] conv: Make function signature conversion allow to reflect on index of argument. --- .../Conversion/TypeConverters/TypeConverter.hpp | 12 ++++++++++-- .../TypeConverters/TypeConvertingPattern.hpp | 13 ++++--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/include/vast/Conversion/TypeConverters/TypeConverter.hpp b/include/vast/Conversion/TypeConverters/TypeConverter.hpp index 14bfa179a4..f0916e4e67 100644 --- a/include/vast/Conversion/TypeConverters/TypeConverter.hpp +++ b/include/vast/Conversion/TypeConverters/TypeConverter.hpp @@ -152,6 +152,10 @@ namespace vast::conv::tc { .template take_wrapped< maybe_type_t >(); } + maybe_type_t convert_arg_type(mlir_type t, unsigned long /* idx */) const { + return convert_type_to_type(t); + } + auto appender(types_t &out) const { return [&](auto collection) { out.insert( @@ -178,8 +182,12 @@ namespace vast::conv::tc { maybe_signature_conversion_t signature_conversion(const auto &inputs) const { signature_conversion_t sc(inputs.size()); - if (mlir::failed(self().convertSignatureArgs(inputs, sc))) { - return {}; + for (auto [i, arg] : llvm::enumerate(inputs)) { + if (auto trg = self().convert_arg_type(arg, i)) { + sc.addInputs(i, *trg); + } else { + return {}; + } } return { std::move(sc) }; } diff --git a/include/vast/Conversion/TypeConverters/TypeConvertingPattern.hpp b/include/vast/Conversion/TypeConverters/TypeConvertingPattern.hpp index 03fec17523..0e53daeb27 100644 --- a/include/vast/Conversion/TypeConverters/TypeConvertingPattern.hpp +++ b/include/vast/Conversion/TypeConverters/TypeConvertingPattern.hpp @@ -27,13 +27,7 @@ namespace vast::conv::tc { return replace_impl(op, rewriter, tc); } - logical_result replace(operation op, auto &rewriter) const { - auto tc = static_cast< const type_converter & >(*self().getTypeConverter()); - return replace(op, rewriter, tc); - } - private: - const auto &self() const { return static_cast< const derived & >(*this); } logical_result replace_impl(core::function_op_interface fn, auto &rewriter, const type_converter &tc) const { auto old_type = fn.getFunctionType(); @@ -81,8 +75,8 @@ namespace vast::conv::tc { } void fixup_entry_block(mlir::Block &block, const type_converter &tc) const { - for (auto arg : block.getArguments()) { - auto trg = tc.convert_type_to_type(arg.getType()); + for (auto [idx, arg] : llvm::enumerate(block.getArguments())) { + auto trg = tc.convert_arg_type(arg.getType(), idx); VAST_CHECK(trg, "Type conversion failed: {0}", arg); arg.setType(*trg); } @@ -114,7 +108,8 @@ namespace vast::conv::tc { operation op, mlir::ArrayRef< mlir::Value >, conversion_rewriter &rewriter ) const override { - return replace(op, rewriter); + auto tc = static_cast< const type_converter & >(*getTypeConverter()); + return replace(op, rewriter, tc); } }; From b512ade869f309be7c4bef65abb9e00eb0b4d9ba Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 11:27:47 +0100 Subject: [PATCH 12/24] conv: Add parser function conversion. --- lib/vast/Conversion/Parser/ToParser.cpp | 105 ++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 4a3200edc8..9f71ac1e24 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -17,6 +17,9 @@ VAST_UNRELAX_WARNINGS #include "vast/Conversion/Common/Mixins.hpp" #include "vast/Conversion/Common/Patterns.hpp" + +#include "vast/Conversion/TypeConverters/TypeConvertingPattern.hpp" + #include "vast/Util/Common.hpp" #include "vast/Dialect/Parser/Ops.hpp" @@ -58,6 +61,10 @@ namespace vast::conv { return to_mlir_type(return_type, mctx); } + mlir_type get_argument_type(unsigned int idx, mcontext_t *mctx) const { + return to_mlir_type(idx < arguments.size() ? arguments[idx] : arguments.back(), mctx); + } + std::vector< mlir_type > get_argument_types(mcontext_t *mctx) const { std::vector< mlir_type > out; out.reserve(arguments.size()); @@ -151,6 +158,58 @@ namespace vast::conv { const function_models ⊧ }; + struct function_type_converter + : tc::identity_type_converter + , tc::mixins< function_type_converter > + { + mcontext_t &mctx; + std::optional< function_model > model; + + using mixin_base = tc::mixins< function_type_converter >; + using mixin_base::convert_type_to_type; + + explicit function_type_converter(mcontext_t &mctx, std::optional< function_model > model) + : mctx(mctx), model(model) + { + addConversion([this](tc::core_function_type ty) -> maybe_type_t { + return convert_type_to_type(ty); + }); + } + + maybe_type_t convert_arg_type(mlir_type ty, unsigned long idx) const { + return Maybe(model + ? model->get_argument_type(idx, &mctx) + : pr::MaybeDataType::get(&mctx) + ).template take_wrapped< maybe_type_t >(); + } + + maybe_type_t convert_type_to_type(tc::core_function_type ty) const { + auto sig = signature_conversion(ty.getInputs()); + if (!sig) { + return std::nullopt; + } + + auto rty = convert_types_to_types(ty.getResults()); + if (!rty) { + return std::nullopt; + } + + return tc::core_function_type::get( + ty.getContext(), sig->getConvertedTypes(), *rty, ty.isVarArg() + ); + } + + maybe_type_t convert_type_to_type(mlir_type ty) const { + if (auto ft = mlir::dyn_cast< tc::core_function_type >(ty)) { + return convert_type_to_type(ft); + } + return Maybe(model + ? model->get_return_type(&mctx) + : pr::MaybeDataType::get(&mctx) + ).template take_wrapped< maybe_type_t >(); + } + }; + namespace pattern { mlir_value cast_value(mlir_value val, mlir_type ty, conversion_rewriter &rewriter) { @@ -289,9 +348,55 @@ namespace vast::conv { } }; + struct FuncConversion + : parser_conversion_pattern_base< hl::FuncOp > + , tc::op_type_conversion< hl::FuncOp, function_type_converter > + { + using op_t = hl::FuncOp; + using base = parser_conversion_pattern_base< op_t >; + using base::base; + + using adaptor_t = typename op_t::Adaptor; + + static std::optional< function_model > get_model( + const function_models &models, op_t op + ) { + if (auto kv = models.find(op.getSymName()); kv != models.end()) { + return kv->second; + } + + return std::nullopt; + } + + std::optional< function_model > get_model(op_t op) const { + return get_model(models, op); + } + + logical_result matchAndRewrite( + op_t op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + auto tc = function_type_converter(*rewriter.getContext(), get_model(op)); + if (auto func_op = mlir::dyn_cast< core::function_op_interface >(op.getOperation())) { + return this->replace(func_op, rewriter, tc); + } + + return mlir::failure(); + } + + static void legalize(parser_conversion_config &cfg) { + cfg.target.addLegalOp< mlir::UnrealizedConversionCastOp >(); + cfg.target.addDynamicallyLegalOp< op_t >([models = cfg.models](op_t op) { + return function_type_converter( + *op.getContext(), get_model(models, op) + ).isLegal(op.getFunctionType()); + }); + } + }; + using operation_conversions = util::type_list< ToNoParse< hl::ConstantOp >, ToNoParse< hl::ImplicitCastOp >, + FuncConversion, CallConversion >; From d4556e511a4c331a2e1a9cdffabec995a47acf25 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 11:28:34 +0100 Subject: [PATCH 13/24] pr: Add model for main function. --- .../vast/Conversion/Parser/default-parsers-config.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/vast/Conversion/Parser/default-parsers-config.yaml b/include/vast/Conversion/Parser/default-parsers-config.yaml index be5f81db69..e2e12afaf3 100644 --- a/include/vast/Conversion/Parser/default-parsers-config.yaml +++ b/include/vast/Conversion/Parser/default-parsers-config.yaml @@ -153,3 +153,12 @@ arguments: - nodata # FILE * stream category: nonparser + +- function: main + model: + return_type: nodata + arguments: + - nodata # int argc + - data # char * argv[] + - data # char * envp[] + category: nonparser From c165958c320e95bafd8135e043353fd86433cd43 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 11:44:18 +0100 Subject: [PATCH 14/24] pr: Add parser decl. --- include/vast/Dialect/Parser/Ops.hpp | 3 +++ include/vast/Dialect/Parser/Ops.td | 15 +++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/include/vast/Dialect/Parser/Ops.hpp b/include/vast/Dialect/Parser/Ops.hpp index 143f71ed9d..18984001bd 100644 --- a/include/vast/Dialect/Parser/Ops.hpp +++ b/include/vast/Dialect/Parser/Ops.hpp @@ -11,6 +11,9 @@ VAST_UNRELAX_WARNINGS #include "vast/Dialect/Parser/Dialect.hpp" #include "vast/Dialect/Parser/Types.hpp" + +#include "vast/Dialect/Core/Interfaces/SymbolInterface.hpp" + #include "vast/Util/Common.hpp" #define GET_OP_CLASSES diff --git a/include/vast/Dialect/Parser/Ops.td b/include/vast/Dialect/Parser/Ops.td index a92ce31f81..bfd9a02563 100644 --- a/include/vast/Dialect/Parser/Ops.td +++ b/include/vast/Dialect/Parser/Ops.td @@ -6,6 +6,7 @@ include "mlir/IR/OpBase.td" include "vast/Dialect/Core/Utils.td" +include "vast/Dialect/Core/Interfaces/SymbolInterface.td" include "vast/Dialect/Parser/Types.td" class Parser_Op< string mnemonic, list< Trait > traits = [] > @@ -73,4 +74,18 @@ def Parse_ToMaybe }]; } +def Parse_Decl + : Parser_Op< "decl", [Core_VarSymbol] > + , Arguments< (ins + SymbolNameAttr:$sym_name, + TypeAttr:$type + ) > +{ + let summary = "Declaration operation."; + + let assemblyFormat = [{ + $sym_name attr-dict `:` $type + }]; +} + #endif // VAST_DIALECT_PARSER_OPS From 06017f61fac1b50a7eb4dc9225a0012c96c4cd4f Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 11:44:56 +0100 Subject: [PATCH 15/24] conv: Add param to parser decl conversion. --- lib/vast/Conversion/Parser/ToParser.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 9f71ac1e24..0eb89155c0 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -348,6 +348,26 @@ namespace vast::conv { } }; + struct ParamConversion + : one_to_one_conversion_pattern< hl::ParmVarDeclOp, pr::Decl > + { + using op_t = hl::ParmVarDeclOp; + using base = one_to_one_conversion_pattern< hl::ParmVarDeclOp, pr::Decl >; + using base::base; + + using adaptor_t = typename op_t::Adaptor; + + logical_result matchAndRewrite( + op_t op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + rewriter.replaceOpWithNewOp< pr::Decl >( + op, op.getSymName(), op.getParam().getType() + ); + + return mlir::success(); + } + }; + struct FuncConversion : parser_conversion_pattern_base< hl::FuncOp > , tc::op_type_conversion< hl::FuncOp, function_type_converter > @@ -397,6 +417,7 @@ namespace vast::conv { ToNoParse< hl::ConstantOp >, ToNoParse< hl::ImplicitCastOp >, FuncConversion, + ParamConversion, CallConversion >; From 934fad2f81e7774f6427174a01e7be81b8a1a0ad Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 12:34:05 +0100 Subject: [PATCH 16/24] pr: Add reference operation. --- include/vast/Dialect/Parser/Ops.td | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/vast/Dialect/Parser/Ops.td b/include/vast/Dialect/Parser/Ops.td index bfd9a02563..3718c8a86b 100644 --- a/include/vast/Dialect/Parser/Ops.td +++ b/include/vast/Dialect/Parser/Ops.td @@ -88,4 +88,16 @@ def Parse_Decl }]; } +def Parse_Ref + : Parser_Op< "ref" > + , Arguments< (ins FlatSymbolRefAttr:$name) > + , Results< (outs Parser_AnyDataType:$result) > +{ + let summary = "Parser variable reference operation."; + + let assemblyFormat = [{ + $name attr-dict `:` type($result) + }]; +} + #endif // VAST_DIALECT_PARSER_OPS From f42479c16a9e242c5904a36eeb3bc5c6c25896c6 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 12:34:23 +0100 Subject: [PATCH 17/24] hl: Fix scope annotations. --- include/vast/Dialect/HighLevel/HighLevelCF.td | 52 +++++++++++++------ .../vast/Dialect/HighLevel/HighLevelOps.td | 9 +++- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/include/vast/Dialect/HighLevel/HighLevelCF.td b/include/vast/Dialect/HighLevel/HighLevelCF.td index fef8bb7320..bb7631fa05 100644 --- a/include/vast/Dialect/HighLevel/HighLevelCF.td +++ b/include/vast/Dialect/HighLevel/HighLevelCF.td @@ -86,9 +86,13 @@ def HighLevel_TypeYieldOp let assemblyFormat = [{ attr-dict $result `:` type($result) }]; } -def HighLevel_IfOp - : HighLevel_ControlFlowOp< "if" > -{ +def HighLevel_IfOp : HighLevel_ControlFlowOp< "if", [ + NoTerminator, Core_ScopeLikeTrait, + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > { let summary = "VAST if statement"; let description = [{ The operation takes builders of two mandatory regions -- condition and then @@ -293,9 +297,13 @@ def HighLevel_BinaryCondOp let assemblyFormat = [{ attr-dict `:` type(results) $commonRegion `,` $condRegion `?` $thenRegion `:` $elseRegion }]; } -def HighLevel_WhileOp - : HighLevel_ControlFlowOp< "while", [NoTerminator] > -{ +def HighLevel_WhileOp : HighLevel_ControlFlowOp< "while", [ + NoTerminator, Core_ScopeLikeTrait, + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > { let summary = "VAST while statement"; let description = [{ The operation takes builders of two mandatory regions -- condition and body @@ -328,9 +336,13 @@ def HighLevel_WhileOp } -def HighLevel_ForOp - : HighLevel_ControlFlowOp< "for" > -{ +def HighLevel_ForOp : HighLevel_ControlFlowOp< "for", [ + NoTerminator, Core_ScopeLikeTrait, + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > { let summary = "VAST for statement"; let description = [{ Operation represents a for-loop statement. @@ -367,9 +379,14 @@ def HighLevel_ForOp }]; } -def HighLevel_DoOp - : HighLevel_ControlFlowOp< "do" > -{ +def HighLevel_DoOp : HighLevel_ControlFlowOp< "do", [ + NoTerminator, Core_ScopeLikeTrait, + // FIXME: cond region should not expose symbols to the body region + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > { let summary = "VAST do-while statement"; let description = [{ The operation represents a do-while statement. @@ -420,9 +437,14 @@ def HighLevel_ContinueOp let assemblyFormat = [{ attr-dict }]; } -def HighLevel_SwitchOp - : HighLevel_ControlFlowOp< "switch" > -{ +def HighLevel_SwitchOp : HighLevel_ControlFlowOp< "switch", [ + NoTerminator, Core_ScopeLikeTrait, + // FIXME: look at proper scoping + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > { let summary = "VAST switch statement"; let description = [{ The operation represents a switch statement. diff --git a/include/vast/Dialect/HighLevel/HighLevelOps.td b/include/vast/Dialect/HighLevel/HighLevelOps.td index dfd15e9c67..e06ce5c2f1 100644 --- a/include/vast/Dialect/HighLevel/HighLevelOps.td +++ b/include/vast/Dialect/HighLevel/HighLevelOps.td @@ -421,8 +421,13 @@ def HighLevel_IndirectCallOp // TODO: add verifiers to check that callee type matches arg operands } -def HighLevel_ExprOp - : HighLevel_Op< "expr", [SingleBlock] > +def HighLevel_ExprOp: HighLevel_Op< "expr", [ + NoTerminator, SingleBlock, Core_ScopeLikeTrait, + Core_ShadowingSymbolTable< [ + [Core_VarSymbol, Core_TypeSymbol, Core_EnumConstantSymbol], + [Core_ElaboratedTypeSymbol] + ] > +] > , Results<(outs AnyType:$result)> { let summary = "VAST expression"; From cfe9b0d40218186f05cb19cb66b68cd2e41b0274 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 12:35:04 +0100 Subject: [PATCH 18/24] conv: Introduce decl ref converion to parser ref. --- lib/vast/Conversion/Parser/ToParser.cpp | 30 +++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 0eb89155c0..33aae618a2 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -368,6 +368,35 @@ namespace vast::conv { } }; + struct DeclRefConversion + : one_to_one_conversion_pattern< hl::DeclRefOp, pr::Ref > + { + using op_t = hl::DeclRefOp; + using base = one_to_one_conversion_pattern< op_t, pr::Ref >; + using base::base; + + using adaptor_t = typename op_t::Adaptor; + + logical_result matchAndRewrite( + op_t op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + auto rewrite = [&] (auto ty) { + rewriter.replaceOpWithNewOp< pr::Ref >(op, ty, op.getName()); + return mlir::success(); + }; + + if (auto vs = core::symbol_table::lookup< core::var_symbol >(op, op.getName())) { + if (auto var = mlir::dyn_cast< hl::VarDeclOp >(vs)) { + return rewrite(var.getType()); + } else if (auto par = mlir::dyn_cast< hl::ParmVarDeclOp >(vs)) { + return rewrite(par.getParam().getType()); + } + } + + return mlir::failure(); + } + }; + struct FuncConversion : parser_conversion_pattern_base< hl::FuncOp > , tc::op_type_conversion< hl::FuncOp, function_type_converter > @@ -418,6 +447,7 @@ namespace vast::conv { ToNoParse< hl::ImplicitCastOp >, FuncConversion, ParamConversion, + DeclRefConversion, CallConversion >; From 2bda66ac86f2e48edd5a00e8e4378c59a1de63d7 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 16:10:35 +0100 Subject: [PATCH 19/24] pr: Fix include. --- tools/vast-detect-parsers/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/vast-detect-parsers/main.cpp b/tools/vast-detect-parsers/main.cpp index 36aa62af2f..984bb843e4 100644 --- a/tools/vast-detect-parsers/main.cpp +++ b/tools/vast-detect-parsers/main.cpp @@ -5,7 +5,7 @@ #include "vast/Util/Warnings.hpp" VAST_RELAX_WARNINGS -include "mlir/Conversion/Passes.h" +#include "mlir/Conversion/Passes.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/MLIRContext.h" #include "mlir/InitAllDialects.h" From df8f2b2f1938770c49888c0e0852fe71c3192d0b Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 16:36:34 +0100 Subject: [PATCH 20/24] pr: Fix types for decl ref conversion. --- lib/vast/Conversion/Parser/ToParser.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 33aae618a2..e94b20c8bf 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -41,6 +41,13 @@ namespace vast::conv { } } + template< typename... Ts > + auto is_one_of(mlir_type ty) { return (mlir::isa< Ts >(ty) || ...); } + + bool is_parser_type(mlir_type ty) { + return is_one_of< pr::DataType, pr::NoDataType, pr::MaybeDataType >(ty); + } + enum class function_category { sink, source, parser, nonparser }; struct function_model @@ -381,7 +388,11 @@ namespace vast::conv { op_t op, adaptor_t adaptor, conversion_rewriter &rewriter ) const override { auto rewrite = [&] (auto ty) { - rewriter.replaceOpWithNewOp< pr::Ref >(op, ty, op.getName()); + ty = is_parser_type(ty) ? ty : pr::MaybeDataType::get(rewriter.getContext()); + auto converted = rewriter.create< pr::Ref >(op.getLoc(), ty, op.getName()); + rewriter.replaceOpWithNewOp< mlir::UnrealizedConversionCastOp >( + op, op.getType(), converted->getResult(0) + ); return mlir::success(); }; From c41da62c9b16e1d0825a0acec4a4c4590e94d353 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 16:58:38 +0100 Subject: [PATCH 21/24] conv: Add return conversion pattern. --- lib/vast/Conversion/Parser/ToParser.cpp | 71 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index e94b20c8bf..80b7509864 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -258,6 +258,20 @@ namespace vast::conv { : base(mctx), models(models) {} + static std::optional< function_model > get_model( + const function_models &models, string_ref name + ) { + if (auto kv = models.find(name); kv != models.end()) { + return kv->second; + } + + return std::nullopt; + } + + std::optional< function_model > get_model(string_ref name) const { + return get_model(models, name); + } + const function_models ⊧ }; @@ -408,34 +422,60 @@ namespace vast::conv { } }; - struct FuncConversion - : parser_conversion_pattern_base< hl::FuncOp > - , tc::op_type_conversion< hl::FuncOp, function_type_converter > + struct ReturnConversion + : parser_conversion_pattern_base< hl::ReturnOp > { - using op_t = hl::FuncOp; + using op_t = hl::ReturnOp; using base = parser_conversion_pattern_base< op_t >; using base::base; using adaptor_t = typename op_t::Adaptor; - static std::optional< function_model > get_model( - const function_models &models, op_t op - ) { - if (auto kv = models.find(op.getSymName()); kv != models.end()) { - return kv->second; - } + logical_result matchAndRewrite( + op_t op, adaptor_t adaptor, conversion_rewriter &rewriter + ) const override { + auto func = op->getParentOfType< hl::FuncOp >(); + auto model = get_model(func.getSymName()); - return std::nullopt; + auto rty = model + ? model->get_return_type(rewriter.getContext()) + : pr::MaybeDataType::get(rewriter.getContext()); + + rewriter.replaceOpWithNewOp< op_t >( + op, convert_value_types(adaptor.getOperands(), rty, rewriter) + ); + + return mlir::success(); } - std::optional< function_model > get_model(op_t op) const { - return get_model(models, op); + static void legalize(parser_conversion_config &cfg) { + cfg.target.addLegalOp< mlir::UnrealizedConversionCastOp >(); + cfg.target.addDynamicallyLegalOp< op_t >([](op_t op) { + for (auto ty : op.getResult().getType()) { + if (!is_parser_type(ty)) { + return false; + } + } + return true; + }); } + }; + + struct FuncConversion + : parser_conversion_pattern_base< hl::FuncOp > + , tc::op_type_conversion< hl::FuncOp, function_type_converter > + { + using op_t = hl::FuncOp; + using base = parser_conversion_pattern_base< op_t >; + using base::base; + + using adaptor_t = typename op_t::Adaptor; + logical_result matchAndRewrite( op_t op, adaptor_t adaptor, conversion_rewriter &rewriter ) const override { - auto tc = function_type_converter(*rewriter.getContext(), get_model(op)); + auto tc = function_type_converter(*rewriter.getContext(), get_model(op.getSymName())); if (auto func_op = mlir::dyn_cast< core::function_op_interface >(op.getOperation())) { return this->replace(func_op, rewriter, tc); } @@ -447,7 +487,7 @@ namespace vast::conv { cfg.target.addLegalOp< mlir::UnrealizedConversionCastOp >(); cfg.target.addDynamicallyLegalOp< op_t >([models = cfg.models](op_t op) { return function_type_converter( - *op.getContext(), get_model(models, op) + *op.getContext(), get_model(models, op.getSymName()) ).isLegal(op.getFunctionType()); }); } @@ -459,6 +499,7 @@ namespace vast::conv { FuncConversion, ParamConversion, DeclRefConversion, + ReturnConversion, CallConversion >; From 8f44b39d1e600e842bc54f837a30e050718ea923 Mon Sep 17 00:00:00 2001 From: xlauko Date: Fri, 22 Nov 2024 17:18:32 +0100 Subject: [PATCH 22/24] conv: Add non-parsing cmp conversion. --- lib/vast/Conversion/Parser/ToParser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/vast/Conversion/Parser/ToParser.cpp b/lib/vast/Conversion/Parser/ToParser.cpp index 80b7509864..8d02b0c3e9 100644 --- a/lib/vast/Conversion/Parser/ToParser.cpp +++ b/lib/vast/Conversion/Parser/ToParser.cpp @@ -496,6 +496,7 @@ namespace vast::conv { using operation_conversions = util::type_list< ToNoParse< hl::ConstantOp >, ToNoParse< hl::ImplicitCastOp >, + ToNoParse< hl::CmpOp>, ToNoParse< hl::FCmpOp >, FuncConversion, ParamConversion, DeclRefConversion, From 0b52fcd653e8b62b9e97b570782fa0fb7cc109ae Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 25 Nov 2024 09:52:12 +0100 Subject: [PATCH 23/24] conv: Simplify unrealized_materialization. --- include/vast/Conversion/TypeConverters/TypeConverter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/vast/Conversion/TypeConverters/TypeConverter.hpp b/include/vast/Conversion/TypeConverters/TypeConverter.hpp index f0916e4e67..203687018b 100644 --- a/include/vast/Conversion/TypeConverters/TypeConverter.hpp +++ b/include/vast/Conversion/TypeConverters/TypeConverter.hpp @@ -45,7 +45,7 @@ namespace vast::conv::tc { } }; - static inline constexpr auto unrealized_materialization = [] ( + static inline auto unrealized_materialization( mlir::OpBuilder &builder, mlir::Type resultType, mlir::ValueRange inputs, mlir::Location loc ) -> std::optional< mlir::Value > { From 6f04dc7853461c17ce90e40480eea0aab82936d9 Mon Sep 17 00:00:00 2001 From: xlauko Date: Mon, 25 Nov 2024 09:53:02 +0100 Subject: [PATCH 24/24] tools: Remove obsolete detect-parsers. --- tools/detect-parsers/main.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 tools/detect-parsers/main.cpp diff --git a/tools/detect-parsers/main.cpp b/tools/detect-parsers/main.cpp deleted file mode 100644 index 7d5a51baf0..0000000000 --- a/tools/detect-parsers/main.cpp +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (c) 2021-present, Trail of Bits, Inc. - -#include "vast/Util/Warnings.hpp" - -VAST_RELAX_WARNINGS -#include "mlir/Conversion/Passes.h" -#include "mlir/IR/Dialect.h" -#include "mlir/IR/MLIRContext.h" -#include "mlir/InitAllDialects.h" -#include "mlir/Tools/mlir-opt/MlirOptMain.h" -VAST_UNRELAX_WARNINGS - -#include "vast/Conversion/Parser/Passes.hpp" -#include "vast/Dialect/Dialects.hpp" - -#include "vast/Dialect/Parser/Dialect.hpp" - -int main(int argc, char **argv) -{ - mlir::DialectRegistry registry; - // register dialects - vast::registerAllDialects(registry); - mlir::registerAllDialects(registry); - - vast::registerParserConversionPasses(); - mlir::registerConversionPasses(); - registry.insert< vast::pr::ParserDialect >(); - - return mlir::asMainReturnCode( - mlir::MlirOptMain(argc, argv, "VAST Parser Detection driver\n", registry) - ); -}