'likely' hint for IFs
authorWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 21 Nov 2012 16:35:11 +0000 (17:35 +0100)
committerWolfgang (Blub) Bumiller <blub@speed.at>
Wed, 21 Nov 2012 16:37:45 +0000 (17:37 +0100)
ast.c
ir.c
ir.h

diff --git a/ast.c b/ast.c
index 7487e2332798f0a4512f3602cfd802263ee46715..f5ed565e93644b202798d2ff88c33ada85d57656 100644 (file)
--- 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 25fbc73cf3e9f682138f19da7af9f25fc14acddf..bf0a7459120cb9ed2582832217ff8ec17b21d59c 100644 (file)
--- 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 06efa5b21600264a8c29399f37a94ead961b8030..bb26cff2ae2f8c0ed31ae2bc258dd896532860ce 100644 (file)
--- 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;