feat: add initial plot.py module with beast visualization logic

This commit introduces the core plotting module for the beast project, including
the initial implementation of data visualization functions and chart generation
utilities. The module provides the foundational structure for rendering beast-related
metrics and graphical outputs.
This commit is contained in:
2025-12-02 05:54:32 +00:00
commit f9c7a0fa78
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