diff --git a/xls/passes/optimization_pass.h b/xls/passes/optimization_pass.h index 86c77d8121..99a784652b 100644 --- a/xls/passes/optimization_pass.h +++ b/xls/passes/optimization_pass.h @@ -394,9 +394,13 @@ class OptimizationContext { : target_(target), options_(nullptr) {} bool operator==(const ConstructorArguments& other) const { - return target_ == other.target_ && - ((options_ == nullptr && other.options_ == nullptr) || - *options_ == *other.options_); + if (target_ != other.target_) { + return false; + } + if (options_ == nullptr || other.options_ == nullptr) { + return options_ == nullptr && other.options_ == nullptr; + } + return *options_ == *other.options_; } bool operator!=(const ConstructorArguments& other) const { return !(*this == other); diff --git a/xls/passes/resource_sharing_pass.cc b/xls/passes/resource_sharing_pass.cc index 8c0ef805fd..5b76e94828 100644 --- a/xls/passes/resource_sharing_pass.cc +++ b/xls/passes/resource_sharing_pass.cc @@ -2009,6 +2009,49 @@ bool ResourceSharingPass::ShouldTargetNodeForMutualExclusion(Node* node) const { return true; } +// static +absl::StatusOr +ResourceSharingPass::VisibilityAnalyses::Create(FunctionBase* f, + const Config& config) { + auto nda = std::make_unique(); + XLS_RETURN_IF_ERROR(nda->Attach(f).status()); + + auto post_dom = std::make_unique(); + XLS_RETURN_IF_ERROR(post_dom->Attach(f).status()); + + auto bdd_engine = + std::make_unique(config.max_path_count_for_bdd_engine); + XLS_RETURN_IF_ERROR(bdd_engine->Populate(f).status()); + + XLS_ASSIGN_OR_RETURN( + auto op_visibility, + OperandVisibilityAnalysis::Create( + config.max_path_count_for_edge_in_general_visibility_analysis, + nda.get(), bdd_engine.get())); + auto op_visibility_ptr = + std::make_unique(std::move(op_visibility)); + + XLS_ASSIGN_OR_RETURN(auto visibility, VisibilityAnalysis::Create( + op_visibility_ptr.get(), + bdd_engine.get(), post_dom.get())); + + XLS_ASSIGN_OR_RETURN(auto op_vis_large, OperandVisibilityAnalysis::Create( + bdd_engine->path_limit(), + nda.get(), bdd_engine.get())); + auto op_vis_large_ptr = + std::make_unique(std::move(op_vis_large)); + + XLS_ASSIGN_OR_RETURN( + auto single_select_visibility, + SingleSelectVisibilityAnalysis::Create(op_vis_large_ptr.get(), nda.get(), + bdd_engine.get())); + + return VisibilityAnalyses(std::move(nda), std::move(post_dom), + std::move(bdd_engine), std::move(op_visibility_ptr), + std::move(visibility), std::move(op_vis_large_ptr), + std::move(single_select_visibility)); +} + // 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 @@ -2041,39 +2084,11 @@ absl::StatusOr ResourceSharingPass::RunOnFunctionBaseInternal( std::make_unique(options.delay_estimator); XLS_RETURN_IF_ERROR(critical_path_delay->Attach(f).status()); - NodeForwardDependencyAnalysis nda; NodeBackwardDependencyAnalysis nda_backwards; - XLS_RETURN_IF_ERROR(nda.Attach(f).status()); XLS_RETURN_IF_ERROR(nda_backwards.Attach(f).status()); - LazyPostDominatorAnalysis post_dom; - XLS_RETURN_IF_ERROR(post_dom.Attach(f).status()); - - // Run the BDD analysis - std::unique_ptr bdd_engine = - std::make_unique(config_.max_path_count_for_bdd_engine); - XLS_RETURN_IF_ERROR(bdd_engine->Populate(f).status()); - - XLS_ASSIGN_OR_RETURN( - auto op_visibility, - OperandVisibilityAnalysis::Create( - config_.max_path_count_for_edge_in_general_visibility_analysis, &nda, - bdd_engine.get())); - XLS_ASSIGN_OR_RETURN( - auto visibility, - VisibilityAnalysis::Create(&op_visibility, bdd_engine.get(), &post_dom)); - - XLS_ASSIGN_OR_RETURN(auto op_vis_large, - OperandVisibilityAnalysis::Create( - bdd_engine->path_limit(), &nda, bdd_engine.get())); - XLS_ASSIGN_OR_RETURN(auto single_select_visibility, - SingleSelectVisibilityAnalysis::Create( - &op_vis_large, &nda, bdd_engine.get())); - - VisibilityAnalyses visibilities = { - .general = *visibility, - .single_select = *single_select_visibility, - }; + XLS_ASSIGN_OR_RETURN(VisibilityAnalyses visibilities, + VisibilityAnalyses::Create(f, config_)); int64_t next_node_id = 0; for (auto node : f->nodes()) { @@ -2090,9 +2105,9 @@ absl::StatusOr ResourceSharingPass::RunOnFunctionBaseInternal( visibilities)); BitProvenanceAnalysis bpa; - VisibilityEstimator visibility_estimator(next_node_id - 1, bdd_engine.get(), - nda, bpa, options.area_estimator, - options.delay_estimator); + VisibilityEstimator visibility_estimator( + next_node_id - 1, visibilities.bdd_engine.get(), *visibilities.nda, bpa, + options.area_estimator, options.delay_estimator); // Identify the set of legal folding actions XLS_ASSIGN_OR_RETURN( diff --git a/xls/passes/resource_sharing_pass.h b/xls/passes/resource_sharing_pass.h index d779014271..c51f3fdc16 100644 --- a/xls/passes/resource_sharing_pass.h +++ b/xls/passes/resource_sharing_pass.h @@ -32,11 +32,13 @@ #include "xls/ir/function_base.h" #include "xls/ir/node.h" #include "xls/ir/node_util.h" +#include "xls/passes/bdd_query_engine.h" #include "xls/passes/critical_path_delay_analysis.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/post_dominator_analysis.h" #include "xls/passes/visibility_analysis.h" #include "xls/passes/visibility_expr_builder.h" @@ -244,6 +246,56 @@ class ResourceSharingPass : public OptimizationFunctionBasePass { // can be queried to provide the simplest visibility expressions it knows // which prove the mutual exclusivity of a set of nodes. struct VisibilityAnalyses { + static absl::StatusOr Create(FunctionBase* f, + const Config& config); + + VisibilityAnalyses(const VisibilityAnalysis& general_ref, + const SingleSelectVisibilityAnalysis& single_select_ref) + : general(general_ref), single_select(single_select_ref) {} + + VisibilityAnalyses( + std::unique_ptr nda, + std::unique_ptr post_dom, + std::unique_ptr bdd_engine, + std::unique_ptr op_visibility, + std::unique_ptr general_storage, + std::unique_ptr op_vis_large, + std::unique_ptr single_select_storage) + : nda(std::move(nda)), + post_dom(std::move(post_dom)), + bdd_engine(std::move(bdd_engine)), + op_visibility(std::move(op_visibility)), + general_storage(std::move(general_storage)), + op_vis_large(std::move(op_vis_large)), + single_select_storage(std::move(single_select_storage)), + general(*this->general_storage), + single_select(*this->single_select_storage) {} + + VisibilityAnalyses(VisibilityAnalyses&& o) + : nda(std::move(o.nda)), + post_dom(std::move(o.post_dom)), + bdd_engine(std::move(o.bdd_engine)), + op_visibility(std::move(o.op_visibility)), + general_storage(std::move(o.general_storage)), + op_vis_large(std::move(o.op_vis_large)), + single_select_storage(std::move(o.single_select_storage)), + general(general_storage != nullptr ? *general_storage : o.general), + single_select(single_select_storage != nullptr + ? *single_select_storage + : o.single_select) {} + + VisibilityAnalyses& operator=(VisibilityAnalyses&&) = delete; + VisibilityAnalyses(const VisibilityAnalyses&) = delete; + VisibilityAnalyses& operator=(const VisibilityAnalyses&) = delete; + + std::unique_ptr nda; + std::unique_ptr post_dom; + std::unique_ptr bdd_engine; + std::unique_ptr op_visibility; + std::unique_ptr general_storage; + std::unique_ptr op_vis_large; + std::unique_ptr single_select_storage; + const VisibilityAnalysis& general; const SingleSelectVisibilityAnalysis& single_select; };