diff --git a/ir.c b/ir.c index ee07a44..ec45a8f 100644 --- a/ir.c +++ b/ir.c @@ -312,6 +312,7 @@ static void ir_function_delete_quick(ir_function *self); ir_builder* ir_builder_new(const char *modulename) { ir_builder* self; + size_t i; self = (ir_builder*)mem_a(sizeof(*self)); if (!self) @@ -344,6 +345,15 @@ ir_builder* ir_builder_new(const char *modulename) self->nil = ir_value_var("nil", store_value, TYPE_NIL); self->nil->cvq = CV_CONST; + for (i = 0; i != IR_MAX_VINSTR_TEMPS; ++i) { + /* we write to them, but they're not supposed to be used outside the IR, so + * let's not allow the generation of ir_instrs which use these. + * So it's a constant noexpr. + */ + self->vinstr_temp[i] = ir_value_var("vinstr_temp", store_value, TYPE_NOEXPR); + self->vinstr_temp[i]->cvq = CV_CONST; + } + self->reserved_va_count = NULL; self->code = code_init(); @@ -374,6 +384,9 @@ void ir_builder_delete(ir_builder* self) ir_value_delete(self->fields[i]); } ir_value_delete(self->nil); + for (i = 0; i != IR_MAX_VINSTR_TEMPS; ++i) { + ir_value_delete(self->vinstr_temp[i]); + } vec_free(self->fields); vec_free(self->filenames); vec_free(self->filestrings); @@ -3652,6 +3665,14 @@ bool ir_builder_generate(ir_builder *self, const char *filename) vec_push(self->code->globals, 0); vec_push(self->code->globals, 0); + /* generate virtual-instruction temps */ + for (i = 0; i < IR_MAX_VINSTR_TEMPS; ++i) { + ir_value_code_setaddr(self->vinstr_temp[i], vec_size(self->code->globals)); + vec_push(self->code->globals, 0); + vec_push(self->code->globals, 0); + vec_push(self->code->globals, 0); + } + /* generate global temps */ self->first_common_globaltemp = vec_size(self->code->globals); for (i = 0; i < self->max_globaltemps; ++i) { diff --git a/ir.h b/ir.h index b62b09d..46ac464 100644 --- a/ir.h +++ b/ir.h @@ -240,6 +240,7 @@ ir_block* ir_function_create_block(lex_ctx_t ctx, ir_function*, const char /* builder */ #define IR_HT_SIZE 1024 +#define IR_MAX_VINSTR_TEMPS 1 typedef struct ir_builder_s { char *name; @@ -261,12 +262,16 @@ typedef struct ir_builder_s uint32_t first_common_globaltemp; const char **filenames; - qcint_t *filestrings; + qcint_t *filestrings; /* we cache the #IMMEDIATE string here */ - qcint_t str_immediate; + qcint_t str_immediate; /* there should just be this one nil */ ir_value *nil; ir_value *reserved_va_count; + /* some virtual instructions require temps, and their code is isolated + * so that we don't need to keep track of their liveness. + */ + ir_value *vinstr_temp[IR_MAX_VINSTR_TEMPS]; /* code generator */ code_t *code;