/****************************************************************************/
/*                                                                          */
/*                      Chaine de CAO & VLSI   Alliance                     */
/*                                                                          */
/*    Produit :  Synthetiseur Logique                                       */
/*    Fichier :  optimexpr.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 : 16/04/1992     */
/*                                                                          */
/*    Modifie par :                                     le : ../../..       */
/*    Modifie par :                                     le : ../../..       */
/*    Modifie par :                                     le : ../../....     */
/*                                                                          */
/****************************************************************************/

#include MUT_H
#include LOG_H
#include BEH_H
#include "sl_facto.h"
#include "../synthe/sl_type.h"
#include "../prepar/carac.h"
      
/*------------------------------------------------------------------------------
optimDelaiExpr        : optimise une expression localement.
-------------------------------------------------------
parametres 	 : une expression, une liste de delais et un mode d'optimisation.
-------------------------------------------------------
return 		 :une pointeur de CHAIN_LIST.
------------------------------------------------------------------------------*/
chain_list *optimDelaiExpr(expr,beh,dejaTraite,caracTH,del)
chain_list *expr;
befig_list *beh;
pTH dejaTraite,caracTH;
int del;
{
beaux_list *aux;
   
if (ATOM(expr))
   {
   aux = beh->BEAUX;
   while (aux && strcmp(VALUE_ATOM(expr),aux->NAME))
      {
      aux = aux->NEXT;
      }
   if (aux)
      {
      if (searchTH(dejaTraite,VALUE_ATOM(expr)) == EMPTYTH)
         {
         aux->ABL = optimDelaiExpr(aux->ABL,beh,dejaTraite,caracTH,del);
         }
      }
   return (copyExpr(expr));
   }
else
   {
   chain_list *ret;

   ret = createExpr(OPER(expr));

   if (OPER(expr) != NOT)
      {
      int delint;
      chain_list *teteExpr = expr;
      int marge,delMax,delSuivant;

      printf("decoupage : ");
      displayExpr(expr);

      delMax = 0;
      delSuivant = 0;

      while (expr = CDR(expr))
         {
         delint  = searchTH(caracTH,CAR(expr));

         if (delint > delMax)
            {
            delSuivant = delMax;
            delMax = delint;
            }
         else
            if (delint > delSuivant)
               delSuivant = delint;
            
         printf("delai = %d -",delint);
         } 
      printf(" ** delMax = %d - delSuivant = %d - ",delMax,delSuivant);
      marge = del - delMax - 1000;
      printf(" marge = %d\n",marge);
    
      expr = teteExpr ;
      while (expr = CDR(expr))
         {
         delint  = searchTH(caracTH,CAR(expr));

         if (delint == delMax)
            {
            }
         addQExpr(ret,optimDelaiExpr(CAR(expr),beh,dejaTraite,caracTH,del));
         } 
      }
   else
      {
      addQExpr(ret,optimDelaiExpr(CADR(expr),beh,dejaTraite,del));
      return (ret);
      }
   }
}

/*-------------------------------------------------------------------------
optimDelaiBeh	: optimise localement chaque expression d'une befig 
---------------------------------------------------------------------------
retour		: un void.
---------------------------------------------------------------------------*/
void optimDelaiBeh(beh,optim,delais,optimPO)
befig_list *beh;
int optim;
ptype_list *delais;
chain_list *optimPO;
{
beout_list *out;
bereg_list *reg;
bebus_list *bus;
bebux_list *bux;
biabl_list *biabl;
beaux_list *aux;
chain_list *expr;

pTH caracTH,dejaTraite;
int delaisMoyen;
pTH caracBeh();

dejaTraite = createTH(100);

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

	/* 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))
         {
         expr = optimDelaiExpr(out->ABL,beh,dejaTraite,caracTH,del);

         freeExpr(out->ABL);
         out->ABL = expr;
         }
   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))
            {

            expr = optimDelaiExpr(biabl->CNDABL,beh,dejaTraite,caracTH,del);
            freeExpr(biabl->CNDABL);
            biabl->CNDABL = expr;
            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(reg->NAME,optimPO))
            {
            expr = optimDelaiExpr(biabl->VALABL,beh,dejaTraite,caracTH,del);

            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)
         {
	 int del;

         if ((del = searchTH(caracTH,biabl->CNDABL)) > delaisMoyen ||
             memberChain(bus->NAME,optimPO))
            {

            expr = optimDelaiExpr(biabl->CNDABL,beh,dejaTraite,caracTH,del);
            freeExpr(biabl->CNDABL);
            biabl->CNDABL = expr;
            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(bus->NAME,optimPO))
            {
            expr = optimDelaiExpr(biabl->VALABL,beh,dejaTraite,caracTH,del);

            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)
         {
	 int del;

         if ((del = searchTH(caracTH,biabl->CNDABL)) > delaisMoyen ||
             memberChain(bux->NAME,optimPO))
            {
            expr = optimDelaiExpr(biabl->CNDABL,beh,dejaTraite,caracTH,del);

            freeExpr(biabl->CNDABL);
            biabl->CNDABL = expr;
            }
         if ((del = searchTH(caracTH,biabl->VALABL)) > delaisMoyen ||
             memberChain(bux->NAME,optimPO))
            {
            expr = optimDelaiExpr(biabl->VALABL,beh,dejaTraite,caracTH,del);

            freeExpr(biabl->VALABL);
            biabl->VALABL = expr;
            }
         }
      biabl = biabl->NEXT;
      }
   bux = bux->NEXT;
   }

destroyTH(caracTH);
destroyTH(dejaTraite);
}
