diff --git a/xls/dev_tools/dev_passes/literalize_zero_bits_pass.cc b/xls/dev_tools/dev_passes/literalize_zero_bits_pass.cc index 63751c8065..a004298bad 100644 --- a/xls/dev_tools/dev_passes/literalize_zero_bits_pass.cc +++ b/xls/dev_tools/dev_passes/literalize_zero_bits_pass.cc @@ -14,6 +14,8 @@ #include "xls/dev_tools/dev_passes/literalize_zero_bits_pass.h" +#include +#include #include #include "absl/status/statusor.h" @@ -27,6 +29,13 @@ #include "xls/passes/pass_base.h" namespace xls { + +std::optional LiteralizeZeroBits::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr LiteralizeZeroBits::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/dev_tools/dev_passes/literalize_zero_bits_pass.h b/xls/dev_tools/dev_passes/literalize_zero_bits_pass.h index 3fd055b8db..50c2d4fba2 100644 --- a/xls/dev_tools/dev_passes/literalize_zero_bits_pass.h +++ b/xls/dev_tools/dev_passes/literalize_zero_bits_pass.h @@ -15,12 +15,15 @@ #ifndef XLS_DEV_TOOLS_DEV_PASSES_LITERALIZE_ZERO_BITS_PASS_H_ #define XLS_DEV_TOOLS_DEV_PASSES_LITERALIZE_ZERO_BITS_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" #include "xls/ir/function_base.h" #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" + namespace xls { class LiteralizeZeroBits final : public OptimizationFunctionBasePass { @@ -28,6 +31,11 @@ class LiteralizeZeroBits final : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "literalize_zero_bits"; LiteralizeZeroBits() : OptimizationFunctionBasePass(kName, "Literalize zero bits") {} + ~LiteralizeZeroBits() override = default; + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; protected: absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.cc b/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.cc index 4271df8096..e6987cf401 100644 --- a/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.cc +++ b/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.cc @@ -14,6 +14,10 @@ #include "xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.h" +#include +#include +#include + #include "absl/status/statusor.h" #include "xls/common/status/status_macros.h" #include "xls/ir/package.h" @@ -22,6 +26,14 @@ #include "xls/scheduling/scheduling_pass.h" namespace xls { + +std::optional +ProcStateLegalizationPassShim::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ProcStateLegalizationPassShim::RunInternal( Package* p, const OptimizationPassOptions& options, PassResults* pass_results, OptimizationContext& context) const { diff --git a/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.h b/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.h index 7fc7c80069..19ab077f60 100644 --- a/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.h +++ b/xls/dev_tools/dev_passes/proc_state_legalization_pass_shim.h @@ -15,6 +15,8 @@ #ifndef XLS_DEV_TOOLS_DEV_PASSES_PROC_STATE_LEGALIZATION_PASS_SHIM_H_ #define XLS_DEV_TOOLS_DEV_PASSES_PROC_STATE_LEGALIZATION_PASS_SHIM_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -22,6 +24,7 @@ #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" #include "xls/scheduling/proc_state_legalization_pass.h" + namespace xls { // Compatibility shim to use the scheduling pass 'ProcStateLegalizationPass' in @@ -31,6 +34,11 @@ class ProcStateLegalizationPassShim : public OptimizationPass { static constexpr std::string_view kName = "proc_state_legalization_shim"; ProcStateLegalizationPassShim() : OptimizationPass(kName, "Proc State Legalization Pass") {} + ~ProcStateLegalizationPassShim() override = default; + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; protected: absl::StatusOr RunInternal(Package* p, diff --git a/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.cc b/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.cc index 2969ed4b16..373c87e2a9 100644 --- a/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.cc +++ b/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.cc @@ -14,6 +14,8 @@ #include "xls/dev_tools/dev_passes/remove_assert_and_cover_pass.h" +#include +#include #include #include "absl/status/statusor.h" @@ -27,6 +29,12 @@ namespace xls { +std::optional AssertAndCoverRemovalPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr AssertAndCoverRemovalPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.h b/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.h index 69ee16f7de..5d2876d9e7 100644 --- a/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.h +++ b/xls/dev_tools/dev_passes/remove_assert_and_cover_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_DEV_TOOLS_DEV_PASSES_REMOVE_ASSERT_AND_COVER_PASS_H_ #define XLS_DEV_TOOLS_DEV_PASSES_REMOVE_ASSERT_AND_COVER_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -22,6 +24,7 @@ #include "xls/ir/node.h" #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" + namespace xls { class AssertAndCoverRemovalPass : public OptimizationFunctionBasePass { @@ -29,6 +32,11 @@ class AssertAndCoverRemovalPass : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "assert_and_cover_removal"; AssertAndCoverRemovalPass() : OptimizationFunctionBasePass(kName, "Assert and cover removal") {} + ~AssertAndCoverRemovalPass() override = default; + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; protected: absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/dslx/run_routines/run_routines.cc b/xls/dslx/run_routines/run_routines.cc index cafe47046f..5a9bf3ae81 100644 --- a/xls/dslx/run_routines/run_routines.cc +++ b/xls/dslx/run_routines/run_routines.cc @@ -243,6 +243,12 @@ class QuickCheckProveAssertsNotFiredPass final "add asserts to quickcheck goal") {} ~QuickCheckProveAssertsNotFiredPass() final = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override { + return std::string(short_name()); + } + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* fb, const OptimizationPassOptions& options, diff --git a/xls/passes/BUILD b/xls/passes/BUILD index be1a876260..8ad1c055c8 100644 --- a/xls/passes/BUILD +++ b/xls/passes/BUILD @@ -604,6 +604,7 @@ xls_pass( "//xls/ir:value", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/types:span", ], ) @@ -747,6 +748,7 @@ cc_library( "@com_google_absl//absl/log:check", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/types:span", ], @@ -1114,6 +1116,7 @@ xls_pass( "@com_google_absl//absl/random", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/types:span", "@cppitertools", ], @@ -1147,6 +1150,7 @@ xls_pass( "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/types:span", ], ) @@ -1952,6 +1956,7 @@ cc_library( "//xls/common/status:status_macros", "//xls/ir", "//xls/passes/tools:passes_profile", + "@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/log", "@com_google_absl//absl/log:check", "@com_google_absl//absl/status", @@ -1991,8 +1996,11 @@ cc_test( "@com_google_absl//absl/status", "@com_google_absl//absl/status:status_matchers", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings", "@com_google_absl//absl/strings:str_format", + "@com_google_absl//absl/time", "@com_google_absl//absl/types:span", + "@com_google_protobuf//:duration_cc_proto", "@googletest//:gtest", ], ) @@ -2577,6 +2585,7 @@ xls_pass( "@com_google_absl//absl/algorithm:container", "@com_google_absl//absl/log:check", "@com_google_absl//absl/status:statusor", + "@com_google_absl//absl/strings:str_format", "@com_google_absl//absl/types:span", "@cppitertools", ], diff --git a/xls/passes/arith_simplification_pass.cc b/xls/passes/arith_simplification_pass.cc index 4f278bf04a..50e9fbd719 100644 --- a/xls/passes/arith_simplification_pass.cc +++ b/xls/passes/arith_simplification_pass.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -2022,6 +2023,12 @@ absl::StatusOr MatchArithPatterns(int64_t opt_level, Node* n, } // namespace +std::optional ArithSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr ArithSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/arith_simplification_pass.h b/xls/passes/arith_simplification_pass.h index a39d4f1b24..0f65fe1c0c 100644 --- a/xls/passes/arith_simplification_pass.h +++ b/xls/passes/arith_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_ARITH_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_ARITH_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -169,6 +171,12 @@ class ArithSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Arithmetic Simplifications") {} ~ArithSimplificationPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/array_simplification_pass.cc b/xls/passes/array_simplification_pass.cc index 9ea1ed5d56..456bb30f48 100644 --- a/xls/passes/array_simplification_pass.cc +++ b/xls/passes/array_simplification_pass.cc @@ -1699,6 +1699,12 @@ absl::StatusOr SimplifySelect(Node* select, } // namespace +std::optional ArraySimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr ArraySimplificationPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/array_simplification_pass.h b/xls/passes/array_simplification_pass.h index a931757ba7..7290969f25 100644 --- a/xls/passes/array_simplification_pass.h +++ b/xls/passes/array_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_ARRAY_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_ARRAY_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -176,6 +178,12 @@ class ArraySimplificationPass : public OptimizationFunctionBasePass { explicit ArraySimplificationPass() : OptimizationFunctionBasePass(kName, "Array Simplification") {} + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/array_untuple_pass.cc b/xls/passes/array_untuple_pass.cc index 5d5c1f9d65..a0bea66d3d 100644 --- a/xls/passes/array_untuple_pass.cc +++ b/xls/passes/array_untuple_pass.cc @@ -597,8 +597,15 @@ class UntupleVisitor : public DfsVisitorWithDefault { absl::flat_hash_map> components_; bool changed_ = false; }; + } // namespace +std::optional ArrayUntuplePass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ArrayUntuplePass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/array_untuple_pass.h b/xls/passes/array_untuple_pass.h index a806cb756f..1f1618eb21 100644 --- a/xls/passes/array_untuple_pass.h +++ b/xls/passes/array_untuple_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_ARRAY_UNTUPLE_PASS_H_ #define XLS_PASSES_ARRAY_UNTUPLE_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -180,6 +182,10 @@ class ArrayUntuplePass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Array UnTuple") {} ~ArrayUntuplePass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/basic_simplification_pass.cc b/xls/passes/basic_simplification_pass.cc index 7f643ce6ac..cde0aa0d3a 100644 --- a/xls/passes/basic_simplification_pass.cc +++ b/xls/passes/basic_simplification_pass.cc @@ -15,6 +15,8 @@ #include #include +#include +#include #include #include "absl/container/flat_hash_map.h" @@ -778,6 +780,12 @@ absl::StatusOr MatchPatterns(Node* n) { } // namespace +std::optional BasicSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr BasicSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/basic_simplification_pass.h b/xls/passes/basic_simplification_pass.h index e5176cfc27..66289a8e80 100644 --- a/xls/passes/basic_simplification_pass.h +++ b/xls/passes/basic_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_BASIC_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_BASIC_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -127,6 +129,12 @@ class BasicSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Basic Simplifications") {} ~BasicSimplificationPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/bdd_cse_pass.cc b/xls/passes/bdd_cse_pass.cc index 4b596630ad..1720ae12d0 100644 --- a/xls/passes/bdd_cse_pass.cc +++ b/xls/passes/bdd_cse_pass.cc @@ -16,6 +16,8 @@ #include #include +#include +#include #include #include "absl/container/flat_hash_map.h" @@ -97,6 +99,12 @@ absl::StatusOr> GetNodeOrder(FunctionBase* f, } // namespace +std::optional BddCsePass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr BddCsePass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/bdd_cse_pass.h b/xls/passes/bdd_cse_pass.h index f63939f29a..9f4a8b9665 100644 --- a/xls/passes/bdd_cse_pass.h +++ b/xls/passes/bdd_cse_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_BDD_CSE_PASS_H_ #define XLS_PASSES_BDD_CSE_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -139,6 +141,10 @@ class BddCsePass : public OptimizationFunctionBasePass { kName, "BDD-based Common Subexpression Elimination") {} ~BddCsePass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/bdd_simplification_pass.cc b/xls/passes/bdd_simplification_pass.cc index 719098aeae..97898addbe 100644 --- a/xls/passes/bdd_simplification_pass.cc +++ b/xls/passes/bdd_simplification_pass.cc @@ -442,6 +442,12 @@ absl::StatusOr SimplifyNode(Node* node, const QueryEngine& query_engine, } // namespace +std::optional BddSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr BddSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/bdd_simplification_pass.h b/xls/passes/bdd_simplification_pass.h index 1d90fe7df8..5f2b4a311c 100644 --- a/xls/passes/bdd_simplification_pass.h +++ b/xls/passes/bdd_simplification_pass.h @@ -15,9 +15,12 @@ #ifndef XLS_PASSES_BDD_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_BDD_SIMPLIFICATION_PASS_H_ -#include +#include +#include +#include #include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "xls/ir/function_base.h" #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" @@ -91,6 +94,10 @@ class BddSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "BDD-based Simplification") {} ~BddSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Run all registered passes in order of registration. absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/bit_slice_simplification_pass.cc b/xls/passes/bit_slice_simplification_pass.cc index 3bf7238b76..e3c8273cd6 100644 --- a/xls/passes/bit_slice_simplification_pass.cc +++ b/xls/passes/bit_slice_simplification_pass.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -1056,6 +1057,12 @@ absl::StatusOr SimplifyBitSliceUpdate(BitSliceUpdate* update, } // namespace +std::optional BitSliceSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr BitSliceSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/bit_slice_simplification_pass.h b/xls/passes/bit_slice_simplification_pass.h index 9272aac7d4..a1852a1863 100644 --- a/xls/passes/bit_slice_simplification_pass.h +++ b/xls/passes/bit_slice_simplification_pass.h @@ -15,9 +15,12 @@ #ifndef XLS_PASSES_BIT_SLICE_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_BIT_SLICE_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "xls/ir/function_base.h" #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" @@ -156,6 +159,10 @@ class BitSliceSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Bit-slice simplification") {} ~BitSliceSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/boolean_simplification_pass.cc b/xls/passes/boolean_simplification_pass.cc index 0e6f03f9a2..8efced54c9 100644 --- a/xls/passes/boolean_simplification_pass.cc +++ b/xls/passes/boolean_simplification_pass.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -495,6 +496,12 @@ class BooleanFlowTracker : public DfsVisitorWithDefault { } // namespace +std::optional BooleanSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr BooleanSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/boolean_simplification_pass.h b/xls/passes/boolean_simplification_pass.h index e21e5edeb2..1e95258615 100644 --- a/xls/passes/boolean_simplification_pass.h +++ b/xls/passes/boolean_simplification_pass.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/status/statusor.h" @@ -145,6 +146,10 @@ class BooleanSimplificationPass : public OptimizationFunctionBasePass { BooleanSimplificationPass() : OptimizationFunctionBasePass(kName, "boolean simplification") {} + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/canonicalization_pass.cc b/xls/passes/canonicalization_pass.cc index 3ea6f2c0c5..15f224252a 100644 --- a/xls/passes/canonicalization_pass.cc +++ b/xls/passes/canonicalization_pass.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include "absl/log/log.h" @@ -160,14 +161,12 @@ absl::StatusOr MaybeCanonicalizeClamp(Node* n, return false; } -} // namespace - // CanonicalizeNodes performs simple canonicalization of expressions, // such as moving a literal in an associative expression to the right. // Being able to rely on the shape of such nodes greatly simplifies // the implementation of transformation passes, as only one pattern needs // to be matched, instead of two. -static absl::StatusOr CanonicalizeNode(Node* n) { +absl::StatusOr CanonicalizeNode(Node* n) { FunctionBase* f = n->function_base(); StatelessQueryEngine query_engine; @@ -351,6 +350,14 @@ static absl::StatusOr CanonicalizeNode(Node* n) { return false; } +} // namespace + +std::optional CanonicalizationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr CanonicalizationPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/canonicalization_pass.h b/xls/passes/canonicalization_pass.h index 55876ff861..2dfdf6ac0d 100644 --- a/xls/passes/canonicalization_pass.h +++ b/xls/passes/canonicalization_pass.h @@ -17,6 +17,8 @@ #ifndef XLS_PASSES_CANONICALIZATION_PASS_H_ #define XLS_PASSES_CANONICALIZATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -169,6 +171,12 @@ class CanonicalizationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Canonicalization") {} ~CanonicalizationPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/channel_legalization_pass.cc b/xls/passes/channel_legalization_pass.cc index d6ba2ceda9..52dae965ac 100644 --- a/xls/passes/channel_legalization_pass.cc +++ b/xls/passes/channel_legalization_pass.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -567,6 +568,12 @@ absl::Status CheckMutualExclusion(Proc* proc, } // namespace +std::optional ChannelLegalizationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ChannelLegalizationPass::RunInternal( Package* p, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/channel_legalization_pass.h b/xls/passes/channel_legalization_pass.h index bebd91b021..5c2691c880 100644 --- a/xls/passes/channel_legalization_pass.h +++ b/xls/passes/channel_legalization_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_CHANNEL_LEGALIZATION_PASS_H_ #define XLS_PASSES_CHANNEL_LEGALIZATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -185,6 +187,10 @@ class ChannelLegalizationPass : public OptimizationPass { : OptimizationPass(kName, "Legalize multiple send/recvs per channel") {} ~ChannelLegalizationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunInternal(Package* p, const OptimizationPassOptions& options, diff --git a/xls/passes/comparison_simplification_pass.cc b/xls/passes/comparison_simplification_pass.cc index fca1b312f6..31afeb54c6 100644 --- a/xls/passes/comparison_simplification_pass.cc +++ b/xls/passes/comparison_simplification_pass.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -320,6 +321,12 @@ absl::StatusOr TransformDerivedComparisons(FunctionBase* f, } // namespace +std::optional ComparisonSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ComparisonSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/comparison_simplification_pass.h b/xls/passes/comparison_simplification_pass.h index 6650d405f4..693e0ce311 100644 --- a/xls/passes/comparison_simplification_pass.h +++ b/xls/passes/comparison_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_COMPARISON_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_COMPARISON_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -151,6 +153,10 @@ class ComparisonSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Comparison Simplification") {} ~ComparisonSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/concat_simplification_pass.cc b/xls/passes/concat_simplification_pass.cc index 7f0e1e8d77..84e79b4935 100644 --- a/xls/passes/concat_simplification_pass.cc +++ b/xls/passes/concat_simplification_pass.cc @@ -20,11 +20,13 @@ #include #include #include +#include #include #include #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_format.h" #include "absl/types/span.h" #include "xls/common/status/ret_check.h" #include "xls/common/status/status_macros.h" @@ -739,6 +741,12 @@ absl::StatusOr TryDistributeReducibleOperation(Node* node) { } // namespace +std::optional ConcatSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr ConcatSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/concat_simplification_pass.h b/xls/passes/concat_simplification_pass.h index 3d6edbccbf..62b0a838a7 100644 --- a/xls/passes/concat_simplification_pass.h +++ b/xls/passes/concat_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_CONCAT_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_CONCAT_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -191,6 +193,10 @@ class ConcatSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Concat simplification") {} ~ConcatSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/conditional_specialization_pass.cc b/xls/passes/conditional_specialization_pass.cc index 5e8c31723a..59c4b4eab9 100644 --- a/xls/passes/conditional_specialization_pass.cc +++ b/xls/passes/conditional_specialization_pass.cc @@ -932,6 +932,17 @@ static constexpr int64_t kBddGcThreshold = 5'000'000'000; // 5GB } // namespace +std::optional +ConditionalSpecializationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat( + "%s(%s,%s,%s)", short_name(), use_bdd_ ? "bdd" : "no_bdd", + options.eliminate_noop_next ? "drop_noop_next" : "keep_noop_next", + options.optimize_for_best_case_throughput ? "opt_throughput" + : "opt_area"); +} + absl::StatusOr ConditionalSpecializationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/conditional_specialization_pass.h b/xls/passes/conditional_specialization_pass.h index 562635da30..31ca63f098 100644 --- a/xls/passes/conditional_specialization_pass.h +++ b/xls/passes/conditional_specialization_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_CONDITIONAL_SPECIALIZATION_PASS_H_ #define XLS_PASSES_CONDITIONAL_SPECIALIZATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -64,6 +66,11 @@ class ConditionalSpecializationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(ConfiguredName(use_bdd), "Conditional specialization"), use_bdd_(use_bdd) {} + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + ~ConditionalSpecializationPass() override = default; protected: diff --git a/xls/passes/constant_folding_pass.cc b/xls/passes/constant_folding_pass.cc index be977ae6c2..b66766e021 100644 --- a/xls/passes/constant_folding_pass.cc +++ b/xls/passes/constant_folding_pass.cc @@ -14,6 +14,8 @@ #include "xls/passes/constant_folding_pass.h" +#include +#include #include #include "absl/algorithm/container.h" @@ -35,6 +37,7 @@ namespace xls { namespace { + // Check if we can do constant folding on this node. bool NodeIsConstantFoldable(Node* node, QueryEngine& query_engine) { if (node->users().empty() && !node->function_base()->HasImplicitUse(node)) { @@ -58,8 +61,15 @@ bool NodeIsConstantFoldable(Node* node, QueryEngine& query_engine) { return query_engine.IsFullyKnown(operand); }); } + } // namespace +std::optional ConstantFoldingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ConstantFoldingPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/constant_folding_pass.h b/xls/passes/constant_folding_pass.h index c7b617791d..fb1d023a83 100644 --- a/xls/passes/constant_folding_pass.h +++ b/xls/passes/constant_folding_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_CONSTANT_FOLDING_PASS_H_ #define XLS_PASSES_CONSTANT_FOLDING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -116,7 +118,10 @@ class ConstantFoldingPass : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "const_fold"; ConstantFoldingPass() : OptimizationFunctionBasePass(kName, "Constant folding") {} - ~ConstantFoldingPass() override = default; + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; protected: absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/cse_pass.cc b/xls/passes/cse_pass.cc index 2af32d352a..593cc94699 100644 --- a/xls/passes/cse_pass.cc +++ b/xls/passes/cse_pass.cc @@ -23,6 +23,8 @@ #include #include #include +#include +#include #include #include #include @@ -458,6 +460,13 @@ absl::StatusOr RunCse(FunctionBase* f, OptimizationContext& context, return true; } +std::optional CsePass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(%s)", short_name(), + common_literals_ ? "literals" : "no_literals"); +} + absl::StatusOr CsePass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/cse_pass.h b/xls/passes/cse_pass.h index e7f18ddbf0..7cd2f23288 100644 --- a/xls/passes/cse_pass.h +++ b/xls/passes/cse_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_CSE_PASS_H_ #define XLS_PASSES_CSE_PASS_H_ +#include +#include #include #include "absl/container/flat_hash_map.h" @@ -173,6 +175,10 @@ class CsePass : public OptimizationFunctionBasePass { common_literals_(common_literals) {} ~CsePass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/dataflow_simplification_pass.cc b/xls/passes/dataflow_simplification_pass.cc index fa0376d285..09b98c80b8 100644 --- a/xls/passes/dataflow_simplification_pass.cc +++ b/xls/passes/dataflow_simplification_pass.cc @@ -15,6 +15,8 @@ #include "xls/passes/dataflow_simplification_pass.h" #include +#include +#include #include #include @@ -82,6 +84,12 @@ absl::StatusOr MaybeReplaceWithArrayOfExistingNodes( } // namespace +std::optional DataflowSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr DataflowSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/dataflow_simplification_pass.h b/xls/passes/dataflow_simplification_pass.h index e4d110b1b7..51743961d5 100644 --- a/xls/passes/dataflow_simplification_pass.h +++ b/xls/passes/dataflow_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_DATAFLOW_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_DATAFLOW_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -144,8 +146,13 @@ class DataflowSimplificationPass : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "dataflow"; explicit DataflowSimplificationPass() : OptimizationFunctionBasePass(kName, "Dataflow Optimization") {} + ~DataflowSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/dce_pass.cc b/xls/passes/dce_pass.cc index 05b43c47f2..ae51de48eb 100644 --- a/xls/passes/dce_pass.cc +++ b/xls/passes/dce_pass.cc @@ -16,6 +16,8 @@ #include #include +#include +#include #include "absl/container/flat_hash_set.h" #include "absl/log/log.h" @@ -30,6 +32,13 @@ namespace xls { +std::optional DeadCodeEliminationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + // DCE is not affected by the options; it's the same pass every time. + return std::string(short_name()); +} + absl::StatusOr DeadCodeEliminationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/dce_pass.h b/xls/passes/dce_pass.h index fa4b16678f..8d1b93b30b 100644 --- a/xls/passes/dce_pass.h +++ b/xls/passes/dce_pass.h @@ -17,6 +17,8 @@ #ifndef XLS_PASSES_DCE_PASS_H_ #define XLS_PASSES_DCE_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -146,6 +148,12 @@ class DeadCodeEliminationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Dead Code Elimination") {} ~DeadCodeEliminationPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Iterate all nodes, mark and eliminate the unvisited nodes. absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/dfe_pass.cc b/xls/passes/dfe_pass.cc index 1cfd30e4dc..079c56cdcd 100644 --- a/xls/passes/dfe_pass.cc +++ b/xls/passes/dfe_pass.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -158,6 +159,12 @@ absl::StatusOr ProcLiveness(Proc* top) { } // namespace +std::optional DeadFunctionEliminationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + // Starting from the return_value(s), DFS over all nodes. Unvisited // nodes, or parameters, are dead. absl::StatusOr DeadFunctionEliminationPass::RunInternal( diff --git a/xls/passes/dfe_pass.h b/xls/passes/dfe_pass.h index dfcfbaedf8..1daacb9c3b 100644 --- a/xls/passes/dfe_pass.h +++ b/xls/passes/dfe_pass.h @@ -17,6 +17,8 @@ #ifndef XLS_PASSES_DFE_PASS_H_ #define XLS_PASSES_DFE_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -101,6 +103,12 @@ class DeadFunctionEliminationPass : public OptimizationPass { : OptimizationPass(kName, "Dead Function Elimination") {} ~DeadFunctionEliminationPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Iterate all nodes and mark and eliminate unreachable functions. absl::StatusOr RunInternal(Package* p, diff --git a/xls/passes/identity_removal_pass.cc b/xls/passes/identity_removal_pass.cc index 17d3f8abb3..6c98d3cfd3 100644 --- a/xls/passes/identity_removal_pass.cc +++ b/xls/passes/identity_removal_pass.cc @@ -14,6 +14,9 @@ #include "xls/passes/identity_removal_pass.h" +#include +#include + #include "absl/status/statusor.h" #include "xls/common/status/status_macros.h" #include "xls/ir/function_base.h" @@ -24,6 +27,12 @@ namespace xls { +std::optional IdentityRemovalPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + // Identity Removal performs one forward pass over the nodes and replaces // identities with their respective operands. absl::StatusOr IdentityRemovalPass::RunOnFunctionBaseInternal( diff --git a/xls/passes/identity_removal_pass.h b/xls/passes/identity_removal_pass.h index 9150139696..fa401550e7 100644 --- a/xls/passes/identity_removal_pass.h +++ b/xls/passes/identity_removal_pass.h @@ -17,6 +17,8 @@ #ifndef XLS_PASSES_IDENTITY_REMOVAL_PASS_H_ #define XLS_PASSES_IDENTITY_REMOVAL_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -112,6 +114,12 @@ class IdentityRemovalPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Identity Removal") {} ~IdentityRemovalPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Iterate all nodes and eliminate identities. absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/inlining_pass.cc b/xls/passes/inlining_pass.cc index f9fb4cf476..3e63b97eb8 100644 --- a/xls/passes/inlining_pass.cc +++ b/xls/passes/inlining_pass.cc @@ -255,6 +255,12 @@ std::vector GetFunctionsToInlineByLeaf(Package* p, } // namespace +std::optional InliningPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(ConfiguredName(depth_)); +} + absl::Status InliningPass::InlineOneInvoke(Invoke* invoke) { OptimizationContext context; return InlineInvoke(invoke, context, diff --git a/xls/passes/inlining_pass.h b/xls/passes/inlining_pass.h index 0bdb6b0723..6edc078d30 100644 --- a/xls/passes/inlining_pass.h +++ b/xls/passes/inlining_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_INLINING_PASS_H_ #define XLS_PASSES_INLINING_PASS_H_ +#include +#include #include #include "absl/status/status.h" @@ -175,6 +177,10 @@ class InliningPass : public OptimizationPass { : OptimizationPass(ConfiguredName(depth), "Inlines invocations"), depth_(depth) {} + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + // Inline a single invoke instruction. Provided for test and utility // (ir_minimizer) use. // Because this is only for ir-minimizer use it allows the inlined function to diff --git a/xls/passes/label_recovery_pass.cc b/xls/passes/label_recovery_pass.cc index 3670571e9b..fd99996041 100644 --- a/xls/passes/label_recovery_pass.cc +++ b/xls/passes/label_recovery_pass.cc @@ -89,6 +89,12 @@ absl::StatusOr RecoverLabels(FunctionBase* f) { } // namespace +std::optional LabelRecoveryPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr LabelRecoveryPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/label_recovery_pass.h b/xls/passes/label_recovery_pass.h index a6468858fd..746d500ec2 100644 --- a/xls/passes/label_recovery_pass.h +++ b/xls/passes/label_recovery_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_LABEL_RECOVERY_PASS_H_ #define XLS_PASSES_LABEL_RECOVERY_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -151,6 +153,10 @@ class LabelRecoveryPass : public OptimizationFunctionBasePass { LabelRecoveryPass() : OptimizationFunctionBasePass(kName, "LabelRecovery") {} ~LabelRecoveryPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/lut_conversion_pass.cc b/xls/passes/lut_conversion_pass.cc index a68ab4a7d2..62219e3da8 100644 --- a/xls/passes/lut_conversion_pass.cc +++ b/xls/passes/lut_conversion_pass.cc @@ -352,6 +352,12 @@ absl::StatusOr SimplifyNode( } // namespace +std::optional LutConversionPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr LutConversionPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/lut_conversion_pass.h b/xls/passes/lut_conversion_pass.h index 13979b92ed..ff9293452f 100644 --- a/xls/passes/lut_conversion_pass.h +++ b/xls/passes/lut_conversion_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_LUT_CONVERSION_PASS_H_ #define XLS_PASSES_LUT_CONVERSION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -162,6 +164,10 @@ class LutConversionPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "LUT Conversion") {} ~LutConversionPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/map_inlining_pass.cc b/xls/passes/map_inlining_pass.cc index c1fdc64d52..0b14b615ac 100644 --- a/xls/passes/map_inlining_pass.cc +++ b/xls/passes/map_inlining_pass.cc @@ -14,6 +14,8 @@ #include "xls/passes/map_inlining_pass.h" +#include +#include #include #include "absl/status/status.h" @@ -33,6 +35,12 @@ MapInliningPass::MapInliningPass() : OptimizationFunctionBasePass(MapInliningPass::kName, "Inline map operations") {} +std::optional MapInliningPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr MapInliningPass::RunOnFunctionBaseInternal( FunctionBase* function, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/map_inlining_pass.h b/xls/passes/map_inlining_pass.h index c54eff4edb..b4c112f07d 100644 --- a/xls/passes/map_inlining_pass.h +++ b/xls/passes/map_inlining_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_MAP_INLINING_PASS_H_ #define XLS_PASSES_MAP_INLINING_PASS_H_ +#include +#include #include #include "absl/status/status.h" @@ -109,6 +111,10 @@ class MapInliningPass : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "map_inlining"; MapInliningPass(); + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + // Inline a single Map instruction. Provided for test and utility // (ir_minimizer) use. static absl::Status InlineOneMap(Map* map); diff --git a/xls/passes/narrowing_pass.cc b/xls/passes/narrowing_pass.cc index 45db1da180..3812a487cc 100644 --- a/xls/passes/narrowing_pass.cc +++ b/xls/passes/narrowing_pass.cc @@ -2252,6 +2252,19 @@ absl::StatusOr GetQueryEngine( } // namespace +std::optional NarrowingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + if (options.convert_array_index_to_select.has_value() && + options.convert_array_index_to_select.value() > 0) { + return absl::StrFormat("%s(%v,O%d,small_index=%d)", short_name(), + RealAnalysis(options), options.opt_level, + options.convert_array_index_to_select.value()); + } + return absl::StrFormat("%s(%v,O%d)", short_name(), RealAnalysis(options), + options.opt_level); +} + absl::StatusOr NarrowingPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/narrowing_pass.h b/xls/passes/narrowing_pass.h index f9c4e4660f..be234c3850 100644 --- a/xls/passes/narrowing_pass.h +++ b/xls/passes/narrowing_pass.h @@ -16,7 +16,9 @@ #define XLS_PASSES_NARROWING_PASS_H_ #include +#include #include +#include #include #include "absl/status/statusor.h" @@ -195,12 +197,34 @@ class NarrowingPass : public OptimizationFunctionBasePass { // Use the select context controlled by the optimization options. kRangeWithOptionalContext, }; + template + void AbslStringify(Sink& sink, AnalysisType e) { + switch (e) { + case AnalysisType::kTernary: + sink.Append("Ternary"); + break; + case AnalysisType::kRange: + sink.Append("Range"); + break; + case AnalysisType::kRangeWithContext: + sink.Append("Context"); + break; + case AnalysisType::kRangeWithOptionalContext: + sink.Append("OptionalContext"); + break; + } + } + static constexpr std::string_view kName = "narrow"; explicit NarrowingPass(AnalysisType analysis = AnalysisType::kRange) : OptimizationFunctionBasePass(ConfiguredName(analysis), "Narrowing"), analysis_(analysis) {} ~NarrowingPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: AnalysisType analysis_; diff --git a/xls/passes/next_value_optimization_pass.cc b/xls/passes/next_value_optimization_pass.cc index 49e7ef078b..92b79a915d 100644 --- a/xls/passes/next_value_optimization_pass.cc +++ b/xls/passes/next_value_optimization_pass.cc @@ -323,6 +323,19 @@ struct StateElementPair { } // namespace +std::optional NextValueOptimizationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + if (options.split_next_value_selects.has_value() && + *options.split_next_value_selects > 0) { + return absl::StrFormat("%s(O%d,max_depth=%d,split_selects=%d)", + short_name(), options.opt_level, max_split_depth_, + *options.split_next_value_selects); + } + return absl::StrFormat("%s(O%d,max_depth=%d)", short_name(), + options.opt_level, max_split_depth_); +} + absl::StatusOr NextValueOptimizationPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/next_value_optimization_pass.h b/xls/passes/next_value_optimization_pass.h index b3170e1191..cad01a4397 100644 --- a/xls/passes/next_value_optimization_pass.h +++ b/xls/passes/next_value_optimization_pass.h @@ -16,6 +16,8 @@ #define XLS_PASSES_NEXT_VALUE_OPTIMIZATION_PASS_H_ #include +#include +#include #include #include "absl/status/statusor.h" @@ -96,6 +98,10 @@ class NextValueOptimizationPass : public OptimizationProcPass { max_split_depth_(max_split_depth) {} ~NextValueOptimizationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: const int64_t max_split_depth_; absl::StatusOr RunOnProcInternal( diff --git a/xls/passes/non_synth_separation_pass.cc b/xls/passes/non_synth_separation_pass.cc index c9b0523a41..bd4db37860 100644 --- a/xls/passes/non_synth_separation_pass.cc +++ b/xls/passes/non_synth_separation_pass.cc @@ -354,6 +354,12 @@ bool IsNonSynthNode(Node* node) { } // namespace +std::optional NonSynthSeparationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr NonSynthSeparationPass::RunInternal( Package* p, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/non_synth_separation_pass.h b/xls/passes/non_synth_separation_pass.h index bc517d116e..297ace373c 100644 --- a/xls/passes/non_synth_separation_pass.h +++ b/xls/passes/non_synth_separation_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_NON_SYNTH_SEPARATION_PASS_H_ #define XLS_PASSES_NON_SYNTH_SEPARATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -163,6 +165,10 @@ class NonSynthSeparationPass : public OptimizationPass { : OptimizationPass(kName, "Non-Synthesizable Separation") {} ~NonSynthSeparationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunInternal(Package* p, const OptimizationPassOptions& options, diff --git a/xls/passes/optimization_pass.h b/xls/passes/optimization_pass.h index be2c117e24..fffb1f732a 100644 --- a/xls/passes/optimization_pass.h +++ b/xls/passes/optimization_pass.h @@ -38,6 +38,7 @@ #include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_format.h" #include "absl/types/span.h" #include "xls/common/status/ret_check.h" #include "xls/common/status/status_macros.h" @@ -552,6 +553,13 @@ class DynamicCapOptLevel : public FilterOptimizationPass { return res; } + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override { + return this->inner_pass()->GetInvocationSignature( + options.WithOptLevel(std::min(level_, options.opt_level)), context); + } + // Override name functions for better logging to include the capped level std::string short_name() const override { return absl::StrCat(FilterOptimizationPass::short_name(), @@ -587,7 +595,12 @@ class DynamicIfOptLevelAtLeast : public FilterOptimizationPass { template explicit DynamicIfOptLevelAtLeast(int64_t level, Args... args) : FilterOptimizationPass(std::forward(args)...), - level_(level) {} + level_(level) { + this->short_name_ = absl::StrFormat( + "%s(opt_level>=%d)", this->inner_pass()->short_name(), level); + this->long_name_ = absl::StrFormat("%s when opt_level >= %d", + this->inner_pass()->long_name(), level); + } absl::StatusOr ToProto() const override { XLS_ASSIGN_OR_RETURN( @@ -682,7 +695,12 @@ class IfResourceSharingEnabled template explicit IfResourceSharingEnabled(Args... args) : internal::FilterOptimizationPass( - std::forward(args)...) {} + std::forward(args)...) { + this->short_name_ = absl::StrFormat("%s(enable_resource_sharing)", + this->inner_pass()->short_name()); + this->long_name_ = absl::StrFormat("%s when resource sharing is enabled", + this->inner_pass()->long_name()); + } absl::StatusOr ToProto() const override { XLS_ASSIGN_OR_RETURN( diff --git a/xls/passes/pass_base.h b/xls/passes/pass_base.h index acbc167509..6c413704f9 100644 --- a/xls/passes/pass_base.h +++ b/xls/passes/pass_base.h @@ -26,7 +26,7 @@ #include #include -#include "absl/log/check.h" +#include "absl/container/flat_hash_set.h" #include "absl/log/log.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -189,6 +189,10 @@ class PassResults { int64_t total_invocations() const { return total_invocations_; } int64_t finished_invocations() const { return finished_invocations_; } + // Set of invocation signatures for passes that have been run and are known + // to not change the IR since the last time the IR was changed. + absl::flat_hash_set known_unchanged_passes; + private: // This vector contains and entry for each invocation of each pass. std::unique_ptr root_invocation_; @@ -353,6 +357,31 @@ class PassBase { return false; } + std::optional invocation_signature = + GetInvocationSignature(options, context...); + // If debugging, we verify that the pass really doesn't change anything if + // we think it's known-unchanged. Otherwise, we can skip it. +#ifndef DEBUG + if (invocation_signature.has_value() && + results->known_unchanged_passes.contains(*invocation_signature)) { + VLOG(1) << "Skipping known-unchanged pass: " << short_name(); + + // Record the no-op invocation so that we can still track pass numbers + // and such as if the pass had actually run. + PassInvocation& invocation = results->PushInvocation(base_short_name); + RecordPassEntry(base_short_name); + RecordPassAnnotation(pass_profile::kNodeCountBefore, ir->GetNodeCount()); + invocation.metrics() = ir->transform_metrics(); + invocation.run_duration() = absl::ZeroDuration(); + invocation.set_ir_changed(false); + RecordPassAnnotation(pass_profile::kNodeCountAfter, ir->GetNodeCount()); + ExitPass(false); + results->PopInvocation(); + + return false; + } +#endif + ScopedPassInvocation invocation(results, base_short_name, ir); VLOG(2) << absl::StreamFormat("Running %s [pass #%d]", long_name(), invocation->pass_number()); @@ -423,12 +452,58 @@ class PassBase { } } #endif + +#ifdef DEBUG + if (invocation_signature.has_value() && + results->known_unchanged_passes.contains(*invocation_signature) && + changed) { + return absl::InternalError( + absl::StrFormat("Pass %s appeared redundant, but IR is " + "changed:\n\n[Before]\n%s !=\n[after]\n%s", + short_name(), ir_before, ir_after)); + } +#endif + + if (invocation_signature.has_value()) { + if (invocation.changed()) { + // This pass changed the IR, so we clear the known unchanged passes. + results->known_unchanged_passes.clear(); + if (IsIdempotent()) { + // If the pass is idempotent, we can mark it as known unchanged + // for next time, since running it twice in a row is the same as + // running it once. + results->known_unchanged_passes.insert( + *std::move(invocation_signature)); + } + } else { + // This pass did not change the IR, so it will have no effect until the + // IR changes. + results->known_unchanged_passes.insert( + *std::move(invocation_signature)); + } + } else if (invocation.changed()) { + results->known_unchanged_passes.clear(); + } + return invocation.changed(); } // Returns true if this is a compound pass. virtual bool IsCompound() const { return false; } + // Returns true if this pass is idempotent (i.e., if it is run twice in a + // row without the IR changing in between, the second run will not change the + // IR). + virtual bool IsIdempotent() const { return false; } + + // Returns a signature of the pass invocation, including any options that + // might affect its behavior (like opt_level). If a pass does not have a + // signature, it cannot be skipped even if it is idempotent. + virtual std::optional GetInvocationSignature( + const OptionsT& options, ContextT&... context) const { + return std::nullopt; + } + // Adds an invariant checker to the pass. The invariant checker is // run after the pass if it changed anything. For compound passes they are // also run before anything is run. Arguments to method are the arguments to @@ -605,6 +680,21 @@ class CompoundPassBase : public PassBase { bool IsCompound() const override { return true; } + std::optional GetInvocationSignature( + const OptionsT& options, ContextT&... context) const override { + std::string signature = absl::StrCat(this->short_name(), "["); + for (const auto& pass : passes_) { + std::optional child_sig = + pass->GetInvocationSignature(options, context...); + if (!child_sig.has_value()) { + return std::nullopt; + } + absl::StrAppend(&signature, *child_sig, ","); + } + absl::StrAppend(&signature, "]"); + return signature; + } + protected: // Internal implementation of Run for compound passes. Invoked when a compound // pass is nested within another compound pass. Enables passing of invariant @@ -640,6 +730,8 @@ class FixedPointCompoundPassBase return res; } + bool IsIdempotent() const override { return true; } + absl::StatusOr RunNested(Package* ir, const OptionsT& options, PassResults* results, ContextT&... context) const final { diff --git a/xls/passes/pass_base_test.cc b/xls/passes/pass_base_test.cc index 82af28b7d6..d13a6c957b 100644 --- a/xls/passes/pass_base_test.cc +++ b/xls/passes/pass_base_test.cc @@ -23,12 +23,16 @@ #include #include +#include "google/protobuf/duration.pb.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "absl/status/status.h" #include "absl/status/status_matchers.h" #include "absl/status/statusor.h" +#include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/time/clock.h" +#include "absl/time/time.h" #include "absl/types/span.h" #include "xls/common/file/filesystem.h" #include "xls/common/file/temp_directory.h" @@ -61,7 +65,10 @@ using ::absl_testing::IsOkAndHolds; using ::testing::ElementsAre; using ::testing::Eq; using ::testing::Field; +using ::testing::Ge; using ::testing::IsEmpty; +using ::testing::Not; +using ::testing::SizeIs; using ::testing::UnorderedElementsAre; class PassBaseTest : public IrTestBase {}; @@ -847,5 +854,125 @@ TEST_F(PassBaseTest, MetricsTest) { )pb"))); } +class MutatingIdempotentPass : public OptimizationFunctionBasePass { + public: + explicit MutatingIdempotentPass(int64_t nodes_to_add) + : OptimizationFunctionBasePass("mutating_idempotent", + "Mutating Idempotent Pass"), + nodes_to_add_(nodes_to_add) {} + ~MutatingIdempotentPass() override = default; + + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override { + return absl::StrCat(short_name(), "(", nodes_to_add_, ")"); + } + + protected: + absl::StatusOr RunOnFunctionBaseInternal( + FunctionBase* f, const OptimizationPassOptions& options, + PassResults* results, OptimizationContext& context) const override { + bool changed = false; + for (int64_t i = 0; i < nodes_to_add_; ++i) { + std::string node_name = absl::StrCat("added_node_", i); + if (f->HasNode(node_name)) { + continue; + } + XLS_RETURN_IF_ERROR(f->MakeNodeWithName( + SourceInfo(), Value(UBits(0, 32)), node_name) + .status()); + changed = true; + } + absl::SleepFor(absl::Milliseconds(1)); + return changed; + } + + int64_t nodes_to_add_; +}; + +TEST_F(PassBaseTest, IdempotentPassTracking) { + auto p = CreatePackage(); + FunctionBuilder fb(TestName(), p.get()); + fb.Literal(UBits(0, 64)); + XLS_ASSERT_OK(fb.Build()); + + OptimizationCompoundPass opt("opt", "opt"); + opt.Add(/*nodes_to_add=*/1); + opt.Add(/*nodes_to_add=*/1); + opt.Add(/*nodes_to_add=*/1); + opt.Add(/*nodes_to_add=*/1); + opt.Add(/*nodes_to_add=*/1); + opt.Add(/*nodes_to_add=*/0); + opt.Add(/*nodes_to_add=*/2); + + PassResults results; + OptimizationContext context; + OptimizationPassOptions options; + EXPECT_THAT(opt.Run(p.get(), options, &results, context), IsOkAndHolds(true)); + + PassPipelineMetricsProto metrics_proto = results.ToProto(); + EXPECT_THAT(metrics_proto, + proto_testing::Partially(proto_testing::EqualsProto(R"pb( + total_passes: 8 + pass_metrics { + pass_name: "opt" + changed: 1 + pass_numbers: 0 + nested_results { + pass_name: "mutating_idempotent" + changed: 1 + pass_numbers: 1 + } + nested_results { + pass_name: "mutating_idempotent" + changed: 0 + duration { seconds: 0 nanos: 0 } # Skipped + pass_numbers: 2 + } + nested_results { + pass_name: "node_adder_1" + changed: 1 + pass_numbers: 3 + } + nested_results { + pass_name: "mutating_idempotent" + changed: 0 + pass_numbers: 4 + } + nested_results { + pass_name: "mutating_idempotent" + changed: 0 + duration { seconds: 0 nanos: 0 } # Skipped + pass_numbers: 5 + } + nested_results { + pass_name: "mutating_idempotent" + changed: 0 # This version hasn't run, so we don't skip it - + # but it won't mutate the IR. + pass_numbers: 6 + } + nested_results { + pass_name: "mutating_idempotent" + changed: 1 # This version will actually mutate the IR. + pass_numbers: 7 + } + } + )pb"))); + // Make sure that passes #3 and #6 actually ran, even though they didn't + // change anything. + ASSERT_THAT(metrics_proto.pass_metrics().nested_results(), SizeIs(Ge(3))); + EXPECT_THAT(metrics_proto.pass_metrics().nested_results(2).duration(), + Not(proto_testing::EqualsProto(R"pb( + seconds: 0 nanos: 0 + )pb"))); + ASSERT_THAT(metrics_proto.pass_metrics().nested_results(), SizeIs(Ge(6))); + EXPECT_THAT(metrics_proto.pass_metrics().nested_results(5).duration(), + Not(proto_testing::EqualsProto(R"pb( + seconds: 0 nanos: 0 + )pb"))); +} + } // namespace } // namespace xls diff --git a/xls/passes/proc_state_array_flattening_pass.cc b/xls/passes/proc_state_array_flattening_pass.cc index 8653815b79..1fd931d3cf 100644 --- a/xls/passes/proc_state_array_flattening_pass.cc +++ b/xls/passes/proc_state_array_flattening_pass.cc @@ -15,6 +15,8 @@ #include "xls/passes/proc_state_array_flattening_pass.h" #include +#include +#include #include #include "absl/log/log.h" @@ -147,6 +149,12 @@ absl::StatusOr SimplifyProcState(Proc* proc, } // namespace +std::optional ProcStateArrayFlatteningPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ProcStateArrayFlatteningPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/proc_state_array_flattening_pass.h b/xls/passes/proc_state_array_flattening_pass.h index 0392ead6b4..3a08c1b7db 100644 --- a/xls/passes/proc_state_array_flattening_pass.h +++ b/xls/passes/proc_state_array_flattening_pass.h @@ -16,6 +16,8 @@ #define XLS_PASSES_PROC_STATE_ARRAY_FLATTENING_PASS_H_ #include +#include +#include #include #include "absl/status/statusor.h" @@ -157,6 +159,10 @@ class ProcStateArrayFlatteningPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Array Flattening") {} ~ProcStateArrayFlatteningPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/proc_state_bits_shattering_pass.cc b/xls/passes/proc_state_bits_shattering_pass.cc index c7ce1e94cb..188d03e5e2 100644 --- a/xls/passes/proc_state_bits_shattering_pass.cc +++ b/xls/passes/proc_state_bits_shattering_pass.cc @@ -18,12 +18,14 @@ #include #include #include +#include #include #include #include "absl/algorithm/container.h" #include "absl/log/check.h" #include "absl/status/statusor.h" +#include "absl/strings/str_format.h" #include "absl/types/span.h" #include "cppitertools/reversed.hpp" #include "xls/common/status/status_macros.h" @@ -201,6 +203,13 @@ absl::StatusOr MaybeSplitStateElements( } // namespace +std::optional ProcStateBitsShatteringPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(split_selects=%d)", short_name(), + options.split_next_value_selects.value_or(0)); +} + absl::StatusOr ProcStateBitsShatteringPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/proc_state_bits_shattering_pass.h b/xls/passes/proc_state_bits_shattering_pass.h index 5d0a0ba176..e9cae85550 100644 --- a/xls/passes/proc_state_bits_shattering_pass.h +++ b/xls/passes/proc_state_bits_shattering_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_PROC_STATE_BITS_SHATTERING_PASS_H_ #define XLS_PASSES_PROC_STATE_BITS_SHATTERING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -148,6 +150,10 @@ class ProcStateBitsShatteringPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Bits Shattering") {} ~ProcStateBitsShatteringPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/proc_state_narrowing_pass.cc b/xls/passes/proc_state_narrowing_pass.cc index 879708fe2a..2897921edd 100644 --- a/xls/passes/proc_state_narrowing_pass.cc +++ b/xls/passes/proc_state_narrowing_pass.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -138,6 +139,12 @@ absl::Status RemoveSignBits(StateRead* state_read, const Value& orig_init_value, } // namespace +std::optional ProcStateNarrowingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + // TODO(allight): Technically we'd probably want to run this whole pass to fixed // point (incorporating the results into later runs) to get optimal results. // It's not clear how much we'd gain there though. For now we will just run it diff --git a/xls/passes/proc_state_narrowing_pass.h b/xls/passes/proc_state_narrowing_pass.h index d4081a200a..bf29ffc01e 100644 --- a/xls/passes/proc_state_narrowing_pass.h +++ b/xls/passes/proc_state_narrowing_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_PROC_STATE_NARROWING_PASS_H_ #define XLS_PASSES_PROC_STATE_NARROWING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -127,6 +129,10 @@ class ProcStateNarrowingPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Narrowing") {} ~ProcStateNarrowingPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/proc_state_optimization_pass.cc b/xls/passes/proc_state_optimization_pass.cc index 0f729f4274..d03d328cb9 100644 --- a/xls/passes/proc_state_optimization_pass.cc +++ b/xls/passes/proc_state_optimization_pass.cc @@ -504,6 +504,12 @@ absl::StatusOr ConvertConstantChainsToStateMachines( } // namespace +std::optional ProcStateOptimizationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ProcStateOptimizationPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/proc_state_optimization_pass.h b/xls/passes/proc_state_optimization_pass.h index 65582c8f86..d9a5061d87 100644 --- a/xls/passes/proc_state_optimization_pass.h +++ b/xls/passes/proc_state_optimization_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_PROC_STATE_OPTIMIZATION_PASS_H_ #define XLS_PASSES_PROC_STATE_OPTIMIZATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -191,6 +193,10 @@ class ProcStateOptimizationPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Optimization") {} ~ProcStateOptimizationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/proc_state_provenance_narrowing_pass.cc b/xls/passes/proc_state_provenance_narrowing_pass.cc index 2c7effb739..b1c4caba5a 100644 --- a/xls/passes/proc_state_provenance_narrowing_pass.cc +++ b/xls/passes/proc_state_provenance_narrowing_pass.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -248,6 +249,13 @@ absl::StatusOr UnchangedBits(Proc* proc, StateElement* state_element, } // namespace +std::optional +ProcStateProvenanceNarrowingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ProcStateProvenanceNarrowingPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/proc_state_provenance_narrowing_pass.h b/xls/passes/proc_state_provenance_narrowing_pass.h index e7e4b05271..0fbe0ce40f 100644 --- a/xls/passes/proc_state_provenance_narrowing_pass.h +++ b/xls/passes/proc_state_provenance_narrowing_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_PROC_STATE_PROVENANCE_NARROWING_PASS_H_ #define XLS_PASSES_PROC_STATE_PROVENANCE_NARROWING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -175,6 +177,10 @@ class ProcStateProvenanceNarrowingPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Provenance Narrowing") {} ~ProcStateProvenanceNarrowingPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/proc_state_tuple_flattening_pass.cc b/xls/passes/proc_state_tuple_flattening_pass.cc index ae81be2b8d..8fe3704ba7 100644 --- a/xls/passes/proc_state_tuple_flattening_pass.cc +++ b/xls/passes/proc_state_tuple_flattening_pass.cc @@ -319,6 +319,12 @@ absl::Status FlattenState(Proc* proc) { } // namespace +std::optional ProcStateTupleFlatteningPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ProcStateTupleFlatteningPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/proc_state_tuple_flattening_pass.h b/xls/passes/proc_state_tuple_flattening_pass.h index d3184f6696..deaf4b099d 100644 --- a/xls/passes/proc_state_tuple_flattening_pass.h +++ b/xls/passes/proc_state_tuple_flattening_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_PROC_STATE_TUPLE_FLATTENING_PASS_H_ #define XLS_PASSES_PROC_STATE_TUPLE_FLATTENING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -37,6 +39,10 @@ class ProcStateTupleFlatteningPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Proc State Tuple Flattening") {} ~ProcStateTupleFlatteningPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/ram_rewrite_pass.cc b/xls/passes/ram_rewrite_pass.cc index 205cecdd33..a97eb31daa 100644 --- a/xls/passes/ram_rewrite_pass.cc +++ b/xls/passes/ram_rewrite_pass.cc @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -30,6 +31,7 @@ #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" #include "absl/strings/str_format.h" +#include "absl/strings/str_join.h" #include "absl/types/span.h" #include "xls/common/status/ret_check.h" #include "xls/common/status/status_macros.h" @@ -960,6 +962,28 @@ Type* GetMaskType(Package* package, std::optional mask_width) { return package->GetTupleType({}); } +std::optional RamRewritePass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + std::vector rewrite_strs; + rewrite_strs.reserve(options.ram_rewrites.size()); + for (const RamRewrite& rw : options.ram_rewrites) { + std::string channel_remap = + absl::StrJoin(rw.from_channels_logical_to_physical, ",", + [](std::string* out, const auto& pair) { + absl::StrAppend(out, pair.first, ":", pair.second); + }); + if (rw.proc_name.has_value()) { + rewrite_strs.push_back( + absl::StrCat("[proc=", *rw.proc_name, ",", channel_remap, "]")); + } else { + rewrite_strs.push_back(absl::StrCat("[", channel_remap, "]")); + } + } + return absl::StrFormat("%s(%s)", short_name(), + absl::StrJoin(rewrite_strs, ",")); +} + absl::StatusOr RamRewritePass::RunInternal( Package* p, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/ram_rewrite_pass.h b/xls/passes/ram_rewrite_pass.h index fa688b5f5c..3fc6275682 100644 --- a/xls/passes/ram_rewrite_pass.h +++ b/xls/passes/ram_rewrite_pass.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "absl/status/statusor.h" @@ -153,6 +154,12 @@ class RamRewritePass : public OptimizationPass { ~RamRewritePass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunInternal(Package* p, const OptimizationPassOptions& options, diff --git a/xls/passes/reassociation_pass.cc b/xls/passes/reassociation_pass.cc index 1186d174ee..90b03ecf3c 100644 --- a/xls/passes/reassociation_pass.cc +++ b/xls/passes/reassociation_pass.cc @@ -1416,6 +1416,12 @@ class Reassociation { } // namespace +std::optional ReassociationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ReassociationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/reassociation_pass.h b/xls/passes/reassociation_pass.h index 78fafcafa5..a8bc4aa78a 100644 --- a/xls/passes/reassociation_pass.h +++ b/xls/passes/reassociation_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_REASSOCIATION_PASS_H_ #define XLS_PASSES_REASSOCIATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -184,6 +186,10 @@ class ReassociationPass : public OptimizationFunctionBasePass { ReassociationPass() : OptimizationFunctionBasePass(kName, "Reassociation") {} ~ReassociationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/receive_default_value_simplification_pass.cc b/xls/passes/receive_default_value_simplification_pass.cc index 1441f179ac..571d288319 100644 --- a/xls/passes/receive_default_value_simplification_pass.cc +++ b/xls/passes/receive_default_value_simplification_pass.cc @@ -15,6 +15,7 @@ #include "xls/passes/receive_default_value_simplification_pass.h" #include +#include #include "absl/status/statusor.h" #include "xls/common/status/status_macros.h" @@ -128,6 +129,13 @@ std::optional MatchUselessSelectAfterReceive( } // namespace +std::optional +ReceiveDefaultValueSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr ReceiveDefaultValueSimplificationPass::RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/receive_default_value_simplification_pass.h b/xls/passes/receive_default_value_simplification_pass.h index 868a6f6c3f..fdeab66185 100644 --- a/xls/passes/receive_default_value_simplification_pass.h +++ b/xls/passes/receive_default_value_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_RECEIVE_DEFAULT_VALUE_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_RECEIVE_DEFAULT_VALUE_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -117,6 +119,10 @@ class ReceiveDefaultValueSimplificationPass : public OptimizationProcPass { : OptimizationProcPass(kName, "Receive default value simplification") {} ~ReceiveDefaultValueSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnProcInternal( Proc* proc, const OptimizationPassOptions& options, PassResults* results, diff --git a/xls/passes/resource_sharing_pass.cc b/xls/passes/resource_sharing_pass.cc index dfdf2f89d9..00e8e5cd09 100644 --- a/xls/passes/resource_sharing_pass.cc +++ b/xls/passes/resource_sharing_pass.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,7 @@ #include "absl/random/random.h" #include "absl/status/status.h" #include "absl/status/statusor.h" +#include "absl/strings/str_format.h" #include "absl/types/span.h" #include "cppitertools/combinations.hpp" #include "cppitertools/zip.hpp" @@ -1958,6 +1960,16 @@ absl::StatusOr ResourceSharingPass::PerformFoldingActions( return modified; } +std::optional ResourceSharingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + if (!options.enable_resource_sharing) { + return absl::StrFormat("%s(disabled)", short_name()); + } + return absl::StrFormat("%s(%v,%v)", short_name(), + RealProfitabilityGuard(options), config_); +} + // This function computes the resource sharing optimization for multiplication // instructions. In more detail, this function folds a multiplication // instruction into another multiplication instruction that has the same @@ -2052,8 +2064,7 @@ absl::StatusOr ResourceSharingPass::RunOnFunctionBaseInternal( // Select the folding actions to perform ResourceSharingPass::ProfitabilityGuard selection_heuristic = - options.force_resource_sharing ? ProfitabilityGuard::kAlways - : profitability_guard_; + RealProfitabilityGuard(options); XLS_ASSIGN_OR_RETURN( std::vector> folding_actions_to_perform, diff --git a/xls/passes/resource_sharing_pass.h b/xls/passes/resource_sharing_pass.h index 2f83eeae45..ce31276a04 100644 --- a/xls/passes/resource_sharing_pass.h +++ b/xls/passes/resource_sharing_pass.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -32,6 +33,7 @@ #include "xls/ir/node.h" #include "xls/ir/node_util.h" #include "xls/passes/folding_graph.h" +#include "xls/passes/node_dependency_analysis.h" #include "xls/passes/optimization_pass.h" #include "xls/passes/pass_base.h" #include "xls/passes/visibility_analysis.h" @@ -183,6 +185,22 @@ class ResourceSharingPass : public OptimizationFunctionBasePass { const int64_t max_path_count_for_edge_in_general_visibility_analysis; const int64_t max_path_count_for_bdd_engine; }; + template + friend void AbslStringify(Sink& sink, const Config& config) { + absl::Format(&sink, + "min_area_savings=%f," + "max_delay_spread_squared=%f," + "max_delay_increase=%d," + "max_delay_increase_per_fold=%d," + "max_edges_to_handle=%d," + "max_path_count_for_general_visibility_analysis=%d," + "max_path_count_for_bdd_engine=%d", + config.min_area_savings, config.max_delay_spread_squared, + config.max_delay_increase, config.max_delay_increase_per_fold, + config.max_edges_to_handle, + config.max_path_count_for_edge_in_general_visibility_analysis, + config.max_path_count_for_bdd_engine); + } // TODO: area vs. delay trade-off heuristics in resource sharing should be // queried from area/delay models instead of being hard-coded on this pass. @@ -242,6 +260,23 @@ class ResourceSharingPass : public OptimizationFunctionBasePass { kAlways, // This heuristic applies resource sharing whenever possible. This // is used for testing only. }; + template + void AbslStringify(Sink& sink, ProfitabilityGuard e) { + switch (e) { + case ProfitabilityGuard::kInDegree: + sink.Append("inDegree"); + break; + case ProfitabilityGuard::kCliques: + sink.Append("cliques"); + break; + case ProfitabilityGuard::kRandom: + sink.Append("random"); + break; + case ProfitabilityGuard::kAlways: + sink.Append("always"); + break; + } + } // This function computes the set of mutual exclusive pairs of instructions. // Each pair of instruction is associated with the select (of any kind) that @@ -347,12 +382,24 @@ class ResourceSharingPass : public OptimizationFunctionBasePass { ResourceSharingPass::kDefaultMaxPathCountForBddEngine, }; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const override; private: + ProfitabilityGuard RealProfitabilityGuard( + const OptimizationPassOptions& options) const { + if (options.force_resource_sharing) { + return ProfitabilityGuard::kAlways; + } + return profitability_guard_; + } + ProfitabilityGuard profitability_guard_; Config config_; }; diff --git a/xls/passes/select_lifting_pass.cc b/xls/passes/select_lifting_pass.cc index 863e24dff6..1d114e016d 100644 --- a/xls/passes/select_lifting_pass.cc +++ b/xls/passes/select_lifting_pass.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -28,6 +29,7 @@ #include "absl/status/status.h" #include "absl/status/statusor.h" #include "absl/strings/str_cat.h" +#include "absl/strings/str_format.h" #include "absl/types/span.h" #include "xls/common/status/ret_check.h" #include "xls/common/status/status_macros.h" @@ -1088,6 +1090,14 @@ absl::StatusOr LiftSelects( } // namespace +std::optional SelectLiftingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat( + "%s(O%d,%s)", short_name(), options.opt_level, + options.delay_estimator ? "estimated_delay" : "no_delay_estimation"); +} + absl::StatusOr SelectLiftingPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/select_lifting_pass.h b/xls/passes/select_lifting_pass.h index 293571b80d..c0d651a311 100644 --- a/xls/passes/select_lifting_pass.h +++ b/xls/passes/select_lifting_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_SELECT_LIFTING_PASS_H_ #define XLS_PASSES_SELECT_LIFTING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -156,6 +158,12 @@ class SelectLiftingPass : public OptimizationFunctionBasePass { ~SelectLiftingPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/select_merging_pass.cc b/xls/passes/select_merging_pass.cc index bf289f3a9b..2ca25cf0c7 100644 --- a/xls/passes/select_merging_pass.cc +++ b/xls/passes/select_merging_pass.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "absl/algorithm/container.h" @@ -252,6 +253,12 @@ absl::StatusOr MergeNode(Node* node) { return false; } +std::optional SelectMergingPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr SelectMergingPass::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/select_merging_pass.h b/xls/passes/select_merging_pass.h index ff6be26597..2b14e4db63 100644 --- a/xls/passes/select_merging_pass.h +++ b/xls/passes/select_merging_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_SELECT_MERGING_PASS_H_ #define XLS_PASSES_SELECT_MERGING_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -151,6 +153,10 @@ class SelectMergingPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Select Merging") {} ~SelectMergingPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/select_simplification_pass.cc b/xls/passes/select_simplification_pass.cc index 84f89d26a0..87b49a0a6d 100644 --- a/xls/passes/select_simplification_pass.cc +++ b/xls/passes/select_simplification_pass.cc @@ -2387,6 +2387,12 @@ absl::StatusOr SimplifyNode(Node* node, const QueryEngine& query_engine, } // namespace +std::optional SelectSimplificationPassBase::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr SelectSimplificationPassBase::RunOnFunctionBaseInternal( FunctionBase* func, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/select_simplification_pass.h b/xls/passes/select_simplification_pass.h index ac93b9c216..9344aa3249 100644 --- a/xls/passes/select_simplification_pass.h +++ b/xls/passes/select_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_SELECT_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_SELECT_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -189,6 +191,10 @@ class SelectSimplificationPassBase : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(short_name, name), range_analysis_(with_range_analysis) {} + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const override; diff --git a/xls/passes/sparsify_select_pass.cc b/xls/passes/sparsify_select_pass.cc index eac132e68b..f03ba6d073 100644 --- a/xls/passes/sparsify_select_pass.cc +++ b/xls/passes/sparsify_select_pass.cc @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "absl/status/status.h" @@ -37,10 +38,11 @@ #include "xls/passes/query_engine.h" namespace xls { +namespace { // Returns a vector of the intervals contained within the given `IntervalSet`, // sorted from smallest to largest in terms of number of points covered. -static std::vector IntervalsSortedBySize(IntervalSet set) { +std::vector IntervalsSortedBySize(IntervalSet set) { set.Normalize(); std::vector intervals(set.Intervals().begin(), set.Intervals().end()); @@ -65,8 +67,8 @@ static std::vector IntervalsSortedBySize(IntervalSet set) { // // TODO(taktoa): build a binary search tree based on interval lower bounds // rather than a linear chain. -static absl::Status SparsifySelect(FunctionBase* f, Select* select, - const IntervalSet& selector_intervals) { +absl::Status SparsifySelect(FunctionBase* f, Select* select, + const IntervalSet& selector_intervals) { // As we build up the select chain, this represents the rest of the chain, // i.e.: what we should use when the current select we are adding is false. Node* other = nullptr; @@ -150,6 +152,14 @@ static absl::Status SparsifySelect(FunctionBase* f, Select* select, return absl::OkStatus(); } +} // namespace + +std::optional SparsifySelectPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr SparsifySelectPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/sparsify_select_pass.h b/xls/passes/sparsify_select_pass.h index 4c09aac1e3..505079a8d0 100644 --- a/xls/passes/sparsify_select_pass.h +++ b/xls/passes/sparsify_select_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_SPARSIFY_SELECT_PASS_H_ #define XLS_PASSES_SPARSIFY_SELECT_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -145,6 +147,10 @@ class SparsifySelectPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Sparsify Select") {} ~SparsifySelectPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Sparsify selects using range analysis. absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/strength_reduction_pass.cc b/xls/passes/strength_reduction_pass.cc index 9623a8c577..f58f17e391 100644 --- a/xls/passes/strength_reduction_pass.cc +++ b/xls/passes/strength_reduction_pass.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -752,6 +753,12 @@ absl::StatusOr StrengthReduceNode(Node* node, } // namespace +std::optional StrengthReductionPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return absl::StrFormat("%s(O%d)", short_name(), options.opt_level); +} + absl::StatusOr StrengthReductionPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/strength_reduction_pass.h b/xls/passes/strength_reduction_pass.h index a7244bc3f2..fd59e08fc0 100644 --- a/xls/passes/strength_reduction_pass.h +++ b/xls/passes/strength_reduction_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_STRENGTH_REDUCTION_PASS_H_ #define XLS_PASSES_STRENGTH_REDUCTION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -167,6 +169,10 @@ class StrengthReductionPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Strength Reduction") {} ~StrengthReductionPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: // Run all registered passes in order of registration. absl::StatusOr RunOnFunctionBaseInternal( diff --git a/xls/passes/table_switch_pass.cc b/xls/passes/table_switch_pass.cc index 51d4fba8d7..da38c1abce 100644 --- a/xls/passes/table_switch_pass.cc +++ b/xls/passes/table_switch_pass.cc @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "absl/algorithm/container.h" @@ -413,6 +414,12 @@ absl::StatusOr> LinksToTable( } // namespace +std::optional TableSwitchPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr TableSwitchPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/table_switch_pass.h b/xls/passes/table_switch_pass.h index e60c1f0a29..f75f252592 100644 --- a/xls/passes/table_switch_pass.h +++ b/xls/passes/table_switch_pass.h @@ -14,6 +14,8 @@ #ifndef XLS_PASSES_TABLE_SWITCH_PASS_H_ #define XLS_PASSES_TABLE_SWITCH_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -148,6 +150,10 @@ class TableSwitchPass : public OptimizationFunctionBasePass { TableSwitchPass() : OptimizationFunctionBasePass(kName, "Table switch conversion") {} + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/token_dependency_pass.cc b/xls/passes/token_dependency_pass.cc index 168fe6c580..413dbfb628 100644 --- a/xls/passes/token_dependency_pass.cc +++ b/xls/passes/token_dependency_pass.cc @@ -14,6 +14,7 @@ #include "xls/passes/token_dependency_pass.h" +#include #include #include @@ -39,6 +40,12 @@ namespace xls { +std::optional TokenDependencyPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr TokenDependencyPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/token_dependency_pass.h b/xls/passes/token_dependency_pass.h index 4e71f77e49..11d17c7993 100644 --- a/xls/passes/token_dependency_pass.h +++ b/xls/passes/token_dependency_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_TOKEN_DEPENDENCY_PASS_H_ #define XLS_PASSES_TOKEN_DEPENDENCY_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -81,6 +83,12 @@ class TokenDependencyPass : public OptimizationFunctionBasePass { "dependencies") {} ~TokenDependencyPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/token_simplification_pass.cc b/xls/passes/token_simplification_pass.cc index c99431630d..70c929293a 100644 --- a/xls/passes/token_simplification_pass.cc +++ b/xls/passes/token_simplification_pass.cc @@ -18,6 +18,8 @@ #include #include #include +#include +#include #include #include "absl/algorithm/container.h" @@ -333,6 +335,12 @@ int64_t NumberOfTokensInType(Type* type) { } // namespace +std::optional TokenSimplificationPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr TokenSimplificationPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/token_simplification_pass.h b/xls/passes/token_simplification_pass.h index b60f189300..ef71d2171b 100644 --- a/xls/passes/token_simplification_pass.h +++ b/xls/passes/token_simplification_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_TOKEN_SIMPLIFICATION_PASS_H_ #define XLS_PASSES_TOKEN_SIMPLIFICATION_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -169,6 +171,10 @@ class TokenSimplificationPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass(kName, "Simplify token networks") {} ~TokenSimplificationPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/unroll_pass.cc b/xls/passes/unroll_pass.cc index 8835390f51..b2c1bfbf74 100644 --- a/xls/passes/unroll_pass.cc +++ b/xls/passes/unroll_pass.cc @@ -15,6 +15,8 @@ #include "xls/passes/unroll_pass.h" #include +#include +#include #include #include "absl/status/status.h" @@ -73,6 +75,12 @@ absl::Status UnrollCountedFor(CountedFor* loop) { } // namespace +std::optional UnrollPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr UnrollPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/unroll_pass.h b/xls/passes/unroll_pass.h index 2199fcd34f..052c5547a5 100644 --- a/xls/passes/unroll_pass.h +++ b/xls/passes/unroll_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_UNROLL_PASS_H_ #define XLS_PASSES_UNROLL_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -61,6 +63,12 @@ class UnrollPass : public OptimizationFunctionBasePass { static constexpr std::string_view kName = "loop_unroll"; UnrollPass() : OptimizationFunctionBasePass(kName, "Unroll counted loops") {} + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/useless_assert_removal_pass.cc b/xls/passes/useless_assert_removal_pass.cc index bbf1ae200d..676d7dbc2d 100644 --- a/xls/passes/useless_assert_removal_pass.cc +++ b/xls/passes/useless_assert_removal_pass.cc @@ -15,6 +15,7 @@ #include "xls/passes/useless_assert_removal_pass.h" #include +#include #include "absl/status/statusor.h" #include "xls/common/status/status_macros.h" @@ -28,6 +29,12 @@ namespace xls { +std::optional UselessAssertRemovalPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr UselessAssertRemovalPass::RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/useless_assert_removal_pass.h b/xls/passes/useless_assert_removal_pass.h index 16925d5a95..f71541e994 100644 --- a/xls/passes/useless_assert_removal_pass.h +++ b/xls/passes/useless_assert_removal_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_USELESS_ASSERT_REMOVAL_PASS_H_ #define XLS_PASSES_USELESS_ASSERT_REMOVAL_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -34,6 +36,12 @@ class UselessAssertRemovalPass : public OptimizationFunctionBasePass { "Remove useless (always true) asserts") {} ~UselessAssertRemovalPass() override = default; + bool IsIdempotent() const override { return true; } + + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options, diff --git a/xls/passes/useless_io_removal_pass.cc b/xls/passes/useless_io_removal_pass.cc index 82faf8ba8d..ec11c6114f 100644 --- a/xls/passes/useless_io_removal_pass.cc +++ b/xls/passes/useless_io_removal_pass.cc @@ -16,6 +16,7 @@ #include #include +#include #include #include "absl/container/flat_hash_map.h" @@ -68,6 +69,12 @@ absl::StatusOr ComputeChannelMaps(Package* package) { } // namespace +std::optional UselessIORemovalPass::GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const { + return std::string(short_name()); +} + absl::StatusOr UselessIORemovalPass::RunInternal( Package* p, const OptimizationPassOptions& options, PassResults* results, OptimizationContext& context) const { diff --git a/xls/passes/useless_io_removal_pass.h b/xls/passes/useless_io_removal_pass.h index d611d32e86..458d8dd000 100644 --- a/xls/passes/useless_io_removal_pass.h +++ b/xls/passes/useless_io_removal_pass.h @@ -15,6 +15,8 @@ #ifndef XLS_PASSES_USELESS_IO_REMOVAL_PASS_H_ #define XLS_PASSES_USELESS_IO_REMOVAL_PASS_H_ +#include +#include #include #include "absl/status/statusor.h" @@ -79,6 +81,10 @@ class UselessIORemovalPass : public OptimizationPass { : OptimizationPass(kName, "Remove useless send/receive") {} ~UselessIORemovalPass() override = default; + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override; + protected: absl::StatusOr RunInternal(Package* p, const OptimizationPassOptions& options, diff --git a/xls/solvers/z3_ir_equivalence.cc b/xls/solvers/z3_ir_equivalence.cc index b4c3182302..e4b0f8dd8e 100644 --- a/xls/solvers/z3_ir_equivalence.cc +++ b/xls/solvers/z3_ir_equivalence.cc @@ -138,6 +138,12 @@ class RemoveAssertsPass : public OptimizationFunctionBasePass { : OptimizationFunctionBasePass( "remove_asserts", "remove asserts for z3 equivalence checking") {} + std::optional GetInvocationSignature( + const OptimizationPassOptions& options, + OptimizationContext& context) const override { + return std::string(short_name()); + } + protected: absl::StatusOr RunOnFunctionBaseInternal( FunctionBase* f, const OptimizationPassOptions& options,