"array"
};
-size_t type_sizeof[TYPE_COUNT] = {
+size_t type_sizeof_[TYPE_COUNT] = {
1, /* TYPE_VOID */
1, /* TYPE_STRING */
1, /* TYPE_FLOAT */
(op >= INSTR_LOAD_F && op <= INSTR_LOAD_FNC) ||
(op == INSTR_ADDRESS) ||
(op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) ||
- (op >= INSTR_AND && op <= INSTR_BITOR) );
+ (op >= INSTR_AND && op <= INSTR_BITOR) ||
+ (op >= INSTR_CALL0 && op <= INSTR_CALL8) );
}
bool ir_function_pass_peephole(ir_function *self)
return true;
}
-bool ir_function_pass_tailcall(ir_function *self)
+bool ir_function_pass_tailrecursion(ir_function *self)
{
size_t b, p;
}
if (OPTS_OPTIMIZATION(OPTIM_TAIL_RECURSION)) {
- if (!ir_function_pass_tailcall(self)) {
- irerror(self->context, "tailcall optimization pass broke something in `%s`", self->name);
+ if (!ir_function_pass_tailrecursion(self)) {
+ irerror(self->context, "tail-recursion optimization pass broke something in `%s`", self->name);
return false;
}
}
return m;
}
+static GMQCC_INLINE size_t ir_value_sizeof(const ir_value *self)
+{
+ if (self->vtype == TYPE_FIELD && self->fieldtype == TYPE_VECTOR)
+ return type_sizeof_[TYPE_VECTOR];
+ return type_sizeof_[self->vtype];
+}
+
ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int vtype)
{
ir_value *v = ir_value_var(name, storetype, vtype);
in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0));
if (!in)
return NULL;
- /*
if (noreturn) {
self->final = true;
self->is_return = true;
}
- */
out = ir_value_out(self->owner, label, (func->outtype == TYPE_VOID) ? store_return : store_value, func->outtype);
if (!out) {
ir_instr_delete(in);
return NULL;
}
vec_push(self->instr, in);
+ /*
if (noreturn) {
if (!ir_block_create_return(self, ctx, NULL)) {
compile_error(ctx, "internal error: failed to generate dummy-return instruction");
return NULL;
}
}
+ */
return in;
}
static bool function_allocator_alloc(function_allocator *alloc, const ir_value *var)
{
ir_value *slot;
- size_t vsize = type_sizeof[var->vtype];
+ size_t vsize = ir_value_sizeof(var);
slot = ir_value_var("reg", store_global, var->vtype);
if (!slot)
for (i = 0; i < vec_size(self->locals); ++i)
{
+#if 0
if (!OPTS_OPTIMIZATION(OPTIM_LOCALTEMPS))
+#endif
self->locals[i]->unique_life = true;
if (!function_allocator_alloc(&alloc, self->locals[i]))
goto error;
* will be required later when overlapping temps + locals
*/
if (a < vec_size(self->params) &&
- alloc.sizes[a] < type_sizeof[v->vtype])
+ alloc.sizes[a] < ir_value_sizeof(v))
{
continue;
}
goto error;
/* adjust size for this slot */
- if (alloc.sizes[a] < type_sizeof[v->vtype])
- alloc.sizes[a] = type_sizeof[v->vtype];
+ if (alloc.sizes[a] < ir_value_sizeof(v))
+ alloc.sizes[a] = ir_value_sizeof(v);
self->values[i]->code.local = a;
break;
code_push_statement(&stmt, instr->context.line);
retvalue = instr->_ops[0];
- if (retvalue && retvalue->store != store_return && vec_size(retvalue->life))
+ if (retvalue && retvalue->store != store_return && (vec_size(retvalue->life) || retvalue->store == store_global))
{
/* not to be kept in OFS_RETURN */
- if (retvalue->vtype == TYPE_FIELD)
- stmt.opcode = field_store_instr[retvalue->vtype];
+ if (retvalue->vtype == TYPE_FIELD && OPTS_FLAG(ADJUST_VECTOR_FIELDS))
+ stmt.opcode = field_store_instr[retvalue->fieldtype];
else
stmt.opcode = type_store_instr[retvalue->vtype];
stmt.o1.u1 = OFS_RETURN;
ir_function *irfun;
size_t i;
-#ifndef NEW_ALLOC_STRAT
- size_t local_var_end;
-#endif
if (!global->hasvalue || (!global->constval.vfunc))
{
if ((int32_t)i >= fun.nargs)
fun.argsize[i] = 0;
else
- fun.argsize[i] = type_sizeof[irfun->params[i]];
+ fun.argsize[i] = type_sizeof_[irfun->params[i]];
}
fun.firstlocal = vec_size(code_globals);
-#ifndef NEW_ALLOC_STRAT
- local_var_end = fun.firstlocal;
- for (i = 0; i < vec_size(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;
- }
- }
- if (vec_size(irfun->locals)) {
- ir_value *last = vec_last(irfun->locals);
- local_var_end = last->code.globaladdr;
- if (last->vtype == TYPE_FIELD && last->fieldtype == TYPE_VECTOR)
- local_var_end += type_sizeof[TYPE_VECTOR];
- else
- local_var_end += type_sizeof[last->vtype];
- }
- for (i = 0; i < vec_size(irfun->values); ++i)
- {
- /* generate code.globaladdr for ssa values */
- ir_value *v = irfun->values[i];
- ir_value_code_setaddr(v, local_var_end + v->code.local);
- }
- for (i = 0; i < irfun->allocated_locals; ++i) {
- /* fill the locals with zeros */
- vec_push(code_globals, 0);
- }
-
- fun.locals = vec_size(code_globals) - fun.firstlocal;
-#else
fun.locals = irfun->allocated_locals;
for (i = 0; i < vec_size(irfun->locals); ++i) {
if (!ir_builder_gen_global(ir, irfun->locals[i], true)) {
}
ir_value_code_setaddr(irfun->locals[i], fun.firstlocal + irfun->locals[i]->code.local);
}
- for (i = vec_size(code_globals) - fun.firstlocal; i < fun.locals; ++i) {
- vec_push(code_globals, 0);
- }
for (i = 0; i < vec_size(irfun->values); ++i)
{
/* generate code.globaladdr for ssa values */
ir_value *v = irfun->values[i];
ir_value_code_setaddr(v, fun.firstlocal + v->code.local);
}
-#endif
+ for (i = vec_size(code_globals); i < fun.firstlocal + irfun->allocated_locals; ++i)
+ vec_push(code_globals, 0);
if (irfun->builtin)
fun.entry = irfun->builtin+1;
vec_push(code_globals, iptr[0]);
if (global->code.globaladdr < 0)
return false;
- for (d = 1; d < type_sizeof[global->vtype]; ++d) {
+ for (d = 1; d < type_sizeof_[global->vtype]; ++d) {
vec_push(code_globals, iptr[d]);
}
} else {
vec_push(code_globals, 0);
if (global->code.globaladdr < 0)
return false;
- for (d = 1; d < type_sizeof[global->vtype]; ++d) {
+ for (d = 1; d < type_sizeof_[global->vtype]; ++d) {
vec_push(code_globals, 0);
}
}
/* assume biggest type */
ir_value_code_setaddr(global, vec_size(code_globals));
vec_push(code_globals, 0);
- for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i)
+ for (i = 1; i < type_sizeof_[TYPE_VARIANT]; ++i)
vec_push(code_globals, 0);
return true;
default:
static void ir_builder_prepare_field(ir_value *field)
{
- field->code.fieldaddr = code_alloc_field(type_sizeof[field->fieldtype]);
+ field->code.fieldaddr = code_alloc_field(type_sizeof_[field->fieldtype]);
}
static bool ir_builder_gen_field(ir_builder *self, ir_value *field)