1
0
mirror of https://github.com/exaloop/codon.git synced 2025-06-03 15:03:52 +08:00
Mark Henderson d010f889dd
Namespace update to codon (#2)
* namespace seq to codon

* using namespace seq -> codon

* seq:: to codon::

Co-authored-by: ‘markhend’ <‘markhend@gmail.com’>
2021-10-04 13:10:59 -04:00

74 lines
1.8 KiB
C++

#pragma once
#include "sir/transform/pass.h"
#include "sir/util/visitor.h"
namespace codon {
namespace ir {
namespace transform {
/// Base for rewrite rules.
class RewriteRule : public util::Visitor {
private:
Value *result = nullptr;
protected:
void defaultVisit(Node *) override {}
void setResult(Value *r) { result = r; }
void resetResult() { setResult(nullptr); }
Value *getResult() const { return result; }
public:
virtual ~RewriteRule() noexcept = default;
/// Apply the rule.
/// @param v the value to rewrite
/// @return nullptr if no rewrite, the replacement otherwise
Value *apply(Value *v) {
v->accept(*this);
auto *replacement = getResult();
resetResult();
return replacement;
}
};
/// A collection of rewrite rules.
class Rewriter {
private:
std::unordered_map<std::string, std::unique_ptr<RewriteRule>> rules;
int numReplacements = 0;
public:
/// Adds a given rewrite rule with the given key.
/// @param key the rule's key
/// @param rule the rewrite rule
void registerRule(const std::string &key, std::unique_ptr<RewriteRule> rule) {
rules.emplace(std::make_pair(key, std::move(rule)));
}
/// Applies all rewrite rules to the given node, and replaces the given
/// node with the result of the rewrites.
/// @param v the node to rewrite
void rewrite(Value *v) {
Value *result = v;
for (auto &r : rules) {
if (auto *rep = r.second->apply(result)) {
++numReplacements;
result = rep;
}
}
if (v != result)
v->replaceAll(result);
}
/// @return the number of replacements
int getNumReplacements() const { return numReplacements; }
/// Sets the replacement count to zero.
void reset() { numReplacements = 0; }
};
} // namespace transform
} // namespace ir
} // namespace codon