Skip to content

Commit

Permalink
clone replace utilities
Browse files Browse the repository at this point in the history
  • Loading branch information
vla5924 committed Apr 21, 2024
1 parent ce8466e commit ff63f44
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class OptBuilder : public Builder {
Operation::Ptr clone(const Operation::Ptr &op);
void erase(const Operation::Ptr &op);
void update(const Operation::Ptr &op, const std::function<void()> &actor);
void replace(const Operation::Ptr &op, const Operation::Ptr &newOp);

private:
const Notifier &notifier;
Expand Down
3 changes: 3 additions & 0 deletions compiler/include/compiler/optree/attribute.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ struct Attribute {
Attribute(Attribute &&) = default;
~Attribute() = default;

Attribute &operator=(const Attribute &) = default;
Attribute &operator=(Attribute &&) = default;

template <typename VariantType>
explicit Attribute(const VariantType &value) : storage(value){};

Expand Down
5 changes: 5 additions & 0 deletions compiler/include/compiler/optree/operation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,17 @@ struct Operation {
}

void addOperand(const Value::Ptr &value);
void insertOperand(size_t operandNumber, const Value::Ptr &value);
void setOperand(size_t operandNumber, const Value::Ptr &value);
void eraseOperand(size_t operandNumber);
Value::Ptr addResult(const Type::Ptr &type);
Value::Ptr addInward(const Type::Ptr &type);
Body::iterator addToBody(const Operation::Ptr &op);
void erase();

Ptr clone();
Ptr cloneWithoutBody();

std::string dump() const;
void dump(std::ostream &stream) const;

Expand Down
4 changes: 2 additions & 2 deletions compiler/include/compiler/optree/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,15 @@ struct Value {
using Ptr = std::shared_ptr<Value>;

struct Use {
Operation *user;
const Operation *user;
size_t operandNumber;

Use() = delete;
Use(const Use &) = delete;
Use(Use &&) = default;
~Use() = default;

Use(Operation *user, size_t operandNumber) : user(user), operandNumber(operandNumber){};
Use(const Operation *user, size_t operandNumber) : user(user), operandNumber(operandNumber){};
};

Type::Ptr type;
Expand Down
40 changes: 38 additions & 2 deletions compiler/lib/backend/optree/optimizer/opt_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,36 @@
using namespace optree;
using namespace optree::optimizer;

namespace {

void notifyInsertRecursively(const Operation::Ptr &op, const OptBuilder::Notifier &notifier) {
for (const auto &nestedOp : op->body)
notifyInsertRecursively(nestedOp, notifier);
notifier.onInsert(op);
}

Operation::Ptr findPtr(const Operation *ptr, const Operation::Body &body, const Operation::Body::iterator &afterPos) {
for (auto it = afterPos; it != body.end(); ++it) {
if (it->get() == ptr)
return *it;
const auto &op = *it;
if (auto nestedOp = findPtr(ptr, op->body, op->body.begin()))
return nestedOp;
}
return {};
}

} // namespace

void OptBuilder::insert(const Operation::Ptr &op) {
Builder::insert(op);
notifier.onInsert(op);
}

Operation::Ptr OptBuilder::clone(const Operation::Ptr &op) {
// TODO
notifier.onInsert(op);
auto newOp = op->clone();
Builder::insert(op);
notifyInsertRecursively(op, notifier);
return op;
}

Expand All @@ -32,3 +54,17 @@ void OptBuilder::update(const Operation::Ptr &op, const std::function<void()> &a
actor();
notifier.onUpdate(op);
}

void OptBuilder::replace(const Operation::Ptr &op, const Operation::Ptr &newOp) {
for (auto oldResultIt = op->results.begin(), newResultIt = newOp->results.begin();
oldResultIt != op->results.end() && newResultIt != newOp->results.end(); ++oldResultIt, ++newResultIt) {
const Value::Ptr &oldResult = *oldResultIt;

Check failure

Code scanning / clang-tidy

no header providing "optree::Value" is directly included [misc-include-cleaner,-warnings-as-errors] Error

no header providing "optree::Value" is directly included [misc-include-cleaner,-warnings-as-errors]
const Value::Ptr &newResult = *newResultIt;

Check failure

Code scanning / clang-tidy

no header providing "optree::Value" is directly included [misc-include-cleaner,-warnings-as-errors] Error

no header providing "optree::Value" is directly included [misc-include-cleaner,-warnings-as-errors]
for (const auto &use : oldResult->uses) {
auto user = findPtr(use.user, op->parent->body, op->position);
update(user, [&] { user->operand(use.operandNumber) = newResult; });
}
newResult->uses.splice_after(newResult->uses.before_begin(), oldResult->uses);
}
erase(op);
}
70 changes: 66 additions & 4 deletions compiler/lib/optree/operation.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "operation.hpp"

#include <cstddef>
#include <functional>
#include <ostream>
#include <sstream>
#include <stdexcept>
Expand All @@ -15,16 +16,57 @@

using namespace optree;

namespace {

void addUse(const Value::Ptr &value, const Operation *user, size_t operandNumber) {
value->uses.emplace_front(user, operandNumber);
}

void removeUse(const Value::Ptr &value, const Operation *user, size_t operandNumber) {
value->uses.remove_if(
[&](const Value::Use &use) { return use.user == user && use.operandNumber == operandNumber; });
}

void updateUses(const Value::Ptr &value, const std::function<void(Value::Use &)> &actor) {
for (auto &use : value->uses)
actor(use);
}

} // namespace

void Operation::addOperand(const Value::Ptr &value) {
size_t operandNumber = operands.size();
operands.emplace_back(value);
value->uses.emplace_front(this, operandNumber);
addUse(value, this, operandNumber);
}

void Operation::insertOperand(size_t operandNumber, const Value::Ptr &value) {
auto operandIt = operands.emplace(operands.begin() + operandNumber, value);
addUse(value, this, operandNumber);
for (auto it = std::next(operandIt); it != operands.end(); ++it) {

Check failure

Code scanning / clang-tidy

no header providing "std::next" is directly included [misc-include-cleaner,-warnings-as-errors] Error

no header providing "std::next" is directly included [misc-include-cleaner,-warnings-as-errors]
updateUses(*it, [&](Value::Use &use) {
if (use.user == this)
operandNumber++;
});
}
}

void Operation::setOperand(size_t operandNumber, const Value::Ptr &value) {
auto &operand = operands[operandNumber];
removeUse(operand, this, operandNumber);
operand = value;
addUse(value, this, operandNumber);
}

void Operation::eraseOperand(size_t operandNumber) {
auto &uses = operands[operandNumber]->uses;
uses.remove_if([&](const Value::Use &use) { return use.user == this && use.operandNumber == operandNumber; });
operands.erase(operands.begin() + operandNumber);
removeUse(operands[operandNumber], this, operandNumber);
auto operandIt = operands.erase(operands.begin() + operandNumber);
for (auto it = operandIt; it != operands.end(); ++it) {
updateUses(*it, [&](Value::Use &use) {
if (use.user == this)
operandNumber--;
});
}
}

Value::Ptr Operation::addResult(const Type::Ptr &type) {
Expand Down Expand Up @@ -64,6 +106,26 @@ void Operation::erase() {
parent->body.erase(position);
}

Operation::Ptr Operation::clone() {
auto newOp = cloneWithoutBody();
for (auto nestedOp : body) {

Check failure

Code scanning / clang-tidy

loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy,-warnings-as-errors] Error

loop variable is copied but only used as const reference; consider making it a const reference [performance-for-range-copy,-warnings-as-errors]
auto nestedNewOp = nestedOp->clone();
newOp->addToBody(nestedNewOp);
nestedNewOp->parent = newOp;
}
return newOp;
}

Operation::Ptr Operation::cloneWithoutBody() {
auto newOp = std::make_shared<Operation>(specId, name);

Check failure

Code scanning / clang-tidy

no header providing "std::make_shared" is directly included [misc-include-cleaner,-warnings-as-errors] Error

no header providing "std::make_shared" is directly included [misc-include-cleaner,-warnings-as-errors]
newOp->ref = ref;
newOp->operands = operands;
newOp->results = results;
newOp->inwards = inwards;
newOp->attributes = attributes;
return newOp;
}

std::string Operation::dump() const {
std::stringstream str;
dump(str);
Expand Down

0 comments on commit ff63f44

Please sign in to comment.