/*
- * Copyright (C) 2012
+ * Copyright (C) 2012, 2013
* Wolfgang Bumiller
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
"variant",
"struct",
"union",
- "array"
+ "array",
+
+ "nil",
+ "<no-expression>"
};
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] = {
AINSTR_END, /* struct */
AINSTR_END, /* union */
AINSTR_END, /* array */
+ AINSTR_END, /* nil */
+ AINSTR_END, /* noexpr */
};
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] = {
AINSTR_END, /* struct */
AINSTR_END, /* union */
AINSTR_END, /* array */
+ AINSTR_END, /* nil */
+ AINSTR_END, /* noexpr */
};
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] = {
AINSTR_END, /* struct */
AINSTR_END, /* union */
AINSTR_END, /* array */
+ AINSTR_END, /* nil */
+ AINSTR_END, /* noexpr */
};
uint16_t type_not_instr[TYPE_COUNT] = {
AINSTR_END, /* struct */
AINSTR_END, /* union */
AINSTR_END, /* array */
+ AINSTR_END, /* nil */
+ AINSTR_END, /* noexpr */
};
/* protos */
return NULL;
}
+ self->nil = ir_value_var("nil", store_value, TYPE_NIL);
+ self->nil->cvq = CV_CONST;
+
return 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);
}
}
- 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];
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;
}
if (onfalse->generated) {
/* fixup the jump address */
code_statements[stidx].o2.s1 = (onfalse->code_start) - (stidx);
- if (code_statements[stidx].o2.s1 == 1) {
+ if (stidx+2 == vec_size(code_statements) && code_statements[stidx].o2.s1 == 1) {
code_statements[stidx] = code_statements[stidx+1];
if (code_statements[stidx].o1.s1 < 0)
code_statements[stidx].o1.s1++;
code_push_statement(&stmt, instr->context.line);
return true;
}
- else if (code_statements[stidx].o2.s1 == 1) {
+ else if (stidx+2 == vec_size(code_statements) && code_statements[stidx].o2.s1 == 1) {
code_statements[stidx] = code_statements[stidx+1];
if (code_statements[stidx].o1.s1 < 0)
code_statements[stidx].o1.s1++;
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);
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);
}
}
+ /* 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) {
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);
}
}
}
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))
{