Compare commits
3 Commits
6f4ab269e2
...
8a2d98e69e
| Author | SHA1 | Date | |
|---|---|---|---|
| 8a2d98e69e | |||
| ad17a59d65 | |||
| 7995dd2bdf |
32
TODO.md
32
TODO.md
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -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:
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
Reference in New Issue
Block a user