mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:57:35 +00:00
JSSpecCompiler: Prepare for building SSA
This commit introduces NamedVariableDeclaration and SSAVariableDeclaration and allows storing both of them in Variable node. Also, it adds additional structures in FunctionDefinition and BasicBlock, which will be used to store SSA form related information.
This commit is contained in:
parent
23164bc570
commit
0aeb7a26e9
11 changed files with 173 additions and 13 deletions
|
@ -4,6 +4,7 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/StringBuilder.h>
|
||||
|
||||
#include "AST/AST.h"
|
||||
|
@ -17,6 +18,15 @@ ErrorOr<void> AK::Formatter<ControlFlowGraph>::format(FormatBuilder& format_buil
|
|||
|
||||
for (auto const& block : control_flow_graph.blocks) {
|
||||
builder.appendff("{}:\n", block->m_index);
|
||||
for (auto const& phi_node : block->m_phi_nodes) {
|
||||
builder.appendff("{} = phi(", phi_node.var->name());
|
||||
for (auto const& branches : phi_node.branches) {
|
||||
builder.appendff("{}: {}", branches.block->m_index, branches.value->name());
|
||||
if (&branches != &phi_node.branches.last())
|
||||
builder.appendff(", ");
|
||||
}
|
||||
builder.appendff(")\n");
|
||||
}
|
||||
for (auto const& expression : block->m_expressions)
|
||||
builder.appendff("{}", expression);
|
||||
builder.appendff("{}\n", Tree(block->m_continuation));
|
||||
|
|
|
@ -16,15 +16,28 @@ namespace JSSpecCompiler {
|
|||
|
||||
class BasicBlock : public RefCounted<BasicBlock> {
|
||||
public:
|
||||
struct PhiNode {
|
||||
struct Branch {
|
||||
BasicBlockRef block;
|
||||
VariableRef value;
|
||||
};
|
||||
|
||||
VariableRef var;
|
||||
Vector<Branch> branches;
|
||||
};
|
||||
|
||||
BasicBlock(size_t index, NonnullRefPtr<ControlFlowOperator> continuation)
|
||||
: m_index(index)
|
||||
, m_continuation(move(continuation))
|
||||
, m_immediate_dominator(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
size_t m_index;
|
||||
Vector<PhiNode> m_phi_nodes;
|
||||
Vector<Tree> m_expressions;
|
||||
NonnullRefPtr<ControlFlowOperator> m_continuation;
|
||||
BasicBlockRef m_immediate_dominator;
|
||||
};
|
||||
|
||||
class ControlFlowGraph : public RefCounted<ControlFlowGraph> {
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Dan Klishch <danilklishch@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/NumericLimits.h>
|
||||
#include <AK/Vector.h>
|
||||
|
||||
namespace JSSpecCompiler {
|
||||
|
||||
struct VoidRef { };
|
||||
|
||||
template<typename T, typename NativeNodeRef = VoidRef>
|
||||
class EnableGraphPointers {
|
||||
public:
|
||||
class VertexBase {
|
||||
public:
|
||||
VertexBase() = default;
|
||||
VertexBase(size_t index)
|
||||
: m_index(index)
|
||||
{
|
||||
}
|
||||
|
||||
bool is_invalid() const { return m_index == invalid_node; }
|
||||
operator size_t() const { return m_index; }
|
||||
|
||||
explicit VertexBase(NativeNodeRef const& node)
|
||||
requires(!IsSame<NativeNodeRef, VoidRef>)
|
||||
: VertexBase(node->m_index)
|
||||
{
|
||||
}
|
||||
|
||||
auto& operator*() const { return m_instance->m_nodes[m_index]; }
|
||||
auto* operator->() const { return &m_instance->m_nodes[m_index]; }
|
||||
|
||||
protected:
|
||||
size_t m_index = invalid_node;
|
||||
};
|
||||
|
||||
using Vertex = VertexBase;
|
||||
|
||||
inline static constexpr size_t invalid_node = NumericLimits<size_t>::max();
|
||||
|
||||
template<typename Func>
|
||||
void with_graph(Func func)
|
||||
{
|
||||
m_instance = static_cast<T*>(this);
|
||||
func();
|
||||
m_instance = nullptr;
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
void with_graph(size_t n, Func func)
|
||||
{
|
||||
m_instance = static_cast<T*>(this);
|
||||
m_instance->m_nodes.resize(n);
|
||||
func();
|
||||
m_instance->m_nodes.clear();
|
||||
m_instance = nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
inline static thread_local T* m_instance = nullptr;
|
||||
};
|
||||
|
||||
}
|
|
@ -23,7 +23,7 @@ RecursionDecision ReferenceResolvingPass::on_entry(Tree tree)
|
|||
if (auto variable_name = as<UnresolvedReference>(binary_operation->m_left); variable_name) {
|
||||
auto name = variable_name->m_name;
|
||||
if (!m_function->m_local_variables.contains(name))
|
||||
m_function->m_local_variables.set(name, make_ref_counted<VariableDeclaration>(name));
|
||||
m_function->m_local_variables.set(name, make_ref_counted<NamedVariableDeclaration>(name));
|
||||
}
|
||||
}
|
||||
return RecursionDecision::Recurse;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue