aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2019-10-07 00:51:40 +0200
committerdec05eba <dec05eba@protonmail.com>2020-07-25 14:36:46 +0200
commit111bd0c7cb4b446c4bfe192b1df82845de17c005 (patch)
treef8efde64837e03f13dfb2baae3160a98bda8913a
parenta9a8cf8d337470bb9b4466aea9593df7f5fac776 (diff)
Rename ssa to ir
-rw-r--r--doc/Documentation.md2
-rw-r--r--include/ast.h8
-rw-r--r--include/bytecode/bytecode.h2
-rw-r--r--include/ir/ir.h165
-rw-r--r--include/parser.h2
-rw-r--r--include/ssa/ssa.h165
-rw-r--r--src/ast.c4
-rw-r--r--src/bytecode/bytecode.c274
-rw-r--r--src/compiler.c34
-rw-r--r--src/ir/ir.c (renamed from src/ssa/ssa.c)546
-rw-r--r--src/parser.c2
-rw-r--r--src/program.c2
12 files changed, 603 insertions, 603 deletions
diff --git a/doc/Documentation.md b/doc/Documentation.md
index f04a3a2..96cd3ef 100644
--- a/doc/Documentation.md
+++ b/doc/Documentation.md
@@ -29,7 +29,7 @@ is being called from. Which means that import index 1 is actually import index 0
@AmalReg is an alias for u8.
# Compiler flow
-(Tokenize&parse -> Resolve AST -> Generate SSA -> Generate bytecode) -> Generate program\
+(Tokenize&parse -> Resolve AST -> Generate IR -> Generate bytecode) -> Generate program\
Each step except the last is done using multiple threads in parallel and the output of each step is used
in the next step. The last step is not done in parallel because the last step is combining all bytecode
and writing it to a file, which is an IO bottlenecked operation and it won't benefit from multithreading
diff --git a/include/ast.h b/include/ast.h
index f62d31f..eaaf93e 100644
--- a/include/ast.h
+++ b/include/ast.h
@@ -11,7 +11,7 @@
#include "std/hash_map.h"
#include "number.h"
#include "binop_type.h"
-#include "ssa/ssa.h"
+#include "ir/ir.h"
#include <setjmp.h>
@@ -75,7 +75,7 @@ typedef enum {
AST_NOT_RESOLVED,
AST_RESOLVING,
AST_RESOLVED,
- AST_SSA_RESOLVED
+ AST_IR_RESOLVED
} AstResolveStatus;
typedef enum {
@@ -96,7 +96,7 @@ typedef struct {
typedef struct {
AstResolvedType type;
AstResolveStatus status;
- SsaRegister ssa_reg;
+ IrRegister ir_reg;
} AstResolveData;
typedef enum {
@@ -192,7 +192,7 @@ struct FunctionDecl {
LhsExpr *lhs_expr; /* Borrowed from the LhsExpr that owns this FunctionDecl if it exists, otherwise NULL */
FunctionSignature *signature; /* TODO: Make this a non-pointer type? */
Scope body;
- SsaFuncIndex ssa_func_index;
+ IrFuncIndex ir_func_index;
};
struct FunctionCall {
diff --git a/include/bytecode/bytecode.h b/include/bytecode/bytecode.h
index f649368..a70bb6f 100644
--- a/include/bytecode/bytecode.h
+++ b/include/bytecode/bytecode.h
@@ -173,6 +173,6 @@ CHECK_RESULT int bytecode_init(Bytecode *self, ArenaAllocator *allocator);
CHECK_RESULT int buffer_append_header(Buffer *program_data);
/* longjump to self->env on failure */
-void generate_bytecode_from_ssa(BytecodeCompilerContext *self);
+void generate_bytecode_from_ir(BytecodeCompilerContext *self);
#endif
diff --git a/include/ir/ir.h b/include/ir/ir.h
new file mode 100644
index 0000000..f7aa4a7
--- /dev/null
+++ b/include/ir/ir.h
@@ -0,0 +1,165 @@
+#ifndef AMALGAM_IR_H
+#define AMALGAM_IR_H
+
+#include "../std/buffer.h"
+#include "../std/hash_map.h"
+#include "../std/defs.h"
+#include "../defs.h"
+
+#include <setjmp.h>
+
+#define IR_ERR_EXTERN_FUNC_SIG_MISMATCH -20
+
+/* Important: The number of fields in this enum can't exceed 255 */
+typedef enum {
+ IR_ASSIGN_INTER,
+ IR_ASSIGN_STRING,
+ IR_ASSIGN_REG,
+ IR_ADD,
+ IR_SUB,
+ IR_IMUL,
+ IR_MUL,
+ IR_IDIV,
+ IR_DIV,
+ IR_EQUALS,
+ IR_NOT_EQUAL,
+ IR_AND,
+ IR_ILT,
+ IR_ILE,
+ IR_IGT,
+ IR_IGE,
+ IR_LT,
+ IR_LE,
+ IR_GT,
+ IR_GE,
+ IR_FUNC_START,
+ IR_FUNC_END,
+ IR_PUSH,
+ IR_PUSH_RET,
+ IR_CALL_START,
+ IR_CALL,
+ IR_CALL_EXTERN,
+ IR_JUMP_ZERO,
+ IR_JUMP,
+ IR_RET,
+ IR_LABEL
+} IrInstruction;
+
+typedef enum {
+ IR_NUMBER_TYPE_INTEGER,
+ IR_NUMBER_TYPE_FLOAT
+} IrNumberType;
+
+typedef struct {
+ union {
+ i64 integer;
+ f64 floating;
+ } value;
+ IrNumberType type;
+} IrNumber;
+
+typedef struct {
+ FunctionSignature *func_sig;
+ BufferView name;
+} IrExternFunc;
+
+typedef struct {
+ FunctionSignature *func_sig;
+ BufferView name;
+} IrExportFunc;
+
+typedef struct {
+ FunctionSignature *func_sig;
+} IrFunc;
+
+typedef i16 JumpOffset;
+typedef i16 IrRegister;
+typedef u16 IrIntermediateIndex;
+typedef u16 IrStringIndex;
+typedef u16 IrExternFuncIndex;
+typedef u16 IrExportFuncIndex;
+typedef u16 IrFuncIndex;
+typedef u16 IrLabelIndex;
+
+typedef struct {
+ Buffer/*instruction data*/ instructions;
+ HashMapType(IrNumber, IrIntermediateIndex) intermediates_map;
+ Buffer/*IrNumber*/ intermediates;
+ HashMapType(BufferView, IrStringIndex) strings_map;
+ Buffer/*BufferView*/ strings;
+ HashMapType(BufferView, IrExternFuncIndex) extern_funcs_map;
+ Buffer/*IrExternFunc*/ extern_funcs;
+ Buffer/*IrExportFunc*/ export_funcs;
+ Buffer/*IrFunc*/ funcs;
+
+ IrIntermediateIndex intermediate_counter;
+ IrStringIndex string_counter;
+ IrExternFuncIndex extern_func_counter;
+ IrExportFuncIndex export_func_counter;
+ IrFuncIndex func_counter;
+ IrRegister reg_counter;
+ IrRegister param_counter;
+ IrLabelIndex label_counter;
+ Parser *parser; /* Borrowed */
+} Ir;
+
+typedef struct {
+ IrRegister lhs;
+ u16 rhs;
+} IrInsForm1;
+
+typedef struct {
+ IrRegister result;
+ IrRegister lhs;
+ IrRegister rhs;
+} IrInsForm2;
+
+typedef struct {
+ u8 flags;
+ u16 num_local_vars_regs;
+} IrInsFuncStart;
+
+typedef struct {
+ FunctionDecl *func_decl;
+ u8 import_index;
+} IrInsFuncCall;
+
+typedef struct {
+ LhsExpr *func_decl_lhs;
+ int import_index;
+} IrInsFuncCallExtern;
+
+typedef struct {
+ u8 num_args;
+} IrInsCallStart;
+
+typedef struct {
+ IrRegister condition_reg;
+ IrLabelIndex target_label;
+} IrInsJumpZero;
+
+typedef struct {
+ IrLabelIndex target_label;
+} IrInsJump;
+
+/* None of these functions are thread-safe */
+IrNumber create_ir_integer(i64 value);
+IrNumber create_ir_float(f64 value);
+
+IrNumber ir_get_intermediate(Ir *self, IrIntermediateIndex index);
+BufferView ir_get_string(Ir *self, IrStringIndex index);
+
+CHECK_RESULT int ir_init(Ir *self, Parser *parser);
+
+typedef struct {
+ jmp_buf env;
+ Ir *ir;
+ amal_compiler *compiler;
+ /* 0 if the current scope belongs to the file, otherwise ParserFileScopeReference's import_index (the import file that contains the scope) */
+ u8 import_index;
+} IrCompilerContext;
+
+/* longjump to context->env on failure */
+void scope_generate_ir(Scope *self, IrCompilerContext *context);
+
+#endif
diff --git a/include/parser.h b/include/parser.h
index 88bed93..b9a09b2 100644
--- a/include/parser.h
+++ b/include/parser.h
@@ -29,7 +29,7 @@ struct Parser {
bool has_func_parent;
ArenaAllocator *allocator; /* Owned */
amal_compiler *compiler;
- Ssa *ssa;
+ Ir *ir;
bool started;
TokenizerError error;
ErrorContext error_context;
diff --git a/include/ssa/ssa.h b/include/ssa/ssa.h
deleted file mode 100644
index e8e68c3..0000000
--- a/include/ssa/ssa.h
+++ /dev/null
@@ -1,165 +0,0 @@
-#ifndef AMALGAM_SSA_H
-#define AMALGAM_SSA_H
-
-#include "../std/buffer.h"
-#include "../std/hash_map.h"
-#include "../std/defs.h"
-#include "../defs.h"
-
-#include <setjmp.h>
-
-#define SSA_ERR_EXTERN_FUNC_SIG_MISMATCH -20
-
-/* Important: The number of fields in this enum can't exceed 255 */
-typedef enum {
- SSA_ASSIGN_INTER,
- SSA_ASSIGN_STRING,
- SSA_ASSIGN_REG,
- SSA_ADD,
- SSA_SUB,
- SSA_IMUL,
- SSA_MUL,
- SSA_IDIV,
- SSA_DIV,
- SSA_EQUALS,
- SSA_NOT_EQUAL,
- SSA_AND,
- SSA_ILT,
- SSA_ILE,
- SSA_IGT,
- SSA_IGE,
- SSA_LT,
- SSA_LE,
- SSA_GT,
- SSA_GE,
- SSA_FUNC_START,
- SSA_FUNC_END,
- SSA_PUSH,
- SSA_PUSH_RET,
- SSA_CALL_START,
- SSA_CALL,
- SSA_CALL_EXTERN,
- SSA_JUMP_ZERO,
- SSA_JUMP,
- SSA_RET,
- SSA_LABEL
-} SsaInstruction;
-
-typedef enum {
- SSA_NUMBER_TYPE_INTEGER,
- SSA_NUMBER_TYPE_FLOAT
-} SsaNumberType;
-
-typedef struct {
- union {
- i64 integer;
- f64 floating;
- } value;
- SsaNumberType type;
-} SsaNumber;
-
-typedef struct {
- FunctionSignature *func_sig;
- BufferView name;
-} SsaExternFunc;
-
-typedef struct {
- FunctionSignature *func_sig;
- BufferView name;
-} SsaExportFunc;
-
-typedef struct {
- FunctionSignature *func_sig;
-} SsaFunc;
-
-typedef i16 JumpOffset;
-typedef i16 SsaRegister;
-typedef u16 SsaIntermediateIndex;
-typedef u16 SsaStringIndex;
-typedef u16 SsaExternFuncIndex;
-typedef u16 SsaExportFuncIndex;
-typedef u16 SsaFuncIndex;
-typedef u16 SsaLabelIndex;
-
-typedef struct {
- Buffer/*instruction data*/ instructions;
- HashMapType(SsaNumber, SsaIntermediateIndex) intermediates_map;
- Buffer/*SsaNumber*/ intermediates;
- HashMapType(BufferView, SsaStringIndex) strings_map;
- Buffer/*BufferView*/ strings;
- HashMapType(BufferView, SsaExternFuncIndex) extern_funcs_map;
- Buffer/*SsaExternFunc*/ extern_funcs;
- Buffer/*SsaExportFunc*/ export_funcs;
- Buffer/*SsaFunc*/ funcs;
-
- SsaIntermediateIndex intermediate_counter;
- SsaStringIndex string_counter;
- SsaExternFuncIndex extern_func_counter;
- SsaExportFuncIndex export_func_counter;
- SsaFuncIndex func_counter;
- SsaRegister reg_counter;
- SsaRegister param_counter;
- SsaLabelIndex label_counter;
- Parser *parser; /* Borrowed */
-} Ssa;
-
-typedef struct {
- SsaRegister lhs;
- u16 rhs;
-} SsaInsForm1;
-
-typedef struct {
- SsaRegister result;
- SsaRegister lhs;
- SsaRegister rhs;
-} SsaInsForm2;
-
-typedef struct {
- u8 flags;
- u16 num_local_vars_regs;
-} SsaInsFuncStart;
-
-typedef struct {
- FunctionDecl *func_decl;
- u8 import_index;
-} SsaInsFuncCall;
-
-typedef struct {
- LhsExpr *func_decl_lhs;
- int import_index;
-} SsaInsFuncCallExtern;
-
-typedef struct {
- u8 num_args;
-} SsaInsCallStart;
-
-typedef struct {
- SsaRegister condition_reg;
- SsaLabelIndex target_label;
-} SsaInsJumpZero;
-
-typedef struct {
- SsaLabelIndex target_label;
-} SsaInsJump;
-
-/* None of these functions are thread-safe */
-SsaNumber create_ssa_integer(i64 value);
-SsaNumber create_ssa_float(f64 value);
-
-SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index);
-BufferView ssa_get_string(Ssa *self, SsaStringIndex index);
-
-CHECK_RESULT int ssa_init(Ssa *self, Parser *parser);
-
-typedef struct {
- jmp_buf env;
- Ssa *ssa;
- amal_compiler *compiler;
- /* 0 if the current scope belongs to the file, otherwise ParserFileScopeReference's import_index (the import file that contains the scope) */
- u8 import_index;
-} SsaCompilerContext;
-
-/* longjump to context->env on failure */
-void scope_generate_ssa(Scope *self, SsaCompilerContext *context);
-
-#endif
diff --git a/src/ast.c b/src/ast.c
index e18b906..04ec646 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -136,7 +136,7 @@ static AstResolvedType scope_named_object_get_resolved_type(ScopeNamedObject *se
static void resolve_data_init(AstResolveData *self) {
self->status = AST_NOT_RESOLVED;
ast_resolved_type_init(&self->type);
- self->ssa_reg = 0;
+ self->ir_reg = 0;
}
int ast_create(ArenaAllocator *allocator, void *value, AstType type, Ast **result) {
@@ -287,7 +287,7 @@ void function_parameter_init(FunctionParameter *self) {
int funcdecl_init(FunctionDecl *self, FunctionSignature *signature, Scope *parent, ArenaAllocator *allocator) {
self->lhs_expr = NULL;
self->signature = signature;
- self->ssa_func_index = 0;
+ self->ir_func_index = 0;
return scope_init(&self->body, parent, allocator);
}
diff --git a/src/bytecode/bytecode.c b/src/bytecode/bytecode.c
index 98698bc..af9251b 100644
--- a/src/bytecode/bytecode.c
+++ b/src/bytecode/bytecode.c
@@ -1,7 +1,7 @@
#include "../../include/bytecode/bytecode.h"
#include "../../include/std/mem.h"
#include "../../include/std/log.h"
-#include "../../include/ssa/ssa.h"
+#include "../../include/ir/ir.h"
#include "../../include/parser.h"
#include "../../include/ast.h"
#include "../../include/compiler.h"
@@ -60,7 +60,7 @@ CHECK_RESULT int buffer_append_header(Buffer *program_data) {
return 0;
}
-static CHECK_RESULT usize ssa_extract_data(u8 *instruction_data, void *result, usize size) {
+static CHECK_RESULT usize ir_extract_data(u8 *instruction_data, void *result, usize size) {
am_memcpy(result, instruction_data, size);
return size;
}
@@ -80,13 +80,13 @@ static void add_intermediates(BytecodeCompilerContext *self) {
|u64 |Value|The type of the value depends on the value of @Type.|
*/
- Ssa *ssa = self->parser->ssa;
+ Ir *ir = self->parser->ir;
Buffer *instructions = &self->bytecode->data;
- SsaNumber *intermediate = buffer_begin(&ssa->intermediates);
- SsaNumber *intermediates_end = buffer_end(&ssa->intermediates);
+ IrNumber *intermediate = buffer_begin(&ir->intermediates);
+ IrNumber *intermediates_end = buffer_end(&ir->intermediates);
int i = 0;
- u32 intemediates_size = (sizeof(u8) + sizeof(u64)) * buffer_get_size(&ssa->intermediates, SsaNumber);
+ u32 intemediates_size = (sizeof(u8) + sizeof(u64)) * buffer_get_size(&ir->intermediates, IrNumber);
throw_if_error(buffer_expand(instructions, sizeof(u32) + intemediates_size));
throw_if_error(buffer_append(instructions, &intemediates_size, sizeof(u32)));
for(; intermediate != intermediates_end; ++intermediate) {
@@ -113,19 +113,19 @@ static void add_strings(BytecodeCompilerContext *self) {
|u8* |Data|The data of the string, where the size is defined by @Size. Strings are null-terminated.|
*/
- Ssa *ssa = self->parser->ssa;
+ Ir *ir = self->parser->ir;
Buffer *instructions = &self->bytecode->data;
- BufferView *string = buffer_begin(&ssa->strings);
- BufferView *strings_end = buffer_end(&ssa->strings);
+ BufferView *string = buffer_begin(&ir->strings);
+ BufferView *strings_end = buffer_end(&ir->strings);
u32 strings_size = 0;
for(; string != strings_end; ++string) {
strings_size += sizeof(u16) + string->size + 1; /* +1 for null-termination of string */
}
- string = buffer_begin(&ssa->strings);
+ string = buffer_begin(&ir->strings);
throw_if_error(buffer_expand(instructions, sizeof(u16) + sizeof(u32) + strings_size));
- throw_if_error(buffer_append(instructions, &ssa->string_counter, sizeof(u16)));
+ throw_if_error(buffer_append(instructions, &ir->string_counter, sizeof(u16)));
throw_if_error(buffer_append(instructions, &strings_size, sizeof(u32)));
for(; string != strings_end; ++string) {
const char null_s = '\0';
@@ -188,16 +188,16 @@ static void add_functions(BytecodeCompilerContext *self) {
|u32 |return_types_fixed_size |The size of all non-pointer type return types, in bytes. |
*/
- Ssa *ssa = self->parser->ssa;
+ Ir *ir = self->parser->ir;
Buffer *instructions = &self->bytecode->data;
- SsaFunc *func = buffer_begin(&ssa->funcs);
- SsaFunc *func_end = buffer_end(&ssa->funcs);
- u32 funcs_size = (u32)ssa->func_counter * sizeof(BytecodeHeaderFunction);
+ IrFunc *func = buffer_begin(&ir->funcs);
+ IrFunc *func_end = buffer_end(&ir->funcs);
+ u32 funcs_size = (u32)ir->func_counter * sizeof(BytecodeHeaderFunction);
assert(sizeof(BytecodeHeaderFunction) == 22);
self->bytecode->funcs_index = instructions->size;
throw_if_error(buffer_expand(instructions, sizeof(u16) + sizeof(u32) + funcs_size));
- throw_if_error(buffer_append(instructions, &ssa->func_counter, sizeof(u16)));
+ throw_if_error(buffer_append(instructions, &ir->func_counter, sizeof(u16)));
throw_if_error(buffer_append(instructions, &funcs_size, sizeof(u32)));
for(; func != func_end; ++func) {
BytecodeHeaderFunction header_func;
@@ -216,7 +216,7 @@ static void add_functions(BytecodeCompilerContext *self) {
throw_if_error(buffer_append(instructions, &header_func, sizeof(header_func)));
}
- assert(sizeof(ssa->func_counter) == sizeof(u16) && "Program decoder needs to be updated since size of func index has changed");
+ assert(sizeof(ir->func_counter) == sizeof(u16) && "Program decoder needs to be updated since size of func index has changed");
}
static void add_extern_functions(BytecodeCompilerContext *self) {
@@ -241,21 +241,21 @@ static void add_extern_functions(BytecodeCompilerContext *self) {
|u32 |return_types_fixed_size |The size of all non-pointer type return types, in bytes. |
|u8[]|name |The name of the external function, where the size is defined by @name_len. Names are null-terminated.|
*/
- Ssa *ssa = self->parser->ssa;
+ Ir *ir = self->parser->ir;
Buffer *instructions = &self->bytecode->data;
- SsaExternFunc *extern_func = buffer_begin(&ssa->extern_funcs);
- SsaExternFunc *extern_func_end = buffer_end(&ssa->extern_funcs);
- u32 extern_funcs_size = (u32)ssa->extern_func_counter * sizeof(BytecodeHeaderExternFunction);
+ IrExternFunc *extern_func = buffer_begin(&ir->extern_funcs);
+ IrExternFunc *extern_func_end = buffer_end(&ir->extern_funcs);
+ u32 extern_funcs_size = (u32)ir->extern_func_counter * sizeof(BytecodeHeaderExternFunction);
assert(sizeof(BytecodeHeaderExternFunction) == 20);
for(; extern_func != extern_func_end; ++extern_func) {
extern_funcs_size += extern_func->name.size + 1; /* +1 for null-termination of string */
}
- extern_func = buffer_begin(&ssa->extern_funcs);
+ extern_func = buffer_begin(&ir->extern_funcs);
self->bytecode->extern_funcs_index = instructions->size;
throw_if_error(buffer_expand(instructions, sizeof(u16) + sizeof(u32) + extern_funcs_size));
- throw_if_error(buffer_append(instructions, &ssa->extern_func_counter, sizeof(u16)));
+ throw_if_error(buffer_append(instructions, &ir->extern_func_counter, sizeof(u16)));
throw_if_error(buffer_append(instructions, &extern_funcs_size, sizeof(u32)));
for(; extern_func != extern_func_end; ++extern_func) {
const char null_s = '\0';
@@ -288,7 +288,7 @@ static void add_extern_functions(BytecodeCompilerContext *self) {
throw_if_error(buffer_append(instructions, &null_s, sizeof(char)));
}
- assert(sizeof(SsaExternFuncIndex) == sizeof(u16) && "Program decoder needs to be updated since size of extern func index has changed");
+ assert(sizeof(IrExternFuncIndex) == sizeof(u16) && "Program decoder needs to be updated since size of extern func index has changed");
}
static void add_export_functions(BytecodeCompilerContext *self) {
@@ -308,19 +308,19 @@ static void add_export_functions(BytecodeCompilerContext *self) {
|u8 |name_len |The length of the exported function name, in bytes. Excluding the null-terminate character. |
|u8[]|name |The name of the exported function, where the size is defined by @name_len. Names are null-terminated. |
*/
- Ssa *ssa = self->parser->ssa;
+ Ir *ir = self->parser->ir;
Buffer *instructions = &self->bytecode->data;
- SsaExportFunc *export_func = buffer_begin(&ssa->export_funcs);
- SsaExportFunc *export_func_end = buffer_end(&ssa->export_funcs);
- u32 export_funcs_size = (u32)ssa->export_func_counter * (sizeof(u32) + sizeof(u8) + sizeof(u8));
+ IrExportFunc *export_func = buffer_begin(&ir->export_funcs);
+ IrExportFunc *export_func_end = buffer_end(&ir->export_funcs);
+ u32 export_funcs_size = (u32)ir->export_func_counter * (sizeof(u32) + sizeof(u8) + sizeof(u8));
for(; export_func != export_func_end; ++export_func) {
export_funcs_size += export_func->name.size + 1; /* +1 for null-termination of string */
}
- export_func = buffer_begin(&ssa->export_funcs);
+ export_func = buffer_begin(&ir->export_funcs);
throw_if_error(buffer_expand(instructions, sizeof(u16) + sizeof(u32) + export_funcs_size));
- throw_if_error(buffer_append(instructions, &ssa->export_func_counter, sizeof(u16)));
+ throw_if_error(buffer_append(instructions, &ir->export_func_counter, sizeof(u16)));
throw_if_error(buffer_append(instructions, &export_funcs_size, sizeof(u32)));
for(; export_func != export_func_end; ++export_func) {
const char null_s = '\0';
@@ -333,7 +333,7 @@ static void add_export_functions(BytecodeCompilerContext *self) {
throw_if_error(buffer_append(instructions, &null_s, sizeof(char)));
}
- assert(sizeof(SsaExportFuncIndex) == sizeof(u16) && "Program decoder needs to be updated since size of export func index has changed");
+ assert(sizeof(IrExportFuncIndex) == sizeof(u16) && "Program decoder needs to be updated since size of export func index has changed");
}
static void add_imports(BytecodeCompilerContext *self) {
@@ -455,183 +455,183 @@ static void add_instructions(BytecodeCompilerContext *self) {
|Instruction[]|Instructions data|The instructions data. Each instructions begins with an opcode, see #Opcode|
*/
- SsaInsForm1 ssa_ins_form1;
- SsaInsForm2 ssa_ins_form2;
- SsaInsFuncStart ssa_ins_func_start;
- SsaInsFuncCall ssa_ins_func_call;
- SsaInsFuncCallExtern ssa_ins_func_call_extern;
- SsaInsCallStart ssa_ins_call_start;
- SsaInsJumpZero ssa_ins_jump_zero;
- SsaInsJump ssa_ins_jump;
-
- Ssa *ssa = self->parser->ssa;
- u8 *instruction = buffer_begin(&ssa->instructions);
- u8 *instructions_end = buffer_end(&ssa->instructions);
+ IrInsForm1 ir_ins_form1;
+ IrInsForm2 ir_ins_form2;
+ IrInsFuncStart ir_ins_func_start;
+ IrInsFuncCall ir_ins_func_call;
+ IrInsFuncCallExtern ir_ins_func_call_extern;
+ IrInsCallStart ir_ins_call_start;
+ IrInsJumpZero ir_ins_jump_zero;
+ IrInsJump ir_ins_jump;
+
+ Ir *ir = self->parser->ir;
+ u8 *instruction = buffer_begin(&ir->instructions);
+ u8 *instructions_end = buffer_end(&ir->instructions);
u16 label_counter = 0;
u32 num_instructions_index = self->bytecode->data.size;
throw_if_error(buffer_append_empty(&self->bytecode->data, sizeof(num_instructions_index)));
while(instruction != instructions_end) {
- SsaInstruction ins = (SsaInstruction)*instruction++;
+ IrInstruction ins = (IrInstruction)*instruction++;
switch(ins) {
- case SSA_ASSIGN_INTER: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
- add_ins6(self, AMAL_OP_MOVI, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movi r%d, i%d");
+ case IR_ASSIGN_INTER: {
+ instruction += ir_extract_data(instruction, &ir_ins_form1, sizeof(ir_ins_form1));
+ add_ins6(self, AMAL_OP_MOVI, ir_ins_form1.lhs, ir_ins_form1.rhs, "movi r%d, i%d");
break;
}
- case SSA_ASSIGN_STRING: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
- add_ins6(self, AMAL_OP_MOVD, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "movd r%d, s%d");
+ case IR_ASSIGN_STRING: {
+ instruction += ir_extract_data(instruction, &ir_ins_form1, sizeof(ir_ins_form1));
+ add_ins6(self, AMAL_OP_MOVD, ir_ins_form1.lhs, ir_ins_form1.rhs, "movd r%d, s%d");
break;
}
- case SSA_ASSIGN_REG: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form1, sizeof(ssa_ins_form1));
- add_ins3(self, AMAL_OP_MOV, ssa_ins_form1.lhs, ssa_ins_form1.rhs, "mov r%d, r%d");
+ case IR_ASSIGN_REG: {
+ instruction += ir_extract_data(instruction, &ir_ins_form1, sizeof(ir_ins_form1));
+ add_ins3(self, AMAL_OP_MOV, ir_ins_form1.lhs, ir_ins_form1.rhs, "mov r%d, r%d");
break;
}
- case SSA_ADD: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_ADD, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "add r%d, r%d, r%d");
+ case IR_ADD: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_ADD, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "add r%d, r%d, r%d");
break;
}
- case SSA_SUB: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_SUB, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "sub r%d, r%d, r%d");
+ case IR_SUB: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_SUB, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "sub r%d, r%d, r%d");
break;
}
- case SSA_IMUL: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_IMUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "imul r%d, r%d, r%d");
+ case IR_IMUL: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_IMUL, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "imul r%d, r%d, r%d");
break;
}
- case SSA_MUL: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_MUL, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "mul r%d, r%d, r%d");
+ case IR_MUL: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_MUL, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "mul r%d, r%d, r%d");
break;
}
- case SSA_IDIV: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_IDIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "idiv r%d, r%d, r%d");
+ case IR_IDIV: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_IDIV, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "idiv r%d, r%d, r%d");
break;
}
- case SSA_DIV: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_DIV, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "div r%d, r%d, r%d");
+ case IR_DIV: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_DIV, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "div r%d, r%d, r%d");
break;
}
- case SSA_EQUALS: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_EQ, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "eq r%d, r%d, r%d");
+ case IR_EQUALS: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_EQ, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "eq r%d, r%d, r%d");
break;
}
- case SSA_NOT_EQUAL: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_NEQ, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "neq r%d, r%d, r%d");
+ case IR_NOT_EQUAL: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_NEQ, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "neq r%d, r%d, r%d");
break;
}
- case SSA_AND: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_BIT_AND, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "and r%d, r%d, r%d");
+ case IR_AND: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_BIT_AND, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "and r%d, r%d, r%d");
break;
}
- case SSA_ILT: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_ILT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ilt r%d, r%d, r%d");
+ case IR_ILT: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_ILT, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "ilt r%d, r%d, r%d");
break;
}
- case SSA_ILE: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_ILE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ile r%d, r%d, r%d");
+ case IR_ILE: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_ILE, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "ile r%d, r%d, r%d");
break;
}
- case SSA_IGT: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_IGT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "igt r%d, r%d, r%d");
+ case IR_IGT: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_IGT, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "igt r%d, r%d, r%d");
break;
}
- case SSA_IGE: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_IGE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ige r%d, r%d, r%d");
+ case IR_IGE: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_IGE, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "ige r%d, r%d, r%d");
break;
}
- case SSA_LT: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_LT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "lt r%d, r%d, r%d");
+ case IR_LT: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_LT, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "lt r%d, r%d, r%d");
break;
}
- case SSA_LE: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_LE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "le r%d, r%d, r%d");
+ case IR_LE: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_LE, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "le r%d, r%d, r%d");
break;
}
- case SSA_GT: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_GT, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "gt r%d, r%d, r%d");
+ case IR_GT: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_GT, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "gt r%d, r%d, r%d");
break;
}
- case SSA_GE: {
- instruction += ssa_extract_data(instruction, &ssa_ins_form2, sizeof(ssa_ins_form2));
- add_ins5(self, AMAL_OP_GE, ssa_ins_form2.result, ssa_ins_form2.lhs, ssa_ins_form2.rhs, "ge r%d, r%d, r%d");
+ case IR_GE: {
+ instruction += ir_extract_data(instruction, &ir_ins_form2, sizeof(ir_ins_form2));
+ add_ins5(self, AMAL_OP_GE, ir_ins_form2.result, ir_ins_form2.lhs, ir_ins_form2.rhs, "ge r%d, r%d, r%d");
break;
}
- case SSA_FUNC_START: {
- instruction += ssa_extract_data(instruction, &ssa_ins_func_start, sizeof(ssa_ins_func_start));
- add_ins6(self, AMAL_OP_FUNC_START, ssa_ins_func_start.flags, ssa_ins_func_start.num_local_vars_regs, "func_start 0x%02x, %u");
+ case IR_FUNC_START: {
+ instruction += ir_extract_data(instruction, &ir_ins_func_start, sizeof(ir_ins_func_start));
+ add_ins6(self, AMAL_OP_FUNC_START, ir_ins_func_start.flags, ir_ins_func_start.num_local_vars_regs, "func_start 0x%02x, %u");
label_counter = 0;
break;
}
- case SSA_FUNC_END: {
+ case IR_FUNC_END: {
add_ins1(self, AMAL_OP_FUNC_END, "func_end");
break;
}
- case SSA_PUSH: {
- SsaRegister reg;
- am_memcpy(&reg, instruction, sizeof(SsaRegister));
- instruction += sizeof(SsaRegister);
+ case IR_PUSH: {
+ IrRegister reg;
+ am_memcpy(&reg, instruction, sizeof(IrRegister));
+ instruction += sizeof(IrRegister);
add_ins2(self, AMAL_OP_PUSH, reg, "push r%d");
break;
}
- case SSA_PUSH_RET: {
- SsaRegister reg;
- am_memcpy(&reg, instruction, sizeof(SsaRegister));
- instruction += sizeof(SsaRegister);
+ case IR_PUSH_RET: {
+ IrRegister reg;
+ am_memcpy(&reg, instruction, sizeof(IrRegister));
+ instruction += sizeof(IrRegister);
add_ins2(self, AMAL_OP_PUSH_RET, reg, "push_ret r%d");
break;
}
- case SSA_CALL_START: {
- instruction += ssa_extract_data(instruction, &ssa_ins_call_start, sizeof(ssa_ins_call_start));
- add_ins2(self, AMAL_OP_CALL_START, ssa_ins_call_start.num_args, "call_start %d");
+ case IR_CALL_START: {
+ instruction += ir_extract_data(instruction, &ir_ins_call_start, sizeof(ir_ins_call_start));
+ add_ins2(self, AMAL_OP_CALL_START, ir_ins_call_start.num_args, "call_start %d");
break;
}
- case SSA_CALL: {
- instruction += ssa_extract_data(instruction, &ssa_ins_func_call, sizeof(ssa_ins_func_call));
- add_ins6(self, AMAL_OP_CALL, ssa_ins_func_call.import_index, ssa_ins_func_call.func_decl->ssa_func_index, "call f(%d,%d)");
+ case IR_CALL: {
+ instruction += ir_extract_data(instruction, &ir_ins_func_call, sizeof(ir_ins_func_call));
+ add_ins6(self, AMAL_OP_CALL, ir_ins_func_call.import_index, ir_ins_func_call.func_decl->ir_func_index, "call f(%d,%d)");
break;
}
- case SSA_CALL_EXTERN: {
- instruction += ssa_extract_data(instruction, &ssa_ins_func_call_extern, sizeof(ssa_ins_func_call_extern));
- add_ins6(self, AMAL_OP_CALLE, ssa_ins_func_call_extern.import_index, ssa_ins_func_call_extern.func_decl_lhs->extern_index, "calle ef(%d,%d)");
+ case IR_CALL_EXTERN: {
+ instruction += ir_extract_data(instruction, &ir_ins_func_call_extern, sizeof(ir_ins_func_call_extern));
+ add_ins6(self, AMAL_OP_CALLE, ir_ins_func_call_extern.import_index, ir_ins_func_call_extern.func_decl_lhs->extern_index, "calle ef(%d,%d)");
break;
}
- case SSA_JUMP_ZERO: {
- instruction += ssa_extract_data(instruction, &ssa_ins_jump_zero, sizeof(ssa_ins_jump_zero));
- add_ins6(self, AMAL_OP_JZ, ssa_ins_jump_zero.condition_reg, ssa_ins_jump_zero.target_label, "jz r%d, l%d");
+ case IR_JUMP_ZERO: {
+ instruction += ir_extract_data(instruction, &ir_ins_jump_zero, sizeof(ir_ins_jump_zero));
+ add_ins6(self, AMAL_OP_JZ, ir_ins_jump_zero.condition_reg, ir_ins_jump_zero.target_label, "jz r%d, l%d");
break;
}
- case SSA_JUMP: {
- instruction += ssa_extract_data(instruction, &ssa_ins_jump, sizeof(ssa_ins_jump));
- add_ins4(self, AMAL_OP_JMP, ssa_ins_jump.target_label, "jmp l%d");
+ case IR_JUMP: {
+ instruction += ir_extract_data(instruction, &ir_ins_jump, sizeof(ir_ins_jump));
+ add_ins4(self, AMAL_OP_JMP, ir_ins_jump.target_label, "jmp l%d");
break;
}
- case SSA_RET: {
- SsaRegister reg;
- am_memcpy(&reg, instruction, sizeof(SsaRegister));
- instruction += sizeof(SsaRegister);
+ case IR_RET: {
+ IrRegister reg;
+ am_memcpy(&reg, instruction, sizeof(IrRegister));
+ instruction += sizeof(IrRegister);
add_ins2(self, AMAL_OP_RET, reg, "ret r%d");
break;
}
- case SSA_LABEL: {
+ case IR_LABEL: {
add_ins1(self, AMAL_OP_LABEL, NULL);
fprintf(stderr, "label l%d\n", label_counter++);
break;
@@ -652,7 +652,7 @@ static void add_section_magic_number(BytecodeCompilerContext *self) {
throw_if_error(buffer_append(&self->bytecode->data, &section_magic_number, sizeof(section_magic_number)));
}
-void generate_bytecode_from_ssa(BytecodeCompilerContext *self) {
+void generate_bytecode_from_ir(BytecodeCompilerContext *self) {
add_section_magic_number(self);
add_intermediates(self);
diff --git a/src/compiler.c b/src/compiler.c
index 46d20a8..48ba71e 100644
--- a/src/compiler.c
+++ b/src/compiler.c
@@ -1,6 +1,6 @@
#include "../include/compiler.h"
#include "../include/parser.h"
-#include "../include/ssa/ssa.h"
+#include "../include/ir/ir.h"
#include "../include/bytecode/bytecode.h"
#include "../include/std/log.h"
#include "../include/std/mem.h"
@@ -169,7 +169,7 @@ void amal_compiler_deinit(amal_compiler *self) {
typedef enum {
THREAD_WORK_PARSE,
THREAD_WORK_RESOLVE_AST,
- THREAD_WORK_GENERATE_SSA,
+ THREAD_WORK_GENERATE_IR,
THREAD_WORK_GENERATE_BYTECODE
} ThreadWorkType;
@@ -254,20 +254,20 @@ static CHECK_RESULT int thread_resolve_ast(amal_compiler *compiler, Parser *pars
return result;
}
-static CHECK_RESULT int thread_generate_ssa(Parser *parser) {
- SsaCompilerContext compiler_context;
+static CHECK_RESULT int thread_generate_ir(Parser *parser) {
+ IrCompilerContext compiler_context;
int result;
- return_if_error(arena_allocator_alloc(parser->allocator, sizeof(Ssa), (void**)&compiler_context.ssa));
- return_if_error(ssa_init(compiler_context.ssa, parser));
+ return_if_error(arena_allocator_alloc(parser->allocator, sizeof(Ir), (void**)&compiler_context.ir));
+ return_if_error(ir_init(compiler_context.ir, parser));
compiler_context.compiler = parser->compiler;
compiler_context.import_index = 0;
- parser->ssa = compiler_context.ssa;
- amal_log_debug("Generating SSA for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data);
+ parser->ir = compiler_context.ir;
+ amal_log_debug("Generating IR for file: %.*s", parser->tokenizer.code_name.size, parser->tokenizer.code_name.data);
result = setjmp(compiler_context.env);
if(result == 0)
- scope_generate_ssa(&parser->struct_decl.body, &compiler_context);
+ scope_generate_ir(&parser->struct_decl.body, &compiler_context);
return result;
}
@@ -283,7 +283,7 @@ static CHECK_RESULT int thread_generate_bytecode(Parser *parser) {
result = setjmp(compiler_context.env);
if(result == 0) {
- generate_bytecode_from_ssa(&compiler_context);
+ generate_bytecode_from_ir(&compiler_context);
parser->bytecode = compiler_context.bytecode;
}
@@ -301,8 +301,8 @@ static int thread_callback_generic(void *userdata) {
case THREAD_WORK_RESOLVE_AST:
result = thread_resolve_ast(compiler_userdata->compiler, compiler_userdata->parser);
break;
- case THREAD_WORK_GENERATE_SSA:
- result = thread_generate_ssa(compiler_userdata->parser);
+ case THREAD_WORK_GENERATE_IR:
+ result = thread_generate_ir(compiler_userdata->parser);
break;
case THREAD_WORK_GENERATE_BYTECODE:
result = thread_generate_bytecode(compiler_userdata->parser);
@@ -327,7 +327,7 @@ static CHECK_RESULT int amal_compiler_add_task(amal_compiler *self, ThreadWorkDa
break;
}
case THREAD_WORK_RESOLVE_AST:
- case THREAD_WORK_GENERATE_SSA:
+ case THREAD_WORK_GENERATE_IR:
case THREAD_WORK_GENERATE_BYTECODE: {
CompilerGenericThreadUserData *userdata;
cleanup_if_error(am_malloc(sizeof(CompilerGenericThreadUserData), (void**)&userdata));
@@ -521,7 +521,7 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
if(main_job) {
/*doc(Compiler flow)
- (Tokenize&parse -> Resolve AST -> Generate SSA -> Generate bytecode) -> Generate program\
+ (Tokenize&parse -> Resolve AST -> Generate IR -> Generate bytecode) -> Generate program\
Each step except the last is done using multiple threads in parallel and the output of each step is used
in the next step. The last step is not done in parallel because the last step is combining all bytecode
and writing it to a file, which is an IO bottlenecked operation and it won't benefit from multithreading
@@ -542,10 +542,10 @@ int amal_compiler_internal_load_file(amal_compiler *self, const char *filepath,
main_func->decl_flags |= DECL_FLAG_EXPORT;
return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_RESOLVE_AST));
- amal_log_info("Finished resolving AST, generating SSA");
+ amal_log_info("Finished resolving AST, generating IR");
- return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_SSA));
- amal_log_info("Finished generating SSA");
+ return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_IR));
+ amal_log_info("Finished generating IR");
return_if_error(amal_compiler_dispatch_generic(self, THREAD_WORK_GENERATE_BYTECODE));
amal_compiler_update_import_references(self);
diff --git a/src/ssa/ssa.c b/src/ir/ir.c
index 44b5589..62d3516 100644
--- a/src/ssa/ssa.c
+++ b/src/ir/ir.c
@@ -1,4 +1,4 @@
-#include "../../include/ssa/ssa.h"
+#include "../../include/ir/ir.h"
#include "../../include/std/mem.h"
#include "../../include/std/log.h"
#include "../../include/std/hash.h"
@@ -9,7 +9,7 @@
#include <assert.h>
/*
- TODO: Instead of using memcpy to copy data to the ssa, make it cleaner by
+ TODO: Instead of using memcpy to copy data to the ir, make it cleaner by
defining all the data in structs and copying the structs. Even if it takes more space,
it might even be faster.
*/
@@ -27,42 +27,42 @@ do { \
#define MAX_STRING_LENGTH UINT16_MAX
#define FUNC_MAX_ARGS 128
-static CHECK_RESULT SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context);
+static CHECK_RESULT IrRegister variable_generate_ir(Variable *self, IrCompilerContext *context);
static int compare_number(const void *a, const void *b) {
- const SsaNumber *lhs = a;
- const SsaNumber *rhs = b;
+ const IrNumber *lhs = a;
+ const IrNumber *rhs = b;
return (rhs->type == lhs->type && rhs->value.integer == lhs->value.integer);
}
static usize hash_number(const u8 *data, usize size) {
- SsaNumber number;
- assert(size == sizeof(SsaNumber));
+ IrNumber number;
+ assert(size == sizeof(IrNumber));
am_memcpy(&number, data, size);
return number.value.integer;
}
-SsaNumber create_ssa_integer(i64 value) {
- SsaNumber result;
+IrNumber create_ir_integer(i64 value) {
+ IrNumber result;
result.value.integer = value;
- result.type = SSA_NUMBER_TYPE_INTEGER;
+ result.type = IR_NUMBER_TYPE_INTEGER;
return result;
}
-SsaNumber create_ssa_float(f64 value) {
- SsaNumber result;
+IrNumber create_ir_float(f64 value) {
+ IrNumber result;
result.value.floating = value;
- result.type = SSA_NUMBER_TYPE_FLOAT;
+ result.type = IR_NUMBER_TYPE_FLOAT;
return result;
}
-int ssa_init(Ssa *self, Parser *parser) {
+int ir_init(Ir *self, Parser *parser) {
return_if_error(buffer_init(&self->instructions, parser->allocator));
- return_if_error(hash_map_init(&self->intermediates_map, parser->allocator, sizeof(SsaIntermediateIndex), compare_number, hash_number));
+ return_if_error(hash_map_init(&self->intermediates_map, parser->allocator, sizeof(IrIntermediateIndex), compare_number, hash_number));
return_if_error(buffer_init(&self->intermediates, parser->allocator));
- return_if_error(hash_map_init(&self->strings_map, parser->allocator, sizeof(SsaStringIndex), hash_map_compare_string, amal_hash_string));
+ return_if_error(hash_map_init(&self->strings_map, parser->allocator, sizeof(IrStringIndex), hash_map_compare_string, amal_hash_string));
return_if_error(buffer_init(&self->strings, parser->allocator));
- return_if_error(hash_map_init(&self->extern_funcs_map, parser->allocator, sizeof(SsaExternFuncIndex), hash_map_compare_string, amal_hash_string));
+ return_if_error(hash_map_init(&self->extern_funcs_map, parser->allocator, sizeof(IrExternFuncIndex), hash_map_compare_string, amal_hash_string));
return_if_error(buffer_init(&self->extern_funcs, parser->allocator));
return_if_error(buffer_init(&self->export_funcs, parser->allocator));
return_if_error(buffer_init(&self->funcs, parser->allocator));
@@ -78,11 +78,11 @@ int ssa_init(Ssa *self, Parser *parser) {
return 0;
}
-static CHECK_RESULT int ssa_get_unique_reg(Ssa *self, SsaRegister *result) {
+static CHECK_RESULT int ir_get_unique_reg(Ir *self, IrRegister *result) {
assert(result);
/* Overflow */
if((u16)self->reg_counter + 1 > INT16_MAX) {
- amal_log_error("Ssa too many registers!");
+ amal_log_error("Ir too many registers!");
return -1;
}
assert(self->reg_counter <= INT8_MAX && "TODO: Implement usage of reg higher than 128");
@@ -90,11 +90,11 @@ static CHECK_RESULT int ssa_get_unique_reg(Ssa *self, SsaRegister *result) {
return 0;
}
-static CHECK_RESULT int ssa_get_unique_param_reg(Ssa *self, SsaRegister *result) {
+static CHECK_RESULT int ir_get_unique_param_reg(Ir *self, IrRegister *result) {
assert(result);
/* Overflow */
if((u16)self->param_counter + 1 > INT16_MAX) {
- amal_log_error("Ssa too many param registers!");
+ amal_log_error("Ir too many param registers!");
return -1;
}
assert(self->param_counter <= INT8_MAX && "TODO: Implement usage of reg higher than 128");
@@ -102,21 +102,21 @@ static CHECK_RESULT int ssa_get_unique_param_reg(Ssa *self, SsaRegister *result)
return 0;
}
-SsaNumber ssa_get_intermediate(Ssa *self, SsaIntermediateIndex index) {
- SsaNumber result;
- assert(index < buffer_get_size(&self->intermediates, SsaNumber));
- am_memcpy(&result, buffer_get(&self->intermediates, index, sizeof(SsaNumber)), sizeof(SsaNumber));
+IrNumber ir_get_intermediate(Ir *self, IrIntermediateIndex index) {
+ IrNumber result;
+ assert(index < buffer_get_size(&self->intermediates, IrNumber));
+ am_memcpy(&result, buffer_get(&self->intermediates, index, sizeof(IrNumber)), sizeof(IrNumber));
return result;
}
-BufferView ssa_get_string(Ssa *self, SsaStringIndex index) {
+BufferView ir_get_string(Ir *self, IrStringIndex index) {
BufferView result;
assert(index < buffer_get_size(&self->strings, BufferView));
am_memcpy(&result, buffer_get(&self->strings, index, sizeof(BufferView)), sizeof(BufferView));
return result;
}
-static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, SsaIntermediateIndex *result_index) {
+static CHECK_RESULT int ir_try_add_intermediate(Ir *self, IrNumber number, IrIntermediateIndex *result_index) {
bool exists;
BufferView key;
@@ -129,18 +129,18 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss
/* Overflow */
if(self->intermediate_counter + 1 <= self->intermediate_counter) {
- amal_log_error("Ssa too many intermediates!");
+ amal_log_error("Ir too many intermediates!");
return -1;
}
*result_index = self->intermediate_counter;
++self->intermediate_counter;
switch(number.type) {
- case SSA_NUMBER_TYPE_INTEGER: {
+ case IR_NUMBER_TYPE_INTEGER: {
amal_log_debug("i%u = %lld", *result_index, number.value.integer);
break;
}
- case SSA_NUMBER_TYPE_FLOAT: {
+ case IR_NUMBER_TYPE_FLOAT: {
amal_log_debug("i%u = %f", *result_index, number.value.floating);
break;
}
@@ -150,7 +150,7 @@ static CHECK_RESULT int ssa_try_add_intermediate(Ssa *self, SsaNumber number, Ss
return hash_map_insert(&self->intermediates_map, key, result_index);
}
-static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringIndex *result_index) {
+static CHECK_RESULT int ir_try_add_string(Ir *self, BufferView str, IrStringIndex *result_index) {
bool exists;
assert(result_index);
@@ -160,7 +160,7 @@ static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringI
/* Overflow */
if(self->string_counter + 1 <= self->string_counter) {
- amal_log_error("Ssa too many strings!");
+ amal_log_error("Ir too many strings!");
return -1;
}
@@ -180,23 +180,23 @@ static CHECK_RESULT int ssa_try_add_string(Ssa *self, BufferView str, SsaStringI
TODO: Right now this has the same scope as a file. This should be global, otherwise you could define multiple
extern func with the same name but different signature as long as they are defined in different files
*/
-static CHECK_RESULT int ssa_try_add_extern_func(Ssa *self, FunctionSignature *func_sig, BufferView name, SsaExternFuncIndex *result_index, BufferView *existing_func) {
+static CHECK_RESULT int ir_try_add_extern_func(Ir *self, FunctionSignature *func_sig, BufferView name, IrExternFuncIndex *result_index, BufferView *existing_func) {
bool exists;
assert(result_index);
assert(existing_func);
exists = hash_map_get(&self->extern_funcs_map, name, result_index);
if(exists) {
- const SsaExternFunc *existing_extern_func = buffer_get(&self->extern_funcs, *result_index, sizeof(SsaExternFunc));
+ const IrExternFunc *existing_extern_func = buffer_get(&self->extern_funcs, *result_index, sizeof(IrExternFunc));
*existing_func = existing_extern_func->name;
if(!function_signature_equals(func_sig, existing_extern_func->func_sig))
- return SSA_ERR_EXTERN_FUNC_SIG_MISMATCH;
+ return IR_ERR_EXTERN_FUNC_SIG_MISMATCH;
return 0;
}
/* Overflow */
if(self->extern_func_counter + 1 <= self->extern_func_counter) {
- amal_log_error("Ssa too many extern closures!");
+ amal_log_error("Ir too many extern closures!");
return -1;
}
@@ -204,7 +204,7 @@ static CHECK_RESULT int ssa_try_add_extern_func(Ssa *self, FunctionSignature *fu
++self->extern_func_counter;
amal_log_debug("extern_func%u = %.*s", *result_index, name.size, name.data);
{
- SsaExternFunc extern_func;
+ IrExternFunc extern_func;
extern_func.func_sig = func_sig;
extern_func.name = name;
return_if_error(buffer_append(&self->extern_funcs, &extern_func, sizeof(extern_func)));
@@ -218,55 +218,55 @@ static CHECK_RESULT int ssa_try_add_extern_func(Ssa *self, FunctionSignature *fu
as that is already checked in the AST stage, as you are not allowed to have multiple variables of the same name in the same scope,
exported or not.
*/
-static CHECK_RESULT int ssa_try_add_export_func(Ssa *self, FunctionSignature *func_sig, BufferView name) {
+static CHECK_RESULT int ir_try_add_export_func(Ir *self, FunctionSignature *func_sig, BufferView name) {
/* Overflow */
if(self->export_func_counter + 1 <= self->export_func_counter) {
- amal_log_error("Ssa too many exported closures!");
+ amal_log_error("Ir too many exported closures!");
return -1;
}
amal_log_debug("exported_func%u = %.*s", self->export_func_counter, name.size, name.data);
++self->export_func_counter;
{
- SsaExportFunc export_func;
+ IrExportFunc export_func;
export_func.func_sig = func_sig;
export_func.name = name;
return buffer_append(&self->export_funcs, &export_func, sizeof(export_func));
}
}
-static CHECK_RESULT int ssa_add_ins_form1(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, u16 rhs) {
- SsaInsForm1 ins_form_1;
+static CHECK_RESULT int ir_add_ins_form1(Ir *self, IrInstruction ins_type, IrRegister lhs, u16 rhs) {
+ IrInsForm1 ins_form_1;
ins_form_1.lhs = lhs;
ins_form_1.rhs = rhs;
return_if_error(buffer_append(&self->instructions, &ins_type, 1));
return buffer_append(&self->instructions, &ins_form_1, sizeof(ins_form_1));
}
-static const char* binop_type_to_string(SsaInstruction binop_type) {
- assert(binop_type >= SSA_ADD && binop_type <= SSA_GE);
+static const char* binop_type_to_string(IrInstruction binop_type) {
+ assert(binop_type >= IR_ADD && binop_type <= IR_GE);
switch(binop_type) {
- case SSA_ADD: return "+";
- case SSA_SUB: return "-";
- case SSA_MUL: return "*";
- case SSA_DIV: return "/";
- case SSA_EQUALS: return "==";
- case SSA_AND: return "&&";
- case SSA_ILT: return "<";
- case SSA_LT: return "<";
- case SSA_ILE: return "<=";
- case SSA_LE: return "<=";
- case SSA_IGT: return ">";
- case SSA_GT: return ">";
- case SSA_IGE: return ">=";
- case SSA_GE: return ">=";
+ case IR_ADD: return "+";
+ case IR_SUB: return "-";
+ case IR_MUL: return "*";
+ case IR_DIV: return "/";
+ case IR_EQUALS: return "==";
+ case IR_AND: return "&&";
+ case IR_ILT: return "<";
+ case IR_LT: return "<";
+ case IR_ILE: return "<=";
+ case IR_LE: return "<=";
+ case IR_IGT: return ">";
+ case IR_GT: return ">";
+ case IR_IGE: return ">=";
+ case IR_GE: return ">=";
default: return "";
}
}
-static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) {
- SsaInsForm2 ins_form_2;
- return_if_error(ssa_get_unique_reg(self, result));
+static CHECK_RESULT int ir_add_ins_form2(Ir *self, IrInstruction ins_type, IrRegister lhs, IrRegister rhs, IrRegister *result) {
+ IrInsForm2 ins_form_2;
+ return_if_error(ir_get_unique_reg(self, result));
ins_form_2.result = *result;
ins_form_2.lhs = lhs;
ins_form_2.rhs = rhs;
@@ -275,43 +275,43 @@ static CHECK_RESULT int ssa_add_ins_form2(Ssa *self, SsaInstruction ins_type, Ss
return buffer_append(&self->instructions, &ins_form_2, sizeof(ins_form_2));
}
-static CHECK_RESULT int ssa_ins_assign_inter(Ssa *self, SsaRegister dest, SsaNumber number) {
- SsaIntermediateIndex index;
- return_if_error(ssa_try_add_intermediate(self, number, &index));
+static CHECK_RESULT int ir_ins_assign_inter(Ir *self, IrRegister dest, IrNumber number) {
+ IrIntermediateIndex index;
+ return_if_error(ir_try_add_intermediate(self, number, &index));
amal_log_debug("r%d = i%u", dest, index);
- return ssa_add_ins_form1(self, SSA_ASSIGN_INTER, dest, index);
+ return ir_add_ins_form1(self, IR_ASSIGN_INTER, dest, index);
}
-static CHECK_RESULT int ssa_ins_assign_string(Ssa *self, SsaRegister dest, BufferView str) {
- SsaStringIndex index;
- return_if_error(ssa_try_add_string(self, str, &index));
+static CHECK_RESULT int ir_ins_assign_string(Ir *self, IrRegister dest, BufferView str) {
+ IrStringIndex index;
+ return_if_error(ir_try_add_string(self, str, &index));
amal_log_debug("r%d = s%u", dest, index);
- return ssa_add_ins_form1(self, SSA_ASSIGN_STRING, dest, index);
+ return ir_add_ins_form1(self, IR_ASSIGN_STRING, dest, index);
}
-static CHECK_RESULT int ssa_ins_assign_reg(Ssa *self, SsaRegister dest, SsaRegister src) {
+static CHECK_RESULT int ir_ins_assign_reg(Ir *self, IrRegister dest, IrRegister src) {
amal_log_debug("r%d = r%d", dest, src);
- return ssa_add_ins_form1(self, SSA_ASSIGN_REG, dest, src);
+ return ir_add_ins_form1(self, IR_ASSIGN_REG, dest, src);
}
-static CHECK_RESULT int ssa_ins_binop(Ssa *self, SsaInstruction binop_type, SsaRegister lhs, SsaRegister rhs, SsaRegister *result) {
- assert(binop_type >= SSA_ADD && binop_type <= SSA_GE);
- return ssa_add_ins_form2(self, binop_type, lhs, rhs, result);
+static CHECK_RESULT int ir_ins_binop(Ir *self, IrInstruction binop_type, IrRegister lhs, IrRegister rhs, IrRegister *result) {
+ assert(binop_type >= IR_ADD && binop_type <= IR_GE);
+ return ir_add_ins_form2(self, binop_type, lhs, rhs, result);
}
-static CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 func_flags, FunctionSignature *func_sig, SsaFuncIndex *result, usize *func_metadata_index) {
- const u8 ins_type = SSA_FUNC_START;
- SsaInsFuncStart ins_func_start;
+static CHECK_RESULT int ir_ins_func_start(Ir *self, u8 func_flags, FunctionSignature *func_sig, IrFuncIndex *result, usize *func_metadata_index) {
+ const u8 ins_type = IR_FUNC_START;
+ IrInsFuncStart ins_func_start;
/* Overflow */
if(self->func_counter + 1 <= self->func_counter) {
- amal_log_error("Ssa too many closures!");
+ amal_log_error("Ir too many closures!");
return -1;
}
*result = self->func_counter++;
{
- SsaFunc func;
+ IrFunc func;
func.func_sig = func_sig;
return_if_error(buffer_append(&self->funcs, &func, sizeof(func)));
}
@@ -325,37 +325,37 @@ static CHECK_RESULT int ssa_ins_func_start(Ssa *self, u8 func_flags, FunctionSig
return 0;
}
-static CHECK_RESULT int ssa_ins_func_end(Ssa *self) {
- const u8 ins_type = SSA_FUNC_END;
+static CHECK_RESULT int ir_ins_func_end(Ir *self) {
+ const u8 ins_type = IR_FUNC_END;
amal_log_debug("FUNC_END");
return buffer_append(&self->instructions, &ins_type, 1);
}
-static CHECK_RESULT int ssa_ins_push(Ssa *self, SsaRegister reg) {
- const u8 ins_type = SSA_PUSH;
+static CHECK_RESULT int ir_ins_push(Ir *self, IrRegister reg) {
+ const u8 ins_type = IR_PUSH;
amal_log_debug("PUSH r%d", reg);
return_if_error(buffer_append(&self->instructions, &ins_type, 1));
return buffer_append(&self->instructions, &reg, sizeof(reg));
}
-static CHECK_RESULT int ssa_ins_push_ret(Ssa *self, SsaRegister reg) {
- const u8 ins_type = SSA_PUSH_RET;
+static CHECK_RESULT int ir_ins_push_ret(Ir *self, IrRegister reg) {
+ const u8 ins_type = IR_PUSH_RET;
amal_log_debug("PUSH RET r%d", reg);
return_if_error(buffer_append(&self->instructions, &ins_type, 1));
return buffer_append(&self->instructions, &reg, sizeof(reg));
}
-static CHECK_RESULT int ssa_ins_call_start(Ssa *self, u8 num_args) {
- const u8 ins_type = SSA_CALL_START;
- SsaInsCallStart ins_call_start;
+static CHECK_RESULT int ir_ins_call_start(Ir *self, u8 num_args) {
+ const u8 ins_type = IR_CALL_START;
+ IrInsCallStart ins_call_start;
ins_call_start.num_args = num_args;
return_if_error(buffer_append(&self->instructions, &ins_type, 1));
return buffer_append(&self->instructions, &ins_call_start, sizeof(ins_call_start));
}
-static CHECK_RESULT int ssa_ins_call(Ssa *self, int import_index, FunctionDecl *func_decl) {
- const u8 ins_type = SSA_CALL;
- SsaInsFuncCall ins_func_call;
+static CHECK_RESULT int ir_ins_call(Ir *self, int import_index, FunctionDecl *func_decl) {
+ const u8 ins_type = IR_CALL;
+ IrInsFuncCall ins_func_call;
ins_func_call.func_decl = func_decl;
ins_func_call.import_index = import_index;
amal_log_debug("CALL f(%d,%p)", import_index, func_decl);
@@ -363,9 +363,9 @@ static CHECK_RESULT int ssa_ins_call(Ssa *self, int import_index, FunctionDecl *
return buffer_append(&self->instructions, &ins_func_call, sizeof(ins_func_call));
}
-static CHECK_RESULT int ssa_ins_call_extern(Ssa *self, int import_index, LhsExpr *func_decl_lhs) {
- const u8 ins_type = SSA_CALL_EXTERN;
- SsaInsFuncCallExtern ins_func_call_extern;
+static CHECK_RESULT int ir_ins_call_extern(Ir *self, int import_index, LhsExpr *func_decl_lhs) {
+ const u8 ins_type = IR_CALL_EXTERN;
+ IrInsFuncCallExtern ins_func_call_extern;
ins_func_call_extern.func_decl_lhs = func_decl_lhs;
ins_func_call_extern.import_index = import_index;
amal_log_debug("CALL_EXTERN ef(%d,%p)", import_index, func_decl_lhs);
@@ -373,9 +373,9 @@ static CHECK_RESULT int ssa_ins_call_extern(Ssa *self, int import_index, LhsExpr
return buffer_append(&self->instructions, &ins_func_call_extern, sizeof(ins_func_call_extern));
}
-static CHECK_RESULT int ssa_ins_jumpzero(Ssa *self, SsaRegister condition_reg, SsaLabelIndex target_label, usize *instruction_offset) {
- const u8 ins_type = SSA_JUMP_ZERO;
- SsaInsJumpZero ins_jump_zero;
+static CHECK_RESULT int ir_ins_jumpzero(Ir *self, IrRegister condition_reg, IrLabelIndex target_label, usize *instruction_offset) {
+ const u8 ins_type = IR_JUMP_ZERO;
+ IrInsJumpZero ins_jump_zero;
ins_jump_zero.condition_reg = condition_reg;
ins_jump_zero.target_label = target_label;
if(target_label == 0)
@@ -387,9 +387,9 @@ static CHECK_RESULT int ssa_ins_jumpzero(Ssa *self, SsaRegister condition_reg, S
return buffer_append(&self->instructions, &ins_jump_zero, sizeof(ins_jump_zero));
}
-static CHECK_RESULT int ssa_ins_jump(Ssa *self, SsaLabelIndex target_label, usize *instruction_offset) {
- const u8 ins_type = SSA_JUMP;
- SsaInsJump ins_jump;
+static CHECK_RESULT int ir_ins_jump(Ir *self, IrLabelIndex target_label, usize *instruction_offset) {
+ const u8 ins_type = IR_JUMP;
+ IrInsJump ins_jump;
ins_jump.target_label = target_label;
if(target_label == 0)
@@ -404,17 +404,17 @@ static CHECK_RESULT int ssa_ins_jump(Ssa *self, SsaLabelIndex target_label, usiz
return buffer_append(&self->instructions, &ins_jump, sizeof(ins_jump));
}
-static CHECK_RESULT int ssa_ins_return(Ssa *self, SsaRegister reg) {
- const u8 ins_type = SSA_RET;
+static CHECK_RESULT int ir_ins_return(Ir *self, IrRegister reg) {
+ const u8 ins_type = IR_RET;
return_if_error(buffer_append(&self->instructions, &ins_type, 1));
return buffer_append(&self->instructions, &reg, sizeof(reg));
}
-static CHECK_RESULT int ssa_ins_label(Ssa *self, u16 *label_index) {
- const u8 ins_type = SSA_LABEL;
+static CHECK_RESULT int ir_ins_label(Ir *self, u16 *label_index) {
+ const u8 ins_type = IR_LABEL;
/* Overflow */
if(self->label_counter + 1 <= self->label_counter) {
- amal_log_error("Ssa too many labels!");
+ amal_log_error("Ir too many labels!");
return -1;
}
*label_index = self->label_counter;
@@ -422,16 +422,16 @@ static CHECK_RESULT int ssa_ins_label(Ssa *self, u16 *label_index) {
return buffer_append(&self->instructions, &ins_type, 1);
}
-static CHECK_RESULT int ssa_set_jump_label(Ssa *self, usize jump_ins_index, SsaLabelIndex label) {
+static CHECK_RESULT int ir_set_jump_label(Ir *self, usize jump_ins_index, IrLabelIndex label) {
switch(self->instructions.data[jump_ins_index]) {
- case SSA_JUMP_ZERO: {
+ case IR_JUMP_ZERO: {
/* +1 to skip instruction opcode */
- am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(SsaInsJumpZero, target_label), &label, sizeof(SsaLabelIndex));
+ am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(IrInsJumpZero, target_label), &label, sizeof(IrLabelIndex));
break;
}
- case SSA_JUMP: {
+ case IR_JUMP: {
/* +1 to skip instruction opcode */
- am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(SsaInsJump, target_label), &label, sizeof(SsaLabelIndex));
+ am_memcpy(self->instructions.data + jump_ins_index + 1 + offsetof(IrInsJump, target_label), &label, sizeof(IrLabelIndex));
break;
}
default:
@@ -441,8 +441,8 @@ static CHECK_RESULT int ssa_set_jump_label(Ssa *self, usize jump_ins_index, SsaL
return 0;
}
-static CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context);
-static CHECK_RESULT SsaRegister scope_named_object_generate_ssa(ScopeNamedObject *self, SsaCompilerContext *context);
+static CHECK_RESULT IrRegister ast_generate_ir(Ast *self, IrCompilerContext *context);
+static CHECK_RESULT IrRegister scope_named_object_generate_ir(ScopeNamedObject *self, IrCompilerContext *context);
#if 0
static bool ast_resolved_type_is_decl(AstResolvedType *self) {
@@ -484,33 +484,33 @@ static bool lhs_expr_is_decl(LhsExpr *self) {
}
}
-static CHECK_RESULT SsaRegister number_generate_ssa(Number *self, SsaCompilerContext *context) {
- SsaRegister reg;
- SsaNumber number;
+static CHECK_RESULT IrRegister number_generate_ir(Number *self, IrCompilerContext *context) {
+ IrRegister reg;
+ IrNumber number;
switch(self->value.type) {
case AMAL_NUMBER_SIGNED_INTEGER:
case AMAL_NUMBER_UNSIGNED_INTEGER:
- number = create_ssa_integer(self->value.value.integer);
+ number = create_ir_integer(self->value.value.integer);
break;
case AMAL_NUMBER_FLOAT:
- number = create_ssa_float(self->value.value.floating);
+ number = create_ir_float(self->value.value.floating);
break;
}
- throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
- throw_if_error(ssa_ins_assign_inter(context->ssa, reg, number));
+ throw_if_error(ir_get_unique_reg(context->ir, &reg));
+ throw_if_error(ir_ins_assign_inter(context->ir, reg, number));
return reg;
}
-static CHECK_RESULT SsaRegister lhsexpr_extern_generate_ssa(LhsExpr *self, SsaCompilerContext *context) {
- /* TODO: SsaRegister should be extended to include static and extern data */
+static CHECK_RESULT IrRegister lhsexpr_extern_generate_ir(LhsExpr *self, IrCompilerContext *context) {
+ /* TODO: IrRegister should be extended to include static and extern data */
if(self->type.type == VARIABLE_TYPE_SIGNATURE) {
int err;
BufferView existing_func;
- err = ssa_try_add_extern_func(context->ssa, self->type.value.signature, self->var_name, &self->extern_index, &existing_func);
- if(err == SSA_ERR_EXTERN_FUNC_SIG_MISMATCH) {
+ err = ir_try_add_extern_func(context->ir, self->type.value.signature, self->var_name, &self->extern_index, &existing_func);
+ if(err == IR_ERR_EXTERN_FUNC_SIG_MISMATCH) {
Tokenizer *tokenizer;
- tokenizer = &context->ssa->parser->tokenizer;
+ tokenizer = &context->ir->parser->tokenizer;
tokenizer_print_error(tokenizer, tokenizer_get_code_reference_index(tokenizer, self->var_name.data),
"Extern closure defined here with the name %.*s doesn't match extern closure with the same name defined in another location",
self->var_name.size, self->var_name.data);
@@ -529,39 +529,39 @@ static CHECK_RESULT SsaRegister lhsexpr_extern_generate_ssa(LhsExpr *self, SsaCo
if(err != 0)
throw(err);
} else {
- assert(bool_false && "TODO: Implement lhsexpr_extern_generate_ssa for other data than functions");
+ assert(bool_false && "TODO: Implement lhsexpr_extern_generate_ir for other data than functions");
}
return 0;
}
-static CHECK_RESULT SsaRegister lhsexpr_export_generate_ssa(LhsExpr *self, SsaCompilerContext *context) {
- /* TODO: SsaRegister should be extended to include static and export data */
+static CHECK_RESULT IrRegister lhsexpr_export_generate_ir(LhsExpr *self, IrCompilerContext *context) {
+ /* TODO: IrRegister should be extended to include static and export data */
if(self->rhs_expr->type == AST_FUNCTION_DECL) {
- throw_if_error(ssa_try_add_export_func(context->ssa, self->rhs_expr->value.func_decl->signature, self->var_name));
+ throw_if_error(ir_try_add_export_func(context->ir, self->rhs_expr->value.func_decl->signature, self->var_name));
} else {
- assert(bool_false && "TODO: Implement lhsexpr_export_generate_ssa for other data than functions");
+ assert(bool_false && "TODO: Implement lhsexpr_export_generate_ir for other data than functions");
}
return 0;
}
-static CHECK_RESULT SsaRegister lhsexpr_generate_ssa(LhsExpr *self, AstResolveData *resolve_data, SsaCompilerContext *context) {
- SsaRegister reg;
+static CHECK_RESULT IrRegister lhsexpr_generate_ir(LhsExpr *self, AstResolveData *resolve_data, IrCompilerContext *context) {
+ IrRegister reg;
if(LHS_EXPR_IS_EXTERN(self))
- return lhsexpr_extern_generate_ssa(self, context);
+ return lhsexpr_extern_generate_ir(self, context);
if(self->rhs_expr) {
Ast *rhs_expr = self->rhs_expr;
- SsaRegister rhs_reg;
- rhs_reg = ast_generate_ssa(rhs_expr, context);
+ IrRegister rhs_reg;
+ rhs_reg = ast_generate_ir(rhs_expr, context);
if(LHS_EXPR_IS_EXPORT(self))
- return lhsexpr_export_generate_ssa(self, context);
+ return lhsexpr_export_generate_ir(self, context);
/*
Declarations (struct and function declaration) resolves to itself and in that case this expression
is just a compile-time name for the declaration.
- Import expression also has no meaning in SSA until it's used.
+ Import expression also has no meaning in IR until it's used.
TODO: Shouldn't lhsexpr that have struct/function declaration as rhs be different ast expression types?
*/
if(lhs_expr_is_decl(self) || rhs_expr->type == AST_IMPORT) {
@@ -572,15 +572,15 @@ static CHECK_RESULT SsaRegister lhsexpr_generate_ssa(LhsExpr *self, AstResolveDa
} else {
/* TODO: Do not assign if we dont want default value */
if(resolve_data->type.type == RESOLVED_TYPE_LHS_EXPR) {
- SsaNumber number;
+ IrNumber number;
if(resolve_data->type.value.lhs_expr == (LhsExpr*)context->compiler->default_types.i64)
- number = create_ssa_integer(0);
+ number = create_ir_integer(0);
else if(resolve_data->type.value.lhs_expr == (LhsExpr*)context->compiler->default_types.f64)
- number = create_ssa_float(0.0);
+ number = create_ir_float(0.0);
else
assert(bool_false && "TODO: assign default value to reg depending on LhsExpr type");
- throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
- throw_if_error(ssa_ins_assign_inter(context->ssa, reg, number));
+ throw_if_error(ir_get_unique_reg(context->ir, &reg));
+ throw_if_error(ir_ins_assign_inter(context->ir, reg, number));
} else if(resolve_data->type.type == RESOLVED_TYPE_FUNC_SIG) {
assert(bool_false && "TODO: Implement this when variable can be null. Then the function pointer should be null");
} else {
@@ -590,41 +590,41 @@ static CHECK_RESULT SsaRegister lhsexpr_generate_ssa(LhsExpr *self, AstResolveDa
return reg;
}
-static CHECK_RESULT SsaRegister assignmentexpr_generate_ssa(AssignmentExpr *self, SsaCompilerContext *context) {
- SsaRegister lhs_reg, rhs_reg;
- lhs_reg = ast_generate_ssa(self->lhs_expr, context);
- rhs_reg = ast_generate_ssa(self->rhs_expr, context);
- throw_if_error(ssa_ins_assign_reg(context->ssa, lhs_reg, rhs_reg));
+static CHECK_RESULT IrRegister assignmentexpr_generate_ir(AssignmentExpr *self, IrCompilerContext *context) {
+ IrRegister lhs_reg, rhs_reg;
+ lhs_reg = ast_generate_ir(self->lhs_expr, context);
+ rhs_reg = ast_generate_ir(self->rhs_expr, context);
+ throw_if_error(ir_ins_assign_reg(context->ir, lhs_reg, rhs_reg));
return lhs_reg;
}
-static CHECK_RESULT SsaRegister function_parameter_generate_ssa(FunctionParameter *self, SsaCompilerContext *context) {
- SsaRegister reg;
- if(self->resolve_data.status == AST_SSA_RESOLVED)
- return self->resolve_data.ssa_reg;
+static CHECK_RESULT IrRegister function_parameter_generate_ir(FunctionParameter *self, IrCompilerContext *context) {
+ IrRegister reg;
+ if(self->resolve_data.status == AST_IR_RESOLVED)
+ return self->resolve_data.ir_reg;
- throw_if_error(ssa_get_unique_param_reg(context->ssa, &reg));
- self->resolve_data.status = AST_SSA_RESOLVED;
- self->resolve_data.ssa_reg = reg;
+ throw_if_error(ir_get_unique_param_reg(context->ir, &reg));
+ self->resolve_data.status = AST_IR_RESOLVED;
+ self->resolve_data.ir_reg = reg;
return reg;
}
-static CHECK_RESULT void function_signature_generate_params_ssa(FunctionSignature *self, SsaCompilerContext *context) {
+static CHECK_RESULT void function_signature_generate_params_ir(FunctionSignature *self, IrCompilerContext *context) {
FunctionParameter *param, *param_end;
param = buffer_begin(&self->parameters);
param_end = buffer_end(&self->parameters);
for(; param != param_end; ++param) {
- SsaRegister reg;
- reg = function_parameter_generate_ssa(param, context);
+ IrRegister reg;
+ reg = function_parameter_generate_ir(param, context);
(void)reg;
}
}
/*
-TODO: Each function declaration should be in separate SSA instances so ast can be converted into ssa
+TODO: Each function declaration should be in separate IR instances so ast can be converted into ir
in any order.
*/
-static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCompilerContext *context) {
+static CHECK_RESULT IrRegister funcdecl_generate_ir(FunctionDecl *self, IrCompilerContext *context) {
/* TODO: Implement */
/*
Reset reg counter in each function, because each function has a separate register context
@@ -632,40 +632,40 @@ static CHECK_RESULT SsaRegister funcdecl_generate_ssa(FunctionDecl *self, SsaCom
*/
usize func_metadata_index;
u8 func_flags = 0;
- context->ssa->reg_counter = 0;
- context->ssa->param_counter = 0;
- context->ssa->label_counter = 0;
+ context->ir->reg_counter = 0;
+ context->ir->param_counter = 0;
+ context->ir->label_counter = 0;
/*
- Parameters need to have generated ssa so the first ssa registers belong to the function.
+ Parameters need to have generated ir so the first ir registers belong to the function.
This way we can know if a register access is for a parameter or not by checking the number
*/
- function_signature_generate_params_ssa(self->signature, context);
+ function_signature_generate_params_ir(self->signature, context);
- amal_log_debug("SSA funcdecl %p", self);
+ amal_log_debug("IR funcdecl %p", self);
/* Anonymous closure doesn't have lhs_expr, and neither can it have any flags (extern, export etc) */
if(self->lhs_expr) {
assert(!LHS_EXPR_IS_EXTERN(self->lhs_expr));
if(LHS_EXPR_IS_EXPORT(self->lhs_expr))
func_flags |= FUNC_FLAG_EXPORTED;
}
- throw_if_error(ssa_ins_func_start(context->ssa, func_flags, self->signature, &self->ssa_func_index, &func_metadata_index));
- scope_generate_ssa(&self->body, context);
- throw_if_error(ssa_ins_func_end(context->ssa));
+ throw_if_error(ir_ins_func_start(context->ir, func_flags, self->signature, &self->ir_func_index, &func_metadata_index));
+ scope_generate_ir(&self->body, context);
+ throw_if_error(ir_ins_func_end(context->ir));
/* Add the number of registers used to the function metadata (FUNC_START) */
- am_memcpy(context->ssa->instructions.data + func_metadata_index, &context->ssa->reg_counter, sizeof(u16));
+ am_memcpy(context->ir->instructions.data + func_metadata_index, &context->ir->reg_counter, sizeof(u16));
return 0;
}
-static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCompilerContext *context) {
- SsaRegister reg;
+static CHECK_RESULT IrRegister funccall_generate_ir(FunctionCall *self, IrCompilerContext *context) {
+ IrRegister reg;
FunctionSignature *func_sig;
FunctionDecl *func_decl;
LhsExpr *func_lhs_expr;
int import_index = context->import_index;
context->import_index = 0;
- throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
+ throw_if_error(ir_get_unique_reg(context->ir, &reg));
assert(self->func.resolved_var.type == NAMED_OBJECT_LHS_EXPR);
func_lhs_expr = self->func.resolved_var.value.lhs_expr;
@@ -689,18 +689,18 @@ static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCom
It should also take into account the size of the type.
*/
assert(buffer_get_size(&func_sig->return_types, FunctionReturnType) <= 1);
- throw_if_error(ssa_ins_push_ret(context->ssa, reg));
+ throw_if_error(ir_ins_push_ret(context->ir, reg));
}
/* Push parameter arguments */
assert(buffer_get_size(&self->args, Ast*) <= FUNC_MAX_ARGS);
{
- SsaRegister arg_regs[FUNC_MAX_ARGS];
+ IrRegister arg_regs[FUNC_MAX_ARGS];
Ast **arg = buffer_begin(&self->args);
Ast **arg_end = buffer_end(&self->args);
for(; arg != arg_end; ++arg) {
- arg_regs[arg_end - arg] = ast_generate_ssa(*arg, context);
+ arg_regs[arg_end - arg] = ast_generate_ir(*arg, context);
}
/*
@@ -711,31 +711,31 @@ static CHECK_RESULT SsaRegister funccall_generate_ssa(FunctionCall *self, SsaCom
*/
arg = buffer_begin(&self->args);
- throw_if_error(ssa_ins_call_start(context->ssa, arg_end - arg));
+ throw_if_error(ir_ins_call_start(context->ir, arg_end - arg));
for(; arg != arg_end; ++arg) {
- throw_if_error(ssa_ins_push(context->ssa, arg_regs[arg_end - arg]));
+ throw_if_error(ir_ins_push(context->ir, arg_regs[arg_end - arg]));
}
}
if(func_lhs_expr && LHS_EXPR_IS_EXTERN(func_lhs_expr)) {
- throw_if_error(ssa_ins_call_extern(context->ssa, import_index, func_lhs_expr));
+ throw_if_error(ir_ins_call_extern(context->ir, import_index, func_lhs_expr));
} else {
assert(func_decl);
/* rhs wont be null here because only extern variable can't have rhs */
- throw_if_error(ssa_ins_call(context->ssa, import_index, func_decl));
+ throw_if_error(ir_ins_call(context->ir, import_index, func_decl));
}
return reg;
}
-static CHECK_RESULT SsaRegister structdecl_generate_ssa(StructDecl *self, SsaCompilerContext *context) {
+static CHECK_RESULT IrRegister structdecl_generate_ir(StructDecl *self, IrCompilerContext *context) {
/* TODO: Implement */
/*assert(bool_false);*/
- scope_generate_ssa(&self->body, context);
+ scope_generate_ir(&self->body, context);
return 0;
}
-static CHECK_RESULT SsaRegister structfield_generate_ssa(StructField *self, SsaCompilerContext *context) {
+static CHECK_RESULT IrRegister structfield_generate_ir(StructField *self, IrCompilerContext *context) {
/* TODO: Implement */
assert(bool_false);
(void)self;
@@ -743,47 +743,47 @@ static CHECK_RESULT SsaRegister structfield_generate_ssa(StructField *self, SsaC
return 0;
}
-static CHECK_RESULT SsaRegister string_generate_ssa(String *self, SsaCompilerContext *context) {
- SsaRegister reg;
- throw_if_error(ssa_get_unique_reg(context->ssa, &reg));
- throw_if_error(ssa_ins_assign_string(context->ssa, reg, self->str));
+static CHECK_RESULT IrRegister string_generate_ir(String *self, IrCompilerContext *context) {
+ IrRegister reg;
+ throw_if_error(ir_get_unique_reg(context->ir, &reg));
+ throw_if_error(ir_ins_assign_string(context->ir, reg, self->str));
return reg;
}
-SsaRegister variable_generate_ssa(Variable *self, SsaCompilerContext *context) {
+IrRegister variable_generate_ir(Variable *self, IrCompilerContext *context) {
/* TODO: If resolved_var refers to a variable in another file, use a cross file reference that requires no locking (not yet implemented) */
/* This is not thread-safe:*/
assert(self->resolved_var.type != NAMED_OBJECT_NONE);
- return scope_named_object_generate_ssa(&self->resolved_var, context);
+ return scope_named_object_generate_ir(&self->resolved_var, context);
}
-static SsaInstruction binop_type_to_ssa_type(BinopType binop_type, amal_default_type *type) {
+static IrInstruction binop_type_to_ir_type(BinopType binop_type, amal_default_type *type) {
switch(binop_type) {
case BINOP_ADD:
- return SSA_ADD;
+ return IR_ADD;
case BINOP_SUB:
- return SSA_SUB;
+ return IR_SUB;
case BINOP_MUL:
- return amal_default_type_is_signed(type) ? SSA_IMUL : SSA_MUL;
+ return amal_default_type_is_signed(type) ? IR_IMUL : IR_MUL;
case BINOP_DIV:
- return amal_default_type_is_signed(type) ? SSA_IDIV : SSA_DIV;
+ return amal_default_type_is_signed(type) ? IR_IDIV : IR_DIV;
case BINOP_DOT:
assert(bool_false && "Binop dot not valid for arithmetic operation and requires special functionality");
return 0;
case BINOP_EQUALS:
- return SSA_EQUALS;
+ return IR_EQUALS;
case BINOP_NOT_EQUAL:
- return SSA_NOT_EQUAL;
+ return IR_NOT_EQUAL;
case BINOP_AND:
- return SSA_AND;
+ return IR_AND;
case BINOP_LESS:
- return amal_default_type_is_signed(type) ? SSA_ILT : SSA_LT;
+ return amal_default_type_is_signed(type) ? IR_ILT : IR_LT;
case BINOP_LESS_EQUAL:
- return amal_default_type_is_signed(type) ? SSA_ILE : SSA_LE;
+ return amal_default_type_is_signed(type) ? IR_ILE : IR_LE;
case BINOP_GREATER:
- return amal_default_type_is_signed(type) ? SSA_IGT : SSA_GT;
+ return amal_default_type_is_signed(type) ? IR_IGT : IR_GT;
case BINOP_GREATER_EQUAL:
- return amal_default_type_is_signed(type) ? SSA_IGE : SSA_GE;
+ return amal_default_type_is_signed(type) ? IR_IGE : IR_GE;
}
return 0;
}
@@ -798,8 +798,8 @@ static Import* binop_lhs_get_import_or_null(Binop *self) {
return NULL;
}
-static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerContext *context) {
- SsaRegister reg;
+static CHECK_RESULT IrRegister binop_generate_ir(Binop *self, IrCompilerContext *context) {
+ IrRegister reg;
/*
Syntax example for binop dot + func_decl expr
@@ -810,173 +810,173 @@ static CHECK_RESULT SsaRegister binop_generate_ssa(Binop *self, SsaCompilerConte
Import *lhs_import = binop_lhs_get_import_or_null(self);
if(lhs_import)
context->import_index = 1 + lhs_import->file_scope->import_index;
- reg = ast_generate_ssa(self->rhs, context);
+ reg = ast_generate_ir(self->rhs, context);
context->import_index = 0;
} else {
- const SsaRegister lhs_reg = ast_generate_ssa(self->lhs, context);
- const SsaRegister rhs_reg = ast_generate_ssa(self->rhs, context);
- assert(self->lhs->resolve_data.type.type == RESOLVED_TYPE_LHS_EXPR && "TODO: Implement binop_generate_ssa for function signature");
- throw_if_error(ssa_ins_binop(context->ssa, binop_type_to_ssa_type(self->type, (amal_default_type*)self->lhs->resolve_data.type.value.lhs_expr), lhs_reg, rhs_reg, &reg));
+ const IrRegister lhs_reg = ast_generate_ir(self->lhs, context);
+ const IrRegister rhs_reg = ast_generate_ir(self->rhs, context);
+ assert(self->lhs->resolve_data.type.type == RESOLVED_TYPE_LHS_EXPR && "TODO: Implement binop_generate_ir for function signature");
+ throw_if_error(ir_ins_binop(context->ir, binop_type_to_ir_type(self->type, (amal_default_type*)self->lhs->resolve_data.type.value.lhs_expr), lhs_reg, rhs_reg, &reg));
}
return reg;
}
-static void else_if_statement_generate_ssa(ElseIfStatement *else_if_stmt, SsaCompilerContext *context, SsaLabelIndex *skip_other_else_statements_label) {
+static void else_if_statement_generate_ir(ElseIfStatement *else_if_stmt, IrCompilerContext *context, IrLabelIndex *skip_other_else_statements_label) {
if(else_if_stmt->condition) {
usize jump_ins_index;
usize jump_skip_else_index;
- SsaLabelIndex skip_body_label;
- SsaRegister condition_reg = ast_generate_ssa(else_if_stmt->condition, context);
- throw_if_error(ssa_ins_jumpzero(context->ssa, condition_reg, 0, &jump_ins_index));
- scope_generate_ssa(&else_if_stmt->body, context);
+ IrLabelIndex skip_body_label;
+ IrRegister condition_reg = ast_generate_ir(else_if_stmt->condition, context);
+ throw_if_error(ir_ins_jumpzero(context->ir, condition_reg, 0, &jump_ins_index));
+ scope_generate_ir(&else_if_stmt->body, context);
if(else_if_stmt->next_else_if_stmt)
- throw_if_error(ssa_ins_jump(context->ssa, 0, &jump_skip_else_index));
+ throw_if_error(ir_ins_jump(context->ir, 0, &jump_skip_else_index));
- throw_if_error(ssa_ins_label(context->ssa, &skip_body_label));
- throw_if_error(ssa_set_jump_label(context->ssa, jump_ins_index, skip_body_label));
+ throw_if_error(ir_ins_label(context->ir, &skip_body_label));
+ throw_if_error(ir_set_jump_label(context->ir, jump_ins_index, skip_body_label));
if(else_if_stmt->next_else_if_stmt) {
- else_if_statement_generate_ssa(else_if_stmt->next_else_if_stmt, context, skip_other_else_statements_label);
- /* Skip over all other else if statements, since else_if_statement_generate_ssa is recursive */
- throw_if_error(ssa_set_jump_label(context->ssa, jump_skip_else_index, *skip_other_else_statements_label));
+ else_if_statement_generate_ir(else_if_stmt->next_else_if_stmt, context, skip_other_else_statements_label);
+ /* Skip over all other else if statements, since else_if_statement_generate_ir is recursive */
+ throw_if_error(ir_set_jump_label(context->ir, jump_skip_else_index, *skip_other_else_statements_label));
return;
}
} else {
assert(!else_if_stmt->next_else_if_stmt);
- scope_generate_ssa(&else_if_stmt->body, context);
+ scope_generate_ir(&else_if_stmt->body, context);
}
/* Note: The last else if statement doesn't need a jump */
- throw_if_error(ssa_ins_label(context->ssa, skip_other_else_statements_label));
+ throw_if_error(ir_ins_label(context->ir, skip_other_else_statements_label));
}
-static void if_statement_generate_ssa(IfStatement *if_stmt, SsaCompilerContext *context) {
+static void if_statement_generate_ir(IfStatement *if_stmt, IrCompilerContext *context) {
usize jump_ins_index;
usize jump_skip_else_index;
- SsaLabelIndex skip_body_label;
- SsaLabelIndex skip_else_statements_label;
+ IrLabelIndex skip_body_label;
+ IrLabelIndex skip_else_statements_label;
- SsaRegister condition_reg = ast_generate_ssa(if_stmt->condition, context);
- throw_if_error(ssa_ins_jumpzero(context->ssa, condition_reg, 0, &jump_ins_index));
- scope_generate_ssa(&if_stmt->body, context);
+ IrRegister condition_reg = ast_generate_ir(if_stmt->condition, context);
+ throw_if_error(ir_ins_jumpzero(context->ir, condition_reg, 0, &jump_ins_index));
+ scope_generate_ir(&if_stmt->body, context);
if(if_stmt->else_if_stmt)
- throw_if_error(ssa_ins_jump(context->ssa, 0, &jump_skip_else_index));
+ throw_if_error(ir_ins_jump(context->ir, 0, &jump_skip_else_index));
- throw_if_error(ssa_ins_label(context->ssa, &skip_body_label));
- throw_if_error(ssa_set_jump_label(context->ssa, jump_ins_index, skip_body_label));
+ throw_if_error(ir_ins_label(context->ir, &skip_body_label));
+ throw_if_error(ir_set_jump_label(context->ir, jump_ins_index, skip_body_label));
if(if_stmt->else_if_stmt) {
- else_if_statement_generate_ssa(if_stmt->else_if_stmt, context, &skip_else_statements_label);
+ else_if_statement_generate_ir(if_stmt->else_if_stmt, context, &skip_else_statements_label);
/*
- Skip over all else if statements, since else_if_statement_generate_ssa is recursive.
+ Skip over all else if statements, since else_if_statement_generate_ir is recursive.
We want to jump since we want to skip the else if statements if we are inside the first if-statement
*/
- throw_if_error(ssa_set_jump_label(context->ssa, jump_skip_else_index, skip_else_statements_label));
+ throw_if_error(ir_set_jump_label(context->ir, jump_skip_else_index, skip_else_statements_label));
}
}
-static void while_statement_generate_ssa(WhileStatement *while_stmt, SsaCompilerContext *context) {
- SsaLabelIndex before_condition_label;
- SsaLabelIndex skip_body_label;
+static void while_statement_generate_ir(WhileStatement *while_stmt, IrCompilerContext *context) {
+ IrLabelIndex before_condition_label;
+ IrLabelIndex skip_body_label;
usize jump_after_condition_index;
- SsaRegister condition_reg;
+ IrRegister condition_reg;
- throw_if_error(ssa_ins_label(context->ssa, &before_condition_label));
- condition_reg = ast_generate_ssa(while_stmt->condition, context);
- throw_if_error(ssa_ins_jumpzero(context->ssa, condition_reg, 0, &jump_after_condition_index));
- scope_generate_ssa(&while_stmt->body, context);
+ throw_if_error(ir_ins_label(context->ir, &before_condition_label));
+ condition_reg = ast_generate_ir(while_stmt->condition, context);
+ throw_if_error(ir_ins_jumpzero(context->ir, condition_reg, 0, &jump_after_condition_index));
+ scope_generate_ir(&while_stmt->body, context);
- throw_if_error(ssa_ins_jump(context->ssa, before_condition_label, NULL));
- throw_if_error(ssa_ins_label(context->ssa, &skip_body_label));
- throw_if_error(ssa_set_jump_label(context->ssa, jump_after_condition_index, skip_body_label));
+ throw_if_error(ir_ins_jump(context->ir, before_condition_label, NULL));
+ throw_if_error(ir_ins_label(context->ir, &skip_body_label));
+ throw_if_error(ir_set_jump_label(context->ir, jump_after_condition_index, skip_body_label));
}
-static void return_expr_generate_ssa(ReturnExpr *self, SsaCompilerContext *context) {
- const SsaRegister reg = ast_generate_ssa(self->rhs_expr, context);
- throw_if_error(ssa_ins_return(context->ssa, reg));
+static void return_expr_generate_ir(ReturnExpr *self, IrCompilerContext *context) {
+ const IrRegister reg = ast_generate_ir(self->rhs_expr, context);
+ throw_if_error(ir_ins_return(context->ir, reg));
}
-static CHECK_RESULT SsaRegister ast_generate_ssa_resolve_data(void *ast_data, AstType ast_type, AstResolveData *resolve_data, SsaCompilerContext *context) {
- if(resolve_data->status == AST_SSA_RESOLVED)
- return resolve_data->ssa_reg;
+static CHECK_RESULT IrRegister ast_generate_ir_resolve_data(void *ast_data, AstType ast_type, AstResolveData *resolve_data, IrCompilerContext *context) {
+ if(resolve_data->status == AST_IR_RESOLVED)
+ return resolve_data->ir_reg;
switch(ast_type) {
case AST_NUMBER:
- resolve_data->ssa_reg = number_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = number_generate_ir(ast_data, context);
break;
case AST_FUNCTION_DECL:
- resolve_data->ssa_reg = funcdecl_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = funcdecl_generate_ir(ast_data, context);
break;
case AST_FUNCTION_CALL:
- resolve_data->ssa_reg = funccall_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = funccall_generate_ir(ast_data, context);
break;
case AST_STRUCT_DECL:
- resolve_data->ssa_reg = structdecl_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = structdecl_generate_ir(ast_data, context);
break;
case AST_STRUCT_FIELD:
- resolve_data->ssa_reg = structfield_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = structfield_generate_ir(ast_data, context);
break;
case AST_LHS:
- resolve_data->ssa_reg = lhsexpr_generate_ssa(ast_data, resolve_data, context);
+ resolve_data->ir_reg = lhsexpr_generate_ir(ast_data, resolve_data, context);
break;
case AST_ASSIGN:
- resolve_data->ssa_reg = assignmentexpr_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = assignmentexpr_generate_ir(ast_data, context);
break;
case AST_IMPORT:
/* TODO: Implement cross file references */
- resolve_data->ssa_reg = 0;
+ resolve_data->ir_reg = 0;
break;
case AST_STRING:
- resolve_data->ssa_reg = string_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = string_generate_ir(ast_data, context);
break;
case AST_VARIABLE:
- resolve_data->ssa_reg = variable_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = variable_generate_ir(ast_data, context);
break;
case AST_BINOP:
- resolve_data->ssa_reg = binop_generate_ssa(ast_data, context);
+ resolve_data->ir_reg = binop_generate_ir(ast_data, context);
break;
case AST_IF_STATEMENT:
- if_statement_generate_ssa(ast_data, context);
+ if_statement_generate_ir(ast_data, context);
break;
case AST_WHILE_STATEMENT:
- while_statement_generate_ssa(ast_data, context);
+ while_statement_generate_ir(ast_data, context);
break;
case AST_RETURN:
- return_expr_generate_ssa(ast_data, context);
- resolve_data->ssa_reg = 0;
+ return_expr_generate_ir(ast_data, context);
+ resolve_data->ir_reg = 0;
break;
}
- resolve_data->status = AST_SSA_RESOLVED;
- return resolve_data->ssa_reg;
+ resolve_data->status = AST_IR_RESOLVED;
+ return resolve_data->ir_reg;
}
-CHECK_RESULT SsaRegister ast_generate_ssa(Ast *self, SsaCompilerContext *context) {
+CHECK_RESULT IrRegister ast_generate_ir(Ast *self, IrCompilerContext *context) {
assert(self);
#ifdef DEBUG
- if(self->resolve_data.status != AST_RESOLVED && self->resolve_data.status != AST_SSA_RESOLVED) {
+ if(self->resolve_data.status != AST_RESOLVED && self->resolve_data.status != AST_IR_RESOLVED) {
amal_log_error("Ast type not resolved: %d", self->type);
assert(bool_false);
}
#endif
- return ast_generate_ssa_resolve_data(self->value.data, self->type, &self->resolve_data, context);
+ return ast_generate_ir_resolve_data(self->value.data, self->type, &self->resolve_data, context);
}
-CHECK_RESULT SsaRegister scope_named_object_generate_ssa(ScopeNamedObject *self, SsaCompilerContext *context) {
+CHECK_RESULT IrRegister scope_named_object_generate_ir(ScopeNamedObject *self, IrCompilerContext *context) {
switch(self->type) {
case NAMED_OBJECT_NONE:
assert(bool_false);
return 0;
case NAMED_OBJECT_LHS_EXPR:
- return ast_generate_ssa_resolve_data(self->value.lhs_expr, AST_LHS, self->resolve_data, context);
+ return ast_generate_ir_resolve_data(self->value.lhs_expr, AST_LHS, self->resolve_data, context);
case NAMED_OBJECT_FUNC_PARAM:
- return function_parameter_generate_ssa(self->value.func_param, context);
+ return function_parameter_generate_ir(self->value.func_param, context);
}
return 0;
}
-void scope_generate_ssa(Scope *self, SsaCompilerContext *context) {
+void scope_generate_ir(Scope *self, IrCompilerContext *context) {
Ast **ast = buffer_begin(&self->ast_objects);
Ast **ast_end = buffer_end(&self->ast_objects);
for(; ast != ast_end; ++ast) {
- ignore_result_int(ast_generate_ssa(*ast, context));
+ ignore_result_int(ast_generate_ir(*ast, context));
}
}
diff --git a/src/parser.c b/src/parser.c
index 01cf196..fb21b19 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -37,7 +37,7 @@ static void parser_queue_file(Parser *self, BufferView path, ParserFileScopeRefe
int parser_init(Parser *self, amal_compiler *compiler, ArenaAllocator *allocator) {
self->allocator = allocator;
self->compiler = compiler;
- self->ssa = NULL;
+ self->ir = NULL;
self->started = bool_false;
self->error.index = 0;
self->error.str = NULL;
diff --git a/src/program.c b/src/program.c
index 169d270..6c5ac7b 100644
--- a/src/program.c
+++ b/src/program.c
@@ -15,7 +15,7 @@
/* TODO: If system is big-endian, then do endian conversion for all reads */
-/* This matches SsaNumberType */
+/* This matches IrNumberType */
typedef enum {
NUMBER_TYPE_INTEGER,
NUMBER_TYPE_FLOAT