Структура оптимизатора

Общая структура класса, рекурсивно совершающего оптимизации (трансформации) над текущим представлением, выглядит следующим образом:

class Optimizer {
    std::vector<BaseTransform::Ptr> transforms;
    size_t iterLimit;

public:
    Optimizer();
    void add(const BaseTransform::Ptr &transform);
    void process(Program &program) const;
};

Класс оптимизатора содержит:

  • набор трансформаций transforms, имплементированных и впоследствии зарегистрированных для применения на очередном дереве операций;

  • метод add для добавления новых трансформаций к списку;

  • метод process, содержащий реализацию главного цикла оптимизатора с последовательным применением трансформаций к дереву.

Последовательность трансформаций определяется разработчиками компилятора, каждая последующая трансформация может быть добавлена с использованием соответствующих методов. После очередного применения трансформаций из списка добавленных, оптимизатор проверяет, было ли изменено промежуточное представление и достигло ли число итераций максимума. Если одно из этих условий не выполнено, процесс оптимизации останавливается и текущее дерево направляется в следующий компонент компилятора.

Предполагается, что при имплементации трансформаций, в специализации шаблона явно передается список операций, над которыми совершается трансформация. Таким образом, трансформация точно знает, на каких операциях она выполняется и не проверяет это внутри своей реализации.

В свою очередь информация о последовательности трансформаций, применяемых к дереву операций, содержится в объявлении класса Transform. Выглядит класс следующим образом:

template <typename... AdaptorTypes>
struct Transform : public BaseTransform {
    Transform() = default;
    Transform(const Transform &) = default;
    Transform(Transform &&) = default;
    ~Transform() override = default;

    bool canRun(const Operation::Ptr &op) const final {
        if constexpr (sizeof...(AdaptorTypes) == 0)
            return true;
        else
            return (op->is<AdaptorTypes>() || ...);
    }
};

Трансформация содержит единственный реализованный метод canRun, проверяющий соответствие типов операций, на которых запускается преобразование. Именно этот механизм и обеспечивает применение очередного преобразования только на заданных операциях.

Назад