X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ir.c;h=1f9a80db3d213436fce94ad993f45dd46d1ab31b;hp=4dc791410f415908cca89cdd21e79d6b93c3bd5b;hb=04dca17cffcf250a6f561b8624fe053b96e37f86;hpb=f9746a59ae2d39df53d1526527297b52121581cf diff --git a/ir.c b/ir.c index 4dc7914..1f9a80d 100644 --- a/ir.c +++ b/ir.c @@ -462,7 +462,7 @@ ir_block* ir_block_new(ir_function* owner, const char *name) memset(self, 0, sizeof(*self)); self->label = NULL; - if (!ir_block_set_label(self, name)) { + if (name && !ir_block_set_label(self, name)) { mem_d(self); return NULL; } @@ -491,7 +491,7 @@ MEM_VEC_FUNCTIONS_ALL(ir_block, ir_value*, living) void ir_block_delete(ir_block* self) { size_t i; - mem_d(self->label); + if (self->label) mem_d(self->label); for (i = 0; i != self->instr_count; ++i) ir_instr_delete(self->instr[i]); MEM_VECTOR_CLEAR(self, instr); @@ -630,7 +630,11 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype) self->context.file = "<@no context>"; self->context.line = 0; self->name = NULL; - ir_value_set_name(self, name); + if (name && !ir_value_set_name(self, name)) { + irerror(self->context, "out of memory"); + mem_d(self); + return NULL; + } memset(&self->constval, 0, sizeof(self->constval)); memset(&self->code, 0, sizeof(self->code)); @@ -723,11 +727,12 @@ void ir_value_delete(ir_value* self) mem_d(self); } -void ir_value_set_name(ir_value *self, const char *name) +bool ir_value_set_name(ir_value *self, const char *name) { if (self->name) mem_d((void*)self->name); self->name = util_strdup(name); + return !!self->name; } bool ir_value_set_float(ir_value *self, float f) @@ -919,14 +924,14 @@ bool ir_value_life_merge_into(ir_value *self, const ir_value *other) } if (life->start < entry->start && - life->end >= entry->start) + life->end+1 >= entry->start) { /* starts earlier and overlaps */ entry->start = life->start; } - if (life->end > entry->end && - life->start-1 <= entry->end) + if (life->end > entry->end && + life->start <= entry->end+1) { /* ends later and overlaps */ entry->end = life->end; @@ -2231,7 +2236,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change * * Breaking conventions is annoying... */ -static bool ir_builder_gen_global(ir_builder *self, ir_value *global); +static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal); static bool gen_global_field(ir_value *global) { @@ -2576,7 +2581,7 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) local_var_end = fun.firstlocal; for (i = 0; i < irfun->locals_count; ++i) { - if (!ir_builder_gen_global(ir, irfun->locals[i])) { + if (!ir_builder_gen_global(ir, irfun->locals[i], true)) { irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name); return false; } @@ -2639,7 +2644,7 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global) return true; } -static bool ir_builder_gen_global(ir_builder *self, ir_value *global) +static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal) { size_t i; int32_t *iptr; @@ -2667,8 +2672,9 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global) /* I'd argue setting it to 0 is sufficient, but maybe some depend on knowing how far * the system fields actually go? Though the engine knows this anyway... * Maybe this could be an -foption + * fteqcc creates data for end_sys_* - of size 1, so let's do the same */ - ir_value_code_setaddr(global, def.offset); + ir_value_code_setaddr(global, code_globals_add(0)); /* Add the def */ if (code_defs_add(def) < 0) return false; @@ -2685,33 +2691,35 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global) /* fall through */ case TYPE_FLOAT: { - if (code_defs_add(def) < 0) - return false; - if (global->isconst) { iptr = (int32_t*)&global->constval.vfloat; ir_value_code_setaddr(global, code_globals_add(*iptr)); - } else + } else { ir_value_code_setaddr(global, code_globals_add(0)); + if (!islocal) + def.type |= DEF_SAVEGLOBAL; + } + if (code_defs_add(def) < 0) + return false; return global->code.globaladdr >= 0; } case TYPE_STRING: { - if (code_defs_add(def) < 0) - return false; if (global->isconst) ir_value_code_setaddr(global, code_globals_add(code_cachedstring(global->constval.vstring))); - else + else { ir_value_code_setaddr(global, code_globals_add(0)); + if (!islocal) + def.type |= DEF_SAVEGLOBAL; + } + if (code_defs_add(def) < 0) + return false; return global->code.globaladdr >= 0; } case TYPE_VECTOR: { size_t d; - if (code_defs_add(def) < 0) - return false; - if (global->isconst) { iptr = (int32_t*)&global->constval.vvec; ir_value_code_setaddr(global, code_globals_add(iptr[0])); @@ -2731,20 +2739,30 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global) if (code_globals_add(0) < 0) return false; } + if (!islocal) + def.type |= DEF_SAVEGLOBAL; } + + if (code_defs_add(def) < 0) + return false; return global->code.globaladdr >= 0; } case TYPE_FUNCTION: - if (code_defs_add(def) < 0) - return false; if (!global->isconst) { ir_value_code_setaddr(global, code_globals_add(0)); - return global->code.globaladdr >= 0; + if (global->code.globaladdr < 0) + return false; } else { ir_value_code_setaddr(global, code_globals_elements); code_globals_add(code_functions_elements); - return gen_global_function(self, global); + if (!gen_global_function(self, global)) + return false; + if (!islocal) + def.type |= DEF_SAVEGLOBAL; } + if (code_defs_add(def) < 0) + return false; + return true; case TYPE_VARIANT: /* assume biggest type */ ir_value_code_setaddr(global, code_globals_add(0)); @@ -2836,7 +2854,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename) for (i = 0; i < self->globals_count; ++i) { - if (!ir_builder_gen_global(self, self->globals[i])) { + if (!ir_builder_gen_global(self, self->globals[i], false)) { return false; } } @@ -3096,10 +3114,10 @@ void ir_value_dump(ir_value* v, int (*oprintf)(const char*, ...)) } } -void ir_value_dump_life(ir_value *self, int (*oprintf)(const char*,...)) +void ir_value_dump_life(const ir_value *self, int (*oprintf)(const char*,...)) { size_t i; - oprintf("Life of %s:\n", self->name); + oprintf("Life of %12s:", self->name); for (i = 0; i < self->life_count; ++i) { oprintf(" + [%i, %i]\n", self->life[i].start, self->life[i].end);