6#include <unordered_map>
53 std::vector<std::shared_ptr<const LibNodeExpander>> expanders_;
55 std::unordered_map<std::string, const LibNodeExpander*> by_code_;
57 std::vector<const LibNodeExpander*> fallback_;
66 template<
typename... Expanders>
68 expanders_.reserve(
sizeof...(Expanders));
73 explicit SwitchExpander(std::vector<std::shared_ptr<const LibNodeExpander>> expanders) {
74 expanders_.reserve(expanders.size());
75 for (
auto& expander : expanders) {
89 if (
const auto* code = expander->matched_code()) {
92 fallback_.push_back(expander.get());
93 expanders_.push_back(std::move(expander));
108 auto [it, inserted] = by_code_.emplace(code.
value(), expander.get());
110 throw std::invalid_argument(
111 "SwitchExpander: more than one expander registered for library node code '" + code.
value() +
"'"
114 expanders_.push_back(std::move(expander));
122 if (
auto it = by_code_.find(node.
code().
value()); it != by_code_.end()) {
123 if (
const auto* match = it->second->for_lib_node(node)) {
127 for (
const auto* expander : fallback_) {
128 if (
const auto* match = expander->for_lib_node(node)) {
145 if (
const auto* expander =
for_lib_node(node); expander && expander !=
this) {
146 return expander->handle_expand(context, block, node);
std::string value() const
Definition exceptions.h:47
Base class for all library nodes in the dataflow graph.
Definition library_node.h:106
const LibraryNodeCode & code() const
Get the operation code.
Definition lib_node_expander.h:122
virtual ExpandOutcome unapplicable()=0
Definition lib_node_expander.h:8
ExpandOutcome handle_expand(ExpandContext &context, structured_control_flow::Block &block, data_flow::LibraryNode &node) const override
Delegate expansion to the matching sub-expander.
Definition switch_expander.h:142
void register_for_code(const data_flow::LibraryNodeCode &code, std::shared_ptr< const LibNodeExpander > expander)
Register expander as the handler for library nodes with the given code.
Definition switch_expander.h:104
SwitchExpander(std::vector< std::shared_ptr< const LibNodeExpander > > expanders)
Construct from an already assembled list of expanders.
Definition switch_expander.h:73
SwitchExpander(Expanders... expanders)
Construct from a variadic list of expanders.
Definition switch_expander.h:67
void register_expander(std::shared_ptr< const LibNodeExpander > expander)
Register expander.
Definition switch_expander.h:85
const LibNodeExpander * for_lib_node(const data_flow::LibraryNode &node) const override
Find the expander that applies to node via an O(1) code lookup, with a linear fallback.
Definition switch_expander.h:121
A control flow node representing a basic block with dataflow computations.
Definition block.h:42
Library node definitions for calling functions beyond simple instructions.
StringEnum LibraryNodeCode
Definition library_node.h:65
Definition approximate_math.h:12
Definition lib_node_expander.h:12