Skip to content

Commit

Permalink
feat(ir, compiler): implementing the IR optimizer
Browse files Browse the repository at this point in the history
  • Loading branch information
SuperFola committed Oct 12, 2024
1 parent ee87cf3 commit 139084d
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 7 deletions.
2 changes: 1 addition & 1 deletion .github/images/diagram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion include/Ark/Compiler/IntermediateRepresentation/Entity.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ namespace Ark::internal::IR

Kind m_kind;
label_t m_label { 0 };
Instruction m_inst;
Instruction m_inst { NOP };
uint16_t m_primary_arg { 0 };
uint16_t m_secondary_arg { 0 };
};
Expand Down
2 changes: 1 addition & 1 deletion include/Ark/Compiler/Welder.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ namespace Ark

void dumpIRToFile() const;

bool computeAST(const std::string& filename, const std::string& code, bool fail_with_exception);
bool computeAST(const std::string& filename, const std::string& code);
};
} // namespace Ark

Expand Down
2 changes: 1 addition & 1 deletion src/arkreactor/Compiler/Compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ namespace Ark::internal
// in order to be able to handle things like (op A B C D...)
// which should be transformed into A B op C op D op...
if (exp_count >= 2)
page(p).emplace_back(op, 2); // TODO generalize to n arguments (n >= 2)
page(p).emplace_back(op);
}

if (isUnaryInst(op))
Expand Down
121 changes: 120 additions & 1 deletion src/arkreactor/Compiler/IntermediateRepresentation/IROptimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,128 @@ namespace Ark::internal

void IROptimizer::process(const std::vector<IR::Block>& pages, const std::vector<std::string>& symbols, const std::vector<ValTableElem>& values)
{
m_ir = pages;
m_symbols = symbols;
m_values = values;

for (const auto& block : pages)
{
m_ir.emplace_back();
IR::Block& current_block = m_ir.back();

std::size_t i = 0;
const std::size_t end = block.size();

while (i < end)
{
const Instruction first = block[i].inst();
const uint16_t arg_1 = block[i].primaryArg();

if (i + 1 < end)
{
const Instruction second = block[i + 1].inst();
const uint16_t arg_2 = block[i + 1].primaryArg();

// LOAD_CONST x
// LOAD_CONST y
// ---> LOAD_CONST_LOAD_CONST x y
if (first == LOAD_CONST && second == LOAD_CONST)
{
current_block.emplace_back(LOAD_CONST_LOAD_CONST, arg_1, arg_2);
i += 2;
}
// LOAD_CONST x
// STORE / SET_VAL a
// ---> LOAD_CONST_STORE x a ; LOAD_CONST_SET_VAL x a
else if (first == LOAD_CONST && second == STORE)
{
current_block.emplace_back(LOAD_CONST_STORE, arg_1, arg_2);
i += 2;
}
else if (first == LOAD_CONST && second == SET_VAL)
{
current_block.emplace_back(LOAD_CONST_SET_VAL, arg_1, arg_2);
i += 2;
}
// LOAD_SYMBOL a
// STORE / SET_VAL b
// ---> STORE_FROM a b ; SET_VAL_FROM a b
else if (first == LOAD_SYMBOL && second == STORE)
{
current_block.emplace_back(STORE_FROM, arg_1, arg_2);
i += 2;
}
else if (first == LOAD_SYMBOL && second == SET_VAL)
{
current_block.emplace_back(SET_VAL_FROM, arg_1, arg_2);
i += 2;
}
else if (i + 2 < end)
{
const Instruction third = block[i + 2].inst();
const uint16_t arg_3 = block[i + 2].primaryArg();

// LOAD_SYMBOL a
// LOAD_CONST n (1)
// ADD / SUB
// ---> INCREMENT / DECREMENT a
if (third == ADD && first == LOAD_CONST && second == LOAD_SYMBOL && m_values[arg_1].type == ValTableElemType::Number && std::get<double>(m_values[arg_1].value) == 1)
{
current_block.emplace_back(INCREMENT, arg_2);
i += 3;
}
else if (third == ADD && first == LOAD_SYMBOL && second == LOAD_CONST && m_values[arg_2].type == ValTableElemType::Number && std::get<double>(m_values[arg_2].value) == 1)
{
current_block.emplace_back(INCREMENT, arg_1);
i += 3;
}
else if (third == SUB && first == LOAD_SYMBOL && second == LOAD_CONST && m_values[arg_2].type == ValTableElemType::Number && std::get<double>(m_values[arg_2].value) == 1)
{
current_block.emplace_back(DECREMENT, arg_1);
i += 3;
}
// LOAD_SYMBOL list
// TAIL / HEAD
// STORE / SET_VAL a
// ---> STORE_TAIL list a ; STORE_HEAD ; SET_VAL_TAIL ; SET_VAL_HEAD
else if (first == LOAD_SYMBOL && second == TAIL && third == STORE)
{
current_block.emplace_back(STORE_TAIL, arg_1, arg_3);
i += 3;
}
else if (first == LOAD_SYMBOL && second == TAIL && third == SET_VAL)
{
current_block.emplace_back(SET_VAL_TAIL, arg_1, arg_3);
i += 3;
}
else if (first == LOAD_SYMBOL && second == HEAD && third == STORE)
{
current_block.emplace_back(STORE_HEAD, arg_1, arg_3);
i += 3;
}
else if (first == LOAD_SYMBOL && second == HEAD && third == SET_VAL)
{
current_block.emplace_back(SET_VAL_HEAD, arg_1, arg_3);
i += 3;
}
else
{
current_block.emplace_back(block[i]);
++i;
}
}
else
{
current_block.emplace_back(block[i]);
++i;
}
}
else
{
current_block.emplace_back(block[i]);
++i;
}
}
}
}

const std::vector<IR::Block>& IROptimizer::intermediateRepresentation() const noexcept
Expand Down
4 changes: 2 additions & 2 deletions src/arkreactor/Compiler/Welder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ namespace Ark
break;

case internal::IR::Kind::Opcode2Args:
fmt::println(output, "\t{} {} ({})", internal::InstructionNames[entity.inst()], entity.primaryArg(), entity.secondaryArg());
fmt::println(output, "\t{} {}, {}", internal::InstructionNames[entity.inst()], entity.primaryArg(), entity.secondaryArg());
break;
}
}
Expand All @@ -153,7 +153,7 @@ namespace Ark
output.close();
}

bool Welder::computeAST(const std::string& filename, const std::string& code, const bool fail_with_exception)
bool Welder::computeAST(const std::string& filename, const std::string& code)
{
try
{
Expand Down

0 comments on commit 139084d

Please sign in to comment.