Initial commit of dem beast./plot.py

This commit is contained in:
2025-12-02 06:54:32 +01:00
commit c9cf356cbd
58 changed files with 9092 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
#include "fastframe.h"
#include <string.h>
FastFrame_t rava_frame_pool[RAVA_MAX_CALL_DEPTH];
size_t rava_frame_depth = 0;
void rava_fastframe_init(void) {
rava_frame_depth = 0;
memset(rava_frame_pool, 0, sizeof(rava_frame_pool));
}
FastFrame_t* rava_fastframe_push(RavaMethod_t* method, int local_count) {
if (rava_frame_depth >= RAVA_MAX_CALL_DEPTH) {
return NULL;
}
FastFrame_t* frame = &rava_frame_pool[rava_frame_depth++];
frame->method = method;
frame->stack_top = 0;
frame->pc = 0;
frame->has_this = false;
frame->this_ref = rava_nanbox_null();
if (local_count > 0 && local_count <= RAVA_MAX_LOCALS_FIXED) {
memset(frame->locals, 0, (size_t)local_count * sizeof(RavaNanboxValue_t));
}
return frame;
}
void rava_fastframe_pop(void) {
if (rava_frame_depth > 0) {
rava_frame_depth--;
}
}
FastFrame_t* rava_fastframe_current(void) {
if (rava_frame_depth == 0) return NULL;
return &rava_frame_pool[rava_frame_depth - 1];
}
size_t rava_fastframe_get_depth(void) {
return rava_frame_depth;
}
void rava_fastframe_reset(void) {
rava_frame_depth = 0;
}
+63
View File
@@ -0,0 +1,63 @@
#ifndef RAVA_FASTFRAME_H
#define RAVA_FASTFRAME_H
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "nanbox.h"
#include "../ir/ir.h"
#define RAVA_MAX_CALL_DEPTH 1024
#define RAVA_MAX_LOCALS_FIXED 64
#define RAVA_MAX_STACK_FIXED 512
typedef struct {
RavaMethod_t* method;
RavaNanboxValue_t locals[RAVA_MAX_LOCALS_FIXED];
RavaNanboxValue_t stack[RAVA_MAX_STACK_FIXED];
size_t stack_top;
size_t pc;
bool has_this;
RavaNanboxValue_t this_ref;
} FastFrame_t;
extern FastFrame_t rava_frame_pool[RAVA_MAX_CALL_DEPTH];
extern size_t rava_frame_depth;
void rava_fastframe_init(void);
FastFrame_t* rava_fastframe_push(RavaMethod_t* method, int local_count);
void rava_fastframe_pop(void);
FastFrame_t* rava_fastframe_current(void);
size_t rava_fastframe_get_depth(void);
void rava_fastframe_reset(void);
static inline void rava_fastframe_stack_push(FastFrame_t* frame, RavaNanboxValue_t v) {
if (frame->stack_top < RAVA_MAX_STACK_FIXED) {
frame->stack[frame->stack_top++] = v;
}
}
static inline RavaNanboxValue_t rava_fastframe_stack_pop(FastFrame_t* frame) {
if (frame->stack_top > 0) {
return frame->stack[--frame->stack_top];
}
return rava_nanbox_null();
}
static inline RavaNanboxValue_t rava_fastframe_stack_peek(FastFrame_t* frame) {
if (frame->stack_top > 0) {
return frame->stack[frame->stack_top - 1];
}
return rava_nanbox_null();
}
static inline void rava_fastframe_stack_clear(FastFrame_t* frame) {
frame->stack_top = 0;
}
static inline bool rava_fastframe_stack_is_empty(FastFrame_t* frame) {
return frame->stack_top == 0;
}
#endif
+52
View File
@@ -0,0 +1,52 @@
#include "labeltable.h"
#include <stdlib.h>
#include <string.h>
LabelTable_t* rava_labeltable_create(RavaInstructionList_t* instructions) {
if (!instructions) return NULL;
LabelTable_t* table = malloc(sizeof(LabelTable_t));
if (!table) return NULL;
int max_label = 0;
for (size_t i = 0; i < instructions->count; i++) {
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
int lid = instructions->instructions[i].operand.label_id;
if (lid > max_label) max_label = lid;
}
}
table->max_label_id = (size_t)max_label;
table->label_to_pc = calloc((size_t)(max_label + 1), sizeof(int));
if (!table->label_to_pc) {
free(table);
return NULL;
}
for (int i = 0; i <= max_label; i++) {
table->label_to_pc[i] = -1;
}
for (size_t i = 0; i < instructions->count; i++) {
if (instructions->instructions[i].opcode == RAVA_OP_LABEL) {
int lid = instructions->instructions[i].operand.label_id;
table->label_to_pc[lid] = (int)(i + 1);
}
}
return table;
}
void rava_labeltable_destroy(LabelTable_t* table) {
if (!table) return;
free(table->label_to_pc);
free(table);
}
size_t rava_labeltable_lookup(LabelTable_t* table, int label_id) {
if (!table || label_id < 0 || (size_t)label_id > table->max_label_id) {
return 0;
}
int pc = table->label_to_pc[label_id];
return (pc >= 0) ? (size_t)pc : 0;
}
+17
View File
@@ -0,0 +1,17 @@
#ifndef RAVA_LABELTABLE_H
#define RAVA_LABELTABLE_H
#include <stddef.h>
#include <stdint.h>
#include "../ir/ir.h"
typedef struct LabelTable_s {
int* label_to_pc;
size_t max_label_id;
} LabelTable_t;
LabelTable_t* rava_labeltable_create(RavaInstructionList_t* instructions);
void rava_labeltable_destroy(LabelTable_t* table);
size_t rava_labeltable_lookup(LabelTable_t* table, int label_id);
#endif
+57
View File
@@ -0,0 +1,57 @@
#include "methodcache.h"
#include <stdlib.h>
#include <string.h>
MethodCache_t* rava_methodcache_create(void) {
MethodCache_t* cache = malloc(sizeof(MethodCache_t));
if (cache) {
memset(cache, 0, sizeof(MethodCache_t));
}
return cache;
}
void rava_methodcache_destroy(MethodCache_t* cache) {
if (cache) free(cache);
}
RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
const char* classname,
const char* methodname) {
if (!cache || !classname || !methodname) return NULL;
uint32_t class_hash = rava_methodcache_hash(classname);
uint32_t method_hash = rava_methodcache_hash(methodname);
uint32_t idx = (class_hash ^ method_hash) & RAVA_METHOD_CACHE_MASK;
MethodCacheEntry_t* entry = &cache->entries[idx];
if (entry->class_hash == class_hash &&
entry->method_hash == method_hash &&
entry->method != NULL) {
return entry->method;
}
return NULL;
}
void rava_methodcache_insert(MethodCache_t* cache,
const char* classname,
const char* methodname,
RavaMethod_t* method) {
if (!cache || !classname || !methodname) return;
uint32_t class_hash = rava_methodcache_hash(classname);
uint32_t method_hash = rava_methodcache_hash(methodname);
uint32_t idx = (class_hash ^ method_hash) & RAVA_METHOD_CACHE_MASK;
MethodCacheEntry_t* entry = &cache->entries[idx];
entry->class_hash = class_hash;
entry->method_hash = method_hash;
entry->method = method;
}
void rava_methodcache_clear(MethodCache_t* cache) {
if (cache) {
memset(cache->entries, 0, sizeof(cache->entries));
}
}
+41
View File
@@ -0,0 +1,41 @@
#ifndef RAVA_METHODCACHE_H
#define RAVA_METHODCACHE_H
#include <stddef.h>
#include <stdint.h>
#include "../ir/ir.h"
#define RAVA_METHOD_CACHE_SIZE 256
#define RAVA_METHOD_CACHE_MASK (RAVA_METHOD_CACHE_SIZE - 1)
typedef struct {
uint32_t class_hash;
uint32_t method_hash;
RavaMethod_t* method;
} MethodCacheEntry_t;
typedef struct MethodCache_s {
MethodCacheEntry_t entries[RAVA_METHOD_CACHE_SIZE];
} MethodCache_t;
static inline uint32_t rava_methodcache_hash(const char* str) {
uint32_t hash = 5381;
while (*str) {
hash = ((hash << 5) + hash) ^ (uint32_t)*str;
str++;
}
return hash;
}
MethodCache_t* rava_methodcache_create(void);
void rava_methodcache_destroy(MethodCache_t* cache);
RavaMethod_t* rava_methodcache_lookup(MethodCache_t* cache,
const char* classname,
const char* methodname);
void rava_methodcache_insert(MethodCache_t* cache,
const char* classname,
const char* methodname,
RavaMethod_t* method);
void rava_methodcache_clear(MethodCache_t* cache);
#endif
+156
View File
@@ -0,0 +1,156 @@
#ifndef RAVA_NANBOX_H
#define RAVA_NANBOX_H
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
typedef uint64_t RavaNanboxValue_t;
#define RAVA_SIGN_BIT 0x8000000000000000ULL
#define RAVA_EXPONENT_MASK 0x7FF0000000000000ULL
#define RAVA_QNAN 0x7FF8000000000000ULL
#define RAVA_TAG_MASK 0xFFFF000000000000ULL
#define RAVA_PAYLOAD_MASK 0x0000FFFFFFFFFFFFULL
#define RAVA_TAG_INT (RAVA_QNAN | 0x0001000000000000ULL)
#define RAVA_TAG_LONG (RAVA_QNAN | 0x0002000000000000ULL)
#define RAVA_TAG_BOOL (RAVA_QNAN | 0x0003000000000000ULL)
#define RAVA_TAG_NULL (RAVA_QNAN | 0x0004000000000000ULL)
#define RAVA_TAG_OBJECT (RAVA_QNAN | 0x0005000000000000ULL)
#define RAVA_TAG_STRING (RAVA_QNAN | 0x0006000000000000ULL)
#define RAVA_TAG_ARRAY (RAVA_QNAN | 0x0007000000000000ULL)
static inline RavaNanboxValue_t rava_nanbox_int(int32_t v) {
return RAVA_TAG_INT | (uint64_t)(uint32_t)v;
}
static inline RavaNanboxValue_t rava_nanbox_long(int64_t v) {
return RAVA_TAG_LONG | ((uint64_t)v & RAVA_PAYLOAD_MASK);
}
static inline RavaNanboxValue_t rava_nanbox_bool(bool v) {
return RAVA_TAG_BOOL | (v ? 1ULL : 0ULL);
}
static inline RavaNanboxValue_t rava_nanbox_null(void) {
return RAVA_TAG_NULL;
}
static inline RavaNanboxValue_t rava_nanbox_double(double v) {
union { double d; uint64_t u; } u = {.d = v};
return u.u;
}
static inline RavaNanboxValue_t rava_nanbox_object(void* ptr) {
return RAVA_TAG_OBJECT | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
}
static inline RavaNanboxValue_t rava_nanbox_string(const char* ptr) {
return RAVA_TAG_STRING | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
}
static inline RavaNanboxValue_t rava_nanbox_array(void* ptr) {
return RAVA_TAG_ARRAY | ((uint64_t)(uintptr_t)ptr & RAVA_PAYLOAD_MASK);
}
static inline bool rava_nanbox_is_int(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_INT;
}
static inline bool rava_nanbox_is_long(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_LONG;
}
static inline bool rava_nanbox_is_bool(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_BOOL;
}
static inline bool rava_nanbox_is_null(RavaNanboxValue_t v) {
return v == RAVA_TAG_NULL;
}
static inline bool rava_nanbox_is_object(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_OBJECT;
}
static inline bool rava_nanbox_is_string(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_STRING;
}
static inline bool rava_nanbox_is_array(RavaNanboxValue_t v) {
return (v & RAVA_TAG_MASK) == RAVA_TAG_ARRAY;
}
static inline bool rava_nanbox_is_double(RavaNanboxValue_t v) {
return (v & RAVA_QNAN) != RAVA_QNAN;
}
static inline int32_t rava_nanbox_as_int(RavaNanboxValue_t v) {
return (int32_t)(v & 0xFFFFFFFF);
}
static inline int64_t rava_nanbox_as_long(RavaNanboxValue_t v) {
int64_t payload = (int64_t)(v & RAVA_PAYLOAD_MASK);
if (payload & 0x800000000000ULL) {
payload |= (int64_t)0xFFFF000000000000ULL;
}
return payload;
}
static inline bool rava_nanbox_as_bool(RavaNanboxValue_t v) {
return (v & 1) != 0;
}
static inline double rava_nanbox_as_double(RavaNanboxValue_t v) {
union { double d; uint64_t u; } u = {.u = v};
return u.d;
}
static inline void* rava_nanbox_as_object(RavaNanboxValue_t v) {
return (void*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
}
static inline const char* rava_nanbox_as_string(RavaNanboxValue_t v) {
return (const char*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
}
static inline void* rava_nanbox_as_array(RavaNanboxValue_t v) {
return (void*)(uintptr_t)(v & RAVA_PAYLOAD_MASK);
}
static inline int32_t rava_nanbox_to_int(RavaNanboxValue_t v) {
if (rava_nanbox_is_int(v)) return rava_nanbox_as_int(v);
if (rava_nanbox_is_long(v)) return (int32_t)rava_nanbox_as_long(v);
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1 : 0;
if (rava_nanbox_is_double(v)) return (int32_t)rava_nanbox_as_double(v);
return 0;
}
static inline int64_t rava_nanbox_to_long(RavaNanboxValue_t v) {
if (rava_nanbox_is_int(v)) return (int64_t)rava_nanbox_as_int(v);
if (rava_nanbox_is_long(v)) return rava_nanbox_as_long(v);
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1 : 0;
if (rava_nanbox_is_double(v)) return (int64_t)rava_nanbox_as_double(v);
return 0;
}
static inline double rava_nanbox_to_double(RavaNanboxValue_t v) {
if (rava_nanbox_is_double(v)) return rava_nanbox_as_double(v);
if (rava_nanbox_is_int(v)) return (double)rava_nanbox_as_int(v);
if (rava_nanbox_is_long(v)) return (double)rava_nanbox_as_long(v);
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v) ? 1.0 : 0.0;
return 0.0;
}
static inline bool rava_nanbox_to_bool(RavaNanboxValue_t v) {
if (rava_nanbox_is_null(v)) return false;
if (rava_nanbox_is_bool(v)) return rava_nanbox_as_bool(v);
if (rava_nanbox_is_int(v)) return rava_nanbox_as_int(v) != 0;
if (rava_nanbox_is_long(v)) return rava_nanbox_as_long(v) != 0;
if (rava_nanbox_is_double(v)) return rava_nanbox_as_double(v) != 0.0;
return true;
}
#endif
+2810
View File
File diff suppressed because it is too large Load Diff
+149
View File
@@ -0,0 +1,149 @@
#ifndef RAVA_RUNTIME_H
#define RAVA_RUNTIME_H
#include "../ir/ir.h"
#include "../types/types.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
typedef enum {
RAVA_VAL_INT,
RAVA_VAL_LONG,
RAVA_VAL_FLOAT,
RAVA_VAL_DOUBLE,
RAVA_VAL_BOOLEAN,
RAVA_VAL_CHAR,
RAVA_VAL_NULL,
RAVA_VAL_OBJECT,
RAVA_VAL_ARRAY,
RAVA_VAL_STRING
} RavaValueType_e;
typedef struct {
RavaValueType_e element_type;
size_t length;
void *data;
} RavaArray_t;
typedef struct RavaObject_t RavaObject_t;
typedef struct RavaValue_t RavaValue_t;
struct RavaObject_t {
char *class_name;
char **field_names;
RavaValue_t *field_values;
size_t field_count;
size_t field_capacity;
};
struct RavaValue_t {
RavaValueType_e type;
union {
int32_t int_val;
int64_t long_val;
float float_val;
double double_val;
bool bool_val;
char char_val;
RavaObject_t *object_val;
RavaArray_t *array_val;
char *string_val;
} data;
};
typedef struct {
RavaValue_t *values;
size_t capacity;
size_t top;
} RavaStack_t;
typedef struct {
RavaMethod_t *method;
RavaValue_t *locals;
size_t local_count;
size_t pc;
RavaStack_t *operand_stack;
RavaValue_t this_ref;
bool has_this;
} RavaCallFrame_t;
typedef struct {
RavaCallFrame_t **frames;
size_t capacity;
size_t count;
} RavaCallStack_t;
typedef struct {
char *class_name;
char *field_name;
RavaValue_t value;
} RavaStaticField_t;
typedef struct {
RavaStaticField_t *fields;
size_t count;
size_t capacity;
} RavaStaticFieldTable_t;
struct MethodCache_s;
typedef struct {
RavaProgram_t *program;
RavaCallStack_t *call_stack;
RavaStaticFieldTable_t *static_fields;
struct MethodCache_s *method_cache;
char *error_message;
bool had_error;
} RavaVM_t;
RavaValue_t rava_value_int(int32_t value);
RavaValue_t rava_value_long(int64_t value);
RavaValue_t rava_value_float(float value);
RavaValue_t rava_value_double(double value);
RavaValue_t rava_value_boolean(bool value);
RavaValue_t rava_value_null();
RavaValue_t rava_value_array(RavaArray_t *array);
RavaValue_t rava_value_string(const char *str);
int32_t rava_value_as_int(RavaValue_t value);
int64_t rava_value_as_long(RavaValue_t value);
double rava_value_as_double(RavaValue_t value);
bool rava_value_as_boolean(RavaValue_t value);
const char* rava_value_as_string(RavaValue_t value);
RavaArray_t* rava_array_create(RavaValueType_e element_type, size_t length);
void rava_array_destroy(RavaArray_t *array);
void rava_array_set_int(RavaArray_t *array, size_t index, int32_t value);
int32_t rava_array_get_int(RavaArray_t *array, size_t index);
size_t rava_array_length(RavaArray_t *array);
RavaObject_t* rava_object_create(const char *class_name);
void rava_object_destroy(RavaObject_t *obj);
void rava_object_set_field(RavaObject_t *obj, const char *name, RavaValue_t value);
RavaValue_t rava_object_get_field(RavaObject_t *obj, const char *name);
RavaValue_t rava_value_object(RavaObject_t *obj);
RavaStack_t* rava_stack_create(size_t capacity);
void rava_stack_destroy(RavaStack_t *stack);
void rava_stack_push(RavaStack_t *stack, RavaValue_t value);
RavaValue_t rava_stack_pop(RavaStack_t *stack);
RavaValue_t rava_stack_peek(RavaStack_t *stack);
bool rava_stack_is_empty(RavaStack_t *stack);
RavaCallFrame_t* rava_call_frame_create(RavaMethod_t *method);
void rava_call_frame_destroy(RavaCallFrame_t *frame);
RavaCallStack_t* rava_call_stack_create();
void rava_call_stack_destroy(RavaCallStack_t *stack);
void rava_call_stack_push(RavaCallStack_t *stack, RavaCallFrame_t *frame);
RavaCallFrame_t* rava_call_stack_pop(RavaCallStack_t *stack);
RavaCallFrame_t* rava_call_stack_current(RavaCallStack_t *stack);
RavaVM_t* rava_vm_create(RavaProgram_t *program);
void rava_vm_destroy(RavaVM_t *vm);
bool rava_vm_execute(RavaVM_t *vm, const char *class_name, const char *method_name);
RavaValue_t rava_vm_get_result(RavaVM_t *vm);
#endif
+149
View File
@@ -0,0 +1,149 @@
#include "superinst.h"
#include <string.h>
static void optimize_inc_dec_local(RavaInstruction_t *instrs, size_t count) {
for (size_t i = 0; i + 3 < count; i++) {
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
instrs[i+1].operand.int_value == 1 &&
instrs[i+2].opcode == RAVA_OP_ADD &&
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
instrs[i].opcode = RAVA_OP_INC_LOCAL;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
instrs[i+1].operand.int_value == 1 &&
instrs[i+2].opcode == RAVA_OP_SUB &&
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
instrs[i].opcode = RAVA_OP_DEC_LOCAL;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
}
}
static void optimize_loop_comparison(RavaInstruction_t *instrs, size_t count) {
for (size_t i = 0; i + 3 < count; i++) {
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
instrs[i+2].opcode == RAVA_OP_LT &&
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
int local_idx = instrs[i].operand.var.index;
int64_t const_val = instrs[i+1].operand.int_value;
int label = instrs[i+3].operand.label_id;
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_CONST_LT_JUMPFALSE;
instrs[i].operand.super.local_index = local_idx;
instrs[i].operand.super.const_value = const_val;
instrs[i].operand.super.label_id = label;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_CONST &&
instrs[i+2].opcode == RAVA_OP_LE &&
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
int local_idx = instrs[i].operand.var.index;
int64_t const_val = instrs[i+1].operand.int_value;
int label = instrs[i+3].operand.label_id;
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_CONST_LE_JUMPFALSE;
instrs[i].operand.super.local_index = local_idx;
instrs[i].operand.super.const_value = const_val;
instrs[i].operand.super.label_id = label;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
}
}
static void optimize_two_locals(RavaInstruction_t *instrs, size_t count) {
for (size_t i = 0; i + 1 < count; i++) {
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL) {
int idx1 = instrs[i].operand.var.index;
int idx2 = instrs[i+1].operand.var.index;
instrs[i].opcode = RAVA_OP_LOAD_TWO_LOCALS;
instrs[i].operand.two_locals.index1 = idx1;
instrs[i].operand.two_locals.index2 = idx2;
instrs[i+1].opcode = RAVA_OP_NOP;
}
}
}
static void optimize_add_local_to_local(RavaInstruction_t *instrs, size_t count) {
for (size_t i = 0; i + 3 < count; i++) {
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+2].opcode == RAVA_OP_ADD &&
instrs[i+3].opcode == RAVA_OP_STORE_LOCAL &&
instrs[i].operand.var.index == instrs[i+3].operand.var.index) {
int dest_idx = instrs[i].operand.var.index;
int src_idx = instrs[i+1].operand.var.index;
instrs[i].opcode = RAVA_OP_ADD_LOCAL_TO_LOCAL;
instrs[i].operand.add_locals.dest_index = dest_idx;
instrs[i].operand.add_locals.src_index = src_idx;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
}
}
static void optimize_local_lt_local_jump(RavaInstruction_t *instrs, size_t count) {
for (size_t i = 0; i + 3 < count; i++) {
if (instrs[i].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+1].opcode == RAVA_OP_LOAD_LOCAL &&
instrs[i+2].opcode == RAVA_OP_LT &&
instrs[i+3].opcode == RAVA_OP_JUMP_IF_FALSE) {
int local1 = instrs[i].operand.var.index;
int local2 = instrs[i+1].operand.var.index;
int label = instrs[i+3].operand.label_id;
instrs[i].opcode = RAVA_OP_LOAD_LOCAL_LT_LOCAL_JUMPFALSE;
instrs[i].operand.cmp_locals.local1 = local1;
instrs[i].operand.cmp_locals.local2 = local2;
instrs[i].operand.cmp_locals.label_id = label;
instrs[i+1].opcode = RAVA_OP_NOP;
instrs[i+2].opcode = RAVA_OP_NOP;
instrs[i+3].opcode = RAVA_OP_NOP;
}
}
}
void rava_optimize_superinstructions(RavaMethod_t* method) {
if (!method || !method->instructions) return;
RavaInstruction_t *instrs = method->instructions->instructions;
size_t count = method->instructions->count;
optimize_add_local_to_local(instrs, count);
optimize_local_lt_local_jump(instrs, count);
optimize_inc_dec_local(instrs, count);
optimize_loop_comparison(instrs, count);
optimize_two_locals(instrs, count);
}
+8
View File
@@ -0,0 +1,8 @@
#ifndef RAVA_SUPERINST_H
#define RAVA_SUPERINST_H
#include "../ir/ir.h"
void rava_optimize_superinstructions(RavaMethod_t* method);
#endif