diff --git a/furlang/include/furlang/ir/instruction.hpp b/furlang/include/furlang/ir/instruction.hpp index 668c730..94978b6 100644 --- a/furlang/include/furlang/ir/instruction.hpp +++ b/furlang/include/furlang/ir/instruction.hpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include namespace furlang { namespace ir { @@ -21,6 +23,7 @@ enum class instruction_t { Branch, /**< Branch */ BranchCond, /**< Conditional branch */ Return, /**< Return */ + Phi, /**< Phi function */ }; /** @@ -458,7 +461,58 @@ protected: } }; +/** + * @brief Phi instruction + * + * Used to implement the phi node in the SSA graph. + */ +class phi_instruction final : public instruction { +public: + phi_instruction(std::vector>&& labels) + : m_labels(std::move(labels)) {} + + ~phi_instruction() override = default; + + /** + * @brief Move constructor. + */ + phi_instruction(phi_instruction&&) noexcept = default; + + /** + * @brief Move constructor. + */ + phi_instruction& operator=(phi_instruction&&) noexcept = default; + + phi_instruction(const phi_instruction&) = delete; + + phi_instruction& operator=(const phi_instruction&) = delete; +public: + /** + * @brief Returns this instruction's type. + * + * @return instruction_t::Phi. + */ + instruction_t type() const override { return instruction_t::Phi; } + + /** + * @brief Returns this instruction's labels. + * + * @return The labels. + */ + const std::vector>& labels() const { return m_labels; } +private: + std::vector> m_labels; +protected: + std::ostream& print(std::ostream& os) const override { + os << "phi"; + for (const auto& pair : m_labels) { + os << ' ' << pair.second << ": " << pair.first; + } + return os; + } +}; + } // namespace ir } // namespace furlang -#endif // FURLANG_IR_INSTRUCTION_HPP \ No newline at end of file +#endif // FURLANG_IR_INSTRUCTION_HPP