X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.c;h=afe4a40d1d5258988dac2e665f43c75a37faca21;hb=18b9473cf823e9e69f0557f125ac5d255236a899;hp=6081b5545bc049ef78b105a0fdd1275d1dab8ad1;hpb=24f3098418003271b26b6f0f1ba6e8411fa6e672;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index 6081b55..afe4a40 100644 --- a/ir.c +++ b/ir.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012, 2013 * Wolfgang Bumiller * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -42,7 +42,10 @@ const char *type_name[TYPE_COUNT] = { "variant", "struct", "union", - "array" + "array", + + "nil", + "" }; size_t type_sizeof_[TYPE_COUNT] = { @@ -59,6 +62,8 @@ size_t type_sizeof_[TYPE_COUNT] = { 0, /* TYPE_STRUCT */ 0, /* TYPE_UNION */ 0, /* TYPE_ARRAY */ + 0, /* TYPE_NIL */ + 0, /* TYPE_NOESPR */ }; uint16_t type_store_instr[TYPE_COUNT] = { @@ -81,6 +86,8 @@ uint16_t type_store_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; uint16_t field_store_instr[TYPE_COUNT] = { @@ -103,6 +110,8 @@ uint16_t field_store_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; uint16_t type_storep_instr[TYPE_COUNT] = { @@ -125,6 +134,8 @@ uint16_t type_storep_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; uint16_t type_eq_instr[TYPE_COUNT] = { @@ -147,6 +158,8 @@ uint16_t type_eq_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; uint16_t type_ne_instr[TYPE_COUNT] = { @@ -169,6 +182,8 @@ uint16_t type_ne_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; uint16_t type_not_instr[TYPE_COUNT] = { @@ -191,6 +206,8 @@ uint16_t type_not_instr[TYPE_COUNT] = { AINSTR_END, /* struct */ AINSTR_END, /* union */ AINSTR_END, /* array */ + AINSTR_END, /* nil */ + AINSTR_END, /* noexpr */ }; /* protos */ @@ -300,6 +317,9 @@ ir_builder* ir_builder_new(const char *modulename) return NULL; } + self->nil = ir_value_var("nil", store_value, TYPE_NIL); + self->nil->cvq = CV_CONST; + return self; } @@ -325,6 +345,7 @@ void ir_builder_delete(ir_builder* self) for (i = 0; i != vec_size(self->fields); ++i) { ir_value_delete(self->fields[i]); } + ir_value_delete(self->nil); vec_free(self->fields); vec_free(self->filenames); vec_free(self->filestrings); @@ -759,8 +780,10 @@ bool ir_function_finalize(ir_function *self) } } - if (!ir_function_naive_phi(self)) + if (!ir_function_naive_phi(self)) { + irerror(self->context, "internal error: ir_function_naive_phi failed"); return false; + } for (i = 0; i < vec_size(self->locals); ++i) { ir_value *v = self->locals[i]; @@ -2297,6 +2320,9 @@ bool ir_function_allocate_locals(ir_function *self) if (vec_size(v->writes) == 1 && v->writes[0]->opcode == INSTR_CALL0) { v->store = store_return; + if (v->members[0]) v->members[0]->store = store_return; + if (v->members[1]) v->members[1]->store = store_return; + if (v->members[2]) v->members[2]->store = store_return; ++opts_optimizationcount[OPTIM_CALL_STORES]; continue; } @@ -2481,7 +2507,9 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change size_t i, o, p, mem; /* bitmasks which operands are read from or written to */ size_t read, write; - char dbg_ind[16] = { '#', '0' }; + char dbg_ind[16]; + dbg_ind[0] = '#'; + dbg_ind[1] = '0'; (void)dbg_ind; if (prev) @@ -2912,6 +2940,8 @@ tailcall: if (param->vtype == TYPE_FIELD) stmt.opcode = field_store_instr[param->fieldtype]; + else if (param->vtype == TYPE_NIL) + stmt.opcode = INSTR_STORE_V; else stmt.opcode = type_store_instr[param->vtype]; stmt.o1.u1 = ir_value_code_addr(param); @@ -2939,6 +2969,8 @@ tailcall: if (param->vtype == TYPE_FIELD) stmt.opcode = field_store_instr[param->fieldtype]; + else if (param->vtype == TYPE_NIL) + stmt.opcode = INSTR_STORE_V; else stmt.opcode = type_store_instr[param->vtype]; stmt.o1.u1 = ir_value_code_addr(param); @@ -3619,6 +3651,12 @@ bool ir_builder_generate(ir_builder *self, const char *filename) } } + /* generate nil */ + ir_value_code_setaddr(self->nil, vec_size(code_globals)); + vec_push(code_globals, 0); + vec_push(code_globals, 0); + vec_push(code_globals, 0); + /* generate global temps */ self->first_common_globaltemp = vec_size(code_globals); for (i = 0; i < self->max_globaltemps; ++i) { @@ -3764,7 +3802,7 @@ void ir_function_dump(ir_function *f, char *ind, attr = "unique "; else if (v->locked) attr = "locked "; - oprintf("%s\t%s: %s@%i ", ind, v->name, attr, (int)v->code.local); + oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local); for (l = 0; l < vec_size(v->life); ++l) { oprintf("[%i,%i] ", v->life[l].start, v->life[l].end); } @@ -3787,13 +3825,36 @@ void ir_function_dump(ir_function *f, char *ind, } } for (i = 0; i < vec_size(f->values); ++i) { - size_t l; + const char *attr = ""; + size_t l, m; ir_value *v = f->values[i]; - oprintf("%s\t%s: @%i ", ind, v->name, (int)v->code.local); + if (v->unique_life && v->locked) + attr = "unique,locked "; + else if (v->unique_life) + attr = "unique "; + else if (v->locked) + attr = "locked "; + oprintf("%s\t%s: %s %s@%i ", ind, v->name, type_name[v->vtype], attr, (int)v->code.local); for (l = 0; l < vec_size(v->life); ++l) { oprintf("[%i,%i] ", v->life[l].start, v->life[l].end); } oprintf("\n"); + for (m = 0; m < 3; ++m) { + ir_value *vm = v->members[m]; + if (!vm) + continue; + if (vm->unique_life && vm->locked) + attr = "unique,locked "; + else if (vm->unique_life) + attr = "unique "; + else if (vm->locked) + attr = "locked "; + oprintf("%s\t%s: %s@%i ", ind, vm->name, attr, (int)vm->code.local); + for (l = 0; l < vec_size(vm->life); ++l) { + oprintf("[%i,%i] ", vm->life[l].start, vm->life[l].end); + } + oprintf("\n"); + } } if (vec_size(f->blocks)) {