/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit : synthetiseur logique                                        */
/*    Fichier : prep.c                                                      */
/*                                                                          */
/*    (c) copyright 1991 Laboratoire MASI equipe CAO & VLSI                 */
/*    Tous droits reserves                                                  */
/*    Support : e-mail cao-vlsi@masi.ibp.fr                                 */
/*                                                                          */
/*    Auteur(s) : L. Burgun                             le : 31/01/1992     */
/*                                                                          */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include MUT_H
#include LOG_H
#include BEH_H
#include "carac.h"
#include "bib.h"

/*-------------------------------------------------------------------------
memberPType	: renvoie 1 si le signal doit etre elimine 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/
short memberPType(name,ptl)
char *name;
ptype_list *ptl;
 
{
ptype_list *l;
 
for(l = ptl;l;l = l->NEXT)
        if (strcmp((char *)l->DATA,name) == 0) return 1;
return 0;
}

/*-------------------------------------------------------------------------
memberChain	: renvoie 1 si name appartient a liste 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/
short memberChain(name,cl)
char *name;
chain_list *cl;
 
{
chain_list *l;
 
for(l = cl;l;l = l->NEXT)
        if (strcmp((char *)l->DATA,name) == 0) return 1;
return 0;
}

/*-------------------------------------------------------------------------
elimSignal	: renvoie 1 si le signal doit etre elimine 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/
int elimSignal(occ,num,optim)
int occ,num;
int optim;
{
if (optim == 1)		/* optimisation delais */
   {
   if (occ == 1 || num == 1 ||
       (occ <= MAXOCC+1 && num <= MAXNUM+1))
      return(1);
   else
      return(0);
   }
else
   if (occ == 1 || num == 1 ||
       (occ <= MAXOCC && num <= MAXNUM))
      return(1);
   else
      return(0);
}

/*-------------------------------------------------------------------------
searchNameBeh 	: renvoie 1 si name est dans une expression de beh. 
---------------------------------------------------------------------------
retour		: un int.
---------------------------------------------------------------------------*/
int searchNameBeh(beh,name)

befig_list *beh;
char *name;
{
beout_list *out;
bereg_list *reg;
biabl_list *biabl;
bebus_list *bus;
bebux_list *bux;
beaux_list *aux;
chain_list *expr;


aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      if (searchExpr(aux->ABL,name))
         return(1);
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      if (searchExpr(out->ABL,name))
         return(1);
      }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,name))
            return(1);
         if (searchExpr(biabl->CNDABL,name))
            return(1);
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }


bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,name))
            return(1);
         if (searchExpr(biabl->CNDABL,name))
            return(1);
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchExpr(biabl->VALABL,name))
            return(1);
         if (searchExpr(biabl->CNDABL,name))
            return(1);
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }

return 0;
}
/*-------------------------------------------------------------------------
mapCarExprBeh	: applique une fonction de conversion sur chaque expression
                  d'une befig 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void mapCarExprBeh(beh,func)

befig_list *beh;
chain_list *(*func)();
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux;
chain_list *expr;


aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      expr = (*func)(aux->ABL);
      freeExpr(aux->ABL); 
      aux->ABL = expr;
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      expr = (*func)(out->ABL);
      freeExpr(out->ABL);
      out->ABL = expr;
      }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         expr = (*func)(biabl->CNDABL);
         freeExpr(biabl->CNDABL);
         biabl->CNDABL = expr;
         expr = (*func)(biabl->VALABL);
         freeExpr(biabl->VALABL);
         biabl->VALABL = expr;
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         expr = (*func)(biabl->CNDABL);
         freeExpr(biabl->CNDABL);
         biabl->CNDABL = expr;
         expr = (*func)(biabl->VALABL);
         freeExpr(biabl->VALABL);
         biabl->VALABL = expr;
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         expr = (*func)(biabl->CNDABL);
         freeExpr(biabl->CNDABL);
         biabl->CNDABL = expr;
         expr = (*func)(biabl->VALABL);
         freeExpr(biabl->VALABL);
         biabl->VALABL = expr;
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }
}
/*-------------------------------------------------------------------------
mapExprBeh	: applique une procedure sur chaque expression d'une befig 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void mapExprBeh(beh,func)
befig_list *beh;
void (*func)();
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux;

	/* parcours de la befig avec remplissage de pTHOcc */

aux = beh->BEAUX;
while (aux) 
   {
   if (aux->ABL)
      {
      (*func)(aux->ABL);
      }
   aux = aux->NEXT;
   }

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      {
      (*func)(out->ABL);
      }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         (*func)(biabl->CNDABL);
         (*func)(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         (*func)(biabl->CNDABL);
         (*func)(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         (*func)(biabl->CNDABL);
         (*func)(biabl->VALABL);
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }
}

/*-------------------------------------------------------------------------
mergeChain_list : merge deux listes sans double
---------------------------------------------------------------------------
retour		: une chain_list*.
---------------------------------------------------------------------------*/
chain_list *mergeChain_list(l1,l2)
chain_list *l1,*l2;
{
chain_list *ret,*tete_l1;

ret = (chain_list *) copyChain_list(l1);

while (l2)
   {
   int trouve;

   tete_l1 = l1;
   trouve = 0;
   while (l1)
      {
      if (!strcmp(l1->DATA,l2->DATA))   /* deja mis ! */
         trouve = 1;
      l1 = l1->NEXT;
      }
   l1 = tete_l1;
   if (trouve == 0)
      ret = addchain(ret,l2->DATA);
   l2 = l2->NEXT;
   }
return ret;
}

/*-------------------------------------------------------------------------
substTHOccExpr : susbtitue les auxiliaires  de trop petite granularite
                 par leurs expressions associes. 
---------------------------------------------------------------------------
retour		: une expression.
---------------------------------------------------------------------------*/
void substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,expr,optim,dejaTraite)
befig_list *beh;
pTH pTHOcc;
pTH pTHNum;
pTH pTHAux,pTHSucc;
chain_list *expr;
int optim;
pTH dejaTraite;
{
chain_list *support,*tete_support;
int num,occ;

if (expr == NULL)
   {
   printf("substTHOccExpr : error - expression = NULL\n");
   exit(-1);
   }

support = supportChain_listExpr(expr);
tete_support = support;

while (support)
   {

		/* on s'interresse aux auxiliaires de l'expression qui
                   n'ont pas encore ete traites  */

   if (strcmp(support->DATA,"'0'") &&
       strcmp(support->DATA,"'1'") &&
       strcmp(support->DATA,"'d'") &&
       (searchTH(pTHOcc,support->DATA) != EMPTYTH) &&
       (searchTH(dejaTraite,support->DATA) == EMPTYTH))
      {
      beaux_list *aux;

      aux = (beaux_list *) searchTH(pTHAux,support->DATA);
      if (aux == (beaux_list *) EMPTYTH)
         {
         printf("substTHOccExpr : error auxiliary signal doesn't exist %s\n",aux->NAME);
         exit(-1);
         }

                /* descente recursive dans la befig */

      substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,aux->ABL,optim,dejaTraite);

               /* le signal peut-il etre eliminer */

      num = searchTH(pTHNum,support->DATA);
      occ = searchTH(pTHOcc,support->DATA);

/*
      printf("\nje traite : %s\n",support->DATA);
      printf("occ = %d, num = %d, optim = %d\n",occ,num,optim);
      printf("successeurs = ");
      displayChain_list(searchTH(pTHSucc,support->DATA));
      printf("\n");
*/

		/* on regarde le fanout des predecesseurs */

      if (optim == 0 && FILTRE && (num > 2 || occ > 2))
         {
         chain_list *supp = supportChain_listExpr(aux->ABL);
         int filtreOK;
         int valocc;

         filtreOK = 1;
         while (supp && filtreOK)
            {
            valocc = searchTH(pTHOcc,(char *) supp->DATA);

			/*  c'est un aux. */
                        /* on elimine la variable si tous
                           les predecesseurs ont un fanout min de 10 */ 

            if (valocc != EMPTYTH)
               {
               if (valocc <= 10)
                  {
                  filtreOK = 0;
                  num = 100;
                  }
               }
            supp = supp->NEXT;
            }
         }

      if (elimSignal(occ,num,optim))
         {
         chain_list *supp,*tete_supp;

/*
         printf("===> elimine !\n");
*/

         addTH(pTHOcc,support->DATA,0);

                /* Modification des successeurs */

         supp = (chain_list *) searchTH(pTHSucc,support->DATA);

                /* on substitue dans les expressions des successeurs
                   le signal par son expression */

         while (supp)
            {
            beaux_list *aux1;
            beout_list *out;
            bereg_list *reg;
            bebus_list *bus;
            bebux_list *bux;
            biabl_list *biabl;


            aux1 = beh->BEAUX;
            while (aux1)
               {
               if (!strcmp(supp->DATA,aux1->NAME))
                  {
                  if (ATOM(aux1->ABL) && 
                      !strcmp(VALUE_ATOM(aux1->ABL),support->DATA))
                     aux1->ABL = copyExpr(aux->ABL);
                  else
                     substPhyExpr(aux1->ABL,support->DATA,aux->ABL);

		  /* on calcule en plus pour les auxiliaires le nouveau
                     nombre de litteraux ...*/

                  addTH(pTHNum,aux1->NAME,numberAtomExpr(aux1->ABL));
                  }
               aux1 = aux1->NEXT;
               }

            out = beh->BEOUT;
            while (out)
               {
               if (!strcmp(supp->DATA,out->NAME))
                  {
                  if (ATOM(out->ABL) && 
                      !strcmp(VALUE_ATOM(out->ABL),support->DATA))
                     out->ABL = copyExpr(aux->ABL);
                  else
                     substPhyExpr(out->ABL,support->DATA,aux->ABL);
                  }
               out = out->NEXT;
               }

            reg = beh->BEREG;
            while (reg)
               {
               if (!strcmp(supp->DATA,reg->NAME))
                  {
                  biabl = reg->BIABL;
                  while (biabl)
                     {
                     if (ATOM(biabl->VALABL) && 
                         !strcmp(VALUE_ATOM(biabl->VALABL),support->DATA))
                        biabl->VALABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->VALABL,support->DATA,aux->ABL);

                     if (ATOM(biabl->CNDABL) && 
                         !strcmp(VALUE_ATOM(biabl->CNDABL),support->DATA))
                        biabl->CNDABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->CNDABL,support->DATA,aux->ABL);
                     biabl = biabl->NEXT;
                     }
                  }
               reg = reg->NEXT;
               }
 
            bus = beh->BEBUS;
            while (bus)
               {
               if (!strcmp(supp->DATA,bus->NAME))
                  {
                  biabl = bus->BIABL;
                  while (biabl)
                     {
                     if (ATOM(biabl->VALABL) && 
                         !strcmp(VALUE_ATOM(biabl->VALABL),support->DATA))
                        biabl->VALABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->VALABL,support->DATA,aux->ABL);

                     if (ATOM(biabl->CNDABL) && 
                         !strcmp(VALUE_ATOM(biabl->CNDABL),support->DATA))
                        biabl->CNDABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->CNDABL,support->DATA,aux->ABL);
                     biabl = biabl->NEXT;
                     }
                  }
               bus = bus->NEXT;
               }
 
            bux = beh->BEBUX;
            while (bux)
               {
               if (!strcmp(supp->DATA,bus->NAME))
                  {
                  biabl = bux->BIABL;
                  while (biabl)
                     {
                     if (ATOM(biabl->VALABL) && 
                         !strcmp(VALUE_ATOM(biabl->VALABL),support->DATA))
                        biabl->VALABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->VALABL,support->DATA,aux->ABL);

                     if (ATOM(biabl->CNDABL) && 
                         !strcmp(VALUE_ATOM(biabl->CNDABL),support->DATA))
                        biabl->CNDABL = copyExpr(aux->ABL);
                     else
                        substPhyExpr(biabl->CNDABL,support->DATA,aux->ABL);
                     biabl = biabl->NEXT;
                     }
                  }
               bux = bux->NEXT;
               }

            supp = supp->NEXT;
            }

                /* Modification des predecesseurs */

		/* on recupere le support et on incremente le nombre
                   d'occurence de chaque aux avec occ-1 */

         supp = supportChain_listExpr(aux->ABL);
         tete_supp = supp;
         while (supp)
            {
            int occaux;
			/* c'est une aux. */

            occaux =  searchTH(pTHOcc,(char *) supp->DATA);
            if (occaux != EMPTYTH)
               {
               chain_list *succ;

               addTH(pTHOcc,(char *) supp->DATA,occaux + occ -1);

			/* on calcule le nouvel ensemble de successeurs */
            
			/* on enleve le signal elimine */

               succ = (chain_list *) searchTH(pTHSucc,supp->DATA);
/*
               printf("j'elimine %s de ",aux->NAME);
               displayChain_list(succ);
*/

               succ = (chain_list *) delElementChain_list(succ,aux->NAME);
/*
               printf(" = ");
               displayChain_list(succ); 
               printf("\n");
*/

			/* on rajoute les successeurs du signal elimine */
               
               succ = mergeChain_list(succ,
                            (chain_list *) searchTH(pTHSucc,support->DATA));
/*
               displayChain_list(succ); 
               printf("\n");
*/

               addTH(pTHSucc,supp->DATA,succ);
               }
            supp=supp->NEXT;
            }

         freechain(tete_supp);
         }

      addTH(dejaTraite,support->DATA,1);
      }

   support = support->NEXT;
   }

freechain(tete_support);
}

/*-------------------------------------------------------------------------
compactExprBeh	: changement de la granularite des equations par elimination
		selective des signaux intermediaires. 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void compactExprBeh(beh,optim,delais,optimPO,level)
befig_list *beh;
int optim;
ptype_list *delais;
chain_list *optimPO;
int level;
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux,*auxp;
chain_list *expr;

pTH pTHOcc,pTHNum,pTHAux;
pTH caracTH,dejaTraite;
pTH pTHSucc;
int delaisMoyen;

		/* le niveau de compactage est initialise */

if (level == 0)
   {
   MAXOCC = 1;
   MAXNUM = 1;
   }

if (level == 1)
   {
   MAXOCC = 2;
   MAXNUM = 2;
   }

if (level == 2)
   {
   MAXOCC = 3;
   MAXNUM = 3;
   }


		/* elimination des 1 et 0 */

mapCarExprBeh(beh,simplif10Expr);

pTHNum = createTH(100);	/* table des auxiliaires/nombre de litteraux */
pTHOcc = createTH(100); /* table des auxiliaires/nombre d'occurences */
pTHAux = createTH(100); /* table des auxiliaires/expression */
pTHSucc = createTH(100); /* table des auxiliaires/successeurs */

dejaTraite = createTH(100);

   /* parcours des auxiliaires avec remplissage des tables de hachage */

aux = beh->BEAUX;
while (aux) 
   {
   		    /* variables aux que l'on peut eliminer */

   if (!memberPType(aux->NAME,delais))
      {
      addTH(pTHOcc,aux->NAME,0);
      addTH(pTHSucc,aux->NAME,NULL);
      }
   if (aux->ABL)
      {
      chain_list *support,*tete_support;

      addTH(pTHNum,aux->NAME,numberAtomExpr(aux->ABL));
      addTH(pTHAux,aux->NAME,(int) aux);
      }
   aux = aux->NEXT;
   }

	/* remplissage de la table pTHSucc */

remplTHSuccBeh(beh,pTHSucc);

	/* remplissage de la table pTHOcc */

remplTHOccBeh(beh,pTHOcc);

                /* caracterisation */
 
caracTH = caracBeh(beh,delais,0);
 
                /* ----- a correler avec le mode d'optimisation */
 
delaisMoyen = delaisCarac(caracTH,optim);

 
		/* substitution des signaux auxiliaires inutiles */

	/* on commence par les cones a optimiser en delais */

out = beh->BEOUT;
while (out) 
   {
   int del;

   if (out->ABL)
      if ((del = searchTH(caracTH,out->ABL)) > delaisMoyen ||
          memberChain(out->NAME,optimPO))
         {
         substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,out->ABL,1,dejaTraite);
         }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
	 int del;

         if ((del = searchTH(caracTH,biabl->CNDABL)) > delaisMoyen ||
             memberChain(reg->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,1,dejaTraite);

            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(reg->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);

            }
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
	 int del;

         if ((del = searchTH(caracTH,biabl->CNDABL)) > delaisMoyen ||
             memberChain(bus->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,1,dejaTraite);

            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(bus->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);

            }
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
	 int del;

         if ((del = searchTH(caracTH,biabl->CNDABL)) > delaisMoyen ||
             memberChain(bux->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,1,dejaTraite);

            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(bux->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);

            }
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }


	/* calcul des cones non optimise en delais */
	/* optimisatiom en surface */

out = beh->BEOUT;
while (out) 
   {
   if (out->ABL)
      if (searchTH(caracTH,out->ABL) <= delaisMoyen &&
          !memberChain(out->NAME,optimPO))
         {
         substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,out->ABL,0,dejaTraite);

         }
   out = out->NEXT;
   }

reg = beh->BEREG;
while (reg) 
   {
   biabl = reg->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchTH(caracTH,biabl->CNDABL) > delaisMoyen &&
             !memberChain(reg->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,0,dejaTraite);
            }
         if (searchTH(caracTH,biabl->VALABL) > delaisMoyen &&
             !memberChain(reg->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);
            }
         }
      biabl = biabl->NEXT;
      }
   reg = reg->NEXT;
   }

bus = beh->BEBUS;
while (bus) 
   {
   biabl = bus->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchTH(caracTH,biabl->CNDABL) > delaisMoyen &&
             !memberChain(bus->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,0,dejaTraite);
            }
         if (searchTH(caracTH,biabl->VALABL) > delaisMoyen &&
             !memberChain(bus->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);
            }
         }
      biabl = biabl->NEXT;
      }
   bus = bus->NEXT;
   }

bux = beh->BEBUX;
while (bux) 
   {
   biabl = bux->BIABL;
   while (biabl)
      {
      if (biabl->CNDABL && biabl->VALABL)
         {
         if (searchTH(caracTH,biabl->CNDABL) > delaisMoyen &&
             !memberChain(bux->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->CNDABL,0,dejaTraite);
            }
         if (searchTH(caracTH,biabl->VALABL) > delaisMoyen &&
             !memberChain(bux->NAME,optimPO))
            {
            substTHOccExpr(beh,pTHOcc,pTHNum,pTHAux,pTHSucc,biabl->VALABL,0,dejaTraite);
            }
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }
	/* elimination des signaux auxiliaires expanses */ 

	/* on elimine les signaux de fanout 0 */

aux = beh->BEAUX;
auxp = NULL;
while (aux) 
   {
   int occ;

   occ = searchTH(pTHOcc,aux->NAME);

   if (occ != 0)
      {
      auxp = beh_addbeaux(auxp,aux->NAME,aux->ABL,NULL);
      auxp->NODE = aux->NODE;
      } 
   aux = aux->NEXT;
   }
beh->BEAUX = auxp;


		/* simplification des not */

mapCarExprBeh(beh,simplifNotExpr);

mapExprBeh(beh,flatArityExpr);

destroyTH(caracTH);
destroyTH(dejaTraite);
destroyTH(pTHOcc);
destroyTH(pTHNum);
destroyTH(pTHAux);
destroyTH(pTHSucc);
}
