refactor(furlang/ir): improve instruction interface

Refs: #2
This commit is contained in:
2026-06-12 14:45:26 +02:00
parent 6b92e19b23
commit a14252bd1d
3 changed files with 112 additions and 25 deletions
+7 -17
View File
@@ -31,25 +31,15 @@ void ssa::optimize(const std::unique_ptr<furlang::ir::function>& func) {
const auto& block = func->blocks()[i]; const auto& block = func->blocks()[i];
for (const auto& instr : block->instructions()) { for (const auto& instr : block->instructions()) {
switch (instr->type()) { if (instr->has_destination()) {
case furlang::ir::instruction_t::Assign: { if (instr->destination().type() == furlang::ir::operand_t::Register) {
const auto& assign = dynamic_cast<const furlang::ir::assign_instruction&>(*instr); regSites[instr->destination().reg()].insert(i);
regSites[assign.destination().reg()].insert(i);
if (assign.source().type() == furlang::ir::operand_t::Register) {
regUses[i].insert(assign.source().reg());
} }
} break;
case furlang::ir::instruction_t::BinaryOp: {
const auto& binOp = dynamic_cast<const furlang::ir::binary_op_instruction&>(*instr);
regSites[binOp.dst().reg()].insert(i);
if (binOp.lhs().type() == furlang::ir::operand_t::Register) {
regUses[i].insert(binOp.lhs().reg());
} }
if (binOp.rhs().type() == furlang::ir::operand_t::Register) {
regUses[i].insert(binOp.rhs().reg()); for (const furlang::ir::operand* src : instr->sources()) {
} if (src->type() != furlang::ir::operand_t::Register) continue;
} break; regUses[i].insert(src->reg());
default: break;
} }
} }
+91 -7
View File
@@ -6,6 +6,7 @@
#include <cstdint> #include <cstdint>
#include <optional> #include <optional>
#include <ostream> #include <ostream>
#include <stdexcept>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -69,6 +70,41 @@ public:
* @return The type. * @return The type.
*/ */
virtual instruction_t type() const = 0; virtual instruction_t type() const = 0;
/**
* @brief Returns whether this instruction has a destination operand.
*
* @return true if this instruction has the destination operand.
*/
virtual bool has_destination() const { return false; }
/**
* @brief Returns destination operand of this instruction.
*
* @return The destination operand.
*/
virtual operand& destination() { throw std::runtime_error("instruction type mismatch"); }
/**
* @brief Returns destination operand of this instruction.
*
* @return The destination operand.
*/
virtual const operand& destination() const { throw std::runtime_error("instruction type mismatch"); }
/**
* @brief Returns a list of source operands of this instruction.
*
* @return The list of source operands.
*/
virtual std::vector<operand*> sources() { return {}; }
/**
* @brief Returns a list of source operands of this instruction.
*
* @return The list of source operands.
*/
virtual std::vector<const operand*> sources() const { return {}; }
public: public:
/** /**
* @brief Prints an instruction to an output stream. * @brief Prints an instruction to an output stream.
@@ -161,18 +197,39 @@ public:
instruction_t type() const override { return instruction_t::Assign; } instruction_t type() const override { return instruction_t::Assign; }
/** /**
* @brief Returns this instruction's source. * @brief Returns whether this instruction has a destination operand.
* *
* @return The source. * @return true
*/ */
const operand& source() const { return m_source; } bool has_destination() const override { return true; }
/** /**
* @brief Returns this instruction's destination. * @brief Returns this instruction's destination.
* *
* @return The destination. * @return The destination.
*/ */
const operand& destination() const { return m_destination; } operand& destination() override { return m_destination; }
/**
* @brief Returns this instruction's destination.
*
* @return The destination.
*/
const operand& destination() const override { return m_destination; }
/**
* @brief Returns a list of this instruction's source operands.
*
* @return The list of source operands.
*/
std::vector<operand*> sources() override { return { &m_source }; }
/**
* @brief Returns a list of this instruction's source operands.
*
* @return The list of source operands.
*/
std::vector<const operand*> sources() const override { return { &m_source }; }
private: private:
operand m_source; operand m_source;
operand m_destination; operand m_destination;
@@ -256,6 +313,16 @@ public:
*/ */
instruction_t type() const override { return instruction_t::BinaryOp; } instruction_t type() const override { return instruction_t::BinaryOp; }
bool has_destination() const override { return true; }
operand& destination() override { return m_dst; }
const operand& destination() const override { return m_dst; }
std::vector<operand*> sources() override { return { &m_lhs, &m_rhs }; }
std::vector<const operand*> sources() const override { return { &m_lhs, &m_rhs }; }
/** /**
* @brief Returns this instruction's operation type. * @brief Returns this instruction's operation type.
* *
@@ -445,6 +512,16 @@ public:
*/ */
instruction_t type() const override { return instruction_t::Return; } instruction_t type() const override { return instruction_t::Return; }
std::vector<operand*> sources() override {
if (m_value.has_value()) return { &*m_value };
return {};
}
std::vector<const operand*> sources() const override {
if (m_value.has_value()) return { &*m_value };
return {};
}
/** /**
* @brief Returns this instruction's return value operand. * @brief Returns this instruction's return value operand.
* *
@@ -469,7 +546,7 @@ protected:
class phi_instruction final : public instruction { class phi_instruction final : public instruction {
public: public:
phi_instruction(register_operand dst) phi_instruction(register_operand dst)
: m_dst(dst) {} : m_dst(operand::new_reg(dst)) {}
~phi_instruction() override = default; ~phi_instruction() override = default;
@@ -499,7 +576,14 @@ public:
* *
* @return The register. * @return The register.
*/ */
register_operand destination() const { return m_dst; } operand& destination() override { return m_dst; }
/**
* @brief Returns this instruction's destination register.
*
* @return The register.
*/
const operand& destination() const override { return m_dst; }
/** /**
* @brief Returns this instruction's labels. * @brief Returns this instruction's labels.
@@ -515,7 +599,7 @@ public:
*/ */
const std::vector<std::pair<operand, block_index>>& labels() const { return m_labels; } const std::vector<std::pair<operand, block_index>>& labels() const { return m_labels; }
private: private:
register_operand m_dst; operand m_dst;
std::vector<std::pair<operand, block_index>> m_labels; std::vector<std::pair<operand, block_index>> m_labels;
protected: protected:
std::ostream& print(std::ostream& os) const override { std::ostream& print(std::ostream& os) const override {
+13
View File
@@ -137,6 +137,19 @@ public:
return operand; return operand;
} }
/**
* @brief Construct a new register operand.
*
* @param value Value of the new register operand.
* @return The register operand.
*/
static operand new_reg(register_operand value) {
operand operand;
operand.m_type = operand_t::Register;
operand.m_value.reg = value;
return operand;
}
/** /**
* @brief Construct a new variable operand. * @brief Construct a new variable operand.
* *