home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dosdisas.zip / dccsrcoo.zip / dataflow.cpp < prev    next >
C/C++ Source or Header  |  1997-04-09  |  42KB  |  1,125 lines

  1. /*****************************************************************************
  2.  *$Log:    dataflow.c,v $
  3.  * Revision 1.10  94/03/11  10:21:20  cifuente
  4.  * numArgs of library functions is checked.
  5.  * 
  6.  * Revision 1.9  94/02/22  15:14:44  cifuente
  7.  * Data flow analysis: elimination of condition codes, extraneous
  8.  * intermediate instructions, registers, etc.
  9.  * 
  10.  * Revision 1.8  93/12/13  12:19:21  cifuente
  11.  * Interprocedural live analysis finished
  12.  * 
  13.  * Revision 1.7  93/11/10  17:26:10  cifuente
  14.  * Procedure header, locals
  15.  * 
  16.  * Revision 1.6  93/11/08  12:01:57  cifuente
  17.  * du1 analysis finished.  Instantiates procedure arguments for user
  18.  * declared procedures.
  19.  * 
  20.  * Revision 1.5  93/11/01  15:03:58  cifuente
  21.  * Finds byte and integer expressions
  22.  * 
  23.  * Revision 1.4  93/10/25  10:57:49  cifuente
  24.  * New SYNTHETIC instructions for d/u analysis.
  25.  * 
  26.  * Revision 1.3  93/10/11  11:34:57  cifuente
  27.  * First walk through HIGH_LEVEL icodes.
  28.  * 
  29.  * Project: dcc
  30.  * File:    dataflow.c
  31.  * Purpose: Data flow analysis module.
  32.  ****************************************************************************/
  33.  
  34. #include "dcc.h"
  35. #include <string.h>
  36. #include <stdio.h>
  37.  
  38.  
  39. static Int getLocVar (PSTKFRAME pStkFrame, Int off)
  40. /* Returns the index of the local variable or parameter at offset off, if it 
  41.  * is in the stack frame provided.  */
  42. {   Int     i;
  43.  
  44.     for (i = 0; i < pStkFrame->csym; i++)
  45.        if (pStkFrame->sym[i].off == off) 
  46.           break;
  47.     return (i);
  48. }
  49.  
  50.  
  51. static COND_EXPR *srcIdent (PICODE Icode, PPROC pProc, Int i, PICODE duIcode, 
  52.                             operDu du)
  53. /* Returns a string with the source operand of Icode */
  54. { COND_EXPR *n;
  55.  
  56.     if (Icode->ic.ll.flg & I)   /* immediate operand */
  57.     {
  58.         if (Icode->ic.ll.flg & B)
  59.             n = idCondExpKte (Icode->ic.ll.immed.op, 1);
  60.         else
  61.             n = idCondExpKte (Icode->ic.ll.immed.op, 2);
  62.     }
  63.     else
  64.        n = idCondExp (Icode, SRC, pProc, i, duIcode, du);
  65.     return (n);
  66. }
  67.  
  68.  
  69. static COND_EXPR *dstIdent (PICODE pIcode, PPROC pProc, Int i, PICODE duIcode,
  70.                             operDu du) 
  71. /* Returns the destination operand */
  72. { COND_EXPR *n; 
  73.  
  74.     n = idCondExp (pIcode, DST, pProc, i, duIcode, du);
  75.             /** Is it needed? (pIcode->ic.ll.flg) & NO_SRC_B **/
  76.     return (n);
  77. }
  78.  
  79.  
  80.  
  81. static void elimCondCodes (PPROC pProc)
  82. /* Eliminates all condition codes and generates new hlIcode instructions */
  83. { Int i, 
  84.       useAt,            /* Index to instruction that used flag    */
  85.       defAt;            /* Index to instruction that defined flag */
  86.   byte use;             /* Used flags bit vector                  */
  87.   byte def;             /* Defined flags bit vector               */
  88.   boolT notSup;         /* Use/def combination not supported      */
  89.   COND_EXPR *rhs;       /* Source operand                         */
  90.   COND_EXPR *lhs;       /* Destination operand                    */
  91.   COND_EXPR *exp;       /* Boolean expression                     */
  92.   PBB pBB;              /* Pointer to BBs in dfs last ordering    */
  93.   ICODE *prev;          /* For extended basic blocks - previous icode inst */
  94.  
  95.   for (i = 0; i < pProc->numBBs; i++) 
  96.   {
  97.     pBB = pProc->dfsLast[i];
  98.     if (pBB->flg & INVALID_BB)    continue; /* Do not process invalid BBs */
  99.  
  100.     for (useAt = pBB->start + pBB->length; useAt != pBB->start; useAt--)
  101.         if ((pProc->Icode.GetIcode(useAt-1)->type == LOW_LEVEL) &&
  102.             (pProc->Icode.GetIcode(useAt-1)->invalid == FALSE) &&
  103.             (use = pProc->Icode.GetIcode(useAt-1)->ic.ll.flagDU.u))
  104.         {
  105.             /* Find definition within the same basic block */
  106.             for (defAt = useAt-1; defAt != pBB->start; defAt--)
  107.             {
  108.                 def = pProc->Icode.GetIcode(defAt-1)->ic.ll.flagDU.d;
  109.                 if ((use & def) == use)
  110.                 {
  111.                     notSup = FALSE;
  112.                     if ((pProc->Icode.GetLlOpcode(useAt-1) >= iJB) &&
  113.                         (pProc->Icode.GetLlOpcode(useAt-1) <= iJNS))
  114.                     {
  115.                         switch (pProc->Icode.GetLlOpcode(defAt-1))
  116.                         {
  117.                           case iCMP:
  118.                             rhs = srcIdent (pProc->Icode.GetIcode(defAt-1),
  119.                                             pProc, defAt-1, 
  120.                                             pProc->Icode.GetIcode(useAt-1), E_USE);
  121.                             lhs = dstIdent (pProc->Icode.GetIcode(defAt-1),
  122.                                             pProc, defAt-1, 
  123.                                             pProc->Icode.GetIcode(useAt-1), E_USE);
  124.                             break;
  125.  
  126.                           case iOR:
  127.                             lhs = copyCondExp (pProc->Icode.GetIcode(defAt-1)->ic.hl.oper.asgn.lhs);
  128.                             copyDU (pProc->Icode.GetIcode(useAt-1),
  129.                                     pProc->Icode.GetIcode(defAt-1), E_USE, E_DEF);
  130.                             if (pProc->Icode.GetLlFlag(defAt-1) & B)
  131.                                 rhs = idCondExpKte (0, 1); 
  132.                             else
  133.                                 rhs = idCondExpKte (0, 2); 
  134.                             break;
  135.  
  136.                           case iTEST:
  137.                             rhs = srcIdent (pProc->Icode.GetIcode(defAt-1),
  138.                                             pProc, defAt-1, 
  139.                                             pProc->Icode.GetIcode(useAt-1), E_USE);
  140.                             lhs = dstIdent (pProc->Icode.GetIcode(defAt-1), 
  141.                                             pProc, defAt-1, 
  142.                                             pProc->Icode.GetIcode(useAt-1), E_USE);
  143.                             lhs = boolCondExp (lhs, rhs, AND);
  144.                             if (pProc->Icode.GetLlFlag(defAt-1) & B)
  145.                                 rhs = idCondExpKte (0, 1); 
  146.                             else
  147.                                 rhs = idCondExpKte (0, 2); 
  148.                             break;
  149.  
  150.                           default: 
  151.                             notSup = TRUE;
  152.                             reportError (JX_NOT_DEF, pProc->Icode.GetLlOpcode(defAt-1));
  153.                             pProc->flg |= PROC_ASM;        /* generate asm */
  154.                         }
  155.                         if (! notSup)
  156.                         {
  157.                             exp = boolCondExp (lhs, rhs,
  158.                               condOpJCond[pProc->Icode.GetLlOpcode(useAt-1)-iJB]);
  159.                             newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
  160.                         }
  161.                     }
  162.                     
  163.                     else if (pProc->Icode.GetLlOpcode(useAt-1) == iJCXZ) 
  164.                     {
  165.                         lhs = idCondExpReg (rCX, 0, &pProc->localId);
  166.                         setRegDU (pProc->Icode.GetIcode(useAt-1), rCX, E_USE);
  167.                         rhs = idCondExpKte (0, 2);
  168.                         exp = boolCondExp (lhs, rhs, EQUAL);
  169.                         newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
  170.                     }
  171.  
  172.                     else
  173.                     {
  174.                         reportError (NOT_DEF_USE, 
  175.                             pProc->Icode.GetLlOpcode(defAt-1),
  176.                             pProc->Icode.GetLlOpcode(useAt-1));
  177.                         pProc->flg |= PROC_ASM;        /* generate asm */
  178.                     }
  179.                     break;
  180.                 }
  181.             }
  182.  
  183.             /* Check for extended basic block */
  184.             if ((pBB->length == 1) && 
  185.                 (pProc->Icode.GetLlOpcode(useAt-1) >= iJB) &&
  186.                 (pProc->Icode.GetLlOpcode(useAt-1) <= iJNS))
  187.             {
  188.                 prev = pProc->Icode.GetIcode(pBB->inEdges[0]->start + 
  189.                                             pBB->inEdges[0]->length - 1);
  190.                 if (prev->ic.hl.opcode == HLI_JCOND)
  191.                 {
  192.                     exp = copyCondExp (prev->ic.hl.oper.exp);
  193.                     changeBoolCondExpOp (exp, 
  194.                         condOpJCond[pProc->Icode.GetLlOpcode(useAt-1)-iJB]);
  195.                     copyDU (pProc->Icode.GetIcode(useAt-1), prev, E_USE, E_USE);
  196.                     newJCondHlIcode (pProc->Icode.GetIcode(useAt-1), exp);
  197.                 }
  198.             }
  199.             /* Error - definition not found for use of a cond code */
  200.             else if (defAt == pBB->start)
  201.                 fatalError (DEF_NOT_FOUND, 
  202.                             pProc->Icode.GetLlOpcode(useAt-1));
  203.         }
  204.   }
  205. }
  206.  
  207.  
  208. static void genLiveKtes (PPROC pproc)
  209. /* Generates the LiveUse() and Def() sets for each basic block in the graph.
  210.  * Note: these sets are constant and could have been constructed during
  211.  *       the construction of the graph, but since the code hasn't been 
  212.  *       analyzed yet for idioms, the procedure preamble misleads the
  213.  *       analysis (eg: push si, would include si in LiveUse; although it
  214.  *       is not really meant to be a register that is used before defined). */
  215. { Int i, j;
  216.   PBB pbb;
  217.   PICODE picode;
  218.   dword liveUse, def;
  219.  
  220.     for (i = 0; i < pproc->numBBs; i++)
  221.     {
  222.         liveUse = def = 0;
  223.         pbb = pproc->dfsLast[i];
  224.         if (pbb->flg & INVALID_BB)    continue;    /* skip invalid BBs */
  225.         for (j = pbb->start; j < (pbb->start + pbb->length); j++)
  226.         {
  227.             picode = pproc->Icode.GetIcode(j);
  228.             if ((picode->type == HIGH_LEVEL) && (picode->invalid == FALSE))
  229.             {
  230.                 liveUse |= (picode->du.use & ~def); 
  231.                 def |= picode->du.def;
  232.             }
  233.         }
  234.         pbb->liveUse = liveUse;
  235.         pbb->def = def;
  236.     }
  237. }
  238.  
  239.  
  240. static void liveRegAnalysis (PPROC pproc, dword liveOut)
  241. /* Generates the liveIn() and liveOut() sets for each basic block via an
  242.  * iterative approach.  
  243.  * Propagates register usage information to the procedure call. */
  244. { Int i, j;
  245.   PBB pbb;              /* pointer to current basic block   */
  246.   PPROC pcallee;        /* invoked subroutine               */
  247.   PICODE ticode,        /* icode that invokes a subroutine  */
  248.          picode;        /* icode of function return            */
  249.   dword prevLiveOut,    /* previous live out                 */
  250.         prevLiveIn;        /* previous live in                    */
  251.   boolT change;            /* is there change in the live sets?*/
  252.  
  253.     /* liveOut for this procedure */
  254.     pproc->liveOut = liveOut;
  255.  
  256.   change = TRUE;
  257.   while (change)
  258.   {
  259.     /* Process nodes in reverse postorder order */
  260.     change = FALSE;
  261.     for (i = pproc->numBBs; i > 0; i--)
  262.     {
  263.         pbb = pproc->dfsLast[i-1];
  264.         if (pbb->flg & INVALID_BB)        /* Do not process invalid BBs */
  265.             continue;
  266.  
  267.         /* Get current liveIn() and liveOut() sets */
  268.         prevLiveIn = pbb->liveIn;
  269.         prevLiveOut = pbb->liveOut;
  270.  
  271.         /* liveOut(b) = U LiveIn(s); where s is successor(b) 
  272.          * liveOut(b) = {liveOut}; when b is a HLI_RET node     */
  273.         if (pbb->numOutEdges == 0)      /* HLI_RET node         */
  274.         {
  275.             pbb->liveOut = liveOut;
  276.  
  277.             /* Get return expression of function */
  278.             if (pproc->flg & PROC_IS_FUNC)
  279.             {
  280.                 picode = pproc->Icode.GetIcode(pbb->start + pbb->length - 1);
  281.                 if (picode->ic.hl.opcode == HLI_RET)
  282.                 {
  283.                     picode->ic.hl.oper.exp = idCondExpID (&pproc->retVal, 
  284.                             &pproc->localId, pbb->start + pbb->length - 1);
  285.                     picode->du.use = liveOut;
  286.                 }
  287.             }
  288.         }
  289.         else                            /* Check successors */
  290.         {
  291.             for (j = 0; j < pbb->numOutEdges; j++)
  292.                 pbb->liveOut |= pbb->edges[j].BBptr->liveIn;
  293.  
  294.             /* propagate to invoked procedure */
  295.             if (pbb->nodeType == CALL_NODE)
  296.             {
  297.                 ticode = pproc->Icode.GetIcode(pbb->start + pbb->length - 1);
  298.                 pcallee = ticode->ic.hl.oper.call.proc;
  299.  
  300.                 /* user/runtime routine */
  301.                 if (! (pcallee->flg & PROC_ISLIB))
  302.                 {
  303.                     if (pcallee->liveAnal == FALSE) /* hasn't been processed */
  304.                         dataFlow (pcallee, pbb->liveOut);
  305.                     pbb->liveOut = pcallee->liveIn;
  306.                 }
  307.                 else    /* library routine */
  308.                 {
  309.                     if ((pcallee->flg & PROC_IS_FUNC) && /* returns a value */
  310.                         (pcallee->liveOut & pbb->edges[0].BBptr->liveIn)) 
  311.                         pbb->liveOut = pcallee->liveOut;
  312.                     else
  313.                         pbb->liveOut = 0;
  314.                 } 
  315.  
  316.                 if ((! (pcallee->flg & PROC_ISLIB)) || (pbb->liveOut != 0))
  317.                 {
  318.                     switch (pcallee->retVal.type) {
  319.                       case TYPE_LONG_SIGN: case TYPE_LONG_UNSIGN:
  320.                           ticode->du1.numRegsDef = 2;
  321.                         break;
  322.                       case TYPE_WORD_SIGN: case TYPE_WORD_UNSIGN:
  323.                       case TYPE_BYTE_SIGN: case TYPE_BYTE_UNSIGN:
  324.                         ticode->du1.numRegsDef = 1;
  325.                         break;
  326.                         } /*eos*/
  327.  
  328.                     /* Propagate def/use results to calling icode */
  329.                     ticode->du.use = pcallee->liveIn;
  330.                     ticode->du.def = pcallee->liveOut;
  331.                 }
  332.             }
  333.         }
  334.  
  335.         /* liveIn(b) = liveUse(b) U (liveOut(b) - def(b) */
  336.         pbb->liveIn = pbb->liveUse | (pbb->liveOut & ~pbb->def);
  337.  
  338.         /* Check if live sets have been modified */
  339.         if ((prevLiveIn != pbb->liveIn) || (prevLiveOut != pbb->liveOut))
  340.             change = TRUE;
  341.     }
  342.   }
  343.  
  344.     /* Propagate liveIn(b) to procedure header */
  345.     if (pbb->liveIn != 0)   /* uses registers */
  346.         pproc->liveIn = pbb->liveIn;
  347.  
  348.     /* Remove any references to register variables */
  349.     if (pproc->flg & SI_REGVAR)
  350.     {
  351.         pproc->liveIn &= maskDuReg[rSI];
  352.         pbb->liveIn &= maskDuReg[rSI];
  353.     }
  354.     if (pproc->flg & DI_REGVAR)
  355.     {
  356.         pproc->liveIn &= maskDuReg[rDI];
  357.         pbb->liveIn &= maskDuReg[rDI];
  358.     }
  359. }
  360.  
  361.  
  362. static void genDU1 (PPROC pProc)
  363. /* Generates the du chain of each instruction in a basic block */
  364. { byte regi;            /* Register that was defined */
  365.   Int i, j, k, p, n, lastInst, defRegIdx, useIdx;
  366.   PICODE picode, ticode;/* Current and target bb    */
  367.   PBB pbb, tbb;         /* Current and target basic block */
  368.   boolT res;
  369.   COND_EXPR *exp, *lhs;
  370.  
  371.     /* Traverse tree in dfsLast order */
  372.     for (i = 0; i < pProc->numBBs; i++)
  373.     {
  374.         pbb = pProc->dfsLast[i];
  375.         if (pbb->flg & INVALID_BB)    continue;
  376.  
  377.         /* Process each register definition of a HIGH_LEVEL icode instruction.  
  378.          * Note that register variables should not be considered registers.  
  379.          */
  380.         lastInst = pbb->start + pbb->length;
  381.         for (j = pbb->start; j < lastInst; j++)
  382.         {
  383.             picode = pProc->Icode.GetIcode(j);
  384.             if (picode->type == HIGH_LEVEL)
  385.             {
  386.               regi = 0;
  387.               defRegIdx = 0;
  388.               for (k = 0; k < INDEXBASE; k++)
  389.               {
  390.                 if ((picode->du.def & power2(k)) != 0)
  391.                 {
  392.                     regi = (byte)(k + 1);       /* defined register */
  393.                     picode->du1.regi[defRegIdx] = regi;
  394.  
  395.                     /* Check remaining instructions of the BB for all uses
  396.                      * of register regi, before any definitions of the
  397.                      * register */
  398.                     if ((regi == rDI) && (pProc->flg & DI_REGVAR))
  399.                         continue;
  400.                     if ((regi == rSI) && (pProc->flg & SI_REGVAR))
  401.                         continue;
  402.                     if ((j + 1) < lastInst)        /* several instructions */
  403.                     {
  404.                         useIdx = 0;
  405.                         for (n = j+1; n < lastInst; n++)
  406.                         {
  407.                             /* Only check uses of HIGH_LEVEL icodes */
  408.                             ticode = pProc->Icode.GetIcode(n);
  409.                             if (ticode->type == HIGH_LEVEL) 
  410.                             {
  411.                                 /* if used, get icode index */
  412.                                 if (ticode->du.use & duReg[regi])
  413.                                     picode->du1.idx[defRegIdx][useIdx++] = n;
  414.  
  415.                                 /* if defined, stop finding uses for this reg */
  416.                                 if (ticode->du.def & duReg[regi])
  417.                                     break;
  418.                             }
  419.                         }
  420.  
  421.                         /* Check if last definition of this register */
  422.                         if ((! (ticode->du.def & duReg[regi])) &&
  423.                               (pbb->liveOut & duReg[regi]))
  424.                             picode->du.lastDefRegi |= duReg[regi]; 
  425.                     }
  426.                     else        /* only 1 instruction in this basic block */
  427.                     {
  428.                         /* Check if last definition of this register */
  429.                           if (pbb->liveOut & duReg[regi])
  430.                             picode->du.lastDefRegi |= duReg[regi]; 
  431.                     }
  432.  
  433.                     /* Find target icode for HLI_CALL icodes to procedures
  434.                      * that are functions.  The target icode is in the
  435.                      * next basic block (unoptimized code) or somewhere else
  436.                      * on optimized code. */
  437.                     if ((picode->ic.hl.opcode == HLI_CALL) && 
  438.                         (picode->ic.hl.oper.call.proc->flg & PROC_IS_FUNC))
  439.                     {
  440.                         tbb = pbb->edges[0].BBptr;
  441.                         useIdx = 0;
  442.                         for (n = tbb->start; n < tbb->start + tbb->length; n++)
  443.                         {
  444.                             ticode = pProc->Icode.GetIcode(n);
  445.                             if (ticode->type == HIGH_LEVEL)
  446.                             {
  447.                                 /* if used, get icode index */
  448.                                 if (ticode->du.use & duReg[regi])
  449.                                     picode->du1.idx[defRegIdx][useIdx++] = n;
  450.  
  451.                                 /* if defined, stop finding uses for this reg */
  452.                                 if (ticode->du.def & duReg[regi])
  453.                                     break;
  454.                             }
  455.                         }
  456.  
  457.                         /* if not used in this basic block, check if the
  458.                          * register is live out, if so, make it the last
  459.                          * definition of this register */
  460.                         if ((picode->du1.idx[defRegIdx][useIdx] == 0) &&
  461.                             (tbb->liveOut & duReg[regi]))
  462.                             picode->du.lastDefRegi |= duReg[regi];
  463.                     }
  464.  
  465.                     /* If not used within this bb or in successors of this
  466.                      * bb (ie. not in liveOut), then register is useless, 
  467.                      * thus remove it.  Also check that this is not a return
  468.                      * from a library function (routines such as printf 
  469.                      * return an integer, which is normally not taken into
  470.                      * account by the programmer).     */
  471.                     if ((picode->invalid == FALSE) &&
  472.                         (picode->du1.idx[defRegIdx][0] == 0) &&
  473.                         (! (picode->du.lastDefRegi & duReg[regi])) &&
  474. //                        (! ((picode->ic.hl.opcode != HLI_CALL) &&
  475.                         (! ((picode->ic.hl.opcode == HLI_CALL) &&
  476.                             (picode->ic.hl.oper.call.proc->flg & PROC_ISLIB)))) 
  477.                     {
  478.                       if (! (pbb->liveOut & duReg[regi]))    /* not liveOut */
  479.                       {
  480.                         res = removeDefRegi (regi, picode, defRegIdx+1,
  481.                                              &pProc->localId); 
  482.  
  483.                         /* Backpatch any uses of this instruction, within
  484.                          * the same BB, if the instruction was invalidated */
  485.                         if (res == TRUE) 
  486.                             for (p = j; p > pbb->start; p--)
  487.                             {
  488.                                 ticode = pProc->Icode.GetIcode(p-1);
  489.                                 for (n = 0; n < MAX_USES; n++) 
  490.                                 {
  491.                                     if (ticode->du1.idx[0][n] == j)
  492.                                     {
  493.                                         if (n < MAX_USES - 1)
  494.                                         {
  495.                                             memmove (&ticode->du1.idx[0][n],
  496.                                              &ticode->du1.idx[0][n+1], 
  497.                                              (size_t)((MAX_USES - n - 1) * sizeof(Int)));
  498.                                             n--;
  499.                                         }
  500.                                         ticode->du1.idx[0][MAX_USES - 1] = 0;
  501.                                     }
  502.                                 }
  503.                             }
  504.                       }
  505.                       else        /* liveOut */
  506.                         picode->du.lastDefRegi |= duReg[regi];
  507.                     }
  508.                     defRegIdx++;
  509.  
  510.                     /* Check if all defined registers have been processed */
  511.                     if ((defRegIdx >= picode->du1.numRegsDef) ||
  512.                         (defRegIdx == MAX_REGS_DEF))
  513.                         break;
  514.                 }
  515.               }
  516.             }   
  517.         }
  518.     }
  519.  
  520. }
  521.  
  522.  
  523. static void forwardSubs (COND_EXPR *lhs, COND_EXPR *rhs, PICODE picode, 
  524.                          PICODE ticode, LOCAL_ID *locsym, Int *numHlIcodes)
  525. /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the rhs
  526.  * of picode. */
  527. { boolT res;
  528.  
  529.     if (rhs == NULL)        /* In case expression popped is NULL */
  530.         return;
  531.  
  532.     /* Insert on rhs of ticode, if possible */
  533.     res = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.rhs, 
  534.                             locsym->id[lhs->expr.ident.idNode.regiIdx].id.regi,
  535.                             locsym);
  536.     if (res)
  537.     {
  538.         invalidateIcode (picode);   
  539.         (*numHlIcodes)--;
  540.     }
  541.     else
  542.     {
  543.         /* Try to insert it on lhs of ticode*/
  544.         res = insertSubTreeReg (rhs, &ticode->ic.hl.oper.asgn.lhs,
  545.                             locsym->id[lhs->expr.ident.idNode.regiIdx].id.regi,
  546.                             locsym);
  547.         if (res)
  548.         {
  549.             invalidateIcode (picode);
  550.             (*numHlIcodes)--;
  551.         }
  552.     }
  553. }
  554.  
  555.  
  556. static void forwardSubsLong (Int longIdx, COND_EXPR *exp, PICODE picode,
  557.                              PICODE ticode, Int *numHlIcodes) 
  558. /* Substitutes the rhs (or lhs if rhs not possible) of ticode for the 
  559.  * expression exp given */
  560. { boolT res;
  561.  
  562.     if (exp == NULL)        /* In case expression popped is NULL */
  563.         return;
  564.  
  565.     /* Insert on rhs of ticode, if possible */
  566.     res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.rhs, longIdx);
  567.     if (res)
  568.     {
  569.         invalidateIcode (picode);   
  570.         (*numHlIcodes)--;
  571.     }
  572.     else
  573.     {
  574.         /* Try to insert it on lhs of ticode*/
  575.         res = insertSubTreeLongReg (exp, &ticode->ic.hl.oper.asgn.lhs, longIdx);
  576.         if (res)
  577.         {
  578.             invalidateIcode (picode);
  579.             (*numHlIcodes)--;
  580.         }
  581.     }
  582. }
  583.  
  584.  
  585. static boolT xClear (COND_EXPR *rhs, Int f, Int t, Int lastBBinst, PPROC pproc)
  586. /* Returns whether the elements of the expression rhs are all x-clear from
  587.  * instruction f up to instruction t.    */
  588. { Int i;
  589.   boolT res;
  590.   byte regi;
  591.   PICODE picode;
  592.  
  593.     if (rhs == NULL)
  594.         return (FALSE);
  595.  
  596.     switch (rhs->type) {
  597.       case IDENTIFIER:
  598.             if (rhs->expr.ident.idType == REGISTER)
  599.             {
  600.                 picode = pproc->Icode.GetFirstIcode();
  601.                 regi= pproc->localId.id[rhs->expr.ident.idNode.regiIdx].id.regi;
  602.                 for (i = (f + 1); (i < lastBBinst) && (i < t); i++)
  603.                     if ((picode[i].type == HIGH_LEVEL) &&
  604.                         (picode[i].invalid == FALSE))
  605.                     {
  606.                         if (picode[i].du.def & duReg[regi])
  607.                             return (FALSE);
  608.                     }
  609.                 if (i < lastBBinst)
  610.                     return (TRUE);
  611.                 else
  612.                     return (FALSE);    
  613.             }
  614.             else
  615.                 return (TRUE);
  616.             /* else if (rhs->expr.ident.idType == LONG_VAR)
  617.             {
  618. missing all other identifiers ****
  619.             } */
  620.  
  621.       case BOOLEAN_OP:
  622.             res = xClear (rhs->expr.boolExpr.rhs, f, t, lastBBinst, pproc);
  623.             if (res == FALSE)
  624.                 return (FALSE);
  625.             return (xClear (rhs->expr.boolExpr.lhs, f, t, lastBBinst, pproc));
  626.  
  627.       case NEGATION:
  628.       case ADDRESSOF:
  629.       case DEREFERENCE:
  630.             return (xClear (rhs->expr.unaryExp, f, t, lastBBinst, pproc));
  631.     } /* eos */
  632.     return FALSE;
  633. }
  634.  
  635.  
  636. static void processCArg (PPROC pp, PPROC pProc, PICODE picode, Int numArgs,
  637.                          Int *k)
  638. /* Checks the type of the formal argument as against to the actual argument,
  639.  * whenever possible, and then places the actual argument on the procedure's
  640.  * argument list.    */
  641. { COND_EXPR *exp;
  642.   boolT res;
  643.  
  644.     /* if (numArgs == 0)
  645.         return; */
  646.  
  647.     exp = popExpStk();
  648.     if (pp->flg & PROC_ISLIB) /* library function */
  649.     {
  650.       if (pp->args.numArgs > 0)
  651.         if (pp->flg & PROC_VARARG) 
  652.         {
  653.             if (numArgs < pp->args.csym)
  654.                 adjustActArgType (exp, pp->args.sym[numArgs].type, pProc);
  655.         }
  656.         else
  657.             adjustActArgType (exp, pp->args.sym[numArgs].type, pProc);
  658.       res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc);
  659.     }
  660.     else            /* user function */
  661.     {
  662.         if (pp->args.numArgs > 0)
  663.             adjustForArgType (&pp->args, numArgs, expType (exp, pProc));
  664.         res = newStkArg (picode, exp, picode->ic.ll.opcode, pProc);
  665.     }
  666.  
  667.     /* Do not update the size of k if the expression was a segment register
  668.      * in a near call */
  669.     if (res == FALSE)
  670.         *k += hlTypeSize (exp, pProc);
  671. }
  672.  
  673.  
  674. static void findExps (PPROC pProc)
  675. /* Eliminates extraneous intermediate icode instructions when finding
  676.  * expressions.  Generates new hlIcodes in the form of expression trees. 
  677.  * For HLI_CALL hlIcodes, places the arguments in the argument list.    */
  678. { Int i, j, k, lastInst, lastInstN, numHlIcodes;
  679.   PICODE picode,        /* Current icode                            */
  680.          ticode;        /* Target icode                             */
  681.   PBB pbb, nbb;         /* Current and next basic block             */
  682.   boolT res;
  683.   COND_EXPR *exp,       /* expression pointer - for HLI_POP and HLI_CALL    */
  684.             *lhs;        /* exp ptr for return value of a HLI_CALL        */
  685.   PSTKFRAME args;       /* pointer to arguments - for HLI_CALL          */
  686.   byte regi, regi2;        /* register(s) to be forward substituted    */
  687.   ID *retVal;            /* function return value                     */
  688.  
  689.     /* Initialize expression stack */
  690.     initExpStk();
  691.  
  692.     /* Traverse tree in dfsLast order */
  693.     for (i = 0; i < pProc->numBBs; i++)
  694.     {
  695.         /* Process one BB */
  696.         pbb = pProc->dfsLast[i];
  697.         if (pbb->flg & INVALID_BB)     continue;
  698.         lastInst = pbb->start + pbb->length;
  699.         numHlIcodes = 0;
  700.         for (j = pbb->start; j < lastInst; j++)
  701.         {
  702.             picode = pProc->Icode.GetIcode(j);
  703.             if ((picode->type == HIGH_LEVEL) && (picode->invalid == FALSE))
  704.             {
  705.                 numHlIcodes++;
  706.                 if (picode->du1.numRegsDef == 1)    /* byte/word regs */ 
  707.                 {
  708.                     /* Check for only one use of this register.  If this is 
  709.                      * the last definition of the register in this BB, check
  710.                      * that it is not liveOut from this basic block */
  711.                     if ((picode->du1.idx[0][0] != 0) && 
  712.                         (picode->du1.idx[0][1] == 0)) 
  713.                     {
  714.                         /* Check that this register is not liveOut, if it
  715.                          * is the last definition of the register */
  716.                         regi = picode->du1.regi[0];
  717.  
  718.                         /* Check if we can forward substitute this register */
  719.                         switch (picode->ic.hl.opcode) {
  720.                         case HLI_ASSIGN:    
  721.                             /* Replace rhs of current icode into target
  722.                              * icode expression */
  723.                             ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  724.                             if ((picode->du.lastDefRegi & duReg[regi]) &&
  725.                                 ((ticode->ic.hl.opcode != HLI_CALL) &&
  726.                                  (ticode->ic.hl.opcode != HLI_RET)))
  727.                                 continue;
  728.  
  729.                             if (xClear (picode->ic.hl.oper.asgn.rhs, j,
  730.                                     picode->du1.idx[0][0],  lastInst, pProc)) 
  731.                             {
  732.                               switch (ticode->ic.hl.opcode) {
  733.                               case HLI_ASSIGN:
  734.                                     forwardSubs (picode->ic.hl.oper.asgn.lhs,
  735.                                             picode->ic.hl.oper.asgn.rhs,
  736.                                             picode, ticode, &pProc->localId,
  737.                                             &numHlIcodes);
  738.                                     break;
  739.  
  740.                               case HLI_JCOND: case HLI_PUSH: case HLI_RET:
  741.                                 res = insertSubTreeReg (
  742.                                     picode->ic.hl.oper.asgn.rhs,
  743.                                     &ticode->ic.hl.oper.exp,
  744.                                     pProc->localId.id[picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.regiIdx].id.regi,
  745.                                     &pProc->localId);
  746.                                 if (res)
  747.                                 {
  748.                                     invalidateIcode (picode);
  749.                                     numHlIcodes--;
  750.                                 }
  751.                                 break;
  752.  
  753.                               case HLI_CALL:    /* register arguments */
  754.                                 newRegArg (pProc, picode, ticode);
  755.                                 invalidateIcode (picode);
  756.                                 numHlIcodes--;
  757.                                 break;
  758.                               } /* eos */
  759.                             }
  760.                             break;
  761.  
  762.                         case HLI_POP:
  763.                             ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  764.                             if ((picode->du.lastDefRegi & duReg[regi]) &&
  765.                                 ((ticode->ic.hl.opcode != HLI_CALL) &&
  766.                                  (ticode->ic.hl.opcode != HLI_RET)))
  767.                                 continue;
  768.  
  769.                             exp = popExpStk();  /* pop last exp pushed */
  770.                             switch (ticode->ic.hl.opcode) {
  771.                               case HLI_ASSIGN:
  772.                                 forwardSubs (picode->ic.hl.oper.exp, exp, 
  773.                                              picode, ticode, &pProc->localId,
  774.                                              &numHlIcodes); 
  775.                                 break;
  776.  
  777.                               case HLI_JCOND: case HLI_PUSH: case HLI_RET:
  778.                                 res = insertSubTreeReg (exp,
  779.                                     &ticode->ic.hl.oper.exp,
  780.                                     pProc->localId.id[picode->ic.hl.oper.exp->expr.ident.idNode.regiIdx].id.regi,
  781.                                     &pProc->localId);
  782.                                 if (res)
  783.                                 {
  784.                                     invalidateIcode (picode);
  785.                                     numHlIcodes--;
  786.                                 }
  787.                                 break;
  788.  
  789.                               /****case HLI_CALL:    /* register arguments 
  790.                                 newRegArg (pProc, picode, ticode);
  791.                                 invalidateIcode (picode);
  792.                                 numHlIcodes--;
  793.                                 break;    */
  794.                             } /* eos */
  795.                             break;
  796.  
  797.                         case HLI_CALL:  
  798.                             ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  799.                             switch (ticode->ic.hl.opcode) {
  800.                               case HLI_ASSIGN:
  801.                                   exp = idCondExpFunc (
  802.                                                 picode->ic.hl.oper.call.proc,
  803.                                                 picode->ic.hl.oper.call.args);
  804.                                   res = insertSubTreeReg (exp,
  805.                                         &ticode->ic.hl.oper.asgn.rhs,
  806.                                         picode->ic.hl.oper.call.proc->retVal.id.regi,
  807.                                         &pProc->localId);
  808.                                   if (! res)
  809.                                       insertSubTreeReg (exp,
  810.                                         &ticode->ic.hl.oper.asgn.lhs,
  811.                                         picode->ic.hl.oper.call.proc->retVal.id.regi,
  812.                                         &pProc->localId);
  813.     /***  HERE missing: 2 regs ****/
  814.                                     invalidateIcode (picode); 
  815.                                   numHlIcodes--;
  816.                                     break;
  817.  
  818.                               case HLI_PUSH: case HLI_RET:
  819.                                     exp = idCondExpFunc (
  820.                                                 picode->ic.hl.oper.call.proc,
  821.                                                 picode->ic.hl.oper.call.args);
  822.                                     ticode->ic.hl.oper.exp = exp;    
  823.                                     invalidateIcode (picode);
  824.                                   numHlIcodes--;
  825.                                     break; 
  826.  
  827.                               case HLI_JCOND:
  828.                                 exp = idCondExpFunc (
  829.                                                 picode->ic.hl.oper.call.proc,
  830.                                                 picode->ic.hl.oper.call.args);
  831.                                 retVal = &picode->ic.hl.oper.call.proc->retVal,
  832.                                 res = insertSubTreeReg (exp, 
  833.                                         &ticode->ic.hl.oper.exp,
  834.                                         retVal->id.regi, &pProc->localId);
  835.                                 if (res)    /* was substituted */
  836.                                 {
  837.                                       invalidateIcode (picode);
  838.                                     numHlIcodes--;
  839.                                 }
  840.                                 else    /* cannot substitute function */
  841.                                 {
  842.                                     lhs = idCondExpID(retVal,&pProc->localId,j);
  843.                                     newAsgnHlIcode (picode, lhs, exp);
  844.                                 }
  845.                                 break;
  846.                             } /* eos */
  847.                             break;
  848.                       } /* eos */
  849.                     }
  850.                 }
  851.  
  852.                 else if (picode->du1.numRegsDef == 2)   /* long regs */
  853.                 {
  854.                     /* Check for only one use of these registers */
  855.                     if ((picode->du1.idx[0][0] != 0) && 
  856.                         (picode->du1.idx[0][1] == 0) && 
  857.                         (picode->du1.idx[1][0] != 0) &&
  858.                         (picode->du1.idx[1][1] == 0))
  859.                     {
  860.                         switch (picode->ic.hl.opcode) {
  861.                           case HLI_ASSIGN:  
  862.                             /* Replace rhs of current icode into target
  863.                              * icode expression */
  864.                             if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
  865.                             {
  866.                                 ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  867.                                 if ((picode->du.lastDefRegi & duReg[regi]) &&
  868.                                     ((ticode->ic.hl.opcode != HLI_CALL) &&
  869.                                       (ticode->ic.hl.opcode != HLI_RET)))
  870.                                 continue;
  871.  
  872.                                 switch (ticode->ic.hl.opcode) {
  873.                                   case HLI_ASSIGN:
  874.                                     forwardSubsLong (picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx,
  875.                                         picode->ic.hl.oper.asgn.rhs, picode,
  876.                                         ticode, &numHlIcodes);
  877.                                     break;
  878.  
  879.                                   case HLI_JCOND:  case HLI_PUSH:  case HLI_RET:
  880.                                     res = insertSubTreeLongReg (
  881.                                         picode->ic.hl.oper.asgn.rhs,
  882.                                         &ticode->ic.hl.oper.exp,
  883.                                         picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx);
  884.                                     if (res)
  885.                                     {
  886.                                         invalidateIcode (picode);
  887.                                         numHlIcodes--;
  888.                                     }
  889.                                     break;
  890.  
  891.                                     case HLI_CALL:    /* register arguments */
  892.                                     newRegArg (pProc, picode, ticode);
  893.                                     invalidateIcode (picode);
  894.                                     numHlIcodes--;
  895.                                     break;
  896.                                 } /* eos */
  897.                             }
  898.                             break;
  899.  
  900.                           case HLI_POP:
  901.                             if (picode->du1.idx[0][0] == picode->du1.idx[1][0])
  902.                             {
  903.                                 ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  904.                                 if ((picode->du.lastDefRegi & duReg[regi]) &&
  905.                                     ((ticode->ic.hl.opcode != HLI_CALL) &&
  906.                                       (ticode->ic.hl.opcode != HLI_RET)))
  907.                                 continue;
  908.  
  909.                                 exp = popExpStk(); /* pop last exp pushed */
  910.                                 switch (ticode->ic.hl.opcode) {
  911.                                   case HLI_ASSIGN:
  912.                                     forwardSubsLong (picode->ic.hl.oper.exp->expr.ident.idNode.longIdx,
  913.                                         exp, picode, ticode, &numHlIcodes);
  914.                                     break;
  915.                                   case HLI_JCOND: case HLI_PUSH:
  916.                                     res = insertSubTreeLongReg (exp,
  917.                                         &ticode->ic.hl.oper.exp,
  918.                                         picode->ic.hl.oper.asgn.lhs->expr.ident.idNode.longIdx);
  919.                                     if (res)
  920.                                     {
  921.                                         invalidateIcode (picode);
  922.                                         numHlIcodes--;
  923.                                     }
  924.                                     break;
  925.                                 case HLI_CALL:    /*** missing ***/
  926.                                     break;
  927.                                 } /* eos */
  928.                             }
  929.                             break;
  930.  
  931.                           case HLI_CALL:    /* check for function return */
  932.                             ticode = pProc->Icode.GetIcode(picode->du1.idx[0][0]);
  933.                             switch (ticode->ic.hl.opcode) {
  934.                               case HLI_ASSIGN:
  935.                                 exp = idCondExpFunc (
  936.                                             picode->ic.hl.oper.call.proc,
  937.                                             picode->ic.hl.oper.call.args);
  938.                                 ticode->ic.hl.oper.asgn.lhs = 
  939.                                     idCondExpLong(&pProc->localId, DST, ticode,
  940.                                                   HIGH_FIRST, j, E_DEF, 1);
  941.                                 ticode->ic.hl.oper.asgn.rhs = exp; 
  942.                                 invalidateIcode (picode); 
  943.                                 numHlIcodes--;
  944.                                 break;
  945.  
  946.                               case HLI_PUSH:  case HLI_RET:
  947.                                 exp = idCondExpFunc (
  948.                                                 picode->ic.hl.oper.call.proc,
  949.                                                 picode->ic.hl.oper.call.args);
  950.                                 ticode->ic.hl.oper.exp = exp; 
  951.                                 invalidateIcode (picode); 
  952.                                 numHlIcodes--;
  953.                                 break;
  954.  
  955.                               case HLI_JCOND:
  956.                                 exp = idCondExpFunc (
  957.                                                 picode->ic.hl.oper.call.proc,
  958.                                                 picode->ic.hl.oper.call.args);
  959.                                 retVal = &picode->ic.hl.oper.call.proc->retVal;
  960.                                 res = insertSubTreeLongReg (exp,
  961.                                         &ticode->ic.hl.oper.exp,
  962.                                         newLongRegId (&pProc->localId,
  963.                                             retVal->type, retVal->id.longId.h,
  964.                                             retVal->id.longId.l, j));
  965.                                 if (res)    /* was substituted */
  966.                                 {
  967.                                       invalidateIcode (picode);
  968.                                     numHlIcodes--;
  969.                                 }
  970.                                 else    /* cannot substitute function */
  971.                                 {
  972.                                     lhs = idCondExpID(retVal,&pProc->localId,j);
  973.                                     newAsgnHlIcode (picode, lhs, exp);
  974.                                 }
  975.                                 break;
  976.                             } /* eos */
  977.                         } /* eos */
  978.                     }
  979.                 }
  980.  
  981.                 /* HLI_PUSH doesn't define any registers, only uses registers.
  982.                  * Push the associated expression to the register on the local 
  983.                  * expression stack */
  984.                 else if (picode->ic.hl.opcode == HLI_PUSH)
  985.                 {
  986.                     pushExpStk (picode->ic.hl.oper.exp);
  987.                     invalidateIcode (picode);
  988.                     numHlIcodes--;
  989.                 }
  990.  
  991.                 /* For HLI_CALL instructions that use arguments from the stack,
  992.                  * pop them from the expression stack and place them on the 
  993.                  * procedure's argument list */
  994.                 if ((picode->ic.hl.opcode == HLI_CALL) &&
  995.                     ! (picode->ic.hl.oper.call.proc->flg & REG_ARGS)) 
  996.                 { PPROC pp;
  997.                   Int cb, numArgs;
  998.                   boolT res;
  999.  
  1000.                     pp = picode->ic.hl.oper.call.proc;
  1001.                     if (pp->flg & CALL_PASCAL)
  1002.                     {
  1003.                         cb = pp->cbParam;    /* fixed # arguments */
  1004.                         for (k = 0, numArgs = 0; k < cb; numArgs++)
  1005.                         {
  1006.                             exp = popExpStk();
  1007.                             if (pp->flg & PROC_ISLIB)    /* library function */
  1008.                             {
  1009.                                 if (pp->args.numArgs > 0)
  1010.                                     adjustActArgType(exp,
  1011.                                             pp->args.sym[numArgs].type, pProc);
  1012.                                 res = newStkArg (picode, exp, 
  1013.                                                  picode->ic.ll.opcode, pProc);
  1014.                             }
  1015.                             else            /* user function */
  1016.                             {
  1017.                                 if (pp->args.numArgs >0)
  1018.                                     adjustForArgType (&pp->args, numArgs, 
  1019.                                                         expType (exp, pProc));
  1020.                                 res = newStkArg (picode, exp, 
  1021.                                                  picode->ic.ll.opcode, pProc);
  1022.                             }
  1023.                             if (res == FALSE)
  1024.                                 k += hlTypeSize (exp, pProc);
  1025.                         }
  1026.                     }
  1027.                     else        /* CALL_C */
  1028.                     {
  1029.                         cb = picode->ic.hl.oper.call.args->cb;
  1030.                         numArgs = 0;
  1031.                         if (cb) 
  1032.                             for (k = 0; k < cb; numArgs++)
  1033.                                 processCArg (pp, pProc, picode, numArgs, &k);
  1034.                         else if ((cb == 0) && (picode->ic.ll.flg & REST_STK))
  1035.                             while (! emptyExpStk())
  1036.                             {
  1037.                                 processCArg (pp, pProc, picode, numArgs, &k);
  1038.                                 numArgs++;
  1039.                             }
  1040.                     }
  1041.                 } 
  1042.  
  1043.                 /* If we could not substitute the result of a function, 
  1044.                  * assign it to the corresponding registers */
  1045.                 if ((picode->ic.hl.opcode == HLI_CALL) &&
  1046.                     ((picode->ic.hl.oper.call.proc->flg & PROC_ISLIB) !=
  1047.                       PROC_ISLIB) && (picode->du1.idx[0][0] == 0) &&
  1048.                     (picode->du1.numRegsDef > 0))
  1049.                 {
  1050.                     exp = idCondExpFunc (picode->ic.hl.oper.call.proc,
  1051.                                          picode->ic.hl.oper.call.args);
  1052.                     lhs = idCondExpID (&picode->ic.hl.oper.call.proc->retVal,
  1053.                                        &pProc->localId, j);
  1054.                     newAsgnHlIcode (picode, lhs, exp);
  1055.                 }
  1056.             }
  1057.         }
  1058.  
  1059.         /* Store number of high-level icodes in current basic block */
  1060.         pbb->numHlIcodes = numHlIcodes;
  1061.     }
  1062. }
  1063.  
  1064.  
  1065. void dataFlow (PPROC pProc, dword liveOut)
  1066. /* Invokes procedures related with data flow analysis.  Works on a procedure
  1067.  * at a time basis. 
  1068.  * Note: indirect recursion in liveRegAnalysis is possible. */
  1069. { boolT isAx, isBx, isCx, isDx;
  1070.   Int idx;
  1071.  
  1072.     /* Remove references to register variables */
  1073.     if (pProc->flg & SI_REGVAR)
  1074.         liveOut &= maskDuReg[rSI];
  1075.     if (pProc->flg & DI_REGVAR)
  1076.         liveOut &= maskDuReg[rDI];
  1077.  
  1078.     /* Function - return value register(s) */
  1079.     if (liveOut != 0)
  1080.     {
  1081.         pProc->flg |= PROC_IS_FUNC;
  1082.         isAx = (boolT)(liveOut & power2(rAX - rAX));
  1083.         isBx = (boolT)(liveOut & power2(rBX - rAX));
  1084.         isCx = (boolT)(liveOut & power2(rCX - rAX));
  1085.         isDx = (boolT)(liveOut & power2(rDX - rAX));
  1086.  
  1087.         if (isAx && isDx)       /* long or pointer */
  1088.         {
  1089.             pProc->retVal.type = TYPE_LONG_SIGN;
  1090.             pProc->retVal.loc = REG_FRAME;
  1091.             pProc->retVal.id.longId.h = rDX;
  1092.             pProc->retVal.id.longId.l = rAX;
  1093.             idx = newLongRegId (&pProc->localId, TYPE_LONG_SIGN, rDX, rAX, 0);
  1094.             propLongId (&pProc->localId, rAX, rDX, "\0"); 
  1095.         }
  1096.         else if (isAx || isBx || isCx || isDx)    /* word */
  1097.         {
  1098.             pProc->retVal.type = TYPE_WORD_SIGN;
  1099.             pProc->retVal.loc = REG_FRAME;
  1100.             if (isAx)
  1101.                 pProc->retVal.id.regi = rAX;
  1102.             else if (isBx)
  1103.                 pProc->retVal.id.regi = rBX;
  1104.             else if (isCx)
  1105.                 pProc->retVal.id.regi = rCX;
  1106.             else 
  1107.                 pProc->retVal.id.regi = rDX;
  1108.             idx = newByteWordRegId (&pProc->localId, TYPE_WORD_SIGN,
  1109.                                     pProc->retVal.id.regi);
  1110.         }
  1111.     }
  1112.  
  1113.     /* Data flow analysis */
  1114.     pProc->liveAnal = TRUE;
  1115.     elimCondCodes (pProc);
  1116.     genLiveKtes (pProc);
  1117.     liveRegAnalysis (pProc, liveOut);   /* calls dataFlow() recursively */
  1118.     if (! (pProc->flg & PROC_ASM))        /* can generate C for pProc        */
  1119.     {
  1120.         genDU1 (pProc);            /* generate def/use level 1 chain */
  1121.         findExps (pProc);         /* forward substitution algorithm */ 
  1122.     }
  1123. }
  1124.  
  1125.