[buddy] Hint gcc about likely/unlikely branches.

* src/bdd.h (__likely, __unlikely): Introduce these two macros.
* src/bddop.c, src/kerner.c: Use them in many situations.
This commit is contained in:
Alexandre Duret-Lutz 2011-04-30 13:30:05 +02:00
parent 24054605da
commit 2b58fb90c4
4 changed files with 182 additions and 98 deletions

View file

@ -1,3 +1,10 @@
2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
Hint gcc about likely/unlikely branches.
* src/bdd.h (__likely, __unlikely): Introduce these two macros.
* src/bddop.c, src/kerner.c: Use them in many situations.
2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr> 2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
* src/pairs.c (bdd_pairalloc): Fix prototype. * src/pairs.c (bdd_pairalloc): Fix prototype.

View file

@ -42,10 +42,14 @@
#define __purefn __attribute__((__pure__)) #define __purefn __attribute__((__pure__))
#define __constfn __attribute__((__const__)) #define __constfn __attribute__((__const__))
#define __noreturnfn __attribute__((__noreturn__)) #define __noreturnfn __attribute__((__noreturn__))
#define __likely(expr) __builtin_expect(!!(expr), 1)
#define __unlikely(expr) __builtin_expect(!!(expr), 0)
#else #else
#define __purefn #define __purefn
#define __constfn #define __constfn
#define __noreturnfn #define __noreturnfn
#define __likely(expr) (expr)
#define __unlikely(expr) (expr)
#endif #endif
/* Allow this headerfile to define C++ constructs if requested */ /* Allow this headerfile to define C++ constructs if requested */

View file

@ -411,15 +411,20 @@ BDD bdd_not(BDD r)
CHECKa(r, bddfalse); CHECKa(r, bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = not_rec(r); res = not_rec(r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = not_rec(r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -516,23 +521,30 @@ BDD bdd_apply(BDD l, BDD r, int op)
CHECKa(l, bddfalse); CHECKa(l, bddfalse);
CHECKa(r, bddfalse); CHECKa(r, bddfalse);
#ifndef NDEBUG
if (op<0 || op>bddop_invimp) if (op<0 || op>bddop_invimp)
{ {
bdd_error(BDD_OP); bdd_error(BDD_OP);
return bddfalse; return bddfalse;
} }
#endif
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
applyop = op; applyop = op;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = apply_rec(l, r); res = apply_rec(l, r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = apply_rec(l, r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -855,15 +867,20 @@ BDD bdd_ite(BDD f, BDD g, BDD h)
CHECKa(h, bddfalse); CHECKa(h, bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = ite_rec(f,g,h); res = ite_rec(f,g,h);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = ite_rec(f,g,h);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1026,7 +1043,7 @@ BDD bdd_restrict(BDD r, BDD var)
return r; return r;
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
if (varset2svartable(var) < 0) if (varset2svartable(var) < 0)
return bddfalse; return bddfalse;
@ -1034,11 +1051,16 @@ BDD bdd_restrict(BDD r, BDD var)
INITREF; INITREF;
miscid = (var << 3) | CACHEID_RESTRICT; miscid = (var << 3) | CACHEID_RESTRICT;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = restrict_rec(r); res = restrict_rec(r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = restrict_rec(r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1118,16 +1140,21 @@ BDD bdd_constrain(BDD f, BDD c)
CHECKa(c,bddfalse); CHECKa(c,bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
miscid = CACHEID_CONSTRAIN; miscid = CACHEID_CONSTRAIN;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = constrain_rec(f, c); res = constrain_rec(f, c);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = constrain_rec(f, c);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1238,18 +1265,23 @@ BDD bdd_replace(BDD r, bddPair *pair)
CHECKa(r, bddfalse); CHECKa(r, bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
replacepair = pair->result; replacepair = pair->result;
replacelast = pair->last; replacelast = pair->last;
replaceid = (pair->id << 2) | CACHEID_REPLACE; replaceid = (pair->id << 2) | CACHEID_REPLACE;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = replace_rec(r); res = replace_rec(r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = replace_rec(r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1306,11 +1338,13 @@ static BDD bdd_correctify(int level, BDD l, BDD r)
if (level < LEVEL(l) && level < LEVEL(r)) if (level < LEVEL(l) && level < LEVEL(r))
return bdd_makenode(level, l, r); return bdd_makenode(level, l, r);
#ifndef NDEBUG
if (level == LEVEL(l) || level == LEVEL(r)) if (level == LEVEL(l) || level == LEVEL(r))
{ {
bdd_error(BDD_REPLACE); bdd_error(BDD_REPLACE);
return 0; return 0;
} }
#endif
if (LEVEL(l) == LEVEL(r)) if (LEVEL(l) == LEVEL(r))
{ {
@ -1356,24 +1390,32 @@ BDD bdd_compose(BDD f, BDD g, int var)
CHECKa(f, bddfalse); CHECKa(f, bddfalse);
CHECKa(g, bddfalse); CHECKa(g, bddfalse);
#ifndef NDEBUG
if (var < 0 || var >= bddvarnum) if (var < 0 || var >= bddvarnum)
{ {
bdd_error(BDD_VAR); bdd_error(BDD_VAR);
return bddfalse; return bddfalse;
} }
#endif
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
composelevel = bddvar2level[var]; composelevel = bddvar2level[var];
replaceid = (composelevel << 2) | CACHEID_COMPOSE; replaceid = (composelevel << 2) | CACHEID_COMPOSE;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = compose_rec(f, g); res = compose_rec(f, g);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = compose_rec(f, g);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1475,18 +1517,23 @@ BDD bdd_veccompose(BDD f, bddPair *pair)
CHECKa(f, bddfalse); CHECKa(f, bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
replacepair = pair->result; replacepair = pair->result;
replaceid = (pair->id << 2) | CACHEID_VECCOMPOSE; replaceid = (pair->id << 2) | CACHEID_VECCOMPOSE;
replacelast = pair->last; replacelast = pair->last;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = veccompose_rec(f); res = veccompose_rec(f);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = veccompose_rec(f);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1558,16 +1605,21 @@ BDD bdd_simplify(BDD f, BDD d)
CHECKa(d, bddfalse); CHECKa(d, bddfalse);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
INITREF; INITREF;
applyop = bddop_or; applyop = bddop_or;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = simplify_rec(f, d); res = simplify_rec(f, d);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = simplify_rec(f, d);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1661,7 +1713,7 @@ static BDD quantify(BDD r, BDD var, int op, int comp, int id)
return r; return r;
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
if (varset2vartable(var, comp) < 0) if (varset2vartable(var, comp) < 0)
return bddfalse; return bddfalse;
@ -1670,11 +1722,16 @@ static BDD quantify(BDD r, BDD var, int op, int comp, int id)
quantid = (var << 4) | id; /* FIXME: range */ quantid = (var << 4) | id; /* FIXME: range */
applyop = op; applyop = op;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = quant_rec(r); res = quant_rec(r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = quant_rec(r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -1835,17 +1892,19 @@ static BDD appquantify(BDD l, BDD r, int opr, BDD var,
CHECKa(r, bddfalse); CHECKa(r, bddfalse);
CHECKa(var, bddfalse); CHECKa(var, bddfalse);
#ifndef NDEBUG
if (opr<0 || opr>bddop_invimp) if (opr<0 || opr>bddop_invimp)
{ {
bdd_error(BDD_OP); bdd_error(BDD_OP);
return bddfalse; return bddfalse;
} }
#endif
if (var < 2 && !comp) /* Empty set */ if (var < 2 && !comp) /* Empty set */
return bdd_apply(l,r,opr); return bdd_apply(l,r,opr);
again: again:
if (setjmp(bddexception) == 0) if (__likely(setjmp(bddexception) == 0))
{ {
if (varset2vartable(var, comp) < 0) if (varset2vartable(var, comp) < 0)
return bddfalse; return bddfalse;
@ -1856,11 +1915,16 @@ static BDD appquantify(BDD l, BDD r, int opr, BDD var,
appexid = (var << 5) | (appexop << 1); /* FIXME: range! */ appexid = (var << 5) | (appexop << 1); /* FIXME: range! */
quantid = (appexid << 4) | qid; quantid = (appexid << 4) | qid;
if (!firstReorder) if (__likely(firstReorder))
bdd_disable_reorder(); {
res = appquant_rec(l, r); res = appquant_rec(l, r);
if (!firstReorder) }
bdd_enable_reorder(); else
{
bdd_disable_reorder();
res = appquant_rec(l, r);
bdd_enable_reorder();
}
} }
else else
{ {
@ -2148,11 +2212,11 @@ BDD bdd_support(BDD r)
return bddtrue; return bddtrue;
/* On-demand allocation of support set */ /* On-demand allocation of support set */
if (supportSize < bddvarnum) if (__unlikely(supportSize < bddvarnum))
{ {
if (supportSet) if (__likely(supportSet))
free(supportSet); free(supportSet);
if ((supportSet=(int*)malloc(bddvarnum*sizeof(int))) == NULL) if (__unlikely((supportSet=(int*)malloc(bddvarnum*sizeof(int))) == NULL))
{ {
bdd_error(BDD_MEMORY); bdd_error(BDD_MEMORY);
return bddfalse; return bddfalse;
@ -2168,7 +2232,7 @@ BDD bdd_support(BDD r)
* - and instead of reading the whole array afterwards, we just * - and instead of reading the whole array afterwards, we just
* look from 'min' to 'max' used BDD variables. * look from 'min' to 'max' used BDD variables.
*/ */
if (supportID == 0x0FFFFFFF) if (__unlikely(supportID == 0x0FFFFFFF))
{ {
/* We probably don't get here -- but let's just be sure */ /* We probably don't get here -- but let's just be sure */
memset(supportSet, 0, bddvarnum*sizeof(int)); memset(supportSet, 0, bddvarnum*sizeof(int));
@ -2289,7 +2353,7 @@ BDD bdd_satprefix(BDD* r)
BDD res; BDD res;
CHECKa(*r, bddfalse); CHECKa(*r, bddfalse);
if (*r < 2) if (__unlikely(*r < 2))
return *r; return *r;
bdd_disable_reorder(); bdd_disable_reorder();
@ -2349,12 +2413,13 @@ BDD bdd_satoneset(BDD r, BDD var, BDD pol)
CHECKa(r, bddfalse); CHECKa(r, bddfalse);
if (ISZERO(r)) if (ISZERO(r))
return r; return r;
#ifndef NDEBUG
if (!ISCONST(pol)) if (!ISCONST(pol))
{ {
bdd_error(BDD_ILLBDD); bdd_error(BDD_ILLBDD);
return bddfalse; return bddfalse;
} }
#endif
bdd_disable_reorder(); bdd_disable_reorder();
INITREF; INITREF;
@ -2522,7 +2587,7 @@ void bdd_allsat(BDD r, bddallsathandler handler)
CHECKn(r); CHECKn(r);
if ((allsatProfile=(char*)malloc(bddvarnum)) == NULL) if (__unlikely((allsatProfile=(char*)malloc(bddvarnum)) == NULL))
{ {
bdd_error(BDD_MEMORY); bdd_error(BDD_MEMORY);
return; return;
@ -2826,7 +2891,7 @@ int *bdd_varprofile(BDD r)
{ {
CHECKa(r, NULL); CHECKa(r, NULL);
if ((varprofile=(int*)malloc(sizeof(int)*bddvarnum)) == NULL) if (__unlikely((varprofile=(int*)malloc(sizeof(int)*bddvarnum)) == NULL))
{ {
bdd_error(BDD_MEMORY); bdd_error(BDD_MEMORY);
return NULL; return NULL;
@ -2912,8 +2977,10 @@ static int varset2vartable(BDD r, int comp)
{ {
BDD n; BDD n;
#ifndef NDEBUG
if (r < 2 && !comp) if (r < 2 && !comp)
return bdd_error(BDD_VARSET); return bdd_error(BDD_VARSET);
#endif
quantvarsetID++; quantvarsetID++;
quantvarsetcomp = comp; quantvarsetcomp = comp;
@ -2943,8 +3010,10 @@ static int varset2svartable(BDD r)
{ {
BDD n; BDD n;
#ifndef NDEBUG
if (r < 2) if (r < 2)
return bdd_error(BDD_VARSET); return bdd_error(BDD_VARSET);
#endif
quantvarsetID++; quantvarsetID++;

View file

@ -298,43 +298,47 @@ int bdd_setvarnum(int num)
bdd_disable_reorder(); bdd_disable_reorder();
#ifndef NDEBUG
if (num < 1 || num > MAXVAR) if (num < 1 || num > MAXVAR)
{ {
bdd_error(BDD_RANGE); return bdd_error(BDD_RANGE);
return bddfalse;
} }
if (num < bddvarnum) if (num < bddvarnum)
return bdd_error(BDD_DECVNUM); return bdd_error(BDD_DECVNUM);
#endif
if (num == bddvarnum) if (num == bddvarnum)
return 0; return 0;
if (bddvarset == NULL) if (__unlikely(bddvarset == NULL))
{ {
if ((bddvarset=(BDD*)malloc(sizeof(BDD)*num*2)) == NULL) if (__unlikely((bddvarset = (BDD*)malloc(sizeof(BDD)*num*2)) == NULL))
return bdd_error(BDD_MEMORY); return bdd_error(BDD_MEMORY);
if ((bddlevel2var=(int*)malloc(sizeof(int)*(num+1))) == NULL) if (__unlikely((bddlevel2var = (int*)malloc(sizeof(int)*(num+1))) == NULL))
{ {
free(bddvarset); free(bddvarset);
return bdd_error(BDD_MEMORY); return bdd_error(BDD_MEMORY);
} }
if ((bddvar2level=(int*)malloc(sizeof(int)*(num+1))) == NULL) if (__unlikely((bddvar2level = (int*)malloc(sizeof(int)*(num+1))) == NULL))
{ {
free(bddvarset); free(bddvarset);
free(bddlevel2var); free(bddlevel2var);
return bdd_error(BDD_MEMORY); return bdd_error(BDD_MEMORY);
} }
} }
else else
{ {
if ((bddvarset=(BDD*)realloc(bddvarset,sizeof(BDD)*num*2)) == NULL) if (__unlikely((bddvarset =
return bdd_error(BDD_MEMORY); (BDD*)realloc(bddvarset,sizeof(BDD)*num*2)) == NULL))
if ((bddlevel2var=(int*)realloc(bddlevel2var,sizeof(int)*(num+1))) == NULL) return bdd_error(BDD_MEMORY);
{ if (__unlikely((bddlevel2var =
(int*)realloc(bddlevel2var,sizeof(int)*(num+1))) == NULL))
{
free(bddvarset); free(bddvarset);
return bdd_error(BDD_MEMORY); return bdd_error(BDD_MEMORY);
} }
if ((bddvar2level=(int*)realloc(bddvar2level,sizeof(int)*(num+1))) == NULL) if (__unlikely((bddvar2level =
(int*)realloc(bddvar2level,sizeof(int)*(num+1))) == NULL))
{ {
free(bddvarset); free(bddvarset);
free(bddlevel2var); free(bddlevel2var);
@ -342,7 +346,7 @@ int bdd_setvarnum(int num)
} }
} }
if (bddrefstack != NULL) if (__likely(bddrefstack != NULL))
free(bddrefstack); free(bddrefstack);
bddrefstack = bddrefstacktop = (int*)malloc(sizeof(int)*(num*2+4)); bddrefstack = bddrefstacktop = (int*)malloc(sizeof(int)*(num*2+4));
@ -352,7 +356,7 @@ int bdd_setvarnum(int num)
bddvarset[bddvarnum*2+1] = bdd_makenode(bddvarnum, 1, 0); bddvarset[bddvarnum*2+1] = bdd_makenode(bddvarnum, 1, 0);
POPREF(1); POPREF(1);
if (bdderrorcond) if (__unlikely(bdderrorcond))
{ {
bddvarnum = bdv; bddvarnum = bdv;
return -bdderrorcond; return -bdderrorcond;
@ -392,7 +396,7 @@ int bdd_extvarnum(int num)
{ {
int start = bddvarnum; int start = bddvarnum;
if (num < 0 || num > 0x3FFFFFFF) if (__unlikely(num < 0 || num > 0x3FFFFFFF))
return bdd_error(BDD_RANGE); return bdd_error(BDD_RANGE);
bdd_setvarnum(bddvarnum+num); bdd_setvarnum(bddvarnum+num);
@ -1167,7 +1171,7 @@ void bdd_mark(int i)
{ {
BddNode *node; BddNode *node;
if (i < 2) if (__unlikely(i < 2))
return; return;
node = &bddnodes[i]; node = &bddnodes[i];
@ -1185,7 +1189,7 @@ void bdd_mark_upto(int i, int level)
{ {
BddNode *node = &bddnodes[i]; BddNode *node = &bddnodes[i];
if (i < 2) if (__unlikely(i < 2))
return; return;
if (LEVELp(node) & MARKON || LOWp(node) == -1) if (LEVELp(node) & MARKON || LOWp(node) == -1)
@ -1205,7 +1209,7 @@ void bdd_markcount(int i, int *cou)
{ {
BddNode *node; BddNode *node;
if (i < 2) if (__unlikely(i < 2))
return; return;
node = &bddnodes[i]; node = &bddnodes[i];
@ -1242,7 +1246,7 @@ void bdd_unmark_upto(int i, int level)
{ {
BddNode *node = &bddnodes[i]; BddNode *node = &bddnodes[i];
if (i < 2) if (__unlikely(i < 2))
return; return;
if (!(LEVELp(node) & MARKON)) if (!(LEVELp(node) & MARKON))