self->params = NULL;
self->eid = 0;
+
+ self->likely = true;
return self;
}
bool ir_block_create_store_op(ir_block *self, int op, ir_value *target, ir_value *what)
{
- ir_instr *in = ir_instr_new(self, op);
+ ir_instr *in;
+ if (self->final) {
+ irerror(self->context, "unreachable statement (%s)", self->label);
+ return false;
+ }
+ in = ir_instr_new(self, op);
if (!in)
return false;
{
ir_instr *in;
if (self->final) {
- irerror(self->context, "block already ended (%s)", self->label);
+ irerror(self->context, "unreachable statement (%s)", self->label);
return false;
}
self->final = true;
{
ir_instr *in;
if (self->final) {
- irerror(self->context, "block already ended (%s)", self->label);
+ irerror(self->context, "unreachable statement (%s)", self->label);
return false;
}
self->final = true;
{
ir_instr *in;
if (self->final) {
- irerror(self->context, "block already ended (%s)", self->label);
+ irerror(self->context, "unreachable statement (%s)", self->label);
return false;
}
self->final = true;
{
ir_instr *in;
if (self->final) {
- irerror(self->context, "block already ended (%s)", self->label);
+ irerror(self->context, "unreachable statement (%s)", self->label);
return false;
}
self->final = true;
return true;
}
+#if 0
static bool ir_naive_phi_emit_store(ir_block *block, size_t iid, ir_value *old, ir_value *what)
{
ir_instr *instr;
return true;
}
+#endif
static bool ir_block_naive_phi(ir_block *self)
{
- size_t i, p, w;
+ size_t i, p; /*, w;*/
/* FIXME: optionally, create_phi can add the phis
* to a list so we don't need to loop through blocks
* - anyway: "don't optimize YET"
for (p = 0; p < vec_size(instr->phi); ++p)
{
+ ir_value *v = instr->phi[p].value;
+ ir_block *b = instr->phi[p].from;
+
+ if (v->store == store_value &&
+ vec_size(v->reads) == 1 &&
+ vec_size(v->writes) == 1)
+ {
+ /* replace the value */
+ if (!ir_instr_op(v->writes[0], 0, instr->_ops[0], true))
+ return false;
+ }
+ else
+ {
+ /* force a move instruction */
+ ir_instr *prevjump = vec_last(b->instr);
+ vec_pop(b->instr);
+ b->final = false;
+ instr->_ops[0]->store = store_global;
+ if (!ir_block_create_store(b, instr->_ops[0], v))
+ return false;
+ instr->_ops[0]->store = store_value;
+ vec_push(b->instr, prevjump);
+ b->final = true;
+ }
+
+#if 0
ir_value *v = instr->phi[p].value;
for (w = 0; w < vec_size(v->writes); ++w) {
ir_value *old;
}
}
}
+#endif
}
ir_instr_delete(instr);
}
}
/* neither ontrue nor onfalse exist */
stmt.opcode = INSTR_IFNOT;
+ if (!instr->likely) {
+ /* Honor the likelyhood hint */
+ ir_block *tmp = onfalse;
+ stmt.opcode = INSTR_IF;
+ onfalse = ontrue;
+ ontrue = tmp;
+ }
stidx = vec_size(code_statements);
vec_push(code_statements, stmt);
/* on false we jump, so add ontrue-path */
if (onfalse->generated) {
/* fixup the jump address */
code_statements[stidx].o2.s1 = (onfalse->code_start) - (stidx);
+ stmt.opcode = vec_last(code_statements).opcode;
/* may have been generated in the previous recursive call */
stmt.opcode = INSTR_GOTO;
stmt.o1.s1 = (onfalse->code_start) - vec_size(code_statements);