diff --git a/ast.c b/ast.c index 7487e23..f5ed565 100644 --- a/ast.c +++ b/ast.c @@ -1538,6 +1538,8 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va if (!ir_block_create_if(func->curblock, left, merge, other)) return false; } + /* use the unlikely flag */ + vec_last(func->curblock->instr)->likely = false; func->curblock = other; cgen = self->right->expression.codegen; diff --git a/ir.c b/ir.c index 25fbc73..bf0a745 100644 --- a/ir.c +++ b/ir.c @@ -654,6 +654,8 @@ ir_instr* ir_instr_new(ir_block* owner, int op) self->params = NULL; self->eid = 0; + + self->likely = true; return self; } @@ -2501,6 +2503,13 @@ tailcall: } /* 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 */ @@ -2512,6 +2521,7 @@ tailcall: 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); diff --git a/ir.h b/ir.h index 06efa5b..bb26cff 100644 --- a/ir.h +++ b/ir.h @@ -133,6 +133,9 @@ typedef struct ir_instr_s /* For the temp-allocation */ size_t eid; + /* For IFs */ + bool likely; + struct ir_block_s *owner; } ir_instr;