Store node list via shared_ptr in module_context
This commit is contained in:
parent
dd3eb5d14b
commit
c3c5010e04
4 changed files with 48 additions and 43 deletions
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <pslang/ast/statement_fwd.hpp>
|
||||
#include <pslang/ir/node.hpp>
|
||||
#include <pslang/ir/node_fwd.hpp>
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
|
|
@ -17,7 +17,7 @@ namespace pslang::ir
|
|||
|
||||
struct module_context
|
||||
{
|
||||
node_list nodes;
|
||||
node_list_ptr nodes;
|
||||
|
||||
std::unordered_map<node const *, std::string> labels;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
|
||||
namespace pslang::ir
|
||||
{
|
||||
|
|
@ -8,5 +9,6 @@ namespace pslang::ir
|
|||
struct node;
|
||||
using node_list = std::list<node>;
|
||||
using node_ref = node_list::iterator;
|
||||
using node_list_ptr = std::shared_ptr<node_list>;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace pslang::ir
|
|||
template <typename T>
|
||||
node_ref apply(ast::primitive_literal_base<T> const & node)
|
||||
{
|
||||
mcontext.nodes.emplace_back(literal{node}, ast::get_type(node));
|
||||
mcontext.nodes->emplace_back(literal{node}, ast::get_type(node));
|
||||
return last();
|
||||
}
|
||||
|
||||
|
|
@ -75,13 +75,13 @@ namespace pslang::ir
|
|||
}
|
||||
else if (node.function_node)
|
||||
{
|
||||
mcontext.nodes.emplace_back(instruction_address{}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(instruction_address{}, node.inferred_type);
|
||||
lcontext.resolve_address.emplace_back(last(), node.function_node);
|
||||
return last();
|
||||
}
|
||||
else if (node.foreign_function_node)
|
||||
{
|
||||
mcontext.nodes.emplace_back(extern_symbol{node.name}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(extern_symbol{node.name}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
else
|
||||
|
|
@ -94,11 +94,11 @@ namespace pslang::ir
|
|||
|
||||
if (node.type == ast::unary_operation_type::dereference)
|
||||
{
|
||||
mcontext.nodes.emplace_back(load{arg1}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(load{arg1}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
||||
mcontext.nodes.emplace_back(unary_operation{node.type, arg1}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(unary_operation{node.type, arg1}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
||||
|
|
@ -108,38 +108,38 @@ namespace pslang::ir
|
|||
|
||||
if (node.type == ast::binary_operation_type::logical_and)
|
||||
{
|
||||
mcontext.nodes.emplace_back(jump_if_zero{arg1});
|
||||
mcontext.nodes->emplace_back(jump_if_zero{arg1});
|
||||
auto jump = last();
|
||||
auto arg2 = apply(*node.arg2);
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::binary_and, arg1, arg2}, node.inferred_type);
|
||||
mcontext.nodes.emplace_back(assignment{arg1, last()});
|
||||
mcontext.nodes.emplace_back(nop{});
|
||||
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_and, arg1, arg2}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(assignment{arg1, last()});
|
||||
mcontext.nodes->emplace_back(nop{});
|
||||
std::get<jump_if_zero>(jump->instruction).target = last();
|
||||
return arg1;
|
||||
}
|
||||
|
||||
if (node.type == ast::binary_operation_type::logical_or)
|
||||
{
|
||||
mcontext.nodes.emplace_back(unary_operation{ast::unary_operation_type::logical_not, arg1}, node.inferred_type);
|
||||
mcontext.nodes.emplace_back(jump_if_zero{last()});
|
||||
mcontext.nodes->emplace_back(unary_operation{ast::unary_operation_type::logical_not, arg1}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(jump_if_zero{last()});
|
||||
auto jump = last();
|
||||
auto arg2 = apply(*node.arg2);
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::binary_or, arg1, arg2}, node.inferred_type);
|
||||
mcontext.nodes.emplace_back(assignment{arg1, last()});
|
||||
mcontext.nodes.emplace_back(nop{});
|
||||
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::binary_or, arg1, arg2}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(assignment{arg1, last()});
|
||||
mcontext.nodes->emplace_back(nop{});
|
||||
std::get<jump_if_zero>(jump->instruction).target = last();
|
||||
return arg1;
|
||||
}
|
||||
|
||||
auto arg2 = apply(*node.arg2);
|
||||
mcontext.nodes.emplace_back(binary_operation{node.type, arg1, arg2}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(binary_operation{node.type, arg1, arg2}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
||||
node_ref apply(ast::cast_operation const & node)
|
||||
{
|
||||
auto arg = apply(*node.expression);
|
||||
mcontext.nodes.emplace_back(cast_operation{arg, node.inferred_type}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(cast_operation{arg, node.inferred_type}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
|
||||
|
|
@ -154,13 +154,13 @@ namespace pslang::ir
|
|||
|
||||
if (auto identifier = std::get_if<ast::identifier>(node.function.get()); identifier && identifier->function_node)
|
||||
{
|
||||
mcontext.nodes.emplace_back(call{{}, std::move(arguments)}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(call{{}, std::move(arguments)}, node.inferred_type);
|
||||
lcontext.resolve_call.emplace_back(last(), identifier->function_node);
|
||||
return last();
|
||||
}
|
||||
|
||||
auto function = apply(*node.function);
|
||||
mcontext.nodes.emplace_back(call_pointer{function, std::move(arguments)}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(call_pointer{function, std::move(arguments)}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
else // if (node.type)
|
||||
|
|
@ -176,8 +176,8 @@ namespace pslang::ir
|
|||
auto array_type = ast::get_type(*node.array);
|
||||
if (std::get_if<types::pointer_type>(array_type.get()))
|
||||
{
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, array, index}, array_type);
|
||||
mcontext.nodes.emplace_back(load{last()}, node.inferred_type);
|
||||
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::addition, array, index}, array_type);
|
||||
mcontext.nodes->emplace_back(load{last()}, node.inferred_type);
|
||||
return last();
|
||||
}
|
||||
throw std::runtime_error("Unknown array access left-hand side");
|
||||
|
|
@ -199,7 +199,7 @@ namespace pslang::ir
|
|||
if (std::holds_alternative<ast::identifier>(*node.lhs))
|
||||
{
|
||||
auto lhs = apply(*node.lhs);
|
||||
mcontext.nodes.emplace_back(assignment{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
mcontext.nodes->emplace_back(assignment{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
|
||||
|
|
@ -210,8 +210,8 @@ namespace pslang::ir
|
|||
{
|
||||
auto base_ptr = apply(*array_access->array);
|
||||
auto index = apply(*array_access->index);
|
||||
mcontext.nodes.emplace_back(binary_operation{ast::binary_operation_type::addition, base_ptr, index}, array_type);
|
||||
mcontext.nodes.emplace_back(store{last(), rhs}, ast::get_type(*node.rhs));
|
||||
mcontext.nodes->emplace_back(binary_operation{ast::binary_operation_type::addition, base_ptr, index}, array_type);
|
||||
mcontext.nodes->emplace_back(store{last(), rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ namespace pslang::ir
|
|||
if (unary_operation->type == ast::unary_operation_type::dereference)
|
||||
{
|
||||
auto lhs = apply(*unary_operation->arg1);
|
||||
mcontext.nodes.emplace_back(store{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
mcontext.nodes->emplace_back(store{lhs, rhs}, ast::get_type(*node.rhs));
|
||||
return last();
|
||||
}
|
||||
}
|
||||
|
|
@ -238,7 +238,7 @@ namespace pslang::ir
|
|||
// Evaluating variable initializer didn't produce any nodes
|
||||
// It must have been just a reference to another variable or smth like that
|
||||
// Introduce a copy node to prevent accidental variable coalescing
|
||||
mcontext.nodes.emplace_back(copy{result});
|
||||
mcontext.nodes->emplace_back(copy{result});
|
||||
result = last();
|
||||
}
|
||||
lcontext.variables[&node] = result;
|
||||
|
|
@ -255,7 +255,7 @@ namespace pslang::ir
|
|||
if (block.condition)
|
||||
{
|
||||
auto condition = apply(*block.condition);
|
||||
mcontext.nodes.emplace_back(jump_if_zero{condition, {}});
|
||||
mcontext.nodes->emplace_back(jump_if_zero{condition, {}});
|
||||
jump_to_next = last();
|
||||
}
|
||||
|
||||
|
|
@ -263,10 +263,10 @@ namespace pslang::ir
|
|||
apply(*block.statements);
|
||||
lcontext.scopes.pop_back();
|
||||
|
||||
mcontext.nodes.emplace_back(jump{});
|
||||
mcontext.nodes->emplace_back(jump{});
|
||||
jumps_to_end.push_back(last());
|
||||
|
||||
mcontext.nodes.emplace_back(nop{});
|
||||
mcontext.nodes->emplace_back(nop{});
|
||||
if (jump_to_next)
|
||||
std::get<jump_if_zero>((*jump_to_next)->instruction).target = last();
|
||||
}
|
||||
|
|
@ -282,15 +282,15 @@ namespace pslang::ir
|
|||
{
|
||||
auto before = last();
|
||||
auto condition = apply(*node.condition);
|
||||
mcontext.nodes.emplace_back(jump_if_zero{condition, {}});
|
||||
mcontext.nodes->emplace_back(jump_if_zero{condition, {}});
|
||||
auto jump1 = last();
|
||||
|
||||
lcontext.scopes.emplace_back();
|
||||
apply(*node.statements);
|
||||
lcontext.scopes.pop_back();
|
||||
|
||||
mcontext.nodes.emplace_back(jump{std::next(before)});
|
||||
mcontext.nodes.emplace_back(nop{});
|
||||
mcontext.nodes->emplace_back(jump{std::next(before)});
|
||||
mcontext.nodes->emplace_back(nop{});
|
||||
std::get<jump_if_zero>(jump1->instruction).target = last();
|
||||
return last();
|
||||
}
|
||||
|
|
@ -310,10 +310,10 @@ namespace pslang::ir
|
|||
if (node.value)
|
||||
{
|
||||
auto value = apply(*node.value);
|
||||
mcontext.nodes.emplace_back(return_value{value}, value->inferred_type);
|
||||
mcontext.nodes->emplace_back(return_value{value}, value->inferred_type);
|
||||
}
|
||||
else
|
||||
mcontext.nodes.emplace_back(return_value{}, std::make_shared<types::type>(types::unit_type{}));
|
||||
mcontext.nodes->emplace_back(return_value{}, std::make_shared<types::type>(types::unit_type{}));
|
||||
return last();
|
||||
}
|
||||
|
||||
|
|
@ -331,13 +331,13 @@ namespace pslang::ir
|
|||
lcontext.scopes.emplace_back();
|
||||
for (std::size_t i = 0; i < node.arguments.size(); ++i)
|
||||
{
|
||||
mcontext.nodes.emplace_back(argument{i}, ast::get_type(*node.arguments[i].type));
|
||||
mcontext.nodes->emplace_back(argument{i}, ast::get_type(*node.arguments[i].type));
|
||||
lcontext.variables[&node.arguments[i]] = last();
|
||||
}
|
||||
apply(*node.statements);
|
||||
|
||||
if (types::equal(*ast::get_type(*node.return_type), types::unit_type{}))
|
||||
mcontext.nodes.emplace_back(return_value{}, std::make_shared<types::type>(types::unit_type{}));
|
||||
mcontext.nodes->emplace_back(return_value{}, std::make_shared<types::type>(types::unit_type{}));
|
||||
|
||||
lcontext.scopes.pop_back();
|
||||
|
||||
|
|
@ -349,7 +349,7 @@ namespace pslang::ir
|
|||
private:
|
||||
node_ref last()
|
||||
{
|
||||
return std::prev(mcontext.nodes.end());
|
||||
return std::prev(mcontext.nodes->end());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -410,6 +410,9 @@ namespace pslang::ir
|
|||
|
||||
void compile(module_context & mcontext, ast::statement_list_ptr const & statements)
|
||||
{
|
||||
if (!mcontext.nodes)
|
||||
mcontext.nodes = std::make_shared<node_list>();
|
||||
|
||||
// Add a fake AST node for the entry point
|
||||
auto root = std::make_shared<ast::statement>(ast::function_definition{
|
||||
{
|
||||
|
|
@ -422,12 +425,12 @@ namespace pslang::ir
|
|||
{},
|
||||
});
|
||||
|
||||
mcontext.nodes.emplace_back(nop{});
|
||||
auto extra_nop = std::prev(mcontext.nodes.end());
|
||||
mcontext.nodes->emplace_back(nop{});
|
||||
auto extra_nop = std::prev(mcontext.nodes->end());
|
||||
local_context lcontext;
|
||||
compile_visitor{{}, mcontext, lcontext}.apply(*root);
|
||||
mcontext.labels[&(*std::next(extra_nop))] = "[entry point]";
|
||||
mcontext.nodes.erase(extra_nop);
|
||||
mcontext.nodes->erase(extra_nop);
|
||||
|
||||
for (auto const & resolve : lcontext.resolve_address)
|
||||
std::get<instruction_address>(resolve.address->instruction).target = lcontext.functions.at(resolve.target);
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ namespace pslang::ir
|
|||
|
||||
void print(std::ostream & out, module_context const & context)
|
||||
{
|
||||
print_impl(out, context.nodes, &context);
|
||||
print_impl(out, *context.nodes, &context);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue