Compare commits

...

3 Commits

Author SHA1 Message Date
8a2d98e69e feat: remove unused imports, todos and typos 2026-01-01 16:09:51 +01:00
ad17a59d65 feat: move allocator and slots into codegen folder 2026-01-01 16:09:33 +01:00
7995dd2bdf feat: write plan for future dev 2026-01-01 16:09:21 +01:00
5 changed files with 42 additions and 36 deletions

32
TODO.md
View File

@@ -1,6 +1,33 @@
0. Define how many physical regs are available, which are caller-saved and callee-saved # Milestones
1. Implement if-else and while statements
## Clean codebase structure
0. Prelude classes like FileIO, strings null-termination etc.
1. Diagnostic helper class for logging
2. Remove "void" valuehandle class and use it as ValueHandle::Type instead
3. Function multiple arguments support
4. Implement if-else and while statements
## Types support in language
## Stack based code generation
0. Stack based codegen, i.e. for fasm x86_64
## IR Optimizations aka const folding, deadcode elimination
## Register allocation
## First beta assembly code generation with registers
## ...
-------------------------------------------------
# References for IR optimizations
2. Find out what use[B] and def[B] are for each block 2. Find out what use[B] and def[B] are for each block
3. Define successors and predecessors of each block and make them accessible 3. Define successors and predecessors of each block and make them accessible
4. Compute liveIn[B] and liveOut[B] for each block 4. Compute liveIn[B] and liveOut[B] for each block
@@ -19,6 +46,7 @@
- Spill to stack slots - Spill to stack slots
- Add “CALL clobbers regs” rule - Add “CALL clobbers regs” rule
# References for register allocation
function's reserved registers: function's reserved registers:
EAX, ECX, EDX EAX, ECX, EDX

View File

@@ -1,18 +1,19 @@
#pragma once #pragma once
#include "prelude/string.hpp" #include "prelude/string.hpp"
#include "ir/slot.hpp" #include "codegen/slot.hpp"
#define AVAILABLE_REGISTERS 4 #define AVAILABLE_REGISTERS 4
#define AVAILABLE_STACK_SIZE 4096 #define AVAILABLE_STACK_SIZE 4096
template<typename Slot, typename SlotAddr = const StringView&> template <typename Slot, typename SlotAddr = const StringView &>
class Allocator class Allocator
{ {
public: public:
virtual ~Allocator() {}; virtual ~Allocator() {};
public: public:
virtual const Slot& Allocate(SlotAddr addr) = 0; virtual const Slot &Allocate(SlotAddr addr) = 0;
virtual const Slot& Resolve(SlotAddr addr) = 0; virtual const Slot &Resolve(SlotAddr addr) = 0;
}; };
class SlotAllocator : public Allocator<IR::IRSlot> class SlotAllocator : public Allocator<IR::IRSlot>
@@ -20,8 +21,9 @@ class SlotAllocator : public Allocator<IR::IRSlot>
public: public:
SlotAllocator() = default; SlotAllocator() = default;
~SlotAllocator() = default; ~SlotAllocator() = default;
public: public:
const IR::IRSlot& Allocate(const StringView& addr) override const IR::IRSlot &Allocate(const StringView &addr) override
{ {
if (m_regs < AVAILABLE_REGISTERS) if (m_regs < AVAILABLE_REGISTERS)
{ {
@@ -38,7 +40,7 @@ public:
assert(0 && "failed to allocate local"); assert(0 && "failed to allocate local");
} }
const IR::IRSlot& Resolve(const StringView& addr) override const IR::IRSlot &Resolve(const StringView &addr) override
{ {
for (size_t i = 0; i < m_slots.size; ++i) for (size_t i = 0; i < m_slots.size; ++i)
{ {
@@ -50,10 +52,13 @@ public:
assert(0 && "could not resolve stack offset for specified address"); assert(0 && "could not resolve stack offset for specified address");
} }
public: public:
View<IR::IRSlot> slots() const { return m_slots.view(); } View<IR::IRSlot> slots() const { return m_slots.view(); }
public: public:
unsigned int GetStackSize() const { return m_offset_counter; } unsigned int GetStackSize() const { return m_offset_counter; }
public: public:
int m_regs = 0; int m_regs = 0;
unsigned int m_offset_counter = 0; unsigned int m_offset_counter = 0;

View File

@@ -2,8 +2,6 @@
#include <unordered_map> #include <unordered_map>
#include "prelude/string.hpp" #include "prelude/string.hpp"
#include "parser/ast.hpp" #include "parser/ast.hpp"
#include "ir/slot.hpp"
#include "ir/allocator.hpp"
#include "ir/value.hpp" #include "ir/value.hpp"
#include "ir/ops.hpp" #include "ir/ops.hpp"
@@ -158,7 +156,6 @@ namespace IR
} }
public: public:
// TODO: think about safety (copying m_ops->data before giving)
OpView ops() const { return OpView(m_ops->data, m_ops->size); } OpView ops() const { return OpView(m_ops->data, m_ops->size); }
private: private:

View File

@@ -32,7 +32,7 @@ namespace IR
StringView m_symbol; StringView m_symbol;
}; };
// TODO: Make function return value (i.e. inhreit the OpValued class instead) // TODO: Make function return value (i.e. inherit the OpValued class instead)
class FnOp : public Op class FnOp : public Op
{ {
public: public:
@@ -87,30 +87,6 @@ namespace IR
ValueHandle::Type *m_typ; ValueHandle::Type *m_typ;
}; };
// class LoadConstOp : public OpValued
// {
// public:
// LoadConstOp(ValueHandle *dest, long value)
// : OpValued(dest), m_value(value) {}
// ~LoadConstOp() {}
// OP_TYPE(LOAD_CONST)
// public:
// StringView Format(int indent) const override
// {
// StringBuilder sb;
// sb.AppendIndent(indent);
// sb << result()->Format() << " = LOAD_CONST " << m_value;
// return sb.view();
// }
// public:
// long value() const { return m_value; }
// private:
// long m_value;
// };
class LoadOp : public OpValued class LoadOp : public OpValued
{ {
public: public: