[buddy] Inline the "is bdd constant" check performed in copies/constructors.
This avoids a library call to bdd_addref or bdd_delref. * src/kernel.c (bdd_delref_nc, bdd_addref_nc): New function, that work only on BDD that are not constant. * src/cpext.cxx (bdd::operator=): Move... * src/bdd.hh (bdd::operator=): ... here. (bdd::bdd, bdd::~bdd, bdd::operator=): Inline the "is bdd constant" check and call bdd_delref_nc/bdd_addref_nc only otherwise.
This commit is contained in:
parent
2b58fb90c4
commit
1d1872ab90
4 changed files with 104 additions and 59 deletions
|
|
@ -1,3 +1,16 @@
|
||||||
|
2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
|
Inline the "is bdd constant" check performed in copies/constructors.
|
||||||
|
|
||||||
|
This avoids a library call to bdd_addref or bdd_delref.
|
||||||
|
|
||||||
|
* src/kernel.c (bdd_delref_nc, bdd_addref_nc): New function,
|
||||||
|
that work only on BDD that are not constant.
|
||||||
|
* src/cpext.cxx (bdd::operator=): Move...
|
||||||
|
* src/bdd.hh (bdd::operator=): ... here.
|
||||||
|
(bdd::bdd, bdd::~bdd, bdd::operator=): Inline the "is bdd constant"
|
||||||
|
check and call bdd_delref_nc/bdd_addref_nc only otherwise.
|
||||||
|
|
||||||
2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
2011-04-30 Alexandre Duret-Lutz <adl@lrde.epita.fr>
|
||||||
|
|
||||||
Hint gcc about likely/unlikely branches.
|
Hint gcc about likely/unlikely branches.
|
||||||
|
|
|
||||||
|
|
@ -272,7 +272,9 @@ extern int bdd_var(BDD) __purefn;
|
||||||
extern BDD bdd_low(BDD) __purefn;
|
extern BDD bdd_low(BDD) __purefn;
|
||||||
extern BDD bdd_high(BDD) __purefn;
|
extern BDD bdd_high(BDD) __purefn;
|
||||||
extern int bdd_varlevel(int) __purefn;
|
extern int bdd_varlevel(int) __purefn;
|
||||||
|
extern BDD bdd_addref_nc(BDD);
|
||||||
extern BDD bdd_addref(BDD);
|
extern BDD bdd_addref(BDD);
|
||||||
|
extern BDD bdd_delref_nc(BDD);
|
||||||
extern BDD bdd_delref(BDD);
|
extern BDD bdd_delref(BDD);
|
||||||
extern void bdd_gbc(void);
|
extern void bdd_gbc(void);
|
||||||
extern int bdd_scanset(BDD, int**, int*);
|
extern int bdd_scanset(BDD, int**, int*);
|
||||||
|
|
@ -453,8 +455,8 @@ class bdd
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bdd(void) { root=0; }
|
bdd(void) { root=0; }
|
||||||
bdd(const bdd &r) { bdd_addref(root=r.root); }
|
bdd(const bdd &r) { root=r.root; if (root > 1) bdd_addref_nc(root); }
|
||||||
~bdd(void) { bdd_delref(root); }
|
~bdd(void) { if (root > 1) bdd_delref_nc(root); }
|
||||||
|
|
||||||
int id(void) const;
|
int id(void) const;
|
||||||
|
|
||||||
|
|
@ -481,7 +483,7 @@ class bdd
|
||||||
private:
|
private:
|
||||||
BDD root;
|
BDD root;
|
||||||
|
|
||||||
bdd(BDD r) { bdd_addref(root=r); }
|
bdd(BDD r) { root=r; if (root > 1) bdd_addref_nc(root); }
|
||||||
bdd operator=(BDD r);
|
bdd operator=(BDD r);
|
||||||
|
|
||||||
friend int bdd_init(int, int);
|
friend int bdd_init(int, int);
|
||||||
|
|
@ -849,6 +851,32 @@ inline int bdd::operator==(const bdd &r) const
|
||||||
inline int bdd::operator!=(const bdd &r) const
|
inline int bdd::operator!=(const bdd &r) const
|
||||||
{ return r.root!=root; }
|
{ return r.root!=root; }
|
||||||
|
|
||||||
|
inline bdd bdd::operator=(const bdd &r)
|
||||||
|
{
|
||||||
|
if (__likely(root != r.root))
|
||||||
|
{
|
||||||
|
if (root > 1)
|
||||||
|
bdd_delref_nc(root);
|
||||||
|
root = r.root;
|
||||||
|
if (root > 1)
|
||||||
|
bdd_addref_nc(root);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bdd bdd::operator=(int r)
|
||||||
|
{
|
||||||
|
if (__likely(root != r))
|
||||||
|
{
|
||||||
|
if (root > 1)
|
||||||
|
bdd_delref_nc(root);
|
||||||
|
root = r;
|
||||||
|
if (root > 1)
|
||||||
|
bdd_addref_nc(root);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
inline bdd bdd_true(void)
|
inline bdd bdd_true(void)
|
||||||
{ return 1; }
|
{ return 1; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ static bddstrmhandler strmhandler_fdd;
|
||||||
int bdd_cpp_init(int n, int c)
|
int bdd_cpp_init(int n, int c)
|
||||||
{
|
{
|
||||||
int ok = bdd_init(n,c);
|
int ok = bdd_init(n,c);
|
||||||
|
|
||||||
strmhandler_bdd = NULL;
|
strmhandler_bdd = NULL;
|
||||||
strmhandler_fdd = NULL;
|
strmhandler_fdd = NULL;
|
||||||
|
|
||||||
|
|
@ -115,11 +115,11 @@ int bdd_setbddpairs(bddPair *pair, int *oldvar, const bdd *newvar, int size)
|
||||||
{
|
{
|
||||||
if (pair == NULL)
|
if (pair == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (int n=0,e=0 ; n<size ; n++)
|
for (int n=0,e=0 ; n<size ; n++)
|
||||||
if ((e=bdd_setbddpair(pair, oldvar[n], newvar[n].root)) < 0)
|
if ((e=bdd_setbddpair(pair, oldvar[n], newvar[n].root)) < 0)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -135,39 +135,12 @@ int bdd_anodecountpp(const bdd *r, int num)
|
||||||
cpr[n] = r[n].root;
|
cpr[n] = r[n].root;
|
||||||
|
|
||||||
cou = bdd_anodecount(cpr,num);
|
cou = bdd_anodecount(cpr,num);
|
||||||
|
|
||||||
free(cpr);
|
free(cpr);
|
||||||
|
|
||||||
return cou;
|
return cou;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
|
||||||
BDD class functions
|
|
||||||
*************************************************************************/
|
|
||||||
|
|
||||||
bdd bdd::operator=(const bdd &r)
|
|
||||||
{
|
|
||||||
if (root != r.root)
|
|
||||||
{
|
|
||||||
bdd_delref(root);
|
|
||||||
root = r.root;
|
|
||||||
bdd_addref(root);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bdd bdd::operator=(int r)
|
|
||||||
{
|
|
||||||
if (root != r)
|
|
||||||
{
|
|
||||||
bdd_delref(root);
|
|
||||||
root = r;
|
|
||||||
bdd_addref(root);
|
|
||||||
}
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
C++ iostream operators
|
C++ iostream operators
|
||||||
|
|
@ -216,14 +189,14 @@ ostream &operator<<(ostream &o, const bdd &r)
|
||||||
o << (r.root == 0 ? "F" : "T");
|
o << (r.root == 0 ? "F" : "T");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
int *set = new int[bddvarnum];
|
int *set = new int[bddvarnum];
|
||||||
if (set == NULL)
|
if (set == NULL)
|
||||||
{
|
{
|
||||||
bdd_error(BDD_MEMORY);
|
bdd_error(BDD_MEMORY);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(set, 0, sizeof(int) * bddvarnum);
|
memset(set, 0, sizeof(int) * bddvarnum);
|
||||||
bdd_printset_rec(o, r.root, set);
|
bdd_printset_rec(o, r.root, set);
|
||||||
delete[] set;
|
delete[] set;
|
||||||
|
|
@ -234,7 +207,7 @@ ostream &operator<<(ostream &o, const bdd &r)
|
||||||
o << "ROOT: " << r.root << "\n";
|
o << "ROOT: " << r.root << "\n";
|
||||||
if (r.root < 2)
|
if (r.root < 2)
|
||||||
return o;
|
return o;
|
||||||
|
|
||||||
bdd_mark(r.root);
|
bdd_mark(r.root);
|
||||||
|
|
||||||
for (int n=0 ; n<bddnodesize ; n++)
|
for (int n=0 ; n<bddnodesize ; n++)
|
||||||
|
|
@ -242,7 +215,7 @@ ostream &operator<<(ostream &o, const bdd &r)
|
||||||
if (LEVEL(n) & MARKON)
|
if (LEVEL(n) & MARKON)
|
||||||
{
|
{
|
||||||
BddNode *node = &bddnodes[n];
|
BddNode *node = &bddnodes[n];
|
||||||
|
|
||||||
LEVELp(node) &= MARKOFF;
|
LEVELp(node) &= MARKOFF;
|
||||||
|
|
||||||
o << "[" << setw(5) << n << "] ";
|
o << "[" << setw(5) << n << "] ";
|
||||||
|
|
@ -263,9 +236,9 @@ ostream &operator<<(ostream &o, const bdd &r)
|
||||||
o << "digraph G {\n";
|
o << "digraph G {\n";
|
||||||
o << "0 [shape=box, label=\"0\", style=filled, shape=box, height=0.3, width=0.3];\n";
|
o << "0 [shape=box, label=\"0\", style=filled, shape=box, height=0.3, width=0.3];\n";
|
||||||
o << "1 [shape=box, label=\"1\", style=filled, shape=box, height=0.3, width=0.3];\n";
|
o << "1 [shape=box, label=\"1\", style=filled, shape=box, height=0.3, width=0.3];\n";
|
||||||
|
|
||||||
bdd_printdot_rec(o, r.root);
|
bdd_printdot_rec(o, r.root);
|
||||||
|
|
||||||
o << "}\n";
|
o << "}\n";
|
||||||
|
|
||||||
bdd_unmark(r.root);
|
bdd_unmark(r.root);
|
||||||
|
|
@ -278,19 +251,19 @@ ostream &operator<<(ostream &o, const bdd &r)
|
||||||
o << (r == 0 ? "F" : "T");
|
o << (r == 0 ? "F" : "T");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
int *set = new int[bddvarnum];
|
int *set = new int[bddvarnum];
|
||||||
if (set == NULL)
|
if (set == NULL)
|
||||||
{
|
{
|
||||||
bdd_error(BDD_MEMORY);
|
bdd_error(BDD_MEMORY);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(set, 0, sizeof(int) * bddvarnum);
|
memset(set, 0, sizeof(int) * bddvarnum);
|
||||||
fdd_printset_rec(o, r.root, set);
|
fdd_printset_rec(o, r.root, set);
|
||||||
delete[] set;
|
delete[] set;
|
||||||
}
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -333,7 +306,7 @@ ostream &operator<<(ostream &o, const bdd_ioformat &f)
|
||||||
for (int n=0 ; n<bddnodesize ; n++)
|
for (int n=0 ; n<bddnodesize ; n++)
|
||||||
{
|
{
|
||||||
const BddNode *node = &bddnodes[n];
|
const BddNode *node = &bddnodes[n];
|
||||||
|
|
||||||
if (LOWp(node) != -1)
|
if (LOWp(node) != -1)
|
||||||
{
|
{
|
||||||
o << "[" << setw(5) << n << "] ";
|
o << "[" << setw(5) << n << "] ";
|
||||||
|
|
@ -347,7 +320,7 @@ ostream &operator<<(ostream &o, const bdd_ioformat &f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -356,7 +329,7 @@ static void bdd_printset_rec(ostream& o, int r, int* set)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
int first;
|
int first;
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
|
|
@ -364,7 +337,7 @@ static void bdd_printset_rec(ostream& o, int r, int* set)
|
||||||
{
|
{
|
||||||
o << "<";
|
o << "<";
|
||||||
first = 1;
|
first = 1;
|
||||||
|
|
||||||
for (n=0 ; n<bddvarnum ; n++)
|
for (n=0 ; n<bddvarnum ; n++)
|
||||||
{
|
{
|
||||||
if (set[n] > 0)
|
if (set[n] > 0)
|
||||||
|
|
@ -386,10 +359,10 @@ static void bdd_printset_rec(ostream& o, int r, int* set)
|
||||||
{
|
{
|
||||||
set[LEVEL(r)] = 1;
|
set[LEVEL(r)] = 1;
|
||||||
bdd_printset_rec(o, LOW(r), set);
|
bdd_printset_rec(o, LOW(r), set);
|
||||||
|
|
||||||
set[LEVEL(r)] = 2;
|
set[LEVEL(r)] = 2;
|
||||||
bdd_printset_rec(o, HIGH(r), set);
|
bdd_printset_rec(o, HIGH(r), set);
|
||||||
|
|
||||||
set[LEVEL(r)] = 0;
|
set[LEVEL(r)] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +383,7 @@ static void bdd_printdot_rec(ostream& o, int r)
|
||||||
o << r << " -> " << HIGH(r) << "[style=filled];\n";
|
o << r << " -> " << HIGH(r) << "[style=filled];\n";
|
||||||
|
|
||||||
SETMARK(r);
|
SETMARK(r);
|
||||||
|
|
||||||
bdd_printdot_rec(o, LOW(r));
|
bdd_printdot_rec(o, LOW(r));
|
||||||
bdd_printdot_rec(o, HIGH(r));
|
bdd_printdot_rec(o, HIGH(r));
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +395,7 @@ static void fdd_printset_rec(ostream &o, int r, int *set)
|
||||||
int used = 0;
|
int used = 0;
|
||||||
int *binval;
|
int *binval;
|
||||||
int ok, first;
|
int ok, first;
|
||||||
|
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
|
|
@ -431,18 +404,18 @@ static void fdd_printset_rec(ostream &o, int r, int *set)
|
||||||
o << "<";
|
o << "<";
|
||||||
first=1;
|
first=1;
|
||||||
int fdvarnum = fdd_domainnum();
|
int fdvarnum = fdd_domainnum();
|
||||||
|
|
||||||
for (n=0 ; n<fdvarnum ; n++)
|
for (n=0 ; n<fdvarnum ; n++)
|
||||||
{
|
{
|
||||||
int firstval=1;
|
int firstval=1;
|
||||||
used = 0;
|
used = 0;
|
||||||
int binsize = fdd_varnum(n);
|
int binsize = fdd_varnum(n);
|
||||||
int *vars = fdd_vars(n);
|
int *vars = fdd_vars(n);
|
||||||
|
|
||||||
for (m=0 ; m<binsize ; m++)
|
for (m=0 ; m<binsize ; m++)
|
||||||
if (set[vars[m]] != 0)
|
if (set[vars[m]] != 0)
|
||||||
used = 1;
|
used = 1;
|
||||||
|
|
||||||
if (used)
|
if (used)
|
||||||
{
|
{
|
||||||
if (!first)
|
if (!first)
|
||||||
|
|
@ -458,7 +431,7 @@ static void fdd_printset_rec(ostream &o, int r, int *set)
|
||||||
{
|
{
|
||||||
binval = fdddec2bin(n, m);
|
binval = fdddec2bin(n, m);
|
||||||
ok=1;
|
ok=1;
|
||||||
|
|
||||||
for (i=0 ; i<binsize && ok ; i++)
|
for (i=0 ; i<binsize && ok ; i++)
|
||||||
if (set[vars[i]] == 1 && binval[i] != 0)
|
if (set[vars[i]] == 1 && binval[i] != 0)
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
|
@ -486,10 +459,10 @@ static void fdd_printset_rec(ostream &o, int r, int *set)
|
||||||
{
|
{
|
||||||
set[bddlevel2var[LEVEL(r)]] = 1;
|
set[bddlevel2var[LEVEL(r)]] = 1;
|
||||||
fdd_printset_rec(o, LOW(r), set);
|
fdd_printset_rec(o, LOW(r), set);
|
||||||
|
|
||||||
set[bddlevel2var[LEVEL(r)]] = 2;
|
set[bddlevel2var[LEVEL(r)]] = 2;
|
||||||
fdd_printset_rec(o, HIGH(r), set);
|
fdd_printset_rec(o, HIGH(r), set);
|
||||||
|
|
||||||
set[bddlevel2var[LEVEL(r)]] = 0;
|
set[bddlevel2var[LEVEL(r)]] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -581,7 +554,7 @@ bvec bvec_map2(const bvec &a, const bvec &b,
|
||||||
bdd_error(BVEC_SIZE);
|
bdd_error(BVEC_SIZE);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = bvec_false(a.bitnum());
|
res = bvec_false(a.bitnum());
|
||||||
for (n=0 ; n < a.bitnum() ; n++)
|
for (n=0 ; n < a.bitnum() ; n++)
|
||||||
res.set(n, fun(a[n], b[n]));
|
res.set(n, fun(a[n], b[n]));
|
||||||
|
|
@ -601,7 +574,7 @@ bvec bvec_map3(const bvec &a, const bvec &b, const bvec &c,
|
||||||
bdd_error(BVEC_SIZE);
|
bdd_error(BVEC_SIZE);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
res = bvec_false(a.bitnum());
|
res = bvec_false(a.bitnum());
|
||||||
for (n=0 ; n < a.bitnum() ; n++)
|
for (n=0 ; n < a.bitnum() ; n++)
|
||||||
res.set(n, fun(a[n], b[n], c[n]) );
|
res.set(n, fun(a[n], b[n], c[n]) );
|
||||||
|
|
|
||||||
|
|
@ -1102,6 +1102,20 @@ void bdd_gbc(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BDD bdd_addref_nc(BDD root)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (!bddrunning)
|
||||||
|
return root;
|
||||||
|
if (root < 2 || root >= bddnodesize)
|
||||||
|
return bdd_error(BDD_ILLBDD);
|
||||||
|
if (LOW(root) == -1)
|
||||||
|
return bdd_error(BDD_ILLBDD);
|
||||||
|
#endif
|
||||||
|
INCREF(root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NAME {* bdd\_addref *}
|
NAME {* bdd\_addref *}
|
||||||
SECTION {* kernel *}
|
SECTION {* kernel *}
|
||||||
|
|
@ -1131,6 +1145,23 @@ BDD bdd_addref(BDD root)
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Non constant version
|
||||||
|
BDD bdd_delref_nc(BDD root)
|
||||||
|
{
|
||||||
|
#ifndef NDEBUG
|
||||||
|
if (root < 2 || !bddrunning)
|
||||||
|
return root;
|
||||||
|
if (root >= bddnodesize)
|
||||||
|
return bdd_error(BDD_ILLBDD);
|
||||||
|
if (LOW(root) == -1)
|
||||||
|
return bdd_error(BDD_ILLBDD);
|
||||||
|
|
||||||
|
/* if the following line is present, fails there much earlier */
|
||||||
|
if (!HASREF(root)) bdd_error(BDD_BREAK); /* distinctive */
|
||||||
|
#endif
|
||||||
|
DECREF(root);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NAME {* bdd\_delref *}
|
NAME {* bdd\_delref *}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue